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!」除非這是一個服務使用一個線程。