NoteZ icon indicating copy to clipboard operation
NoteZ copied to clipboard

Dobby and Linker Android Restriction

Open jmpews opened this issue 4 years ago • 0 comments

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();
}

go to detail

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;
}

go to detail

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);

go to detail

0x2. hook dlopen

void *__loader_dlopen = DobbySymbolResolver(NULL, "__loader_dlopen");
DobbyHook((void *)__loader_dlopen, (void *)fake_loader_dlopen, (void **)&orig_loader_dlopen);

go to detail

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");

go to detail

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");
}

go to detail

Reference

frida

quarkslab

jmpews avatar Jul 29 '20 02:07 jmpews