jyz*_*jyz 10 assembly gcc inline-assembly dev-c++ att
下面的代码只是在屏幕上显示一个消息框.
地址是硬编码的,以方便:
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"
);
}
Run Code Online (Sandbox Code Playgroud)
(我没有评论所有代码,因为我的问题不是关于代码)
我的问题是:有没有办法在程序集内联中编写字符串"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 \n"
"1: .asciz \"Hello\" \n"
".section .text \n"
"pushl $1b \n"
"call _puts \n"
"add $4, %esp \n"
);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我没有一个Windows系统可以方便地测试它,但它编译好了,看起来应该在Linux上使用MinGW交叉编译器做正确的事情(我相信Dev-C++基于MinGW).
注意:这种技术通常适用于使用GNU工具链.如果你正在构建ELF二进制文件(例如本机Linux),那么有一种更简洁的方法可以切换回要使用的文本部分.previous
,这意味着"无论前一部分.section
是什么".(上面的例子,如果你改变在Linux上工作_puts
,以puts
考虑到不同的符号前缀约定.)