【发布时间】:2016-10-17 13:26:21
【问题描述】:
为什么
我想使用 gdb 作为拦截 open 系统调用的一种方式,并让应用程序获得与它所要求的不同文件的句柄。类似的东西:
replace-file filea=fileb cat filea
# prints out contents of fileb
我可以拦截open 系统调用,但我必须提供一个新的文件名,它应该是一个存在于下层内存中的字符串。
我想避免为此使用malloc,因为那时我依赖于下级中可用的库,而是将其存储在堆栈中(“在”进程使用的部分之后),因为我只需要下一个代码线,我对它之后被覆盖没有问题。
什么
但是,我很难写入堆栈。
我知道堆栈向下增长,所以我尝试将堆栈指针减少我的字符串的大小,将字符串复制到指针,然后增加堆栈指针。我在将字符串复制到堆栈指针指向的位置时遇到了麻烦。
到目前为止我所拥有的:
# script.gdb
handle all pass handle al pass
set print thread-events off
set $file_a = "/etc/fstab"
set $file_b = "/etc/passwd"
set $len = $_strlen($file_b)
set $len = $len + 1
catch syscall open
commands
silent
# $rax == return value
# IF x64, $rdi == filename
set $outside = ! $outside
if ( $_streq((char *)$rdi, $file_a) )
printf "rsp: %d\n", $rsp
set $rsp = $rsp - $len
printf "rsp: %d\n", $rsp
call strcpy($rsp, $file_b)
printf "rsp: %d\n", $rsp
printf "%d: %s\n", $rsp,$rsp
set $rsp = $rsp + $len
end
continue
end
run
测试用例:
$ gdb -batch -q -x script.gdb --args python -c "print open('/etc/fstab').read()"
Catchpoint 1 (syscall 'open' [2])
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
rsp: -10392
rsp: -10404
$1 = -10404
rsp: -10404
-10404: /etc/passwd
Traceback (most recent call last):
File "<string>", line 1, in <module>
IOError: [Errno 38] Function not implemented: '/etc/fstab'
[Inferior 1 (process 25336) exited with code 01]
【问题讨论】:
-
堆栈对齐是否可能是问题所在? linux 上的 x86-64 需要 16 字节的堆栈对齐。所以像
set $old = $rsp、set $rsp = $rsp - $len、set $rsp = (unsigned long long)$rsp & (unsigned long long)~0xf、.....、set $rsp = $old这样的东西可能会起作用 -
@Andrew 不。虽然对齐很有趣,因为它提到了“strcpy-sse2-unaligned”。我怀疑这里的 strcpy 不好,需要换成别的东西
-
我目前认为在系统调用中间执行代码是问题所在。我得到的错误看起来类似于github.com/mozilla/rr/issues/605