├── .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 | 16 | 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 | 71 | -------------------------------------------------------------------------------- /CustomSoLoader/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CustomSoLoader/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 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 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #ifndef _UTILS_H_ 16 | #define _UTILS_H_ 17 | 18 | #define MAX_NAME_LENGTH 256 19 | #define MEMORY_ONLY "[memory]" 20 | 21 | typedef struct { 22 | char name[MAX_NAME_LENGTH]; 23 | unsigned long start, end; // memory address start/end of components 24 | } MemoryMap; 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | int loadMemoryMap(pid_t pid,MemoryMap *map); 31 | int hookSoAddress(pid_t pid,MemoryMap myMap,char* soLibName); 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /ShellUtil/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 | -------------------------------------------------------------------------------- /ShellUtil/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 | #define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */ 22 | /* Next two are historical and binaries and 23 | modules of these types will be rejected by 24 | Linux. */ 25 | #define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ 26 | #define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ 27 | 28 | #define EM_PARISC 15 /* HPPA */ 29 | #define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ 30 | #define EM_PPC 20 /* PowerPC */ 31 | #define EM_PPC64 21 /* PowerPC64 */ 32 | #define EM_SH 42 /* SuperH */ 33 | #define EM_SPARCV9 43 /* SPARC v9 64-bit */ 34 | #define EM_IA_64 50 /* HP/Intel IA-64 */ 35 | #define EM_X86_64 62 /* AMD x86-64 */ 36 | #define EM_S390 22 /* IBM S/390 */ 37 | #define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ 38 | #define EM_V850 87 /* NEC v850 */ 39 | #define EM_M32R 88 /* Renesas M32R */ 40 | #define EM_H8_300 46 /* Renesas H8/300,300H,H8S */ 41 | #define EM_FRV 0x5441 /* Fujitsu FR-V */ 42 | 43 | /* 44 | * This is an interim value that we will use until the committee comes 45 | * up with a final number. 46 | */ 47 | #define EM_ALPHA 0x9026 48 | 49 | /* Bogus old v850 magic number, used by old tools. */ 50 | #define EM_CYGNUS_V850 0x9080 51 | /* Bogus old m32r magic number, used by old tools. */ 52 | #define EM_CYGNUS_M32R 0x9041 53 | /* This is the old interim value for S/390 architecture */ 54 | #define EM_S390_OLD 0xA390 55 | 56 | 57 | #endif /* _LINUX_ELF_EM_H */ 58 | -------------------------------------------------------------------------------- /ShellUtil/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 | #define EM_ARM 40 17 | #ifndef elf_read_implies_exec 18 | #define elf_read_implies_exec(ex, have_pt_gnu_stack) 0 19 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 20 | #endif 21 | typedef __u32 Elf32_Addr; 22 | typedef __u16 Elf32_Half; 23 | typedef __u32 Elf32_Off; 24 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 25 | typedef __s32 Elf32_Sword; 26 | typedef __u32 Elf32_Word; 27 | typedef __u64 Elf64_Addr; 28 | typedef __u16 Elf64_Half; 29 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 30 | typedef __s16 Elf64_SHalf; 31 | typedef __u64 Elf64_Off; 32 | typedef __s32 Elf64_Sword; 33 | typedef __u32 Elf64_Word; 34 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 35 | typedef __u64 Elf64_Xword; 36 | typedef __s64 Elf64_Sxword; 37 | #define R_ARM_NONE 0 38 | #define PT_NULL 0 39 | #define PT_LOAD 1 40 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 41 | #define PT_DYNAMIC 2 42 | #define PT_INTERP 3 43 | #define PT_NOTE 4 44 | #define PT_SHLIB 5 45 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 46 | #define PT_PHDR 6 47 | #define PT_TLS 7 48 | #define PT_LOOS 0x60000000 49 | #define PT_HIOS 0x6fffffff 50 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 51 | #define PT_LOPROC 0x70000000 52 | #define PT_HIPROC 0x7fffffff 53 | #define PT_GNU_EH_FRAME 0x6474e550 54 | #define PT_GNU_STACK (PT_LOOS + 0x474e551) 55 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 56 | #define ET_NONE 0 57 | #define ET_REL 1 58 | #define ET_EXEC 2 59 | #define ET_DYN 3 60 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 61 | #define ET_CORE 4 62 | #define ET_LOPROC 0xff00 63 | #define ET_HIPROC 0xffff 64 | #define DT_NULL 0 65 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 66 | #define DT_NEEDED 1 67 | #define DT_PLTRELSZ 2 68 | #define DT_PLTGOT 3 69 | #define DT_HASH 4 70 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 71 | #define DT_STRTAB 5 72 | #define DT_SYMTAB 6 73 | #define DT_RELA 7 74 | #define DT_RELASZ 8 75 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 76 | #define DT_RELAENT 9 77 | #define DT_STRSZ 10 78 | #define DT_SYMENT 11 79 | #define DT_INIT 12 80 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 81 | #define DT_FINI 13 82 | #define DT_SONAME 14 83 | #define DT_RPATH 15 84 | #define DT_SYMBOLIC 16 85 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 86 | #define DT_REL 17 87 | #define DT_RELSZ 18 88 | #define DT_RELENT 19 89 | #define DT_PLTREL 20 90 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 91 | #define DT_DEBUG 21 92 | #define DT_TEXTREL 22 93 | #define DT_JMPREL 23 94 | #define DT_LOPROC 0x70000000 95 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 96 | #define DT_HIPROC 0x7fffffff 97 | #define STB_LOCAL 0 98 | #define STB_GLOBAL 1 99 | #define STB_WEAK 2 100 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 101 | #define STT_NOTYPE 0 102 | #define STT_OBJECT 1 103 | #define STT_FUNC 2 104 | #define STT_SECTION 3 105 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 106 | #define STT_FILE 4 107 | #define STT_COMMON 5 108 | #define STT_TLS 6 109 | #define ELF_ST_BIND(x) ((x) >> 4) 110 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 111 | #define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf) 112 | #define ELF32_ST_BIND(x) ELF_ST_BIND(x) 113 | #define ELF32_ST_TYPE(x) ELF_ST_TYPE(x) 114 | #define ELF64_ST_BIND(x) ELF_ST_BIND(x) 115 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 116 | #define ELF64_ST_TYPE(x) ELF_ST_TYPE(x) 117 | typedef struct dynamic{ 118 | Elf32_Sword d_tag; 119 | union{ 120 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 121 | Elf32_Sword d_val; 122 | Elf32_Addr d_ptr; 123 | } d_un; 124 | } Elf32_Dyn; 125 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 126 | typedef struct { 127 | Elf64_Sxword d_tag; 128 | union { 129 | Elf64_Xword d_val; 130 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 131 | Elf64_Addr d_ptr; 132 | } d_un; 133 | } Elf64_Dyn; 134 | #define ELF32_R_SYM(x) ((x) >> 8) 135 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 136 | #define ELF32_R_TYPE(x) ((x) & 0xff) 137 | #define ELF64_R_SYM(i) ((i) >> 32) 138 | #define ELF64_R_TYPE(i) ((i) & 0xffffffff) 139 | typedef struct elf32_rel { 140 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 141 | Elf32_Addr r_offset; 142 | Elf32_Word r_info; 143 | } Elf32_Rel; 144 | typedef struct elf64_rel { 145 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 146 | Elf64_Addr r_offset; 147 | Elf64_Xword r_info; 148 | } Elf64_Rel; 149 | typedef struct elf32_rela{ 150 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 151 | Elf32_Addr r_offset; 152 | Elf32_Word r_info; 153 | Elf32_Sword r_addend; 154 | } Elf32_Rela; 155 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 156 | typedef struct elf64_rela { 157 | Elf64_Addr r_offset; 158 | Elf64_Xword r_info; 159 | Elf64_Sxword r_addend; 160 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 161 | } Elf64_Rela; 162 | typedef struct elf32_sym{ 163 | Elf32_Word st_name; 164 | Elf32_Addr st_value; 165 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 166 | Elf32_Word st_size; 167 | unsigned char st_info; 168 | unsigned char st_other; 169 | Elf32_Half st_shndx; 170 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 171 | } Elf32_Sym; 172 | typedef struct elf64_sym { 173 | Elf64_Word st_name; 174 | unsigned char st_info; 175 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 176 | unsigned char st_other; 177 | Elf64_Half st_shndx; 178 | Elf64_Addr st_value; 179 | Elf64_Xword st_size; 180 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 181 | } Elf64_Sym; 182 | #define EI_NIDENT 16 183 | typedef struct elf32_hdr{ 184 | unsigned char e_ident[EI_NIDENT]; 185 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 186 | Elf32_Half e_type; 187 | Elf32_Half e_machine; 188 | Elf32_Word e_version; 189 | Elf32_Addr e_entry; 190 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 191 | Elf32_Off e_phoff; 192 | Elf32_Off e_shoff; 193 | Elf32_Word e_flags; 194 | Elf32_Half e_ehsize; 195 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 196 | Elf32_Half e_phentsize; 197 | Elf32_Half e_phnum; 198 | Elf32_Half e_shentsize; 199 | Elf32_Half e_shnum; 200 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 201 | Elf32_Half e_shstrndx; 202 | } Elf32_Ehdr; 203 | typedef struct elf64_hdr { 204 | unsigned char e_ident[16]; 205 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 206 | Elf64_Half e_type; 207 | Elf64_Half e_machine; 208 | Elf64_Word e_version; 209 | Elf64_Addr e_entry; 210 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 211 | Elf64_Off e_phoff; 212 | Elf64_Off e_shoff; 213 | Elf64_Word e_flags; 214 | Elf64_Half e_ehsize; 215 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 216 | Elf64_Half e_phentsize; 217 | Elf64_Half e_phnum; 218 | Elf64_Half e_shentsize; 219 | Elf64_Half e_shnum; 220 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 221 | Elf64_Half e_shstrndx; 222 | } Elf64_Ehdr; 223 | #define PF_R 0x4 224 | #define PF_W 0x2 225 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 226 | #define PF_X 0x1 227 | typedef struct elf32_phdr{ 228 | Elf32_Word p_type; 229 | Elf32_Off p_offset; 230 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 231 | Elf32_Addr p_vaddr; 232 | Elf32_Addr p_paddr; 233 | Elf32_Word p_filesz; 234 | Elf32_Word p_memsz; 235 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 236 | Elf32_Word p_flags; 237 | Elf32_Word p_align; 238 | } Elf32_Phdr; 239 | typedef struct elf64_phdr { 240 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 241 | Elf64_Word p_type; 242 | Elf64_Word p_flags; 243 | Elf64_Off p_offset; 244 | Elf64_Addr p_vaddr; 245 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 246 | Elf64_Addr p_paddr; 247 | Elf64_Xword p_filesz; 248 | Elf64_Xword p_memsz; 249 | Elf64_Xword p_align; 250 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 251 | } Elf64_Phdr; 252 | #define SHT_NULL 0 253 | #define SHT_PROGBITS 1 254 | #define SHT_SYMTAB 2 255 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 256 | #define SHT_STRTAB 3 257 | #define SHT_RELA 4 258 | #define SHT_HASH 5 259 | #define SHT_DYNAMIC 6 260 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 261 | #define SHT_NOTE 7 262 | #define SHT_NOBITS 8 263 | #define SHT_REL 9 264 | #define SHT_SHLIB 10 265 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 266 | #define SHT_DYNSYM 11 267 | #define SHT_NUM 12 268 | #define SHT_LOPROC 0x70000000 269 | #define SHT_HIPROC 0x7fffffff 270 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 271 | #define SHT_LOUSER 0x80000000 272 | #define SHT_HIUSER 0xffffffff 273 | #define SHF_WRITE 0x1 274 | #define SHF_ALLOC 0x2 275 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 276 | #define SHF_EXECINSTR 0x4 277 | #define SHF_MASKPROC 0xf0000000 278 | #define SHN_UNDEF 0 279 | #define SHN_LORESERVE 0xff00 280 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 281 | #define SHN_LOPROC 0xff00 282 | #define SHN_HIPROC 0xff1f 283 | #define SHN_ABS 0xfff1 284 | #define SHN_COMMON 0xfff2 285 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 286 | #define SHN_HIRESERVE 0xffff 287 | typedef struct { 288 | Elf32_Word sh_name; 289 | Elf32_Word sh_type; 290 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 291 | Elf32_Word sh_flags; 292 | Elf32_Addr sh_addr; 293 | Elf32_Off sh_offset; 294 | Elf32_Word sh_size; 295 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 296 | Elf32_Word sh_link; 297 | Elf32_Word sh_info; 298 | Elf32_Word sh_addralign; 299 | Elf32_Word sh_entsize; 300 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 301 | } Elf32_Shdr; 302 | typedef struct elf64_shdr { 303 | Elf64_Word sh_name; 304 | Elf64_Word sh_type; 305 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 306 | Elf64_Xword sh_flags; 307 | Elf64_Addr sh_addr; 308 | Elf64_Off sh_offset; 309 | Elf64_Xword sh_size; 310 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 311 | Elf64_Word sh_link; 312 | Elf64_Word sh_info; 313 | Elf64_Xword sh_addralign; 314 | Elf64_Xword sh_entsize; 315 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 316 | } Elf64_Shdr; 317 | #define EI_MAG0 0 318 | #define EI_MAG1 1 319 | #define EI_MAG2 2 320 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 321 | #define EI_MAG3 3 322 | #define EI_CLASS 4 323 | #define EI_DATA 5 324 | #define EI_VERSION 6 325 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 326 | #define EI_OSABI 7 327 | #define EI_PAD 8 328 | #define ELFMAG0 0x7f 329 | #define ELFMAG1 'E' 330 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 331 | #define ELFMAG2 'L' 332 | #define ELFMAG3 'F' 333 | #define ELFMAG "\177ELF" 334 | #define SELFMAG 4 335 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 336 | #define ELFCLASSNONE 0 337 | #define ELFCLASS32 1 338 | #define ELFCLASS64 2 339 | #define ELFCLASSNUM 3 340 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 341 | #define ELFDATANONE 0 342 | #define ELFDATA2LSB 1 343 | #define ELFDATA2MSB 2 344 | #define EV_NONE 0 345 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 346 | #define EV_CURRENT 1 347 | #define EV_NUM 2 348 | #define ELFOSABI_NONE 0 349 | #define ELFOSABI_LINUX 3 350 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 351 | #ifndef ELF_OSABI 352 | #define ELF_OSABI ELFOSABI_NONE 353 | #endif 354 | #define NT_PRSTATUS 1 355 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 356 | #define NT_PRFPREG 2 357 | #define NT_PRPSINFO 3 358 | #define NT_TASKSTRUCT 4 359 | #define NT_AUXV 6 360 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 361 | #define NT_PRXFPREG 0x46e62b7f 362 | typedef struct elf32_note { 363 | Elf32_Word n_namesz; 364 | Elf32_Word n_descsz; 365 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 366 | Elf32_Word n_type; 367 | } Elf32_Nhdr; 368 | typedef struct elf64_note { 369 | Elf64_Word n_namesz; 370 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 371 | Elf64_Word n_descsz; 372 | Elf64_Word n_type; 373 | } Elf64_Nhdr; 374 | #if ELF_CLASS == ELFCLASS32 375 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 376 | #define elfhdr elf32_hdr 377 | #define elf_phdr elf32_phdr 378 | #define elf_note elf32_note 379 | #else 380 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 381 | #define elfhdr elf64_hdr 382 | #define elf_phdr elf64_phdr 383 | #define elf_note elf64_note 384 | #endif 385 | /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ 386 | #endif 387 | 388 | -------------------------------------------------------------------------------- /ShellUtil/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 | -------------------------------------------------------------------------------- /ShellUtil/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 | -------------------------------------------------------------------------------- /ShellUtil/libdata.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liumengdeqq/CustomLinker/ce9aeea2595c7b6ef27c8e8c59871535b91f8d05/ShellUtil/libdata.so -------------------------------------------------------------------------------- /ShellUtil/log.h: -------------------------------------------------------------------------------- 1 | // 2 | // log.h 3 | // shell 4 | // 5 | // Created by liu meng on 2018/2/4. 6 | // Copyright © 2018年 liu mengcom.example. All rights reserved. 7 | // 8 | 9 | #ifndef log_h 10 | #define log_h 11 | #define TRACE(fmt,args...) printf(fmt,args) 12 | #define DL_ERR(fmt,args...) printf(fmt,args) 13 | #endif /* log_h */ 14 | -------------------------------------------------------------------------------- /ShellUtil/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // main.c 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 | //#include 10 | //#include "Utils.h" 11 | #include "Encryption.h" 12 | //char *white[]={"/system/lib/libc.so","/system/lib/liblog.so","/system/lib/libm.so","/system/lib/libdl.so","/system/lib/libstdc++.so"}; 13 | //int iswhite(char* name){ 14 | // for(int i=0;i dddd_MAX) { 44 | // printf("ddddd"); 45 | // } 46 | // printf("%ul\n",PAGE_SIZE); 47 | encryption("/Users/liumeng/shell/shell/shell/libdata.so"); 48 | 49 | // pid_t pid=getpid(); 50 | // MemoryMap myMap; 51 | // char *name="/system/lib/libc.so"; 52 | // if(iswhite(name)==1){ 53 | // hookSoAddress(pid,myMap,name); 54 | // } 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /ShellUtil/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 | --------------------------------------------------------------------------------