
下载、查壳、jadx反编译打开encoder类和MainActlvity 类这道题的核心逻辑分为两个类Encoder加密算法类和MainActlvity主界面 反射改密钥类下面逐行拆解。一、Encoder 类加密核心public class Encoder { // 【迷惑项】初始默认密钥private私有外部无法直接访问 private int key 123456789; // 加密方法输入明文字符串输出密文字符串 public String encode(String str) { StringBuilder sb new StringBuilder(); // 遍历输入字符串的每一个字符 for (char c : str.toCharArray()) { // 核心运算字符 与 key 做异或运算强转为char类型拼接 sb.append((char) (c ^ this.key)); } return sb.toString(); } }逻辑说明加密算法单字节异或对称加密。加密密文字符 明文字符 ^ 密钥解密明文字符 密文字符 ^ 密钥异或是可逆运算同一个密钥运算两次就还原明文数据类型Java 的char是 16 位 Unicode 字符因此异或后会得到中文类的宽字符也就是我们看到的乱码密文。坑点提示这里的key 123456789是写死的初始值但程序运行时并不会用这个值后面会通过反射动态修改。二、MainActlvity 类反射改密钥核心考点public class MainActlvity { public MainActlvity() { try { // 1. 获取Encoder类中名为key的私有字段 Field declaredField Encoder.class.getDeclaredField(key); // 2. 暴力反射打破private访问权限限制 declaredField.setAccessible(true); // 3. 动态修改将encoder对象的key字段设置为新值 987654321 declaredField.set(MainActivity.encoder, 987654321); } catch (IllegalAccessException | NoSuchFieldException e) { e.printStackTrace(); } } }逐行逻辑getDeclaredField(key)反射获取Encoder类的key成员变量。因为key是private私有的常规方式访问不到必须用反射。setAccessible(true)开启暴力访问忽略 Java 的访问修饰符检查才能修改 private 字段。set(..., 987654321)把全局encoder实例的key值从原来的123456789覆盖为987654321。✅程序运行时真实生效的加密密钥是 987654321不是类里写的 123456789这是这道题最核心的考点。三、完整校验流程结合题目逻辑APP 启动时创建MainActlvity实例构造方法执行通过反射把Encoder的key改成987654321。用户在输入框输入 flag点击校验按钮。调用encoder.encode(输入内容)用修改后的密钥 987654321对输入做异或加密。把加密后的结果和代码里固定的密文字符串棿棢棢棲棥棷棊棐棁棚棨棨棵棢棌做对比。完全相等则提示验证成功否则失败。成员变量public static Encoder encoder;静态加密类引用Encoder 是外部类截图看不到实现。public static MainActivity mainActivity;静态 Activity 引用mainActivity new MainActivity();这行写法不符合 Android 规范Activity 不能直接 new该行不会参与业务逻辑属于冗余无效代码。onCreate 生命周期方法setContentView(R.layout.activity_main)加载布局页面findViewById获取输入框、按钮控件给按钮绑定点击事件点击时调用lambda$onCreate$0$MainActivity方法。lambda$onCreate$0$MainActivitysynthetic 合成方法Java 编译 lambda / 匿名内部类时自动生成不是开发者手写的原始方法名。校验逻辑 lambda$onCreate000MainActivity获取输入框文本调用encoder.encode()做加密把加密结果打印控制台关键条件用户输入 → encode加密 → 和写死的中文密文字符串比对如果加密结果等于梡椆梮棜椋椒粜棐棁梲棨槮梀→ Toast 弹出YES否则弹出NOToast第三个参数 0等价Toast.LENGTH_SHORT短时弹窗。写解密脚本cipher棿棢棢棲棥棷棊棐棁棚棨棨棵棢棌key987654321flagforcincipher:flagchr((ord(c)^key)%128);print(flag)对128取模的原因是因为ASCII字符集只有128个字符所以如果不取模那么异或运算的结果可能超出ASCII范围导致无法正确解密。取模128可以保证结果在0到127之间也就是ASCII字符集的有效范围。本题知识点1、查壳2、加后缀名3、知道函数逻辑4、知道对128求余