Java混淆案例

wen java案例 2

本文目录导读:

Java混淆案例

  1. 基础混淆案例
  2. 控制流混淆案例
  3. 完整混淆案例
  4. 使用工具混淆案例(ProGuard)
  5. 高级混淆综合案例
  6. 防护建议

我来为您详细介绍Java混淆的案例,包括常见的混淆技术、实际示例以及防护措施。

基础混淆案例

名称混淆(最简单的混淆)

原始代码:

public class UserController {
    private UserService userService;
    public User getUserById(Long userId) {
        return userService.findById(userId);
    }
    public void saveUser(User user) {
        userService.save(user);
    }
}

混淆后:

public class a {
    private b c;
    public d e(Long f) {
        return c.g(f);
    }
    public void h(d i) {
        c.j(i);
    }
}

字符串加密混淆

原始代码:

public class LoginService {
    private static final String DB_CONNECTION = "jdbc:mysql://localhost:3306/mydb";
    private static final String SECRET_KEY = "MySecretKey123";
    public boolean checkPassword(String input) {
        return input.equals("admin123");
    }
}

加密混淆后(简化的示例):

public class LoginService {
    private static final String DB_CONNECTION = decrypt("\u8F9E\u7A0B\u53D8\u91CF...");
    private static String decrypt(String data) {
        char[] chars = data.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            chars[i] = (char)(chars[i] ^ 0x5A);
        }
        return new String(chars);
    }
}

控制流混淆案例

控制流平坦化

原始代码:

public void processOrder(Order order) {
    if (order.isValid()) {
        if (order.getType() == 1) {
            processNormal(order);
        } else {
            processSpecial(order);
        }
    } else {
        rejectOrder(order);
    }
    if (order.getStatus() == 0) {
        sendNotification(order);
    }
}

平坦化混淆后:

public void processOrder(Order order) {
    int state = 0;
    boolean[] flags = new boolean[10];
    while (true) {
        switch (state) {
            case 0:
                if (order.isValid()) {
                    state = 1;
                } else {
                    state = 4;
                }
                break;
            case 1:
                if (order.getType() == 1) {
                    state = 2;
                } else {
                    state = 3;
                }
                break;
            case 2:
                processNormal(order);
                state = 5;
                break;
            case 3:
                processSpecial(order);
                state = 5;
                break;
            case 4:
                rejectOrder(order);
                state = 5;
                break;
            case 5:
                if (order.getStatus() == 0) {
                    state = 6;
                } else {
                    state = 7;
                }
                break;
            case 6:
                sendNotification(order);
                state = 7;
                break;
            case 7:
                return;
        }
    }
}

不透明谓词混淆

原始代码:

public void transferFunds(double amount) {
    if (amount > 0 && this.balance >= amount) {
        this.balance -= amount;
        logTransaction(amount);
    }
}

不透明谓词混淆后:

public void transferFunds(double amount) {
    // 使用永远为真的不透明谓词
    int x = 5;
    int y = 7;
    boolean alwaysTrue = (x * y == 35);
    if (alwaysTrue) {
        if (amount > 0 && this.balance >= amount) {
            this.balance -= amount;
            logTransaction(amount);
        }
    }
    // 使用永远为假的不透明谓词,添加冗余代码
    int p = 10;
    int q = 20;
    boolean alwaysFalse = (p * q == 1000);
    if (alwaysFalse) {
        // 永远不会执行的代码
        System.out.println("This code never executes");
    }
}

完整混淆案例

原始功能类:

public class PaymentProcessor {
    private static final String ENCRYPTION_KEY = "SecureKey#2024";
    private double balance;
    public boolean makePayment(String creditCard, double amount) {
        if (amount <= 0) {
            return false;
        }
        if (creditCard.length() != 16) {
            return false;
        }
        if (balance < amount) {
            return false;
        }
        balance -= amount;
        return true;
    }
    private String encryptData(String data) {
        // 简单的加密逻辑
        StringBuilder encrypted = new StringBuilder();
        for (char c : data.toCharArray()) {
            encrypted.append((char)(c ^ ENCRYPTION_KEY.length()));
        }
        return encrypted.toString();
    }
}

多重混淆后:

public class a {
    private static final String[] b = {new String(new char[]{'S','e','c','u','r','e','K','e','y'}), "#2024"};
    private double c;
    public boolean d(String e, double f) {
        int g = 0;
        boolean h = false;
        // 控制流混淆
        String[] i = new String[10];
        int[] j = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
        for (int k = 0; k < 10; k++) {
            switch (j[k]) {
                case 1:
                    if (f > 0) {
                        g++;
                    }
                    break;
                case 2:
                    if (e.length() == 16) {
                        g++;
                    }
                    break;
                case 3:
                    if (c < f) {
                        h = true;
                    }
                    break;
                case 4:
                    if (!h && g == 3) {
                        c -= f;
                        h = true;
                        g = 10;
                    }
                    break;
                default:
                    break;
            }
        }
        return g == 10 && h;
    }
    private String l(String m) {
        char[] n = m.toCharArray();
        for (int o = 0; o < n.length; o++) {
            n[o] = (char)(n[o] ^ b[0].length() + Integer.parseInt(b[1].substring(1)));
        }
        return new String(n);
    }
}

使用工具混淆案例(ProGuard)

配置文件示例:

# proguard-rules.pro
-keep public class com.example.MainApplication {
    public static void main(java.lang.String[]);
}
-keep class com.example.core.** {
    *;
}
-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}
-obfuscationdictionary dictionary.txt
-packageobfuscationdictionary dictionary.txt
-classobfuscationdictionary dictionary.txt
-overloadaggressively
-optimizationpasses 5
-allowaccessmodification
-mergeinterfacesaggressively

混淆前后对比:

混淆前:

public class Customer {
    private String firstName;
    private String lastName;
    private int age;
    public String getFullName() {
        return firstName + " " + lastName;
    }
    public boolean isAdult() {
        return age >= 18;
    }
}

ProGuard混淆后:

public class a {
    private String a;
    private String b;
    private int c;
    public String a() {
        return this.a + " " + this.b;
    }
    public boolean b() {
        return this.c >= 18;
    }
}

高级混淆综合案例

反射+加密+控制流混淆:

public class SecureDataHandler {
    private String[] encryptedData = {
        "x9dK#2mQ", "PqR5#vL8", "mN3#bWx7"
    };
    public String getData(int index) {
        int key = 3; // 解密的密钥
        char[] chars = encryptedData[index].toCharArray();
        // 使用反射增加复杂度
        try {
            Class<?> stringBuilder = Class.forName("java.lang.StringBuilder");
            Object sb = stringBuilder.getConstructor().newInstance();
            java.lang.reflect.Method append = stringBuilder.getMethod("append", char.class);
            java.lang.reflect.Method toString = stringBuilder.getMethod("toString");
            for (int i = 0; i < chars.length; i++) {
                chars[i] = (char)(chars[i] - key + i);
                append.invoke(sb, chars[i]);
            }
            // 额外添加混淆逻辑
            if (chars.length > 0) {
                reverseString(generateDummyData());
            }
            return (String)toString.invoke(sb);
        } catch (Exception e) {
            return null;
        }
    }
    private String generateDummyData() {
        // 为了混淆,添加无意义但看起来很复杂的代码
        int x = 42;
        double y = Math.PI;
        return "Obfuscated-" + x + "-" + y;
    }
}

防护建议

针对混淆,建议采取以下措施:

  1. 合法合规使用:确保混淆不违反任何开源许可证
  2. 性能权衡:过度混淆可能影响性能
  3. 测试充分:混淆后必须进行完整性测试
  4. 日志维护:保留混淆映射文件便于问题排查
  5. 结合多种技术:混合使用多种混淆技术提高安全性

混淆不是绝对安全,只是一个安全措施,它增加了逆向工程的难度,但不能完全阻止专业逆向工程师的分析。

抱歉,评论功能暂时关闭!