首页 > 解决方案 > 使用内联 asm 调用 WriteProcessMemory 时出错

问题描述

我想使用__asm块在我的c++应用程序(msvc Visual Studio)中调用WriteProcessMemory 。

#include <windows.h>    
#include <stdio.h>
#include <iostream>
#include <memory>       
const char* TextVar = "loon";
int main(){
 auto addrof = std::addressof(TextVar);
 unsigned int address = (unsigned int)addrof;
 HANDLE ProcessHandle = GetCurrentProcess();
 //WriteProcessMemory( HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten );
 __asm 
 {
   xor  eax, eax           // clear eax
   push 0x74736554         // push "Test"
   mov  eax, esp           // mov "Test" to eax

   push 0x0                // lpNumberOfBytesWritten
   push 0x4                // nSize [strlen("Test") = 4]
   push eax                // lpBuffer - "Test"
   push [address]          // lpBaseAddress - address of TextVar
   push ProcessHandle      // hProcess - Handle of current process
   call WriteProcessMemory

   push DWORD PTR[TextVar]
   call printf             //Print TextVar
  }
  return 0;
}

但我明白了:

在 Test.exe 中的地址 0x753F288E (ucrtbase.dll) 处引发异常:0xC0000005:在 0x74736554 处读取访问冲突。

//0x753F288E - printf 地址

//0x74736554 - 我的文字 - [测试]

我究竟做错了什么?据我了解,WPM 将文本作为地址写入 TextVar。但是如何解决呢?

PS - 我不想在 c++ 中使用局部变量作为 WPM 的缓冲区。

标签: c++assemblyinline

解决方案


我相信 Windows API 使用 Pascal 调用约定,将参数从左到右推送到堆栈。您似乎正在做相反的事情,使用 C 调用约定。


推荐阅读