check the needed stack size before translating the instruction to avoid throwing that much emptystackexceptions during deobfuscarion

This commit is contained in:
honfika@gmail.com
2015-08-22 21:01:41 +02:00
parent 7ad7e80057
commit 0498fadbb4
23 changed files with 130 additions and 0 deletions

View File

@@ -257,6 +257,12 @@ public class AVM2DeobfuscatorSimple implements SWFDecompilerListener {
}
}
} else {
// do not throw EmptyStackException, much faster
int requiredStackSize = ins.getRequiredStackSize();
if (stack.size() < requiredStackSize) {
return;
}
ins.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");
}

View File

@@ -340,6 +340,10 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
aLocalData.constants, this, aLocalData.methodInfo, output, aLocalData.methodBody, aLocalData.abc, aLocalData.localRegNames, aLocalData.fullyQualifiedNames, null, aLocalData.localRegAssignmentIps, aLocalData.ip, aLocalData.refs, aLocalData.code);
}
public int getRequiredStackSize() {
return definition.getRequiredStackSize(this);
}
@Override
public boolean isJump() {
return (definition instanceof JumpIns) || (fixedBranch > -1);

View File

@@ -43,4 +43,9 @@ public class DeobfuscatePopIns extends PopIns {
public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List<MethodInfo> method_info, List<GraphTargetItem> output, MethodBody body, ABC abc, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
stack.pop(); //Just ignore the value
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 1;
}
}

View File

@@ -91,6 +91,10 @@ public class InstructionDefinition implements Serializable {
public void translate(boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2ConstantPool constants, AVM2Instruction ins, List<MethodInfo> method_info, List<GraphTargetItem> output, MethodBody body, ABC abc, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) throws InterruptedException {
}
public int getRequiredStackSize(AVM2Instruction ins) {
return 0;
}
protected FullMultinameAVM2Item resolveMultiname(TranslateStack stack, AVM2ConstantPool constants, int multinameIndex, AVM2Instruction ins) {
GraphTargetItem ns = null;
GraphTargetItem name = null;

View File

@@ -44,6 +44,11 @@ public class AddIIns extends AddIns {
stack.push(new AddAVM2Item(ins, v1, v2));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 2;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -2 + 1;

View File

@@ -67,6 +67,11 @@ public class AddIns extends InstructionDefinition {
stack.push(new AddAVM2Item(ins, v1, v2));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 2;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -2 + 1;

View File

@@ -53,6 +53,11 @@ public class BitAndIns extends InstructionDefinition {
stack.push(new BitAndAVM2Item(ins, v1, v2));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 2;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -2 + 1;

View File

@@ -65,6 +65,11 @@ public class CallMethodIns extends InstructionDefinition {
stack.push(new CallMethodAVM2Item(ins, receiver, methodName, args));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return ins.operands[1] + 1;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -1 + 1 - ins.operands[1];

View File

@@ -72,6 +72,12 @@ public class CallPropVoidIns extends InstructionDefinition {
output.add(new CallPropertyAVM2Item(ins, true, receiver, multiname, args));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return ins.operands[1] + 1;
// todo: honfika: add resolveMultiname stack size
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
int ret = -ins.operands[1] - 1;

View File

@@ -53,6 +53,11 @@ public class IfNGtIns extends InstructionDefinition implements IfTypeIns {
stack.push(new GtAVM2Item(ins, v1, v2));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 2;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -2;

View File

@@ -53,6 +53,11 @@ public class IfNeIns extends InstructionDefinition implements IfTypeIns {
stack.push(new EqAVM2Item(ins, v1, v2));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 2;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -2;

View File

@@ -124,6 +124,11 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
output.add(new SetLocalAVM2Item(ins, regId, value));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 1;
}
@Override
public String getObject(Stack<AVM2Item> stack, ABC abc, AVM2Instruction ins, List<AVM2Item> output, MethodBody body, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames) {
return AVM2Item.localRegName(localRegNames, getRegisterId(ins));

View File

@@ -46,6 +46,25 @@ public class GetPropertyIns extends InstructionDefinition {
stack.push(new GetPropertyAVM2Item(ins, obj, multiname));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
int ret = 1;
int multinameIndex = ins.operands[0];
//Note: In official compiler, the stack can be wrong(greater) for some MULTINAMEL/A, e.g. increments
/*
var arr=[1,2,3];
return arr[2]++;
*/
/* todo: honfika
if (abc.constants.getMultiname(multinameIndex).needsName()) {
ret--;
}
if (abc.constants.getMultiname(multinameIndex).needsNs()) {
ret--;
}*/
return ret;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
int ret = -1 + 1;

View File

@@ -48,6 +48,12 @@ public class InitPropertyIns extends InstructionDefinition {
output.add(new InitPropertyAVM2Item(ins, obj, multiname, val));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 2;
// todo: honfika: add resolveMultiname stack size
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
int ret = -2;

View File

@@ -143,6 +143,11 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 2;
}
@Override
public String getObject(Stack<AVM2Item> stack, ABC abc, AVM2Instruction ins, List<AVM2Item> output, MethodBody body, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames) {
int multinameIndex = ins.operands[0];

View File

@@ -54,6 +54,11 @@ public class DupIns extends InstructionDefinition {
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 1;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -1 + 2;

View File

@@ -47,6 +47,11 @@ public class PushScopeIns extends InstructionDefinition {
scopeStack.push(stack.pop());
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 1;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -1;

View File

@@ -61,6 +61,11 @@ public class ApplyTypeIns extends InstructionDefinition {
stack.push(new ApplyTypeAVM2Item(ins, stack.pop(), params));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return ins.operands[0];
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -ins.operands[0] - 1 + 1;

View File

@@ -56,6 +56,11 @@ public class AsTypeIns extends InstructionDefinition {
stack.push(new AsTypeAVM2Item(ins, val, new FullMultinameAVM2Item(ins, ins.operands[0])));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 1;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -1 + 1;

View File

@@ -54,6 +54,11 @@ public class AsTypeLateIns extends InstructionDefinition {
stack.push(new AsTypeAVM2Item(ins, val, cls));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 2;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -2 + 1;

View File

@@ -51,6 +51,11 @@ public class CoerceIns extends InstructionDefinition implements CoerceOrConvertT
stack.push(new CoerceAVM2Item(ins, stack.pop(), PropertyAVM2Item.multinameToType(multinameIndex, constants)));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 1;
}
@Override
public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins, List<DottedChain> fullyQualifiedNames) {
int multinameIndex = ins.operands[0];

View File

@@ -50,6 +50,11 @@ public class CoerceSIns extends InstructionDefinition implements CoerceOrConvert
stack.push(new CoerceAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames)));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 1;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -1 + 1;

View File

@@ -66,6 +66,11 @@ public class ConvertIIns extends InstructionDefinition implements CoerceOrConver
stack.push(new ConvertAVM2Item(ins, stack.pop(), getTargetType(constants, ins, fullyQualifiedNames)));
}
@Override
public int getRequiredStackSize(AVM2Instruction ins) {
return 1;
}
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
return -1 + 1;