Jim's遊戲外掛學習筆記1——動態分配內存的遊戲怎麼樣找內存地址
遊戲:天龍八部
版本:0.13.0402
系統:windows xp
工具:CE5.2+OD1.10
目標:搜索人物基地址
第一步,用CE搜索人物HP,得到一堆地址,掉血後繼續搜索,得到唯一地址0ABDC360(HP地址)
第二步,切換地圖後發現該地址裏的值已經不是HP,是動態地址,重複第一步搜索出新的HP地址(地址
省略)
第三步,這時候不再切換地圖,用CE5.2對找到的HP地址下寫訪問內存斷點,此步也可用OD下寫內存
斷點,找到彙編語句如下
0044B280 55 PUSH EBP
0044B281 8BEC MOV EBP,ESP
0044B283 56 PUSH ESI
0044B284 8BF1 MOV ESI,ECX ; 1.2 esi=ecx
0044B286 8B4E 04 MOV ECX,DWORD PTR DS:[ESI+4]
0044B289 8B01 MOV EAX,DWORD PTR DS:[ECX]
0044B28B 57 PUSH EDI
0044B28C FF90 14010000 CALL DWORD PTR DS:[EAX+114]
0044B292 83F8 02 CMP EAX,2
0044B295 8B3D 48465700 MOV EDI,DWORD PTR DS:[<&tEngine.?tThrowS>;
tEngine.?tThrowStringException@@YAXPBDZZ
0044B29B 75 19 JNZ SHORT Game.0044B2B6
0044B29D 68 63050000 PUSH 563
0044B2A2 68 54975700 PUSH Game.00579754 ; ASCII
".\DataPool\GMDP_CharacterData.cpp"
0044B2A7 68 48975700 PUSH Game.00579748 ; ASCII "CT_MONSTER"
0044B2AC 68 20975700 PUSH Game.00579720 ; ASCII "Character must not
%s,(File:%s Line:%d)"
0044B2B1 FFD7 CALL EDI
0044B2B3 83C4 10 ADD ESP,10
0044B2B6 8B4E 04 MOV ECX,DWORD PTR DS:[ESI+4]
0044B2B9 8B11 MOV EDX,DWORD PTR DS:[ECX]
0044B2BB FF92 14010000 CALL DWORD PTR DS:[EDX+114]
0044B2C1 83F8 01 CMP EAX,1
0044B2C4 75 19 JNZ SHORT Game.0044B2DF
0044B2C6 68 64050000 PUSH 564
0044B2CB 68 54975700 PUSH Game.00579754 ; ASCII
".\DataPool\GMDP_CharacterData.cpp"
0044B2D0 68 78975700 PUSH Game.00579778 ; ASCII
"CT_PLAYEROTHER"
0044B2D5 68 20975700 PUSH Game.00579720 ; ASCII "Character must not
%s,(File:%s Line:%d)"
0044B2DA FFD7 CALL EDI
0044B2DC 83C4 10 ADD ESP,10
0044B2DF 8B46 08 MOV EAX,DWORD PTR DS:[ESI+8] ; 1.2 eax=[esi+8]
0044B2E2 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8] ; 01.1 血來自父函數第一
個參數
0044B2E5 8988 B8060000 MOV DWORD PTR DS:[EAX+6B8],ECX ; 1.1 血被寫入
0044B2EB 8B0D 9C975B00 MOV ECX,DWORD PTR DS:[5B979C]
0044B2F1 8B11 MOV EDX,DWORD PTR DS:[ECX]
0044B2F3 68 B4545700 PUSH Game.005754B4 ; ASCII "player"
0044B2F8 6A 19 PUSH 19
0044B2FA FF52 4C CALL DWORD PTR DS:[EDX+4C]
0044B2FD 5F POP EDI
0044B2FE 5E POP ESI
0044B2FF 5D POP EBP
0044B300 C2 0400 RETN 4
這是完整的子函數,實際血被寫入的那句代碼是紅色那句,由此可得知血被存在[eax+6b8]中,6b8是個偏移
量,HP指針地址其實存在eax中,根據該段代碼的分析,得知eax=[esi+8],而esi=調用函數帶進來的ecx,
以上代碼中註釋1.1,1.2,1.3有說明,記好此時的eax,ecx兩個值,下面一步就是要查這兩個值存的東西
變不變
第四步,讓自己掉一次血,發現HP地址沒變,OD中0044B2F5行代碼處下斷點,發現此時的eax,ecx
也沒變,猜測HP地址切換地圖時纔可能重新分配
第五步:切換一次地圖後代碼中斷,發現此時的eax,ecx與上次又不一樣了,上步的猜測可能正確,因爲
eax=[esi+8]=[ecx+8],所以eax是依賴ecx的,ecx又是來自調用函數的,所以使用調用堆棧去查看調用
函數中ecx是怎麼來的,OD中調用堆棧的父函數處回車即可,以下是父函數代碼
004D7A10 55 PUSH EBP
004D7A11 8BEC MOV EBP,ESP
004D7A13 51 PUSH ECX
004D7A14 A1 F0975B00 MOV EAX,DWORD PTR DS:[5B97F0]
004D7A19 3B05 E4975B00 CMP EAX,DWORD PTR DS:[5B97E4]
004D7A1F 53 PUSH EBX
004D7A20 56 PUSH ESI
004D7A21 0F85 AB080000 JNZ Game.004D82D2
004D7A27 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8]
004D7A2A 8B0D 78695B00 MOV ECX,DWORD PTR DS:[5B6978]
004D7A30 8B46 08 MOV EAX,DWORD PTR DS:[ESI+8]
004D7A33 8B11 MOV EDX,DWORD PTR DS:[ECX]
004D7A35 50 PUSH EAX
004D7A36 FF52 44 CALL DWORD PTR DS:[EDX+44] ; 2.5 eax是該函數的返回值,
該函數返回一個重要的地址
004D7A39 8BD8 MOV EBX,EAX ; 2.4 ebx=eax
004D7A3B 85DB TEST EBX,EBX
004D7A3D 0F84 8F080000 JE Game.004D82D2
004D7A43 33C0 XOR EAX,EAX
004D7A45 8A46 0C MOV AL,BYTE PTR DS:[ESI+C]
004D7A48 57 PUSH EDI
004D7A49 8BBB 2C010000 MOV EDI,DWORD PTR DS:[EBX+12C] ; 2.3 edi=[ebx+12c]
004D7A4F 83E0 01 AND EAX,1
004D7A52 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
004D7A55 74 2B JE SHORT Game.004D7A82
004D7A57 8B4E 18 MOV ECX,DWORD PTR DS:[ESI+18]
004D7A5A 51 PUSH ECX
004D7A5B 8BCF MOV ECX,EDI
004D7A5D E8 DE1FF7FF CALL Game.00449A40
004D7A62 8B15 78695B00 MOV EDX,DWORD PTR DS:[5B6978]
004D7A68 3B5A 44 CMP EBX,DWORD PTR DS:[EDX+44]
004D7A6B 75 15 JNZ SHORT Game.004D7A82
004D7A6D 8B57 08 MOV EDX,DWORD PTR DS:[EDI+8]
004D7A70 8B0D 10985B00 MOV ECX,DWORD PTR DS:[5B9810]
004D7A76 8B52 70 MOV EDX,DWORD PTR DS:[EDX+70]
004D7A79 8B01 MOV EAX,DWORD PTR DS:[ECX]
004D7A7B 52 PUSH EDX
004D7A7C FF90 A0000000 CALL DWORD PTR DS:[EAX+A0]
004D7A82 33C0 XOR EAX,EAX
004D7A84 8A46 0C MOV AL,BYTE PTR DS:[ESI+C]
004D7A87 83E0 02 AND EAX,2
004D7A8A D1E8 SHR EAX,1
004D7A8C 85C0 TEST EAX,EAX
004D7A8E 74 0B JE SHORT Game.004D7A9B
004D7A90 8B46 20 MOV EAX,DWORD PTR DS:[ESI+20]
004D7A93 50 PUSH EAX ; 02.1 eax裏存放了血,給子函數使
用
004D7A94 8BCF MOV ECX,EDI ; 2.2 ecx=edi
004D7A96 E8 E537F7FF CALL Game.0044B280 ; 2.1 ecx影響了子函數
004D7A9B 33C0 XOR EAX,EAX
CALL Game.0044B280即第三步找到的子函數,調用子函數時血量值作爲參數傳進去,具體的子函數功能
我也沒搞清楚,大體感覺上可能是拿到數據包後給內存中的HP地址賦值。
繼續分析這段代碼,2.1,2.2,2.3這三句發現ecx=[ebx+12c],看來這裏的12c又是一個偏移量,在2.3
上下斷點,獲取到此時的ebx=0B387708,繼續分析發現2.4,2.5中ebx=eax=2.5調用的子函數的返回值,
動態調試跟下去發現2.5那行調用的子函數裏,的確是爲了獲取這個0b387708,具體函數功能沒看懂,裏
面是一堆比較複雜的地址運算得到了這個值
第六步:CE中查找0b387708存在什麼地址裏,找到兩個地址013D2BD8和013D6064,隨後切換地圖
發現這兩個地址裏的值都改變了,但還是相同,用這個新值進行[[[新值+12c]+8]+6b8]運算,終於得到了
HP值。
感覺這兩個地址有可能是個不變的值,重開遊戲後確認,的確同樣的運算還能得到HP值。
姑且任務第一個值013D2BD8爲要查找的基地址,而血是經過偏移3次後找到的,偏移量分別是12c,8,
6b8
目標基本完成,OVER!
版本:0.13.0402
系統:windows xp
工具:CE5.2+OD1.10
目標:搜索人物基地址
第一步,用CE搜索人物HP,得到一堆地址,掉血後繼續搜索,得到唯一地址0ABDC360(HP地址)
第二步,切換地圖後發現該地址裏的值已經不是HP,是動態地址,重複第一步搜索出新的HP地址(地址
省略)
第三步,這時候不再切換地圖,用CE5.2對找到的HP地址下寫訪問內存斷點,此步也可用OD下寫內存
斷點,找到彙編語句如下
0044B280 55 PUSH EBP
0044B281 8BEC MOV EBP,ESP
0044B283 56 PUSH ESI
0044B284 8BF1 MOV ESI,ECX ; 1.2 esi=ecx
0044B286 8B4E 04 MOV ECX,DWORD PTR DS:[ESI+4]
0044B289 8B01 MOV EAX,DWORD PTR DS:[ECX]
0044B28B 57 PUSH EDI
0044B28C FF90 14010000 CALL DWORD PTR DS:[EAX+114]
0044B292 83F8 02 CMP EAX,2
0044B295 8B3D 48465700 MOV EDI,DWORD PTR DS:[<&tEngine.?tThrowS>;
tEngine.?tThrowStringException@@YAXPBDZZ
0044B29B 75 19 JNZ SHORT Game.0044B2B6
0044B29D 68 63050000 PUSH 563
0044B2A2 68 54975700 PUSH Game.00579754 ; ASCII
".\DataPool\GMDP_CharacterData.cpp"
0044B2A7 68 48975700 PUSH Game.00579748 ; ASCII "CT_MONSTER"
0044B2AC 68 20975700 PUSH Game.00579720 ; ASCII "Character must not
%s,(File:%s Line:%d)"
0044B2B1 FFD7 CALL EDI
0044B2B3 83C4 10 ADD ESP,10
0044B2B6 8B4E 04 MOV ECX,DWORD PTR DS:[ESI+4]
0044B2B9 8B11 MOV EDX,DWORD PTR DS:[ECX]
0044B2BB FF92 14010000 CALL DWORD PTR DS:[EDX+114]
0044B2C1 83F8 01 CMP EAX,1
0044B2C4 75 19 JNZ SHORT Game.0044B2DF
0044B2C6 68 64050000 PUSH 564
0044B2CB 68 54975700 PUSH Game.00579754 ; ASCII
".\DataPool\GMDP_CharacterData.cpp"
0044B2D0 68 78975700 PUSH Game.00579778 ; ASCII
"CT_PLAYEROTHER"
0044B2D5 68 20975700 PUSH Game.00579720 ; ASCII "Character must not
%s,(File:%s Line:%d)"
0044B2DA FFD7 CALL EDI
0044B2DC 83C4 10 ADD ESP,10
0044B2DF 8B46 08 MOV EAX,DWORD PTR DS:[ESI+8] ; 1.2 eax=[esi+8]
0044B2E2 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8] ; 01.1 血來自父函數第一
個參數
0044B2E5 8988 B8060000 MOV DWORD PTR DS:[EAX+6B8],ECX ; 1.1 血被寫入
0044B2EB 8B0D 9C975B00 MOV ECX,DWORD PTR DS:[5B979C]
0044B2F1 8B11 MOV EDX,DWORD PTR DS:[ECX]
0044B2F3 68 B4545700 PUSH Game.005754B4 ; ASCII "player"
0044B2F8 6A 19 PUSH 19
0044B2FA FF52 4C CALL DWORD PTR DS:[EDX+4C]
0044B2FD 5F POP EDI
0044B2FE 5E POP ESI
0044B2FF 5D POP EBP
0044B300 C2 0400 RETN 4
這是完整的子函數,實際血被寫入的那句代碼是紅色那句,由此可得知血被存在[eax+6b8]中,6b8是個偏移
量,HP指針地址其實存在eax中,根據該段代碼的分析,得知eax=[esi+8],而esi=調用函數帶進來的ecx,
以上代碼中註釋1.1,1.2,1.3有說明,記好此時的eax,ecx兩個值,下面一步就是要查這兩個值存的東西
變不變
第四步,讓自己掉一次血,發現HP地址沒變,OD中0044B2F5行代碼處下斷點,發現此時的eax,ecx
也沒變,猜測HP地址切換地圖時纔可能重新分配
第五步:切換一次地圖後代碼中斷,發現此時的eax,ecx與上次又不一樣了,上步的猜測可能正確,因爲
eax=[esi+8]=[ecx+8],所以eax是依賴ecx的,ecx又是來自調用函數的,所以使用調用堆棧去查看調用
函數中ecx是怎麼來的,OD中調用堆棧的父函數處回車即可,以下是父函數代碼
004D7A10 55 PUSH EBP
004D7A11 8BEC MOV EBP,ESP
004D7A13 51 PUSH ECX
004D7A14 A1 F0975B00 MOV EAX,DWORD PTR DS:[5B97F0]
004D7A19 3B05 E4975B00 CMP EAX,DWORD PTR DS:[5B97E4]
004D7A1F 53 PUSH EBX
004D7A20 56 PUSH ESI
004D7A21 0F85 AB080000 JNZ Game.004D82D2
004D7A27 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8]
004D7A2A 8B0D 78695B00 MOV ECX,DWORD PTR DS:[5B6978]
004D7A30 8B46 08 MOV EAX,DWORD PTR DS:[ESI+8]
004D7A33 8B11 MOV EDX,DWORD PTR DS:[ECX]
004D7A35 50 PUSH EAX
004D7A36 FF52 44 CALL DWORD PTR DS:[EDX+44] ; 2.5 eax是該函數的返回值,
該函數返回一個重要的地址
004D7A39 8BD8 MOV EBX,EAX ; 2.4 ebx=eax
004D7A3B 85DB TEST EBX,EBX
004D7A3D 0F84 8F080000 JE Game.004D82D2
004D7A43 33C0 XOR EAX,EAX
004D7A45 8A46 0C MOV AL,BYTE PTR DS:[ESI+C]
004D7A48 57 PUSH EDI
004D7A49 8BBB 2C010000 MOV EDI,DWORD PTR DS:[EBX+12C] ; 2.3 edi=[ebx+12c]
004D7A4F 83E0 01 AND EAX,1
004D7A52 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
004D7A55 74 2B JE SHORT Game.004D7A82
004D7A57 8B4E 18 MOV ECX,DWORD PTR DS:[ESI+18]
004D7A5A 51 PUSH ECX
004D7A5B 8BCF MOV ECX,EDI
004D7A5D E8 DE1FF7FF CALL Game.00449A40
004D7A62 8B15 78695B00 MOV EDX,DWORD PTR DS:[5B6978]
004D7A68 3B5A 44 CMP EBX,DWORD PTR DS:[EDX+44]
004D7A6B 75 15 JNZ SHORT Game.004D7A82
004D7A6D 8B57 08 MOV EDX,DWORD PTR DS:[EDI+8]
004D7A70 8B0D 10985B00 MOV ECX,DWORD PTR DS:[5B9810]
004D7A76 8B52 70 MOV EDX,DWORD PTR DS:[EDX+70]
004D7A79 8B01 MOV EAX,DWORD PTR DS:[ECX]
004D7A7B 52 PUSH EDX
004D7A7C FF90 A0000000 CALL DWORD PTR DS:[EAX+A0]
004D7A82 33C0 XOR EAX,EAX
004D7A84 8A46 0C MOV AL,BYTE PTR DS:[ESI+C]
004D7A87 83E0 02 AND EAX,2
004D7A8A D1E8 SHR EAX,1
004D7A8C 85C0 TEST EAX,EAX
004D7A8E 74 0B JE SHORT Game.004D7A9B
004D7A90 8B46 20 MOV EAX,DWORD PTR DS:[ESI+20]
004D7A93 50 PUSH EAX ; 02.1 eax裏存放了血,給子函數使
用
004D7A94 8BCF MOV ECX,EDI ; 2.2 ecx=edi
004D7A96 E8 E537F7FF CALL Game.0044B280 ; 2.1 ecx影響了子函數
004D7A9B 33C0 XOR EAX,EAX
CALL Game.0044B280即第三步找到的子函數,調用子函數時血量值作爲參數傳進去,具體的子函數功能
我也沒搞清楚,大體感覺上可能是拿到數據包後給內存中的HP地址賦值。
繼續分析這段代碼,2.1,2.2,2.3這三句發現ecx=[ebx+12c],看來這裏的12c又是一個偏移量,在2.3
上下斷點,獲取到此時的ebx=0B387708,繼續分析發現2.4,2.5中ebx=eax=2.5調用的子函數的返回值,
動態調試跟下去發現2.5那行調用的子函數裏,的確是爲了獲取這個0b387708,具體函數功能沒看懂,裏
面是一堆比較複雜的地址運算得到了這個值
第六步:CE中查找0b387708存在什麼地址裏,找到兩個地址013D2BD8和013D6064,隨後切換地圖
發現這兩個地址裏的值都改變了,但還是相同,用這個新值進行[[[新值+12c]+8]+6b8]運算,終於得到了
HP值。
感覺這兩個地址有可能是個不變的值,重開遊戲後確認,的確同樣的運算還能得到HP值。
姑且任務第一個值013D2BD8爲要查找的基地址,而血是經過偏移3次後找到的,偏移量分別是12c,8,
6b8
目標基本完成,OVER!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.