FlowTransformer который обфуцирует код
Для начала давайте узнаем зачем нужен FlowTransformer -данный трансформер нужен для байткода JAVA, который используется для изменения структуры кода и его поведения. Получается он нужен для усложнения кода и его анализа.
Пример обфускации кода
Вот такая вот обфускация получилось, надеюсь вам понравился данный пост, если будет большая активность сделай простенькую обфускаю булеан элементов
Для начала давайте узнаем зачем нужен FlowTransformer -данный трансформер нужен для байткода JAVA, который используется для изменения структуры кода и его поведения. Получается он нужен для усложнения кода и его анализа.
Java:
// TODO: Code create https://discord.gg/fn3YRpBjkS
public class ModifierFlow implements ClassModifier {
@Override
public void modify(ClassNode node) {
for (MethodNode method : node.methods) {
if (!method.name.startsWith("<")) {
List<AbstractInsnNode> nodesToRemove = new ArrayList<>();
for (AbstractInsnNode insnNode : method.instructions.toArray()) {
int opcode = insnNode.getOpcode();
if (shouldBeModified(opcode)) {
mutateInstruction(method, insnNode);
}
}
}
}
}
private boolean shouldBeModified(int opcode) {
return opcode == Opcodes.DUP ||
opcode == Opcodes.POP ||
opcode == Opcodes.SWAP ||
opcode == Opcodes.FSUB ||
opcode == Opcodes.ISUB ||
opcode == Opcodes.DSUB ||
opcode == Opcodes.ATHROW ||
opcode == Opcodes.IXOR; // Добавление IXOR для мутации
}
private void mutateInstruction(MethodNode method, AbstractInsnNode insnNode) {
Random random = new Random();
int mutationType = random.nextInt(9); // Увеличение количества типов мутаций
switch (mutationType) {
case 0: // Вставка случайных инструкций
for (int i = 0; i < 1 + random.nextInt(5); i++) {
method.instructions.insertBefore(insnNode, new LdcInsnNode(NameGen.String(random.nextInt(5))));
method.instructions.insertBefore(insnNode, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "length", "()I", false));
method.instructions.insertBefore(insnNode, new LdcInsnNode(NameGen.String(random.nextInt(5))));
method.instructions.insertBefore(insnNode, new InsnNode(Opcodes.POP));
if (random.nextBoolean()) {
method.instructions.insertBefore(insnNode, new InsnNode(Opcodes.DUP));
method.instructions.insertBefore(insnNode, new InsnNode(Opcodes.POP2));
} else {
method.instructions.insertBefore(insnNode, new InsnNode(Opcodes.DUP));
method.instructions.insertBefore(insnNode, new InsnNode(Opcodes.POP));
method.instructions.insertBefore(insnNode, new InsnNode(Opcodes.POP));
}
}
break;
case 1: // Замена инструкции на NOP
method.instructions.insertBefore(insnNode, new InsnNode(Opcodes.NOP));
break;
case 2: // Удаление инструкции
method.instructions.remove(insnNode);
break;
case 3: // Мутация стека
if (insnNode.getOpcode() == Opcodes.DUP) {
// Замена DUP на SWAP
method.instructions.insertBefore(insnNode, new InsnNode(Opcodes.SWAP));
// Вставка POP2
method.instructions.insertBefore(insnNode, new InsnNode(Opcodes.POP2));
}
break;
case 4: // Преобразование IXOR в IADD
if (insnNode.getOpcode() == Opcodes.IXOR) {
method.instructions.set(insnNode, new InsnNode(Opcodes.IADD));
}
break;
case 5: // Вставка бесполезных инструкций
for (int i = 0; i < 3 + random.nextInt(5); i++) {
method.instructions.insertBefore(insnNode, new InsnNode(Opcodes.DUP));
method.instructions.insertBefore(insnNode, new InsnNode(Opcodes.POP));
method.instructions.insertBefore(insnNode, new InsnNode(Opcodes.SWAP));
}
break;
case 6: // Вставка ложных ветвлений
LabelNode label = new LabelNode();
method.instructions.insertBefore(insnNode, new JumpInsnNode(Opcodes.IFNE, label));
method.instructions.insertBefore(insnNode, new LdcInsnNode(0));
method.instructions.insertBefore(insnNode, new JumpInsnNode(Opcodes.GOTO, label));
method.instructions.insertBefore(insnNode, label);
break;
case 7: // Изменение порядка инструкций
AbstractInsnNode prevInsn = insnNode.getPrevious();
if (prevInsn != null) {
method.instructions.remove(prevInsn);
method.instructions.insertBefore(insnNode, prevInsn);
}
break;
case 8: // Вставка массивов
int arraySize = 1 + random.nextInt(5);
Type arrayType = Type.INT_TYPE;
if (random.nextBoolean()) {
arrayType = Type.DOUBLE_TYPE;
}
method.instructions.insertBefore(insnNode, new IntInsnNode(Opcodes.BIPUSH, arraySize));
method.instructions.insertBefore(insnNode, new TypeInsnNode(Opcodes.ANEWARRAY, arrayType.getInternalName()));
break;
}
}
}
Java:
public class Example {
private int f;
public Example(int v) {
this.f = v;
}
public void e(int v) {
this.f = v;
}
public int d() {
return this.f;
}
public static void main(String[] args) {
Example a = new Example(10);
System.out.println("test1: " + a.d());
a.e(20);
System.out.println("test2: " + a.d());
}
}