曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5305|回复: 0
打印 上一主题 下一主题

linux objdump

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2009-5-19 11:00:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
概述:

  objdump有点象那个快速查看之流的工具,就是以一种可阅读的格式让你更多地了解二进制文件可能带有的附加信息。对于一般只想让自己程序跑起来的程序员,这个命令没有更多意义,对于想进一步了解系统的程序员,应该掌握这种工具,至少你可以自己写写shellcode了,或者看看人家给的exploit中的shellcode是什么东西。

目录:

★ 测试练习前的准备工作
    ★ Redhat 6.0 objdump命令的man手册
    ★ objdump应用举例(待增加)
★ 相关命令

★ 测试练习前的准备工作

cp /usr/lib/libpcap.a /home/scz/src
nm -s libpcap.a | more
ar tv libpcap.a
ar xv libpcap.a inet.o
nm -s inet.o

关于nm -s的显示请自己man nm查看

★ Redhat 6.0 objdump命令的man手册

objdump - 显示二进制文件信息

objdump
[-a] [-b bfdname |
--target=bfdname] [-C] [--debugging]
[-d] [-D]
[--disassemble-zeroes]
[-EB|-EL|--endian={big|little}] [-f]
[-h] [-i|--info]
[-j section | --section=section]
[-l] [-m machine ] [--prefix-addresses]
[-r] [-R]
[-s|--full-contents] [-S|--source]
[--[no-]show-raw-insn] [--stabs] [-t]
[-T] [-x]
[--start-address=address] [--stop-address=address]
[--adjust-vma=offset] [--version] [--help]
objfile...

--archive-headers
-a 显示档案库的成员信息,与 ar tv 类似

objdump -a libpcap.a 和 ar -tv libpcap.a 显示结果比较比较显然这个选项没有什么意思。

--adjust-vma=offset
Whendumping information, first add offset to all the section addresses.This is useful if the section addresses do not correspond to the symboltable, which can happen when putting sections at particular addresseswhen using a format which can not represent section addresses, such asa.out.

-b bfdname
--target=bfdname
指定目标码格式。这不是必须的,objdump能自动识别许多格式,
比如:objdump -b oasys -m vax -h fu.o
显示fu.o的头部摘要信息,明确指出该文件是Vax系统下用Oasys
编译器生成的目标文件。objdump -i将给出这里可以指定的
目标码格式列表

--demangle
-C 将底层的符号名解码成用户级名字,除了去掉所有开头的下划线之外,还使得C++函数名以可理解的方式显示出来。

--debugging
显示调试信息。企图解析保存在文件中的调试信息并以C语言的语法显示出来。仅仅支持某些类型的调试信息。

--disassemble
-d 反汇编那些应该还有指令机器码的section

--disassemble-all
-D 与 -d 类似,但反汇编所有section

--prefix-addresses
反汇编的时候,显示每一行的完整地址。这是一种比较老的反汇编格式。显示效果并不理想,但可能会用到其中的某些显示,自己可以对比。

--disassemble-zeroes
一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。

-EB
-EL
--endian={big|little}
这个选项将影响反汇编出来的指令。
little-endian就是我们当年在dos下玩汇编的时候常说的高位在高地址,x86都是这种。

--file-headers
-f 显示objfile中每个文件的整体头部摘要信息。

--section-headers
--headers
-h 显示目标文件各个section的头部摘要信息。

--help 简短的帮助信息。

--info
-i 显示对于 -b 或者 -m 选项可用的架构和目标格式列表。

--section=name
-j name 仅仅显示指定section的信息

--line-numbers
-l 用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。

--architecture=machine
-m machine
指定反汇编目标文件时使用的架构,当待反汇编文件本身没有描述架构信息的时候(比如S-records),这个选项很有用。可以用-i选项列出这里能够指定的架构

--reloc
-r 显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示出来。

--dynamic-reloc
-R 显示文件的动态重定位入口,仅仅对于动态目标文件有意义,比如某些共享库。

--full-contents
-s 显示指定section的完整内容。

objdump --section=.text -s inet.o | more

--source
-S 尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数。

--show-raw-insn
反汇编的时候,显示每条汇编指令对应的机器码,除非指定了
--prefix-addresses,这将是缺省选项。

--no-show-raw-insn
反汇编时,不显示汇编指令的机器码,这是指定 --prefix-addresses
选项时的缺省设置。

--stabs
Displaythe contents of the .stab, .stab.index, and .stab.excl sections from anELF file. This is only useful on systems (such as Solaris 2.0) in which.stab debugging symbol-table entries are carried in an ELF section. Inmost other file formats, debugging symbol-table entries are interleavedwith linkage symbols, and are visible in the --syms output.

--start-address=address
从指定地址开始显示数据,该选项影响-d、-r和-s选项的输出。

--stop-address=address
显示数据直到指定地址为止,该选项影响-d、-r和-s选项的输出。

--syms
-t 显示文件的符号表入口。类似于nm -s提供的信息

--dynamic-syms
-T 显示文件的动态符号表入口,仅仅对动态目标文件有意义,比如某些
共享库。它显示的信息类似于 nm -D|--dynamic 显示的信息。

--version 版本信息

objdump --version

--all-headers
-x 显示所有可用的头信息,包括符号表、重定位入口。-x 等价于
-a -f -h -r -t 同时指定。

objdump -x inet.o

参看 nm(1)

★ objdump应用举例(待增加)

/*
g++ -g -Wstrict-prototypes -Wall -Wunused -o objtest objtest.c
*/
#include
#include
int main ( int argc, char * argv[] )
{
execl( "/bin/sh", "/bin/sh", "-i", 0 );
return 0;
}

g++ -g -Wstrict-prototypes -Wall -Wunused -o objtest objtest.c
objdump -j .text -Sl objtest | more
/main(查找)

08048750 :
main():
/home/scz/src/objtest.c:7
*/
#include
#include
int main ( int argc, char * argv[] )
{
8048750: 55 pushl %ebp
8048751: 89 e5 movl %esp,%ebp
/home/scz/src/objtest.c:8
execl( "/bin/sh", "/bin/sh", "-i", 0 );
8048753: 6a 00 pushl $0x0
8048755: 68 d0 87 04 08 pushl $0x80487d0
804875a: 68 d3 87 04 08 pushl $0x80487d3
804875f: 68 d3 87 04 08 pushl $0x80487d3
8048764: e8 db fe ff ff call 8048644 <_init+0x40>
8048769: 83 c4 10 addl $0x10,%esp
/home/scz/src/objtest.c:9
return 0;
804876c: 31 c0 xorl %eax,%eax
804876e: eb 04 jmp 8048774
8048770: 31 c0 xorl %eax,%eax
8048772: eb 00 jmp 8048774
/home/scz/src/objtest.c:10
}
8048774: c9 leave
8048775: c3 ret
8048776: 90 nop

如果说上面还不够清楚,可以用下面的命令辅助一下:

objdump -j .text -Sl objtest --prefix-addresses | more
objdump -j .text -Dl objtest | more

去掉调试编译选项重新编译
g++ -O3 -o objtest objtest.c
objdump -j .text -S objtest | more

08048778 :
main():
8048778: 55 pushl %ebp
8048779: 89 e5 movl %esp,%ebp
804877b: 6a 00 pushl $0x0
804877d: 68 f0 87 04 08 pushl $0x80487f0
8048782: 68 f3 87 04 08 pushl $0x80487f3
8048787: 68 f3 87 04 08 pushl $0x80487f3
804878c: e8 db fe ff ff call 804866c <_init+0x40>
8048791: 31 c0 xorl %eax,%eax
8048793: c9 leave
8048794: c3 ret
8048795: 90 nop

与前面-g编译后的二进制代码比较一下,有不少区别。

至于如何写shellcode、如何理解别人给出的shellcode,请参看华中站系统安全版精华区中的"如何写自己的shellcode"


示例-1
[beyes@beyes ELF]$ objdump -h simplesection.o

simplesection.o:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000004f  00000000  00000000  00000034  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000008  00000000  00000000  00000084  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000004  00000000  00000000  0000008c  2**2
                  ALLOC
  3 .rodata       00000004  00000000  00000000  0000008c  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .comment      0000002e  00000000  00000000  00000090  2**0
                  CONTENTS, READONLY
  5 .note.GNU-stack 00000000  00000000  00000000  000000be  2**0
                  CONTENTS, READONLY
  6 .eh_frame     00000058  00000000  00000000  000000c0  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
上面的输出结果中,"CONTENTS"  ,"ALLOC" 等表示该段的属性,其中 "CONTENTS" 表示该段在文件中存在。如 .bss 段没有 "CONTENTS"  属性,表示 .bss 段在 ELF 文件中不存在内容。

经常使用 -s -d 两个选项来查看目标文件。-s 选项将所有段的内容以十六进制形式打印出来;-d 选项可以将所有包含指令的段反汇编。如:
[beyes@beyes ELF]$ objdump -s -d simplesection.o

simplesection.o:     file format elf32-i386

Contents of section .text:
0000 5589e583 ec188b45 08894424 04c70424  U......E..D$...$
0010 00000000 e8fcffff ffc9c355 89e583e4  ...........U....
0020 f083ec20 c744241c 01000000 8b150400  ... .D$.........
0030 0000a100 00000001 d0034424 1c034424  ..........D$..D$
0040 18890424 e8fcffff ff8b4424 1cc9c3    ...$......D$...
Contents of section .data:
0000 54000000 55000000                    T...U...
Contents of section .rodata:
0000 25640a00                             %d..
Contents of section .comment:
0000 00474343 3a202847 4e552920 342e362e  .GCC: (GNU) 4.6.
0010 30203230 31313036 30332028 52656420  0 20110603 (Red
0020 48617420 342e362e 302d3130 2900      Hat 4.6.0-10).
Contents of section .eh_frame:
0000 14000000 00000000 017a5200 017c0801  .........zR..|..
0010 1b0c0404 88010000 1c000000 1c000000  ................
0020 00000000 1b000000 00410e08 8502420d  .........A....B.
0030 0557c50c 04040000 1c000000 3c000000  .W..........<...
0040 1b000000 34000000 00410e08 8502420d  ....4....A....B.
0050 0570c50c 04040000                    .p......

Disassembly of section .text:

00000000 <func1>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 18                sub    $0x18,%esp
   6:   8b 45 08                mov    0x8(%ebp),%eax
   9:   89 44 24 04             mov    %eax,0x4(%esp)
   d:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  14:   e8 fc ff ff ff          call   15 <func1+0x15>
  19:   c9                      leave
  1a:   c3                      ret

0000001b <main>:
  1b:   55                      push   %ebp
  1c:   89 e5                   mov    %esp,%ebp
  1e:   83 e4 f0                and    $0xfffffff0,%esp
  21:   83 ec 20                sub    $0x20,%esp
  24:   c7 44 24 1c 01 00 00    movl   $0x1,0x1c(%esp)
  2b:   00
  2c:   8b 15 04 00 00 00       mov    0x4,%edx
  32:   a1 00 00 00 00          mov    0x0,%eax
  37:   01 d0                   add    %edx,%eax
  39:   03 44 24 1c             add    0x1c(%esp),%eax
  3d:   03 44 24 18             add    0x18(%esp),%eax
  41:   89 04 24                mov    %eax,(%esp)
  44:   e8 fc ff ff ff          call   45 <main+0x2a>
  49:   8b 44 24 1c             mov    0x1c(%esp),%eax
  4d:   c9                      leave
  4e:   c3                      ret
"Contents of section .text" 就是 .text 代码段的数据以十六进制方式打印出来的内容,总共 0x4f 个字节,最左边一列是偏移量,中间 4 列是十六进制的内容,最有一列是 .text 段的 ASCII 码形式。对照下面的反汇编结果,可以很明显的看到,.text 段里所包含的正是目标文件里所对应的同名 .c 文件中的 func1() 和 main() 里的指令。.text 段的第 1 个字节 0x55 就是 func1() 函数的第 1 条 push %ebp 指令,而最后一个字节的 0xc3 正是 main() 函数的最后一跳指令 ret 。

-t 选项用来打印出符号表入口信息,该选项的功能和 nm 命令比较相似,尽管它们两的显示格式有点不一样。如下所示:
$ objdump -t simplesection.o

simplesection.o:     file format elf32-i386

SYMBOL TABLE:
00000000 l    df *ABS*  00000000 simplesection.c
00000000 l    d  .text  00000000 .text
00000000 l    d  .data  00000000 .data
00000000 l    d  .bss   00000000 .bss
00000000 l    d  .rodata        00000000 .rodata
00000004 l     O .data  00000004 static_var.1220
00000000 l     O .bss   00000004 static_var2.1221
00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack
00000000 l    d  .eh_frame      00000000 .eh_frame
00000000 l    d  .comment       00000000 .comment
00000000 g     O .data  00000004 global_init_var
00000004       O *COM*  00000004 global_uninit_var
00000000 g     F .text  0000001b func1
00000000         *UND*  00000000 printf
0000001b g     F .text  00000034 main
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-18 04:49 , Processed in 0.065140 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表