diff --git a/CHANGELOG.md b/CHANGELOG.md index b9759aa41..578151c44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ All notable changes to this project will be documented in this file. - AS3 deobfuscator in some cases - #349 AS3 - better handling of declarations - #735 AS3 - index out of bounds in deobfuscator +- AS3 deobfuscator on &&, || operators ### Changed - AS3 test methods separated to classes diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java index ab7e106be..72cd2a2ab 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java @@ -170,6 +170,7 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush AVM2LocalData localData = newLocalData(scriptIndex, abc, abc.constants, body, isStatic, classIndex); int localReservedCount = body.getLocalReservedCount(); + Set importantOffsets = code.getImportantOffsets(body, isStatic); for (int i = 0; i < code.code.size(); i++) { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); @@ -181,7 +182,7 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush localData.localRegs.clear(); initLocalRegs(localData, localReservedCount, body.max_regs); - executeInstructions(staticRegs, body, abc, code, localData, i, code.code.size() - 1, null, inlineIns, jumpTargets); + executeInstructions(importantOffsets, staticRegs, body, abc, code, localData, i, code.code.size() - 1, null, inlineIns, jumpTargets); } return false; @@ -213,7 +214,7 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush } } - private void executeInstructions(Map staticRegs, MethodBody body, ABC abc, AVM2Code code, AVM2LocalData localData, int idx, int endIdx, ExecutionResult result, List inlineIns, List jumpTargets) throws InterruptedException { + private void executeInstructions(Set importantOffsets, Map staticRegs, MethodBody body, ABC abc, AVM2Code code, AVM2LocalData localData, int idx, int endIdx, ExecutionResult result, List inlineIns, List jumpTargets) throws InterruptedException { List output = new ArrayList<>(); FixItemCounterTranslateStack stack = new FixItemCounterTranslateStack(""); @@ -269,6 +270,8 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush } else { idx = code.code.indexOf(nins); } + importantOffsets.clear(); + importantOffsets.addAll(code.getImportantOffsets(body, false)); continue; } } @@ -284,6 +287,9 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush int regId = ((SetLocalTypeIns) def).getRegisterId(ins); staticRegs.put(regId, localData.localRegs.get(regId).getNotCoerced()); code.replaceInstruction(idx, new AVM2Instruction(0, DeobfuscatePopIns.getInstance(), null), body); + + importantOffsets.clear(); + importantOffsets.addAll(code.getImportantOffsets(body, false)); } } } @@ -304,6 +310,9 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush stack.push(staticRegs.get(regId)); ins = pushins; def = ins.definition; + + importantOffsets.clear(); + importantOffsets.addAll(code.getImportantOffsets(body, false)); } } @@ -401,6 +410,12 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush throw new TranslateException("Jump target not found: " + address); } } else if (def instanceof IfTypeIns) { + + long ifAddress = code.pos2adr(idx); + if (importantOffsets.contains(ifAddress)) { + //There is jump directly to ifTypeIns like in &&, || operator + return; + } if (stack.isEmpty()) { return; } @@ -433,6 +448,9 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush //ins.definition = DeobfuscatePopIns.getInstance(); idx++; } + + importantOffsets.clear(); + importantOffsets.addAll(code.getImportantOffsets(body, false)); ifed = true; //break; } else { diff --git a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf index 5c96c6ba1..e18d5d092 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf and b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf differ diff --git a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf index 165b4821c..fcc5ea768 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf and b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf differ diff --git a/libsrc/ffdec_lib/testdata/as3_new/src/Main.as b/libsrc/ffdec_lib/testdata/as3_new/src/Main.as index 1d638e23d..9d00886d3 100644 --- a/libsrc/ffdec_lib/testdata/as3_new/src/Main.as +++ b/libsrc/ffdec_lib/testdata/as3_new/src/Main.as @@ -21,6 +21,7 @@ package TestContinueLevels; TestDecl2; TestDeclarations; + TestDeobfuscation; TestDefaultNotLastGrouped; TestDotParent; TestDoWhile; diff --git a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestDeobfuscation.as b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestDeobfuscation.as new file mode 100644 index 000000000..4ebd55c99 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestDeobfuscation.as @@ -0,0 +1,18 @@ +package tests +{ + + public class TestDeobfuscation + { + public function run():* + { + var r:int = Math.random(); + var f:Boolean = false; + + if(r > 5 || f) + { + return "okay"; + } + return "after"; + } + } +}