登陆游戏,等待TP驱动加载完成。
WindDbg输入 u NtReadVirtualMemory,来到被游戏Hook的地方。
在地址0B06FDD10 下访问断点。几秒钟后游戏断下
下面分析改位置的代码:
绕过检测的方法就不贴了。另外这部分代码上面同样有代码校验,并且有个地方进行了VM。
有意思的就是 esi 寄存器就是 校验表的地址,
这个表里面 存储了被 校验的代码位置,校验长度,校验值。
WindDbg输入 u NtReadVirtualMemory,来到被游戏Hook的地方。
代码:
kd> u NtReadVirtualMemory
nt!NtReadVirtualMemory:
805b52c2 b810dd6fb0 mov eax,0B06FDD10h
805b52c7 ffe0 jmp eax
下面分析改位置的代码:
代码:
tessafe + 0x1AF082
b08fb082 8bff mov edi,edi
b08fb084 55 push ebp
b08fb085 8bec mov ebp,esp
b08fb087 83ec10 sub esp,10h
b08fb08a 8b0d649a90b0 mov ecx,dword ptr ds:[0B0909A64h] ecx = 0xbd
b08fb090 53 push ebx
b08fb091 56 push esi
b08fb092 57 push edi
b08fb093 bf609a90b0 mov edi,0B0909A60h
b08fb098 81ef602a0100 sub edi,12A60h edi = 0B0909A60 - 12a60 = B08F7000
b08fb09e 8d0449 lea eax,[ecx+ecx*2] eax = ecx*3 = 237
b08fb0a1 c1e002 shl eax,2 eax = 8DC
b08fb0a4 6a00 push 0
b08fb0a6 897df0 mov dword ptr [ebp-10h],edi 参数3 = b08f7000
b08fb0a9 8945fc mov dword ptr [ebp-4],eax
b08fb0ac 5a pop edx
b08fb0ad 741f je b08fb0ce 不跳
b08fb0af 0fb6b2608290b0 movzx esi,byte ptr TesSafe+0x11260 (b0908260)[edx]
b08fb0b6 8b5dfc mov ebx,dword ptr [ebp-4]
b08fb0b9 c1eb1b shr ebx,1Bh
b08fb0bc 33f3 xor esi,ebx
b08fb0be 8b5dfc mov ebx,dword ptr [ebp-4]
b08fb0c1 c1e305 shl ebx,5
b08fb0c4 33f3 xor esi,ebx
b08fb0c6 42 inc edx
b08fb0c7 3bd0 cmp edx,eax
b08fb0c9 8975fc mov dword ptr [ebp-4],esi
b08fb0cc 72e1 jb b08fb0af 依次读取TesSafe+0x11260处的[0B0909A64h]*3 个字节进行加密运算
最后运算的结果保存在ebp-4当中
b08fb0ce 817dfc52f61bd7 cmp dword ptr [ebp-4],0D71BF652h 把上面加密运算后的值与0D71BF652h
b08fb0d5 742f je b08fb106 这里单步结果是相等 跳
b08fb0d7 803dfbe690b000 cmp byte ptr ds:[0B090E6FBh],0
b08fb0de 7516 jne b08fb0f6
b08fb0e0 68c94d6e43 push 436E4DC9h
b08fb0e5 6878426e57 push 576E4278h
b08fb0ea e87ff9ffff call b08faa6e
b08fb0ef c605fbe690b001 mov byte ptr ds:[0B090E6FBh],1
b08fb0f6 68e8030000 push 3E8h
b08fb0fb e8e6d1ffff call b08f82e6
b08fb100 8b0d649a90b0 mov ecx,dword ptr ds:[0B0909A64h]
b08fb106 8365f400 and dword ptr [ebp-0Ch],0 ******跳到这里 参数2清0
b08fb10a 85c9 test ecx,ecx 看看ecx是否是负数或者0 ,如果为0或负数跳结束
b08fb10c 0f8681000000 jbe b08fb193
b08fb112 be648290b0 mov esi,0B0908264h ********esi = 0B0908264
b08fb117 8b46fc mov eax,dword ptr [esi-4] [esi-4] = eax = 0000ce4a
**有时外部会直接call到上面这条代码,而且从这条代码开始就有检测,也就是双层校验 直接从这里修改代码,然后跳到尾部就行了
特征码 s -b b091f000 l108000 8b 46 fc 8b 16
b08fb11a 8b16 mov edx,dword ptr [esi] edx = [esi]就是要检测的长度
b08fb11c 8365f800 and dword ptr [ebp-8],0 参数1清0
b08fb120 03c7 add eax,edi eax = eax+edi 要检测的起始位置
b08fb122 85d2 test edx,edx
b08fb124 8955fc mov dword ptr [ebp-4],edx [ebp-4]等于要检测的长度
b08fb127 7625 jbe b08fb14e 不跳
b08fb129 8b7df8 mov edi,dword ptr [ebp-8] edi = [ebp-8] = 6 edi是 当前检查位置偏移 起始为0
b08fb12c 0fb63c38 movzx edi,byte ptr [eax+edi] eax是检测的地址 把基地址+偏移处的第一个字节读取出来给edi
b08fb130 8b5dfc mov ebx,dword ptr [ebp-4] 全部断在这里 ebx = 前面计算后的值,原始为 检测长度
b08fb133 c1eb1b shr ebx,1Bh ebx右移27位
b08fb136 33fb xor edi,ebx 把原先的计算结果右移27位之后再与读取的新字节进行异或
b08fb138 8b5dfc mov ebx,dword ptr [ebp-4] 再次获得原先的运算结果
b08fb13b c1e305 shl ebx,5
b08fb13e 33fb xor edi,ebx 再次异或
b08fb140 ff45f8 inc dword ptr [ebp-8] 位置+1
b08fb143 3955f8 cmp dword ptr [ebp-8],edx 位置跟edx比较
b08fb146 897dfc mov dword ptr [ebp-4],edi
b08fb149 72de jb b08fb129 跳回去读取下一个字节
******上面的代码就是循环提取被校验地址中字节进行加密运算,然后保存在[ebp-4]中
b08fb14b 8b7df0 mov edi,dword ptr [ebp-10h] 这里等于b08f7000
b08fb14e 8b45fc mov eax,dword ptr [ebp-4] 前面的hash值
b08fb151 3b4604 cmp eax,dword ptr [esi+4] 把esi+4里面的值跟上面计算的hash值比较
b08fb154 7432 je b08fb188 相等就跳 这里如果没有修改游戏的驱动代码就是相等的
b08fb156 803dfce690b000 cmp byte ptr ds:[0B090E6FCh],0
b08fb15d 7529 jne b08fb188
b08fb15f ff75f4 push dword ptr [ebp-0Ch]
b08fb162 68ca4d6e43 push 436E4DCAh
b08fb167 6878426e57 push 576E4278h
b08fb16c e81bf9ffff call b08faa8c
b08fb171 68e8030000 push 3E8h
b08fb176 c605fce690b001 mov byte ptr ds:[0B090E6FCh],1
b08fb17d e864d1ffff call b08f82e6
b08fb182 8b0d649a90b0 mov ecx,dword ptr ds:[0B0909A64h]
b08fb188 ff45f4 inc dword ptr [ebp-0Ch] 跳这里 参数2加1 在上面 参数2已经被清0了,这里等于1
b08fb18b 83c60c add esi,0Ch
b08fb18e 394df4 cmp dword ptr [ebp-0Ch],ecx ecx = bd的值一直没有改变过
b08fb191 7284 jb b08fb117 这里要跳
b08fb193 5f pop edi
b08fb194 5e pop esi
b08fb195 5b pop ebx 正常情况上面的代码要跳 所以如果上面没跳的话就说明修改了游戏代码
b08fb196 c9 leave
b08fb197 c3 ret
**************************************************************************************************************
综合起来看 就是 esi = 0B0908264 [esi-4]是要校验地址的相对偏移
[esi]里面是要校验的长度 [esi+4]是正确的校验值
[ebp-4]是计算的校验值
edi = 0B0909A60 - 12a60 = B08F7000 就是要校验的基地址.
所以被校验地址 = B08F7000 + [0B0908264-4]
校验长度 = [0B0908264]
校验真实值 = [0B0908264+4]
有意思的就是 esi 寄存器就是 校验表的地址,
这个表里面 存储了被 校验的代码位置,校验长度,校验值。