我真的对系统调用地址感到困惑。
1现在我挂了一个系统调用(fake_sendto)替换真正的系统调用(sct [__ NR_sendto]),它正常工作。
# define fm_alert(fmt, ...) fm_printk(KERN_ALERT, fmt, ##__VA_ARGS__)
void
print_ascii(void *addr, size_t count, const char *prompt)
{
size_t index;
fm_alert("%s:\n", prompt);
for (index = 0; index < count; index += 1) {
pr_cont("%c", *((unsigned char *)addr + index));
}
return;
}
asmlinkage long
fake_sendto(int fd, void __user *buff, size_t len, unsigned flags,
struct sockaddr __user *addr, int addr_len)
{
void *kbuf = kmalloc(len + 1, GFP_KERNEL);
if (kbuf != NULL) {
if (copy_from_user(kbuf, buff, len)) {
fm_alert("%s\n", "copy_from_user failed.");
} else {
if (memcmp(kbuf, "GET", 3) == 0 ||
memcmp(kbuf, "POST", 4) == 0) {
print_ascii(kbuf, len, "ascii");
}
}
kfree(kbuf);
} else {
fm_alert("%s\n", "kmalloc failed.");
}
fm_alert("hook:%p, orig:%p\n", fake_sendto, real_sendto);
return real_sendto(fd, buff, len, flags, addr, addr_len);
}
现在我dmesg显示日志:
[ 3466.057815] ifmonko.fake_sendto: hook:ffffffffc06d9070, orig:ffffffff8156b2c0
好吧,我认为真正的sys_sento地址高于0xffffffff8156b2c0
但是当我写一个测试程序时,gdb print sendto函数地址是0x7ffff7b11400! 请参阅以下gdb调试信息:
(gdb) disas main
Dump of assembler code for function main:
...
0x0000000000400cb4 <+743>: callq 0x400810 <sendto@plt>
...
End of assembler dump.
(gdb) b *0x0000000000400cb4
Breakpoint 1 at 0x400cb4: file ser.c, line 89.
(gdb) r
Starting program: /home/lid/ser 9898
Breakpoint 1, 0x0000000000400cb4 in main (argc=2, argv=0x7fffffffe6d8) at ser.c:89
89 nwrite = sendto(sfd, buf, strlen(buf), 0,
(gdb) c
Continuing.
Breakpoint 1, 0x0000000000400cb4 in main (argc=2, argv=0x7fffffffe6d8) at ser.c:89
89 nwrite = sendto(sfd, buf, strlen(buf), 0,
(gdb) p sendto
$1 = {<text variable, no debug info>} 0x7ffff7b11400 <sendto>
(gdb) si
0x0000000000400810 in sendto@plt ()
(gdb)
sendto () at ../sysdeps/unix/syscall-template.S:81
81 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) bt
#0 sendto () at ../sysdeps/unix/syscall-template.S:81
#1 0x0000000000400cb9 in main (argc=2, argv=0x7fffffffe6d8) at ser.c:89
(gdb) disas
Dump of assembler code for function sendto:
=> 0x00007ffff7b11400 <+0>: cmpl $0x0,0x2c8b6d(%rip) # 0x7ffff7dd9f74 <__libc_multiple_threads>
0x00007ffff7b11407 <+7>: jne 0x7ffff7b1141c <sendto+28>
0x00007ffff7b11409 <+0>: mov %rcx,%r10
0x00007ffff7b1140c <+3>: mov $0x2c,%eax
0x00007ffff7b11411 <+8>: syscall
0x00007ffff7b11413 <+10>: cmp $0xfffffffffffff001,%rax
0x00007ffff7b11419 <+16>: jae 0x7ffff7b1144f <sendto+79>
0x00007ffff7b1141b <+18>: retq
0x00007ffff7b1141c <+28>: sub $0x8,%rsp
0x00007ffff7b11420 <+32>: callq 0x7ffff7b1df20 <__libc_enable_asynccancel>
0x00007ffff7b11425 <+37>: mov %rax,(%rsp)
0x00007ffff7b11429 <+41>: mov %rcx,%r10
0x00007ffff7b1142c <+44>: mov $0x2c,%eax
0x00007ffff7b11431 <+49>: syscall
0x00007ffff7b11433 <+51>: mov (%rsp),%rdi
0x00007ffff7b11437 <+55>: mov %rax,%rdx
0x00007ffff7b1143a <+58>: callq 0x7ffff7b1df80 <__libc_disable_asynccancel>
0x00007ffff7b1143f <+63>: mov %rdx,%rax
0x00007ffff7b11442 <+66>: add $0x8,%rsp
0x00007ffff7b11446 <+70>: cmp $0xfffffffffffff001,%rax
0x00007ffff7b1144c <+76>: jae 0x7ffff7b1144f <sendto+79>
0x00007ffff7b1144e <+78>: retq
0x00007ffff7b1144f <+79>: mov 0x2c2a12(%rip),%rcx # 0x7ffff7dd3e68
0x00007ffff7b11456 <+86>: neg %eax
0x00007ffff7b11458 <+88>: mov %eax,%fs:(%rcx)
---Type <return> to continue, or q <return> to quit---
0x00007ffff7b1145b <+91>: or $0xffffffffffffffff,%rax
0x00007ffff7b1145f <+95>: retq
End of assembler dump.
(gdb)
为什么gdb在钩子函数和系统调用表之间显示不同?
答案 0 :(得分:0)
为什么gdb在钩子函数和系统调用表之间显示不同?
一个在内核空间,另一个在用户空间。他们彼此差不多没有。