關於找人物包裹地址方法

早就答應給大家說一下我是怎麼找包裹地址的,今天有空,我就簡單的講一下,希望對大家有幫助...

首先我們用CE來找出是什麼指令修改了我們包裹中物品的數量(怎麼找我就不說了,不懂的看CCB老大的教程)

找到指令是

0048F0AB     mov     dword ptr [ecx+14], edx

用OD打開武林elementclient.exe,Ctrl+G轉到表達式0048F0AB...

可以看到這條指令是在一個函數中

0048F0A0 /$ 8B4424 04     mov     eax, dword ptr [esp+4]
0048F0A4 |. 8B51 14       mov     edx, dword ptr [ecx+14]
0048F0A7 |. 03D0         add     edx, eax
0048F0A9 |. 8BC2         mov     eax, edx
0048F0AB |. 8951 14       mov     dword ptr [ecx+14], edx
0048F0AE |. 85C0         test     eax, eax
0048F0B0 |. 7D 07         jge     short 0048F0B9
0048F0B2 |. C741 14 00000>mov     dword ptr [ecx+14], 0
0048F0B9 |> 8B41 18       mov     eax, dword ptr [ecx+18]
0048F0BC |. 8B51 14       mov     edx, dword ptr [ecx+14]
0048F0BF |. 3BD0         cmp     edx, eax
0048F0C1 |. 7E 03         jle     short 0048F0C6
0048F0C3 |. 8941 14       mov     dword ptr [ecx+14], eax
0048F0C6 |> 8B41 14       mov     eax, dword ptr [ecx+14]
0048F0C9 /. C2 0400       retn     4

我們在開始的地方F2下斷,F8單步步過看看每條指令都做了些什麼...

粗略的看一下,可以發現,當前CALL傳入的參數1也就是[ESP+4]是-1,也就是我們使用了這個物品(比如吃藥),[ECX+14]是存放的當前物品的數量,而[ECX+18]上存放的當前物品堆疊上限...因爲是16進制的,所以大家要習慣看這些數值...

再看看程序流程,基本可以看出這個函數的功能是判斷當前使用的物品是否超出1~99這個範圍,也就是判斷是否用完了或者是撿滿了...

那麼找包裹物品的地址,我們就要找出ECX的值是怎麼來的!!!

OK,Ctrl+F9執行到返回,我們來看看是哪條指令調用了這個CALL...

返回到指令

0048908D |. E8 0E600000     call     0048F0A0

老習慣,我們上下拖動大致看看這段指令有多長...(其實主要是大概要回溯多長,因爲我們要找ECX的值)

00489060 /$ 53           push     ebx
00489061 |. 8B5C24 08     mov     ebx, dword ptr [esp+8]
00489065 |. 56           push     esi
00489066 |. 57           push     edi
00489067 |. 85DB         test     ebx, ebx
00489069 |. 8BF9         mov     edi, ecx
0048906B |. 7C 3E         jl       short 004890AB
0048906D |. 3B5F 10       cmp     ebx, dword ptr [edi+10]
00489070 |. 7D 39         jge     short 004890AB
00489072 |. 8B47 0C       mov     eax, dword ptr [edi+C]
00489075 |. 8B3498       mov     esi, dword ptr [eax+ebx*4]
00489078 |. 85F6         test     esi, esi
0048907A |. 75 08         jnz     short 00489084
0048907C |. 5F           pop     edi
0048907D |. 5E           pop     esi
0048907E |. B0 01         mov     al, 1
00489080 |. 5B           pop     ebx
00489081 |. C2 0800       retn     8
00489084 |> 8B4C24 14     mov     ecx, dword ptr [esp+14]
00489088 |. F7D9         neg     ecx
0048908A |. 51           push     ecx
0048908B |. 8BCE         mov     ecx, esi
0048908D |. E8 0E600000     call     0048F0A0

先看看指令,發現ECX=ESI,往上ESI=[EAX+EBX*4],OK!!!我們在

00489075 |. 8B3498       mov     esi, dword ptr [eax+ebx*4]

處下斷...

發現EBX的值實際上就是我們點擊包裹的格子序號(當然,人家是從0開始計數的...)

恩,有門...再就是找EAX的值是怎麼來的了...

往上看,EAX=[EDI+C],EDI=ECX...

沒辦法,ECX是由上一級函數傳入的,好吧,繼續Ctrl+F9...

轉到指令

00457724 |. E8 37190300     call     00489060

還是上下看看...有點長,中間還有好幾個CALL,鬱悶ce...

004576B0 /$ 8B4424 04     mov     eax, dword ptr [esp+4]
004576B4 |. 53           push     ebx
004576B5 |. 55           push     ebp
004576B6 |. 56           push     esi
004576B7 |. 8B70 0C       mov     esi, dword ptr [eax+C]
004576BA |. 8BD9         mov     ebx, ecx
004576BC |. 33C9         xor     ecx, ecx
004576BE |. 57           push     edi
004576BF |. 8A0E         mov     cl, byte ptr [esi]
004576C1 |. 51           push     ecx
004576C2 |. 8BCB         mov     ecx, ebx
004576C4 |. E8 C7860000     call     0045FD90                
004576C9 |. 8BE8         mov     ebp, eax
004576CB |. 85ED         test     ebp, ebp
004576CD |. 0F84 AC000000 je       0045777F
004576D3 |. 33D2         xor     edx, edx
004576D5 |. 6A 00         push     0
004576D7 |. 8A56 01       mov     dl, byte ptr [esi+1]
004576DA |. 8BCD         mov     ecx, ebp
004576DC |. 52           push     edx
004576DD |. E8 EE0F0300     call     004886D0
004576E2 |. 8BF8         mov     edi, eax
004576E4 |. 85FF         test     edi, edi
004576E6 |. 0F84 93000000 je       0045777F
004576EC |. 8B46 02       mov     eax, dword ptr [esi+2]
004576EF |. 8B4F 08       mov     ecx, dword ptr [edi+8]
004576F2 |. 3BC8         cmp     ecx, eax
004576F4 |. 0F85 85000000 jnz     0045777F
004576FA |. 6A 00         push     0                       ; /Arg3 = 00000000
004576FC |. 6A 00         push     0                       ; |Arg2 = 00000000
004576FE |. 50           push     eax                       ; |Arg1
004576FF |. 8BCB         mov     ecx, ebx                   ; |
00457701 |. E8 9A4A0200     call     0047C1A0                   ; /elementc.0047C1A0
00457706 |. 8B07         mov     eax, dword ptr [edi]
00457708 |. 8BCF         mov     ecx, edi
0045770A |. FF50 1C       call     dword ptr [eax+1C]
0045770D |. 66:8B46 06     mov     ax, word ptr [esi+6]
00457711 |. 66:85C0       test     ax, ax
00457714 |. 74 3C         je       short 00457752
00457716 |. 33C9         xor     ecx, ecx
00457718 |. 25 FFFF0000     and     eax, 0FFFF
0045771D |. 8A4E 01       mov     cl, byte ptr [esi+1]
00457720 |. 50           push     eax
00457721 |. 51           push     ecx
00457722 |. 8BCD         mov     ecx, ebp
00457724 |. E8 37190300     call     00489060

打起精神,記住我們要找的是ECX的值...

仔細看,就可以看出,ECX=EBP,而EBP=EAX

004576DA |. 8BCD         mov     ecx, ebp

004576C9 |. 8BE8         mov     ebp, eax

從函數開始下斷,我們看看是什麼指令修改了EAX的值...

恩,mov ebp, eax上面有個CALL,大家都應該知道對於高級語言,編譯器一般習慣於將返回值放如EAX中的吧...

二話不說,先進call 0045FD90裏面看看是個什麼情況...

0045FD90 /$ 8B4424 04     mov     eax, dword ptr [esp+4]
0045FD94 |. 83F8 04       cmp     eax, 4                     ; Switch (cases 0..4)
0045FD97 |. 77 34         ja       short 0045FDCD
0045FD99 |. FF2485 D4FD45>jmp     dword ptr [eax*4+45FDD4]
0045FDA0 |> 8B81 3C080000 mov     eax, dword ptr [ecx+83C]         ; Case 0 of switch 0045FD94
0045FDA6 |. C2 0400       retn     4
0045FDA9 |> 8B81 40080000 mov     eax, dword ptr [ecx+840]         ; Case 1 of switch 0045FD94
0045FDAF |. C2 0400       retn     4
0045FDB2 |> 8B81 44080000 mov     eax, dword ptr [ecx+844]         ; Case 2 of switch 0045FD94
0045FDB8 |. C2 0400       retn     4
0045FDBB |> 8B81 78080000 mov     eax, dword ptr [ecx+878]         ; Case 3 of switch 0045FD94
0045FDC1 |. C2 0400       retn     4
0045FDC4 |> 8B81 7C080000 mov     eax, dword ptr [ecx+87C]         ; Case 4 of switch 0045FD94
0045FDCA |. C2 0400       retn     4
0045FDCD |> 33C0         xor     eax, eax                   ; Default case of switch 0045FD94
0045FDCF /. C2 0400       retn     4
0045FDD2       8BFF         mov     edi, edi
0045FDD4     . A0FD4500       dd       elementc.0045FDA0             ; 分支表 被用於 0045FD99
0045FDD8     . A9FD4500       dd       elementc.0045FDA9
0045FDDC     . B2FD4500       dd       elementc.0045FDB2
0045FDE0     . BBFD4500       dd       elementc.0045FDBB
0045FDE4     . C4FD4500       dd       elementc.0045FDC4

發現是個分支處理的函數,至於吃藥是怎麼分支的,我們先出去看看這個參數[ESP+4]和ECX的值是怎麼來的...

004576BF |. 8A0E         mov     cl, byte ptr [esi]
004576C1 |. 51           push     ecx
004576C2 |. 8BCB         mov     ecx, ebx
004576C4 |. E8 C7860000     call     0045FD90

下斷,可以知道push ecx的時候ECX是0,而mov ecx,ebx的時候不知道大家看出來什麼沒有...

當時我就覺得這個EBX的值很熟,後來一想,這個值不就是人物屬性地址[[8BCB44]+1C]+24的值麼...

而且,吃藥的時候,那個CALL要傳入的參數始終是0...

至此,所有的我們需要的信息都找到了...

那我們就可以總結了...

[[[[8BCB44]+1C]+24]+83C]+10 的值是角色包裹最大容量...

[[[[8BCB44]+1C]+24]+83C]+C 是角色包裹首地址...

[[[[[8BCB44]+1C]+24]+83C]+C]+4*格子序號 是格子物品首地址...

[[[[[[8BCB44]+1C]+24]+83C]+C]+4*格子序號]+14 是此格物品的數量...

[[[[[[8BCB44]+1C]+24]+83C]+C]+4*格子序號]+18 是此格物品的堆疊上限...

授人以魚,不如授人以漁...關於其他的地址需要大家舉一反三,自己查找了,我在這只是起個拋磚引玉的作用...

呵呵,寫完了,不知道寫得明不明白,有什麼問題希望大家多多批評,謝謝!
 

發佈了5 篇原創文章 · 獲贊 2 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章