2010-10-26 60 views
1

我已经继承了一些在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

您的实际问题是,你能解释这一点更“如何让kernel32.CtrlRoutine的地址” – Abyx 2010-10-26 10:37:59

回答

0

要获得KERNEL32的地址!CtrlRoutine你可以得到它由RVA使用一个包含所有(kernel32版本,CtrlRoutine RVA)对的表。这是最可靠的方法。

+0

? – solidstore 2010-11-08 10:19:00

+0

@solidstore获取kernel32的所有版本,找到它们中的CtrlRoutine,制作其RVA的表,然后使用此表获取程序中的CtrlRoutine的RVA。 – Abyx 2010-11-08 11:12:26

1

奇怪。用调试器看,线程堆栈中的第一个非空值是参数的值,即CreateThread的第四个参数。当你写这样的线程过程,它被交给你一个银盘:

DWORD WINAPI threadProc(void* arg) { 
    // arg is the value you are looking for 
    // etc.. 
} 

不知道这是如何与“KERNEL32 CtrlRoutine!”除非这是一个服务使用一个线程。