From e37e6b7d9acc014e3fcf4715fb72cfe16ff249e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Fri, 5 Feb 2021 13:33:10 +0100 Subject: [PATCH] AS3 deobfuscator - remove push simple, not, pop. --- .../deobfuscation/AVM2DeobfuscatorSimple.java | 59 +------------------ .../AVM2DeobfuscatorZeroJumpsNullPushes.java | 48 +++++++++++---- 2 files changed, 40 insertions(+), 67 deletions(-) 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 a26c53d8e..20c89763b 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 @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.abc.avm2.deobfuscation; import com.jpexs.decompiler.flash.abc.ABC; @@ -89,7 +90,7 @@ import java.util.Stack; * * @author JPEXS */ -public class AVM2DeobfuscatorSimple extends SWFDecompilerAdapter { +public class AVM2DeobfuscatorSimple extends AVM2DeobfuscatorZeroJumpsNullPushes { private final int executionLimit = 30000; @@ -130,60 +131,6 @@ public class AVM2DeobfuscatorSimple extends SWFDecompilerAdapter { return false; } - protected boolean removeZeroJumps(AVM2Code code, MethodBody body) throws InterruptedException { - boolean result = false; - 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) { - if (Thread.currentThread().isInterrupted()) { - throw new InterruptedException(); - } - - code.removeInstruction(i, body); - i--; - result = true; - } - } - } - return result; - } - - protected boolean removeNullPushes(AVM2Code code, MethodBody body) throws InterruptedException { - boolean result = false; - Set offsets = code.getImportantOffsets(body, true); - - // Deliberately skip over instruction zero - for (int i = 1; i < code.code.size(); i++) { - AVM2Instruction ins1 = code.code.get(i - 1); - AVM2Instruction ins2 = code.code.get(i); - if (ins2.definition instanceof PopIns - && !offsets.contains(ins2.getAddress()) - && (ins1.definition instanceof PushByteIns - || ins1.definition instanceof PushDoubleIns - || ins1.definition instanceof PushFalseIns - || ins1.definition instanceof PushIntIns - || ins1.definition instanceof PushNanIns - || ins1.definition instanceof PushNullIns - || ins1.definition instanceof PushShortIns - || ins1.definition instanceof PushStringIns - || ins1.definition instanceof PushTrueIns - || ins1.definition instanceof PushUIntIns - || ins1.definition instanceof PushUndefinedIns)) { - if (Thread.currentThread().isInterrupted()) { - throw new InterruptedException(); - } - - code.removeInstruction(i - 1, body); - i--; - code.removeInstruction(i, body); - i--; - offsets = code.getImportantOffsets(body, true); //update offsets, they changed because of removing instruction - result = true; - } - } - return result; - } protected void initLocalRegs(LocalDataArea localData, int localReservedCount, int maxRegs, boolean executeFromFirst) { for (int i = 0; i < localReservedCount; i++) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorZeroJumpsNullPushes.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorZeroJumpsNullPushes.java index 083dcd4d0..4cc535dcf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorZeroJumpsNullPushes.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorZeroJumpsNullPushes.java @@ -19,6 +19,8 @@ package com.jpexs.decompiler.flash.abc.avm2.deobfuscation; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.NotIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns; @@ -43,6 +45,7 @@ import java.util.Set; * @author JPEXS */ public class AVM2DeobfuscatorZeroJumpsNullPushes extends SWFDecompilerAdapter { + protected boolean removeZeroJumps(AVM2Code code, MethodBody body) throws InterruptedException { boolean result = false; for (int i = 0; i < code.code.size(); i++) { @@ -62,6 +65,20 @@ public class AVM2DeobfuscatorZeroJumpsNullPushes extends SWFDecompilerAdapter { return result; } + private boolean isSimplePush(InstructionDefinition def) { + return (def instanceof PushByteIns + || def instanceof PushDoubleIns + || def instanceof PushFalseIns + || def instanceof PushIntIns + || def instanceof PushNanIns + || def instanceof PushNullIns + || def instanceof PushShortIns + || def instanceof PushStringIns + || def instanceof PushTrueIns + || def instanceof PushUIntIns + || def instanceof PushUndefinedIns); + } + protected boolean removeNullPushes(AVM2Code code, MethodBody body) throws InterruptedException { boolean result = false; Set offsets = code.getImportantOffsets(body, true); @@ -72,17 +89,7 @@ public class AVM2DeobfuscatorZeroJumpsNullPushes extends SWFDecompilerAdapter { AVM2Instruction ins2 = code.code.get(i); if (ins2.definition instanceof PopIns && !offsets.contains(ins2.getAddress()) - && (ins1.definition instanceof PushByteIns - || ins1.definition instanceof PushDoubleIns - || ins1.definition instanceof PushFalseIns - || ins1.definition instanceof PushIntIns - || ins1.definition instanceof PushNanIns - || ins1.definition instanceof PushNullIns - || ins1.definition instanceof PushShortIns - || ins1.definition instanceof PushStringIns - || ins1.definition instanceof PushTrueIns - || ins1.definition instanceof PushUIntIns - || ins1.definition instanceof PushUndefinedIns)) { + && isSimplePush(ins1.definition)) { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } @@ -93,6 +100,25 @@ public class AVM2DeobfuscatorZeroJumpsNullPushes extends SWFDecompilerAdapter { i--; offsets = code.getImportantOffsets(body, true); //update offsets, they changed because of removing instruction result = true; + } else if (i >= 2) { + AVM2Instruction ins0 = code.code.get(i - 2); + if ((ins2.definition instanceof PopIns) + && (ins1.definition instanceof NotIns) + && !offsets.contains(ins2.getAddress()) + && !offsets.contains(ins1.getAddress()) + && isSimplePush(ins0.definition)) { + if (Thread.currentThread().isInterrupted()) { + throw new InterruptedException(); + } + code.removeInstruction(i - 2, body); + i--; + code.removeInstruction(i - 1, body); + i--; + code.removeInstruction(i, body); + i--; + offsets = code.getImportantOffsets(body, true); //update offsets, they changed because of removing instruction + result = true; + } } } return result;