mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-15 19:38:19 +00:00
AS1/2 better deobfuscation
This commit is contained in:
@@ -21,6 +21,8 @@ import com.jpexs.decompiler.flash.action.ActionGraphSource;
|
||||
import com.jpexs.decompiler.flash.action.UnknownActionException;
|
||||
import com.jpexs.decompiler.flash.action.parser.ASMParser;
|
||||
import com.jpexs.decompiler.flash.action.parser.ParseException;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionContainer;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionEnd;
|
||||
import com.jpexs.decompiler.flash.action.special.ActionNop;
|
||||
import com.jpexs.decompiler.flash.action.swf3.*;
|
||||
import com.jpexs.decompiler.flash.action.swf4.*;
|
||||
@@ -509,7 +511,11 @@ public class SWFInputStream extends InputStream {
|
||||
if (ins instanceof ActionConstantPool) {
|
||||
constantPools.add(new ConstantPool(((ActionConstantPool) ins).constantPool));
|
||||
}
|
||||
|
||||
|
||||
//for..in return
|
||||
if (((ins instanceof ActionEquals) || (ins instanceof ActionEquals2)) && (stack.size() == 1) && (stack.peek() instanceof DirectValueTreeItem)) {
|
||||
stack.push(new DirectValueTreeItem(null, 0, new Null(), new ArrayList<String>()));
|
||||
}
|
||||
ins.translate(localData, stack, output);
|
||||
if (ins.isExit()) {
|
||||
break;
|
||||
@@ -602,6 +608,17 @@ public class SWFInputStream extends InputStream {
|
||||
}
|
||||
last = a;
|
||||
}
|
||||
int len=retdups.size();
|
||||
for(int i=0;i<retdups.size();i++){
|
||||
Action a=retdups.get(i);
|
||||
if(a instanceof ActionEnd){
|
||||
if(i<retdups.size()-1){
|
||||
ActionJump jmp=new ActionJump(0);
|
||||
jmp.offset = retdups.size()-i-jmp.getBytes(version).length;
|
||||
a.replaceWith = jmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<ConstantPool> pools = new ArrayList<ConstantPool>();
|
||||
pools = getConstantPool(new ActionGraphSource(ret, version, new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>()), ip);
|
||||
@@ -639,16 +656,22 @@ public class SWFInputStream extends InputStream {
|
||||
long filePos = rri.getPos();
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int prevIp = ip;
|
||||
while ((a = sis.readAction()) != null) {
|
||||
while ((a = sis.readAction()) != null) {
|
||||
a.setAddress(prevIp, SWF.DEFAULT_VERSION);
|
||||
int info = a.actionLength + 1 + ((a.actionCode > 0x80) ? 2 : 0);
|
||||
int actual = a.getBytes(sis.version).length;
|
||||
if (info != actual) {
|
||||
if (!(a instanceof ActionDefineFunction)) {
|
||||
if (!(a instanceof ActionDefineFunction2)) {
|
||||
//throw new RuntimeException("Lengths do not match "+a+" "+info+"<>"+actual);
|
||||
}
|
||||
int actual = 0;
|
||||
if(a instanceof ActionContainer){
|
||||
actual=((ActionContainer)a).getHeaderBytes().length;
|
||||
}else{
|
||||
actual=a.getBytes(sis.version).length;
|
||||
}
|
||||
if(!(a instanceof ActionContainer)){
|
||||
int change=info-(rri.getPos()-ip);
|
||||
if(change > 0){
|
||||
a.afterInsert=new ActionJump(change);
|
||||
}
|
||||
}else{
|
||||
info=rri.getPos()-ip;
|
||||
}
|
||||
if (ip < startIp) {
|
||||
retv = true;
|
||||
@@ -805,10 +828,13 @@ public class SWFInputStream extends InputStream {
|
||||
ret.set(ip + i, a);
|
||||
}
|
||||
|
||||
if(a instanceof ActionEnd){
|
||||
break;
|
||||
}
|
||||
if (newip > -1) {
|
||||
ip = newip;
|
||||
} else {
|
||||
ip = ip + (int) actionLen;
|
||||
ip = ip + info; //(int) actionLen;
|
||||
}
|
||||
rri.setPos(ip);
|
||||
filePos = rri.getPos();
|
||||
@@ -1172,7 +1198,7 @@ public class SWFInputStream extends InputStream {
|
||||
{
|
||||
int actionCode = readUI8();
|
||||
if (actionCode == 0) {
|
||||
return null;
|
||||
return new ActionEnd();
|
||||
}
|
||||
if (actionCode == -1) {
|
||||
return null;
|
||||
|
||||
@@ -52,6 +52,8 @@ import java.util.logging.Logger;
|
||||
public class Action implements GraphSourceItem {
|
||||
|
||||
public Action beforeInsert;
|
||||
public Action afterInsert;
|
||||
public Action replaceWith;
|
||||
public boolean ignored = false;
|
||||
/**
|
||||
* Action type identifier
|
||||
@@ -157,8 +159,20 @@ public class Action implements GraphSourceItem {
|
||||
public static List<Long> getActionsAllRefs(List<Action> list, int version) {
|
||||
List<Long> ret = new ArrayList<Long>();
|
||||
for (Action a : list) {
|
||||
if (a.replaceWith != null) {
|
||||
a.replaceWith.setAddress(a.getAddress(), version);
|
||||
ret.addAll(a.replaceWith.getAllRefs(version));
|
||||
}
|
||||
if (a.beforeInsert != null) {
|
||||
a.beforeInsert.setAddress(a.getAddress(), version);
|
||||
ret.addAll(a.beforeInsert.getAllRefs(version));
|
||||
}
|
||||
List<Long> part = a.getAllRefs(version);
|
||||
ret.addAll(part);
|
||||
if (a.afterInsert != null) {
|
||||
a.afterInsert.setAddress(a.getAddress(), version);
|
||||
ret.addAll(a.afterInsert.getAllRefs(version));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -371,7 +385,9 @@ public class Action implements GraphSourceItem {
|
||||
ret += "loc" + Helper.formatAddress(offset) + ":";
|
||||
}
|
||||
|
||||
if (a.ignored) {
|
||||
if (a.replaceWith != null) {
|
||||
ret += Highlighting.hilighOffset("", offset) + a.replaceWith.getASMSource(importantOffsets, constantPool, version, hex) + "\r\n";
|
||||
} else if (a.ignored) {
|
||||
int len = a.getBytes(version).length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
ret += "Nop\r\n";
|
||||
@@ -383,6 +399,9 @@ public class Action implements GraphSourceItem {
|
||||
//if (!(a instanceof ActionNop)) {
|
||||
ret += Highlighting.hilighOffset("", offset) + a.getASMSource(importantOffsets, constantPool, version, hex) + (a.ignored ? "; ignored" : "") + "\r\n";
|
||||
//}
|
||||
if (a.afterInsert != null) {
|
||||
ret += a.afterInsert.getASMSource(importantOffsets, constantPool, version, hex) + "\r\n";
|
||||
}
|
||||
}
|
||||
offset += a.getBytes(version).length;
|
||||
}
|
||||
@@ -758,14 +777,6 @@ public class Action implements GraphSourceItem {
|
||||
|
||||
ip++;
|
||||
}
|
||||
if (stack.size() > 0) {
|
||||
for (int i = stack.size() - 1; i >= 0; i--) {
|
||||
if (stack.get(i) instanceof FunctionTreeItem) {
|
||||
output.add(0, stack.get(i));
|
||||
stack.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
//output = checkClass(output);
|
||||
log("Leaving " + start + "-" + end);
|
||||
return output;
|
||||
@@ -809,6 +820,7 @@ public class Action implements GraphSourceItem {
|
||||
GraphTargetItem extendsOp = null;
|
||||
List<GraphTargetItem> implementsOp = new ArrayList<GraphTargetItem>();
|
||||
boolean ok = true;
|
||||
int prevCount = 0;
|
||||
for (GraphTargetItem t : output) {
|
||||
if (t instanceof IfItem) {
|
||||
IfItem it = (IfItem) t;
|
||||
@@ -843,6 +855,14 @@ public class Action implements GraphSourceItem {
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (parts.size() <= pos) {
|
||||
List<GraphTargetItem> output2 = new ArrayList<GraphTargetItem>();
|
||||
for (int i = 0; i < prevCount; i++) {
|
||||
output2.add(output.get(i));
|
||||
}
|
||||
output2.add(new ClassTreeItem(className, extendsOp, implementsOp, functions, vars, staticFunctions, staticVars));
|
||||
return output2;
|
||||
}
|
||||
if (parts.get(pos) instanceof StoreRegisterTreeItem) {
|
||||
int instanceReg = -1;
|
||||
if (((StoreRegisterTreeItem) parts.get(pos)).value instanceof GetMemberTreeItem) {
|
||||
@@ -934,7 +954,10 @@ public class Action implements GraphSourceItem {
|
||||
}
|
||||
if (ok) {
|
||||
List<GraphTargetItem> output2 = new ArrayList<GraphTargetItem>();
|
||||
output2.add(new ClassTreeItem(className, extendsOp, implementsOp, functions, vars, staticFunctions, staticVars));
|
||||
for (int i = 0; i < prevCount; i++) {
|
||||
output2.add(output.get(i));
|
||||
}
|
||||
output2.add(new ClassTreeItem(className, extendsOp, implementsOp, functions, vars, staticFunctions, staticVars));
|
||||
return output2;
|
||||
}
|
||||
} else {
|
||||
@@ -965,6 +988,9 @@ public class Action implements GraphSourceItem {
|
||||
}
|
||||
}
|
||||
List<GraphTargetItem> output2 = new ArrayList<GraphTargetItem>();
|
||||
for (int i = 0; i < prevCount; i++) {
|
||||
output2.add(output.get(i));
|
||||
}
|
||||
output2.add(new InterfaceTreeItem(sm.objectName, implementsOp));
|
||||
return output2;
|
||||
} else {
|
||||
@@ -990,16 +1016,14 @@ public class Action implements GraphSourceItem {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
prevCount++;
|
||||
//ok = false;
|
||||
}
|
||||
if (!ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
return output;
|
||||
}
|
||||
return ret;
|
||||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.action.swf4.Null;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionEquals2;
|
||||
import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem;
|
||||
import com.jpexs.decompiler.flash.action.treemodel.EnumerateTreeItem;
|
||||
import com.jpexs.decompiler.flash.action.treemodel.FunctionTreeItem;
|
||||
import com.jpexs.decompiler.flash.action.treemodel.SetTypeTreeItem;
|
||||
import com.jpexs.decompiler.flash.action.treemodel.StoreRegisterTreeItem;
|
||||
import com.jpexs.decompiler.flash.action.treemodel.clauses.ForInTreeItem;
|
||||
@@ -69,6 +70,23 @@ public class ActionGraph extends Graph {
|
||||
return g.translate(localData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalProcessStack(Stack<GraphTargetItem> stack,List<GraphTargetItem> output) {
|
||||
if (stack.size() > 0) {
|
||||
for (int i = stack.size() - 1; i >= 0; i--) {
|
||||
//System.err.println(stack.get(i));
|
||||
if (stack.get(i) instanceof FunctionTreeItem) {
|
||||
FunctionTreeItem f=(FunctionTreeItem)stack.remove(i);
|
||||
if(!output.contains(f)){
|
||||
output.add(0, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void finalProcess(List<GraphTargetItem> list, int level) {
|
||||
List<GraphTargetItem> ret = Action.checkClass(list);
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.special;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public class ActionEnd extends Action {
|
||||
|
||||
public ActionEnd() {
|
||||
super(0, 0);
|
||||
ignored = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "End";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(Stack<com.jpexs.decompiler.flash.graph.GraphTargetItem> stack, List<com.jpexs.decompiler.flash.graph.GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
|
||||
//output.add(new SimpleActionTreeItem(this, "end()"));
|
||||
}
|
||||
}
|
||||
@@ -38,8 +38,8 @@ public class ActionGetURL extends Action {
|
||||
|
||||
public ActionGetURL(int actionLength, SWFInputStream sis, int version) throws IOException {
|
||||
super(0x83, actionLength);
|
||||
byte data[] = sis.readBytes(actionLength);
|
||||
sis = new SWFInputStream(new ByteArrayInputStream(data), version);
|
||||
//byte data[] = sis.readBytes(actionLength);
|
||||
//sis = new SWFInputStream(new ByteArrayInputStream(data), version);
|
||||
urlString = sis.readString();
|
||||
targetString = sis.readString();
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ public class ActionGoToLabel extends Action {
|
||||
|
||||
public ActionGoToLabel(int actionLength, SWFInputStream sis, int version) throws IOException {
|
||||
super(0x8C, actionLength);
|
||||
byte data[] = sis.readBytes(actionLength);
|
||||
sis = new SWFInputStream(new ByteArrayInputStream(data), version);
|
||||
//byte data[] = sis.readBytes(actionLength);
|
||||
//sis = new SWFInputStream(new ByteArrayInputStream(data), version);
|
||||
label = sis.readString();
|
||||
}
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ public class ActionSetTarget extends Action {
|
||||
|
||||
public ActionSetTarget(int actionLength, SWFInputStream sis, int version) throws IOException {
|
||||
super(0x8B, actionLength);
|
||||
byte data[] = sis.readBytes(actionLength);
|
||||
sis = new SWFInputStream(new ByteArrayInputStream(data), version);
|
||||
//byte data[] = sis.readBytes(actionLength);
|
||||
//sis = new SWFInputStream(new ByteArrayInputStream(data), version);
|
||||
targetName = sis.readString();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public class ActionConstantPool extends Action {
|
||||
|
||||
public ActionConstantPool(int actionLength, SWFInputStream sis, int version) throws IOException {
|
||||
super(0x88, actionLength);
|
||||
sis = new SWFInputStream(new ByteArrayInputStream(sis.readBytes(actionLength)), version);
|
||||
//sis = new SWFInputStream(new ByteArrayInputStream(sis.readBytes(actionLength)), version);
|
||||
int count = sis.readUI16();
|
||||
for (int i = 0; i < count; i++) {
|
||||
constantPool.add(sis.readString());
|
||||
|
||||
@@ -17,8 +17,11 @@
|
||||
package com.jpexs.decompiler.flash.action.swf5;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.swf4.Null;
|
||||
import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem;
|
||||
import com.jpexs.decompiler.flash.action.treemodel.EnumerateTreeItem;
|
||||
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
@@ -37,6 +40,7 @@ public class ActionEnumerate extends Action {
|
||||
@Override
|
||||
public void translate(Stack<GraphTargetItem> stack, List<GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
|
||||
GraphTargetItem object = stack.pop();
|
||||
stack.push(new EnumerateTreeItem(this, object));
|
||||
stack.push(new DirectValueTreeItem(null, 0, new Null(), new ArrayList<String>()));
|
||||
stack.push(new EnumerateTreeItem(this, object));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ActionSetMember extends Action {
|
||||
|
||||
@Override
|
||||
public void translate(Stack<GraphTargetItem> stack, List<GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
|
||||
GraphTargetItem value = stack.pop();
|
||||
GraphTargetItem value = stack.pop();
|
||||
GraphTargetItem objectName = stack.pop();
|
||||
GraphTargetItem object = stack.pop();
|
||||
output.add(new SetMemberTreeItem(this, object, objectName, value));
|
||||
|
||||
@@ -17,8 +17,11 @@
|
||||
package com.jpexs.decompiler.flash.action.swf6;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.swf4.Null;
|
||||
import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem;
|
||||
import com.jpexs.decompiler.flash.action.treemodel.EnumerateTreeItem;
|
||||
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
@@ -37,6 +40,7 @@ public class ActionEnumerate2 extends Action {
|
||||
@Override
|
||||
public void translate(Stack<GraphTargetItem> stack, List<GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions) {
|
||||
GraphTargetItem object = stack.pop();
|
||||
stack.push(new EnumerateTreeItem(this, object));
|
||||
stack.push(new DirectValueTreeItem(null, 0, new Null(), new ArrayList<String>()));
|
||||
stack.push(new EnumerateTreeItem(this, object));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.List;
|
||||
|
||||
public class ClassTreeItem extends TreeItem implements Block {
|
||||
|
||||
public List<GraphTargetItem> functions;
|
||||
private List<GraphTargetItem> functions;
|
||||
public List<GraphTargetItem> staticFunctions;
|
||||
public GraphTargetItem extendsOp;
|
||||
public List<GraphTargetItem> implementsOp;
|
||||
|
||||
@@ -290,11 +290,17 @@ public class Graph {
|
||||
for (GraphPart head : heads) {
|
||||
populateParts(head, allParts);
|
||||
}
|
||||
List<GraphTargetItem> ret = printGraph(localData, new Stack<GraphTargetItem>(), allParts, null, heads.get(0), null, new ArrayList<Loop>(), new HashMap<Loop, List<GraphTargetItem>>());
|
||||
Stack<GraphTargetItem> stack = new Stack<GraphTargetItem>();
|
||||
List<GraphTargetItem> ret = printGraph(localData, stack, allParts, null, heads.get(0), null, new ArrayList<Loop>(), new HashMap<Loop, List<GraphTargetItem>>());
|
||||
finalProcessStack(stack,ret);
|
||||
finalProcessAll(ret, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void finalProcessStack(Stack<GraphTargetItem> stack,List<GraphTargetItem> output){
|
||||
|
||||
}
|
||||
|
||||
private void finalProcessAll(List<GraphTargetItem> list, int level) {
|
||||
finalProcess(list, level);
|
||||
for (GraphTargetItem item : list) {
|
||||
|
||||
Reference in New Issue
Block a user