大佬教程收集整理的这篇文章主要介绍了x86 Linux汇编程序从_start获取程序参数,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
EX:
./Program "text"
我正在使用(Gnu Assembler)
通常我会使用这些参数
[esp+4]
因为esp是程序/函数调用指针,但在纯asm中它没有得到命令行参数.
有没有办法做到这一点?
在x86 Linux可执行文件的ELF入口点(a.k.a._start):
> ESP指向argc
> ESP 4指向argv [0],数组的开始.即你应该传递给main的值为char ** argv是lea eax,[esp 4],而不是mov eax,[esp 4])
最小装配程序如何获得argc和argv
我将展示如何在GDB中读取argv和argc [0].
CMDLINE-x86.S
#include <sys/syscall.h> .global _start _start: /* Cause a breakpoint trap */ int $0x03 /* exit_group(0) */ mov $SYS_exit_group,%eax mov $0,%ebx int $0x80
CMDLINE-x86.gdb
set confirm off file cmdline-x86 run # We'll regain control here after the breakpoint trap printf "argc: %d\n",*(int*)$esp printf "argv[0]: %s\n",((char**)($esp + 4))[0] quit
示例会话
$cc -nostdlib -g3 -m32 cmdline-x86.S -o cmdline-x86 $gdb -q -x cmdline-x86.gdb cmdline-x86 <...> Program received signal SIGTRAP,Trace/breakpoint trap. _start () at cmdline-x86.S:8 8 mov $SYS_exit_group,%eax argc: 1 argv[0]: /home/scottt/DropBox/stackoverflow/cmdline-x86
说明
>我放置了一个软件断点(int $0x03),使程序在ELF入口点(_start)之后立即陷入调试器.
>然后我在GDB脚本中使用printf进行打印
>带有表达式*(int *)$esp的argc
>带表达式的argv((char **)($esp 4))[0]
x86-64版本
差异很小:
>用RSP替换ESP
>将地址大小从4更改为8
>当我们调用exit_group(0)来正确终止进程时,遵守不同的Linux系统调用约定
cmdline.S
#include <sys/syscall.h> .global _start _start: /* Cause a breakpoint trap */ int $0x03 /* exit_group(0) */ mov $SYS_exit_group,%rax mov $0,%rdi syscall
cmdline.gdb
set confirm off file cmdline run printf "argc: %d\n",*(int*)$rsp printf "argv[0]: %s\n",((char**)($rsp + 8))[0] quit
常规C程序如何获得argc和argv
您可以从常规C程序中反汇编_start,以查看它是如何从堆栈中获取argc和argv并在调用__libc_start_main时传递它们的.以我的x86-64机器上的/ bin / true程序为例:
$gdb -q /bin/true Reading symbols from /usr/bin/true...Reading symbols from /usr/lib/debug/usr/bin/true.debug...done. done. (gdb) disassemble _start Dump of assembler code for function _start: 0x0000000000401580 <+0>: xor %ebp,%ebp 0x0000000000401582 <+2>: mov %rdx,%r9 0x0000000000401585 <+5>: pop %rsi 0x0000000000401586 <+6>: mov %rsp,%rdx 0x0000000000401589 <+9>: and $0xfffffffffffffff0,%rsp 0x000000000040158d <+13>: push %rax 0x000000000040158e <+14>: push %rsp 0x000000000040158f <+15>: mov $0x404040,%r8 0x0000000000401596 <+22>: mov $0x403fb0,%rcx 0x000000000040159d <+29>: mov $0x4014c0,%rdi 0x00000000004015a4 <+36>: callq 0x401310 <__libc_start_main@plt> 0x00000000004015a9 <+41>: hlt 0x00000000004015aa <+42>: xchg %ax,%ax 0x00000000004015ac <+44>: nopl 0x0(%raX)
__libc_start_main()的前三个参数是:
> RDI:指向main()的指针
> RSI:argc,你可以看到它是如何从堆栈弹出的第一件事
> RDX:argv,弹出argc后RSP的值. (GLIBC源代码中的ubp_av)
x86 _start非常相似:
Dump of assembler code for function _start: 0x0804842c <+0>: xor %ebp,%ebp 0x0804842e <+2>: pop %esi 0x0804842f <+3>: mov %esp,%ecx 0x08048431 <+5>: and $0xfffffff0,%esp 0x08048434 <+8>: push %eax 0x08048435 <+9>: push %esp 0x08048436 <+10>: push %edx 0x08048437 <+11>: push $0x80485e0 0x0804843c <+16>: push $0x8048570 0x08048441 <+21>: push %ecx 0x08048442 <+22>: push %esi 0x08048443 <+23>: push $0x80483d0 0x08048448 <+28>: call 0x80483b0 <__libc_start_main@plt> 0x0804844d <+33>: hlt 0x0804844e <+34>: xchg %ax,%ax End of assembler dump.
以上是大佬教程为你收集整理的x86 Linux汇编程序从_start获取程序参数全部内容,希望文章能够帮你解决x86 Linux汇编程序从_start获取程序参数所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。