2010-09-08 46 views
4

我想直接在彙編中使用gcc內聯調用MessageBoxA()。不過,我需要通過兩種方式來實現:首先是使用動態尋址,使用LoadLibrary()和GetProcAddress() - 我找到了關於這個的教程,試圖遵循它。但我也有興趣直接調用MessageBoxA的地址,在我的Windows SP3英文中是0x7e4507ea。Windows中的MessageBoxA AT&T彙編

我試圖執行此代碼:

/* 
* eax holds return value 
* ebx will hold function addresses 
* ecx will hold string pointers 
* edx will hold NULL 
* 
*/ 


int main(int argc, char **argv) 
{ 
asm(" xor %eax, %eax   \t\n\ 
     xor %ebx, %ebx   \t\n\ 
     xor %ecx, %ecx   \t\n\ 
     xor %edx, %edx   \t\n\ 
     push $0x0    \t\n\ 
     push $0x44444444  \t\n\ 
     push $0x44444444  \t\n\ 
     pop %ecx    \t\n\ 
     mov %dl,0x3(%ecx)  \t\n\ 
     mov $0x7e4507ea, %ebx \t\n\ 
     push %edx    \t\n\ 
     push %ecx    \t\n\ 
     push %ecx    \t\n\ 
     push %edx    \t\n\ 
     mov $0x8, %ax   \t\n\ 
     call *%ebx    \t\n\ 
     "); 
} 

我不知道,如果在Windows中甚至可以做到這一點,直接調用地址,沒有在此指定庫(USER32.DLL案件)。我知道在Linux中很容易調用write()系統調用,但在Windows中我還不太熟悉。

我期望看到帶有「DDDDDDDD」的消息框。有人可以幫我嗎?欣賞任何幫助,也有教程鏈接!

非常感謝

+0

嘿,正如你在評論中提到的,你已經做到了。你能否描述我如何與IAT相處?在上例 – 2016-11-03 06:57:34

回答

2

寫在C第一,編譯和查看裝配清單,看看編譯器生成的。這是最簡單的學習方式。 如果您看到一條您不明白的指令,請在「英特爾指令集參考手冊」中查找它。

+0

我試過這樣做,但那不是那麼簡單。我這樣編譯:gcc -c msgbox3.c -static -mpreferred-stack-boundary = 2。但是我得到的目標文件包含一些彙編指令,這些指令並沒有太多幫助......無論如何感謝發佈。 – jyz 2010-09-09 13:53:24

+0

@jyzuz:在學習之前,你學會了在閱讀之前學會閱讀的理由。對於計算機語言,這同樣適用。如果你不能閱讀大會,你就不要試圖寫出它。 – MSalters 2010-09-09 15:10:34

+0

@ MSalters:我正在學習與Richard Blum的書(適用於Linux)的閱讀/寫作。還學習Windows程序集閱讀互聯網上的一些文章。我認爲最好的學習方法是閱讀和練習。如果我在寫一個單詞之前首先成爲閱讀專家,那麼我無法記錄自己是小孩的時候。但我認爲,如果不嘗試和犯錯誤,你永遠不會學習編程。也許我試圖跑「比我的腿快」...呃...我很好奇嘿嘿;) – jyz 2010-09-09 16:49:41

1

直接調用地址

聽起來像一個大禁忌。 API調用沒有固定的地址。這取決於它在內存中加載的位置。儘管我確信User32.dll在OS啓動時被加載,但我不會指望它佔據相同的空間。

要調用API例程,必須將其導入,以便操作系統可以爲您提供正確的地址。

+0

但這有點奇怪,因爲我在這裏做了幾個星期的測試,每一次我在user32.dll中查找MessageBoxA的地址,它返回0x7e4507ea。這是否意味着這是MessageBoxA在user32.dll或內存中的地址? – jyz 2010-09-09 13:41:32

+0

'0x7e4507ea'是您的進程空間中的地址。這是合理的穩定有兩個原因:首先,user32.dll本身加載很早。因此,它每次都傾向於在同一個位置加載。稍後加載的DLL將不得不採取任何地址,如果離開。其次,user32.dll通常只在微軟修正了一個錯誤時纔會改變,而這並不是每週都會發生的 - 當然不適用於只有安全錯誤得到修復的XP SP3。 – MSalters 2010-09-09 15:04:49

+0

還是一個壞主意,就像通過序數調用一樣。 – 2010-09-09 15:09:51

1

「直接」調用MessageBoxA是不可能的。是的,你可以添加電話0x7e4507ea,但它並不重要。你必須添加一個條目到你的導入地址表,它說你從user32.dll調用MessageBoxA,並從哪裏。當Windows加載可執行文件時,它會看到您正在調用MessageBoxA,爲您加載user32.dll,並修正MessageBoxA結束的實際地址。

+0

好吧,我想我明白了。我知道Windows可執行文件與Linux ELF文件完全不同。這個「導入地址表」是Windows可執行文件中的一個會話,對吧?我會閱讀更多關於此..感謝回答 – jyz 2010-09-09 16:55:51

+0

是的,也被稱爲「IAT」部分 – MSalters 2010-09-10 07:49:08

+0

事實上,這是可能的。現在我可以這樣做:) – jyz 2010-10-07 13:38:38

2

我這樣做:

int main() 
{ 
    asm("xorl %eax, %eax  \n" 
     "xorl %ebx, %ebx  \n" 
     "xorl %ecx, %ecx  \n" 
     "xorl %edx, %edx  \n" 
     "pushl %ecx    \n" 
     "pushl $0x20206c6c  \n" 
     "pushl $0x642e3233  \n" 
     "pushl $0x72657375  \n" 
     "movl %esp, %ecx  \n" 
     "movl $0x7c801d7b, %ebx \n" 
     "pushl %ecx    \n" 
     "call *%ebx    \n" 
     "movl $0xef30675e, %ecx \n" 
     "addl $0x11111111, %ecx \n" 
     "pushl %ecx    \n" 
     "pushl $0x42656761  \n" 
     "pushl $0x7373654d  \n" 
     "movl %esp, %ecx  \n" 
     "pushl %ecx    \n" 
     "pushl %eax    \n" 
     "movl $0x7c80ae40, %ebx \n" 
     "call *%ebx    \n" 
     "movl %esp, %ecx  \n" 
     "xorl %edx, %edx  \n" 
     "pushl %edx    \n" 
     "pushl %ecx    \n" 
     "pushl %ecx    \n" 
     "pushl %edx    \n" 
     "call *%eax    \n" 
     "xorl %eax, %eax  \n" 
     "pushl %eax    \n" 
     "movl $0x7c81cb12, %eax \n" 
     "call *%eax    \n" 
    ); 
} 

即使強悍完全可以硬編碼的函數的地址,我更喜歡動態加載(雖然我硬編碼地址KERNEL32),因此,它的工作原理在任何Windows XP上(SP1,2,3)

+0

[地址空間佈局隨機化](http://blogs.msdn.com/b/michael_howard/archive/2006/05/26/address-space-layout-randomization-in -windows-vista.aspx)幾乎改變了圖片。 *硬編碼地址*和*失敗*已成爲同義詞。 – IInspectable 2015-03-28 17:13:49

相關問題