string - 为什么这个堆栈字符串不会在 macOS 上的 x64 NASM 中打印?
问题描述
我已经能够sys_write
在 macOS 上使用 to stdout 成功打印字符串。但是,我无法使用execve
syscall打印此堆栈字符串echo
:
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
目前,我的回报是来自 EFAULT 状态码execve
。
屏幕截图中显示的内存布局是字符串“This is a test”,后跟用于终止的空字节。
更新:跟踪输出:execve("/bin/echo", [0x6863652f6e69622f, 0x6f, 0x7420612073696874, 0x747365], NULL) = -1 EFAULT (Bad address)
解决方案
execve
需要 3 个参数:一个char*
和两个char *[]
数组,每个数组都由一个 NULL 指针终止。
你的第一个参数很好。它指向一个以零结尾的 ASCII 字符数组,这是一个有效的路径。
您argv
是 a char[]
,不是char *[]
,因为您传递的值与您的第一个 arg 相同!因此,当系统调用将数据解释为要复制到新进程的 arg 数组中的指针数组时,它会找到一个无效指针0x6863652f6e69622f
作为第一个指针。(该指针的字节是 ASCII 代码。)
跟踪输出非常清楚。
您的第三个是 NULL,而不是指向NULL 的指针。Linux 支持这一点,将 NULL 视为空数组。我不知道 MacOS 有没有;如果在将有效的argv[]
集合 RDX 传递给指向堆栈上某处的 qword 0 的指针后仍然得到 EFAULT。
保留现有的设置代码,您可以将最后一部分更改为
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[]
andargv[]
由相同的 NULL 指针终止。如果你想要一个非空的envp
,你就不能这样做。
如果这应该是 shellcode,你将需要push 0
用推送一个异或零寄存器来替换,看起来你可以简化一些其他的东西。但先让它工作。
推荐阅读
- jquery - 如何使用 jQuery 滑块显示文本值?
- node.js - Nightwatch:无法创建新服务:ChromeDriverService
- python - 如何从 Pandas 中的给定行和列开始读取 Excel 文件
- ignite - Apache Ignite 与 SQL Server 性能对比
- c# - 通过 .NET 访问电话文件
- azure - MarkLogic - 森林数据文件夹和 Azure Blob
- c# - Automapper EF 类到模型类
- python - 从 CSV 读取并计算平均值(python)
- charts - Chart.js 图表只有两个坐标
- reactjs - 将 basename 设置为 Domain/reactapp/#/home 而不是 Domain/#/reactapp/home