首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内核代码中的SuspendThread WOW64挂起

内核代码中的SuspendThread WOW64挂起
EN

Stack Overflow用户
提问于 2010-11-10 12:46:13
回答 4查看 2.3K关注 0票数 6

更新:微软还没有在Windows8.1中修复它。

编辑:这原来是WOW64中的错误 - GetThreadContext()可能会在长模式ring-3 (用户模式)中挂起线程时返回陈旧的内容。我已经向微软建议使用ring-2来执行翻译。然后,SuspendThread将只在ring-3中挂起线程(就像现在一样--没有必要的更改),而ring-2中的崩溃/故障/漏洞不会影响内核--它只会影响ring-2和ring-3。

这样的改变将需要更改一些WinAPI函数,如Wow64Get/SetThreadContext等。这将破坏依赖无文档化功能的应用程序,但这是意料之中的。当然,转换要慢一些,因为从ring-3过渡到ring-2需要几个CPU周期(取决于CPU系列),但我认为操作系统的作用首先是确保正确的操作。翻译已经增加了运行在WOW64下的应用程序的开销,所以这也是意料之中的。

我确实希望微软能够解决这个问题--否则在WOW64下依赖WOW64()的调试器/ Mono应用程序/ Boehm GC /应用程序将无法工作(首先,我已经看到调试器显示了陈旧的堆栈跟踪)。

EDIT2:坏消息。从我和微软(这里)的亚历克西的谈话来看,它看起来可能根本没有被修复,因为担心修复会破坏那些依赖于无文档功能的应用程序。

原始问题

  • 有些人似乎对以下问题感到困惑。我最初认为这是由于SuspendThread在内核模式代码中挂起一个线程。但事实并非如此,以下只是我最初的怀疑,结果与实际的根本原因无关--这是GetThreadContext()返回的陈腐内容。

来自MSDN:

Suspending a thread causes the thread to stop executing user-mode (application) code.

然而,我发现我在Windows 7下运行的32位应用程序,线程A调用线程B上的SuspendThread,可以在运行64位代码时暂停它(我想这不是用户模式代码)。EIP显示挂起的线程停止在

代码语言:javascript
复制
wow64cpu!X86SwitchTo64BitMode:
00000000`759c31b0 ea27369c753300  jmp     0033:759C3627

由于它的ESP已经改变(我知道这一点,因为当ESP指向与该线程的堆栈相同的页面时,它的地址比当前堆栈指针高得多)。如果我在上面返回的指令上放置一个断点,然后让线程继续运行,我发现ESP会更改回X86SwitchTo64BitMode调用之前的值(这是正确的堆栈指针)。我还发现,当单步进入同一个函数时,在单个步骤的任何一点上,我都无法得到较高的地址ESP值。实际上,在单步执行时,ESP值在X86SwitchTo64BitMode调用之前和之后都不会发生变化。

此外,我还确保了SuspendThread通过检查(DWORD)-1而获得成功。

所有这些都使我相信线程在内核模式代码中是挂起的。

是什么原因导致操作系统在运行非用户模式代码时挂起线程?我怎么才能防止这种情况?这基本上阻止了我获得线程B的实际堆栈指针。注意,当应用程序运行在WOW64之外(在原生x86操作系统上)时,不存在这样的问题。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-11-13 05:58:01

我已经确认这是一个操作系统问题,当GetThreadContext在WOW64下被调用时,返回陈旧的内容。

这里有更多的信息

感谢每一个试图回答这个问题的人。我正在和MS合作解决这个问题。

票数 3
EN

Stack Overflow用户

发布于 2010-11-10 13:47:33

参见以下解释:GetThreadContext in Wow64

本文解释了x86和amd64模式之间的转换是在用户模式下进行的.

票数 1
EN

Stack Overflow用户

发布于 2010-11-10 13:29:11

您的线程在用户模式下做什么?当您调用SuspendThread时,它似乎已经处于内核模式。是否有可能在挂起系统功能时执行系统功能?

是什么原因导致操作系统在运行非用户模式代码时挂起线程?

许多系统或库调用可能导致切换到内核模式。而且,由于Windows内核在大多数情况下都是可重入的,所以从一个线程切换到另一个线程,而第一个线程处于内核模式是非常正常的。

我怎么才能防止这种情况?

只是一个想法:创建一个只执行空循环(例如for(;;);)的线程,并挂起该线程。这个程序不应该在内核模式下挂起。

另外,为什么ESP寄存器等是否正确对你很重要?我希望您正在编写某种调试器或相关的东西,因为这就是SuspendThread的目的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4144600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档