Linux下反彙編指定的函數

在debug二進制程序的時候,偶爾會用到反彙編,有時候也想反彙編指定的函數,那麼以下有兩種方法可以試試:用objdump的-d參數或者gdb的disassemble命令:

一、用objdump的-d參數,但不能指定函數名,objdump還有另外兩個參數--start-address和--stop-address,我們只要指定反彙編的起始地址和結束地址那應該就可以了,那怎麼得到函數的起止地址呢,這就需要nm工具了,整合成shell腳本如下:

#!/bin/sh
#file: /usr/bin/dis
#disassemble a function
#author: [email protected]

routine=$1
func=$2

if [ -z "$routine" ]; then
    exit
fi

start=$(nm -n $routine | grep "\w\s$func" | awk '{print "0x"$1;exit}')
end=$(nm -n $routine | grep -A1 "\w\s$func" | awk '{getline; print "0x"$1;exit}')

if [ -z "$func" ]; then
    objdump -d $routine
else
    echo "start-address: $start, end-address: $end"
    objdump -d $routine --start-address=$start --stop-address=$end
fi


保存到/usr/bin/dis,並添加可執行權限,這樣就可以隨時反彙編指定的函數了,比如反彙編nginx的ngx_array_init函數的結果如下:

root@jusse:~/work/#dis ./nginx ngx_array_init
start-address: 0x0000000000404404, end-address: 0x000000000040448a

nginx:     file format elf64-x86-64


Disassembly of section .text:

0000000000404404 <ngx_array_init>:
  404404:       55                      push   %rbp
  404405:       48 89 e5                mov    %rsp,%rbp
  404408:       48 83 ec 20             sub    $0x20,%rsp
  40440c:       48 89 7d f8             mov    %rdi,-0x8(%rbp)
  404410:       48 89 75 f0             mov    %rsi,-0x10(%rbp)
  404414:       48 89 55 e8             mov    %rdx,-0x18(%rbp)
  404418:       48 89 4d e0             mov    %rcx,-0x20(%rbp)
  40441c:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  404420:       48 c7 40 08 00 00 00    movq   $0x0,0x8(%rax)
  404427:       00 
  404428:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  40442c:       48 8b 55 e0             mov    -0x20(%rbp),%rdx
  404430:       48 89 50 10             mov    %rdx,0x10(%rax)
  404434:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  404438:       48 8b 55 e8             mov    -0x18(%rbp),%rdx
  40443c:       48 89 50 18             mov    %rdx,0x18(%rax)
  404440:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  404444:       48 8b 55 f0             mov    -0x10(%rbp),%rdx
  404448:       48 89 50 20             mov    %rdx,0x20(%rax)
  40444c:       48 8b 45 e8             mov    -0x18(%rbp),%rax
  404450:       48 89 c2                mov    %rax,%rdx
  404453:       48 0f af 55 e0          imul   -0x20(%rbp),%rdx
  404458:       48 8b 45 f0             mov    -0x10(%rbp),%rax
  40445c:       48 89 d6                mov    %rdx,%rsi
  40445f:       48 89 c7                mov    %rax,%rdi
  404462:       e8 4e 37 00 00          callq  407bb5 <ngx_palloc>
  404467:       48 8b 55 f8             mov    -0x8(%rbp),%rdx
  40446b:       48 89 02                mov    %rax,(%rdx)
  40446e:       48 8b 45 f8             mov    -0x8(%rbp),%rax
  404472:       48 8b 00                mov    (%rax),%rax
  404475:       48 85 c0                test   %rax,%rax
  404478:       75 09                   jne    404483 <ngx_array_init+0x7f>
  40447a:       48 c7 c0 ff ff ff ff    mov    $0xffffffffffffffff,%rax
  404481:       eb 05                   jmp    404488 <ngx_array_init+0x84>
  404483:       b8 00 00 00 00          mov    $0x0,%eax
  404488:       c9                      leaveq 
  404489:       c3                      retq   

二、用gdb的disassemble命令:

root@jusse:~/work/#gdb -q ./nginx
Reading symbols from /home/wangzuxi/work/svn/l7waf_build/install_dir/sbin/nginx...done.
(gdb) disassemble ngx_array_init
Dump of assembler code for function ngx_array_init:
   0x00000000004cb21c <+0>:     push   %rbp
   0x00000000004cb21d <+1>:     mov    %rsp,%rbp
   0x00000000004cb220 <+4>:     sub    $0x20,%rsp
   0x00000000004cb224 <+8>:     mov    %rdi,-0x8(%rbp)
   0x00000000004cb228 <+12>:    mov    %rsi,-0x10(%rbp)
   0x00000000004cb22c <+16>:    mov    %rdx,-0x18(%rbp)
   0x00000000004cb230 <+20>:    mov    %rcx,-0x20(%rbp)
   0x00000000004cb234 <+24>:    mov    -0x8(%rbp),%rax
   0x00000000004cb238 <+28>:    movq   $0x0,0x8(%rax)
   0x00000000004cb240 <+36>:    mov    -0x8(%rbp),%rax
   0x00000000004cb244 <+40>:    mov    -0x20(%rbp),%rdx
   0x00000000004cb248 <+44>:    mov    %rdx,0x10(%rax)
   0x00000000004cb24c <+48>:    mov    -0x8(%rbp),%rax
   0x00000000004cb250 <+52>:    mov    -0x18(%rbp),%rdx
   0x00000000004cb254 <+56>:    mov    %rdx,0x18(%rax)
   0x00000000004cb258 <+60>:    mov    -0x8(%rbp),%rax
   0x00000000004cb25c <+64>:    mov    -0x10(%rbp),%rdx
   0x00000000004cb260 <+68>:    mov    %rdx,0x20(%rax)
   0x00000000004cb264 <+72>:    mov    -0x18(%rbp),%rax
   0x00000000004cb268 <+76>:    mov    %rax,%rdx
   0x00000000004cb26b <+79>:    imul   -0x20(%rbp),%rdx
   0x00000000004cb270 <+84>:    mov    -0x10(%rbp),%rax
   0x00000000004cb274 <+88>:    mov    %rdx,%rsi
   0x00000000004cb277 <+91>:    mov    %rax,%rdi
   0x00000000004cb27a <+94>:    callq  0x407bb5 <ngx_palloc>
   0x00000000004cb27f <+99>:    mov    -0x8(%rbp),%rdx
   0x00000000004cb283 <+103>:   mov    %rax,(%rdx)
   0x00000000004cb286 <+106>:   mov    -0x8(%rbp),%rax
   0x00000000004cb28a <+110>:   mov    (%rax),%rax
   0x00000000004cb28d <+113>:   test   %rax,%rax
   0x00000000004cb290 <+116>:   jne    0x4cb29b <ngx_array_init+127>
   0x00000000004cb292 <+118>:   mov    $0xffffffffffffffff,%rax
   0x00000000004cb299 <+125>:   jmp    0x4cb2a0 <ngx_array_init+132>
   0x00000000004cb29b <+127>:   mov    $0x0,%eax
   0x00000000004cb2a0 <+132>:   leaveq 
   0x00000000004cb2a1 <+133>:   retq   
End of assembler dump.
(gdb) q


可以看出反彙編代碼與第一種方法的結果是一樣的,但這麼用gdb有點費勁了,還可以像下面這麼玩:

#!/bin/sh
#file: /usr/bin/gdbdis
#disassemble a function use gdb
#author: [email protected]

if test $# -ne 2; then
echo "Usage: `basename $0 .sh` file function" 1>&2
echo "For exampl: `basename $0 .sh` xxx func" 1>&2
exit 1
fi

result=""
GDB=${GDB:-/usr/bin/gdb}
# Run GDB, strip out unwanted noise.
result=`$GDB -quiet $1 <<EOF
disassemble $2
EOF`

echo "$result" | egrep -A 1000 -e "^\(gdb\)" | egrep -B 1000 -e "^\(gdb\)"

同樣反彙編nginx的ngx_array_init函數的結果是一樣的:

./gdbdis ./nginx ngx_array_init
(gdb) Dump of assembler code for function ngx_array_init:
   0x00000000004cb21c <+0>:     push   %rbp
   0x00000000004cb21d <+1>:     mov    %rsp,%rbp
   0x00000000004cb220 <+4>:     sub    $0x20,%rsp
   0x00000000004cb224 <+8>:     mov    %rdi,-0x8(%rbp)
   0x00000000004cb228 <+12>:    mov    %rsi,-0x10(%rbp)
   0x00000000004cb22c <+16>:    mov    %rdx,-0x18(%rbp)
   0x00000000004cb230 <+20>:    mov    %rcx,-0x20(%rbp)
   0x00000000004cb234 <+24>:    mov    -0x8(%rbp),%rax
   0x00000000004cb238 <+28>:    movq   $0x0,0x8(%rax)
   0x00000000004cb240 <+36>:    mov    -0x8(%rbp),%rax
   0x00000000004cb244 <+40>:    mov    -0x20(%rbp),%rdx
   0x00000000004cb248 <+44>:    mov    %rdx,0x10(%rax)
   0x00000000004cb24c <+48>:    mov    -0x8(%rbp),%rax
   0x00000000004cb250 <+52>:    mov    -0x18(%rbp),%rdx
   0x00000000004cb254 <+56>:    mov    %rdx,0x18(%rax)
   0x00000000004cb258 <+60>:    mov    -0x8(%rbp),%rax
   0x00000000004cb25c <+64>:    mov    -0x10(%rbp),%rdx
   0x00000000004cb260 <+68>:    mov    %rdx,0x20(%rax)
   0x00000000004cb264 <+72>:    mov    -0x18(%rbp),%rax
   0x00000000004cb268 <+76>:    mov    %rax,%rdx
   0x00000000004cb26b <+79>:    imul   -0x20(%rbp),%rdx
   0x00000000004cb270 <+84>:    mov    -0x10(%rbp),%rax
   0x00000000004cb274 <+88>:    mov    %rdx,%rsi
   0x00000000004cb277 <+91>:    mov    %rax,%rdi
   0x00000000004cb27a <+94>:    callq  0x407bb5 <ngx_palloc>
   0x00000000004cb27f <+99>:    mov    -0x8(%rbp),%rdx
   0x00000000004cb283 <+103>:   mov    %rax,(%rdx)
   0x00000000004cb286 <+106>:   mov    -0x8(%rbp),%rax
   0x00000000004cb28a <+110>:   mov    (%rax),%rax
   0x00000000004cb28d <+113>:   test   %rax,%rax
   0x00000000004cb290 <+116>:   jne    0x4cb29b <ngx_array_init+127>
   0x00000000004cb292 <+118>:   mov    $0xffffffffffffffff,%rax
   0x00000000004cb299 <+125>:   jmp    0x4cb2a0 <ngx_array_init+132>
   0x00000000004cb29b <+127>:   mov    $0x0,%eax
   0x00000000004cb2a0 <+132>:   leaveq 
   0x00000000004cb2a1 <+133>:   retq   
End of assembler dump.
(gdb) quit




發佈了24 篇原創文章 · 獲贊 26 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章