【问题标题】:WriteProcessMemory to memcpyWriteProcessMemory 到 memcpy
【发布时间】:2014-08-10 22:27:06
【问题描述】:

我想将我的挂钩方法转换为更有效的方式。我当前的代码使用 WriteProcessMemory() 和 GetCurrentProcess(),这完全没用。我认为一个简单的 memcpy 可以很容易地做同样的事情。这是我尝试做的:

DWORD dwAddr = (DWORD)GetProcAddress(lpModule, lpFuncName);
BYTE jmp[6] = { 0xe9, 0x00, 0x00, 0x00, 0x00, 0xc3 };

memcpy((LPVOID)dwAddr, &jmp[0], 6);
//WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, jmp, 6, 0);

WriteProcessMemory API 运行良好,但使用我的自定义 memcpy 时,它无法运行。谁能告诉我我在哪里失败了?

【问题讨论】:

  • 太宽泛了——“不起作用”是一个无用的问题描述符。
  • 对不起,你是对的。在我的情况下,“不起作用”意味着字节没有被复制到 dwAddr。
  • 什么,就这样?之后它们是相同的字节吗?应用程序因错误而崩溃?究竟会发生什么?
  • 它没有崩溃,字节和以前一样。

标签: c++ memory-management


【解决方案1】:

WriteProcessMemory() 的全部意义在于写入另一个进程的虚拟内存。你不需要它来编辑你自己的进程虚拟内存。

但是,您必须确保您有权修改该特定地址中的数据。即使内存是你的,它也可能是只读的,系统内核会强制执行。

使用VirtualProtect() 更改您尝试修改的内存空间的权限。

另外,请注意,当您覆盖该地址中的数据时,您正在破坏原始功能代码。 这不是挂钩 Windows API 的方法。

如果你感兴趣,我有this function that hooks APIs。它用您在 PE 表中的原始函数指针替换原始函数指针,同时返回原始函数指针,以便您以后使用。不幸的是,它已经过时了,应该只适用于 32 位。

【讨论】:

  • 是否在 WriteProcessMemory API 中自动检查?因为它正在使用它。我理解,有可能它是不可写的,但在目前的情况下,我确信内存空间是可写的。
  • @user 它肯定是不可写的,因为它是代码
  • 好吧,好吧。你是对的。我正在尝试在复制之前添加 VirtualProtect。
  • @Havenard 我没有破坏原始功能。我存了,还有一些其他的代码,这里没必要写。
  • 对不起,真的是我的错。我无法确保内存区域是可写的。添加 VirtualProtect 后,它工作得很好。对不起,谢谢!
【解决方案2】:

在这里使用memcpy 完全没有问题。但是,您需要使用VirtualProtect 将目标的保护标志更改为PAGE_EXECUTE_READWRITE。完成写入后恢复原始保护。

如果您的目标是 x86/x64,这就是您需要做的所有事情。对于其他架构,您需要致电 FlushInstructionCache

存储指向DWORD 的指针也是错误的。不要转换GetProcAddress 的返回值。它是一个指针。

【讨论】:

  • 当然,我刚刚意识到这两个答案都是有效的。 “不工作”的 OP 不够清晰。
  • 我只针对 x86/x64。一个小问题:如果它失败了,例如因为我没有设置 VirtualProtect,那么为什么 WriteProcess 也没有失败?它会在 WriteProcess API 内部自动检查吗?
  • WriteProcess 映射内存(显然是可写的),然后写入内核内部的内存。这与 VirtualProtect 的作用相同。
  • WriteProcessMemory 正在修改保护标志。我猜。
  • 对不起,真的是我的错。我无法确保内存区域是可写的。添加 VirtualProtect 后,它工作得很好。对不起,谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-04-17
  • 1970-01-01
  • 1970-01-01
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-10
相关资源
最近更新 更多