将字符串复制到gdb中的堆栈

时间:2016-10-17 13:26:21

标签: c pointers gdb

为什么

我想使用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]

1 个答案:

答案 0 :(得分:2)

你有自己的论据可以绕开错误的方向。它&#39; S:

char *strcpy(char *dest, const char *src);

但你有:

call strcpy($newfile, $rsp)

我认为$newfile确实是$file_b您要使用的新名称,因此这应该是src,而$rsp是您要放置新文件名的位置,所以这个。

您还需要将修改后的$rsp值存储到$rdi中,以便open看到更改的参数。