From dbcaaf01e8576ad33a9a189161911fc211922a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Tue, 2 Apr 2013 20:02:41 +0200 Subject: [PATCH] AS1/2 deobfuscation fix for variables renaming --- trunk/src/com/jpexs/decompiler/flash/SWF.java | 45 +++++++++++++------ .../decompiler/flash/SWFInputStream.java | 27 ++++++++--- .../flash/action/ActionGraphSource.java | 7 ++- .../flash/action/swf4/ActionJump.java | 2 +- .../jpexs/decompiler/flash/graph/Graph.java | 13 ++++-- .../decompiler/flash/graph/GraphSource.java | 4 ++ 6 files changed, 74 insertions(+), 24 deletions(-) diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index 329f5e773..03aea9f66 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.graph.GraphSourceItemContainer; import com.jpexs.decompiler.flash.action.swf4.ActionEquals; import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable; import com.jpexs.decompiler.flash.action.swf4.ActionIf; +import com.jpexs.decompiler.flash.action.swf4.ActionJump; import com.jpexs.decompiler.flash.action.swf4.ActionPush; import com.jpexs.decompiler.flash.action.swf4.ActionSetVariable; import com.jpexs.decompiler.flash.action.swf4.Null; @@ -45,6 +46,7 @@ import com.jpexs.decompiler.flash.flv.FLVOutputStream; import com.jpexs.decompiler.flash.flv.FLVTAG; import com.jpexs.decompiler.flash.flv.VIDEODATA; import com.jpexs.decompiler.flash.graph.GraphSourceItem; +import com.jpexs.decompiler.flash.graph.GraphSourceItemPos; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import com.jpexs.decompiler.flash.gui.FrameNode; import com.jpexs.decompiler.flash.gui.TagNode; @@ -238,7 +240,7 @@ public class SWF { * @param is Stream to read SWF from * @throws IOException */ - public SWF(InputStream is, PercentListener listener) throws IOException { + public SWF(InputStream is, PercentListener listener) throws IOException { byte hdr[] = new byte[3]; is.read(hdr); String shdr = new String(hdr); @@ -285,7 +287,7 @@ public class SWF { int tmpFirstByetOfFrameRate = sis.readUI8(); frameRate = sis.readUI8(); frameCount = sis.readUI16(); - tags = sis.readTagList(0); + tags = sis.readTagList(0); } /** @@ -510,13 +512,13 @@ public class SWF { } return ret; } - protected HashSet listeners = new HashSet(); + private HashSet listeners = new HashSet(); - public void addEventListener(EventListener listener) { + public final void addEventListener(EventListener listener) { listeners.add(listener); } - public void removeEventListener(EventListener listener) { + public final void removeEventListener(EventListener listener) { listeners.remove(listener); } @@ -947,7 +949,6 @@ public class SWF { } return null; } - private static void getVariables(ConstantPool constantPool, List localData, Stack stack, List output, ActionGraphSource code, int ip, int lastIp, HashMap variables, List functions, List visited) { boolean debugMode = false; while ((ip > -1) && ip < code.size()) { @@ -957,8 +958,13 @@ public class SWF { lastIp = ip; GraphSourceItem ins = code.get(ip); + if (debugMode) { - System.out.println("Visit " + ip + ": " + ins + " stack:" + Highlighting.stripHilights(stack.toString())); + System.err.println("Visit " + ip + ": ofs" +Helper.formatAddress(((Action)ins).getAddress())+":" + ((Action)ins).getASMSource(new ArrayList(), new ArrayList(), new ArrayList(), code.version,false) + " stack:" + Helper.stackToString(stack, Helper.toList(new ConstantPool()))); + } + if(ins.isIgnored()){ + ip++; + continue; } GraphTargetItem name = null; @@ -978,7 +984,12 @@ public class SWF { } if (ins instanceof GraphSourceItemContainer) { - //getVariables(variables, functions, new ActionGraphSource(((ActionContainer) ins).getActions(), code.version, new HashMap(), new HashMap(), new HashMap()), 0); + long endAddr=((GraphSourceItemContainer)ins).getEndAddress(); + int endIp=code.adr2pos(endAddr); + getVariables(variables, functions, new ActionGraphSource(code.getActions().subList(ip+1, endIp), code.version, new HashMap(),new HashMap(),new HashMap()),0); + ((GraphSourceItemContainer)ins).translateContainer(new ArrayList(), stack, output, new HashMap(),new HashMap(),new HashMap()); + ip=endIp; + continue; } if ((ins instanceof ActionSetVariable) || (ins instanceof ActionSetMember) || (ins instanceof ActionDefineLocal)) { @@ -1006,7 +1017,7 @@ public class SWF { break; } - if (ins.isBranch() || ins.isJump()) { + if (ins.isBranch() || ins.isJump()) { if (ins instanceof ActionIf) { stack.pop(); } @@ -1022,7 +1033,7 @@ public class SWF { } } } - + // } break; } ip++; @@ -1041,6 +1052,13 @@ public class SWF { private HashMap getVariables(HashMap variables, List functions, ASMSource src) { HashMap ret = new HashMap(); List actions = src.getActions(version); + /* int ip=0; + for(Action a:actions){ + System.out.println("ip "+ip+" "+a.getASMSource(new ArrayList(), new ArrayList(), new ArrayList(), version, false)); + ip++; + } + if(true) + return ret;*/ actionsMap.put(src, actions); List ss=new ArrayList(); ss.addAll(actions); @@ -1049,13 +1067,14 @@ public class SWF { } private HashMap> actionsMap = new HashMap>(); - private void getVariables(List objs) { + private void getVariables(List objs,String path) { for (Object o : objs) { if (o instanceof ASMSource) { + informListeners("getVariables", path+"/"+o.toString()); getVariables(allVariableNames, allFunctions, (ASMSource) o); } if (o instanceof Container) { - getVariables(((Container) o).getSubItems()); + getVariables(((Container) o).getSubItems(),path+"/"+o.toString()); } } } @@ -1067,7 +1086,7 @@ public class SWF { List objs = new ArrayList(); int ret = 0; objs.addAll(tags); - getVariables(objs); + getVariables(objs,""); for (GraphSourceItem fun : allFunctions) { if (fun instanceof ActionDefineFunction) { ActionDefineFunction f = (ActionDefineFunction) fun; diff --git a/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java b/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java index 3a62f5791..847c60ec5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -540,8 +540,15 @@ public class SWFInputStream extends InputStream { } } if (debugMode) { - System.err.println("getConstantPool ip " + ip + ": " + ins + " stack:" + Helper.stackToString(stack,Helper.toList(cpool))); - if(ip==68){ + String add=""; + if(ins instanceof ActionIf){ + add+=" change:"+((ActionIf)ins).getJumpOffset(); + } + if(ins instanceof ActionJump){ + add+=" change:"+(((ActionJump)ins).getJumpOffset()); + } + System.err.println("getConstantPool ip " + ip + ", addr "+Helper.formatAddress(((Action)ins).getAddress())+": " + ((Action)ins).getASMSource(new ArrayList(),new ArrayList(), Helper.toList(cpool), version, false) +add+ " stack:" + Helper.stackToString(stack,Helper.toList(cpool))); + if(ip==116){ System.err.println("kok"); } } @@ -698,6 +705,16 @@ public class SWFInputStream extends InputStream { } List pools = new ArrayList(); + StringBuilder br=new StringBuilder(); + for(int i=0;i(), new ArrayList(), cpool.constants, version, false)); + br.append("\r\n"); + } + Helper.writeFile("test.txt", br.toString().getBytes()); pools = getConstantPool(new ActionGraphSource(ret, version, new HashMap(), new HashMap(), new HashMap()), ip, version); if (pools.size() == 1) { @@ -814,7 +831,7 @@ public class SWFInputStream extends InputStream { } System.err.println(); //} - if(ip - startIp==911){ + if(ip - startIp==110){ System.err.println("dd"); //readActionListAtPos ip: 116 (0x0074) action(len 2): If loc0125 ;compileTime stack:[!(==734)] [9d 02 00 21 00] } @@ -985,10 +1002,10 @@ public class SWFInputStream extends InputStream { List localData2 = Helper.toList(new HashMap(), new HashMap(), new HashMap()); List output2=new ArrayList(); readActionListAtPos(output2,containers, address, containerSWFOffset, notCompileTime, enableVariables, localData2, new Stack(), cpool, sis, rri, ip+info, ret, startIp, (int)endAddr); - cnt.translateContainer(output2, stack, output,(HashMap) localData.get(0),(HashMap)localData.get(1),(HashMap)localData.get(2)); - + cnt.translateContainer(output2, stack, output,(HashMap) localData.get(0),(HashMap)localData.get(1),(HashMap)localData.get(2)); ip = (int)endAddr; prevIp = ip; + rri.setPos(ip); filePos = rri.getPos(); continue; //infoCorrect += ((ActionContainer) a).getDataLength(); diff --git a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraphSource.java b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraphSource.java index 117ab9b81..b6e0f889c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraphSource.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraphSource.java @@ -9,6 +9,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Stack; +import java.util.logging.Level; +import java.util.logging.Logger; /** * @@ -110,12 +112,13 @@ public class ActionGraphSource extends GraphSource { } //ret = adr2posInside(adr); if(ret==-1){ - System.err.println("Addr loc"+Helper.formatAddress(adr)+" not found"); + Logger.getLogger(ActionGraphSource.class.getName()).log(Level.SEVERE, "Address loc"+Helper.formatAddress(adr)+" not found"); + /*System.err.println("Addr loc"+Helper.formatAddress(adr)+" not found"); int pos=0; for(long l:posCache){ System.err.println("ip "+pos+" action "+get(pos).toString()+" loc"+Helper.formatAddress(l)); pos++; - } + }*/ } } return ret; diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionJump.java b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionJump.java index dfcb1b69f..20406273d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionJump.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionJump.java @@ -52,7 +52,7 @@ public class ActionJump extends Action { public ActionJump(SWFInputStream sis) throws IOException { super(0x99, 2); - offset = sis.readSI16(); + setJumpOffset(sis.readSI16()); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java b/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java index edf3b3bee..4f8d24f31 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.graph; +import com.jpexs.decompiler.flash.action.treemodel.ConstantPool; import com.jpexs.decompiler.flash.helpers.Highlighting; import java.util.ArrayList; import java.util.HashMap; @@ -948,8 +949,7 @@ public class Graph { } else { ret.addAll(output); } - GraphPart loopBodyStart = null; - GraphPart next = part.getNextPartPath(loopContinues); + GraphPart loopBodyStart = null; if (reversed == loop) { if (expr instanceof LogicalOpItem) { expr = ((LogicalOpItem) expr).invert(); @@ -957,6 +957,8 @@ public class Graph { expr = new NotItem(null, expr); } } + + GraphPart next = part.getNextPartPath(loopContinues); List retx = ret; if ((!loop) || (doWhile && (part.nextParts.size() > 1))) { if (doWhile) { @@ -1288,6 +1290,9 @@ public class Graph { GraphPart part = ret; while (ip < code.size()) { if (visited2[ip] || ((ip != startip) && (refs.get(ip).size() > 1))) { + if(lastIp==497){ + System.out.println("dff"); + } part.end = lastIp; GraphPart found = null; for (GraphPart p : allBlocks) { @@ -1311,6 +1316,7 @@ public class Graph { part = gp; } } + ip = checkIp(ip); lastIp = ip; GraphSourceItem ins = code.get(ip); @@ -1319,7 +1325,7 @@ public class Graph { continue; } if(ins instanceof GraphSourceItemContainer){ - ip=code.adr2pos(((GraphSourceItemContainer)ins).getEndAddress()); + ip = code.adr2pos(((GraphSourceItemContainer)ins).getEndAddress()); continue; }else if (ins.isExit()) { @@ -1335,6 +1341,7 @@ public class Graph { break; } else if (ins.isBranch()) { part.end = ip; + allBlocks.add(part); List branches = ins.getBranches(code); for (int i = 0; i < branches.size(); i++) { diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/GraphSource.java b/trunk/src/com/jpexs/decompiler/flash/graph/GraphSource.java index d7c62ad58..eba9f3cac 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/GraphSource.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/GraphSource.java @@ -40,6 +40,10 @@ public abstract class GraphSource { break; } + if(ins instanceof GraphSourceItemContainer){ + visitCode(adr2pos(((GraphSourceItemContainer)ins).getEndAddress()), ip, refs); + } + if (ins.isBranch() || ins.isJump()) { List branches = ins.getBranches(this); for (int b : branches) {