欢迎来到 嗅灵易学

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

都不够给力,我来个给力的,手把手一起写现在某热门游戏的跑钱外挂(一)(二)(三)(四)

都不够给力,我来个给力的,手把手一起写现在某热门游戏的跑钱外挂(一)(二)(三)(四)

2010年10月30日..
先声明,此为技术研究,不要拿来当非法用途.面向中高级的逆向与程序编写程序员.
此游戏为某公司的某个热门回合制游戏,我会从一开始入手调试到分析,再到成品分批写文放出.....
我所用的写代码语言是masm32 就是汇编啦,哈哈...用C的高手们就不好意思了.因为地址定位用C太麻烦,又不想用C内嵌汇编,太难看..
技术层面从基本的调试分析思路,到内存搜索定位,注入,SEH搜索错误处理来定点搜索内存,内存地址位置转跳修改和修改挟持(系统API也有),由于是内存外挂,所以要处理游戏程序的自校验,过自校验方法不放出(我可不想收律师信),请自行思索..不过自校验也只是提示,还是能执行的.
外挂程序成品是该游戏的一个分支的自动挣游戏币,里面包括战斗,走路,NPC对话,地图转换,物品检测.
OK,废话完了,我们开始动手.从理论开始做..
先搞清楚我们要做的,就是利用游戏的内存定位修改来得到游戏数据,接着按照得到的数据利用鼠标键盘模仿操作(SendMessage,或者直接压参数call也行,随你喜欢),不要搞变态功能(因为为了跑钱的),实现人物走路加速和战斗加速只要修改一下断点内存就能做到,我会在后面的文章加以说明.
首先,就是OD载入(又废话了..),收集数据开始...
0051171E > $  6A 60         push    60
00511720   .  68 F0975700   push    005797F0
00511725   .  E8 9A520000   call    005169C4
0051172A   .  BF 94000000   mov     edi, 94
0051172F   .  8BC7          mov     eax, edi
00511731   .  E8 3ADBFFFF   call    0050F270
00511736   .  8965 E8       mov     dword ptr [ebp-18], esp
00511739   .  8BF4          mov     esi, esp
0051173B   .  893E          mov     dword ptr [esi], edi
0051173D   .  56            push    esi                              ; /pVersionInformation
0051173E   .  FF15 58715500 call    dword ptr [<&KERNEL32.GetVersion>; \GetVersionExA
标准的C++,,我暴汗,以前我调试时那游戏可是加了License的,那时过检测和分析代码累死我,API全是乱序的.现在居然把壳放掉? OK,那就更简单了.
Shift+F9直接就跑起来了,汗.还真不检测了...
开始,注入方式考虑,由于是外挂,不是木马,所以是用户配合程序,所以注入方式可以有很多,DLL替换或者远线程注入,既然用户配合,那就不用DLL替换,我们来远线程注入(无视杀毒)..
下面代码是我自己写的远线程DLL加载,自己看代码处理方式,使用方法是对目标程序使用VirtualAllocEx申请内存,之后将下面代码的DllNameA填充好我们的外挂DLL的路径,用WriteProcessMemory写入目标程序,之后用CreateRemoteThread建立远线程
下面代码会在目标程序加载我们指定的DLL文件,我们在DLL文件的入口,DLL_PROCESS_ATTACH时对游戏程序做内存修改与挟持就可以了.
此代码可通用XP,2003,VISTA,WIN7.
assume   fs:nothing
mov   eax,fs:[30h]
mov   eax,[eax + 0ch]
mov   esi,[eax + 1ch]
lodsd
mov   eax,[eax + 8h]
mov  edi,eax
call  @f
loadlib  db  'LoadLibraryExA',0  ;为什么是ExA?不用A? 因为啊,要兼容WIN7.所以是ExA 再问就自己去调试WIN7的处理方式- -!..
@@:
pop  edx
mov  esi,edx
call  _test
add  edx,143          ;这里编译后的代码大小,用来定位DllNameA路径数据的 没修改代码的情况下别改
push  0
push  0
push  edx
call  esi
add  eax,1000h  ;无视掉.懒得编译修改,修改的话上面的143大小也要修改.
mov  ecx,1234  ;同上
nop      ;同上
ret
assume  esi:nothing
_test    proc  uses eax ebx ecx edx edi    ;这段代码用来搜索函数的.
    
    add     eax, [eax + 3Ch]
    assume    eax: ptr IMAGE_NT_HEADERS
    mov  ebx, edi
    add  ebx, [eax].OptionalHeader.DataDirectory.VirtualAddress    ;IMAGE_EXPORT_DIRECTORY引出表入口
    assume    eax: nothing
    mov        ecx, ebx
    mov  ebx, [ecx + 1Ch]                ;AddressOfFunctions的地址
    mov  edx, ecx
    mov  edx, [edx + 18h]                ;NumberOfNames地址
    push  edx
    mov  edx,esi
    mov  ebp, ecx      ;IMAGE_EXPORT_DIRECTORY引出表入口
    mov  ebp, [ebp + 20h]    ;AddressOfNames 地址
    
    mov  esi, ecx
    mov  esi, [esi + 24h]    ;AddressOfNameOrdinals
    push    ebx
    push    esi
    xor  ebx, ebx
    xor  ecx, ecx
    xor  eax, eax
    add  ebp, edi
    
  getApiGetModuleHandleA:
    mov  esi, edi
    add  esi, [ebp + ecx * 4]
  cmpAPI:
    mov  al, [edx + ebx]
    cmp  al, [esi + ebx]
    jne  getNext
    inc  ebx
    mov  al, 0
    cmp  al, [esi + ebx]
    jne  cmpAPI
    je  getOK
  getNext:
    xor  ebx, ebx
    inc  ecx
    cmp  ecx, [esp + 8]
    jne  getApiGetModuleHandleA
  getOK:
    pop  esi   
    pop  ebx
    add  ebx, edi
    mov  esi, [ebx + ecx * 4]
    add  esi, edi      ;esi为API地址
    pop  eax
  ret
_test endp
DllNameA  db  260 dup (0)
面向中高手,代码我就不一一说明了,只是用来加载DLL到目标进程的东西,自己看,看不懂的话下面我写的游戏调试和其它的处理估计也会看得不太懂,努力吧.
基础的远线程载入就好了,现在我们建立我们的DLL文件,从空白的开始.masm32汇编,自己看着办
    .586
    .model flat, stdcall
    option casemap :none
include    windows.inc
include    kernel32.inc
includelib  kernel32.lib
    .code
_Init    proc  uses ebx esi edi
          ;这里写入初始化的数据,用来写游戏进程的内存.先用messagebox来先测试代码的可用性吧.
    ret
_Init endp
DllEntry  proc  _hInstance,_dwReason,_dwReserved
    
    cmp  _dwReason,DLL_PROCESS_ATTACH
    jnz  @f
    push  eax
    invoke  CreateThread,0,0,offset _Init,0,0,esp
    invoke  CloseHandle,eax
    pop  eax
    @@:
    mov  eax,TRUE
    ret
DllEntry  Endp
    End  DllEntry
DLL文件加载和处理基本就上面那些,当然细节要自己搞了,哈哈  ..准备工作做好了,我们来对游戏进程调试了...GO`````
再用OD载入,为了写个程序开始的执行点,以前代码是一开始就加密了的,现在不用,我们还是定位个程序开始执行后的点吧,以后会有用的.
断点:CreateWindowExA  Shift+F9,断下来了..
77D2E4A9 >  8BFF            mov     edi, edi                ;CreateWindowExA入口
77D2E4AB    55              push    ebp
77D2E4AC    8BEC            mov     ebp, esp
断到第1次窗口建立,它有建立窗口,利用价值有了,我们利用它能知道代码已经全部解密(对已加壳的程序来说),在这里开始对游戏内存进行修改了,写一次性代码写入它,再用代码还原覆盖回去再JMP跳回CreateWindowExA让它继续跑就行了.
注入条件齐备,下一篇是游戏调试分析,每天晚上一篇不同技术,到说完出成品,呵呵.
说点题外话,什么防外挂木马的,要处理我觉得还是可行吧?即使没游戏的源代码,最可行的是写驱动进行游戏数据加密与发送数据加密,驱动进行本进程的数据校对(不让你修改看你怎么搞,干掉驱动我让你玩不了,没驱动加密的异常数据发送过来了,嘻嘻,写段代码自动封号..),其实驱动模版我写了1个,嘻嘻,通用32位的WIN7,VISTA,2003,XP
主要功能就是保护指定进程内存不被修改(一发现任何1字节内存修改马上退出)当然驱动也有自校对保护了,哈哈,功能能嘛,是用驱动限制程序启动,也就是每打开进程的话先提示进程路径,用户选择是否启动该进程(所有用户级的进程,不包含服务进程,呵呵,因为驱动HOOK的是createprocess,某种意义上说我HOOK的是系统所有内核调用- -!).

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

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

0 0 0 举报
复制成功