From 60d42e76c3eaca2f0b9ba84227d208f1f921066e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 31 Aug 2025 19:58:10 +0200 Subject: [PATCH] deobfuscation fixes --- .../avm2/graph/AVM2GraphTargetDialect.java | 1 + .../avm2/instructions/DeobfuscatePopIns.java | 45 +++++++++++++++---- .../abc/avm2/instructions/stack/DupIns.java | 2 +- .../abc/avm2/instructions/stack/SwapIns.java | 2 +- .../action/ActionGraphTargetDialect.java | 1 + .../src/com/jpexs/decompiler/graph/Graph.java | 2 +- .../decompiler/graph/TranslateStack.java | 10 ++--- .../graph/model/SetTemporaryItem.java | 4 +- 8 files changed, 48 insertions(+), 19 deletions(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphTargetDialect.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphTargetDialect.java index a04e0bb95..ad8a9645d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphTargetDialect.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphTargetDialect.java @@ -114,6 +114,7 @@ public class AVM2GraphTargetDialect extends GraphTargetDialect { public GraphTextWriter writeTemporaryDeclaration(GraphTextWriter writer, LocalData localData, String suffix, int tempIndex, GraphTargetItem value) throws InterruptedException { writer.append("var "); writer.append("_temp"); + writer.append(suffix); writer.append("_").append(tempIndex).append(":*"); if (value != null) { writer.append(" = "); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/DeobfuscatePopIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/DeobfuscatePopIns.java index 46efef3d9..710338303 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/DeobfuscatePopIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/DeobfuscatePopIns.java @@ -19,10 +19,14 @@ package com.jpexs.decompiler.flash.abc.avm2.instructions; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.AVM2LocalData; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns; +import com.jpexs.decompiler.graph.AbstractGraphTargetVisitor; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.DuplicateItem; import com.jpexs.decompiler.graph.model.DuplicateSourceItem; +import com.jpexs.decompiler.graph.model.HasTempIndex; import com.jpexs.decompiler.graph.model.SetTemporaryItem; +import com.jpexs.decompiler.graph.model.TemporaryItem; import java.util.List; /** @@ -70,15 +74,40 @@ public class DeobfuscatePopIns extends PopIns { @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { GraphTargetItem item = stack.pop(); - if (item instanceof DuplicateSourceItem) { - DuplicateSourceItem ds = (DuplicateSourceItem) item; - if (!output.isEmpty() && output.get(output.size() - 1) instanceof SetTemporaryItem) { - SetTemporaryItem st = (SetTemporaryItem) output.get(output.size() - 1); - if (st.tempIndex == ds.tempIndex) { - output.remove(output.size() - 1); + AbstractGraphTargetVisitor visitor = new AbstractGraphTargetVisitor() { + @Override + public boolean visit(GraphTargetItem subItem) { + if ((subItem instanceof DuplicateSourceItem) || (subItem instanceof DuplicateItem)) { + int tempIndex = ((HasTempIndex) subItem).getTempIndex(); + if (!output.isEmpty() && output.get(output.size() - 1) instanceof SetTemporaryItem) { + SetTemporaryItem st = (SetTemporaryItem) output.get(output.size() - 1); + if (st.tempIndex == tempIndex) { + st.refCount--; + if (st.refCount <= 0) { + output.remove(output.size() - 1); + stack.moveToStack(output); + } else if (st.refCount == 1) { + for (int i = 0; i < stack.size(); i++) { + if (stack.get(i) instanceof HasTempIndex) { + HasTempIndex ht = (HasTempIndex) stack.get(i); + if (ht.getTempIndex() == tempIndex) { + stack.set(i, st.value); + st.refCount--; + output.remove(output.size() - 1); + stack.moveToStack(output); + } + } + } + } + } + } + return false; } - } - } + return true; + } + }; + visitor.visit(item); + item.visitRecursively(visitor); } /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/DupIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/DupIns.java index ddcd92e47..1f561b22c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/DupIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/DupIns.java @@ -72,7 +72,7 @@ public class DupIns extends InstructionDefinition { temp = localData.maxTempIndex.getVal() + 1; localData.maxTempIndex.setVal(temp); stack.finishBlock(output); - stack.addToOutput(new SetTemporaryItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, v, temp, "dup")); + stack.addToOutput(new SetTemporaryItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, v, temp, "dup", 2)); stack.finishBlock(output); stack.push(new DuplicateSourceItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, v, temp)); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/SwapIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/SwapIns.java index 1106669d4..3b5943fad 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/SwapIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/SwapIns.java @@ -153,7 +153,7 @@ public class SwapIns extends InstructionDefinition { int temp = localData.maxTempIndex.getVal() + 1; localData.maxTempIndex.setVal(temp); stack.finishBlock(output); - stack.addToOutput(new SetTemporaryItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, o2, temp, "swap")); + stack.addToOutput(new SetTemporaryItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, o2, temp, "swap", 1)); stack.push(o1); stack.push(new TemporaryItem(AVM2GraphTargetDialect.INSTANCE, ins, localData.lineStartInstruction, o2, temp)); stack.finishBlock(output); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraphTargetDialect.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraphTargetDialect.java index 20cff2051..8a7f20ece 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraphTargetDialect.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraphTargetDialect.java @@ -119,6 +119,7 @@ public class ActionGraphTargetDialect extends GraphTargetDialect { public GraphTextWriter writeTemporaryDeclaration(GraphTextWriter writer, LocalData localData, String suffix, int tempIndex, GraphTargetItem value) throws InterruptedException { writer.append("var "); writer.append("_temp"); + writer.append(suffix); writer.append("_").append(tempIndex); if (value != null) { writer.append(" = "); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java index 582904c43..ae0260946 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java @@ -1057,7 +1057,7 @@ public class Graph { public void visit(GraphTargetItem item, Stack parentStack) { if (item instanceof SetTemporaryItem) { SetTemporaryItem st = (SetTemporaryItem) item; - SetTemporaryItem dec = new SetTemporaryItem(dialect, null, null, null, st.tempIndex, st.getSuffix()); + SetTemporaryItem dec = new SetTemporaryItem(dialect, null, null, null, st.tempIndex, st.getSuffix(), st.refCount); dec.declaration = true; items.add(iRef.getVal(), dec); iRef.setVal(iRef.getVal() + 1); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/TranslateStack.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/TranslateStack.java index e135895c4..8402aa83c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/TranslateStack.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/TranslateStack.java @@ -27,12 +27,10 @@ import com.jpexs.decompiler.graph.model.ContinueItem; import com.jpexs.decompiler.graph.model.DuplicateItem; import com.jpexs.decompiler.graph.model.DuplicateSourceItem; import com.jpexs.decompiler.graph.model.ExitItem; -import com.jpexs.decompiler.graph.model.HasTempIndex; import com.jpexs.decompiler.graph.model.PopItem; import com.jpexs.decompiler.graph.model.PushItem; import com.jpexs.decompiler.graph.model.ScriptEndItem; import com.jpexs.decompiler.graph.model.SetTemporaryItem; -import com.jpexs.decompiler.graph.model.SwapItem; import com.jpexs.decompiler.graph.model.TemporaryItem; import java.util.ArrayList; import java.util.HashMap; @@ -106,10 +104,8 @@ public class TranslateStack extends Stack { return super.push(item); } - private boolean isDupsOnly() { - if (true) { - return false; - } + //for #116 + private boolean isDupsOnly() { for (GraphTargetItem item : this) { if (item instanceof DuplicateItem) { continue; @@ -280,7 +276,7 @@ public class TranslateStack extends Stack { } else { int temp = localData.maxTempIndex.getVal() + 1; localData.maxTempIndex.setVal(temp); - connectedOutput.set(i, new SetTemporaryItem(pi.dialect, pi.value.getSrc(), pi.value.getLineStartItem(), pi.value, temp, "push")); + connectedOutput.set(i, new SetTemporaryItem(pi.dialect, pi.value.getSrc(), pi.value.getLineStartItem(), pi.value, temp, "push", 1)); return new TemporaryItem(pi.dialect, pi.value.getSrc(), pi.value.getLineStartItem(), pi.value, temp); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/SetTemporaryItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/SetTemporaryItem.java index 5537fa79b..8913f4a83 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/SetTemporaryItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/SetTemporaryItem.java @@ -39,6 +39,7 @@ public class SetTemporaryItem extends GraphTargetItem implements SimpleValue, Ha public int tempIndex; public boolean declaration = false; + public int refCount = 0; private final String suffix; @@ -54,10 +55,11 @@ public class SetTemporaryItem extends GraphTargetItem implements SimpleValue, Ha * @param lineStartIns Line start item * @param value Value */ - public SetTemporaryItem(GraphTargetDialect dialect, GraphSourceItem src, GraphSourceItem lineStartIns, GraphTargetItem value, int tempIndex, String suffix) { + public SetTemporaryItem(GraphTargetDialect dialect, GraphSourceItem src, GraphSourceItem lineStartIns, GraphTargetItem value, int tempIndex, String suffix, int refCount) { super(dialect, src, lineStartIns, PRECEDENCE_ASSIGNMENT, value); this.tempIndex = tempIndex; this.suffix = suffix; + this.refCount = refCount; } @Override