Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这个极简C代码在汇编级别上到底发生了什么?_C_Assembly - Fatal编程技术网

这个极简C代码在汇编级别上到底发生了什么?

这个极简C代码在汇编级别上到底发生了什么?,c,assembly,C,Assembly,我目前正在努力理解 C代码,用cc-ggdb-exploitable.C-o-exploitable #include <stdio.h> void exploitableFunction (void) { char small[30]; gets (small); printf("%s\n", small); } main() { exploitableFunction(); return 0; } #包括 void可利用函数(void

我目前正在努力理解

C代码,用
cc-ggdb-exploitable.C-o-exploitable

#include <stdio.h>

void exploitableFunction (void) {
    char small[30];
    gets (small);
    printf("%s\n", small);
}

main() {
    exploitableFunction();
    return 0;
}
#包括
void可利用函数(void){
半焦小[30];
得到(小);
printf(“%s\n”,小);
}
main(){
可利用函数();
返回0;
}
似乎有汇编代码

0x000000000040063b <+0>:    push   %rbp
0x000000000040063c <+1>:    mov    %rsp,%rbp
0x000000000040063f <+4>:    callq  0x4005f6 <exploitableFunction>
0x0000000000400644 <+9>:    mov    $0x0,%eax
0x0000000000400649 <+14>:   pop    %rbp
0x000000000040064a <+15>:   retq
0x0000000000040063B:推送%rbp
0x0000000000040063C:mov%rsp,%rbp
0x000000000040063f:callq 0x4005f6
0x00000000000400644:mov$0x0,%eax
0x0000000000400649:弹出%rbp
0x000000000040064a:retq
我认为它可以做到以下几点,但我真的不确定,如果我是对的/什么是对的,我想听听有汇编代码经验的人的意见

  • 40063b:将当前在基指针寄存器中的地址放入堆栈段(该寄存器是如何初始化的?为什么要初始化?)
  • 40063c:将堆栈指针寄存器中的值复制到基指针寄存器中(为什么?)
  • 40063f:调用可利用函数(在程序集中“调用”函数到底意味着什么?这里发生了什么?)
  • 400644:将值从地址$0x0复制到EAX寄存器
  • 400649:将堆栈顶部的值(由%rsp中的值确定)复制到基指针寄存器中(似乎由确认)
  • 40064a:返回(操作系统使用%EAX中的内容作为返回代码-因此我猜地址$0x0包含常量0?或者这不是地址而是常量?)
我发现了一个与您自己的代码类似的代码,并提供了完整的解释

  • 40063b:将旧的基指针推送到堆栈上以保存它以备将来使用。推送它是因为这不是代码中的唯一进程。其他一些过程称之为
  • 40063c:将堆栈指针的值复制到基指针。在此之后,
    %rbp
    指向
    堆栈帧的底部
  • 40063f:调用address
    0x4005f6
    中的函数,该函数将程序计数器推入堆栈,并将address
    0x4005f6
    加载到程序上下文中,当函数返回时,发生pop操作,将堆栈中保存的地址返回到程序计数器,此处为
    0x400644
  • 400644:此指令将
    0
    复制到
    %eax
    中,x86调用约定规定函数的返回值存储在
    %eax
  • 400649:我们从堆栈中弹出旧的基指针,并将其存储回
    %rbp
  • 40064a:跳回返回地址,返回地址也存储在堆栈帧中。它指定程序的结束
另外,您没有提到函数的汇编代码
可利用函数
。这里只有
main
函数

我找到了一个与您自己的代码类似的函数,并且有完整的解释

  • 40063b:将旧的基指针推送到堆栈上以保存它以备将来使用。推送它是因为这不是代码中的唯一进程。其他一些过程称之为
  • 40063c:将堆栈指针的值复制到基指针。在此之后,
    %rbp
    指向
    堆栈帧的底部
  • 40063f:调用address
    0x4005f6
    中的函数,该函数将程序计数器推入堆栈,并将address
    0x4005f6
    加载到程序上下文中,当函数返回时,发生pop操作,将堆栈中保存的地址返回到程序计数器,此处为
    0x400644
  • 400644:此指令将
    0
    复制到
    %eax
    中,x86调用约定规定函数的返回值存储在
    %eax
  • 400649:我们从堆栈中弹出旧的基指针,并将其存储回
    %rbp
  • 40064a:跳回返回地址,返回地址也存储在堆栈帧中。它指定程序的结束
另外,您没有提到函数的汇编代码
可利用函数
。这里只有
main
功能

40063b:将当前在基指针寄存器中的地址放入堆栈段(该寄存器是如何初始化的?为什么要初始化?)


您希望保存基指针,因为调用函数可能正在使用它

40063c:将堆栈指针寄存器中的值复制到基指针寄存器中(为什么?)

这为您提供了堆栈中的固定位置,其中可能包含函数的参数。它也可以用作任何局部变量的基址

40063f:调用可利用函数(在程序集中“调用”函数到底意味着什么?这里发生了什么?)

“调用”意味着将返回地址(下一条指令的地址)推到堆栈上,然后跳到被调用函数的开头

400644:将值从地址$0x0复制到EAX寄存器

它实际上是return语句中的值0

400649:将堆栈顶部的值(由%rsp中的值确定)复制到基指针寄存器(似乎已由汇编器确认:Push/pop寄存器?)

这将恢复我们在顶部保存的基本指针。调用函数可能会假定我们这样做

40064a:返回(操作系统使用%EAX中的内容作为返回代码-因此我猜地址$0x0包含常量0?或者这不是地址而是常量?)

它是
返回0
中的常量。将EAX用于较小的返回值是一种常见的约定

40063b:将当前在基指针寄存器中的地址放入堆栈段(该寄存器是如何初始化的?为什么要初始化?)


您希望保存基指针,因为调用函数可能正在使用它

40063c:将堆栈指针寄存器中的值复制到bas中
; int example(char *s, int i)
    push        bp                    ; save the caller's value of bp
    mov         bp,sp                 ; set-up our base pointer to the stack-frame
    sub         sp, 16                ; room for automatic variables
    mov         ax,dword ptr [bp+8]   ; ax has *s
    mov         bx,dword ptr [bp+12]  ; bx has i
    ...                               ; do your thing
    mov         ax, dword ptr[result] ; function return in ax
    pop         bp                    ; restore caller's base-pointer
    ret
; i= example(myString, k);
    mov         ax, [bp+16]        ; this gets a parameter of the curent function
    push        ax                 ; this will be parameter i
    mov         ax, [bp-16]        ; this gets a local variable
    push        ax                 ; this is parameter s
    call        example
    add         sp,8               ; remove the pushed parameters from the stack
    mov         dword ptr [i], ax  ; save return value - always in ax