[原创]浅析RING3层的CRC
浅析RING3层 的CRC
早期的CRC校验可能是单线程的
这种模型可以分成两种类型
跨进程的校验
通过OpenProcess、ReadProcessMemory、VirtualQueryEx等函数来校验代码
本进程的校验
通过汇编直接操作底层来校验代码,但这里可能还是需要用到一些API函数比如:GetModuleHandle、IsBadReadPtr
这些函数都是可以做文章的
早期的Anti可以是挂起线程,在线程中插入无限Sleep
但经过发展,CRC变成了多线程的校验,线程与线程之间互相校验代码,以及VM,与主线程通讯达到防止挂起
Anti有下面三种模型(为了增加逼格,起个洋名吧)
1)干(Fxck)

2)欺骗(Cheat)


(ID:核心未拥有 补充)
假设原执行流程的代码CRC值是A,篡改内存后的代码CRC值是B
想办法把A变成B就可以达到Anti的效果
校验线程存取原始内存CRC值的方法
1.与进程文件对比
直接修改文件的方式达到修改代码,或者Hook CreatFile 给个假文件
2.与第一次算出的值对比
在CreateProcess的时候挂起进程,然后修改代码,恢复进程
此时CRC线程进行第一次计算的值就会变成已经篡改后的代码值了
3.与服务器对比
3)绕(Reload)

CRC只对某片特定的代码或整片代码进行校验,但是通过改变原代码的执行流程就可以达到Anti的效果
不管这里通过什么方式来转移执行流程,最后能达到上图所述的效果,即可Anti
这里我将介绍几种玩法
1)通过异常中断机制转移执行流程
1.硬件断点
2.VEH
3.UEH
4.调试器附加
2)在未被CRC校验的代码处转移执行流程
1.直接HOOK
2.虚函数HOOK
替换整个虚函数表或替换指向该函数的地址
其实这种HOOK构造的原理就是基于call dword ptr ds:[eax]
当然,举一反三,只要有jmp dword ptr ds:[xxxxxx] 或者 call dword ptr ds:[xxxxxx],就可以构造这类型的HOOK
3.栈劫持
在原执行流程处的某个必经过的函数中HOOK,然后修改栈中的返回地址
这样的玩法又可以衍生出新的玩法
1)在API函数中修改栈的返回地址
在API HOOK中判断调用来源,然后对应修改返回地址.
2)虚函数HOOK与栈劫持结合
在必经过的虚函数调用中HOOK,然后修改返回地址
4.循环劫持
在进程中任意一个循环结构中转移执行流程。这种劫持方法基于的原理是相对寻址。因为在备份内存的时候,像JMP这种指令都是相对寻址的,也就是说,在原循环中跳到备份的循环中,会让指令一直在那个备份的循环中执行。怎么利用这种模型呢,比如WIN32程序中的消息循环,可以在GetMessage、TranslateMessage和DispatchMessage中HOOK并修改栈中的返回地址,转移到备份的循环中,然后还原HOOK。当然这种利用的方法不限于消息循环。
5.进程重载
方法不限于以上几种,欢迎补充
转移执行流程的方法可以相互结合,原则是越隐蔽越好,越干净越好,当然时机非常重要,时机掌握好,可以玩出新玩法
Anti Reload
针对大区域的内存Reload,可以通过特征码来查和检查栈中的返回地址是否合法(插桩)
针对局部的Reload,直接检测转移的那个点吧
检查栈的方法会比较好,隐蔽性较好,维护起来方便
当然能够做到随机动态插桩的话,就太妙了
方法太多了,主要还是要脑洞够大
