Dark Angle
C++博客
首頁
新隨筆
聯(lián)系
聚合
管理
隨筆 - 298 文章 - 377 trackbacks - 0
<
2007年7月
>
日
一
二
三
四
五
六
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
常用鏈接
我的隨筆
我的評論
我參與的隨筆
留言簿
(34)
給我留言
查看公開留言
查看私人留言
隨筆分類
ascent(19)
Audio&Video(3)
c++(21)
Database(30)
Game(9)
ios-Develop(1)
Linux(113)
net work(25)
PHP-web develop(1)
some hack imformation(4)
Visual C++(23)
軟件下載(1)
軟件應(yīng)用(12)
一些小技巧(4)
隨筆檔案
2021年7月 (1)
2018年3月 (2)
2018年2月 (1)
2018年1月 (4)
2017年12月 (5)
2017年11月 (1)
2017年10月 (2)
2017年9月 (4)
2017年8月 (3)
2017年7月 (1)
2017年6月 (1)
2017年5月 (5)
2017年4月 (1)
2017年3月 (2)
2016年11月 (12)
2016年10月 (1)
2016年9月 (7)
2016年8月 (4)
2016年7月 (6)
2016年6月 (14)
2016年5月 (1)
2016年4月 (2)
2016年3月 (3)
2015年12月 (2)
2015年6月 (6)
2015年5月 (6)
2014年10月 (1)
2014年8月 (2)
2014年6月 (1)
2013年11月 (1)
2013年8月 (1)
2013年6月 (9)
2013年4月 (7)
2013年3月 (7)
2013年2月 (1)
2013年1月 (3)
2012年8月 (1)
2012年7月 (2)
2012年6月 (5)
2011年10月 (1)
2009年7月 (1)
2009年6月 (10)
2009年1月 (1)
2008年12月 (2)
2008年11月 (1)
2008年10月 (8)
2008年9月 (1)
2008年8月 (5)
2008年7月 (8)
2008年6月 (12)
2008年3月 (8)
2008年2月 (2)
2007年12月 (1)
2007年10月 (7)
2007年9月 (12)
2007年8月 (44)
2007年7月 (12)
2007年6月 (12)
2007年5月 (4)
2007年4月 (8)
文章檔案
2008年12月 (1)
2007年4月 (1)
相冊
ascent
收藏夾
office 插件開發(fā)(2)
搜索
最新評論
1.?re: 禁止 .mysql_history
評論內(nèi)容較長,點(diǎn)擊標(biāo)題查看
--聶文龍
2.?re: chromium .cipd_client 失敗的解決辦法
評論內(nèi)容較長,點(diǎn)擊標(biāo)題查看
--聶文龍
3.?re: 微信web版 協(xié)議
評論內(nèi)容較長,點(diǎn)擊標(biāo)題查看
--聶文龍
4.?re: 相似圖片搜索hash的php實(shí)現(xiàn)
評論內(nèi)容較長,點(diǎn)擊標(biāo)題查看
--聶文龍
5.?re: Gnome3提取gnome-shell.css以及修改和編譯
評論內(nèi)容較長,點(diǎn)擊標(biāo)題查看
--聶文龍
閱讀排行榜
1.?ofstream ifstream 文件操作(68627)
2.?Linux下如何修改ip地址(55499)
3.?Linux修改IP和DNS(51338)
4.?http://evaphone.com/(27294)
5.?程序調(diào)試的利器GDB(18123)
評論排行榜
1.?http://evaphone.com/(48)
2.?百分之百解決ARP欺騙、聚生網(wǎng)管、P2P終結(jié)者導(dǎo)致頻繁掉線不能上網(wǎng)的問題(15)
3.?ascent wow(15)
4.?[mysql]ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)(11)
5.?代理服務(wù)器代碼(11)
內(nèi)存中找怪物之代碼注入篇
網(wǎng)上看了N多的文章,對內(nèi)存中找怪極少有詳細(xì)介紹,大多數(shù)人搞定人物內(nèi)存中的有關(guān)參數(shù)后,止步于內(nèi)存中的找怪。人物只有一個,而怪有各種各樣的,數(shù)量又同時(shí)出現(xiàn)多個,比在內(nèi)存中找人物坐標(biāo)難度要大得多。
下面我將盡可能詳細(xì)的講講內(nèi)存中找怪之代碼注入篇,拋磚引玉,望高人指點(diǎn)。這里的代碼注入是直接把代碼注入到游戲文件中,學(xué)個破解的人都知道,哪怕游戲原文件加了殼,在游戲原文件中加入自己的代碼也是完全可以的。
由于本人水平有限,有的地方可能表達(dá)不清,請耐心慢慢看。有的地方采取的方法也許對高手來說好低劣,見笑了。
一、把周圍的怪物名稱起始地址集中寫到內(nèi)存中一固定區(qū)域。
游戲中,玩家周圍有許多怪物,所有怪物的名稱、坐標(biāo)、血量等參數(shù)不可能會固定在某一內(nèi)存位置,但對于每一個怪物而言,它的名稱、
坐標(biāo)、血量等在內(nèi)存中的地址之間有著相對固定的差值,只要知道怪物的名稱地址就能知道這個怪物的坐標(biāo)、血量等地址。因此,只要把周圍
每個怪物的名稱地址固定在內(nèi)存中一定區(qū)域,就可知道這些怪物的其他參數(shù)。
1
、先把游戲中我們需要打的怪物名稱(不是所有怪物,因?yàn)橛械墓治锊槐瑬|西等不值得打)固定放到內(nèi)存地址為004d2a60起的一塊區(qū)域,制做
一張需要打的怪物名稱列表。每個怪名稱占12字節(jié),不夠12字節(jié)的后面用00填充。
內(nèi)存地址:004d2a60是怎樣來的呢?
我們用PEditor打開游戲原文件,可以看到PE文件分了好多塊,有的塊是可以改寫的(屬性為E0000020或C0000040的可以改寫),塊里并不全
部寫滿了數(shù)據(jù),還有大塊連續(xù)為00的空閑區(qū)域。用UltraEdit等軟件打開游戲文件,看到文件物理地址為000d2a60起有一大塊為00的空閑區(qū)域
。映射到內(nèi)存中就是地址為004d2a60起一塊為00的空閑區(qū)域,我們先把怪物名稱寫到這塊地方。
具體操做是用UltraEdit打開游戲文件,修改
文件物理地址為000d2a60起的數(shù)據(jù)。原文件中這里全部為00,我們把下面數(shù)據(jù)填進(jìn)去(部分怪物名稱列表)。
000D2A60 B0 EB CA DE D5 BD CA BF 00 00 00 00 B0 EB CA DE 半獸戰(zhàn)士....半獸
000D2A70 D3 C2 CA BF 00 00 00 00 BB A2 C9 DF 00 00 00 00 勇士....虎蛇....
000D2A80 00 00 00 00 B6 BE D6 A9 D6 EB 00 00 00 00 00 00 ....毒蜘蛛......
000D2A90 C9 AD C1 D6 D1 A9 C8 CB 00 00 00 00 CD FE CB BC 森林雪人....威思
000D2AA0 B6 F8 D0 A1 B3 E6 00 00 B6 E0 BD C7 B3 E6 00 00 而小蟲..多角蟲..
000D2AB0 00 00 00 00 BF F8 BC D7 B3 E6 00 00 00 00 00 00 ....盔甲蟲......
000D2AC0 B8 AF CA B4 C8 CB B9 ED 00 00 00 00 C0 CB D7 D3 腐蝕人鬼....浪子
000D2AD0 C8 CB B9 ED 00 00 00 00 C0 D7 B5 E7 BD A9 CA AC 人鬼....雷電僵尸
000D2AE0 00 00 00 00 BD A9 CA AC 00 00 00 00 00 00 00 00 ....僵尸........
000D2AF0 C9 AE C2 C2 BD A9 CA AC 00 00 00 00 B6 B4 C7 F9 僧侶僵尸....洞蛆
000D2B00 00 00 00 00 00 00 00 00 F7 BC F7 C3 BE AB C1 E9 ........骷髏精靈
000D2B10 00 00 00 00 CA AC CD F5 00 00 00 00 00 00 00 00 ....尸王........
這樣,當(dāng)游戲運(yùn)行時(shí),從內(nèi)存地址004d2a60起的一段區(qū)域有了我們需要打的怪物列表。
2、
再把玩家周圍實(shí)際刷的怪物名稱的起始地址(注意是名稱的起始地址)固定在內(nèi)存為004D3000起的長為100(16進(jìn)制)的地方。
內(nèi)存地址:004D3000是游戲運(yùn)行時(shí)我們查到的空閑內(nèi)存地址,我們利用它們來放周圍怪物名稱的起始地址,每個怪物名稱的起始地址占4個字
節(jié),長為100(16進(jìn)制)可以放64個怪物,玩家周圍不會超過64個怪物吧,長為100應(yīng)足夠了。
3
、怎么寫入這些怪物名稱的起始地址呢?
首先應(yīng)知道,游戲從哪里把怪物名稱寫入內(nèi)存中。
Cheat Engine會用吧?具體怎么找,簡單的說一下:
先運(yùn)行游戲再運(yùn)行Cheat Engine,CE中選擇游戲程序,查看內(nèi)存,搜索內(nèi)存玩家周圍的一個怪物名稱。找到后記下怪物名稱的起始內(nèi)存地址,
手動添加地址,把找到的地址添加到列表,類型為文本。從列表中選剛才添加的地址,右鍵選“尋找什么寫入這個地址”?;氐接螒蛑幸苿油婕?/font>
,觀察剛添加的內(nèi)存地址的數(shù)值變化。變?yōu)?0時(shí)為該怪物從玩家視眼中消失。再移動玩家到看見這怪物,如果運(yùn)氣好,怪物名會再次寫入這個
內(nèi)存地址。這樣在“以下處理將改變運(yùn)算碼”的窗口中會有匯編代碼出現(xiàn)。
如我的游戲:
能看到00409872 mov byte ptr [edi+ecx], dl 這句。
游戲是從這句把怪物名寫入內(nèi)存中的。
用OllyICE打開游戲。跳到以下這段代碼可以看到:
00409870 > /8A11 mov dl, byte ptr [ecx] //從這里開始寫怪物名稱
00409872 . |88140F mov byte ptr [edi+ecx], dl
//名稱從[edi+ecx]開始
00409875 . |41 inc ecx
00409876 . |84D2 test dl, dl
00409878 .^\75 F6 jnz short 00409870
0040987A . 50 push eax //寫完了運(yùn)行到這里。
0040987B ? 68 4C774C00 push 004C774C
00409880 . 56 push esi
00409881 . E8 02F10A00 call 004B8988
游戲每出現(xiàn)一個怪都會把怪物名稱寫入[edi+ecx]開始的內(nèi)存中,顯然內(nèi)存地址[edi+ecx]不是一個固定的值。我們要把這個值復(fù)制一份固定到
內(nèi)存中地址為004D3000開始的一塊區(qū)域。
這樣,周圍的怪物名稱的起始地址就固定在004D3000、004d3004、004D3008等等內(nèi)存中.知道怪物名稱的起始地址就能算出怪物的坐標(biāo)、血量等
地址。
具體怎么做呢?
我們看到游戲運(yùn)行到0040987A . 50 push eax 這行時(shí),怪物名稱已經(jīng)寫到內(nèi)存中,我們從這行開始寫入我們的代碼,原文件中緊接這行的
下面肯定沒有多余的空間來寫我們的代碼,這就要求改寫這行代碼,跳到空閑的地方把我們的代碼加進(jìn)去,運(yùn)行完我們的代碼后再跳回來。
因此把原文件改為如下(對照上面):
00409870 > /8A11 mov dl, byte ptr [ecx]
00409872 . |88140F mov byte ptr [edi+ecx], dl
00409875 . |41 inc ecx
00409876 . |84D2 test dl, dl
00409878 .^\75 F6 jnz short 00409870
0040987A .- E9 FB690C00 jmp 004D027A
//這里改為跳到004d027a
0040987F 90 nop
00409880 . 56 push esi
00409881 . E8 02F10A00 call 004B8988
就是把這行0040987A . 50 push eax改為:
0040987A .- E9 FB690C00 jmp 004D027A
從004d027A開始寫我們的代碼,原文件中
004D027A
也是一塊為00的空閑區(qū)域。
下面是我們添加進(jìn)去的代碼,原文件中是為00的空閑區(qū)域。
004D027A
50 push eax //先把一些用到的寄存器數(shù)據(jù)入棧,保護(hù)現(xiàn)場。
004D027B 53 push ebx
004D027C 51 push ecx
004D027D 52 push edx
004D027E 31D2 xor edx, edx
004D0280 81C7 A4F61200 add edi, 12F6A4 //此處就是edi+ecx,ecx為常數(shù)12F6A4
004D0286 833F 00 cmp dword ptr [edi], 0 //怪名是否為空
004D0289 74 63 je short 004D02EE //為空不是怪名,直接跳回去不寫入
004D028B 33C9 xor ecx, ecx
004D028D 8B0439 mov eax, dword ptr [ecx+edi] //怪名前4個字節(jié)放入eax中
004D0290 8B9C11 602A4D00 mov ebx, dword ptr [ecx+edx+4D2A60] //
需要打的怪名前4個字節(jié)
004D0297 83C1 04 add ecx, 4
004D029A 3BC3 cmp eax, ebx //比較刷的怪名與需要打的怪名前4個字節(jié)
004D029C 75 07 jnz short 004D02A5 //不相等,跳到與下一個需要打的怪名
004D029E 83F9 0C cmp ecx, 0C //因?yàn)楣置L占12個字節(jié),所以要比較三次
004D02A1 ^ 7C EA jl short 004D028D //沒比較完返回繼續(xù)比較
004D02A3 EB 0D jmp short 004D02B2 //
刷的怪名從需要打的怪名列表中找到了,跳到開始寫入.
004D02A5 83C2 0C add edx, 0C //下一個需要打的怪名
004D02A8 81FA 08010000 cmp edx, 108 //是否到了需要打的怪名列表盡頭
004D02AE ^ 7C DB jl short 004D028B //沒到繼續(xù)比較
004D02B0 EB 3C jmp short 004D02EE //到了盡頭刷的這個怪不是需要打的,跳回不寫入
004D02B2 33C9 xor ecx, ecx //
從這開始寫入
004D02B4 8B81 00304D00 mov eax, dword ptr [ecx+4D3000] //把想寫入的內(nèi)存地址放入eax
004D02BA 83C1 04 add ecx, 4
004D02BD 81F9 00010000 cmp ecx, 100 //是否寫滿,能寫64個怪,周圍一般同時(shí)沒有這么多
004D02C3 7F 12 jg short 004D02D7 //寫滿了清空這塊區(qū)域.
004D02C5 83F8 00 cmp eax, 0 //比較內(nèi)存地址[ecx+4D3000],是否寫了其他怪
004D02C8 ^ 75 EA jnz short 004D02B4 //寫了,找下一個內(nèi)存地址
004D02CA 89B9 FC2F4D00 mov dword ptr [ecx+4D2FFC], edi //把怪名的起始內(nèi)存地址寫入
004D02D0 E8 BB000000 call 004D0390 //寫入一怪后,重新找最近怪,后面詳細(xì)講這個call
004D02D5 EB 17 jmp short 004D02EE //整理后返回
004D02D7 33C9 xor ecx, ecx
004D02D9 33C0 xor eax, eax
004D02DB 8981 00304D00 mov dword ptr [ecx+4D3000], eax
004D02E1 83C1 04 add ecx, 4
004D02E4 81F9 00010000 cmp ecx, 100
004D02EA ^ 7C EF jl short 004D02DB
004D02EC ^ EB C4 jmp short 004D02B2
004D02EE 5A pop edx //各寄存器出棧,恢復(fù)現(xiàn)場
004D02EF 59 pop ecx
004D02F0 5B pop ebx
004D02F1 58 pop eax
004D02F2 50 push eax //把原文件的代碼補(bǔ)上
004D02F3 68 4C774C00 push 004C774C //這也是原文件的代碼補(bǔ)上
004D02F8 - E9 8395F3FF jmp 00409880 //跳回到原文件插入跳轉(zhuǎn)指令的下一行
通過以上代碼,我們把玩家周圍出現(xiàn)的怪,而且是我們需要打的怪名的起始內(nèi)存地址放到了以內(nèi)存地址004D3000開始的一段區(qū)域內(nèi)。
4
、修改游戲原始文件,下次啟動游戲時(shí)能運(yùn)行我們的代碼:
用UltraEdit打開原文件,把原文件地址為0000987A起數(shù)據(jù):
50684C774C00 改為:E9FB690C0090
把下面數(shù)據(jù)復(fù)制到000d027A起的文件里.
50 53 51 52 31 D2 81 C7 A4 F6 12 00 83 3F 00 74
63 33 C9 8B 04 39 8B 9C 11 60 2A 4D 00 83 C1 04
3B C3 75 07 83 F9 0C 7C EA EB 0D 83 C2 0C 81 FA
08 01 00 00 7C DB EB 3C 33 C9 8B 81 00 30 4D 00
83 C1 04 81 F9 00 01 00 00 7F 12 83 F8 00 75 EA
89 B9 FC 2F 4D 00 E8 BB 00 00 00 EB 17 33 C9 33
C0 89 81 00 30 4D 00 83 C1 04 81 F9 00 01 00 00
7C EF EB C4 5A 59 5B 58 50 68 4C 77 4C 00 E9 83
95 F3 FF
上面的這些16進(jìn)制數(shù)據(jù)就是我們上面加入的代碼,修改好后存盤。
至此,游戲運(yùn)行時(shí),不需要其他工具,游戲本身就會把怪名的起始內(nèi)存地址固定到了以內(nèi)存地址004D3000開始的一段區(qū)域內(nèi)。
二、怪物消失時(shí),怪名的起始內(nèi)存地址從004D3000開始的一段區(qū)域內(nèi)清除
上面只是把怪名的起始地址寫到以內(nèi)存地址004D3000開始的一段區(qū)域內(nèi)。當(dāng)怪物從玩家視眼中消失時(shí),我們必需把怪名的起始內(nèi)存地址從
004D3000開始的一段區(qū)域內(nèi)清除掉。
1
、怎么把我們先前寫入的怪名起始地址清除掉呢?
先看看游戲本身當(dāng)怪物消失時(shí)從哪里把怪物名稱從內(nèi)存中清除掉。
同樣使用Cheat Engine,當(dāng)怪物消失時(shí)會有這么一句:
0040F5A8 mov ecx, 30
游戲運(yùn)行到這句時(shí),怪名的內(nèi)存地址清空為00,寄存器edi正好是怪名的起始內(nèi)存地址。
用OllyICE打開游戲。跳到以下這段代碼可以看到:
0040F5A2 . 8DBD 48270600 lea edi, dword ptr [ebp+62748] //這里開始清空
0040F5A8 B9 30000000 mov ecx, 30
0040F5AD . F3:AB rep stos dword ptr es:[edi]
因此把原文件改為如下(對照上面):
0040F5A2 . 8DBD 48270600 lea edi, dword ptr [ebp+62748]
0040F5A8 - E9 540D0C00 jmp 004D0301 //
修改這里,跳到004d0301
0040F5AD . F3:AB rep stos dword ptr es:[edi]
從004d0301開始寫我們的代碼,原文件中004d0301也是一塊為00的空閑區(qū)域。
004D0301
50 push eax //先把一些用到的寄存器數(shù)據(jù)入棧,保護(hù)現(xiàn)場。
004D0302 53 push ebx
004D0303 51 push ecx
004D0304 52 push edx
004D0305 33C9 xor ecx, ecx
004D0307 8B07 mov eax, dword ptr [edi] //把[edi]內(nèi)數(shù)據(jù)放入eax中
004D0309 83F8 00 cmp eax, 0 //比較是否為怪名
004D030C 74 22 je short 004D0330 //為零,不是怪名,不清除跳到返回
004D030E 8B99 00304D00 mov ebx, dword ptr [ecx+4D3000] //把已寫入的怪名起始地址放入ebx004D0314 83C1 04 add ecx, 4
004D0317 81F9 00010000 cmp ecx, 100 //比較是否全部比較完
004D031D 7F 11 jg short 004D0330 //沒找到,說明以前沒把這怪寫入,也就不用清除
004D031F 3BDF cmp ebx, edi //比較游戲剛消失的怪名地址,是否以前寫入過這個地址
004D0321 ^ 75 EB jnz short 004D030E //不是這個再比較下一個
004D0323 33D2 xor edx, edx //剛消失的怪名地址在以前寫入的區(qū)域內(nèi)找到了,開始清除
004D0325 8991 FC2F4D00 mov dword ptr [ecx+4D2FFC], edx //以前寫入的起始怪名地址清零
004D032B E8 60000000 call 004D0390 //清除掉一怪后,重新找最近怪,后面詳細(xì)講這個call
004D0330 5A pop edx //各寄存器出棧,恢復(fù)現(xiàn)場
004D0331 59 pop ecx
004D0332 5B pop ebx
004D0333 58 pop eax
004D0334 B9 30000000 mov ecx, 30 //把原文件的代碼補(bǔ)上
004D0339 - E9 6FF2F3FF jmp 0040F5AD //跳回到原文件插入跳轉(zhuǎn)指令的下一行
通過以上代碼,我們把玩家周圍消失的怪,從內(nèi)存地址004D3000開始的一段區(qū)域內(nèi)清除掉。
2
、修改游戲原始文件,下次啟動游戲時(shí)能運(yùn)行我們的代碼:
用UltraEdit打開原文件,把原文件地址為0000F5A8起數(shù)據(jù):
B930000000 改為:E9540D0C00
把下面數(shù)據(jù)復(fù)制到000d0301起的文件里.
50 53 51 52 33 C9 8B 07 83 F8 00 74 22 8B 99 00
30 4D 00 83 C1 04 81 F9 00 01 00 00 7F 11 3B DF
75 EB 33 D2 89 91 FC 2F 4D 00 E8 60 00 00 00 5A
59 5B 58 B9 30 00 00 00 E9 6F F2 F3 FF 90
數(shù)據(jù)怎么來的,上面已經(jīng)說了。改后存盤。
至此,把玩家周圍消失的怪,從內(nèi)存地址004D3000開始的一段區(qū)域內(nèi)清除掉了。
三、當(dāng)怪物死亡時(shí),怪名的起始內(nèi)存地址從004D3000開始的一段區(qū)域內(nèi)清除
當(dāng)怪物死亡時(shí),游戲并不會立即把怪名內(nèi)存地址清零,要等怪物尸體消失時(shí)才清零。我們必需立即把怪名的起始內(nèi)存地址從004D3000開始的一
段區(qū)域內(nèi)清除掉。
1
、同樣,我們用Cheat Engine找到怪物血量減少時(shí)的匯編代碼:
00419BBA word ptr [esi+626F4], ax
ax中存的就是怪物的血量。
用OllyICE打開游戲。跳到以下這段代碼可以看到:
00419BBA . 66:8986 F4260>mov word ptr [esi+626F4], ax //esi+626f4為血量地址
00419BC1 . 66:8B4F 08 mov cx, word ptr [edi+8]
00419BC5 . 66:898E C2010>mov word ptr [esi+1C2], cx
00419BCC . E8 CFF10900 call 004B8DA0
因此把原文件改為如下(對照上面):
00419BBA . 66:8986 F4260>mov word ptr [esi+626F4], ax
00419BC1 - E9 CB680B00 jmp 004D0491 //
修改這里,跳到004d0491
00419BC6 90 nop
00419BC7 90 nop
00419BC8 90 nop
00419BC9 90 nop
00419BCA 90 nop
00419BCB 90 nop
00419BCC . E8 CFF10900 call 004B8DA0
從004d0491開始寫我們的代碼,原文件中004d0491也是一塊為00的空閑區(qū)域。
下面是我們添加進(jìn)去的代碼,原文件中是為00的空閑區(qū)域。
004D0491 50 push eax //先把一些用到的寄存器數(shù)據(jù)入棧,保護(hù)現(xiàn)場。
004D0492 53 push ebx
004D0493 51 push ecx
004D0494 52 push edx
004D0495 56 push esi
004D0496 33C9 xor ecx, ecx
004D0498 90 nop
004D0499 90 nop
004D049A 66:83F8 00 cmp ax, 0 //比較血量是否為0
004D049E 7F 28 jg short 004D04C8 //大于0,不用清除,直接到返回
004D04A0 81C6 48270600 add esi, 62748 //esi+62748為怪名的起始內(nèi)存地址
004D04A6 8B99 00304D00 mov ebx, dword ptr [ecx+4D3000] //
把以前寫入的怪名起始地址放入ebx
004D04AC 83C1 04 add ecx, 4
004D04AF 81F9 00010000 cmp ecx, 100
004D04B5 7F 11 jg short 004D04C8
004D04B7 3BDE cmp ebx, esi //比較游戲剛死亡的怪名地址,是否以前寫入過這個地址
004D04B9 ^ 75 EB jnz short 004D04A6 //不是這個再比較下一個
004D04BB 33D2 xor edx, edx //剛死亡的怪名地址在以前寫入的區(qū)域內(nèi)找到了,開始清除
004D04BD 8991 FC2F4D00 mov dword ptr [ecx+4D2FFC], edx //清零
004D04C3 E8 C8FEFFFF call 004D0390 //清除掉一怪后,重新找最近怪,后面詳細(xì)講這個call
004D04C8 5E pop esi //各寄存器出棧,恢復(fù)現(xiàn)場
004D04C9 5A pop edx
004D04CA 59 pop ecx
004D04CB 5B pop ebx
004D04CC 58 pop eax
004D04CD 66:8B4F 08 mov cx, word ptr [edi+8] //把原文件的代碼補(bǔ)上
004D04D1 66:898E C201000>mov word ptr [esi+1C2], cx //這也是原文件的代碼補(bǔ)上
004D04D8 - E9 EF96F4FF jmp 00419BCC //跳回到原文件插入跳轉(zhuǎn)指令的下一行
通過以上代碼,把玩家周圍死亡的怪,立即從內(nèi)存地址004D3000開始的一段區(qū)域內(nèi)清除掉。
2
、修改游戲原始文件,下次啟動游戲時(shí)能運(yùn)行我們的代碼:
用UltraEdit打開原文件,把原文件地址為00019BC1起數(shù)據(jù):
668B4F0866898EC2010改為:E9CB680B00909090909090
把下面數(shù)據(jù)復(fù)制到000d0491起的文件里.
50 53 51 52 56 33 C9 90 90 66 83 F8 00 7F 28 81
C6 48 27 06 00 8B 99 00 30 4D 00 83 C1 04 81 F9
00 01 00 00 7F 11 3B DE 75 EB 33 D2 89 91 FC 2F
4D 00 E8 C8 FE FF FF 5E 5A 59 5B 58 66 8B 4F 08
66 89 8E C2 01 00 00 E9 EF 96 F4 FF
同樣,數(shù)據(jù)由上面代碼段而來,改好后存盤。
至些,把玩家周圍死亡的怪,立即從內(nèi)存地址004D3000開始的一段區(qū)域內(nèi)清除掉。
四、把離玩家最近的怪物參數(shù)固定在內(nèi)存中的某處
通過以上三大步驟,我們已經(jīng)實(shí)現(xiàn)了把玩家周圍的,而且是需要打的活的怪物名稱起始內(nèi)存地址集中寫入到了從004D3000到004D3100這小段區(qū)域內(nèi),在這小段區(qū)域內(nèi)每組不為零的四個字節(jié)就代表了一個怪物名的起始內(nèi)存地址,沒有其他不相關(guān)的數(shù)據(jù)在這一小段。如果用按鍵精靈,已經(jīng)可以通過讀這一小段內(nèi)存數(shù)據(jù)可以實(shí)現(xiàn)讀內(nèi)存打怪了。為了減少按鍵精靈讀內(nèi)存次數(shù),和過多的轉(zhuǎn)換運(yùn)算,我們直接把最近怪的有關(guān)參數(shù)固定下來。
這就到了前面多次提到的call 004D0390 這句。
1
、先分析游戲,用Cheat Engine容易找到:
內(nèi)存中怪名起始內(nèi)存地址與其他地址之間的關(guān)系:
以下為16進(jìn)制數(shù):
怪名起始內(nèi)存地址-54=怪血量地址(占兩個字節(jié))
怪名起始內(nèi)存地址-62570=怪X坐標(biāo)地址(占四個字節(jié))
怪名起始內(nèi)存地址-625C0=怪y坐標(biāo)地址(占四個字節(jié))
人物參數(shù)內(nèi)存地址(此游戲竟然是固定的):
人名稱內(nèi)存地址=008AFAF8
人血量內(nèi)存地址=008AFAA4
人氣量內(nèi)存地址=008AFBD8
人X坐標(biāo)內(nèi)存地址=008AFEAC
人y坐標(biāo)內(nèi)存地址=008AFEB0
2
、人物坐標(biāo),怪物坐標(biāo)與屏幕坐標(biāo)的關(guān)系
游戲中人物在屏幕正中心,離上下左右各8步,超過8步在屏幕外,鼠標(biāo)不能點(diǎn)擊。游戲坐標(biāo)差不能超過8。
窗口模式下鼠標(biāo)能點(diǎn)到這個怪的極限區(qū)域(坐標(biāo)為窗口坐標(biāo))。
正上頂點(diǎn):(393,0)與(408,21)組成的區(qū)域。
正下頂點(diǎn):(393,512)與(408,533)組成的區(qū)域。
正左頂點(diǎn):(10,256)與(24,276)組成的區(qū)域。
正右頂點(diǎn):(778,256)與(792,276)組成的區(qū)域。
假設(shè)人物坐標(biāo)(Rx,Ry),怪坐標(biāo)(Gx,Gy),鼠標(biāo)點(diǎn)擊坐標(biāo)(X,Y)
其中人物坐標(biāo),怪坐標(biāo)為游戲里的坐標(biāo),鼠標(biāo)點(diǎn)擊坐標(biāo)為窗口坐標(biāo)。
通過以上分析則有鼠標(biāo)點(diǎn)擊能點(diǎn)到怪的窗口坐標(biāo)X,Y為:
X=(Gx-(Rx-8))*48+17 (后面加值范圍10~24,最好取中間值+17)
y=(Gy-(Ry-8))*32+2 (后面加值范圍0~21,因可能點(diǎn)到左下角頭像選+2)
3
、有了以上理論就可以寫call 004D0390的代碼了
同樣從004D0390開始寫我們的代碼,原文件中004D0390也是一塊為00的空閑區(qū)域。
把最近怪物名的起始內(nèi)存地址固定在[004D2FE0]中,X坐標(biāo)固定在[004D2FF0]中,Y坐標(biāo)固定在[004D2FF4]中,怪血量固定在[004D2FF8]中。
004D0390
50 push eax //先把一些用到的寄存器數(shù)據(jù)入棧,保護(hù)現(xiàn)場。
004D0391 53 push ebx
004D0392 51 push ecx
004D0393 52 push edx
004D0394 56 push esi
004D0395 57 push edi
004D0396 33C0 xor eax, eax
004D0398 A3 E02F4D00 mov dword ptr [4D2FE0], eax //初始化內(nèi)存
004D039D A3 F02F4D00 mov dword ptr [4D2FF0], eax
004D03A2 A3 F42F4D00 mov dword ptr [4D2FF4], eax
004D03A7 05 FFFF0000 add eax, 0FFFF
004D03AC A3 E42F4D00 mov dword ptr [4D2FE4], eax
004D03B1 33C9 xor ecx, ecx
004D03B3 8BB9 00304D00 mov edi, dword ptr [ecx+4D3000] //把怪物起始內(nèi)存地址放入edi
004D03B9 83C1 04 add ecx, 4
004D03BC 81F9 00010000 cmp ecx, 100
004D03C2 0F8F AA000000 jg 004D0472 //全部比較完后返回
004D03C8 83FF 00 cmp edi, 0
004D03CB ^ 74 E6 je short 004D03B3 //為零找下一個
004D03CD 8B87 90DAF9FF mov eax, dword ptr [edi+FFF9DA90] //怪Gx坐標(biāo)放入eax
004D03D3 8B1D ACFE8A00 mov ebx, dword ptr [8AFEAC] //人Rx坐標(biāo)放入ebx
004D03D9 3BC3 cmp eax, ebx
004D03DB 7F 01 jg short 004D03DE
004D03DD 93 xchg eax, ebx
004D03DE 2BC3 sub eax, ebx //Gx與Rx之差放入eax
004D03E0 83F8 08 cmp eax, 8 //兩者差是否大于8
004D03E3 ^ 7F CE jg short 004D03B3 //大于8在屏幕外,直接找下一個怪
004D03E5 F7E0 mul eax //橫坐標(biāo)差平方運(yùn)算
004D03E7 8BF0 mov esi, eax //橫坐標(biāo)差的平方放入esi中
004D03E9 8B87 40DAF9FF mov eax, dword ptr [edi+FFF9DA40] //怪Gy坐標(biāo)放入eax
004D03EF 8B1D B0FE8A00 mov ebx, dword ptr [8AFEB0] //人Ry坐標(biāo)放入ebx
004D03F5 3BC3 cmp eax, ebx
004D03F7 7F 01 jg short 004D03FA
004D03F9 93 xchg eax, ebx
004D03FA 2BC3 sub eax, ebx //Gy與Ry之差放入eax
004D03FC 83F8 08 cmp eax, 8 //兩者差是否大于8
004D03FF ^ 7F B2 jg short 004D03B3 //大于8在屏幕外,直接找下一個怪
004D0401 F7E0 mul eax //樅坐標(biāo)差平方運(yùn)算
004D0403 03F0 add esi, eax //橫、樅坐標(biāo)之差的平方的和放入esi中
004D0405 3B35 E42F4D00 cmp esi, dword ptr [4D2FE4] //
這個距離的平方與前次保存的距離的平方
004D040B ^ 7D A6 jge short 004D03B3 //大于或等于說明這個怪離玩家距離更遠(yuǎn),找下一個怪
004D040D 893D E02F4D00 mov dword ptr [4D2FE0], edi //
更近怪名的起始地址固定在[4D2FE0]中
004D0413 8B47 AC mov eax, dword ptr [edi-54]
004D0416 66:A3 F82F4D00 mov word ptr [4D2FF8], ax //血量固定在[4D2FF8]中
004D041C 8935 E42F4D00 mov dword ptr [4D2FE4], esi //距離平方放在[4D2FE4]中
004D0422 8B87 90DAF9FF mov eax, dword ptr [edi+FFF9DA90] //更近怪Gx坐標(biāo)放入eax
004D0428 8B1D ACFE8A00 mov ebx, dword ptr [8AFEAC] //人Rx坐標(biāo)放入ebx
004D0431 2BC3 sub eax, ebx
004D0433 BB 30000000 mov ebx, 30
004D0438 F7E3 mul ebx
004D043A 83C0 17 add eax, 17
004D043D A3 F02F4D00 mov dword ptr [4D2FF0], eax //換算后,鼠標(biāo)點(diǎn)擊X坐標(biāo)放入[4D2FF0]中
004D0442 8B87 40DAF9FF mov eax, dword ptr [edi+FFF9DA40]
004D0448 8B1D B0FE8A00 mov ebx, dword ptr [8AFEB0]
004D044E 83C0 08 add eax, 8
004D0451 2BC3 sub eax, ebx
004D0453 BB 20000000 mov ebx, 20
004D0458 F7E3 mul ebx
004D045A 83C0 02 add eax, 2
004D045D A3 F42F4D00 mov dword ptr [4D2FF4], eax //換算后,鼠標(biāo)點(diǎn)擊Y坐標(biāo)放入[4D2FF4]中
004D0462 83FE 02 cmp esi, 2 //距離平方是否小于或等于2
004D0465 7E 0B jle short 004D0472 //怪已經(jīng)緊挨著玩家了,不用再找下一個怪了
004D0467 ^ E9 47FFFFFF jmp 004D03B3 //這個怪離玩家還有距離,可能還有更近的
004D046C 90 nop
004D046D 90 nop
004D046E 90 nop
004D046F 90 nop
004D0470 90 nop
004D0471 90 nop
004D0472 5F pop edi //各寄存器出棧,恢復(fù)現(xiàn)場
004D0473 5E pop esi
004D0474 5A pop edx
004D0475 59 pop ecx
004D0476 5B pop ebx
004D0477 58 pop eax
004D0478 C3 retn //返回調(diào)用call的下一行
游戲運(yùn)行過程中,只要運(yùn)行以上這段代碼,就會把最近怪的窗口X坐標(biāo)固定在[004D2FF0]中,窗口Y坐標(biāo)固定在[004D2FF4]中,血量固定在[004D2FF8]中。
4
、用UltraEdit打開原文件,把下面數(shù)據(jù)復(fù)制到000d0390起的文件里.
50 53 51 52 56 57 33 C0 A3 E0 2F 4D 00 A3 F0 2F
4D 00 A3 F4 2F 4D 00 05 FF FF 00 00 A3 E4 2F 4D
00 33 C9 8B B9 00 30 4D 00 83 C1 04 81 F9 00 01
00 00 0F 8F AA 00 00 00 83 FF 00 74 E6 8B 87 90
DA F9 FF 8B 1D AC FE 8A 00 3B C3 7F 01 93 2B C3
83 F8 08 7F CE F7 E0 8B F0 8B 87 40 DA F9 FF 8B
1D B0 FE 8A 00 3B C3 7F 01 93 2B C3 83 F8 08 7F
B2 F7 E0 03 F0 3B 35 E4 2F 4D 00 7D A6 89 3D E0
2F 4D 00 8B 47 AC 66 A3 F8 2F 4D 00 89 35 E4 2F
4D 00 8B 87 90 DA F9 FF 8B 1D AC FE 8A 00 83 C0
08 2B C3 BB 30 00 00 00 F7 E3 83 C0 17 A3 F0 2F
4D 00 8B 87 40 DA F9 FF 8B 1D B0 FE 8A 00 83 C0
08 2B C3 BB 20 00 00 00 F7 E3 83 C0 02 A3 F4 2F
4D 00 83 FE 02 7E 0B E9 47 FF FF FF 90 90 90 90
90 90 5F 5E 5A 59 5B 58 C3
改好后存盤,這樣運(yùn)行游戲時(shí),游戲本身會把最近怪的窗口X坐標(biāo)固定在[004D2FF0]中,窗口Y坐標(biāo)固定在[004D2FF4]中,血量固定在
[004D2FF8]中。
五、人物移動時(shí),及時(shí)更新最近怪物參數(shù)
上面三個大步驟,刷出一個怪,消失一個怪,死亡一個怪時(shí),都會運(yùn)行call 004D0390,也就是都會馬上更新一下內(nèi)存地址004D2FE0、004D2FF0、04D2FF4
、004D2FF8的數(shù)據(jù)。人物移動時(shí)也必需及時(shí)更新最近怪物參數(shù)。
1
、同樣,我們用Cheat Engine找到人物移動時(shí)的匯編代碼:
人物每移動一步都會經(jīng)過以下代碼:
00432A78 pop edi
用OllyICE打開游戲。跳到以下這段代碼可以看到:
00432A78 |. 5F pop edi
00432A79 |. 5E pop esi
00432A7A |. 5B pop ebx
00432A7B |. 8BE5 mov esp, ebp
00432A7D |. 5D pop ebp
00432A7E |. C2 0400 retn 4
因此把原文件改為如下(對照上面):
00432A78 - E9 D4D80900 jmp 004D0351 //
這里改為跳到004d0351
00432A7D |. 5D pop ebp
00432A7E |. C2 0400 retn 4
從004D0351開始寫我們的代碼,原文件中004D0351也是一塊為00的空閑區(qū)域。
下面是我們添加進(jìn)去的代碼,原文件中是為00的空閑區(qū)域。
004D0351 E8 3A000000 call 004D0390 //
就是為了補(bǔ)進(jìn)這句
004D0356 5F pop edi //把原文件的代碼補(bǔ)上
004D0357 5E pop esi
004D0358 5B pop ebx
004D0359 8BE5 mov esp, ebp
004D035B - E9 1D27F6FF jmp 00432A7D //跳回到原文件插入跳轉(zhuǎn)指令的下一行
2、
修改游戲原始文件,下次啟動游戲時(shí)能運(yùn)行我們的代碼:
用UltraEdit打開原文件,把原文件地址為00032a78起數(shù)據(jù):
5F5E5B8BE5 改為:E9D4D80900
把下面數(shù)據(jù)復(fù)制到000d0351起的文件里.
E8 3A 00 00 00 5F 5E 5B 8B E5 E9 1D 27 F6 FF
到此為止,我們終于把最近怪物的有用參數(shù)固定在004D2FE0、004D2FF0、04D2FF4、004D2FF8四個內(nèi)存地址中,當(dāng)然如果還想加入最近怪物的
其他參數(shù),如怪物是否被其他玩家攻擊,是否為小BOSS等等只要修改CALL 004D0390這段代碼就行。
把以上所有要改的數(shù)據(jù)改好存盤后,游戲原文件大小沒有改變,但已經(jīng)成功的把我們的代碼注入進(jìn)去了,啟動游戲。查看游戲內(nèi)存數(shù)據(jù),可以看到內(nèi)存004D2FE0、004D2FF0、04D2FF4、004D2FF8,正是我們需要的離玩家最近怪物的名稱起址、窗口X坐標(biāo)、窗口Y坐標(biāo)、血量。隨著游戲的進(jìn)行,這幾個內(nèi)存地址都會及時(shí)正確的更新著。
六、寫個簡單的內(nèi)存找怪打怪腳本
前期工作做好后,編寫內(nèi)存找怪打怪按鍵精靈腳本就簡單多了。
下面是簡單的腳本:
Dim handle,Rx,Ry,Gx,Gy,G1,G2,X,Y //其中G1,G2為怪名的起始內(nèi)存地址
Plugin handle=Window.MousePoint()
Rem 找怪
Plugin G1=Memory.Read32Bit(handle,&h004d2fe0)
Plugin X=Memory.Read32Bit(handle,&h004d2ff0)
Plugin Y=Memory.Read32Bit(handle,&h004d2ff4)
Plugin BGKM4.MMove(handle,X,Y)
Delay 100
Plugin BGKM4.LClick(handle,X,Y)
Rem 判斷
Plugin G2=Memory.Read32Bit(handle,&h004d2fe0)
If G2=G1
Delay 100
Goto 判斷
EndIf
Delay 100
Goto 找怪
連怪血量的內(nèi)存地址都不需要用上,因?yàn)楣置钠鹗嫉刂芬彩羌皶r(shí)更新的。
七、其他
以上腳本只是簡單的砍怪,沒有加入使用技能,沒有加入補(bǔ)血補(bǔ)氣,也沒有加入撿取物品。游戲中遇到特殊情況也沒做相應(yīng)處理。
關(guān)于使用技能,如可以通過統(tǒng)計(jì)緊挨玩家怪物的數(shù)量使用群攻技能。
知道人物的血、氣內(nèi)存地址,補(bǔ)血補(bǔ)氣那是很容易實(shí)現(xiàn)的了。
關(guān)于游戲地面物品內(nèi)存中的查找,原理其實(shí)同找怪一樣,也可預(yù)先做一個需要撿取的物品清單,然后,把地面出現(xiàn)的物品與清單相比較,如果是要撿的,可以臨時(shí)把坐標(biāo)放入一固定內(nèi)存區(qū)域內(nèi),跟據(jù)判定物品離玩家距離的遠(yuǎn)近和周圍怪物的多少,決定恰當(dāng)?shù)臅r(shí)候去撿起。
游戲中還有些關(guān)鍵的元素,如打怪路線,撿到極品自動存?zhèn)}庫,自動買藥買藍(lán)都可以通過讀內(nèi)存實(shí)現(xiàn)。
不說了,再說又是長篇大論。
posted on 2007-07-21 01:39
聶文龍
閱讀(8153)
評論(5)
編輯
收藏
引用
所屬分類:
c++
FeedBack:
#
re: 內(nèi)存中找怪物之代碼注入篇[未登錄] 2008-02-01 14:47
sea
及時(shí)雨呀,頂頂頂
回復(fù)
更多評論
#
re: 內(nèi)存中找怪物之代碼注入篇 2008-06-11 06:52
是
大哥 能告訴一下怪物的內(nèi)存地址怎么找么?
回復(fù)
更多評論
#
re: 內(nèi)存中找怪物之代碼注入篇 2008-06-11 06:59
是
我想做個怪物提示的功能~~想知道怪物的內(nèi)存地址怎么找 您能告訴我么?
回復(fù)
更多評論
#
re: 內(nèi)存中找怪物之代碼注入篇 2008-08-08 09:36
小弟
大哥,看了你的文章,知道你很了得,,我有個想法,不知道你能否和我談?wù)?,,我的電話?3961465149,,,有個項(xiàng)目和你合作一下,,,是合作,希望能聽到你的回音。謝謝!
回復(fù)
更多評論
#
re: 內(nèi)存中找怪物之代碼注入篇
2009-07-01 12:28
風(fēng)格
# re: 內(nèi)存中找怪物之代碼注入篇 2008-08-08 09:36 小弟
大哥,看了你的文章,知道你很了得,,我有個想法,不知道你能否和我談?wù)劊?,我的?
刪除好嗎,把我手機(jī)刪除好嗎
回復(fù)
更多評論
刷新評論列表
只有注冊用戶
登錄
后才能發(fā)表評論。
【推薦】100%開源!大型工業(yè)跨平臺軟件C++源碼提供,建模,組態(tài)!
相關(guān)文章:
VS2017 install Boost
linux c學(xué)習(xí)筆記----文件的創(chuàng)建與讀寫(open,read,write)
Mysql日期和時(shí)間函數(shù)不求人
Visual C++線程同步技術(shù)
類型轉(zhuǎn)換問題
編碼問題
經(jīng)典的東
端口復(fù)用技術(shù)與實(shí)現(xiàn)代碼
內(nèi)存中找怪物之代碼注入篇
在內(nèi)存中修改數(shù)據(jù)的網(wǎng)游外掛
網(wǎng)站導(dǎo)航:
博客園
IT新聞
BlogJava
博問
Chat2DB
管理
Copyright ©2025 聶文龍 Powered by:
博客園
模板提供:
滬江博客
青青草国产精品久久久久
|
AA级片免费看视频久久
|
亚洲精品视频久久久
|
欧美午夜精品久久久久久浪潮
|
久久精品国产亚洲网站
|
2021久久国自产拍精品
|
亚洲精品美女久久久久99
|
日韩美女18网站久久精品
|
国产精品一久久香蕉国产线看观看
|
亚洲午夜久久久久久久久电影网
|
无码人妻精品一区二区三区久久久
|
久久综合给合久久狠狠狠97色
|
伊人久久大香线蕉精品
|
久久综合亚洲色HEZYO社区
|
www.久久热.com
|
…久久精品99久久香蕉国产
|
香港aa三级久久三级老师2021国产三级精品三级在
|
国产V亚洲V天堂无码久久久
|
999久久久国产精品
|
亚洲欧美日韩中文久久
|
久久国产成人
|
…久久精品99久久香蕉国产
|
亚洲精品国产第一综合99久久
|
香蕉久久夜色精品国产小说
|
亚洲国产精品无码久久一线
|
欧美麻豆久久久久久中文
|
少妇人妻88久久中文字幕
|
久久久精品久久久久久
|
伊人久久免费视频
|
69国产成人综合久久精品
|
天天躁日日躁狠狠久久
|
噜噜噜色噜噜噜久久
|
久久国产成人精品国产成人亚洲
|
久久99精品久久久久久动态图
|
无码AV中文字幕久久专区
|
久久99这里只有精品国产
|
久久久久无码中
|
亚洲va久久久久
|
青青草原综合久久大伊人
|
91精品国产91久久综合
|
久久99热国产这有精品
|