为什么在macOS的x64 NASM中不显示此堆栈字符串?

时间:2019-12-05 00:22:38

标签: string macos assembly stack nasm

我已经能够使用sys_write成功打印一个字符串到stdout在macOS上。但是,我无法使用execveecho的系统调用来打印此堆栈字符串:

global _main
default rel

section .text
_main:
mov rbp, rsp
sub rsp, 32
mov rax, 'this a t'
mov [rbp-16], rax
mov rax, 'est'
mov [rbp-8], rax
mov rax, '/bin/ech'
mov [rbp-32], rax
xor rax, rax
mov al, 'o'
mov [rbp-24], rax
push 0
mov rax, 0
mov [rbp], rax



exit_program:

;rdi filename
;rsi argv
;rdx envp
lea rdi, [rbp-32]
lea rsi, [rbp-32]
mov rdx, 0
mov rax, 0x200003b
syscall

目前,我的回馈是来自execve的EFAULT状态代码。

如屏幕快照所示,内存布局是字符串“ This is a test”,后跟空字节以终止。

更新:跟踪输出:execve("/bin/echo", [0x6863652f6e69622f, 0x6f, 0x7420612073696874, 0x747365], NULL) = -1 EFAULT (Bad address) enter image description here

1 个答案:

答案 0 :(得分:2)

execve需要3个参数:一个char*和两个char *[]数组,每个数组都由NULL指针终止。

您的第一个arg很好。它指向一个以零结尾的ASCII字符数组,这是一个有效路径。

您的argvchar[],而不是char *[],因为您传递的值与第一个arg相同!因此,当系统调用将数据解释为要复制到新进程的arg数组的指针数组时,它将发现无效的指针0x6863652f6e69622f作为第一个指针。 (该指针的字节是ASCII码。)

跟踪输出清楚地表明了这一点。

您的第3个为NULL,而不是指向 NULL的指针。 Linux支持此功能,将NULL视为空数组。我不知道MacOS是否可以。如果您在传递有效的argv[]之后仍然得到EFAULT,请将RDX设置为指向堆栈中某个位置的qword 0的指针。

保留现有的设置代码,您可以将最后一部分更改为

lea rdi, [rbp-32]  ; pointer to "/bin/echo"

push 0             ; NULL terminator
mov  rdx, rsp      ; envp = empty array
push some_reg    ; holding a pointer to "this is a test"
push rdi           ; pointer to "/bin/echo" = argv[0]
mov  rsi, rsp      ; argv

syscall

请注意,envp[]argv[]由相同的NULL指针终止。如果您想要一个非空的envp,则不能这样做。

如果这应该是shellcode,则您需要通过推送异或为零的寄存器来替换push 0,并且看起来您可以简化其他一些内容。但是先让它工作。