NoteZ
NoteZ copied to clipboard
Dobby and Linker Android Restriction
Dobby and Linker Android Restriction
Google Pixel 2, Android 10, ARM64
Prologue
看到很多文章在讲, 然后可能最近也需要, 就抽空实现了下.
可能存在实现不合理/不恰当/错误的地方, 欢迎提出各种意见/批评, 非常感谢.
Dobby/builtin-plugin/AndroidRestriction/android_restriction.cc
Dobby/SymbolResolver/elf/dobby_symbol_resolver.cc
0xff. process module map
static std::vector<RuntimeModule> get_process_map_with_linker_iterator() {
dl_iterate_phdr(
[](dl_phdr_info *info, size_t size, void *data) {
RuntimeModule module = {0};
if (info->dlpi_name && info->dlpi_name[0] == '/')
strcpy(module.path, info->dlpi_name);
module.load_address = (void *)info->dlpi_addr;
ProcessModuleMap.push_back(module);
return 0;
},
NULL);
return ProcessModuleMap;
}
std::vector<RuntimeModule> ProcessRuntimeUtility::GetProcessModuleMap() {
if (!ProcessMemoryLayout.empty()) {
ProcessMemoryLayout.clear();
}
return get_process_map_with_linker_iterator();
}
0x0. linker solist
// impl at "android_restriction.cc"
extern std::vector<void *> linker_get_solist();
void *DobbySymbolResolver(const char *image_name, const char *symbol_name_pattern) {
void *result = NULL;
auto solist = linker_get_solist();
for (auto soinfo : solist) {
uintptr_t handle = linker_soinfo_to_handle(soinfo);
if (image_name == NULL || strstr(linker_soinfo_get_realpath(soinfo), image_name) != 0) {
DLOG("DobbySymbolResolver::dlsym: %s", linker_soinfo_get_realpath(soinfo));
result = dlsym((void *)handle, symbol_name_pattern);
if (result)
return result;
}
}
result = resolve_elf_internal_symbol(image_name, symbol_name_pattern);
return result;
}
0x1. symbol resolver
// impl at "android_restriction.cc"
extern std::vector<void *> linker_get_solist();
void *DobbySymbolResolver(const char *image_name, const char *symbol_name_pattern) {
void *result = NULL;
auto solist = linker_get_solist();
for (auto soinfo : solist) {
uintptr_t handle = linker_soinfo_to_handle(soinfo);
if (image_name == NULL || strstr(linker_soinfo_get_realpath(soinfo), image_name) != 0) {
DLOG("DobbySymbolResolver::dlsym: %s", linker_soinfo_get_realpath(soinfo));
result = dlsym((void *)handle, symbol_name_pattern);
if (result)
return result;
}
}
result = resolve_elf_internal_symbol(image_name, symbol_name_pattern);
return result;
}
void *__loader_dlopen = DobbySymbolResolver(NULL, "__loader_dlopen");
DobbyHook((void *)__loader_dlopen, (void *)fake_loader_dlopen, (void **)&orig_loader_dlopen);
0x2. hook dlopen
void *__loader_dlopen = DobbySymbolResolver(NULL, "__loader_dlopen");
DobbyHook((void *)__loader_dlopen, (void *)fake_loader_dlopen, (void **)&orig_loader_dlopen);
0x3. linker dlopen(fake caller address)
#if defined(__LP64__)
lib = "/system/lib64/libandroid_runtime.so";
#else
lib = "/system/lib/libandroid_runtime.so";
#endif
void *handle = NULL;
handle = linker_dlopen(lib, RTLD_LAZY);
void *vm;
vm = dlsym(handle, "_ZN7android14AndroidRuntime7mJavaVME");
0x4. disable android namespace restriction
void linker_disable_namespace_restriction() {
linker_iterate_soinfo(iterate_soinfo_cb);
// no need for this actually
void *linker_namespace_is_is_accessible_ptr =
resolve_elf_internal_symbol(LINKER_PATH, "__dl__ZN19android_namespace_t13is_accessibleERKNSt3__112basic_"
"stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE");
DobbyHook(linker_namespace_is_is_accessible_ptr, (void *)linker_namespace_is_is_accessible,
(void **)&orig_linker_namespace_is_is_accessible);
LOG("disable namespace restriction done");
}