Linux下查看分析可執行文件的方式

轉自:https://mp.weixin.qq.com/s/BpGphYGj12gvo6uMMzCL0Q

本文主要講解可執行文件信息的查看方式和方法:readelf,ldd,nm,file,strip,size, strings,objdump

簡單的實例代碼:

#include <stdio.h>

int main(int argc, char *argv[])
{
        char *p = "hello";
        char ap[] = "hello";

        printf("p = %p ap = %p sizeof(p) = %d, sizeof(ap) = %d\n", p, ap, sizeo$
}

編譯:sudo gcc -o test test.c

測試平臺:raspberry pi cm3+(bcm2837)

執行:

pi@raspberrypi:~ $ ./test 
p = 0x104e0 ap = 0x7eed1274 sizeof(p) = 4, sizeof(ap) = 6

1.使用readelf查看可執行文件的頭信息:

pi@raspberrypi:~ $ readelf -h test
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x10318
  Start of program headers:          52 (bytes into file)
  Start of section headers:          6820 (bytes into file)
  Flags:                             0x5000400, Version5 EABI, hard-float ABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         9
  Size of section headers:           40 (bytes)
  Number of section headers:         29
  Section header string table index: 28

Class展示了該程序的位數

Data展示了程序的大小端

Machine展示了程序的運行平臺

查看只讀取的內容:

pi@raspberrypi:~ $ readelf test -x .rodata

Hex dump of section '.rodata':
  0x000104dc 01000200 68656c6c 6f000000 70203d20 ....hello...p = 
  0x000104ec 25702061 70203d20 25702073 697a656f %p ap = %p sizeo
  0x000104fc 66287029 203d2025 642c2073 697a656f f(p) = %d, sizeo
  0x0001050c 66286170 29203d20 25640a00          f(ap) = %d..

2.使用ldd命令查看程序依賴的動態庫:

pi@raspberrypi:~ $ ldd test
	linux-vdso.so.1 (0x7ef81000)
	/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so => /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so (0x76ef7000)
	libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76d7c000)
	/lib/ld-linux-armhf.so.3 (0x76f0c000)

3.使用nm命令查看elf文件的符號表信息

pi@raspberrypi:~ $ nm test
         U abort@@GLIBC_2.4
0002102c B __bss_end__
0002102c B _bss_end__
00021028 B __bss_start
00021028 B __bss_start__
00010354 t call_weak_fn
00021028 b completed.10783
00021020 D __data_start
00021020 W data_start
00010378 t deregister_tm_clones
000103dc t __do_global_dtors_aux
00020f14 t __do_global_dtors_aux_fini_array_entry
00021024 D __dso_handle
00020f18 d _DYNAMIC
00021028 D _edata
0002102c B __end__
0002102c B _end
000104d4 T _fini
00010404 t frame_dummy
00020f10 t __frame_dummy_init_array_entry
00010520 r __FRAME_END__
00021000 d _GLOBAL_OFFSET_TABLE_
         w __gmon_start__
000102c8 T _init
00020f14 t __init_array_end
00020f10 t __init_array_start
000104dc R _IO_stdin_used
000104d0 T __libc_csu_fini
00010470 T __libc_csu_init
         U __libc_start_main@@GLIBC_2.4
00010408 T main
         U printf@@GLIBC_2.4
000103a4 t register_tm_clones
00010318 T _start
00021028 D __TMC_END__

4.使用file命令查看文件的信息信息,以及是否包含符號表

pi@raspberrypi:~ $ file test test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=3779ccaf885035d737eaa63de6e7051a751be969, not stripped

如果使用file命令看到最後是not stripped,那麼則含有符號表,一般線上的程序可能會選擇去掉符號表信息,因爲可以大大減少可執行文件的空間佔用。

5.去掉符號表的方式:$ strip test

pi@raspberrypi:~ $ ls -al test
-rwxr-xr-x 1 root root 7980 Jul  2 21:07 test
pi@raspberrypi:~ $ 
pi@raspberrypi:~ $ strip test
pi@raspberrypi:~ $ 
pi@raspberrypi:~ $ nm test
nm: test: no symbols
pi@raspberrypi:~ $ 
pi@raspberrypi:~ $ ls -al test
-rwxr-xr-x 1 pi pi 5544 Jul  2 10:30 test
pi@raspberrypi:~ $ 
pi@raspberrypi:~ $ 
pi@raspberrypi:~ $ file test
test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=3779ccaf885035d737eaa63de6e7051a751be969, stripped

6.使用size查看可執行文件的大小

pi@raspberrypi:~ $ size test
   text	   data	    bss	    dec	    hex	filename
    970	    280	      4	   1254	    4e6	test

如果data佔用空間過大,那可能是你程序中用到了太多的全局變量和靜態變量或常量。

7.strings查看可執行文件中的字符串

pi@raspberrypi:~ $ strings test
/lib/ld-linux-armhf.so.3
libc.so.6
abort
printf
__libc_start_main
GLIBC_2.4
__gmon_start__
hello
p = %p ap = %p sizeof(p) = %d, sizeof(ap) = %d
GCC: (Raspbian 8.3.0-6+rpi1) 8.3.0
aeabi
.shstrtab
.interp
.note.ABI-tag
.note.gnu.build-id
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rel.dyn
.rel.plt
.init
.text
.fini
.rodata
.ARM.exidx
.eh_frame
.init_array
.fini_array
.dynamic
.got
.data
.bss
.comment
.ARM.attributes

8.objdump反彙編所有代碼

pi@raspberrypi:~ $ objdump -d test

test:     file format elf32-littlearm


Disassembly of section .init:

000102c8 <.init>:
   102c8:	e92d4008 	push	{r3, lr}
   102cc:	eb000020 	bl	10354 <abort@plt+0x48>
   102d0:	e8bd8008 	pop	{r3, pc}

Disassembly of section .plt:

000102d4 <printf@plt-0x14>:
   102d4:	e52de004 	push	{lr}		; (str lr, [sp, #-4]!)
   102d8:	e59fe004 	ldr	lr, [pc, #4]	; 102e4 <printf@plt-0x4>
   102dc:	e08fe00e 	add	lr, pc, lr
   102e0:	e5bef008 	ldr	pc, [lr, #8]!
   102e4:	00010d1c 	andeq	r0, r1, ip, lsl sp

000102e8 <printf@plt>:
   102e8:	e28fc600 	add	ip, pc, #0, 12
   102ec:	e28cca10 	add	ip, ip, #16, 20	; 0x10000
   102f0:	e5bcfd1c 	ldr	pc, [ip, #3356]!	; 0xd1c

000102f4 <__libc_start_main@plt>:
   102f4:	e28fc600 	add	ip, pc, #0, 12
   102f8:	e28cca10 	add	ip, ip, #16, 20	; 0x10000
   102fc:	e5bcfd14 	ldr	pc, [ip, #3348]!	; 0xd14

00010300 <__gmon_start__@plt>:
   10300:	e28fc600 	add	ip, pc, #0, 12
   10304:	e28cca10 	add	ip, ip, #16, 20	; 0x10000
   10308:	e5bcfd0c 	ldr	pc, [ip, #3340]!	; 0xd0c

0001030c <abort@plt>:
   1030c:	e28fc600 	add	ip, pc, #0, 12
   10310:	e28cca10 	add	ip, ip, #16, 20	; 0x10000
   10314:	e5bcfd04 	ldr	pc, [ip, #3332]!	; 0xd04

Disassembly of section .text:

00010318 <.text>:
   10318:	e3a0b000 	mov	fp, #0
   1031c:	e3a0e000 	mov	lr, #0
   10320:	e49d1004 	pop	{r1}		; (ldr r1, [sp], #4)
   10324:	e1a0200d 	mov	r2, sp
   10328:	e52d2004 	push	{r2}		; (str r2, [sp, #-4]!)
   1032c:	e52d0004 	push	{r0}		; (str r0, [sp, #-4]!)
   10330:	e59fc010 	ldr	ip, [pc, #16]	; 10348 <abort@plt+0x3c>
   10334:	e52dc004 	push	{ip}		; (str ip, [sp, #-4]!)
   10338:	e59f000c 	ldr	r0, [pc, #12]	; 1034c <abort@plt+0x40>
   1033c:	e59f300c 	ldr	r3, [pc, #12]	; 10350 <abort@plt+0x44>
   10340:	ebffffeb 	bl	102f4 <__libc_start_main@plt>
   10344:	ebfffff0 	bl	1030c <abort@plt>
   10348:	000104d0 	ldrdeq	r0, [r1], -r0	; <UNPREDICTABLE>
   1034c:	00010408 	andeq	r0, r1, r8, lsl #8
   10350:	00010470 	andeq	r0, r1, r0, ror r4
   10354:	e59f3014 	ldr	r3, [pc, #20]	; 10370 <abort@plt+0x64>
   10358:	e59f2014 	ldr	r2, [pc, #20]	; 10374 <abort@plt+0x68>
   1035c:	e08f3003 	add	r3, pc, r3
   10360:	e7932002 	ldr	r2, [r3, r2]
   10364:	e3520000 	cmp	r2, #0
   10368:	012fff1e 	bxeq	lr
   1036c:	eaffffe3 	b	10300 <__gmon_start__@plt>
   10370:	00010c9c 	muleq	r1, ip, ip
   10374:	0000001c 	andeq	r0, r0, ip, lsl r0
   10378:	e59f0018 	ldr	r0, [pc, #24]	; 10398 <abort@plt+0x8c>
   1037c:	e59f3018 	ldr	r3, [pc, #24]	; 1039c <abort@plt+0x90>
   10380:	e1530000 	cmp	r3, r0
   10384:	012fff1e 	bxeq	lr
   10388:	e59f3010 	ldr	r3, [pc, #16]	; 103a0 <abort@plt+0x94>
   1038c:	e3530000 	cmp	r3, #0
   10390:	012fff1e 	bxeq	lr
   10394:	e12fff13 	bx	r3
   10398:	00021028 	andeq	r1, r2, r8, lsr #32
   1039c:	00021028 	andeq	r1, r2, r8, lsr #32
   103a0:	00000000 	andeq	r0, r0, r0
   103a4:	e59f0024 	ldr	r0, [pc, #36]	; 103d0 <abort@plt+0xc4>
   103a8:	e59f1024 	ldr	r1, [pc, #36]	; 103d4 <abort@plt+0xc8>
   103ac:	e0411000 	sub	r1, r1, r0
   103b0:	e1a01141 	asr	r1, r1, #2
   103b4:	e0811fa1 	add	r1, r1, r1, lsr #31
   103b8:	e1b010c1 	asrs	r1, r1, #1
   103bc:	012fff1e 	bxeq	lr
   103c0:	e59f3010 	ldr	r3, [pc, #16]	; 103d8 <abort@plt+0xcc>
   103c4:	e3530000 	cmp	r3, #0
   103c8:	012fff1e 	bxeq	lr
   103cc:	e12fff13 	bx	r3
   103d0:	00021028 	andeq	r1, r2, r8, lsr #32
   103d4:	00021028 	andeq	r1, r2, r8, lsr #32
   103d8:	00000000 	andeq	r0, r0, r0
   103dc:	e92d4010 	push	{r4, lr}
   103e0:	e59f4018 	ldr	r4, [pc, #24]	; 10400 <abort@plt+0xf4>
   103e4:	e5d43000 	ldrb	r3, [r4]
   103e8:	e3530000 	cmp	r3, #0
   103ec:	18bd8010 	popne	{r4, pc}
   103f0:	ebffffe0 	bl	10378 <abort@plt+0x6c>
   103f4:	e3a03001 	mov	r3, #1
   103f8:	e5c43000 	strb	r3, [r4]
   103fc:	e8bd8010 	pop	{r4, pc}
   10400:	00021028 	andeq	r1, r2, r8, lsr #32
   10404:	eaffffe6 	b	103a4 <abort@plt+0x98>
   10408:	e92d4800 	push	{fp, lr}
   1040c:	e28db004 	add	fp, sp, #4
   10410:	e24dd020 	sub	sp, sp, #32
   10414:	e50b0018 	str	r0, [fp, #-24]	; 0xffffffe8
   10418:	e50b101c 	str	r1, [fp, #-28]	; 0xffffffe4
   1041c:	e59f3044 	ldr	r3, [pc, #68]	; 10468 <abort@plt+0x15c>
   10420:	e50b3008 	str	r3, [fp, #-8]
   10424:	e59f203c 	ldr	r2, [pc, #60]	; 10468 <abort@plt+0x15c>
   10428:	e24b3010 	sub	r3, fp, #16
   1042c:	e8920003 	ldm	r2, {r0, r1}
   10430:	e5830000 	str	r0, [r3]
   10434:	e2833004 	add	r3, r3, #4
   10438:	e1c310b0 	strh	r1, [r3]
   1043c:	e24b2010 	sub	r2, fp, #16
   10440:	e3a03006 	mov	r3, #6
   10444:	e58d3000 	str	r3, [sp]
   10448:	e3a03004 	mov	r3, #4
   1044c:	e51b1008 	ldr	r1, [fp, #-8]
   10450:	e59f0014 	ldr	r0, [pc, #20]	; 1046c <abort@plt+0x160>
   10454:	ebffffa3 	bl	102e8 <printf@plt>
   10458:	e3a03000 	mov	r3, #0
   1045c:	e1a00003 	mov	r0, r3
   10460:	e24bd004 	sub	sp, fp, #4
   10464:	e8bd8800 	pop	{fp, pc}
   10468:	000104e0 	andeq	r0, r1, r0, ror #9
   1046c:	000104e8 	andeq	r0, r1, r8, ror #9
   10470:	e92d47f0 	push	{r4, r5, r6, r7, r8, r9, sl, lr}
   10474:	e1a07000 	mov	r7, r0
   10478:	e59f6048 	ldr	r6, [pc, #72]	; 104c8 <abort@plt+0x1bc>
   1047c:	e59f5048 	ldr	r5, [pc, #72]	; 104cc <abort@plt+0x1c0>
   10480:	e08f6006 	add	r6, pc, r6
   10484:	e08f5005 	add	r5, pc, r5
   10488:	e0466005 	sub	r6, r6, r5
   1048c:	e1a08001 	mov	r8, r1
   10490:	e1a09002 	mov	r9, r2
   10494:	ebffff8b 	bl	102c8 <printf@plt-0x20>
   10498:	e1b06146 	asrs	r6, r6, #2
   1049c:	08bd87f0 	popeq	{r4, r5, r6, r7, r8, r9, sl, pc}
   104a0:	e3a04000 	mov	r4, #0
   104a4:	e2844001 	add	r4, r4, #1
   104a8:	e4953004 	ldr	r3, [r5], #4
   104ac:	e1a02009 	mov	r2, r9
   104b0:	e1a01008 	mov	r1, r8
   104b4:	e1a00007 	mov	r0, r7
   104b8:	e12fff33 	blx	r3
   104bc:	e1560004 	cmp	r6, r4
   104c0:	1afffff7 	bne	104a4 <abort@plt+0x198>
   104c4:	e8bd87f0 	pop	{r4, r5, r6, r7, r8, r9, sl, pc}
   104c8:	00010a8c 	andeq	r0, r1, ip, lsl #21
   104cc:	00010a84 	andeq	r0, r1, r4, lsl #21
   104d0:	e12fff1e 	bx	lr

Disassembly of section .fini:

000104d4 <.fini>:
   104d4:	e92d4008 	push	{r3, lr}
   104d8:	e8bd8008 	pop	{r3, pc}
pi@raspberrypi:~/sharedir/study $ 

9.反彙編特定函數(如main函數)

先按照地址順序輸出符號表信息:

pi@raspberrypi:~ $ nm -n test | grep main -A 1
         U __libc_start_main@@GLIBC_2.4
         U printf@@GLIBC_2.4
--
00010408 T main
00010470 T __libc_csu_init

我們得到main的開始地址爲0x00010408,結束地址爲0x00010470。

反彙編main函數:

pi@raspberrypi:~ $ objdump -d test --start-address=0x00010408 --stop-address=0x00010470

test:     file format elf32-littlearm


Disassembly of section .text:

00010408 <main>:
   10408:	e92d4800 	push	{fp, lr}
   1040c:	e28db004 	add	fp, sp, #4
   10410:	e24dd020 	sub	sp, sp, #32
   10414:	e50b0018 	str	r0, [fp, #-24]	; 0xffffffe8
   10418:	e50b101c 	str	r1, [fp, #-28]	; 0xffffffe4
   1041c:	e59f3044 	ldr	r3, [pc, #68]	; 10468 <main+0x60>
   10420:	e50b3008 	str	r3, [fp, #-8]
   10424:	e59f203c 	ldr	r2, [pc, #60]	; 10468 <main+0x60>
   10428:	e24b3010 	sub	r3, fp, #16
   1042c:	e8920003 	ldm	r2, {r0, r1}
   10430:	e5830000 	str	r0, [r3]
   10434:	e2833004 	add	r3, r3, #4
   10438:	e1c310b0 	strh	r1, [r3]
   1043c:	e24b2010 	sub	r2, fp, #16
   10440:	e3a03006 	mov	r3, #6
   10444:	e58d3000 	str	r3, [sp]
   10448:	e3a03004 	mov	r3, #4
   1044c:	e51b1008 	ldr	r1, [fp, #-8]
   10450:	e59f0014 	ldr	r0, [pc, #20]	; 1046c <main+0x64>
   10454:	ebffffa3 	bl	102e8 <printf@plt>
   10458:	e3a03000 	mov	r3, #0
   1045c:	e1a00003 	mov	r0, r3
   10460:	e24bd004 	sub	sp, fp, #4
   10464:	e8bd8800 	pop	{fp, pc}
   10468:	000104e0 	.word	0x000104e0
   1046c:	000104e8 	.word	0x000104e8

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章