JS逆向实战:扣代码时如何快速定位结果不对的问题?
大家好,今天分享一个在扣代码的时候如何快速定位数据问题的方法。
扣代码
不知道有没有小伙伴遇到过类似的问题,在扣代码的时候,一般都是缺啥补啥,遇到了报错就补上对应的函数,缺失什么就补什么。但是在补完所有缺失函数后,发现运行加密函数,返回的结果不对,和在网页上面计算的不一致,这个时候要如何解决呢?
我们来想一下,在运行扣完的代码后,正常来说执行这些代码会运行正确的计算逻辑,得到正确的结果。但是结果是错误的,反推一下,那执行逻辑应该也是错误的。会有什么问题导致执行逻辑发生错误呢?做过后端开发的小伙伴应该知道,大概率就是两种方法:
- if 判断、逻辑运算符、三元运算符
- 报错捕获
if 判断
先说 if
判断,代码中可以使用 if
判断是否为浏览器环境来让正常的逻辑分叉,进而执行错误的逻辑。逻辑运算符和三元运算符也是一样的,通过判断环境检测的结果来让变量初始化成正确的值或者错误的值。
例如这里执行了一段混淆后的代码,里面检测了一些环境和函数,通过执行结果和三元运算符来判断浏览器环境,从而让 b
变量的某些属性赋值为不同的值,可能会导致计算结果出错。
报错捕获
报错捕获也是常见的检测方式,一般会在 try
关键字中执行一些本来不报错的指令,例如浏览器中存在的函数,但是在 nodejs
中不存在,执行后就会报错。但是在报错后使用 catch
捕获然后继续执行,会导致 try
中的部分语句没有执行到,从而让计算过程缺失部分步骤,导致计算结果出现错误。
当然了,也有反过来的,在浏览器中执行只有 nodejs
中存在的函数,本来应该报错的但在 nodejs
中就不报错了,也会导致执行了错误的逻辑导致错误。
例如这里,使用 eval
执行 CanvasCaptureMediaStreamTrack
函数但不调用,在浏览器中会正常执行不报错,但是在 nodejs
中会报错,从而被 catch
捕获,让 cb
变量和 cu
变量初始化为错误的值,进而影响后续的计算结果。
如何快速定位
那么对于以上两种情况,如何快速定位问题呢?
代理之环境自吐
对于第一种不会报错的情况,可以使用代理的方式让代码将环境自己吐出来,简称环境自吐。原理就是使用代理,封装对于特定对象的 get
和 set
方法,有点类似于 Java 的 getter
和 setter
注解哈哈。
以下代码仅供参考,代码来源
1 | function setProxy(proxyObjs) { |
通过监控某些对象的 set
和 get
方法,可以将代码在运行时对这些对象所做的操作都打印出来, 后续可以从日志中看到代码都访问了哪些环境,然后将对应的属性放到浏览器获取正确的值后,就可以补上对应的环境,再次运行代码就不会报错了。
在 nodejs
中运行后,可以看到好多的属性获取的时候返回值都是 undefined
,这都是要补的环境。
补环境这里多说一句,除了写代码也可以使用 v_jstools 插件来输出对应的环境,只需要勾选对应的对象,不用写一行代码即可获取大量的环境信息,大大节省补环境的时间。
补环境还有更多好用的工具和方法就不多讲了(其实我不会哈哈),留给大家慢慢探索。
报错检测
报错检测会稍微简单一些,既然报错的时候会使用 try
和 catch
,那执行报错了肯定会输出错误信息。但是在混淆后的代码中 catch
一般都会被置空,我们手动补上输出语句不就好了。
以猿人学的第 14 题为例,扣完代码后发现运行的结果不对,但是也不缺失任何函数,说明肯定有环境检测或者在哪里报错了但是没有提示出来,环境检测可以使用上面的方法来检测。
我们将所有的 catch
都搜索出来并且补上打印语句,将错误都打印出来看看。
再次运行,会发现在打印结果之前打印出来很多错误堆栈,按照报错堆栈将所有问题一一解决以后,重新运行,发现结果正确了,至此扣代码完成,可以本地运行或者远程调用了。
总结
上面所说的所有方法并不是唯一,还有更多的大佬开发了很多的好用的工具,大家可以多多试用,可以在逆向的时候事半功倍,感谢大家的阅读。
本文章首发于个人博客 LLLibra146’s blog
本文作者:LLLibra146
更多文章请关注公众号 (LLLibra146):
版权声明:本博客所有文章除特别声明外,均采用 © BY-NC-ND 许可协议。非商用转载请注明出处!严禁商业转载!