【转载】查找怪数据数组的内存分布和地址(天龙八部)
游戏:天龙八部,版本:0.16.0108,系统windows xp,工具:CE5.2+OD1.10+C#2005
目标:查找到内存中怪数据的数组格式和位置
首先更正笔记1中的人物基址的查找方法,具体查找方法以下简单说明:
1.CE中根据人物经验或血找到某唯一地址(实际中我是根据经验的)
2.OD中对经验地址下内存写断点
0044BC28 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C] 此处为写经验地址,得到第二个偏移值C和地址ESI的值
0044BC2B 89B8 C0060000 MOV DWORD PTR DS:[EAX+6C0],EDI 此处为写经验,得到第一个偏移值6C0和地址EAX的值
0044BC31 8B0D C4B75B00 MOV ECX,DWORD PTR DS:[5BB7C4]
0044BC37 8B11 MOV EDX,DWORD PTR DS:[ECX]
0044BC39 68 04755700 PUSH Game.00577504 ; ASCII "player"
0044BC3E 6A 1D PUSH 1D
0044BC40 FF52 4C CALL DWORD PTR DS:[EDX+4C]
3.OD中逆向分析
004D82D0 55 PUSH EBP
……………………省略……………………………………………………………………………………
004D82F6 FF52 44 CALL DWORD PTR DS:[EDX+44]
004D82F9 8BD8 MOV EBX,EAX ; ebx=eax
004D82FB 85DB TEST EBX,EBX
004D82FD 0F84 8F080000 JE Game.004D8B92
004D8303 33C0 XOR EAX,EAX
004D8305 8A46 0C MOV AL,BYTE PTR DS:[ESI+C]
004D8308 57 PUSH EDI
004D8309 8BBB 2C020000 MOV EDI,DWORD PTR DS:[EBX+22C] ; edi=ebx+22c,此处的ebx得到第三个偏移值22C和地址ebx值
004D830F 83E0 01 AND EAX,1
……………………省略……………………………………………………………………………………
004D838A E8 4137F7FF CALL Game.0044BAD0 ; 调用经验获取函数
4.发现此处ebx的值切换地图时不变,始终偏移三次后能取到经验(笔记一中认为这时的ebx已经是基地址,此处更正),对ebx的地址下内存写访问断点,得到下面代码片段
00501957 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX
0050195A A1 88895B00 MOV EAX,DWORD PTR DS:[5B8988] ;基地址5b5888
0050195F 57 PUSH EDI
00501960 8BF9 MOV EDI,ECX
00501962 8B48 44 MOV ECX,DWORD PTR DS:[EAX+44] ;第四个偏移值44
00501965 894F 08 MOV DWORD PTR DS:[EDI+8],ECX ; 写地址
00501968 8B11 MOV EDX,DWORD PTR DS:[ECX]
0050196A FF52 3C CALL DWORD PTR DS:[EDX+3C]
总结,人物数据地址=[[[5B8988]+44]+22C]+C,经验值=[人物数据地址+6C0]
好了,接下来开始寻找怪数组了
找内存地址这几天学下来已经比较熟练了,所以后面的步骤简写,只写方法和关键步骤
第一步:CE中查找当前地图某个怪的名称(text)格式的,找出一堆地址来。切换怪区域,发现哪些地址有变化,结果有几个地址有变化,这几个地址特征是比较接近,猜测可能是数组中某几项,查看该内存区域,截取片段如下:
02816660 02 00 00 00 41 F1 0F 43 \u0002A?C
02816668 00 00 00 00 3F 57 5B 42 .?W[B
02816670 00 00 00 00 00 00 00 00 ..
02816678 B5 C1 C4 B9 D0 A1 D4 F4 盗墓小贼
02816680 00 00 00 00 00 00 00 00 ..
02816688 08 00 00 00 0F 00 00 00 \u0008\u000F
02816690 F5 00 00 00 00 00 00 00 ?
02816698 00 00 00 00 2D 23 10 43 .-#\u0010C
028166A0 00 00 00 00 8C 9B 83 42 .寷傿
028166A8 00 00 00 00 00 00 00 00 ..
028166B0 B5 C1 C4 B9 D0 A1 D4 F4 盗墓小贼
028166B8 00 B4 B6 FE B2 E3 00 00 .炊?.
028166C0 08 00 00 00 0F 00 00 00 \u0008\u000F
028166C8 EC 00 00 00 00 00 00 00 ?
028166D0 00 00 00 00 6B 8F 18 43 .k?C
028166D8 00 00 00 00 4F 40 26 42 .O@&B
028166E0 00 00 00 00 00 00 00 00 ..
028166E8 B5 C1 C4 B9 D0 A1 D4 F4 盗墓小贼
028166F0 00 B4 B6 FE B2 E3 00 00 .炊?.
028166F8 08 00 00 00 0F 00 00 00 \u0008\u000F
02816700 E9 00 00 00 00 00 00 00 ?
02816708 00 00 00 00 2F DB 1B 43 ./?C
02816710 00 00 00 00 1E BA 52 42 .\u001E篟B
02816718 00 00 00 00 00 00 00 00 ..
经分析发现其中存了怪坐标,名称,编号,类型等数据
第二步:OD中对自己认为最有把握的地址下内存写访问断点,得到代码如下:
7C364344 89448F E4 MOV DWORD PTR DS:[EDI+ECX*4-1C],EAX
7C364348 8B448E E8 MOV EAX,DWORD PTR DS:[ESI+ECX*4-18]
7C36434C 89448F E8 MOV DWORD PTR DS:[EDI+ECX*4-18],EAX
7C364350 8B448E EC MOV EAX,DWORD PTR DS:[ESI+ECX*4-14]
7C364354 89448F EC MOV DWORD PTR DS:[EDI+ECX*4-14],EAX
7C364358 8B448E F0 MOV EAX,DWORD PTR DS:[ESI+ECX*4-10]
7C36435C 89448F F0 MOV DWORD PTR DS:[EDI+ECX*4-10],EAX
7C364360 8B448E F4 MOV EAX,DWORD PTR DS:[ESI+ECX*4-C]
7C364364 89448F F4 MOV DWORD PTR DS:[EDI+ECX*4-C],EAX
7C364368 8B448E F8 MOV EAX,DWORD PTR DS:[ESI+ECX*4-8]
7C36436C 89448F F8 MOV DWORD PTR DS:[EDI+ECX*4-8],EAX
7C364370 8B448E FC MOV EAX,DWORD PTR DS:[ESI+ECX*4-4]
7C364374 89448F FC MOV DWORD PTR DS:[EDI+ECX*4-4],EAX
7C364378 8D048D 00000000 LEA EAX,DWORD PTR DS:[ECX*4]
第三步:中断后逆向分析代码退后几步代码如下:
0050143E 8B0D 50895B00 MOV ECX,DWORD PTR DS:[5B8950] ;基地址
00501444 8B11 MOV EDX,DWORD PTR DS:[ECX]
00501446 FF52 54 CALL DWORD PTR DS:[EDX+54]
如上红色部分为基地址,怪物数组的起始地址为[5B8950]+7C
目标:查找到内存中怪数据的数组格式和位置
首先更正笔记1中的人物基址的查找方法,具体查找方法以下简单说明:
1.CE中根据人物经验或血找到某唯一地址(实际中我是根据经验的)
2.OD中对经验地址下内存写断点
0044BC28 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C] 此处为写经验地址,得到第二个偏移值C和地址ESI的值
0044BC2B 89B8 C0060000 MOV DWORD PTR DS:[EAX+6C0],EDI 此处为写经验,得到第一个偏移值6C0和地址EAX的值
0044BC31 8B0D C4B75B00 MOV ECX,DWORD PTR DS:[5BB7C4]
0044BC37 8B11 MOV EDX,DWORD PTR DS:[ECX]
0044BC39 68 04755700 PUSH Game.00577504 ; ASCII "player"
0044BC3E 6A 1D PUSH 1D
0044BC40 FF52 4C CALL DWORD PTR DS:[EDX+4C]
3.OD中逆向分析
004D82D0 55 PUSH EBP
……………………省略……………………………………………………………………………………
004D82F6 FF52 44 CALL DWORD PTR DS:[EDX+44]
004D82F9 8BD8 MOV EBX,EAX ; ebx=eax
004D82FB 85DB TEST EBX,EBX
004D82FD 0F84 8F080000 JE Game.004D8B92
004D8303 33C0 XOR EAX,EAX
004D8305 8A46 0C MOV AL,BYTE PTR DS:[ESI+C]
004D8308 57 PUSH EDI
004D8309 8BBB 2C020000 MOV EDI,DWORD PTR DS:[EBX+22C] ; edi=ebx+22c,此处的ebx得到第三个偏移值22C和地址ebx值
004D830F 83E0 01 AND EAX,1
……………………省略……………………………………………………………………………………
004D838A E8 4137F7FF CALL Game.0044BAD0 ; 调用经验获取函数
4.发现此处ebx的值切换地图时不变,始终偏移三次后能取到经验(笔记一中认为这时的ebx已经是基地址,此处更正),对ebx的地址下内存写访问断点,得到下面代码片段
00501957 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX
0050195A A1 88895B00 MOV EAX,DWORD PTR DS:[5B8988] ;基地址5b5888
0050195F 57 PUSH EDI
00501960 8BF9 MOV EDI,ECX
00501962 8B48 44 MOV ECX,DWORD PTR DS:[EAX+44] ;第四个偏移值44
00501965 894F 08 MOV DWORD PTR DS:[EDI+8],ECX ; 写地址
00501968 8B11 MOV EDX,DWORD PTR DS:[ECX]
0050196A FF52 3C CALL DWORD PTR DS:[EDX+3C]
总结,人物数据地址=[[[5B8988]+44]+22C]+C,经验值=[人物数据地址+6C0]
好了,接下来开始寻找怪数组了
找内存地址这几天学下来已经比较熟练了,所以后面的步骤简写,只写方法和关键步骤
第一步:CE中查找当前地图某个怪的名称(text)格式的,找出一堆地址来。切换怪区域,发现哪些地址有变化,结果有几个地址有变化,这几个地址特征是比较接近,猜测可能是数组中某几项,查看该内存区域,截取片段如下:
02816660 02 00 00 00 41 F1 0F 43 \u0002A?C
02816668 00 00 00 00 3F 57 5B 42 .?W[B
02816670 00 00 00 00 00 00 00 00 ..
02816678 B5 C1 C4 B9 D0 A1 D4 F4 盗墓小贼
02816680 00 00 00 00 00 00 00 00 ..
02816688 08 00 00 00 0F 00 00 00 \u0008\u000F
02816690 F5 00 00 00 00 00 00 00 ?
02816698 00 00 00 00 2D 23 10 43 .-#\u0010C
028166A0 00 00 00 00 8C 9B 83 42 .寷傿
028166A8 00 00 00 00 00 00 00 00 ..
028166B0 B5 C1 C4 B9 D0 A1 D4 F4 盗墓小贼
028166B8 00 B4 B6 FE B2 E3 00 00 .炊?.
028166C0 08 00 00 00 0F 00 00 00 \u0008\u000F
028166C8 EC 00 00 00 00 00 00 00 ?
028166D0 00 00 00 00 6B 8F 18 43 .k?C
028166D8 00 00 00 00 4F 40 26 42 .O@&B
028166E0 00 00 00 00 00 00 00 00 ..
028166E8 B5 C1 C4 B9 D0 A1 D4 F4 盗墓小贼
028166F0 00 B4 B6 FE B2 E3 00 00 .炊?.
028166F8 08 00 00 00 0F 00 00 00 \u0008\u000F
02816700 E9 00 00 00 00 00 00 00 ?
02816708 00 00 00 00 2F DB 1B 43 ./?C
02816710 00 00 00 00 1E BA 52 42 .\u001E篟B
02816718 00 00 00 00 00 00 00 00 ..
经分析发现其中存了怪坐标,名称,编号,类型等数据
第二步:OD中对自己认为最有把握的地址下内存写访问断点,得到代码如下:
7C364344 89448F E4 MOV DWORD PTR DS:[EDI+ECX*4-1C],EAX
7C364348 8B448E E8 MOV EAX,DWORD PTR DS:[ESI+ECX*4-18]
7C36434C 89448F E8 MOV DWORD PTR DS:[EDI+ECX*4-18],EAX
7C364350 8B448E EC MOV EAX,DWORD PTR DS:[ESI+ECX*4-14]
7C364354 89448F EC MOV DWORD PTR DS:[EDI+ECX*4-14],EAX
7C364358 8B448E F0 MOV EAX,DWORD PTR DS:[ESI+ECX*4-10]
7C36435C 89448F F0 MOV DWORD PTR DS:[EDI+ECX*4-10],EAX
7C364360 8B448E F4 MOV EAX,DWORD PTR DS:[ESI+ECX*4-C]
7C364364 89448F F4 MOV DWORD PTR DS:[EDI+ECX*4-C],EAX
7C364368 8B448E F8 MOV EAX,DWORD PTR DS:[ESI+ECX*4-8]
7C36436C 89448F F8 MOV DWORD PTR DS:[EDI+ECX*4-8],EAX
7C364370 8B448E FC MOV EAX,DWORD PTR DS:[ESI+ECX*4-4]
7C364374 89448F FC MOV DWORD PTR DS:[EDI+ECX*4-4],EAX
7C364378 8D048D 00000000 LEA EAX,DWORD PTR DS:[ECX*4]
第三步:中断后逆向分析代码退后几步代码如下:
0050143E 8B0D 50895B00 MOV ECX,DWORD PTR DS:[5B8950] ;基地址
00501444 8B11 MOV EDX,DWORD PTR DS:[ECX]
00501446 FF52 54 CALL DWORD PTR DS:[EDX+54]
如上红色部分为基地址,怪物数组的起始地址为[5B8950]+7C