最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

【滴水基礎(chǔ)】4.Win32Api調(diào)用(下2)

2023-02-26 19:28 作者:沙漠里的鯨  | 我要投稿

第三十:模塊隱藏

---使用API,遍歷進(jìn)程有那些模塊

#模塊隱藏之?dāng)噫?/p>

#線程環(huán)境塊:TEB(Thread Environment Block)

---用戶層的結(jié)構(gòu)體,它記錄了相關(guān)線程的信息。每一個(gè)線程都有自己的TEB

---FS:[0]就是當(dāng)前線程的TEB

#進(jìn)程環(huán)境塊:PEB(Process Environment Block)

---用戶層的結(jié)構(gòu)體,它記錄了相關(guān)進(jìn)程的信息。每一個(gè)線程都有自己的PEB

---哪個(gè)線程在執(zhí)行的時(shí)候,fs就存儲(chǔ)那個(gè)線程的TEB

---TEB偏移0x30即FS:[0x30],就是當(dāng)前線程的TEB

---使用Windbg(我的Win11直接在搜索框里面搜索)

---隨便打開一個(gè)exe模塊,使用"dt _TEB"命令來查看TEB結(jié)構(gòu)體信息

---可以發(fā)現(xiàn)TEB信息如下,這里存在三個(gè)主要的指針,指向三個(gè)重要的結(jié)構(gòu)體

---這里打開的是X64的WinDbg

---查看_PEB結(jié)構(gòu)體(可以看出,這里x64位系統(tǒng)PEB和TEB的偏移因該是0x60)

#x86x64的區(qū)別(32位系統(tǒng)也稱x86,64位系統(tǒng)也稱x64)

----1、內(nèi)存尋址能力區(qū)別:32位系統(tǒng)尋址能力是4G容量,而64位系統(tǒng)可以支持128GB大內(nèi)存,甚至更大。

---2、運(yùn)算速度區(qū)別:x64的CPU數(shù)據(jù)寬度為64位,64位指令集可以運(yùn)行64位數(shù)據(jù)指令,

---處理器一次可提取64位數(shù)據(jù)(只要兩個(gè)指令,一次提取8個(gè)字節(jié)的數(shù)據(jù))

----比32位(四個(gè)指令,一次提取4個(gè)字節(jié)的數(shù)據(jù)),性能會(huì)相應(yīng)提升一倍。

---3.通常情況下,x86(32位)的軟件可在64位和32位上的系統(tǒng)運(yùn)行,但x64(64位)的軟件在32位系統(tǒng)上有可能出現(xiàn)不兼容的情形。

#查看_PEB_LDR_DATA結(jié)構(gòu)體信息

---理解其三個(gè)成員的順序,其指向_LDR_DATA_TABLE_ENTRY元素中開始的三個(gè)成員

--- _LDR_DATA_TABLE_ENTRY 中存儲(chǔ)著就是關(guān)于有關(guān)模塊信息的元素(比如模塊名等)

---什么是雙向鏈表

---這里我搞錯(cuò)了一點(diǎn),X86和X64不僅僅是操作系統(tǒng),還有exe文件

---比如我用VC6編譯的Test.exe文件就是X86系統(tǒng)的(可以在資源管理器查看)

---Test.exe就是打印0-9

---還有就是我系統(tǒng)自帶的WinDbg(X64)

---可以通過命令設(shè)置WinDbg轉(zhuǎn)為x86模式,需要切換到該 32 位進(jìn)程轉(zhuǎn)儲(chǔ)的 32 位視圖

---x64切換x86模式代碼如下(emmm找了好久這個(gè)代碼

---再來查看_TEB,發(fā)現(xiàn)_PEB和TEB的偏移是0x30

---查看_NT_TIB

---查看_CLIENT_ID

---查看_PEB_LDR_DATA

---其中_LIST_ENTRY存儲(chǔ)的是指向_LDR_DATA_TABLE_ENTRY的雙向鏈表指針

---32位的結(jié)構(gòu)體存儲(chǔ)信息

---用DTDebug打開之前的Test.exe(這個(gè)沒有dll,打開就是main函數(shù)的領(lǐng)空)

---查看FS的值:2C8000(注意:每次打開的都不一樣)

---查看對(duì)應(yīng)內(nèi)存的值:dd 2C8000

---查看_CLIENT_ID結(jié)構(gòu)體信息(偏移0x20)

---則獲取到了:進(jìn)程ID、線程ID

---找到TEB的偏移0x30,右鍵:follow in Dump進(jìn)入指針指向的地址

---因?yàn)門EB的偏移0x30的內(nèi)存里面,存儲(chǔ)者指向PEB的指針

---follow in Dump之后,發(fā)現(xiàn)來到了PEB的內(nèi)存地址

---查看PEB中LDR的偏移

---找到0xC的偏移

---再次follow in Dump到_PEB_LDR_DATA的內(nèi)存地址

---然后根據(jù)0xC的偏移,來到InLoadOrderModuleList的位置

---里面存儲(chǔ)的指針也就是_LDR_DATA_TABLE_ENTRY起始位置

---注意:前面加_的應(yīng)該是存儲(chǔ)的結(jié)構(gòu)體指針

---可以發(fā)現(xiàn)InLoadOrderModuleList的單位?_LIST_ENTRY里面

---起始就是雙向鏈表的兩個(gè)指針,可見_PEB_LDR_DATA這也是存在的3個(gè)?_LIST_ENTRY

---?_LIST_ENTRY這個(gè)雙鏈表指向進(jìn)程裝載的模塊,結(jié)構(gòu)中的每個(gè)指針,指向了一個(gè)LDR_DATA_TABLE_ENTRY 的結(jié)構(gòu):

---查看_LDR_DATA_TABLE_ENTRY結(jié)構(gòu)體的成員

---選擇第一個(gè)follow in dump,進(jìn)入_LDR_DATA_TABLE_ENTRY起始位置

---PEB_LDR_DATA 中的三個(gè)LIST_ENTRY全部是雙向鏈表結(jié)構(gòu)

---它的兩個(gè)成員Flink,Blink都指向LDR_DATA_TABLE_ENTRY

---首先看Test.exe加載了幾個(gè)模塊

---這里也是_LIST_ENTRY的Flink

---BaseDllName的偏移是0x024

---發(fā)現(xiàn)_LDR_DATA_TABLE_ENTRY的InLoadOrderModuleList的Blink正好是_LDR_DATA_DATA的InLoadOrderModuleList的Flink

---查看 BaseDllName 的單位_UNICODE_STRING(重要)

---偏移4個(gè)單位才是模塊名稱,也是對(duì)的上的

#總結(jié)

---_TEB偏移0x30,里面存儲(chǔ)著指向_PEB的指針

---_PEB偏移0xC,里面存儲(chǔ)著指向_PEB_LDR_DATA結(jié)構(gòu)體的指針

---_PEB_LDR_DATA偏移0xC,里面存儲(chǔ)著_LIST_ENTRY結(jié)構(gòu)體的2個(gè)指針

---通過_LIST_ENTRY的Flink成員獲取_LDR_DATA_TABLE_ENTRY結(jié)構(gòu)體地址

---(注意:這里的Flink指向的是_LDR_DATA_TABLE_ENTRY結(jié)構(gòu)中的InLoadOrderLinks成員)

---通過_LDR_DATA_TABLE_ENTRY的偏移獲取BaseDllName或FullDllName成員信

---這里感覺很難,可以再梳理一下

---TEB > PEB > _PEB_LDR_DATA > _LDR_DATA_TABLE_ENTRY 的關(guān)系如下

---Ldr中有的三個(gè)List,根據(jù)MSDN規(guī)定LIST_ENTRY的結(jié)構(gòu),其中有兩個(gè)成員:Flink和Blink,他們分別指向著一個(gè)LDR_DATA_TABLE_ENTRY

---不同模塊之間,通過Flink和Blink連接

------而且不管怎樣,第一個(gè)加載的一定是Test.exe模塊(參考進(jìn)程創(chuàng)建的流程

---不難發(fā)現(xiàn),PEB_LDR_DATA給出的是三個(gè)List(InLoadOrderModuleList,InMemoryOrderModuleLis以及InInitializationOrderModuleList)

---模塊加載首個(gè)基址,也可以看成是整個(gè)List雙向鏈表的表頭,然后通過這個(gè)雙向循環(huán)鏈表的不斷的遍歷,來依此獲取不同List加載的順序。

---同時(shí)系統(tǒng)為每一個(gè)DLL維護(hù)的一個(gè)LDR_DATA_TABLE_ENTRY,

---該結(jié)構(gòu)中,每一個(gè)DLL在不同List中,不但包含著著前繼加載模塊或者后繼加載模塊,還有著非常詳細(xì)的各個(gè)加載模塊的信息,包括加載基址和DLL名稱等等。
?---這樣,我們根據(jù)PEB_LDR_DATA 后找到LDR_DATA_TABLE_ENTRY

---通過不斷地遍歷,讀取其中的各項(xiàng)結(jié)構(gòu),至此,我們可以得出每一個(gè)List的在測(cè)試系統(tǒng)下,模塊的加載的依此順序:

----總結(jié):關(guān)系如下

#模塊隱藏的思路:

---對(duì)于指向Test.exe的雙鏈表進(jìn)行斷鏈操作,跳過第一個(gè)Test.exe模塊(讓PEB_LDR_DATA的Flink指向模塊A,讓模塊A的Blink指向PEB_LDR_DATA)

---由于存在3個(gè)List,所以上面的操作要進(jìn)行三次

---這里的斷鏈思想是這樣的:通過改變雙向鏈表的指針

---進(jìn)而將代表Kernel32.dll的_LDR_DATA_TABLE_ENTRY結(jié)構(gòu)體進(jìn)行跳過

---運(yùn)行該exe,用DTDebug的attach打開,點(diǎn)E查看模塊加載

---按回車嘗試隱藏模塊

---發(fā)現(xiàn)模塊已經(jīng)隱藏

#但是通過WinDbg查看內(nèi)核的情況還是可以看到該模塊

---通過查看內(nèi)存情況(我的Windows11無法打開kernel debug,因該是不支持本地內(nèi)核調(diào)試)

---發(fā)現(xiàn)kernel32.dll沒有被隱藏

---而且這里不能斷鏈,如果斷鏈,內(nèi)存就卸載了該模塊

#在PE結(jié)構(gòu)中查看模塊在內(nèi)存中存儲(chǔ)的規(guī)律(PE指紋)

---查看Kernel32.dll的基址0x75860000

---db 0x75860000,開頭5A 4D對(duì)應(yīng)的MZ

---然后往后找64個(gè)Byte,發(fā)現(xiàn):00 00 00 E8

---然后將0x75860000偏移E8,對(duì)應(yīng)的PE

---這里的MZ、PE,是任何模塊都存在的指紋

---因此:最好的隱藏:無模塊注入,也就是代碼注入

第三十一:代碼注入

#回顧遠(yuǎn)程線程

---原來的遠(yuǎn)程線程是執(zhí)行目標(biāo)進(jìn)程的已有函數(shù)

---代碼注入:1.將自定義函數(shù)復(fù)制到目標(biāo)進(jìn)程 2.指定遠(yuǎn)程線程執(zhí)行自定義函數(shù)

#代碼注入的問題:

---1.復(fù)制的函數(shù)本質(zhì)是什么?

---2.復(fù)制的函數(shù)可以正常執(zhí)行的前提條件是什么?

#函數(shù)的本質(zhì)

---函數(shù)在本質(zhì)就是機(jī)器碼,而VC6將機(jī)器碼翻譯成匯編代碼來幫助人們查看

#不能使用全局變量進(jìn)行拷貝

---g=1:對(duì)應(yīng)的匯編:

---00427e34是全局變量的地址,將1存儲(chǔ)到這個(gè)地址中

---機(jī)器碼:05 34 7E 42 00代表全局變量的地址:00427e3205

---01是存儲(chǔ)的值,C7代表的是mov

---但是如果直接復(fù)制機(jī)器碼會(huì)失敗,因?yàn)榱硗庖粋€(gè)進(jìn)程沒有00427e3205的全局變量的地址

#不能使用常量字符串

---查看匯編和機(jī)器碼

---字符串的的本質(zhì):在堆中申請(qǐng)內(nèi)存,將字符串以數(shù)組的形式存儲(chǔ)到堆內(nèi)存,然后將堆內(nèi)存數(shù)組的首地址放到緩沖區(qū)中[ebp-4]

---機(jī)器碼(6C 2F 42 00)代表堆內(nèi)存地址,但是另一個(gè)進(jìn)程不存在該堆內(nèi)存的地址

#不能使用系統(tǒng)調(diào)用

---對(duì)應(yīng)的匯編和機(jī)器碼

---程序?qū)essageBox的函數(shù)(根據(jù)exe的導(dǎo)入表)地址放入堆內(nèi)存,

---MessageBox()的調(diào)用流程

#不能嵌套調(diào)用其它函數(shù)

---查看匯編:直接call的是Test的函數(shù)地址

---但是在另外一個(gè)進(jìn)程中,這個(gè)函數(shù)地址是不一致的

#總結(jié)

---發(fā)現(xiàn)限制太多,基本做不了什么事情

#代碼注入思路

---在同一個(gè)OS中,系統(tǒng)函數(shù)的地址都是一樣的,如LoadLibrary()

---在當(dāng)前進(jìn)程,創(chuàng)建相關(guān)系統(tǒng)函數(shù),然后將系統(tǒng)函數(shù)的地址,傳到目標(biāo)進(jìn)程中

---對(duì)之前的Test.exe進(jìn)行代碼注入,任務(wù)管理器查看Pid:2060

---注意:我的VC是32位,所以只能注入32位的exe

---注意:一般的程序頂不住,我最后寫了一個(gè)死循環(huán)才注入成功

----注入代碼:在D盤創(chuàng)建一個(gè)Test.txt文件

---之前試了很多次,都沒有成功,但是我的調(diào)試語句卻輸出創(chuàng)建文件成功(還以為是我的代碼問題,copy了網(wǎng)上成功的代碼還是不行)

---猜測(cè)是被注入的程序在被注入的時(shí)候,直接崩了,所以沒有頂?shù)轿募?chuàng)建成功,因此寫了一個(gè)死循環(huán),發(fā)現(xiàn)文件創(chuàng)建成功

---發(fā)現(xiàn)文件被創(chuàng)建

#代碼注入的總結(jié)

#為什么要進(jìn)行修正函數(shù)的

---對(duì)于調(diào)用函數(shù)來說,會(huì)call一個(gè)函數(shù)的地址:00401005

---但是從00401005跟進(jìn)去發(fā)現(xiàn),并不是Fun函數(shù)的真正地址

---而是JMP到真正的Fun函數(shù)的地址

---E9代表的是JMP命令,16代表的:當(dāng)前的跳轉(zhuǎn)地址的下一行地址,和Fun()地址相差16

---當(dāng)前跳轉(zhuǎn)地址下一行=00401005+5個(gè)機(jī)器碼=0040100A

---Fun()地址:0x0040100A+0x16=401020

#總結(jié)

---真正的地址 = 匯編Call的地址 + 5 + JMP下一行到真正函數(shù)地址的偏移

#再來看代碼里面的修正函數(shù)起始地址的代碼

---原來的地址裝在DWORD里面,是小端存儲(chǔ),所以 *(00401005)=E9 16 00 00 00

---但是如果將DWORD類型的dwFunAddr轉(zhuǎn)換為BYTE,那么*(BYTE*)(00401005)=E9(因?yàn)槲覀冎恍枰x取1Byte,所以轉(zhuǎn)為Byte類型)

---獲取JMP下一行到真正函數(shù)地址的偏移:讀取dwFunAddr的后面4個(gè)Byte,所以需要轉(zhuǎn)化為DWORD類型

---dwFunAddr+1則是跳過E9進(jìn)行讀取

#總結(jié)代碼注入

---優(yōu)點(diǎn):難以檢測(cè)

---缺點(diǎn):繁瑣復(fù)雜

【滴水基礎(chǔ)】4.Win32Api調(diào)用(下2)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
邻水| 高密市| 宣威市| 金阳县| 嘉义县| 隆化县| 饶河县| 双流县| 台东县| 潢川县| 磐石市| 高台县| 吉林市| 专栏| 榆树市| 晋江市| 珠海市| 望奎县| 小金县| 策勒县| 西藏| 延吉市| 哈尔滨市| 安庆市| 博野县| 康定县| 德格县| 洛南县| 南和县| 辽阳县| 炎陵县| 河北区| 淮北市| 景泰县| 江陵县| 永昌县| 玉树县| 托里县| 白城市| 凌海市| 宣威市|