Searching for thread start parameters at top of stack
I've inherited some code that worked on Windows 2000 thats using a small piece of assembly code to locate the base address of the stack, then it uses an offset to grab the parameter value passed to the thread start function.
However this doesnt work in Windows 2008 Server. The offset is obviously different.
#define TEB_OFFSET 4
DWORD * pStackBase;
__asm { mov eax,fs:[TEB_OFFSET]}
__asm { 开发者_开发问答mov pStackBase,eax}
// Read the parameter off the stack
#define PARAM_0_OF_BASE_THEAD_START_OFFSET -3
g_dwCtrlRoutineAddr = pStackBase[PARAM_0_OF_BASE_THEAD_START_OFFSET];
After experimenting, I modified the code to look up the stack till it finds the first non-NULL value. hack
DWORD* pStack = pStackBase;
do
{
pStack--;
}
while (*pStack == NULL);
// Read the parameter off the stack
g_dwCtrlRoutineAddr = *pStack;
Its works! But I want a 'correct' solution.
Does anyone know a safer/better solution for getting the parameter passed to the starting function of a thread on Windows 2008 Server?
The thread start function is ntdll!_RtlUserThreadStart
And the first parameter I'm trying to locate is the address of the function kernel32!CtrlRoutine
Bizarre. Looking with the debugger, the first non-null value on the thread's stack is the value of the argument, the 4th argument to CreateThread. Which gets handed to you on a silver platter when you write the thread procedure like this:
DWORD WINAPI threadProc(void* arg) {
// arg is the value you are looking for
// etc..
}
Not sure how that's related to "kernel32!CtrlRoutine" unless this is a thread used in a service.
To get address of kernel32!CtrlRoutine you can get it by RVA, using a table with all (kernel32 version, CtrlRoutine RVA) pairs. It's the most reliable way.
This is also discussed http://www.latenighthacking.com/projects/2003/sendsignal/
精彩评论