游戏:天龙八部
版本:0.13.0402
系统:windows xp
工具:CE5.2+OD1.10+C# 2005
目标:
继续找当前地图数据和
所处坐标存放的
地址目标明确了,接下来开始干活!
第一步:打开游戏(废话),当前地图处于宝藏洞一层,好了,打开CE搜一下text为宝藏洞一层吧,很顺利,第一次搜到的结果就不是很多,21个,左边
地址列表已经显示了,人物走了几步,比较稳定,看来要二次搜索。好,出洞了,地图位于敦煌,切换过去一看,21个
地址中只有一个变化了,变成敦煌,暂且保存下这个
地址吧,04296F90(这个
地址不是固定的,是个动态
地址),打开内存显示界面,转到这个
地址大概看了一下内容,下面一堆好象是地图数据,先不管了,OD出马吧
第二步:开OD附加上来,直接到04296F90处下访问断点,切换地图后中断,停在了MSVCRT71里,字符串操作停在这里很正常,看看调用堆栈,回到game的领空,这段代码我觉得全部都很重要,所以全部复制下来,红色部分是写地图名的地方
00406310 55 PUSH EBP
00406311 8BEC MOV EBP,ESP
00406313 83EC 20 SUB ESP,20
00406316 53 PUSH EBX
00406317 56 PUSH ESI
00406318 8BF1 MOV ESI,ECX
0040631A 8B06 MOV EAX,DWORD PTR DS:[ESI]
0040631C 57 PUSH EDI
0040631D FF10 CALL DWORD PTR DS:[EAX]
0040631F 8BD8 MOV EBX,EAX
00406321 8B4B 24 MOV ECX,DWORD PTR DS:[EBX+24]
00406324 894E 2C MOV DWORD PTR DS:[ESI+2C],ECX
00406327 8B4B 08 MOV ECX,DWORD PTR DS:[EBX+8]
0040632A B8 67666666 MOV EAX,66666667
0040632F F7E9 IMUL ECX
00406331 C1FA 02 SAR EDX,2
00406334 8BC2 MOV EAX,EDX
00406336 C1E8 1F SHR EAX,1F
00406339 03C2 ADD EAX,EDX
0040633B 8D1480 LEA EDX,DWORD PTR DS:[EAX+EAX*4]
0040633E 8946 10 MOV DWORD PTR DS:[ESI+10],EAX
00406341 8B4B 08 MOV ECX,DWORD PTR DS:[EBX+8]
00406344 D1E2 SHL EDX,1
00406346 3BD1 CMP EDX,ECX
00406348 895D F0 MOV DWORD PTR SS:[EBP-10],EBX
0040634B 7D 04 JGE SHORT Game.00406351
0040634D 40 INC EAX
0040634E 8946 10 MOV DWORD PTR DS:[ESI+10],EAX
00406351 8B4B 0C MOV ECX,DWORD PTR DS:[EBX+C]
00406354 B8 67666666 MOV EAX,66666667
00406359 F7E9 IMUL ECX
0040635B C1FA 02 SAR EDX,2
0040635E 8BC2 MOV EAX,EDX
00406360 C1E8 1F SHR EAX,1F
00406363 03C2 ADD EAX,EDX
00406365 8D0C80 LEA ECX,DWORD PTR DS:[EAX+EAX*4]
00406368 8946 14 MOV DWORD PTR DS:[ESI+14],EAX
0040636B 8B53 0C MOV EDX,DWORD PTR DS:[EBX+C]
0040636E D1E1 SHL ECX,1
00406370 3BCA CMP ECX,EDX
00406372 7D 04 JGE SHORT Game.00406378
00406374 40 INC EAX
00406375 8946 14 MOV DWORD PTR DS:[ESI+14],EAX
00406378 8B56 14 MOV EDX,DWORD PTR DS:[ESI+14]
0040637B 0FAF56 10 IMUL EDX,DWORD PTR DS:[ESI+10]
0040637F 8D7E 18 LEA EDI,DWORD PTR DS:[ESI+18]
00406382 52 PUSH EDX
00406383 8BCF MOV ECX,EDI
00406385 E8 56FFFFFF CALL Game.004062E0
0040638A 33C0 XOR EAX,EAX
0040638C 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
0040638F 8945 F4 MOV DWORD PTR SS:[EBP-C],EAX
00406392 8B47 04 MOV EAX,DWORD PTR DS:[EDI+4]
00406395 85C0 TEST EAX,EAX
00406397 74 18 JE SHORT Game.004063B1
00406399 8B4F 08 MOV ECX,DWORD PTR DS:[EDI+8]
0040639C 2BC8 SUB ECX,EAX
0040639E B8 93244992 MOV EAX,92492493
004063A3 F7E9 IMUL ECX
004063A5 03D1 ADD EDX,ECX
004063A7 C1FA 04 SAR EDX,4
004063AA 8BC2 MOV EAX,EDX
004063AC C1E8 1F SHR EAX,1F
004063AF 03C2 ADD EAX,EDX
004063B1 3945 FC CMP DWORD PTR SS:[EBP-4],EAX
004063B4 7D 1A JGE SHORT Game.004063D0
004063B6 8B4E 1C MOV ECX,DWORD PTR DS:[ESI+1C]
004063B9 034D F4 ADD ECX,DWORD PTR SS:[EBP-C]
004063BC E8 BF250000 CALL Game.00408980
004063C1 8B4D FC MOV ECX,DWORD PTR SS:[EBP-4]
004063C4 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C]
004063C7 41 INC ECX
004063C8 894D FC MOV DWORD PTR SS:[EBP-4],ECX
004063CB 83C0 1C ADD EAX,1C
004063CE ^ EB BF JMP SHORT Game.0040638F
004063D0 8B46 04 MOV EAX,DWORD PTR DS:[ESI+4]
004063D3 8B48 14 MOV ECX,DWORD PTR DS:[EAX+14]
004063D6 51 PUSH ECX
004063D7 8BCE MOV ECX,ESI
004063D9 E8 C2FBFFFF CALL Game.00405FA0
004063DE 8DBE 80000000 LEA EDI,DWORD PTR DS:[ESI+80]
004063E4 8BCF MOV ECX,EDI
004063E6 E8 A57C0000 CALL Game.0040E090
004063EB 8B56 04 MOV EDX,DWORD PTR DS:[ESI+4]
004063EE 8B42 18 MOV EAX,DWORD PTR DS:[EDX+18]
004063F1 50 PUSH EAX
004063F2 8BCF MOV ECX,EDI
004063F4 E8 977D0000 CALL Game.0040E190
004063F9 8BCE MOV ECX,ESI
004063FB E8 10E9FFFF CALL Game.00404D10
00406400 8A46 48 MOV AL,BYTE PTR DS:[ESI+48]
00406403 84C0 TEST AL,AL
00406405 0F84 95000000 JE Game.004064A0
0040640B A1 3C695B00 MOV EAX,DWORD PTR DS:[5B693C]
00406410 85C0 TEST EAX,EAX
00406412 75 33 JNZ SHORT Game.00406447
00406414 8B0D 1C985B00 MOV ECX,DWORD PTR DS:[5B981C]
0040641A 8B11 MOV EDX,DWORD PTR DS:[ECX]
0040641C 68 89000000 PUSH 89
00406421 FF52 40 CALL DWORD PTR DS:[EDX+40]
00406424 85C0 TEST EAX,EAX
00406426 A3 3C695B00 MOV DWORD PTR DS:[5B693C],EAX
0040642B 75 1A JNZ SHORT Game.00406447
0040642D 68 AC4B5700 PUSH Game.00574BAC ; ASCII "s_pCityBuilding"
00406432 6A 57 PUSH 57
00406434 68 604B5700 PUSH Game.00574B60 ; ASCII ".\World\Scene.cpp"
00406439 FF15 38465700 CALL DWORD PTR DS:[<&tEngine.?tThrowAss>; tEngine.?tThrowAssertException@@YAXPBDH0@Z
0040643F A1 3C695B00 MOV EAX,DWORD PTR DS:[5B693C]
00406444 83C4 0C ADD ESP,0C
00406447 8B10 MOV EDX,DWORD PTR DS:[EAX]
00406449 8BC8 MOV ECX,EAX
0040644B FF52 18 CALL DWORD PTR DS:[EDX+18]
0040644E 33DB XOR EBX,EBX
00406450 85C0 TEST EAX,EAX
00406452 8945 F4 MOV DWORD PTR SS:[EBP-C],EAX
00406455 76 46 JBE SHORT Game.0040649D
00406457 8B0D 3C695B00 MOV ECX,DWORD PTR DS:[5B693C]
0040645D 8B01 MOV EAX,DWORD PTR DS:[ECX]
0040645F 53 PUSH EBX
00406460 FF50 04 CALL DWORD PTR DS:[EAX+4]
00406463 8B16 MOV EDX,DWORD PTR DS:[ESI]
00406465 8BCE MOV ECX,ESI
00406467 8BF8 MOV EDI,EAX
00406469 FF52 04 CALL DWORD PTR DS:[EDX+4]
0040646C 3947 04 CMP DWORD PTR DS:[EDI+4],EAX
0040646F 75 24 JNZ SHORT Game.00406495
00406471 8B17 MOV EDX,DWORD PTR DS:[EDI]
00406473 83C8 FF OR EAX,FFFFFFFF
00406476 83C9 FF OR ECX,FFFFFFFF
00406479 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX
0040647C 894D EC MOV DWORD PTR SS:[EBP-14],ECX
0040647F 8D45 E0 LEA EAX,DWORD PTR SS:[EBP-20]
00406482 50 PUSH EAX
00406483 8D4D F8 LEA ECX,DWORD PTR SS:[EBP-8]
00406486 51 PUSH ECX
00406487 8D4E 4C LEA ECX,DWORD PTR DS:[ESI+4C]
0040648A 8955 E0 MOV DWORD PTR SS:[EBP-20],EDX
0040648D 897D E4 MOV DWORD PTR SS:[EBP-1C],EDI
00406490 E8 5BD1FFFF CALL Game.004035F0
00406495 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C]
00406498 43 INC EBX
00406499 3BD8 CMP EBX,EAX
0040649B ^ 72 BA JB SHORT Game.00406457
0040649D 8B5D F0 MOV EBX,DWORD PTR SS:[EBP-10]
004064A0 A1 38695B00 MOV EAX,DWORD PTR DS:[5B6938]
004064A5 85C0 TEST EAX,EAX
004064A7 75 33 JNZ SHORT Game.004064DC
004064A9 8B0D 1C985B00 MOV ECX,DWORD PTR DS:[5B981C]
004064AF 8B11 MOV EDX,DWORD PTR DS:[ECX]
004064B1 68 B5000000 PUSH 0B5
004064B6 FF52 40 CALL DWORD PTR DS:[EDX+40]
004064B9 85C0 TEST EAX,EAX
004064BB A3 38695B00 MOV DWORD PTR DS:[5B6938],EAX
004064C0 75 1A JNZ SHORT Game.004064DC
004064C2 68 9C4B5700 PUSH Game.00574B9C ; ASCII "s_pSceneAttrDBC"
004064C7 6A 6A PUSH 6A
004064C9 68 604B5700 PUSH Game.00574B60 ; ASCII ".\World\Scene.cpp"
004064CE FF15 38465700 CALL DWORD PTR DS:[<&tEngine.?tThrowAss>; tEngine.?tThrowAssertException@@YAXPBDH0@Z
004064D4 A1 38695B00 MOV EAX,DWORD PTR DS:[5B6938]
004064D9 83C4 0C ADD ESP,0C
004064DC 8B0B MOV ECX,DWORD PTR DS:[EBX]
004064DE 8B10 MOV EDX,DWORD PTR DS:[EAX]
004064E0 51 PUSH ECX
004064E1 8BC8 MOV ECX,EAX
004064E3 FF12 CALL DWORD PTR DS:[EDX]
004064E5 85C0 TEST EAX,EAX
004064E7 74 06 JE SHORT Game.004064EF
004064E9 8B50 0C MOV EDX,DWORD PTR DS:[EAX+C]
004064EC 8956 0C MOV DWORD PTR DS:[ESI+C],EDX
004064EF 68 8B475700 PUSH Game.0057478B
004064F4 81C6 8C000000 ADD ESI,8C
004064FA 56 PUSH ESI
004064FB FF15 F8415700 CALL DWORD PTR DS:[<&MSVCP71.??$?8DU?$c>; msvcp71.??$?8DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@PBD@Z
00406501 83C4 08 ADD ESP,8
00406504 84C0 TEST AL,AL
00406506 74 2B JE SHORT Game.00406533
00406508 8B0D 40695B00 MOV ECX,DWORD PTR DS:[5B6940]
0040650E 8B01 MOV EAX,DWORD PTR DS:[ECX]
00406510 FF50 3C CALL DWORD PTR DS:[EAX+3C]
00406513 8B0D 40695B00 MOV ECX,DWORD PTR DS:[5B6940]
00406519 8B11 MOV EDX,DWORD PTR DS:[ECX]
0040651B 8BF0 MOV ESI,EAX
0040651D FF52 3C CALL DWORD PTR DS:[EDX+3C]
00406520 8BF8 MOV EDI,EAX
00406522 8B06 MOV EAX,DWORD PTR DS:[ESI]
00406524 8B1F MOV EBX,DWORD PTR DS:[EDI]
00406526 8BCE MOV ECX,ESI
00406528 FF10 CALL DWORD PTR DS:[EAX]
0040652A 8B48 04 MOV ECX,DWORD PTR DS:[EAX+4]
0040652D 51 PUSH ECX
0040652E 8BCF MOV ECX,EDI ; [地图分析]1.2 ecx恰好跟记下的
地址很接近,只小了9C
00406530 FF53 10 CALL DWORD PTR DS:[EBX+10] ; [地图分析]1.1 写地图名
00406533 5F POP EDI
00406534 5E POP ESI
00406535 5B POP EBX
00406536 8BE5 MOV ESP,EBP
00406538 5D POP EBP
00406539 C3 RETN
分析上面的代码,调用了一个子函数后写地图名完成,在这个函数里,前半部似乎是加载地图数据,当前要做的是找到地图
地址,不管其他的了,在0040652D上下断点吧,同时清楚前面的内存断点。
切换地图中断后发现,push ecx进去的参数暂时看不懂,但蓝色那句mov ecx,edi,到这里edi竟然正好与CE里找到的
地址04296F90很接近,它的值是04296EF0,小了90,猜想90可能是个偏移量。继续按F7跟进子函数里,代码如下,果然猜想正确,注意红色那句
00402040 55 PUSH EBP
00402041 8BEC MOV EBP,ESP
00402043 81C1 8C000000 ADD ECX,8C ; [地图分析]2.1 这句把调用函数带进来的ecx+8c还得+4后正好等于地图名写的
地址00402049 5D POP EBP
0040204A - FF25 0C425700 JMP DWORD PTR DS:[<&MSVCP71.??4?$basic_s>; msvcp71.??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@PBD@Z
00402050 8B41 04 MOV EAX,DWORD PTR DS:[ECX+4]
00402053 85C0 TEST EAX,EAX
00402055 75 01 JNZ SHORT Game.00402058
00402057 C3 RETN
00402058 8B49 08 MOV ECX,DWORD PTR DS:[ECX+8]
0040205B 2BC8 SUB ECX,EAX
0040205D B8 93244992 MOV EAX,92492493
00402062 F7E9 IMUL ECX
00402064 03D1 ADD EDX,ECX
00402066 C1FA 04 SAR EDX,4
00402069 8BC2 MOV EAX,EDX
0040206B C1E8 1F SHR EAX,1F
0040206E 03C2 ADD EAX,EDX
00402070 C3 RETN
红色那句说明了这个
地址的确跟调用函数的edi有关,只能逆向去跟踪edi怎么来的了,继续回到调用函数中下断点,经过很简单的几步跟踪后发现ecx=edi=eax=[ecx+30]=[[5b5940]+30]
代码过程如下
00406513 8B0D 40695B00 MOV ECX,DWORD PTR DS:[5B6940] ; [地图分析]1.5 ecx=[5b6940]
00406519 8B11 MOV EDX,DWORD PTR DS:[ECX]
0040651B 8BF0 MOV ESI,EAX
0040651D FF52 3C CALL DWORD PTR DS:[EDX+3C] ; [地图分析]1.4 eax=该函数的返回值=[ecx+30]
00406520 8BF8 MOV EDI,EAX ; [地图分析]1.3 edi=eax
00406522 8B06 MOV EAX,DWORD PTR DS:[ESI]
00406524 8B1F MOV EBX,DWORD PTR DS:[EDI]
00406526 8BCE MOV ECX,ESI
00406528 FF10 CALL DWORD PTR DS:[EAX]
0040652A 8B48 04 MOV ECX,DWORD PTR DS:[EAX+4]
0040652D 51 PUSH ECX
0040652E 8BCF MOV ECX,EDI ; [地图分析]1.2 ecx恰好跟记下的
地址很接近,只小了9C
00406530 FF53 10 CALL DWORD PTR DS:[EBX+10] ; [地图分析]1.1 写地图名
所以坐标名称=[ecx+8c]=[[[5b5940]+30]+8c]
其中1.4那步,是跟到另个子函数里看到的结果
分析至此,暂且得出结果地图名
地址是由5b5940偏移三次得来的
第三步:查找人物当前坐标所在的
地址搜索
地址我觉得CE比OD好用,继续CE登场
游戏里看到的
地址是60,202,就搜Y坐标吧,第一次搜索无数结果,回游戏移动一步变成204,再次搜,结果一个都没了,看来坐标不是整数存放的(以前看过别人的文章说坐标通常是Float类型的),好接下来重新搜,全float类型,由于不确定数值是多少,选between……and……模式,搜between 204and 205(无论如何Y也是204到205之间吧,呵呵),之后移动人物,重复这两步搜索,最终确定下来12个
地址郁闷,这么多
地址无法确定该跟踪哪个
地址了,只好全部双击加进
地址表
回游戏里乱动几步看看,先是小范围走动,发现这些
地址里的值改变频率不同,但最终随人物停止都等于人物X坐标了,猜想可能是寻路算法之类的造成的,于是游戏中鼠标朝很远的地方点一下,带绕路的那种,果然
一半
地址直接改成我所点的那个
地址上了,只有3个
地址013D609C,056EA6CC,056EA6D4在不停的变,但第一个
地址变的速度还是不一样,只是无法猜出原因了,暂时保留这三个
地址感觉上013D609C是个固定
地址,但无法确定,于是退出游戏重新进了一下,发现这三个
地址的值还保存着人物坐标。
一个一个来吧,OD中对013D609C下写访问断点,中断结果如下
004F4B70 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
004F4B74 8B10 MOV EDX,DWORD PTR DS:[EAX]
004F4B76 8951 54 MOV DWORD PTR DS:[ECX+54],EDX ; [坐标分析]1.1 该处为写X坐标
004F4B79 8B50 04 MOV EDX,DWORD PTR DS:[EAX+4]
004F4B7C 8951 58 MOV DWORD PTR DS:[ECX+58],EDX ; [坐标分析]01.1 该处为写什么不清楚?
004F4B7F 8B40 08 MOV EAX,DWORD PTR DS:[EAX+8]
004F4B82 8941 5C MOV DWORD PTR DS:[ECX+5C],EAX ; [坐标分析]01.1 该处为Y坐标
004F4B85 C2 0400 RETN 4
红色那句为中断行,此时ecx=013D6040,看来坐标位置是由此
地址偏移过来的,逆向跟踪吧,调用堆栈返回上层,发现ecx仍是再上一层的调用函数传进来的,继续往回走,遇到很重要的几句代码
004F4E92 FF50 14 CALL DWORD PTR DS:[EAX+14]
004F4E95 8B0D 18985B00 MOV ECX,DWORD PTR DS:[5B9818] ; [坐标分析]2.2 ecx=[5b9818]
004F4E9B 8B11 MOV EDX,DWORD PTR DS:[ECX]
004F4E9D FF52 14 CALL DWORD PTR DS:[EDX+14] ; [坐标分析]2.1 子函数需要ecx
由此得到结论地图y坐标=[ecx+5C]=[[5b9818]+5C],同样x坐标为]=[[5b9818]+54],上上个图中不清楚的那个[ecx+58],后面继续把他搞清楚
第四步:这次要搞清楚58偏移量放的是啥,内存监视那个点,人物满地图乱跑,发现这个值乱变,猜测下来由于这是3D游戏,应该存着是Z坐标。于是回城,找块平的空地跑来跑去,该值固定为6(也是个float数),找个楼梯往上爬,呵,该值不断往上加,爬到顶又是个平地了,该值固定为12,由此推断出该值存的是Z坐标
第五步:笔记2里的演示程序又可以更进一层了,加上刚搜到的地图名和人物坐标吧,顺便加个定时器让状态每200ms更新一次
1. AddressListConfig.xml中的Configs节点下加两个节点,再PlayerClass类中把新的4个属性加上吧,.net是老本行,这个快,好了搞定,程序最终运行界面如下
> >