我想知道在创建 Win32 线程时是否有办法设置线程堆栈的地址。
有人建议使用SetThreadContext
,事实证明这是设置线程堆栈地址的一种方法。对于我的处理器(特定于处理器(,我必须将CONTEXT
结构的Esp
成员设置为我所需的堆栈地址。请注意,堆栈向 0 增长,因此您需要将堆栈设置为堆栈区域的末尾。另请注意,看起来 Win32 会在您指定的地址之后立即修改某些堆栈,因此您需要稍微备份一下地址。
您需要权限才能使用SetThreadContext
;要启用权限,请遵循本指南:https://learn.microsoft.com/en-us/windows/win32/secauthz/creating-a-security-descriptor-for-a-new-object-in-c--.基本上,您需要设置一个传递给CreateThread
的SECURITY_ATTRIBUTES
结构。对于指南设置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(_chkstk((函数的目的是什么?(不会尝试访问无效内存。请注意,TIB 中的堆栈上限是当前上限 wrt 分页,而不是堆栈的最顶部。