转自: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