动态分配内存的游戏怎么样找内存地址

游戏:天龙八部

版本: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!
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
课程安排,暂定,有可能会实时修改 编程语言,VC++6.0 工具主要为(OD1.1,CE5.4) 预计平均3天左右更新一课 大家好,我是郁金香老师:QQ150330575 欢迎大家参加梅州技术 VC++外挂编程VIP培训班。 在接下来的一段时间将由我和大家一起学习游戏外挂的分析,制作。 课程分四个大章节 初级篇,中级篇,进阶篇,高级篇 初级篇内容:编写一个完整的,简单的外挂 C++的数据类型:Byte,Word,DWORD,int,float API函数的调mouse_event,GetWindowRect,SetCursorPos,FindWindow,SendMessage) CE5.4工具的使用方法 中级篇内容:调试工具的使用技巧,功能CALL的概念 调试工具OD1.1的使用技巧(如硬件断点,条件断点,内存断点。 常用汇编指令与对应高级语言的转换。 游戏功能CALL概念 第一个功能CALL 外挂框架的构建(通用) 进阶篇内容:分析游戏内部数据,分析常用功能CALL 游戏数据实践各种功能CALL(如打怪,选怪,物品使用,技能栏之类)及相应的代码编写 高级篇内容:编写完整外挂 完成一个相对完整的外挂,实现 自动挂机,打怪,存放物品之类的功能 1 入门篇.以《QQ连连看为例》 1.1、一个最简单的外挂 1.1.1、游戏数据分析(SPY++) 1.1.1、游戏窗口数据分析(SPY++) a、取得窗口相对坐标 b、读出游戏窗口信息GetWindowRect c、移动鼠标指针SetCursorPos 1.1.2 用VC++写个最简单的外挂(实现游戏开局) a、鼠拟鼠标单击mouse_event b、鼠标指针移动还原 c、集成到startgame函数里 1.2、用CE查棋盘数据 1.2.1、数据类型:Bit,Byte,Word,Dword 、用CE查坐位号; 1.2.2、用CE查出4个棋盘基址; 1.3、用模拟技术编制外挂 1.3.1 模拟鼠标点击实现 交换棋子 1.3.2 把所有功能集成封装到 函数里 1.3.3 利用棋盘数据 ,模拟实现下棋功能 1.3.4 编写完整外挂,界面美化 1.4、游戏加速.去掉对动画效果.非HOOK 1.4.1:用OD出 动画延时代码 1.4.2:写代码去掉延时,实现游戏加速 2 中级篇 以热血江湖为例 2.1、分析前的准备..CALL简介: 2.1.1、CALL调用示例分析.远程代码注入器 2.1.2、调试工具OD简介,血值,魔力值,坐标偏移; 2.1.3、游戏基址概念; 2.1.4、常用汇编指令详解 2.1.5、内联汇编编程实例 2.2、游戏分析利器OD(OllyDbg) 2.2.1、分析角色基址 2.2.2、打坐CALL 2.2.3、读出角色当前血值 2.2.4、远程注入代码,调用打坐CALL; 2.2.5、实例分析:技能栏对象数组基址+偏移: 2.2.6: 拦截F1-F8功能CALL 2.3、外挂框架构建 2.3.1、DLL动态链接库构建,与调用 2.3.2、API与回调函数 2.3.3、DLL中构建窗口 2.4、用OD分析游戏功能CALL.《热血江湖》为例:主要是CALL 2.4.1、选怪CALL 2.4.2、游戏物品背包的基址+偏移 2.4.3、 吃红药(补血)CALL 2.4.4、 吃蓝(补魔)CALL 2.4.5、 技能CALL1 2.4.6、技能CALL2 2.4.7、所有技能CALL 2.4.8、捡物CALL 2.4.9、所有动作CALL 3、进阶篇 主要讲功能CALL的参数分析 汇编浮点指令/浮点运行/浮点数整数转换/汇编里的指针 3.1、喊话功能 3.2、走路 3.3、 怪物过滤 3.3.1、怪物属性分析 3.3.2、怪物列表关键代码分析 3.3.3、怪物列表基址+大小 3.3.4、怪物列表编写代码 3.3.5、怪物过滤 3.4、 物品过滤 3.4.1、物品属性分析 3.4.2、物品列表关键代码分析 3.4.3、出物品列表基址+偏移 3.4.4、物品过滤(编程读出物品列表数据) 3.5、 组队相关 3.5.1、 玩家列表 3.5.2、 组队功能 3.5.3、 离队功能 3.6、购物/售物 3.6.1、与NPC对话框 3.6.2、打开购物/售物对话框 3.6.3、购物功能 3.6.4、售物功能 3.7、 摆摊.开店 a、开店CALL参数分析 b、写代码测试 4、高级篇 4.1、编写完整的外挂 4.2、游戏更新后的外挂更新 4.3、脚本功能 4.4、游戏多开实现 4.5、盗号的实现
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值