Merge origin/master

This commit is contained in:
Jindra Petřík
2014-09-21 16:10:45 +02:00
41 changed files with 280 additions and 262 deletions

View File

@@ -806,7 +806,7 @@ public class ABC {
if (t instanceof TraitSlotConst) {
TraitSlotConst s = ((TraitSlotConst) t);
if (s.isNamespace()) {
String key = constants.getNamespace(s.value_index).getName(constants,true); //assume not null
String key = constants.getNamespace(s.value_index).getName(constants, true); //assume not null
String val = constants.getMultiname(s.name_index).getNameWithNamespace(constants, true);
namespaceMap.put(key, val);
}

View File

@@ -74,7 +74,7 @@ public class ScriptPack implements TreeElementItem {
Multiname name = abc.script_info.get(scriptIndex).traits.traits.get(t).getName(abc);
Namespace ns = name.getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
packageName = ns.getName(abc.constants,false); //assume not null
packageName = ns.getName(abc.constants, false); //assume not null
}
}
return packageName;

View File

@@ -1209,17 +1209,18 @@ public class AVM2Code implements Cloneable {
/**
* Test for killed register. CalcKilledStats must be called before
*
* @param regName
* @param start
* @param end
* @return
* @return
*/
public boolean isKilled(int regName, int start, int end) {
if(!killedRegs.containsKey(regName)){
public boolean isKilled(int regName, int start, int end) {
if (!killedRegs.containsKey(regName)) {
return false;
}
for(int ip:killedRegs.get(regName)){
if(ip>=start && ip<=end){
for (int ip : killedRegs.get(regName)) {
if (ip >= start && ip <= end) {
return true;
}
}
@@ -1239,32 +1240,32 @@ public class AVM2Code implements Cloneable {
return localRegNames;
}
private Map<Integer,Set<Integer>> killedRegs=new HashMap<Integer,Set<Integer>>();
public void calcKilledStats(MethodBody body){
private Map<Integer, Set<Integer>> killedRegs = new HashMap<>();
public void calcKilledStats(MethodBody body) {
killedRegs.clear();
try {
HashMap<Integer,List<Integer>> vis=visitCode(body);
for(int k=0;k<code.size();k++){
if(vis.get(k).isEmpty()){
HashMap<Integer, List<Integer>> vis = visitCode(body);
for (int k = 0; k < code.size(); k++) {
if (vis.get(k).isEmpty()) {
continue;
}
if (code.get(k).definition instanceof KillIns) {
int regid = code.get(k).operands[0];
if(!killedRegs.containsKey(regid)){
if (!killedRegs.containsKey(regid)) {
killedRegs.put(regid, new HashSet<Integer>());
}
killedRegs.get(regid).add(k);
}
}
} catch (InterruptedException ex) {
//ignored
}
}
public List<GraphTargetItem> clearTemporaryRegisters(List<GraphTargetItem> output) {
for (int i = 0; i < output.size(); i++) {
for (int i = 0; i < output.size(); i++) {
if (output.get(i) instanceof SetLocalAVM2Item) {
if (isKilled(((SetLocalAVM2Item) output.get(i)).regIndex, 0, code.size() - 1)) {
SetLocalAVM2Item lsi = (SetLocalAVM2Item) output.get(i);

View File

@@ -34,7 +34,7 @@ public class FindDefAVM2Item extends AVM2Item {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) {
return writer.append(propertyName.getNamespace(localData.constantsAvm2).getName(localData.constantsAvm2,false)); //assume not null name
return writer.append(propertyName.getNamespace(localData.constantsAvm2).getName(localData.constantsAvm2, false)); //assume not null name
}
@Override

View File

@@ -70,7 +70,7 @@ public class FullMultinameAVM2Item extends AVM2Item {
} else {
Namespace ns = constants.getMultiname(multinameIndex).getNamespace(constants);
if ((ns != null) && (ns.name_index != 0)) {
cns = ns.getName(constants,false);
cns = ns.getName(constants, false);
}
}
return cname.equals("XML") && cns.isEmpty();

View File

@@ -2136,7 +2136,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
abc.constants.getMultinameId(
new Multiname(Multiname.QNAME,
abc.constants.getStringId(superName.getName(a.constants, new ArrayList<String>(), true), true),
abc.constants.getNamespaceId(new Namespace(superName.getNamespace(a.constants).kind, abc.constants.getStringId(superName.getNamespace(a.constants).getName(a.constants,true), true)), 0, true), 0, 0, new ArrayList<Integer>()), true)
abc.constants.getNamespaceId(new Namespace(superName.getNamespace(a.constants).kind, abc.constants.getStringId(superName.getNamespace(a.constants).getName(a.constants, true), true)), 0, true), 0, 0, new ArrayList<Integer>()), true)
);
}
}
@@ -2190,11 +2190,11 @@ public class AVM2SourceGenerator implements SourceGenerator {
continue;
}
for (Trait t : ii.traits.traits) {
if (eq(pkg, t.getName(abc).getNamespace(abc.constants).getName(abc.constants,true))) {
if (eq(pkg, t.getName(abc).getNamespace(abc.constants).getName(abc.constants, true))) {
if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList<String>(), true))) {
outName.setVal(obj);
outNs.setVal(pkg);
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants,true));
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants, true));
outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind);
outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index));
outPropType.setVal(getTraitReturnType(abc, t));
@@ -2215,7 +2215,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
Multiname clsName = ii.getName(abc.constants);
if (obj.equals(clsName.getName(abc.constants, new ArrayList<String>(), true))) {
if (eq(pkg, clsName.getNamespace(abc.constants).getName(abc.constants,true))) {
if (eq(pkg, clsName.getNamespace(abc.constants).getName(abc.constants, true))) {
//class found
for (Trait t : ii.instance_traits.traits) {
@@ -2225,7 +2225,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList<String>(), true))) {
outName.setVal(obj);
outNs.setVal(pkg);
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants,true));
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants, true));
outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind);
outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index));
outPropType.setVal(getTraitReturnType(abc, t));
@@ -2245,7 +2245,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList<String>(), true))) {
outName.setVal(obj);
outNs.setVal(pkg);
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants,true));
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants, true));
outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind);
outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index));
outPropType.setVal(getTraitReturnType(abc, t));
@@ -2260,7 +2260,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
Multiname superName = abc.constants.constant_multiname.get(ii.super_index);
if (superName != null) {
return searchPrototypeChain(instanceOnly, abcs, superName.getNamespace(abc.constants).getName(abc.constants,true), superName.getName(abc.constants, new ArrayList<String>(), true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue);
return searchPrototypeChain(instanceOnly, abcs, superName.getNamespace(abc.constants).getName(abc.constants, true), superName.getName(abc.constants, new ArrayList<String>(), true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue);
} else {
return false;
}
@@ -2274,7 +2274,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
public static void parentNames(ABC abc, List<ABC> allABCs, int name_index, List<Integer> indices, List<String> names, List<String> namespaces, List<ABC> outABCs) {
indices.add(name_index);
names.add(abc.constants.constant_multiname.get(name_index).getName(abc.constants, new ArrayList<String>(), true));
namespaces.add(abc.constants.constant_multiname.get(name_index).getNamespace(abc.constants).getName(abc.constants,true));
namespaces.add(abc.constants.constant_multiname.get(name_index).getNamespace(abc.constants).getName(abc.constants, true));
Multiname mname = abc.constants.constant_multiname.get(name_index);
outABCs.add(abc);
@@ -2288,7 +2288,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
Multiname m = a.constants.constant_multiname.get(a.instance_info.get(i).name_index);
if (m.getName(a.constants, new ArrayList<String>(), true).equals(mname.getName(abc.constants, new ArrayList<String>(), true))) {
if (m.getNamespace(a.constants).hasName(mname.getNamespace(abc.constants).getName(abc.constants,true),a.constants)) {
if (m.getNamespace(a.constants).hasName(mname.getNamespace(abc.constants).getName(abc.constants, true), a.constants)) {
//Multiname superName = a.constants.constant_multiname.get(a.instance_info.get(i).super_index);
abcs.remove(a);
if (a.instance_info.get(i).super_index != 0) {
@@ -2392,7 +2392,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
for (int i = 1; i < abc.constants.constant_multiname.size(); i++) {
Multiname mname = abc.constants.constant_multiname.get(i);
if (mname != null && name.equals(mname.getName(abc.constants, new ArrayList<String>(), true))) {
if (mname.getNamespace(abc.constants) != null && pkg.equals(mname.getNamespace(abc.constants).getName(abc.constants,true))) {
if (mname.getNamespace(abc.constants) != null && pkg.equals(mname.getNamespace(abc.constants).getName(abc.constants, true))) {
name_index = i;
break;
}

View File

@@ -219,7 +219,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
Reference<Integer> outPropNsIndex = new Reference<>(0);
Reference<GraphTargetItem> outPropType = new Reference<>(null);
Reference<ValueKind> outPropValue = new Reference<>(null);
if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, m.getNamespace(a.constants).getName(a.constants,true), m.getName(a.constants, new ArrayList<String>(), true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) {
if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, m.getNamespace(a.constants).getName(a.constants, true), m.getName(a.constants, new ArrayList<String>(), true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) {
objType = new TypeItem("".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal());
propType = outPropType.getVal();
propIndex = abc.constants.getMultinameId(new Multiname(Multiname.QNAME,
@@ -258,7 +258,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
for (int i = 0; i < openedNamespaces.size(); i++) {
int nsindex = openedNamespaces.get(i);
int nsKind = abc.constants.constant_namespace.get(openedNamespaces.get(i)).kind;
String nsname = abc.constants.constant_namespace.get(openedNamespaces.get(i)).getName(abc.constants,true);
String nsname = abc.constants.constant_namespace.get(openedNamespaces.get(i)).getName(abc.constants, true);
int name_index = 0;
for (int m = 1; m < abc.constants.constant_multiname.size(); m++) {
Multiname mname = abc.constants.constant_multiname.get(m);
@@ -328,7 +328,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
continue;
}
Multiname n = a.constants.constant_multiname.get(ii.name_index);
if (n.getNamespace(a.constants).kind == Namespace.KIND_PACKAGE && n.getNamespace(a.constants).getName(a.constants,true).equals(nsname)) {
if (n.getNamespace(a.constants).kind == Namespace.KIND_PACKAGE && n.getNamespace(a.constants).getName(a.constants, true).equals(nsname)) {
Reference<String> outName = new Reference<>("");
Reference<String> outNs = new Reference<>("");
Reference<String> outPropNs = new Reference<>("");

View File

@@ -407,7 +407,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
continue;
}
if ((a.instance_info.get(c).getName(a.constants) != null && a == abc && a.instance_info.get(c).getName(a.constants).namespace_index == ni)
|| (ons.kind != Namespace.KIND_PRIVATE && a.instance_info.get(c).getName(a.constants) != null && a.instance_info.get(c).getName(a.constants).getNamespace(a.constants) != null && a.instance_info.get(c).getName(a.constants).getNamespace(a.constants).hasName(ons.getName(abc.constants,true), a.constants))) {
|| (ons.kind != Namespace.KIND_PRIVATE && a.instance_info.get(c).getName(a.constants) != null && a.instance_info.get(c).getName(a.constants).getNamespace(a.constants) != null && a.instance_info.get(c).getName(a.constants).getNamespace(a.constants).hasName(ons.getName(abc.constants, true), a.constants))) {
String cname = a.instance_info.get(c).getName(a.constants).getName(a.constants, new ArrayList<String>(), true);
if (parts.get(0).equals(cname)) {
if (!subtypes.isEmpty() && parts.size() > 1) {

View File

@@ -157,7 +157,7 @@ public class Multiname {
}
int type = constants.getNamespace(index).kind;
int name_index = constants.getNamespace(index).name_index;
String name = name_index == 0 ? null : constants.getNamespace(index).getName(constants,true);
String name = name_index == 0 ? null : constants.getNamespace(index).getName(constants, true);
int sub = -1;
for (int n = 1; n < constants.getNamespaceCount(); n++) {
if (constants.getNamespace(n).kind == type && constants.getNamespace(n).name_index == name_index) {
@@ -272,7 +272,7 @@ public class Multiname {
String ret = "";
Namespace ns = getNamespace(constants);
if (ns != null) {
String nsname = ns.getName(constants,raw);
String nsname = ns.getName(constants, raw);
if (nsname != null && !nsname.isEmpty()) {
ret += nsname + ".";
}

View File

@@ -77,7 +77,7 @@ public class Namespace {
}
public String toString(AVM2ConstantPool constants) {
return getName(constants,false);
return getName(constants, false);
}
public String getNameWithKind(AVM2ConstantPool constants) {
@@ -101,7 +101,7 @@ public class Namespace {
if (name_index == 0) {
return null;
}
if(raw){
if (raw) {
return constants.getString(name_index);
}
return Deobfuscation.printNamespace(constants.getString(name_index));

View File

@@ -50,7 +50,7 @@ public class ScriptInfo {
Namespace ns = name.getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE_INTERNAL)
|| (ns.kind == Namespace.KIND_PACKAGE)) {
String packageName = ns.getName(abc.constants,false); //assume not null package
String packageName = ns.getName(abc.constants, false); //assume not null package
String objectName = name.getName(abc.constants, new ArrayList<String>(), false);
List<Integer> traitIndices = new ArrayList<>();

View File

@@ -134,7 +134,7 @@ public class ValueKind {
case CONSTANT_ExplicitNamespace:
case CONSTANT_StaticProtectedNs:
case CONSTANT_PrivateNs:
ret = "\"" + constants.getNamespace(value_index).getName(constants,true) + "\""; //assume not null name
ret = "\"" + constants.getNamespace(value_index).getName(constants, true) + "\""; //assume not null name
break;
}
return ret;
@@ -176,7 +176,7 @@ public class ValueKind {
case CONSTANT_ExplicitNamespace:
case CONSTANT_StaticProtectedNs:
case CONSTANT_PrivateNs:
ret = constants.getNamespace(value_index).getKindStr() + "(\"" + constants.getNamespace(value_index).getName(constants,true) + "\")"; //assume not null name
ret = constants.getNamespace(value_index).getKindStr() + "(\"" + constants.getNamespace(value_index).getName(constants, true) + "\")"; //assume not null name
break;
}
return ret;

View File

@@ -63,7 +63,7 @@ public abstract class Trait implements Serializable {
if (m.namespace_index == -1) {
break;
}
nsname = abcTag.getABC().nsValueToName(abc.constants.getNamespace(m.namespace_index).getName(abc.constants,true));
nsname = abcTag.getABC().nsValueToName(abc.constants.getNamespace(m.namespace_index).getName(abc.constants, true));
if (nsname == null) {
break;
}
@@ -85,7 +85,7 @@ public abstract class Trait implements Serializable {
} else {
if (ns != null) {
if (ns.kind == Namespace.KIND_NAMESPACE) {
nsname = ns.getName(abc.constants,true);
nsname = ns.getName(abc.constants, true);
}
}
}
@@ -132,7 +132,7 @@ public abstract class Trait implements Serializable {
public GraphTextWriter toStringPackaged(Trait parent, String path, List<ABCContainerTag> abcTags, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
String nsname = ns.getName(abc.constants,false);
String nsname = ns.getName(abc.constants, false);
writer.appendNoHilight("package");
if (!nsname.isEmpty()) {
writer.appendNoHilight(" " + nsname); //assume not null name
@@ -174,7 +174,7 @@ public abstract class Trait implements Serializable {
public String getPath(ABC abc) {
Multiname name = getName(abc);
Namespace ns = name.getNamespace(abc.constants);
String packageName = ns.getName(abc.constants,false);
String packageName = ns.getName(abc.constants, false);
String objectName = name.getName(abc.constants, new ArrayList<String>(), false);
return packageName + "." + objectName; //assume not null name
}

View File

@@ -91,7 +91,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
if (name.isEmpty()) {
name = "*";
}
String newimport = ns.getName(abc.constants,false);
String newimport = ns.getName(abc.constants, false);
/*if ((ns.kind != Namespace.KIND_PACKAGE)
&& (ns.kind != Namespace.KIND_NAMESPACE)
&& (ns.kind != Namespace.KIND_STATIC_PROTECTED)) {
@@ -163,7 +163,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
if (name.isEmpty()) {
name = "*";
}
String newimport = ns.getName(abc.constants,false);
String newimport = ns.getName(abc.constants, false);
if (parseUsagesFromNS(abcTags, abc, imports, uses, namespace_index, ignorePackage, name)) {
return;
} else if ((ns.kind != Namespace.KIND_PACKAGE) && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) {
@@ -321,7 +321,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
private List<String> getImportsUsages(List<ABCContainerTag> abcTags, ABC abc, List<String> imports, List<String> uses, List<String> fullyQualifiedNames) {
//constructor
String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants,false); //assume not null name
String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants, false); //assume not null name
parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(abc.instance_info.get(class_info).name_index), packageName, fullyQualifiedNames);
@@ -360,7 +360,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
public GraphTextWriter toString(Trait parent, String path, List<ABCContainerTag> abcTags, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
writer.startClass(class_info);
String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants,false); //assume not null name
String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants, false); //assume not null name
List<String> namesInThisPackage = new ArrayList<>();
for (ABCContainerTag tag : abcTags) {
for (ScriptInfo si : tag.getABC().script_info) {

View File

@@ -403,14 +403,14 @@ public class Action implements GraphSourceItem {
* @param version SWF version
* @param exportMode PCode or hex?
* @return source ASM
*
*
*/
public static String actionsToString(List<DisassemblyListener> listeners, long address, ActionList list, int version, ScriptExportMode exportMode) {
HilightedTextWriter writer = new HilightedTextWriter(new CodeFormatting(), false);
actionsToString(listeners, address, list, version, exportMode, writer);
return writer.toString();
}
/**
* Converts list of actions to ASM source
*

View File

@@ -190,7 +190,7 @@ public class ActionList extends ArrayList<Action> {
public String toString() {
return Action.actionsToString(new ArrayList<DisassemblyListener>(), 0, this, SWF.DEFAULT_VERSION, ScriptExportMode.PCODE);
}
public String toSource() {
try {
return Action.actionsToSource(null, this, "");

View File

@@ -28,12 +28,12 @@ import com.jpexs.decompiler.flash.action.ActionLocalData;
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
import com.jpexs.decompiler.flash.action.model.ReturnActionItem;
import com.jpexs.decompiler.flash.action.special.ActionEnd;
import com.jpexs.decompiler.flash.action.special.ActionStore;
import com.jpexs.decompiler.flash.action.swf4.ActionAdd;
import com.jpexs.decompiler.flash.action.swf4.ActionEquals;
import com.jpexs.decompiler.flash.action.swf4.ActionGetVariable;
import com.jpexs.decompiler.flash.action.swf4.ActionIf;
import com.jpexs.decompiler.flash.action.swf4.ActionJump;
import com.jpexs.decompiler.flash.action.swf4.ActionLess;
import com.jpexs.decompiler.flash.action.swf4.ActionMultiply;
import com.jpexs.decompiler.flash.action.swf4.ActionNot;
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
@@ -54,14 +54,13 @@ import com.jpexs.decompiler.flash.action.swf5.ActionDefineFunction;
import com.jpexs.decompiler.flash.action.swf5.ActionDefineLocal;
import com.jpexs.decompiler.flash.action.swf5.ActionEquals2;
import com.jpexs.decompiler.flash.action.swf5.ActionIncrement;
import com.jpexs.decompiler.flash.action.swf5.ActionLess2;
import com.jpexs.decompiler.flash.action.swf5.ActionModulo;
import com.jpexs.decompiler.flash.action.swf5.ActionPushDuplicate;
import com.jpexs.decompiler.flash.action.swf5.ActionReturn;
import com.jpexs.decompiler.flash.action.swf6.ActionGreater;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.helpers.SWFDecompilerListener;
import com.jpexs.decompiler.graph.Graph;
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateException;
import com.jpexs.decompiler.graph.TranslateStack;
@@ -80,7 +79,7 @@ import java.util.logging.Logger;
*
* @author JPEXS
*/
public class ActionDeobfuscator implements SWFDecompilerListener {
public class ActionDeobfuscator extends ActionDeobfuscatorSimple {
private final int executionLimit = 30000;
@@ -131,89 +130,6 @@ public class ActionDeobfuscator implements SWFDecompilerListener {
return true;
}
private boolean removeUnreachableActions(ActionList actions) {
Set<Action> reachableActions = new HashSet<>();
Set<Action> processedActions = new HashSet<>();
reachableActions.add(actions.get(0));
boolean modified = true;
while (modified) {
modified = false;
for (int i = 0; i < actions.size(); i++) {
Action action = actions.get(i);
if (reachableActions.contains(action) && !processedActions.contains(action)) {
if (!action.isExit() && !(action instanceof ActionJump) && i != actions.size() - 1) {
Action next = actions.get(i + 1);
if (!reachableActions.contains(next)) {
reachableActions.add(next);
}
}
if (action instanceof ActionJump) {
ActionJump aJump = (ActionJump) action;
long ref = aJump.getAddress() + aJump.getTotalActionLength() + aJump.getJumpOffset();
Action target = actions.getByAddress(ref);
if (target != null && !reachableActions.contains(target)) {
reachableActions.add(target);
}
} else if (action instanceof ActionIf) {
ActionIf aIf = (ActionIf) action;
long ref = aIf.getAddress() + aIf.getTotalActionLength() + aIf.getJumpOffset();
Action target = actions.getByAddress(ref);
if (target != null && !reachableActions.contains(target)) {
reachableActions.add(target);
}
} else if (action instanceof ActionStore) {
ActionStore aStore = (ActionStore) action;
int storeSize = aStore.getStoreSize();
if (actions.size() > i + storeSize) {
Action target = actions.get(i + storeSize);
if (!reachableActions.contains(target)) {
reachableActions.add(target);
}
}
} else if (action instanceof GraphSourceItemContainer) {
GraphSourceItemContainer container = (GraphSourceItemContainer) action;
long ref = action.getAddress() + action.getTotalActionLength();
for (Long size : container.getContainerSizes()) {
ref += size;
Action target = actions.getByAddress(ref);
if (target != null && !reachableActions.contains(target)) {
reachableActions.add(target);
}
}
}
processedActions.add(action);
modified = true;
}
}
}
boolean result = false;
for (int i = 0; i < actions.size(); i++) {
if (!reachableActions.contains(actions.get(i))) {
actions.removeAction(i);
i--;
result = true;
}
}
return result;
}
private boolean removeZeroJumps(ActionList actions) {
boolean result = false;
for (int i = 0; i < actions.size(); i++) {
Action action = actions.get(i);
if (action instanceof ActionJump && ((ActionJump) action).getJumpOffset() == 0) {
actions.removeAction(i);
i--;
result = true;
}
}
return result;
}
private boolean removeObfuscationIfs(ActionList actions, Map<String, Object> fakeFunctions) {
if (actions.size() == 0) {
return false;
@@ -303,7 +219,7 @@ public class ActionDeobfuscator implements SWFDecompilerListener {
}
return cPool;
}
private void executeActions(ActionList actions, int idx, int endIdx, ActionConstantPool constantPool, ExecutionResult result, Map<String, Object> fakeFunctions) {
List<GraphTargetItem> output = new ArrayList<>();
ActionLocalData localData = new ActionLocalData();
@@ -383,6 +299,8 @@ public class ActionDeobfuscator implements SWFDecompilerListener {
|| action instanceof ActionSetVariable
|| action instanceof ActionEquals
|| action instanceof ActionEquals2
|| action instanceof ActionLess
|| action instanceof ActionLess2
|| action instanceof ActionGreater
|| action instanceof ActionNot
|| action instanceof ActionIf

View File

@@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.ActionList;
import com.jpexs.decompiler.flash.action.ActionLocalData;
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
import com.jpexs.decompiler.flash.action.special.ActionStore;
import com.jpexs.decompiler.flash.action.swf4.ActionAdd;
import com.jpexs.decompiler.flash.action.swf4.ActionEquals;
import com.jpexs.decompiler.flash.action.swf4.ActionIf;
@@ -44,12 +45,15 @@ import com.jpexs.decompiler.flash.action.swf5.ActionPushDuplicate;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.helpers.SWFDecompilerListener;
import com.jpexs.decompiler.graph.Graph;
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateException;
import com.jpexs.decompiler.graph.TranslateStack;
import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
*
@@ -69,6 +73,9 @@ public class ActionDeobfuscatorSimple implements SWFDecompilerListener {
return false;
}
removeUnreachableActions(actions);
removeZeroJumps(actions);
for (int i = 0; i < actions.size(); i++) {
ExecutionResult result = new ExecutionResult();
executeActions(actions, i, actions.size() - 1, result);
@@ -79,7 +86,7 @@ public class ActionDeobfuscatorSimple implements SWFDecompilerListener {
newIstructionCount++;
}
if (newIstructionCount * 2 < result.instructionsProcessed) {
if (newIstructionCount + 1 < result.instructionsProcessed) {
Action target = actions.get(result.idx);
Action prevAction = actions.get(i);
@@ -99,6 +106,18 @@ public class ActionDeobfuscatorSimple implements SWFDecompilerListener {
jump.setAddress(prevAction.getAddress());
jump.setJumpOffset((int) (target.getAddress() - jump.getAddress() - jump.getTotalActionLength()));
actions.addAction(i++, jump);
Action nextAction = actions.size() > i ? actions.get(i) : null;
removeUnreachableActions(actions);
removeZeroJumps(actions);
if (nextAction != null) {
int nextIdx = actions.indexOf(nextAction);
if (nextIdx < i) {
i = nextIdx;
}
}
}
}
}
@@ -106,6 +125,89 @@ public class ActionDeobfuscatorSimple implements SWFDecompilerListener {
return false;
}
protected boolean removeUnreachableActions(ActionList actions) {
Set<Action> reachableActions = new HashSet<>();
Set<Action> processedActions = new HashSet<>();
reachableActions.add(actions.get(0));
boolean modified = true;
while (modified) {
modified = false;
for (int i = 0; i < actions.size(); i++) {
Action action = actions.get(i);
if (reachableActions.contains(action) && !processedActions.contains(action)) {
if (!action.isExit() && !(action instanceof ActionJump) && i != actions.size() - 1) {
Action next = actions.get(i + 1);
if (!reachableActions.contains(next)) {
reachableActions.add(next);
}
}
if (action instanceof ActionJump) {
ActionJump aJump = (ActionJump) action;
long ref = aJump.getAddress() + aJump.getTotalActionLength() + aJump.getJumpOffset();
Action target = actions.getByAddress(ref);
if (target != null && !reachableActions.contains(target)) {
reachableActions.add(target);
}
} else if (action instanceof ActionIf) {
ActionIf aIf = (ActionIf) action;
long ref = aIf.getAddress() + aIf.getTotalActionLength() + aIf.getJumpOffset();
Action target = actions.getByAddress(ref);
if (target != null && !reachableActions.contains(target)) {
reachableActions.add(target);
}
} else if (action instanceof ActionStore) {
ActionStore aStore = (ActionStore) action;
int storeSize = aStore.getStoreSize();
if (actions.size() > i + storeSize) {
Action target = actions.get(i + storeSize);
if (!reachableActions.contains(target)) {
reachableActions.add(target);
}
}
} else if (action instanceof GraphSourceItemContainer) {
GraphSourceItemContainer container = (GraphSourceItemContainer) action;
long ref = action.getAddress() + action.getTotalActionLength();
for (Long size : container.getContainerSizes()) {
ref += size;
Action target = actions.getByAddress(ref);
if (target != null && !reachableActions.contains(target)) {
reachableActions.add(target);
}
}
}
processedActions.add(action);
modified = true;
}
}
}
boolean result = false;
for (int i = 0; i < actions.size(); i++) {
if (!reachableActions.contains(actions.get(i))) {
actions.removeAction(i);
i--;
result = true;
}
}
return result;
}
protected boolean removeZeroJumps(ActionList actions) {
boolean result = false;
for (int i = 0; i < actions.size(); i++) {
Action action = actions.get(i);
if (action instanceof ActionJump && ((ActionJump) action).getJumpOffset() == 0) {
actions.removeAction(i);
i--;
result = true;
}
}
return result;
}
private void executeActions(ActionList actions, int idx, int endIdx, ExecutionResult result) {
List<GraphTargetItem> output = new ArrayList<>();
ActionLocalData localData = new ActionLocalData();
@@ -146,7 +248,8 @@ public class ActionDeobfuscatorSimple implements SWFDecompilerListener {
|| action instanceof ActionBitRShift
|| action instanceof ActionEquals
|| action instanceof ActionNot
|| action instanceof ActionIf)) {
|| action instanceof ActionIf
|| action instanceof ActionJump)) {
break;
}
@@ -166,6 +269,15 @@ public class ActionDeobfuscatorSimple implements SWFDecompilerListener {
idx++;
if (action instanceof ActionJump) {
ActionJump jump = (ActionJump) action;
long address = jump.getAddress() + jump.getTotalActionLength() + jump.getJumpOffset();
idx = actions.indexOf(actions.getByAddress(address));
if (idx == -1) {
throw new TranslateException("Jump target not found: " + address);
}
}
if (action instanceof ActionIf) {
ActionIf aif = (ActionIf) action;
if (EcmaScript.toBoolean(stack.pop().getResult())) {

View File

@@ -181,8 +181,8 @@ public class ActionSourceGenerator implements SourceGenerator {
private void fixLoop(List<Action> code, int breakOffset, int continueOffset) {
int pos = 0;
for (Action a : code) {
pos += a.getBytes(SWF.DEFAULT_VERSION).length;
for (Action a : code) {
pos += a.getTotalActionLength();
if (a instanceof ActionJump) {
ActionJump aj = (ActionJump) a;
if (aj.isContinue && (continueOffset != Integer.MAX_VALUE)) {

View File

@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.action.swf4;
import com.jpexs.decompiler.flash.EndOfStreamException;
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;
@@ -185,6 +186,7 @@ public class ActionPush extends Action {
super(0x96, 0);
this.values = new ArrayList<>();
this.values.add(value);
updateLength(SWF.DEFAULT_VERSION);
}
public ActionPush(FlasmLexer lexer, List<String> constantPool) throws IOException, ActionParseException {

View File

@@ -119,16 +119,16 @@ public class SoundExporter {
int nativeFormat = fmt.getNativeExportFormat();
if (nativeFormat == SoundFormat.EXPORT_MP3 && mode.hasMP3()) {
List<byte[]> datas=st.getRawSoundData();
for(byte[] data:datas){
List<byte[]> datas = st.getRawSoundData();
for (byte[] data : datas) {
fos.write(data);
}
} else if ((nativeFormat == SoundFormat.EXPORT_FLV && mode.hasFlv()) || mode == SoundExportMode.FLV) {
if (st instanceof DefineSoundTag) {
FLVOutputStream flv = new FLVOutputStream(fos);
flv.writeHeader(true, false);
List<byte[]> datas=st.getRawSoundData();
for(byte[] data:datas){
List<byte[]> datas = st.getRawSoundData();
for (byte[] data : datas) {
flv.writeTag(new FLVTAG(0, new AUDIODATA(st.getSoundFormatId(), st.getSoundRate(), st.getSoundSize(), st.getSoundType(), data)));
}
} else if (st instanceof SoundStreamHeadTypeTag) {
@@ -149,8 +149,8 @@ public class SoundExporter {
} else {
List<byte[]> soundData = st.getRawSoundData();
SWF swf = ((Tag) st).getSwf();
List<SWFInputStream> siss=new ArrayList<>();
for(byte[] data:soundData){
List<SWFInputStream> siss = new ArrayList<>();
for (byte[] data : soundData) {
siss.add(new SWFInputStream(swf, data));
}
fmt.createWav(siss, fos);

View File

@@ -37,7 +37,7 @@ import java.util.List;
* @author JPEXS
*/
public class DefineFontTag extends FontTag {
@SWFType(BasicType.UI16)
public int fontId;
public List<SHAPE> glyphShapeTable;
@@ -46,22 +46,22 @@ public class DefineFontTag extends FontTag {
@Internal
private DefineFontInfo2Tag fontInfo2Tag = null;
public static final int ID = 10;
@Override
public boolean isSmall() {
return false;
}
@Override
public double getGlyphAdvance(int glyphIndex) {
return -1;
}
@Override
public int getGlyphWidth(int glyphIndex) {
return glyphShapeTable.get(glyphIndex).getBounds().getWidth();
}
private void ensureFontInfo() {
if (fontInfoTag == null) {
for (Tag t : swf.tags) {
@@ -80,7 +80,7 @@ public class DefineFontTag extends FontTag {
}
}
}
@Override
public char glyphToChar(int glyphIndex) {
ensureFontInfo();
@@ -92,7 +92,7 @@ public class DefineFontTag extends FontTag {
return '?';
}
}
@Override
public int charToGlyph(char c) {
ensureFontInfo();
@@ -102,7 +102,7 @@ public class DefineFontTag extends FontTag {
return fontInfoTag.codeTable.indexOf((int) c);
}
return -1;
}
/**
@@ -147,7 +147,7 @@ public class DefineFontTag extends FontTag {
int firstOffset = sis.readUI16("firstOffset");
int nGlyphs = firstOffset / 2;
glyphShapeTable = new ArrayList<>();
for (int i = 1; i < nGlyphs; i++) {
sis.readUI16("offset"); //offset
}
@@ -155,22 +155,22 @@ public class DefineFontTag extends FontTag {
glyphShapeTable.add(sis.readSHAPE(1, false, "shape"));
}
}
@Override
public int getFontId() {
return fontId;
}
@Override
public List<SHAPE> getGlyphShapeTable() {
return glyphShapeTable;
}
@Override
public int getCharacterId() {
return fontId;
}
@Override
public String getFontName() {
ensureFontInfo();
@@ -182,7 +182,7 @@ public class DefineFontTag extends FontTag {
}
return null;
}
@Override
public boolean isBold() {
if (fontInfo2Tag != null) {
@@ -193,7 +193,7 @@ public class DefineFontTag extends FontTag {
}
return false;
}
@Override
public boolean isItalic() {
if (fontInfo2Tag != null) {
@@ -204,26 +204,26 @@ public class DefineFontTag extends FontTag {
}
return false;
}
@Override
public boolean isSmallEditable() {
return false;
}
@Override
public boolean isBoldEditable() {
return fontInfo2Tag != null || fontInfoTag != null;
}
@Override
public boolean isItalicEditable() {
return fontInfo2Tag != null || fontInfoTag != null;
}
@Override
public void setSmall(boolean value) {
}
@Override
public void setBold(boolean value) {
if (fontInfo2Tag != null) {
@@ -233,7 +233,7 @@ public class DefineFontTag extends FontTag {
fontInfoTag.fontFlagsBold = value;
}
}
@Override
public void setItalic(boolean value) {
if (fontInfo2Tag != null) {
@@ -243,27 +243,27 @@ public class DefineFontTag extends FontTag {
fontInfoTag.fontFlagsItalic = value;
}
}
@Override
public int getAscent() {
return -1;
}
@Override
public int getDescent() {
return -1;
}
@Override
public int getLeading() {
return -1;
}
@Override
public int getDivider() {
return 1;
}
@Override
public void addCharacter(char character, String fontName) {
SHAPE shp = SHAPERECORD.systemFontCharacterToSHAPE(fontName, getFontStyle(), getDivider() * 1024, character);
@@ -297,10 +297,10 @@ public class DefineFontTag extends FontTag {
} else {
glyphShapeTable.set(pos, shp);
}
setModified(true);
}
@Override
public String getCharacters(List<Tag> tags) {
String ret = "";
@@ -317,7 +317,7 @@ public class DefineFontTag extends FontTag {
}
return ret;
}
@Override
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
return 0;

View File

@@ -307,7 +307,7 @@ public class DefineSoundTag extends CharacterTag implements SoundTag {
@Override
public List<byte[]> getRawSoundData() {
List<byte[]> ret=new ArrayList<byte[]>();
List<byte[]> ret = new ArrayList<>();
if (soundFormat == SoundFormat.FORMAT_MP3) {
ret.add(Arrays.copyOfRange(soundData, 2, soundData.length));
return ret;

View File

@@ -182,7 +182,7 @@ public class SoundStreamHead2Tag extends CharacterIdTag implements SoundStreamHe
@Override
public List<SoundStreamBlockTag> getBlocks() {
List<SoundStreamBlockTag> ret = new ArrayList<>();
SoundStreamHeadTag.populateSoundStreamBlocks(0,swf.tags, this, ret);
SoundStreamHeadTag.populateSoundStreamBlocks(0, swf.tags, this, ret);
return ret;
}
@@ -199,7 +199,7 @@ public class SoundStreamHead2Tag extends CharacterIdTag implements SoundStreamHe
@Override
public List<byte[]> getRawSoundData() {
List<byte[]> ret = new ArrayList<byte[]>();
List<byte[]> ret = new ArrayList<>();
List<SoundStreamBlockTag> blocks = getBlocks();
for (SoundStreamBlockTag block : blocks) {
if (streamSoundCompression == SoundFormat.FORMAT_MP3) {

View File

@@ -172,16 +172,16 @@ public class SoundStreamHeadTag extends CharacterIdTag implements SoundStreamHea
return streamSoundType;
}
public static void populateSoundStreamBlocks(int containerId,List<? extends ContainerItem> tags, Tag head, List<SoundStreamBlockTag> output) {
public static void populateSoundStreamBlocks(int containerId, List<? extends ContainerItem> tags, Tag head, List<SoundStreamBlockTag> output) {
boolean found = false;
for (ContainerItem t : tags) {
if (t == head) {
found = true;
((SoundStreamHeadTypeTag)head).setVirtualCharacterId(containerId);
((SoundStreamHeadTypeTag) head).setVirtualCharacterId(containerId);
continue;
}
if (t instanceof Container) {
populateSoundStreamBlocks(((CharacterIdTag)t).getCharacterId(),((Container) t).getSubItems(), head, output);
populateSoundStreamBlocks(((CharacterIdTag) t).getCharacterId(), ((Container) t).getSubItems(), head, output);
}
if (!found) {
continue;
@@ -198,7 +198,7 @@ public class SoundStreamHeadTag extends CharacterIdTag implements SoundStreamHea
@Override
public List<SoundStreamBlockTag> getBlocks() {
List<SoundStreamBlockTag> ret = new ArrayList<>();
populateSoundStreamBlocks(0,swf.tags, this, ret);
populateSoundStreamBlocks(0, swf.tags, this, ret);
return ret;
}
@@ -215,7 +215,7 @@ public class SoundStreamHeadTag extends CharacterIdTag implements SoundStreamHea
@Override
public List<byte[]> getRawSoundData() {
List<byte[]> ret = new ArrayList<byte[]>();
List<byte[]> ret = new ArrayList<>();
List<SoundStreamBlockTag> blocks = getBlocks();
for (SoundStreamBlockTag block : blocks) {
if (streamSoundCompression == SoundFormat.FORMAT_MP3) {

View File

@@ -43,7 +43,6 @@ import java.awt.font.FontRenderContext;
import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.geom.Area;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -174,7 +173,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
} else if (t instanceof DefineText2Tag) {
textRecords = ((DefineText2Tag) t).textRecords;
}
if (textRecords != null) {
int curFontId = 0;
for (TEXTRECORD tr : textRecords) {
@@ -192,7 +191,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
en.glyphIndex++;
}
}
t.setModified(true);
}
}

View File

@@ -166,7 +166,7 @@ public class SoundFormat {
public boolean createWav(List<SWFInputStream> siss, OutputStream os) {
ensureFormat();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for(SWFInputStream sis:siss){
for (SWFInputStream sis : siss) {
decode(sis, baos);
}
try {