fake-linker
fake-linker copied to clipboard
Modify Android linker to provide loading module and hook function
fake-linker
Chinese document click here
Project description
Modify Android linker to provide loading module and plt hook features.Please check the detailed principle modify linker to implement plt hook
Supported Android
Android version: Android 5.0 ~ Android 11+. Support instructions: x86, x86_64, arm, arm64
Build
- Source build
Add it as an
Android Libraryto theAndroidproject,the main module adds its dependencies.Changebuild.gradlebuildApivariable,compile the specified Api level.
- Use build library
Download the latest version of the binary file, decompress it, add the
aarfile as a library to the project dependencies, and import the header file under theincludedirectory into the Hook module for use.
- Build configuration
Refer to FakeXposed configuration scripts
build.pyandbuild.gradle
Hook module development
- Copy the export header file (the source code is in the export directory under the
cppdirectory) to theHookmodule. - Implement the
fake_load_library_initexport function inlinker_export.h. - Call various implementation methods, check the definition of
FakeLinkerinlinker_export.h. - Normally implement Hook methods such as:
open,dlopen,dlsymmethod, etc., the method must be exported. - Hook module distinguishes Android7.0 or lower (no namespace,
soinfo handle), Android7.0 and above (namespace,soinfo handle).
Java initialization
- Install the library correctly to the specified location, install the
fake-linkerandHookmodules to the path that the application has access to, such as:/data/local/tmp, you can call the system method to load directly. The module has integrated the installation executable file, and the Java layer calls the method under the FileInstaller class to install, and various different platform architectures have been processed inside. - Set the
fake-linkermodule throughFileInstaller. TheHookmodule requires different selinux and uid, gid file attributes. - Load and initialize the
fake-linkermodule, call theFakeLinker.initFakeLinkermethod, internally load the Hook module and call back thefake_load_library_initmethod to complete the module initialization.
Other description
- The project is different from directly setting the
LD_PRELOADenvironment variable. Direct setting usually cannot intercept thedlsymmethod, because once intercepted, you need to implement the search symbol yourself and the higher version has thecalleraddress restriction, and the module passes the transfer modulefake- linkerprovides callingdlsymmethod, so Hook module can interceptdlsymand provide moreLinkerrelated functions. - Each version of Android
Linkerhas corresponding modifications, so the module depends on theapilevel of the phone, and the corresponding modules can be loaded at different levels. When loading manually, you need to pay attention toApi 25directly use the library ofApi 24
Note
- When hooking the system process, please do a good job of deleting the backup to avoid the situation that the system process is dead and cannot be booted due to an error.
- Relocate the loaded module according to the module loading time.
Usage example
- Set the
Hookmodule as the global libraryremote->CallCommonFunction(kCFAddSoinfoToGlobal, kSPAddress, nullptr, kSPNull, nullptr, &error_code);. - Relocate some loaded modules
remote->CallCommonFunction(kCFCallManualRelinks, kSPAddress, nullptr, kSPNames, libs, &error_code);.static const FakeLinker *remote; // Hook the jni function RegisterNatives static jint HookJniRegisterNatives(JNIEnv *env, jclass c, const JNINativeMethod *methods, jint nMethods) { LOG("start register native function %p", __builtin_return_address(0)); jint ret = original_functions->RegisterNatives(env, c, methods, nMethods); if (ret != JNI_ERR && !original_functions->ExceptionCheck(env)) { std::string cls = JNIHelper::GetClassName(env, c); for (int i = 0; i < nMethods; ++i) { LOG("native register class: %s, method name: %s, function signature: %s, register address: %p", cls.c_str(), methods[i].name, methods[i].signature, methods[i].fnPtr); } } return ret; } static void InitHook() { int error_code; // Add this hook module to the global module, which will affect all modules loaded later remote->CallCommonFunction(kCFAddSoinfoToGlobal, kSPAddress, nullptr, kSPNull, nullptr, &error_code); if (error_code != kErrorNo) { LOGE("init global soinfo error, error code: %x", error_code); return; } VarArray<const char *> *libs; // Re-parse the import table of the following modules, because the following modules have been loaded before we have loaded them, and all re-links make their symbolic links to our Hook method // The java system code also mainly uses the following libraries, and relinking also means the core import function of Hook's java libs = VaargToVarArray<const char *>(5, "libjavacore.so", "libnativehelper.so", "libnativeloader.so", "libart.so", "libopenjdk.so"); remote->CallCommonFunction(kCFCallManualRelinks, kSPAddress, nullptr, kSPNames, libs, &error_code); // Hook JNI interface remote_->HookJniNative(offsetof(JNINativeInterface, RegisterNatives), (void *)HookJniRegisterNatives, nullptr); } C_API void fake_load_library_init(JNIEnv *env, void *fake_soinfo, const FakeLinker *interface, const char *cache_path, const char *config_path, const char *_process_name){ remote = interface; InitHook(); } - For other more uses
FakeXposed
Xposed,rootShield detection,File redirection, etc.