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