我想使用gdb作为拦截open
系统调用的方法,并让应用程序获取不同文件的句柄。类似的东西:
replace-file filea=fileb cat filea
# prints out contents of fileb
我可以拦截open
系统调用,但我必须提供一个新的文件名,该文件名应该是一个存在于下级内存中的字符串。
我想避免使用malloc
,因为那时我依赖于下层可用的lib,而是将它存储在堆栈中(“在流程使用的部分之后”),因为我只需要它下一个代码行,我之后被覆盖没有问题。
# 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]
答案 0 :(得分:2)
你有自己的论据可以绕开错误的方向。它&#39; S:
char *strcpy(char *dest, const char *src);
但你有:
call strcpy($newfile, $rsp)
我认为$newfile
确实是$file_b
您要使用的新名称,因此这应该是src,而$rsp
是您要放置新文件名的位置,所以这个。
您还需要将修改后的$rsp
值存储到$rdi
中,以便open
看到更改的参数。