二进制行为的差异(执行/在调试器下)

逆向工程 x86-64 数据库
2021-06-19 22:54:24

我正在尝试一个简单的堆溢出示例(http://highaltitudehacks.com/2020/09/05/arm64-reversing-and-exploitation-part-1-arm-instruction-set-heap-overflow/)但复制了x86/x64 中的相关代码以更好地理解它。这是我使用的代码

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

int main(int argc, char *argv[])
{
    char *name = malloc(0x6);
    char *command = malloc(0x6);
    strcpy(command,"whoami");
    strcpy(name,"zzzzzzzzzzzzzzzzls -l");

    system(command);
}

我注意到如果我编译代码并正常运行它,我会让系统执行“ls -l”并列出文件夹。但是,如果我从开始到中途使用 lldb 单步执行二进制文件,然后在 lldb 内部继续执行其余的操作,我将看到执行的是“whoami”。

我正在 Mac OS 上测试这个,我不确定这是由于 lldb 还是 Mac OS 行为?

1个回答

为了使nameto的溢出command起作用,两者的地址之间的差应为 0x10 字节。

我验证了我之前在案例中提到的内容 - 添加

printf("%p:%p\n", name, command);

在调试器单步执行 main 下给出的地址为

0x100404080:0x1002059f0

这里 delta > 0x10 字节,因此name strcpy不会溢出到command

而没有步进或没有调试器出来

0x7fa890405830:0x7fa890405840

正好是 0x10 字节。