逆向工程核心方法论:定位、Hook、跟值与混淆对抗实战

前言

在 Web 逆向工程领域,定位、Hook、跟值分析与混淆对抗是核心技能栈。本文结合实际场景,系统性梳理逆向流程中的关键策略与技术细节,帮助读者建立结构化的逆向思维体系。

一、定位策略:从攻击到稳定的逆向流程

1. 重放攻击优先原则

目标:快速验证接口可用性
步骤

  1. 通过抓包工具(如 Charles)获取原始请求
  2. 直接重放请求,验证响应有效性(状态码、业务逻辑)
  3. 理想场景:重放成功后直接进入参数精简阶段

2. 参数精简与稳定性测试

场景分类核心流程关键操作
理想情况重放有效 → 参数精简 → 稳定性测试(几小时)保留必要参数,忽略非关键值
复杂情况重放无效 → 关键参数逆向(JS/Set-Cookie)→ 测试 → 参数精简 → 稳定性测试优先处理会话相关参数
异常崩溃稳定性测试中突发失败 → 回滚参数 → 重新验证记录参数组合变化历史

核心思想:通过最少必要参数降低暴露风险,优先处理Set-Cookie等会话关键参数。

二、Hook 技术:函数与对象的拦截实战

1. 函数 Hook 深度解析

a. 基础函数 Hook(非对象场景)

javascript

// 拦截eval函数,监控代码执行
const originalEval = window.eval;
window.eval = function(code) {
  console.log(`[Hooked] Eval: ${code}`);
  return originalEval.call(this, code);
};
b. 对象方法 Hook(原型链修改)

javascript

// 拦截数组push操作,记录参数
Array.prototype.push = (function(originalPush) {
  return function(...args) {
    console.log(`[Hooked] Push: ${JSON.stringify(args)}`);
    return originalPush.apply(this, args);
  };
})(Array.prototype.push);
c. 对抗检测方案
  • 检测手段:通过fn.toString()检测 Hook 痕迹
  • 反制措施

    javascript

    // 伪造函数toString方法
    function hookedFn() { /* 实际逻辑 */ }
    hookedFn.toString = () => "function() { /* original code */ }";
    

2. 对象属性 Hook 高级技巧

a. Cookie 监控(描述符劫持)

javascript

// 监控document.cookie读写
let _cookie = document.cookie;
Object.defineProperty(document, 'cookie', {
  get: () => _cookie,
  set: (value) => {
    console.log(`[Hooked] Cookie Set: ${value}`);
    _cookie = value;
  }
});
b. 全局对象代理(Proxy)

javascript

// 代理window对象,监控所有属性访问
const windowProxy = new Proxy(window, {
  get(target, key) {
    console.log(`[Proxy] Access: ${String(key)}`);
    return target[key];
  }
});

三、跟值分析:从同步到异步的追踪策略

1. 同步跟值核心逻辑

步骤

  1. 在密文出现处设置断点(如 XHR 响应回调)
  2. 通过调用堆栈(Call Stack)向上追溯参数来源
  3. 重点关注函数参数(Arguments)与闭包变量

工具技巧:利用 Chrome DevTools 的Step IntoStep Over逐步追踪。

2. 异步跟值难点突破

挑战:事件循环导致堆栈断裂
解决方案

  • 在异步入口(如setTimeout、Promise)设置断点
  • 使用debugger语句强制中断微任务执行
  • 监控EventEmitter事件触发点

实战技巧:在异步回调中临时插入console.trace()打印调用栈。

3. 特殊场景经验总结

特征标识可能加密方式处理策略
hex_md5函数MD5 哈希替换为 JS-md5 库验证
大数组 + 移位位运算加密记录数组索引与运算模式
RC4关键词对称加密搜索 JS 文件头部的密钥定义
自执行函数传参字符串解码打印参数值并分析编码格式

四、混淆对抗:从基础到 JSVMP 的突破

1. 常见混淆手段解析

a. 变量名混淆
  • 青铜级a,b,c → 王者级_0x4f3a = String.fromCharCode(97, 98, 99)
  • 应对:利用 IDE 重命名功能或调试器 watch 表达式映射变量。
b. 控制流平坦化

原始逻辑

javascript

a = 1; b = 2; c = a + b;

混淆后

javascript

var _step = 0;
while(true) {
  switch(_step) {
    case 0: a=1; _step=1; break;
    case 1: b=2; _step=2; break;
    case 2: c=a+b; return;
  }
}

应对:使用 AST 工具(如 AST Explorer)还原控制流。

c. 死代码注入

特征:存在未调用函数或冗余变量赋值

javascript

function unused() { var temp = "dead code"; }
unused(); // 无实际作用的调用

应对:通过代码覆盖率工具标记无效代码。

2. JSVMP(JavaScript 虚拟化保护)

核心原理

  1. 将原始代码编译为自定义指令数组(如[110, 'var', 'a']表示声明变量)
  2. 通过解释器逐指令执行,模拟寄存器和变量存储

简化示例

javascript

// 指令数组(等价于a=1+b)
const instructions = [
  [110, 'var', 'a'], // 声明变量
  [66, 'b', 2],     // 赋值
  [88, 'a', 'b']     // 加法运算
];

// 解释器
function JSVMP(instructions) {
  let reg = 0, vars = {};
  for (const [op, arg1, arg2] of instructions) {
    if (op === 110) vars[arg2] = 0; // 声明
    if (op === 66) vars[arg1] = arg2; // 赋值
    if (op === 88) reg = vars[arg1] + vars[arg2]; // 计算
  }
  return reg; // 返回3
}

应对思路

  1. 分析指令集映射关系(操作码→实际功能)
  2. 跟踪寄存器与变量的映射关系
  3. 利用动态调试工具逐指令模拟执行

五、实战方法论总结

  1. 定位阶段:先验证重放攻击,再逐步精简参数,避免过早陷入逆向细节
  2. Hook 阶段:优先使用 Proxy 进行对象拦截,函数 Hook 需注意对抗检测
  3. 跟值阶段:同步依赖堆栈追踪,异步依赖事件断点,JSVMP 需指令集分析
  4. 混淆处理:先格式化代码,再移除死代码,最后分析控制流逻辑

关键认知:逆向工程是经验驱动的决策过程,需根据实际场景动态调整策略,同时遵守法律边界,确保技术的合理应用。

​​
声明:本文仅用于技术交流,严禁用于非法用途。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值