我正在使用windbg在windows上除錯32位x86代碼級別的東西。有些事情讓我感到困惑,我將其縮減為似乎通過 ds 段選擇器的呼叫,這顯然我不明白。
下面只是重現我的困惑的最小示例,它不是我正在處理的實際問題。
我在 DLL 中有一個函式
__declspec(dllexport) void __cdecl MyDllTest_Cdecl(int i);
void __cdecl MyDllTest_Cdecl(int i)
{
printf("In MyDll MyDllTest_Cdecl(%d)\n", i);
}
在可執行檔案中,我靜態鏈接到 DLL 并呼叫函式
void __cdecl MyDllTest_Cdecl(int i);
MyDllTest_Cdecl(1);
在windbg中除錯行程,執行是在函式呼叫的位置,我找到了windbg所示的以下機器代碼
call dword ptr [UseDll_Static!_imp__MyDllTest_Cdecl (00062118)] ds:002b:00062118={MyDll!MyDllTest_Cdecl (68391100)}
我在 windbg 中關閉了源模式(lt),因此跟蹤命令(t)應該始終單步執行機器代碼而不隱藏任何內容。
當我使用 trace ( t ) 命令時,執行突然移動到 0x68391100 (如 call 命令的反匯編所示)。
這是如何運作的?地址 0x68391100 來自哪里?x86 反匯編程式顯示機器代碼 ff1518219e00 是
call DWORD PTR ds:0x00062118
正如windbg所示。
我知道編譯器/聯結器/加載器通過call和jmp指令使用間接,特別是對于呼叫 DLL 中的函式。我在其他情況下看到了這一點,但我能夠單步執行構成 C 級函式呼叫的每個呼叫和jmp 。在這種情況下,這是一個步驟。所以這不是編譯器/聯結器/加載器創建的呼叫和jmp指令的間接呼叫。
At address 0x00062118 I see the following:
0:000> u 00062118
UseDll_Static!_imp__MyDllTest_Cdecl:
00062118 0011 add byte ptr [ecx],dl
0006211a 396820 cmp dword ptr [eax 20h],ebp
0006211d 1139 adc dword ptr [ecx],edi
So there is no jmp or call there that might be part of an indirection. It is the address of the symbol UseDll_Static!_imp__MyDllTest_Cdecl but the code there looks like garbage.
The symbols can be ignored, I would just like to know how
call DWORD PTR ds:00062118
moves execution to 0x68391100. The ds register is 0x002b.
I think I basically understand x86 segmentation in real mode. But I thought on modern Windows in protected mode the virtual memory was basically a flat 2^32 address space. Anyway if there was some segmentation offset, in this case it would be 0x68391100 - 0x00062118 which is 0x6832efe8. I would expect offsets to end in one or more zeros.
This may be completely irrelevant but when I try display the 0x002b selector (which is what is in the ds register) with the dg command in windbg it shows
0:000> dg 0x002b
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
002B 00000000 ffffffff Data RW Ac 3 Bg Pg P Nl 00000cf3
感謝您的幫助...這是一個簡單的問題,但我試圖避免關注 DLL 中的函式是如何鏈接和加載的,或者關注 x86 實模式分割的歷史。我只想在機器代碼的層面上理解。
uj5u.com熱心網友回復:
0x00062118 是存盤實際函式地址的段偏移量。如果你看你的反匯編,0x00062118 的前四個位元組是 0x00、0x11、0x39 和 0x68。它們將以相反的順序加載到 EIP 中,產生 0x68391100,這是您跳轉到的地址!
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/424438.html
