游戏安全实验室 首页 技术入门 查看内容

 阅读目录

反外挂技术手段:【特征定位】

发布于:2019-7-5 09:59   |    129391次阅读 作者: 外部投稿    |   原作者: 通化程序员

        每个程序、甚至是不同版本的同一个程序,都有“特征”这一说法。那么“特征”在外挂与反外挂领域,有什么用呢?
        首先是“第三方”领域,特征可以用来定位基址,偏移,call等等。甚至可以用来定位“动态crc”,这里的动态crc指的是正常手段无法断到,或者无法被定位的代码段。这个时候可以将整个模块内存拷贝出来,进行一个特征搜索。
       同样,在反外挂领域,“特征”也功不可没,在这里举两个例子:
       
        例子一:
        某游戏外挂,对游戏进行注入了dll,实现了某些功能,而作者非常狡猾,加了壳或者每次加载Dll都会打乱头部特征,抹除pe等等。这个时候,安全系统应该如何对其进行特征呢?这个时候就需要找到对游戏进行读写内存的第三方call,进行一个特征定位。
        反外挂突破口推荐为最常见的人物坐标。不管是FPS,还是RPG,几乎绝大部分外挂,都要对其进行读取,通过一系列算法写出自动打怪,或者自动瞄准之类的功能。而安全人员,可以在人物坐标上下断点,查看是否有非游戏自身代码,对人物坐标进行访问,抓到访问代码后,顺藤摸瓜,可对三方程序的函数进行一个特征定位,让“误查”的可能性降到最低。
         这里以QQ的代码为例子,随便找一个CALL,假设该CALL是第三方外挂功能,应该如何定位他?  如下图:

        首先,该函数位于Mail.dll模块中,而非主模块。那么该函数的地址,肯定是每次加载都会进行一个变动的,跟外挂动态加载比较接近,刚好用来练手。
        既然在非主模块,就需要先将Maill.dll进行一个内存拷贝,将内存复制出来后,再进行特征搜索。而OD观察,该模块的大小为  0x2b0000,我们需要拷贝的大小,即为模块大小。那么如何用代码实现,非常简单:
        
GetModuleHandle(Mail.dll)

BOOL ReadProcessMemory(
HANDLE -1,
LPCVOID lpBaseAddress,
LPVOID lpBuffer,
DWORD 0x2b0000,
LPDWORD lpNumberOfBytesRead
);

如此,便将Mail.dll整个模块都拷贝出来存放在lpBuffer,大小为0x2b0000。
    接下来对lpBuffer进行一个特征搜索,对其定位,如果在特征库中匹配到,就说明该dll被劫持了。既然是匹配,肯定要有一个特征,那么,该函数的特征是什么呢?
所谓的特征,即死码,不经常发生变化的,观察下该函数可以有哪些“死码”:

从1692B5C8 开始,可用作特征的机器码为(十六进制  ??代表可能发生变化的):
75 29 8B 45 ??  ?? ???? 8B ?? 50 ?? ?? ?? ?? ??  57  ?? ?? ?? 8B CE E8 ?? ?? ?? ??.
得到这串特征码后,在lpBuffer中搜索匹配,如果匹配到,代表Dll可能被劫持,那么就出现第三方,木马加载等等。
    那么如何搜索匹配上面的字符串呢?非常简单,以易语言和汇编代码为例子:
易语言代码:

翻译成汇编代码:

[ebp-n]
分别代表
被搜索的代码段(lpBuffer)
欲搜索的特征码
开始搜索的位置

' mov edi,[ebp-4]
' mov ecx,[ebp-8]
' mov esi,[ebp-12]
' mov edx ,[esi-04]
' xor eax,eax
' @for:;循环
' test ecx,ecx
' jz @over;搜索完成
' mov al,[esi+1]
' repne scasb
' jnz @over;搜索完成跳到失败;
' mov ebx,2;首个字符串匹配成功,开始匹配其他字符串
' @for2:;子循环
' mov al,[ebx+esi];取对应位置
' mov al,[eax+edi];将被搜索字节集对应位置的值取出来
' cmp al,[ebx+esi+1];与搜索的字节集对比
' jnz @for;子串对比失败,跳到开始位置
' add ebx,2;子串对比成功加2继续对比
' cmp ebx,edx;判断子串是否对比完成
' jnb @end;比较完成成功了
' jmp @for2;子循环继续
' @over:;失败
' mov eax,-1
' mov esp,ebp
' pop ebp
' retn 10
' @end:;成功
' sub edi,[ebp-4]
' mov [ebp-4],edi

例子二:
   相信易语言很多人都不陌生,开发的本意是中文编程能让更多人学习和了解编程,而近年来大多数人听到易语言的第一反应,就是外挂。很多游戏公司,干脆将所有易语言程序都定位为外挂,只要你开了易语言所写的程序,就会产生“误封”。那么如何通过“特征”来判断一个程序是不是易语言所写的呢?非常简单。
   易语言很多函数都是封装好的,拥有着特定的死码,列如易语言的窗口程序,入口函数可以为_启动窗口的函数名,该函数有着特定的死码,游戏公司只要定位这个特征码,几乎绝大多数易语言所写的窗口程序都会被判定为外挂,而想要改变这些易语言的特征码,也是可以的,只是相对来说,工程量较大。


来源:通化程序员—投稿

GSLAB网站投稿文章仅代表作者本人的观点,与本网站立场无关。

*转载请注明来自游戏安全实验室(GSLAB.QQ.COM)


分享到:
踩0 赞0

收藏

上一篇:【游戏安全】逆向中共享内存的应用

下一篇:深度揭秘:你的游戏账号是否真的安全?

最新评论
B Color Image Link Quote Code Smilies

发表评论