亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        在遠程進程中注入DLL鉤掛IAT的方法

        2014-08-23 10:46:50
        計算機與現(xiàn)代化 2014年4期
        關(guān)鍵詞:鉤子線程調(diào)用

        張 鐘

        (重慶理工大學(xué),重慶 400054)

        0 引言

        在Windows系統(tǒng)的編程應(yīng)用中,有時需要對某些API函數(shù)進行攔截,在攔截函數(shù)里執(zhí)行自己的代碼功能后,再返回原函數(shù)執(zhí)行或者改變原函數(shù)操作行為等。攔截簡稱為鉤子,可分為內(nèi)核級和用戶級鉤子,內(nèi)核級鉤子有SYSENTER鉤子、SSDT鉤子、內(nèi)聯(lián)鉤子、IRP鉤子、LADDR 鉤子、IDT 鉤子、IOAPIC 鉤子[1]等,實現(xiàn)起來較難,須具有0環(huán)權(quán)限;用戶級鉤子3環(huán)權(quán)限就可實現(xiàn)。用戶級攔截API函數(shù)常用的方法有2種:一種是內(nèi)聯(lián)鉤子,一種是導(dǎo)入地址表(Import Address Table,IAT)鉤子。內(nèi)聯(lián)鉤子的特點是將被攔截函數(shù)的首部的5個字節(jié)先保存起來,然后修改為JMP+鉤子函數(shù)的偏移地址,待鉤子函數(shù)代碼執(zhí)行完后,再將保存起來的5個字節(jié)寫回原函數(shù)的首部,然后再執(zhí)行原函數(shù)。這種方法的缺點是:(1)對硬件CPU有依賴性,不同的CPU其JMP指令是不同的;(2)在搶占式、多線程環(huán)境下根本不能工作。因為一個線程覆蓋另一個函數(shù)起始位置的代碼是需要時間的,在這個過程中,另一個線程可能調(diào)用同一函數(shù),其結(jié)果將是災(zāi)難性的[2]。而導(dǎo)入地址表鉤子不存在上述2個問題,方法簡單,容易實現(xiàn),而且程序也相當(dāng)健壯。此外,在軟件的加密、解密和反病毒應(yīng)用中也往往涉及PE文件的IAT。當(dāng)Windows裝載器把PE文件裝入內(nèi)存時,會根據(jù)PE文件頭中的導(dǎo)入表所記錄的DLL名稱,將DLL裝入內(nèi)存,以供PE文件使用DLL中的函數(shù)代碼來實現(xiàn)程序的各種功能。當(dāng)程序調(diào)用API函數(shù)時會首先在導(dǎo)入表中的IAT中查找該函數(shù)入口地址,找到后調(diào)用該函數(shù)。PE文件的導(dǎo)入表可分為2種結(jié)構(gòu)形式:(1)導(dǎo)入表磁盤映像,可供查看導(dǎo)入表所記錄的DLL名稱和導(dǎo)入函數(shù)名稱或序號;(2)導(dǎo)入表的內(nèi)存映像,適用于鉤掛導(dǎo)入地址表IAT。本文在分析闡明導(dǎo)入表的內(nèi)存數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)上,重點闡明導(dǎo)入地址表(IAT)與鉤子函數(shù)關(guān)聯(lián)起來的鉤子原理:直接鉤掛和間接鉤掛,據(jù)此原理編程實現(xiàn)鉤掛IAT的鉤子模塊。

        1 鉤掛IAT的原理與編程實現(xiàn)

        1.1 導(dǎo)入表的數(shù)據(jù)結(jié)構(gòu)

        圖1 PE文件裝入內(nèi)存中的導(dǎo)入表結(jié)構(gòu)(部分)

        要鉤掛IAT首先要掌握導(dǎo)入表的內(nèi)存映像結(jié)構(gòu),圖1是PE文件裝入內(nèi)存中的導(dǎo)入表的部分結(jié)構(gòu)。PE文件的導(dǎo)入表是由一系列的IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)組成的數(shù)組,每一個IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)對應(yīng)一個DLL,導(dǎo)入表的最后由一個內(nèi)容全為0的IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)結(jié)束。該結(jié)構(gòu)的定義如下:

        字段OriginalFirstThunk所指的導(dǎo)入名稱表(Import Name Table,INT)由若干個 IMAGE_THUNK_DATA結(jié)構(gòu)組成的數(shù)組,每一個IMAGE_THUNK_DATA結(jié)構(gòu)對應(yīng)一個API導(dǎo)入函數(shù),數(shù)組的最后由一個內(nèi)容全為0的IMAGE_THUNK_DATA結(jié)構(gòu)結(jié)束。有的鏈接器產(chǎn)生的 PE文件沒有 INT,如 Borland公司的TLINK,因此由Borland生成的PE文件是不能綁定的[3],但這不影響鉤掛IAT。該結(jié)構(gòu)的定義如下:

        從這個結(jié)構(gòu)的定義可看到,該結(jié)構(gòu)是一個共用體,實際上就是一個雙字。當(dāng)雙字的最高位是1時,表示函數(shù)是以序號導(dǎo)入的,低31位就是函數(shù)的序號值;當(dāng)最高位是0時,表示函數(shù)是以函數(shù)名稱(ANSI字符串,以0結(jié)尾)導(dǎo)入的,雙字表示是一個RVA,此時指向一個IMAGE_IMPORT_BY_NAME結(jié)構(gòu)。IMAGE_IMPORT_BY_NAME結(jié)構(gòu)定義如下:

        1.2 鉤掛IAT的原理

        (1)直接法鉤掛。在圖1中的IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)中,字段FirstThunk指向?qū)氲刂繁?IAT),導(dǎo)入地址表中的每一項都對應(yīng)一個導(dǎo)入函數(shù)的入口地址,用鉤子函數(shù)的地址取代IAT中導(dǎo)入函數(shù)的入口地址即可實現(xiàn)鉤掛。

        (2)間接法鉤掛。在圖1中,字段FirstThunk同時也指向IMAGE_THUNK_DATA結(jié)構(gòu)數(shù)組,在內(nèi)存中IMAGE_THUNK_DATA結(jié)構(gòu)數(shù)組就是導(dǎo)入地址表IAT,該結(jié)構(gòu)中的共用體字段成員變量u1.Function的值是與IAT共用的同一個導(dǎo)入函數(shù)的入口地址,用鉤子函數(shù)的地址取代成員變量u1.Function的值即可實現(xiàn)鉤掛,并自動同步取代IAT中對應(yīng)導(dǎo)入函數(shù)的入口地址。

        在查看內(nèi)存中的導(dǎo)入地址表時,看到的只是一個IAT。但用編程的方法去鉤掛IAT時,則可選擇字段FirstThunk指向的2條路徑之一去鉤掛IAT。

        1.3 鉤掛IAT的編程實現(xiàn)

        要鉤掛IAT,首先要定位內(nèi)存中導(dǎo)入表的位置,然后由IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)中的字段FirstThunk找到IAT,再置換導(dǎo)入函數(shù)在IAT中對應(yīng)的入口地址(直接法)或者置換成員變量u1.Function的值(間接法)即可。定位IAT位置的方法有3種。

        (1)從PE基地址開始將其定位到PE頭的IMAGE_NT_HEADERS結(jié)構(gòu)體,由結(jié)構(gòu)中的字段名OptionalHeader再定位到 IMAGE_OPTIONAL_HEADER32結(jié)構(gòu)體,由該結(jié)構(gòu)中的字段名DataDirectory所指的第2個IMAGE_DATA_DIRECTORY結(jié)構(gòu)體,由該結(jié)構(gòu)中的字段名VirtualAddress所指即是導(dǎo)入表IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)體數(shù)組,通過該結(jié)構(gòu)的字段名FirstThunk即指向IAT的RVA。

        (2)通過 IMAGE_OPTIONAL_HEADER32結(jié)構(gòu)體中的字段名DataDirectory所指的第13個IMAGE_DATA_DIRECTORY結(jié)構(gòu)體,由該結(jié)構(gòu)中的字段名VirtualAddress直接指向IAT的RVA。

        (3)使用imagehlp.dll動態(tài)鏈接庫中的函數(shù)ImageDirectoryEntryToData,該函數(shù)的返回值即是指向?qū)氡鞩MAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)體數(shù)組的VA,通過該結(jié)構(gòu)的字段名FirstThunk即指向IAT的RVA。

        本文采用方法(1)并結(jié)合圖1的導(dǎo)入表的內(nèi)存結(jié)構(gòu),用Win32匯編語言實現(xiàn)直接法鉤子模塊Hook-PEIAT用于鉤掛IAT,可用于鉤掛導(dǎo)入表中指定的DLL中的指定API導(dǎo)入函數(shù);此外,為測試直接法和間接法實現(xiàn)的鉤子模塊的鉤掛效果,所要注入遠程進程中的DLL模塊必須包括鉤子模塊和鉤子函數(shù)模塊,因為鉤掛IAT的目的就是為了實現(xiàn)鉤子函數(shù)的代碼功能。

        按圖1所示的字段FirstThunk指向的間接法去鉤掛IAT,可在鉤子模塊HookPEIAT中用下面程序代碼(Ⅱ)置換代碼(Ⅰ)即可實現(xiàn)。

        現(xiàn)在用C或VC++編寫的鉤掛IAT的程序代碼都是采用間接法實現(xiàn)導(dǎo)入地址表鉤子。這是因為C和VC++操作匯編指令比較麻煩,而操作變量和取變量地址卻很容易。

        2 測試實驗結(jié)果及分析

        在 Windows 7 旗艦版,CPU:Core i3,2.2 GHz和Windows XP SP2,CPU:Celeron,1.4 GHz 等環(huán)境下,采用遠程線程注入DLL的方法:(1)用GetProcAddress取得LoadLibraryA的實際地址;(2)用VirtualAllocEx在遠程進程中分配一塊內(nèi)存(用于存放DLL的全路徑名);(3)將DLL的全路徑名復(fù)制到(2)所分配的內(nèi)存中;(4)用CreateRemoteThread在遠程進程中創(chuàng)建一個線程,線程函數(shù)的地址就是LoadLibraryA的實際地址,參數(shù)就是(2)中分配的內(nèi)存地址,這樣就把DLL注入到遠程進程地址空間中。對記事本進程注入DLL進行了測試,直接法和間接法均可靠鉤掛IAT中的CreateFileW函數(shù)入口地址,并實現(xiàn)了測試鉤子函數(shù)的簡單功能:(1)允許打開所選擇的文件;(2)放棄打開所選擇的文件。本文除對Create-FileW函數(shù)進行了鉤掛測試,還對最常用的Message-BoxA、MessageBoxW和ExitProcess等導(dǎo)入函數(shù)用鉤子模塊HookPEIAT進行了鉤掛測試,測試結(jié)果表明,直接法和間接法都可靠鉤掛了IAT。

        3 討論

        (1)替代原導(dǎo)入函數(shù)的鉤子函數(shù)所有的參數(shù)類型應(yīng)相同,參數(shù)個數(shù)要相同;返回值應(yīng)相同;調(diào)用約定也應(yīng)相同[2]。如果不一致可能會引發(fā)異?;虿荒軐崿F(xiàn)鉤子函數(shù)預(yù)期的目的。另外,將Win32匯編編寫的鉤掛MessageBoxA或MessageBoxW的DLL分別注入用C或VC++編寫的程序進程中進行測試,均能可靠地鉤掛IAT中的導(dǎo)入函數(shù)地址,測試用的鉤子函數(shù)顯示正常,這說明了Win32匯編寫的鉤子函數(shù)在調(diào)用約定,參數(shù)個數(shù)等與C或VC++是一致的。

        (2)在進行鉤掛前應(yīng)先檢查該PE文件的導(dǎo)入表中有無要鉤掛的導(dǎo)入函數(shù),如沒有要鉤掛的導(dǎo)入函數(shù),則注入DLL后將不會有任何反映。如果鉤掛前經(jīng)檢查PE文件的導(dǎo)入表中有要鉤掛的函數(shù),但注入DLL后沒有反映,有一種情況是該導(dǎo)入函數(shù)已在DLL注入前就已執(zhí)行過了,雖已鉤掛但該導(dǎo)入函數(shù)此后沒有再調(diào)用了,像這種情況可先將線程掛起后,再注入DLL,然后啟動線程即可。

        (3)對于用 LoadLibrary和 GetProcAddress顯式裝入的函數(shù),由于PE文件的導(dǎo)入表中沒有此函數(shù),所以是無法通過鉤掛IAT的方法鉤住此函數(shù)。但可以鉤掛LoadLibrary和GetProcAddress這2個函數(shù)來攔截所要鉤掛的函數(shù),實際上通過鉤掛GetProcAddress就可實現(xiàn)攔截顯式裝入的函數(shù),因為要取得函數(shù)的地址必須調(diào)用GetProcAddress。本文僅對MessageBoxA進行了簡單的顯式裝入攔截測試。思路是:通過鉤掛GetProcAddress導(dǎo)入函數(shù),在鉤子函數(shù)內(nèi)部對每次調(diào)用GetProcAddress的每一個函數(shù)名參數(shù)都與字符串“MessageBoxA”,0進行比對,如果找到了,表明是要鉤掛的函數(shù)MessageBoxA,顯示攔截成功的信息,再返回GetProcAddress的值,繼續(xù)調(diào)用顯式裝入函數(shù)MessageBoxA來顯示原來的信息;如果不是字符串“MessageBoxA”,0,就直接返回 GetProcAddress的值。

        (4)鉤掛IAT除可采用遠程注入DLL的方法外,還可以采用遠程注入代碼的方式;但后者需要對注入代碼中的全局變量和函數(shù)進行重定位,并需要自己動態(tài)搜索API函數(shù),而前者則沒有這方面的問題。

        (5)要解除對PE或DLL的IAT的鉤掛,只要在鉤子模塊HookPEIAT中,將參數(shù)lpoldfunc(原函數(shù)入口地址)與lphookfunc(鉤子函數(shù)入口地址)值進行對換,然后調(diào)用HookPEIAT,即可解除對IAT的鉤掛。

        (6)在實際的鉤掛IAT的程序時,為了防止因考慮不周而引發(fā)異常暴露鉤子函數(shù)的行為,建議編程時加入異常處理程序,以便出現(xiàn)小錯誤時異常處理程序內(nèi)部自己就處理了,以保護自己的程序能隱蔽執(zhí)行。

        (7)對于使用了延遲加載DLL技術(shù)的PE文件,由于API函數(shù)在使用前無法在IAT中找到入口地址,這樣會使直接鉤掛IAT失?。?],但仍可以通過鉤掛LoadLibrary和GetProcAddress來實施攔截。本文就利用鉤子模塊HookPEIAT,對PE文件的延遲加載的user32.dll中的MessageBoxW函數(shù),通過鉤掛GetProcAddress,成功攔截了MessageBoxW函數(shù)。

        (8)對于綁定的導(dǎo)入表,建議在內(nèi)存中鉤掛導(dǎo)入地址表為好;因為Windows裝載器在加載PE文件時會先檢查所裝入的DLL地址的有效性,如不滿足要求,將會重新生成一個新的IAT[2],從而使靜態(tài)鉤掛的IAT完全失效。

        4 結(jié)束語

        Windows鉤子技術(shù)博大精深,在防火墻、進程監(jiān)控、進程隱藏、進程自我防護、實時數(shù)據(jù)采集、即時翻譯、內(nèi)存信息隱藏、注冊表項隱藏、網(wǎng)絡(luò)攻擊與防御、反病毒、加密解密等方面得到廣泛的應(yīng)用,鉤子技術(shù)還擴展了原函數(shù)的功能。本文所介紹的用戶級IAT鉤子,由于簡單、可靠和適用,也得到了廣泛的使用。IAT鉤子在使用中有幾點要注意:(1)任何阻止DLL或代碼注入到進程中的方法,都會阻止鉤掛IAT;還有將其注入的DLL釋放掉,也會使IAT鉤子失效,這可以采用注入代碼的方法來應(yīng)對。(2)任何對導(dǎo)入表或IAT進行加密處理,也會阻止鉤掛IAT。對于加密的程序,只有當(dāng)外殼程序把執(zhí)行權(quán)交給被加密程序時,PE文件的導(dǎo)入表和IAT才恢復(fù)原狀,這時才能正確鉤掛IAT,但時間點的確定是以后鉤掛IAT研究的方向。(3)反鉤掛IAT。Rootkit反鉤掛是通過比較IAT中的地址與DLL中導(dǎo)出函數(shù)的地址,如發(fā)現(xiàn)二者之間有任何差異[4],表明可能帶有 IAT鉤子,可用DLL中導(dǎo)出函數(shù)的地址覆蓋掉IAT中鉤子函數(shù)地址,使IAT鉤子失效。

        :

        [1]任曉琿.黑客免殺攻防[M].北京:機械工業(yè)出版社,2013:375-376,390-413.

        [2][美]杰夫瑞,[法]克里斯托夫.Windows核心編程(第5版)[M].葛子昂,周靖,廖敏譯.北京:清華大學(xué)出版社,2008:600-601.

        [3]段鋼.加密與解密(第3版)[M].北京:電子工業(yè)出版社,2008:285-286.

        [4][美]戴維斯,等.黑客惡意軟件和RootKit安全大曝光[M].姚軍,等譯.北京:機械工業(yè)出版社,2011:218-219.

        [5]蘇雪麗,袁丁.Windows下兩種API鉤掛技術(shù)的研究與實現(xiàn)[J].計算機工程與設(shè)計,2011,32(7):2548-2552.

        [6]陳云超,馬兆豐.基于API函數(shù)攔截技術(shù)的跨進程攻擊防護研究[C]//2011年通信與信息技術(shù)新進展——第八屆中國通信學(xué)會學(xué)術(shù)年會論文集.2011.

        [7]舒敬榮,朱安國,齊善明.HOOK API時代碼注入方法和函數(shù)重定向技術(shù)研究[J].計算機應(yīng)用與軟件,2009,26(5):107-110.

        [8]黃頂源,李陶深,嚴毅,等.HOOK API在內(nèi)網(wǎng)安全監(jiān)管系統(tǒng)中的應(yīng)用[J].廣西物理,2006,27(4):38-41.

        [9]陶廷頁,孫樂昌,汪永益.利用API HOOK技術(shù)實現(xiàn)計算機保密通信[J].安徽電子信息職業(yè)技術(shù)學(xué)院學(xué)報,2004,3(5-6):107-108.

        [10]鄧樂,李曉勇.基于IAT表的木馬自啟動技術(shù)[J].信息安全與通信保密,2007(2):151-153.

        [11]王泰格,邵玉如,楊翌.全局IAT Hook技術(shù)原理及實現(xiàn)[J].信息與電腦:理論版,2012(7):110-111.

        [12]程彥,楊建召.Win32中API攔截技術(shù)及其應(yīng)用[J].長春工業(yè)大學(xué)學(xué)報:自然科學(xué)版,2006,27(4):369-371.

        猜你喜歡
        鉤子線程調(diào)用
        核電項目物項調(diào)用管理的應(yīng)用研究
        LabWindows/CVI下基于ActiveX技術(shù)的Excel調(diào)用
        誰和誰好
        快樂語文(2018年15期)2018-11-29 10:23:17
        幸福的一家
        淺談linux多線程協(xié)作
        《脈望館鈔校本古今雜劇》穿關(guān)之“鉤子困帶”考
        中華戲曲(2017年2期)2017-02-16 06:53:24
        基于系統(tǒng)調(diào)用的惡意軟件檢測技術(shù)研究
        精鉤子
        金山(2016年5期)2016-05-30 14:18:17
        利用RFC技術(shù)實現(xiàn)SAP系統(tǒng)接口通信
        Linux線程實現(xiàn)技術(shù)研究
        国内精品自在自线视频| 久久精品国产自产对白一区| 色综合久久中文综合网亚洲| 三年中文在线观看免费大全| 国产女人18毛片水真多| 亚洲日产国无码| 亚洲av日韩专区在线观看| 好紧好爽免费午夜视频| 处破痛哭a√18成年片免费| 亚州毛色毛片免费观看| 男人的精品天堂一区二区在线观看| 亚洲av综合色一区二区| 日本少妇春药特殊按摩3| 亚洲乱码日产精品bd在线观看| av超碰在线免费观看| 日本大胆人体亚裔一区二区| 成人大片免费观看视频| 精品无码久久久久久国产| 精品十八禁免费观看| 加勒比一本大道大香蕉| 中文字日产幕码三区的做法大全| 熟妇人妻久久中文字幕| 国产乱子伦露脸在线| 亚洲国产精品免费一区| 在线播放亚洲丝袜美腿| 朝鲜女人大白屁股ass| 色欲国产精品一区成人精品| 国产一区二区三区特区| 日韩精品 在线 国产 丝袜| 少妇特黄a一区二区三区| 综合久久久久6亚洲综合| 野花视频在线观看免费| 午夜精品久久久久久毛片| 欧美黑人性色黄在线视频| 亚洲最大视频一区二区三区| 丰满少妇高潮惨叫久久久| 亚洲av纯肉无码精品动漫| 人妻无码中文专区久久AV| 少妇被按摩出高潮了一区二区| 久久久噜噜噜久久中文福利| 日本人与黑人做爰视频网站|