0x00 Android SO 文件结构
so文件结构详细的分析,请看Android逆向之旅---SO(ELF)文件格式详解,这里就不重复造车轮子了。
我们待分析的so已经上传到csdn,下载地址:http://download.csdn.net/detail/jltxgcy/9602803。
0x01 readelf命令
1.1 so文件整体图
1.2 readelf文件位置
Android下readelf位于android-ndk-r12/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin中,文件名称为arm-linux-androideabi-readelf。
1.3 read ELF Header
arm-linux-androideabi-readelf -h ~/Public/libPLTUtils.so
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: DYN (Shared object file)
Machine: ARM
Version: 0x1
Entry point address: 0x0
Start of program headers: 52 (bytes into file)
Start of section headers: 12664 (bytes into file)
Flags: 0x5000200, Version5 EABI, soft-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: 26
Section header string table index: 25
1.4 read Program Header
arm-linux-androideabi-readelf -l ~/Public/libPLTUtils.so
Elf file type is DYN (Shared object file)Entry point 0x0There are 9 program headers, starting at offset 52Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000034 0x00000034 0x00000034 0x00120 0x00120 R 0x4 INTERP 0x000154 0x00000154 0x00000154 0x00013 0x00013 R 0x1 [Requesting program interpreter: /system/bin/linker] LOAD 0x000000 0x00000000 0x00000000 0x0246a 0x0246a R E 0x1000 LOAD 0x002e80 0x00003e80 0x00003e80 0x00188 0x00188 RW 0x1000 DYNAMIC 0x002e8c 0x00003e8c 0x00003e8c 0x00128 0x00128 RW 0x4 NOTE 0x000168 0x00000168 0x00000168 0x00024 0x00024 R 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0 EXIDX 0x002304 0x00002304 0x00002304 0x00100 0x00100 R 0x4 GNU_RELRO 0x002e80 0x00003e80 0x00003e80 0x00180 0x00180 RW 0x4 Section to Segment mapping: Segment Sections... 00 01 .interp 02 .interp .note.gnu.build-id .dynsym .dynstr .hash .gnu.version .gnu.version_d .gnu.version_r .rel.dyn .rel.plt .plt .text .ARM.extab .ARM.exidx .rodata 03 .fini_array .init_array .dynamic .got .data 04 .dynamic 05 .note.gnu.build-id 06 07 .ARM.exidx 08 .fini_array .init_array .dynamic .got
There are 26 section headers, starting at offset 0x3178:Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .interp PROGBITS 00000154 000154 000013 00 A 0 0 1 [ 2] .note.gnu.build-i NOTE 00000168 000168 000024 00 A 0 0 4 [ 3] .dynsym DYNSYM 0000018c 00018c 000390 10 A 4 1 4 [ 4] .dynstr STRTAB 0000051c 00051c 0004d7 00 A 0 0 1 [ 5] .hash HASH 000009f4 0009f4 000180 04 A 3 0 4 [ 6] .gnu.version VERSYM 00000b74 000b74 000072 02 A 3 0 2 [ 7] .gnu.version_d VERDEF 00000be8 000be8 00001c 00 A 4 1 4 [ 8] .gnu.version_r VERNEED 00000c04 000c04 000020 00 A 4 1 4 [ 9] .rel.dyn REL 00000c24 000c24 000050 08 A 3 0 4 [10] .rel.plt REL 00000c74 000c74 000040 08 AI 3 11 4 [11] .plt PROGBITS 00000cb4 000cb4 000074 00 AX 0 0 4 [12] .text PROGBITS 00000d28 000d28 0015a0 00 AX 0 0 4 [13] .ARM.extab PROGBITS 000022c8 0022c8 00003c 00 A 0 0 4 [14] .ARM.exidx ARM_EXIDX 00002304 002304 000100 08 AL 12 0 4 [15] .rodata PROGBITS 00002404 002404 000066 01 AMS 0 0 1 [16] .fini_array FINI_ARRAY 00003e80 002e80 000008 00 WA 0 0 4 [17] .init_array INIT_ARRAY 00003e88 002e88 000004 00 WA 0 0 1 [18] .dynamic DYNAMIC 00003e8c 002e8c 000128 08 WA 4 0 4 [19] .got PROGBITS 00003fb4 002fb4 00004c 00 WA 0 0 4 [20] .data PROGBITS 00004000 003000 000008 00 WA 0 0 4 [21] .bss NOBITS 00004008 003008 000000 00 WA 0 0 1 [22] .comment PROGBITS 00000000 003008 000028 01 MS 0 0 1 [23] .note.gnu.gold-ve NOTE 00000000 003030 00001c 00 0 0 4 [24] .ARM.attributes ARM_ATTRIBUTES 00000000 00304c 00002b 00 0 0 1 [25] .shstrtab STRTAB 00000000 003077 0000fe 00 0 0 1Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific)这里我们看到从.fini_array段开始虚拟地址都比文件偏移增加了0x1000, 与此对应的是Program Header的第三个段,Load段,也是以.fini_array为开始,并且虚拟地址也比文件偏移增加了0x1000。
1.6 Section Actual Data
这里面是放1.4提到的25个段的实际数据。
1.7 read Dynamic Setion Actual Data
arm-linux-androideabi-readelf -d ~/Public/libPLTUtils.so
Dynamic section at offset 0x2e8c contains 32 entries: Tag Type Name/Value 0x00000003 (PLTGOT) 0x3fd4 0x00000002 (PLTRELSZ) 64 (bytes) 0x00000017 (JMPREL) 0xc74 0x00000014 (PLTREL) REL 0x00000011 (REL) 0xc24 0x00000012 (RELSZ) 80 (bytes) 0x00000013 (RELENT) 8 (bytes) 0x6ffffffa (RELCOUNT) 7 0x00000006 (SYMTAB) 0x18c 0x0000000b (SYMENT) 16 (bytes) 0x00000005 (STRTAB) 0x51c 0x0000000a (STRSZ) 1239 (bytes) 0x00000004 (HASH) 0x9f4 0x00000001 (NEEDED) Shared library: [liblog.so] 0x00000001 (NEEDED) Shared library: [libdl.so] 0x00000001 (NEEDED) Shared library: [libstdc++.so] 0x00000001 (NEEDED) Shared library: [libm.so] 0x00000001 (NEEDED) Shared library: [libc.so] 0x0000000e (SONAME) Library soname: [libPLTUtils.so] 0x0000001a (FINI_ARRAY) 0x3e80 0x0000001c (FINI_ARRAYSZ) 8 (bytes) 0x00000019 (INIT_ARRAY) 0x3e88 0x0000001b (INIT_ARRAYSZ) 4 (bytes) 0x00000010 (SYMBOLIC) 0x0 0x0000001e (FLAGS) SYMBOLIC BIND_NOW 0x6ffffffb (FLAGS_1) Flags: NOW 0x6ffffff0 (VERSYM) 0xb74 0x6ffffffc (VERDEF) 0xbe8 0x6ffffffd (VERDEFNUM) 1 0x6ffffffe (VERNEED) 0xc04 0x6fffffff (VERNEEDNUM) 1 0x00000000 (NULL) 0x0关于Dynamic Section字段的含义,详细请参考 http://download.csdn.net/detail/jiangwei0910410003/9204051。
1.8 read Dynsym Section Actual Data
arm-linux-androideabi-readelf -s ~/Public/libPLTUtils.so
Symbol table '.dynsym' contains 57 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_finalize@LIBC (2) 2: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit@LIBC (2) 3: 00000d65 52 FUNC GLOBAL DEFAULT 12 Java_com_example_ndkplt_P 4: 00000000 0 FUNC GLOBAL DEFAULT UND puts@LIBC (2) 5: 00004004 4 OBJECT GLOBAL DEFAULT 20 global_fun 6: 00001904 8 FUNC WEAK DEFAULT 12 __aeabi_unwind_cpp_pr1 7: 000018fc 8 FUNC GLOBAL DEFAULT 12 __aeabi_unwind_cpp_pr0 8: 0000190c 8 FUNC WEAK DEFAULT 12 __aeabi_unwind_cpp_pr2 9: 00000000 0 FUNC WEAK DEFAULT UND __gnu_Unwind_Find_exidx 10: 00001ca4 0 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Restore_VFP_ 11: 00001c94 0 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Restore_VFP 12: 00001cb4 0 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Restore_VFP_ 13: 00001cc4 0 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Restore_WMMX 14: 00001d4c 0 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Restore_WMMX 15: 00000000 0 FUNC GLOBAL DEFAULT UND abort@LIBC (2) 16: 00001c80 20 FUNC GLOBAL DEFAULT 12 restore_core_regs 17: 00000000 0 FUNC GLOBAL DEFAULT UND memcpy@LIBC (2) 18: 000011c0 8 FUNC GLOBAL DEFAULT 12 _Unwind_GetCFA 19: 000011c8 164 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_RaiseExcepti 20: 0000126c 28 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_ForcedUnwind 21: 00001288 116 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Resume 22: 000012fc 32 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Resume_or_Re 23: 0000131c 4 FUNC GLOBAL DEFAULT 12 _Unwind_Complete 24: 00001320 24 FUNC GLOBAL DEFAULT 12 _Unwind_DeleteException 25: 00001338 92 FUNC GLOBAL DEFAULT 12 _Unwind_VRS_Get 26: 000013bc 92 FUNC GLOBAL DEFAULT 12 _Unwind_VRS_Set 27: 00001444 200 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Backtrace 28: 00000000 0 NOTYPE WEAK DEFAULT UND __cxa_begin_cleanup 29: 00000000 0 NOTYPE WEAK DEFAULT UND __cxa_type_match 30: 00001eb4 904 FUNC GLOBAL DEFAULT 12 __gnu_unwind_execute 31: 00000000 0 NOTYPE WEAK DEFAULT UND __cxa_call_unexpected 32: 00001914 876 FUNC GLOBAL DEFAULT 12 _Unwind_VRS_Pop 33: 00001cac 0 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Save_VFP_D 34: 00001c9c 0 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Save_VFP 35: 00001cbc 0 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Save_VFP_D_1 36: 00001d08 0 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Save_WMMXD 37: 00001d60 0 FUNC GLOBAL DEFAULT 12 __gnu_Unwind_Save_WMMXC 38: 00001c80 20 FUNC GLOBAL DEFAULT 12 __restore_core_regs 39: 00001d74 36 FUNC GLOBAL DEFAULT 12 ___Unwind_RaiseException 40: 00001d74 36 FUNC GLOBAL DEFAULT 12 _Unwind_RaiseException 41: 00001d98 36 FUNC GLOBAL DEFAULT 12 ___Unwind_Resume 42: 00001d98 36 FUNC GLOBAL DEFAULT 12 _Unwind_Resume 43: 00001dbc 36 FUNC GLOBAL DEFAULT 12 ___Unwind_Resume_or_Rethr 44: 00001dbc 36 FUNC GLOBAL DEFAULT 12 _Unwind_Resume_or_Rethrow 45: 00001de0 36 FUNC GLOBAL DEFAULT 12 ___Unwind_ForcedUnwind 46: 00001de0 36 FUNC GLOBAL DEFAULT 12 _Unwind_ForcedUnwind 47: 00001e04 36 FUNC GLOBAL DEFAULT 12 ___Unwind_Backtrace 48: 00001e04 36 FUNC GLOBAL DEFAULT 12 _Unwind_Backtrace 49: 0000223c 64 FUNC GLOBAL DEFAULT 12 __gnu_unwind_frame 50: 0000227c 16 FUNC GLOBAL DEFAULT 12 _Unwind_GetRegionStart 51: 0000228c 28 FUNC GLOBAL DEFAULT 12 _Unwind_GetLanguageSpecif 52: 000022a8 8 FUNC GLOBAL DEFAULT 12 _Unwind_GetDataRelBase 53: 000022b0 8 FUNC GLOBAL DEFAULT 12 _Unwind_GetTextRelBase 54: 00004008 0 NOTYPE GLOBAL DEFAULT ABS _edata 55: 00004008 0 NOTYPE GLOBAL DEFAULT ABS __bss_start 56: 00004008 0 NOTYPE GLOBAL DEFAULT ABS _end关于DynSym Section字段的含义,详细请参考 http://download.csdn.net/detail/jiangwei0910410003/9204051 。
1.9 Dynstr Section和Shstrtab Section Actual Data
Dynstr Section的实际数据是Dynsym Setion Actual Data中的函数名组成的字符表。
而Shstrtab则是Section Header中的每个setion名字组成的字符表。
2.0 read Relocation Section
arm-linux-androideabi-readelf -r ~/Public/libPLTUtils.so
Relocation section '.rel.dyn' at offset 0xc24 contains 10 entries: Offset Info Type Sym.Value Sym. Name00003e80 00000017 R_ARM_RELATIVE 00003fb4 00000017 R_ARM_RELATIVE 00003fb8 00000017 R_ARM_RELATIVE 00003fbc 00000017 R_ARM_RELATIVE 00003fc0 00000017 R_ARM_RELATIVE 00003fc8 00000017 R_ARM_RELATIVE 00003fcc 00000017 R_ARM_RELATIVE 00004004 00000402 R_ARM_ABS32 00000000 puts00003fc4 00000915 R_ARM_GLOB_DAT 00000000 __gnu_Unwind_Find_exid00003fd0 00001f15 R_ARM_GLOB_DAT 00000000 __cxa_call_unexpectedRelocation section '.rel.plt' at offset 0xc74 contains 8 entries: Offset Info Type Sym.Value Sym. Name00003fe0 00000216 R_ARM_JUMP_SLOT 00000000 __cxa_atexit00003fe4 00000116 R_ARM_JUMP_SLOT 00000000 __cxa_finalize00003fe8 00000416 R_ARM_JUMP_SLOT 00000000 puts00003fec 00000916 R_ARM_JUMP_SLOT 00000000 __gnu_Unwind_Find_exid00003ff0 00000f16 R_ARM_JUMP_SLOT 00000000 abort00003ff4 00001116 R_ARM_JUMP_SLOT 00000000 memcpy00003ff8 00001c16 R_ARM_JUMP_SLOT 00000000 __cxa_begin_cleanup00003ffc 00001d16 R_ARM_JUMP_SLOT 00000000 __cxa_type_match
2.1 read Text Section
./arm-linux-androideabi-objdump -d ~/Public/libPLTUtils.so