2012-05-28 31 views
2

最近我嘗試過使用Win32二進制文件(這是我的一個大項目)。 因此,經過幾周的研究,我現在對Assembly的工作原理,如何將其轉換爲二進制代碼以及x86/x64操作碼如何工作有了深刻的理解。每個使用Win32 API的打印函數等效程序的程序在啓動時崩潰。我怎樣才能解決這個問題?

最後一塊難題是搞清楚如何正確調用Win32 API方法。 我其實在這裏問了一個關於這個問題,我得到的答案是,我應該嘗試編譯一個Assembly或C程序來做到這一點。所以我繼續前進,並在Assembly中嘗試了這個(我使用FASM):

format PE console 
entry start 

section '.idata' import data readable writable 
    include 'win32a.inc' 

    library kernel,'kernel32.dll' 


    import kernel,\ 
      GetStdHandle,'GetStdHandle',\ 
      WriteConsoleA,'WriteConsoleA' 

section '.data' data readable writable 
    string db 'Hello!', 0h 
    output dd ? 

section '.code' code readable executable 
    start: push -11 
      call GetStdHandle 

      pushd 0 
      pushd output 
      pushd 7 
      pushd string 
      pushd eax 
      call WriteConsoleA 

這是實際上這個代碼的許多版本之一。主要的問題是,當我調用諸如「ExitProcess」之類的方法時,通常來自kernel32.dll庫的其他函數,事情似乎都行得通。這是IO功能,bug我...

我不明白這個代碼有什麼問題,我沒有得到任何編譯時錯誤,雖然當我運行它,它只是崩潰。

所以我的下一個想法是,因爲這沒有工作,嘗試在C 我使用Cygwin的編譯器和鏈接一樣...

#include <windows.h> 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { 
    MessageBox(NULL, "Hello, world!", "Test", MB_OK); 
    return 0; 
} 

此代碼產生相同結果,應用程序崩潰。

現在,我不是在尋找任何C/C++代碼。我最初感興趣的問題是知道如何調用外部庫函數看起來像在x86/x64二進制(組合)代碼。但我會非常感謝關於這個話題的任何資源。

預先感謝您。

-Tom S.

回答

4

你的問題是,你需要調用ExitProcess在結束正常結束進程。由於您沒有這樣做,因此代碼將繼續執行並最終導致段錯誤,因爲它會嘗試執行垃圾字節。

+0

實際上,'ExitProcess'不是*必需的 - 您可以從入口點返回。 –

+0

謝謝!對於彙編代碼,這實際上起作用。但我不明白爲什麼C代碼畢竟不能工作。我的意思是,我從初學者教程中獲取了這些代碼。 –

+0

我看不出C代碼會崩潰的原因。除非字符集現在定義爲Unicode嗎? –

相關問題