diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java index 8fc43f598..33b18496e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -1072,7 +1072,7 @@ public class SWFInputStream implements AutoCloseable { * @throws java.lang.InterruptedException */ public List readTagList(Timelined timelined, int level, boolean parallel, boolean skipUnusualTags, boolean parseTags, boolean lazy) throws IOException, InterruptedException { - if (Thread.currentThread().interrupted()) { + if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorJumps.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorJumps.java index 913c71caf..465563423 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorJumps.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorJumps.java @@ -50,7 +50,7 @@ public class AVM2DeobfuscatorJumps extends AVM2DeobfuscatorSimple { 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); + //removeUnreachableInstructions(body.getCode(), cpool, trait, minfo, body); AVM2Code code = body.getCode(); boolean found; @@ -81,7 +81,7 @@ public class AVM2DeobfuscatorJumps extends AVM2DeobfuscatorSimple { } } } - removeUnreachableActions(body.getCode(), cpool, trait, minfo, body); + removeUnreachableInstructions(body.getCode(), cpool, trait, minfo, body); } while (found); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorRegisters.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorRegisters.java index 083411cc8..ba917a153 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorRegisters.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorRegisters.java @@ -46,7 +46,6 @@ import com.jpexs.decompiler.graph.TranslateException; import com.jpexs.decompiler.graph.TranslateStack; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -72,15 +71,10 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { public void deobfuscate(String path, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody abody) throws InterruptedException { //System.err.println("regdeo:" + path); - removeUnreachableActions(abody.getCode(), cpool, trait, minfo, abody); - /*for (AVM2Instruction ins : abody.getCode().code) { - System.err.println("" + ins.offset + ": " + ins); - }*/ + removeUnreachableInstructions(abody.getCode(), cpool, trait, minfo, abody); Set ignoredRegs = new HashSet<>(); - MethodBody body = abody; - - body = abody.clone(); + MethodBody body = abody.clone(); Reference assignment = new Reference<>(null); ignoredRegs.clear(); for (int i = 0; i < body.getLocalReservedCount(); i++) { @@ -100,6 +94,7 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { if (setReg < 0) { break; } + //if there is second assignment if (listedRegs.contains(setReg)) { //System.err.println("second assignment of loc" + setReg + ", ignoring"); @@ -118,23 +113,29 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { if ((assignment.getVal().definition instanceof SetLocalTypeIns) || (assignment.getVal().definition instanceof GetLocalTypeIns /*First usage -> value undefined*/)) { super.removeObfuscationIfs(classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body, Arrays.asList(assignment.getVal())); } + if (assignment.getVal().definition instanceof GetLocalTypeIns) { ignoredRegGets.add(setReg); } + listedRegs.add(setReg); listedLastBodies.add(bodybefore); } abody.exceptions = body.exceptions; abody.setCode(body.getCode()); - removeUnreachableActions(body.getCode(), cpool, trait, minfo, body); + removeUnreachableInstructions(body.getCode(), cpool, trait, minfo, body); //System.err.println("/deo"); } - private void replaceSingleUseRegisters(Map singleRegisters, List setInss, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) { + private void replaceSingleUseRegisters(Map singleRegisters, List setInss, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) throws InterruptedException { AVM2Code code = body.getCode(); for (int i = 0; i < code.code.size(); i++) { + if (Thread.currentThread().isInterrupted()) { + throw new InterruptedException(); + } + AVM2Instruction ins = code.code.get(i); if (((setInss == null) || setInss.contains(ins)) && (ins.definition instanceof SetLocalTypeIns)) { SetLocalTypeIns slt = (SetLocalTypeIns) ins.definition; @@ -143,6 +144,7 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { code.replaceInstruction(i, new AVM2Instruction(ins.offset, new DeobfuscatePopIns(), new int[]{}), body); } } + if (ins.definition instanceof GetLocalTypeIns) { GetLocalTypeIns glt = (GetLocalTypeIns) ins.definition; int regId = glt.getRegisterId(ins); @@ -155,7 +157,6 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { private int getFirstRegisterSetter(Reference assignment, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body, Set ignoredRegisters, Set ignoredGets) throws InterruptedException { AVM2Code code = body.getCode(); - Map ret = new HashMap<>(); if (code.code.isEmpty()) { return -1; @@ -187,32 +188,32 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { } visited.add(idx); - AVM2Instruction action = code.code.get(idx); - InstructionDefinition def = action.definition; - //System.err.println("" + idx + ": " + action + " stack:" + stack.size()); + AVM2Instruction ins = code.code.get(idx); + InstructionDefinition def = ins.definition; + //System.err.println("" + idx + ": " + ins + " stack:" + stack.size()); - action.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); + ins.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); //if (!(def instanceof KillIns)) if (def instanceof SetLocalTypeIns) { - int regId = ((SetLocalTypeIns) def).getRegisterId(action); + int regId = ((SetLocalTypeIns) def).getRegisterId(ins); if (!ignored.contains(regId)) { - assignment.setVal(action); + assignment.setVal(ins); return regId; } } else if (def instanceof GetLocalTypeIns) { - int regId = ((GetLocalTypeIns) def).getRegisterId(action); + int regId = ((GetLocalTypeIns) def).getRegisterId(ins); if (!ignored.contains(regId) && !ignoredGets.contains(regId)) { - assignment.setVal(action); + assignment.setVal(ins); return regId; } } else { - for (int p = 0; p < action.definition.operands.length; p++) { - int op = action.definition.operands[p]; + for (int p = 0; p < ins.definition.operands.length; p++) { + int op = ins.definition.operands[p]; if (op == AVM2Code.DAT_REGISTER_INDEX) { - int regId = action.operands[p]; + int regId = ins.operands[p]; if (!ignored.contains(regId)) { - assignment.setVal(action); + assignment.setVal(ins); return regId; } } @@ -221,17 +222,17 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { idx++; - if (action.definition instanceof JumpIns) { + if (ins.definition instanceof JumpIns) { - long address = action.offset + action.getBytesLength() + action.operands[0]; + long address = ins.offset + ins.getBytesLength() + ins.operands[0]; idx = code.adr2pos(address);//code.indexOf(code.getByAddress(address)); if (idx == -1) { throw new TranslateException("Jump target not found: " + address); } } - if (action.isBranch()) { - List branches = action.getBranches(new GraphSource() { + if (ins.isBranch()) { + List branches = ins.getBranches(new GraphSource() { @Override public int size() { @@ -274,8 +275,8 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { toVisitStacks.add((TranslateStack) stack.clone()); } } - /*if (action.definition instanceof IfTypeIns) { - long address = action.offset + action.getBytes().length + action.operands[0]; + /*if (ins.definition instanceof IfTypeIns) { + long address = ins.offset + ins.getBytes().length + ins.operands[0]; int newIdx = code.adr2pos(address); if (newIdx == -1) { throw new TranslateException("If target not found: " + address); @@ -283,15 +284,15 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { visitCode(visited, (TranslateStack) stack.clone(), classIndex, isStatic, body, scriptIndex, abc, code, newIdx, endIdx, result); }*/ - if (action.definition instanceof ReturnValueIns) { + if (ins.definition instanceof ReturnValueIns) { break; } - if (action.definition instanceof ThrowIns) { + if (ins.definition instanceof ThrowIns) { break; } - if (action.definition instanceof ReturnVoidIns) { + if (ins.definition instanceof ReturnVoidIns) { break; } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimple.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimple.java index beef52bdc..4f67df2e1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimple.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimple.java @@ -170,24 +170,28 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { } } for (int i = 0; i < code.code.size(); i++) { + if (Thread.currentThread().isInterrupted()) { + throw new InterruptedException(); + } + ExecutionResult result = new ExecutionResult(); - executeActions(staticRegs, classIndex, isStatic, body, scriptIndex, abc, code, i, code.code.size() - 1, result, inlineIns); + executeInstructions(staticRegs, classIndex, isStatic, body, scriptIndex, abc, code, i, code.code.size() - 1, result, inlineIns); } return false; } - protected void removeUnreachableActions(AVM2Code code, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) throws InterruptedException { + protected void removeUnreachableInstructions(AVM2Code code, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) throws InterruptedException { code.removeDeadCode(body); } - protected boolean removeZeroJumps(AVM2Code actions, MethodBody body) { + protected boolean removeZeroJumps(AVM2Code code, MethodBody body) { boolean result = false; - for (int i = 0; i < actions.code.size(); i++) { - AVM2Instruction action = actions.code.get(i); - if (action.definition instanceof JumpIns) { - if (action.operands[0] == 0) { - actions.removeInstruction(i, body); + for (int i = 0; i < code.code.size(); i++) { + AVM2Instruction ins = code.code.get(i); + if (ins.definition instanceof JumpIns) { + if (ins.operands[0] == 0) { + code.removeInstruction(i, body); i--; result = true; } @@ -226,7 +230,7 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { return localData; } - private void executeActions(Map staticRegs, int classIndex, boolean isStatic, MethodBody body, int scriptIndex, ABC abc, AVM2Code code, int idx, int endIdx, ExecutionResult result, List inlineIns) throws InterruptedException { + private void executeInstructions(Map staticRegs, int classIndex, boolean isStatic, MethodBody body, int scriptIndex, ABC abc, AVM2Code code, int idx, int endIdx, ExecutionResult result, List inlineIns) throws InterruptedException { List output = new ArrayList<>(); AVM2LocalData localData = newLocalData(scriptIndex, abc, abc.constants, body, isStatic, classIndex); @@ -243,8 +247,8 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { break; } - AVM2Instruction action = code.code.get(idx); - if (action.definition instanceof NewFunctionIns) { + AVM2Instruction ins = code.code.get(idx); + if (ins.definition instanceof NewFunctionIns) { if (idx + 1 < code.code.size()) { if (code.code.get(idx + 1).definition instanceof PopIns) { code.removeInstruction(idx + 1, body); @@ -253,27 +257,27 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { } } } else { - action.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); + ins.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); } - InstructionDefinition def = action.definition; + InstructionDefinition def = ins.definition; - if (inlineIns.contains(action)) { + if (inlineIns.contains(ins)) { if (def instanceof SetLocalTypeIns) { - int regId = ((SetLocalTypeIns) def).getRegisterId(action); + int regId = ((SetLocalTypeIns) def).getRegisterId(ins); staticRegs.put(regId, localData.localRegs.get(regId).getNotCoerced()); code.replaceInstruction(idx, new AVM2Instruction(0, new DeobfuscatePopIns(), new int[]{}), body); } } if (def instanceof GetLocalTypeIns) { - int regId = ((GetLocalTypeIns) def).getRegisterId(action); + int regId = ((GetLocalTypeIns) def).getRegisterId(ins); if (staticRegs.containsKey(regId)) { stack.pop(); AVM2Instruction pushins = makePush(abc.constants, staticRegs.get(regId)); code.replaceInstruction(idx, pushins, body); stack.push(staticRegs.get(regId)); - action = pushins; - def = action.definition; + ins = pushins; + def = ins.definition; } } @@ -329,7 +333,7 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { } if (def instanceof GetLocalTypeIns) { - int regId = ((GetLocalTypeIns) def).getRegisterId(action); + int regId = ((GetLocalTypeIns) def).getRegisterId(ins); if (staticRegs.containsKey(regId)) { stack.pop(); stack.push(staticRegs.get(regId)); @@ -340,41 +344,40 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { boolean ifed = false; if (def instanceof JumpIns) { - //ActionJump jump = (ActionJump) action; - long address = action.offset + action.getBytesLength() + action.operands[0]; + long address = ins.offset + ins.getBytesLength() + ins.operands[0]; idx = code.adr2pos(address); if (idx == -1) { throw new TranslateException("Jump target not found: " + address); } } else if (def instanceof IfTypeIns) { - //ActionIf aif = (ActionIf) action; GraphTargetItem top = stack.pop(); Object res = top.getResult(); - long address = action.offset + action.getBytesLength() + action.operands[0]; + long address = ins.offset + ins.getBytesLength() + ins.operands[0]; int nidx = code.adr2pos(address);//code.indexOf(code.getByAddress(address)); AVM2Instruction tarIns = code.code.get(nidx); + //Some IfType instructions need more than 1 operand, we must pop out all of them - int stackCount = -action.definition.getStackDelta(action, abc); + int stackCount = -ins.definition.getStackDelta(ins, abc); if (EcmaScript.toBoolean(res)) { - //System.err.println("replacing " + action + " on " + idx + " with jump"); + //System.err.println("replacing " + ins + " on " + idx + " with jump"); AVM2Instruction jumpIns = new AVM2Instruction(0, new JumpIns(), new int[]{0}); - //jumpIns.operands[0] = action.operands[0] /*- action.getBytes().length*/ + jumpIns.getBytes().length; + //jumpIns.operands[0] = ins.operands[0] /*- ins.getBytes().length*/ + jumpIns.getBytes().length; code.replaceInstruction(idx, jumpIns, body); jumpIns.operands[0] = (int) (tarIns.offset - jumpIns.offset - jumpIns.getBytesLength()); for (int s = 0; s < stackCount; s++) { - code.insertInstruction(idx, new AVM2Instruction(action.offset, new DeobfuscatePopIns(), new int[]{}), true, body); + code.insertInstruction(idx, new AVM2Instruction(ins.offset, new DeobfuscatePopIns(), new int[]{}), true, body); } idx = code.adr2pos(jumpIns.offset + jumpIns.getBytesLength() + jumpIns.operands[0]); } else { - //System.err.println("replacing " + action + " on " + idx + " with pop"); - code.replaceInstruction(idx, new AVM2Instruction(action.offset, new DeobfuscatePopIns(), new int[]{}), body); + //System.err.println("replacing " + ins + " on " + idx + " with pop"); + code.replaceInstruction(idx, new AVM2Instruction(ins.offset, new DeobfuscatePopIns(), new int[]{}), body); for (int s = 1 /*first is replaced*/; s < stackCount; s++) { - code.insertInstruction(idx, new AVM2Instruction(action.offset, new DeobfuscatePopIns(), new int[]{}), true, body); + code.insertInstruction(idx, new AVM2Instruction(ins.offset, new DeobfuscatePopIns(), new int[]{}), true, body); } - //action.definition = new DeobfuscatePopIns(); + //ins.definition = new DeobfuscatePopIns(); idx++; } ifed = true; @@ -422,7 +425,7 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { public void deobfuscate(String path, int classIndex, boolean isStatic, int scriptIndex, ABC abc, AVM2ConstantPool cpool, Trait trait, MethodInfo minfo, MethodBody body) throws InterruptedException { AVM2Code code = body.getCode(); - removeUnreachableActions(code, cpool, trait, minfo, body); + removeUnreachableInstructions(code, cpool, trait, minfo, body); removeObfuscationIfs(classIndex, isStatic, scriptIndex, abc, cpool, trait, minfo, body, new ArrayList<>()); removeZeroJumps(code, body); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewObjectIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewObjectIns.java index 3e8a9db08..c52d245a3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewObjectIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewObjectIns.java @@ -44,7 +44,7 @@ public class NewObjectIns extends InstructionDefinition { List args = new ArrayList<>(argCount); for (int a = 0; a < argCount; a++) { if (Thread.currentThread().isInterrupted()) { - // int obfuscated method argCount can be 16M + // in obfuscated method argCount can be 16M throw new InterruptedException(); }