用汇编语言解释这一行?
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 代码故意使用其他代码生成不依赖的寻址模式,以使攻击者尽可能难以了解秘密值。
【讨论】:
非常感谢!您对以下代码绝对正确。我用一组整数对其进行了测试,并且能够重新创建整个事物。非常感激!这现在更有意义了。以上是关于用汇编语言解释这一行?的主要内容,如果未能解决你的问题,请参考以下文章