0x00 背景
略
0x01 方法
用以下Android.mk
和main.c
编译即可。编译出的libmain.so
既可以当作动态库来链接,也可当作可执行文件执行。需要注意的是,如果是使用cpp
后缀,__attribute__((section(".interp")))
将不起作用。包含__attribute__((section(".interp")))
的源码只能使用.c
后缀
//Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main
LOCAL_CFLAGS += -fPIC -pie
LOCAL_LDFLAGS += -Wl,-e,entry -llog
LOCAL_MODULE := main
LOCAL_SRC_FILES := main.c
include $(BUILD_SHARED_LIBRARY)
//main.c
#include <stdlib.h>
#include <stdio.h>
#include <android/log.h>
#define LOG_TAG "MY_LOG"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
const char interp_section[] __attribute__((section(".interp"))) = "/system/bin/linker";
void entry()
{
printf("hello\n");
LOGD("hell0, main\n");
exit(0);
}
编译出libmain.so
后我们来看一下:
$ file ../libs/armeabi-v7a/libmain.so
../libs/armeabi-v7a/libmain.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, BuildID[sha1]=3d99b878a4db700cde253a277d23ac9c1d92aa23, stripped
interpreter
有了。
$ arm-linux-androideabi-readelf -l ../libs/armeabi-v7a/libmain.so
Elf file type is DYN (Shared object file)
Entry point 0xfb5
There are 9 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00000034 0x00000034 0x00120 0x00120 R 0x4
INTERP 0x00263c 0x0000263c 0x0000263c 0x00013 0x00013 R 0x1
[Requesting program interpreter: /system/bin/linker]
LOAD 0x000000 0x00000000 0x00000000 0x0264f 0x0264f R E 0x1000
LOAD 0x002e34 0x00003e34 0x00003e34 0x001d0 0x001d0 RW 0x1000
DYNAMIC 0x002e40 0x00003e40 0x00003e40 0x00120 0x00120 RW 0x4
NOTE 0x000154 0x00000154 0x00000154 0x000bc 0x000bc R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
EXIDX 0x00253c 0x0000253c 0x0000253c 0x00100 0x00100 R 0x4
GNU_RELRO 0x002e34 0x00003e34 0x00003e34 0x001cc 0x001cc RW 0x4
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .note.android.ident .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 .interp
03 .fini_array .init_array .dynamic .got .data
04 .dynamic
05 .note.android.ident .note.gnu.build-id
06
07 .ARM.exidx
08 .fini_array .init_array .dynamic .got
Entry point
有了: 0xfb5 (0xfb4)。
$ arm-linux-androideabi-objdump -d ../libs/armeabi-v7a/libmain.so | grep fb4 -A20
00000fb4 <entry@@Base>:
fb4: b580 push {r7, lr}
fb6: 466f mov r7, sp
fb8: a005 add r0, pc, #20 ; (adr r0, fd0 <entry@@Base+0x1c>)
fba: f7ff ef36 blx e28 <puts@plt>
fbe: a106 add r1, pc, #24 ; (adr r1, fd8 <entry@@Base+0x24>)
fc0: a207 add r2, pc, #28 ; (adr r2, fe0 <entry@@Base+0x2c>)
fc2: 2003 movs r0, #3
fc4: f7ff ef36 blx e34 <__android_log_print@plt>
fc8: 2000 movs r0, #0
fca: f7ff ef3a blx e40 <exit@plt>
fce: bf00 nop
...
看一下Entry point
,确实是我们写的entry
函数。