zoukankan      html  css  js  c++  java
  • Windows内核——直接调用0环函数实现ReadProcessMemory&WriteProcessMemory函数

    直接调用0环函数实现ReadProcessMemory&WriteProcessMemory函数

    工具

    IDA

    VC++6.0

    步骤

    一、实现ring0调用ReadProcessMemory

    1、ALT+T 找到ReadProcessMemory

    2、找到NtReadVirtualMemory(ntdll.dll)函数
    去导入表里面查看这个函数在哪个dll里

    发现这个函数也只是间接调用的一个内核函数的地址而已

    二、实现ring0调用WriteProcessMemory

    1、ALT+T 找到 WriteProcessMemory

    2、找到NtProtectVirtualMemory(ntdll.dll)函数
    去导入表里面查看这个函数在哪个dll里

    发现这个函数也只是间接调用的一个内核函数的地址而已

    从上面NtReadVirtualMemory、NtProtectVirtualMemory中的具体实现可以知道,这里调用的知识内核函数的一个地址,换个系统可能这个地址就会不一样,所以这样的函数兼容性差。

    为啥要直接调用ring0实现函数功能?

    1. Windows所提供给Ring3的API,实质就是对操作系统接口的封装,其实现部分都是在Ring0实现的。

      观察上面图中分析函数就可以很清楚的知道了。

    2. 防止恶意程序会利用钩子来钩取这些API,从而达到截取内容,修改数据的意图。

    二、实现ring0调用ReadProcessMemory

    1、汇编实现

       lea     eax, [ebp + 0x14]
    		push    eax
    		push[ebp + 0x14]
    		push[ebp + 0x10]
    		push[ebp + 0xc]
    		push[ebp + 8]
    		sub esp, 4			//调用NtReadVirtualMemory的是call xxx,实质是 将返回地址压栈&JMP,所以这里sub 4个byte实现返回地址的压栈
    			mov eax, 0x0BA
    			mov edx, 0X7FFE0300   //不能直接调用内核,间接call函数地址来实现
    			CALL DWORD PTR[EDX]
    		add esp, 24				//堆栈平衡 24=6*4
    

    2、测试

    
    #ifdef debug
    int main()
    {
    	//  HANDLE hProcess = 0;
        int t = 0x12345678;
        DWORD pBuffer;
    	//	DWORD dwChromeID = GetCurrentProcessId();
    	
    	//1、不调用dll实现ReadProcessMemory
        ReadMemory((HANDLE)-1, (PVOID)&t, &pBuffer, sizeof(int), 0);
        printf("%X
    ", pBuffer);
    	
    	//2、调用api实现
        ReadProcessMemory((HANDLE)-1, &t, &pBuffer, sizeof(int), 0);
        printf("%X
    ", pBuffer);
    	
    	//结果:1 2的结果一致
        getchar();
        return 0;
    }
    #endif
    

    第二种方法:

    #include<windows.h>
    #include<stdio.h>
    
    void __declspec(naked) read(HANDLE hProcess,LPVOID addr,LPVOID buffer,DWORD len)
    {
    	_asm
    	{
    		mov   eax, 0BAh
    		mov   edx, 7FFE0300h
    		call  dword ptr[edx]
    
    		ret
    	}
    }
    
    #ifndef debug
    int main() {
    
        int t;
    	int a[8];
    
        // 依次往 p 指针中写入数据,再用ReadProcessMemory读取数据
        for (int i = 0; i < 8; i++) {
            WriteProcessMemory(INVALID_HANDLE_VALUE, &a[i], &i, sizeof(int),NULL);
            
        }
        for (int j = 0; j < 8; j++) {
            read(INVALID_HANDLE_VALUE, &a[j], &t, sizeof(int));
            printf("%d
    ", t);
        }
        getchar();
        return 0;
    }
    #endif
    

    三、实现ring0调用WriteProcessMemory

    1、汇编实现

    void WriteMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesWritten)
    {
    	_asm{
    		push    ecx  ;Buffer
    		push    ecx
    		mov     eax, [ebp+0x0C]  ;lpBaseAddress 2
    		push    ebx
    		mov     ebx, [ebp+0x14]	 ;OldProtect??? 
    		push    edi
    		mov     edi, [ebp+8]	;ProcessHandle 1
    		mov     [ebp-8], eax	;BaseAddress 
    		lea     eax, [ebp+0x14]
    		push    eax             ; OldProtect
    		push    0x40             ; NewProtect
    		lea     eax, [ebp-4]
    		push    eax             ; ProtectSize
    		lea     eax, [ebp-8]
    		push    eax             ; BaseAddress
    		push    edi             ; ProcessHandle
    		mov     [ebp-4], ebx
    		sub esp, 4              ;call    esi ; NtProtectVirtualMemory
    			mov     eax, 0x89
    			mov     edx, 0x7FFE0300
    			call    dword ptr [edx]
    		add esp, 0x28
    	}
    }
    

    批注:这个还有些问题没想明白:这里ecx为什么要push两次???

    2、测试

    #ifndef debug
    int main() {
    
        int t;
    	int a[8];
    
        // 依次往 p 指针中写入数据,再用ReadProcessMemory读取数据
        for (int i = 0; i < 8; i++) {
            WriteMemory(INVALID_HANDLE_VALUE, &a[i], &i, sizeof(int),NULL);
            
        }
        for (int j = 0; j < 8; j++) {
            ReadProcessMemory(INVALID_HANDLE_VALUE, &a[j], &t, sizeof(int), NULL);
            printf("%d
    ", t);
        }
        getchar();
        return 0;
    }
    #endif
    
  • 相关阅读:
    数字三角形W(加强版) codevs 2189
    数字三角形W(加强版) codevs 2189
    线段树模板
    树状数组模板 洛谷3374
    洛谷 2327 [SCOI2005]扫雷
    洛谷 2327 [SCOI2005]扫雷
    洛谷1144 最短路计数
    洛谷1144 最短路计数
    洛谷1346 电车
    洛谷1346 电车
  • 原文地址:https://www.cnblogs.com/Erma/p/12917399.html
Copyright © 2011-2022 走看看