Deobfuscation simplified

This commit is contained in:
Honfika
2013-12-01 13:55:08 +01:00
parent ac96c7dbb5
commit 09aeafb77b
10 changed files with 70 additions and 81 deletions
@@ -71,6 +71,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction;
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
@@ -927,7 +928,7 @@ public class AVM2Code implements Serializable {
}
if (ins.labelname != null) {
writer.appendNoHilight(ins.labelname + ":");
} else if (offsets.contains(ofs)) {
} else if (Configuration.showAllAddresses.get() || offsets.contains(ofs)) {
writer.appendNoHilight("ofs" + Helper.formatAddress(ofs) + ":");
}
/*for (int e = 0; e < body.exceptions.length; e++) {
@@ -2375,7 +2376,7 @@ public class AVM2Code implements Serializable {
}
@SuppressWarnings("unchecked")
private static int removeTraps(HashMap<Integer, List<Integer>> refs, boolean secondPass, boolean indeterminate, List<Object> localData, Stack<GraphTargetItem> stack, List<GraphTargetItem> output, AVM2GraphSource code, int ip, HashMap<Integer, Integer> visited, HashMap<Integer, HashMap<Integer, GraphTargetItem>> visitedStates, HashMap<GraphSourceItem, Decision> decisions, String path, int recursionLevel) throws InterruptedException {
private static int removeTraps(HashMap<Integer, List<Integer>> refs, boolean secondPass, boolean indeterminate, List<Object> localData, Stack<GraphTargetItem> stack, List<GraphTargetItem> output, AVM2GraphSource code, int ip, HashMap<Integer, Integer> visited, HashMap<Integer, HashMap<Integer, GraphTargetItem>> visitedStates, HashMap<AVM2Instruction, Decision> decisions, String path, int recursionLevel) throws InterruptedException {
if (Thread.interrupted()) {
throw new InterruptedException();
}
@@ -2427,20 +2428,16 @@ public class AVM2Code implements Serializable {
}
}*/
GraphSourceItem ins = code.get(ip);
if (ins instanceof AVM2Instruction) {
AVM2Instruction ains = (AVM2Instruction) ins;
//Errorneous code inserted by some obfuscators
if (ains.definition instanceof NewObjectIns) {
if (ains.operands[0] > stack.size()) {
ains.setIgnored(true, 0);
}
AVM2Instruction ins = code.get(ip);
//Errorneous code inserted by some obfuscators
if (ins.definition instanceof NewObjectIns) {
if (ins.operands[0] > stack.size()) {
ins.setIgnored(true, 0);
}
if (ains.definition instanceof NewArrayIns) {
if (ains.operands[0] > stack.size()) {
ains.setIgnored(true, 0);
}
}
if (ins.definition instanceof NewArrayIns) {
if (ins.operands[0] > stack.size()) {
ins.setIgnored(true, 0);
}
}
@@ -2482,7 +2479,7 @@ public class AVM2Code implements Serializable {
if ((ins instanceof AVM2Instruction) && (((AVM2Instruction) ins).definition instanceof NewFunctionIns)) {
if (((AVM2Instruction) ins).definition instanceof NewFunctionIns) {
stack.push(new BooleanAVM2Item(null, true));
} else {
localData.set(15, ip);
@@ -2490,17 +2487,14 @@ public class AVM2Code implements Serializable {
}
if (ins instanceof AVM2Instruction) {
AVM2Instruction ains = (AVM2Instruction) ins;
if (ains.definition instanceof SetLocalTypeIns) {
SetLocalTypeIns slt = (SetLocalTypeIns) ains.definition;
int regId = slt.getRegisterId(ains);
if (indeterminate) {
HashMap<Integer, GraphTargetItem> registers = (HashMap<Integer, GraphTargetItem>) localData.get(2);
GraphTargetItem regVal = registers.get(regId);
if (regVal.isCompileTime()) {
registers.put(regId, new NotCompileTimeItem(null, regVal));
}
if (ins.definition instanceof SetLocalTypeIns) {
SetLocalTypeIns slt = (SetLocalTypeIns) ins.definition;
int regId = slt.getRegisterId(ins);
if (indeterminate) {
HashMap<Integer, GraphTargetItem> registers = (HashMap<Integer, GraphTargetItem>) localData.get(2);
GraphTargetItem regVal = registers.get(regId);
if (regVal.isCompileTime()) {
registers.put(regId, new NotCompileTimeItem(null, regVal));
}
}
}
@@ -2512,8 +2506,11 @@ public class AVM2Code implements Serializable {
if (ins.isBranch() || ins.isJump()) {
List<Integer> branches = ins.getBranches(code);
if ((ins instanceof AVM2Instruction) && ((AVM2Instruction) ins).definition instanceof IfTypeIns
&& (!(((AVM2Instruction) ins).definition instanceof JumpIns)) && (!stack.isEmpty()) && (stack.peek().isCompileTime()) && (!stack.peek().hasSideEffect())) {
if (((AVM2Instruction) ins).definition instanceof IfTypeIns
&& (!(((AVM2Instruction) ins).definition instanceof JumpIns))
&& (!stack.isEmpty())
&& (stack.peek().isCompileTime())
&& (!stack.peek().hasSideEffect())) {
boolean condition = EcmaScript.toBoolean(stack.peek().getResult());
if (debugMode) {
if (condition) {
@@ -2629,7 +2626,7 @@ public class AVM2Code implements Serializable {
break;
}
ip++;
};
}
if (ip < 0) {
System.out.println("Visited Negative: " + ip);
}
@@ -2637,16 +2634,17 @@ public class AVM2Code implements Serializable {
}
public static int removeTraps(ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, List<Object> localData, AVM2GraphSource code, int addr, String path, HashMap<Integer, List<Integer>> refs) throws InterruptedException {
HashMap<GraphSourceItem, AVM2Code.Decision> decisions = new HashMap<>();
HashMap<AVM2Instruction, AVM2Code.Decision> decisions = new HashMap<>();
removeTraps(refs, false, false, localData, new Stack<GraphTargetItem>(), new ArrayList<GraphTargetItem>(), code, code.adr2pos(addr), new HashMap<Integer, Integer>(), new HashMap<Integer, HashMap<Integer, GraphTargetItem>>(), decisions, path, 0);
int cnt = 0;
for (GraphSourceItem src : decisions.keySet()) {
for (AVM2Instruction src : decisions.keySet()) {
Decision dec = decisions.get(src);
if (dec != null) {
if ((src instanceof AVM2Instruction) && (((AVM2Instruction) src).definition instanceof LookupSwitchIns)) {
if (((AVM2Instruction) src).definition instanceof LookupSwitchIns) {
AVM2Instruction asrc = (AVM2Instruction) src;
if (dec.casesUsed.size() == 1) {
for (int c : dec.casesUsed) {
src.setFixBranch(c);
asrc.setFixBranch(c);
cnt++;
}
}
@@ -3,6 +3,7 @@ package com.jpexs.decompiler.flash.abc.avm2.graph;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.ConvertOutput;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.graph.GraphPart;
import com.jpexs.decompiler.graph.GraphSource;
@@ -57,7 +58,7 @@ public class AVM2GraphSource extends GraphSource {
}
@Override
public GraphSourceItem get(int pos) {
public AVM2Instruction get(int pos) {
return code.code.get(pos);
}
@@ -350,13 +350,11 @@ public class AVM2Instruction implements Serializable, GraphSourceItem {
this.ignored = ignored;
}
@Override
public void setFixBranch(int pos) {
this.fixedBranch = pos;
}
private int fixedBranch = -1;
@Override
public int getFixBranch() {
return fixedBranch;
}
@@ -478,7 +478,7 @@ public class Action implements GraphSourceItem {
}
}
if (importantOffsets.contains(offset)) {
if (Configuration.showAllAddresses.get() || importantOffsets.contains(offset)) {
if (lastPush) {
writer.newLine();
lastPush = false;
@@ -488,8 +488,6 @@ public class Action implements GraphSourceItem {
writer.appendNoHilight(":");
}
if (a.replaceWith != null) {
if (lastPush) {
writer.newLine();
@@ -536,26 +534,24 @@ public class Action implements GraphSourceItem {
writer.append("", offset);
int fixBranch = -1;
if (a instanceof ActionIf) {
ActionIf aif = (ActionIf) a;
if (aif.jumpUsed && !aif.ignoreUsed) {
aif.setFixBranch(0);
fixBranch = 0;
}
if (!aif.jumpUsed && aif.ignoreUsed) {
aif.setFixBranch(1);
fixBranch = 1;
}
}
int fixBranch = a.getFixBranch();
if (fixBranch > -1) {
if (a instanceof ActionIf) {
writer.appendNoHilight("ffdec_deobfuscatepop").newLine();
if (fixBranch == 0) { //jump
writer.appendNoHilight("jump loc");
writer.appendNoHilight(Helper.formatAddress(a.getAddress() + a.getBytes(version).length + ((ActionIf) a).getJumpOffset()));
} else {
//nojump, ignore
}
writer.appendNoHilight("FFDec_DeobfuscatePop").newLine();
if (fixBranch == 0) { //jump
writer.appendNoHilight("Jump loc");
writer.appendNoHilight(Helper.formatAddress(a.getAddress() + a.getBytes(version).length + ((ActionIf) a).getJumpOffset()));
} else {
//nojump, ignore
}
} else {
a.getASMSourceReplaced(list, importantOffsets, constantPool, version, exportMode, writer);
@@ -564,7 +560,7 @@ public class Action implements GraphSourceItem {
writer.appendNoHilight(add);
if (!(a instanceof ActionPush)) {
writer.newLine();
};
}
}
if (a instanceof ActionPush) {
lastPush = true;
@@ -1266,17 +1262,6 @@ public class Action implements GraphSourceItem {
return 0;
}
@Override
public void setFixBranch(int pos) {
this.fixedBranch = pos;
}
private int fixedBranch = -1;
@Override
public int getFixBranch() {
return fixedBranch;
}
public static GraphTargetItem gettoset(GraphTargetItem get, GraphTargetItem value) {
GraphTargetItem ret = get;
if (ret instanceof GetVariableActionItem) {
@@ -214,7 +214,13 @@ public class ActionListReader {
if (a instanceof ActionIf || a instanceof GraphSourceItemContainer) {
maxRecursionLevel++;
}
if (a instanceof ActionIf) {
ActionIf aif = (ActionIf) a;
aif.ignoreUsed = false;
aif.jumpUsed = false;
}
}
deobfustaceActionListAtPosRecursive(listeners, new ArrayList<GraphTargetItem>(), new HashMap<Long, List<GraphSourceItemContainer>>(), containerSWFOffset, localData, stack, cpool, actionMap, ip, ip, retdups, ip, endIp, path, new HashMap<Integer, Integer>(), false, new HashMap<Integer, HashMap<String, GraphTargetItem>>(), version, 0, maxRecursionLevel);
if (!retdups.isEmpty()) {
@@ -759,24 +765,17 @@ public class ActionListReader {
break;
}
} else if (top.isCompileTime() && (!top.hasSideEffect())) {
((ActionIf) a).compileTime = true;
if (debugMode) {
System.err.print("is compiletime -> ");
}
if (EcmaScript.toBoolean(top.getResult())) {
newip = pos + aif.getJumpOffset();
aif.jumpUsed = true;
if (aif.ignoreUsed) {
aif.compileTime = false;
}
if (debugMode) {
System.err.println("jump");
}
} else {
aif.ignoreUsed = true;
if (aif.jumpUsed) {
aif.compileTime = false;
}
if (debugMode) {
System.err.println("ignore");
}
@@ -60,10 +60,15 @@ public class ASMParser {
} else if (symb.type == ASMParsedSymbol.TYPE_COMMENT) {
if (!list.isEmpty()) {
String cmt = (String) symb.value;
if (cmt.equals("compileTime")) {
if (cmt.equals("compileTimeJump")) {
Action a = list.get(list.size() - 1);
if (a instanceof ActionIf) {
((ActionIf) a).compileTime = true;
((ActionIf) a).ignoreUsed = false;
}
} else if (cmt.equals("compileTimeIgnore")) {
Action a = list.get(list.size() - 1);
if (a instanceof ActionIf) {
((ActionIf) a).jumpUsed = false;
}
}
}
@@ -37,9 +37,8 @@ public class ActionIf extends Action {
private int offset;
public String identifier;
public boolean compileTime;
public boolean jumpUsed = false;
public boolean ignoreUsed = false;
public boolean jumpUsed = true;
public boolean ignoreUsed = true;
public int getJumpOffset() {
return offset;
@@ -85,7 +84,7 @@ public class ActionIf extends Action {
@Override
public String getASMSource(List<? extends GraphSourceItem> container, List<Long> knownAddreses, List<String> constantPool, int version, ExportMode exportMode) {
String ofsStr = Helper.formatAddress(getAddress() + getBytes(version).length + offset);
return "If loc" + ofsStr + (compileTime ? " ;compileTime" : "");
return "If loc" + ofsStr + (!jumpUsed ? " ;compileTimeIgnore" : (!ignoreUsed ? " ;compileTimeJump" : ""));
}
public ActionIf(FlasmLexer lexer) throws IOException, ParseException {
@@ -69,6 +69,10 @@ public class Configuration {
public static final ConfigurationItem<Boolean> removeNops = null;
@ConfigurationDefaultBoolean(false)
public static final ConfigurationItem<Boolean> showHexOnlyButton = null;
@ConfigurationDefaultBoolean(false)
public static final ConfigurationItem<Boolean> decimalAddress = null;
@ConfigurationDefaultBoolean(false)
public static final ConfigurationItem<Boolean> showAllAddresses = null;
/**
* Debug mode = throwing an error when comparing original file and
@@ -44,9 +44,5 @@ public interface GraphSourceItem extends Serializable {
public void setIgnored(boolean ignored, int pos);
public void setFixBranch(int pos);
public int getFixBranch();
public boolean isDeobfuscatePop();
}
+4
View File
@@ -16,6 +16,7 @@
*/
package com.jpexs.helpers;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.helpers.Freed;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
@@ -122,6 +123,9 @@ public class Helper {
* @return String representation of the address
*/
public static String formatAddress(long number) {
if (Configuration.decimalAddress.get()) {
return padZeros(Long.toString(number), 4);
}
return padZeros(Long.toHexString(number), 4);
}