Linux内核之vmlinuz反汇编

本文介绍在Fedora上对Linux内核的vmlinuz进行反汇编。如果内核是debug版本,可以用来查看某个函数的源代码。

1. 安装kernel-devel软件包

dnf -y install kernel-devel

2. 提取vmlinux

  • vmlinux是一个包括Linux kernel的静态链接的可运行文件。
  • vmlinuz是vmlinux经过gzip和objcopy制作出来的压缩文件。
/usr/src/kernels/$(uname -r)/scripts/extract-vmlinux /boot/vmlinuz-$(uname -r) > vmlinux

3. 反汇编vmlinux

objdump -D vmlinux > vmlinux.out

4.  查看vmlinux里的函数

这里以函数tcp4_proc_init为例。/proc/kallsyms存储了所有的内核符号表,/boot/System.map则存储了静态的内核符号表。有关System.map,请阅读这里

e.g.

root# grep tcp4_proc_init /proc/kallsyms
ffffffffa37dd330 t tcp4_proc_init_net
ffffffffa479d258 T tcp4_proc_init

root# grep tcp4_proc_init /boot/System.map-$(uname -r)
ffffffff817dd330 t tcp4_proc_init_net
ffffffff8279d258 T tcp4_proc_init

root# egrep -in ffffffff8279d258 vmlinux.out
8960512:ffffffff8279d258:       e8 93 47 26 ff          callq  0xffffffff81a019f0
8960912:ffffffff8279d96d:       e8 e6 f8 ff ff          callq  0xffffffff8279d258

root# N=8960512
root# sed -n "$((N-5)),$((N+5))"p vmlinux.out
ffffffff8279d24e:       e8 7d 14 91 fe          callq  0xffffffff810ae6d0
ffffffff8279d253:       eb bd                   jmp    0xffffffff8279d212
ffffffff8279d255:       5b                      pop    %rbx
ffffffff8279d256:       5d                      pop    %rbp
ffffffff8279d257:       c3                      retq   
ffffffff8279d258:       e8 93 47 26 ff          callq  0xffffffff81a019f0
ffffffff8279d25d:       48 c7 c7 40 ca 31 82    mov    $0xffffffff8231ca40,%rdi
ffffffff8279d264:       e9 27 d3 fb fe          jmpq   0xffffffff8175a590
ffffffff8279d269:       e8 82 47 26 ff          callq  0xffffffff81a019f0
ffffffff8279d26e:       48 c7 c7 60 c8 31 82    mov    $0xffffffff8231c860,%rdi
ffffffff8279d275:       e8 16 d3 fb fe          callq  0xffffffff8175a590

函数tcp4_proc_init()的源代码如下:

/* https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/net/ipv4/tcp_ipv4.c?h=v4.16.9#n2392 */ 
2377  static int __net_init tcp4_proc_init_net(struct net *net)
2378  {
2379          return tcp_proc_register(net, &tcp4_seq_afinfo);
2380  }
2381  
2382  static void __net_exit tcp4_proc_exit_net(struct net *net)
2383  {
2384          tcp_proc_unregister(net, &tcp4_seq_afinfo);
2385  }
2386  
2387  static struct pernet_operations tcp4_net_ops = {
2388          .init = tcp4_proc_init_net,
2389          .exit = tcp4_proc_exit_net,
2390  };
2391  
2392  int __init tcp4_proc_init(void)
2393  {
2394          return register_pernet_subsys(&tcp4_net_ops);
2395  }
2396  
2397  void tcp4_proc_exit(void)
2398  {
2399          unregister_pernet_subsys(&tcp4_net_ops);
2400  }

从L2394,我们可以看出tcp4_proc_init()调用了函数register_pernet_subsys(), 重新查看vmlinux.out验证一下。

root# egrep 'T register_pernet_subsys' /boot/System.map-$(uname -r)
ffffffff8175a590 T register_pernet_subsys

root# sed -n "$N, $((N+20))"p vmlinux.out > /tmp/1
root# egrep -in retq /tmp/1
11:ffffffff8279d28a:    c3                      retq   

root# sed -n '1,11'p /tmp/1 | cat -n
     1  ffffffff8279d258:       e8 93 47 26 ff          callq  0xffffffff81a019f0
     2  ffffffff8279d25d:       48 c7 c7 40 ca 31 82    mov    $0xffffffff8231ca40,%rdi
     3  ffffffff8279d264:       e9 27 d3 fb fe          jmpq   0xffffffff8175a590
     4  ffffffff8279d269:       e8 82 47 26 ff          callq  0xffffffff81a019f0
     5  ffffffff8279d26e:       48 c7 c7 60 c8 31 82    mov    $0xffffffff8231c860,%rdi
     6  ffffffff8279d275:       e8 16 d3 fb fe          callq  0xffffffff8175a590
     7  ffffffff8279d27a:       85 c0                   test   %eax,%eax
     8  ffffffff8279d27c:       74 0c                   je     0xffffffff8279d28a
     9  ffffffff8279d27e:       48 c7 c7 c0 d0 14 82    mov    $0xffffffff8214d0c0,%rdi
    10  ffffffff8279d285:       e8 b4 c1 90 fe          callq  0xffffffff810a943e
    11  ffffffff8279d28a:       c3                      retq   
root# sed -n '1,11'p /tmp/1 | cat -n | egrep ffffffff8175a590
     3  ffffffff8279d264:       e9 27 d3 fb fe          jmpq   0xffffffff8175a590
     6  ffffffff8279d275:       e8 16 d3 fb fe          callq  0xffffffff8175a590

参考资料:

原文地址:https://www.cnblogs.com/idorax/p/11171394.html