[外挂学习]Jim's游戏外挂学习笔记1——动态分配内存的游戏怎么样找内存地址

转载 2007年09月19日 17:14:00
作者:Jim's

支持原创,经典收藏!
这贴之前有朋友发过,东西很全面,所以整理了一下发出来,应该对新来的朋友有帮助!

[外挂学习]Jim's游戏外挂学习笔记1——动态分配内存的游戏怎么样找内存地址(原创)
游戏:天龙八部
版本:0.13.0402
系统:windows xp
工具:CE5.2+OD1.10
目标:搜索人物基地址

第一步,用CE搜索人物HP,得到一堆地址,掉血后继续搜索,得到唯一地址0ABDC360(HP地址)

第二步,切换地图后发现该地址里的值已经不是HP,是动态地址,重复第一步搜索出新的HP地址(地址省略)

第三步,这时候不再切换地图,用CE5.2对找到的HP地址下写访问内存断点,此步也可用OD下写内存断点,找到汇编语句如下

0044B280    55              PUSH EBP
0044B281    8BEC            MOV EBP,ESP
0044B283    56              PUSH ESI
0044B284    8BF1            MOV ESI,ECX                              ; 1.2 esi=ecx
0044B286    8B4E 04        MOV ECX,DWORD PTR DS:[ESI+4]
0044B289    8B01            MOV EAX,DWORD PTR DS:[ECX]
0044B28B    57              PUSH EDI
0044B28C    FF90 14010000  CALL DWORD PTR DS:[EAX+114]
0044B292    83F8 02        CMP EAX,2
0044B295    8B3D 48465700  MOV EDI,DWORD PTR DS:[<&tEngine.?tThrowS>; tEngine.?tThrowStringException@@YAXPBDZZ
0044B29B    75 19          JNZ SHORT Game.0044B2B6
0044B29D    68 63050000    PUSH 563
0044B2A2    68 54975700    PUSH Game.00579754                      ; ASCII "./DataPool/GMDP_CharacterData.cpp"
0044B2A7    68 48975700    PUSH Game.00579748                      ; ASCII "CT_MONSTER"
0044B2AC    68 20975700    PUSH Game.00579720                      ; ASCII "Character must not %s,(File:%s Line:%d)"
0044B2B1    FFD7            CALL EDI
0044B2B3    83C4 10        ADD ESP,10
0044B2B6    8B4E 04        MOV ECX,DWORD PTR DS:[ESI+4]
0044B2B9    8B11            MOV EDX,DWORD PTR DS:[ECX]
0044B2BB    FF92 14010000  CALL DWORD PTR DS:[EDX+114]
0044B2C1    83F8 01        CMP EAX,1
0044B2C4    75 19          JNZ SHORT Game.0044B2DF
0044B2C6    68 64050000    PUSH 564
0044B2CB    68 54975700    PUSH Game.00579754                      ; ASCII "./DataPool/GMDP_CharacterData.cpp"
0044B2D0    68 78975700    PUSH Game.00579778                      ; ASCII "CT_PLAYEROTHER"
0044B2D5    68 20975700    PUSH Game.00579720                      ; ASCII "Character must not %s,(File:%s Line:%d)"
0044B2DA    FFD7            CALL EDI
0044B2DC    83C4 10        ADD ESP,10
0044B2DF    8B46 08        MOV EAX,DWORD PTR DS:[ESI+8]            ; 1.2 eax=[esi+8]
0044B2E2    8B4D 08        MOV ECX,DWORD PTR SS:[EBP+8]            ; 01.1 血来自父函数第一个参数
0044B2E5    8988 B8060000  MOV DWORD PTR DS:[EAX+6B8],ECX          ; 1.1 血被写入
0044B2EB    8B0D 9C975B00  MOV ECX,DWORD PTR DS:[5B979C]
0044B2F1    8B11            MOV EDX,DWORD PTR DS:[ECX]
0044B2F3    68 B4545700    PUSH Game.005754B4                      ; ASCII "player"
0044B2F8    6A 19          PUSH 19
0044B2FA    FF52 4C        CALL DWORD PTR DS:[EDX+4C]
0044B2FD    5F              POP EDI
0044B2FE    5E              POP ESI
0044B2FF    5D              POP EBP
0044B300    C2 0400        RETN 4


这是完整的子函数,实际血被写入的那句代码是红色那句,由此可得知血被存在[eax+6b8]中,6b8是个偏移量,HP指针地址其实存在eax中,根据该段代码的分析,得知eax=[esi+8],而esi=调用函数带进来的ecx,以上代码中注释1.1,1.2,1.3有说明,记好此时的eax,ecx两个值,下面一步就是要查这两个值存的东西变不变

第四步,让自己掉一次血,发现HP地址没变,OD中0044B2F5行代码处下断点,发现此时的eax,ecx也没变,猜测HP地址切换地图时才可能重新分配

第五步:切换一次地图后代码中断,发现此时的eax,ecx与上次又不一样了,上步的猜测可能正确,因为eax=[esi+8]=[ecx+8],所以eax是依赖ecx的,ecx又是来自调用函数的,所以使用调用堆栈去查看调用函数中ecx是怎么来的,OD中调用堆栈的父函数处回车即可,以下是父函数代码
004D7A10    55              PUSH EBP
004D7A11    8BEC            MOV EBP,ESP
004D7A13    51              PUSH ECX
004D7A14    A1 F0975B00    MOV EAX,DWORD PTR DS:[5B97F0]
004D7A19    3B05 E4975B00  CMP EAX,DWORD PTR DS:[5B97E4]
004D7A1F    53              PUSH EBX
004D7A20    56              PUSH ESI
004D7A21    0F85 AB080000  JNZ Game.004D82D2
004D7A27    8B75 08        MOV ESI,DWORD PTR SS:[EBP+8]
004D7A2A    8B0D 78695B00  MOV ECX,DWORD PTR DS:[5B6978]
004D7A30    8B46 08        MOV EAX,DWORD PTR DS:[ESI+8]
004D7A33    8B11            MOV EDX,DWORD PTR DS:[ECX]
004D7A35    50              PUSH EAX
004D7A36    FF52 44        CALL DWORD PTR DS:[EDX+44]              ; 2.5 eax是该函数的返回值,该函数返回一个重要的地址
004D7A39    8BD8            MOV EBX,EAX                              ; 2.4 ebx=eax
004D7A3B    85DB            TEST EBX,EBX
004D7A3D    0F84 8F080000  JE Game.004D82D2
004D7A43    33C0            XOR EAX,EAX
004D7A45    8A46 0C        MOV AL,BYTE PTR DS:[ESI+C]
004D7A48    57              PUSH EDI
004D7A49    8BBB 2C010000  MOV EDI,DWORD PTR DS:[EBX+12C]          ; 2.3 edi=[ebx+12c]
004D7A4F    83E0 01        AND EAX,1
004D7A52    8945 FC        MOV DWORD PTR SS:[EBP-4],EAX
004D7A55    74 2B          JE SHORT Game.004D7A82
004D7A57    8B4E 18        MOV ECX,DWORD PTR DS:[ESI+18]
004D7A5A    51              PUSH ECX
004D7A5B    8BCF            MOV ECX,EDI
004D7A5D    E8 DE1FF7FF    CALL Game.00449A40
004D7A62    8B15 78695B00  MOV EDX,DWORD PTR DS:[5B6978]
004D7A68    3B5A 44        CMP EBX,DWORD PTR DS:[EDX+44]
004D7A6B    75 15          JNZ SHORT Game.004D7A82
004D7A6D    8B57 08        MOV EDX,DWORD PTR DS:[EDI+8]
004D7A70    8B0D 10985B00  MOV ECX,DWORD PTR DS:[5B9810]
004D7A76    8B52 70        MOV EDX,DWORD PTR DS:[EDX+70]
004D7A79    8B01            MOV EAX,DWORD PTR DS:[ECX]
004D7A7B    52              PUSH EDX
004D7A7C    FF90 A0000000  CALL DWORD PTR DS:[EAX+A0]
004D7A82    33C0            XOR EAX,EAX
004D7A84    8A46 0C        MOV AL,BYTE PTR DS:[ESI+C]
004D7A87    83E0 02        AND EAX,2
004D7A8A    D1E8            SHR EAX,1
004D7A8C    85C0            TEST EAX,EAX
004D7A8E    74 0B          JE SHORT Game.004D7A9B
004D7A90    8B46 20        MOV EAX,DWORD PTR DS:[ESI+20]
004D7A93    50              PUSH EAX                                ; 02.1 eax里存放了血,给子函数使用
004D7A94    8BCF            MOV ECX,EDI                              ; 2.2 ecx=edi
004D7A96    E8 E537F7FF    CALL Game.0044B280                      ; 2.1 ecx影响了子函数
004D7A9B    33C0            XOR EAX,EAX


CALL Game.0044B280即第三步找到的子函数,调用子函数时血量值作为参数传进去,具体的子函数功能我也没搞清楚,大体感觉上可能是拿到数据包后给内存中的HP地址赋值。

继续分析这段代码,2.1,2.2,2.3这三句发现ecx=[ebx+12c],看来这里的12c又是一个偏移量,在2.3上下断点,获取到此时的ebx=0B387708,继续分析发现2.4,2.5中ebx=eax=2.5调用的子函数的返回值,动态调试跟下去发现2.5那行调用的子函数里,的确是为了获取这个0b387708,具体函数功能没看懂,里面是一堆比较复杂的地址运算得到了这个值

第六步:CE中查找0b387708存在什么地址里,找到两个地址013D2BD8和013D6064,随后切换地图发现这两个地址里的值都改变了,但还是相同,用这个新值进行[[[新值+12c]+8]+6b8]运算,终于得到了HP值。
感觉这两个地址有可能是个不变的值,重开游戏后确认,的确同样的运算还能得到HP值。
姑且任务第一个值013D2BD8为要查找的基地址,而血是经过偏移3次后找到的,偏移量分别是12c,8,6b8
目标基本完成,OVER! 

Jim's游戏外挂学习笔记1——动态分配内存的游戏怎么样找内存地址

游戏:天龙八部  版本:0.13.0402  系统:windows xp  工具:CE5.2+OD1.10  目标:搜索人物基地址    第一步,用CE搜索人物HP,得到一堆地...

[C++学习笔记]--动态分配内存空间

我们在C语言中学过malloc函数,来动态分配内存空间,然而在C++中我们用的是new运算符。强调一下,malloc();是函数。而new是运算符,和sizeof()不是函数一个意思。     ...

C++学习实战——通过动态分配内存打印杨辉三角

边学边用,忍不住写了个代码,写代码还是挺有意思的,哈哈//通过动态分配内存打印杨辉三角 #include using namespace std;int main() { int *p=NUL...

C++随记(二)---动态分配内存问题(1)

作者:teeyohuang 邮箱:teeyohuang@163.com 本文系原创,供交流学习使用,转载请注明出处,谢谢 C++随记(二)---动态分配内存问题(1) 面向对象的编程的一...

动态分配内存——Ada应用实例之十二

Ada易于避免动态分配内存相关的错误。

<学习笔记>王爽汇编语言__更加灵活的定位内存地址的方法

在之前的文章中,我们用[0],[bx]的方法定位内存单元的地址,我们现在将用一些具体问题来复习一些更灵活的定位地址内存的方法和相关的编程方法。   and和or指令: (1)and指令,逻辑与指...
  • aksnzhy
  • aksnzhy
  • 2011年09月14日 11:17
  • 1474

王爽《汇编语言》(第二版) 学习笔记 (第七章 更灵活的定位内存地址的方法 )

第七章更灵活的定位内存地址的方法一、     and和or指令1.         and指令:逻辑与指令,按位进行与运算2.         or指令:逻辑或指令,按位进行或运算二、     关于A...
  • lr2131
  • lr2131
  • 2011年04月20日 22:26
  • 998

王爽《汇编语言》(第二版) 学习笔记 (第七章 更灵活的定位内存地址的方法 )

 第七章更灵活的定位内存地址的方法一、     and和or指令1.         and指令:逻辑与指令,按位进行与运算2.         or指令:逻辑或指令,按位进行或运算二、     关于...
  • lr2131
  • lr2131
  • 2011年04月26日 19:42
  • 734
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[外挂学习]Jim's游戏外挂学习笔记1——动态分配内存的游戏怎么样找内存地址
举报原因:
原因补充:

(最多只允许输入30个字)