@Override public void deobfuscate( String path, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) throws InterruptedException { // body.getCode().markMappedOffsets(); // removeUnreachableActions(body.getCode(), cpool, trait, minfo, body); AVM2Code code = body.getCode(); boolean found; do { found = false; Map<Integer, List<Integer>> refs = body.getCode().visitCode(body); loopi: for (int i = 0; i < code.code.size(); i++) { AVM2Instruction ins = code.code.get(i); if (ins.definition instanceof JumpIns) { long targetAddr = ins.offset + ins.operands[0] + ins.getBytesLength(); { for (int r : refs.get(i)) { if (r >= 0) { // Not Exception start/end AVM2Instruction srcIns = code.code.get(r); if ((srcIns.definition instanceof JumpIns) || ((srcIns.definition instanceof IfTypeIns) && (r != i - 1))) { { int oldop = srcIns.operands[0]; srcIns.operands[0] = (int) (targetAddr - (srcIns.offset + srcIns.getBytesLength())); if (srcIns.operands[0] != oldop) { found = true; } } } } } } } } removeUnreachableActions(body.getCode(), cpool, trait, minfo, body); } while (found); }
private int getFirstRegisterSetter( Reference<AVM2Instruction> assignment, int classIndex, boolean isStatic, int scriptIndex, ABC abc, MethodBody body, Set<Integer> ignoredRegisters, Set<Integer> ignoredGets) throws InterruptedException { AVM2Code code = body.getCode(); if (code.code.isEmpty()) { return -1; } return visitCode( assignment, new HashSet<>(), new TranslateStack("deo"), classIndex, isStatic, body, scriptIndex, abc, code, 0, code.code.size() - 1, ignoredRegisters, ignoredGets); }
@Override public void avm2CodeRemoveTraps( String path, int classIndex, boolean isStatic, int scriptIndex, ABC abc, Trait trait, int methodInfo, MethodBody body) throws InterruptedException { AVM2Code code = body.getCode(); code.removeDeadCode(body); removeObfuscationIfs(classIndex, isStatic, scriptIndex, abc, body, null); removeZeroJumps(code, body); }
protected boolean removeObfuscationIfs( int classIndex, boolean isStatic, int scriptIndex, ABC abc, MethodBody body, AVM2Instruction inlineIns) throws InterruptedException { AVM2Code code = body.getCode(); if (code.code.isEmpty()) { return false; } Map<Integer, Object> staticRegs = new HashMap<>(); if (inlineIns != null && inlineIns.definition instanceof GetLocalTypeIns) { staticRegs.put( ((GetLocalTypeIns) inlineIns.definition).getRegisterId(inlineIns), Undefined.INSTANCE); } if (code.code.isEmpty()) { return false; } FixItemCounterStack stack = new FixItemCounterStack(); LocalDataArea localData = new LocalDataArea(); localData.operandStack = stack; int localReservedCount = body.getLocalReservedCount(); for (int i = 0; i < code.code.size(); i++) { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } localData.clear(); initLocalRegs(localData, localReservedCount, body.max_regs, i == 0); if (executeInstructions( staticRegs, body, abc, code, localData, i, code.code.size() - 1, null, inlineIns)) { code.removeDeadCode(body); i--; } } return false; }
@Override public void avm2CodeRemoveTraps( String path, int classIndex, boolean isStatic, int scriptIndex, ABC abc, Trait trait, int methodInfo, MethodBody body) throws InterruptedException { // System.err.println("regdeo:" + path); MethodBody originalBody = body; body.getCode().removeDeadCode(body); Set<Integer> ignoredRegs = new HashSet<>(); int localReservedCount = body.getLocalReservedCount(); for (int i = 0; i < localReservedCount; i++) { ignoredRegs.add(i); } int setReg = 0; List<Integer> listedRegs = new ArrayList<>(); List<MethodBody> listedLastBodies = new ArrayList<>(); Set<Integer> ignoredRegGets = new HashSet<>(); Reference<AVM2Instruction> assignmentRef = new Reference<>(null); while (setReg > -1) { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } MethodBody bodybefore = body; body = bodybefore.clone(); setReg = getFirstRegisterSetter( assignmentRef, classIndex, isStatic, scriptIndex, abc, body, ignoredRegs, ignoredRegGets); // System.err.println("setreg " + setReg + " ass:" + assignmentRef.getVal()); if (setReg < 0) { break; } // if there is second assignment if (listedRegs.contains(setReg)) { // System.err.println("second assignment of loc" + setReg + ", ignoring"); int lindex = listedRegs.indexOf(setReg); body = listedLastBodies.get(lindex); // switch to body before ignoredRegs.add(setReg); // this is not obfuscated for (int i = listedRegs.size() - 1; i >= lindex; i--) { int r = listedRegs.get(i); listedRegs.remove(i); listedLastBodies.remove(i); ignoredRegGets.remove(r); } continue; } AVM2Instruction assignment = assignmentRef.getVal(); InstructionDefinition def = assignment.definition; if ((def instanceof SetLocalTypeIns) || (def instanceof GetLocalTypeIns /*First usage -> value undefined*/)) { super.removeObfuscationIfs( classIndex, isStatic, scriptIndex, abc, body, Arrays.asList(assignment)); } if (def instanceof GetLocalTypeIns) { ignoredRegGets.add(setReg); } listedRegs.add(setReg); listedLastBodies.add(bodybefore); } body.getCode().removeDeadCode(body); originalBody.exceptions = body.exceptions; originalBody.setCode(body.getCode()); }