JavaScript 逆向分析中的常用 Hook 技术详解

在 JavaScript 逆向工程中,Hook(钩子)技术是定位关键逻辑、拦截数据生成、调试加密函数的核心手段。通过修改或监控原生方法的行为,我们可以深入理解目标网站的运行机制。本文整理了 11 种常见的 Hook 技术,并附上实用示例代码,适用于油猴脚本(Tampermonkey)、浏览器调试及安全研究场景。

📌 提示:以下代码建议在浏览器控制台或用户脚本中使用,用于辅助分析,切勿用于非法用途。

01. DOM 操作 Hook

通过修改 DOM 元素的属性或样式,实现对页面行为的干预,常用于隐藏元素、触发事件或篡改界面状态。

// 修改元素属性
document.getElementById('elementId').setAttribute('attrName', 'attrValue');

// 修改元素样式
document.getElementById('elementId').style.color = 'red';
document.getElementById('elementId').style.display = 'none';

02. Cookie 操作 Hook

用于监控 document.cookie 的读写操作,定位 Cookie 中关键字段(如 __dfptoken)的生成位置。

方式一:使用 Object.defineProperty

(function () {
  'use strict';
  let cookieTemp = '';

  Object.defineProperty(document, 'cookie', {
    set: function (val) {
      if (val.includes('__dfp')) {
        debugger; // 断点触发
      }
      console.log('Hook 捕获到 Cookie 设置 ->', val);
      cookieTemp = val;
      return val;
    },
    get: function () {
      return cookieTemp;
    }
  });
})();

方式二:使用 __defineSetter__(已废弃,兼容旧环境)

(function () {
  'use strict';
  var org = document.__lookupSetter__('cookie');
  document.__defineSetter__('cookie', function (cookie) {
    if (cookie.includes('__dfp')) {
      debugger;
    }
    org = cookie;
  });
  document.__defineGetter__('cookie', function () {
    return org;
  });
})();

⚠️ 注意:__defineSetter__ 已被弃用,推荐使用 Object.defineProperty

03. 事件监听 Hook

监听用户交互事件(如点击、输入),用于追踪行为触发逻辑。

// 监听按钮点击
document.getElementById('buttonId').addEventListener('click', function () {
  console.log('按钮被点击!');
  // 可在此注入自定义逻辑
});

也可用于监听 copyinputsubmit 等敏感事件。

04. AJAX 请求拦截 Hook

通过重写 XMLHttpRequest.prototype.send,拦截所有 AJAX 请求,便于分析参数与加密逻辑。

// 保存原始方法
XMLHttpRequest.prototype._send = XMLHttpRequest.prototype.send;

XMLHttpRequest.prototype.send = function (data) {
  console.log('拦截到 AJAX 请求,发送数据:', data);
  // 可在此修改 data 或插入断点
  debugger;

  // 继续执行原方法
  this._send.apply(this, arguments);
};

05. 函数替换 Hook

替换全局函数以插入日志或断点,常用于追踪加密函数调用。

// 保存原始函数
const originalFunction = window.encryptData;

// 替换为自定义函数
window.encryptData = function (...args) {
  console.log('encryptData 被调用,参数:', args);
  debugger;

  // 调用原函数并返回结果
  return originalFunction.apply(this, args);
};

06. HTTP Header 操作 Hook

监控 setRequestHeader,定位如 AuthorizationX-Token 等关键头部字段的设置位置。

(function () {
  const originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;

  XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
    if (key === 'Authorization') {
      console.log('检测到 Authorization Header:', value);
      debugger;
    }
    // 继续执行原方法
    return originalSetRequestHeader.apply(this, arguments);
  };
})();

07. URL 请求地址 Hook

XMLHttpRequest.open 中检测请求 URL,用于定位登录、加密接口等关键请求。

(function () {
  const originalOpen = XMLHttpRequest.prototype.open;

  XMLHttpRequest.prototype.open = function (method, url, async) {
    if (url.includes('login')) {
      console.log('拦截到包含 "login" 的请求:', url);
      debugger;
    }
    return originalOpen.apply(this, arguments);
  };
})();

🔍 注意:indexOf("login") != -1 才是正确判断,原文 != 1 有误,已修正。

08. JSON.stringify Hook

监控 JSON.stringify 调用,常用于分析加密前的数据结构。

(function () {
  const originalStringify = JSON.stringify;

  JSON.stringify = function (params) {
    console.log('Hook JSON.stringify ——> ', params);
    debugger;
    return originalStringify(params);
  };
})();

09. JSON.parse Hook

监控 JSON.parse,用于查看解密后或响应返回的原始数据。

(function () {
  const originalParse = JSON.parse;

  JSON.parse = function (params) {
    console.log('Hook JSON.parse ——> ', params);
    debugger;
    return originalParse(params);
  };
})();

10. eval 函数 Hook

eval 常用于动态执行加密代码,Hook 它可查看被加密的 JS 源码。

(function () {
  // 保存原始 eval
  window.__cr_eval = window.eval;

  // 自定义 eval 包装函数
  const myeval = function (src) {
    console.log('eval 执行代码:\n', src);
    console.log('=============== eval end ===============');
    debugger;
    return window.__cr_eval(src);
  };

  // 模拟原生 toString,绕过检测
  const _myeval = myeval.bind(null);
  _myeval.toString = function () {
    return 'function eval() { [native code] }';
  };

  // 重新定义 window.eval
  Object.defineProperty(window, 'eval', {
    value: _myeval,
    writable: false,
    configurable: false
  });
})();

11. Function 构造函数 Hook

监控通过 new Function() 创建的函数,常用于反混淆。

(function () {
  // 保存原始 Function 构造函数
  window.__cr_fun = window.Function;

  // 重写 Function
  const myfun = function () {
    const args = Array.from(arguments);
    const lastArg = args.pop(); // 最后一个参数是函数体
    console.log('Function 构造函数调用,函数体:\n', lastArg);
    console.log('=============== Function end ===============');
    debugger;
    return new window.__cr_fun(...args, lastArg);
  };

  // 模拟原生 toString 行为
  myfun.toString = function () {
    return window.__cr_fun.toString();
  };

  // 重新定义 Function
  Object.defineProperty(window, 'Function', {
    value: myfun,
    writable: false,
    configurable: false
  });
})();

总结

技术 用途 关键点
DOM 操作 控制页面元素 属性/样式修改
Cookie Hook 定位 Cookie 生成 Object.defineProperty
事件监听 跟踪用户行为 addEventListener
AJAX 拦截 分析请求参数 重写 send/open
函数替换 调试加密函数 保存原函数引用
Header Hook 定位认证头 setRequestHeader
URL Hook 拦截关键请求 open 方法重写
JSON.stringify/parse 查看数据结构 前后数据对比
eval / Function 反混淆动态代码 绕过 native 检测