【问题标题】:MessageBoxA in Windows AT&T AssemblyWindows AT&T 程序集中的 MessageBoxA
【发布时间】:2011-04-09 22:09:32
【问题描述】:

我正在尝试使用 gcc 内联直接在程序集中调用 MessageBoxA()。但是我需要以两种方式做到这一点:首先是使用动态寻址,使用 LoadLibrary() 和 GetProcAddress() - 我找到了一个关于这个的教程,试图遵循它。但是我也有兴趣直接调用 MessageBoxA 的地址,在我的 Windows SP3 英语中是 0x7e4507ea。

我正在尝试执行此代码:

/*
 *    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”的消息框。有人可以帮我吗?感谢任何帮助,还有教程链接!

非常感谢

【问题讨论】:

  • 嘿,正如您在评论中提到的,您已经做到了。请您描述一下您如何与 IAT 相处?在上面的例子中

标签: c assembly messagebox inline-assembly dev-c++


【解决方案1】:

先用C写,编译并查看汇编列表,看看编译器生成了什么。这是最简单的学习方法。 如果您看到不理解的指令,请在英特尔指令集参考 PDF 中查找。

【讨论】:

  • 我尝试过这样做,但这并不是那么简单。我这样编译: gcc -c msgbox3.c -static -mpreferred-stack-boundary=2 。但是我得到的目标文件包含一些没有太大帮助的组装说明......无论如何感谢您的发布。
  • @jyzuz:在学校里,你在学习写作之前先学会阅读,这是有充分理由的。对于计算机语言,同样如此。如果你不会读汇编,你不应该尝试写它。
  • @MSalters:我正在使用 Richard Blum 的书(适用于 Linux)学习汇编中的读/写。并且还通过阅读 Internet 上的一些文章来学习 Windows 汇编。我认为最好的学习方式是阅读和练习。如果我在写单词之前首先成为阅读专家,我无法记录我小时候的情况。但我认为如果不尝试和犯错误,你永远不会学习编程。也许我正在尝试“跑得比我的腿还快”……嗯……我很好奇呵呵;)
【解决方案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)上运行

【讨论】:

【解决方案3】:

直接调用地址

听起来像是一个很大的禁忌。 API 调用没有固定地址。这取决于它在内存中的加载位置。虽然我确信 User32.dll 是在操作系统启动时加载的,但我不会指望它占用相同的空间。

要调用 API 例程,您必须导入它,以便操作系统可以为您提供正确的调用地址。

【讨论】:

  • 但这有点奇怪,因为我在这里做了几个星期的测试,每次我在 user32.dll 中查找 MessageBoxA 的地址时,它都会返回 0x7e4507ea。是说这个是MessageBoxA在user32.dll里面还是内存里面的地址?
  • 0x7e4507ea 是您进程空间中的地址。它之所以稳定,有两个原因:首先,user32.dll 本身加载得非常早。因此,它倾向于每次都在同一个位置加载。稍后加载的 DLL 将必须采用任何地址(如果留下)。其次,user32.dll 通常只有在 Microsoft 修复其中的错误时才会更改,这不是每周都会发生的 - 对于 XP SP3 肯定不会,因为只有安全错误得到修复。
  • 还是个坏主意,很像按序号调用。
【解决方案4】:

“直接”调用 MessageBoxA 是不可能的。是的,您可以添加对0x7e4507ea 的呼叫,但这并不重要。您必须在您的导入地址表中添加一个条目,说明您正在从 user32.dll 以及从哪里调用 MessageBoxA。当 Windows 加载您的可执行文件时,它会看到您正在调用 MessageBoxA,为您加载 user32.dll,并修补 MessageBoxA 结束的实际地址。

【讨论】:

  • 好的,我想我明白了。我知道 Windows Executable 与 Linux ELF 文件完全不同。这个“导入地址表”是 Windows 可执行文件中的一个会话,对吧?我会阅读更多关于此的内容。感谢您的回答
  • 是的,也称为“IAT”部分
  • 事实上这是可能的。现在我可以做到了:)
猜你喜欢
  • 2017-10-23
  • 2019-04-04
  • 2021-03-05
  • 1970-01-01
  • 2013-06-30
  • 2016-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多