【问题标题】:Reading Win32 variables读取 Win32 变量
【发布时间】:2012-06-20 19:12:29
【问题描述】:

如果我可以挂接到 Win32 进程,我能做到吗:

  • 从进程内部的类中读取变量?

  • 我有上面 Win32 应用程序的完整源代码,我可以将其用作本主题的参考吗?

干杯。

【问题讨论】:

  • 如果您可以找到变量的存储位置,并且拥有正确的权限,请继续:ReadProcessMemory。这并不是说这是您在大多数情况下特别想做的事情。
  • -1,你能澄清你在这里问什么吗?我完全不明白。
  • @MichaelKristofik 他想编写一个程序来附加到一个已经运行的程序以读取类中变量的内容。他有这个正在运行的程序的源代码。基本上他想实现一个调试器的基本组件(变量监视/检查)。
  • 你能澄清一下你所说的“挂钩”这个过程是什么意思吗?您是否像调试器一样附加到它(因此实际上在单独的进程中运行)?您是否将代码注入进程(并因此在该进程的地址空间中运行)?你在写一个 HookProc 吗?
  • @AdrianMcCarthy 不像调试器,更具体地说是加载 DLL 的进程。抱歉,这个词含糊不清。

标签: c++ winapi


【解决方案1】:

是的。一旦您的模块被挂接到进程中,您就共享相同的地址空间。这意味着您可以访问进程已分配的内存(例如,用于类实例)。

如果您知道类实例的偏移量,那么您可以:

  • 将此内存地址转换为指向类的指针(前提是包含类头)
  • 使用此内存地址的偏移量来访问类的成员。

请参阅 MSDN 上的 Traversing the Module List。一旦你有了想要“挂钩”的进程的MODULEENTRY32,你就可以使用modBaseAddr作为你的偏移量的基础。例如,如果您知道指向类实例的全局变量位于 0x000AD421,您可以这样做:

ClassName *pClassBase = moduleEntry->modBaseAddr + 0x000AD421;
pClassBase->UseSomeFunctions();

unsigned char *pClassBase = moduleEntry->modBaseAddr + 0x000AD421; // if we don't know the exact definition of the class we want to play with
float flMemberValue = *reinterpret_cast<float*>((unsigned char *)pClassBase + 24); // float member value at offset 24
// value of member is flMemberValue

*reinterpret_cast<float*>((unsigned char *)pClassBase + 24) = 15.25; // setting the same member value to 15.25.

正如其他评论者所说,找到类基的偏移量是这个过程中最难的部分。但是,如果您有方便的类定义,这基本上是您必须做的唯一工作(即您也不必找到类成员偏移量)。

【讨论】:

  • 主要问题是找到东西的地址。非调试版本将删除大部分元数据,这使得查找任何非全局的东西变得相当复杂(在某些情况下甚至是一堆东西)。
  • 非常如此。检查等效的 Linux 二进制文件通常更容易(编译的程序集与我的经验相似),然后在运行时使用签名扫描来查找偏移量。提问者已经知道如何加入这个过程这一事实让我相信他已经有了偏移量。如果不是,那么这是一个完全不同的问题。
  • @SaulRennison 你的意思是如果宿主进程加载一个DLL,你的意思是DLL可以访问宿主进程中的类成员变量?另外,如果我有 exe 文件,我可以检查它并在运行时进行签名扫描,也就是实际加载 DLL 的时候?此外,您的意思是 dll 可以对其主机进程进行签名扫描?
  • @SaulRennison 我能够对 DLL 进行编码,使其可以获取其父进程 ID
  • @SaulRennison 你的想法是最好的,我可以接受这个答案,尽管我仍然需要知道如何获取成员变量的偏移量;因为我刚刚问过我的想法是否可行。
猜你喜欢
  • 1970-01-01
  • 2023-04-07
  • 2012-05-21
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 2010-10-16
  • 2014-10-28
  • 2010-11-26
相关资源
最近更新 更多