游戏外挂制作教材
前言:
? ? ? 做自己喜歡的!------ 明天你來(lái)自己做外掛?
? ? ? 隨著網(wǎng)絡(luò)游戲的日益火爆,很多玩家都投身到游戲中。目前很多玩家都依賴于一些游戲的外掛程序來(lái)進(jìn)行游戲。那么做一個(gè)游戲的外掛程序是否是一件很困難的事呢?回答是"否",誠(chéng)然編寫(xiě)一些程序是需要一些基本知識(shí)的,所以我們想以最簡(jiǎn)單的語(yǔ)言來(lái)給你講授編寫(xiě)外掛程序的一些技巧,一些方法,并提供給你一些基本的輔助工具,即使你是一個(gè)菜鳥(niǎo),看了我們的教程,并技巧地使用我們提供給你的工具,你完全能夠編寫(xiě)出一個(gè)完全屬于你自己的外掛。在本教程內(nèi),我們提供了金庸群俠傳,以及網(wǎng)絡(luò)三國(guó)這兩個(gè)游戲的修改實(shí)際例子,因?yàn)檫@兩款游戲都是對(duì)封包進(jìn)行過(guò)加密運(yùn)算的,如果你對(duì)這兩個(gè)游戲的修改有了一定的了解后,相信你在其他游戲中也能非常好地做出屬于自己的外掛。我們提供了金庸打增援20個(gè)NPC和網(wǎng)絡(luò)三國(guó)在PK中自動(dòng)吃藥,自動(dòng)發(fā)鏢這兩個(gè)實(shí)際的例子,讓你上手更容易。我們也會(huì)本教程內(nèi)附上這兩個(gè)軟件以提供給你使用和學(xué)習(xí)。我們會(huì)在教程內(nèi)講授給你怎么去破解封包的加密算法,怎么利用我們提供給你工具來(lái)偽造和發(fā)送封包。本教程除了文字教程外,我們還會(huì)提供金庸群俠和三國(guó)的外掛程序,另外還提供6個(gè)外掛制作工具,以供你使用。希望在以后的游戲中,每一個(gè)玩家都能夠在游戲中成長(zhǎng)起來(lái),不但游戲玩的出色,修改游戲也同樣出色,做一個(gè)真正的游戲DIY。 要想在修改游戲中做到百戰(zhàn)百勝,是需要相當(dāng)豐富的計(jì)算機(jī)知識(shí)的。有很多計(jì)算機(jī)高手就是從玩游戲,修改游戲中,逐步對(duì)計(jì)算機(jī)產(chǎn)生濃厚的興趣,逐步成長(zhǎng)起來(lái)的。不要在羨慕別人能夠做到的,因?yàn)閯e人能夠做的你也能夠!我相信你們看了本教程后,會(huì)對(duì)游戲有一個(gè)全新的認(rèn)識(shí),呵呵,因?yàn)槲沂莻€(gè)好老師!(別拿雞蛋砸我呀,救命啊!#¥%……*)?
? ? ? 不過(guò)要想從修改游戲中學(xué)到知識(shí),增加自己的計(jì)算機(jī)水平,可不能只是靠修改游戲呀!?
? ? ? 要知道,修改游戲只是一個(gè)驗(yàn)證你對(duì)你所了解的某些計(jì)算機(jī)知識(shí)的理解程度的場(chǎng)所,只能給你一些發(fā)現(xiàn)問(wèn)題、解決問(wèn)題的機(jī)會(huì),只能起到幫助你提高學(xué)習(xí)計(jì)算機(jī)的興趣的作用,而決不是學(xué)習(xí)計(jì)算機(jī)的捷徑。
一:什么叫外掛?
? ? ? 現(xiàn)在的網(wǎng)絡(luò)游戲多是基于Internet上客戶/服務(wù)器模式,服務(wù)端程序運(yùn)行在游戲服務(wù)器上,游戲的設(shè)計(jì)者在其中創(chuàng)造一個(gè)龐大的游戲空間,各地的玩家可以通過(guò)運(yùn)行客戶端程序同時(shí)登錄到游戲中。簡(jiǎn)單地說(shuō),網(wǎng)絡(luò)游戲?qū)嶋H上就是由游戲開(kāi)發(fā)商提供一個(gè)游戲環(huán)境,而玩家們就是在這個(gè)環(huán)境中相對(duì)自由和開(kāi)放地進(jìn)行游戲操作。那么既然在網(wǎng)絡(luò)游戲中有了服務(wù)器這個(gè)概念,我們以前傳統(tǒng)的修改游戲方法就顯得無(wú)能為力了。記得我們?cè)趩螜C(jī)版的游戲中,隨心所欲地通過(guò)內(nèi)存搜索來(lái)修改角色的各種屬性,這在網(wǎng)絡(luò)游戲中就沒(méi)有任何用處了。因?yàn)槲覀冊(cè)诰W(wǎng)絡(luò)游戲中所扮演角色的各種屬性及各種重要資料都存放在服務(wù)器上,在我們自己機(jī)器上(客戶端)只是顯示角色的狀態(tài),所以通過(guò)修改客戶端內(nèi)存里有關(guān)角色的各種屬性是不切實(shí)際的。那么是否我們就沒(méi)有辦法在網(wǎng)絡(luò)游戲中達(dá)到我們修改的目的?回答是"否"。我們知道Internet客戶/服務(wù)器模式的通訊一般采用TCP/IP通信協(xié)議,數(shù)據(jù)交換是通過(guò)IP數(shù)據(jù)包的傳輸來(lái)實(shí)現(xiàn)的,一般來(lái)說(shuō)我們客戶端向服務(wù)器發(fā)出某些請(qǐng)求,比如移動(dòng)、戰(zhàn)斗等指令都是通過(guò)封包的形式和服務(wù)器交換數(shù)據(jù)。那么我們把本地發(fā)出消息稱為SEND,意思就是發(fā)送數(shù)據(jù),服務(wù)器收到我們SEND的消息后,會(huì)按照既定的程序把有關(guān)的信息反饋給客戶端,比如,移動(dòng)的坐標(biāo),戰(zhàn)斗的類(lèi)型。那么我們把客戶端收到服務(wù)器發(fā)來(lái)的有關(guān)消息稱為RECV。知道了這個(gè)道理,接下來(lái)我們要做的工作就是分析客戶端和服務(wù)器之間往來(lái)的數(shù)據(jù)(也就是封包),這樣我們就可以提取到對(duì)我們有用的數(shù)據(jù)進(jìn)行修改,然后模擬服務(wù)器發(fā)給客戶端,或者模擬客戶端發(fā)送給服務(wù)器,這樣就可以實(shí)現(xiàn)我們修改游戲的目的了。 目前除了修改游戲封包來(lái)實(shí)現(xiàn)修改游戲的目的,我們也可以修改客戶端的有關(guān)程序來(lái)達(dá)到我們的要求。我們知道目前各個(gè)服務(wù)器的運(yùn)算能力是有限的,特別在游戲中,游戲服務(wù)器要計(jì)算游戲中所有玩家的狀況幾乎是不可能的,所以有一些運(yùn)算還是要依靠我們客戶端來(lái)完成,這樣又給了我們修改游戲提供了一些便利。比如我們可以通過(guò)將客戶端程序脫殼來(lái)發(fā)現(xiàn)一些程序的判斷分支,通過(guò)跟蹤調(diào)試我們可以把一些對(duì)我們不利的判斷去掉,以此來(lái)滿足我們修改游戲的需求。?
? ? ??
在下幾個(gè)章節(jié)中,我們將給大家講述封包的概念,和修改跟蹤客戶端的有關(guān)知識(shí)。大家準(zhǔn)備好了嗎?
游戲數(shù)據(jù)格式和存儲(chǔ):
? ? ? 在進(jìn)行我們的工作之前,我們需要掌握一些關(guān)于計(jì)算機(jī)中儲(chǔ)存數(shù)據(jù)方式的知識(shí)和游戲中儲(chǔ)存數(shù)據(jù)的特點(diǎn)。本章節(jié)是提供給菜鳥(niǎo)級(jí)的玩家看的,如果你是高手就可以跳過(guò)了,呵呵! 如果,你想成為無(wú)堅(jiān)不摧的劍客,那么,這些東西就會(huì)花掉你一些時(shí)間;如果,你只想作個(gè)江湖的游客的話,那么這些東西,了解與否無(wú)關(guān)緊要。是作劍客,還是作游客,你選擇吧!
現(xiàn)在我們開(kāi)始!首先,你要知道游戲中儲(chǔ)存數(shù)據(jù)的幾種格式,這幾種格式是:字節(jié)(BYTE)、字(WORD)和雙字(DOUBLE WORD),或者說(shuō)是8位、16位和32位儲(chǔ)存方式。字節(jié)也就是8位方式能儲(chǔ)存0~255的數(shù)字;字或說(shuō)是16位儲(chǔ)存方式能儲(chǔ)存0~65535的數(shù);雙字即32位方式能儲(chǔ)存0~4294967295的數(shù)。為何要了解這些知識(shí)呢?在游戲中各種參數(shù)的最大值是不同的,有些可能100左右就夠了,比如,金庸群俠傳中的角色的等級(jí)、隨機(jī)遇敵個(gè)數(shù)等等。而有些卻需要大于255甚至大于65535,象金庸群俠傳中角色的金錢(qián)值可達(dá)到數(shù)百萬(wàn)。所以,在游戲中各種不同的數(shù)據(jù)的類(lèi)型是不一樣的。在我們修改游戲時(shí)需要尋找準(zhǔn)備修改的數(shù)據(jù)的封包,在這種時(shí)候,正確判斷數(shù)據(jù)的類(lèi)型是迅速找到正確地址的重要條件。在計(jì)算機(jī)中數(shù)據(jù)以字節(jié)為基本的儲(chǔ)存單位,每個(gè)字節(jié)被賦予一個(gè)編號(hào),以確定各自的位置。這個(gè)編號(hào)我們就稱為地址。在需要用到字或雙字時(shí),計(jì)算機(jī)用連續(xù)的兩個(gè)字節(jié)來(lái)組成一個(gè)字,連續(xù)的兩個(gè)字組成一個(gè)雙字。而一個(gè)字或雙字的地址就是它們的低位字節(jié)的地址。現(xiàn)在我們常用的Windows 9x操作系統(tǒng)中,地址是用一個(gè)32位的二進(jìn)制數(shù)表示的。而在平時(shí)我們用到內(nèi)存地址時(shí),總是用一個(gè)8位的16進(jìn)制數(shù)來(lái)表示它。 ? ?
? ? ? 二進(jìn)制和十六進(jìn)制又是怎樣一回事呢?
? ? ? 簡(jiǎn)單說(shuō)來(lái),二進(jìn)制數(shù)就是一種只有0和1兩個(gè)數(shù)碼,每滿2則進(jìn)一位的計(jì)數(shù)進(jìn)位法。同樣,16進(jìn)制就是每滿十六就進(jìn)一位的計(jì)數(shù)進(jìn)位法。16進(jìn)制有0--F十六個(gè)數(shù)字,它為表示十到十五的數(shù)字采用了A、B、C、D、E、F六個(gè)數(shù)字,它們和十進(jìn)制的對(duì)應(yīng)關(guān)系是:A對(duì)應(yīng)于10,B對(duì)應(yīng)于11,C對(duì)應(yīng)于12,D對(duì)應(yīng)于13,E對(duì)應(yīng)于14,F對(duì)應(yīng)于15。而且,16進(jìn)制數(shù)和二進(jìn)制數(shù)間有一個(gè)簡(jiǎn)單的對(duì)應(yīng)關(guān)系,那就是;四位二進(jìn)制數(shù)相當(dāng)于一位16進(jìn)制數(shù)。比如,一個(gè)四位的二進(jìn)制數(shù)1111就相當(dāng)于16進(jìn)制的F,1010就相當(dāng)于A。了解這些基礎(chǔ)知識(shí)對(duì)修改游戲有著很大的幫助,下面我就要談到這個(gè)問(wèn)題。由于在計(jì)算機(jī)中數(shù)據(jù)是以二進(jìn)制的方式儲(chǔ)存的,同時(shí)16進(jìn)制數(shù)和二進(jìn)制間的轉(zhuǎn)換關(guān)系十分簡(jiǎn)單,所以大部分的修改工具在顯示計(jì)算機(jī)中的數(shù)據(jù)時(shí)會(huì)顯示16進(jìn)制的代碼,而且在你修改時(shí)也需要輸入16進(jìn)制的數(shù)字。你清楚了吧?在游戲中看到的數(shù)據(jù)可都是十進(jìn)制的,在要尋找并修改參數(shù)的值時(shí),可以使用Windows提供的計(jì)算器來(lái)進(jìn)行十進(jìn)制和16進(jìn)制的換算,我們可以在開(kāi)始菜單里的程序組中的附件中找到它。現(xiàn)在要了解的知識(shí)也差不多了!不過(guò),有個(gè)問(wèn)題在游戲修改中是需要注意的。在計(jì)算機(jī)中數(shù)據(jù)的儲(chǔ)存方式一般是低位數(shù)儲(chǔ)存在低位字節(jié),高位數(shù)儲(chǔ)存在高位字節(jié)。比如,十進(jìn)制數(shù)41715轉(zhuǎn)換為16進(jìn)制的數(shù)為A2F3,但在計(jì)算機(jī)中這個(gè)數(shù)被存為F3A2。 ? ? ?看了以上內(nèi)容大家對(duì)數(shù)據(jù)的存貯和數(shù)據(jù)的對(duì)應(yīng)關(guān)系都了解了嗎??
? ? ? 好了,接下來(lái)我們要告訴大家在游戲中,封包到底是怎么一回事了,來(lái)!大家把袖口卷起來(lái),讓我們來(lái)干活吧!
二:什么是封包?
? ? ? 怎么截獲一個(gè)游戲的封包? 怎么去檢查游戲服務(wù)器的ip地址和端口號(hào)?Internet用戶使用的各種信息服務(wù),其通訊的信息最終均可以歸結(jié)為以IP包為單位的信息傳送,IP包除了包括要傳送的數(shù)據(jù)信息外,還包含有信息要發(fā)送到的目的IP地址、信息發(fā)送的源IP地址、以及一些相關(guān)的控制信息。當(dāng)一臺(tái)路由器收到一個(gè)IP數(shù)據(jù)包時(shí),它將根據(jù)數(shù)據(jù)包中的目的IP地址項(xiàng)查找路由表,根據(jù)查找的結(jié)果將此IP數(shù)據(jù)包送往對(duì)應(yīng)端口。下一臺(tái)IP路由器收到此數(shù)據(jù)包后繼續(xù)轉(zhuǎn)發(fā),直至發(fā)到目的地。路由器之間可以通過(guò)路由協(xié)議來(lái)進(jìn)行路由信息的交換,從而更新路由表。但是您仔細(xì)看,您的名字在每個(gè)封包中并不是出現(xiàn)在相同的位置上- 在第2個(gè)封包里,名字是出現(xiàn)在第4個(gè)位置上 - 在第4個(gè)封包里,名字是出現(xiàn)在第6個(gè)位置上在這種情況下,您就需要使用ADVANCED MODE - 您在搜尋列﹝SEARCH﹞填上:53 68 61 64 6F 77 請(qǐng)務(wù)必從位置1開(kāi)始填﹞ - 您想要從原來(lái)名字Shadow的第一個(gè)字母開(kāi)始置換新名字,因此您要選擇從數(shù)值被發(fā)現(xiàn)的位置開(kāi)始替代連續(xù)數(shù)值﹝from the position of the chain found﹞。 - 現(xiàn)在,在修改列﹝MODIFY﹞000的位置填上:6D 6F 6F 6E 20 20 ﹝此為相對(duì)應(yīng)位置,也就是從原來(lái)搜尋欄的+001位置開(kāi)始遞換﹞ - 如果您想從封包的第一個(gè)位置就修改數(shù)值,請(qǐng)選擇﹝from the beginning of the packet﹞了解一點(diǎn)TCP/IP協(xié)議常識(shí)的人都知道,互聯(lián)網(wǎng)是將信息數(shù)據(jù)打包之后再傳送出去的。每個(gè)數(shù)據(jù)包分為頭部信息和數(shù)據(jù)信息兩部分。頭部信息包括數(shù)據(jù)包的發(fā)送地址和到達(dá)地址等。數(shù)據(jù)信息包括我們?cè)谟螒蛑邢嚓P(guān)操作的各項(xiàng)信息。那么在做截獲封包的過(guò)程之前我們先要知道游戲服務(wù)器的IP地址和端口號(hào)等各種信息,實(shí)際上最簡(jiǎn)單的是看看我們游戲目錄下,是否有一個(gè)SERVER.INI的配置文件,這個(gè)文件里你可以查看到個(gè)游戲服務(wù)器的IP地址,比如金庸群俠傳就是如此,那么除了這個(gè)我們還可以在DOS下使用NETSTAT這個(gè)命令,NETSTAT命令的功能是顯示網(wǎng)絡(luò)連接、路由表和網(wǎng)絡(luò)接口信息,可以讓用戶得知目前都有哪些網(wǎng)絡(luò)連接正在運(yùn)作。或者你可以使用木馬客星等工具來(lái)查看網(wǎng)絡(luò)連接。工具是很多的,看你喜歡用哪一種了。
? ? ? NETSTAT命令的一般格式為: NETSTAT [選項(xiàng)]
? ? ? 命令中各選項(xiàng)的含義如下: -a 顯示所有socket,包括正在監(jiān)聽(tīng)的。 -c 每隔1秒就重新顯示一遍,直到用戶中斷它。 -i?
? ? ? 顯示所有網(wǎng)絡(luò)接口的信息。 -n 以網(wǎng)絡(luò)IP地址代替名稱,顯示出網(wǎng)絡(luò)連接情形。 -r 顯示核心路由表,格式同"route -e"。 -t?
? ? ? 顯示TCP協(xié)議的連接情況。 -u 顯示UDP協(xié)議的連接情況。 -v 顯示正在進(jìn)行的工作。
三:怎么來(lái)分析我們截獲的封包?
? ? ? 首先我們將WPE截獲的封包保存為文本文件,然后打開(kāi)它,這時(shí)會(huì)看到如下的數(shù)據(jù)(這里我們以金庸群俠傳里PK店小二客戶端發(fā)送的數(shù)據(jù)為例來(lái)講解):
? ? ? 第一個(gè)文件:?
? ? ? SEND-> 0000 E6 56 0D 22 7E 6B E4 17 13 13 12 13 12 13 67 1B?
? ? ? SEND-> 0010 17 12 DD 34 12 12 12 12 17 12 0E 12 12 12 9B?
? ? ? SEND-> 0000 E6 56 1E F1 29 06 17 12 3B 0E 17 1A?
? ? ? SEND-> 0000 E6 56 1B C0 68 12 12 12 5A?
? ? ? SEND-> 0000 E6 56 02 C8 13 C9 7E 6B E4 17 10 35 27 13 12 12?
? ? ? SEND-> 0000 E6 56 17 C9 12
? ? ? 第二個(gè)文件:?
? ? ? SEND-> 0000 83 33 68 47 1B 0E 81 72 76 76 77 76 77 76 02 7E?
? ? ? SEND-> 0010 72 77 07 1C 77 77 77 77 72 77 72 77 77 77 6D?
? ? ? SEND-> 0000 83 33 7B 94 4C 63 72 77 5E 6B 72 F3?
? ? ? SEND-> 0000 83 33 7E A5 21 77 77 77 3F?
? ? ? SEND-> 0000 83 33 67 AD 76 CF 1B 0E 81 72 75 50 42 76 77 77?
? ? ? SEND-> 0000 83 33 72 AC 77
? ? ? 我們發(fā)現(xiàn)兩次PK店小二的數(shù)據(jù)格式一樣,但是內(nèi)容卻不相同,我們是PK的同一個(gè)NPC,為什么會(huì)不同呢??
? ? ? 原來(lái)金庸群俠傳的封包是經(jīng)過(guò)了加密運(yùn)算才在網(wǎng)路上傳輸?shù)?#xff0c;那么我們面臨的問(wèn)題就是如何將密文解密成明文再分析了。因?yàn)橐话愕臄?shù)據(jù)包加密都是異或運(yùn)算,所以這里先講一下什么是異或。 簡(jiǎn)單的說(shuō),異或就是"相同為0,不同為1"(這是針對(duì)二進(jìn)制按位來(lái)講的),舉個(gè)例子,0001和0010異或,我們按位對(duì)比,得到異或結(jié)果是0011,計(jì)算的方法是:0001的第4位為0,0010的第4位為0,它們相同,則異或結(jié)果的第4位按照"相同為0,不同為1"的原則得到0,0001的第3位為0,0010的第3位為0,則異或結(jié)果的第3位得到0,0001的第2位為0,0010的第2位為1,則異或結(jié)果的第2位得到1,0001的第1位為1,0010的第1位為0,則異或結(jié)果的第1位得到1,組合起來(lái)就是0011。異或運(yùn)算今后會(huì)遇到很多,大家可以先熟悉熟悉,熟練了對(duì)分析很有幫助的。下面我們繼續(xù)看看上面的兩個(gè)文件,按照常理,數(shù)據(jù)包的數(shù)據(jù)不會(huì)全部都有值的,游戲開(kāi)發(fā)時(shí)會(huì)預(yù)留一些字節(jié)空間來(lái)便于日后的擴(kuò)充,也就是說(shuō)數(shù)據(jù)包里會(huì)存在一些"00"的字節(jié),觀察上面的文件,我們會(huì)發(fā)現(xiàn)文件一里很多"12",文件二里很多"77",那么這是不是代表我們說(shuō)的"00"呢?推理到這里,我們就開(kāi)始行動(dòng)吧!我們把文件一與"12"異或,文件二與"77"異或,當(dāng)然用手算很費(fèi)事,我們使用"M2M 1.0 加密封包分析工具"來(lái)計(jì)算就方便多了。得到下面的結(jié)果:第一個(gè)文件:?
? ? ? SEND-> 0000 F4 44 1F 30 6C 79 F6 05 01 01 00 01 00 01 75 09?
? ? ? SEND-> 0010 05 00 CF 26 00 00 00 00 05 00 1C 00 00 00 89?
? ? ? SEND-> 0000 F4 44 0C E3 3B 13 05 00 29 1C 05 08?
? ? ? SEND-> 0000 F4 44 09 D2 7A 00 00 00 48?
? ? ? SEND-> 0000 F4 44 10 DA 01 DB 6C 79 F6 05 02 27 35 01 00 00
? ? ? SEND-> 0000 F4 44 05 DB 00
? ? ? 第二個(gè)文件:?
? ? ? SEND-> 0000 F4 44 1F 30 6C 79 F6 05 01 01 00 01 00 01 75 09?
? ? ? SEND-> 0010 05 00 70 6B 00 00 00 00 05 00 05 00 00 00 1A?
? ? ? SEND-> 0000 F4 44 0C E3 3B 13 05 00 29 1C 05 84?
? ? ? SEND-> 0000 F4 44 09 D2 56 00 00 00 48?
? ? ? SEND-> 0000 F4 44 10 DA 01 B8 6C 79 F6 05 02 27 35 01 00 00?
? ? ? SEND-> 0000 F4 44 05 DB 00
? ? ? 哈,這一下兩個(gè)文件大部分都一樣啦,說(shuō)明我們的推理是正確的,上面就是我們需要的明文!接下來(lái)就是搞清楚一些關(guān)鍵的字節(jié)所代表的含義,這就需要截獲大量的數(shù)據(jù)來(lái)分析。首先我們會(huì)發(fā)現(xiàn)每個(gè)數(shù)據(jù)包都是"F4 44"開(kāi)頭,第3個(gè)字節(jié)是變化的,但是變化很有規(guī)律。我們來(lái)看看各個(gè)包的長(zhǎng)度,發(fā)現(xiàn)什么沒(méi)有?對(duì)了,第3個(gè)字節(jié)就是包的長(zhǎng)度!通過(guò)截獲大量的數(shù)據(jù)包,我們判斷第4個(gè)字節(jié)代表指令,也就是說(shuō)客戶端告訴服務(wù)器進(jìn)行的是什么操作。例如向服務(wù)器請(qǐng)求戰(zhàn)斗指令為"30",戰(zhàn)斗中移動(dòng)指令為"D4"等。 接下來(lái),我們就需要分析一下上面第一個(gè)包"F4 44 1F 30 6C 79 F6 05 01 01 00 01 00 01 75 09 05 00 CF 26 00 00 00 00 05 00 1C 00 00 00 89",在這個(gè)包里包含什么信息呢?應(yīng)該有通知服務(wù)器你PK的哪個(gè)NPC吧,我們就先來(lái)找找這個(gè)店小二的代碼在什么地方。我們?cè)貾K一個(gè)小嘍羅(就是大理客棧外的那個(gè)咯): SEND-> 0000 F4 44 1F 30 D4 75 F6 05 01 01 00 01 00 01 75 09 SEND-> 0010 05 00 8A 19 00 00 00 00 11 00 02 00 00 00 C0 我們根據(jù)常理分析,游戲里的NPC種類(lèi)雖然不會(huì)超過(guò)65535(FFFF),但開(kāi)發(fā)時(shí)不會(huì)把自己限制在字的范圍,那樣不利于游戲的擴(kuò)充,所以我們?cè)陔p字里看看。通過(guò)"店小二"和"小嘍羅"兩個(gè)包的對(duì)比,我們把目標(biāo)放在"6C 79 F6 05"和"CF 26 00 00"上。(對(duì)比一下很容易的,但你不能太遲鈍咯,呵呵)我們?cè)倏纯春竺娴陌?#xff0c;在后面的包里應(yīng)該還會(huì)出現(xiàn)NPC的代碼,比如移動(dòng)的包,游戲允許觀戰(zhàn),服務(wù)器必然需要知道NPC的移動(dòng)坐標(biāo),再?gòu)V播給觀戰(zhàn)的其他玩家。在后面第4個(gè)包"SEND-> 0000 F4 44 10 DA 01 DB 6C 79 F6 05 02 27 35 01 00 00"里我們又看到了"6C 79 F6 05",初步斷定店小二的代碼就是它了! (
這分析里邊包含了很多工作的,大家可以用WPE截下數(shù)據(jù)來(lái)自己分析分析)第一個(gè)包的分析暫時(shí)就到這里(里面還有的信息我們暫時(shí)不需要完全清楚了)我們看看第4個(gè)包"SEND-> 0000 F4 44 10 DA 01 DB 6C 79 F6 05 02 27 35 01 00 00",再截獲PK黃狗的包,(狗會(huì)出來(lái)2只哦)看看包的格式: SEND-> 0000 F4 44 1A DA 02 0B 4B 7D F6 05 02 27 35 01 00 00 SEND-> 0010 EB 03 F8 05 02 27 36 01 00 00根據(jù)上面的分析,黃狗的代碼為"4B 7D F6 00040011),不過(guò)兩只黃狗服務(wù)器怎樣分辨呢?看看"EB 03 F8 05"(100140011),是上一個(gè)代碼加上100000,呵呵,這樣服務(wù)器就可以認(rèn)出兩只黃狗了。我們?cè)偻ㄟ^(guò)野外遇敵截獲的數(shù)據(jù)包來(lái)證實(shí),果然如此。 那么,這個(gè)包的格式應(yīng)該比較清楚了:第3個(gè)字節(jié)為包的長(zhǎng)度,"DA"為指令,第5個(gè)字節(jié)為NPC個(gè)數(shù),從第7個(gè)字節(jié)開(kāi)始的10個(gè)字節(jié)代表一個(gè)NPC的信息,多一個(gè)NPC就多10個(gè)字節(jié)來(lái)表示。大家如果玩過(guò)網(wǎng)金,必然知道隨機(jī)遇敵有時(shí)會(huì)出現(xiàn)增援,我們就利用游戲這個(gè)增援來(lái)讓每次戰(zhàn)斗都會(huì)出現(xiàn)增援的NPC吧。通過(guò)在戰(zhàn)斗中出現(xiàn)增援截獲的數(shù)據(jù)包,我們會(huì)發(fā)現(xiàn)服務(wù)器端發(fā)送了這樣一個(gè)包: F4 44 12 E9 EB 03 F8 05 02 00 00 03 00 00 00 00 00 00 第5-第8個(gè)字節(jié)為增援NPC的代碼(這里我們就簡(jiǎn)單的以黃狗的代碼來(lái)舉例)。 那么,我們就利用單機(jī)代理技術(shù)來(lái)同時(shí)欺騙客戶端和服務(wù)器吧!好了,呼叫NPC的工作到這里算是完成了一小半,接下來(lái)的事情,怎樣修改封包和發(fā)送封包,我們下節(jié)繼續(xù)講解吧。
四:怎么冒充"客戶端"向"服務(wù)器"發(fā)我們需要的封包?
? ? ? 這里我們需要使用一個(gè)工具,它位于客戶端和服務(wù)器端之間,它的工作就是進(jìn)行數(shù)據(jù)包的接收和轉(zhuǎn)發(fā),這個(gè)工具我們稱為代理。如果代理的工作單純就是接收和轉(zhuǎn)發(fā)的話,這就毫無(wú)意義了,但是請(qǐng)注意:所有的數(shù)據(jù)包都要通過(guò)它來(lái)傳輸,這里的意義就重大了。我們可以分析接收到的數(shù)據(jù)包,或者直接轉(zhuǎn)發(fā),或者修改后轉(zhuǎn)發(fā),或者壓住不轉(zhuǎn)發(fā),甚至偽造我們需要的封包來(lái)發(fā)送。下面我們繼續(xù)講怎樣來(lái)同時(shí)欺騙服務(wù)器和客戶端,也就是修改封包和偽造封包。 通過(guò)我們上節(jié)的分析,我們已經(jīng)知道了打多個(gè)NPC的封包格式,那么我們就動(dòng)手吧!首先我們要查找客戶端發(fā)送的包,找到戰(zhàn)斗的特征,就是請(qǐng)求戰(zhàn)斗的第1個(gè)包,我們找"F4 44 1F 30"這個(gè)特征,這是不會(huì)改變的,當(dāng)然是要解密后來(lái)查找哦。 找到后,表示客戶端在向服務(wù)器請(qǐng)求戰(zhàn)斗,我們不動(dòng)這個(gè)包,轉(zhuǎn)發(fā)。 繼續(xù)向下查找,這時(shí)需要查找的特征碼不太好辦,我們先查找"DA",這是客戶端發(fā)送NPC信息的數(shù)據(jù)包的指令,那么可能其他包也有"DA",沒(méi)關(guān)系,我們看前3個(gè)字節(jié)有沒(méi)有"F4 44"就行了。找到后,我們的工作就開(kāi)始了!我們確定要打的NPC數(shù)量。這個(gè)數(shù)量不能很大,原因在于網(wǎng)金的封包長(zhǎng)度用一個(gè)字節(jié)表示,那么一個(gè)包可以有255個(gè)字節(jié),我們上面分析過(guò),增加一個(gè)NPC要增加10個(gè)字節(jié),所以大家算算就知道,打20個(gè)NPC比較合適。然后我們要把客戶端原來(lái)的NPC代碼分析計(jì)算出來(lái),因?yàn)樵黾拥腘PC代碼要加上100000哦。再把我們?cè)黾拥腘PC代碼計(jì)算出來(lái),并且組合成新的封包,注意代表包長(zhǎng)度的字節(jié)要修改啊,然后轉(zhuǎn)發(fā)到服務(wù)器,這一步在編寫(xiě)程序的時(shí)候要注意算法,不要造成較大延遲。 上面我們欺騙服務(wù)器端完成了,欺騙客戶端就簡(jiǎn)單了,^-^發(fā)送了上面的封包后,我們根據(jù)新增NPC代碼構(gòu)造封包馬上發(fā)給客戶端,格式就是"F4 44 12 E9 NPC代碼 02 00 00 03 00 00 00 00 00 00",把每個(gè)新增的NPC都構(gòu)造這樣一個(gè)包,按順序連在一起發(fā)送給客戶端,客戶端也就被我們騙過(guò)了,很簡(jiǎn)單吧。以后戰(zhàn)斗中其他的事我們就不
管了,盡情地開(kāi)打吧,呵呵。
? ? ? ?上面講的需要一定的編程基礎(chǔ),但是不難,即使你不會(huì)編程,相信你繼續(xù)看下去就會(huì)有收獲了。
五:怎么用計(jì)算機(jī)語(yǔ)言去寫(xiě)一個(gè)單機(jī)代理?
? ? ? 在上一章,我們已經(jīng)對(duì)于代理的原理進(jìn)行了講解,大家對(duì)于代理已經(jīng)有了一個(gè)初步的認(rèn)識(shí),現(xiàn)在我教大家如何用計(jì)算機(jī)語(yǔ)言編寫(xiě)一個(gè)自己的代理,我們考慮到簡(jiǎn)單明了,我們選用VB,因?yàn)橛肰B編寫(xiě)代理只需要很少的代碼
。
? ? ? 代碼如下:
? ? ? Private Sub
? ? ? Form_Load()?
? ? ? DaiLi.LocalPort = "1234"?
? ? ? Server.RemotePort = "1234"
? ? ? Server.RemoteHost = "211.100.20.26"
? ? ? DaiLi.Listen
? ? ? End Sub
? ? ? Private Sub
? ? ? DaiLi_ConnectionRequest(ByVal requestID As Long)?
? ? ? Server.Connect
? ? ? Client.Accept
? ? ? requestID
? ? ? End Sub
? ? ? Private Sub?
? ? ? Client_DataArrival(ByVal bytesTotal As Long)?
? ? ? Dim ClientToServer() As Byte Client.GetData
? ? ? ClientToServer Server.SendData?
? ? ? ClientToServer
? ? ? End Sub
? ? ? Private Sub Server_DataArrival(ByVal bytesTotal As Long) Dim?
? ? ? ServerToClient() As Byte Server.GetData ServerToClient Client.SendData?
? ? ? ServerToClient
? ? ? End Sub
? ? ? Form_Load()這個(gè)過(guò)程表示在程序啟動(dòng)的時(shí)候要做的一些初始化操作。 DaiLi.LocalPort = "1234" 設(shè)定監(jiān)聽(tīng)端口Server.RemotePort = "1234" 設(shè)定象游戲服務(wù)器連接的端口(和監(jiān)聽(tīng)端口是相同的)Server.RemoteHost = ? "211.100.20.26" 設(shè)定游戲服務(wù)器的IP地址 DaiLi.Listen 監(jiān)聽(tīng)本地的連接請(qǐng)求這時(shí)你只要將游戲的服務(wù)器列表的IP改成127.0.0.1,那么游戲的客戶端程序就會(huì)來(lái)連接我們的代理,我們的代理會(huì)調(diào)用如下的過(guò)程: Private Sub DaiLi_ConnectionRequest(ByVal requestID As Long) Server.Connect ?代理客戶端向服務(wù)器連接 Client.Accept requestID 接受客戶端的連接請(qǐng)求 End Sub當(dāng)客戶端向服務(wù)器發(fā)送數(shù)據(jù)時(shí),就會(huì)調(diào)用下邊的過(guò)程 Private Sub Client_DataArrival(ByVal bytesTotal As Long) Dim ClientToServer() As Byte 變量定義,請(qǐng)求了一個(gè)用于存放數(shù)據(jù)的空間 Client.GetData ClientToServer 客戶端的連接接收這些數(shù)據(jù) 在這里我們可以添加自己的代碼,對(duì)封包進(jìn)行修改,然后再發(fā)向服務(wù)器。Server.SendData ClientToServer 服務(wù)器的連接把這些數(shù)據(jù)發(fā)向服務(wù)器 End Sub當(dāng)服務(wù)器發(fā)送數(shù)據(jù)給客戶端時(shí),會(huì)調(diào)用下邊的過(guò)程 Private Sub Server_DataArrival(ByVal bytesTotal As Long) Dim ServerToClient() As Byte 變量定義,請(qǐng)求了一個(gè)用于存放數(shù)據(jù)的空間 Server.GetData ServerToClient 服務(wù)器連接接收數(shù)據(jù) 在這里我們可以添加自己的代碼,對(duì)封包進(jìn)行修改,然后再發(fā)給客戶端。Client.SendData ServerToClient End Sub用其他語(yǔ)言編寫(xiě)基本的原理也是差不多的,不過(guò)可能稍微要麻煩一些,因?yàn)閂B本身有一個(gè)MSWINSCK.OCX控件,這個(gè)控件封裝了WINDOWS的網(wǎng)絡(luò)操作,而且接口很簡(jiǎn)單,推薦大家使用。
六:如果單機(jī)代理被封,我們?cè)趺蠢玫讓拥募夹g(shù)來(lái)接管游戲的發(fā)包?
? ? ? 在WINDOWS系統(tǒng)中,網(wǎng)絡(luò)通訊的任務(wù)是由一個(gè)叫WSOCK32.DLL(在SYSTEM目錄下)來(lái)完成的,每當(dāng)游戲被運(yùn)行時(shí),他都會(huì)自動(dòng)的去調(diào)用這個(gè)動(dòng)態(tài)連接庫(kù),因?yàn)樵赪INDOWS系統(tǒng)中對(duì)于文件的搜索順序是程序目錄>系統(tǒng)目錄>路徑中設(shè)置的目錄,所以我們就有機(jī)會(huì)替換掉系統(tǒng)的WSOCK32.DLL使的游戲調(diào)用我們的WSOCK32.DLL,這樣我們就有了對(duì)于游戲封包絕對(duì)的控制權(quán),有人問(wèn):"我們應(yīng)該怎么做呢?",我們只要自己編寫(xiě)一個(gè)WSOCK32.DLL放到游戲的目錄下,就OK了,當(dāng)然讓我們完全自己去編寫(xiě)一個(gè)WSOCK32.DLL是不太現(xiàn)實(shí)的,因?yàn)楸旧砭W(wǎng)絡(luò)通訊要處理很多更底層的東西,比如說(shuō)從網(wǎng)卡讀取BIT流,所以我們選擇由我們的WSOCK32.DLL去調(diào)用系統(tǒng)的WSOCK32.DLL來(lái)完成這個(gè)功能。
? ? ? WSOCK32.DLL有很多的輸出函數(shù),函數(shù)如下:
? ? ? __WSAFDIsSet accept AcceptEx Arecv Asend bind?
? ? ? closesocket closesockinfo connect dn_expand EnumProtocolsA EnumProtocolsW?
? ? ? GetAcceptExSockaddrs GetAddressByNameA GetAddressByNameW gethostbyaddr?
? ? ? gethostbyname gethostname GetNameByTypeA GetNameByTypeW getnetbyname?
? ? ? getpeername getprotobyname getprotobynumber getservbyname getservbyport?
? ? ? GetServiceA GetServiceW getsockname getsockopt GetTypeByNameA?
? ? ? GetTypeByNameW htonl htons inet_addr inet_network inet_ntoa ioctlsocket?
? ? ? listen MigrateWinsockConfiguration NPLoadNameSpaces NSPStartup ntohl ntohs?
? ? ? rcmd recv recvfrom rexec rresvport s_perror select send sendto sethostname?
? ? ? SetServiceA SetServiceW setsockopt shutdown socket TransmitFile WEP?
? ? ? WSAAsyncGetHostByAddr WSAAsyncGetHostByName WSAAsyncGetProtoByName?
? ? ? WSAAsyncGetProtoByNumber WSAAsyncGetServByName WSAAsyncGetServByPort?
? ? ? WSAAsyncSelect WSACancelAsyncRequest WSACancelBlockingCall WSACleanup?
? ? ? WSAGetLastError WSAIsBlocking WSApSetPostRoutine WSARecvEx?
? ? ? WSASetBlockingHook WSASetLastError WSAStartup WSAUnhookBlockingHook?
? ? ? WsControl WSHEnumProtocols
在這里,不是所有的函數(shù)都要修改,因?yàn)槲覀冎魂P(guān)心發(fā)送和接收的封包,所以我們只要修改send 和recv兩個(gè)函數(shù),前者是發(fā)送封包的后者是接收封包的,我們?cè)谶@兩個(gè)函數(shù)的處理中加入我們自己的代碼,來(lái)完成封包的辨認(rèn),修改以
及轉(zhuǎn)發(fā)等功能。
七:怎么來(lái)分析客戶端的有關(guān)資料?
? ? ? 自己作外掛,大多時(shí)候要分析封包,不過(guò)因?yàn)橛械墓δ苁怯煽蛻舳藖?lái)辨別的,所以分析客戶端的程序同樣也很重要,分析客戶端首先要求你能看懂匯編指令(只要"看懂",要求很低的),其次是要能夠熟練的運(yùn)用一些工
具,然后能剩下的也就是運(yùn)氣和游戲公司的漏洞了。(哈,不是每次都能成功的啊)下邊我分步教給大家。
? ? ? 第一章 8086匯編指令
? ? ? 注:AX,BX,CX...,EAX,EBX,ECX...這些都是CPU用來(lái)存儲(chǔ)數(shù)據(jù)的地方。
一、數(shù)據(jù)傳輸指令 作用:它們?cè)诖尜A器和寄存器、寄存器和輸入輸出端口之間傳送數(shù)據(jù).?
1. 通用數(shù)據(jù)傳送指令. MOV 傳送字或字節(jié). MOVSX先符號(hào)擴(kuò)展,再傳送. MOVZX 先零擴(kuò)展,再傳送. PUSH 把字壓入堆棧. POP 把字彈出堆棧. PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次壓入堆棧. POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次彈出堆棧. PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次壓入堆棧. POP把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次彈出堆棧. BSWAP 交換32位寄存器里字節(jié)的順序 XCHG 交換字或字節(jié).(至少有一個(gè)操作數(shù)為寄存器,段寄存器不可作為操作數(shù)) CMPXCHG 比較并交換操作數(shù).( 第二個(gè)操作數(shù)必須為累加器AL/AX/EAX ) XADD先交換再累加.( 結(jié)果在第一個(gè)操作數(shù)里 ) XLAT 字節(jié)查表轉(zhuǎn)換. BX 指向一張 256 字節(jié)的表的起點(diǎn), AL 為表的索引值 (0-255,即0-FFH); 返回 AL 為查表結(jié)果. ( [BX+AL]->AL ) ? ?
2. 輸入輸出端口傳送指令. IN I/O端口輸入. ( 語(yǔ)法: IN 累加器, {端口號(hào)│DX} ) OUT I/O端口輸出. ( 語(yǔ)法: OUT 端口號(hào)│DX},累加器 ) 輸入輸出端口由立即方式指定時(shí), 其范圍是 0-255; 由寄存器 DX 指定時(shí),其范圍是?
0-65535.
3. 目的地址傳送指令. LEA 裝入有效地址. 例: LEA DX,string ;把偏移地址存到DX. LDS?
? ? ? 傳送目標(biāo)指針,把指針內(nèi)容裝入DS. 例: LDS SI,string ;把段地址:偏移地址存到DS:SI. LES?
? ? ? 傳送目標(biāo)指針,把指針內(nèi)容裝入ES. 例: LES DI,string ;把段地址:偏移地址存到ES:DI. LFS?
? ? ? 傳送目標(biāo)指針,把指針內(nèi)容裝入FS. 例: LFS DI,string ;把段地址:偏移地址存到FS:DI. LGS?
? ? ? 傳送目標(biāo)指針,把指針內(nèi)容裝入GS. 例: LGS DI,string ;把段地址:偏移地址存到GS:DI. LSS?
? ? ? 傳送目標(biāo)指針,把指針內(nèi)容裝入SS. 例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
4. 標(biāo)志傳送指令. LAHF 標(biāo)志寄存器傳送,把標(biāo)志裝入AH. SAHF 標(biāo)志寄存器傳送,把AH內(nèi)容裝入標(biāo)志寄存器. PUSHF 標(biāo)志入棧. POPF 標(biāo)志出棧. PUSHD 32位標(biāo)志入棧. POPD 32位標(biāo)志出棧.
二、算術(shù)運(yùn)算指令 ADD 加法. ADC 帶進(jìn)位加法. INC 加 1. AAA 加法的ASCII碼調(diào)整. DAA 加法的十進(jìn)制調(diào)整. SUB減法. SBB 帶借位減法. DEC 減 1. NEC 求反(以 0 減之). CMP 比較.(兩操作數(shù)作減法,僅修改標(biāo)志位,不回送結(jié)果). AAS減法的ASCII碼調(diào)整. DAS 減法的十進(jìn)制調(diào)整. MUL 無(wú)符號(hào)乘法. IMUL 整數(shù)乘法. 以上兩條,結(jié)果回送AH和AL(字節(jié)運(yùn)算),或DX和AX(字運(yùn)算), AAM 乘法的ASCII碼調(diào)整. DIV 無(wú)符號(hào)除法. IDIV 整數(shù)除法. ?以上兩條,結(jié)果回送: 商回送AL,余數(shù)回送AH, (字節(jié)運(yùn)算); 或 商回送AX,余數(shù)回送DX, (字運(yùn)算). AAD 除法的ASCII碼調(diào)整. CBW 字節(jié)轉(zhuǎn)換為字. (把AL中字節(jié)的符號(hào)擴(kuò)展到AH中去) CWD 字轉(zhuǎn)換為雙字. (把AX中的字的符號(hào)擴(kuò)展到DX中去)CWDE 字轉(zhuǎn)換為雙字. (把AX中的字符號(hào)擴(kuò)展到EAX中去) CDQ 雙字?jǐn)U展. (把EAX中的字的符號(hào)擴(kuò)展到EDX中去)三、邏輯運(yùn)算指令 AND 與運(yùn)算. OR 或運(yùn)算. XOR 異或運(yùn)算. NOT 取反. TEST 測(cè)試.(兩操作數(shù)作與運(yùn)算,僅修改標(biāo)志位,不回送結(jié)果). SHL 邏輯左移. SAL 算術(shù)左移.(=SHL) SHR 邏輯右移. SAR 算術(shù)右移.(=SHR) ROL 循環(huán)左移. ROR 循環(huán)右移. RCL 通過(guò)進(jìn)位的循環(huán)左移. RCR 通過(guò)進(jìn)位的循環(huán)右移. 以上八種移位指令,其移位次數(shù)可達(dá)255次. 移位一次時(shí), 可直接用操作碼. 如 SHL AX,1. 移位>1次時(shí), 則由寄存器CL給出移位次數(shù). 如 MOV CL,04 SHL?
AX,CL
四、串指令 DS:SI 源串段寄存器 :源串變址. ES:DI 目標(biāo)串段寄存器:目標(biāo)串變址. CX 重復(fù)次數(shù)計(jì)數(shù)器. AL/AX 掃描值. D標(biāo)志 0表示重復(fù)操作中SI和DI應(yīng)自動(dòng)增量; 1表示應(yīng)自動(dòng)減量. Z標(biāo)志 用來(lái)控制掃描或比較操作的結(jié)束. MOVS 串傳送. ( MOVSB 傳送字符. MOVSW 傳送字. MOVSD 傳送雙字. ) CMPS 串比較. ( CMPSB 比較字符. CMPSW 比較字. ) SCAS 串掃描. 把AL或AX的內(nèi)容與目標(biāo)串作比較,比較結(jié)果反映在標(biāo)志位. LODS 裝入串. 把源串中的元素(字或字節(jié))逐一裝入AL或AX中. ( LODSB 傳送字符. LODSW 傳送字. LODSD 傳送雙字. ) STOS 保存串. 是LODS的逆過(guò)程. REP 當(dāng)CX/ECX<>0時(shí)重復(fù). REPE/REPZ 當(dāng)ZF=1或比較結(jié)果相等,且CX/ECX<>0時(shí)重復(fù). REPNE/REPNZ 當(dāng)ZF=0或比較結(jié)果不相等,且CX/ECX<>0時(shí)重復(fù). REPC 當(dāng)CF=1且CX/ECX<>0時(shí)重復(fù). REPNC 當(dāng)CF=0且CX/ECX<>0時(shí)重復(fù).
五、程序轉(zhuǎn)移指令?
1>無(wú)條件轉(zhuǎn)移指令 (長(zhǎng)轉(zhuǎn)移) JMP 無(wú)條件轉(zhuǎn)移指令 CALL 過(guò)程調(diào)用 RET/RETF過(guò)程返回.?
2>條件轉(zhuǎn)移指令 (短轉(zhuǎn)移,-128到+127的距離內(nèi)) ( 當(dāng)且僅當(dāng)(SF XOR OF)=1時(shí),OP1循環(huán)控制指令(短轉(zhuǎn)移) LOOP CX不為零時(shí)循環(huán). LOOPE/LOOPZ CX不為零且標(biāo)志Z=1時(shí)循環(huán). LOOPNE/LOOPNZ CX不為零且標(biāo)志Z=0時(shí)循環(huán). JCXZ CX為
零時(shí)轉(zhuǎn)移. JECXZ ECX為零時(shí)轉(zhuǎn)移.?
4>中斷指令 INT 中斷指令 INTO 溢出中斷 IRET 中斷返回?
5>處理器控制指令 HLT 處理器暫停, 直到出現(xiàn)中斷或復(fù)位信號(hào)才繼續(xù). WAIT 當(dāng)芯片引線TEST為高電平時(shí)使CPU進(jìn)入等待狀態(tài). ESC 轉(zhuǎn)換到外處理器. LOCK 封鎖總線. NOP 空操作. STC 置進(jìn)位標(biāo)志位. CLC 清進(jìn)位標(biāo)志位. CMC?
進(jìn)位標(biāo)志取反. STD 置方向標(biāo)志位. CLD 清方向標(biāo)志位. STI 置中斷允許位. CLI 清中斷允許位.
六、偽指令 DW 定義字(2字節(jié)). PROC 定義過(guò)程. ENDP 過(guò)程結(jié)束. SEGMENT 定義段. ASSUME 建立段寄存器尋址. ENDS 段結(jié)束. END 程序結(jié)束. 當(dāng)然不是所有的指令都能用的上的,我在這里全部寫(xiě)出來(lái)是為了讓大家認(rèn)識(shí)一下,
方便大家以后的學(xué)習(xí),我歸納了一下常用的指令,這些指令大家一定要熟練掌握才可以啊。MOV 數(shù)據(jù)傳送指令 PUSH,POP 堆棧指令 CMP 比較指令 LEA 取地址指令 XOR 異或指令 JE,JZ,JMP...(所有的轉(zhuǎn)移指令)
一些工具的使用
? ? ? 用到的工具包括Fi2.9,Wasm8.9 ,UltraEdit
? ? ? 一、 Fi2.9?
? ? ? 因?yàn)楝F(xiàn)在軟件為了保護(hù),另外也為了減少程序的大小,都采用了加殼技術(shù)。有人問(wèn)了"殼是什么呢",在自然界中,我想大家對(duì)"殼"這東西應(yīng)該都不會(huì)陌生了,植物用它來(lái)保護(hù)種子,動(dòng)物用它來(lái)保護(hù)身體等等。同樣,在一些計(jì)算機(jī)軟件里也有一段專門(mén)負(fù)責(zé)保護(hù)軟件不被非法修改或反編譯的程序。它們一般都是先于程序運(yùn)行,拿到控制權(quán),然后完成它們保護(hù)軟件的任務(wù)。就像動(dòng)植物的殼一般都是在身體外面一樣理所當(dāng)然。由于這段程序和自然界的殼在功能上有很多相同的地方,基于命名的規(guī)則,大家就把這樣的程序稱為"殼"了。 現(xiàn)在我們已經(jīng)知道"殼"是用來(lái)保護(hù)程序的,那我們要分析游戲程序,必須先把他的這層殼退掉,我們稱之為"脫殼",這個(gè)很容易的,因?yàn)楝F(xiàn)在網(wǎng)上有很多的脫殼軟件可以脫殼,不過(guò)在脫殼前我們必須先知道程序用什么加的"殼",Fi就是這樣一個(gè)軟件,操作很簡(jiǎn)單,將要分析的軟件和Fi放在同一個(gè)目錄,然后直接運(yùn)行Fi,在按回車(chē)就OK了。?
? ? ? 二、Wasm8.9 這是一個(gè)用來(lái)反匯編程序的軟件(反匯編,就是把機(jī)器代碼轉(zhuǎn)變?yōu)閰R編代碼)。操作很簡(jiǎn)單, 圖一(打開(kāi)文件) 圖二(簡(jiǎn)單介紹)首先打開(kāi)文件,進(jìn)行反匯編操作,然后選擇"串式參考"找到在程序中出現(xiàn)
的內(nèi)容,定位到該地址,進(jìn)行分析,分析完成,進(jìn)行修改,加亮當(dāng)前要修改的指令,然后看"當(dāng)前指令在文件中的地址偏移",記下這個(gè)值。
? ? ? 三、UltraEdit 是一個(gè)功能強(qiáng)大的編輯軟件,能直接修改程序的16進(jìn)制指令代碼。
? ? ? 實(shí)例解析
? ? ? 下邊以金庸的隨地逃為例進(jìn)行解析。
? ? ? 首先將金庸的Loginp.exe文件和Fi放在同一個(gè)目錄,然后運(yùn)行Fi,可以看到屏幕如圖 ?
? ? ? 可以看到程序用UPX加過(guò)殼了,所以首先進(jìn)行脫殼(由于該文件用UPX加殼后進(jìn)行了修改,用現(xiàn)成的工具無(wú)法脫殼,鑒于會(huì)員當(dāng)前水平的考慮,這個(gè)文件的脫殼方法以后講給大家聽(tīng),我們直接提供一個(gè)脫過(guò)殼的文件給會(huì)員
用于會(huì)員的學(xué)習(xí)),脫過(guò)殼之后,運(yùn)行Wasm進(jìn)行反匯編,然后點(diǎn)"串式參考",找到"次處非逃離點(diǎn)"如圖
? ? ? 程序如下(請(qǐng)打開(kāi)MagicWin)
? ? ? :00616376 6681B8EC470000AD65 cmp word ptr [eax+000047EC],?
? ? ? 65AD<---此處比較是否為逃離點(diǎn) :0061637F 7577 jne 006163F8 <---不是就跳走
? ? ? * Referenced by a (U)nconditional or (C)onditional Jump at?
? ? ? Address:|:0061636D(C)|:00616381 8BC3 mov eax, ebx:00616383 E8D4D1FFFF call?
? ? ? 0061355<----一個(gè)隨機(jī)處理判斷是否逃跑成功:00616388 84C0 test al, al:0061638A 7440 je?
? ? ? 006163CC <----不成功就跳走:0061638C 66C743530600 mov [ebx+53], 0006:00616392?
? ? ? B81E000000 mov eax, 0000001E:00616397 E80CC9DEFF call 00402CA8:0061639C?
? ? ? 890424 mov dword ptr [esp], eax:0061639F DB0424 fild dword ptr?
? ? ? [esp]:006163A2 DB2DDC656100 fld tbyte ptr [006165DC]:006163A8 DEC9 fmulp?
? ? ? st(1), st(0):006163AA D80550666100 fadd dword ptr [00616650]:006163B0?
? ? ? DB2DDC656100 fld tbyte ptr [006165DC]:006163B6 DEC1 faddp st(1),?
? ? ? st(0):006163B8 DD9BF8D06500 fstp qword ptr [ebx+0065D0F8]:006163BE 9B?
? ? ? wait:006163BF C6435201 mov [ebx+52], 01:006163C3 8BC3 mov eax,?
? ? ? ebx:006163C5 E8924E0000 call 0061B25C:006163CA EB3F jmp 0061640B
? ? ? * Referenced by a (U)nconditional or (C)onditional Jump at?
? ? ? Address:|:0061638A(C)|:006163CC A11CA36700 mov eax, dword ptr?
? ? ? [0067A31C]:006163D1 8B00 mov eax, dword ptr [eax]:006163D3 33C9 xor ecx,?
? ? ? ecx
? ? ? * Possible StringData Ref from Data Obj ->"発瞞ア毖"|:006163D5 BA5C666100 mov?
? ? ? edx, 0061665C:006163DA E83D9BF7FF call 0058FF1C:006163DF 8A8368010000 mov?
? ? ? al, byte ptr [ebx+00000168]:006163E5 04F9 add al, F9:006163E7 2C02 sub al,?
? ? ? 02:006163E9 7320 jnb 0061640B:006163EB 33C9 xor ecx, ecx:006163ED 33D2 xor?
? ? ? edx, edx:006163EF B0DE mov al, DE:006163F1 E8C6AE0100 call?
? ? ? 006312BC:006163F6 EB13 jmp 0061640B
? ? ? * Referenced by a (U)nconditional or (C)onditional Jump at?
? ? ? Address:|:0061637F(C)|:006163F8 A11CA36700 mov eax, dword ptr?
? ? ? [0067A31C]:006163FD 8B00 mov eax, dword ptr [eax]:006163FF 33C9 xor ecx,?
? ? ? ecx
? ? ? * Possible StringData Ref from Data Obj ->"矪獶発瞞翴"|:00616401 BA70666100?
? ? ? mov edx, 00616670:00616406 E8119BF7FF call 0058FF1C
? ? ? * Referenced by a (U)nconditional or (C)onditional Jump at?
? ? ? Addresses:|:006163CA(U), :006163E9(C), :006163F6(U)|:0061640B B201 mov dl,?
? ? ? 01:0061640D 8BC3 mov eax, ebx:0061640F E8BCC10000 call 006225D0:00616414?
? ? ? C6836801000000 mov byte ptr [ebx+00000168], 00:0061641B E977010000 jmp?
? ? ? 00616597:00616420 888368010000 mov byte ptr [ebx+00000168], al:00616426?
? ? ? C68300D1650000 mov byte ptr [ebx+0065D100], 00:0061642D 33C9 xor ecx,?
? ? ? ecx:0061642F 33D2 xor edx, edx:00616431 B0DE mov al, DE:00616433?
? ? ? E884AE0100 call 006312BC:00616438 B201 mov dl, 01
? ? ? 所以我們只要讓上邊兩個(gè)注釋的地方都不要跳走,就可以實(shí)現(xiàn)隨時(shí)隨地逃的功能了,修改很簡(jiǎn)單,我們把上邊的兩個(gè)跳轉(zhuǎn)語(yǔ)句全部注銷(xiāo)掉就OK了,匯編語(yǔ)言里注銷(xiāo)語(yǔ)句為NOP?
? ? ? 轉(zhuǎn)為機(jī)器指令也就是90,所以修改如下
? ? ? 原文:00616376 6681B8EC470000AD65 cmp word ptr [eax+000047EC],?
? ? ? 65AD<---此處比較是否為逃離點(diǎn):0061637F 7577 jne 006163F8 <---不是就跳走
? ? ? * Referenced by a (U)nconditional or (C)onditional Jump at?
? ? ? Address:|:0061636D(C)|:00616381 8BC3 mov eax, ebx:00616383 E8D4D1FFFF call?
? ? ? 0061355<----一個(gè)隨機(jī)處理判斷是否逃跑成功:00616388 84C0 test al, al:0061638A 7440 je?
? ? ? 006163CC <----不成功就跳走
? ? ? 修改之后
? ? ? :00616376 6681B8EC470000AD65 cmp word ptr [eax+000047EC],?
? ? ? 65AD<---此處比較是否為逃離點(diǎn):0061637F 90 nop:00616380 90 nop <---不是就跳走
? ? ? * Referenced by a (U)nconditional or (C)onditional Jump at?
? ? ? Address:|:0061636D(C)|:00616381 8BC3 mov eax, ebx:00616383 E8D4D1FFFF call?
? ? ? 0061355<----一個(gè)隨機(jī)處理判斷是否逃跑成功:00616388 84C0 test al, al:0061638A 90 nop?
? ? ? :0061638B 90 nop
? ? ? 當(dāng)然我們要把修改落實(shí)到文件上的,用UltraEdit打開(kāi)脫殼后的Loginp.exe 選擇Search->Goto?
? ? ? Line/Page來(lái)到地址0x21637f 可以看到這里的兩個(gè)字節(jié)內(nèi)容為7577(jne?
? ? ? 006163f8)把兩個(gè)字節(jié)內(nèi)容改為9090,來(lái)到地址0x21638a 可以看到這里的兩個(gè)字節(jié)內(nèi)容為7440(je?
? ? ? 006163cc)把兩個(gè)字節(jié)內(nèi)容改為9090,然后保存進(jìn)入金庸游戲看看,是不是可以隨地逃了啊,:)
? ? ? 注:教程中提供的地址會(huì)隨著loginp.exe的版本的不同有所改變,教程中采用的文件為1月7號(hào)的版本,會(huì)員可以到下載去下載到,如果會(huì)員需要最新的脫殼版本我們可以提供。
? ? ?
? ? ? 做自己喜歡的!------ 明天你來(lái)自己做外掛?
? ? ? 隨著網(wǎng)絡(luò)游戲的日益火爆,很多玩家都投身到游戲中。目前很多玩家都依賴于一些游戲的外掛程序來(lái)進(jìn)行游戲。那么做一個(gè)游戲的外掛程序是否是一件很困難的事呢?回答是"否",誠(chéng)然編寫(xiě)一些程序是需要一些基本知識(shí)的,所以我們想以最簡(jiǎn)單的語(yǔ)言來(lái)給你講授編寫(xiě)外掛程序的一些技巧,一些方法,并提供給你一些基本的輔助工具,即使你是一個(gè)菜鳥(niǎo),看了我們的教程,并技巧地使用我們提供給你的工具,你完全能夠編寫(xiě)出一個(gè)完全屬于你自己的外掛。在本教程內(nèi),我們提供了金庸群俠傳,以及網(wǎng)絡(luò)三國(guó)這兩個(gè)游戲的修改實(shí)際例子,因?yàn)檫@兩款游戲都是對(duì)封包進(jìn)行過(guò)加密運(yùn)算的,如果你對(duì)這兩個(gè)游戲的修改有了一定的了解后,相信你在其他游戲中也能非常好地做出屬于自己的外掛。我們提供了金庸打增援20個(gè)NPC和網(wǎng)絡(luò)三國(guó)在PK中自動(dòng)吃藥,自動(dòng)發(fā)鏢這兩個(gè)實(shí)際的例子,讓你上手更容易。我們也會(huì)本教程內(nèi)附上這兩個(gè)軟件以提供給你使用和學(xué)習(xí)。我們會(huì)在教程內(nèi)講授給你怎么去破解封包的加密算法,怎么利用我們提供給你工具來(lái)偽造和發(fā)送封包。本教程除了文字教程外,我們還會(huì)提供金庸群俠和三國(guó)的外掛程序,另外還提供6個(gè)外掛制作工具,以供你使用。希望在以后的游戲中,每一個(gè)玩家都能夠在游戲中成長(zhǎng)起來(lái),不但游戲玩的出色,修改游戲也同樣出色,做一個(gè)真正的游戲DIY。 要想在修改游戲中做到百戰(zhàn)百勝,是需要相當(dāng)豐富的計(jì)算機(jī)知識(shí)的。有很多計(jì)算機(jī)高手就是從玩游戲,修改游戲中,逐步對(duì)計(jì)算機(jī)產(chǎn)生濃厚的興趣,逐步成長(zhǎng)起來(lái)的。不要在羨慕別人能夠做到的,因?yàn)閯e人能夠做的你也能夠!我相信你們看了本教程后,會(huì)對(duì)游戲有一個(gè)全新的認(rèn)識(shí),呵呵,因?yàn)槲沂莻€(gè)好老師!(別拿雞蛋砸我呀,救命啊!#¥%……*)?
? ? ? 不過(guò)要想從修改游戲中學(xué)到知識(shí),增加自己的計(jì)算機(jī)水平,可不能只是靠修改游戲呀!?
? ? ? 要知道,修改游戲只是一個(gè)驗(yàn)證你對(duì)你所了解的某些計(jì)算機(jī)知識(shí)的理解程度的場(chǎng)所,只能給你一些發(fā)現(xiàn)問(wèn)題、解決問(wèn)題的機(jī)會(huì),只能起到幫助你提高學(xué)習(xí)計(jì)算機(jī)的興趣的作用,而決不是學(xué)習(xí)計(jì)算機(jī)的捷徑。
一:什么叫外掛?
? ? ? 現(xiàn)在的網(wǎng)絡(luò)游戲多是基于Internet上客戶/服務(wù)器模式,服務(wù)端程序運(yùn)行在游戲服務(wù)器上,游戲的設(shè)計(jì)者在其中創(chuàng)造一個(gè)龐大的游戲空間,各地的玩家可以通過(guò)運(yùn)行客戶端程序同時(shí)登錄到游戲中。簡(jiǎn)單地說(shuō),網(wǎng)絡(luò)游戲?qū)嶋H上就是由游戲開(kāi)發(fā)商提供一個(gè)游戲環(huán)境,而玩家們就是在這個(gè)環(huán)境中相對(duì)自由和開(kāi)放地進(jìn)行游戲操作。那么既然在網(wǎng)絡(luò)游戲中有了服務(wù)器這個(gè)概念,我們以前傳統(tǒng)的修改游戲方法就顯得無(wú)能為力了。記得我們?cè)趩螜C(jī)版的游戲中,隨心所欲地通過(guò)內(nèi)存搜索來(lái)修改角色的各種屬性,這在網(wǎng)絡(luò)游戲中就沒(méi)有任何用處了。因?yàn)槲覀冊(cè)诰W(wǎng)絡(luò)游戲中所扮演角色的各種屬性及各種重要資料都存放在服務(wù)器上,在我們自己機(jī)器上(客戶端)只是顯示角色的狀態(tài),所以通過(guò)修改客戶端內(nèi)存里有關(guān)角色的各種屬性是不切實(shí)際的。那么是否我們就沒(méi)有辦法在網(wǎng)絡(luò)游戲中達(dá)到我們修改的目的?回答是"否"。我們知道Internet客戶/服務(wù)器模式的通訊一般采用TCP/IP通信協(xié)議,數(shù)據(jù)交換是通過(guò)IP數(shù)據(jù)包的傳輸來(lái)實(shí)現(xiàn)的,一般來(lái)說(shuō)我們客戶端向服務(wù)器發(fā)出某些請(qǐng)求,比如移動(dòng)、戰(zhàn)斗等指令都是通過(guò)封包的形式和服務(wù)器交換數(shù)據(jù)。那么我們把本地發(fā)出消息稱為SEND,意思就是發(fā)送數(shù)據(jù),服務(wù)器收到我們SEND的消息后,會(huì)按照既定的程序把有關(guān)的信息反饋給客戶端,比如,移動(dòng)的坐標(biāo),戰(zhàn)斗的類(lèi)型。那么我們把客戶端收到服務(wù)器發(fā)來(lái)的有關(guān)消息稱為RECV。知道了這個(gè)道理,接下來(lái)我們要做的工作就是分析客戶端和服務(wù)器之間往來(lái)的數(shù)據(jù)(也就是封包),這樣我們就可以提取到對(duì)我們有用的數(shù)據(jù)進(jìn)行修改,然后模擬服務(wù)器發(fā)給客戶端,或者模擬客戶端發(fā)送給服務(wù)器,這樣就可以實(shí)現(xiàn)我們修改游戲的目的了。 目前除了修改游戲封包來(lái)實(shí)現(xiàn)修改游戲的目的,我們也可以修改客戶端的有關(guān)程序來(lái)達(dá)到我們的要求。我們知道目前各個(gè)服務(wù)器的運(yùn)算能力是有限的,特別在游戲中,游戲服務(wù)器要計(jì)算游戲中所有玩家的狀況幾乎是不可能的,所以有一些運(yùn)算還是要依靠我們客戶端來(lái)完成,這樣又給了我們修改游戲提供了一些便利。比如我們可以通過(guò)將客戶端程序脫殼來(lái)發(fā)現(xiàn)一些程序的判斷分支,通過(guò)跟蹤調(diào)試我們可以把一些對(duì)我們不利的判斷去掉,以此來(lái)滿足我們修改游戲的需求。?
? ? ??
在下幾個(gè)章節(jié)中,我們將給大家講述封包的概念,和修改跟蹤客戶端的有關(guān)知識(shí)。大家準(zhǔn)備好了嗎?
游戲數(shù)據(jù)格式和存儲(chǔ):
? ? ? 在進(jìn)行我們的工作之前,我們需要掌握一些關(guān)于計(jì)算機(jī)中儲(chǔ)存數(shù)據(jù)方式的知識(shí)和游戲中儲(chǔ)存數(shù)據(jù)的特點(diǎn)。本章節(jié)是提供給菜鳥(niǎo)級(jí)的玩家看的,如果你是高手就可以跳過(guò)了,呵呵! 如果,你想成為無(wú)堅(jiān)不摧的劍客,那么,這些東西就會(huì)花掉你一些時(shí)間;如果,你只想作個(gè)江湖的游客的話,那么這些東西,了解與否無(wú)關(guān)緊要。是作劍客,還是作游客,你選擇吧!
現(xiàn)在我們開(kāi)始!首先,你要知道游戲中儲(chǔ)存數(shù)據(jù)的幾種格式,這幾種格式是:字節(jié)(BYTE)、字(WORD)和雙字(DOUBLE WORD),或者說(shuō)是8位、16位和32位儲(chǔ)存方式。字節(jié)也就是8位方式能儲(chǔ)存0~255的數(shù)字;字或說(shuō)是16位儲(chǔ)存方式能儲(chǔ)存0~65535的數(shù);雙字即32位方式能儲(chǔ)存0~4294967295的數(shù)。為何要了解這些知識(shí)呢?在游戲中各種參數(shù)的最大值是不同的,有些可能100左右就夠了,比如,金庸群俠傳中的角色的等級(jí)、隨機(jī)遇敵個(gè)數(shù)等等。而有些卻需要大于255甚至大于65535,象金庸群俠傳中角色的金錢(qián)值可達(dá)到數(shù)百萬(wàn)。所以,在游戲中各種不同的數(shù)據(jù)的類(lèi)型是不一樣的。在我們修改游戲時(shí)需要尋找準(zhǔn)備修改的數(shù)據(jù)的封包,在這種時(shí)候,正確判斷數(shù)據(jù)的類(lèi)型是迅速找到正確地址的重要條件。在計(jì)算機(jī)中數(shù)據(jù)以字節(jié)為基本的儲(chǔ)存單位,每個(gè)字節(jié)被賦予一個(gè)編號(hào),以確定各自的位置。這個(gè)編號(hào)我們就稱為地址。在需要用到字或雙字時(shí),計(jì)算機(jī)用連續(xù)的兩個(gè)字節(jié)來(lái)組成一個(gè)字,連續(xù)的兩個(gè)字組成一個(gè)雙字。而一個(gè)字或雙字的地址就是它們的低位字節(jié)的地址。現(xiàn)在我們常用的Windows 9x操作系統(tǒng)中,地址是用一個(gè)32位的二進(jìn)制數(shù)表示的。而在平時(shí)我們用到內(nèi)存地址時(shí),總是用一個(gè)8位的16進(jìn)制數(shù)來(lái)表示它。 ? ?
? ? ? 二進(jìn)制和十六進(jìn)制又是怎樣一回事呢?
? ? ? 簡(jiǎn)單說(shuō)來(lái),二進(jìn)制數(shù)就是一種只有0和1兩個(gè)數(shù)碼,每滿2則進(jìn)一位的計(jì)數(shù)進(jìn)位法。同樣,16進(jìn)制就是每滿十六就進(jìn)一位的計(jì)數(shù)進(jìn)位法。16進(jìn)制有0--F十六個(gè)數(shù)字,它為表示十到十五的數(shù)字采用了A、B、C、D、E、F六個(gè)數(shù)字,它們和十進(jìn)制的對(duì)應(yīng)關(guān)系是:A對(duì)應(yīng)于10,B對(duì)應(yīng)于11,C對(duì)應(yīng)于12,D對(duì)應(yīng)于13,E對(duì)應(yīng)于14,F對(duì)應(yīng)于15。而且,16進(jìn)制數(shù)和二進(jìn)制數(shù)間有一個(gè)簡(jiǎn)單的對(duì)應(yīng)關(guān)系,那就是;四位二進(jìn)制數(shù)相當(dāng)于一位16進(jìn)制數(shù)。比如,一個(gè)四位的二進(jìn)制數(shù)1111就相當(dāng)于16進(jìn)制的F,1010就相當(dāng)于A。了解這些基礎(chǔ)知識(shí)對(duì)修改游戲有著很大的幫助,下面我就要談到這個(gè)問(wèn)題。由于在計(jì)算機(jī)中數(shù)據(jù)是以二進(jìn)制的方式儲(chǔ)存的,同時(shí)16進(jìn)制數(shù)和二進(jìn)制間的轉(zhuǎn)換關(guān)系十分簡(jiǎn)單,所以大部分的修改工具在顯示計(jì)算機(jī)中的數(shù)據(jù)時(shí)會(huì)顯示16進(jìn)制的代碼,而且在你修改時(shí)也需要輸入16進(jìn)制的數(shù)字。你清楚了吧?在游戲中看到的數(shù)據(jù)可都是十進(jìn)制的,在要尋找并修改參數(shù)的值時(shí),可以使用Windows提供的計(jì)算器來(lái)進(jìn)行十進(jìn)制和16進(jìn)制的換算,我們可以在開(kāi)始菜單里的程序組中的附件中找到它。現(xiàn)在要了解的知識(shí)也差不多了!不過(guò),有個(gè)問(wèn)題在游戲修改中是需要注意的。在計(jì)算機(jī)中數(shù)據(jù)的儲(chǔ)存方式一般是低位數(shù)儲(chǔ)存在低位字節(jié),高位數(shù)儲(chǔ)存在高位字節(jié)。比如,十進(jìn)制數(shù)41715轉(zhuǎn)換為16進(jìn)制的數(shù)為A2F3,但在計(jì)算機(jī)中這個(gè)數(shù)被存為F3A2。 ? ? ?看了以上內(nèi)容大家對(duì)數(shù)據(jù)的存貯和數(shù)據(jù)的對(duì)應(yīng)關(guān)系都了解了嗎??
? ? ? 好了,接下來(lái)我們要告訴大家在游戲中,封包到底是怎么一回事了,來(lái)!大家把袖口卷起來(lái),讓我們來(lái)干活吧!
二:什么是封包?
? ? ? 怎么截獲一個(gè)游戲的封包? 怎么去檢查游戲服務(wù)器的ip地址和端口號(hào)?Internet用戶使用的各種信息服務(wù),其通訊的信息最終均可以歸結(jié)為以IP包為單位的信息傳送,IP包除了包括要傳送的數(shù)據(jù)信息外,還包含有信息要發(fā)送到的目的IP地址、信息發(fā)送的源IP地址、以及一些相關(guān)的控制信息。當(dāng)一臺(tái)路由器收到一個(gè)IP數(shù)據(jù)包時(shí),它將根據(jù)數(shù)據(jù)包中的目的IP地址項(xiàng)查找路由表,根據(jù)查找的結(jié)果將此IP數(shù)據(jù)包送往對(duì)應(yīng)端口。下一臺(tái)IP路由器收到此數(shù)據(jù)包后繼續(xù)轉(zhuǎn)發(fā),直至發(fā)到目的地。路由器之間可以通過(guò)路由協(xié)議來(lái)進(jìn)行路由信息的交換,從而更新路由表。但是您仔細(xì)看,您的名字在每個(gè)封包中并不是出現(xiàn)在相同的位置上- 在第2個(gè)封包里,名字是出現(xiàn)在第4個(gè)位置上 - 在第4個(gè)封包里,名字是出現(xiàn)在第6個(gè)位置上在這種情況下,您就需要使用ADVANCED MODE - 您在搜尋列﹝SEARCH﹞填上:53 68 61 64 6F 77 請(qǐng)務(wù)必從位置1開(kāi)始填﹞ - 您想要從原來(lái)名字Shadow的第一個(gè)字母開(kāi)始置換新名字,因此您要選擇從數(shù)值被發(fā)現(xiàn)的位置開(kāi)始替代連續(xù)數(shù)值﹝from the position of the chain found﹞。 - 現(xiàn)在,在修改列﹝MODIFY﹞000的位置填上:6D 6F 6F 6E 20 20 ﹝此為相對(duì)應(yīng)位置,也就是從原來(lái)搜尋欄的+001位置開(kāi)始遞換﹞ - 如果您想從封包的第一個(gè)位置就修改數(shù)值,請(qǐng)選擇﹝from the beginning of the packet﹞了解一點(diǎn)TCP/IP協(xié)議常識(shí)的人都知道,互聯(lián)網(wǎng)是將信息數(shù)據(jù)打包之后再傳送出去的。每個(gè)數(shù)據(jù)包分為頭部信息和數(shù)據(jù)信息兩部分。頭部信息包括數(shù)據(jù)包的發(fā)送地址和到達(dá)地址等。數(shù)據(jù)信息包括我們?cè)谟螒蛑邢嚓P(guān)操作的各項(xiàng)信息。那么在做截獲封包的過(guò)程之前我們先要知道游戲服務(wù)器的IP地址和端口號(hào)等各種信息,實(shí)際上最簡(jiǎn)單的是看看我們游戲目錄下,是否有一個(gè)SERVER.INI的配置文件,這個(gè)文件里你可以查看到個(gè)游戲服務(wù)器的IP地址,比如金庸群俠傳就是如此,那么除了這個(gè)我們還可以在DOS下使用NETSTAT這個(gè)命令,NETSTAT命令的功能是顯示網(wǎng)絡(luò)連接、路由表和網(wǎng)絡(luò)接口信息,可以讓用戶得知目前都有哪些網(wǎng)絡(luò)連接正在運(yùn)作。或者你可以使用木馬客星等工具來(lái)查看網(wǎng)絡(luò)連接。工具是很多的,看你喜歡用哪一種了。
? ? ? NETSTAT命令的一般格式為: NETSTAT [選項(xiàng)]
? ? ? 命令中各選項(xiàng)的含義如下: -a 顯示所有socket,包括正在監(jiān)聽(tīng)的。 -c 每隔1秒就重新顯示一遍,直到用戶中斷它。 -i?
? ? ? 顯示所有網(wǎng)絡(luò)接口的信息。 -n 以網(wǎng)絡(luò)IP地址代替名稱,顯示出網(wǎng)絡(luò)連接情形。 -r 顯示核心路由表,格式同"route -e"。 -t?
? ? ? 顯示TCP協(xié)議的連接情況。 -u 顯示UDP協(xié)議的連接情況。 -v 顯示正在進(jìn)行的工作。
三:怎么來(lái)分析我們截獲的封包?
? ? ? 首先我們將WPE截獲的封包保存為文本文件,然后打開(kāi)它,這時(shí)會(huì)看到如下的數(shù)據(jù)(這里我們以金庸群俠傳里PK店小二客戶端發(fā)送的數(shù)據(jù)為例來(lái)講解):
? ? ? 第一個(gè)文件:?
? ? ? SEND-> 0000 E6 56 0D 22 7E 6B E4 17 13 13 12 13 12 13 67 1B?
? ? ? SEND-> 0010 17 12 DD 34 12 12 12 12 17 12 0E 12 12 12 9B?
? ? ? SEND-> 0000 E6 56 1E F1 29 06 17 12 3B 0E 17 1A?
? ? ? SEND-> 0000 E6 56 1B C0 68 12 12 12 5A?
? ? ? SEND-> 0000 E6 56 02 C8 13 C9 7E 6B E4 17 10 35 27 13 12 12?
? ? ? SEND-> 0000 E6 56 17 C9 12
? ? ? 第二個(gè)文件:?
? ? ? SEND-> 0000 83 33 68 47 1B 0E 81 72 76 76 77 76 77 76 02 7E?
? ? ? SEND-> 0010 72 77 07 1C 77 77 77 77 72 77 72 77 77 77 6D?
? ? ? SEND-> 0000 83 33 7B 94 4C 63 72 77 5E 6B 72 F3?
? ? ? SEND-> 0000 83 33 7E A5 21 77 77 77 3F?
? ? ? SEND-> 0000 83 33 67 AD 76 CF 1B 0E 81 72 75 50 42 76 77 77?
? ? ? SEND-> 0000 83 33 72 AC 77
? ? ? 我們發(fā)現(xiàn)兩次PK店小二的數(shù)據(jù)格式一樣,但是內(nèi)容卻不相同,我們是PK的同一個(gè)NPC,為什么會(huì)不同呢??
? ? ? 原來(lái)金庸群俠傳的封包是經(jīng)過(guò)了加密運(yùn)算才在網(wǎng)路上傳輸?shù)?#xff0c;那么我們面臨的問(wèn)題就是如何將密文解密成明文再分析了。因?yàn)橐话愕臄?shù)據(jù)包加密都是異或運(yùn)算,所以這里先講一下什么是異或。 簡(jiǎn)單的說(shuō),異或就是"相同為0,不同為1"(這是針對(duì)二進(jìn)制按位來(lái)講的),舉個(gè)例子,0001和0010異或,我們按位對(duì)比,得到異或結(jié)果是0011,計(jì)算的方法是:0001的第4位為0,0010的第4位為0,它們相同,則異或結(jié)果的第4位按照"相同為0,不同為1"的原則得到0,0001的第3位為0,0010的第3位為0,則異或結(jié)果的第3位得到0,0001的第2位為0,0010的第2位為1,則異或結(jié)果的第2位得到1,0001的第1位為1,0010的第1位為0,則異或結(jié)果的第1位得到1,組合起來(lái)就是0011。異或運(yùn)算今后會(huì)遇到很多,大家可以先熟悉熟悉,熟練了對(duì)分析很有幫助的。下面我們繼續(xù)看看上面的兩個(gè)文件,按照常理,數(shù)據(jù)包的數(shù)據(jù)不會(huì)全部都有值的,游戲開(kāi)發(fā)時(shí)會(huì)預(yù)留一些字節(jié)空間來(lái)便于日后的擴(kuò)充,也就是說(shuō)數(shù)據(jù)包里會(huì)存在一些"00"的字節(jié),觀察上面的文件,我們會(huì)發(fā)現(xiàn)文件一里很多"12",文件二里很多"77",那么這是不是代表我們說(shuō)的"00"呢?推理到這里,我們就開(kāi)始行動(dòng)吧!我們把文件一與"12"異或,文件二與"77"異或,當(dāng)然用手算很費(fèi)事,我們使用"M2M 1.0 加密封包分析工具"來(lái)計(jì)算就方便多了。得到下面的結(jié)果:第一個(gè)文件:?
? ? ? SEND-> 0000 F4 44 1F 30 6C 79 F6 05 01 01 00 01 00 01 75 09?
? ? ? SEND-> 0010 05 00 CF 26 00 00 00 00 05 00 1C 00 00 00 89?
? ? ? SEND-> 0000 F4 44 0C E3 3B 13 05 00 29 1C 05 08?
? ? ? SEND-> 0000 F4 44 09 D2 7A 00 00 00 48?
? ? ? SEND-> 0000 F4 44 10 DA 01 DB 6C 79 F6 05 02 27 35 01 00 00
? ? ? SEND-> 0000 F4 44 05 DB 00
? ? ? 第二個(gè)文件:?
? ? ? SEND-> 0000 F4 44 1F 30 6C 79 F6 05 01 01 00 01 00 01 75 09?
? ? ? SEND-> 0010 05 00 70 6B 00 00 00 00 05 00 05 00 00 00 1A?
? ? ? SEND-> 0000 F4 44 0C E3 3B 13 05 00 29 1C 05 84?
? ? ? SEND-> 0000 F4 44 09 D2 56 00 00 00 48?
? ? ? SEND-> 0000 F4 44 10 DA 01 B8 6C 79 F6 05 02 27 35 01 00 00?
? ? ? SEND-> 0000 F4 44 05 DB 00
? ? ? 哈,這一下兩個(gè)文件大部分都一樣啦,說(shuō)明我們的推理是正確的,上面就是我們需要的明文!接下來(lái)就是搞清楚一些關(guān)鍵的字節(jié)所代表的含義,這就需要截獲大量的數(shù)據(jù)來(lái)分析。首先我們會(huì)發(fā)現(xiàn)每個(gè)數(shù)據(jù)包都是"F4 44"開(kāi)頭,第3個(gè)字節(jié)是變化的,但是變化很有規(guī)律。我們來(lái)看看各個(gè)包的長(zhǎng)度,發(fā)現(xiàn)什么沒(méi)有?對(duì)了,第3個(gè)字節(jié)就是包的長(zhǎng)度!通過(guò)截獲大量的數(shù)據(jù)包,我們判斷第4個(gè)字節(jié)代表指令,也就是說(shuō)客戶端告訴服務(wù)器進(jìn)行的是什么操作。例如向服務(wù)器請(qǐng)求戰(zhàn)斗指令為"30",戰(zhàn)斗中移動(dòng)指令為"D4"等。 接下來(lái),我們就需要分析一下上面第一個(gè)包"F4 44 1F 30 6C 79 F6 05 01 01 00 01 00 01 75 09 05 00 CF 26 00 00 00 00 05 00 1C 00 00 00 89",在這個(gè)包里包含什么信息呢?應(yīng)該有通知服務(wù)器你PK的哪個(gè)NPC吧,我們就先來(lái)找找這個(gè)店小二的代碼在什么地方。我們?cè)貾K一個(gè)小嘍羅(就是大理客棧外的那個(gè)咯): SEND-> 0000 F4 44 1F 30 D4 75 F6 05 01 01 00 01 00 01 75 09 SEND-> 0010 05 00 8A 19 00 00 00 00 11 00 02 00 00 00 C0 我們根據(jù)常理分析,游戲里的NPC種類(lèi)雖然不會(huì)超過(guò)65535(FFFF),但開(kāi)發(fā)時(shí)不會(huì)把自己限制在字的范圍,那樣不利于游戲的擴(kuò)充,所以我們?cè)陔p字里看看。通過(guò)"店小二"和"小嘍羅"兩個(gè)包的對(duì)比,我們把目標(biāo)放在"6C 79 F6 05"和"CF 26 00 00"上。(對(duì)比一下很容易的,但你不能太遲鈍咯,呵呵)我們?cè)倏纯春竺娴陌?#xff0c;在后面的包里應(yīng)該還會(huì)出現(xiàn)NPC的代碼,比如移動(dòng)的包,游戲允許觀戰(zhàn),服務(wù)器必然需要知道NPC的移動(dòng)坐標(biāo),再?gòu)V播給觀戰(zhàn)的其他玩家。在后面第4個(gè)包"SEND-> 0000 F4 44 10 DA 01 DB 6C 79 F6 05 02 27 35 01 00 00"里我們又看到了"6C 79 F6 05",初步斷定店小二的代碼就是它了! (
這分析里邊包含了很多工作的,大家可以用WPE截下數(shù)據(jù)來(lái)自己分析分析)第一個(gè)包的分析暫時(shí)就到這里(里面還有的信息我們暫時(shí)不需要完全清楚了)我們看看第4個(gè)包"SEND-> 0000 F4 44 10 DA 01 DB 6C 79 F6 05 02 27 35 01 00 00",再截獲PK黃狗的包,(狗會(huì)出來(lái)2只哦)看看包的格式: SEND-> 0000 F4 44 1A DA 02 0B 4B 7D F6 05 02 27 35 01 00 00 SEND-> 0010 EB 03 F8 05 02 27 36 01 00 00根據(jù)上面的分析,黃狗的代碼為"4B 7D F6 00040011),不過(guò)兩只黃狗服務(wù)器怎樣分辨呢?看看"EB 03 F8 05"(100140011),是上一個(gè)代碼加上100000,呵呵,這樣服務(wù)器就可以認(rèn)出兩只黃狗了。我們?cè)偻ㄟ^(guò)野外遇敵截獲的數(shù)據(jù)包來(lái)證實(shí),果然如此。 那么,這個(gè)包的格式應(yīng)該比較清楚了:第3個(gè)字節(jié)為包的長(zhǎng)度,"DA"為指令,第5個(gè)字節(jié)為NPC個(gè)數(shù),從第7個(gè)字節(jié)開(kāi)始的10個(gè)字節(jié)代表一個(gè)NPC的信息,多一個(gè)NPC就多10個(gè)字節(jié)來(lái)表示。大家如果玩過(guò)網(wǎng)金,必然知道隨機(jī)遇敵有時(shí)會(huì)出現(xiàn)增援,我們就利用游戲這個(gè)增援來(lái)讓每次戰(zhàn)斗都會(huì)出現(xiàn)增援的NPC吧。通過(guò)在戰(zhàn)斗中出現(xiàn)增援截獲的數(shù)據(jù)包,我們會(huì)發(fā)現(xiàn)服務(wù)器端發(fā)送了這樣一個(gè)包: F4 44 12 E9 EB 03 F8 05 02 00 00 03 00 00 00 00 00 00 第5-第8個(gè)字節(jié)為增援NPC的代碼(這里我們就簡(jiǎn)單的以黃狗的代碼來(lái)舉例)。 那么,我們就利用單機(jī)代理技術(shù)來(lái)同時(shí)欺騙客戶端和服務(wù)器吧!好了,呼叫NPC的工作到這里算是完成了一小半,接下來(lái)的事情,怎樣修改封包和發(fā)送封包,我們下節(jié)繼續(xù)講解吧。
四:怎么冒充"客戶端"向"服務(wù)器"發(fā)我們需要的封包?
? ? ? 這里我們需要使用一個(gè)工具,它位于客戶端和服務(wù)器端之間,它的工作就是進(jìn)行數(shù)據(jù)包的接收和轉(zhuǎn)發(fā),這個(gè)工具我們稱為代理。如果代理的工作單純就是接收和轉(zhuǎn)發(fā)的話,這就毫無(wú)意義了,但是請(qǐng)注意:所有的數(shù)據(jù)包都要通過(guò)它來(lái)傳輸,這里的意義就重大了。我們可以分析接收到的數(shù)據(jù)包,或者直接轉(zhuǎn)發(fā),或者修改后轉(zhuǎn)發(fā),或者壓住不轉(zhuǎn)發(fā),甚至偽造我們需要的封包來(lái)發(fā)送。下面我們繼續(xù)講怎樣來(lái)同時(shí)欺騙服務(wù)器和客戶端,也就是修改封包和偽造封包。 通過(guò)我們上節(jié)的分析,我們已經(jīng)知道了打多個(gè)NPC的封包格式,那么我們就動(dòng)手吧!首先我們要查找客戶端發(fā)送的包,找到戰(zhàn)斗的特征,就是請(qǐng)求戰(zhàn)斗的第1個(gè)包,我們找"F4 44 1F 30"這個(gè)特征,這是不會(huì)改變的,當(dāng)然是要解密后來(lái)查找哦。 找到后,表示客戶端在向服務(wù)器請(qǐng)求戰(zhàn)斗,我們不動(dòng)這個(gè)包,轉(zhuǎn)發(fā)。 繼續(xù)向下查找,這時(shí)需要查找的特征碼不太好辦,我們先查找"DA",這是客戶端發(fā)送NPC信息的數(shù)據(jù)包的指令,那么可能其他包也有"DA",沒(méi)關(guān)系,我們看前3個(gè)字節(jié)有沒(méi)有"F4 44"就行了。找到后,我們的工作就開(kāi)始了!我們確定要打的NPC數(shù)量。這個(gè)數(shù)量不能很大,原因在于網(wǎng)金的封包長(zhǎng)度用一個(gè)字節(jié)表示,那么一個(gè)包可以有255個(gè)字節(jié),我們上面分析過(guò),增加一個(gè)NPC要增加10個(gè)字節(jié),所以大家算算就知道,打20個(gè)NPC比較合適。然后我們要把客戶端原來(lái)的NPC代碼分析計(jì)算出來(lái),因?yàn)樵黾拥腘PC代碼要加上100000哦。再把我們?cè)黾拥腘PC代碼計(jì)算出來(lái),并且組合成新的封包,注意代表包長(zhǎng)度的字節(jié)要修改啊,然后轉(zhuǎn)發(fā)到服務(wù)器,這一步在編寫(xiě)程序的時(shí)候要注意算法,不要造成較大延遲。 上面我們欺騙服務(wù)器端完成了,欺騙客戶端就簡(jiǎn)單了,^-^發(fā)送了上面的封包后,我們根據(jù)新增NPC代碼構(gòu)造封包馬上發(fā)給客戶端,格式就是"F4 44 12 E9 NPC代碼 02 00 00 03 00 00 00 00 00 00",把每個(gè)新增的NPC都構(gòu)造這樣一個(gè)包,按順序連在一起發(fā)送給客戶端,客戶端也就被我們騙過(guò)了,很簡(jiǎn)單吧。以后戰(zhàn)斗中其他的事我們就不
管了,盡情地開(kāi)打吧,呵呵。
? ? ? ?上面講的需要一定的編程基礎(chǔ),但是不難,即使你不會(huì)編程,相信你繼續(xù)看下去就會(huì)有收獲了。
五:怎么用計(jì)算機(jī)語(yǔ)言去寫(xiě)一個(gè)單機(jī)代理?
? ? ? 在上一章,我們已經(jīng)對(duì)于代理的原理進(jìn)行了講解,大家對(duì)于代理已經(jīng)有了一個(gè)初步的認(rèn)識(shí),現(xiàn)在我教大家如何用計(jì)算機(jī)語(yǔ)言編寫(xiě)一個(gè)自己的代理,我們考慮到簡(jiǎn)單明了,我們選用VB,因?yàn)橛肰B編寫(xiě)代理只需要很少的代碼
。
? ? ? 代碼如下:
? ? ? Private Sub
? ? ? Form_Load()?
? ? ? DaiLi.LocalPort = "1234"?
? ? ? Server.RemotePort = "1234"
? ? ? Server.RemoteHost = "211.100.20.26"
? ? ? DaiLi.Listen
? ? ? End Sub
? ? ? Private Sub
? ? ? DaiLi_ConnectionRequest(ByVal requestID As Long)?
? ? ? Server.Connect
? ? ? Client.Accept
? ? ? requestID
? ? ? End Sub
? ? ? Private Sub?
? ? ? Client_DataArrival(ByVal bytesTotal As Long)?
? ? ? Dim ClientToServer() As Byte Client.GetData
? ? ? ClientToServer Server.SendData?
? ? ? ClientToServer
? ? ? End Sub
? ? ? Private Sub Server_DataArrival(ByVal bytesTotal As Long) Dim?
? ? ? ServerToClient() As Byte Server.GetData ServerToClient Client.SendData?
? ? ? ServerToClient
? ? ? End Sub
? ? ? Form_Load()這個(gè)過(guò)程表示在程序啟動(dòng)的時(shí)候要做的一些初始化操作。 DaiLi.LocalPort = "1234" 設(shè)定監(jiān)聽(tīng)端口Server.RemotePort = "1234" 設(shè)定象游戲服務(wù)器連接的端口(和監(jiān)聽(tīng)端口是相同的)Server.RemoteHost = ? "211.100.20.26" 設(shè)定游戲服務(wù)器的IP地址 DaiLi.Listen 監(jiān)聽(tīng)本地的連接請(qǐng)求這時(shí)你只要將游戲的服務(wù)器列表的IP改成127.0.0.1,那么游戲的客戶端程序就會(huì)來(lái)連接我們的代理,我們的代理會(huì)調(diào)用如下的過(guò)程: Private Sub DaiLi_ConnectionRequest(ByVal requestID As Long) Server.Connect ?代理客戶端向服務(wù)器連接 Client.Accept requestID 接受客戶端的連接請(qǐng)求 End Sub當(dāng)客戶端向服務(wù)器發(fā)送數(shù)據(jù)時(shí),就會(huì)調(diào)用下邊的過(guò)程 Private Sub Client_DataArrival(ByVal bytesTotal As Long) Dim ClientToServer() As Byte 變量定義,請(qǐng)求了一個(gè)用于存放數(shù)據(jù)的空間 Client.GetData ClientToServer 客戶端的連接接收這些數(shù)據(jù) 在這里我們可以添加自己的代碼,對(duì)封包進(jìn)行修改,然后再發(fā)向服務(wù)器。Server.SendData ClientToServer 服務(wù)器的連接把這些數(shù)據(jù)發(fā)向服務(wù)器 End Sub當(dāng)服務(wù)器發(fā)送數(shù)據(jù)給客戶端時(shí),會(huì)調(diào)用下邊的過(guò)程 Private Sub Server_DataArrival(ByVal bytesTotal As Long) Dim ServerToClient() As Byte 變量定義,請(qǐng)求了一個(gè)用于存放數(shù)據(jù)的空間 Server.GetData ServerToClient 服務(wù)器連接接收數(shù)據(jù) 在這里我們可以添加自己的代碼,對(duì)封包進(jìn)行修改,然后再發(fā)給客戶端。Client.SendData ServerToClient End Sub用其他語(yǔ)言編寫(xiě)基本的原理也是差不多的,不過(guò)可能稍微要麻煩一些,因?yàn)閂B本身有一個(gè)MSWINSCK.OCX控件,這個(gè)控件封裝了WINDOWS的網(wǎng)絡(luò)操作,而且接口很簡(jiǎn)單,推薦大家使用。
六:如果單機(jī)代理被封,我們?cè)趺蠢玫讓拥募夹g(shù)來(lái)接管游戲的發(fā)包?
? ? ? 在WINDOWS系統(tǒng)中,網(wǎng)絡(luò)通訊的任務(wù)是由一個(gè)叫WSOCK32.DLL(在SYSTEM目錄下)來(lái)完成的,每當(dāng)游戲被運(yùn)行時(shí),他都會(huì)自動(dòng)的去調(diào)用這個(gè)動(dòng)態(tài)連接庫(kù),因?yàn)樵赪INDOWS系統(tǒng)中對(duì)于文件的搜索順序是程序目錄>系統(tǒng)目錄>路徑中設(shè)置的目錄,所以我們就有機(jī)會(huì)替換掉系統(tǒng)的WSOCK32.DLL使的游戲調(diào)用我們的WSOCK32.DLL,這樣我們就有了對(duì)于游戲封包絕對(duì)的控制權(quán),有人問(wèn):"我們應(yīng)該怎么做呢?",我們只要自己編寫(xiě)一個(gè)WSOCK32.DLL放到游戲的目錄下,就OK了,當(dāng)然讓我們完全自己去編寫(xiě)一個(gè)WSOCK32.DLL是不太現(xiàn)實(shí)的,因?yàn)楸旧砭W(wǎng)絡(luò)通訊要處理很多更底層的東西,比如說(shuō)從網(wǎng)卡讀取BIT流,所以我們選擇由我們的WSOCK32.DLL去調(diào)用系統(tǒng)的WSOCK32.DLL來(lái)完成這個(gè)功能。
? ? ? WSOCK32.DLL有很多的輸出函數(shù),函數(shù)如下:
? ? ? __WSAFDIsSet accept AcceptEx Arecv Asend bind?
? ? ? closesocket closesockinfo connect dn_expand EnumProtocolsA EnumProtocolsW?
? ? ? GetAcceptExSockaddrs GetAddressByNameA GetAddressByNameW gethostbyaddr?
? ? ? gethostbyname gethostname GetNameByTypeA GetNameByTypeW getnetbyname?
? ? ? getpeername getprotobyname getprotobynumber getservbyname getservbyport?
? ? ? GetServiceA GetServiceW getsockname getsockopt GetTypeByNameA?
? ? ? GetTypeByNameW htonl htons inet_addr inet_network inet_ntoa ioctlsocket?
? ? ? listen MigrateWinsockConfiguration NPLoadNameSpaces NSPStartup ntohl ntohs?
? ? ? rcmd recv recvfrom rexec rresvport s_perror select send sendto sethostname?
? ? ? SetServiceA SetServiceW setsockopt shutdown socket TransmitFile WEP?
? ? ? WSAAsyncGetHostByAddr WSAAsyncGetHostByName WSAAsyncGetProtoByName?
? ? ? WSAAsyncGetProtoByNumber WSAAsyncGetServByName WSAAsyncGetServByPort?
? ? ? WSAAsyncSelect WSACancelAsyncRequest WSACancelBlockingCall WSACleanup?
? ? ? WSAGetLastError WSAIsBlocking WSApSetPostRoutine WSARecvEx?
? ? ? WSASetBlockingHook WSASetLastError WSAStartup WSAUnhookBlockingHook?
? ? ? WsControl WSHEnumProtocols
在這里,不是所有的函數(shù)都要修改,因?yàn)槲覀冎魂P(guān)心發(fā)送和接收的封包,所以我們只要修改send 和recv兩個(gè)函數(shù),前者是發(fā)送封包的后者是接收封包的,我們?cè)谶@兩個(gè)函數(shù)的處理中加入我們自己的代碼,來(lái)完成封包的辨認(rèn),修改以
及轉(zhuǎn)發(fā)等功能。
七:怎么來(lái)分析客戶端的有關(guān)資料?
? ? ? 自己作外掛,大多時(shí)候要分析封包,不過(guò)因?yàn)橛械墓δ苁怯煽蛻舳藖?lái)辨別的,所以分析客戶端的程序同樣也很重要,分析客戶端首先要求你能看懂匯編指令(只要"看懂",要求很低的),其次是要能夠熟練的運(yùn)用一些工
具,然后能剩下的也就是運(yùn)氣和游戲公司的漏洞了。(哈,不是每次都能成功的啊)下邊我分步教給大家。
? ? ? 第一章 8086匯編指令
? ? ? 注:AX,BX,CX...,EAX,EBX,ECX...這些都是CPU用來(lái)存儲(chǔ)數(shù)據(jù)的地方。
一、數(shù)據(jù)傳輸指令 作用:它們?cè)诖尜A器和寄存器、寄存器和輸入輸出端口之間傳送數(shù)據(jù).?
1. 通用數(shù)據(jù)傳送指令. MOV 傳送字或字節(jié). MOVSX先符號(hào)擴(kuò)展,再傳送. MOVZX 先零擴(kuò)展,再傳送. PUSH 把字壓入堆棧. POP 把字彈出堆棧. PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次壓入堆棧. POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次彈出堆棧. PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次壓入堆棧. POP把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次彈出堆棧. BSWAP 交換32位寄存器里字節(jié)的順序 XCHG 交換字或字節(jié).(至少有一個(gè)操作數(shù)為寄存器,段寄存器不可作為操作數(shù)) CMPXCHG 比較并交換操作數(shù).( 第二個(gè)操作數(shù)必須為累加器AL/AX/EAX ) XADD先交換再累加.( 結(jié)果在第一個(gè)操作數(shù)里 ) XLAT 字節(jié)查表轉(zhuǎn)換. BX 指向一張 256 字節(jié)的表的起點(diǎn), AL 為表的索引值 (0-255,即0-FFH); 返回 AL 為查表結(jié)果. ( [BX+AL]->AL ) ? ?
2. 輸入輸出端口傳送指令. IN I/O端口輸入. ( 語(yǔ)法: IN 累加器, {端口號(hào)│DX} ) OUT I/O端口輸出. ( 語(yǔ)法: OUT 端口號(hào)│DX},累加器 ) 輸入輸出端口由立即方式指定時(shí), 其范圍是 0-255; 由寄存器 DX 指定時(shí),其范圍是?
0-65535.
3. 目的地址傳送指令. LEA 裝入有效地址. 例: LEA DX,string ;把偏移地址存到DX. LDS?
? ? ? 傳送目標(biāo)指針,把指針內(nèi)容裝入DS. 例: LDS SI,string ;把段地址:偏移地址存到DS:SI. LES?
? ? ? 傳送目標(biāo)指針,把指針內(nèi)容裝入ES. 例: LES DI,string ;把段地址:偏移地址存到ES:DI. LFS?
? ? ? 傳送目標(biāo)指針,把指針內(nèi)容裝入FS. 例: LFS DI,string ;把段地址:偏移地址存到FS:DI. LGS?
? ? ? 傳送目標(biāo)指針,把指針內(nèi)容裝入GS. 例: LGS DI,string ;把段地址:偏移地址存到GS:DI. LSS?
? ? ? 傳送目標(biāo)指針,把指針內(nèi)容裝入SS. 例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
4. 標(biāo)志傳送指令. LAHF 標(biāo)志寄存器傳送,把標(biāo)志裝入AH. SAHF 標(biāo)志寄存器傳送,把AH內(nèi)容裝入標(biāo)志寄存器. PUSHF 標(biāo)志入棧. POPF 標(biāo)志出棧. PUSHD 32位標(biāo)志入棧. POPD 32位標(biāo)志出棧.
二、算術(shù)運(yùn)算指令 ADD 加法. ADC 帶進(jìn)位加法. INC 加 1. AAA 加法的ASCII碼調(diào)整. DAA 加法的十進(jìn)制調(diào)整. SUB減法. SBB 帶借位減法. DEC 減 1. NEC 求反(以 0 減之). CMP 比較.(兩操作數(shù)作減法,僅修改標(biāo)志位,不回送結(jié)果). AAS減法的ASCII碼調(diào)整. DAS 減法的十進(jìn)制調(diào)整. MUL 無(wú)符號(hào)乘法. IMUL 整數(shù)乘法. 以上兩條,結(jié)果回送AH和AL(字節(jié)運(yùn)算),或DX和AX(字運(yùn)算), AAM 乘法的ASCII碼調(diào)整. DIV 無(wú)符號(hào)除法. IDIV 整數(shù)除法. ?以上兩條,結(jié)果回送: 商回送AL,余數(shù)回送AH, (字節(jié)運(yùn)算); 或 商回送AX,余數(shù)回送DX, (字運(yùn)算). AAD 除法的ASCII碼調(diào)整. CBW 字節(jié)轉(zhuǎn)換為字. (把AL中字節(jié)的符號(hào)擴(kuò)展到AH中去) CWD 字轉(zhuǎn)換為雙字. (把AX中的字的符號(hào)擴(kuò)展到DX中去)CWDE 字轉(zhuǎn)換為雙字. (把AX中的字符號(hào)擴(kuò)展到EAX中去) CDQ 雙字?jǐn)U展. (把EAX中的字的符號(hào)擴(kuò)展到EDX中去)三、邏輯運(yùn)算指令 AND 與運(yùn)算. OR 或運(yùn)算. XOR 異或運(yùn)算. NOT 取反. TEST 測(cè)試.(兩操作數(shù)作與運(yùn)算,僅修改標(biāo)志位,不回送結(jié)果). SHL 邏輯左移. SAL 算術(shù)左移.(=SHL) SHR 邏輯右移. SAR 算術(shù)右移.(=SHR) ROL 循環(huán)左移. ROR 循環(huán)右移. RCL 通過(guò)進(jìn)位的循環(huán)左移. RCR 通過(guò)進(jìn)位的循環(huán)右移. 以上八種移位指令,其移位次數(shù)可達(dá)255次. 移位一次時(shí), 可直接用操作碼. 如 SHL AX,1. 移位>1次時(shí), 則由寄存器CL給出移位次數(shù). 如 MOV CL,04 SHL?
AX,CL
四、串指令 DS:SI 源串段寄存器 :源串變址. ES:DI 目標(biāo)串段寄存器:目標(biāo)串變址. CX 重復(fù)次數(shù)計(jì)數(shù)器. AL/AX 掃描值. D標(biāo)志 0表示重復(fù)操作中SI和DI應(yīng)自動(dòng)增量; 1表示應(yīng)自動(dòng)減量. Z標(biāo)志 用來(lái)控制掃描或比較操作的結(jié)束. MOVS 串傳送. ( MOVSB 傳送字符. MOVSW 傳送字. MOVSD 傳送雙字. ) CMPS 串比較. ( CMPSB 比較字符. CMPSW 比較字. ) SCAS 串掃描. 把AL或AX的內(nèi)容與目標(biāo)串作比較,比較結(jié)果反映在標(biāo)志位. LODS 裝入串. 把源串中的元素(字或字節(jié))逐一裝入AL或AX中. ( LODSB 傳送字符. LODSW 傳送字. LODSD 傳送雙字. ) STOS 保存串. 是LODS的逆過(guò)程. REP 當(dāng)CX/ECX<>0時(shí)重復(fù). REPE/REPZ 當(dāng)ZF=1或比較結(jié)果相等,且CX/ECX<>0時(shí)重復(fù). REPNE/REPNZ 當(dāng)ZF=0或比較結(jié)果不相等,且CX/ECX<>0時(shí)重復(fù). REPC 當(dāng)CF=1且CX/ECX<>0時(shí)重復(fù). REPNC 當(dāng)CF=0且CX/ECX<>0時(shí)重復(fù).
五、程序轉(zhuǎn)移指令?
1>無(wú)條件轉(zhuǎn)移指令 (長(zhǎng)轉(zhuǎn)移) JMP 無(wú)條件轉(zhuǎn)移指令 CALL 過(guò)程調(diào)用 RET/RETF過(guò)程返回.?
2>條件轉(zhuǎn)移指令 (短轉(zhuǎn)移,-128到+127的距離內(nèi)) ( 當(dāng)且僅當(dāng)(SF XOR OF)=1時(shí),OP1循環(huán)控制指令(短轉(zhuǎn)移) LOOP CX不為零時(shí)循環(huán). LOOPE/LOOPZ CX不為零且標(biāo)志Z=1時(shí)循環(huán). LOOPNE/LOOPNZ CX不為零且標(biāo)志Z=0時(shí)循環(huán). JCXZ CX為
零時(shí)轉(zhuǎn)移. JECXZ ECX為零時(shí)轉(zhuǎn)移.?
4>中斷指令 INT 中斷指令 INTO 溢出中斷 IRET 中斷返回?
5>處理器控制指令 HLT 處理器暫停, 直到出現(xiàn)中斷或復(fù)位信號(hào)才繼續(xù). WAIT 當(dāng)芯片引線TEST為高電平時(shí)使CPU進(jìn)入等待狀態(tài). ESC 轉(zhuǎn)換到外處理器. LOCK 封鎖總線. NOP 空操作. STC 置進(jìn)位標(biāo)志位. CLC 清進(jìn)位標(biāo)志位. CMC?
進(jìn)位標(biāo)志取反. STD 置方向標(biāo)志位. CLD 清方向標(biāo)志位. STI 置中斷允許位. CLI 清中斷允許位.
六、偽指令 DW 定義字(2字節(jié)). PROC 定義過(guò)程. ENDP 過(guò)程結(jié)束. SEGMENT 定義段. ASSUME 建立段寄存器尋址. ENDS 段結(jié)束. END 程序結(jié)束. 當(dāng)然不是所有的指令都能用的上的,我在這里全部寫(xiě)出來(lái)是為了讓大家認(rèn)識(shí)一下,
方便大家以后的學(xué)習(xí),我歸納了一下常用的指令,這些指令大家一定要熟練掌握才可以啊。MOV 數(shù)據(jù)傳送指令 PUSH,POP 堆棧指令 CMP 比較指令 LEA 取地址指令 XOR 異或指令 JE,JZ,JMP...(所有的轉(zhuǎn)移指令)
一些工具的使用
? ? ? 用到的工具包括Fi2.9,Wasm8.9 ,UltraEdit
? ? ? 一、 Fi2.9?
? ? ? 因?yàn)楝F(xiàn)在軟件為了保護(hù),另外也為了減少程序的大小,都采用了加殼技術(shù)。有人問(wèn)了"殼是什么呢",在自然界中,我想大家對(duì)"殼"這東西應(yīng)該都不會(huì)陌生了,植物用它來(lái)保護(hù)種子,動(dòng)物用它來(lái)保護(hù)身體等等。同樣,在一些計(jì)算機(jī)軟件里也有一段專門(mén)負(fù)責(zé)保護(hù)軟件不被非法修改或反編譯的程序。它們一般都是先于程序運(yùn)行,拿到控制權(quán),然后完成它們保護(hù)軟件的任務(wù)。就像動(dòng)植物的殼一般都是在身體外面一樣理所當(dāng)然。由于這段程序和自然界的殼在功能上有很多相同的地方,基于命名的規(guī)則,大家就把這樣的程序稱為"殼"了。 現(xiàn)在我們已經(jīng)知道"殼"是用來(lái)保護(hù)程序的,那我們要分析游戲程序,必須先把他的這層殼退掉,我們稱之為"脫殼",這個(gè)很容易的,因?yàn)楝F(xiàn)在網(wǎng)上有很多的脫殼軟件可以脫殼,不過(guò)在脫殼前我們必須先知道程序用什么加的"殼",Fi就是這樣一個(gè)軟件,操作很簡(jiǎn)單,將要分析的軟件和Fi放在同一個(gè)目錄,然后直接運(yùn)行Fi,在按回車(chē)就OK了。?
? ? ? 二、Wasm8.9 這是一個(gè)用來(lái)反匯編程序的軟件(反匯編,就是把機(jī)器代碼轉(zhuǎn)變?yōu)閰R編代碼)。操作很簡(jiǎn)單, 圖一(打開(kāi)文件) 圖二(簡(jiǎn)單介紹)首先打開(kāi)文件,進(jìn)行反匯編操作,然后選擇"串式參考"找到在程序中出現(xiàn)
的內(nèi)容,定位到該地址,進(jìn)行分析,分析完成,進(jìn)行修改,加亮當(dāng)前要修改的指令,然后看"當(dāng)前指令在文件中的地址偏移",記下這個(gè)值。
? ? ? 三、UltraEdit 是一個(gè)功能強(qiáng)大的編輯軟件,能直接修改程序的16進(jìn)制指令代碼。
? ? ? 實(shí)例解析
? ? ? 下邊以金庸的隨地逃為例進(jìn)行解析。
? ? ? 首先將金庸的Loginp.exe文件和Fi放在同一個(gè)目錄,然后運(yùn)行Fi,可以看到屏幕如圖 ?
? ? ? 可以看到程序用UPX加過(guò)殼了,所以首先進(jìn)行脫殼(由于該文件用UPX加殼后進(jìn)行了修改,用現(xiàn)成的工具無(wú)法脫殼,鑒于會(huì)員當(dāng)前水平的考慮,這個(gè)文件的脫殼方法以后講給大家聽(tīng),我們直接提供一個(gè)脫過(guò)殼的文件給會(huì)員
用于會(huì)員的學(xué)習(xí)),脫過(guò)殼之后,運(yùn)行Wasm進(jìn)行反匯編,然后點(diǎn)"串式參考",找到"次處非逃離點(diǎn)"如圖
? ? ? 程序如下(請(qǐng)打開(kāi)MagicWin)
? ? ? :00616376 6681B8EC470000AD65 cmp word ptr [eax+000047EC],?
? ? ? 65AD<---此處比較是否為逃離點(diǎn) :0061637F 7577 jne 006163F8 <---不是就跳走
? ? ? * Referenced by a (U)nconditional or (C)onditional Jump at?
? ? ? Address:|:0061636D(C)|:00616381 8BC3 mov eax, ebx:00616383 E8D4D1FFFF call?
? ? ? 0061355<----一個(gè)隨機(jī)處理判斷是否逃跑成功:00616388 84C0 test al, al:0061638A 7440 je?
? ? ? 006163CC <----不成功就跳走:0061638C 66C743530600 mov [ebx+53], 0006:00616392?
? ? ? B81E000000 mov eax, 0000001E:00616397 E80CC9DEFF call 00402CA8:0061639C?
? ? ? 890424 mov dword ptr [esp], eax:0061639F DB0424 fild dword ptr?
? ? ? [esp]:006163A2 DB2DDC656100 fld tbyte ptr [006165DC]:006163A8 DEC9 fmulp?
? ? ? st(1), st(0):006163AA D80550666100 fadd dword ptr [00616650]:006163B0?
? ? ? DB2DDC656100 fld tbyte ptr [006165DC]:006163B6 DEC1 faddp st(1),?
? ? ? st(0):006163B8 DD9BF8D06500 fstp qword ptr [ebx+0065D0F8]:006163BE 9B?
? ? ? wait:006163BF C6435201 mov [ebx+52], 01:006163C3 8BC3 mov eax,?
? ? ? ebx:006163C5 E8924E0000 call 0061B25C:006163CA EB3F jmp 0061640B
? ? ? * Referenced by a (U)nconditional or (C)onditional Jump at?
? ? ? Address:|:0061638A(C)|:006163CC A11CA36700 mov eax, dword ptr?
? ? ? [0067A31C]:006163D1 8B00 mov eax, dword ptr [eax]:006163D3 33C9 xor ecx,?
? ? ? ecx
? ? ? * Possible StringData Ref from Data Obj ->"発瞞ア毖"|:006163D5 BA5C666100 mov?
? ? ? edx, 0061665C:006163DA E83D9BF7FF call 0058FF1C:006163DF 8A8368010000 mov?
? ? ? al, byte ptr [ebx+00000168]:006163E5 04F9 add al, F9:006163E7 2C02 sub al,?
? ? ? 02:006163E9 7320 jnb 0061640B:006163EB 33C9 xor ecx, ecx:006163ED 33D2 xor?
? ? ? edx, edx:006163EF B0DE mov al, DE:006163F1 E8C6AE0100 call?
? ? ? 006312BC:006163F6 EB13 jmp 0061640B
? ? ? * Referenced by a (U)nconditional or (C)onditional Jump at?
? ? ? Address:|:0061637F(C)|:006163F8 A11CA36700 mov eax, dword ptr?
? ? ? [0067A31C]:006163FD 8B00 mov eax, dword ptr [eax]:006163FF 33C9 xor ecx,?
? ? ? ecx
? ? ? * Possible StringData Ref from Data Obj ->"矪獶発瞞翴"|:00616401 BA70666100?
? ? ? mov edx, 00616670:00616406 E8119BF7FF call 0058FF1C
? ? ? * Referenced by a (U)nconditional or (C)onditional Jump at?
? ? ? Addresses:|:006163CA(U), :006163E9(C), :006163F6(U)|:0061640B B201 mov dl,?
? ? ? 01:0061640D 8BC3 mov eax, ebx:0061640F E8BCC10000 call 006225D0:00616414?
? ? ? C6836801000000 mov byte ptr [ebx+00000168], 00:0061641B E977010000 jmp?
? ? ? 00616597:00616420 888368010000 mov byte ptr [ebx+00000168], al:00616426?
? ? ? C68300D1650000 mov byte ptr [ebx+0065D100], 00:0061642D 33C9 xor ecx,?
? ? ? ecx:0061642F 33D2 xor edx, edx:00616431 B0DE mov al, DE:00616433?
? ? ? E884AE0100 call 006312BC:00616438 B201 mov dl, 01
? ? ? 所以我們只要讓上邊兩個(gè)注釋的地方都不要跳走,就可以實(shí)現(xiàn)隨時(shí)隨地逃的功能了,修改很簡(jiǎn)單,我們把上邊的兩個(gè)跳轉(zhuǎn)語(yǔ)句全部注銷(xiāo)掉就OK了,匯編語(yǔ)言里注銷(xiāo)語(yǔ)句為NOP?
? ? ? 轉(zhuǎn)為機(jī)器指令也就是90,所以修改如下
? ? ? 原文:00616376 6681B8EC470000AD65 cmp word ptr [eax+000047EC],?
? ? ? 65AD<---此處比較是否為逃離點(diǎn):0061637F 7577 jne 006163F8 <---不是就跳走
? ? ? * Referenced by a (U)nconditional or (C)onditional Jump at?
? ? ? Address:|:0061636D(C)|:00616381 8BC3 mov eax, ebx:00616383 E8D4D1FFFF call?
? ? ? 0061355<----一個(gè)隨機(jī)處理判斷是否逃跑成功:00616388 84C0 test al, al:0061638A 7440 je?
? ? ? 006163CC <----不成功就跳走
? ? ? 修改之后
? ? ? :00616376 6681B8EC470000AD65 cmp word ptr [eax+000047EC],?
? ? ? 65AD<---此處比較是否為逃離點(diǎn):0061637F 90 nop:00616380 90 nop <---不是就跳走
? ? ? * Referenced by a (U)nconditional or (C)onditional Jump at?
? ? ? Address:|:0061636D(C)|:00616381 8BC3 mov eax, ebx:00616383 E8D4D1FFFF call?
? ? ? 0061355<----一個(gè)隨機(jī)處理判斷是否逃跑成功:00616388 84C0 test al, al:0061638A 90 nop?
? ? ? :0061638B 90 nop
? ? ? 當(dāng)然我們要把修改落實(shí)到文件上的,用UltraEdit打開(kāi)脫殼后的Loginp.exe 選擇Search->Goto?
? ? ? Line/Page來(lái)到地址0x21637f 可以看到這里的兩個(gè)字節(jié)內(nèi)容為7577(jne?
? ? ? 006163f8)把兩個(gè)字節(jié)內(nèi)容改為9090,來(lái)到地址0x21638a 可以看到這里的兩個(gè)字節(jié)內(nèi)容為7440(je?
? ? ? 006163cc)把兩個(gè)字節(jié)內(nèi)容改為9090,然后保存進(jìn)入金庸游戲看看,是不是可以隨地逃了啊,:)
? ? ? 注:教程中提供的地址會(huì)隨著loginp.exe的版本的不同有所改變,教程中采用的文件為1月7號(hào)的版本,會(huì)員可以到下載去下載到,如果會(huì)員需要最新的脫殼版本我們可以提供。
? ? ?
總結(jié)