1

I was wondering if there was a way to set the address of a thread stack when creating a Win32 thread.

hacksoi
  • 1,301
  • 13
  • 23
  • 2
    for what you need set this address ? – RbMm Aug 19 '19 at 22:46
  • thanks for asking. i am simply trying to simulate what i can do on embedded systems for the sake of testing. – hacksoi Aug 19 '19 at 22:48
  • 2
    still dont understand for what you need set thread stack address (instead it reserved/commit size) but if very want - possible use (already absolete but still existing) `ZwCreateThread` where you can yourself set thread stack addresses. but this thread not connected to csrss (so restricted what you can do on this thread) also possible change thread stack after create and free original. but again i personally not view here big sense. hard to implement and what we gain ? – RbMm Aug 19 '19 at 22:57
  • @RbMm thanks for reply. i want to have all the RW data of a DLL in the same address range. i want the stacks to be part of this range – hacksoi Aug 19 '19 at 23:03
  • 1
    in windows this have no sense, dont know about another systems. then you must restrict - how many threads you can create in DLL and at begin design say .bss section in dll for this. you can after you create thread swap it stack to some place in dll , but sense ?! what you got by this . may be you need describe this in question in more details – RbMm Aug 19 '19 at 23:08

1 Answers1

3

Someone suggested using SetThreadContext and it turns out it's one way of setting a thread's stack address. For my processor (it's processor-specific), I had to set the Esp member of the CONTEXT struct to my desired stack address. Note that stacks grow toward 0, so you need to set the stack to the end of the stack region. Also note that it looks like Win32 modifies some of the stack right after address you specify, so you'll want to back up the address a bit.

You'll need permission to use SetThreadContext; to enable permissions, follow this guide: https://learn.microsoft.com/en-us/windows/win32/secauthz/creating-a-security-descriptor-for-a-new-object-in-c--. Basically, you need to set up a SECURITY_ATTRIBUTES struct which you pass to CreateThread. For the part where the guide sets up the EXPLICIT_ACCESS struct, I used the following:

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;

Technically, you only need THREAD_GET_CONTEXT, but I just used THREAD_ALL_ACCESS.

Another thing to note is that SEH (structured error handling) doesn't seem to work anymore.

This is unsafe, but I'm just doing it for testing a module mechanism normally implemented on MCUs.

Edit: For 64-bit, I also had to modify the internal Windows TIB (https://en.wikipedia.org/wiki/Win32_Thread_Information_Block), specifically, I had to make sure the stack base and ceiling were correct so that _chkstk (What is the purpose of the _chkstk() function?) wouldn't try to access invalid memory. Note that the stack ceiling in the TIB is the current ceiling wrt paging, not the very very top of the stack.

hacksoi
  • 1,301
  • 13
  • 23
  • Windows uses SEH to grow the stack, and to trigger a stack overflow exception, when available space is exhausted. – IInspectable Aug 21 '19 at 16:21
  • @IInspectable so when an non-stack-overflow exception like a memory access violation exception is occurs, SEH triggers a stack overflow? Do you have a source? I'd like to read more about this. – hacksoi Aug 21 '19 at 18:38
  • Microsoft's CRT implementation sets up a guard page right next to the last page allocated for the stack. When a program tries to read through the stack pointer into that guard page, the system triggers a `STATUS_GUARD_PAGE_VIOLATION` exception, that's either used to dynamically grow the stack, or raises a `EXCEPTION_STACK_OVERFLOW` exception if stack memory is exhausted. [_resetstkoflw](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/resetstkoflw) has some details on the internals, but I recall having read a more complete document that I'm unable to find. – IInspectable Aug 21 '19 at 19:11
  • Okay, thanks for the explanation. So,I no longer have the protection of guard page, so stack overflows won't be detected. – hacksoi Aug 21 '19 at 20:09