日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Hacking Diablo II之D2HACKIT技术详解

發(fā)布時(shí)間:2024/8/1 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hacking Diablo II之D2HACKIT技术详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
趁著圣誕又歇了幾天,沒博,倒是主動(dòng)被動(dòng)的看了不少片子。我發(fā)現(xiàn)我的觀影口味挺雜,什么都看,還什么都能看的津津有味。這些片中,有肥皂劇型的“Ally McBeal”(甜心俏佳人),柯恩兄弟的黑幫型的"Miller's Crossing",悶騷型的“Country Life”,一直想看的“北京樂與路”,還有成龍大叔的“神話”。
前幾天有博友留言希望我多談點(diǎn)兒d2hackit,那我就隨便說說。
D2中的外掛,比較有代表性的大致可以分為三類:以maphack為代表的輔助型,以幫助玩家更有效的玩游戲?yàn)槟康?#xff1b;以D2JSP為代表的BOT型,用于在無人值守的狀態(tài)下自動(dòng)進(jìn)行游戲;還有一類就是以d2hackit為代表的全能型,bot、pickit、dupe、pk hack、packet sniffer、trade hack、drop hack什么都能做,D2中dupe泛濫有一部分原因要?dú)w功于它,比較有代表性的基于d2hackit的插件外掛有09時(shí)期的pickit、PindleBot,和1.10時(shí)期的zPickit。
從結(jié)果上看,d2hackit無疑是成功的,然而從軟件設(shè)計(jì)角度看,它當(dāng)初的部分設(shè)計(jì)目標(biāo)并沒有達(dá)到。d2hackit的設(shè)計(jì)意圖,是要實(shí)現(xiàn)一個(gè)外掛的開發(fā)平臺(tái),其他開發(fā)者只需用這個(gè)平臺(tái)提供的基礎(chǔ)設(shè)施,不必具備逆向工程,甚至匯編語(yǔ)言的能力就能夠做出外掛。按照d2hackit原作者thohell的設(shè)想,d2hackit甚至不必局限于D2,而是一個(gè)通用的外掛開發(fā)平臺(tái),可以用于其他游戲。
降低外掛開發(fā)的難度這一點(diǎn)d2hackit是做到了,d2hackit插件泛濫就說明了它的成功。通用平臺(tái)這一目標(biāo)它顯然沒有達(dá)到,別說用于其它游戲,在09補(bǔ)丁上能用的插件,在1.10上都用不了,必須重新編譯甚至修改源代碼。
d2hackit的基本工作原理,跟我以前寫的一篇 介紹外掛工作原理的文章里說的大致相同:d2hackit的加載、卸載,地址(旁路點(diǎn)、游戲內(nèi)部函數(shù)和全局變量)的定位,以及旁路點(diǎn)被觸發(fā)時(shí)的處理等幾部份。不同的是d2hackit做為一個(gè)外掛平臺(tái),還需要加載它的插件,并在適當(dāng)時(shí)刻(收、發(fā)數(shù)據(jù)包,進(jìn)入、退出游戲等)通知插件。下面逐一分析。
1,d2hackit的加載和卸載。 d2hackit在本質(zhì)上就是一個(gè)windows的DLL,因此任何能在游戲進(jìn)程加載、卸載DLL的方法都適用于d2hackit。d2hackit 自帶的loader用的是遠(yuǎn)程DLL注入的方法,另外d2hackit本身也可以做為d2loader的插件在游戲程序運(yùn)行時(shí)自動(dòng)加載。
2,地址的定位。d2hackit對(duì)地址的定位是比較有特色的,它除了支持基址+偏移量的通常做法,還支持指紋式的內(nèi)存數(shù)據(jù)匹配搜索,也就是說它可以通過搜索特定模式的字節(jié)序列來定位內(nèi)存地址。這樣設(shè)計(jì)的意圖是在游戲補(bǔ)丁升級(jí)時(shí)只需更新指紋數(shù)據(jù)就可以讓d2hackit工作于新版本補(bǔ)丁(當(dāng)然大家都知道這個(gè)目標(biāo)沒有達(dá)到)。指紋模式在配置文件中指定(d2hackit.ini),格式如下:
;Name=Module,patchsize,offset,fingerprint
GamePacketReceivedIntercept
=D2Client.dll,7,13,8B5C2410xxxxxxxxxxxx8D145B8B0495 上面這行指定了接收數(shù)據(jù)包的旁路點(diǎn)地址的匹配模式:在d2client.dll中搜索8B5C2410xxxxxxxxxxxx8D145B8B0495特征數(shù)據(jù),每xx匹配任意1字節(jié)數(shù)據(jù)。7為patch長(zhǎng)度,13為距離匹配地址的偏移。
3,旁路點(diǎn)的事件處理。以接收游戲數(shù)據(jù)包的處理為例。在安裝了GamePacketReceivedIntercept旁路點(diǎn)以后,每當(dāng)收到游戲內(nèi)數(shù)據(jù)包時(shí),d2hackit的相應(yīng)旁路點(diǎn)處理例程就會(huì)先獲取控制權(quán)。為了不破壞原先的寄存器內(nèi)容,旁路點(diǎn)處理例程必須先保存必要的寄存器然后再做真正的處理。因此處理例程分為兩部分,用匯編寫的GamePacketReceivedInterceptSTUB函數(shù)和C函數(shù)GamePacketReceivedIntercept。
DWORD__fastcallGamePacketReceivedIntercept(BYTE*aPacket,DWORDaLength)
{
//Passpackettoallclientswhowantstosnoop
LinkedItem*li=ClientModules.GetFirstItem();
while(li)
{
PCISpCIS
=ClientModules.GetCIS(li);
if(pCIS&&pCIS->OnGamePacketBeforeReceived)
{
aLength
=pCIS->OnGamePacketBeforeReceived(aPacket,aLength);
if(!aLength)break;
}
li
=ClientModules.GetNextItem(li);
}
returnaLength;
}
上面是d2hackit的收到數(shù)據(jù)包時(shí)的處理代碼,很簡(jiǎn)單,就是遍歷加載的插件模塊,挨個(gè)調(diào)用插件模塊中的 OnGamePacketBeforeReceived函數(shù)進(jìn)行進(jìn)一步的分析。
4,d2hackit插件模塊。d2hackit的插件以d2h為后綴,其實(shí)也是普通的DLL。做為d2hackit的插件,d2h必須提供一些回調(diào)入口點(diǎn)(即DLL的導(dǎo)出函數(shù)),供d2hackit在必要的時(shí)刻調(diào)用。這些入口點(diǎn)有:
BOOLEXPORTOnClientStart();
BOOLEXPORTOnClientStop
();
DWORDEXPORTOnGameTimerTick
();
BOOLEXPORTOnGameCommandLine
(char**argv,intargc);
DWORDEXPORTOnBnetPacketBeforeSent
(BYTE*aPacket,DWORDaLen);
DWORDEXPORTOnBnetPacketBeforeReceived
(BYTE*aPacket,DWORDaLen);
DWORDEXPORTOnRealmPacketBeforeSent
(BYTE*aPacket,DWORDaLen);
DWORDEXPORTOnRealmPacketBeforeReceived
(BYTE*aPacket,DWORDaLen);
DWORDEXPORTOnGamePacketBeforeSent
(BYTE*aPacket,DWORDaLen);
DWORDEXPORTOnGamePacketBeforeReceived
(BYTE*aPacket,DWORDaLen);
LPCSTREXPORTGetModuleAuthor
();
LPCSTREXPORTGetModuleWebsite
();
LPCSTREXPORTGetModuleEmail
();
LPCSTREXPORTGetModuleDescription
();
DWORDEXPORTGetModuleVersion
();
VOIDEXPORTOnGameJoin
(THISGAMESTRUCT*thisgame);
VOIDEXPORTOnGameLeave
(THISGAMESTRUCT*thisgame); 通過名字你就能猜出它們?cè)谑裁磿r(shí)候會(huì)被d2hackit調(diào)用,比如說收到數(shù)據(jù)包時(shí)就是 OnGamePacketBeforeReceived
d2hackit插件的加載有兩種方法,一種是在d2hackit.ini里設(shè)定隨著d2hackit本身加載時(shí)自動(dòng)加載,另一種可以由玩家在進(jìn)入游戲后在聊天輸入框中以特定的命令加載(d2hackit截獲了聊天輸入框的處理)。
5,d2hackit也給插件模塊提供了一組接口(API),供插件模塊使用。比如在OnGamePacketBeforeReceived函數(shù)中,插件可以直接修改數(shù)據(jù)包buffer的數(shù)據(jù),但有的時(shí)候你需要向玩家顯示分析結(jié)果或者向服務(wù)器發(fā)送一些定制數(shù)據(jù)包,這時(shí)候就得調(diào)用d2hackit提供的API。基本的API大概有這些:
DWORDEXPORTGameSendPacketToServer(LPBYTEbuf,DWORDlen);
DWORDEXPORTBnetSendPacketToServer(LPBYTEbuf,DWORDlen);
DWORDEXPORTRealmSendPacketToServer(LPBYTEbuf,DWORDlen);
BOOLEXPORTGameSendMessageToChat(LPSTRmsg);
DWORDEXPORTGameSendPacketToGame(LPBYTEbuf,DWORDlen);
BOOLEXPORTGameInsertPacketToGame(LPBYTEbuf,DWORDlen);
BOOLEXPORTGamePrintInfo(LPCSTRbuf);
BOOLEXPORTGamePrintError(LPCSTRbuf);
BOOLEXPORTGamePrintVerbose(LPCSTRbuf);
BOOLEXPORTGamePrintString(LPCSTRbuf);
DWORDEXPORTGameSendPacketToServer(LPBYTEbuf,DWORDlen);
PTHISGAMESTRUCTEXPORTGetThisgameStruct(
void);
PSERVERINFOEXPORTGetServerInfo(DWORDdwVersion,LPCSTRszModule);
BOOLEXPORTGameSaveAndExit();

這樣,d2hackit的插件通過處理特定的事件和調(diào)用d2hackit提供的API就可以實(shí)現(xiàn)它想要的功能,無須匯編和逆向工程知識(shí)。由于網(wǎng)絡(luò)游戲的功能實(shí)現(xiàn)非常依賴于數(shù)據(jù)包,因此通過截獲數(shù)據(jù)包的收發(fā)來分析、篡改、偽造數(shù)據(jù)包可以完成絕大部分外掛的功能。

6,d2hackit的升級(jí)。由于d2hackit利用游戲的特定函數(shù)和數(shù)據(jù)進(jìn)行工作,每次D2升級(jí)補(bǔ)丁d2hackit本身也必須重定位這些地址。做一個(gè)可以用于1.11b補(bǔ)丁的d2hackit其實(shí)也主要就是這個(gè)工作。比起d2hackmap來,d2hackit用的的地址很少(10個(gè)),難度小多了。要定位的地址有:
GamePacketReceivedIntercept=D2Client.dll,7,13,8B5C2410xxxxxxxxxxxx8D145B8B0495
GamePacketReceivedIntercept2=D2Client.dll,7,18,85C9894C24xx0F8FxxxxxxxxFF05xxxxxxxx5F5E5D
GamePacketSentIntercept=D2Net.dll,5,0,!10005
GamePlayerInfoIntercept=D2Client.dll,6,10,E8xxxxxxxxE8xxxxxxxx8935xxxxxxxx5EC3
pPlayerInfoStruct=D2Client.dll,0,12,E8xxxxxxxxE8xxxxxxxx8935xxxxxxxx5EC3
GamePrintStringLocation=D2Client.dll,0,0,81ECxxxxxxxx53558BE956578A45xx84C0
LoaderStruct=Game.exe,0,0,1d10abd1
GameKeyDownIntercept=D2Client.dll,5,5,8B770833D2xxxxxxxxxxxxC0668B41043BC6
GameSendPacketToGameLocation=d2net.dll,0,21,81EC0C010000538B1Dxxxxxxxx5556
GameSaveAndExit=D2client.dll,0,0,33c9e8xxxxxxxxc705xxxxxxxxxxxxxxxxe8xxxxxxxxc705
GameSendMessageToChat=bnclient.dll,0,15,C390909090909090909090909090908BD1
pGameInfoStruct=d2client.dll,0,0,#6FAA1C5A

第二個(gè)要做的工作是修改旁路點(diǎn)的入口代碼,因?yàn)椴煌膁2補(bǔ)丁具體代碼可能有變化,對(duì)寄存器的利用也有所不同。具體的說就是要改這幾個(gè)函數(shù):
voidGamePacketReceivedInterceptSTUB();
voidGamePacketReceivedIntercept2STUB();
voidBnetPacketReceivedSaveSTUB();
voidBnetPacketReceivedInterceptSTUB();
voidGamePacketSentInterceptSTUB();
voidBnetPacketSentInterceptSTUB();
voidGamePlayerInfoInterceptSTUB();
第三步是修正兩個(gè)游戲內(nèi)部的數(shù)據(jù)結(jié)構(gòu):
typedefstructplayerinfostruct_t_110
...{
BYTEUnitType;
//+0x00
DWORDCharacterClass;//+0x04
DWORDunknown1;//+0x08
DWORDPlayerID;//+0x0c
DWORDPlayerLocation;//+0x10(defineslocationsomehowinoroutoftownandmaybeotherlocations(0x05=intown,0x01=outoftown)
LPCSTRPlayerName;//+0x14pointertoLPSZplayername
BYTEAct;//+0x18
BYTEunknown2[0x73];//+0x19
WORDPlayerPositionX;//+0x8c
WORDPlayerPositionY;//+0x8e

}
PLAYERINFOSTRUCT_110,*PPLAYERINFOSTRUCT_110;

typedef
structgamestruct_t_110
...{
charUnknown1[0x1a];
charGameName[0x10];
charUnknown2[0x08];
charServerIP[0x10];
charUnknown3[0x46];
charAccountName[0x10];
charUnknown4[0x20];
charCharacterName[0x10];
charUnknown5[0x08];
charRealmName[0x10];
charUnknown6[0x147];
charRealmName2[0x10];
charUnknown7[0x08];
charGamePassword[0x10];

}
GAMESTRUCT_110,*PGAMESTRUCT_110;

總結(jié)

以上是生活随笔為你收集整理的Hacking Diablo II之D2HACKIT技术详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。