Skip to content

Commit

Permalink
avoid throwing EmptyStackExceptions in as2 deobfuscation
Browse files Browse the repository at this point in the history
  • Loading branch information
honfika committed Aug 26, 2015
1 parent 5465043 commit 696ee04
Show file tree
Hide file tree
Showing 104 changed files with 1,453 additions and 471 deletions.
9 changes: 9 additions & 0 deletions ffdec-findbugs-config.fbp
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project projectName="JPEXS">
<Jar>.\dist\ffdec.jar</Jar>
<AuxClasspathEntry>.\dist\lib</AuxClasspathEntry>
<SrcDir>.\src</SrcDir>
<SrcDir>.\libsrc</SrcDir>
<SuppressionFilter>
<LastVersion value="-1" relOp="NEQ"/>
</SuppressionFilter>
</Project>
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ private int visitCode(Reference<AVM2Instruction> assignment, Set<Integer> visite
toVisit.add(idx); toVisit.add(idx);
List<TranslateStack> toVisitStacks = new ArrayList<>(); List<TranslateStack> toVisitStacks = new ArrayList<>();
toVisitStacks.add(stack); toVisitStacks.add(stack);
outer:
while (!toVisit.isEmpty()) { while (!toVisit.isEmpty()) {
idx = toVisit.remove(0); idx = toVisit.remove(0);
stack = toVisitStacks.remove(0); stack = toVisitStacks.remove(0);
Expand All @@ -192,6 +193,12 @@ private int visitCode(Reference<AVM2Instruction> assignment, Set<Integer> visite
InstructionDefinition def = ins.definition; InstructionDefinition def = ins.definition;
//System.err.println("" + idx + ": " + ins + " stack:" + stack.size()); //System.err.println("" + idx + ": " + ins + " stack:" + stack.size());


// do not throw EmptyStackException, much faster
int requiredStackSize = ins.getStackPopCount(localData);
if (stack.size() < requiredStackSize) {
continue outer;
}

ins.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); ins.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");


//if (!(def instanceof KillIns)) //if (!(def instanceof KillIns))
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -331,19 +331,39 @@ public String toStringNoAddress(AVM2ConstantPool constants, List<DottedChain> fu
@Override @Override
public void translate(BaseLocalData localData, TranslateStack stack, List<GraphTargetItem> output, int staticOperation, String path) throws InterruptedException { public void translate(BaseLocalData localData, TranslateStack stack, List<GraphTargetItem> output, int staticOperation, String path) throws InterruptedException {
AVM2LocalData aLocalData = (AVM2LocalData) localData; AVM2LocalData aLocalData = (AVM2LocalData) localData;
//int expectedSize = stack.size() - getStackPopCount(localData, stack) + getStackPushCount(localData, stack);
definition.translate(aLocalData.isStatic, definition.translate(aLocalData.isStatic,
aLocalData.scriptIndex, aLocalData.scriptIndex,
aLocalData.classIndex, aLocalData.classIndex,
aLocalData.localRegs, aLocalData.localRegs,
stack, stack,
aLocalData.scopeStack, aLocalData.scopeStack,
aLocalData.constants, this, aLocalData.methodInfo, output, aLocalData.methodBody, aLocalData.abc, aLocalData.localRegNames, aLocalData.fullyQualifiedNames, null, aLocalData.localRegAssignmentIps, aLocalData.ip, aLocalData.refs, aLocalData.code); aLocalData.constants, this, aLocalData.methodInfo, output, aLocalData.methodBody, aLocalData.abc, aLocalData.localRegNames, aLocalData.fullyQualifiedNames, null, aLocalData.localRegAssignmentIps, aLocalData.ip, aLocalData.refs, aLocalData.code);
/*if (stack.size() != expectedSize) {
throw new Error("HONFIKA stack size mismatch");
}*/
}

@Override
public int getStackPopCount(BaseLocalData localData, TranslateStack stack) {
AVM2LocalData aLocalData = (AVM2LocalData) localData;
return getStackPopCount(aLocalData);
}

@Override
public int getStackPushCount(BaseLocalData localData, TranslateStack stack) {
AVM2LocalData aLocalData = (AVM2LocalData) localData;
return getStackPushCount(aLocalData);
} }


public int getStackPopCount(AVM2LocalData aLocalData) { public int getStackPopCount(AVM2LocalData aLocalData) {
return definition.getStackPopCount(this, aLocalData.abc); return definition.getStackPopCount(this, aLocalData.abc);
} }


public int getStackPushCount(AVM2LocalData aLocalData) {
return definition.getStackPushCount(this, aLocalData.abc);
}

@Override @Override
public boolean isJump() { public boolean isJump() {
return (definition instanceof JumpIns) || (fixedBranch > -1); return (definition instanceof JumpIns) || (fixedBranch > -1);
Expand Down
19 changes: 19 additions & 0 deletions libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -711,6 +711,16 @@ public String getASMSource(ActionList container, Set<Long> knownAddreses, Script
public void translate(TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException { public void translate(TranslateStack stack, List<GraphTargetItem> output, HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) throws InterruptedException {
} }


@Override
public int getStackPopCount(BaseLocalData localData, TranslateStack stack) {
return 0;
}

@Override
public int getStackPushCount(BaseLocalData localData, TranslateStack stack) {
return 0;
}

/** /**
* Pops long value off the stack * Pops long value off the stack
* *
Expand Down Expand Up @@ -870,7 +880,16 @@ public static List<GraphTargetItem> actionsToTree(HashMap<Integer, String> regNa
@Override @Override
public void translate(BaseLocalData localData, TranslateStack stack, List<GraphTargetItem> output, int staticOperation, String path) throws InterruptedException { public void translate(BaseLocalData localData, TranslateStack stack, List<GraphTargetItem> output, int staticOperation, String path) throws InterruptedException {
ActionLocalData aLocalData = (ActionLocalData) localData; ActionLocalData aLocalData = (ActionLocalData) localData;
/*int expectedSize = stack.size() - getStackPopCount(localData, stack);
if (expectedSize < 0) {
expectedSize = 0;
}
expectedSize += getStackPushCount(localData, stack);*/

translate(stack, output, aLocalData.regNames, aLocalData.variables, aLocalData.functions, staticOperation, path); translate(stack, output, aLocalData.regNames, aLocalData.variables, aLocalData.functions, staticOperation, path);
/*if (stack.size() != expectedSize && !(this instanceof ActionPushDuplicate)) {
throw new Error("HONFIKA stack size mismatch");
}*/
} }


@Override @Override
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -257,20 +257,30 @@ private void executeActions(ActionList actions, int idx, int endIdx, ActionConst
} }


if (action instanceof ActionDefineLocal) { if (action instanceof ActionDefineLocal) {
GraphTargetItem top = stack.pop(); if (stack.size() < 2) {
String variableName = stack.peek().getResult().toString(); return;
}

String variableName = stack.peek(2).getResult().toString();
result.defines.add(variableName); result.defines.add(variableName);
stack.push(top);
} }


if (action instanceof ActionGetVariable) { if (action instanceof ActionGetVariable) {
if (stack.isEmpty()) {
return;
}

String variableName = stack.peek().getResult().toString(); String variableName = stack.peek().getResult().toString();
if (!localData.variables.containsKey(variableName)) { if (!localData.variables.containsKey(variableName)) {
break; break;
} }
} }


if (action instanceof ActionCallFunction) { if (action instanceof ActionCallFunction) {
if (stack.isEmpty()) {
return;
}

String functionName = stack.pop().getResult().toString(); String functionName = stack.pop().getResult().toString();
long numArgs = EcmaScript.toUint32(stack.pop().getResult()); long numArgs = EcmaScript.toUint32(stack.pop().getResult());
if (numArgs == 0) { if (numArgs == 0) {
Expand All @@ -283,6 +293,12 @@ private void executeActions(ActionList actions, int idx, int endIdx, ActionConst
break; break;
} }
} else { } else {
// do not throw EmptyStackException, much faster
int requiredStackSize = action.getStackPopCount(localData, stack);
if (stack.size() < requiredStackSize) {
return;
}

action.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); action.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");
} }


Expand Down Expand Up @@ -348,6 +364,10 @@ private void executeActions(ActionList actions, int idx, int endIdx, ActionConst


if (action instanceof ActionIf) { if (action instanceof ActionIf) {
ActionIf aif = (ActionIf) action; ActionIf aif = (ActionIf) action;
if (stack.isEmpty()) {
return;
}

if (EcmaScript.toBoolean(stack.pop().getResult())) { if (EcmaScript.toBoolean(stack.pop().getResult())) {
long address = aif.getAddress() + aif.getTotalActionLength() + aif.getJumpOffset(); long address = aif.getAddress() + aif.getTotalActionLength() + aif.getJumpOffset();
idx = actions.indexOf(actions.getByAddress(address)); idx = actions.indexOf(actions.getByAddress(address));
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -291,6 +291,12 @@ private void executeActions(ActionList actions, int idx, int endIdx, ExecutionRe
System.out.print(" '" + stack.get(j).getResult() + "'"); System.out.print(" '" + stack.get(j).getResult() + "'");
} }
System.out.println();*/ System.out.println();*/
// do not throw EmptyStackException, much faster
int requiredStackSize = action.getStackPopCount(localData, stack);
if (stack.size() < requiredStackSize) {
return;
}

action.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); action.translate(localData, stack, output, Graph.SOP_USE_STATIC, "");


if (!(action instanceof ActionPush if (!(action instanceof ActionPush
Expand Down Expand Up @@ -341,6 +347,10 @@ private void executeActions(ActionList actions, int idx, int endIdx, ExecutionRe


if (action instanceof ActionIf) { if (action instanceof ActionIf) {
ActionIf aif = (ActionIf) action; ActionIf aif = (ActionIf) action;
if (stack.isEmpty()) {
return;
}

if (EcmaScript.toBoolean(stack.pop().getResult())) { if (EcmaScript.toBoolean(stack.pop().getResult())) {
long address = aif.getAddress() + aif.getTotalActionLength() + aif.getJumpOffset(); long address = aif.getAddress() + aif.getTotalActionLength() + aif.getJumpOffset();
idx = actions.indexOf(actions.getByAddress(address)); idx = actions.indexOf(actions.getByAddress(address));
Expand Down
Original file line number Original file line Diff line number Diff line change
@@ -1,20 +1,22 @@
/* /*
* Copyright (C) 2010-2015 JPEXS, All rights reserved. * Copyright (C) 2010-2015 JPEXS, All rights reserved.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version. * 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, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * 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.action.flashlite; package com.jpexs.decompiler.flash.action.flashlite;


import com.jpexs.decompiler.flash.BaseLocalData;
import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.model.FSCommand2ActionItem; import com.jpexs.decompiler.flash.action.model.FSCommand2ActionItem;
import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.GraphTargetItem;
Expand Down Expand Up @@ -44,4 +46,19 @@ public void translate(TranslateStack stack, List<GraphTargetItem> output, HashMa
} }
stack.push(new FSCommand2ActionItem(this, command, args)); stack.push(new FSCommand2ActionItem(this, command, args));
} }

@Override
public int getStackPopCount(BaseLocalData localData, TranslateStack stack) {
int result = 2;
if (!stack.isEmpty()) {
result += stack.peek().getAsLong();
}

return result;
}

@Override
public int getStackPushCount(BaseLocalData localData, TranslateStack stack) {
return 1;
}
} }
Original file line number Original file line Diff line number Diff line change
@@ -1,18 +1,19 @@
/* /*
* Copyright (C) 2010-2015 JPEXS, All rights reserved. * Copyright (C) 2010-2015 JPEXS, All rights reserved.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version. * 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, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * 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.action.special; package com.jpexs.decompiler.flash.action.special;


import com.jpexs.decompiler.flash.BaseLocalData; import com.jpexs.decompiler.flash.BaseLocalData;
Expand Down Expand Up @@ -40,7 +41,8 @@ public void translate(BaseLocalData localData, TranslateStack stack, List<GraphT
if (stack.isEmpty()) { if (stack.isEmpty()) {
return; return;
} }
GraphTargetItem val = stack.pop();
stack.pop(); //Just ignore the value
} }


@Override @Override
Expand Down
Original file line number Original file line Diff line number Diff line change
@@ -1,20 +1,22 @@
/* /*
* Copyright (C) 2010-2015 JPEXS, All rights reserved. * Copyright (C) 2010-2015 JPEXS, All rights reserved.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version. * 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, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * 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.action.swf4; package com.jpexs.decompiler.flash.action.swf4;


import com.jpexs.decompiler.flash.BaseLocalData;
import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.model.operations.AddActionItem; import com.jpexs.decompiler.flash.action.model.operations.AddActionItem;
import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.GraphTargetItem;
Expand All @@ -39,4 +41,14 @@ public void translate(TranslateStack stack, List<GraphTargetItem> output, HashMa
GraphTargetItem b = stack.pop(); GraphTargetItem b = stack.pop();
stack.push(new AddActionItem(this, b, a, false)); stack.push(new AddActionItem(this, b, a, false));
} }

@Override
public int getStackPopCount(BaseLocalData localData, TranslateStack stack) {
return 2;
}

@Override
public int getStackPushCount(BaseLocalData localData, TranslateStack stack) {
return 1;
}
} }
Original file line number Original file line Diff line number Diff line change
@@ -1,20 +1,22 @@
/* /*
* Copyright (C) 2010-2015 JPEXS, All rights reserved. * Copyright (C) 2010-2015 JPEXS, All rights reserved.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version. * 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, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * 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.action.swf4; package com.jpexs.decompiler.flash.action.swf4;


import com.jpexs.decompiler.flash.BaseLocalData;
import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.model.operations.AndActionItem; import com.jpexs.decompiler.flash.action.model.operations.AndActionItem;
import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.GraphTargetItem;
Expand All @@ -39,4 +41,14 @@ public void translate(TranslateStack stack, List<GraphTargetItem> output, HashMa
GraphTargetItem b = stack.pop(); GraphTargetItem b = stack.pop();
stack.push(new AndActionItem(this, b, a)); stack.push(new AndActionItem(this, b, a));
} }

@Override
public int getStackPopCount(BaseLocalData localData, TranslateStack stack) {
return 2;
}

@Override
public int getStackPushCount(BaseLocalData localData, TranslateStack stack) {
return 1;
}
} }
Original file line number Original file line Diff line number Diff line change
@@ -1,20 +1,22 @@
/* /*
* Copyright (C) 2010-2015 JPEXS, All rights reserved. * Copyright (C) 2010-2015 JPEXS, All rights reserved.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version. * 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, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * 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.action.swf4; package com.jpexs.decompiler.flash.action.swf4;


import com.jpexs.decompiler.flash.BaseLocalData;
import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.model.AsciiToCharActionItem; import com.jpexs.decompiler.flash.action.model.AsciiToCharActionItem;
import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.GraphTargetItem;
Expand All @@ -38,4 +40,14 @@ public void translate(TranslateStack stack, List<GraphTargetItem> output, HashMa
GraphTargetItem a = stack.pop(); GraphTargetItem a = stack.pop();
stack.push(new AsciiToCharActionItem(this, a)); stack.push(new AsciiToCharActionItem(this, a));
} }

@Override
public int getStackPopCount(BaseLocalData localData, TranslateStack stack) {
return 1;
}

@Override
public int getStackPushCount(BaseLocalData localData, TranslateStack stack) {
return 1;
}
} }
Loading

0 comments on commit 696ee04

Please sign in to comment.