mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-31 19:54:37 +00:00
Improved deobfuscation
This commit is contained in:
@@ -61,6 +61,7 @@ import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Scanner;
|
||||
import java.util.Stack;
|
||||
@@ -90,6 +91,10 @@ public class SWFInputStream extends InputStream {
|
||||
private ByteArrayOutputStream buffer;
|
||||
private static boolean DEOBFUSCATION_ALL_CODE_IN_PREVIOUS_TAG = (Boolean) Configuration.getConfig("deobfuscateUsePrevTagOnly", true);
|
||||
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public int getBufferLength() {
|
||||
return buffer.size();
|
||||
}
|
||||
@@ -636,33 +641,6 @@ public class SWFInputStream extends InputStream {
|
||||
if (ins.isBranch() || ins.isJump()) {
|
||||
|
||||
if (deobfuscate && (ins instanceof ActionIf) && !stack.isEmpty() && (stack.peek().isCompileTime() && (!stack.peek().hasSideEffect()))) {
|
||||
ActionIf aif = (ActionIf) ins;
|
||||
if (aif.ignoreUsed && (!aif.jumpUsed)) {
|
||||
ins.setIgnored(true, 0);
|
||||
}
|
||||
if ((!aif.ignoreUsed) && aif.jumpUsed) {
|
||||
ActionJump jmpIns = new ActionJump(aif.getJumpOffset());
|
||||
((ActionJump) jmpIns).setAddress(aif.getAddress(), version);
|
||||
code.set(ip, (ActionJump) jmpIns);
|
||||
}
|
||||
|
||||
if ((aif.ignoreUsed && (!aif.jumpUsed)) || ((!aif.ignoreUsed) && aif.jumpUsed)) {
|
||||
List<GraphSourceItemPos> needed = stack.peek().getNeededSources();
|
||||
for (GraphSourceItemPos ig : needed) {
|
||||
/*if (ig.item instanceof ActionPush) {
|
||||
if (!((ActionPush) ig.item).ignoredParts.contains(ig.pos)) {
|
||||
((ActionPush) ig.item).ignoredParts.add(ig.pos);
|
||||
|
||||
if (((ActionPush) ig.item).ignoredParts.size() == ((ActionPush) ig.item).values.size()) {
|
||||
((Action) ig.item).setIgnored(true, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
}*/
|
||||
((Action) ig.item).setIgnored(true, ig.pos);
|
||||
}
|
||||
}
|
||||
boolean condition = EcmaScript.toBoolean(stack.peek().getResult());
|
||||
if (debugMode) {
|
||||
if (condition) {
|
||||
@@ -683,7 +661,7 @@ public class SWFInputStream extends InputStream {
|
||||
@SuppressWarnings("unchecked")
|
||||
Stack<GraphTargetItem> brStack = (Stack<GraphTargetItem>) stack.clone();
|
||||
if (b >= 0) {
|
||||
getConstantPool(listeners, cpool, localData, brStack, output, code, b, constantPools, visited, version, endIp, path);
|
||||
getConstantPool(listeners, cpool, prepareLocalBranch(localData), brStack, output, code, b, constantPools, visited, version, endIp, path);
|
||||
} else {
|
||||
if (debugMode) {
|
||||
System.out.println("Negative branch:" + b);
|
||||
@@ -714,6 +692,20 @@ public class SWFInputStream extends InputStream {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static List<Object> prepareLocalBranch(List<Object> localData) {
|
||||
@SuppressWarnings("unchecked")
|
||||
HashMap<Integer, String> regNames = (HashMap<Integer, String>) localData.get(0);
|
||||
@SuppressWarnings("unchecked")
|
||||
HashMap<String, GraphTargetItem> variables = (HashMap<String, GraphTargetItem>) localData.get(1);
|
||||
@SuppressWarnings("unchecked")
|
||||
HashMap<String, GraphTargetItem> functions = (HashMap<String, GraphTargetItem>) localData.get(2);
|
||||
List<Object> ret = new ArrayList<>();
|
||||
ret.add(new HashMap<Integer, String>(regNames));
|
||||
ret.add(new HashMap<String, GraphTargetItem>(variables));
|
||||
ret.add(new HashMap<String, GraphTargetItem>(functions));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads list of actions from the stream. Reading ends with
|
||||
* ActionEndFlag(=0) or end of the stream.
|
||||
@@ -747,7 +739,7 @@ public class SWFInputStream extends InputStream {
|
||||
method = 2;
|
||||
goesPrev = readActionListAtPos(true, localData, stack, cpool, sis, rri, ip, retdups, ip);
|
||||
}*/
|
||||
goesPrev = readActionListAtPos(listeners, new ArrayList<GraphTargetItem>(), new HashMap<Long, List<GraphSourceItemContainer>>(), address, containerSWFOffset, false, true, localData, stack, cpool, sis, rri, ip, retdups, ip, endip, path);
|
||||
goesPrev = readActionListAtPos(listeners, new ArrayList<GraphTargetItem>(), new HashMap<Long, List<GraphSourceItemContainer>>(), address, containerSWFOffset, localData, stack, cpool, sis, rri, ip, retdups, ip, endip, path, new HashMap<Integer, Integer>());
|
||||
|
||||
if (goesPrev) {
|
||||
} else {
|
||||
@@ -777,15 +769,6 @@ public class SWFInputStream extends InputStream {
|
||||
}
|
||||
|
||||
List<ConstantPool> pools;
|
||||
StringBuilder br = new StringBuilder();
|
||||
for (int i = 0; i < ret.size(); i++) {
|
||||
br.append(i);
|
||||
br.append(", loc");
|
||||
br.append(Helper.formatAddress(((Action) ret.get(i)).getAddress()));
|
||||
br.append(": ");
|
||||
br.append(((Action) ret.get(i)).getASMSource(new ArrayList<GraphSourceItem>(), new ArrayList<Long>(), cpool.constants, version, false));
|
||||
br.append("\r\n");
|
||||
}
|
||||
ret = Action.removeNops(0, ret, version, 0, path);
|
||||
pools = getConstantPool(listeners, new ActionGraphSource(ret, version, new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>()), 0, version, path);
|
||||
|
||||
@@ -815,7 +798,7 @@ public class SWFInputStream extends InputStream {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static boolean readActionListAtPos(List<DisassemblyListener> listeners, List<GraphTargetItem> output, HashMap<Long, List<GraphSourceItemContainer>> containers, long address, long containerSWFOffset, boolean notCompileTime, boolean enableVariables, List<Object> localData, Stack<GraphTargetItem> stack, ConstantPool cpool, SWFInputStream sis, ReReadableInputStream rri, int ip, List<Action> ret, int startIp, int endip, String path) throws IOException {
|
||||
private static boolean readActionListAtPos(List<DisassemblyListener> listeners, List<GraphTargetItem> output, HashMap<Long, List<GraphSourceItemContainer>> containers, long address, long containerSWFOffset, List<Object> localData, Stack<GraphTargetItem> stack, ConstantPool cpool, SWFInputStream sis, ReReadableInputStream rri, int ip, List<Action> ret, int startIp, int endip, String path, Map<Integer, Integer> visited) throws IOException {
|
||||
boolean debugMode = false;
|
||||
boolean decideBranch = false;
|
||||
|
||||
@@ -826,7 +809,14 @@ public class SWFInputStream extends InputStream {
|
||||
long filePos = rri.getPos();
|
||||
Scanner sc = new Scanner(System.in, "utf-8");
|
||||
int prevIp = ip;
|
||||
loopip:
|
||||
while (((endip == -1) || (endip > ip)) && (a = sis.readAction(rri)) != null) {
|
||||
if (!visited.containsKey(ip)) {
|
||||
visited.put(ip, 0);
|
||||
}
|
||||
int curVisited = visited.get(ip);
|
||||
curVisited++;
|
||||
visited.put(ip, curVisited);
|
||||
for (int i = 0; i < listeners.size(); i++) {
|
||||
listeners.get(i).progress("Reading", rri.getCount(), rri.length());
|
||||
}
|
||||
@@ -908,9 +898,6 @@ public class SWFInputStream extends InputStream {
|
||||
|
||||
ensureCapacity(ret, ip);
|
||||
int newip = -1;
|
||||
if (!enableVariables && (!(ret.get(ip) instanceof ActionNop))) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (a instanceof ActionConstantPool) {
|
||||
if (cpool == null) {
|
||||
@@ -943,22 +930,13 @@ public class SWFInputStream extends InputStream {
|
||||
} else if (next.equals("c")) {
|
||||
goaif = true;
|
||||
}
|
||||
} else if (deobfuscate && top.isCompileTime() && (!top.hasSideEffect()) && ((!top.isVariableComputed()) || (top.isVariableComputed() && enableVariables && (!notCompileTime)))) {
|
||||
//if(top.isCompileTime()) {
|
||||
//if(false){
|
||||
if (enableVariables) {
|
||||
((ActionIf) a).compileTime = true;
|
||||
}
|
||||
} else if (deobfuscate && top.isCompileTime() && (!top.hasSideEffect())) {
|
||||
((ActionIf) a).compileTime = true;
|
||||
if (debugMode) {
|
||||
System.err.print("is compiletime -> ");
|
||||
}
|
||||
if (EcmaScript.toBoolean(top.getResult())) {
|
||||
newip = rri.getPos() + aif.getJumpOffset();
|
||||
//rri.setPos(newip);
|
||||
if (((!enableVariables) || (!top.isVariableComputed())) && (!aif.ignoreUsed)) {
|
||||
a = new ActionJump(aif.getJumpOffset());
|
||||
a.setAddress(aif.getAddress(), SWF.DEFAULT_VERSION);
|
||||
}
|
||||
aif.jumpUsed = true;
|
||||
if (aif.ignoreUsed) {
|
||||
aif.compileTime = false;
|
||||
@@ -974,32 +952,7 @@ public class SWFInputStream extends InputStream {
|
||||
if (debugMode) {
|
||||
System.err.println("ignore");
|
||||
}
|
||||
if (((!enableVariables) || (!top.isVariableComputed())) && (!aif.jumpUsed)) {
|
||||
//a = new ActionNop();
|
||||
aif.setIgnored(true, 0);
|
||||
//a.setAddress(aif.getAddress(), SWF.DEFAULT_VERSION);
|
||||
}
|
||||
}
|
||||
if (((!enableVariables) || (!top.isVariableComputed())) && (!(aif.jumpUsed && aif.ignoreUsed))) {
|
||||
List<GraphSourceItemPos> needed = top.getNeededSources();
|
||||
for (GraphSourceItemPos ig : needed) {
|
||||
if (ig.item == null) {
|
||||
continue;
|
||||
}
|
||||
if (ig.item instanceof ActionPush) {
|
||||
if (!((ActionPush) ig.item).ignoredParts.contains(ig.pos)) {
|
||||
((ActionPush) ig.item).ignoredParts.add(ig.pos);
|
||||
|
||||
if (((ActionPush) ig.item).ignoredParts.size() == ((ActionPush) ig.item).values.size()) {
|
||||
((Action) ig.item).setIgnored(true, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
((Action) ig.item).setIgnored(true, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (debugMode) {
|
||||
System.err.println("goaif");
|
||||
@@ -1025,9 +978,9 @@ public class SWFInputStream extends InputStream {
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException ex) {
|
||||
if (!enableVariables) {
|
||||
throw ex;
|
||||
}
|
||||
/*if (!enableVariables) {
|
||||
throw ex;
|
||||
}*/
|
||||
log.log(Level.SEVERE, "Disassembly exception", ex);
|
||||
break;
|
||||
}
|
||||
@@ -1064,9 +1017,14 @@ public class SWFInputStream extends InputStream {
|
||||
output2s.add(new ArrayList<GraphTargetItem>());
|
||||
continue;
|
||||
}
|
||||
List<Object> localData2 = Helper.toList(new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>());
|
||||
List<Object> localData2;
|
||||
List<GraphTargetItem> output2 = new ArrayList<>();
|
||||
readActionListAtPos(listeners, output2, containers, address, containerSWFOffset, notCompileTime, enableVariables, localData2, new Stack<GraphTargetItem>(), cpool, sis, rri, (int) endAddr, ret, startIp, (int) (endAddr + size), path + (cntName == null ? "" : "/" + cntName));
|
||||
if ((cnt instanceof ActionDefineFunction) || (cnt instanceof ActionDefineFunction2)) {
|
||||
localData2 = Helper.toList(new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>());
|
||||
} else {
|
||||
localData2 = localData;
|
||||
}
|
||||
readActionListAtPos(listeners, output2, containers, address, containerSWFOffset, localData2, new Stack<GraphTargetItem>(), cpool, sis, rri, (int) endAddr, ret, startIp, (int) (endAddr + size), path + (cntName == null ? "" : "/" + cntName), visited);
|
||||
output2s.add(output2);
|
||||
endAddr += size;
|
||||
}
|
||||
@@ -1098,14 +1056,33 @@ public class SWFInputStream extends InputStream {
|
||||
}
|
||||
aif.ignoreUsed = true;
|
||||
aif.jumpUsed = true;
|
||||
|
||||
if (curVisited > 1) {
|
||||
List<Integer> branches = new ArrayList<>();
|
||||
branches.add(rri.getPos() + aif.getJumpOffset());
|
||||
branches.add(rri.getPos());
|
||||
for (int br : branches) {
|
||||
int visc = 0;
|
||||
if (visited.containsKey(br)) {
|
||||
visc = visited.get(br);
|
||||
}
|
||||
if (visc == 0) {//<curVisited){
|
||||
ip = br;
|
||||
prevIp = ip;
|
||||
rri.setPos(br);
|
||||
continue loopip;
|
||||
}
|
||||
}
|
||||
break loopip;
|
||||
}
|
||||
|
||||
int oldPos = rri.getPos();
|
||||
@SuppressWarnings("unchecked")
|
||||
Stack<GraphTargetItem> substack = (Stack<GraphTargetItem>) stack.clone();
|
||||
if (readActionListAtPos(listeners, output, containers, address, containerSWFOffset, true, enableVariables, localData, substack, cpool, sis, rri, rri.getPos() + aif.getJumpOffset(), ret, startIp, endip, path)) {
|
||||
if (readActionListAtPos(listeners, output, containers, address, containerSWFOffset, prepareLocalBranch(localData), substack, cpool, sis, rri, rri.getPos() + aif.getJumpOffset(), ret, startIp, endip, path, visited)) {
|
||||
retv = true;
|
||||
}
|
||||
rri.setPos(oldPos);
|
||||
notCompileTime = true;
|
||||
}
|
||||
prevIp = ip;
|
||||
if (a.isExit()) {
|
||||
|
||||
@@ -1483,6 +1483,30 @@ public class AVM2Code implements Serializable {
|
||||
code.add(pos, instruction);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static List<Object> prepareBranchLocalData(List<Object> localData) {
|
||||
List<Object> ret = new ArrayList<>();
|
||||
ret.add(localData.get(0)); //isStatic
|
||||
ret.add(localData.get(1)); //classIndex
|
||||
ret.add(new HashMap<Integer, GraphTargetItem>((HashMap<Integer, GraphTargetItem>) localData.get(2)));
|
||||
ret.add((Stack<GraphTargetItem>) ((Stack<GraphTargetItem>) localData.get(3)).clone());
|
||||
ret.add(localData.get(4)); //constants
|
||||
ret.add(localData.get(5)); //method_info
|
||||
ret.add(localData.get(6)); //body
|
||||
ret.add(localData.get(7)); //abc
|
||||
ret.add(localData.get(8)); //localgetNames
|
||||
ret.add(localData.get(9));
|
||||
ret.add(localData.get(10));
|
||||
ret.add(localData.get(11));
|
||||
ret.add(localData.get(12));
|
||||
ret.add(localData.get(13));
|
||||
ret.add(localData.get(14));
|
||||
ret.add(localData.get(15));
|
||||
ret.add(localData.get(16));
|
||||
ret.add(localData.get(17));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int removeTraps(ConstantPool constants, MethodBody body, ABC abc, int scriptIndex, int classIndex, boolean isStatic, String path) {
|
||||
removeDeadCode(constants, body);
|
||||
List<Object> localData = new ArrayList<>();
|
||||
@@ -2212,6 +2236,14 @@ public class AVM2Code implements Serializable {
|
||||
|
||||
}
|
||||
|
||||
int curVisited;
|
||||
if (!visited.containsKey(ip)) {
|
||||
curVisited = 1;
|
||||
} else {
|
||||
curVisited = visited.get(ip) + 1;
|
||||
}
|
||||
visited.put(ip, curVisited);
|
||||
|
||||
List<Integer> r = refs.get(ip);
|
||||
/*if (r != null) {
|
||||
if (r.size() > 1) {
|
||||
@@ -2245,6 +2277,16 @@ public class AVM2Code implements Serializable {
|
||||
}
|
||||
if (debugMode) {
|
||||
System.out.println((useVisited ? "useV " : "") + (secondPass ? "secondPass " : "") + "Visit " + ip + ": " + ins + " stack:" + Highlighting.stripHilights(stack.toString()));
|
||||
HashMap<Integer, GraphTargetItem> registers = (HashMap<Integer, GraphTargetItem>) localData.get(2);
|
||||
System.out.print("Registers:");
|
||||
for (int reg : registers.keySet()) {
|
||||
try {
|
||||
System.out.print(" r" + reg + ": " + registers.get(reg).getResult());
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.print(" r" + reg + ": " + "null");
|
||||
}
|
||||
}
|
||||
System.out.println("");
|
||||
}
|
||||
if (secondPass) {
|
||||
/*if ((ins instanceof AVM2Instruction) && (((AVM2Instruction) ins).definition instanceof PopIns)) {
|
||||
@@ -2349,12 +2391,26 @@ public class AVM2Code implements Serializable {
|
||||
}
|
||||
dec.jumpUsed = true;
|
||||
dec.skipUsed = true;
|
||||
|
||||
if (curVisited > 1) {
|
||||
for (int b : branches) {
|
||||
int visc = 0;
|
||||
if (visited.containsKey(b)) {
|
||||
visc = visited.get(b);
|
||||
}
|
||||
if (visc == 0) {//<curVisited){
|
||||
ip = b;
|
||||
continue iploop;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int b : branches) {
|
||||
Stack<GraphTargetItem> brStack = (Stack<GraphTargetItem>) stack.clone();
|
||||
if (b >= 0) {
|
||||
ret += removeTraps(refs, secondPass, useVisited || (!ins.isJump()), localData, brStack, output, code, b, visited, visitedStates, decisions, path);
|
||||
if (b >= 0) { //useVisited || (!ins.isJump())
|
||||
ret += removeTraps(refs, secondPass, false, prepareBranchLocalData(localData), brStack, output, code, b, visited, visitedStates, decisions, path);
|
||||
} else {
|
||||
if (debugMode) {
|
||||
System.out.println("Negative branch:" + b);
|
||||
@@ -2375,8 +2431,30 @@ public class AVM2Code implements Serializable {
|
||||
public static int removeTraps(ConstantPool constants, MethodBody body, List<Object> localData, AVM2GraphSource code, int addr, String path, HashMap<Integer, List<Integer>> refs) {
|
||||
HashMap<GraphSourceItem, 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);
|
||||
localData.set(2, new HashMap<Integer, GraphTargetItem>());
|
||||
int cnt = removeTraps(refs, true, false, localData, new Stack<GraphTargetItem>(), new ArrayList<GraphTargetItem>(), code, code.adr2pos(addr), new HashMap<Integer, Integer>(), new HashMap<Integer, HashMap<Integer, GraphTargetItem>>(), decisions, path);
|
||||
int cnt = 0;
|
||||
for (GraphSourceItem src : decisions.keySet()) {
|
||||
Decision dec = decisions.get(src);
|
||||
if (dec != null) {
|
||||
if ((src instanceof AVM2Instruction) && (((AVM2Instruction) src).definition instanceof LookupSwitchIns)) {
|
||||
if (dec.casesUsed.size() == 1) {
|
||||
for (int c : dec.casesUsed) {
|
||||
src.setFixBranch(c);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dec.jumpUsed && !dec.skipUsed) {
|
||||
src.setFixBranch(0);
|
||||
cnt++;
|
||||
}
|
||||
if (!dec.jumpUsed && dec.skipUsed) {
|
||||
src.setFixBranch(1);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//int cnt = removeTraps(refs, true, false, localData, new Stack<GraphTargetItem>(), new ArrayList<GraphTargetItem>(), code, code.adr2pos(addr), new HashMap<Integer, Integer>(), new HashMap<Integer, HashMap<Integer, GraphTargetItem>>(), decisions, path);
|
||||
code.getCode().removeIgnored(constants, body);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@@ -57,14 +57,18 @@ public class DecLocalIIns extends InstructionDefinition {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> stack, java.util.Stack<GraphTargetItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<GraphTargetItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
|
||||
int regIndex = ins.operands[0];
|
||||
output.add(new DecLocalAVM2Item(ins, regIndex));
|
||||
if (localRegs.containsKey(regIndex)) {
|
||||
localRegs.put(regIndex, new NotCompileTimeAVM2Item(ins, new SubtractAVM2Item(ins, localRegs.get(regIndex), new IntegerValueAVM2Item(ins, Long.valueOf(1)))));
|
||||
public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> stack, java.util.Stack<GraphTargetItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<GraphTargetItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> regAssignCount, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
|
||||
int regId = ins.operands[0];
|
||||
output.add(new DecLocalAVM2Item(ins, regId));
|
||||
if (localRegs.containsKey(regId)) {
|
||||
localRegs.put(regId, new SubtractAVM2Item(ins, localRegs.get(regId), new IntegerValueAVM2Item(ins, Long.valueOf(1))));
|
||||
} else {
|
||||
//localRegs.put(regIndex, new SubtractAVM2Item(ins, new IntegerValueAVM2Item(ins, new Long(0)), new IntegerValueAVM2Item(ins, new Long(1))));
|
||||
}
|
||||
if (!regAssignCount.containsKey(regId)) {
|
||||
regAssignCount.put(regId, 0);
|
||||
}
|
||||
regAssignCount.put(regId, regAssignCount.get(regId) + 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,13 +57,17 @@ public class DecLocalIns extends InstructionDefinition {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> stack, java.util.Stack<GraphTargetItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<GraphTargetItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
|
||||
int regIndex = ins.operands[0];
|
||||
output.add(new DecLocalAVM2Item(ins, regIndex));
|
||||
if (localRegs.containsKey(regIndex)) {
|
||||
localRegs.put(regIndex, new NotCompileTimeAVM2Item(ins, new SubtractAVM2Item(ins, localRegs.get(regIndex), new IntegerValueAVM2Item(ins, Long.valueOf(1)))));
|
||||
public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> stack, java.util.Stack<GraphTargetItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<GraphTargetItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> regAssignCount, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
|
||||
int regId = ins.operands[0];
|
||||
output.add(new DecLocalAVM2Item(ins, regId));
|
||||
if (localRegs.containsKey(regId)) {
|
||||
localRegs.put(regId, new SubtractAVM2Item(ins, localRegs.get(regId), new IntegerValueAVM2Item(ins, Long.valueOf(1))));
|
||||
} else {
|
||||
//localRegs.put(regIndex, new SubtractAVM2Item(ins, new IntegerValueAVM2Item(ins, new Long(0)), new IntegerValueAVM2Item(ins, new Long(1))));
|
||||
}
|
||||
if (!regAssignCount.containsKey(regId)) {
|
||||
regAssignCount.put(regId, 0);
|
||||
}
|
||||
regAssignCount.put(regId, regAssignCount.get(regId) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,17 +37,24 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> stack, java.util.Stack<GraphTargetItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<GraphTargetItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
|
||||
public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> stack, java.util.Stack<GraphTargetItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<GraphTargetItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> regAssignCount, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
|
||||
int regId = getRegisterId(ins);
|
||||
GraphTargetItem computedValue = localRegs.get(regId);
|
||||
if (!isRegisterCompileTime(regId, ip, refs, code)) {
|
||||
int assignCount = 0;
|
||||
if (regAssignCount.containsKey(regId)) {
|
||||
assignCount = regAssignCount.get(regId);
|
||||
}
|
||||
if (assignCount > 5) { //Do not allow change register more than 5 - for deobfuscation
|
||||
computedValue = new NotCompileTimeAVM2Item(ins, computedValue);
|
||||
}
|
||||
if (computedValue == null) {
|
||||
if (!localRegNames.containsKey(regId)) {
|
||||
computedValue = new UndefinedAVM2Item(null); //In some obfuscated code there seems to be reading of undefined registers
|
||||
}
|
||||
}
|
||||
/*if (!isRegisterCompileTime(regId, ip, refs, code)) {
|
||||
computedValue = new NotCompileTimeAVM2Item(ins, computedValue);
|
||||
}
|
||||
if (computedValue == null) {
|
||||
if (!localRegNames.containsKey(regId)) {
|
||||
computedValue = new UndefinedAVM2Item(null); //In some obfuscated code there seems to be reading of undefined registers
|
||||
}
|
||||
}*/
|
||||
stack.push(new LocalRegAVM2Item(ins, regId, computedValue));
|
||||
}
|
||||
|
||||
|
||||
@@ -37,13 +37,17 @@ public class IncLocalIIns extends InstructionDefinition {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> stack, java.util.Stack<GraphTargetItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<GraphTargetItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
|
||||
int regIndex = ins.operands[0];
|
||||
output.add(new IncLocalAVM2Item(ins, regIndex));
|
||||
if (localRegs.containsKey(regIndex)) {
|
||||
localRegs.put(regIndex, new NotCompileTimeAVM2Item(ins, new AddAVM2Item(ins, localRegs.get(regIndex), new IntegerValueAVM2Item(ins, Long.valueOf(1)))));
|
||||
public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> stack, java.util.Stack<GraphTargetItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<GraphTargetItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> regAssignCount, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
|
||||
int regId = ins.operands[0];
|
||||
output.add(new IncLocalAVM2Item(ins, regId));
|
||||
if (localRegs.containsKey(regId)) {
|
||||
localRegs.put(regId, new AddAVM2Item(ins, localRegs.get(regId), new IntegerValueAVM2Item(ins, Long.valueOf(1))));
|
||||
} else {
|
||||
//localRegs.put(regIndex, new AddAVM2Item(ins, null, new IntegerValueAVM2Item(ins, new Long(1))));
|
||||
}
|
||||
if (!regAssignCount.containsKey(regId)) {
|
||||
regAssignCount.put(regId, 0);
|
||||
}
|
||||
regAssignCount.put(regId, regAssignCount.get(regId) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,13 +37,17 @@ public class IncLocalIns extends InstructionDefinition {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> stack, java.util.Stack<GraphTargetItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<GraphTargetItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
|
||||
int regIndex = ins.operands[0];
|
||||
output.add(new IncLocalAVM2Item(ins, regIndex));
|
||||
if (localRegs.containsKey(regIndex)) {
|
||||
localRegs.put(regIndex, new NotCompileTimeAVM2Item(ins, new AddAVM2Item(ins, localRegs.get(regIndex), new IntegerValueAVM2Item(ins, Long.valueOf(1)))));
|
||||
public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> stack, java.util.Stack<GraphTargetItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<GraphTargetItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> regAssignCount, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
|
||||
int regId = ins.operands[0];
|
||||
output.add(new IncLocalAVM2Item(ins, regId));
|
||||
if (localRegs.containsKey(regId)) {
|
||||
localRegs.put(regId, new AddAVM2Item(ins, localRegs.get(regId), new IntegerValueAVM2Item(ins, Long.valueOf(1))));
|
||||
} else {
|
||||
//localRegs.put(regIndex, new AddAVM2Item(ins, null, new IntegerValueAVM2Item(ins, new Long(1))));
|
||||
}
|
||||
if (!regAssignCount.containsKey(regId)) {
|
||||
regAssignCount.put(regId, 0);
|
||||
}
|
||||
regAssignCount.put(regId, regAssignCount.get(regId) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,15 +47,20 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> stack, java.util.Stack<GraphTargetItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<GraphTargetItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
|
||||
public void translate(boolean isStatic, int scriptIndex, int classIndex, java.util.HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> stack, java.util.Stack<GraphTargetItem> scopeStack, ConstantPool constants, AVM2Instruction ins, MethodInfo[] method_info, List<GraphTargetItem> output, com.jpexs.decompiler.flash.abc.types.MethodBody body, com.jpexs.decompiler.flash.abc.ABC abc, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, String path, HashMap<Integer, Integer> regAssignCount, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) {
|
||||
int regId = getRegisterId(ins);
|
||||
GraphTargetItem value = (GraphTargetItem) stack.pop();
|
||||
if (localRegs.containsKey(regId)) {
|
||||
localRegs.put(regId, new NotCompileTimeAVM2Item(ins, value));
|
||||
} else {
|
||||
localRegs.put(regId, value);
|
||||
/*if (localRegs.containsKey(regId)) {
|
||||
localRegs.put(regId, new NotCompileTimeAVM2Item(ins, value));
|
||||
} else {
|
||||
localRegs.put(regId, value);
|
||||
}*/
|
||||
localRegs.put(regId, value);
|
||||
if (!regAssignCount.containsKey(regId)) {
|
||||
regAssignCount.put(regId, 0);
|
||||
}
|
||||
localRegsAssignmentIps.put(regId, ip);
|
||||
regAssignCount.put(regId, regAssignCount.get(regId) + 1);
|
||||
//localRegsAssignmentIps.put(regId, ip);
|
||||
if (value instanceof NewActivationAVM2Item) {
|
||||
return;
|
||||
}
|
||||
@@ -63,7 +68,7 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
|
||||
return;
|
||||
}
|
||||
if (value.getNotCoerced() instanceof IncrementAVM2Item) {
|
||||
GraphTargetItem inside = ((IncrementAVM2Item) value.getNotCoerced()).object.getNotCoerced().getThroughDuplicate();
|
||||
GraphTargetItem inside = ((IncrementAVM2Item) value.getNotCoerced()).value.getNotCoerced().getThroughDuplicate();
|
||||
if (inside instanceof LocalRegAVM2Item) {
|
||||
if (((LocalRegAVM2Item) inside).regIndex == regId) {
|
||||
if (stack.size() > 0) {
|
||||
@@ -71,7 +76,7 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
|
||||
if (top == inside) {
|
||||
stack.pop();
|
||||
stack.push(new PostIncrementAVM2Item(ins, inside));
|
||||
} else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).object == inside)) {
|
||||
} else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) {
|
||||
stack.pop();
|
||||
stack.push(new PreIncrementAVM2Item(ins, inside));
|
||||
} else {
|
||||
@@ -86,7 +91,7 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
|
||||
}
|
||||
|
||||
if (value.getNotCoerced() instanceof DecrementAVM2Item) {
|
||||
GraphTargetItem inside = ((DecrementAVM2Item) value.getNotCoerced()).object.getNotCoerced().getThroughDuplicate();
|
||||
GraphTargetItem inside = ((DecrementAVM2Item) value.getNotCoerced()).value.getNotCoerced().getThroughDuplicate();
|
||||
if (inside instanceof LocalRegAVM2Item) {
|
||||
if (((LocalRegAVM2Item) inside).regIndex == regId) {
|
||||
if (stack.size() > 0) {
|
||||
@@ -94,7 +99,7 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S
|
||||
if (top == inside) {
|
||||
stack.pop();
|
||||
stack.push(new PostDecrementAVM2Item(ins, inside));
|
||||
} else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).object == inside)) {
|
||||
} else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) {
|
||||
stack.pop();
|
||||
stack.push(new PreDecrementAVM2Item(ins, inside));
|
||||
} else {
|
||||
|
||||
@@ -52,7 +52,7 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(stack, constants, multinameIndex, ins);
|
||||
GraphTargetItem obj = (GraphTargetItem) stack.pop();
|
||||
if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof IncrementAVM2Item) {
|
||||
GraphTargetItem inside = ((IncrementAVM2Item) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).object.getThroughRegister().getNotCoerced().getThroughDuplicate();
|
||||
GraphTargetItem inside = ((IncrementAVM2Item) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).value.getThroughRegister().getNotCoerced().getThroughDuplicate();
|
||||
if (inside instanceof GetPropertyAVM2Item) {
|
||||
GetPropertyAVM2Item insideProp = ((GetPropertyAVM2Item) inside);
|
||||
if (insideProp.propertyName.compareSame(multiname)) {
|
||||
@@ -68,7 +68,7 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
|
||||
if (top == insideProp) {
|
||||
stack.pop();
|
||||
stack.push(new PostIncrementAVM2Item(ins, insideProp));
|
||||
} else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).object == inside)) {
|
||||
} else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) {
|
||||
stack.pop();
|
||||
stack.push(new PreIncrementAVM2Item(ins, insideProp));
|
||||
} else {
|
||||
@@ -84,7 +84,7 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
|
||||
}
|
||||
|
||||
if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof DecrementAVM2Item) {
|
||||
GraphTargetItem inside = ((DecrementAVM2Item) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).object.getThroughRegister().getNotCoerced().getThroughDuplicate();
|
||||
GraphTargetItem inside = ((DecrementAVM2Item) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).value.getThroughRegister().getNotCoerced().getThroughDuplicate();
|
||||
if (inside instanceof GetPropertyAVM2Item) {
|
||||
GetPropertyAVM2Item insideProp = ((GetPropertyAVM2Item) inside);
|
||||
if (insideProp.propertyName.compareSame(multiname)) {
|
||||
@@ -100,7 +100,7 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
|
||||
if (top == insideProp) {
|
||||
stack.pop();
|
||||
stack.push(new PostDecrementAVM2Item(ins, insideProp));
|
||||
} else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).object == inside)) {
|
||||
} else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) {
|
||||
stack.pop();
|
||||
stack.push(new PreDecrementAVM2Item(ins, insideProp));
|
||||
} else {
|
||||
|
||||
@@ -105,7 +105,7 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
|
||||
}
|
||||
|
||||
if (value.getNotCoerced().getThroughDuplicate() instanceof IncrementAVM2Item) {
|
||||
GraphTargetItem inside = ((IncrementAVM2Item) value.getNotCoerced()).object.getThroughRegister().getNotCoerced().getThroughDuplicate();
|
||||
GraphTargetItem inside = ((IncrementAVM2Item) value.getNotCoerced()).value.getThroughRegister().getNotCoerced().getThroughDuplicate();
|
||||
if (inside instanceof GetSlotAVM2Item) {
|
||||
GetSlotAVM2Item slotItem = (GetSlotAVM2Item) inside;
|
||||
if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister())
|
||||
@@ -115,7 +115,7 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
|
||||
if (top == inside) {
|
||||
stack.pop();
|
||||
stack.push(new PostIncrementAVM2Item(ins, inside));
|
||||
} else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).object == inside)) {
|
||||
} else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) {
|
||||
stack.pop();
|
||||
stack.push(new PreIncrementAVM2Item(ins, inside));
|
||||
} else {
|
||||
@@ -130,7 +130,7 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
|
||||
}
|
||||
|
||||
if (value.getNotCoerced().getThroughDuplicate() instanceof DecrementAVM2Item) {
|
||||
GraphTargetItem inside = ((DecrementAVM2Item) value.getNotCoerced()).object.getThroughRegister().getNotCoerced().getThroughDuplicate();
|
||||
GraphTargetItem inside = ((DecrementAVM2Item) value.getNotCoerced()).value.getThroughRegister().getNotCoerced().getThroughDuplicate();
|
||||
if (inside instanceof GetSlotAVM2Item) {
|
||||
GetSlotAVM2Item slotItem = (GetSlotAVM2Item) inside;
|
||||
if ((slotItem.scope.getThroughRegister() == obj.getThroughRegister())
|
||||
@@ -140,7 +140,7 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
|
||||
if (top == inside) {
|
||||
stack.pop();
|
||||
stack.push(new PostDecrementAVM2Item(ins, inside));
|
||||
} else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).object == inside)) {
|
||||
} else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) {
|
||||
stack.pop();
|
||||
stack.push(new PreDecrementAVM2Item(ins, inside));
|
||||
} else {
|
||||
|
||||
@@ -18,21 +18,30 @@ package com.jpexs.decompiler.flash.abc.avm2.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class DecrementAVM2Item extends AVM2Item {
|
||||
|
||||
public GraphTargetItem object;
|
||||
|
||||
public DecrementAVM2Item(AVM2Instruction instruction, GraphTargetItem object) {
|
||||
super(instruction, PRECEDENCE_ADDITIVE);
|
||||
this.object = object;
|
||||
this.value = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ConstantPool constants, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
return object.toString(constants, localRegNames, fullyQualifiedNames) + hilight("-1");
|
||||
return value.toString(constants, localRegNames, fullyQualifiedNames) + hilight("-1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime() {
|
||||
return value.isCompileTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
return EcmaScript.toNumber(value.getResult()) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,21 +18,30 @@ package com.jpexs.decompiler.flash.abc.avm2.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class IncrementAVM2Item extends AVM2Item {
|
||||
|
||||
public GraphTargetItem object;
|
||||
|
||||
public IncrementAVM2Item(AVM2Instruction instruction, GraphTargetItem object) {
|
||||
super(instruction, PRECEDENCE_ADDITIVE);
|
||||
this.object = object;
|
||||
this.value = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ConstantPool constants, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames) {
|
||||
return object.toString(constants, localRegNames, fullyQualifiedNames) + hilight("+1");
|
||||
return value.toString(constants, localRegNames, fullyQualifiedNames) + hilight("+1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime() {
|
||||
return value.isCompileTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
return EcmaScript.toNumber(value.getResult()) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,12 +29,21 @@ public class LocalRegAVM2Item extends AVM2Item {
|
||||
|
||||
public int regIndex;
|
||||
public GraphTargetItem computedValue;
|
||||
private Object computedResult;
|
||||
private boolean isCT = false;
|
||||
|
||||
public LocalRegAVM2Item(AVM2Instruction instruction, int regIndex, GraphTargetItem computedValue) {
|
||||
super(instruction, PRECEDENCE_PRIMARY);
|
||||
this.regIndex = regIndex;
|
||||
if (computedValue == null) {
|
||||
//computedValue = new UndefinedAVM2Item(instruction);
|
||||
computedResult = null;
|
||||
} else {
|
||||
if (computedValue.isCompileTime()) {
|
||||
computedResult = computedValue.getResult();
|
||||
isCT = true;
|
||||
} else {
|
||||
computedResult = null;
|
||||
}
|
||||
}
|
||||
this.computedValue = computedValue;
|
||||
}
|
||||
@@ -57,18 +66,15 @@ public class LocalRegAVM2Item extends AVM2Item {
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
if (computedValue == null) {
|
||||
if (computedResult == null) {
|
||||
return new Undefined();
|
||||
}
|
||||
return computedValue.getResult();
|
||||
return computedResult;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime() {
|
||||
if (computedValue == null) {
|
||||
return false;
|
||||
}
|
||||
return computedValue.isCompileTime();
|
||||
return isCT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class NotCompileTimeAVM2Item extends AVM2Item {
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getThroughNotCompilable() {
|
||||
if(object==null){
|
||||
if (object == null) {
|
||||
return object;
|
||||
}
|
||||
return object.getThroughNotCompilable();
|
||||
|
||||
@@ -125,8 +125,8 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
if ((Boolean) Configuration.getConfig("autoDeobfuscate", true)) {
|
||||
try {
|
||||
deobfuscated.removeTraps(constants, b, abc, scriptIndex, classIndex, isStatic, path);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, "Error during remove traps", ex);
|
||||
} catch (Exception | StackOverflowError ex) {
|
||||
Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, "Error during remove traps in " + path, ex);
|
||||
}
|
||||
}
|
||||
//deobfuscated.restoreControlFlow(constants, b);
|
||||
|
||||
@@ -536,13 +536,23 @@ public class Action implements GraphSourceItem {
|
||||
|
||||
ret.append(Highlighting.hilighOffset("", offset));
|
||||
|
||||
if (a instanceof ActionIf) {
|
||||
ActionIf aif = (ActionIf) a;
|
||||
if (aif.jumpUsed && !aif.ignoreUsed) {
|
||||
aif.setFixBranch(0);
|
||||
}
|
||||
if (!aif.jumpUsed && aif.ignoreUsed) {
|
||||
aif.setFixBranch(1);
|
||||
}
|
||||
}
|
||||
|
||||
int fixBranch = a.getFixBranch();
|
||||
if (fixBranch > -1) {
|
||||
if (a instanceof ActionIf) {
|
||||
ret.append("pop\r\n");
|
||||
ret.append("ffdec_deobfuscatepop\r\n");
|
||||
if (fixBranch == 0) { //jump
|
||||
ret.append("jump ofs");
|
||||
ret.append(Helper.formatAddress(offset + ((ActionIf) a).getJumpOffset()));
|
||||
ret.append("jump loc");
|
||||
ret.append(Helper.formatAddress(a.getAddress() + a.getBytes(version).length + ((ActionIf) a).getJumpOffset()));
|
||||
} else {
|
||||
//nojump, ignore
|
||||
}
|
||||
@@ -1337,10 +1347,10 @@ public class Action implements GraphSourceItem {
|
||||
if (o instanceof Long) {
|
||||
return (Long) o;
|
||||
}
|
||||
if(o instanceof String){
|
||||
try{
|
||||
return Double.parseDouble((String)o);
|
||||
}catch(NumberFormatException nfe){
|
||||
if (o instanceof String) {
|
||||
try {
|
||||
return Double.parseDouble((String) o);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.flashlite.ActionFSCommand2;
|
||||
import com.jpexs.decompiler.flash.action.flashlite.ActionStrictMode;
|
||||
import com.jpexs.decompiler.flash.action.parser.ParseException;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionDeobfuscatePop;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionNop;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionStore;
|
||||
import com.jpexs.decompiler.flash.action.swf3.*;
|
||||
@@ -282,6 +283,8 @@ public class ASMParser {
|
||||
if (!ignoreNops) {
|
||||
a = (new ActionNop());
|
||||
}
|
||||
} else if (instructionName.equals("FFDec_DeobfuscatePop".toLowerCase())) {
|
||||
a = new ActionDeobfuscatePop();
|
||||
}/* else if(instructionName.startsWith("ofs")) {
|
||||
continue;
|
||||
}*/ else {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.special;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionPop;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ActionDeobfuscatePop extends ActionPop {
|
||||
|
||||
public ActionDeobfuscatePop() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FFDec_DeobfuscatePop";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(List<Object> localData, Stack<GraphTargetItem> stack, List<GraphTargetItem> output, int staticOperation, String path) {
|
||||
if (stack.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
GraphTargetItem val = stack.pop();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf3;
|
||||
|
||||
import com.jpexs.decompiler.flash.Configuration;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
@@ -25,8 +27,11 @@ import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.IfFrameLoadedActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.ParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionEnd;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionStore;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -46,15 +51,48 @@ public class ActionWaitForFrame extends Action implements ActionStore {
|
||||
skipCount = sis.readUI8();
|
||||
skipped = new ArrayList<>();
|
||||
for (int i = 0; i < skipCount; i++) {
|
||||
skipped.add(sis.readAction());
|
||||
Action a = sis.readAction();
|
||||
if (a instanceof ActionEnd) {
|
||||
skipCount = i;
|
||||
break;
|
||||
}
|
||||
if (a == null) {
|
||||
skipCount = i;
|
||||
break;
|
||||
}
|
||||
skipped.add(a);
|
||||
}
|
||||
boolean deobfuscate = (Boolean) Configuration.getConfig("autoDeobfuscate", true);
|
||||
if (deobfuscate) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
for (int i = 0; i < skipCount; i++) {
|
||||
baos.write(skipped.get(i).getBytes(sis.getVersion()));
|
||||
}
|
||||
baos.write(new ActionEnd().getBytes(sis.getVersion()));
|
||||
SWFInputStream sis2 = new SWFInputStream(new ByteArrayInputStream(baos.toByteArray()), sis.getVersion());
|
||||
skipped = sis2.readActionList(new ArrayList<DisassemblyListener>(), 0, 0, "");
|
||||
if (!skipped.isEmpty()) {
|
||||
if (skipped.get(skipped.size() - 1) instanceof ActionEnd) {
|
||||
skipped.remove(skipped.size() - 1);
|
||||
}
|
||||
}
|
||||
skipCount = skipped.size();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WaitForFrame";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getASMSource(List<? extends GraphSourceItem> container, List<Long> knownAddreses, List<String> constantPool, int version, boolean hex) {
|
||||
String ret = "WaitForFrame " + frame + " " + skipCount;
|
||||
for (int i = 0; i < skipped.size(); i++) {
|
||||
ret += "\r\n" + skipped.get(i).toString();
|
||||
if (skipped.get(i) instanceof ActionEnd) {
|
||||
break;
|
||||
}
|
||||
ret += "\r\n" + skipped.get(i).getASMSource(container, knownAddreses, constantPool, version, hex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.swf4;
|
||||
|
||||
import com.jpexs.decompiler.flash.Configuration;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
@@ -24,8 +26,11 @@ import com.jpexs.decompiler.flash.action.ActionGraph;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.IfFrameLoadedActionItem;
|
||||
import com.jpexs.decompiler.flash.action.parser.ParseException;
|
||||
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionEnd;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionStore;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -59,7 +64,32 @@ public class ActionWaitForFrame2 extends Action implements ActionStore {
|
||||
skipCount = sis.readUI8();
|
||||
skipped = new ArrayList<>();
|
||||
for (int i = 0; i < skipCount; i++) {
|
||||
skipped.add(sis.readAction());
|
||||
Action a = sis.readAction();
|
||||
if (a instanceof ActionEnd) {
|
||||
skipCount = i;
|
||||
break;
|
||||
}
|
||||
if (a == null) {
|
||||
skipCount = i;
|
||||
break;
|
||||
}
|
||||
skipped.add(a);
|
||||
}
|
||||
boolean deobfuscate = (Boolean) Configuration.getConfig("autoDeobfuscate", true);
|
||||
if (deobfuscate) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
for (int i = 0; i < skipCount; i++) {
|
||||
baos.write(skipped.get(i).getBytes(sis.getVersion()));
|
||||
}
|
||||
baos.write(new ActionEnd().getBytes(sis.getVersion()));
|
||||
SWFInputStream sis2 = new SWFInputStream(new ByteArrayInputStream(baos.toByteArray()), sis.getVersion());
|
||||
skipped = sis2.readActionList(new ArrayList<DisassemblyListener>(), 0, 0, "");
|
||||
if (!skipped.isEmpty()) {
|
||||
if (skipped.get(skipped.size() - 1) instanceof ActionEnd) {
|
||||
skipped.remove(skipped.size() - 1);
|
||||
}
|
||||
}
|
||||
skipCount = skipped.size();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,9 +112,17 @@ public class ActionWaitForFrame2 extends Action implements ActionStore {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WaitForFrame2";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getASMSource(List<? extends GraphSourceItem> container, List<Long> knownAddreses, List<String> constantPool, int version, boolean hex) {
|
||||
String ret = "WaitForFrame2 " + skipCount;
|
||||
for (Action a : skipped) {
|
||||
ret += "\r\n" + a.toString();
|
||||
for (int i = 0; i < skipped.size(); i++) {
|
||||
if (skipped.get(i) instanceof ActionEnd) {
|
||||
break;
|
||||
}
|
||||
ret += "\r\n" + skipped.get(i).getASMSource(container, knownAddreses, constantPool, version, hex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -77,10 +77,11 @@ public class RenameDialog extends AppDialog implements ActionListener {
|
||||
cancelButton.addActionListener(this);
|
||||
add(panButtons, BorderLayout.SOUTH);
|
||||
setModalityType(ModalityType.APPLICATION_MODAL);
|
||||
View.centerScreen(this);
|
||||
View.setWindowIcon(this);
|
||||
setTitle(translate("dialog.title"));
|
||||
getRootPane().setDefaultButton(okButton);
|
||||
pack();
|
||||
View.centerScreen(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -128,9 +128,10 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
|
||||
depthMap.put(pot.getDepth(), charId);
|
||||
characterId = (charId);
|
||||
} else {
|
||||
Integer chi= (depthMap.get(pot.getDepth()));
|
||||
if(chi!=null)
|
||||
characterId = chi;
|
||||
Integer chi = (depthMap.get(pot.getDepth()));
|
||||
if (chi != null) {
|
||||
characterId = chi;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (characterId == -1) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.helpers.Helper;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -47,6 +48,7 @@ public class DoActionTag extends Tag implements ASMSource {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param swf
|
||||
* @param data Data bytes
|
||||
* @param version SWF version
|
||||
* @param pos
|
||||
|
||||
@@ -175,12 +175,12 @@ public abstract class TextTag extends CharacterTag implements BoundedTag {
|
||||
updateRect(textBounds, x + rect.Xmin, y + rect.Ymin);
|
||||
updateRect(textBounds, x + rect.Xmax, y + rect.Ymax);
|
||||
int adv = entry.glyphAdvance;
|
||||
|
||||
|
||||
int defaultAdvance;
|
||||
if (font.hasLayout()) {
|
||||
defaultAdvance = 20 * (int) Math.round((double) textHeight * font.getGlyphAdvance(entry.glyphIndex) / (font.getDivider() * 1024.0));
|
||||
} else {
|
||||
defaultAdvance = 20 * FontTag.getSystemFontAdvance(aFont, font.glyphToChar(tags, entry.glyphIndex));
|
||||
defaultAdvance = 20 * FontTag.getSystemFontAdvance(aFont, font.glyphToChar(tags, entry.glyphIndex));
|
||||
}
|
||||
letterSpacing = adv - defaultAdvance;
|
||||
x += adv;
|
||||
|
||||
Reference in New Issue
Block a user