@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()); }
private void addTraitButtonActionPerformed(ActionEvent evt) { int class_index = decompiledTextArea.getClassIndex(); if (class_index < 0) { return; } if (newTraitDialog == null) { newTraitDialog = new NewTraitDialog(); } int void_type = abc.constants.getPublicQnameId( "void", true); // abc.constants.forceGetMultinameId(new Multiname(Multiname.QNAME, // abc.constants.forceGetStringId("void"), abc.constants.forceGetNamespaceId(new // Namespace(Namespace.KIND_PACKAGE, abc.constants.forceGetStringId("")), 0), -1, // -1, new ArrayList<Integer>())); int int_type = abc.constants.getPublicQnameId( "int", true); // abc.constants.forceGetMultinameId(new Multiname(Multiname.QNAME, // abc.constants.forceGetStringId("int"), abc.constants.forceGetNamespaceId(new // Namespace(Namespace.KIND_PACKAGE, abc.constants.forceGetStringId("")), 0), -1, // -1, new ArrayList<Integer>())); Trait t = null; int kind; int nskind; String name = null; boolean isStatic; Multiname m; boolean again = false; loopm: do { if (again) { View.showMessageDialog( null, AppStrings.translate("error.trait.exists").replace("%name%", name), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); } again = false; if (newTraitDialog.showDialog() != AppDialog.OK_OPTION) { return; } kind = newTraitDialog.getTraitType(); nskind = newTraitDialog.getNamespaceKind(); name = newTraitDialog.getTraitName(); isStatic = newTraitDialog.getStatic(); m = new Multiname( Multiname.QNAME, abc.constants.getStringId(name, true), abc.constants.getNamespaceId( new Namespace(nskind, abc.constants.getStringId("", true)), 0, true), 0, 0, new ArrayList<>()); int mid = abc.constants.getMultinameId(m); if (mid == 0) { break; } for (Trait tr : abc.class_info.get(class_index).static_traits.traits) { if (tr.name_index == mid) { again = true; break; } } for (Trait tr : abc.instance_info.get(class_index).instance_traits.traits) { if (tr.name_index == mid) { again = true; break; } } } while (again); switch (kind) { case Trait.TRAIT_GETTER: case Trait.TRAIT_SETTER: case Trait.TRAIT_METHOD: TraitMethodGetterSetter tm = new TraitMethodGetterSetter(); MethodInfo mi = new MethodInfo( new int[0], void_type, abc.constants.getStringId(name, true), 0, new ValueKind[0], new int[0]); int method_info = abc.addMethodInfo(mi); tm.method_info = method_info; MethodBody body = new MethodBody(); body.method_info = method_info; body.init_scope_depth = 1; body.max_regs = 1; body.max_scope_depth = 1; body.max_stack = 1; body.exceptions = new ABCException[0]; AVM2Code code = new AVM2Code(); code.code.add(new AVM2Instruction(0, new GetLocal0Ins(), new int[0])); code.code.add(new AVM2Instruction(0, new PushScopeIns(), new int[0])); code.code.add(new AVM2Instruction(0, new ReturnVoidIns(), new int[0])); body.setCode(code); Traits traits = new Traits(); traits.traits = new ArrayList<>(); body.traits = traits; abc.addMethodBody(body); mi.setBody(body); t = tm; break; case Trait.TRAIT_SLOT: case Trait.TRAIT_CONST: TraitSlotConst ts = new TraitSlotConst(); ts.type_index = int_type; ts.value_kind = ValueKind.CONSTANT_Int; ts.value_index = abc.constants.getIntId(0, true); t = ts; break; } if (t != null) { t.kindType = kind; t.name_index = abc.constants.getMultinameId(m, true); int traitId; if (isStatic) { traitId = abc.class_info.get(class_index).static_traits.addTrait(t); } else { traitId = abc.class_info.get(class_index).static_traits.traits.size() + abc.instance_info.get(class_index).instance_traits.addTrait(t); } reload(); decompiledTextArea.gotoTrait(traitId); } }