在Dev-C ++中定义GCC内联汇编中的字节(Windows中AT& T语法中的ascii) [英] Defining Bytes in GCC Inline Assembly in Dev-C++(.ascii in AT&T syntax on Windows)

查看:236
本文介绍了在Dev-C ++中定义GCC内联汇编中的字节(Windows中AT& T语法中的ascii)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码只是在屏幕上显示一个消息框。

这些地址被硬编码以方便:

  int main()
{
asm(xorl%eax,%eax \\\

xorl%ebx,%ebx \\\

xorl%ecx,%ecx \\\

xorl%edx,%edx \\\

pushl%ecx \\\
// $ 0x0
pushl $ 0x20206c6c \\ \\ n//ll
pushl $ 0x642e3233 \\\
//\"d.23
pushl $ 0x72657375 \\\
//resu
movl %esp,%ecx \\\
//在%ecx
movl $ 0x7c801d7b,%ebx \\\
中存储user32.dll地址//将LoadLibraryA的地址存储在%ebx中
pushl%ecx \\\

call *%ebx \\\

movl $ 0xef30675e,%ecx \\\

addl $ 0x11111111,%ecx \\\

pushl%ecx \\\

pushl $ 0x42656761 \\ n
pushl $ 0x7373654d \\\

movl%esp,%ecx \\\

pushl%ecx \\\

pushl%eax \\\

movl $ 0x7c80ae40,%ebx \\\

call *%ebx \\\

movl%esp,%ecx \\\

xorl%edx,%edx \\\

pushl%edx \\\

pushl%ecx \\\

pushl%ecx \\\

pushl%edx \\\

call *%eax \\\

xorl%eax,%eax \\\

pushl%eax \\\

movl $ 0x7c81cb12,%eax \\\

call *%eax \\\

);

$ / code>

(我没有评论所有的代码,因为我的问题不是真的代码)

我的问题是:有没有办法在内联程序集中编写字符串user32.dll而不手动推入堆栈?我的意思是这样在NASM中: db'Hello'



我知道在AT& T语法中我可以做 .ascii'Hello' .string'Hello'但是如何在gcc内联?



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



谢谢!

是的,通过在内联汇编程序中使用汇编程序指令。诀窍是将字符串放在正确的位置(数据部分),您可以通过使用 .section .data 切换,然后再使用 .section .text



您必须为数据提供一个标签,以便您可以引用它;我建议在这里使用本地标签语法(其中标签是一个数字,例如 1:),并将其引用为 1b 为第一个 1:标签倒退,或 1f 为第一个 1 :标签转发 - 请参阅 GNU汇编程序文档

像这样:

  int main(void)
{
asm(。section .data \\\

1:.asciz \Hello \\\\

.section .text \\\

pushl $ 1b \\\

call _puts \\\

add $ 4,%esp \\\

) ;
返回0;
}

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

注意:这个技术通常适用于使用GNU工具链的情况。如果您正在构建ELF二进制文件(例如本机Linux),则可以使用 .previous 来切换回文本部分,这意味着任何前面的 .section 之前的部分是。 (如果将 _puts 更改为 puts 来说明不同的符号前缀约定,则上述示例在Linux上运行。 p>

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!

解决方案

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.)

这篇关于在Dev-C ++中定义GCC内联汇编中的字节(Windows中AT& T语法中的ascii)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆