网站改版方案,可信赖的武进网站建设,迁西个人网页设计制作软件,广州注册公司网址WindowsAPI函数的调用过程什么是WindowsApi#xff1f;Windows API#xff08;Application Programming Interface#xff0c;应用程序编程接口#xff09;是微软为Windows操作系统提供的一套系统级编程接口#xff0c;允许开发者与操作系统内核、硬件、系统服务等进行交互…WindowsAPI函数的调用过程什么是WindowsApiWindows APIApplication Programming Interface应用程序编程接口是微软为Windows操作系统提供的一套系统级编程接口允许开发者与操作系统内核、硬件、系统服务等进行交互。它是开发Windows应用程序的基础几乎所有Windows软件包括系统工具、驱动程序、桌面应用等都直接或间接依赖于Windows API
WindowsApi主要存放在C:\Windows\system32下的所有.dll文件
几个重要的DLl
Kernel32.dll最核心的功能模块比如管理内存进程和线程相关的函数等User32.dll是Windows用户界面相关应用程序接口如创建窗口和发送消息等。GDI32.dll图形设备接口包含用于画图和显示NTdll.dll大多数的Api都会通过这个dll进入内核0环
分析ReadProcessMemory函数
使用IDA Pro打开Kernel32.dll这个DLL中就有ReadProcessMemory在windows7系统之后 微软把很多内部函数的实现细节放到了KernelBase.dll这个DLL当中Kernel32.dll在后面的系统为了兼容任然存在这里我们直接分析KernelBase.dllx86这里就是它32位的ReadProcessMemory的代码
.text:10152910 ; BOOL __stdcall ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead)
.text:10152910 public _ReadProcessMemory20
.text:10152910 _ReadProcessMemory20 proc near ; CODE XREF: EnumProcessModulesInternal(x,x,x,x,x)55↑p
.text:10152910 ; EnumProcessModulesInternal(x,x,x,x,x)74↑p ...
.text:10152910
.text:10152910 NumberOfBytesRead dword ptr -4
.text:10152910 hProcess dword ptr 8
.text:10152910 lpBaseAddress dword ptr 0Ch
.text:10152910 lpBuffer dword ptr 10h
.text:10152910 nSize dword ptr 14h
.text:10152910 lpNumberOfBytesRead dword ptr 18h
.text:10152910
.text:10152910 ; FUNCTION CHUNK AT .text:101E1E90 SIZE 0000000E BYTES
.text:10152910
.text:10152910 mov edi, edi ; 热补丁占用
.text:10152912 push ebp ; ebp入栈
.text:10152913 mov ebp, esp ; 提升堆栈
.text:10152915 push ecx ; 提升栈相当于sub esp,4
.text:10152916 lea eax, [ebpNumberOfBytesRead] ; 获取ebp-4位置的地址给eax
.text:10152919 push eax ; NumberOfBytesRead 参数5: 实际读取字节数的指针
.text:1015291A push [ebpnSize] ; NumberOfBytesToRead 参数4: 要读取的字节数
.text:1015291D push [ebplpBuffer] ; Buffer 参数3: 目标缓冲区
.text:10152920 push [ebplpBaseAddress] ; BaseAddress 参数2: 源内存地址
.text:10152923 push [ebphProcess] ; ProcessHandle 参数1: 进程句柄
.text:10152926 call ds:__imp__NtReadVirtualMemory20 ; 调用内核函数
.text:1015292C mov edx, [ebplpNumberOfBytesRead] ; 取lpNumberOfBytesRead指针
.text:1015292F test edx, edx ; 判断参数lpNumberOfBytesRead是否为空
.text:10152931 jnz short loc_10152946 ; 不等于0则跳转
.text:10152933
.text:10152933 loc_10152933: ; CODE XREF: ReadProcessMemory(x,x,x,x,x)3B↓j
.text:10152933 test eax, eax ; 判断是否成功执行函数
.text:10152935 js loc_101E1E90 ; 为负数失败则跳转
.text:1015293B mov eax, 1 ; 成功返回1
.text:10152940
.text:10152940 loc_10152940: ; CODE XREF: ReadProcessMemory(x,x,x,x,x)8F589↓j
.text:10152940 mov esp, ebp ; 还原栈底
.text:10152942 pop ebp ; 恢复ebp
.text:10152943 retn 14h ; 栈内平衡
.text:10152946 ; ---------------------------------------------------------------------------
.text:10152946
.text:10152946 loc_10152946: ; CODE XREF: ReadProcessMemory(x,x,x,x,x)21↑j
.text:10152946 mov ecx, [ebpNumberOfBytesRead] ; 从局部变量加载实际读取的字节数
.text:10152949 mov [edx], ecx ; 写入lpNumberOfBytesRead
.text:1015294B jmp short loc_10152933 ; 返回
.text:1015294B _ReadProcessMemory20 endpx64这里就是它64位的ReadProcessMemory的代码
.text:00000001800BBF70 ; 由于x64的调用约定前4个参数是由rcx,rdx,r8,r9来传递的
.text:00000001800BBF70
.text:00000001800BBF70 ; BOOL __stdcall ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead)
.text:00000001800BBF70 public ReadProcessMemory
.text:00000001800BBF70 ReadProcessMemory proc near ; CODE XREF: WerpReadPeb32FromProcessEA↓p
.text:00000001800BBF70 ; tip2::details::recover_vectortip2::details::TestData *(void * const,void const *,tip2::vector_nothrowtip2::details::TestData * )3D↓p ...
.text:00000001800BBF70
.text:00000001800BBF70 NumberOfBytesRead qword ptr -28h
.text:00000001800BBF70 var_18 qword ptr -18h
.text:00000001800BBF70 lpNumberOfBytesRead qword ptr 28h
.text:00000001800BBF70
.text:00000001800BBF70 sub rsp, 48h ; 分配48h(72)字节的栈空间
.text:00000001800BBF74 lea rax, [rsp48hvar_18] ; 获取局部变量var_18的地址
.text:00000001800BBF79 mov [rsp48hvar_18], 0 ; 初始化var_18为0
.text:00000001800BBF82 mov [rsp48hNumberOfBytesRead], rax ; NumberOfBytesRead
.text:00000001800BBF87 call cs:__imp_NtReadVirtualMemory ; 调用内核函数
.text:00000001800BBF8E nop dword ptr [raxrax00h] ; 什么都不做字节对齐
.text:00000001800BBF93 mov rcx, [rsp48hlpNumberOfBytesRead] ; 获取lpNumberOfBytesRead地址值给rcx
.text:00000001800BBF98 test rcx, rcx ; 是否为null
.text:00000001800BBF9B jz short loc_1800BBFA5 ; 为null则跳过
.text:00000001800BBF9D mov rdx, [rsp48hvar_18] ; 获取实际读取的字节数
.text:00000001800BBFA2 mov [rcx], rdx ; 保存到lpNumberOfBytesRead指针
.text:00000001800BBFA5
.text:00000001800BBFA5 loc_1800BBFA5: ; CODE XREF: ReadProcessMemory2B↑j
.text:00000001800BBFA5 test eax, eax ; 校验值
.text:00000001800BBFA7 js short loc_1800BBFB4 ; 为负数则跳转
.text:00000001800BBFA9 mov eax, 1 ; 设置eax为1
.text:00000001800BBFAE add rsp, 48h ; 堆栈平衡
.text:00000001800BBFB2 retn ; 返回
.text:00000001800BBFB2 ; ---------------------------------------------------------------------------
.text:00000001800BBFB3 align 4
.text:00000001800BBFB4
.text:00000001800BBFB4 loc_1800BBFB4: ; CODE XREF: ReadProcessMemory37↑j
.text:00000001800BBFB4 mov ecx, eax
.text:00000001800BBFB6 call BaseSetLastNTError ; 调用方法
.text:00000001800BBFBB xor eax, eax ; eax清0
.text:00000001800BBFBD add rsp, 48h ; 堆栈平衡
.text:00000001800BBFC1 retn ; 返回函数真正的实现是在NtReadVirtualMemory中分析NtReadVirtualMemory
查看导出表可以看到是由ntdll来提供的打开ntdll打到这个方法真正的实现是在0环实现的这里只是提供了一个接口给应用程序