From 064679b6e298ad29f6244df31d236532f281d29d Mon Sep 17 00:00:00 2001 From: "honfika@gmail.com" Date: Sat, 4 Jul 2015 00:21:55 +0200 Subject: [PATCH] AS3 deobfuscation fix --- .../decompiler/flash/abc/avm2/AVM2Code.java | 106 ++++++++++-------- .../AVM2DeobfuscatorRegisters.java | 5 +- .../deobfuscation/AVM2DeobfuscatorSimple.java | 3 - .../flash/abc/types/MethodBody.java | 5 +- 4 files changed, 63 insertions(+), 56 deletions(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 09db8b13f..00c663ee3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -243,7 +243,6 @@ import com.jpexs.decompiler.flash.abc.avm2.model.HasNextAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.InitPropertyAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NewFunctionAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.ReturnValueAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ReturnVoidAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.SetPropertyAVM2Item; @@ -868,6 +867,12 @@ public class AVM2Code implements Cloneable { return s.toString(); } + public String toASMSource() { + HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); + toASMSource(new AVM2ConstantPool(), null, null, null, new ArrayList<>(), ScriptExportMode.PCODE, writer); + return writer.toString(); + } + public GraphTextWriter toASMSource(AVM2ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, ScriptExportMode exportMode, GraphTextWriter writer) { return toASMSource(constants, trait, info, body, new ArrayList<>(), exportMode, writer); } @@ -982,49 +987,52 @@ public class AVM2Code implements Cloneable { writer.newLine(); } writer.newLine(); - writer.appendNoHilight("body").newLine(); - - writer.appendNoHilight("maxstack "); - writer.appendNoHilight(body.max_stack); - writer.newLine(); - - writer.appendNoHilight("localcount "); - writer.appendNoHilight(body.max_regs); - writer.newLine(); - - writer.appendNoHilight("initscopedepth "); - writer.appendNoHilight(body.init_scope_depth); - writer.newLine(); - - writer.appendNoHilight("maxscopedepth "); - writer.appendNoHilight(body.max_scope_depth); - writer.newLine(); List offsets = new ArrayList<>(); - for (int e = 0; e < body.exceptions.length; e++) { - writer.appendNoHilight("try"); + if (body != null) { + writer.appendNoHilight("body").newLine(); - writer.appendNoHilight(" from "); - writer.appendNoHilight("ofs"); - writer.appendNoHilight(Helper.formatAddress(body.exceptions[e].start)); - offsets.add((long) body.exceptions[e].start); - - writer.appendNoHilight(" to "); - writer.appendNoHilight("ofs"); - writer.appendNoHilight(Helper.formatAddress(body.exceptions[e].end)); - offsets.add((long) body.exceptions[e].end); - - writer.appendNoHilight(" target "); - writer.appendNoHilight("ofs"); - writer.appendNoHilight(Helper.formatAddress(body.exceptions[e].target)); - offsets.add((long) body.exceptions[e].target); - - writer.appendNoHilight(" type "); - writer.hilightSpecial(body.exceptions[e].type_index == 0 ? "null" : constants.getMultiname(body.exceptions[e].type_index).toString(constants, new ArrayList<>()), HighlightSpecialType.TRY_TYPE, e); - - writer.appendNoHilight(" name "); - writer.hilightSpecial(body.exceptions[e].name_index == 0 ? "null" : constants.getMultiname(body.exceptions[e].name_index).toString(constants, new ArrayList<>()), HighlightSpecialType.TRY_NAME, e); + writer.appendNoHilight("maxstack "); + writer.appendNoHilight(body.max_stack); writer.newLine(); + + writer.appendNoHilight("localcount "); + writer.appendNoHilight(body.max_regs); + writer.newLine(); + + writer.appendNoHilight("initscopedepth "); + writer.appendNoHilight(body.init_scope_depth); + writer.newLine(); + + writer.appendNoHilight("maxscopedepth "); + writer.appendNoHilight(body.max_scope_depth); + writer.newLine(); + + for (int e = 0; e < body.exceptions.length; e++) { + writer.appendNoHilight("try"); + + writer.appendNoHilight(" from "); + writer.appendNoHilight("ofs"); + writer.appendNoHilight(Helper.formatAddress(body.exceptions[e].start)); + offsets.add((long) body.exceptions[e].start); + + writer.appendNoHilight(" to "); + writer.appendNoHilight("ofs"); + writer.appendNoHilight(Helper.formatAddress(body.exceptions[e].end)); + offsets.add((long) body.exceptions[e].end); + + writer.appendNoHilight(" target "); + writer.appendNoHilight("ofs"); + writer.appendNoHilight(Helper.formatAddress(body.exceptions[e].target)); + offsets.add((long) body.exceptions[e].target); + + writer.appendNoHilight(" type "); + writer.hilightSpecial(body.exceptions[e].type_index == 0 ? "null" : constants.getMultiname(body.exceptions[e].type_index).toString(constants, new ArrayList<>()), HighlightSpecialType.TRY_TYPE, e); + + writer.appendNoHilight(" name "); + writer.hilightSpecial(body.exceptions[e].name_index == 0 ? "null" : constants.getMultiname(body.exceptions[e].name_index).toString(constants, new ArrayList<>()), HighlightSpecialType.TRY_NAME, e); + writer.newLine(); + } } writer.newLine(); @@ -1830,8 +1838,9 @@ public class AVM2Code implements Cloneable { throw new IndexOutOfBoundsException(); } checkValidOffsets(body); - final long remOffset = code.get(pos).offset; - final int byteCount = code.get(pos).getBytes().length; + AVM2Instruction ins = code.get(pos); + final long remOffset = ins.offset; + final int byteCount = ins.getBytes().length; updateOffsets(new OffsetUpdater() { @Override public long updateInstructionOffset(long address) { @@ -1846,7 +1855,7 @@ public class AVM2Code implements Cloneable { if (targetAddress > remOffset && insAddr < remOffset) { return offset - byteCount; } - if (targetAddress < remOffset && insAddr > remOffset) { + if (targetAddress <= remOffset && insAddr > remOffset) { return offset + byteCount; } return offset; @@ -1860,8 +1869,8 @@ public class AVM2Code implements Cloneable { } /** - * Inserts instuction at specified point. Handles offsets properly. Note: If - * newinstruction is jump, the offset operand must be handled properly by + * Inserts instruction at specified point. Handles offsets properly. Note: + * If newinstruction is jump, the offset operand must be handled properly by * caller. All old jump offsets to pos are targeted before new instruction. * * @param pos Position in the list @@ -1922,8 +1931,8 @@ public class AVM2Code implements Cloneable { } /** - * Inserts instuction at specified point. Handles offsets properly. Note: If - * newinstruction is jump, the offset operand must be handled properly by + * Inserts instruction at specified point. Handles offsets properly. Note: + * If newinstruction is jump, the offset operand must be handled properly by * caller. * * @param pos Position in the list @@ -2586,6 +2595,7 @@ public class AVM2Code implements Cloneable { } removeIgnored(constants, trait, info, body); + for (int i = code.size() - 1; i >= 0; i--) { AVM2Instruction ins = code.get(i); if (ins.definition instanceof JumpIns) { @@ -2596,7 +2606,9 @@ public class AVM2Code implements Cloneable { } } } + removeIgnored(constants, trait, info, body); + return cnt; } 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 e81433260..ab35f1e90 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 @@ -22,10 +22,8 @@ import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.AVM2LocalData; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2GraphSource; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.DeobfuscatePopIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.IfTypeIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalTypeIns; @@ -125,7 +123,7 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { private void visitCode(Set visited, TranslateStack stack, int classIndex, boolean isStatic, MethodBody body, int scriptIndex, ABC abc, AVM2Code code, int idx, int endIdx, ExecutionResult result) { List output = new ArrayList<>(); AVM2LocalData localData = newLocalData(scriptIndex, abc, abc.constants, body, isStatic, classIndex); - localData.localRegs.put(0, new NullAVM2Item(null));//this + localData.localRegs.put(0, new NullAVM2Item(null));//this int instructionsProcessed = 0; try { @@ -240,6 +238,7 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple { class ExecutionResult { public Map assignCount = new HashMap<>(); + public Map lastAssigned = new HashMap<>(); } } 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 8c0bfea1c..d412b70c7 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 @@ -58,7 +58,6 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushStringIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushTrueIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUndefinedIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.SwapIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceOrConvertTypeIns; import com.jpexs.decompiler.flash.abc.avm2.model.FloatValueAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item; @@ -78,7 +77,6 @@ import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.decompiler.graph.TranslateException; import com.jpexs.decompiler.graph.TranslateStack; import com.jpexs.decompiler.graph.model.FalseItem; -import com.jpexs.decompiler.graph.model.PopItem; import com.jpexs.decompiler.graph.model.TrueItem; import java.util.ArrayList; import java.util.EmptyStackException; @@ -413,6 +411,5 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener { public int instructionsProcessed = -1; public TranslateStack stack = new TranslateStack("?"); - } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java index 5d4b0e288..2f09e1c4a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java @@ -20,11 +20,11 @@ import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.ABCInputStream; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; -import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AVM2DeobfuscatorRegisters; -import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AVM2DeobfuscatorSimple; import com.jpexs.decompiler.flash.abc.avm2.CodeStats; import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode; import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AVM2DeobfuscatorJumps; +import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AVM2DeobfuscatorRegisters; +import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AVM2DeobfuscatorSimple; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.Traits; import com.jpexs.decompiler.flash.configuration.Configuration; @@ -293,7 +293,6 @@ public final class MethodBody implements Cloneable { new AVM2DeobfuscatorSimple().deobfuscate(path, classIndex, isStatic, scriptIndex, abc, constants, trait, method_info.get(this.method_info), b); new AVM2DeobfuscatorRegisters().deobfuscate(path, classIndex, isStatic, scriptIndex, abc, constants, trait, method_info.get(this.method_info), b); new AVM2DeobfuscatorJumps().deobfuscate(path, classIndex, isStatic, scriptIndex, abc, constants, trait, method_info.get(this.method_info), b); - } }