以Process分析js对象的初始化

frida-gum 虽然功能强大,但由于使用了 C 语言的接口,扩展开发不方便,因此frida 使用 JavaScript 作为编写 hook 的语言,底层使用quickjs和v8封装。

image.png

相关文件

  • frida-gum/bindings/gumjs/runtime/core.js
  • frida-gum/bindings/gumjs/gumv8process.cpp

代码

void
_gum_v8_process_init (GumV8Process * self,
                      GumV8Module * module,
                      GumV8Core * core,
                      Local<ObjectTemplate> scope)
{
  auto isolate = core->isolate;

  self->module = module;
  self->core = core;

  auto process = _gum_v8_create_module ("Process", scope, isolate);
  process->Set (_gum_v8_string_new_ascii (isolate, "id"),
      Number::New (isolate, gum_process_get_id ()), ReadOnly);
  process->Set (_gum_v8_string_new_ascii (isolate, "arch"),
      String::NewFromUtf8Literal (isolate, GUM_SCRIPT_ARCH), ReadOnly);
  process->Set (_gum_v8_string_new_ascii (isolate, "platform"),
      String::NewFromUtf8Literal (isolate, GUM_SCRIPT_PLATFORM), ReadOnly);
  process->Set (_gum_v8_string_new_ascii (isolate, "pageSize"),
      Number::New (isolate, gum_query_page_size ()), ReadOnly);
  process->Set (_gum_v8_string_new_ascii (isolate, "pointerSize"),
      Number::New (isolate, GLIB_SIZEOF_VOID_P), ReadOnly);
  process->Set (_gum_v8_string_new_ascii (isolate, "codeSigningPolicy"),
      String::NewFromUtf8 (isolate, gum_code_signing_policy_to_string (
      gum_process_get_code_signing_policy ())).ToLocalChecked (), ReadOnly);
  _gum_v8_module_add (External::New (isolate, self), process,
      gumjs_process_functions, isolate);
}

static const GumV8Function gumjs_process_functions[] =
{
  { "getCurrentDir", gumjs_process_get_current_dir },
  { "getHomeDir", gumjs_process_get_home_dir },
  { "getTmpDir", gumjs_process_get_tmp_dir },
  { "isDebuggerAttached", gumjs_process_is_debugger_attached },
  { "getCurrentThreadId", gumjs_process_get_current_thread_id },
  { "_enumerateThreads", gumjs_process_enumerate_threads },
  { "findModuleByName", gumjs_process_find_module_by_name },
  { "_enumerateModules", gumjs_process_enumerate_modules },
  { "_enumerateRanges", gumjs_process_enumerate_ranges },
  { "enumerateSystemRanges", gumjs_process_enumerate_system_ranges },
  { "_enumerateMallocRanges", gumjs_process_enumerate_malloc_ranges },
  { "setExceptionHandler", gumjs_process_set_exception_handler },

  { NULL, NULL }
};

makeEnumerateApi(Process, 'enumerateThreads', 0);
makeEnumerateApi(Process, 'enumerateModules', 0);
makeEnumerateRanges(Process);
makeEnumerateApi(Process, 'enumerateMallocRanges', 0);

Object.defineProperties(Process, {
  findModuleByAddress: {
    enumerable: true,
    value: function (address) {
      let module = null;
      Process._enumerateModules({
        onMatch(m) {
          const base = m.base;
          if (base.compare(address) <= 0 && base.add(m.size).compare(address) > 0) {
            module = m;
            return 'stop';
          }
        },
        onComplete() {
        }
      });
      return module;
    }
  },
  getModuleByAddress: {
    enumerable: true,
    value: function (address) {
      const module = Process.findModuleByAddress(address);
      if (module === null)
        throw new Error('unable to find module containing ' + address);
      return module;
    }
  },
  getModuleByName: {
    enumerable: true,
    value: function (name) {
      const module = Process.findModuleByName(name);
      if (module === null)
        throw new Error("unable to find module '" + name + "'");
      return module;
    }
  },
  getRangeByAddress: {
    enumerable: true,
    value: function (address) {
      const range = Process.findRangeByAddress(address);
      if (range === null)
        throw new Error('unable to find range containing ' + address);
      return range;
    }
  },
});

if (Process.findRangeByAddress === undefined) {
  Object.defineProperty(Process, 'findRangeByAddress', {
    enumerable: true,
    value: function (address) {
      let range = null;
      Process._enumerateRanges('---', {
        onMatch(r) {
          const base = r.base;
          if (base.compare(address) <= 0 && base.add(r.size).compare(address) > 0) {
            range = r;
            return 'stop';
          }
        },
        onComplete() {
        }
      });
      return range;
    }
  });
}


©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容