優(yōu)秀技術(shù)文章轉(zhuǎn)載備份---變速原理-創(chuàng)新互聯(lián)

轉(zhuǎn)載:

注:為節(jié)省篇幅,本文對(duì)一些計(jì)算機(jī)術(shù)語(yǔ)直接使用而沒(méi)有作詳細(xì)的解釋?zhuān)x者若有不熟悉之處,建議參考清華大學(xué)出版社出版,周明德編著的《微型計(jì)算機(jī)系統(tǒng)原理及應(yīng)用》一書(shū)中關(guān)于8253/8254定時(shí)器和x86保護(hù)模式的相應(yīng)章節(jié)。

也許是我孤陋寡聞吧,說(shuō)出來(lái)不怕您笑話,對(duì)于“變速齒輪”這樣著名的軟件,我一直到五天前,也就是2001年2月28號(hào)才第一次聽(tīng)說(shuō)。我有幾個(gè)同學(xué)很喜歡玩圖形MUD,整天見(jiàn)了面就在一起切磋“泥”技。我對(duì)MUD本身并沒(méi)有多大興趣,但是那天早上偶爾聽(tīng)他們說(shuō)某個(gè)MUD站點(diǎn)明文規(guī)定嚴(yán)禁使用“齒輪”,這才好奇地問(wèn)他們什么是“齒輪”。別人告訴我,“齒輪”是一個(gè)軟件,能對(duì)Windows下的游戲加速,他們?cè)谕鍹UD時(shí)就依靠這個(gè)軟件作弊。這不禁令我一頭霧水,能讓W(xué)indows游戲改變速度,太神奇了!
我一貫對(duì)技術(shù)很有興趣,聽(tīng)說(shuō)有這么一個(gè)神奇的軟件,當(dāng)然要想想它是怎么實(shí)現(xiàn)的。這個(gè)軟件看起來(lái)并不復(fù)雜,我原以為一個(gè)早自習(xí)好好琢磨琢磨就行,可是我想了好幾節(jié)課,始終不得其要領(lǐng)。說(shuō)來(lái)也巧,我們這學(xué)期有一面必修課是Linux內(nèi)核原理分析,這幾天正好學(xué)到了進(jìn)程調(diào)度,老師說(shuō),當(dāng)一個(gè)時(shí)鐘中斷發(fā)生的時(shí)候,操作系統(tǒng)要做很多事情,比如必要時(shí)要重新調(diào)度進(jìn)程從而實(shí)現(xiàn)搶先式多任務(wù),還要更新系統(tǒng)時(shí)鐘......慢著,我突發(fā)奇想,如果讓時(shí)鐘中斷產(chǎn)生的更快,會(huì)發(fā)生什么事情呢?
我們已經(jīng)學(xué)過(guò)“微機(jī)原理”這門(mén)課程,我知道讓時(shí)鐘中斷產(chǎn)生的更快不是難事,以前我就用DOS下的匯編語(yǔ)言寫(xiě)過(guò)這樣的程序,這是我們當(dāng)時(shí)的作業(yè)。可是我以前的程序在Windows下雖然可以運(yùn)行,但并不能對(duì)Windows系統(tǒng)加速,道理很顯然:Windows9x是使用x86虛擬機(jī)的機(jī)制來(lái)兼容DOS程序的,我的程序只能改變虛擬機(jī),就是那個(gè)黑窗口的時(shí)鐘中斷。
于是我試圖把以前的DOS程序搬到32位環(huán)境中。用VC內(nèi)嵌匯編做這件事再合適不過(guò)了,在一個(gè)VC程序框架中加上一個(gè)__asm,然后只管把以前的匯編程序往里貼就行。我滿懷希望地運(yùn)行這樣一個(gè)拼湊出來(lái)的怪物,結(jié)果,出現(xiàn)了一個(gè)大家都很熟悉的“該程序執(zhí)行了非法操作”,我的試驗(yàn)以失敗告終。
后來(lái)冷靜下來(lái)仔細(xì)想想,這次失敗的原因是顯然的。Windows作為一個(gè)復(fù)雜的32位操作系統(tǒng),如果能讓你隨便對(duì)硬件進(jìn)行操作,那也許運(yùn)行不了幾個(gè)程序就崩潰了。但是如何繞過(guò)操作系統(tǒng)去操作硬件呢?我首先想到了vxd,編寫(xiě)一個(gè)驅(qū)動(dòng)程序肯定可以操作硬件,但是,很可惜,我不會(huì)設(shè)計(jì)驅(qū)動(dòng)程序。于是我想到了以前看到的CIH的源碼,CIH沒(méi)有寫(xiě)vxd,卻能操作硬件去燒毀BIOS,陳盈豪真是太偉大了,他的程序精巧之處我至今記憶猶新。于是我模仿他的技術(shù),修改IDT表,創(chuàng)建一個(gè)中斷門(mén),然后發(fā)生中斷,進(jìn)入ring0,現(xiàn)在我可以做任何事情了,按照以前的DOS程序那樣,往8253定時(shí)器里寫(xiě)一個(gè)控制字,再分兩次寫(xiě)入新的時(shí)鐘中斷發(fā)生頻率,一切順利!(詳細(xì)技術(shù)請(qǐng)您參考我的“兄弟變速器”源碼)我看到VC編輯區(qū)的光標(biāo)瘋狂的閃爍;雙擊已經(jīng)失效了,因?yàn)閃indows認(rèn)為我雙擊的時(shí)間間隔太長(zhǎng);Windows任務(wù)欄右方的時(shí)間飛快跳動(dòng),應(yīng)該說(shuō),我已經(jīng)成功了。
當(dāng)時(shí)我想當(dāng)然的以為“變速齒輪”的原理也是如此,可是當(dāng)我從同學(xué)那里把“齒輪”拷來(lái)并研究時(shí),發(fā)現(xiàn)Windows的時(shí)鐘并不變快,而游戲速度照樣可以加上去,也就是說(shuō),“齒輪”采用了與我的程序不同的技術(shù),是什么技術(shù)呢?我決定繼續(xù)研究。
我訪問(wèn)了“變速齒輪”的主頁(yè),這個(gè)主頁(yè)上有一個(gè)“你問(wèn)我答”的欄目,由“齒輪”的作者王榮先生進(jìn)行技術(shù)支持。我試圖在這里找到一些關(guān)于“齒輪”的技術(shù)細(xì)節(jié),但是很可惜,沒(méi)有找到,王榮先生只是告訴大家這個(gè)程序不能用VB編寫(xiě)等等根本連皮毛也不涉及的問(wèn)題,好不容易見(jiàn)到一個(gè)外國(guó)人問(wèn)能不能公布源代碼,其實(shí)這也是我想問(wèn)的,但是王榮先生明確表示不行,這不禁令我感到非常失望。
我也想過(guò)寫(xiě)信去索取原碼,也許他不向外國(guó)人公布,中國(guó)人可不一定。但是咱們“臭老九”最?lèi)?ài)一個(gè)面子,我實(shí)在拉不下臉去問(wèn)。這時(shí)已經(jīng)是晚上10點(diǎn)了,我決定祭出SoftIce,用一夜時(shí)間去研究他的程序。
當(dāng)時(shí)使用的工具是SoftIce,WD32ASM和VC,手邊兩本參考書(shū)是《微型計(jì)算機(jī)系統(tǒng)原理及應(yīng)用》和《Linux操作系統(tǒng)內(nèi)核分析》(都是我們的課本,呵呵)。
起初,“變速齒輪”0.2版的一個(gè)叫hook.dll的文件很大程度上吸引了我的注意力,我懷疑他使用Windows消息鉤子實(shí)現(xiàn)變速,消息鉤子我很熟悉,但我把MSDN上面關(guān)于鉤子的介紹看了好久,也沒(méi)有想出它和變速有什么聯(lián)系,這時(shí)偶然看了一下在王榮先生的主頁(yè)上得到的“變速齒輪”0.1版,才發(fā)現(xiàn)老版本中并沒(méi)有這個(gè)文件,也就是說(shuō),我只需要反匯編他的主程序就夠了,于是,二話不說(shuō),用WD32ASM先把0.1版的“齒輪”給拆了,匯編代碼5000多行,并不算多。
我是從這個(gè)程序的導(dǎo)入函數(shù)著手的,以前編程時(shí)用于定時(shí)的SetTimer,timeGetTime,timeSetEvent等等這里都導(dǎo)入了,看看它們被引用的地方,我發(fā)現(xiàn)這些函數(shù)都是集中出現(xiàn)的,而且大都以這樣的形式出現(xiàn):
* Reference To: WINMM.timeGetTime, Ord:0098h
:00401F3E 8B0D64424000 mov ecx, dword ptr [00404264]
:00401F44 8B11 mov edx, dword ptr [ecx]
也就是說(shuō),他并沒(méi)有調(diào)用這些函數(shù),只是取得了函數(shù)的入口地址,保存在ecx中,然后又根據(jù)這個(gè)入口地址得到了函數(shù)的前面幾個(gè)字節(jié),保存在edx中。
這讓我想到了前些日子在CSDN上面和別人討論的Hook API的原理,當(dāng)時(shí)我還索取了一份Hook API的例程,如果我要Hook這里的函數(shù)timeGetTime,修改ecx中的地址或者修改edx處的頭幾條指令就行,用匯編語(yǔ)言寫(xiě),與上面看到的這段代碼類(lèi)似。
為了測(cè)試“齒輪”是不是要Hook這里的timeGetTime,我自己編寫(xiě)了一個(gè)很簡(jiǎn)單的小程序,調(diào)用timeGetTime,每秒鐘顯示一個(gè)數(shù)字。用“齒輪”進(jìn)行加速后,果然顯示的速度快多了。再用SoftIce跟進(jìn)這個(gè)timeGetTime函數(shù),第一條指令變成一個(gè)跳轉(zhuǎn),這充分說(shuō)明“齒輪”確實(shí)Hook了這幾個(gè)API,不難猜測(cè),他要改變函數(shù)的返回值,也就是說(shuō)在timeGetTime結(jié)束時(shí)還要再跳入“齒輪”自身的代碼,耐心跟下去,我發(fā)現(xiàn)回到timeGetTime時(shí)棧里多壓了一個(gè)地址,這樣,當(dāng)timeGetTime用ret指令返回時(shí),先返回“齒輪”的代碼(這個(gè)思想確實(shí)很巧),返回值經(jīng)過(guò)處理后,才跳回我的應(yīng)用程序。至于怎么處理這個(gè)返回值就簡(jiǎn)單了,改到原先的2倍,應(yīng)用程序速度也就提高了2倍。
回頭再看WD32ASM反匯編的代碼,我又發(fā)現(xiàn)在Hook API前面的不遠(yuǎn)處使用了一次SGDT指令和兩次SLDT指令,這是x86保護(hù)方式的特有指令,用于獲得全局描述符表,進(jìn)一步得到局部描述符表,這段代碼引起了我的興趣,用SoftIce跟進(jìn)去,往下走幾步,一邊跟一邊猜,大致整理出了這樣的思路:
1.創(chuàng)建一個(gè)內(nèi)存映射,把自己的代碼映射到0x80000000以上的地方,在Win9x下,這塊虛存是所有進(jìn)程共享的。
2.先得到局部描述符表的地址,然后利用這張表修改代碼段的特權(quán)級(jí)。
3.用局部描述符表創(chuàng)建一個(gè)調(diào)用門(mén),在x86的保護(hù)模式下要進(jìn)入ring0必須通過(guò)門(mén)來(lái)進(jìn)行,CIH是用中斷門(mén)完成的,這里用調(diào)用門(mén)完成,異曲同工。
4.保存幾個(gè)關(guān)鍵函數(shù)前六個(gè)字節(jié),改為一條跳轉(zhuǎn)指令,跳到自己已經(jīng)映射到高端的代碼。
5.發(fā)生函數(shù)調(diào)用時(shí)進(jìn)入自己的代碼,通過(guò)調(diào)用門(mén)進(jìn)入ring0,恢復(fù)函數(shù)開(kāi)頭的幾個(gè)字節(jié),修改返回值。
這時(shí)已經(jīng)是凌晨5點(diǎn)了,既然主要思想已經(jīng)掌握,我也就沒(méi)有細(xì)看這段代碼,8點(diǎn)鐘還要上課,睡覺(jué)去也。
回頭想想,我認(rèn)為王榮先生的代碼還有幾點(diǎn)值得推敲之處:
1.如果要Hook API,一定要改變函數(shù)的第一條指令嗎?如果僅僅改變函數(shù)的入口地址,不是既容易編也容易調(diào)試嗎?
2.即使要改變函數(shù)第一條指令,一定要進(jìn)入ring0嗎?
3.即使要進(jìn)入ring0,使用中斷門(mén)不是比用調(diào)用門(mén)更方便嗎?
當(dāng)然,按照王榮先生在他的主頁(yè)上的說(shuō)法,“變速齒輪”0.1版是他在三年前即1997年寫(xiě)的,那時(shí)Windows95剛剛出來(lái)兩年,能有這樣的技術(shù)已經(jīng)難能可貴了,這里對(duì)王榮先生的鉆研精神表示由衷的敬佩。
在我研究出“變速齒輪”的原理后三天,我以自己原先的研究結(jié)果為核心,編寫(xiě)出了“兄弟變速器”的最初版本,不用“變速齒輪”的技術(shù)是因?yàn)槲艺J(rèn)為我的技術(shù)更優(yōu)越,何況也沒(méi)有拾人牙慧之嫌了 ^_^
最后再次對(duì)王榮先生表示感謝,這樣精彩的創(chuàng)意值得我們敬佩。 主頁(yè)是www.vrbrothers.com

網(wǎng)頁(yè)標(biāo)題:優(yōu)秀技術(shù)文章轉(zhuǎn)載備份---變速原理-創(chuàng)新互聯(lián)
URL鏈接:http://bm7419.com/article0/hcsio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作微信公眾號(hào)、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站制作、網(wǎng)站設(shè)計(jì)公司、建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站