From 92b02e3b56e1329ad5686b09762c7c4133157867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Sun, 10 Feb 2013 14:00:49 +0100 Subject: [PATCH] AS2: p-code deobfuscation --- .../jpexs/asdec/ReReadableInputStream.java | 63 ++++++++ trunk/src/com/jpexs/asdec/SWFInputStream.java | 142 +++++++++++++++++- .../asdec/abc/avm2/treemodel/TreeItem.java | 1 + trunk/src/com/jpexs/asdec/action/Action.java | 28 ++-- .../jpexs/asdec/action/special/ActionNop.java | 41 +++++ .../jpexs/asdec/action/swf3/ActionGetURL.java | 2 +- .../jpexs/asdec/action/swf4/ActionJump.java | 13 ++ .../jpexs/asdec/action/swf4/ActionPush.java | 6 +- .../asdec/action/swf4/ConstantIndex.java | 2 +- .../action/swf5/ActionDefineFunction.java | 28 ++++ .../action/swf7/ActionDefineFunction2.java | 35 +++++ .../action/treemodel/DecrementTreeItem.java | 12 ++ .../action/treemodel/DirectValueTreeItem.java | 28 ++++ .../action/treemodel/FunctionTreeItem.java | 2 +- .../action/treemodel/IncrementTreeItem.java | 12 ++ .../asdec/action/treemodel/TreeItem.java | 13 ++ .../treemodel/operations/AddTreeItem.java | 7 + .../treemodel/operations/AndTreeItem.java | 7 + .../treemodel/operations/AsTypeTreeItem.java | 7 + .../operations/BinaryOpTreeItem.java | 4 + .../treemodel/operations/BitAndTreeItem.java | 5 + .../treemodel/operations/BitNotTreeItem.java | 7 + .../treemodel/operations/BitOrTreeItem.java | 5 + .../treemodel/operations/BitXorTreeItem.java | 5 + .../treemodel/operations/DivideTreeItem.java | 5 + .../treemodel/operations/EqTreeItem.java | 7 + .../treemodel/operations/GeTreeItem.java | 7 + .../treemodel/operations/GtTreeItem.java | 5 + .../treemodel/operations/InTreeItem.java | 7 + .../operations/InstanceOfTreeItem.java | 7 + .../treemodel/operations/IsTypeTreeItem.java | 7 + .../treemodel/operations/LShiftTreeItem.java | 5 + .../treemodel/operations/LeTreeItem.java | 5 + .../treemodel/operations/LtTreeItem.java | 5 + .../treemodel/operations/ModuloTreeItem.java | 5 + .../operations/MultiplyTreeItem.java | 5 + .../treemodel/operations/NegTreeItem.java | 7 + .../treemodel/operations/NeqTreeItem.java | 5 + .../treemodel/operations/NotTreeItem.java | 8 + .../treemodel/operations/OrTreeItem.java | 7 + .../operations/PreDecrementTreeItem.java | 7 + .../operations/PreIncrementTreeItem.java | 7 + .../treemodel/operations/RShiftTreeItem.java | 5 + .../operations/StrictEqTreeItem.java | 5 + .../operations/StrictNeqTreeItem.java | 5 + .../operations/StringAddTreeItem.java | 5 + .../operations/StringEqTreeItem.java | 7 + .../operations/StringLengthTreeItem.java | 5 + .../operations/StringLtTreeItem.java | 5 + .../operations/SubtractTreeItem.java | 7 + .../treemodel/operations/URShiftTreeItem.java | 5 + .../treemodel/operations/UnaryOpTreeItem.java | 5 + 52 files changed, 614 insertions(+), 26 deletions(-) create mode 100644 trunk/src/com/jpexs/asdec/ReReadableInputStream.java create mode 100644 trunk/src/com/jpexs/asdec/action/special/ActionNop.java diff --git a/trunk/src/com/jpexs/asdec/ReReadableInputStream.java b/trunk/src/com/jpexs/asdec/ReReadableInputStream.java new file mode 100644 index 000000000..bdfc7de45 --- /dev/null +++ b/trunk/src/com/jpexs/asdec/ReReadableInputStream.java @@ -0,0 +1,63 @@ +package com.jpexs.asdec; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * + * @author JPEXS + */ +public class ReReadableInputStream extends InputStream { + + InputStream is; + ByteArrayOutputStream baos=new ByteArrayOutputStream(); + byte []converted; + int pos=0; + int count=0; + + public byte[] getAllRead(){ + return baos.toByteArray(); + } + + public int getPos() { + return pos; + } + + + + public ReReadableInputStream(InputStream is) { + this.is=is; + } + + + public void setPos(int pos) throws IOException{ + if(pos>count){ + skip(pos-count); + } + this.pos=pos; + } + + @Override + public int read() throws IOException { + if(pos listeners = new ArrayList(); private long percentMax; + private List buffered = new ArrayList(); + private ByteArrayOutputStream buffer; + + public int getBufferLength() { + return buffer.size(); + } + + public void startBuffer() { + stopBuffer(); + buffer = new ByteArrayOutputStream(); + } + + public byte[] getBuffer() { + return buffer.toByteArray(); + } + + public byte[] stopBuffer() { + if (buffer != null) { + byte[] ret = buffer.toByteArray(); + buffered.add(ret); + buffer = null; + return ret; + } + return null; + } public void addPercentListener(PercentListener listener) { listeners.add(listener); @@ -448,14 +480,118 @@ public class SWFInputStream extends InputStream { * @throws IOException */ public List readActionList() throws IOException { + List retdups = new ArrayList(); + ConstantPool cpool = null; + + Stack stack = new Stack(); + + ReReadableInputStream rri = new ReReadableInputStream(this); + SWFInputStream sis = new SWFInputStream(rri, version); + readActionListAtPos(stack, cpool, sis, rri, 0, retdups); List ret = new ArrayList(); - Action a; - while ((a = readAction()) != null) { - ret.add(a); + Action last = null; + for (Action a : retdups) { + if (a != last) { + ret.add(a); + } + last = a; } return ret; } + private void readActionListAtPos(Stack stack, ConstantPool cpool, SWFInputStream sis, ReReadableInputStream rri, int ip, List ret) throws IOException { + rri.setPos(ip); + Action a; + List output = new ArrayList(); + long filePos = rri.getPos(); + while ((a = sis.readAction()) != null) { + if (a instanceof ActionPush) { + if (cpool != null) { + ((ActionPush) a).constantPool = cpool.constants; + } + } + if (a instanceof ActionDefineFunction) { + if (cpool != null) { + ((ActionDefineFunction) a).setConstantPool(cpool.constants); + } + } + if (a instanceof ActionDefineFunction2) { + if (cpool != null) { + ((ActionDefineFunction2) a).setConstantPool(cpool.constants); + } + } + long newFilePos = rri.getPos(); + long actionLen = newFilePos - filePos; + + ensureCapacity(ret, ip); + int newip = -1; + if (!(ret.get(ip) instanceof ActionNop)) { + break; + } + + if (a instanceof ActionConstantPool) { + if (cpool == null) { + cpool = new ConstantPool(); + } + cpool.constants = ((ActionConstantPool) a).constantPool; + } + Action beforeInsert = null; + ActionIf aif = null; + boolean goaif = false; + if (a instanceof ActionIf) { + aif = (ActionIf) a; + TreeItem top = stack.pop(); + if (top.isCompileTime()) { + if (top.toBoolean()) { + newip = rri.getPos() + aif.offset; + rri.setPos(newip); + a = new ActionJump(aif.offset); + } else { + a = new ActionNop(); + } + beforeInsert = new ActionPop(); + } else { + goaif = true; + } + } else if (a instanceof ActionJump) { + newip = rri.getPos() + ((ActionJump) a).offset; + rri.setPos(newip); + } else { + a.translate(stack, cpool, output, new HashMap()); + } + for (int i = 0; i < actionLen; i++) { + ensureCapacity(ret, ip + i); + if (a instanceof ActionNop) { + a = new ActionNop(); + if (i == 0) { + a.beforeInsert = beforeInsert; + } + } else { + a.beforeInsert = beforeInsert; + } + ret.set(ip + i, a); + } + + if (newip > -1) { + ip = newip; + } else { + ip = ip + (int) actionLen; + } + filePos = rri.getPos(); + if (goaif) { + int oldPos = rri.getPos(); + readActionListAtPos(stack, cpool, sis, rri, rri.getPos() + aif.offset, ret); + rri.setPos(oldPos); + } + } + } + + private void ensureCapacity(List ret, int index) { + while (ret.size() <= index) { + ret.add(new ActionNop()); + } + } + private static void dumpTag(PrintStream out, int version, Tag tag, int level) { StringBuilder sb = new StringBuilder(); sb.append(Helper.formatHex((int) tag.getPos(), 8)); diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/TreeItem.java b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/TreeItem.java index 19d486264..4adcc7c8f 100644 --- a/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/TreeItem.java +++ b/trunk/src/com/jpexs/asdec/abc/avm2/treemodel/TreeItem.java @@ -21,6 +21,7 @@ import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction; import com.jpexs.asdec.helpers.Highlighting; import java.util.HashMap; import java.util.List; +import java.util.Stack; public abstract class TreeItem { diff --git a/trunk/src/com/jpexs/asdec/action/Action.java b/trunk/src/com/jpexs/asdec/action/Action.java index bb57bc69f..a5384feb7 100644 --- a/trunk/src/com/jpexs/asdec/action/Action.java +++ b/trunk/src/com/jpexs/asdec/action/Action.java @@ -21,6 +21,7 @@ import com.jpexs.asdec.SWFOutputStream; import com.jpexs.asdec.action.parser.FlasmLexer; import com.jpexs.asdec.action.parser.ParseException; import com.jpexs.asdec.action.parser.ParsedSymbol; +import com.jpexs.asdec.action.special.ActionNop; import com.jpexs.asdec.action.swf4.*; import com.jpexs.asdec.action.swf5.*; import com.jpexs.asdec.action.swf6.ActionEnumerate2; @@ -46,6 +47,7 @@ import java.util.logging.Logger; */ public class Action { + public Action beforeInsert; /** * Action type identifier */ @@ -361,29 +363,17 @@ public class Action { } offset = 0; - if (Main.LATEST_CONSTANTPOOL_HACK) { - for (Action a : list) { - if (a instanceof ActionConstantPool) { - constantPool.clear(); - constantPool.addAll(((ActionConstantPool) a).constantPool); - } - } - } - for (Action a : list) { - if (!Main.LATEST_CONSTANTPOOL_HACK) { - if (a instanceof ActionConstantPool) { - constantPool.clear(); - constantPool.addAll(((ActionConstantPool) a).constantPool); - } - } - if (a instanceof ActionPush) { - ((ActionPush) a).constantPool = constantPool; - } + for (Action a : list) { offset = a.getAddress(); if (importantOffsets.contains(offset)) { ret += "loc" + Helper.formatAddress(offset) + ":"; } - ret += Highlighting.hilighOffset("", offset) + a.getASMSource(importantOffsets, constantPool, version) + "\r\n"; + if(a.beforeInsert!=null){ + ret+=a.beforeInsert.getASMSource(importantOffsets, constantPool, version) + "\r\n"; + } + if(!(a instanceof ActionNop)){ + ret += Highlighting.hilighOffset("", offset) + a.getASMSource(importantOffsets, constantPool, version) + "\r\n"; + } offset += a.getBytes(version).length; } if (importantOffsets.contains(offset)) { diff --git a/trunk/src/com/jpexs/asdec/action/special/ActionNop.java b/trunk/src/com/jpexs/asdec/action/special/ActionNop.java new file mode 100644 index 000000000..f100fa3ca --- /dev/null +++ b/trunk/src/com/jpexs/asdec/action/special/ActionNop.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010-2013 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.asdec.action.special; + +import com.jpexs.asdec.action.Action; +import com.jpexs.asdec.action.treemodel.ConstantPool; +import com.jpexs.asdec.action.treemodel.SimpleActionTreeItem; +import com.jpexs.asdec.action.treemodel.TreeItem; +import java.util.List; +import java.util.Stack; + +public class ActionNop extends Action { + + public ActionNop() { + super(-1, 0); + } + + @Override + public String toString() { + return "Nop"; + } + + @Override + public void translate(Stack stack, ConstantPool constants, List output, java.util.HashMap regNames) { + output.add(new SimpleActionTreeItem(this, "nop();")); + } +} diff --git a/trunk/src/com/jpexs/asdec/action/swf3/ActionGetURL.java b/trunk/src/com/jpexs/asdec/action/swf3/ActionGetURL.java index 5237e9774..c93119947 100644 --- a/trunk/src/com/jpexs/asdec/action/swf3/ActionGetURL.java +++ b/trunk/src/com/jpexs/asdec/action/swf3/ActionGetURL.java @@ -71,5 +71,5 @@ public class ActionGetURL extends Action { @Override public void translate(Stack stack, ConstantPool constants, List output, java.util.HashMap regNames) { output.add(new GetURLTreeItem(this, urlString, targetString)); - } + } } diff --git a/trunk/src/com/jpexs/asdec/action/swf4/ActionJump.java b/trunk/src/com/jpexs/asdec/action/swf4/ActionJump.java index d7da282d6..cd9e735d2 100644 --- a/trunk/src/com/jpexs/asdec/action/swf4/ActionJump.java +++ b/trunk/src/com/jpexs/asdec/action/swf4/ActionJump.java @@ -32,6 +32,12 @@ public class ActionJump extends Action { public int offset; public String identifier; + public ActionJump(int offset){ + super(0x99,2); + this.offset=offset; + } + + public ActionJump(SWFInputStream sis) throws IOException { super(0x99, 2); offset = sis.readSI16(); @@ -76,4 +82,11 @@ public class ActionJump extends Action { ret.add(this); return ret; } + + @Override + public String toString() { + return "Jump"; + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/swf4/ActionPush.java b/trunk/src/com/jpexs/asdec/action/swf4/ActionPush.java index fced5c592..2e5acfc6c 100644 --- a/trunk/src/com/jpexs/asdec/action/swf4/ActionPush.java +++ b/trunk/src/com/jpexs/asdec/action/swf4/ActionPush.java @@ -201,7 +201,11 @@ public class ActionPush extends Action { public void translate(Stack stack, ConstantPool constants, List output, java.util.HashMap regNames) { for (Object o : values) { if (o instanceof ConstantIndex) { - o = constants.constants.get(((ConstantIndex) o).index); + if((constants==null)||(((ConstantIndex) o).index>=constants.constants.size())){ + o="CONSTNOTFOUND"; + }else{ + o = constants.constants.get(((ConstantIndex) o).index); + } } if (o instanceof RegisterNumber) { if (regNames.containsKey(((RegisterNumber) o).number)) { diff --git a/trunk/src/com/jpexs/asdec/action/swf4/ConstantIndex.java b/trunk/src/com/jpexs/asdec/action/swf4/ConstantIndex.java index 25cf79126..d171b9687 100644 --- a/trunk/src/com/jpexs/asdec/action/swf4/ConstantIndex.java +++ b/trunk/src/com/jpexs/asdec/action/swf4/ConstantIndex.java @@ -28,7 +28,7 @@ public class ConstantIndex { public ConstantIndex(int index) { this.index = index; - this.constantPool = new ArrayList(); + this.constantPool = new ArrayList(); } public ConstantIndex(int index, List constantPool) { diff --git a/trunk/src/com/jpexs/asdec/action/swf5/ActionDefineFunction.java b/trunk/src/com/jpexs/asdec/action/swf5/ActionDefineFunction.java index e3995eeef..9190140f6 100644 --- a/trunk/src/com/jpexs/asdec/action/swf5/ActionDefineFunction.java +++ b/trunk/src/com/jpexs/asdec/action/swf5/ActionDefineFunction.java @@ -23,12 +23,19 @@ import com.jpexs.asdec.action.parser.ASMParser; import com.jpexs.asdec.action.parser.FlasmLexer; import com.jpexs.asdec.action.parser.Label; import com.jpexs.asdec.action.parser.ParseException; +import com.jpexs.asdec.action.swf4.ActionPush; +import com.jpexs.asdec.action.swf7.ActionDefineFunction2; +import com.jpexs.asdec.action.treemodel.ConstantPool; +import com.jpexs.asdec.action.treemodel.FunctionTreeItem; +import com.jpexs.asdec.action.treemodel.TreeItem; import com.jpexs.asdec.helpers.Helper; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Stack; public class ActionDefineFunction extends Action { @@ -36,9 +43,24 @@ public class ActionDefineFunction extends Action { public List paramNames = new ArrayList(); public List code; public int codeSize; + private int version; + public void setConstantPool(List constantPool){ + for(Action a:code){ + if(a instanceof ActionPush){ + ((ActionPush)a).constantPool=constantPool; + } + if(a instanceof ActionDefineFunction2){ + ((ActionDefineFunction2)a).setConstantPool(constantPool); + } + if(a instanceof ActionDefineFunction){ + ((ActionDefineFunction)a).setConstantPool(constantPool); + } + } + } public ActionDefineFunction(int actionLength, SWFInputStream sis, int version) throws IOException { super(0x9B, actionLength); + this.version=version; //byte data[]=sis.readBytes(actionLength); //sis=new SWFInputStream(new ByteArrayInputStream(data),version); functionName = sis.readString(); @@ -127,4 +149,10 @@ public class ActionDefineFunction extends Action { public List getAllIfsOrJumps() { return Action.getActionsAllIfsOrJumps(code); } + + + @Override + public void translate(Stack stack, ConstantPool constants, List output, HashMap regNames) { + stack.push(new FunctionTreeItem(this, functionName, paramNames, Action.actionsToTree(regNames, code,version ), constants)); + } } diff --git a/trunk/src/com/jpexs/asdec/action/swf7/ActionDefineFunction2.java b/trunk/src/com/jpexs/asdec/action/swf7/ActionDefineFunction2.java index 2cf73d29d..c6529c21b 100644 --- a/trunk/src/com/jpexs/asdec/action/swf7/ActionDefineFunction2.java +++ b/trunk/src/com/jpexs/asdec/action/swf7/ActionDefineFunction2.java @@ -23,12 +23,19 @@ import com.jpexs.asdec.action.parser.ASMParser; import com.jpexs.asdec.action.parser.FlasmLexer; import com.jpexs.asdec.action.parser.Label; import com.jpexs.asdec.action.parser.ParseException; +import com.jpexs.asdec.action.swf4.ActionPush; +import com.jpexs.asdec.action.swf5.ActionDefineFunction; +import com.jpexs.asdec.action.treemodel.ConstantPool; +import com.jpexs.asdec.action.treemodel.FunctionTreeItem; +import com.jpexs.asdec.action.treemodel.TreeItem; import com.jpexs.asdec.helpers.Helper; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Stack; public class ActionDefineFunction2 extends Action { @@ -47,9 +54,25 @@ public class ActionDefineFunction2 extends Action { public int registerCount; public int codeSize; public List code; + private int version; + public void setConstantPool(List constantPool){ + for(Action a:code){ + if(a instanceof ActionPush){ + ((ActionPush)a).constantPool=constantPool; + } + if(a instanceof ActionDefineFunction2){ + ((ActionDefineFunction2)a).setConstantPool(constantPool); + } + if(a instanceof ActionDefineFunction){ + ((ActionDefineFunction)a).setConstantPool(constantPool); + } + } + } + public ActionDefineFunction2(int actionLength, SWFInputStream sis, int version) throws IOException { super(0x8E, actionLength); + this.version=version; functionName = sis.readString(); int numParams = sis.readUI16(); registerCount = sis.readUI8(); @@ -185,6 +208,18 @@ public class ActionDefineFunction2 extends Action { + " " + preloadGlobalFlag).trim() + " " + paramStr + " {\r\n" + Action.actionsToString(code, knownAddreses, constantPool, version) + "}"; } + @Override + public String toString() { + return "DefineFunction2"; + } + + @Override + public void translate(Stack stack, ConstantPool constants, List output, HashMap regNames) { + stack.push(new FunctionTreeItem(this, functionName, paramNames, Action.actionsToTree(regNames, code,version ), constants)); + } + + + @Override public List getAllRefs(int version) { return Action.getActionsAllRefs(code, version); diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/DecrementTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/DecrementTreeItem.java index 792e973b5..31f228bd7 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/DecrementTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/DecrementTreeItem.java @@ -31,4 +31,16 @@ public class DecrementTreeItem extends TreeItem { public String toString(ConstantPool constants) { return object.toString(constants) + hilight("-1"); } + + @Override + public boolean isCompileTime(){ + return object.isCompileTime(); + } + + @Override + public double toNumber() { + return object.toNumber()-1; + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/DirectValueTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/DirectValueTreeItem.java index 36853f92e..580fe0985 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/DirectValueTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/DirectValueTreeItem.java @@ -34,6 +34,29 @@ public class DirectValueTreeItem extends TreeItem { this.value = value; } + @Override + public double toNumber() { + if(value instanceof Double){ + return (Double)value; + } + if(value instanceof Float){ + return (Float)value; + } + if(value instanceof Long){ + return (Long)value; + } + return super.toNumber(); + } + + @Override + public boolean toBoolean() { + boolean ret=(value instanceof Boolean)?(Boolean)value:false; + return ret; + } + + + + @Override public String toStringNoQuotes(ConstantPool constants) { if (value instanceof Double) { @@ -75,4 +98,9 @@ public class DirectValueTreeItem extends TreeItem { } return hilight(value.toString()); } + + @Override + public boolean isCompileTime(){ + return (value instanceof Double)||(value instanceof Float)||(value instanceof Boolean)||(value instanceof Long); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/FunctionTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/FunctionTreeItem.java index c57749bcd..c48d0619a 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/FunctionTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/FunctionTreeItem.java @@ -30,7 +30,7 @@ public class FunctionTreeItem extends TreeItem { public FunctionTreeItem(Action instruction, String functionName, List paramNames, List actions, ConstantPool constants) { super(instruction, PRECEDENCE_PRIMARY); this.actions = actions; - this.constants = constants.constants; + this.constants = constants==null?null:constants.constants; this.functionName = functionName; this.paramNames = paramNames; } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/IncrementTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/IncrementTreeItem.java index 3657ed95c..1f5b30026 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/IncrementTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/IncrementTreeItem.java @@ -31,4 +31,16 @@ public class IncrementTreeItem extends TreeItem { public String toString(ConstantPool constants) { return object.toString(constants) + hilight("+1"); } + + @Override + public boolean isCompileTime(){ + return object.isCompileTime(); + } + + @Override + public double toNumber() { + return object.toNumber()+1; + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/TreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/TreeItem.java index 2ffbef7ac..acec9a3c1 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/TreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/TreeItem.java @@ -96,4 +96,17 @@ public abstract class TreeItem { return target.toString(); } } + + public boolean isCompileTime(){ + return false; + } + + + public double toNumber(){ + return 0; + } + + public boolean toBoolean(){ + return Double.compare(toNumber(),0.0)!=0; + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/AddTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/AddTreeItem.java index b44d66bd4..c8d0a27f8 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/AddTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/AddTreeItem.java @@ -24,4 +24,11 @@ public class AddTreeItem extends BinaryOpTreeItem { public AddTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_ADDITIVE, leftSide, rightSide, "+"); } + + @Override + public double toNumber() { + return leftSide.toNumber()+rightSide.toNumber(); + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/AndTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/AndTreeItem.java index be595d440..394bd50e6 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/AndTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/AndTreeItem.java @@ -24,4 +24,11 @@ public class AndTreeItem extends BinaryOpTreeItem { public AndTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_LOGICALAND, leftSide, rightSide, "&&"); } + + @Override + public boolean toBoolean() { + return leftSide.toBoolean()&&rightSide.toBoolean(); + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/AsTypeTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/AsTypeTreeItem.java index c2a75f636..369feb0bb 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/AsTypeTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/AsTypeTreeItem.java @@ -24,4 +24,11 @@ public class AsTypeTreeItem extends BinaryOpTreeItem { public AsTypeTreeItem(Action instruction, TreeItem value, TreeItem type) { super(instruction, PRECEDENCE_RELATIONAL, value, type, " as "); } + + @Override + public boolean isCompileTime() { + return false; + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/BinaryOpTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/BinaryOpTreeItem.java index 92360a439..2ffab4f60 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/BinaryOpTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/BinaryOpTreeItem.java @@ -49,4 +49,8 @@ public abstract class BinaryOpTreeItem extends TreeItem { } return ret; } + @Override + public boolean isCompileTime(){ + return leftSide.isCompileTime()&&rightSide.isCompileTime(); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitAndTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitAndTreeItem.java index 75d887fb0..d95436a44 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitAndTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitAndTreeItem.java @@ -24,4 +24,9 @@ public class BitAndTreeItem extends BinaryOpTreeItem { public BitAndTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_BITWISEAND, leftSide, rightSide, "&"); } + + @Override + public double toNumber() { + return ((int)leftSide.toNumber())&((int)rightSide.toNumber()); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitNotTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitNotTreeItem.java index f53dc8596..3969616c9 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitNotTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitNotTreeItem.java @@ -24,4 +24,11 @@ public class BitNotTreeItem extends UnaryOpTreeItem { public BitNotTreeItem(Action instruction, TreeItem value) { super(instruction, PRECEDENCE_UNARY, value, "~"); } + + @Override + public double toNumber() { + return ~((int)value.toNumber()); + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitOrTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitOrTreeItem.java index 405b39844..002ad6bd6 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitOrTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitOrTreeItem.java @@ -24,4 +24,9 @@ public class BitOrTreeItem extends BinaryOpTreeItem { public BitOrTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_BITWISEOR, leftSide, rightSide, "|"); } + + @Override + public double toNumber() { + return ((int)leftSide.toNumber())|((int)rightSide.toNumber()); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitXorTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitXorTreeItem.java index 27515247a..0e39aef9a 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitXorTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/BitXorTreeItem.java @@ -24,4 +24,9 @@ public class BitXorTreeItem extends BinaryOpTreeItem { public BitXorTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_BITWISEXOR, leftSide, rightSide, "^"); } + + @Override + public double toNumber() { + return ((int)leftSide.toNumber())^((int)rightSide.toNumber()); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/DivideTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/DivideTreeItem.java index 47830f47d..5aa3a0526 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/DivideTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/DivideTreeItem.java @@ -24,4 +24,9 @@ public class DivideTreeItem extends BinaryOpTreeItem { public DivideTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "/"); } + + @Override + public double toNumber() { + return leftSide.toNumber()/rightSide.toNumber(); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/EqTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/EqTreeItem.java index d87db7b63..6eb961fba 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/EqTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/EqTreeItem.java @@ -24,4 +24,11 @@ public class EqTreeItem extends BinaryOpTreeItem { public EqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "=="); } + + @Override + public boolean toBoolean() { + return (leftSide.toBoolean()==rightSide.toBoolean())&&(leftSide.toNumber()==rightSide.toNumber()); + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/GeTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/GeTreeItem.java index 671fb255c..59ab77f09 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/GeTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/GeTreeItem.java @@ -24,4 +24,11 @@ public class GeTreeItem extends BinaryOpTreeItem { public GeTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">="); } + + @Override + public boolean toBoolean() { + return leftSide.toNumber()>=rightSide.toNumber(); + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/GtTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/GtTreeItem.java index 7f7cb67b8..9840b108d 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/GtTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/GtTreeItem.java @@ -24,4 +24,9 @@ public class GtTreeItem extends BinaryOpTreeItem { public GtTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">"); } + + @Override + public boolean toBoolean() { + return leftSide.toNumber()>rightSide.toNumber(); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/InTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/InTreeItem.java index 55fc4c50c..320cb8c84 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/InTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/InTreeItem.java @@ -24,4 +24,11 @@ public class InTreeItem extends BinaryOpTreeItem { public InTreeItem(Action instruction, TreeItem name, TreeItem object) { super(instruction, PRECEDENCE_RELATIONAL, name, object, " in "); } + + @Override + public boolean isCompileTime() { + return false; + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/InstanceOfTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/InstanceOfTreeItem.java index 908a09957..bdc0a1076 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/InstanceOfTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/InstanceOfTreeItem.java @@ -24,4 +24,11 @@ public class InstanceOfTreeItem extends BinaryOpTreeItem { public InstanceOfTreeItem(Action instruction, TreeItem value, TreeItem type) { super(instruction, PRECEDENCE_RELATIONAL, value, type, " instanceof "); } + + @Override + public boolean isCompileTime() { + return false; + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/IsTypeTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/IsTypeTreeItem.java index d13df8306..8035b8842 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/IsTypeTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/IsTypeTreeItem.java @@ -24,4 +24,11 @@ public class IsTypeTreeItem extends BinaryOpTreeItem { public IsTypeTreeItem(Action instruction, TreeItem value, TreeItem type) { super(instruction, PRECEDENCE_RELATIONAL, value, type, " is "); } + + @Override + public boolean isCompileTime() { + return false; + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/LShiftTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/LShiftTreeItem.java index 801bad186..9c262ab6b 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/LShiftTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/LShiftTreeItem.java @@ -24,4 +24,9 @@ public class LShiftTreeItem extends BinaryOpTreeItem { public LShiftTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, "<<"); } + + @Override + public double toNumber() { + return ((int)leftSide.toNumber())<<((int)rightSide.toNumber()); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/LeTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/LeTreeItem.java index a217d8329..02b9d6c25 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/LeTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/LeTreeItem.java @@ -24,4 +24,9 @@ public class LeTreeItem extends BinaryOpTreeItem { public LeTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<="); } + + @Override + public boolean toBoolean() { + return leftSide.toNumber()<=rightSide.toNumber(); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/LtTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/LtTreeItem.java index 372ee71a2..4c6809a5b 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/LtTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/LtTreeItem.java @@ -24,4 +24,9 @@ public class LtTreeItem extends BinaryOpTreeItem { public LtTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<"); } + + @Override + public boolean toBoolean() { + return leftSide.toNumber()>"); } + + @Override + public double toNumber() { + return ((int)leftSide.toNumber())>>((int)rightSide.toNumber()); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/StrictEqTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/StrictEqTreeItem.java index 417831300..b5287a488 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/StrictEqTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/StrictEqTreeItem.java @@ -24,4 +24,9 @@ public class StrictEqTreeItem extends BinaryOpTreeItem { public StrictEqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "==="); } + + @Override + public boolean toBoolean() { + return (leftSide.toBoolean()==rightSide.toBoolean())&&(leftSide.toNumber()==rightSide.toNumber()); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/StrictNeqTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/StrictNeqTreeItem.java index 913e8abbf..adef9619b 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/StrictNeqTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/StrictNeqTreeItem.java @@ -24,4 +24,9 @@ public class StrictNeqTreeItem extends BinaryOpTreeItem { public StrictNeqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "!=="); } + + @Override + public boolean toBoolean() { + return (leftSide.toBoolean()!=rightSide.toBoolean())&&(leftSide.toNumber()!=rightSide.toNumber()); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringAddTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringAddTreeItem.java index daa0a363c..89762a1c2 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringAddTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringAddTreeItem.java @@ -24,4 +24,9 @@ public class StringAddTreeItem extends BinaryOpTreeItem { public StringAddTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_ADDITIVE, leftSide, rightSide, "+"); } + + @Override + public boolean isCompileTime() { + return false; + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringEqTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringEqTreeItem.java index be3c926ef..141ea8e1d 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringEqTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringEqTreeItem.java @@ -24,4 +24,11 @@ public class StringEqTreeItem extends BinaryOpTreeItem { public StringEqTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_EQUALITY, leftSide, rightSide, "=="); } + + @Override + public boolean isCompileTime() { + return false; + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringLengthTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringLengthTreeItem.java index 741daed36..8665a5361 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringLengthTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringLengthTreeItem.java @@ -37,4 +37,9 @@ public class StringLengthTreeItem extends TreeItem { } return s + hilight(".length"); } + + @Override + public boolean isCompileTime() { + return false; + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringLtTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringLtTreeItem.java index e47428b9a..d15ca53df 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringLtTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/StringLtTreeItem.java @@ -24,4 +24,9 @@ public class StringLtTreeItem extends BinaryOpTreeItem { public StringLtTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<"); } + + @Override + public boolean isCompileTime() { + return false; + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/SubtractTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/SubtractTreeItem.java index 4238b125c..ee621ff49 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/SubtractTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/SubtractTreeItem.java @@ -24,4 +24,11 @@ public class SubtractTreeItem extends BinaryOpTreeItem { public SubtractTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_ADDITIVE, leftSide, rightSide, "-"); } + + @Override + public double toNumber() { + return leftSide.toNumber()-rightSide.toNumber(); + } + + } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/URShiftTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/URShiftTreeItem.java index 3022bf959..0abcf56b2 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/URShiftTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/URShiftTreeItem.java @@ -24,4 +24,9 @@ public class URShiftTreeItem extends BinaryOpTreeItem { public URShiftTreeItem(Action instruction, TreeItem leftSide, TreeItem rightSide) { super(instruction, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>>"); } + + @Override + public double toNumber() { + return ((int)leftSide.toNumber())>>>((int)rightSide.toNumber()); + } } diff --git a/trunk/src/com/jpexs/asdec/action/treemodel/operations/UnaryOpTreeItem.java b/trunk/src/com/jpexs/asdec/action/treemodel/operations/UnaryOpTreeItem.java index 24080c47a..7bf0f0da6 100644 --- a/trunk/src/com/jpexs/asdec/action/treemodel/operations/UnaryOpTreeItem.java +++ b/trunk/src/com/jpexs/asdec/action/treemodel/operations/UnaryOpTreeItem.java @@ -39,4 +39,9 @@ public abstract class UnaryOpTreeItem extends TreeItem { } return hilight(operator) + s; } + + @Override + public boolean isCompileTime(){ + return value.isCompileTime(); + } }