在Unidbg文章中, 我们尝试过多次主动调用, 文中可以发现, 只有253b8c85
这个的key是不变的.
Unidbg运行一遍,搜索运行下这个Key, 我们在下面的堆栈中, 可以看到memcpy的调用地址为0x0498ec
Unidbg trace整个流程, 在010editor中搜索253b8c85
可以发现,我们这个数据首次发现的位置位于0x1bfb54
偏移处.
可以知道我们的结果是由 0xa53b8c85
& 0x7fffffff
得到的.
[14:54:36 435][libshpssdk.so 0x1bfb54] [ab010b0a] 0x401bfb54: "and w11, w13, w11" w13=0x7fffffff w11=0xa53b8c85 => w11=0x253b8c85 // w11 = w13 & w11
w13又是固定的. 所以我们需要找到0xa53b8c85
是如何生成的
💡分析trace, 我们应该以结果为导向. 只关注于我们需要的数据. 一些其他无用的运算我们应该选择性跳过. 一行行分析下去十分的疲惫.
搜索0xa53b8c85
, 找到第一次出现的地方.
w14 = w1 + w14
, w1 比较简单, 我们先分析复杂的.
[14:54:36 426][libshpssdk.so 0x1bfe28] [2e000e0b] 0x401bfe28: "add w14, w1, w14" w1=0x65 w14=0xa53b8c20 => w14=0xa53b8c85
搜索0xa53b8c20
, 找到第一次出现的地方
w11 = w11 * w13
[14:54:36 423][libshpssdk.so 0x1bfcb0] [6b7d0d1b] 0x401bfcb0: "mul w11, w11, w13" w11=0x334b w13=0xa1f6f060 => w11=0xa53b8c20
搜索0xa1f6f060
, 找到第一次出现的地方
w14 = w1 + w14
[14:54:36 416][libshpssdk.so 0x1bfe28] [2e000e0b] 0x401bfe28: "add w14, w1, w14" w1=0x75 w14=0xa1f6efeb => w14=0xa1f6f060
搜索0xa1f6efeb
, 找到第一次出现的地方
w11 = w11 * 13
[14:54:36 413][libshpssdk.so 0x1bfcb0] [6b7d0d1b] 0x401bfcb0: "mul w11, w11, w13" w11=0x334b w13=0xf419b1e1 => w11=0xa1f6efeb
搜索0xf419b1e1
, 找到第一次出现的地方
w14 = w1 + w14
[14:54:36 406][libshpssdk.so 0x1bfe28] [2e000e0b] 0x401bfe28: "add w14, w1, w14" w1=0x72 w14=0xf419b16f => w14=0xf419b1e1
搜索0xf419b16f
,找到第一次出现的地方
w11 = w11 * w13
[14:54:36 403][libshpssdk.so 0x1bfcb0] [6b7d0d1b] 0x401bfcb0: "mul w11, w11, w13" w11=0x334b w13=0x8c687fed => w11=0xf419b16f
有兴趣的继续找下去. 我是比较累了. 我们再来看看规律.
[14:54:36 403][libshpssdk.so 0x1bfcb0] [6b7d0d1b] 0x401bfcb0: "mul w11, w11, w13" w11=0x334b w13=0x8c687fed => w11=0xf419b16f
[14:54:36 406][libshpssdk.so 0x1bfe28] [2e000e0b] 0x401bfe28: "add w14, w1, w14" w1=0x72 w14=0xf419b16f => w14=0xf419b1e1
[14:54:36 413][libshpssdk.so 0x1bfcb0] [6b7d0d1b] 0x401bfcb0: "mul w11, w11, w13" w11=0x334b w13=0xf419b1e1 => w11=0xa1f6efeb
[14:54:36 416][libshpssdk.so 0x1bfe28] [2e000e0b] 0x401bfe28: "add w14, w1, w14" w1=0x75 w14=0xa1f6efeb => w14=0xa1f6f060
[14:54:36 423][libshpssdk.so 0x1bfcb0] [6b7d0d1b] 0x401bfcb0: "mul w11, w11, w13" w11=0x334b w13=0xa1f6f060 => w11=0xa53b8c20
[14:54:36 426][libshpssdk.so 0x1bfe28] [2e000e0b] 0x401bfe28: "add w14, w1, w14" w1=0x65 w14=0xa53b8c20 => w14=0xa53b8c85
[14:54:36 435][libshpssdk.so 0x1bfb54] [ab010b0a] 0x401bfb54: "and w11, w13, w11" w13=0x7fffffff w11=0xa53b8c85 => w11=0x253b8c85 // w11 = w13 & w11
通过上面的跟值找值, 可以发现我们最终的结果. 可以大致的翻译成如下大白话:
循环(条件未知){
结果 = (上一次运算的结果 * 0x334b + 未知的字节)
}
结果 = 结果 & 0x7fffffff
因为可以猜测到循环, 并且, 我们目前需要知道,这个未知的字节是什么?
所以我再次搜索0x401bfe28: "add w14, w1, w14" w1=
我们只需要,这个框框选择出来的长的指令. 所以我们匹配到的结果
手动处理了一点数据, 把选择的字节提取出来.
惊奇的发现.这数据有点好看.
没错,这就是我们的URL
并且开头是以0x00开始的
所以, 我们就可以写一个算法进行验证了
url = "/api/v4/search/search_page_common?by=relevancy&extra_param=%7B%22global_search_session_id%22%3A%22NqAYm66NYy45DbQoklaKEBuaQD%2BQgayKLEeqNuK3MhM%3D-1734075545797-global%22%2C%22search_session_id%22%3A%22NqAYm66NYy45DbQoklaKEBuaQD%2BQgayKLEeqNuK3MhM%3D-1734075560832-search%22%7D&keyword=ab&newest=0&order=desc&page=1&page_type=search&scenario=PAGE_GLOBAL_SEARCH&version=2&view_session_id=NqAYm66NYy45DbQoklaKEBuaQD%2BQgayKLEeqNuK3MhM%3D-1734075560832&with_filter_config=true"
result = 0
for i in url:
b = i.encode('utf-8')
# 使用 & 0xffffffff 可以模拟 C/C++ 等语言中 uint32_t 的行为
# 保证结果始终在 0 到 4294967295 之间"
b = ord(b) & 0xffffffff
result = (result * 0x334b + b) & 0xffffffff
# toHex
print(hex(result))
result = result & 0x7fffffff
print(f"{result:04x}")
运算结果正确.