欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]TP驱动中的一处代码校验分析

[原创]TP驱动中的一处代码校验分析

登陆游戏,等待TP驱动加载完成。
WindDbg输入 u NtReadVirtualMemory,来到被游戏Hook的地方。


kd> u NtReadVirtualMemory

nt!NtReadVirtualMemory:

805b52c2 b810dd6fb0      mov     eax,0B06FDD10h

805b52c7 ffe0            jmp     eax


在地址0B06FDD10 下访问断点。几秒钟后游戏断下
下面分析改位置的代码:
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]


绕过检测的方法就不贴了。另外这部分代码上面同样有代码校验,并且有个地方进行了VM。
有意思的就是 esi 寄存器就是 校验表的地址,
这个表里面 存储了被  校验的代码位置,校验长度,校验值。

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功