妖哥 2007-11-24 22:50
【转载】找当前地图数据和所处坐标存放的地址(天龙八部)
游戏:天龙八部
版本:0.13.0402
系统:windows xp
工具:CE5.2+OD1.10+C# 2005
目标:继续找当前地图数据和所处坐标存放的地址
目标明确了,接下来开始干活!
第一步:打开游戏(废话),当前地图处于宝藏洞一层,好了,打开CE搜一下text为宝藏洞一层吧,很顺利,第一次搜到的结果就不是很多,21个,左边地址列表已经显示了,人物走了几步,比较稳定,看来要二次搜索。好,出洞了,地图位于敦煌,切换过去一看,21个地址中只有一个变化了,变成敦煌,暂且保存下这个地址吧,04296F90(这个地址不是固定的,是个动态地址),打开内存显示界面,转到这个地址大概看了一下内容,下面一堆好象是地图数据,先不管了,OD出马吧
第二步:开OD附加上来,直接到04296F90处下访问断点,切换地图后中断,停在了MSVCRT71里,字符串操作停在这里很正常,看看调用堆栈,回到game的领空,红色部分是写地图名的地方
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406506 74 2B JE SHORT Game.00406533
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406508 8B0D 40695B00 MOV ECX,DWORD PTR DS:[5B6940]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040650E 8B01 MOV EAX,DWORD PTR DS:[ECX]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406510 FF50 3C CALL DWORD PTR DS:[EAX+3C]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406513 8B0D 40695B00 MOV ECX,DWORD PTR DS:[5B6940]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406519 8B11 MOV EDX,DWORD PTR DS:[ECX]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040651B 8BF0 MOV ESI,EAX
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040651D FF52 3C CALL DWORD PTR DS:[EDX+3C]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406520 8BF8 MOV EDI,EAX
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406522 8B06 MOV EAX,DWORD PTR DS:[ESI]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406524 8B1F MOV EBX,DWORD PTR DS:[EDI]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406526 8BCE MOV ECX,ESI
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406528 FF10 CALL DWORD PTR DS:[EAX]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040652A 8B48 04 MOV ECX,DWORD PTR DS:[EAX+4]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040652D 51 PUSH ECX
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040652E 8BCF [color=#0000ff]MOV ECX,EDI[/color] ; [地图分析]1.2 ecx恰好跟记下的地址很接近,只小了9C[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]
00406530 FF53 10 [color=red]CALL DWORD PTR DS:[EBX+10][/color] ; [地图分析]1.1 写地图名
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406533 5F POP EDI
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406534 5E POP ESI
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406535 5B POP EBX
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406536 8BE5 MOV ESP,EBP
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406538 5D POP EBP
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406539 C3 RETN[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]
分析上面的代码,调用了一个子函数后写地图名完成,在这个函数里,前半部似乎是加载地图数据,当前要做的是找到地图地址,不管其他的了,在0040652D上下断点吧,同时清楚前面的内存断点。
切换地图中断后发现,push ecx进去的参数暂时看不懂,但蓝色那句mov ecx,edi,到这里edi竟然正好与CE里找到的地址04296F90很接近,它的值是04296EF0,小了90,猜想90可能是个偏移量。继续按F7跟进子函数里,代码如下,果然猜想正确,注意红色那句
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img][color=#000000]00402040 55 PUSH EBP
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402041 8BEC MOV EBP,ESP
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402043 81C1 8C000000 [color=#ff0000]ADD ECX,8C[/color] ; [地图分析]2.1 这句把调用函数带进来的ecx+8c还得+4后正好等于地图名写的地址
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402049 5D POP EBP
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]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
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402050 8B41 04 MOV EAX,DWORD PTR DS:[ECX+4]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402053 85C0 TEST EAX,EAX
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402055 75 01 JNZ SHORT Game.00402058
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402057 C3 RETN
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402058 8B49 08 MOV ECX,DWORD PTR DS:[ECX+8]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040205B 2BC8 SUB ECX,EAX
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040205D B8 93244992 MOV EAX,92492493
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402062 F7E9 IMUL ECX
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402064 03D1 ADD EDX,ECX
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402066 C1FA 04 SAR EDX,4
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402069 8BC2 MOV EAX,EDX
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040206B C1E8 1F SHR EAX,1F
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040206E 03C2 ADD EAX,EDX
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00402070 C3 RETN[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img][/color]
红色那句说明了这个地址的确跟调用函数的edi有关,只能逆向去跟踪edi怎么来的了,继续回到调用函数中下断点,经过很简单的几步跟踪后发现ecx=edi=eax=[ecx+30]=[[5b5940]+30]
代码过程如下
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img][color=#000000]00406513 8B0D 40695B00 MOV ECX,DWORD PTR DS:[5B6940] ; [地图分析]1.5 ecx=[5b6940]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406519 8B11 MOV EDX,DWORD PTR DS:[ECX]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040651B 8BF0 MOV ESI,EAX
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040651D FF52 3C CALL DWORD PTR DS:[EDX+3C] ; [地图分析]1.4 eax=该函数的返回值=[ecx+30]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406520 8BF8 MOV EDI,EAX ; [地图分析]1.3 edi=eax
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406522 8B06 MOV EAX,DWORD PTR DS:[ESI]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406524 8B1F MOV EBX,DWORD PTR DS:[EDI]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406526 8BCE MOV ECX,ESI
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406528 FF10 CALL DWORD PTR DS:[EAX]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040652A 8B48 04 MOV ECX,DWORD PTR DS:[EAX+4]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040652D 51 PUSH ECX
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]0040652E 8BCF MOV ECX,EDI ; [地图分析]1.2 ecx恰好跟记下的地址很接近,只小了9C
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]00406530 FF53 10 CALL DWORD PTR DS:[EBX+10] ; [地图分析]1.1 写地图名[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img][/color]
所以坐标名称=[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下写访问断点,中断结果如下
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]004F4B70 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]004F4B74 8B10 MOV EDX,DWORD PTR DS:[EAX]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]004F4B76 8951 54 MOV DWORD PTR DS:[ECX+54],EDX ; [坐标分析]1.1 该处为写X坐标
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]004F4B79 8B50 04 MOV EDX,DWORD PTR DS:[EAX+4]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]004F4B7C 8951 58 MOV DWORD PTR DS:[ECX+58],EDX ; [坐标分析]01.1 该处为写什么不清楚?
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]004F4B7F 8B40 08 MOV EAX,DWORD PTR DS:[EAX+8]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]004F4B82 8941 5C [color=#ff0000]MOV DWORD PTR DS:[ECX+5C],EAX[/color] ; [坐标分析]01.1 该处为Y坐标
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]004F4B85 C2 0400 RETN 4
红色那句为中断行,此时ecx=013D6040,看来坐标位置是由此地址偏移过来的,逆向跟踪吧,调用堆栈返回上层,发现ecx仍是再上一层的调用函数传进来的,继续往回走,遇到很重要的几句代码
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img][color=#000000]004F4E92 FF50 14 CALL DWORD PTR DS:[EAX+14]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]004F4E95 8B0D 18985B00 MOV ECX,DWORD PTR DS:[5B9818] ; [坐标分析]2.2 ecx=[5b9818]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]004F4E9B 8B11 MOV EDX,DWORD PTR DS:[ECX]
[img]http://www.cnblogs.com/Images/OutliningIndicators/None.gif[/img]004F4E9D FF52 14 CALL DWORD PTR DS:[EDX+14] ; [坐标分析]2.1 子函数需要ecx[/color]
由此得到结论地图y坐标=[ecx+5C]=[[5b9818]+5C],同样x坐标为]=[[5b9818]+54],上上个图中不清楚的那个[ecx+58],后面继续把他搞清楚
第四步:这次要搞清楚58偏移量放的是啥,内存监视那个点,人物满地图乱跑,发现这个值乱变,猜测下来由于这是3D游戏,应该存着是Z坐标。于是回城,找块平的空地跑来跑去,该值固定为6(也是个float数),找个楼梯往上爬,呵,该值不断往上加,爬到顶又是个平地了,该值固定为12,由此推断出该值存的是Z坐标