2

我最近尝试使用 Win32 二进制文件(这是我的一个大项目)。因此,经过几周的研究,我现在对 Assembly 的工作原理、它如何转换为二进制代码以及 x86/x64 操作码的工作原理有了深入的了解。

难题的最后一块是弄清楚如何正确调用 Win32 API 方法。实际上,我在这里问了一个与此相关的问题,我得到的答案是,我应该尝试编译执行​​此操作的程序集或 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功能...

我不明白这段代码有什么问题,我没有收到任何编译时错误,尽管当我运行它时,它只是崩溃了。

所以我的下一个想法是,因为这不起作用,所以在 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 二进制(汇编)代码中调用 extern 库函数的样子。但我将非常感谢有关此主题的任何资源。

先感谢您。

-汤姆·S。

4

1 回答 1

4

您的问题是您需要ExitProcess在最后调用才能正确结束该过程。由于您没有这样做,因此代码当前将继续执行并最终出现段错误,因为它试图执行垃圾字节。

于 2012-05-28T19:31:01.303 回答