用汇编语言解释这一行?

Posted

技术标签:

【中文标题】用汇编语言解释这一行?【英文标题】:Interpreting this line in Assembly language? 【发布时间】:2018-10-21 01:39:21 【问题描述】:

下面是一个反汇编的 C 程序的前 5 行,我试图将其逆向工程回它的 C 代码,以便更好地学习汇编语言。在这段代码的开头,我看到它在堆栈上腾出空间并立即调用

0x000000000040054e <+8>:    mov    %fs:0x28,%rax

我很困惑这条线做了什么,以及从相应的 C 程序中调用它的可能是什么。到目前为止,我唯一一次看到这一行是在调用 C 程序中的不同方法时,但这次它后面没有任何 Callq 指令,所以我不太确定......任何想法还有什么可能在这C 程序进行此调用?

0x0000000000400546 <+0>:    push   %rbp
0x0000000000400547 <+1>:    mov    %rsp,%rbp   
0x000000000040054a <+4>:    sub    $0x40,%rsp
0x000000000040054e <+8>:    mov    %fs:0x28,%rax
0x0000000000400557 <+17>:   mov    %rax,-0x8(%rbp)
0x000000000040055b <+21>:   xor    %eax,%eax
0x000000000040055d <+23>:   movl   $0x17,-0x30(%rbp)
...

我知道这是为缓冲区溢出攻击提供某种形式的堆栈保护,我只需要知道如果不是单独的方法,哪些 C 代码会提示这种保护。

【问题讨论】:

可以设置stack canary吗?您可以尝试使用和不使用 -fno-stack-protector 进行编译,看看它是否会改变。 可能是在堆栈上分配缓冲区的代码(我们已经看到这里发生了这种情况)并可能将其传递给其他函数(在函数后面,未显示)在自动启用时触发此保护。只需将代码转录为 C,然后看看它的发生。或者只是不关心它。 for / while 循环会触发这种类型的保护吗?我注意到在代码的末尾有一个 je 指令在 main() 中前进。 不太可能。但是我们看到sub $0x040,%rsp 这意味着分配了一些本地人。要么它本身就足够了,要么它被传递给其他函数。 【参考方案1】:

正如您所说,这是用于防止缓冲区溢出的代码。编译器为具有可能是可能溢出的缓冲区的局部变量的函数生成此“堆栈金丝雀检查”。请注意您所询问的行上方和下方的说明:

sub  $0x40, %rsp
mov  %fs:0x28, %rax
mov  %rax, -0x8(%ebp)
xor  %eax, %eax

sub 在堆栈上分配了 64 字节的空间,这对于至少一个小数组来说已经足够了。然后将一个秘密值从%fs:0x28 复制到该空间的顶部,就在前一帧指针和返回地址的下方,然后将其从寄存器文件中擦除。

函数体对数组做一些事情;如果它写入到数组末尾足够远的地方,它将覆盖秘密值。在函数的最后,会有类似

的代码
    mov    -0x8(%rbp), %rax
    xor    %fs:28, %rax
    jne    1
    mov    %rbp, %rsp
    pop    %rbp
    ret
1:
    call    __stack_chk_fail   # does not return

这将验证秘密值是否未更改,如果已更改,则程序会崩溃。这个想法是有人试图利用一个简单的缓冲区溢出漏洞,就像你在使用 gets 时遇到的那样,将无法在不修改秘密值的情况下更改返回地址。

编译器有several different heuristics,可通过命令行选项选择,用于决定何时需要生成堆栈金丝雀保护代码。

你不能自己写对应这个汇编语言的C代码,因为它使用了不寻常的%fs:nnnn寻址方式; stack-canary 代码故意使用其他代码生成不依赖的寻址模式,以使攻击者尽可能难以了解秘密值。

【讨论】:

非常感谢!您对以下代码绝对正确。我用一组整数对其进行了测试,并且能够重新创建整个事物。非常感激!这现在更有意义了。

以上是关于用汇编语言解释这一行?的主要内容,如果未能解决你的问题,请参考以下文章

把高级语言编写的源程序转换为可执行程序的过程叫啥?

明解C语言的代码清单5-13看不明白

Python3入门——概述与环境安装

C语言怎么做到从文件中读取一行数据,然后改变这一行内容

c语言中的星号“*” 都有啥作用,含代码提问 求帮忙读一行程序

C语言新手求大佬解释一下代码当中的一行