小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Windows系統(tǒng)調(diào)用中API的3環(huán)部分(依據(jù)分析重寫(xiě)ReadProcessMemory函數(shù))

 印度阿三17 2019-10-19

Windows內(nèi)核分析索引目錄:https://www.cnblogs.com/onetrainee/p/11675224.html

Windows系統(tǒng)調(diào)用中API的3環(huán)部分

?

一、R3環(huán)API分析的重要性

  1. Windows所提供給R3環(huán)的API,實(shí)質(zhì)就是對(duì)操作系統(tǒng)接口的封裝,其實(shí)現(xiàn)部分都是在R0實(shí)現(xiàn)的。
  2. 很多惡意程序會(huì)利用鉤子來(lái)鉤取這些API,從而達(dá)到截取內(nèi)容,修改數(shù)據(jù)的意圖。
  3. 現(xiàn)在我們使用olldbg對(duì)ReadProcessMemory進(jìn)行跟蹤分析,查看其在R3的實(shí)現(xiàn),并根據(jù)我們的分析來(lái)重寫(xiě)一個(gè)ReadProcessMemory。
  4. 重寫(xiě)ReadProcessMemory之后,這就會(huì)加大惡意代碼截獲的難度。
  5. 當(dāng)然,對(duì)于自己來(lái)說(shuō)也有很多弊端,比如只能在指定的操作系統(tǒng)中運(yùn)行(32位與64位操作系統(tǒng),其運(yùn)行ReadProcessMemory的執(zhí)行動(dòng)作是不一樣的,在64位運(yùn)行32位程序,其中間會(huì)調(diào)用wow64cpu.dll來(lái)進(jìn)行轉(zhuǎn)換)

?

二、調(diào)試代碼

 1 #include "pch.h"
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <Windows.h>
 5 
 6 int main() {
 7     getchar();
 8     getchar();
 9     int a[4],t;
10     printf("hello world!");
11     getchar();
12     getchar();
13     // 依次往 p 指針中寫(xiě)入數(shù)據(jù),再用ReadProcessMemory讀取數(shù)據(jù)
14     for (int i = 0; i < 4; i  ) {
15         WriteProcessMemory(INVALID_HANDLE_VALUE, &a[i], &i, sizeof(int),NULL);
16         
17     }
18     for (int i = 0; i < 4; i  ) {
19         ReadProcessMemory(INVALID_HANDLE_VALUE, &a[i], &t, sizeof(int), NULL);
20         printf("%d\n", t);
21     }
22     getchar();
23     getchar();
24     
25 }

?

三、調(diào)試中的關(guān)鍵匯編代碼(系統(tǒng)環(huán)境:在Windows7 32位操作系統(tǒng) / 調(diào)試器:olldbg)

?

?

?

?

1. 在exe 中 調(diào)用 kernel32.ReadProcessMemroy函數(shù)
  01314E3E??? 8BF4???????? mov esi,esp
  01314E40??? 6A 00??????? push 0x0
  01314E42??? 6A 04??????? push 0x4
  01314E44??? 8D45 DC????? lea eax,dword ptr ss:[ebp-0x24]
  01314E47??? 50?????????? push eax
  01314E48??? 8B4D C4????? mov ecx,dword ptr ss:[ebp-0x3C]
  01314E4B??? 8D548D E8??? lea edx,dword ptr ss:[ebp ecx*4-0x18]
  01314E4F??? 52?????????? push edx
  01314E50??? 6A FF??????? push -0x1
  01314E52??? FF15 64B0310>call dword ptr ds:[<&KERNEL32.ReadProcessMemory>]; kernel32.ReadProcessMemory
  01314E58??? 3BF4???????? cmp esi,esp

2. 在 kernel32.ReadProcessMemroy函數(shù) 中調(diào)用 jmp.&API-MS-Win-Core-Memory-L1-1-0.ReadProcessMemory> 函數(shù)
  // 該函數(shù)相當(dāng)于什么也沒(méi)做...
  7622C1CE >? 8BFF???????????? mov edi,edi
  7622C1D0??? 55?????????????? push ebp
  7622C1D1??? 8BEC???????????? mov ebp,esp
  7622C1D3??? 5D?????????????? pop ebp?????????????????????????????????????????????????????????? ;
  7622C1D4? ^ E9 F45EFCFF????? jmp <jmp.&API-MS-Win-Core-Memory-L1-1-0.ReadProcessMemory>

3. 在 API-MS-Win-Core-Memory-L1-1-0.ReadProcessMemo 中調(diào)用 KernelBa.ReadProcessMemory 函數(shù)
  761F20CD? - FF25 0C191F7>jmp dword ptr ds:[<&API-MS-Win-Core-Memory-L1-1-0.ReadProcessMemo>; KernelBa.ReadProcessMemory

4. 在KernelBa.ReadProcessMemory 調(diào)用 <&ntdll.NtReadVirtualMemory> 函數(shù)
  75DA9A0A >? 8BFF???????? mov edi,edi
  // 這兩部分在編寫(xiě)函數(shù)時(shí)就會(huì)使用
  75DA9A0C??? 55?????????? push ebp
  75DA9A0D??? 8BEC???????? mov ebp,esp
  75DA9A0F??? 8D45 14????? lea eax,dword ptr ss:[ebp 0x14]
  75DA9A12??? 50?????????? push eax
  75DA9A13??? FF75 14????? push dword ptr ss:[ebp 0x14]
  75DA9A16??? FF75 10????? push dword ptr ss:[ebp 0x10]
  75DA9A19??? FF75 0C????? push dword ptr ss:[ebp 0xC]
  75DA9A1C??? FF75 08????? push dword ptr ss:[ebp 0x8]
  75DA9A1F??? FF15 C411DA7>call dword ptr ds:[<&ntdll.NtReadVirtualMemory>] ; ntdll.ZwReadVirtualMemory

5. 在 <&ntdll.NtReadVirtualMemory> 中調(diào)用 ntdll.KiFastSystemCall 函數(shù)
  77A162F8 >? B8 15010000? mov eax,0x115? // 對(duì)應(yīng)操作系統(tǒng)內(nèi)核中某一函數(shù)的編號(hào)。
  77A162FD??? BA 0003FE7F? mov edx,0x7FFE0300? // 該地方是一個(gè)函數(shù),該函數(shù)決定了什么方式進(jìn)零環(huán)。
  77A16302??? FF12???????? call dword ptr ds:[edx]? ; ntdll.KiFastSystemCall

6. 在 ntdll.KiFastSystemCall 中 調(diào)用sysenter
  77A170B0 >? 8BD4???????? mov edx,esp
  77A170B2??? 0F34???????? sysenter
  77A170B4 >? C3?????????? retn

?

四、匯編代碼分析解讀(根據(jù)二中的序號(hào)依次解讀)

  1. 這部分是我們程序中調(diào)用ReadProcessMemory后編譯器直接編譯后的匯編代碼,傳入?yún)?shù)與API調(diào)用
  2. 在kenel32.dll中,mov edi,edi 是用于熱補(bǔ)丁技術(shù)所保留的(函數(shù)開(kāi)始處的MOV EDI, EDI的作用),這段代碼仔細(xì)看其實(shí)除了jmp什么也沒(méi)干。
  3. 轉(zhuǎn)到kernelBase.dll中實(shí)現(xiàn)ReadProcessMemory。
  4. 這段匯編代碼,將ReadProcessMemory中傳入的參數(shù)再次入棧,調(diào)用ntdll.ZwReadVirtualMemory函數(shù)。
  5. 這段匯編代碼看注釋,eax中存放了一個(gè)編號(hào),其就是在內(nèi)核中的ReadProcessMemory實(shí)現(xiàn);在 0x7FFE0300 處存放了一個(gè)函數(shù)指針,該函數(shù)指針決定了以什么方式進(jìn)入0環(huán)(中斷/快速調(diào)用)。
  6. 在ntdll.KiFastSystemCall調(diào)用sysenter。

五、重寫(xiě)ReadProcessMemory函數(shù)的思路

  我們所看到的匯編代碼,本質(zhì)就是Windows所執(zhí)行的步驟,我們依據(jù)上面的分析,完全可以重新寫(xiě)一個(gè)該函數(shù),只需要關(guān)鍵部分。

  1) 退而求其次

    我們希望可以在自己的代碼中直接使用 "sysenter",但經(jīng)過(guò)編寫(xiě)發(fā)現(xiàn)其并沒(méi)有提供這種指令。

    因此在"sysenter"無(wú)法直接使用的情況下,只能退而求其次,調(diào)用ntdll.KiFastSystemCall函數(shù)。

  2)傳遞參數(shù),模擬call指令

    ntdll.KiFastSystemCall函數(shù)需要借助ntdll.NtReadVirtualMemory傳遞過(guò)來(lái)的參數(shù),然后執(zhí)行call指令。

    我們并不希望執(zhí)行call指令執(zhí)行,因?yàn)閳?zhí)行call指令意味著又上了一層。(多一層被鉤取的風(fēng)險(xiǎn))

    我們希望自己的代碼中直接傳遞參數(shù),并且直接調(diào)用調(diào)用ntdll.KiFastSystemCall函數(shù)。

    因此我們需要模擬call指令。call指令的本質(zhì)就是將返回地址入棧,并跳轉(zhuǎn)。我們不需要跳轉(zhuǎn),只需要將返回值入棧(四個(gè)字節(jié) sub esp,4)

  3)手動(dòng)實(shí)現(xiàn)棧平衡

    我們內(nèi)嵌匯編代碼后,需要手動(dòng)平衡棧,我們只需要分析esp改變了多少(push、pop以及直接對(duì)esp的計(jì)算)。

    經(jīng)過(guò)分析共減少了24字節(jié),所以代碼最后應(yīng)該有 add esp,24 來(lái)平衡棧。

?

六、ReadProcessMemory函數(shù)重寫(xiě)的實(shí)現(xiàn)(重點(diǎn)看匯編代碼)

(執(zhí)行結(jié)果)

 1 #include "pch.h"
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <Windows.h>
 5 void  ReadMemory(HANDLE hProcess, PVOID pAddr, PVOID pBuffer, DWORD dwSize, DWORD  *dwSizeRet)
 6 {
 7 
 8     _asm
 9     {
10         lea     eax, [ebp   0x14]
11         push    eax
12         push[ebp   0x14]
13         push[ebp   0x10]
14         push[ebp   0xc]
15         push[ebp   8]
16         sub esp, 4
17         mov eax, 0x115
18         mov edx, 0X7FFE0300   //sysenter不能直接調(diào)用,我間接call的
19         CALL DWORD PTR[EDX]
20         add esp, 24
21 
22     }
23 }
24 int main()
25 {
26     HANDLE hProcess = 0;
27     int t = 123;
28     DWORD pBuffer;
29     //hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0,a);
30     ReadMemory((HANDLE)-1, (PVOID)&t, &pBuffer, sizeof(int), 0);
31     printf("%X\n", pBuffer);
32     ReadProcessMemory((HANDLE)-1, &t, &pBuffer, sizeof(int), 0);
33     printf("%X\n", pBuffer);
34 
35     getchar();
36     return 0;
37 }

?

?

?

  

    

來(lái)源:https://www./content-3-512401.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多