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

 

參考資料:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM