在 Dev-C 中的 GCC 内联汇编中定义字节(Windows 上 AT&T 语法中的 .ascii)

发布于 2024-09-18 18:39:36 字数 1680 浏览 16 评论 0原文

下面的代码只是在屏幕上显示一个消息框。
地址被硬编码以方便:(

int main ()
{
    asm("xorl %eax, %eax        \n"
        "xorl %ebx, %ebx        \n"
        "xorl %ecx, %ecx        \n"
        "xorl %edx, %edx        \n"
        "pushl %ecx             \n" //$0x0
        "pushl $0x20206c6c      \n" //"  ll"
        "pushl $0x642e3233      \n" //"d.23"
        "pushl $0x72657375      \n" //"resu"
        "movl %esp, %ecx        \n" //store "user32.dll" address in %ecx
        "movl $0x7c801d7b, %ebx \n" //store address of LoadLibraryA in %ebx
        "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"
    );
}

我没有评论所有代码,因为我的问题并不是真正关于代码)

我的问题是:有没有办法在汇编内联中写入字符串“user32.dll”,而无需手动推送到堆栈?我的意思是在 NASM 中这样: db 'Hello'

我知道在 AT&T 语法中我可以执行 .ascii 'Hello'.string 'Hello' 但是在 gcc 内联怎么样?

请注意,我在 Windows XP SP3 上使用 Dev-C++

谢谢!

The code below is just showing a Message Box on the screen.
The addresses are hardcoded to facilitate:

int main ()
{
    asm("xorl %eax, %eax        \n"
        "xorl %ebx, %ebx        \n"
        "xorl %ecx, %ecx        \n"
        "xorl %edx, %edx        \n"
        "pushl %ecx             \n" //$0x0
        "pushl $0x20206c6c      \n" //"  ll"
        "pushl $0x642e3233      \n" //"d.23"
        "pushl $0x72657375      \n" //"resu"
        "movl %esp, %ecx        \n" //store "user32.dll" address in %ecx
        "movl $0x7c801d7b, %ebx \n" //store address of LoadLibraryA in %ebx
        "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"
    );
}

(I didn't comment all the code because my question is not really about the code)

My question is: Is there a way to write the string "user32.dll" in assembly inline without pushing manually to the stack? I mean like this in NASM: db 'Hello'

I know that in AT&T syntax I could do .ascii 'Hello' or .string 'Hello' but how about in gcc inline?

Please note that I'm using Dev-C++ on Windows XP SP3

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挽清梦 2024-09-25 18:39:36

是的,通过在内联汇编器中使用汇编器指令。诀窍在于将字符串放在正确的位置(数据部分),您可以通过使用 .section .data 进行切换,然后使用 .section .text< 再次切换回来。 /代码>。

您必须给数据贴上标签,以便您可以参考;我建议在这里使用本地标签语法(其中标签是数字,例如 1:,并且您将其引用为第一个 1 的 1b 标签向后,或 1f 表示第一个 1: 标签向前 - 请参阅 GNU 汇编器文档 了解更多详细信息)。

像这样:

int main(void)
{
  asm(".section .data      \n"
      "1: .asciz \"Hello\" \n"
      ".section .text      \n"
      "pushl $1b           \n"
      "call _puts          \n"
      "add $4, %esp        \n"
     );
  return 0;
}

我没有方便的 Windows 系统来测试它,但它编译正常,并且看起来应该在 Linux 上使用 MinGW 交叉编译器做正确的事情(我相信 Dev-C++ 是基于 MinGW 的) 。

注意:此技术通常适用于使用 GNU 工具链的情况。如果您正在构建 ELF 二进制文件(例如本机 Linux),则有一种更简洁的方法可以切换回文本部分,即使用 .previous,这意味着“无论上一个 < 之前的部分是什么”代码>.section 是“。 (如果将 _puts 更改为 puts 以考虑不同的符号前缀约定,则上述示例适用于 Linux。)

Yes, by making use of assembler directives inside your inline assembler. The trick is in putting the string in the right place (the data section), which you can do by switching using .section .data, and then switching back again with .section .text.

You must give the data a label so that you can refer to it; I would recommend using the local label syntax here (where the label is a number, e.g. 1:, and you reference it as either 1b for the first 1: label backwards, or 1f for the first 1: label forwards - see the GNU assembler documentation for more details).

Like this:

int main(void)
{
  asm(".section .data      \n"
      "1: .asciz \"Hello\" \n"
      ".section .text      \n"
      "pushl $1b           \n"
      "call _puts          \n"
      "add $4, %esp        \n"
     );
  return 0;
}

I don't have a Windows system handy to test this on, but it compiles OK and looks like it should be doing the right thing using a MinGW cross-compiler on Linux (I believe Dev-C++ is based on MinGW).

Note: this technique is generally applicable when using a GNU toolchain. If you're building ELF binaries (e.g. native Linux), there is a neater way to switch back to the text section, which is to use .previous, which means "whatever the section before the previous .section was". (The above example works on Linux if you change _puts to puts to account for different symbol prefixing conventions.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文