哈希表概念
1.相信大家经常在UE4或者UE5游戏逆向中遇到下面的代码段
$ ==> > 41:8B42 0C > mov eax,dword ptr ds:[r10+C] >
$+4 > 3B05 AE589B04 > cmp eax,dword ptr ds:[7FF7B68B74F4] >
$+A > 7D 28 > jge projectlh.7FF7B1F01C70 >
$+C > 99 > cdq >
$+D > 0FB7D2 > movzx edx,dx >
$+10 > 03C2 > add eax,edx >
$+12 > 8BC8 > mov ecx,eax >
$+14 > 0FB7C0 > movzx eax,ax >
$+17 > 2BC2 > sub eax,edx >
$+19 > 48:98 > cdqe >
$+1B > C1F9 10 > sar ecx,10 >
$+1E > 48:63C9 > movsxd rcx,ecx >
$+21 > 48:8D1440 > lea rdx,qword ptr ds:[rax+rax*2] >
$+25 > 48:8B05 78589B04 > mov rax,qword ptr ds:[7FF7B68B74E0] >
$+2C > 48:8B0CC8 > mov rcx,qword ptr ds:[rax+rcx*8] >
$+30 > 48:8D1CD1 > lea rbx,qword ptr ds:[rcx+rdx*8] >
$+34 > 8B43 08 > mov eax,dword ptr ds:[rbx+8] >
2.其实这个就是在进行解密哈希ID,有的人不明白这个ID是如何通过这个哈希表拿到我们的哈希对象的
3.额~老师,啥是哈希表?
4.我们首先看看百度是如何解释的
5.正如上面所说我们对任意给定的关键字值key,带入函数后都能返回一个表中的地址,那么我们称这个表是哈希表
6.是不是感觉和我们遇到的情况一样,我们在UE4中通过一个哈希ID(Key),通过上面的代码块拿到对象
7.好~这里明白了大致的概念,现在我们就着手动态分析这段汇编代码,搞清楚是如何解密ID拿到对象
哈希ID来源
1.首先在头下断点,并断下
2.观察此时的寄存器r10
3.转到内存发现r10是一个对象
4.按F8执行一句,继续观察eax
5.发现eax存的是拿到的4字节r10对象+C的哈希ID
6.从来这,我们观察到所有的r10对象+C偏移都是一个哈希ID!
7.结论大家一定要记住!以后看到这个对象+C偏移的地址存有一个4字节ID那么这个对象就是哈希对象
8.然后拿到这个哈希ID经过下面的代码段就可以返回对象了,现在我们看看汇编是如何操作这个哈希ID的
动态分析解密ID
1.我们继续F8执行到这里 movzx edx, dx 的下一句
2.当执行 movzx edx, dx 后,观察寄存器edx是0,好 我们继续
3.执行add eax, edx 后,观察到把原本eax(哈希ID)加上了edx(0),然后赋值给了eax(哈希ID),注意这里都是在操作4字节哦,因为哈希ID就是一个4字节
4.到这里,我们的寄存器edx(0),eax(哈希ID)由于加上0还是等于哈希ID
5.继续执行,经过这句代码 mov ecx, eax,我们观察到eax(哈希ID)赋值给了ecx(哈希ID)
6.继续F8执行movzx eax, ax后,这里就是关键点了,我们观察寄存器变化
7.原本的eax()变成了1D73,是不是取了原本31D73的低4位呢?也就是低2字节,注意我们这里都是按4字节讲的
8.其实不难分析,原来 ax 就是低2字节的意思,为了方便理解,这里画了一张图
9.其实说白了,rax是8字节,eax是4字节,ax是2字节
10.所以我们看到原本31D73,居然取了低2字节为1D73赋值给了eax
11.继续F8执行sub eax, edx
12.eax(1D73)加上edx(0)无任何变化
13.继续F8执行过sar ecx, 0x10, 这句的时候,又来到一个关键点
14.我们发现执行后,ecx变成了3,这个3来源哪里呢?
15.分析得到这个3居然就是上面哈希ID的高2字节
16.额,他是如何得到的呢?其实仔细看到sar ecx, 0x10这个sar汇编指令的作用我们就知道原因了
17.有的同学不太明白sar的作用,我们百度看看
18.居然是位运算!,而且我们看到sar ecx, 0x10中的0x10换算成十进制就是16刚好右移动了16位(二进制位),是不是相当于把原本的低16位给移除了,原本的搞16位变成了现在的
低16位也就是3!
19.这里画了一张图便于分析
20.分析后,原来sar ecx, 0x10这句代码是取哈希ID的高4字节,而movzx eax, ax是取低4字节
偏移表达式
1.上面我们解密了ID分成了2个部分分别存在了rcx(哈希ID的高4字节),eax(哈希ID的低4字节)
2.我们继续执行下,这里比较简单就是偏移表达式的组合
3.能得到一个偏移表达式
[[0x00007FF7B68B74E0]+ecx8]+eax3*8]==哈希对象
4.原来我们的ecx和eax就是2个索引,分别从哈希ID分解得到
5.那么最终我们得出结论如图
6.好了今天的哈希ID解密就讲到这里,是不是很简单呢?
7.感谢同学们的支持,感谢支持迪大学院285530835