简单实例分析objdump反汇编用法

objdump -rdS 可可执行文件

objdump命令是用查看目标文件或者可执行的目标文件的构成的gcc工具。

1. 准备代码hello.c

#include <linux/module.h> 
#include <linux/init.h>  
#include <linux/kernel.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("baoli");
MODULE_DESCRIPTION("hello world module");

static int __init hello_init(void)
{
    int * p = 0;
    printk(KERN_WARNING "hello world.\n");
    *p = 1;

    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_WARNING "hello exit!\n");
}

module_init(hello_init);
module_exit(hello_exit);


 

2. 编译&安装模块

编译成ko模块后,执行isnmod hello.ko,显示killed安装失败。

用dmesg内核日志,可以看到内核跑出了Oops异常:

给出了原因:不能访问NULL指针

错误发生位置:hello_init+0x10,即hello_init偏移0x10处,可以反汇编查看此处对应的具体指令。

3. 反汇编分析

执行:objdump -d hello.o > assemble.txt

汇编代码如下:

hello.o:     file format elf64-x86-64

Disassembly of section .init.text:

0000000000000000 <init_module>:
MODULE_LICENSE("GPL");
MODULE_AUTHOR("baoli");
MODULE_DESCRIPTION("hello world module");

static int __init hello_init(void)
{
   0:	55                   	push   %rbp
   1:	48 c7 c7 00 00 00 00 	mov    $0x0,%rdi
   8:	48 89 e5             	mov    %rsp,%rbp
   b:	e8 00 00 00 00       	callq  10 <init_module+0x10>
  10:	c7 04 25 00 00 00 00 	movl   $0x1,0x0
  17:	01 00 00 00 
  1b:	31 c0                	xor    %eax,%eax
  1d:	5d                   	pop    %rbp
  1e:	c3                   	retq   

Disassembly of section .exit.text:

0000000000000000 <cleanup_module>:
   0:	55                   	push   %rbp
   1:	48 c7 c7 00 00 00 00 	mov    $0x0,%rdi
   8:	48 89 e5             	mov    %rsp,%rbp
   b:	e8 00 00 00 00       	callq  10 <cleanup_module+0x10>
  10:	5d                   	pop    %rbp
  11:	c3                   	retq   


 

可以看到hello_init+0x10处对应汇编指令为movl $0x1,0x0,即*p = 1;

通过objdump反汇编Oops可以轻松的知道错误原因及位置。

4. objdump总结

1)objdump -d:反汇编目标文件中包含的可执行指令。

2)如果需要混合显示源码和汇编代码,需要加上-S选项,并且在编译目标文件时加上-g。

3)如果在编译目标文件时没有加-g选项,则-S相当于-d。

4)-S选项生成的混合代码,有时文件结构混乱,可读性较差。推荐使用-d选项,直接阅读汇编代码。

猜你喜欢

转载自blog.csdn.net/mw_nice/article/details/84871289