我继承了一些适用于Windows 2000的代码,它使用一小段汇编代码来定位堆栈的基址,然后使用偏移量来获取传递给线程启动函数的参数值。
但是,这在Windows 2008 Server中不起作用。偏移明显不同。
#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];
经过实验,我修改了代码以查找堆栈,直到找到第一个非NULL值。的劈
DWORD* pStack = pStackBase;
do
{
pStack--;
}
while (*pStack == NULL);
// Read the parameter off the stack
g_dwCtrlRoutineAddr = *pStack;
它的作品!但我想要一个'正确的'解决方案。
有谁知道在Windows 2008 Server上将参数传递给线程的起始函数更安全/更好的解决方案?
线程启动功能是ntdll!_RtlUserThreadStart
我想找到的第一个参数是函数kernel32的地址!CtrlRoutine
答案 0 :(得分:1)
怪异。查看调试器,线程堆栈上的第一个非空值是参数的值,即CreateThread的第4个参数。当您编写如下的线程程序时,会在银盘上交给您:
DWORD WINAPI threadProc(void* arg) {
// arg is the value you are looking for
// etc..
}
不确定这与“kernel32!CtrlRoutine”有什么关系,除非这是服务中使用的线程。
答案 1 :(得分:0)
要获取kernel32!CtrlRoutine的地址,您可以通过RVA使用包含所有(kernel32版本,CtrlRoutine RVA)对的表来获取它。这是最可靠的方式。
答案 2 :(得分:0)