1. 程式人生 > >簡單例項分析objdump反彙編用法

簡單例項分析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選項,直接閱讀彙編程式碼。