Forest浏览器插件研究

Android 软件整不太明白来浏览器插件试试,居然成功了。

这个浏览器插件没混淆过,直接读就完了。

适用于 4.8.0 版本,下文一切行号都是原文件行号,不是经过更改后的。

从 4.10.0 版本开始,加入了混淆。

以下更新1于 2021-03-28,适用于 4.10.0 版本及以上。

更新2于 2022-01-14,适用于 5.0.8 版本及以上。

注:须登录。

解锁全部树种,包括限定树种

问题在哪?

有两个问题需要解决:

  1. 在界面上看见树种被解锁的样子,才可能点击它从而种下这种树。
  2. 种树需要权限,要通过插件里的权限测试。

一劳永逸(更新2)

之前的方法能解决问题,但挺麻烦的。

所以问题出在哪里了呢?

往根上找。

预处理的时候发了一个 GET 请求叫 unlocked,然后把这个请求结果记录在一个变量里,用的时候就读这个变量。所以直接对它下手就行。很简单的方法:让他请求的时候就认定把所有树种买了。根据之前玩他的网络请求的经验,搜一下这个东西

1
get("/tree_types/unlocked")

改成

1
get("/tree_types")

就行。

似乎省了不少事。

第一个

更新1

根据特征还是能找到。

1
Sr=[31,32,41,42,43,44,46,47,48,49,50,51,52,53,54,55,56,59,60,61,66,70,73];

这个地方就是下文的那个。直接把列表里的元素注释掉或者删掉就好了。

原文

反正都是明文,读就完了。主战场在 background.js 这里。

到处逛逛,能发现 1791 行有一个 TREE_TYPES,里面是各种树的信息,再往下翻,可以看到 2372 行有一个 HIDDEN_TREE_TYPES,对照一下里面的编号,发现这些就是限定树种。

那解决办法很简单啊,把这点数字删掉就行了。

替换:

1
var HIDDEN_TREE_TYPES = [31, 32, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 60, 61, 66, 70, 73];

为:

1
var HIDDEN_TREE_TYPES = [/* 31, 32, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 60, 61, 66, 70, 73 */];

(为了方便恢复还是注释掉比较好)

无注释版:

1
var HIDDEN_TREE_TYPES = [];

然后现在就可以发现那些限定树种都被显示出来了,但是上面挂着锁,怎么办呢?

搜索 locker,发现 5667 行有这么一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
if (isTreeTypePurchased(background_currentTreeIndex)) {
background_hide('locker');
executeToFrontPage(function (fp) {
return Object(helpers["d" /* removeClass */])(fp.document.getElementById('tree'), 'shadowed-tree');
});
topDesc = browser_polyfill_default.a.i18n.getMessage('main_top_description_ready');
} else {
background_unhide('locker');
executeToFrontPage(function (fp) {
return Object(helpers["a" /* addClass */])(fp.document.getElementById('tree'), 'shadowed-tree');
});
topDesc = browser_polyfill_default.a.i18n.getMessage('main_top_description_locked');
}

结合英文理解一下,意思就是如果这种树已经购买过了(那个 if 里面),那么就隐藏掉锁。

这里的解决办法有两种,一种是让 isTreeTypePurchased 这个函数恒返回 true,还有一种是直接跳过对他的判断。

不过嘛,这里选择前者,因为这个函数还涉及到了其他部分的判断,为了不用改那么多地方,就直接默认所有树都买了就好。

第二个

更新1

这个要找的话根据前文的 locker 那里可以发现一个判定函数 nt()

1
function nt(t){return b[t].product_id==-1?!0:ee.find(({gid:r})=>r===b[t].id)!==void 0}

管他三七二十一里面 return true 就好了

原文

书接上文,让我们来到 isTreeTypePurchased 这个函数定义的地方,在 5596 行。

用不着管那么多逻辑了,直接 true 就完了。

替换:

1
2
3
4
5
6
7
8
function isTreeTypePurchased(currentTreeIndex) {
if (tree_types["b" /* TREE_TYPES */][currentTreeIndex].product_id == -1) return true;
var isPurchased = purchasedProducts.find(function (_ref11) {
var gid = _ref11.gid;
return gid === tree_types["b" /* TREE_TYPES */][currentTreeIndex]['id'];
}) !== undefined;
return isPurchased;
}

为:

1
2
3
4
5
6
7
8
9
function isTreeTypePurchased(currentTreeIndex) {
// if (tree_types["b" /* TREE_TYPES */][currentTreeIndex].product_id == -1) return true;
// var isPurchased = purchasedProducts.find(function (_ref11) {
// var gid = _ref11.gid;
// return gid === tree_types["b" /* TREE_TYPES */][currentTreeIndex]['id'];
// }) !== undefined;
// return isPurchased;
return true;
}

或无注释版:

1
2
3
function isTreeTypePurchased(currentTreeIndex) {
return true;
}

结语

如此简单就可以在浏览器里中种所有树了。不过需要专业版账号才能把种的树同步到 app 上。

快速刷树

更新2

找特征。

1
Math.round((new Date(a.endTime).getTime()-Date.now())/1e3)>0?["Started",a.endTime]:["Succeeded",null]

前面是个判断嘛,把问号前的让它恒为否就行。

改为

1
false?["Started",a.endTime]:["Succeeded",null]

更新1

这个根据特征明显的 new Date(new Date() 就能搜到。

1
Ve=new Date(new Date().getTime()+N*1e3+200)

直接改成

1
Ve=new Date(new Date().getTime())

就行了。

原文

插件里实现了一个倒计时,那么如果更改倒计时的终止时间就可以瞬间结束了。

在 6185 行找到叫 startTimer 的函数,里面有一些关键语句。

在 6207 行有一个 targetSysTime,终止时间就是这个。

替换:

1
targetSysTime = new Date(new Date().getTime() + remainingTime * 1000 + 200);

为:

1
targetSysTime = new Date(new Date().getTime()/*  + remainingTime * 1000 + 200 */);

或无注释版:

1
targetSysTime = new Date(new Date().getTime());

于是就能发现种完植物秒出。

(不过好像这么做是领不到金币的)

(不过都能随便种树了要金币干嘛)

  • Copyrights © 2020-2023 STDquantum