反汇编正在运行的内核

Posted

技术标签:

【中文标题】反汇编正在运行的内核【英文标题】:Disassembling running kernel 【发布时间】:2012-02-01 05:30:49 【问题描述】:

我尝试运行gdb来反汇编内核并尝试运行:

root@debian:/home/jestinjoy# gdb /usr/src/linux-2.6.38.8/vmlinux
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/src/linux-2.6.38.8/vmlinux...done.
(gdb) disass sys_read
Dump of assembler code for function sys_read:
0xc10cacb9 <sys_read+0>:    push   %ebp
0xc10cacba <sys_read+1>:    mov    %esp,%ebp
0xc10cacbc <sys_read+3>:    push   %esi
0xc10cacbd <sys_read+4>:    mov    $0xfffffff7,%esi
0xc10cacc2 <sys_read+9>:    push   %ebx
0xc10cacc3 <sys_read+10>:   sub    $0xc,%esp
0xc10cacc6 <sys_read+13>:   mov    0x8(%ebp),%eax
0xc10cacc9 <sys_read+16>:   lea    -0xc(%ebp),%edx
0xc10caccc <sys_read+19>:   call   0xc10cb346 <fget_light>
0xc10cacd1 <sys_read+24>:   test   %eax,%eax
0xc10cacd3 <sys_read+26>:   mov    %eax,%ebx
0xc10cacd5 <sys_read+28>:   je     0xc10cad10 <sys_read+87>
0xc10cacd7 <sys_read+30>:   mov    0x2c(%ebx),%edx
0xc10cacda <sys_read+33>:   mov    0x28(%eax),%eax
0xc10cacdd <sys_read+36>:   mov    0x10(%ebp),%ecx
0xc10cace0 <sys_read+39>:   mov    %edx,-0x10(%ebp)
0xc10cace3 <sys_read+42>:   mov    0xc(%ebp),%edx
0xc10cace6 <sys_read+45>:   mov    %eax,-0x14(%ebp)
0xc10cace9 <sys_read+48>:   lea    -0x14(%ebp),%eax
0xc10cacec <sys_read+51>:   push   %eax
0xc10caced <sys_read+52>:   mov    %ebx,%eax
0xc10cacef <sys_read+54>:   call   0xc10cab82 <vfs_read>
0xc10cacf4 <sys_read+59>:   mov    -0x10(%ebp),%edx
0xc10cacf7 <sys_read+62>:   mov    %eax,%esi

它工作正常。但是当我尝试跑步时

root@debian:/home/jestinjoy# gdb /usr/src/linux-2.6.38.8/vmlinux /proc/kcore 
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/src/linux-2.6.38.8/vmlinux...done.
Core was generated by `BOOT_IMAGE=/boot/vmlinuz-2.6.38.8 root=UUID=b61e8ee2-949a-4810-ac56-42564ee005d7'.
#0  0x00000000 in ?? ()
(gdb) disass sys_read
Dump of assembler code for function sys_read:
0xc10cacb9 <sys_read+0>:    add    %al,(%eax)
0xc10cacbb <sys_read+2>:    add    %al,(%eax)
0xc10cacbd <sys_read+4>:    add    %al,(%eax)
0xc10cacbf <sys_read+6>:    add    %al,(%eax)
0xc10cacc1 <sys_read+8>:    add    %al,(%eax)
0xc10cacc3 <sys_read+10>:   add    %al,(%eax)
0xc10cacc5 <sys_read+12>:   add    %al,(%eax)
0xc10cacc7 <sys_read+14>:   add    %al,(%eax)
0xc10cacc9 <sys_read+16>:   add    %al,(%eax)
0xc10caccb <sys_read+18>:   add    %al,(%eax)
0xc10caccd <sys_read+20>:   add    %al,(%eax)
0xc10caccf <sys_read+22>:   add    %al,(%eax)
0xc10cacd1 <sys_read+24>:   add    %al,(%eax)
0xc10cacd3 <sys_read+26>:   add    %al,(%eax)
0xc10cacd5 <sys_read+28>:   add    %al,(%eax)
0xc10cacd7 <sys_read+30>:   add    %al,(%eax)

它给出了奇怪的结果。我和

一起跑步

CONFIG_DEBUG_INFO=y 和内核 2.6.38

【问题讨论】:

看起来您加载的内核与启动时不同 - 如果您已安装内核,则可能会或可能不会出现这种情况。 /proc/kcore 报告内核是 /boot/vmlinuz-2.6.38.8。另外,如果您可以发布您的 .config 可能有助于获得更好的答案,对于咯咯笑。 我的config 可以在pastebin.com/BiNpDmvY 找到。我是否错过了一些配置? 如果你只是想反汇编你的内核,为什么不直接反汇编镜像呢? 【参考方案1】:

禁用CONFIG_RELOCATABLE

不能简单地用 gdb 调试正在运行的内核!

Linux 内核带有两个不同的调试前端(kdb 和 KGDB),它们有些不同,但幸运的是可以在它们之间动态切换。

kdb 不是源级调试器(因此不是您要查找的调试器),可以在本地机器上的系统控制台上使用,也可以通过来自另一台机器的串行连接使用。

KGDB 是源级调试器,但需要两台机器才能运行 - 其中一台是被调试的主体(也就是运行调试代码的目标机器),另一台是运行 gdb 的开发机器vmlinux 文件(与目标机器运行的文件相同)。目标机和开发机之间的连接是通过串口完成的...

现在,有大量文档说明如何在内核的Documentation 目录下设置所有这些。只需 grep 即可:kdb, kgdboc, ...

【讨论】:

实际上,您可以使用 gdb 调试正在运行的内核(前提是您有带有调试符号的内核映像)——您只是无法在断点等处停止它。 @gby 我不会考虑调试。 因为你可以从任何内存位置提取值,所以调试很多现象非常有用。【参考方案2】:

“grep sys_read /proc/kallsyms”在你的机器上说什么?如果不是 0xc10cacb9 则说明你没有相同的源或运行内核的配置,所以地址不匹配

【讨论】:

cat /boot/System.map-2.6.38.8 | grep sys_read0xc10cacb9 抱歉,我的问题不知何故被截断了。我的意思是问“grep sys_read /proc/kallsyms”在你的机器上读到了什么?原因是 /proc/kallsyms 来自实际运行的内核,而 /boot/Systems.map-2.6.38.8 是使用以前的内核之一安装的。由于我怀疑运行的内核可能不同,所以我想验证实际运行的内核的地址【参考方案3】:

我不能说我使用 GDB 来调试内核,但我使用了 crash (http://people.redhat.com/anderson/crash_whitepaper/),它是 gdb 的一个包装器。我大部分时间都在使用它,它很管用。

【讨论】:

以上是关于反汇编正在运行的内核的主要内容,如果未能解决你的问题,请参考以下文章

linux内核学习之一 简单c语言反汇编

反汇编工具使用

实验---反汇编一个简单的C程序(杨光)

反汇编出来的地址是运行地址还是编译地址?

什么软件能将C语言的执行文件反汇编为汇编源代码

dll文件如何反汇编成源码,C++语言编写