Windows系统调用中API的3环部分(依据分析重写ReadProcessMemory
Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html Windows系统调用中API的3环部分 ? 一、R3环API分析的重要性
? 二、调试代码 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 指针中写入数据,再用ReadProcessMemory读取数据 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,&t,NULL); 20 printf("%dn",t); 21 } 22 getchar(); 23 getchar(); 24 25 } ? 三、调试中的关键汇编代码(系统环境:在Windows7 32位操作系统 / 调试器:olldbg) ? ? ? ? 1. 在exe 中 调用 kernel32.ReadProcessMemroy函数 2. 在 kernel32.ReadProcessMemroy函数 中调用 jmp.&API-MS-Win-Core-Memory-L1-1-0.ReadProcessMemory> 函数 3. 在 API-MS-Win-Core-Memory-L1-1-0.ReadProcessMemo 中调用 KernelBa.ReadProcessMemory 函数 4. 在KernelBa.ReadProcessMemory 调用 <&ntdll.NtReadVirtualMemory> 函数 5. 在 <&ntdll.NtReadVirtualMemory> 中调用 ntdll.KiFastSystemCall 函数 6. 在 ntdll.KiFastSystemCall 中 调用sysenter ? 四、汇编代码分析解读(根据三中的序号依次解读)
五、重写ReadProcessMemory函数的思路 我们所看到的汇编代码,本质就是Windows所执行的步骤,我们依据上面的分析,完全可以重新写一个该函数,只需要关键部分。 1) 退而求其次 我们希望可以在自己的代码中直接使用 "sysenter",但经过编写发现其并没有提供这种指令。 因此在"sysenter"无法直接使用的情况下,只能退而求其次,调用ntdll.KiFastSystemCall函数。 2)传递参数,模拟call指令 ntdll.KiFastSystemCall函数需要借助ntdll.NtReadVirtualMemory传递过来的参数,然后执行call指令。 我们并不希望执行call指令执行,因为执行call指令意味着又上了一层。(多一层被钩取的风险) 我们希望自己的代码中直接传递参数,并且直接调用调用ntdll.KiFastSystemCall函数。 因此我们需要模拟call指令。call指令的本质就是将返回地址入栈,并跳转。我们不需要跳转,只需要将返回地址入栈(四个字节 使用 sub esp,4 模拟) 3)手动实现栈平衡 我们内嵌汇编代码后,需要手动平衡栈,我们只需要分析esp改变了多少(push、pop以及直接对esp的计算)。 经过分析共减少了24字节,所以代码最后应该有 add esp,24 来平衡栈。 ? 六、ReadProcessMemory函数重写的实现(重点看汇编代码) 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不能直接调用,我间接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,a);
30 ReadMemory((HANDLE)-1,(PVOID)&t,&pBuffer,sizeof(int),0); 31 printf("%Xn",pBuffer); 32 ReadProcessMemory((HANDLE)-1,0); 33 printf("%Xn",pBuffer); 34
35 getchar(); 36 return 0; 37 }
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 如何使用命令行界面管理远程Windows Server?
- Windows上的低级是什么:C库或相应的Win32 API函数?
- Win7安装Oracle10 无法定位程序输入点GetProcessImageFileN
- 如何在Windows操作系统中配置或安装GEARMAN?
- active-directory – 在Windows Server 2008 R2中监视Activ
- osx – 在Windows上开发Mac OS X?
- windows-server-2003 – 如何创建PDF打印服务器?
- 配置exim4以将Microsoft Exchange用作smarthost
- WinRT和XAML – 资源文件,但语言不是本地化?
- Dll高级技术之【延迟加载】