gpt4 book ai didi

c++ - 新创建的暂停进程的 EIP 仅在 Windows XP 上失败 - kernel32.dll 镜像下的 EIP?

转载 作者:太空狗 更新时间:2023-10-29 20:04:49 24 4
gpt4 key购买 nike

我的程序在 Windows Vista Ultimate 和 Windows 7 上运行完美,但在 Windows XP 上运行失败。

首先,我的应用程序创建一个系统文件进程,它调用 GetThreadContext(remote_thread) 并将 LPVOID 值设置为值 context->Eip,然后检查从 VirtualQueryEx 设置的结构 MEMORY_BASIC_INFORMATION 中的值。

以下是调用 VirtualQueryEx 时返回的值:

Windows XP

  • 0 - 分配基础
  • 0 - 分配保护
  • 2088828928 - 基地址
  • 1 - 保护
  • 983040 - 区域大小
  • 65536 - 状态
  • 0 - 类型

Windows 7

  • 2003959808 - 分配基数
  • 128 - 分配保护
  • 2004025344 - 基址
  • 32 - 保护
  • 876544 - 区域大小
  • 4096 - 状态
  • 16777216 - 类型

Windows Vista

  • 2006122496 - 分配基数
  • 128 - 分配保护
  • 2006536192 - 基址
  • 32 - 保护
  • 389120 - 区域大小
  • 4096 - 状态
  • 16777216 - 类型

为什么当我在 Windows XP 上运行我的应用程序时它没有分配基础和分配保护,以及与 Windows 7 和 Windows Vista 完全不同的值。

我计划在地址 (context->Eip) 上使用 VirtualProtectEx,所以如果这些是 XP 上的值,那么 VirtualProtectEx 将不可避免地失败,因为我将访问无法访问的内存。

这是我创建流程的方式:

    if ( CreateProcessW(m_pwszContainerPath, NULL, NULL, NULL, FALSE, DETACHED_PROCESS | CREATE_SUSPENDED, NULL, NULL, &m_stStartInfo, &m_stProcessHandles) == TRUE )
{
// Get context of thread
m_stContext.ContextFlags = CONTEXT_FULL;
if ( GetThreadContext(m_stProcessHandles.hThread, &m_stContext) == FALSE )
goto _CLEANUP;
// Grab, Eip
m_pvLdrInitEip = (LPVOID)m_stContext.Eip;
}

事实是:这在 Windows 7 和 Windows Vista 上都能完美运行。

我在这里遗漏了什么吗?感谢您的帮助。

编辑 - 这是一张图片:

Windows 7 Windows XP Windows XP displaying where the EIP in memory is.. Windows 7 showing the address is in ntdll这是运行可执行文件的两个 olly 实例的图片,一个在 XP 虚拟机中,一个在外部。据我所知,XP 图片(下图)将 EIP 设置为 ModuleEntryPoint,而 Windows 7 实例将其设置为 ntdll..

我进一步调查,发现 EIP 实际上在 kernel32.dll 镜像中(在 Windows XP 上),而不是它应该在的 ntdll.dll..

最佳答案

使用 CREATE_SUSPENDED 创建进程意味着主进程不会在您运行代码之前完成初始化。加载程序的实现方式导致 XP 和 Vista/7 之间的不同效果,并且由于 CREATE_SUSPENDED 文档不授予任何进程初始化,因此您不能真正依赖该方法。 CREATE_SUSPENDED 标志仅说明进程是在主线程挂起的情况下创建的。
目前尚不清楚 OP 希望实现什么,但想到了一些实现类似目标的方法:

  1. 编写调试器而不是远程操作另一个进程。可以找到一个简单的教程和代码示例 Here .调试器为每个生成的线程获取一个事件,您可能会使用它。

  2. 通过为您的代码创建一个新部分并在 PE 中放置一个 TLS 条目以在进程的内存空间内执行代码,修改 PE 以在任何其他代码之前执行您的代码。然后,您的代码将在进程的 EntryPoint 之前但在初始化之后运行。

  3. 修改PE,将PE头中的EntryPoint替换为自己的代码,确保自己执行原入口点即可。将缺少一些初始化,但将加载所有 PE 代码部分。

  4. 通过创建挂起的 DLL 并从不同的线程加载 DLL 或任何其他方法,将 DLL 注入(inject)进程的内存地址。 This文章列出了一些,你可以谷歌更多。如果你因为类似的问题想要初始化进程,我不确定这在所有情况下都有效,但我确实认为调用 LoadLibrary 会给你带来想要的效果。这也是一种将代码放入另一个进程并对其进行操作的干净方法,同时比使用调试器更隐蔽。

  5. 您还可以尝试在进程挂起时扫描整个内存以查找您要操作的代码块,这在 XP 上也可能有效。

  6. 您可以尝试创建未挂起的进程,并在挂起线程之前让它运行一小段时间。在计时和一些测试之后,您将对初始化需要多少时间有一个合理的感觉。这有点冒险,但可能会奏效。

创建调试器将是最简单、最可靠/通用的方法,但缺点是容易被检测到(尽管您可以使用反反调试技巧)。加载 DLL 将是最好的方法,如果你想保持不被操纵进程检测到(如果它有任何反调试技巧)完成,因为您的问题尚不清楚。有关该程序的更多详细信息(例如它是 native 的还是 .net 的)也会有所帮助。

编辑: friend 提出的另一个推测是,当系统调用返回并且您调用 VirtualQueryEx 时,内核尚未完成进程初始化。他说在进程的句柄上调用 WaitForSingleObject 将在进程完全初始化后返回,您可以访问所有信息并在之后恢复执行。

关于c++ - 新创建的暂停进程的 EIP 仅在 Windows XP 上失败 - kernel32.dll 镜像下的 EIP?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16882766/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com