C 挂接某些系统调用的linux内核模块无法在用户空间中看到字符串参数

C 挂接某些系统调用的linux内核模块无法在用户空间中看到字符串参数,c,linux,kernel,hook,system-calls,C,Linux,Kernel,Hook,System Calls,我正在为一个类做一个练习,使用linux内核模块在运行的内核上钩住一些系统调用,并使用新的_sys_call()代替旧的。我正在CentOS 7上开发并使用一个股票内核-3.10.0-862.3.2。我能够成功地钩住execve,并且可以访问参数值,但似乎无法访问rename syscall参数值。我意识到这可能不是一种实际的方法,但我正在尝试学习更多关于内核开发和系统调用如何工作的知识 以下是挂钩方法定义的示例: /* Original Syscall Prototype */ asml

我正在为一个类做一个练习,使用linux内核模块在运行的内核上钩住一些系统调用,并使用新的_sys_call()代替旧的。我正在CentOS 7上开发并使用一个股票内核-3.10.0-862.3.2。我能够成功地钩住execve,并且可以访问参数值,但似乎无法访问rename syscall参数值。我意识到这可能不是一种实际的方法,但我正在尝试学习更多关于内核开发和系统调用如何工作的知识

以下是挂钩方法定义的示例:

/*
   Original Syscall Prototype
*/
asmlinkage long (*orig_sys_chdir_fn)(const char __user *filename);

/*
new syscall
*/
asmlinkage long new_sys_chdir(const char __user *filename) {

   // do stuff
   return orig_sys_chdir_fn(filename);
}
我们使用以下代码获取存根chdir地址:

orig_stub_chdir_addr = ((unsigned long *)(sys_call_table_addr))[__NR_chdir];



  Thread 357 hit Breakpoint 3, new_sys_rename (oldname=0xffffff9c <error: Cannot access memory at address 0xffffff9c>,
    newname=0xffffff9c <error: Cannot access memory at address 0xffffff9c>) at /home/ulys/syshooks/kmod/sysrename.c:19
19      asmlinkage long new_sys_rename(const char __user *oldname,  const char __user *newname) {
(gdb) info registers
rax            0xffffffff8122dbd0       -2128421936
rbx            0x0      0
rcx            0x7ffd0faf9480   140724866618496
rdx            0xffffff9c       4294967196
rsi            0xffffff9c       4294967196
rdi            0xffffff9c       4294967196
rbp            0xffff88004183bf48       0xffff88004183bf48
rsp            0xffff88004183bf40       0xffff88004183bf40
r8             0x0      0
r9             0x1      1
r10            0x7ffd0faf7320   140724866609952
r11            0x202    514
r12            0x0      0
r13            0x0      0
r14            0x0      0
r15            0x0      0
rip            0xffffffffc0540b20       0xffffffffc0540b20 <new_sys_rename>
eflags         0x10246  [ PF ZF IF RF ]
cs             0x10     16
ss             0x18     24
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0xb      11
(gdb) info stack
#0  new_sys_rename (oldname=0xffffff9c <error: Cannot access memory at address 0xffffff9c>,
    newname=0xffffff9c <error: Cannot access memory at address 0xffffff9c>) at /home/ulys/syshooks/kmod/sysrename.c:19
#1  0xffffffff8122dbee in gather_surplus_pages (delta=-2123237509, h=0x0 <irq_stack_union>) at mm/hugetlb.c:1764
#2  hugetlb_acct_memory (h=0x0 <irq_stack_union>, delta=-2123237521) at mm/hugetlb.c:3149
#3  0xffffffff8171f82f in inet_netconf_fill_devconf (skb=0xffffffff8171f77b <inet_netconf_fill_devconf+123>,
    ifindex=<optimized out>, devconf=<optimized out>, portid=<optimized out>, seq=<optimized out>, flags=<optimized out>,
    type=<error reading variable: Cannot access memory at address 0x10>, event=80) at net/ipv4/devinet.c:1786
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) x/s 0x7ffd0faf9480
0x7ffd0faf9480: "/tmp/test2"
orig_stub_chdir_addr=((无符号长*)(sys_call_table_addr))[\uu NR_chdir];
线程357命中断点3,新的系统重命名(oldname=0xffffff9c,
newname=0xffffff9c)位于/home/ulys/syshooks/kmod/sysrename.c:19
19.长新建系统重命名(常量字符用户*旧名称,常量字符用户*新名称){
(gdb)信息寄存器
rax 0xFFFFFF8122DBD0-2128421936
rbx 0x0 0
rcx 0x7ffd0faf9480 140724866618496
rdx 0xFFFF9C 4294967196
rsi 0xFFFF9C 4294967196
rdi 0xFFFF9C 4294967196
rbp 0xffff88004183bf48 0xffff88004183bf48
rsp 0xffff88004183bf40 0xffff88004183bf40
r8 0x0 0
r9 0x1
r10 0x7ffd0faf7320 140724866609952
r11 0x202 514
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0xFFFFFFC0540B20 0xffffffffc0540b20
eflags 0x10246[PF ZF IF RF]
cs 0x10 16
ss 0x18 24
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0xb 11
(gdb)信息堆栈
#0新系统重命名(旧名称=0xffffff9c,
newname=0xffffff9c)位于/home/ulys/syshooks/kmod/sysrename.c:19
#1 0xFFFFFF8122DBEE位于mm/hugetlb.c:1764处的聚集页面(增量=-21237509,h=0x0)
#在mm/hugetlb.c:3149处有2个hugetlb账户内存(h=0x0,delta=-21237521)
#3.0xFFFFFF8171F82F在inet_netconf_fill_devconf中(skb=0xffffffff8171f77b,
ifindex=,devconf=,portid=,seq=,flags=,
net/ipv4/devinet.c:1786上的type=,event=80)
回溯已停止:此帧内部的上一帧(堆栈损坏?)
(gdb)x/s 0x7ffd0faf9480
0x7ffd0faf9480:“/tmp/test2”
您可以在0xFFFF9C处看到伪地址,这些地址无法从用户处通过copy_读取,也无法被new_sys_rename函数中的任何东西使用。您可以看到newname在寄存器rcx中,但我找不到oldname。我在几个不同的基于文件名的系统调用(如chmod和chdir)中也注意到了这一点

在chdir上,除了在任何寄存器中都找不到文件名之外,我收到了类似的结果

Thread 304 hit Breakpoint 1, new_sys_chdir (
    filename=0xffffff9c <error: Cannot access memory at address 0xffffff9c>)
    at /home/ulys/syshooks/kmod/syschdir.c:17
17      asmlinkage long new_sys_chdir(const char __user *filename) {
(gdb) info registers
rax            0x0      0
rbx            0x0      0
rcx            0xffff880055d47f18       -131939955343592
rdx            0x3      3
rsi            0x3      3
rdi            0xffffff9c       4294967196
rbp            0xffff880055d47f48       0xffff880055d47f48
rsp            0xffff880055d47f10       0xffff880055d47f10
r8             0xc919d0 13179344
r9             0xcba2d0 13345488
r10            0x7f7147cfd030   140124512833584
r11            0x246    582
r12            0x3      3
r13            0xc8f320 13169440
r14            0x0      0
r15            0x0      0
rip            0xffffffffc0561000       0xffffffffc0561000 <new_sys_chdir>
eflags         0x10246  [ PF ZF IF RF ]
cs             0x10     16
ss             0x18     24
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0xb      11
(gdb) x/s 0xffff880055d47f18
0xffff880055d47f18:     "o\367q\201\377\377\377\377{\367q\201\377\377\377\377\225\"", <incomplete sequence \356>
(gdb) x/s 0xc919d0
0xc919d0:       " "
(gdb) x/s 0xc919d0
0xc919d0:       " "
(gdb) x/s 0x7f7147cfd030
0x7f7147cfd030: "f\017s\372\005f\017t\321f\017\370\320fD\017\327\312\323\352A\323\351D)\312\017\205\v\004"
(gdb) info stack
#0  new_sys_chdir (filename=0xffffff9c <error: Cannot access memory at address 0xffffff9c>)
    at /home/ulys/syshooks/kmod/syschdir.c:17
#1  0xffffffff81218b3e in move_page_tables (vma=<optimized out>, old_addr=3, new_vma=<optimized out>,
    new_addr=18446744071586314095, len=<optimized out>, need_rmap_locks=<optimized out>) at mm/mremap.c:187
#2  0xffffffff8171f82f in inet_netconf_fill_devconf (skb=0xffffffff8171f77b <inet_netconf_fill_devconf+123>,
    ifindex=<optimized out>, devconf=<optimized out>, portid=<optimized out>, seq=<optimized out>, flags=<optimized out>,
    type=<error reading variable: Cannot access memory at address 0x10>, event=80) at net/ipv4/devinet.c:1786
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
线程304命中断点1,新建系统\u chdir(
文件名=0xFFFF9C)
at/home/ulys/syshooks/kmod/syschdir.c:17
17长的新\u系统\u chdir(常量字符\u用户*文件名){
(gdb)信息寄存器
rax 0x0 0
rbx 0x0 0
rcx 0xffff880055d47f18-131939955343592
rdx 0x3
rsi 0x3
rdi 0xFFFF9C 4294967196
rbp 0xffff880055d47f48 0xffff880055d47f48
rsp 0xffff880055d47f10 0xffff880055d47f10
r8 0xc919d0 13179344
r9 0xcba2d0 13345488
r10 0x7f7147cfd030 140124512833584
r11 0x246 582
r12 0x3
r13 0xc8f320 13169440
r14 0x0 0
r15 0x0 0
rip 0xFFFFFFC0561000 0xffffffffc0561000
eflags 0x10246[PF ZF IF RF]
cs 0x10 16
ss 0x18 24
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0xb 11
(gdb)x/s 0xffff880055d47f18
0xffff880055d47f18:“o\367q\201\377\377\377{\367q\201\377\377\377\225\”,
(gdb)x/s 0xc919d0
0xc919d0:“
(gdb)x/s 0xc919d0
0xc919d0:“
(gdb)x/s 0x7f7147cfd030
0x7f7147cfd030:“f\017s\372\005f\017t\321f\017\370\320fD\017\327\312\323\352A\323\351D)\312\017\205\v\004”
(gdb)信息堆栈
#0新的\u系统\u chdir(文件名=0xffffff9c)
at/home/ulys/syshooks/kmod/syschdir.c:17
#移动页面表格中的1 0xFFFFFF81218B3E(vma=,旧地址=3,新地址=,
新地址=18446744071586314095,len=,需要锁=)在mm/mremap.c:187
#inet_netconf_fill_devconf中的2个0xffffffff8171f82f(skb=0xffffffff8171f77b,
ifindex=,devconf=,portid=,seq=,flags=,
net/ipv4/devinet.c:1786上的type=,event=80)
回溯已停止:此帧内部的上一帧(堆栈损坏?)
在execve上,它似乎工作得很好。在这里,您可以看到类似的输出,但我在访问execve的任何文件名或argv字符串时都没有问题

Thread 335 hit Breakpoint 2, new_sys_execve (filename=0x55c85e0d7af0 "/usr/libexec/postfix/pickup", argv=0x55c85e0d3d00,
    envp=0x55c85e0d3d00) at /home/ulys/syshooks/kmod/sysexecve.c:21
21              const char __user * const __user * envp) {
(gdb) info registers
rax            0xffffffff8171fd80       -2123235968
rbx            0x0      0
rcx            0xffffffff       4294967295
rdx            0x55c85e0d3d00   94319059746048
rsi            0x55c85e0d3d00   94319059746048
rdi            0x55c85e0d7af0   94319059761904
rbp            0x0      0x0 <irq_stack_union>
rsp            0xffff88005323ff50       0xffff88005323ff50
r8             0x30     48
r9             0x0      0
r10            0xffffffff       4294967295
r11            0x206    518
r12            0x0      0
r13            0x0      0
r14            0x0      0
r15            0x0      0
rip            0xffffffffc053f880       0xffffffffc053f880 <new_sys_execve>
eflags         0x10282  [ SF IF RF ]
cs             0x10     16
ss             0x18     24
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0xb      11
(gdb) info stack
#0  new_sys_execve (filename=0x55c85e0d7af0 "/usr/libexec/postfix/pickup", argv=0x55c85e0d3d00, envp=0x55c85e0d3d00)
    at /home/ulys/syshooks/kmod/sysexecve.c:21
#1  0xffffffff8171fdc8 in rtm_to_ifaddr (pprefered_lft=<synthetic pointer>, pvalid_lft=<synthetic pointer>,
    nlh=0x0 <irq_stack_union>, net=0x0 <irq_stack_union>) at net/ipv4/devinet.c:801
#2  inet_rtm_newaddr (skb=0x0 <irq_stack_union>, nlh=0x0 <irq_stack_union>) at net/ipv4/devinet.c:854
Backtrace stopped: Cannot access memory at address 0x8
线程335命中断点2,新的系统执行(文件名=0x55c85e0d7af0)/usr/libexec/postfix/pick,argv=0x55c85e0d3d00,
envp=0x55c85e0d3d00)位于/home/ulys/syshooks/kmod/sysexecve.c:21
21常量字符*常量用户*常量用户*环境){
(gdb)信息寄存器
rax 0xFFFF8171FD80-2123235968
rbx 0x0 0
rcx 0xFFFFFFFF4294967295
rdx 0x55c85e0d3d00 94319059746048
rsi 0x55c85e0d3d00 94319059746048
rdi 0x55c85e0d7af0 94319059761904
rbp 0x0 0x0
rsp 0xffff88005323ff50 0xffff88005323ff50
r8 0x30 48
r9 0x0 0
r10 0xFFFFFFFF4294967295
r11 0x206 518
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0xFFFFFFC053F880 0xffffffffc053f880
eflags 0x10282[SF IF RF]
cs 0x10 16
ss 0x18 24
ds 0x0