发新话题
打印

【转载】找当前地图数据和所处坐标存放的地址(天龙八部)

【转载】找当前地图数据和所处坐标存放的地址(天龙八部)

游戏:天龙八部
版本:0.13.0402
系统:windows xp
工具:CE5.2+OD1.10+C# 2005
目标:继续找当前地图数据和所处坐标存放的地址

目标明确了,接下来开始干活!

第一步:打开游戏(废话),当前地图处于宝藏洞一层,好了,打开CE搜一下text为宝藏洞一层吧,很顺利,第一次搜到的结果就不是很多,21个,左边地址列表已经显示了,人物走了几步,比较稳定,看来要二次搜索。好,出洞了,地图位于敦煌,切换过去一看,21个地址中只有一个变化了,变成敦煌,暂且保存下这个地址吧,04296F90(这个地址不是固定的,是个动态地址),打开内存显示界面,转到这个地址大概看了一下内容,下面一堆好象是地图数据,先不管了,OD出马吧

第二步:开OD附加上来,直接到04296F90处下访问断点,切换地图后中断,停在了MSVCRT71里,字符串操作停在这里很正常,看看调用堆栈,回到game的领空,红色部分是写地图名的地方
  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坐标
妖城欢迎您!

TOP

发新话题