feat(core): update privacy protection rules

This commit is contained in:
zpj80231
2026-06-16 17:18:33 +08:00
parent 1c218010fe
commit a70b9798c6
10 changed files with 530 additions and 107 deletions

View File

@@ -1,13 +1,19 @@
package com.novitechie;
import com.janetfilter.core.commons.DebugInfo;
import com.janetfilter.core.plugin.MyTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.*;
import java.util.ListIterator;
import static org.objectweb.asm.Opcodes.*;
public class LicensingFacadeTransformer implements MyTransformer {
private static final int ASM_VERSION = ASM9;
@Override
public String getHookClassName() {
return "com/intellij/ui/LicensingFacade";
@@ -15,24 +21,70 @@ public class LicensingFacadeTransformer implements MyTransformer {
@Override
public byte[] transform(String className, byte[] classBytes, int order) throws Exception {
ClassReader reader = new ClassReader(classBytes);
ClassNode node = new ClassNode(ASM5);
reader.accept(node, 0);
for (MethodNode m : node.methods) {
if ("getLicenseExpirationDate".equals(m.name)) {
InsnList list = new InsnList();
LabelNode L0 = new LabelNode();
list.add(new MethodInsnNode(INVOKESTATIC, "com/novitechie/rules/StackTraceRule", "hook", "()Ljava/util/Date;", false));
list.add(new InsnNode(DUP));
list.add(new JumpInsnNode(IFNULL, L0));
list.add(new InsnNode(ARETURN));
list.add(L0);
list.add(new InsnNode(POP));
m.instructions.insert(list);
if (classBytes == null || classBytes.length == 0) {
return classBytes;
}
try {
ClassReader reader = new ClassReader(classBytes);
ClassNode node = new ClassNode(ASM_VERSION);
reader.accept(node, 0);
for (MethodNode m : node.methods) {
if ("getLicenseExpirationDate".equals(m.name)) {
InsnList list = new InsnList();
LabelNode L0 = new LabelNode();
list.add(new MethodInsnNode(INVOKESTATIC, "com/novitechie/rules/StackTraceRule", "hook", "()Ljava/util/Date;", false));
list.add(new InsnNode(DUP));
list.add(new JumpInsnNode(IFNULL, L0));
list.add(new InsnNode(ARETURN));
list.add(L0);
list.add(new InsnNode(POP));
m.instructions.insert(list);
} else if ("toJson".equals(m.name) && "()Ljava/lang/String;".equals(m.desc)) {
insertToJsonFilterSecure(m);
}
}
ClassWriter writer = new SafeClassWriter(null, null, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
node.accept(writer);
return writer.toByteArray();
} catch (Exception e) {
DebugInfo.warn("[PRIVACY] Failed to transform LicensingFacade, skipping", e);
return classBytes;
}
}
private void insertToJsonFilterSecure(MethodNode m) {
if (m.instructions == null || m.instructions.size() == 0) {
return;
}
int originalJsonIdx = m.maxLocals;
int filteredJsonIdx = originalJsonIdx + 1;
m.maxLocals += 2;
ListIterator<AbstractInsnNode> iterator = m.instructions.iterator();
while (iterator.hasNext()) {
AbstractInsnNode current = iterator.next();
if (current.getOpcode() == ARETURN) {
LabelNode useOriginalLabel = new LabelNode();
LabelNode endLabel = new LabelNode();
InsnList patch = new InsnList();
patch.add(new VarInsnNode(ASTORE, originalJsonIdx));
patch.add(new VarInsnNode(ALOAD, originalJsonIdx));
patch.add(new MethodInsnNode(INVOKESTATIC, "com/novitechie/rules/LicenseRule", "filterJson", "(Ljava/lang/String;)Ljava/lang/String;", false));
patch.add(new VarInsnNode(ASTORE, filteredJsonIdx));
patch.add(new VarInsnNode(ALOAD, filteredJsonIdx));
patch.add(new JumpInsnNode(IFNULL, useOriginalLabel));
patch.add(new VarInsnNode(ALOAD, filteredJsonIdx));
patch.add(new JumpInsnNode(GOTO, endLabel));
patch.add(useOriginalLabel);
patch.add(new VarInsnNode(ALOAD, originalJsonIdx));
patch.add(endLabel);
m.instructions.insertBefore(current, patch);
}
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
node.accept(writer);
return writer.toByteArray();
}
}