首页 > 解决方案 > 如何在 Linux 上从头开始反汇编?

问题描述

   │0x565554fd <main>                       lea    0x4(%esp),%ecx                      │
   │0x56555501 <main+4>                     and    $0xfffffff0,%esp                    │
   │0x56555504 <main+7>                     pushl  -0x4(%ecx)                          │
   │0x56555507 <main+10>                    push   %ebp                                │
   │0x56555508 <main+11>                    mov    %esp,%ebp                           │
   │0x5655550a <main+13>                    push   %ebx                                │
   │0x5655550b <main+14>                    push   %ecx                                │
   │0x5655550c <main+15>                    call   0x56555529 <__x86.get_pc_thunk.ax>  │
   │0x56555511 <main+20>                    add    $0x1acb,%eax                        │
B+>│0x56555516 <main+25>                    mov    %eax,%ebx                           │
   │0x56555518 <main+27>                    call   0x5655552d <swap>                   │
   │0x5655551d <main+32>                    mov    $0x0,%eax                           │
   │0x56555522 <main+37>                    pop    %ecx                                │
   │0x56555523 <main+38>                    pop    %ebx                                │
   │0x56555524 <main+39>                    pop    %ebp                                │
   │0x56555525 <main+40>                    lea    -0x4(%ecx),%esp                     │
   │0x56555528 <main+43>                    ret                                        │
   │0x56555529 <__x86.get_pc_thunk.ax>      mov    (%esp),%eax                         │
   │0x5655552c <__x86.get_pc_thunk.ax+3>    ret                                        │
   │0x5655552d <swap>                       push   %ebp                                │
   │0x5655552e <swap+1>                     mov    %esp,%ebp                           │
   │0x56555530 <swap+3>                     sub    $0x10,%esp                          │
   │0x56555533 <swap+6>                     call   0x56555529 <__x86.get_pc_thunk.ax>  │
   │0x56555538 <swap+11>                    add    $0x1aa4,%eax                        │
   │0x5655553d <swap+16>                    lea    0x3c(%eax),%edx                     │
   │0x56555543 <swap+22>                    lea    0x2c(%eax),%ecx                     │
   │0x56555549 <swap+28>                    lea    0x4(%ecx),%ecx     

事情就是这样。请给我任何线索如何从一开始就使用 GDB 遍历程序集?每次我启动程序时,它都从 main() 函数开始,而不是 __libc_start_main() 的开头。

如果有人能帮我这个忙,我将不胜感激。

标签: linuxassemblyx86gdb

解决方案


使用 GDB 的starti命令 to run,但在第一条用户空间指令之前停止(即使它在动态链接器内部)。这就像在之前的入口点设置一个临时断点run。对于不支持的旧 GDB 版本starti,有一些技巧,比如b *0创建一个无效断点,然后在使用run. (停在 GDB 中的第一条机器代码指令处

或者,如果您只想从__libc_start_main您的_start或动态链接器的开始,请_start在此处设置断点。

从那里您可以使用si(aka stepi) 单步说明。

您可能想要layout reglayout asm为此。

您可能想要构建一个非 PIE 可执行文件 ( gcc -no-pie -fno-pie),尽管无论哪种方式,动态链接器都会在跳转到可执行文件的_start.


如何从我的代码片段的 0x565554fd 开始?

这是一个完全不同的问题。

这只是顶部main

GDB 部分是为 C 调试而设计的,有时喜欢为您省去处理函数序言的麻烦。在这种情况下, 32-bitmain的序言对齐堆栈并使用 PC 相关方法获取 GOT 指针(因为它是 PIE 可执行文件)。

你可以再次b *0x565554fdrun你的程序。

或者使用非 PIE,您可以main在第一次运行之前轻松获取真实地址。


推荐阅读