排除这个asm x86代码

时间:2017-05-31 14:28:10

标签: c assembly x86 instructions

首先,这是汇编代码:

/           0x000006a0      55             push rbp                             
|           0x000006a1      4889e5         mov rbp, rsp                         
|           0x000006a4      4883ec10       sub rsp, 0x10                        
|           0x000006a8      488d05b50000.  lea rax, str.AAAA           ; 0x764  

|           0x000006af      488945f8       mov qword [local_8h], rax  
|           0x000006b3      488b45f8       mov rax, qword [local_8h]

|           0x000006b7      4889c6         mov rsi, rax                         
|           0x000006ba      488d3da80000.  lea rdi, 0x00000769         ; "%s"   
|           0x000006c1      b800000000     mov eax, 0                           
|           0x000006c6      e895feffff     call sym.imp.printf         ;[2] ; i 
|           0x000006cb      b800000000     mov eax, 0                           
|           0x000006d0      c9             leave                                
\           0x000006d1      c3             ret  

到这个c程序:

#include <stdio.h>
#include <string.h>

int main(){

    char* a = "AAAA";

    printf("%s", a);
    return 0;
}

特别是我对这段代码有疑问:

|           0x000006af      488945f8       mov qword [local_8h], rax            
|           0x000006b3      488b45f8       mov rax, qword [local_8h]

这两条指令的含义是什么?我只看到相同的指令,而不是逆转。但那为什么呢?

以下是可执行文件的一些进一步信息:

blksz    0x0
block    0x100
fd       6
file     demo
format   elf64
iorw     false
mode     -r--
size     0x20e0
humansz  8.2K
type     DYN (Shared object file)
arch     x86
binsz    6559
bintype  elf
bits     64
canary   false
class    ELF64
crypto   false
endian   little
havecode true
intrp    /lib64/ld-linux-x86-64.so.2
lang     c
linenum  true
lsyms    true
machine  AMD x86-64 architecture
maxopsz  16
minopsz  1
nx       true
os       linux
pcalign  0
pic      true
relocs   true
relro    partial relro
rpath    NONE
static   false
stripped false
subsys   linux
va       true

2 个答案:

答案 0 :(得分:2)

线条彼此分开:

第一行属于行char* a = "AAAA";,将变量的值保存到RAM。

第二行从RAM中获取行printf("%s", a);的变量作为参数。

从技术上讲,这两行都是可选的,正如你可以写的那样:

printf("%s", "AAAA");

编辑:要跳过此不必要的代码,您可以启用自动优化(对于GCC:-O2)

答案 1 :(得分:0)

问题在于您的反汇编程序已损坏(或至少#34;太聪明&#34;)和#34;有帮助的&#34;从你通常期望的内容中获取不同的,令人困惑的信息。这两行:

|           0x000006af      488945f8       mov qword [local_8h], rax            
|           0x000006b3      488b45f8       mov rax, qword [local_8h]

应该是

|           0x000006af      488945f8       mov qword [rbp-8h], rax            
|           0x000006b3      488b45f8       mov rax, qword [rbp-8h]

它们通过rbp寄存器间接访问堆栈帧中的内存。编译器将此类内存用于局部变量,因此&#34; local&#34;在反汇编程序中显示的内容。