2015-10-09 31 views
1

我正在通過Windows系統編程第四版中的一些示例。使用windbg.exe我試圖檢查傳遞給函數(GetCurrentDirectoryA)的參數。以下是來源。使用windbg傳遞給函數的參數檢查

int _tmain (int argc, LPTSTR argv []) 
{ 
    /* Buffer to receive current directory allows for the CR, 
     LF at the end of the longest possible path. */ 

    TCHAR pwdBuffer [DIRNAME_LEN]; 
    DWORD lenCurDir; 
    lenCurDir = GetCurrentDirectory (DIRNAME_LEN, pwdBuffer); 
    if (lenCurDir == 0) 
     ReportError (_T ("Failure getting pathname."), 1, TRUE); 
    if (lenCurDir > DIRNAME_LEN) 
     ReportError (_T ("Pathname is too long."), 2, FALSE); 

    PrintMsg (GetStdHandle (STD_OUTPUT_HANDLE), pwdBuffer); 
    return 0; 
} 

首先我使用dv -t -v轉儲局部變量。在這種情況下,我對pwdBuffer感興趣。

0018ff3c   int argc = 0n1 
0018ff40   char ** argv = 0x00582470 
0018fe18   unsigned long lenCurDir = 0x775b994a 
0018fe24   char [262] pwdBuffer = char [262] "" 

然後,我在Kernel32!GetCurrentDirectoryA上設置了一個斷點。這產生以下結果。

00 0018ff34 00428759 00000001 00582470 005824c0 kernel32!GetCurrentDirectoryA 

我不明白的是函數的參數值。我期待將0018fe24看作代表pwdbuffer的一個值。

我接下來要做的就是顧。它執行Kernel32!GetCurrentDirectoryA到最後。 此後,我使用dv -v -t命令轉儲了最初獲得的pwdBuffer值。

0:000> da 0018fe24   
0018fe24 "C:\microsoft_press\WSP4_Examples" 
0018fe44 "\Utility_4_dll" 

這是我期望的緩衝區。所以我的問題是爲什麼我沒有看到這個0018fe24值傳遞給GetCurrentDirectory?

回答

3

嘗試在GetCurrentDirectoryA開始時單步執行mov ebp, esp指令。你看到的數字看起來就像你的_tmain函數的值,具體來說就是它的幀指針(EBP),它的返回地址,它的參數argc和argv(以及隱藏的envp參數)。一旦EBP加載了GetCurrentDirectoryA的正確幀指針,windbg就可以正確顯示函數的參數。

+0

@d_blk:沒有upvote的「thanks」是非常不一致的。 – IInspectable

+0

我決定重新評估我最初接受的答案。您的建議確實爲我提供了搜索信息。然而,在折點處,child-ebp等於結束 – dcrearer

1

堆棧應顯示在碰到斷點你一步我只是有類似的代碼(不包括CRT窗口只蜜蜂)後不參數的功能和運行它通過與預期
分析未知時的WinDbg工作或潛在的惡意軟件二進制文件,一個不合時宜的單步就可能導致致命的感染。如果存在邏輯不要使用幸運符。當前目錄的

:\>ls -l 
total 12 
-rwxrwxrwx 1 Admin 0 197 2015-10-10 16:29 compile.bat 
-rw-rw-rw- 1 Admin 0 336 2015-10-10 16:13 getdir.cpp 
-rw-rw-rw- 1 Admin 0 145 2015-10-10 16:47 wtf.txt 

SRC代碼測試

:\>type getdir.cpp 
#include <windows.h> 
int main (void) { 
    PCHAR buff=0;int bufflen=0; 
    bufflen=GetCurrentDirectory(0,NULL); 
    buff = (PCHAR)VirtualAlloc(NULL,bufflen,MEM_COMMIT,PAGE_READWRITE); 
    if(buff){ 
    GetCurrentDirectory(bufflen,buff); 
    MessageBox(NULL,buff,"Current Directory",MB_OK); 
    VirtualFree(buff,0,MEM_RELEASE); 
    } 
} 

我的當前目錄

:\>echo %cd% 
C:\temp\temp\temp\temp 

內容與

:\>type compile.bat 
@call "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86 
cl /Zi /EHsc /O2 /nologo /W4 /analyze *.cpp /link /SUBSYSTEM:Windows /RELEASE /E 
NTRY:main user32.lib kernel32.lib 
pause 
:\>compile.bat 
Setting environment for using Microsoft Visual Studio 2010 x86 tools. 
getdir.cpp 
Press any key to continue . . . 
編譯

:\>cdb -cf wtf.txt getdir.exe 

-CF命令行執行的WinDbg/CDB需要,其內容會,如果你在跆拳道的提示

內容鍵入他們要執行的文件。TXT是

:\>type wtf.txt 
bp kernel32!VirtualAlloc 
g 
gu 
? @eax 
bc * 
bp kernel32!GetCurrentDirectoryA 
g 
dd @esp l3 
r $t0 = poi(@esp+8) 
? @$t0 
gu 
da @$t0; 
g 
q 

第一個系統上打破
設置的VirtualAlloc斷點並運行的二進制
當斷點命中黨團(我們只關心這個函數的返回值),並檢查EAX(從函數返回值)
清楚所有斷點
設置斷點GetCurrentDirectoryA
與克在擊中斷點再次執行二進制檢查堆棧 使用dd @esp L3
(顯示終端來自Stack指針的三個dword指針一個返回地址和兩個函數參數到函數GetCurrentDirectoryA()
請注意,堆棧將包含我們之前在VirtualAlloc返回時使用的相同地址? @eax 緩衝區的地址保存到一個僞變量,然後從緩衝DA @ $ T0 退出會話上去 打印的ASCII字符串

本次會議的結果如下說明中,我們得到了35000所分配從虛擬分配緩衝區的內存地址,並確實傳遞給GetCurrentDirectory並持有該字符串當前目錄

:\>cdb -cf wtf.txt getdir.exe 

0:000> bp kernel32!VirtualAlloc 
0:000> g 

Breakpoint 0 hit 

kernel32!VirtualAlloc: 
7c809af1 8bff   mov  edi,edi 
0:000> gu 

getdir!main+0x21: 
00401021 8bf0   mov  esi,eax 
0:000> ? @eax 
Evaluate expression: 3473408 = 00350000 <-------- 
0:000> bc * 
0:000> bp kernel32!GetCurrentDirectoryA 
0:000> g 
Breakpoint 0 hit 

kernel32!GetCurrentDirectoryA: 
7c83502e 8bff   mov  edi,edi 
0:000> dd @esp l3 
0013ffac 0040102b 00000017 00350000 <------ 
0:000> r $t0 = poi(@esp+8) 
0:000> ? @$t0 
Evaluate expression: 3473408 = 00350000 <---------- 
0:000> gu 

getdir!main+0x2b: 
0040102b 6a00   push 0 
0:000> da @$t0; 
00350000 "C:\temp\temp\temp\temp" 
0:000> g 

編輯所有其他人是一樣只是增加了一個kb的命令腳本文件並執行,以顯示堆棧跟蹤

enter image description here

+0

您的回答非常具有挑釁性。然而,在kb中斷處查看kernel32!GetCurrentDirectoryA的參數不會產生與pwdBuffer相同的值。我必須用t來執行一次。相對於dd @esp l3,該值等於初始Kernel32!GetCurrentDirectoryA斷點處的pdwBuffer的值。如果在kernel32!GetCurrentDirectoryA的中斷點被命中時發出kb命令,您會看到什麼? – dcrearer

+0

我添加了kb的結果截圖 – blabb

相關問題