【问题标题】:How to set the address of a thread stack in Win32?Win32中如何设置线程栈的地址?
【发布时间】:2019-12-25 03:28:56
【问题描述】:

我想知道是否有办法在创建 Win32 线程时设置线程堆栈的地址。

【问题讨论】:

  • 你需要什么设置这个地址?
  • 感谢您的提问。为了测试,我只是想模拟我在嵌入式系统上可以做什么。
  • 仍然不明白你需要什么设置线程堆栈地址(而不是它保留/提交大小)但如果非常想要 - 可能使用(已经过时但仍然存在)ZwCreateThread 你可以自己设置线程堆栈地址。但是此线程未连接到 csrss(因此限制了您可以在此线程上执行的操作)也可能在创建和释放原始文件后更改线程堆栈。但我个人再次认为这里没有大意义。难以实施,我们获得了什么?
  • @RbMm 感谢您的回复。我希望将 DLL 的所有 RW 数据都放在同一个地址范围内。我希望堆栈成为这个范围的一部分
  • 在windows中这没有意义,不知道其他系统。那么你必须限制 - 你可以在 DLL 中创建多少线程,并在开始设计时说 dll 中的 .bss 部分。您可以在创建线程后将其堆栈交换到 dll 中的某个位置,但是有意义吗?!你得到了什么。可能你需要更详细地描述这个问题

标签: c winapi


【解决方案1】:

有人建议使用SetThreadContext,结果证明这是设置线程堆栈地址的一种方式。对于我的处理器(它是特定于处理器的),我必须将CONTEXT 结构的Esp 成员设置为我想要的堆栈地址。请注意,堆栈向 0 增长,因此您需要将堆栈设置到堆栈区域的末尾。另请注意,Win32 似乎在您指定的地址之后立即修改了一些堆栈,因此您需要稍微备份一下地址。

您需要获得使用SetThreadContext 的权限;要启用权限,请遵循本指南:https://docs.microsoft.com/en-us/windows/win32/secauthz/creating-a-security-descriptor-for-a-new-object-in-c--。基本上,您需要设置一个 SECURITY_ATTRIBUTES 结构,并将其传递给 CreateThread。对于指南设置EXPLICIT_ACCESS 结构的部分,我使用了以下内容:

ZeroMemory(&explicit_access, sizeof(EXPLICIT_ACCESS));
explicit_access.grfAccessPermissions = THREAD_ALL_ACCESS;
explicit_access.grfAccessMode = GRANT_ACCESS;
explicit_access.grfInheritance= NO_INHERITANCE;
explicit_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
explicit_access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
explicit_access.Trustee.ptstrName  = (LPTSTR) everyone_sid;

从技术上讲,你只需要THREAD_GET_CONTEXT,但我只是使用了THREAD_ALL_ACCESS

另外需要注意的是,SEH(结构化错误处理)似乎不再起作用了。

这是不安全的,但我只是为了测试通常在 MCU 上实现的模块机制。

编辑:对于 64 位,我还必须修改内部 Windows TIB (https://en.wikipedia.org/wiki/Win32_Thread_Information_Block),具体来说,我必须确保堆栈基数和上限正确,以便 _chkstk (What is the purpose of the _chkstk() function?) 不会尝试访问无效内存。请注意,TIB 中的堆栈上限是当前分页上限,而不是堆栈的最顶端。

【讨论】:

  • Windows 使用 SEH 来增加堆栈,并在可用空间耗尽时触发堆栈溢出异常。
  • @IInspectable 那么当发生内存访问冲突异常等非堆栈溢出异常时,SEH 会触发堆栈溢出吗?你有资源吗?我想了解更多关于这方面的内容。
  • Microsoft 的 CRT 实现在为堆栈分配的最后一页旁边设置了一个保护页。当程序试图通过堆栈指针读取该保护页时,系统会触发STATUS_GUARD_PAGE_VIOLATION 异常,该异常用于动态增长堆栈,或者在堆栈内存耗尽时引发EXCEPTION_STACK_OVERFLOW 异常。 _resetstkoflw 有一些内部细节,但我记得读过更完整的文档,但我找不到。
  • 好的,谢谢您的解释。所以,我不再有保护页的保护,所以不会检测到堆栈溢出。
猜你喜欢
  • 1970-01-01
  • 2019-07-11
  • 2010-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-13
  • 1970-01-01
相关资源
最近更新 更多