呼叫DLL未匯出函式由引數列表引發的問題

2021-08-28 01:11:59 字數 2423 閱讀 3794

為了呼叫乙個dll中未匯出的函式,首先用ida分析它的呼叫約定和引數列表。分析出來的函式宣告是這樣的:

typedef

int (__thiscall* fp_sub)(void *t, int a2, int a3)

然後用乙個for迴圈去呼叫這個函式,**邏輯大致如下:

void call_stub(void* t, int a2, char a3)

char pwd = "12345678";

intlength = 8;

for (int i; i < length; i++)

我使用o2優化方式編譯出來,第一次呼叫sub結果正常,第二次呼叫時發現i的值居然變成了9,length的值變成了莫名其妙的值。當我禁用優化編譯後,呼叫一切正常。這讓我覺得很奇怪,為什麼o2優化反而把程式優化錯了。

首先看一下這個for迴圈的彙編指令:

loc_10001ec1:

movsx dx, dst[edi]

call sub_10001c20

inc edi

cmp edi, esi

jb short loc_10001ec1

不難看出,edi對應的迴圈引數iesi對應的是lengthi變成了9,猜想可能的原因是sub_10001c20呼叫返回後,edi的值被錯誤地賦值給了esi,那麼現在進到call_stub()函式中看一下它的彙編指令:

push    ebp

mov ebp, esp

push

0ffffffffh

push offset sub_1000e078

mov eax, large fs:0

push eax

sub esp, 20h

mov eax, ___security_cookie

xor eax, ebp

mov [ebp+var_10], eax

push esi

push edi

push eax

...push ecx

add eax, 22870h

push

102h

mov ecx, edi

mov dword_10018d34, eax

mov [ebp+var_14], edx

call eax

...mov ecx, [ebp+var_c]

mov large fs:0, ecx

pop ecx

pop edi

pop esi

mov ecx, [ebp+var_10]

xor ecx, ebp

call @__security_check_cookie@4

; __security_check_cookie(x)

mov esp, ebp

pop ebp

retn

如上所示,它用棧去保護了ediesi暫存器的值,在恢復這兩暫存器的值的時候出錯了,可能的原因就是在執行call eax這條指令之後堆疊沒有平衡好。

然後看了一下需要呼叫函式的彙編指令,最後平衡堆疊的指令是:

retn 0ch
這說明用棧傳遞了3個引數(32bit),那麼我的函式指標宣告錯了,使得被呼叫函式平衡後的棧頂指標向下移了乙個位置,導致ecx的值被無形中銷毀了。那麼edi的值出棧儲存在了ecx中,esi的值出棧儲存在了edi中,所以edi的值正好是8,回到原來的迴圈加1變成了9。

最後正確的函式指標宣告應該是:

typedef

int (__thiscall* fp_sub)(void *t, int a2, int a3, int a4)

而在禁用優化的模式下,編譯器壓根就沒有使用ediesi去優化迴圈,也沒有在棧上去儲存暫存器,碰巧避開了這個問題。

變長引數列表函式

可變引數列表 標頭檔案提供了遍歷未知數目和型別的函式引數表的功能。該標頭檔案的實現因不同的機器而不同,但提供的介面是一致的。假定函式 f 帶有可變數目的實際引數,lastarg 是它的最後乙個命名的形式引數 引數列表必須至少包括乙個命名引數 那麼,在函式 f 內宣告乙個型別為 va list 的變數...

變長引數列表函式

可變引數列表 標頭檔案提供了遍歷未知數目和型別的函式引數表的功能。該標頭檔案的實現因不同的機器而不同,但提供的介面是一致的。假定函式 f 帶有可變數目的實際引數,lastarg 是它的最後乙個命名的形式引數 引數列表必須至少包括乙個命名引數 那麼,在函式 f 內宣告乙個型別為 va list 的變數...

php函式引數列表

1.直接傳值 function fun arg1 2.傳引用 function fun arg1 1,arg2 2 一定程度上可以模擬函式過載。同時還要注意任何預設引數一定要放在非預設引數的右邊,也就是說fun arg1 1,arg2 這個函式原型是錯誤的。4.引數為陣列 function fun ...