李恒道 发表于 2023-12-11 20:08:50

抖音JSVMP算法逆向(二)

那我们问题就变成了数字和那个字符串哪里来的

# 数字来源

![图片.png](data/attachment/forum/202312/09/091131tfwgfuvbwjzdrbo8.png)
我们可以看到附近最近的数字是从5647414到54生成的
位置是` 位置 2 索引j 47 索引A 708`,下断点`j===47&A===708&O===21`找到了
![图片.png](data/attachment/forum/202312/09/091243xb9n99f9tt9191v6.png)
这部分是一个位与,将栈的最后一个位置弹出,与当前位置进行位与
根据日志计算5647414&63刚好得54
![图片.png](data/attachment/forum/202312/09/091351wppch4b3bxcacu1a.png)
然后计算63和5647414是怎么得出的,先看63
在最近生成的上一个打断点` 位置 2 索引j 72 索引A 704`
![图片.png](data/attachment/forum/202312/09/093224rk0k08c0x40cclyk.png)
找到了,这里原名字叫f,为了更直观起名叫未知数组f
![图片.png](data/attachment/forum/202312/09/093314c3fl67m6z7lrbl67.png)
他的作用是从一个大数组取出特定位置的数字
![图片.png](data/attachment/forum/202312/09/093346bzw34ktz9o950o50.png)
在vscode更改名字后更具有标识性,搜索找到了
往里插一个log看看情况
![图片.png](data/attachment/forum/202312/09/093745dddt9nq96qsjnbsm.png)
发现有三次生成,其中根据第三次后断下来数组索引,所以第三次是我们需要的
![图片.png](data/attachment/forum/202312/09/093807czewmji3w9yrkm3v.png)
往上堆栈回溯发现A是字节码,不会变动
![图片.png](data/attachment/forum/202312/09/093855gngwlfgnz0swi85n.png)
同理,向上回溯发现另外参数也都是根据这里传入的参数得来的,多次刷新不会变动
所以可以视为该数组的生成时固定的,同时A字节码也是固定的
所以这里暂且可以得出数字的生成(63)是基本稳定的,接下来看5647414是如何得到的
同理,先搜索找最近生成的上一行
![图片.png](data/attachment/forum/202312/09/094518m2h1cuzodou1e6kk.png)
找到了,这里是取最上面的一个变量然后与第二个进行|运算
![图片.png](data/attachment/forum/202312/09/095503fwr9w3wsrbw5hmsv.png)
![图片.png](data/attachment/forum/202312/09/095539f8qsgq995qzgsz8g.png)
我们试一下原数据
![图片.png](data/attachment/forum/202312/09/095552e92m4bgxwzk9d9f9.png)
成功对上了
![图片.png](data/attachment/forum/202312/09/095615avxiymbxu0uhdivm.png)
那问题就变成了54和5647360哪来的了
那我们现在总结一下
```
5636096 ^ 11264 = 5647360
5647360 ^ 54 = 5647414
计算出5647414后,计算最后一位数字
5647414 & 63 = 54
9 字符取自 54位
```
因为5636096 的出处继续追溯可能还要很久,所以我们先逐步计算一下后几位
同理可知倒数第二位是 >>字符计算6位,同时因为都是位运算,所以我们可以再接下来的过程里直接证明计算
如这里的M取自15,15极有可能通过61440和12计算
测试可知61440>>12得出的15
61400又可以通过上面得出,测试可知851356&258048得出61400
所以调都不用调了直接算结果
![图片.png](data/attachment/forum/202312/11/200533qtev2htvj0u5jvjj.png)

我们可以算出来两组表
倒数四位如下
```
5636096 ^ 11264 = 5647360 //未测
5647360 ^ 54 = 5647414

5647414 & 16515072 = 5505024 // 16515072取自数组
5505024 >> 18 = 21
X 字符取自 21

5647414 & 258048 = 139264 // 258048 取自数组
139264 >> 12 = 34
7 字符取自 34

5647414 & 4032 = 3072// 4032 取自数组
3072 >> 6 = 48
j 字符取自 48

5647414 & 63 = 54
9 字符取自 54
```
倒数第二组如下
```
786432 ^ 64768 = 851200 //未测
851200 ^ 156 = 851356

851356 & 16515072 = 786432 // 16515072 取自数组
786432 >> 18 = 3
p 字符取自 3

851356 & 258048 = 61440 // 258048 取自数组
61440 >> 12 = 15
M 字符取自 15

851356 & 4032 = 3456// 4032 取自数组
3456 >> 6 = 54
9 字符取自 54

851356 & 63 = 28
W 字符取自 28
```
可以得出每个组都有特定的字符顺序
同时外套了一个大循环
得出了数组规律后

接下来我们尝试计算出这个数字的来源以及字符串的生成。

王一之 发表于 2023-12-12 10:07:24

曲高和寡{:4_115:}

806350554 发表于 2023-12-12 15:25:25

为什么这么高级。看不明白

李恒道 发表于 2023-12-12 15:28:35

王一之 发表于 2023-12-12 10:07
曲高和寡

{:4_115:}憋了一个月的重磅炸弹,结果没人看

李恒道 发表于 2023-12-12 15:29:57

王一之 发表于 2023-12-12 10:07
曲高和寡

{:4_115:}憋了一个月的重磅炸弹,结果没人看

李恒道 发表于 2023-12-12 15:32:25

806350554 发表于 2023-12-12 15:25
为什么这么高级。看不明白
jsvmp类似于传统vmp
相当于破坏了原本的程序流程
重构了一个简易的解释器执行
比如
function add(a,b){
   return a+b
}
可以被翻译成
if(op==631){
    a=stack,b=stack,stack[++addr]=a+b
}
相当于将系统里原本的栈,PC,都基于系统上再搞了一套
哥哥有兴趣也可以按文章走一遍过程
还是挺有意思的

王一之 发表于 2023-12-12 15:59:00

李恒道 发表于 2023-12-12 15:29
憋了一个月的重磅炸弹,结果没人看

哥哥G点与常人不同(

陈公子的话 发表于 2023-12-12 18:33:17

道总可以试试补环境

李恒道 发表于 2023-12-12 19:29:33

陈公子的话 发表于 2023-12-12 18:33
道总可以试试补环境
就是为了挑战自己玩的,想要写一些比较精品的争取下次骗吾爱衣服

抖音的即使补环境也需要去逆固定字节码
里面有一部分环境检测的东西

李恒道 发表于 2023-12-12 19:31:18

王一之 发表于 2023-12-12 15:59
哥哥G点与常人不同(

jsvmp啊
国内T0强度的细致讲解都不看{:4_115:}
页: [1] 2
查看完整版本: 抖音JSVMP算法逆向(二)