Appearance
分析压缩后的源代码
Analyzing minified source code | Obsidian Typings (fevol.github.io)
遍历和分析源代码
有时仅仅查看函数名称并不足以理解它的功能,这就是为什么查看压缩源代码中的实际函数定义会很有帮助。
首先打开控制台,然后进入 Sources
标签页。在这里你会找到定义了所有内部方法的 app.js
文件。
- 进入
Sources
标签页 - 选择
app.js
文件 格式化代码
(可选)- 将代码复制到你选择的 IDE 中(可选,但推荐)
有了压缩代码的访问权限后,你就可以开始搜索并找到你想要查看的方法的定义。
对于任何方法 "XYZ",首先直接搜索 "XYZ"。通常,方法的定义方式有以下几种:
t.XYZ = ...
(静态方法)t.prototype.XYZ = ...
(原型方法)function XYZ(
(内部/压缩方法)
在这个阶段,你可能会很幸运地找到单一的定义,或者可能会找到多个方法定义。 在后一种情况下, 你需要尝试查看代码上下文来确定该方法属于哪个接口/类。 找到正确定义的主要技巧是,查看在原型上定义的其他方法, 并检查这些方法是否与你的对象的其他方法匹配。
找到正确的定义行后,你就可以开始分析代码来确定输入/输出类型 及其行为。
例如,requestSaveConfig
方法(前面提到过)的定义如下:
js
n.requestSaveConfig = at(n.saveConfig.bind(n), 1e3, !0),
在这里,我们发现了以下三点:
at
是一个接受三个参数的压缩函数,其返回值就是该方法的返回值1e3
是1000
的简写表示法!0
是true
的简写表示法
(在压缩代码中,你需要习惯很多这样的简写和结构变化)
由于我们不知道 at
的作用,我们需要再次搜索代码。确保启用大小写敏感和全字匹配搜索,因为 at
是一个很常见的词。 开始搜索 function at
或 .prototype.at
。如果幸运的话,这会带你找到以下定义:
js
function at(e, t, n) {
void 0 === t && (t = 0), void 0 === n && (n = !1);
var i,
r = null,
o = null,
a = null,
s = 0,
l = function () {
var t = o,
n = a;
/* ... */
};
}
你可能想要通过你喜欢的 LLM 或反压缩工具来处理代码,使其至少变得稍微可以理解。 根据你是否成功解密了代码,你现在可以明确定义该方法的行为和/或类型。
异步函数
逆向工程异步函数更具挑战性。
在 app.js
中,你不会看到很多 async
函数。大多数都被转换成了等效的状态机代码。
- 如果你的函数包含
v(this, void 0,
,那它就是一个异步函数。 - 如果你的函数包含
return [2]
,你的函数不返回任何内容,函数的返回类型将是Promise<void>
。 - 如果你的函数包含
return [2, someValue]
,你的函数返回someValue
,函数的返回类型将是Promise<TypeOfSomeValue>
。 - 如果你的函数包含
return [4, someValue]
,它对应于await someValue
,稍后通过n.sent()
获取等待的值。
关于它具体如何工作的更多细节,请参见 The __generator
helper 文档。