├── .DS_Store
├── CustomSoLoader
├── .gitignore
├── .idea
│ ├── gradle.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── runConfigurations.xml
├── app
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── memloadertest
│ │ │ └── ExampleInstrumentedTest.java
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── cpp
│ │ │ ├── XorUtils.c
│ │ │ ├── XorUtils.h
│ │ │ ├── auxvec.h
│ │ │ ├── elf-em.h
│ │ │ ├── elf.h
│ │ │ ├── elf_arm_const.h
│ │ │ ├── exec.h
│ │ │ ├── exec_elf.h
│ │ │ ├── linker4_4.c
│ │ │ ├── linker4_4.h
│ │ │ ├── linker7_0.c
│ │ │ ├── linker7_0.h
│ │ │ ├── native-lib.c
│ │ │ ├── public.h
│ │ │ ├── sys_dlopen.h
│ │ │ └── types.h
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── memloadertest
│ │ │ │ └── MainActivity.java
│ │ ├── jniLibs
│ │ │ └── armeabi
│ │ │ │ ├── libdata.so
│ │ │ │ └── libfoo.so
│ │ └── res
│ │ │ ├── drawable-v24
│ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── drawable
│ │ │ └── ic_launcher_background.xml
│ │ │ ├── layout
│ │ │ └── activity_main.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── memloadertest
│ │ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── jniLibs
│ ├── armeabi
│ │ └── libnative-lib.so
│ └── libnative-lib.so
└── settings.gradle
├── README.md
└── ShellUtil
├── .DS_Store
├── Encryption.c
├── Encryption.h
├── Utils.c
├── Utils.h
├── auxvec.h
├── elf-em.h
├── elf.h
├── exec.h
├── exec_elf.h
├── libdata.so
├── log.h
├── main.c
└── types.h
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/.DS_Store
--------------------------------------------------------------------------------
/CustomSoLoader/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/CustomSoLoader/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/CustomSoLoader/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Android
36 |
37 |
38 | CorrectnessLintAndroid
39 |
40 |
41 | Gradle
42 |
43 |
44 | InternationalizationLintAndroid
45 |
46 |
47 | Kotlin
48 |
49 |
50 | LintAndroid
51 |
52 |
53 | PerformanceLintAndroid
54 |
55 |
56 | Probable bugsGradle
57 |
58 |
59 | SecurityLintAndroid
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/CustomSoLoader/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CustomSoLoader/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4.1)
2 |
3 | #C 的编译选项是 CMAKE_C_FLAGS
4 | # 指定编译参数,可选
5 | SET(CMAKE_CXX_FLAGS "-Wno-error=format-security -Wno-error=pointer-sign")
6 |
7 | #设置生成的so动态库最后输出的路径
8 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/)
9 |
10 | add_library( # Sets the name of the library.
11 | native-lib
12 | SHARED
13 | src/main/cpp/linker7_0.c
14 | src/main/cpp/linker4_4.c
15 | src/main/cpp/XorUtils.c
16 | src/main/cpp/native-lib.c )
17 |
18 |
19 | target_link_libraries(native-lib
20 | log
21 | z
22 | m)
--------------------------------------------------------------------------------
/CustomSoLoader/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 26
5 | defaultConfig {
6 | applicationId "com.example.memloadertest"
7 | minSdkVersion 15
8 | targetSdkVersion 26
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | externalNativeBuild {
13 | cmake {
14 | abiFilters 'armeabi'
15 | }
16 | }
17 | }
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | externalNativeBuild {
25 | cmake {
26 | path "CMakeLists.txt"
27 | }
28 | }
29 | }
30 |
31 | dependencies {
32 | implementation fileTree(dir: 'libs', include: ['*.jar'])
33 | implementation 'com.android.support:appcompat-v7:26.1.0'
34 | implementation 'com.android.support.constraint:constraint-layout:1.0.2'
35 | testImplementation 'junit:junit:4.12'
36 | androidTestImplementation 'com.android.support.test:runner:1.0.1'
37 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
38 | }
39 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/androidTest/java/com/example/memloadertest/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.example.memloadertest;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.example.memloadertest", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/XorUtils.c:
--------------------------------------------------------------------------------
1 | #include "XorUtils.h"
2 | static void print_debug(const char *msg){
3 | #ifdef DEBUG
4 | __android_log_print(ANDROID_LOG_INFO, "liumeng", "%s", msg);
5 | #endif
6 | }
7 |
8 | static unsigned elfhash(const char *_name)
9 | {
10 | const unsigned char *name = (const unsigned char *) _name;
11 | unsigned h = 0, g;
12 |
13 | while(*name) {
14 | h = (h << 4) + *name++;
15 | g = h & 0xf0000000;
16 | h ^= g;
17 | h ^= g >> 24;
18 | }
19 | return h;
20 | }
21 |
22 | static unsigned int getLibAddr(){
23 | unsigned int ret = 0;
24 | char name[] = "libdata.so";
25 | char buf[4096], *temp;
26 | int pid;
27 | FILE *fp;
28 | pid = getpid();
29 | sprintf(buf, "/proc/%d/maps", pid);
30 | fp = fopen(buf, "r");
31 | if(fp == NULL)
32 | {
33 | puts("open failed");
34 | goto _error;
35 | }
36 | while(fgets(buf, sizeof(buf), fp)){
37 | if(strstr(buf, name)){
38 | temp = strtok(buf, "-");
39 | ret = strtoul(temp, NULL, 16);
40 | break;
41 | }
42 | }
43 | _error:
44 | fclose(fp);
45 | return ret;
46 | }
47 |
48 | static char getTargetFuncInfo(unsigned long base, const char *funcName, funcInfo *info){
49 | char flag = -1, *dynstr;
50 | int i;
51 | Elf32_Ehdr *ehdr;
52 | Elf32_Phdr *phdr;
53 | Elf32_Off dyn_vaddr;
54 | Elf32_Word dyn_size, dyn_strsz;
55 | Elf32_Dyn *dyn;
56 | Elf32_Addr dyn_symtab, dyn_strtab, dyn_hash;
57 | Elf32_Sym *funSym;
58 | unsigned funHash, nbucket;
59 | unsigned *bucket, *chain;
60 |
61 | ehdr = (Elf32_Ehdr *)base;
62 | phdr = (Elf32_Phdr *)(base + ehdr->e_phoff);
63 | // __android_log_print(ANDROID_LOG_INFO, "JNITag", "phdr = 0x%p, size = 0x%x\n", phdr, ehdr->e_phnum);
64 | for (i = 0; i < ehdr->e_phnum; ++i) {
65 | // __android_log_print(ANDROID_LOG_INFO, "JNITag", "phdr = 0x%p\n", phdr);
66 | if(phdr->p_type == PT_DYNAMIC){
67 | flag = 0;
68 | print_debug("Find .dynamic segment");
69 | break;
70 | }
71 | phdr ++;
72 | }
73 | if(flag)
74 | goto _error;
75 | dyn_vaddr = phdr->p_vaddr + base;
76 | dyn_size = phdr->p_filesz;
77 | __android_log_print(ANDROID_LOG_INFO, "liumeng", "dyn_vadd = 0x%x, dyn_size = 0x%x", dyn_vaddr, dyn_size);
78 | flag = 0;
79 | for (i = 0; i < dyn_size / sizeof(Elf32_Dyn); ++i) {
80 | dyn = (Elf32_Dyn *)(dyn_vaddr + i * sizeof(Elf32_Dyn));
81 | if(dyn->d_tag == DT_SYMTAB){
82 | dyn_symtab = (dyn->d_un).d_ptr;
83 | flag += 1;
84 | __android_log_print(ANDROID_LOG_INFO, "liumeng", "Find .dynsym section, addr = 0x%x\n", dyn_symtab);
85 | }
86 | if(dyn->d_tag == DT_HASH){
87 | dyn_hash = (dyn->d_un).d_ptr;
88 | flag += 2;
89 | __android_log_print(ANDROID_LOG_INFO, "liumeng", "Find .hash section, addr = 0x%x\n", dyn_hash);
90 | }
91 | if(dyn->d_tag == DT_STRTAB){
92 | dyn_strtab = (dyn->d_un).d_ptr;
93 | flag += 4;
94 | __android_log_print(ANDROID_LOG_INFO, "liumeng", "Find .dynstr section, addr = 0x%x\n", dyn_strtab);
95 | }
96 | if(dyn->d_tag == DT_STRSZ){
97 | dyn_strsz = (dyn->d_un).d_val;
98 | flag += 8;
99 | __android_log_print(ANDROID_LOG_INFO, "liumeng", "Find strsz size = 0x%x\n", dyn_strsz);
100 | }
101 | }
102 | if((flag & 0x0f) != 0x0f){
103 | print_debug("Find needed .section failed\n");
104 | goto _error;
105 | }
106 | dyn_symtab += base;
107 | dyn_hash += base;
108 | dyn_strtab += base;
109 | dyn_strsz += base;
110 |
111 | funHash = elfhash(funcName);
112 | funSym = (Elf32_Sym *) dyn_symtab;
113 | dynstr = (char*) dyn_strtab;
114 | nbucket = *((int *) dyn_hash);
115 | bucket = (int *)(dyn_hash + 8);
116 | chain = (unsigned int *)(dyn_hash + 4 * (2 + nbucket));
117 |
118 | flag = -1;
119 | __android_log_print(ANDROID_LOG_INFO, "liumeng", "hash = 0x%x, nbucket = 0x%x\n", funHash, nbucket);
120 | for(i = bucket[funHash % nbucket]; i != 0; i = chain[i]){
121 | __android_log_print(ANDROID_LOG_INFO, "liumeng", "Find index = %d\n", i);
122 | if(strcmp(dynstr + (funSym + i)->st_name, funcName) == 0){
123 | flag = 0;
124 | __android_log_print(ANDROID_LOG_INFO, "liumeng", "Find %s\n", funcName);
125 | break;
126 | }
127 | }
128 | if(flag) goto _error;
129 | info->st_value = (funSym + i)->st_value;
130 | info->st_size = (funSym + i)->st_size;
131 | __android_log_print(ANDROID_LOG_INFO, "liumeng", "st_value = %d, st_size = %d", info->st_value, info->st_size);
132 | return 0;
133 | _error:
134 | return -1;
135 | }
136 |
137 |
138 | int xor_code(Elf32_Addr baseParam,void* start_page_address,Elf32_Addr start_page_filelength){
139 | // char secName[] = ".text";
140 | // char funcName[] = "Java_com_example_memloadertest_MainActivity_getString";
141 | // char funcName[] = "JNI_OnLoad";
142 | // char funcName[] = "Java_com_thomas_crackmeso_MainActivity_verify";
143 |
144 |
145 | const char target_fun[] = "JNI_OnLoad";
146 | funcInfo info;
147 | int i;
148 | // unsigned int npage, base = getLibAddr();
149 | Elf32_Addr base=baseParam;
150 | __android_log_print(ANDROID_LOG_INFO, "liumeng", "base addr = 0x%x", base);
151 | if(getTargetFuncInfo(base, target_fun, &info) == -1){
152 | print_debug("Find JNI_OnLoad failed");
153 | return 0;
154 | }
155 | if(mprotect(start_page_address, start_page_filelength, PROT_READ | PROT_EXEC | PROT_WRITE) != 0){
156 | print_debug("mem privilege change failed");
157 | }
158 | // for(i=0;i< info.st_size - 1; i++){
159 | // char *addr = (char*)(base + info.st_value-1 + i);
160 | // *addr = ~(*addr);
161 | // }
162 | for(i=0;i< info.st_size - 1; i++){
163 | char *addr = (char*)(base + info.st_value-1 + i);
164 | *addr = ~(*addr);
165 | }
166 |
167 | if(mprotect(start_page_address, start_page_filelength,PROT_READ | PROT_EXEC) != 0){
168 | print_debug("mem privilege change failed");
169 | }
170 | print_debug("mem success");
171 | return 1;
172 | }
173 |
174 |
175 |
176 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/XorUtils.h:
--------------------------------------------------------------------------------
1 | //
2 | // XorUtils.h
3 | // Goblin_Shell_4.1.2
4 | //
5 | // Created by liu meng on 2018/2/6.
6 | // Copyright © 2018年 com.qunar. All rights reserved.
7 | //
8 |
9 | #ifndef XorUtils_h
10 | #define XorUtils_h
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include "elf.h"
19 | #include
20 | #define DEBUG
21 |
22 | typedef struct _funcInfo{
23 | Elf32_Addr st_value;
24 | Elf32_Word st_size;
25 | }funcInfo;
26 | int xor_code(Elf32_Addr baseParam,void* start_page_address,Elf32_Addr start_page_filelength);
27 |
28 | #endif /* XorUtils_h */
29 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/auxvec.h:
--------------------------------------------------------------------------------
1 | //
2 | // auxvec.h
3 | // Goblin_Shell_4.1.2
4 | //
5 | // Created by liu meng on 2018/1/30.
6 | // Copyright © 2018年 com.qunar. All rights reserved.
7 | //
8 |
9 | #ifndef _LINUX_AUXVEC_H
10 | #define _LINUX_AUXVEC_H
11 |
12 |
13 |
14 | /* Symbolic values for the entries in the auxiliary table
15 | put on the initial stack */
16 | #define AT_NULL 0 /* end of vector */
17 | #define AT_IGNORE 1 /* entry should be ignored */
18 | #define AT_EXECFD 2 /* file descriptor of program */
19 | #define AT_PHDR 3 /* program headers for program */
20 | #define AT_PHENT 4 /* size of program header entry */
21 | #define AT_PHNUM 5 /* number of program headers */
22 | #define AT_PAGESZ 6 /* system page size */
23 | #define AT_BASE 7 /* base address of interpreter */
24 | #define AT_FLAGS 8 /* flags */
25 | #define AT_ENTRY 9 /* entry point of program */
26 | #define AT_NOTELF 10 /* program is not ELF */
27 | #define AT_UID 11 /* real uid */
28 | #define AT_EUID 12 /* effective uid */
29 | #define AT_GID 13 /* real gid */
30 | #define AT_EGID 14 /* effective gid */
31 | #define AT_PLATFORM 15 /* string identifying CPU for optimizations */
32 | #define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
33 | #define AT_CLKTCK 17 /* frequency at which times() increments */
34 |
35 | #define AT_SECURE 23 /* secure mode boolean */
36 |
37 | #define AT_VECTOR_SIZE 44 /* Size of auxiliary table. */
38 |
39 | #endif /* _LINUX_AUXVEC_H */
40 |
41 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/elf-em.h:
--------------------------------------------------------------------------------
1 | //
2 | // elf-em.h
3 | // Goblin_Shell_4.1.2
4 | //
5 | // Created by liu meng on 2018/1/30.
6 | // Copyright © 2018年 com.qunar. All rights reserved.
7 | //
8 |
9 | #ifndef _LINUX_ELF_EM_H
10 | #define _LINUX_ELF_EM_H
11 |
12 | /* These constants define the various ELF target machines */
13 | #define EM_NONE 0
14 | #define EM_M32 1
15 | #define EM_SPARC 2
16 | #define EM_386 3
17 | #define EM_68K 4
18 | #define EM_88K 5
19 | #define EM_486 6 /* Perhaps disused */
20 | #define EM_860 7
21 | #ifndef EM_ARM
22 | #define EM_ARM 40
23 | #endif
24 | #ifndef EM_386
25 | #define EM_386 3
26 | #endif
27 | #ifndef EM_X86_64
28 | #define EM_X86_64 62
29 | #endif
30 | #ifndef EM_MIPS
31 | #define EM_MIPS 8
32 | #endif
33 | #ifndef EM_AARCH64
34 | #define EM_AARCH64 183
35 | #endif
36 |
37 | /* Next two are historical and binaries and
38 | modules of these types will be rejected by
39 | Linux. */
40 | #define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
41 | #define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
42 |
43 | #define EM_PARISC 15 /* HPPA */
44 | #define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
45 | #define EM_PPC 20 /* PowerPC */
46 | #define EM_PPC64 21 /* PowerPC64 */
47 | #define EM_SH 42 /* SuperH */
48 | #define EM_SPARCV9 43 /* SPARC v9 64-bit */
49 | #define EM_IA_64 50 /* HP/Intel IA-64 */
50 | #define EM_X86_64 62 /* AMD x86-64 */
51 | #define EM_S390 22 /* IBM S/390 */
52 | #define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
53 | #define EM_V850 87 /* NEC v850 */
54 | #define EM_M32R 88 /* Renesas M32R */
55 | #define EM_H8_300 46 /* Renesas H8/300,300H,H8S */
56 | #define EM_FRV 0x5441 /* Fujitsu FR-V */
57 |
58 | /*
59 | * This is an interim value that we will use until the committee comes
60 | * up with a final number.
61 | */
62 | #define EM_ALPHA 0x9026
63 |
64 | /* Bogus old v850 magic number, used by old tools. */
65 | #define EM_CYGNUS_V850 0x9080
66 | /* Bogus old m32r magic number, used by old tools. */
67 | #define EM_CYGNUS_M32R 0x9041
68 | /* This is the old interim value for S/390 architecture */
69 | #define EM_S390_OLD 0xA390
70 |
71 |
72 | #endif /* _LINUX_ELF_EM_H */
73 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/elf.h:
--------------------------------------------------------------------------------
1 | //
2 | // elf.h
3 | // Goblin_Shell_4.1.2
4 | //
5 | // Created by liu meng on 2018/1/30.
6 | // Copyright © 2018年 com.qunar. All rights reserved.
7 | //
8 |
9 | #ifndef _LINUX_ELF_H
10 | #define _LINUX_ELF_H
11 | #include "types.h"
12 | #include "auxvec.h"
13 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
14 | #include "elf-em.h"
15 | #include "elf.h"
16 | #ifndef elf_read_implies_exec
17 | #define elf_read_implies_exec(ex, have_pt_gnu_stack) 0
18 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
19 | #endif
20 | typedef __u32 Elf32_Addr;
21 | typedef __u16 Elf32_Half;
22 | typedef __u32 Elf32_Off;
23 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
24 | typedef __s32 Elf32_Sword;
25 | typedef __u32 Elf32_Word;
26 | typedef __u64 Elf64_Addr;
27 | typedef __u16 Elf64_Half;
28 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
29 | typedef __s16 Elf64_SHalf;
30 | typedef __u64 Elf64_Off;
31 | typedef __s32 Elf64_Sword;
32 | typedef __u32 Elf64_Word;
33 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
34 | typedef __u64 Elf64_Xword;
35 | typedef __s64 Elf64_Sxword;
36 | #define R_ARM_NONE 0
37 | #define PT_NULL 0
38 | #define PT_LOAD 1
39 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
40 | #define PT_DYNAMIC 2
41 | #define PT_INTERP 3
42 | #define PT_NOTE 4
43 | #define PT_SHLIB 5
44 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
45 | #define PT_PHDR 6
46 | #define PT_TLS 7
47 | #define PT_LOOS 0x60000000
48 | #define PT_HIOS 0x6fffffff
49 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
50 | #define PT_LOPROC 0x70000000
51 | #define PT_HIPROC 0x7fffffff
52 | #define PT_GNU_EH_FRAME 0x6474e550
53 | #define PT_GNU_STACK (PT_LOOS + 0x474e551)
54 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
55 | #define ET_NONE 0
56 | #define ET_REL 1
57 | #define ET_EXEC 2
58 | #define ET_DYN 3
59 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
60 | #define ET_CORE 4
61 | #define ET_LOPROC 0xff00
62 | #define ET_HIPROC 0xffff
63 | #define DT_NULL 0
64 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
65 | #define DT_NEEDED 1
66 | #define DT_PLTRELSZ 2
67 | #define DT_PLTGOT 3
68 | #define DT_HASH 4
69 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
70 | #define DT_STRTAB 5
71 | #define DT_SYMTAB 6
72 | #define DT_RELA 7
73 | #define DT_RELASZ 8
74 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
75 | #define DT_RELAENT 9
76 | #define DT_STRSZ 10
77 | #define DT_SYMENT 11
78 | #define DT_INIT 12
79 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
80 | #define DT_FINI 13
81 | #define DT_SONAME 14
82 | #define DT_RPATH 15
83 | #define DT_SYMBOLIC 16
84 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
85 | #define DT_REL 17
86 | #define DT_RELSZ 18
87 | #define DT_RELENT 19
88 | #define DT_PLTREL 20
89 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
90 | #define DT_DEBUG 21
91 | #define DT_TEXTREL 22
92 | #define DT_JMPREL 23
93 | #define DT_LOPROC 0x70000000
94 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
95 | #define DT_HIPROC 0x7fffffff
96 | #define STB_LOCAL 0
97 | #define STB_GLOBAL 1
98 | #define STB_WEAK 2
99 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
100 | #define STT_NOTYPE 0
101 | #define STT_OBJECT 1
102 | #define STT_FUNC 2
103 | #define STT_SECTION 3
104 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
105 | #define STT_FILE 4
106 | #define STT_COMMON 5
107 | #define STT_TLS 6
108 | #define ELF_ST_BIND(x) ((x) >> 4)
109 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
110 | #define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf)
111 | #define ELF32_ST_BIND(x) ELF_ST_BIND(x)
112 | #define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
113 | #define ELF64_ST_BIND(x) ELF_ST_BIND(x)
114 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
115 | #define ELF64_ST_TYPE(x) ELF_ST_TYPE(x)
116 | typedef struct dynamic{
117 | Elf32_Sword d_tag;
118 | union{
119 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
120 | Elf32_Sword d_val;
121 | Elf32_Addr d_ptr;
122 | } d_un;
123 | } Elf32_Dyn;
124 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
125 | typedef struct {
126 | Elf64_Sxword d_tag;
127 | union {
128 | Elf64_Xword d_val;
129 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
130 | Elf64_Addr d_ptr;
131 | } d_un;
132 | } Elf64_Dyn;
133 | #define ELF32_R_SYM(x) ((x) >> 8)
134 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
135 | #define ELF32_R_TYPE(x) ((x) & 0xff)
136 | #define ELF64_R_SYM(i) ((i) >> 32)
137 | #define ELF64_R_TYPE(i) ((i) & 0xffffffff)
138 | typedef struct elf32_rel {
139 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
140 | Elf32_Addr r_offset;
141 | Elf32_Word r_info;
142 | } Elf32_Rel;
143 | typedef struct elf64_rel {
144 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
145 | Elf64_Addr r_offset;
146 | Elf64_Xword r_info;
147 | } Elf64_Rel;
148 | typedef struct elf32_rela{
149 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
150 | Elf32_Addr r_offset;
151 | Elf32_Word r_info;
152 | Elf32_Sword r_addend;
153 | } Elf32_Rela;
154 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
155 | typedef struct elf64_rela {
156 | Elf64_Addr r_offset;
157 | Elf64_Xword r_info;
158 | Elf64_Sxword r_addend;
159 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
160 | } Elf64_Rela;
161 | typedef struct elf32_sym{
162 | Elf32_Word st_name;
163 | Elf32_Addr st_value;
164 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
165 | Elf32_Word st_size;
166 | unsigned char st_info;
167 | unsigned char st_other;
168 | Elf32_Half st_shndx;
169 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
170 | } Elf32_Sym;
171 | typedef struct elf64_sym {
172 | Elf64_Word st_name;
173 | unsigned char st_info;
174 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
175 | unsigned char st_other;
176 | Elf64_Half st_shndx;
177 | Elf64_Addr st_value;
178 | Elf64_Xword st_size;
179 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
180 | } Elf64_Sym;
181 | #define EI_NIDENT 16
182 | typedef struct elf32_hdr{
183 | unsigned char e_ident[EI_NIDENT];
184 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
185 | Elf32_Half e_type;
186 | Elf32_Half e_machine;
187 | Elf32_Word e_version;
188 | Elf32_Addr e_entry;
189 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
190 | Elf32_Off e_phoff;
191 | Elf32_Off e_shoff;
192 | Elf32_Word e_flags;
193 | Elf32_Half e_ehsize;
194 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
195 | Elf32_Half e_phentsize;
196 | Elf32_Half e_phnum;
197 | Elf32_Half e_shentsize;
198 | Elf32_Half e_shnum;
199 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
200 | Elf32_Half e_shstrndx;
201 | } Elf32_Ehdr;
202 | typedef struct elf64_hdr {
203 | unsigned char e_ident[16];
204 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
205 | Elf64_Half e_type;
206 | Elf64_Half e_machine;
207 | Elf64_Word e_version;
208 | Elf64_Addr e_entry;
209 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
210 | Elf64_Off e_phoff;
211 | Elf64_Off e_shoff;
212 | Elf64_Word e_flags;
213 | Elf64_Half e_ehsize;
214 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
215 | Elf64_Half e_phentsize;
216 | Elf64_Half e_phnum;
217 | Elf64_Half e_shentsize;
218 | Elf64_Half e_shnum;
219 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
220 | Elf64_Half e_shstrndx;
221 | } Elf64_Ehdr;
222 | #define PF_R 0x4
223 | #define PF_W 0x2
224 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
225 | #define PF_X 0x1
226 | typedef struct elf32_phdr{
227 | Elf32_Word p_type;
228 | Elf32_Off p_offset;
229 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
230 | Elf32_Addr p_vaddr;
231 | Elf32_Addr p_paddr;
232 | Elf32_Word p_filesz;
233 | Elf32_Word p_memsz;
234 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
235 | Elf32_Word p_flags;
236 | Elf32_Word p_align;
237 | } Elf32_Phdr;
238 | typedef struct elf64_phdr {
239 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
240 | Elf64_Word p_type;
241 | Elf64_Word p_flags;
242 | Elf64_Off p_offset;
243 | Elf64_Addr p_vaddr;
244 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
245 | Elf64_Addr p_paddr;
246 | Elf64_Xword p_filesz;
247 | Elf64_Xword p_memsz;
248 | Elf64_Xword p_align;
249 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
250 | } Elf64_Phdr;
251 | #define SHT_NULL 0
252 | #define SHT_PROGBITS 1
253 | #define SHT_SYMTAB 2
254 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
255 | #define SHT_STRTAB 3
256 | #define SHT_RELA 4
257 | #define SHT_HASH 5
258 | #define SHT_DYNAMIC 6
259 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
260 | #define SHT_NOTE 7
261 | #define SHT_NOBITS 8
262 | #define SHT_REL 9
263 | #define SHT_SHLIB 10
264 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
265 | #define SHT_DYNSYM 11
266 | #define SHT_NUM 12
267 | #define SHT_LOPROC 0x70000000
268 | #define SHT_HIPROC 0x7fffffff
269 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
270 | #define SHT_LOUSER 0x80000000
271 | #define SHT_HIUSER 0xffffffff
272 | #define SHF_WRITE 0x1
273 | #define SHF_ALLOC 0x2
274 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
275 | #define SHF_EXECINSTR 0x4
276 | #define SHF_MASKPROC 0xf0000000
277 | #define SHN_UNDEF 0
278 | #define SHN_LORESERVE 0xff00
279 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
280 | #define SHN_LOPROC 0xff00
281 | #define SHN_HIPROC 0xff1f
282 | #define SHN_ABS 0xfff1
283 | #define SHN_COMMON 0xfff2
284 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
285 | #define SHN_HIRESERVE 0xffff
286 | typedef struct {
287 | Elf32_Word sh_name;
288 | Elf32_Word sh_type;
289 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
290 | Elf32_Word sh_flags;
291 | Elf32_Addr sh_addr;
292 | Elf32_Off sh_offset;
293 | Elf32_Word sh_size;
294 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
295 | Elf32_Word sh_link;
296 | Elf32_Word sh_info;
297 | Elf32_Word sh_addralign;
298 | Elf32_Word sh_entsize;
299 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
300 | } Elf32_Shdr;
301 | typedef struct elf64_shdr {
302 | Elf64_Word sh_name;
303 | Elf64_Word sh_type;
304 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
305 | Elf64_Xword sh_flags;
306 | Elf64_Addr sh_addr;
307 | Elf64_Off sh_offset;
308 | Elf64_Xword sh_size;
309 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
310 | Elf64_Word sh_link;
311 | Elf64_Word sh_info;
312 | Elf64_Xword sh_addralign;
313 | Elf64_Xword sh_entsize;
314 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
315 | } Elf64_Shdr;
316 | #define EI_MAG0 0
317 | #define EI_MAG1 1
318 | #define EI_MAG2 2
319 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
320 | #define EI_MAG3 3
321 | #define EI_CLASS 4
322 | #define EI_DATA 5
323 | #define EI_VERSION 6
324 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
325 | #define EI_OSABI 7
326 | #define EI_PAD 8
327 | #define ELFMAG0 0x7f
328 | #define ELFMAG1 'E'
329 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
330 | #define ELFMAG2 'L'
331 | #define ELFMAG3 'F'
332 | #define ELFMAG "\177ELF"
333 | #define SELFMAG 4
334 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
335 | #define ELFCLASSNONE 0
336 | #define ELFCLASS32 1
337 | #define ELFCLASS64 2
338 | #define ELFCLASSNUM 3
339 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
340 | #define ELFDATANONE 0
341 | #define ELFDATA2LSB 1
342 | #define ELFDATA2MSB 2
343 | #define EV_NONE 0
344 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
345 | #define EV_CURRENT 1
346 | #define EV_NUM 2
347 | #define ELFOSABI_NONE 0
348 | #define ELFOSABI_LINUX 3
349 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
350 | #ifndef ELF_OSABI
351 | #define ELF_OSABI ELFOSABI_NONE
352 | #endif
353 | #define NT_PRSTATUS 1
354 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
355 | #define NT_PRFPREG 2
356 | #define NT_PRPSINFO 3
357 | #define NT_TASKSTRUCT 4
358 | #define NT_AUXV 6
359 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
360 | #define NT_PRXFPREG 0x46e62b7f
361 | typedef struct elf32_note {
362 | Elf32_Word n_namesz;
363 | Elf32_Word n_descsz;
364 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
365 | Elf32_Word n_type;
366 | } Elf32_Nhdr;
367 | typedef struct elf64_note {
368 | Elf64_Word n_namesz;
369 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
370 | Elf64_Word n_descsz;
371 | Elf64_Word n_type;
372 | } Elf64_Nhdr;
373 | #if ELF_CLASS == ELFCLASS32
374 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
375 | #define elfhdr elf32_hdr
376 | #define elf_phdr elf32_phdr
377 | #define elf_note elf32_note
378 | #else
379 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
380 | #define elfhdr elf64_hdr
381 | #define elf_phdr elf64_phdr
382 | #define elf_note elf64_note
383 | #endif
384 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
385 | #endif
386 |
387 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/elf_arm_const.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by liu meng on 2018/3/29.
3 | //
4 |
5 | #ifndef CUSTOMSOLOADER_ELF_ARM_CONST_H
6 | #define CUSTOMSOLOADER_ELF_ARM_CONST_H
7 |
8 |
9 | /* Android-added. */
10 | #define R_ARM_IRELATIVE 160
11 |
12 | /* Processor specific flags for the ELF header e_flags field. */
13 | #define EF_ARM_RELEXEC 0x00000001
14 | #define EF_ARM_HASENTRY 0x00000002
15 | #define EF_ARM_INTERWORK 0x00000004 /* GNU binutils 000413 */
16 | #define EF_ARM_SYMSARESORTED 0x00000004 /* ARM ELF A08 */
17 | #define EF_ARM_APCS_26 0x00000008 /* GNU binutils 000413 */
18 | #define EF_ARM_DYNSYMSUSESEGIDX 0x00000008 /* ARM ELF B01 */
19 | #define EF_ARM_APCS_FLOAT 0x00000010 /* GNU binutils 000413 */
20 | #define EF_ARM_MAPSYMSFIRST 0x00000010 /* ARM ELF B01 */
21 | #define EF_ARM_PIC 0x00000020
22 | #define EF_ARM_ALIGN8 0x00000040 /* 8-bit structure alignment. */
23 | #define EF_ARM_NEW_ABI 0x00000080
24 | #define EF_ARM_OLD_ABI 0x00000100
25 | #define EF_ARM_SOFT_FLOAT 0x00000200
26 | #define EF_ARM_BE8 0x00800000
27 | #define EF_ARM_EABIMASK 0xff000000
28 | #define EF_ARM_EABI_VER1 0x01000000
29 | #define EF_ARM_EABI_VER2 0x02000000
30 | #define EF_ARM_EABI_VER3 0x03000000
31 | #define EF_ARM_EABI_VER4 0x04000000
32 | #define EF_ARM_EABI_VER5 0x05000000
33 |
34 | /* Processor specific relocation types */
35 |
36 | #define R_ARM_NONE 0
37 | #define R_ARM_PC24 1
38 | #define R_ARM_ABS32 2
39 | #define R_ARM_REL32 3
40 | #define R_ARM_PC13 4
41 | #define R_ARM_ABS16 5
42 | #define R_ARM_ABS12 6
43 | #define R_ARM_THM_ABS5 7
44 | #define R_ARM_ABS8 8
45 | #define R_ARM_SBREL32 9
46 | #define R_ARM_THM_PC22 10
47 | #define R_ARM_THM_PC8 11
48 | #define R_ARM_AMP_VCALL9 12
49 | #define R_ARM_SWI24 13
50 | #define R_ARM_THM_SWI8 14
51 | #define R_ARM_XPC25 15
52 | #define R_ARM_THM_XPC22 16
53 |
54 | /* TLS relocations */
55 | #define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
56 | #define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
57 | #define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
58 |
59 | /* 20-31 are reserved for ARM Linux. */
60 | #define R_ARM_COPY 20
61 | #define R_ARM_GLOB_DAT 21
62 | #define R_ARM_JUMP_SLOT 22
63 | #define R_ARM_RELATIVE 23
64 | #define R_ARM_GOTOFF 24
65 | #define R_ARM_GOTPC 25
66 | #define R_ARM_GOT32 26
67 | #define R_ARM_PLT32 27
68 | #define R_ARM_CALL 28
69 | #define R_ARM_JUMP24 29
70 | #define R_ARM_THM_JUMP24 30
71 | #define R_ARM_BASE_ABS 31
72 | #define R_ARM_ALU_PCREL_7_0 32
73 | #define R_ARM_ALU_PCREL_15_8 33
74 | #define R_ARM_ALU_PCREL_23_15 34
75 | #define R_ARM_ALU_SBREL_11_0 35
76 | #define R_ARM_ALU_SBREL_19_12 36
77 | #define R_ARM_ALU_SBREL_27_20 37 // depcreated
78 | #define R_ARM_TARGET1 38
79 | #define R_ARM_SBREL31 39 // deprecated
80 | #define R_ARM_V4BX 40
81 | #define R_ARM_TARGET2 41
82 | #define R_ARM_PREL31 42
83 | #define R_ARM_MOVW_ABS_NC 43
84 | #define R_ARM_MOVT_ABS 44
85 | #define R_ARM_MOVW_PREL_NC 45
86 | #define R_ARM_MOVT_PREL 46
87 | #define R_ARM_THM_MOVW_ABS_NC 47
88 | #define R_ARM_THM_MOVT_ABS 48
89 | #define R_ARM_THM_MOVW_PREL_NC 49
90 | #define R_ARM_THM_MOVT_PREL 50
91 |
92 | /* 96-111 are reserved to G++. */
93 | #define R_ARM_GNU_VTENTRY 100
94 | #define R_ARM_GNU_VTINHERIT 101
95 | #define R_ARM_THM_PC11 102
96 | #define R_ARM_THM_PC9 103
97 |
98 | /* More TLS relocations */
99 | #define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic */
100 | #define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic */
101 | #define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS */
102 | #define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of */
103 | #define R_ARM_TLS_LE32 108
104 | #define R_ARM_TLS_LDO12 109
105 | #define R_ARM_TLS_LE12 110
106 | #define R_ARM_TLS_IE12GP 111
107 |
108 | /* 112-127 are reserved for private experiments. */
109 |
110 | #define R_ARM_RXPC25 249
111 | #define R_ARM_RSBREL32 250
112 | #define R_ARM_THM_RPC22 251
113 | #define R_ARM_RREL32 252
114 | #define R_ARM_RABS32 253
115 | #define R_ARM_RPC24 254
116 | #define R_ARM_RBASE 255
117 |
118 | /* Processor specific program header flags */
119 | #define PF_ARM_SB 0x10000000
120 | #define PF_ARM_PI 0x20000000
121 | #define PF_ARM_ENTRY 0x80000000
122 |
123 | /* Processor specific program header types */
124 | #define PT_ARM_EXIDX (PT_LOPROC + 1)
125 |
126 | /* Processor specific section header flags */
127 | #define SHF_ENTRYSECT 0x10000000
128 | #define SHF_COMDEF 0x80000000
129 |
130 | /* Processor specific symbol types */
131 | #define STT_ARM_TFUNC STT_LOPROC
132 |
133 |
134 |
135 | #endif //CUSTOMSOLOADER_ELF_ARM_CONST_H
136 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/exec.h:
--------------------------------------------------------------------------------
1 | //
2 | // exec.h
3 | // Goblin_Shell_4.1.2
4 | //
5 | // Created by liu meng on 2018/1/30.
6 | // Copyright © 2018年 com.qunar. All rights reserved.
7 | //
8 |
9 | #ifndef _ARM_EXEC_H_
10 | #define _ARM_EXEC_H_
11 |
12 | #define __LDPGSZ 4096
13 |
14 | #define NATIVE_EXEC_ELF
15 |
16 | #define ARCH_ELFSIZE 32
17 |
18 | #define ELF_TARG_CLASS ELFCLASS32
19 | #define ELF_TARG_DATA ELFDATA2LSB
20 | #define ELF_TARG_MACH EM_ARM
21 |
22 | #define _NLIST_DO_AOUT
23 | #define _NLIST_DO_ELF
24 |
25 | #define _KERN_DO_AOUT
26 | #define _KERN_DO_ELF
27 |
28 | #endif /* _ARM_EXEC_H_ */
29 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/exec_elf.h:
--------------------------------------------------------------------------------
1 | //
2 | // exec_elf.h
3 | // Goblin_Shell_4.1.2
4 | //
5 | // Created by liu meng on 2018/1/30.
6 | // Copyright © 2018年 com.qunar. All rights reserved.
7 | //
8 |
9 | #ifndef _SYS_EXEC_ELF_H_
10 | #define _SYS_EXEC_ELF_H_
11 |
12 | #include "types.h"
13 | #include "exec.h"
14 | #include "elf.h"
15 |
16 | /* e_ident[] Operating System/ABI */
17 | #define ELFOSABI_SYSV 0 /* UNIX System V ABI */
18 | #define ELFOSABI_HPUX 1 /* HP-UX operating system */
19 | #define ELFOSABI_NETBSD 2 /* NetBSD */
20 | #define ELFOSABI_LINUX 3 /* GNU/Linux */
21 | #define ELFOSABI_HURD 4 /* GNU/Hurd */
22 | #define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
23 | #define ELFOSABI_SOLARIS 6 /* Solaris */
24 | #define ELFOSABI_MONTEREY 7 /* Monterey */
25 | #define ELFOSABI_IRIX 8 /* IRIX */
26 | #define ELFOSABI_FREEBSD 9 /* FreeBSD */
27 | #define ELFOSABI_TRU64 10 /* TRU64 UNIX */
28 | #define ELFOSABI_MODESTO 11 /* Novell Modesto */
29 | #define ELFOSABI_OPENBSD 12 /* OpenBSD */
30 | #define ELFOSABI_ARM 97 /* ARM */
31 | #define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
32 |
33 | /* e_ident */
34 | #define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
35 | (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
36 | (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
37 | (ehdr).e_ident[EI_MAG3] == ELFMAG3)
38 |
39 | /* e_machine */
40 | #define EM_NONE 0 /* No Machine */
41 | #define EM_M32 1 /* AT&T WE 32100 */
42 | #define EM_SPARC 2 /* SPARC */
43 | #define EM_386 3 /* Intel 80386 */
44 | #define EM_68K 4 /* Motorola 68000 */
45 | #define EM_88K 5 /* Motorola 88000 */
46 | #define EM_486 6 /* Intel 80486 - unused? */
47 | #define EM_860 7 /* Intel 80860 */
48 | #define EM_MIPS 8 /* MIPS R3000 Big-Endian only */
49 | /*
50 | * Don't know if EM_MIPS_RS4_BE,
51 | * EM_SPARC64, EM_PARISC,
52 | * or EM_PPC are ABI compliant
53 | */
54 | #define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
55 | #define EM_SPARC64 11 /* SPARC v9 64-bit unoffical */
56 | #define EM_PARISC 15 /* HPPA */
57 | #define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
58 | #define EM_PPC 20 /* PowerPC */
59 | #define EM_ARM 40 /* Advanced RISC Machines ARM */
60 | #define EM_ALPHA 41 /* DEC ALPHA */
61 | #define EM_SPARCV9 43 /* SPARC version 9 */
62 | #define EM_ALPHA_EXP 0x9026 /* DEC ALPHA */
63 | #define EM_AMD64 62 /* AMD64 architecture */
64 | #define EM_VAX 75 /* DEC VAX */
65 | #define EM_NUM 15 /* number of machine types */
66 |
67 |
68 | /* Section names */
69 | #define ELF_BSS ".bss" /* uninitialized data */
70 | #define ELF_DATA ".data" /* initialized data */
71 | #define ELF_DEBUG ".debug" /* debug */
72 | #define ELF_DYNAMIC ".dynamic" /* dynamic linking information */
73 | #define ELF_DYNSTR ".dynstr" /* dynamic string table */
74 | #define ELF_DYNSYM ".dynsym" /* dynamic symbol table */
75 | #define ELF_FINI ".fini" /* termination code */
76 | #define ELF_GOT ".got" /* global offset table */
77 | #define ELF_HASH ".hash" /* symbol hash table */
78 | #define ELF_INIT ".init" /* initialization code */
79 | #define ELF_REL_DATA ".rel.data" /* relocation data */
80 | #define ELF_REL_FINI ".rel.fini" /* relocation termination code */
81 | #define ELF_REL_INIT ".rel.init" /* relocation initialization code */
82 | #define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */
83 | #define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */
84 | #define ELF_REL_TEXT ".rel.text" /* relocation code */
85 | #define ELF_RODATA ".rodata" /* read-only data */
86 | #define ELF_SHSTRTAB ".shstrtab" /* section header string table */
87 | #define ELF_STRTAB ".strtab" /* string table */
88 | #define ELF_SYMTAB ".symtab" /* symbol table */
89 | #define ELF_TEXT ".text" /* code */
90 |
91 | /* Symbol Binding - ELF32_ST_BIND - st_info */
92 | #define STB_LOCAL 0 /* Local symbol */
93 | #define STB_GLOBAL 1 /* Global symbol */
94 | #define STB_WEAK 2 /* like global - lower precedence */
95 | #define STB_NUM 3 /* number of symbol bindings */
96 | #define STB_LOPROC 13 /* reserved range for processor */
97 | #define STB_HIPROC 15 /* specific symbol bindings */
98 |
99 | /* Symbol type - ELF32_ST_TYPE - st_info */
100 | #define STT_NOTYPE 0 /* not specified */
101 | #define STT_OBJECT 1 /* data object */
102 | #define STT_FUNC 2 /* function */
103 | #define STT_SECTION 3 /* section */
104 | #define STT_FILE 4 /* file */
105 | #define STT_NUM 5 /* number of symbol types */
106 | #define STT_LOPROC 13 /* reserved range for processor */
107 | #define STT_HIPROC 15 /* specific symbol types */
108 |
109 | #define PT_GNU_RELRO 0x6474e552 /* Read-only post relocation */
110 |
111 | #endif /* _SYS_EXEC_ELF_H_ */
112 |
113 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/linker4_4.c:
--------------------------------------------------------------------------------
1 | #include "linker4_4.h"
2 | int pid;
3 | #define SO_MAX 128
4 | static int socount4_4 = 0;
5 | static soinfo4_4 sopool4_4[SO_MAX];
6 | static soinfo4_4 *freelist4_4 = NULL;
7 | static unsigned elfhash4_4(const char *_name)
8 | {
9 | const unsigned char *name = (const unsigned char *) _name;
10 | unsigned h = 0, g;
11 |
12 | while(*name) {
13 | h = (h << 4) + *name++;
14 | g = h & 0xf0000000;
15 | h ^= g;
16 | h ^= g >> 24;
17 | }
18 | return h;
19 | }
20 |
21 | static soinfo4_4 *alloc_info4_4(const char *name)
22 | {
23 | soinfo4_4 *soinfo4_4=NULL;
24 |
25 | if(strlen(name) >= SOINFO_NAME_LEN) {
26 | DL_ERR("library name %s too long",name);
27 | return NULL;
28 | }
29 | if (!freelist4_4) {
30 | if(socount4_4 == SO_MAX) {
31 | DL_ERR("too many libraries when loading %s", name);
32 | return NULL;
33 | }
34 | freelist4_4 = sopool4_4 + socount4_4++;
35 | freelist4_4->next = NULL;
36 | }
37 |
38 | soinfo4_4 = freelist4_4;
39 | freelist4_4 = freelist4_4->next;
40 | DL_ERR("library name %s new ",name);
41 | memset(soinfo4_4, 0, sizeof(soinfo4_4));
42 |
43 | strlcpy((char*) soinfo4_4->name, name, sizeof(soinfo4_4->name));
44 |
45 | soinfo4_4->next = NULL;
46 | return soinfo4_4;
47 | }
48 | static void free_info4_4(soinfo4_4 *si)
49 | {
50 | si->next = freelist4_4;
51 | freelist4_4 = si;
52 | }
53 | static int
54 | _phdr_table_set_load_prot4_4(const Elf32_Phdr* phdr_table,
55 | int phdr_count,
56 | Elf32_Addr load_bias,
57 | int extra_prot_flags)
58 | {
59 | const Elf32_Phdr* phdr = phdr_table;
60 | const Elf32_Phdr* phdr_limit = phdr + phdr_count;
61 |
62 | for (; phdr < phdr_limit; phdr++) {
63 | if (phdr->p_type != PT_LOAD || (phdr->p_flags & PF_W) != 0)
64 | continue;
65 |
66 | Elf32_Addr seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
67 | Elf32_Addr seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
68 | DL_ERR("segments ------=%08x",seg_page_start);
69 | int ret = mprotect((void*)seg_page_start,
70 | seg_page_end - seg_page_start,
71 | PFLAGS_TO_PROT(phdr->p_flags) | extra_prot_flags);
72 | if (ret < 0) {
73 | return -1;
74 | }
75 | }
76 | return 0;
77 | }
78 | int
79 | phdr_table_protect_segments4_4(const Elf32_Phdr* phdr_table,
80 | int phdr_count,
81 | Elf32_Addr load_bias)
82 | {
83 | return _phdr_table_set_load_prot4_4(phdr_table, phdr_count,
84 | load_bias, 0);
85 | }
86 |
87 | int
88 | phdr_table_unprotect_segments4_4(const Elf32_Phdr* phdr_table,
89 | int phdr_count,
90 | Elf32_Addr load_bias)
91 | {
92 | return _phdr_table_set_load_prot4_4(phdr_table, phdr_count,
93 | load_bias, PROT_WRITE);
94 | }
95 | static int
96 | _phdr_table_set_gnu_relro_prot4_4(const Elf32_Phdr* phdr_table,
97 | int phdr_count,
98 | Elf32_Addr load_bias,
99 | int prot_flags)
100 | {
101 | const Elf32_Phdr* phdr = phdr_table;
102 | const Elf32_Phdr* phdr_limit = phdr + phdr_count;
103 |
104 | for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
105 | if (phdr->p_type != PT_GNU_RELRO)
106 | continue;
107 | Elf32_Addr seg_page_start = PAGE_START(phdr->p_vaddr) + load_bias;
108 | Elf32_Addr seg_page_end = PAGE_END(phdr->p_vaddr + phdr->p_memsz) + load_bias;
109 | DL_ERR("_phdr_table_set_gnu_relro_prot GNU=%08x",seg_page_start);
110 | int ret = mprotect((void*)seg_page_start,
111 | seg_page_end - seg_page_start,
112 | prot_flags);
113 | if (ret < 0) {
114 | return -1;
115 | }
116 | }
117 | return 0;
118 | }
119 | int
120 | phdr_table_protect_gnu_relro4_4(const Elf32_Phdr* phdr_table,
121 | int phdr_count,
122 | Elf32_Addr load_bias)
123 | {
124 | return _phdr_table_set_gnu_relro_prot4_4(phdr_table,
125 | phdr_count,
126 | load_bias,
127 | PROT_READ);
128 | }
129 |
130 | static Elf32_Sym* soinfo_elf_lookup4_4(soinfo4_4* si, unsigned hash, const char* name) {
131 | Elf32_Sym* symtab = si->symtab;
132 | const char* strtab = si->strtab;
133 | unsigned n=0;
134 | DL_ERR("SEARCH %s in %s@0x%08x %08x %d=====%08x",
135 | name, si->name, si->base, hash, hash % si->nbucket,si->nbucket);
136 |
137 | for (n= si->bucket[hash % si->nbucket]; n != 0; n = si->chain[n]) {
138 | Elf32_Sym* s = symtab + n;
139 | // DL_ERR("NAME %s",strtab + s->st_name);
140 | if (strcmp(strtab + s->st_name, name)) continue;
141 |
142 | /* only concern ourselves with global and weak symbol definitions */
143 | switch(ELF32_ST_BIND(s->st_info)){
144 | case STB_GLOBAL:
145 | case STB_WEAK:
146 | if (s->st_shndx == SHN_UNDEF) {
147 | continue;
148 | }
149 |
150 | DL_ERR("FOUND %s in %s (%08x) %d",
151 | name, si->name, s->st_value, s->st_size);
152 | return s;
153 | }
154 | }
155 | // DL_ERR("NULL");
156 |
157 | return NULL;
158 | }
159 | static Elf32_Sym* soinfo_do_lookup4_4(soinfo4_4* si, const char* name, soinfo4_4** lsi, soinfo4_4* needed[]) {
160 | unsigned elf_hash = elfhash4_4(name);
161 | Elf32_Sym* s = NULL;
162 | int i;
163 | for (i= 0; needed[i] != NULL; i++) {
164 | DEBUG("%s: looking up %s in %s",
165 | si->name, name, needed[i]->name);
166 | s = soinfo_elf_lookup4_4(needed[i], elf_hash, name);
167 | if (s != NULL) {
168 | *lsi = needed[i];
169 | goto done;
170 | }
171 | }
172 |
173 | done:
174 | if (s != NULL) {
175 | DL_ERR("si %s sym %s s->st_value = 0x%08x, "
176 | "found in %s, base = 0x%08x, load bias = 0x%08x",
177 | si->name, name, s->st_value,
178 | (*lsi)->name, (*lsi)->base, (*lsi)->load_bias);
179 | return s;
180 | }
181 |
182 | return NULL;
183 | }
184 | static int soinfo_relocate4_4(soinfo4_4* si, Elf32_Rel* rel, unsigned count,
185 | soinfo4_4* needed[])
186 | {
187 | Elf32_Sym* symtab = si->symtab;
188 | const char* strtab = si->strtab;
189 | Elf32_Sym* s;
190 | Elf32_Rel* start = rel;
191 | soinfo4_4* lsi;
192 | size_t idx;
193 |
194 | for (idx= 0; idx < count; ++idx, ++rel) {
195 | unsigned type = ELF32_R_TYPE(rel->r_info);
196 | unsigned sym = ELF32_R_SYM(rel->r_info);
197 | Elf32_Addr reloc = (Elf32_Addr)(rel->r_offset + si->load_bias);
198 | Elf32_Addr sym_addr = 0;
199 | char* sym_name = NULL;
200 |
201 | DEBUG("Processing '%s' relocation at index %d", si->name, idx);
202 | if (type == 0) { // R_*_NONE
203 | continue;
204 | }
205 | if (sym != 0) {
206 | sym_name = (char *)(strtab + symtab[sym].st_name);
207 | s = soinfo_do_lookup4_4(si, sym_name, &lsi, needed);
208 |
209 | if (s == NULL) {
210 |
211 | /* We only allow an undefined symbol if this is a weak
212 | reference.. */
213 | s = &symtab[sym];
214 | if (ELF32_ST_BIND(s->st_info) != STB_WEAK) {
215 | DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, si->name);
216 | return -1;
217 | }
218 | if(s!=NULL){
219 | DL_ERR(" %s is not null",sym_name);
220 | }
221 | switch (type) {
222 | case R_ARM_JUMP_SLOT:
223 | case R_ARM_GLOB_DAT:
224 | case R_ARM_ABS32:
225 | case R_ARM_RELATIVE: /* Don't care. */
226 |
227 | /* sym_addr was initialized to be zero above or relocation
228 | code below does not care about value of sym_addr.
229 | No need to do anything. */
230 | break;
231 |
232 |
233 |
234 | case R_ARM_COPY:
235 | /* Fall through. Can't really copy if weak symbol is
236 | not found in run-time. */
237 | default:
238 | DL_ERR("unknown weak reloc type %d @ %p (%d)",
239 | type, rel, (int) (rel - start));
240 | return -1;
241 | }
242 | } else {
243 | // if(lsi->load_bias!=NULL){
244 | // lsi->base=lsi->load_bias;
245 | // }
246 | sym_addr = (Elf32_Addr)(s->st_value + lsi->base);
247 | }
248 | } else {
249 | s = NULL;
250 | }
251 |
252 |
253 | switch(type){
254 |
255 | case R_ARM_JUMP_SLOT:
256 |
257 | DL_ERR("RELO JMP_SLOT %08x <- %08x %s", reloc, sym_addr, sym_name);
258 | *((Elf32_Addr *)reloc)= sym_addr;
259 | break;
260 | case R_ARM_GLOB_DAT:
261 |
262 | DL_ERR("RELO GLOB_DAT %08x <- %08x %s", reloc, sym_addr, sym_name);
263 | *((Elf32_Addr *)reloc)=sym_addr;
264 | break;
265 | case R_ARM_ABS32:
266 |
267 | DL_ERR("RELO ABS %08x <- %08x %s", reloc, sym_addr, sym_name);
268 | *((Elf32_Addr *)reloc) += sym_addr;
269 | break;
270 | case R_ARM_REL32:
271 |
272 | DL_ERR("RELO REL32 %08x <- %08x - %08x %s",
273 | reloc, sym_addr, rel->r_offset, sym_name);
274 | *((Elf32_Addr *)reloc) += sym_addr - rel->r_offset;
275 | break;
276 |
277 |
278 |
279 | case R_ARM_RELATIVE:
280 |
281 |
282 | if (sym) {
283 | DL_ERR("odd RELATIVE form...");
284 | return -1;
285 | }
286 | DL_ERR("RELO RELATIVE %08x <- +%08x", reloc, si->base);
287 | *((Elf32_Addr*)reloc) += si->base;
288 | break;
289 |
290 |
291 |
292 | case R_ARM_COPY:
293 | if ((si->flags & FLAG_EXE) == 0) {
294 |
295 | DL_ERR("%s R_ARM_COPY relocations only supported for ET_EXEC", si->name);
296 | return -1;
297 | }
298 |
299 | DL_ERR("RELO %08x <- %d @ %08x %s", reloc, s->st_size, sym_addr, sym_name);
300 | if (reloc == sym_addr) {
301 | Elf32_Sym *src = soinfo_do_lookup4_4(NULL, sym_name, &lsi, needed);
302 |
303 | if (src == NULL) {
304 | DL_ERR("%s R_ARM_COPY relocation source cannot be resolved", si->name);
305 | return -1;
306 | }
307 | if (lsi->has_DT_SYMBOLIC) {
308 | DL_ERR("%s invalid R_ARM_COPY relocation against DT_SYMBOLIC shared "
309 | "library %s (built with -Bsymbolic?)", si->name, lsi->name);
310 | return -1;
311 | }
312 | if (s->st_size < src->st_size) {
313 | DL_ERR("%s R_ARM_COPY relocation size mismatch (%d < %d)",
314 | si->name, s->st_size, src->st_size);
315 | return -1;
316 | }
317 | memcpy((void*)reloc, (void*)(src->st_value + lsi->load_bias), src->st_size);
318 | } else {
319 | DL_ERR("%s R_ARM_COPY relocation target cannot be resolved", si->name);
320 | return -1;
321 | }
322 | break;
323 |
324 |
325 | default:
326 | DL_ERR("unknown reloc type %d @ %p (%d)",
327 | type, rel, (int) (rel - start));
328 | return -1;
329 | }
330 | }
331 | return 1;
332 | }
333 |
334 | #ifdef ANDROID_MIPS_LINKER
335 | static int mips_relocate_got4_4(soinfo* si, soinfo* needed[]) {
336 | unsigned* got = si->plt_got;
337 | if (got == NULL) {
338 | return true;
339 | }
340 | unsigned local_gotno = si->mips_local_gotno;
341 | unsigned gotsym = si->mips_gotsym;
342 | unsigned symtabno = si->mips_symtabno;
343 | Elf32_Sym* symtab = si->symtab;
344 |
345 |
346 | if ((si->flags & FLAG_LINKER) == 0) {
347 | size_t g = 0;
348 | got[g++] = 0xdeadbeef;
349 | if (got[g] & 0x80000000) {
350 | got[g++] = 0xdeadfeed;
351 | }
352 | /*
353 | * Relocate the local GOT entries need to be relocated
354 | */
355 | for (; g < local_gotno; g++) {
356 | got[g] += si->load_bias;
357 | }
358 | }
359 |
360 | /* Now for the global GOT entries */
361 | Elf32_Sym* sym = symtab + gotsym;
362 | got = si->plt_got + local_gotno;
363 | for (size_t g = gotsym; g < symtabno; g++, sym++, got++) {
364 | const char* sym_name;
365 | Elf32_Sym* s;
366 | soinfo* lsi;
367 |
368 | /* This is an undefined reference... try to locate it */
369 | sym_name = si->strtab + sym->st_name;
370 | s = soinfo_do_lookup4_4(si, sym_name, &lsi, needed);
371 | if (s == NULL) {
372 | /* We only allow an undefined symbol if this is a weak
373 | reference.. */
374 | s = &symtab[g];
375 | if (ELF32_ST_BIND(s->st_info) != STB_WEAK) {
376 | DL_ERR("cannot locate \"%s\"...", sym_name);
377 | return -1;
378 | }
379 | *got = 0;
380 | }
381 | else {
382 |
383 | *got = lsi->load_bias + s->st_value;
384 | }
385 | }
386 | return 1;
387 | }
388 | #endif
389 |
390 | #ifdef ANDROID_ARM_LINKER
391 |
392 | # ifndef PT_ARM_EXIDX
393 | # define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */
394 | # endif
395 | int
396 | phdr_table_get_arm_exidx4_4(const Elf32_Phdr* phdr_table,
397 | int phdr_count,
398 | Elf32_Addr load_bias,
399 | Elf32_Addr** arm_exidx,
400 | unsigned* arm_exidx_count)
401 | {
402 | const Elf32_Phdr* phdr = phdr_table;
403 | const Elf32_Phdr* phdr_limit = phdr + phdr_count;
404 |
405 | for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
406 | if (phdr->p_type != PT_ARM_EXIDX)
407 | continue;
408 |
409 | *arm_exidx = (Elf32_Addr*)(load_bias + phdr->p_vaddr);
410 | *arm_exidx_count = (unsigned)(phdr->p_memsz / 8);
411 | return 0;
412 | }
413 | *arm_exidx = NULL;
414 | *arm_exidx_count = 0;
415 | return -1;
416 | }
417 | #endif /* ANDROID_ARM_LINKER */
418 | static void phdr_table_get_dynamic_section4_4(const Elf32_Phdr* phdr_table,
419 | int phdr_count,
420 | Elf32_Addr load_bias,
421 | Elf32_Dyn** dynamic,
422 | size_t* dynamic_count,
423 | Elf32_Word* dynamic_flags)
424 | {
425 | const Elf32_Phdr* phdr = phdr_table;
426 | const Elf32_Phdr* phdr_limit = phdr + phdr_count;
427 |
428 | for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
429 | if (phdr->p_type != PT_DYNAMIC) {
430 | continue;
431 | }
432 |
433 | *dynamic = (Elf32_Dyn*)(load_bias + phdr->p_vaddr);
434 | if (dynamic_count) {
435 | *dynamic_count = (unsigned)(phdr->p_memsz / 8);
436 | }
437 | if (dynamic_flags) {
438 | *dynamic_flags = phdr->p_flags;
439 | }
440 | return;
441 | }
442 | *dynamic = NULL;
443 | if (dynamic_count) {
444 | *dynamic_count = 0;
445 | }
446 | }
447 | //soinfo4_4* find_library_internal4_4(const char* name);
448 | static int soinfo_link_image4_4(soinfo4_4* si) {
449 | /* "base" might wrap around UINT32_MAX. */
450 | Elf32_Addr base = si->load_bias;
451 | const Elf32_Phdr *phdr = si->phdr;
452 | int phnum = si->phnum;
453 | int relocating_linker = (si->flags & FLAG_LINKER) ;
454 |
455 | /* We can't debug anything until the linker is relocated */
456 | if (!relocating_linker) {
457 | INFO("[ linking %s ]", si->name);
458 | DEBUG("si->base = 0x%08x si->flags = 0x%08x", si->base, si->flags);
459 | }
460 |
461 | /* Extract dynamic section */
462 | size_t dynamic_count;
463 | Elf32_Word dynamic_flags;
464 | phdr_table_get_dynamic_section4_4(phdr, phnum, base, &si->dynamic,
465 | &dynamic_count, &dynamic_flags);
466 | if (si->dynamic == NULL) {
467 | if (!relocating_linker) {
468 | DL_ERR("missing PT_DYNAMIC in \"%s\"", si->name);
469 | }
470 | return -1;
471 | } else {
472 | if (!relocating_linker) {
473 | DEBUG("dynamic = %p", si->dynamic);
474 | }
475 | }
476 | #ifdef ANDROID_ARM_LINKER
477 | (void) phdr_table_get_arm_exidx4_4(phdr, phnum, base,
478 | &si->ARM_exidx, &si->ARM_exidx_count);
479 | #endif
480 | // Extract useful information from dynamic section.
481 | uint32_t needed_count = 0;
482 | Elf32_Dyn* d;
483 | for (d = si->dynamic; d->d_tag != DT_NULL; ++d) {
484 | DEBUG("d = %p, d[0](tag) = 0x%08x d[1](val) = 0x%08x", d, d->d_tag, d->d_un.d_val);
485 | switch(d->d_tag){
486 | case DT_HASH:
487 | si->nbucket = ((unsigned *) (base + d->d_un.d_ptr))[0];
488 | si->nchain = ((unsigned *) (base + d->d_un.d_ptr))[1];
489 | si->bucket = (unsigned *) (base + d->d_un.d_ptr + 8);
490 | si->chain = (unsigned *) (base + d->d_un.d_ptr + 8 + si->nbucket * 4);
491 | break;
492 | case DT_STRTAB:
493 | si->strtab = (const char *) (base + d->d_un.d_ptr);
494 | break;
495 | case DT_SYMTAB:
496 | si->symtab = (Elf32_Sym *) (base + d->d_un.d_ptr);
497 | break;
498 | case DT_PLTREL:
499 | if (d->d_un.d_val != DT_REL) {
500 | DL_ERR("unsupported DT_RELA in \"%s\"", si->name);
501 | return -1;
502 | }
503 | break;
504 | case DT_JMPREL:
505 | si->plt_rel = (Elf32_Rel*) (base + d->d_un.d_ptr);
506 | DL_ERR("plt_rel=%p",si->plt_rel);
507 | break;
508 | case DT_PLTRELSZ:
509 | si->plt_rel_count = d->d_un.d_val / sizeof(Elf32_Rel);
510 | DL_ERR("plt_rel_count=%08x",si->plt_rel_count);
511 | break;
512 | case DT_REL:
513 | si->rel = (Elf32_Rel*) (base + d->d_un.d_ptr);
514 | break;
515 | case DT_RELSZ:
516 | si->rel_count = d->d_un.d_val / sizeof(Elf32_Rel);
517 | break;
518 | case DT_PLTGOT:
519 | /* Save this in case we decide to do lazy binding. We don't yet. */
520 | si->plt_got = (unsigned *)(base + d->d_un.d_ptr);
521 | break;
522 | case DT_DEBUG:
523 | // Set the DT_DEBUG entry to the address of _r_debug for GDB
524 | // if the dynamic table is writable
525 | /*
526 | if ((dynamic_flags & PF_W) != 0) {
527 | d->d_un.d_val = (int) &_r_debug;
528 | }*/
529 | break;
530 | case DT_RELA:
531 | DL_ERR("unsupported DT_RELA in \"%s\"", si->name);
532 | return -1;
533 | case DT_INIT:
534 | si->init_func = (void (*)(void))(base + d->d_un.d_ptr);
535 | DEBUG("%s constructors (DT_INIT) found at %p", si->name, si->init_func);
536 | break;
537 | case DT_FINI:
538 | si->fini_func = (void (*)(void))(base + d->d_un.d_ptr);
539 | DEBUG("%s destructors (DT_FINI) found at %p", si->name, si->fini_func);
540 | break;
541 | case DT_INIT_ARRAY:
542 | si->init_array = (unsigned *)(base + d->d_un.d_ptr);
543 | DEBUG("%s constructors (DT_INIT_ARRAY) found at %p", si->name, si->init_array);
544 | break;
545 | case DT_INIT_ARRAYSZ:
546 | si->init_array_count = ((unsigned)d->d_un.d_val) / sizeof(Elf32_Addr);
547 | break;
548 | case DT_FINI_ARRAY:
549 | si->fini_array = (unsigned *)(base + d->d_un.d_ptr);
550 | DEBUG("%s destructors (DT_FINI_ARRAY) found at %p", si->name, si->fini_array);
551 | break;
552 | case DT_FINI_ARRAYSZ:
553 | si->fini_array_count = ((unsigned)d->d_un.d_val) / sizeof(Elf32_Addr);
554 | break;
555 | case DT_PREINIT_ARRAY:
556 | si->preinit_array = (unsigned *)(base + d->d_un.d_ptr);
557 | DEBUG("%s constructors (DT_PREINIT_ARRAY) found at %p", si->name, si->preinit_array);
558 | break;
559 | case DT_PREINIT_ARRAYSZ:
560 | si->preinit_array_count = ((unsigned)d->d_un.d_val) / sizeof(Elf32_Addr);
561 | break;
562 | case DT_TEXTREL:
563 | si->has_text_relocations = 1;
564 | break;
565 | case DT_SYMBOLIC:
566 | si->has_DT_SYMBOLIC = 1;
567 | break;
568 | case DT_NEEDED:
569 | ++needed_count;
570 | break;
571 | #if defined DT_FLAGS
572 | // TODO: why is DT_FLAGS not defined?
573 | case DT_FLAGS:
574 | if (d->d_un.d_val & DF_TEXTREL) {
575 | si->has_text_relocations = 1;
576 | }
577 | if (d->d_un.d_val & DF_SYMBOLIC) {
578 | si->has_DT_SYMBOLIC = 1;
579 | }
580 | break;
581 | #endif
582 | #if defined(ANDROID_MIPS_LINKER)
583 | case DT_STRSZ:
584 | case DT_SYMENT:
585 | case DT_RELENT:
586 | break;
587 | case DT_MIPS_RLD_MAP:
588 | // Set the DT_MIPS_RLD_MAP entry to the address of _r_debug for GDB.
589 | {
590 | r_debug** dp = (r_debug**) d->d_un.d_ptr;
591 | *dp = &_r_debug;
592 | }
593 | break;
594 | case DT_MIPS_RLD_VERSION:
595 | case DT_MIPS_FLAGS:
596 | case DT_MIPS_BASE_ADDRESS:
597 | case DT_MIPS_UNREFEXTNO:
598 | break;
599 |
600 | case DT_MIPS_SYMTABNO:
601 | si->mips_symtabno = d->d_un.d_val;
602 | break;
603 |
604 | case DT_MIPS_LOCAL_GOTNO:
605 | si->mips_local_gotno = d->d_un.d_val;
606 | break;
607 |
608 | case DT_MIPS_GOTSYM:
609 | si->mips_gotsym = d->d_un.d_val;
610 | break;
611 |
612 | default:
613 | DEBUG("Unused DT entry: type 0x%08x arg 0x%08x", d->d_tag, d->d_un.d_val);
614 | break;
615 | #endif
616 | }
617 | }
618 |
619 | DEBUG("si->base = 0x%08x, si->strtab = %p, si->symtab = %p",
620 | si->base, si->strtab, si->symtab);
621 |
622 | // Sanity checks.
623 | if (relocating_linker && needed_count != 0) {
624 | DL_ERR("linker cannot have DT_NEEDED dependencies on other libraries");
625 | return -1;
626 | }
627 | if (si->nbucket == 0) {
628 | DL_ERR("empty/missing DT_HASH in \"%s\" (built with --hash-style=gnu?)", si->name);
629 | return -1;
630 | }
631 | if (si->strtab == 0) {
632 | DL_ERR("empty/missing DT_STRTAB in \"%s\"", si->name);
633 | return -1;
634 | }
635 | if (si->symtab == 0) {
636 | DL_ERR("empty/missing DT_SYMTAB in \"%s\"", si->name);
637 | return -1;
638 | }
639 | soinfo4_4** needed = (soinfo4_4**) alloca((1 + needed_count) * sizeof(soinfo4_4*));
640 | soinfo4_4** pneeded = needed;
641 | // Elf32_Dyn* dd;
642 | for ( d= si->dynamic; d->d_tag != DT_NULL; ++d) {
643 | if (d->d_tag == DT_NEEDED) {
644 | const char* library_name = si->strtab + d->d_un.d_val;
645 | DEBUG("%s needs %s", si->name, library_name);
646 | soinfo4_4* lsi = (soinfo4_4*)dlopen(library_name,0); // ¼ÓÔØÆäËûÒÀÀµµÄso, ÕâÀïÖ±½Óµ÷ÓÃÔÉúlinker
647 | if (lsi == NULL) {
648 | // strlcpy(tmp_err_buf, linker_get_error_buffer(), sizeof(tmp_err_buf));
649 | DL_ERR("could not load library \"%s\" needed by \"%s\"; caused by ",
650 | library_name, si->name);
651 | return -1;
652 | }
653 | DL_ERR(" soname=%s , nbucket=%08x",lsi->name,lsi->nbucket);
654 | *pneeded++ = lsi;
655 | }
656 | }
657 | *pneeded = NULL;
658 |
659 | if (si->has_text_relocations) {
660 | DL_ERR("%s has text relocations. This is wasting memory and is "
661 | "a security risk. Please fix.", si->name);
662 | if (phdr_table_unprotect_segments4_4(si->phdr, si->phnum, si->load_bias) < 0) {
663 | DL_ERR("can't unprotect loadable segments for \"%s\": %s",
664 | si->name, strerror(errno));
665 | return -1;
666 | }
667 | }
668 |
669 | if (si->plt_rel != NULL) {
670 | DEBUG("[ relocating %s plt ] count=%08x", si->name,si->plt_rel_count);
671 | if (soinfo_relocate4_4(si, si->plt_rel, si->plt_rel_count, needed)!=1) {
672 | DL_ERR("relocate fail");
673 | return -1;
674 | }
675 | }
676 | if (si->rel != NULL) {
677 | DEBUG("[ relocating %s ]", si->name );
678 | if (soinfo_relocate4_4(si, si->rel, si->rel_count, needed)!=1) {
679 | DL_ERR("relocate fail");
680 | return -1;
681 | }
682 | }
683 | #ifdef ANDROID_MIPS_LINKER
684 | if (!mips_relocate_got4_4(si, needed)) {
685 | return -1;
686 | }
687 | #endif
688 |
689 | si->flags |= FLAG_LINKED;
690 | DEBUG("[ finished linking %s ]", si->name);
691 |
692 | DL_ERR("has_text_relocations is %08x",si->has_text_relocations);
693 | if (si->has_text_relocations==1) {
694 | /* All relocations are done, we can protect our segments back to
695 | * read-only. */
696 |
697 | if (phdr_table_protect_segments4_4(si->phdr, si->phnum, si->load_bias) < 0) {
698 | DL_ERR("can't protect segments for \"%s\": %s",
699 | si->name, strerror(errno));
700 | return -1;
701 | }
702 | }
703 | if (phdr_table_protect_gnu_relro4_4(si->phdr, si->phnum, si->load_bias) < 0) {
704 | DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
705 | si->name, strerror(errno));
706 | return -1;
707 | }
708 | return 1;
709 | }
710 | static Elf32_Phdr* CheckPhdr4_4(Elf32_Addr loaded,int fd_,const char *name_,const Elf32_Phdr* phdr_table_,size_t phdr_num_,Elf32_Addr load_bias_) {
711 | const Elf32_Phdr* loaded_phdr_;
712 | Elf32_Phdr* phdr;
713 | const Elf32_Phdr* phdr_limit = phdr_table_ + phdr_num_;
714 | Elf32_Addr loaded_end = loaded + (phdr_num_ * sizeof(Elf32_Phdr));
715 | for ( phdr= phdr_table_; phdr < phdr_limit; ++phdr) {
716 | if (phdr->p_type != PT_LOAD) {
717 | continue;
718 | }
719 | Elf32_Addr seg_start = phdr->p_vaddr + load_bias_;
720 | Elf32_Addr seg_end = phdr->p_filesz + seg_start;
721 | if (seg_start <= loaded && loaded_end <= seg_end) {
722 | loaded_phdr_ =(Elf32_Phdr*)loaded;
723 | return loaded_phdr_;
724 | }
725 | }
726 | DL_ERR("\"%s\" loaded phdr %x not in loadable segment", name_, loaded);
727 | return NULL;
728 | }
729 | static Elf32_Phdr* FindPhdr4_4(int fd_,const char *name_,const Elf32_Phdr* phdr_table_,size_t phdr_num_,Elf32_Addr load_bias_) {
730 | const Elf32_Phdr* phdr_limit = phdr_table_ + phdr_num_;
731 | const Elf32_Phdr* phdr;
732 | // If there is a PT_PHDR, use it directly.
733 | for ( phdr= phdr_table_; phdr < phdr_limit; ++phdr) {
734 | if (phdr->p_type == PT_PHDR) {
735 | return CheckPhdr4_4(load_bias_ + phdr->p_vaddr,fd_,name_,phdr_table_,phdr_num_,load_bias_);
736 | }
737 | }
738 | for (phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
739 | if (phdr->p_type == PT_LOAD) {
740 | if (phdr->p_offset == 0) {
741 | Elf32_Addr elf_addr = load_bias_ + phdr->p_vaddr;
742 | const Elf32_Ehdr* ehdr = (const Elf32_Ehdr*)(void*)elf_addr;
743 | Elf32_Addr offset = ehdr->e_phoff;
744 | return CheckPhdr4_4((Elf32_Addr)ehdr + offset,fd_,name_,phdr_table_,phdr_num_,load_bias_);
745 | }
746 | break;
747 | }
748 | }
749 |
750 | DL_ERR("can't find loaded phdr for \"%s\"", name_);
751 | return NULL;
752 | }
753 | soinfo4_4 *soinfos = NULL;
754 | static int LoadSegments4_4(int fd_,const char *name_,const Elf32_Phdr* phdr_table_,size_t phdr_num_,void* load_start_,Elf32_Addr load_size_,Elf32_Addr load_bias_) {
755 | size_t i;
756 | const Elf32_Phdr* loaded_phdr_;
757 | const char *bname;
758 | for(i = 0; i < phdr_num_; ++i) {
759 | const Elf32_Phdr* phdr = &phdr_table_[i];
760 |
761 | if (phdr->p_type != PT_LOAD) {
762 | continue;
763 | }
764 |
765 | // Segment addresses in memory.
766 | Elf32_Addr seg_start = phdr->p_vaddr + load_bias_;
767 | Elf32_Addr seg_end = seg_start + phdr->p_memsz;
768 |
769 | Elf32_Addr seg_page_start = PAGE_START(seg_start);
770 | Elf32_Addr seg_page_end = PAGE_END(seg_end);
771 |
772 | Elf32_Addr seg_file_end = seg_start + phdr->p_filesz;
773 |
774 | // File offsets.
775 | Elf32_Addr file_start = phdr->p_offset;
776 | Elf32_Addr file_end = file_start + phdr->p_filesz;
777 |
778 | Elf32_Addr file_page_start = PAGE_START(file_start);
779 | Elf32_Addr file_length = file_end - file_page_start;
780 |
781 | if (file_length != 0) {
782 | /* ÔÉú: ÕâÀïÖ±½ÓmapÎļþfd, µ¼ÖÂ/proc/pid/mapsÖб©Â¶ÁËÒѼÓÔØÄ£¿é
783 | void* seg_addr = mmap((void*)seg_page_start,
784 | file_length,
785 | PFLAGS_TO_PROT(phdr->p_flags),
786 | MAP_FIXED|MAP_PRIVATE,
787 | fd_,
788 | file_page_start);
789 | if (seg_addr == MAP_FAILED) {
790 | DL_ERR("couldn't mmap \"%s\" segment %d: %s", name_, i, strerror(errno));
791 | return false;
792 | }*/
793 |
794 | // Ð޸ĺó: ÏÈmmapÒ»¿éÎÞfdÄÚ´æ, È»ºóʹÓÃread¶Á³öÖ¸¶¨ÇøÓòÄÚÈÝÌî³äµ½mmapµÄÄÚ´æ´¦, ×îºó½«mmapµÄÄÚ´æÊôÐÔÉèÖÃΪsegmentµÄÊôÐÔ.
795 | DL_ERR("seg_page_start==%08x. file_length=%08x",seg_page_start,file_length);
796 |
797 | void* seg_addr = mmap((void*)seg_page_start,
798 | file_length,
799 | PROT_WRITE|PROT_READ,
800 | MAP_FIXED|MAP_PRIVATE| MAP_ANONYMOUS,
801 | 0,
802 | 0);
803 | if (seg_addr == MAP_FAILED) {
804 | DL_ERR("couldn't mmap1 \"%s\" segment %d: %s", name_, i, strerror(errno));
805 | return -1;
806 | }
807 |
808 | if(lseek( fd_ , file_page_start, SEEK_SET ) == -1L ) {
809 | DL_ERR("couldn't lseek1 \"%s\" segment %d: %s", name_, i, strerror(errno));
810 | return -1;
811 | }
812 |
813 | if(-1 == read(fd_, seg_addr, file_length)) {
814 | DL_ERR("couldn't read \"%s\" segment %d: %s", name_, i, strerror(errno));
815 | return -1;
816 | }
817 | if(start_page_filelength4_4==0){
818 | start_page_address4_4=seg_addr;
819 | start_page_filelength4_4=file_length;
820 | }
821 | DL_ERR("LoadSegments seg_addr=%0x flag=%08x", (unsigned)seg_addr,PFLAGS_TO_PROT(phdr->p_flags));
822 | if( -1 == mprotect(seg_addr, file_length, PFLAGS_TO_PROT(phdr->p_flags))) {
823 | DL_ERR("couldn't mprotect \"%s\" segment %d: %s", name_, i, strerror(errno));
824 | return -1;
825 | }
826 |
827 | DL_ERR("LoadSegments succeed:%s!", name_);
828 | }
829 |
830 | // if the segment is writable, and does not end on a page boundary,
831 | // zero-fill it until the page limit.
832 | if ((phdr->p_flags & PF_W) != 0 && PAGE_OFFSET(seg_file_end) > 0) {
833 | memset((void*)seg_file_end, 0, PAGE_SIZE - PAGE_OFFSET(seg_file_end));
834 | }
835 |
836 | seg_file_end = PAGE_END(seg_file_end);
837 |
838 | // seg_file_end is now the first page address after the file
839 | // content. If seg_end is larger, we need to zero anything
840 | // between them. This is done by using a private anonymous
841 | // map for all extra pages.
842 | if (seg_page_end > seg_file_end) {
843 | void* zeromap = mmap((void*)seg_file_end,
844 | seg_page_end - seg_file_end,
845 | PFLAGS_TO_PROT(phdr->p_flags),
846 | MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE,
847 | -1,
848 | 0);
849 | if (zeromap == MAP_FAILED) {
850 | DL_ERR("couldn't zero fill \"%s\" gap: %s", name_, strerror(errno));
851 | return -1;
852 | }
853 | }
854 | }
855 | loaded_phdr_=FindPhdr4_4(fd_,name_,phdr_table_,phdr_num_,load_bias_);
856 | if(loaded_phdr_!=NULL){
857 | DL_ERR("findphdr success");
858 | bname = strrchr(name_, '/');
859 | DL_ERR("findphdr success %s",bname);
860 | soinfos = alloc_info4_4(bname ? bname + 1 : name_);
861 | if (soinfos == NULL){
862 | goto fail;
863 | }
864 | DL_ERR(" soinfos fail ");
865 | soinfos->flags = 0;
866 | soinfos->entry = 0;
867 |
868 | soinfos->dynamic = (unsigned *)-1;
869 | soinfos->phdr=loaded_phdr_;
870 | soinfos->load_bias=load_bias_;
871 | soinfos->phnum=phdr_num_;
872 | // soinfos->base1=load_start_;
873 | soinfos->base=load_start_;
874 | soinfos->size=load_size_;
875 | DL_ERR("base1----->>%08x ,size---->>%08x",load_start_,load_size_);
876 | close(fd_);
877 | return 1;
878 | fail:
879 | DL_ERR(" alloc_info4_4 fail ");
880 | close(fd_);
881 | if (soinfos){
882 | free_info4_4(soinfos);
883 | return -1;
884 | }
885 |
886 | }
887 | return 1;
888 | }
889 | static size_t phdr_table_get_load_size4_4(const Elf32_Phdr* phdr_table,
890 | size_t phdr_count,
891 | Elf32_Addr* out_min_vaddr,
892 | Elf32_Addr* out_max_vaddr)
893 | {
894 | Elf32_Addr min_vaddr = 0xFFFFFFFFU;
895 | Elf32_Addr max_vaddr = 0x00000000U;
896 | size_t i;
897 | int found_pt_load = -1;
898 | for (i=0; i < phdr_count; ++i) {
899 | const Elf32_Phdr* phdr = &phdr_table[i];
900 |
901 | if (phdr->p_type != PT_LOAD) {
902 | continue;
903 | }
904 | found_pt_load = 1;
905 |
906 | if (phdr->p_vaddr < min_vaddr) {
907 | min_vaddr = phdr->p_vaddr;
908 | }
909 |
910 | if (phdr->p_vaddr + phdr->p_memsz > max_vaddr) {
911 | max_vaddr = phdr->p_vaddr + phdr->p_memsz;
912 | }
913 | }
914 | if (found_pt_load!=1) {
915 | min_vaddr = 0x00000000U;
916 | }
917 |
918 | min_vaddr = PAGE_START(min_vaddr);
919 | max_vaddr = PAGE_END(max_vaddr);
920 | DL_ERR(" min=%08x,max=%08x", min_vaddr,max_vaddr);
921 | if (out_min_vaddr != NULL) {
922 | *out_min_vaddr = min_vaddr;
923 | }
924 | if (out_max_vaddr != NULL) {
925 | *out_max_vaddr = max_vaddr;
926 | }
927 | return max_vaddr - min_vaddr;
928 | }
929 | static int ReserveAddressSpace4_4(int fd_,const char *name_,const Elf32_Phdr* phdr_table_,size_t phdr_num_) {
930 | Elf32_Addr min_vaddr;
931 | Elf32_Addr max_vaddr;
932 | Elf32_Addr load_size_;
933 | Elf32_Addr load_bias_;
934 | void* load_start_;
935 | load_size_ = phdr_table_get_load_size4_4(phdr_table_, phdr_num_, &min_vaddr,&max_vaddr);
936 | if (load_size_ == 0) {
937 | DL_ERR("\"%s\" has no loadable segments", name_);
938 | return -1;
939 | }
940 | uint8_t* addr = (uint8_t*)min_vaddr;
941 | int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
942 | void* start = mmap(addr, load_size_, PROT_NONE, mmap_flags, -1, 0);
943 | if (start == MAP_FAILED) {
944 | DL_ERR("couldn't reserve %d bytes of address space for \"%s\"", load_size_, name_);
945 | return -1;
946 | }
947 | load_start_ = start;
948 | load_bias_ = (uint8_t*)start - addr;
949 | DL_ERR("load_start %p,load_bias %p", load_start_,load_bias_);
950 | if(LoadSegments4_4(fd_,name_,phdr_table_,phdr_num_,load_start_,load_size_,load_bias_)!=1){
951 | DL_ERR("load segments error");
952 | }else{
953 | DL_ERR("load segments success");
954 | }
955 | return 1;
956 | }
957 | static int VerifyElfHeader4_4(const char *name_,Elf32_Ehdr header_) {
958 | if (header_.e_ident[EI_MAG0] != ELFMAG0 ||
959 | header_.e_ident[EI_MAG1] != ELFMAG1 ||
960 | header_.e_ident[EI_MAG2] != ELFMAG2 ||
961 | header_.e_ident[EI_MAG3] != ELFMAG3) {
962 | DL_ERR("\"%s\" has bad ELF magic", name_);
963 | return -1;
964 | }
965 |
966 | if (header_.e_ident[EI_CLASS] != ELFCLASS32) {
967 | DL_ERR("\"%s\" not 32-bit: %d", name_, header_.e_ident[EI_CLASS]);
968 | return -1;
969 | }
970 | if (header_.e_ident[EI_DATA] != ELFDATA2LSB) {
971 | DL_ERR("\"%s\" not little-endian: %d", name_, header_.e_ident[EI_DATA]);
972 | return -1;
973 | }
974 |
975 | if (header_.e_type != ET_DYN) {
976 | DL_ERR("\"%s\" has unexpected e_type: %d", name_, header_.e_type);
977 | return -1;
978 | }
979 |
980 | if (header_.e_version != EV_CURRENT) {
981 | DL_ERR("\"%s\" has unexpected e_version: %d", name_, header_.e_version);
982 | return -1;
983 | }
984 |
985 | if (header_.e_machine !=
986 | EM_ARM
987 | ) {
988 | DL_ERR("\"%s\" has unexpected e_machine: %d", name_, header_.e_machine);
989 | return -1;
990 | }
991 | DL_ERR("verify elf success");
992 | return 1;
993 | }
994 | static int ReadProgramHeader4_4(int fd_, const char *name_,Elf32_Ehdr header_,size_t phdr_num_){
995 | Elf32_Addr phdr_size_;
996 | Elf32_Phdr* phdr_table_;
997 | if (phdr_num_ < 1 || phdr_num_ > 65536/sizeof(Elf32_Phdr)) {
998 | DL_ERR("\"%s\" has invalid e_phnum: %d", name_, phdr_num_);
999 | return -1;
1000 | }
1001 | Elf32_Addr page_min = PAGE_START(header_.e_phoff);
1002 | Elf32_Addr page_max = PAGE_END(header_.e_phoff + (phdr_num_ * sizeof(Elf32_Phdr)));
1003 | Elf32_Addr page_offset = PAGE_OFFSET(header_.e_phoff);
1004 | DL_ERR("page_min --->>>%08x,page_max --->>>%08x",page_min,page_max);
1005 | phdr_size_ = page_max - page_min;
1006 | DL_ERR("phdr_size_ --->>>%08x",phdr_size_);
1007 | void* mmap_result = mmap(NULL, phdr_size_, PROT_READ, MAP_PRIVATE, fd_, page_min);
1008 | if (mmap_result == MAP_FAILED) {
1009 | DL_ERR("\"%s\" phdr mmap failed: %s", name_, strerror(errno));
1010 | return -1;
1011 | }
1012 | if(VerifyElfHeader4_4(name_,header_)!=1){
1013 | DL_ERR("verify elf fail");
1014 | return -1;
1015 | }
1016 | phdr_table_ = (Elf32_Phdr*)((char*)mmap_result + page_offset);
1017 | if(ReserveAddressSpace4_4(fd_,name_,phdr_table_,phdr_num_)==-1){
1018 | DL_ERR("reserve address fail");
1019 | return -1;
1020 | }
1021 | return 1;
1022 |
1023 | }
1024 | static int ReadElfHeader4_4(int fd_,const char *name_) {
1025 | Elf32_Ehdr header_;
1026 |
1027 | size_t phdr_num_;
1028 | ssize_t rc = TEMP_FAILURE_RETRY(read(fd_, &header_, sizeof(header_)));
1029 | phdr_num_ = header_.e_phnum;
1030 | DL_ERR("\"%s\" is e_phnum: %d", name_, phdr_num_);
1031 | if (rc < 0) {
1032 | DL_ERR("can't read file \"%s\": %s", name_, strerror(errno));
1033 | return -1;
1034 | }
1035 | if (rc != sizeof(header_)) {
1036 | DL_ERR("\"%s\" is too small to be an ELF executable", name_);
1037 | return -1;
1038 | }
1039 | if(ReadProgramHeader4_4(fd_,name_,header_,phdr_num_)==1){
1040 | DL_ERR("success1 %08x",phdr_num_);
1041 | }else{
1042 | DL_ERR("fail1 %08x",phdr_num_);
1043 | }
1044 | return 1;
1045 | }
1046 |
1047 | static soinfo4_4 *load_library4_4(const char *name){
1048 |
1049 | int fd = open_library(name);
1050 | if(ReadElfHeader4_4(fd,name)==1){
1051 | DL_ERR("success");
1052 |
1053 | }else{
1054 | DL_ERR("fail");
1055 | }
1056 |
1057 |
1058 | return soinfos;
1059 | }
1060 | #define likely4_4(expr) __builtin_expect (expr, 1)
1061 | #define unlikely4_4(expr) __builtin_expect (expr, 0)
1062 | void *lookup_in_library4_4(soinfo4_4 *si, const char *name)
1063 | {
1064 | soinfo4_4 *found;
1065 | Elf32_Sym *sym;
1066 | unsigned bind;
1067 | found=si;
1068 | sym=soinfo_elf_lookup4_4(si, elfhash4_4(name), name);
1069 | if(likely4_4(sym != 0)) {
1070 | bind = ELF32_ST_BIND(sym->st_info);
1071 | if(likely4_4((bind == STB_GLOBAL) && (sym->st_shndx != 0))) {
1072 | unsigned ret = sym->st_value + found->base;
1073 | return (void*)ret;
1074 | }
1075 | }
1076 | return NULL;
1077 | }
1078 | static void call_constructors_array4_4(unsigned *ctor, int count, int reverse)
1079 | {
1080 | int n, inc = 1;
1081 |
1082 | if (reverse) {
1083 | ctor += (count-1);
1084 | inc = -1;
1085 | }
1086 |
1087 | for(n = count; n > 0; n--) {
1088 | DL_ERR("[ %5d Looking at %s *0x%08x == 0x%08x ]\n", pid,
1089 | reverse ? "dtor" : "ctor",
1090 | (unsigned)ctor, (unsigned)*ctor);
1091 | void (*func)() = (void (*)()) *ctor;
1092 | ctor += inc;
1093 | if(((int) func == 0) || ((int) func == -1)) continue;
1094 | DL_ERR("[ %5d Calling func @ 0x%08x ]\n", pid, (unsigned)func);
1095 | func();
1096 | DL_ERR(" func %s",strerror(errno));
1097 | }
1098 | }
1099 |
1100 | void init_constructors4_4(soinfo4_4 *si)
1101 | {
1102 | if (si->constructors_called)
1103 | return;
1104 | DL_ERR("init");
1105 | si->constructors_called = 1;
1106 |
1107 | if (si->flags & FLAG_EXE) {
1108 | DL_ERR("[ ------%5d Calling preinit_array @ 0x%08x [%d] for '%s' ]\n",
1109 | pid, (unsigned)si->preinit_array, si->preinit_array_count,
1110 | si->name);
1111 | call_constructors_array4_4(si->preinit_array, si->preinit_array_count, 0);
1112 | DL_ERR("[ -------%5d Done calling preinit_array for '%s' ]\n", pid, si->name);
1113 | } else {
1114 | if (si->preinit_array) {
1115 | DL_ERR("--------%5d Shared library '%s' has a preinit_array table @ 0x%08x."
1116 | " This is INVALID.", pid, si->name,
1117 | (unsigned)si->preinit_array);
1118 | }
1119 | }
1120 |
1121 | if (si->init_func) {
1122 | DL_ERR("[--------%5d Calling init_func @ 0x%08x for '%s' ]\n", pid,
1123 | (unsigned)si->init_func, si->name);
1124 | si->init_func();
1125 | DL_ERR("[ --------%5d Done calling init_func for '%s' ]\n", pid, si->name);
1126 | }
1127 |
1128 | if (si->init_array) {
1129 | DL_ERR("[ -------%5d Calling init_array @ 0x%08x [%d] for '%s' ]\n", pid,
1130 | (unsigned)si->init_array, si->init_array_count, si->name);
1131 | call_constructors_array4_4(si->init_array, si->init_array_count, 0);
1132 | DL_ERR("[ --------%5d Done calling init_array for '%s' ]\n", pid, si->name);
1133 | }
1134 |
1135 | }
1136 | soinfo4_4* find_library_internal4_4(const char* name) {
1137 | soinfo4_4 *soinfo4_4=load_library4_4(name);
1138 | if (soinfo4_4 == NULL) {
1139 | return NULL;
1140 | }
1141 | DL_ERR("[ init_library base=0x%08x sz=0x%08x name='%s' ]",
1142 | soinfo4_4->base, soinfo4_4->size, soinfo4_4->name);
1143 | if (soinfo_link_image4_4(soinfo4_4)!=1) {
1144 | munmap((void*)(soinfo4_4->base), soinfo4_4->size);
1145 | free_info4_4(soinfo4_4);
1146 | return NULL;
1147 | }
1148 | if(soinfo4_4!=NULL){
1149 | init_constructors4_4(soinfo4_4);
1150 | }
1151 | DL_ERR("LINK IMAGE SUCCESS");
1152 | return soinfo4_4;
1153 | }
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/linker4_4.h:
--------------------------------------------------------------------------------
1 | #ifndef _LINKER4_4_H_
2 | #define _LINKER4_4_H_
3 | #include
4 | #include
5 | #include "elf.h"
6 | #include "exec_elf.h"
7 | #include "auxvec.h"
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include "public.h"
19 | #include "elf_arm_const.h"
20 | //#define PAGE_SHIFT 12
21 | //#define PAGE_Y_SIZE (1UL << PAGE_SHIFT)
22 | //#define PAGE_Y_MASK (~(PAGE_Y_SIZE-1))
23 | #define PAGE_START(x) ((x) & PAGE_MASK)
24 | #define PAGE_OFFSET(x) ((x) & ~PAGE_MASK)
25 | #define PAGE_END(x) PAGE_START((x) + (PAGE_SIZE-1))
26 | #ifdef __LP64__
27 | typedef long intptr_t;
28 | typedef unsigned long uintptr_t;
29 | #else
30 | typedef int intptr_t;
31 | typedef unsigned int uintptr_t;
32 | #endif
33 | typedef struct soinfo4_4 soinfo4_4;
34 | struct link_map_4_4_t {
35 | uintptr_t l_addr;
36 | char* l_name;
37 | uintptr_t l_ld;
38 | struct link_map_4_4_t* l_next;
39 | struct link_map_4_4_t* l_prev;
40 | };
41 | void* start_page_address4_4;
42 | Elf32_Addr start_page_filelength4_4;
43 | #define ANDROID_ARM_LINKER "arm"
44 | typedef void (*linker_function4_4_t)();
45 | struct soinfo4_4 {
46 | char name[SOINFO_NAME_LEN];
47 | const Elf32_Phdr* phdr;
48 | size_t phnum;
49 | Elf32_Addr entry;
50 | Elf32_Addr base;
51 | unsigned size;
52 |
53 | uint32_t unused1;
54 |
55 | Elf32_Dyn* dynamic;
56 |
57 | uint32_t unused2;
58 | uint32_t unused3;
59 |
60 | soinfo4_4* next;
61 | unsigned flags;
62 |
63 | const char* strtab;
64 | Elf32_Sym* symtab;
65 |
66 | size_t nbucket;
67 | size_t nchain;
68 | unsigned* bucket;
69 | unsigned* chain;
70 |
71 | unsigned* plt_got;
72 |
73 | Elf32_Rel* plt_rel;
74 | size_t plt_rel_count;
75 |
76 | Elf32_Rel* rel;
77 | size_t rel_count;
78 |
79 | linker_function4_4_t* preinit_array;
80 | size_t preinit_array_count;
81 |
82 | linker_function4_4_t* init_array;
83 | size_t init_array_count;
84 | linker_function4_4_t* fini_array;
85 | size_t fini_array_count;
86 |
87 | linker_function4_4_t init_func;
88 | linker_function4_4_t fini_func;
89 | #if defined(ANDROID_ARM_LINKER)
90 | // ARM EABI section used for stack unwinding.
91 | unsigned* ARM_exidx;
92 | size_t ARM_exidx_count;
93 | #elif defined(ANDROID_MIPS_LINKER)
94 | unsigned mips_symtabno;
95 | unsigned mips_local_gotno;
96 | unsigned mips_gotsym;
97 | #endif
98 |
99 | size_t ref_count;
100 | struct link_map_4_4_t link_map;
101 |
102 | unsigned char constructors_called;
103 | Elf32_Addr load_bias;
104 | unsigned char has_text_relocations;
105 | unsigned char has_DT_SYMBOLIC;
106 | };
107 | soinfo4_4* find_library_internal4_4(const char* name);
108 | void *lookup_in_library4_4(soinfo4_4 *si, const char *name);
109 | #endif
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/linker7_0.h:
--------------------------------------------------------------------------------
1 | #ifndef _LINKER7_0_H_
2 | #define _LINKER7_0_H_
3 | #include
4 | #include
5 | #include "elf.h"
6 | #include "exec_elf.h"
7 | #include "auxvec.h"
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include "public.h"
19 |
20 | #define PAGE_S_SIZE 4096
21 | #define PAGE_S_MASK (~(PAGE_S_SIZE-1))
22 |
23 | // Returns the address of the page containing address 'x'.
24 | #define PAGE_S_START(x) ((x) & PAGE_S_MASK)
25 |
26 | #define PAGE_S_OFFSET(x) ((x) & ~PAGE_S_MASK)
27 |
28 | #define PAGE_S_END(x) PAGE_S_START((x) + (PAGE_S_SIZE-1))
29 | #ifndef __cplusplus
30 | #define alignas _Alignas
31 | #define alignof _Alignof
32 | #endif
33 | #if __LP64__
34 | #define ElfW(type) Elf64_ ## type
35 | #else
36 | #define ElfW(type) Elf32_ ## type
37 | #endif
38 |
39 | #ifdef __LP64__
40 | typedef long intptr_t;
41 | typedef unsigned long uintptr_t;
42 | #else
43 | typedef int intptr_t;
44 | typedef unsigned int uintptr_t;
45 | #endif
46 |
47 | void* start_page_address7_0;
48 | Elf32_Addr start_page_filelength7_0;
49 | typedef struct soinfo7_0 soinfo7_0;
50 | struct link_map_t7_0 {
51 | uintptr_t l_addr;
52 | char* l_name;
53 | uintptr_t l_ld;
54 | struct link_map_t7_0* l_next;
55 | struct link_map_t7_0* l_prev;
56 | };
57 |
58 | typedef void (*linker_function_t7_0)();
59 | struct soinfo7_0 {
60 | char name[SOINFO_NAME_LEN];
61 | const Elf32_Phdr* phdr;
62 | size_t phnum;
63 | Elf32_Addr entry;
64 | Elf32_Addr base;
65 | unsigned size;
66 |
67 | uint32_t unused1;
68 |
69 | Elf32_Dyn* dynamic;
70 |
71 | uint32_t unused2;
72 | uint32_t unused3;
73 |
74 | soinfo7_0* next;
75 | unsigned flags;
76 |
77 | const char* strtab;
78 | Elf32_Sym* symtab;
79 |
80 | size_t nbucket;
81 | size_t nchain;
82 | unsigned* bucket;
83 | unsigned* chain;
84 |
85 | unsigned* plt_got;
86 |
87 | Elf32_Rel* plt_rel;
88 | size_t plt_rel_count;
89 |
90 | Elf32_Rel* rel;
91 | size_t rel_count;
92 |
93 | linker_function_t7_0* preinit_array;
94 | size_t preinit_array_count;
95 |
96 | linker_function_t7_0* init_array;
97 | size_t init_array_count;
98 | linker_function_t7_0* fini_array;
99 | size_t fini_array_count;
100 |
101 | linker_function_t7_0 init_func;
102 | linker_function_t7_0 fini_func;
103 | #if defined(ANDROID_ARM_LINKER)
104 | // ARM EABI section used for stack unwinding.
105 | unsigned* ARM_exidx;
106 | size_t ARM_exidx_count;
107 | #elif defined(ANDROID_MIPS_LINKER)
108 | unsigned mips_symtabno;
109 | unsigned mips_local_gotno;
110 | unsigned mips_gotsym;
111 | #endif
112 |
113 | size_t ref_count_;
114 | struct link_map_t7_0 link_map_head;
115 |
116 | unsigned char constructors_called;
117 | Elf32_Addr load_bias;
118 | unsigned char has_text_relocations;
119 | unsigned char has_DT_SYMBOLIC;
120 | size_t strtab_size_;
121 | };
122 | static const char ANDROID_LIBDL_STRTAB1[] =
123 | // 0000000 00011111 111112 22222222 2333333 3333444444444455555555556666666 6667777777777888888888899999 99999
124 | // 0123456 78901234 567890 12345678 9012345 6789012345678901234567890123456 7890123456789012345678901234 56789
125 | "dlopen\0dlclose\0dlsym\0dlerror\0dladdr\0android_update_LD_LIBRARY_PATH\0android_get_LD_LIBRARY_PATH\0dl_it"
126 | // 00000000001 1111111112222222222 3333333333444444444455555555556666666666777 777777788888888889999999999
127 | // 01234567890 1234567890123456789 0123456789012345678901234567890123456789012 345678901234567890123456789
128 | "erate_phdr\0android_dlopen_ext\0android_set_application_target_sdk_version\0android_get_application_tar"
129 | // 0000000000111111 111122222222223333333333 4444444444555555555566666 6666677 777777778888888888
130 | // 0123456789012345 678901234567890123456789 0123456789012345678901234 5678901 234567890123456789
131 | "get_sdk_version\0android_init_namespaces\0android_create_namespace\0dlvsym\0android_dlwarning\0"
132 | #if defined(__arm__)
133 | // 290
134 | "dl_unwind_find_exidx\0"
135 | #endif
136 | ;
137 | static unsigned g_libdl_buckets1[1] = { 1 };
138 | #if defined(__arm__)
139 | static unsigned g_libdl_chains1[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0 };
140 | #else
141 | static unsigned g_libdl_chains[] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0 };
142 | #endif
143 |
144 |
145 |
146 |
147 |
148 | soinfo7_0* find_library_internal7_0(const char* name);
149 | void *lookup_in_library7_0(soinfo7_0 *si, const char *name);
150 | #endif
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/native-lib.c:
--------------------------------------------------------------------------------
1 | #include "linker7_0.h"
2 | #include "linker4_4.h"
3 | #include "XorUtils.h"
4 | #include
5 | #include
6 |
7 |
8 | static void fix_cmdline(char *buf) {
9 | int length = strlen(buf);
10 |
11 | DL_ERR("length=%d", length);
12 |
13 | //TODO fix :remote bug
14 | while (length > -1) {
15 | if (buf[length] == ':') {
16 | buf[length] = '\0';
17 | break;
18 | }
19 | length--;
20 | }
21 |
22 | }
23 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
24 |
25 |
26 | char buf[200];
27 |
28 | FILE *fp;
29 | int pid = getpid();
30 | sprintf(buf,"/proc/%d/cmdline", pid);
31 | fp = fopen(buf, "r");
32 | if(fp == NULL)
33 | {
34 | DL_ERR("Open error!!");
35 | }
36 |
37 | while(fgets(buf, sizeof(buf), fp)){
38 | DL_ERR("cmdline=%s", buf);
39 | fix_cmdline(buf);
40 | DL_ERR("cmdline=%s", buf);
41 | }
42 | fclose(fp);
43 |
44 | char desFile[400];
45 | sprintf(desFile, "/data/data/%s/lib/libdata.so", buf);
46 | DL_ERR("open file is %s", desFile);
47 | // jint (*real_JNI_OnLoad)(JavaVM*, void*);
48 | // real_JNI_OnLoad = (jint (*)(JavaVM*, void*))(gbdlsym(si,"JNI_OnLoad"));
49 | // if(real_JNI_OnLoad == NULL){
50 | // DL_ERR("cannot find sym %s\n", "JNI_OnLoad");
51 | // }
52 | // return real_JNI_OnLoad(vm, reserved);
53 | //4.1.2 end
54 |
55 | __system_property_get("ro.build.version.sdk", buf);
56 | int version = 0;
57 | sscanf(buf, "%d", &version);
58 | if (version < 24) {
59 | //4.4 start
60 | soinfo4_4 *soinfo4_4 = find_library_internal4_4(desFile);
61 | if (soinfo4_4 == NULL) {
62 | DL_ERR("find soinfo fail");
63 | return JNI_VERSION_1_4;
64 | }
65 | DL_ERR("find soinfo success");
66 |
67 | xor_code(soinfo4_4->base,start_page_address4_4,start_page_filelength4_4);
68 | jint (*real_JNI_OnLoad4_4)(JavaVM *, void *);
69 | real_JNI_OnLoad4_4 = (jint (*)(JavaVM *, void *)) (lookup_in_library4_4(soinfo4_4,
70 | "JNI_OnLoad"));
71 | if (real_JNI_OnLoad4_4 == NULL) {
72 | DL_ERR("cannot find sym %s\n", "JNI_OnLoad");
73 | } else {
74 | return real_JNI_OnLoad4_4(vm, reserved);
75 | }
76 | //4.4 end
77 | } else {
78 | soinfo7_0 *soinfo7_0 = find_library_internal7_0(desFile);
79 | if (soinfo7_0 == NULL) {
80 | DL_ERR("find soinfo fail");
81 | return JNI_VERSION_1_4;
82 | }
83 | DL_ERR("find soinfo success");
84 | xor_code(soinfo7_0->base,start_page_address7_0,start_page_filelength7_0);
85 | jint (*real_JNI_OnLoad7_0)(JavaVM *, void *);
86 | real_JNI_OnLoad7_0 = (jint (*)(JavaVM *, void *)) (lookup_in_library7_0(soinfo7_0,
87 | "JNI_OnLoad"));
88 | if (real_JNI_OnLoad7_0 == NULL) {
89 | DL_ERR("cannot find sym %s\n", "JNI_OnLoad");
90 | } else {
91 | return real_JNI_OnLoad7_0(vm, reserved);
92 | }
93 | //7.0 end
94 | }
95 | return JNI_VERSION_1_4;
96 | }
97 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/public.h:
--------------------------------------------------------------------------------
1 | //
2 | // public.h
3 | // goblin4.4.2
4 | //
5 | // Created by liu meng on 2018/2/26.
6 | // Copyright © 2018年 com.qunar. All rights reserved.
7 | //
8 |
9 | #ifndef public_h
10 | #define public_h
11 | #define FLAG_LINKED 0x00000001
12 | #define FLAG_ERROR 0x00000002
13 | #define FLAG_EXE 0x00000004 // The main executable
14 | #define FLAG_LINKER 0x00000010 // The linker itself
15 | #include
16 | #define LOG_TAG "liumeng"
17 | #define SOINFO_NAME_LEN 128
18 | enum RelocationKind {
19 | kRelocAbsolute = 0,
20 | kRelocRelative,
21 | kRelocCopy,
22 | kRelocSymbol,
23 | kRelocMax
24 | };
25 | #define MARK(x) do {} while (0)
26 | #define MAYBE_MAP_FLAG(x,from,to) (((x) & (from)) ? (to) : 0)
27 | #define PFLAGS_TO_PROT(x) (MAYBE_MAP_FLAG((x), PF_X, PROT_EXEC) | \
28 | MAYBE_MAP_FLAG((x), PF_R, PROT_READ) | \
29 | MAYBE_MAP_FLAG((x), PF_W, PROT_WRITE))
30 | #if STATS
31 | struct linker_stats_t {
32 | int count[kRelocMax];
33 | };
34 |
35 | static linker_stats_t linker_stats;
36 |
37 | static void count_relocation(RelocationKind kind) {
38 | ++linker_stats.count[kind];
39 | }
40 | #else
41 | static void count_relocation(RelocationKind) {
42 | }
43 | #endif
44 |
45 | enum {
46 | RT_CONSISTENT,
47 | RT_ADD,
48 | RT_DELETE
49 | };
50 | #ifdef ANDROID_ARM_LINKER
51 |
52 | #define R_ARM_COPY 20
53 | #define R_ARM_GLOB_DAT 21
54 | #define R_ARM_JUMP_SLOT 22
55 | #define R_ARM_RELATIVE 23
56 |
57 | /* According to the AAPCS specification, we only
58 | * need the above relocations. However, in practice,
59 | * the following ones turn up from time to time.
60 | */
61 | #define R_ARM_ABS32 2
62 | #define R_ARM_REL32 3
63 |
64 | #elif defined(ANDROID_X86_LINKER)
65 |
66 | #define R_386_32 1
67 | #define R_386_PC32 2
68 | #define R_386_GLOB_DAT 6
69 | #define R_386_JUMP_SLOT 7
70 | #define R_386_RELATIVE 8
71 |
72 | #endif
73 |
74 | #ifndef DT_INIT_ARRAY
75 | #define DT_INIT_ARRAY 25
76 | #endif
77 |
78 | #ifndef DT_FINI_ARRAY
79 | #define DT_FINI_ARRAY 26
80 | #endif
81 |
82 | #ifndef DT_INIT_ARRAYSZ
83 | #define DT_INIT_ARRAYSZ 27
84 | #endif
85 |
86 | #ifndef DT_FINI_ARRAYSZ
87 | #define DT_FINI_ARRAYSZ 28
88 | #endif
89 |
90 | #ifndef DT_PREINIT_ARRAY
91 | #define DT_PREINIT_ARRAY 32
92 | #endif
93 |
94 | #ifndef DT_PREINIT_ARRAYSZ
95 | #define DT_PREINIT_ARRAYSZ 33
96 | #endif
97 | #define format_buffer(b, s, f, p...) sprintf(b, f, p);
98 | static const char *sopaths[] = {
99 | "/vendor/lib",
100 | "/system/lib",
101 | 0
102 | };
103 | static int _open_lib(const char *name)
104 | {
105 | int fd;
106 | struct stat filestat;
107 |
108 | if ((stat(name, &filestat) >= 0) && S_ISREG(filestat.st_mode)) {
109 | if ((fd = open(name,O_RDONLY | O_CLOEXEC)) >= 0)
110 | return fd;
111 | }
112 |
113 | return -1;
114 | }
115 |
116 | static int open_library(const char *name)
117 | {
118 | int fd;
119 | char buf[512];
120 | const char **path;
121 | int n;
122 | if(name == 0) return -1;
123 | if(strlen(name) > 256) return -1;
124 |
125 | if ((name[0] == '/') && ((fd = _open_lib(name)) >= 0))
126 | return fd;
127 |
128 |
129 | for (path = sopaths; *path; path++) {
130 | n = format_buffer(buf, sizeof(buf), "%s/%s", *path, name);
131 | if (n < 0 || n >= (int)sizeof(buf)) {
132 | continue;
133 | }
134 | if ((fd = _open_lib(buf)) >= 0)
135 | return fd;
136 | }
137 |
138 | return -1;
139 | }
140 |
141 | #define DL_ERR(fmt, args...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,fmt, ##args)
142 | #define DEBUG(fmt, args...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,fmt, ##args)
143 | #define INFO(fmt, args...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,fmt, ##args)
144 |
145 | #endif /* public_h */
146 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/sys_dlopen.h:
--------------------------------------------------------------------------------
1 | #ifndef _SYS_DLOPEN_H_
2 | #define _SYS_DLOPEN_H_
3 | #include
4 | #include
5 | #include "linker7_0.h"
6 | #define SO_MAX 128
7 | static int socount7_0 = 0;
8 | static soinfo7_0 sopool7_0[SO_MAX];
9 | static soinfo7_0 *freelist7_0 = NULL;
10 | static off64_t kPageMasks = ~(PAGE_S_SIZE-1);
11 | static off64_t page_s_start(off64_t offset) {
12 | return offset & kPageMasks;
13 | }
14 | static size_t page_s_offset(off64_t offset) {
15 | return (size_t)(offset & (PAGE_S_SIZE-1));
16 | }
17 | static int safe_s_add(off64_t* out, off64_t a, size_t b) {
18 | if ((uint64_t)(INT64_MAX - a) < b) {
19 | return 0;
20 | }
21 | *out = a + b;
22 | return 1;
23 | }
24 | /**
25 | * 计算so的内存最大地址和最小地址
26 | * @param phdr_table
27 | * @param phdr_count
28 | * @param out_min_vaddr
29 | * @return
30 | */
31 | static size_t sys_phdr_table_size(const ElfW(Phdr)* phdr_table, size_t phdr_count,ElfW(Addr)* out_min_vaddr) {
32 | ElfW(Addr) min_vaddr = UINTPTR_MAX;
33 | ElfW(Addr) max_vaddr = 0;
34 | int i;
35 | int found_pt_load = 0;
36 | for (i=0; i < phdr_count; ++i) {
37 | const ElfW(Phdr)* phdr = &phdr_table[i];
38 |
39 | if (phdr->p_type != PT_LOAD) {
40 | continue;
41 | }
42 | found_pt_load = 1;
43 |
44 | if (phdr->p_vaddr < min_vaddr) {
45 | min_vaddr = phdr->p_vaddr;
46 | }
47 |
48 | if (phdr->p_vaddr + phdr->p_memsz > max_vaddr) {
49 | max_vaddr = phdr->p_vaddr + phdr->p_memsz;
50 | }
51 | }
52 | if (!found_pt_load) {
53 | min_vaddr = 0;
54 | }
55 | if (out_min_vaddr != NULL) {
56 | *out_min_vaddr = min_vaddr;
57 | }
58 | min_vaddr = PAGE_S_START(min_vaddr);
59 | max_vaddr = PAGE_S_END(max_vaddr);
60 | return max_vaddr - min_vaddr;
61 | }
62 | /**
63 | * 获取so的基地址
64 | * @param name
65 | * @param first
66 | * @return
67 | */
68 | static unsigned long get_sys_address(const char *name,unsigned long first){
69 | char *lpCh = NULL;
70 | char szLines[1024] = {0};
71 | unsigned long start = 0;
72 | unsigned long tmp=0;
73 | FILE *fp = fopen("/proc/self/maps", "r");
74 |
75 | if (fp != NULL)
76 | {
77 | while (fgets(szLines, sizeof(szLines), fp))
78 | {
79 | if (strstr(szLines,name)&&strstr(szLines,"r-xp"))
80 | {
81 |
82 | DL_ERR("Find=%s",szLines);
83 | lpCh = strtok(szLines, "-");
84 | tmp=strtoul(lpCh, NULL, 16);
85 | if((start> tmp|| start ==0 )){
86 | start=strtoul(lpCh, NULL, 16);
87 | }
88 |
89 | }
90 | }
91 | fclose(fp);
92 | return start;
93 | }
94 | else
95 | {
96 | DL_ERR("fopen error\r\n");
97 | }
98 | return -1;
99 |
100 | }
101 | /**
102 | * 获取dynamic段
103 | * @param phdr_table
104 | * @param phdr_count
105 | * @param load_bias
106 | * @param dynamic
107 | * @param dynamic_count
108 | * @param dynamic_flags
109 | */
110 | static void sys_phdr_dynamic(const Elf32_Phdr* phdr_table,
111 | int phdr_count,
112 | Elf32_Addr load_bias,
113 | Elf32_Dyn** dynamic,
114 | size_t* dynamic_count,
115 | Elf32_Word* dynamic_flags)
116 | {
117 | const Elf32_Phdr* phdr = phdr_table;
118 | const Elf32_Phdr* phdr_limit = phdr + phdr_count;
119 |
120 | for (phdr = phdr_table; phdr < phdr_limit; phdr++) {
121 | if (phdr->p_type != PT_DYNAMIC) {
122 | continue;
123 | }
124 | *dynamic = (Elf32_Dyn*)(load_bias + phdr->p_vaddr);
125 | if (dynamic_count) {
126 | *dynamic_count = (unsigned)(phdr->p_memsz / 8);
127 | }
128 | if (dynamic_flags) {
129 | *dynamic_flags = phdr->p_flags;
130 | }
131 | return;
132 | }
133 | *dynamic = NULL;
134 | if (dynamic_count) {
135 | *dynamic_count = 0;
136 | }
137 | }
138 | /**
139 | * 检测物理段结构体
140 | * @param loaded
141 | * @param fd_
142 | * @param name_
143 | * @param phdr_table_
144 | * @param phdr_num_
145 | * @param load_bias_
146 | * @return
147 | */
148 | static Elf32_Phdr* sys_check_phdr( Elf32_Addr loaded,int fd_,const char *name_,const Elf32_Phdr* phdr_table_,size_t phdr_num_,Elf32_Addr load_bias_) {
149 | Elf32_Phdr* loaded_phdr_;
150 | const Elf32_Phdr* phdr;
151 | const Elf32_Phdr* phdr_limit = phdr_table_ + phdr_num_;
152 | Elf32_Addr loaded_end = loaded + (phdr_num_ * sizeof(Elf32_Phdr));
153 | for ( phdr= phdr_table_; phdr < phdr_limit; ++phdr) {
154 | if (phdr->p_type != PT_LOAD) {
155 | continue;
156 | }
157 | Elf32_Addr seg_start = phdr->p_vaddr + load_bias_;
158 | Elf32_Addr seg_end = phdr->p_filesz + seg_start;
159 | if (seg_start <= loaded && loaded_end <= seg_end) {
160 | loaded_phdr_ =(Elf32_Phdr*)loaded;
161 | return loaded_phdr_;
162 | }
163 | }
164 | DL_ERR("\"%s\" loaded phdr %x not in loadable segment", name_, loaded);
165 | return NULL;
166 | }
167 |
168 | /**
169 | * 获取物理段
170 | * @param fd_
171 | * @param name_
172 | * @param phdr_table_
173 | * @param phdr_num_
174 | * @param load_bias_
175 | * @return
176 | */
177 | static Elf32_Phdr* sys_find_phdr(int fd_,const char *name_,const Elf32_Phdr* phdr_table_,size_t phdr_num_,Elf32_Addr load_bias_) {
178 | const Elf32_Phdr* phdr_limit = phdr_table_ + phdr_num_;
179 | const Elf32_Phdr* phdr;
180 | for ( phdr= phdr_table_; phdr < phdr_limit; ++phdr) {
181 | if (phdr->p_type == PT_PHDR) {
182 | return sys_check_phdr(load_bias_ + phdr->p_vaddr,fd_,name_,phdr_table_,phdr_num_,load_bias_);
183 | }
184 | }
185 | for (phdr = phdr_table_; phdr < phdr_limit; ++phdr) {
186 | if (phdr->p_type == PT_LOAD) {
187 | if (phdr->p_offset == 0) {
188 | Elf32_Addr elf_addr = load_bias_ + phdr->p_vaddr;
189 | const Elf32_Ehdr* ehdr = (const Elf32_Ehdr*)(void*)elf_addr;
190 | Elf32_Addr offset = ehdr->e_phoff;
191 | return sys_check_phdr((Elf32_Addr)ehdr + offset,fd_,name_,phdr_table_,phdr_num_,load_bias_);
192 | }
193 | break;
194 | }
195 | }
196 |
197 | DL_ERR("can't find loaded phdr for \"%s\"", name_);
198 | return NULL;
199 | }
200 |
201 | /**
202 | * 创建soinfo结构体对象
203 | * @param name
204 | * @return
205 | */
206 | static soinfo7_0 *sys_alloc_info(const char *name)
207 | {
208 | soinfo7_0 *soinfo7_0=NULL;
209 |
210 | if(strlen(name) >= SOINFO_NAME_LEN) {
211 | DL_ERR("library name %s too long",name);
212 | return NULL;
213 | }
214 | if (!freelist7_0) {
215 | if(socount7_0 == SO_MAX) {
216 | DL_ERR("too many libraries when loading %s", name);
217 | return NULL;
218 | }
219 | freelist7_0 = sopool7_0 + socount7_0++;
220 | freelist7_0->next = NULL;
221 | }
222 |
223 | soinfo7_0 = freelist7_0;
224 | freelist7_0 = freelist7_0->next;
225 | DL_ERR("library name %s new ",name);
226 | memset(soinfo7_0, 0, sizeof(soinfo7_0));
227 |
228 | strlcpy((char*) soinfo7_0->name, name, sizeof(soinfo7_0->name));
229 |
230 | soinfo7_0->next = NULL;
231 | return soinfo7_0;
232 | }
233 | /**
234 | * 释放soinfo对象
235 | * @param si
236 | */
237 | static void sys_free_info(soinfo7_0 *si)
238 | {
239 | si->next = freelist7_0;
240 | freelist7_0 = si;
241 | }
242 | /**
243 | * 装在PT_DYNAMIC结构体数据
244 | * @param si
245 | * @return
246 | */
247 | static int sys_link_image(soinfo7_0* si) {
248 | Elf32_Addr base = si->load_bias;
249 | const Elf32_Phdr *phdr = si->phdr;
250 | int phnum = si->phnum;
251 | int relocating_linker = (si->flags & FLAG_LINKER) ;
252 | if (!relocating_linker) {
253 | INFO("[ linking %s ]", si->name);
254 | DEBUG("si->base = 0x%08x si->flags = 0x%08x", si->base, si->flags);
255 | }
256 | size_t dynamic_count;
257 | Elf32_Word dynamic_flags;
258 | sys_phdr_dynamic(phdr, phnum, base, &si->dynamic,
259 | &dynamic_count, &dynamic_flags);
260 | if (si->dynamic == NULL) {
261 | if (!relocating_linker) {
262 | DL_ERR("missing PT_DYNAMIC in \"%s\"", si->name);
263 | }
264 | return -1;
265 | } else {
266 | if (!relocating_linker) {
267 | DEBUG("dynamic = %p", si->dynamic);
268 | }
269 | }
270 | #ifdef ANDROID_ARM_LINKER
271 | (void) phdr_table_get_arm_exidx4_4(phdr, phnum, base,
272 | &si->ARM_exidx, &si->ARM_exidx_count);
273 | #endif
274 | uint32_t needed_count = 0;
275 | Elf32_Dyn* d;
276 | for (d = si->dynamic; d->d_tag != DT_NULL; ++d) {
277 | DEBUG("d = %p, d[0](tag) = 0x%08x d[1](val) = 0x%08x", d, d->d_tag, d->d_un.d_val);
278 | switch(d->d_tag){
279 | case DT_HASH:
280 | si->nbucket = ((unsigned *) (base + d->d_un.d_ptr))[0];
281 | si->nchain = ((unsigned *) (base + d->d_un.d_ptr))[1];
282 | si->bucket = (unsigned *) (base + d->d_un.d_ptr + 8);
283 | si->chain = (unsigned *) (base + d->d_un.d_ptr + 8 + si->nbucket * 4);
284 | break;
285 | case DT_STRTAB:
286 | si->strtab = (const char *) (base + d->d_un.d_ptr);
287 | break;
288 | case DT_SYMTAB:
289 | si->symtab = (Elf32_Sym *) (base + d->d_un.d_ptr);
290 | break;
291 | case DT_PLTREL:
292 | if (d->d_un.d_val != DT_REL) {
293 | DL_ERR("unsupported DT_RELA in \"%s\"", si->name);
294 | return -1;
295 | }
296 | break;
297 | case DT_JMPREL:
298 | si->plt_rel = (Elf32_Rel*) (base + d->d_un.d_ptr);
299 | DL_ERR("plt_rel=%p",si->plt_rel);
300 | break;
301 | case DT_PLTRELSZ:
302 | si->plt_rel_count = d->d_un.d_val / sizeof(Elf32_Rel);
303 | DL_ERR("plt_rel_count=%08x",si->plt_rel_count);
304 | break;
305 | case DT_REL:
306 | si->rel = (Elf32_Rel*) (base + d->d_un.d_ptr);
307 | break;
308 | case DT_RELSZ:
309 | si->rel_count = d->d_un.d_val / sizeof(Elf32_Rel);
310 | break;
311 | case DT_PLTGOT:
312 | si->plt_got = (unsigned *)(base + d->d_un.d_ptr);
313 | break;
314 | case DT_DEBUG:
315 | break;
316 | case DT_RELA:
317 | DL_ERR("unsupported DT_RELA in \"%s\"", si->name);
318 | return -1;
319 | case DT_INIT:
320 | si->init_func = (void (*)(void))(base + d->d_un.d_ptr);
321 | DEBUG("%s constructors (DT_INIT) found at %p", si->name, si->init_func);
322 | break;
323 | case DT_FINI:
324 | si->fini_func = (void (*)(void))(base + d->d_un.d_ptr);
325 | DEBUG("%s destructors (DT_FINI) found at %p", si->name, si->fini_func);
326 | break;
327 | case DT_INIT_ARRAY:
328 | si->init_array = (unsigned *)(base + d->d_un.d_ptr);
329 | DEBUG("%s constructors (DT_INIT_ARRAY) found at %p", si->name, si->init_array);
330 | break;
331 | case DT_INIT_ARRAYSZ:
332 | si->init_array_count = ((unsigned)d->d_un.d_val) / sizeof(Elf32_Addr);
333 | break;
334 | case DT_FINI_ARRAY:
335 | si->fini_array = (unsigned *)(base + d->d_un.d_ptr);
336 | DEBUG("%s destructors (DT_FINI_ARRAY) found at %p", si->name, si->fini_array);
337 | break;
338 | case DT_FINI_ARRAYSZ:
339 | si->fini_array_count = ((unsigned)d->d_un.d_val) / sizeof(Elf32_Addr);
340 | break;
341 | case DT_PREINIT_ARRAY:
342 | si->preinit_array = (unsigned *)(base + d->d_un.d_ptr);
343 | DEBUG("%s constructors (DT_PREINIT_ARRAY) found at %p", si->name, si->preinit_array);
344 | break;
345 | case DT_PREINIT_ARRAYSZ:
346 | si->preinit_array_count = ((unsigned)d->d_un.d_val) / sizeof(Elf32_Addr);
347 | break;
348 | case DT_TEXTREL:
349 | si->has_text_relocations = 1;
350 | break;
351 | case DT_SYMBOLIC:
352 | si->has_DT_SYMBOLIC = 1;
353 | break;
354 | case DT_NEEDED:
355 | ++needed_count;
356 | break;
357 | #if defined DT_FLAGS
358 | // TODO: why is DT_FLAGS not defined?
359 | case DT_FLAGS:
360 | if (d->d_un.d_val & DF_TEXTREL) {
361 | si->has_text_relocations = 1;
362 | }
363 | if (d->d_un.d_val & DF_SYMBOLIC) {
364 | si->has_DT_SYMBOLIC = 1;
365 | }
366 | break;
367 | #endif
368 | #if defined(ANDROID_MIPS_LINKER)
369 | case DT_STRSZ:
370 | case DT_SYMENT:
371 | case DT_RELENT:
372 | break;
373 | case DT_MIPS_RLD_MAP:
374 | // Set the DT_MIPS_RLD_MAP entry to the address of _r_debug for GDB.
375 | {
376 | r_debug** dp = (r_debug**) d->d_un.d_ptr;
377 | *dp = &_r_debug;
378 | }
379 | break;
380 | case DT_MIPS_RLD_VERSION:
381 | case DT_MIPS_FLAGS:
382 | case DT_MIPS_BASE_ADDRESS:
383 | case DT_MIPS_UNREFEXTNO:
384 | break;
385 |
386 | case DT_MIPS_SYMTABNO:
387 | si->mips_symtabno = d->d_un.d_val;
388 | break;
389 |
390 | case DT_MIPS_LOCAL_GOTNO:
391 | si->mips_local_gotno = d->d_un.d_val;
392 | break;
393 |
394 | case DT_MIPS_GOTSYM:
395 | si->mips_gotsym = d->d_un.d_val;
396 | break;
397 |
398 | default:
399 | DEBUG("Unused DT entry: type 0x%08x arg 0x%08x", d->d_tag, d->d_un.d_val);
400 | break;
401 | #endif
402 | }
403 | }
404 |
405 | DEBUG("si->base = 0x%08x, si->strtab = %p, si->symtab = %p",
406 | si->base, si->strtab, si->symtab);
407 |
408 | // Sanity checks.
409 | if (relocating_linker && needed_count != 0) {
410 | DL_ERR("linker cannot have DT_NEEDED dependencies on other libraries");
411 | return -1;
412 | }
413 | if (si->nbucket == 0) {
414 | DL_ERR("empty/missing DT_HASH in \"%s\" (built with --hash-style=gnu?)", si->name);
415 | return -1;
416 | }
417 | if (si->strtab == 0) {
418 | DL_ERR("empty/missing DT_STRTAB in \"%s\"", si->name);
419 | return -1;
420 | }
421 | if (si->symtab == 0) {
422 | DL_ERR("empty/missing DT_SYMTAB in \"%s\"", si->name);
423 | return -1;
424 | }
425 |
426 |
427 |
428 | si->flags |= FLAG_LINKED;
429 |
430 | return 1;
431 | }
432 | /**
433 | * 获取so的根地址
434 | * @param fd_
435 | * @param name_
436 | * @param phdr_table_
437 | * @param phdr_num_
438 | * @param file_size_
439 | * @return
440 | */
441 | static soinfo7_0* sys_reserve_address_space(int fd_,const char* name_, const ElfW(Phdr)* phdr_table_,int phdr_num_,off64_t file_size_){
442 | ElfW(Addr) min_vaddr=NULL;
443 | void* start;
444 | ElfW(Addr) load_bias_=NULL;
445 | const Elf32_Phdr* loaded_phdr_;
446 | const char *bname;
447 | soinfo7_0 *soinfos = NULL;
448 | size_t load_size_ = sys_phdr_table_size(phdr_table_, phdr_num_, &min_vaddr);
449 | if (load_size_ == 0) {
450 | DL_ERR("%s has no loadable segments", name_);
451 | return NULL;
452 | }
453 | DL_ERR("%s get_sys_address", name_);
454 | uint8_t* addr = (uint8_t*)(min_vaddr);
455 | unsigned long address=get_sys_address(name_,-1);
456 | if(address==0){
457 | return NULL;
458 | }
459 | DL_ERR("soname---%s,address=%p",name_,address);
460 | start=(void*)address;
461 | load_bias_ = (uint8_t*)(start) - addr;
462 | loaded_phdr_=sys_find_phdr(fd_,name_,phdr_table_,phdr_num_,load_bias_);
463 | if(loaded_phdr_!=NULL){
464 | DL_ERR("findphdr success");
465 | bname = strrchr(name_, '/');
466 | DL_ERR("findphdr success %s",bname);
467 | soinfos = sys_alloc_info(bname ? bname + 1 : name_);
468 | if (soinfos == NULL){
469 | goto fail;
470 | }
471 | soinfos->flags = 0;
472 | soinfos->entry = 0;
473 | soinfos->dynamic =NULL;
474 | soinfos->phdr=loaded_phdr_;
475 | soinfos->load_bias=load_bias_;
476 | soinfos->phnum=phdr_num_;
477 | soinfos->base=(Elf32_Addr)start;
478 | soinfos->size=load_size_;
479 | DL_ERR("size---->>%08x",load_size_);
480 | if(sys_link_image(soinfos)==1){
481 | DL_ERR("soinfo_link_image7_0 success");
482 | }
483 | close(fd_);
484 | return soinfos;
485 | fail:
486 | DL_ERR(" alloc_info4_4 fail ");
487 | close(fd_);
488 | }
489 | return soinfos;
490 | }
491 |
492 | /**
493 | * 获取so的物理段结构体
494 | * @param fd
495 | * @param name_
496 | * @param base_offset
497 | * @param elf_offset
498 | * @param size
499 | * @return
500 | */
501 | static ElfW(Phdr)* sys_phdr_map(int fd,const char *name_, off64_t base_offset, size_t elf_offset, size_t size) {
502 | off64_t offset;
503 | void* data_;
504 | ElfW(Phdr)* phdr_table_;
505 | safe_s_add(&offset, base_offset, elf_offset);
506 | off64_t page_min = page_s_start(offset);
507 | off64_t end_offset;
508 | safe_s_add(&end_offset, offset, size);
509 | safe_s_add(&end_offset, end_offset, page_s_offset(offset));
510 | size_t map_size = (size_t)(end_offset - page_min);
511 | uint8_t* map_start = (uint8_t*)(mmap64(NULL, map_size, PROT_READ, MAP_PRIVATE, fd, page_min));
512 | if (map_start == MAP_FAILED) {
513 | DL_ERR("%s phdr mmap PROT_READ failed: %s", name_, strerror(errno));
514 | return NULL;
515 | }
516 | data_ = map_start + page_s_offset(offset);
517 | phdr_table_ = (ElfW(Phdr)*) data_;
518 | return phdr_table_;
519 | }
520 |
521 |
522 | static int sys_get_target_elf_machine() {
523 | #if defined(__arm__)
524 | return EM_ARM;
525 | #elif defined(__aarch64__)
526 | return EM_AARCH64;
527 | #elif defined(__i386__)
528 | return EM_386;
529 | #elif defined(__mips__)
530 | return EM_MIPS;
531 | #elif defined(__x86_64__)
532 | return EM_X86_64;
533 | #endif
534 | }
535 | /**
536 | * 验证so文件的header
537 | * @param fd_
538 | * @param name_
539 | * @param header_
540 | * @param file_size_
541 | * @return
542 | */
543 | static soinfo7_0* sys_verify_elf_header(int fd_,const char *name_,Elf32_Ehdr header_,off64_t file_size_) {
544 | size_t phdr_num_;
545 | off64_t file_offset_=0;
546 |
547 | if (memcmp(header_.e_ident, ELFMAG, SELFMAG) != 0) {
548 | DL_ERR("\"%s\" has bad ELF magic", name_);
549 | return NULL;
550 | }
551 | int elf_class = header_.e_ident[EI_CLASS];
552 | if (elf_class != ELFCLASS32) {
553 | DL_ERR("\"%s\" is 64-bit instead of 32-bit %08x", name_,elf_class);
554 | return NULL;
555 | }
556 | if (header_.e_ident[EI_DATA] != ELFDATA2LSB) {
557 | DL_ERR("\"%s\" not little-endian: %d", name_, header_.e_ident[EI_DATA]);
558 | return NULL;
559 | }
560 |
561 | if (header_.e_type != ET_DYN) {
562 | DL_ERR("\"%s\" has unexpected e_type: %d", name_, header_.e_type);
563 | return NULL;
564 | }
565 |
566 | if (header_.e_version != EV_CURRENT) {
567 | DL_ERR("\"%s\" has unexpected e_version: %d", name_, header_.e_version);
568 | return NULL;
569 | }
570 |
571 | if (header_.e_machine != sys_get_target_elf_machine()) {
572 | DL_ERR("\"%s\" has unexpected e_machine: %d", name_, header_.e_machine);
573 | return NULL;
574 | }
575 | phdr_num_ = header_.e_phnum;
576 | size_t size = phdr_num_ * sizeof(ElfW(Phdr));
577 | if (phdr_num_ < 1 || phdr_num_ > 65536/sizeof(ElfW(Phdr))) {
578 | DL_ERR("\"%s\" has invalid e_phnum: %zd", name_, phdr_num_);
579 | return NULL;
580 | }
581 | const ElfW(Phdr)* phdr_table_=sys_phdr_map(fd_,name_,file_offset_, header_.e_phoff, size);
582 | if (phdr_table_==NULL) {
583 | DL_ERR("\"%s\" phdr mmap failed: %s", name_, strerror(errno));
584 | return NULL;
585 | }
586 | soinfo7_0 * soinfo7_0= sys_reserve_address_space(fd_,name_,phdr_table_,phdr_num_,file_size_);
587 | if(soinfo7_0==NULL){
588 | DL_ERR("\"%s\" ReserveAddressSpace7_0 failed: %s", name_, strerror(errno));
589 | }
590 |
591 | return soinfo7_0;
592 | }
593 | static soinfo7_0* sys_read_elf_header(int fd_,const char *name_, off64_t file_size) {
594 | Elf32_Ehdr header_;
595 | size_t phdr_num_;
596 | int n;
597 | off64_t off64=0;
598 | ssize_t rc = TEMP_FAILURE_RETRY(pread64(fd_, &header_, sizeof(header_),off64));
599 | if (rc < 0) {
600 | DL_ERR("can't read file \"%s\": %s", name_, strerror(errno));
601 | return NULL;
602 | }
603 | if (rc != sizeof(header_)) {
604 | DL_ERR("\"%s\" is too small to be an ELF executable", name_);
605 | return NULL;
606 | }
607 | soinfo7_0* soinfo=sys_verify_elf_header(fd_,name_,header_,file_size);
608 | if(soinfo!=NULL){
609 | DL_ERR("success1 %08x",phdr_num_);
610 | }else{
611 | DL_ERR("fail1 %08x",phdr_num_);
612 | }
613 | return soinfo;
614 | }
615 |
616 | static soinfo7_0 *sys_dlopen(const char *name){
617 | int fd = open_library(name);
618 | struct stat file_stat;
619 | unsigned long st_size;
620 |
621 | if (TEMP_FAILURE_RETRY(fstat(fd, &file_stat)) != 0) {
622 | DL_ERR("unable to stat file for the library \"%s\": %s", name, strerror(errno));
623 | return 0;
624 | }
625 | st_size=file_stat.st_size;
626 | soinfo7_0* soinfo=sys_read_elf_header(fd,name,st_size);
627 | if(soinfo!=NULL){
628 | DL_ERR("success");
629 | }else{
630 | DL_ERR("fail");
631 | }
632 | return soinfo;
633 | }
634 |
635 |
636 | #endif
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/cpp/types.h:
--------------------------------------------------------------------------------
1 | //
2 | // types.h
3 | // Goblin_Shell_4.1.2
4 | //
5 | // Created by liu meng on 2018/1/30.
6 | // Copyright © 2018年 com.qunar. All rights reserved.
7 | //
8 |
9 |
10 | typedef unsigned short umode_t;
11 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
12 | typedef __signed__ char __s8;
13 | typedef unsigned char __u8;
14 | typedef __signed__ short __s16;
15 | typedef unsigned short __u16;
16 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
17 | typedef __signed__ int __s32;
18 | typedef unsigned int __u32;
19 | typedef __signed__ long long __s64;
20 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
21 | typedef unsigned long long __u64;
22 |
23 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/java/com/example/memloadertest/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.memloadertest;
2 |
3 | import android.graphics.Color;
4 | import android.os.Build;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.os.Bundle;
7 | import android.widget.TextView;
8 |
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | public class MainActivity extends AppCompatActivity {
13 |
14 | // Used to load the 'native-lib' library on application startup.
15 | static {
16 | System.loadLibrary("native-lib");
17 | }
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_main);
23 |
24 | // CustomTextView customTextView=(CustomTextView)findViewById(R.id.ringView);
25 | // List colors=new ArrayList();
26 | // colors.add(Color.RED);
27 | // colors.add(Color.BLUE);
28 | // List rate=new ArrayList();
29 | // rate.add(50.0f);
30 | // rate.add(50.0f);
31 | // customTextView.setShow(colors,rate,true,true);
32 | //// Example of a call to a native method
33 | TextView tv = (TextView) findViewById(R.id.sample_text);
34 | tv.setText(getString());
35 |
36 | }
37 |
38 | /**
39 | * A native method that is implemented by the 'native-lib' native library,
40 | * which is packaged with this application.
41 | */
42 | public native String getString();
43 | }
44 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/jniLibs/armeabi/libdata.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/app/src/main/jniLibs/armeabi/libdata.so
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/jniLibs/armeabi/libfoo.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/app/src/main/jniLibs/armeabi/libfoo.so
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | CustomSoLoader
3 |
4 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/CustomSoLoader/app/src/test/java/com/example/memloadertest/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.memloadertest;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/CustomSoLoader/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.1'
11 |
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/CustomSoLoader/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/CustomSoLoader/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/CustomSoLoader/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Mar 13 13:42:39 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/CustomSoLoader/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/CustomSoLoader/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/CustomSoLoader/jniLibs/armeabi/libnative-lib.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/jniLibs/armeabi/libnative-lib.so
--------------------------------------------------------------------------------
/CustomSoLoader/jniLibs/libnative-lib.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/CustomSoLoader/jniLibs/libnative-lib.so
--------------------------------------------------------------------------------
/CustomSoLoader/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | https://bbs.pediy.com/thread-226667.htm
2 |
3 | 1.实现动态load so 实现data段进行加密
4 |
5 |
6 | 2.实现工具是android studio3.0以上 和ndk16版本以上
7 |
8 | 3.libfoo.so是没有加密的so libdata.so是加固之后的so
9 |
10 |
11 | 难点分析
12 | 1.在android 7.0之后dlopen不返回soinfo结构体,通过读取maps 获取基地址读取系统so的结构体
13 |
14 | 2.在android5.1之后 出现read被pread64函数读取so的结构
15 |
16 | 3.在android4.1.2 5.0 7.0等page_size 也是内存大小有改变
17 |
18 | 4.在android4.4之后都是c++ 考虑安全问题 用c语言实现
19 |
20 |
21 | 参考TK大神
22 |
23 | https://bbs.pediy.com/thread-216119.htm
24 |
25 | https://bbs.pediy.com/thread-191649.htm
26 |
27 | https://bbs.pediy.com/thread-197512.htm
28 |
--------------------------------------------------------------------------------
/ShellUtil/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/ShellUtil/.DS_Store
--------------------------------------------------------------------------------
/ShellUtil/Encryption.c:
--------------------------------------------------------------------------------
1 | #include "Encryption.h"
2 | typedef struct _funcInfo{
3 | Elf32_Addr st_value;
4 | Elf32_Word st_size;
5 | }funcInfo;
6 |
7 | Elf32_Ehdr ehdr;
8 | char flag = -1, *dynstr;
9 | int i;
10 | Elf32_Sym funSym;
11 | Elf32_Phdr phdr;
12 | Elf32_Off dyn_off;
13 | Elf32_Word dyn_size, dyn_strsz;
14 | Elf32_Dyn dyn;
15 | Elf32_Addr dyn_symtab, dyn_strtab, dyn_hash;
16 | unsigned funHash, nbucket, nchain, funIndex;
17 | //For Test
18 | static void print_all(char *str, int len){
19 | int i;
20 | for(i=0;i> 24;
39 | }
40 | return h;
41 | }
42 |
43 | static Elf32_Off findTargetSectionAddr(const int fd, const char *secName){
44 | Elf32_Shdr shdr;
45 | char *shstr = NULL;
46 | int i;
47 | lseek(fd, 0, SEEK_SET);
48 | if(read(fd, &ehdr, sizeof(Elf32_Ehdr)) != sizeof(Elf32_Ehdr)){
49 | puts("Read ELF header error");
50 | goto _error;
51 | }
52 | lseek(fd, ehdr.e_shoff + sizeof(Elf32_Shdr) * ehdr.e_shstrndx, SEEK_SET);
53 | if(read(fd, &shdr, sizeof(Elf32_Shdr)) != sizeof(Elf32_Shdr)){
54 | puts("Read ELF section string table error");
55 | goto _error;
56 | }
57 |
58 | if((shstr = (char *) malloc(shdr.sh_size)) == NULL){
59 | puts("Malloc space for section string table failed");
60 | goto _error;
61 | }
62 |
63 | lseek(fd, shdr.sh_offset, SEEK_SET);
64 | if(read(fd, shstr, shdr.sh_size) != shdr.sh_size){
65 | puts(shstr);
66 | puts("Read string table failed");
67 | goto _error;
68 | }
69 |
70 | lseek(fd, ehdr.e_shoff, SEEK_SET);
71 | for(i = 0; i < ehdr.e_shnum; i++){
72 | if(read(fd, &shdr, sizeof(Elf32_Shdr)) != sizeof(Elf32_Shdr)){
73 | puts("Find section .text procedure failed");
74 | goto _error;
75 | }
76 | if(strcmp(shstr + shdr.sh_name, secName) == 0){
77 | printf("Find section %s, addr = 0x%x\n", secName, shdr.sh_offset);
78 | break;
79 | }
80 | }
81 | free(shstr);
82 | return shdr.sh_offset;
83 | _error:
84 | return -1;
85 | }
86 |
87 | static char getTargetFuncInfo(int fd, const char *funcName, funcInfo *info){
88 | lseek(fd, ehdr.e_phoff, SEEK_SET);
89 | for(i=0;i < ehdr.e_phnum; i++){
90 | if(read(fd, &phdr, sizeof(Elf32_Phdr)) != sizeof(Elf32_Phdr)){
91 | puts("Read segment failed");
92 | goto _error;
93 | }
94 | if(phdr.p_type == PT_DYNAMIC){
95 | dyn_size = phdr.p_filesz;
96 | dyn_off = phdr.p_offset;
97 | flag = 0;
98 | printf("Find section %s, size = 0x%x, addr = 0x%x\n", ".dynamic", dyn_size, dyn_off);
99 | break;
100 | }
101 | }
102 | if(flag){
103 | puts("Find .dynamic failed");
104 | goto _error;
105 | }
106 | flag = 0;
107 |
108 | lseek(fd, dyn_off, SEEK_SET);
109 | for(i=0;i < dyn_size / sizeof(Elf32_Dyn); i++){
110 | if(read(fd, &dyn, sizeof(Elf32_Dyn)) != sizeof(Elf32_Dyn)){
111 | puts("Read .dynamic information failed");
112 | goto _error;
113 | }
114 | if(dyn.d_tag == DT_SYMTAB){
115 | dyn_symtab = dyn.d_un.d_ptr;
116 | flag += 1;
117 | printf("Find .dynsym, addr = 0x%x\n", dyn_symtab);
118 | }
119 | // if(dyn.d_tag == DT_GNU_HASH){ //For Android: DT_HASH
120 | if(dyn.d_tag == DT_HASH){
121 | dyn_hash = dyn.d_un.d_ptr;
122 | flag += 2;
123 | printf("Find .hash, addr = 0x%x\n", dyn_hash);
124 | }
125 | if(dyn.d_tag == DT_STRTAB){
126 | dyn_strtab = dyn.d_un.d_ptr;
127 | flag += 4;
128 | printf("Find .dynstr, addr = 0x%x\n", dyn_strtab);
129 | }
130 | if(dyn.d_tag == DT_STRSZ){
131 | dyn_strsz = dyn.d_un.d_val;
132 | flag += 8;
133 | printf("Find .dynstr size, size = 0x%x\n", dyn_strsz);
134 | }
135 | }
136 | if((flag & 0x0f) != 0x0f){
137 | puts("Find needed .section failed\n");
138 | goto _error;
139 | }
140 |
141 | dynstr = (char*) malloc(dyn_strsz);
142 | if(dynstr == NULL){
143 | puts("Malloc .dynstr space failed");
144 | goto _error;
145 | }
146 |
147 | lseek(fd, dyn_strtab, SEEK_SET);
148 | if(read(fd, dynstr, dyn_strsz) != dyn_strsz){
149 | puts("Read .dynstr failed");
150 | goto _error;
151 | }
152 | // print_all(dynstr, dyn_strsz);
153 |
154 | funHash = elfhash(funcName);
155 | printf("Function %s hashVal = 0x%x\n", funcName, funHash);
156 |
157 | lseek(fd, dyn_hash, SEEK_SET);
158 | if(read(fd, &nbucket, 4) != 4){
159 | puts("Read hash nbucket failed\n");
160 | goto _error;
161 | }
162 | printf("nbucket = %d\n", nbucket);
163 |
164 | if(read(fd, &nchain, 4) != 4){
165 | puts("Read hash nchain failed\n");
166 | goto _error;
167 | }
168 | // printf("nchain = %d\n", nchain);
169 |
170 | funHash = funHash % nbucket;
171 | printf("funHash mod nbucket = %d \n", funHash);
172 |
173 | lseek(fd, funHash * 4, SEEK_CUR);
174 | if(read(fd, &funIndex, 4) != 4){
175 | puts("Read funIndex failed\n");
176 | goto _error;
177 | }
178 |
179 | lseek(fd, dyn_symtab + funIndex * sizeof(Elf32_Sym), SEEK_SET);
180 | if(read(fd, &funSym, sizeof(Elf32_Sym)) != sizeof(Elf32_Sym)){
181 | puts("Read funSym failed");
182 | goto _error;
183 | }
184 |
185 | if(strcmp(dynstr + funSym.st_name, funcName) != 0){
186 | while(1){
187 | lseek(fd, dyn_hash + 4 * (2 + nbucket + funIndex), SEEK_SET);
188 | if(read(fd, &funIndex, 4) != 4){
189 | puts("Read funIndex failed\n");
190 | goto _error;
191 | }
192 |
193 | if(funIndex == 0){
194 | puts("Cannot find funtion!\n");
195 | goto _error;
196 | }
197 |
198 | lseek(fd, dyn_symtab + funIndex * sizeof(Elf32_Sym), SEEK_SET);
199 | if(read(fd, &funSym, sizeof(Elf32_Sym)) != sizeof(Elf32_Sym)){
200 | puts("In FOR loop, Read funSym failed");
201 | goto _error;
202 | }
203 |
204 | if(strcmp(dynstr + funSym.st_name, funcName) == 0){
205 | break;
206 | }
207 | }
208 | }
209 |
210 | printf("Find: %s, offset = 0x%x, size = 0x%x\n", funcName, funSym.st_value, funSym.st_size);
211 | info->st_value = funSym.st_value;
212 | info->st_size = funSym.st_size;
213 | free(dynstr);
214 | return 0;
215 |
216 | _error:
217 | free(dynstr);
218 | return -1;
219 | }
220 |
221 | int encryption(char *path){
222 | char secName[] = ".text";
223 | // char funcName[] = "Java_com_example_memloadertest_MainActivity_getString";
224 | char funcName[] = "JNI_OnLoad";
225 | // char funcName[] = "Java_com_thomas_crackmeso_MainActivity_verify";
226 |
227 |
228 | char *content = NULL;
229 | int fd, i;
230 | Elf32_Off secOff;
231 | funcInfo info;
232 | fd = open(path, O_RDWR);
233 | if(fd < 0){
234 | goto _error;
235 | }
236 |
237 | secOff = findTargetSectionAddr(fd, secName);
238 | if(secOff == -1){
239 | printf("Find section %s failed\n", secName);
240 | goto _error;
241 | }
242 | if(getTargetFuncInfo(fd, funcName, &info) == -1){
243 | printf("Find function %s failed\n", funcName);
244 | goto _error;
245 | }
246 |
247 | content = (char*) malloc(info.st_size);
248 | if(content == NULL){
249 | puts("Malloc space failed");
250 | goto _error;
251 | }
252 |
253 | lseek(fd, info.st_value - 1, SEEK_SET);
254 | if(read(fd, content, info.st_size) != info.st_size){
255 | puts("Malloc space failed");
256 | goto _error;
257 | }
258 |
259 | for(i=0;i
13 | #include
14 | #include
15 | #include
16 | #include
17 | int encryption(char *path);
18 | #endif /* Encryption_h */
19 |
--------------------------------------------------------------------------------
/ShellUtil/Utils.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "Utils.h"
5 |
6 | #define MAX_SEGMENT_INTERVAL 10 * 4096 // 10 pages
7 | #ifdef __LP64__
8 | #define MAX_COUNT 2048
9 | #else
10 | #define MAX_COUNT 1024
11 | #endif
12 | int loadMemoryMap(pid_t pid,MemoryMap *map) {
13 | #ifdef __LP64__
14 | char raw[64000];
15 | #else
16 | char raw[8000];
17 | #endif
18 |
19 | char name[MAX_NAME_LENGTH];
20 | char *p;
21 | unsigned long start, end;
22 | int itemCount = 0, fd, returnValue;
23 |
24 | // sprintf(raw, "/proc/%d/maps", pid);
25 | fd = open("/Users/liumeng/Desktop/maps", O_RDONLY);
26 | if (fd < 0) {
27 | return -1;
28 | }
29 | memset(raw, 0, sizeof(raw));
30 | p = raw;
31 |
32 | while(1) {
33 | returnValue =(int)read(fd, p, sizeof(raw) - (p - raw));
34 | if (returnValue < 0) {
35 |
36 | return -1;
37 | }
38 | if (returnValue == 0) {
39 | break;
40 | }
41 | p += returnValue;
42 | if (p > raw + sizeof(raw)) {
43 |
44 | return -1;
45 | }
46 | }
47 | close(fd);
48 | p = strtok(raw, "\n");
49 | while (p) {
50 | if(itemCount<1024){
51 | #ifdef __LP64__
52 | returnValue = sscanf(p, "%012lx-%012lx %*s %*s %*s %*s %s\n", &start, &end, name);
53 | #else
54 | returnValue = sscanf(p, "%08lx-%08lx %*s %*s %*s %*s %s\n", &start, &end, name);
55 | #endif
56 | p = strtok(NULL, "\n");
57 | if (returnValue == 2) {
58 | map[itemCount].start=start;
59 | map[itemCount].end=end;
60 | strcpy(map[itemCount].name, name);
61 | continue;
62 | }
63 | map[itemCount].start=start;
64 | map[itemCount].end=end;
65 | strcpy(map[itemCount].name, name);
66 | itemCount++;
67 | }
68 | }
69 |
70 | return 0;
71 | }
72 |
73 | int hookSoAddress(pid_t pid,MemoryMap myMap,char *soLibName){
74 | MemoryMap map[MAX_COUNT];
75 | int count;
76 | int ret = 0;
77 | for(count=0;countmap[i].start||start==0){
95 | start=map[i].start;
96 | }
97 | if(end