Reputation: 6685
I am having a hard time understanding the callstack below.
ntdll!NtCreateThreadEx+0xc
KERNELBASE!CreateRemoteThreadEx+0x1f0
kernel32!CreateThreadStub+0x27
MyModule!_beginthreadex+0x87
Sorry I cannot reveal any more of it because of proprietory issues but I believe we should be able to make at least partial sense just with this. That was the state of one the threads spawned by a third party library inside a crash dump I was looking at. (the thread itself had nothing to do with the problem I was investigating.)
What condition can possibly cause a call to _beginthreadex
to end up in CreateRemoteThread? The MSDN doc for the API does not give me any clues (the word 'remote' doesn't even appear on that page.)
I have symbols for the third party library and the callstack is definitely legit.
Update:
Interesting. If I disassemble backwards from the spot CreateThreadStub
is supposed to return to, I see the following instructions:
call dword ptr [MyModule!_imp__CreateThread (573701a0)]
cmp eax,ebx
When I do:
0:048> dds MyModule!_imp__CreateThread l1
573701a0 75b5cf30 kernel32!CreateThreadStub
and when I disassemble CreateThreadStub
, I do see it calling CreateRemoteThread
. This is all very confusing!
Upvotes: 0
Views: 528
Reputation: 283803
The function description on MSDN is a bit misleading:
Creates a thread that runs in the virtual address space of another process.
The first line of remarks is a much better summary of CreateRemoteThread
:
The
CreateRemoteThread
function causes a new thread of execution to begin in the address space of the specified process.
At least with this description, it's clear that you can create a thread in the local process using CreateRemoteThread
, merely by specifying the current process. Also note this in CreateRemoteThreadEx
remarks:
The
CreateRemoteThreadEx
function causes a new thread of execution to begin in the address space of the specified process. The thread has access to all objects that the process opens. ThelpAttribute
parameter can be used to specify extended attributes such as processor group affinity for the new thread. IflpAttribute
is NULL, the function's behavior is the same asCreateRemoteThread
.
When you think about the transition to kernel-mode, and the fact that CreateRemoteThreadEx
, by choice of parameters, can do everything that CreateThread
or CreateRemoteThread
can do, and the maintenance cost of testing correctness and security of each syscall, it makes sense to provide only one syscall with a superset of all the abilities, and have all these functions use it.
Upvotes: 1
Reputation: 59513
The stack you posted is the normal stack. Compile the following C++ code:
#include "stdafx.h"
#include <iostream>
#include <process.h>
#include <Windows.h>
using namespace std;
void test(void *param)
{
Sleep(1000);
_endthread();
}
int main()
{
HANDLE hThread;
hThread = (HANDLE)_beginthread(test, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
return 0;
}
At the initial breakpoint, set a breakpoint
0:000> bp KERNELBASE!CreateRemoteThreadEx
0:000> bl
0 e Disable Clear 7485b060 0001 (0001) 0:**** KERNELBASE!CreateRemoteThreadEx
0:000> g
See that the main()
method calls CreateRemoteThreadEx()
when it hits the _beginthread()
method:
0:000> k
# ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
00 00f7f714 0f7ba3cd KERNELBASE!CreateRemoteThreadEx
01 00f7f758 000f255f ucrtbased!_beginthread+0xed [d:\rs1\minkernel\crts\ucrt\src\appcrt\startup\thread.cpp @ 174]
02 00f7f844 000f2cbe ThreadStartStack!main+0x2f [c:\users\t\documents\visual studio 2015\projects\threadstartstack\threadstartstack\threadstartstack.cpp @ 19]
03 00f7f858 000f2b20 ThreadStartStack!invoke_main+0x1e [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 64]
04 00f7f8b0 000f29bd ThreadStartStack!__scrt_common_main_seh+0x150 [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 253]
05 00f7f8b8 000f2cd8 ThreadStartStack!__scrt_common_main+0xd [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 296]
06 00f7f8c0 752362c4 ThreadStartStack!mainCRTStartup+0x8 [f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp @ 17]
07 00f7f8d4 77370fd9 KERNEL32!BaseThreadInitThunk+0x24
08 00f7f91c 77370fa4 ntdll!__RtlUserThreadStart+0x2f
09 00f7f92c 00000000 ntdll!_RtlUserThreadStart+0x1b
Upvotes: 3