JS逆向-常见的混淆手段

274 阅读3分钟

Obfuscation 混淆

代码混淆(Obfuscation)是一种将计算机程序的代码转换为功能上等价,但结构和逻辑更难以理解和分析的形式的技术。下面从目的、常见方法、优缺点以及实际应用场景等方面详细介绍

目的

  • 保护知识产权:防止代码被轻易反编译和逆向工程,避免他人窃取代码中的算法、商业逻辑等核心信息。比如,一款商业软件的开发者通过混淆代码,能让竞争对手难以抄袭其独特的功能实现。

  • 防止恶意攻击:增加攻击者分析代码的难度,降低代码被篡改、注入恶意代码等风险。像一些 Web 应用程序,通过混淆代码可以减少 XSS(跨站脚本攻击)、SQL 注入等攻击的可能性

常见的JS混淆方式

在 JavaScript 里,代码混淆是一种把代码转化成难以理解和逆向工程的技术,以此保护代码的知识产权和防止恶意攻击。以下是一些常见的 JavaScript 混淆方式:

变量和函数名混淆

将有意义的变量名和函数名替换成无意义的字符串,让代码难以阅读和理解。

// 原始代码
function calculateSum(a, b) {
    return a + b;
}
let result = calculateSum(1, 2);

// 混淆后代码
function _0xabc(a, b) {
    return a + b;
}
let _0xdef = _0xabc(1, 2);

代码结构打乱

改变代码的执行顺序,插入无用代码,增加代码的复杂度。

// 原始代码
function greet(name) {
    return 'Hello, ' + name;
}
let message = greet('John');

// 混淆后代码
function greet(name) {
    let temp;
    temp = 'Hello, ';
    return temp + name;
    let unused = 10; // 无用代码
}
let message;
let tempResult = greet('John');
message = tempResult;

字符串编码

对代码中的字符串进行编码,在运行时再进行解码,防止字符串被轻易提取。

// 原始代码
let message = 'Hello, World!';
console.log(message);

// 混淆后代码
let encodedMessage = 'SGVsbG8sIFdvcmxkIQ=='; // Base64 编码
let decodedMessage = atob(encodedMessage);
console.log(decodedMessage);

控制流扁平化

把复杂的控制流结构(如循环、条件语句)转化为扁平的结构,让代码逻辑更难理解。

// 原始代码
function isEven(num) {
    if (num % 2 === 0) {
        return true;
    } else {
        return false;
    }
}

// 混淆后代码(简单示例)
function isEven(num) {
    let result;
    let condition = num % 2 === 0;
    if (condition) {
        result = true;
    } else {
        result = false;
    }
    return result;
}

代码分割与合并

将代码分割成多个小函数,然后以复杂的方式合并调用,增加代码的分析难度。

// 原始代码
function calculateProduct(a, b) {
    return a * b;
}
let result = calculateProduct(3, 4);

// 混淆后代码
function multiplyPart1(a) {
    return a;
}
function multiplyPart2(b) {
    return b;
}
function combine(a, b) {
    return a * b;
}
let partA = multiplyPart1(3);
let partB = multiplyPart2(4);
let result = combine(partA, partB);

自修改代码

让代码在运行时动态修改自身,使得静态分析工具难以分析代码逻辑。不过这种方式比较复杂,使用场景相对较少。

function selfModifyingFunction() {
    let code = `function newFunction() { return 'Modified!'; }`;
    eval(code);
    return newFunction();
}
console.log(selfModifyingFunction());

内置函数替换

用自定义函数替换内置函数,让代码行为更难预测。

// 原始代码
let str = 'Hello';
let upperCaseStr = str.toUpperCase();

// 混淆后代码
function customToUpperCase(str) {
    return str.toUpperCase();
}
let str = 'Hello';
let upperCaseStr = customToUpperCase(str);