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 5b389e12f..145c51fa3 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 @@ -64,11 +64,14 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushDoubleIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushFalseIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushIntegerTypeIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushIntIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushNanIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushNullIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushShortIns; 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.PushUIntIns; 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; @@ -148,6 +151,39 @@ public class AVM2DeobfuscatorSimple extends SWFDecompilerAdapter { return result; } + protected boolean removeNullPushes(AVM2Code code, MethodBody body) throws InterruptedException { + boolean result = false; + // Deliberately skip over instruction zero + for(int i = 1; i < code.code.size(); i++) { + Set offsets = code.getImportantOffsets(body, true); + 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 PushIntegerTypeIns || + 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--; + result = true; + } + } return result; + } + protected void initLocalRegs(LocalDataArea localData, int localReservedCount, int maxRegs, boolean executeFromFirst) { for (int i = 0; i < localReservedCount; i++) { localData.localRegisters.put(i, NotCompileTime.INSTANCE); @@ -374,6 +410,7 @@ public class AVM2DeobfuscatorSimple extends SWFDecompilerAdapter { code.removeDeadCode(body); removeObfuscationIfs(classIndex, isStatic, scriptIndex, abc, body, null); removeZeroJumps(code, body); + removeNullPushes(code, body); } class ExecutionResult { 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 11ded804a..1e8e925d2 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 @@ -68,11 +68,14 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushDoubleIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushFalseIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushIntegerTypeIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushIntIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushNanIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushNullIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushShortIns; 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.PushUIntIns; 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; @@ -102,6 +105,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; /** * @@ -203,6 +207,39 @@ public class AVM2DeobfuscatorSimpleOld extends SWFDecompilerAdapter { return result; } + protected boolean removeNullPushes(AVM2Code code, MethodBody body) throws InterruptedException { + boolean result = false; + // Deliberately skip over instruction zero + for(int i = 1; i < code.code.size(); i++) { + Set offsets = code.getImportantOffsets(body, true); + 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 PushIntegerTypeIns || + 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--; + result = true; + } + } return result; + } + protected AVM2LocalData newLocalData(int scriptIndex, ABC abc, AVM2ConstantPool cpool, MethodBody body, boolean isStatic, int classIndex) { AVM2LocalData localData = new AVM2LocalData(); localData.isStatic = isStatic; @@ -475,6 +512,7 @@ public class AVM2DeobfuscatorSimpleOld extends SWFDecompilerAdapter { code.removeDeadCode(body); removeObfuscationIfs(classIndex, isStatic, scriptIndex, abc, body, new ArrayList<>()); removeZeroJumps(code, body); + removeNullPushes(code, body); } class ExecutionResult {