
Java里用正则做字符串替换混淆,String.replaceAll() 是最直接的路
它快、内置、不用引第三方,适合基础混淆场景——比如把变量名 userName 批量替换成 a1。但注意:replaceAll() 第一个参数是正则表达式,不是普通字符串,直接传 "user" 可能误杀 username 里的 user,或匹配到注释/字符串字面量里。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 用
Pattern.quote("user")包裹要替换的原始标识符,避免正则元字符干扰 - 加单词边界
\b,写成"\b" + Pattern.quote(oldName) + "\b",防止子串误替 - 先用
source.contains(oldName)快速筛一遍,避免无谓正则编译开销 - 别在源码字符串里直接替换——得先跳过双引号内、
//和/* */注释内容,否则会破坏字面量
跳过字符串和注释再替换,得手写简易词法扫描
Java 源码不是纯文本,"user" 或 // user is online 里的 user 绝对不能动。靠正则“完美”处理所有边界几乎不可能,简单可靠的做法是逐字符扫描,用状态机区分:代码区 / 字符串内 / 单行注释 / 多行注释。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 维护一个
inString布尔值,遇到未转义的"就翻转;再加inComment标记是否在//或/*后 - 遇到
//要检查前一个字符是不是/,且不在字符串里——否则可能是除法int a = b/c; - 多行注释的
/*和*/需要成对识别,中间全跳过,不参与任何替换 - 状态切换时记录位置,只在
inString == false && inComment == false区域做replaceAll()
混淆后编译报错?大概率是关键字冲突或语法破坏
把 class 替成 a,或者把 return 替成 r,编译器立刻报错。更隐蔽的是:替换后出现连续下划线 __a、以数字开头 1var、或和保留字同名(如 int → int),JDK 8+ 会拒绝加载类文件。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 预定义黑名单:Java 关键字列表(
"if","for","class"…)、基本类型名("int","boolean")、常用类名("String","System") - 生成新名时强制以字母开头,只含字母数字,长度 ≥ 2(避开单字母如
a被当局部变量误判) - 替换完跑一次
javac -Xlint:all,比看日志更快定位语法问题 - 别混淆
main方法签名、注解值、反射用的字符串(如@WebServlet("/user"))——这些必须人工白名单保护
真要上生产?别自己写混淆脚本
ProGuard、R8、Allatori 这些工具早把符号表分析、控制流扁平化、字符串加密、反调试等跑熟了。你写的替换脚本顶多算“重命名预处理”,连字段访问权限(private vs public)都分不清,更别说处理泛型擦除后 List<string></string> 和 List<integer></integer> 的桥接方法。
如果只是想快速改掉几个测试类里的敏感变量名,上面三步够用;但只要涉及 jar 包、依赖、反射调用、或需要保证运行时不崩溃,绕过专业工具就是给自己埋 runtime exception。










