mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-03 23:14:18 +00:00
Fixed - AS3 deobfuscator in some cases - removing zerojumps and null pushes again
Improper try not using stack.
This commit is contained in:
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AVM2DeobfuscatorGetSet;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AVM2DeobfuscatorJumps;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AVM2DeobfuscatorRegistersOld;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AVM2DeobfuscatorSimpleOld;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.AVM2DeobfuscatorZeroJumpsNullPushes;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.exceptions.AVM2ExecutionException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.exceptions.AVM2VerifyErrorException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2Graph;
|
||||
@@ -2333,6 +2334,9 @@ public class AVM2Code implements Cloneable {
|
||||
try (Statistics s = new Statistics("AVM2DeobfuscatorJumps")) {
|
||||
new AVM2DeobfuscatorJumps().avm2CodeRemoveTraps(path, classIndex, isStatic, scriptIndex, abc, trait, methodInfo, body);
|
||||
}
|
||||
try (Statistics s = new Statistics("AVM2DeobfuscatorZeroJumpsNullPushes")) {
|
||||
new AVM2DeobfuscatorZeroJumpsNullPushes().avm2CodeRemoveTraps(path, classIndex, isStatic, scriptIndex, abc, trait, methodInfo, body);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -109,7 +110,7 @@ import java.util.Set;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
*/
|
||||
public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPushes {
|
||||
|
||||
private static final UndefinedAVM2Item UNDEFINED_ITEM = new UndefinedAVM2Item(null, null);
|
||||
|
||||
@@ -186,60 +187,6 @@ public class AVM2DeobfuscatorSimpleOld 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<Long> 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 AVM2LocalData newLocalData(int scriptIndex, ABC abc, AVM2ConstantPool cpool, MethodBody body, boolean isStatic, int classIndex) {
|
||||
AVM2LocalData localData = new AVM2LocalData();
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2021 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
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.jumps.JumpIns;
|
||||
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.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.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.helpers.SWFDecompilerAdapter;
|
||||
import java.util.ArrayList;
|
||||
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++) {
|
||||
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<Long> 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void avm2CodeRemoveTraps(String path, int classIndex, boolean isStatic, int scriptIndex, ABC abc, Trait trait, int methodInfo, MethodBody body) throws InterruptedException {
|
||||
AVM2Code code = body.getCode();
|
||||
removeZeroJumps(code, body);
|
||||
removeNullPushes(code, body);
|
||||
}
|
||||
}
|
||||
@@ -864,7 +864,9 @@ public class AVM2Graph extends Graph {
|
||||
|
||||
GraphPart exAfterPart = endIpPart;
|
||||
|
||||
stack.clear(); //If the original code (before check()) had "if" in it, there would be something on stack
|
||||
if (part.nextParts.size() > 1 && !stack.isEmpty()) { //If the original code (before check()) had "if" in it, there would be something on stack
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
if (finallyException == null) {
|
||||
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
|
||||
|
||||
@@ -45,6 +45,7 @@ import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import com.jpexs.helpers.stat.Statistics;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
Reference in New Issue
Block a user