【问题标题】:Unable to write to process memory无法写入进程内存
【发布时间】:2013-11-08 12:57:27
【问题描述】:

我正在尝试解决我不熟悉的代码中的问题。我已经追踪到调用 WriteProcessMemory 总是以ERROR_INVALID_ADDRESS 失败。我不知道它为什么会失败。我尝试检查我的进程是否具有使用VirtualQUery 写入其子进程所需的访问权限,并且确实如此。任何人都可以对此有所了解吗?代码路径非常复杂,所以我跳过了很多。如果遗漏任何信息,请告诉我。

CreateProcessAsUserW(hToken, exe, cmd_line, 
NULL, // No security attribute.
NULL, // No thread attribute.
false, // do not inherit handles
CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS | EXTENDED_STARTUPINFO_PRESENT | CREATE_BREAKAWAY_FROM_JOB, // start suspended, extended startup info, break out of job
NULL, // Use the environment of the caller
NULL, // Use current directory of the caller.
&si, 
&pi);

/*
 ....lots of work here
*/

void* address = {...};
void* var = address;   // note this line

SIZE_T written;
if(!WriteProcessMemory( pi.handle, 
var, address,  // not completely sure what it is doing here - writing contents of address to address of var?
size, &written))
{
    DWORD error = GetLastError();     // ERROR_INVALID_ADDRESS
    MEMORY_BASIC_INFORMATION buffer;
    SIZE_T num = VirtualQuery(address,&buffer,sizeof(MEMORY_BASIC_INFORMATION));
    if(num > 0)
    {
        DWORD access = buffer.AllocationProtect;  // PAGE_EXECUTE_WRITECOPY
        DWORD state = buffer.State; // MEM_COMMIT
        DWORD type = buffer.Type;
    }
}

这是一个在 64 位 Win7 上运行的 32 位进程。

【问题讨论】:

  • 看起来就像它试图将数据从一个进程复制到一个相同的进程,假设结构将位于相同的地址。 ASLR 在较新的操作系统上不一定是这样,即使它从同一个二进制文件启动一个新进程。
  • @JoachimIsaksson ASLR 已为进程 /DYNAMICBASE:NO 禁用
  • 您应该提供有关意图和上下文的更多信息。特别是,什么是真正的 void* address = {...}

标签: winapi shared-memory createprocess


【解决方案1】:

在尝试写入另一个进程之前,您正在执行本地 VirtualQuery,其地址空间可能大不相同。

如果您想确保在该进程的地址空间中有一个有效的指针,您可以找到该进程将您感兴趣的内容放在哪里(祝您好运,ASLR),或者您在该进程中为您分配一些内存(使用,说 VirtualAllocEx())。

注意:如果你真的想要共享内存,你应该改用 CreateFileMapping(INVALID_HANDLE_VALUE)。

【讨论】:

  • 我正在执行 VirtualQuery after WriteProcessMemory 无法验证我是否确实具有所需的访问级别。我可以删除它而不会产生任何影响。我也很惊讶地址实际上是在本地分配的。你是说它一定会失败吗?即使被写入的进程是相同的,因此结构位于相同的地址?显然,这段代码直到几天前还在工作。
  • 重新阅读答案。您的 VirtualQuery 是您的进程的本地查询,而不是您尝试写入的进程。
  • 好的。知道了。那是我的愚蠢。那么如何检查我必须写入该进程的访问级别。显然,我没有足够的写入失败。
  • @341008 我认为访问权限问题不会给你ERROR_INVALID_ADDRESS...使用VirtualQueryEx检查其他进程中的内存
猜你喜欢
  • 1970-01-01
  • 2011-09-09
  • 2013-08-10
  • 2013-11-28
  • 2016-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多