AS3: New P-code editing syntax inspired by RABCDAsm.

AS3: Multiname and namespace editing.
AS3: Editing whole trait in one textarea
AS3: Removed messages about adding new constants
AS3: Modified colors in editor
AS3: Highlighting pair parenthesis/bracket
AS3: Editing various new P-code parameters
This commit is contained in:
Jindra Pet��k
2013-09-14 18:57:08 +02:00
parent 71d3ba4425
commit c777e82980
76 changed files with 4592 additions and 1054 deletions
+2 -2
View File
@@ -82,8 +82,8 @@ public abstract class CacheEntry {
public String getHeader(String header) {
Map<String, String> m = getResponseHeaders();
if(m == null){
return null;
if (m == null) {
return null;
}
for (String k : m.keySet()) {
if (k.toLowerCase().equals(header.toLowerCase())) {
+11 -13
View File
@@ -9,8 +9,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
@@ -49,17 +47,17 @@ public class Index {
public Index(File file, File externalFilesDir) throws IOException {
dataFiles = new HashMap<>();
this.externalFilesDir = externalFilesDir;
FileInputStream is = new FileInputStream(file);
rootDir = file.getParentFile();
header = new IndexHeader(is, rootDir, dataFiles, externalFilesDir);
int tsize = kIndexTablesize;
if (header.table_len > 0) {
tsize = header.table_len;
try (FileInputStream is = new FileInputStream(file)) {
rootDir = file.getParentFile();
header = new IndexHeader(is, rootDir, dataFiles, externalFilesDir);
int tsize = kIndexTablesize;
if (header.table_len > 0) {
tsize = header.table_len;
}
table = new CacheAddr[tsize];
for (int i = 0; i < tsize; i++) {
table[i] = new CacheAddr(is, rootDir, dataFiles, externalFilesDir);
}
}
table = new CacheAddr[tsize];
for (int i = 0; i < tsize; i++) {
table[i] = new CacheAddr(is, rootDir, dataFiles, externalFilesDir);
}
is.close();
}
}
@@ -34,7 +34,7 @@ public class FirefoxCache implements CacheImplementation {
@Override
public void refresh() {
File dir = getCacheDirectory();
if(dir==null){
if (dir == null) {
return;
}
File cacheMapFile = new File(dir, "_CACHE_MAP_");
@@ -108,10 +108,10 @@ public class FirefoxCache implements CacheImplementation {
if (profileDir != null) {
cacheDir = new File(profileDir, "Cache");
}
if(cacheDir == null){
if (cacheDir == null) {
return null;
}
if(!cacheDir.exists()){
if (!cacheDir.exists()) {
return null;
}
return cacheDir;
@@ -22,8 +22,7 @@ package com.jpexs.browsers.cache.firefox;
*/
public class IncompatibleVersionException extends Exception {
public IncompatibleVersionException(int version) {
super("Incompatible version: "+version);
}
public IncompatibleVersionException(int version) {
super("Incompatible version: " + version);
}
}
+3 -4
View File
@@ -38,8 +38,7 @@ public class MapBucket extends CacheEntry {
if (metadata == null) {
try {
metadata = new MetaData(getMetaDataStream());
}catch(IncompatibleVersionException ie){
} catch (IncompatibleVersionException ie) {
} catch (IOException ex) {
Logger.getLogger(MapBucket.class.getName()).log(Level.SEVERE, null, ex);
}
@@ -71,8 +70,8 @@ public class MapBucket extends CacheEntry {
return null;
}
String responseHead = m.response.get("response-head");
if(responseHead==null){
return null;
if (responseHead == null) {
return null;
}
String headers[] = responseHead.split("\r\n");
Map<String, String> ret = new HashMap<>();
+2 -2
View File
@@ -27,8 +27,8 @@ public class MetaData {
public MetaData(InputStream is) throws IOException, IncompatibleVersionException {
CacheInputStream cis = new CacheInputStream(is);
majorVersion = cis.readInt16();
if(majorVersion!=1){
throw new IncompatibleVersionException(majorVersion);
if (majorVersion != 1) {
throw new IncompatibleVersionException(majorVersion);
}
minorVersion = cis.readInt16();
location = cis.readInt32();
@@ -528,7 +528,7 @@ public class SWFInputStream extends InputStream {
}
public List<Action> readActionList(List<DisassemblyListener> listeners, long containerSWFOffset, ReReadableInputStream rri, int maxlen, String path) throws IOException {
return ActionListReader.readActionList(listeners, containerSWFOffset, rri, version, (int)rri.getPos(), (int)rri.getPos() + maxlen, path);
return ActionListReader.readActionList(listeners, containerSWFOffset, rri, version, (int) rri.getPos(), (int) rri.getPos() + maxlen, path);
}
private static void dumpTag(PrintStream out, int version, Tag tag, int level) {
@@ -88,14 +88,14 @@ public class ABC {
public int removeDeadCode() {
int rem = 0;
for (MethodBody body : bodies) {
rem += body.removeDeadCode(constants);
rem += body.removeDeadCode(constants, null/*FIXME*/, method_info[body.method_info]);
}
return rem;
}
public void restoreControlFlow() {
for (MethodBody body : bodies) {
body.restoreControlFlow(constants);
body.restoreControlFlow(constants, null/*FIXME*/, method_info[body.method_info]);
}
}
@@ -65,7 +65,10 @@ import com.jpexs.decompiler.flash.abc.types.ABCException;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.ValueKind;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction;
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
@@ -715,19 +718,147 @@ public class AVM2Code implements Serializable {
return s.toString();
}
public String toASMSource(ConstantPool constants, MethodBody body, boolean hex, boolean highlight) {
return toASMSource(constants, body, new ArrayList<Integer>(), hex, highlight);
public String toASMSource(ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, boolean hex, boolean highlight) {
return toASMSource(constants, trait, info, body, new ArrayList<Integer>(), hex, highlight);
}
public String toASMSource(ConstantPool constants, MethodBody body, List<Integer> outputMap, boolean hex, boolean highlight) {
public String toASMSource(ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, List<Integer> outputMap, boolean hex, boolean highlight) {
invalidateCache();
StringBuilder ret = new StringBuilder();
String t = "";
for (int e = 0; e < body.exceptions.length; e++) {
ret.append("exception " + e + " m[" + body.exceptions[e].name_index + "]\"" + Helper.escapeString(body.exceptions[e].getVarName(constants, new ArrayList<String>())) + "\" "
+ "m[" + body.exceptions[e].type_index + "]\"" + Helper.escapeString(body.exceptions[e].getTypeName(constants, new ArrayList<String>())) + "\"\n");
if (trait != null) {
if (trait instanceof TraitFunction) {
TraitFunction tf = (TraitFunction) trait;
ret.append("trait function ");
ret.append(constants.multinameToString(tf.name_index));
ret.append(" slotid ");
ret.append(tf.slot_index);
ret.append("\n");
}
if (trait instanceof TraitMethodGetterSetter) {
TraitMethodGetterSetter tm = (TraitMethodGetterSetter) trait;
ret.append("trait ");
switch (tm.kindType) {
case Trait.TRAIT_METHOD:
ret.append("method ");
break;
case Trait.TRAIT_GETTER:
ret.append("getter ");
break;
case Trait.TRAIT_SETTER:
ret.append("setter ");
break;
}
ret.append(constants.multinameToString(tm.name_index));
ret.append(" dispid ");
ret.append(tm.disp_id);
ret.append("\n");
}
}
if (info != null) {
ret.append("method\n");
ret.append("name ");
ret.append(info.name_index == 0 ? "null" : "\"" + Helper.escapeString(info.getName(constants)) + "\"");
ret.append("\n");
if (info.flagExplicit()) {
ret.append("flag EXPLICIT\n");
}
if (info.flagHas_optional()) {
ret.append("flag HAS_OPTIONAL\n");
}
if (info.flagHas_paramnames()) {
ret.append("flag HAS_PARAM_NAMES\n");
}
if (info.flagIgnore_rest()) {
ret.append("flag IGNORE_REST\n");
}
if (info.flagNeed_activation()) {
ret.append("flag NEED_ACTIVATION\n");
}
if (info.flagNeed_arguments()) {
ret.append("flag NEED_ARGUMENTS\n");
}
if (info.flagNeed_rest()) {
ret.append("flag NEED_REST\n");
}
if (info.flagSetsdxns()) {
ret.append("flag SET_DXNS\n");
}
for (int p : info.param_types) {
ret.append("param ");
ret.append(constants.multinameToString(p));
ret.append("\n");
}
if (info.flagHas_paramnames()) {
for (int n : info.paramNames) {
ret.append("paramname ");
ret.append("\"");
ret.append(constants.constant_string[n]);
ret.append("\"");
ret.append("\n");
}
}
if (info.flagHas_optional()) {
for (ValueKind vk : info.optional) {
ret.append("optional ");
ret.append(vk.toString(constants));
ret.append("\n");
}
}
ret.append("returns ");
ret.append(constants.multinameToString(info.ret_type));
ret.append("\n");
}
ret.append("\n");
ret.append("body\n");
ret.append("maxstack ");
ret.append(body.max_stack);
ret.append("\n");
ret.append("localcount ");
ret.append(body.max_regs);
ret.append("\n");
ret.append("initscopedepth ");
ret.append(body.init_scope_depth);
ret.append("\n");
ret.append("maxscopedepth ");
ret.append(body.max_scope_depth);
ret.append("\n");
List<Long> offsets = new ArrayList<>();
for (int e = 0; e < body.exceptions.length; e++) {
ret.append("try");
ret.append(" from ");
ret.append("ofs");
ret.append(Helper.formatAddress(body.exceptions[e].start));
offsets.add((long) body.exceptions[e].start);
ret.append(" to ");
ret.append("ofs");
ret.append(Helper.formatAddress(body.exceptions[e].end));
offsets.add((long) body.exceptions[e].end);
ret.append(" target ");
ret.append("ofs");
ret.append(Helper.formatAddress(body.exceptions[e].target));
offsets.add((long) body.exceptions[e].target);
ret.append(" type ");
ret.append(body.exceptions[e].type_index == 0 ? "null" : constants.constant_multiname[body.exceptions[e].type_index].toString(constants, new ArrayList<String>()));
ret.append(" name ");
ret.append(body.exceptions[e].name_index == 0 ? "null" : constants.constant_multiname[body.exceptions[e].name_index].toString(constants, new ArrayList<String>()));
ret.append("\n");
}
ret.append("\n");
ret.append("code\n");
for (AVM2Instruction ins : code) {
offsets.addAll(ins.getOffsets());
}
@@ -758,17 +889,17 @@ public class AVM2Code implements Serializable {
} else if (offsets.contains(ofs)) {
ret.append("ofs" + Helper.formatAddress(ofs) + ":");
}
for (int e = 0; e < body.exceptions.length; e++) {
if (body.exceptions[e].start == ofs) {
ret.append("exceptionstart " + e + ":");
}
if (body.exceptions[e].end == ofs) {
ret.append("exceptionend " + e + ":");
}
if (body.exceptions[e].target == ofs) {
ret.append("exceptiontarget " + e + ":");
}
}
/*for (int e = 0; e < body.exceptions.length; e++) {
if (body.exceptions[e].start == ofs) {
ret.append("exceptionstart " + e + ":");
}
if (body.exceptions[e].end == ofs) {
ret.append("exceptionend " + e + ":");
}
if (body.exceptions[e].target == ofs) {
ret.append("exceptiontarget " + e + ":");
}
}*/
if (ins.replaceWith != null) {
for (Object o : ins.replaceWith) {
if (o instanceof Integer) {
@@ -1519,8 +1650,8 @@ public class AVM2Code implements Serializable {
return ret;
}
public int removeTraps(ConstantPool constants, MethodBody body, ABC abc, int scriptIndex, int classIndex, boolean isStatic, String path) {
removeDeadCode(constants, body);
public int removeTraps(ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, ABC abc, int scriptIndex, int classIndex, boolean isStatic, String path) {
removeDeadCode(constants, trait, info, body);
List<Object> localData = new ArrayList<>();
localData.add((Boolean) isStatic); //isStatic
localData.add((Integer) (classIndex)); //classIndex
@@ -1542,9 +1673,9 @@ public class AVM2Code implements Serializable {
localData.add(refs);
localData.add(this);
int ret = 0;
ret += removeTraps(constants, body, localData, new AVM2GraphSource(this, false, -1, -1, new HashMap<Integer, GraphTargetItem>(), new Stack<GraphTargetItem>(), abc, body, new HashMap<Integer, String>(), new ArrayList<String>(), new HashMap<Integer, Integer>(), refs), 0, path, refs);
removeIgnored(constants, body);
removeDeadCode(constants, body);
ret += removeTraps(constants, trait, info, body, localData, new AVM2GraphSource(this, false, -1, -1, new HashMap<Integer, GraphTargetItem>(), new Stack<GraphTargetItem>(), abc, body, new HashMap<Integer, String>(), new ArrayList<String>(), new HashMap<Integer, Integer>(), refs), 0, path, refs);
removeIgnored(constants, trait, info, body);
removeDeadCode(constants, trait, info, body);
return ret;
}
@@ -1927,7 +2058,7 @@ public class AVM2Code implements Serializable {
}
private void restoreControlFlowPass(ConstantPool constants, MethodBody body, boolean secondpass) {
private void restoreControlFlowPass(ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, boolean secondpass) {
try {
HashMap<Integer, List<Integer>> refs;
int[] visited2 = new int[code.size()];
@@ -1956,9 +2087,9 @@ public class AVM2Code implements Serializable {
invalidateCache();
try {
List<Integer> outputMap = new ArrayList<>();
String src = toASMSource(constants, body, outputMap, false, false);
String src = toASMSource(constants, trait, info, body, outputMap, false, false);
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(src.getBytes("UTF-8")), constants, null, body);
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(src.getBytes("UTF-8")), constants, null, body, info);
for (int i = 0; i < acode.code.size(); i++) {
if (outputMap.size() > i) {
int tpos = outputMap.get(i);
@@ -1978,11 +2109,11 @@ public class AVM2Code implements Serializable {
Logger.getLogger(AVM2Code.class.getName()).log(Level.FINE, null, ex);
}
invalidateCache();
removeDeadCode(constants, body);
removeDeadCode(constants, trait, info, body);
}
public void restoreControlFlow(ConstantPool constants, MethodBody body) {
restoreControlFlowPass(constants, body, false);
public void restoreControlFlow(ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) {
restoreControlFlowPass(constants, trait, info, body, false);
//restoreControlFlowPass(constants, body, true);
}
@@ -1993,11 +2124,11 @@ public class AVM2Code implements Serializable {
}
}
}*/
public void removeIgnored(ConstantPool constants, MethodBody body) {
public void removeIgnored(ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) {
try {
List<Integer> outputMap = new ArrayList<>();
String src = toASMSource(constants, body, outputMap, false, false);
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(src.getBytes("UTF-8")), constants, body);
String src = toASMSource(constants, trait, info, body, outputMap, false, false);
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(src.getBytes("UTF-8")), constants, trait, body, info);
for (int i = 0; i < acode.code.size(); i++) {
if (outputMap.size() > i) {
int tpos = outputMap.get(i);
@@ -2015,7 +2146,7 @@ public class AVM2Code implements Serializable {
invalidateCache();
}
public int removeDeadCode(ConstantPool constants, MethodBody body) {
public int removeDeadCode(ConstantPool constants, Trait trait, MethodInfo info, MethodBody body) {
HashMap<Integer, List<Integer>> refs = visitCode(body);
int cnt = 0;
@@ -2027,7 +2158,7 @@ public class AVM2Code implements Serializable {
}
}
removeIgnored(constants, body);
removeIgnored(constants, trait, info, body);
for (int i = code.size() - 1; i >= 0; i--) {
AVM2Instruction ins = code.get(i);
if (ins.definition instanceof JumpIns) {
@@ -2038,7 +2169,7 @@ public class AVM2Code implements Serializable {
}
}
}
removeIgnored(constants, body);
removeIgnored(constants, trait, info, body);
return cnt;
}
@@ -2476,7 +2607,7 @@ public class AVM2Code implements Serializable {
return ret;
}
public static int removeTraps(ConstantPool constants, MethodBody body, List<Object> localData, AVM2GraphSource code, int addr, String path, HashMap<Integer, List<Integer>> refs) {
public static int removeTraps(ConstantPool constants, Trait trait, MethodInfo info, 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);
int cnt = 0;
@@ -2503,7 +2634,7 @@ public class AVM2Code implements Serializable {
}
}
//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);
code.getCode().removeIgnored(constants, trait, info, body);
return cnt;
}
/*public static int removeTraps(List<Object> localData, AVM2GraphSource code, int addr) {
@@ -46,6 +46,24 @@ public class ConstantPool {
return constant_int.length - 1;
}
public int addNamespace(Namespace ns) {
constant_namespace = Arrays.copyOf(constant_namespace, constant_namespace.length + 1);
constant_namespace[constant_namespace.length - 1] = ns;
return constant_namespace.length - 1;
}
public int addNamespaceSet(NamespaceSet nss) {
constant_namespace_set = Arrays.copyOf(constant_namespace_set, constant_namespace_set.length + 1);
constant_namespace_set[constant_namespace_set.length - 1] = nss;
return constant_namespace_set.length - 1;
}
public int addMultiname(Multiname m) {
constant_multiname = Arrays.copyOf(constant_multiname, constant_multiname.length + 1);
constant_multiname[constant_multiname.length - 1] = m;
return constant_multiname.length - 1;
}
public int addUInt(long value) {
constant_uint = Arrays.copyOf(constant_uint, constant_uint.length + 1);
constant_uint[constant_uint.length - 1] = value;
@@ -164,4 +182,25 @@ public class ConstantPool {
output.println("Multiname[" + i + "]=" + constant_multiname[i].toString(this, new ArrayList<String>()));
}
}
public String multinameToString(int index) {
if (index == 0) {
return "null";
}
return constant_multiname[index].toString(this, new ArrayList<String>());
}
public String namespaceToString(int index) {
if (index == 0) {
return "null";
}
return constant_namespace[index].toString(this);
}
public String namespaceSetToString(int index) {
if (index == 0) {
return "null";
}
return constant_namespace_set[index].toString(this);
}
}
@@ -171,15 +171,21 @@ public class AVM2Instruction implements Serializable, GraphSourceItem {
for (int i = 0; i < definition.operands.length; i++) {
switch (definition.operands[i]) {
case AVM2Code.DAT_MULTINAME_INDEX:
s.append(" m[");
s.append(operands[i]);
s.append("]\"");
if (constants.constant_multiname[operands[i]] == null) {
s.append("");
if (operands[i] == 0) {
s.append(" null");
} else {
s.append(Helper.escapeString(constants.constant_multiname[operands[i]].toString(constants, fullyQualifiedNames)));
s.append(" ");
s.append(constants.constant_multiname[operands[i]].toString(constants, fullyQualifiedNames));
}
s.append("\"");
/*s.append(" m[");
s.append(operands[i]);
s.append("]\"");
if (constants.constant_multiname[operands[i]] == null) {
s.append("");
} else {
s.append(Helper.escapeString(constants.constant_multiname[operands[i]].toString(constants, fullyQualifiedNames)));
}
s.append("\"");*/
break;
case AVM2Code.DAT_STRING_INDEX:
s.append(" \"");
@@ -46,7 +46,7 @@ public class NewFunctionIns extends InstructionDefinition {
String paramStr = "";
if (mybody != null) {
try {
bodyStr = Highlighting.hilighMethodEnd() + mybody.toString(path + "/inner", false, isStatic, scriptIndex, classIndex, abc, constants, method_info, new Stack<GraphTargetItem>()/*scopeStack*/, false, true, false, fullyQualifiedNames, null) + Highlighting.hilighMethodBegin(body.method_info);
bodyStr = Highlighting.hilighMethodEnd() + mybody.toString(path + "/inner", false, isStatic, scriptIndex, classIndex, abc, null, constants, method_info, new Stack<GraphTargetItem>()/*scopeStack*/, false, true, false, fullyQualifiedNames, null) + Highlighting.hilighMethodBegin(body.method_info);
} catch (Exception ex) {
Logger.getLogger(NewFunctionIns.class.getName()).log(Level.SEVERE, "error during newfunction", ex);
}
@@ -23,12 +23,25 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.DeobfuscatePopIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.types.ABCException;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.abc.types.NamespaceSet;
import com.jpexs.decompiler.flash.abc.types.ValueKind;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction;
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ASM3Parser {
@@ -63,8 +76,8 @@ public class ASM3Parser {
}
}
public static AVM2Code parse(InputStream is, ConstantPool constants, MethodBody body) throws IOException, ParseException {
return parse(is, constants, null, body);
public static AVM2Code parse(InputStream is, ConstantPool constants, Trait trait, MethodBody body, MethodInfo info) throws IOException, ParseException {
return parse(is, constants, trait, null, body, info);
}
private static int checkMultinameIndex(ConstantPool constants, int index, int line) throws ParseException {
@@ -74,7 +87,390 @@ public class ASM3Parser {
return index;
}
public static AVM2Code parse(InputStream is, ConstantPool constants, MissingSymbolHandler missingHandler, MethodBody body) throws IOException, ParseException {
private static void expected(int type, String expStr, Flasm3Lexer lexer) throws IOException, ParseException {
ParsedSymbol s = lexer.lex();
if (s.type != type) {
throw new ParseException(expStr + " expected", lexer.yyline());
}
}
private static void expected(ParsedSymbol s, int type, String expStr) throws IOException, ParseException {
if (s.type != type) {
throw new ParseException(expStr + " expected", 0);
}
}
public static boolean parseSlotConst(InputStream is, ConstantPool constants, TraitSlotConst tsc) throws IOException, ParseException {
Flasm3Lexer lexer = null;
try {
lexer = new Flasm3Lexer(new InputStreamReader(is, "UTF-8"));
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(ASM3Parser.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
expected(ParsedSymbol.TYPE_KEYWORD_TRAIT, "trait", lexer);
int name_index = parseMultiName(constants, lexer);
ParsedSymbol symb = lexer.lex();
int flags = 0;
while (symb.type == ParsedSymbol.TYPE_KEYWORD_FLAG) {
symb = lexer.lex();
switch (symb.type) {
case ParsedSymbol.TYPE_KEYWORD_FINAL:
flags |= Trait.ATTR_Final;
break;
case ParsedSymbol.TYPE_KEYWORD_OVERRIDE:
flags |= Trait.ATTR_Override;
break;
case ParsedSymbol.TYPE_KEYWORD_METADATA:
flags |= Trait.ATTR_Metadata;
break;
default:
throw new ParseException("Invalid trait flag", lexer.yyline());
}
symb = lexer.lex();
}
switch (symb.type) {
case ParsedSymbol.TYPE_KEYWORD_SLOT:
case ParsedSymbol.TYPE_KEYWORD_CONST:
expected(ParsedSymbol.TYPE_KEYWORD_SLOTID, "slotid", lexer);
symb = lexer.lex();
expected(symb, ParsedSymbol.TYPE_INTEGER, "Integer");
int slotid = (int) (long) (Long) symb.value;
expected(ParsedSymbol.TYPE_KEYWORD_TYPE, "type", lexer);
int type = parseMultiName(constants, lexer);
expected(ParsedSymbol.TYPE_KEYWORD_VALUE, "value", lexer);
ValueKind val = parseValue(constants, lexer);
tsc.slot_id = slotid;
tsc.type_index = type;
tsc.value_kind = val.value_kind;
tsc.value_index = val.value_index;
tsc.kindFlags = flags;
break;
/*case ParsedSymbol.TYPE_KEYWORD_CLASS:
break;
case ParsedSymbol.TYPE_KEYWORD_FUNCTION:
break;
case ParsedSymbol.TYPE_KEYWORD_METHOD:
case ParsedSymbol.TYPE_KEYWORD_GETTER:
case ParsedSymbol.TYPE_KEYWORD_SETTER:
break;*/
default:
throw new ParseException("Unexpected trait type", lexer.yyline());
}
tsc.name_index = name_index;
return true;
}
private static int parseNamespaceSet(ConstantPool constants, Flasm3Lexer lexer) throws ParseException, IOException {
List<Integer> namespaceList = new ArrayList<>();
ParsedSymbol s = lexer.lex();
if (s.type == ParsedSymbol.TYPE_KEYWORD_NULL) {
return 0;
}
expected(s, ParsedSymbol.TYPE_BRACKET_OPEN, "[");
s = lexer.lex();
if (s.type != ParsedSymbol.TYPE_BRACKET_CLOSE) {
lexer.pushback(s);
do {
namespaceList.add(parseNamespace(constants, lexer));
s = lexer.lex();
} while (s.type == ParsedSymbol.TYPE_COMMA);
expected(s, ParsedSymbol.TYPE_BRACKET_CLOSE, "]");
}
loopn:
for (int n = 1; n < constants.constant_namespace_set.length; n++) {
int nss[] = constants.constant_namespace_set[n].namespaces;
if (nss.length != namespaceList.size()) {
continue;
}
for (int i = 0; i < nss.length; i++) {
if (nss[i] != namespaceList.get(i)) {
continue loopn;
}
}
return n;
}
int nss[] = new int[namespaceList.size()];
for (int i = 0; i < nss.length; i++) {
nss[i] = namespaceList.get(i);
}
return constants.addNamespaceSet(new NamespaceSet(nss));
}
private static int parseNamespace(ConstantPool constants, Flasm3Lexer lexer) throws ParseException, IOException {
ParsedSymbol type = lexer.lex();
int kind = 0;
switch (type.type) {
case ParsedSymbol.TYPE_KEYWORD_NULL:
return 0;
case ParsedSymbol.TYPE_KEYWORD_NAMESPACE:
kind = Namespace.KIND_NAMESPACE;
break;
case ParsedSymbol.TYPE_KEYWORD_PRIVATENAMESPACE:
kind = Namespace.KIND_PRIVATE;
break;
case ParsedSymbol.TYPE_KEYWORD_PACKAGENAMESPACE:
kind = Namespace.KIND_PACKAGE;
break;
case ParsedSymbol.TYPE_KEYWORD_PACKAGEINTERNALNS:
kind = Namespace.KIND_PACKAGE_INTERNAL;
break;
case ParsedSymbol.TYPE_KEYWORD_PROTECTEDNAMESPACE:
kind = Namespace.KIND_PROTECTED;
break;
case ParsedSymbol.TYPE_KEYWORD_EXPLICITNAMESPACE:
kind = Namespace.KIND_EXPLICIT;
break;
case ParsedSymbol.TYPE_KEYWORD_STATICPROTECTEDNS:
kind = Namespace.KIND_STATIC_PROTECTED;
break;
default:
throw new ParseException("Namespace kind expected", lexer.yyline());
}
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
ParsedSymbol name = lexer.lex();
expected(name, ParsedSymbol.TYPE_STRING, "String");
ParsedSymbol c = lexer.lex();
int index = 0;
if (c.type == ParsedSymbol.TYPE_COMMA) {
ParsedSymbol extra = lexer.lex();
expected(name, ParsedSymbol.TYPE_STRING, "String");
try {
index = Integer.parseInt((String) extra.value);
} catch (NumberFormatException nfe) {
throw new ParseException("Number expected", lexer.yyline());
}
} else {
lexer.pushback(c);
}
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
for (int n = 1; n < constants.constant_namespace.length; n++) {
Namespace ns = constants.constant_namespace[n];
if (ns.getName(constants).equals(name.value) && (ns.kind == kind)) {
if (index == 0) {
return n;
}
index--;
}
}
return constants.addNamespace(new Namespace(kind, constants.forceGetStringId((String) name.value)));
}
private static int parseMultiName(ConstantPool constants, Flasm3Lexer lexer) throws ParseException, IOException {
ParsedSymbol s = lexer.lex();
int kind = 0;
int name_index = -1;
int namespace_index = -1;
int namespace_set_index = -1;
int qname_index = -1;
List<Integer> params = new ArrayList<>();
switch (s.type) {
case ParsedSymbol.TYPE_KEYWORD_NULL:
return 0;
case ParsedSymbol.TYPE_KEYWORD_QNAME:
kind = Multiname.QNAME;
break;
case ParsedSymbol.TYPE_KEYWORD_QNAMEA:
kind = Multiname.QNAMEA;
break;
case ParsedSymbol.TYPE_KEYWORD_RTQNAME:
kind = Multiname.RTQNAME;
break;
case ParsedSymbol.TYPE_KEYWORD_RTQNAMEA:
kind = Multiname.RTQNAMEA;
break;
case ParsedSymbol.TYPE_KEYWORD_RTQNAMEL:
kind = Multiname.RTQNAMEL;
break;
case ParsedSymbol.TYPE_KEYWORD_RTQNAMELA:
kind = Multiname.RTQNAMELA;
break;
case ParsedSymbol.TYPE_KEYWORD_MULTINAME:
kind = Multiname.MULTINAME;
break;
case ParsedSymbol.TYPE_KEYWORD_MULTINAMEA:
kind = Multiname.MULTINAMEA;
break;
case ParsedSymbol.TYPE_KEYWORD_MULTINAMEL:
kind = Multiname.MULTINAMEL;
break;
case ParsedSymbol.TYPE_KEYWORD_MULTINAMELA:
kind = Multiname.MULTINAMELA;
break;
case ParsedSymbol.TYPE_KEYWORD_TYPENAME:
kind = Multiname.TYPENAME;
break;
default:
throw new ParseException("Name expected", lexer.yyline());
}
switch (s.type) {
case ParsedSymbol.TYPE_KEYWORD_QNAME:
case ParsedSymbol.TYPE_KEYWORD_QNAMEA:
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
namespace_index = parseNamespace(constants, lexer);
expected(ParsedSymbol.TYPE_COMMA, ",", lexer);
ParsedSymbol name = lexer.lex();
expected(name, ParsedSymbol.TYPE_STRING, "String");
name_index = constants.forceGetStringId((String) name.value);
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
break;
case ParsedSymbol.TYPE_KEYWORD_RTQNAME:
case ParsedSymbol.TYPE_KEYWORD_RTQNAMEA:
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
ParsedSymbol rtqName = lexer.lex();
expected(rtqName, ParsedSymbol.TYPE_STRING, "String");
name_index = constants.forceGetStringId((String) rtqName.value);
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
break;
case ParsedSymbol.TYPE_KEYWORD_RTQNAMEL:
case ParsedSymbol.TYPE_KEYWORD_RTQNAMELA:
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
break;
case ParsedSymbol.TYPE_KEYWORD_MULTINAME:
case ParsedSymbol.TYPE_KEYWORD_MULTINAMEA:
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
ParsedSymbol mName = lexer.lex();
expected(mName, ParsedSymbol.TYPE_STRING, "String");
name_index = constants.forceGetStringId((String) mName.value);
expected(ParsedSymbol.TYPE_COMMA, ",", lexer);
namespace_set_index = parseNamespaceSet(constants, lexer);
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
break;
case ParsedSymbol.TYPE_KEYWORD_MULTINAMEL:
case ParsedSymbol.TYPE_KEYWORD_MULTINAMELA:
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
namespace_set_index = parseNamespaceSet(constants, lexer);
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
break;
case ParsedSymbol.TYPE_KEYWORD_TYPENAME:
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
qname_index = parseMultiName(constants, lexer);
expected(ParsedSymbol.TYPE_LOWERTHAN, "<", lexer);
params.add(parseMultiName(constants, lexer));
ParsedSymbol nt = lexer.lex();
while (nt.type == ParsedSymbol.TYPE_COMMA) {
params.add(parseMultiName(constants, lexer));
nt = lexer.lex();
}
expected(nt, ParsedSymbol.TYPE_GREATERTHAN, ">");
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
break;
}
loopm:
for (int m = 1; m < constants.constant_multiname.length; m++) {
Multiname mul = constants.constant_multiname[m];
if (mul.kind == kind && mul.name_index == name_index && mul.namespace_index == namespace_index && mul.namespace_set_index == namespace_set_index && mul.qname_index == qname_index && mul.params.size() == params.size()) {
for (int p = 0; p < mul.params.size(); p++) {
if (mul.params.get(p) != params.get(p)) {
continue loopm;
}
}
return m;
}
}
return constants.addMultiname(new Multiname(kind, name_index, namespace_index, namespace_set_index, qname_index, params));
}
public static ValueKind parseValue(ConstantPool constants, Flasm3Lexer lexer) throws IOException, ParseException {
ParsedSymbol type = lexer.lex();
ParsedSymbol value;
int value_index = 0;
int value_kind = 0;
switch (type.type) {
case ParsedSymbol.TYPE_KEYWORD_INTEGER:
value_kind = ValueKind.CONSTANT_Int;
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
value = lexer.lex();
expected(value, ParsedSymbol.TYPE_INTEGER, "Integer");
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
value_index = constants.forceGetIntId((Long) value.value);
break;
case ParsedSymbol.TYPE_KEYWORD_UINTEGER:
value_kind = ValueKind.CONSTANT_UInt;
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
value = lexer.lex();
expected(value, ParsedSymbol.TYPE_INTEGER, "UInteger");
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
value_index = constants.forceGetUIntId((Long) value.value);
break;
case ParsedSymbol.TYPE_KEYWORD_DOUBLE:
value_kind = ValueKind.CONSTANT_Double;
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
value = lexer.lex();
expected(value, ParsedSymbol.TYPE_FLOAT, "Double");
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
value_index = constants.forceGetDoubleId((Double) value.value);
break;
/*case ParsedSymbol.TYPE_KEYWORD_DECIMAL:
value_kind = ValueKind.CONSTANT_Decimal;
break;*/
case ParsedSymbol.TYPE_KEYWORD_UTF8:
value_kind = ValueKind.CONSTANT_Utf8;
expected(ParsedSymbol.TYPE_PARENT_OPEN, "(", lexer);
value = lexer.lex();
expected(value, ParsedSymbol.TYPE_STRING, "String");
expected(ParsedSymbol.TYPE_PARENT_CLOSE, ")", lexer);
value_index = constants.forceGetStringId((String) value.value);
break;
case ParsedSymbol.TYPE_KEYWORD_TRUE:
value_kind = ValueKind.CONSTANT_True;
break;
case ParsedSymbol.TYPE_KEYWORD_FALSE:
value_kind = ValueKind.CONSTANT_False;
break;
case ParsedSymbol.TYPE_KEYWORD_NULL:
value_kind = ValueKind.CONSTANT_Null;
break;
case ParsedSymbol.TYPE_KEYWORD_NAMESPACE:
case ParsedSymbol.TYPE_KEYWORD_PACKAGEINTERNALNS:
case ParsedSymbol.TYPE_KEYWORD_PROTECTEDNAMESPACE:
case ParsedSymbol.TYPE_KEYWORD_EXPLICITNAMESPACE:
case ParsedSymbol.TYPE_KEYWORD_STATICPROTECTEDNS:
case ParsedSymbol.TYPE_KEYWORD_PRIVATENAMESPACE:
case ParsedSymbol.TYPE_KEYWORD_PACKAGENAMESPACE:
switch (type.type) {
case ParsedSymbol.TYPE_KEYWORD_NAMESPACE:
value_kind = ValueKind.CONSTANT_Namespace;
break;
case ParsedSymbol.TYPE_KEYWORD_PACKAGEINTERNALNS:
value_kind = ValueKind.CONSTANT_PackageInternalNs;
break;
case ParsedSymbol.TYPE_KEYWORD_PROTECTEDNAMESPACE:
value_kind = ValueKind.CONSTANT_ProtectedNamespace;
break;
case ParsedSymbol.TYPE_KEYWORD_EXPLICITNAMESPACE:
value_kind = ValueKind.CONSTANT_ExplicitNamespace;
break;
case ParsedSymbol.TYPE_KEYWORD_STATICPROTECTEDNS:
value_kind = ValueKind.CONSTANT_StaticProtectedNs;
break;
case ParsedSymbol.TYPE_KEYWORD_PRIVATENAMESPACE:
value_kind = ValueKind.CONSTANT_PrivateNs;
break;
case ParsedSymbol.TYPE_KEYWORD_PACKAGENAMESPACE:
value_kind = ValueKind.CONSTANT_PackageNamespace;
break;
}
lexer.pushback(type);
value_index = parseNamespace(constants, lexer);
break;
}
return new ValueKind(value_index, value_kind);
}
public static AVM2Code parse(InputStream is, ConstantPool constants, Trait trait, MissingSymbolHandler missingHandler, MethodBody body, MethodInfo info) throws IOException, ParseException {
AVM2Code code = new AVM2Code();
List<OffsetItem> offsetItems = new ArrayList<>();
@@ -83,12 +479,170 @@ public class ASM3Parser {
List<Integer> exceptionIndices = new ArrayList<>();
int offset = 0;
Flasm3Lexer lexer = new Flasm3Lexer(new InputStreamReader(is, "UTF-8"));
ParsedSymbol symb;
AVM2Instruction lastIns = null;
List<String> exceptionsFrom = new ArrayList<>();
List<String> exceptionsTo = new ArrayList<>();
List<String> exceptionsTargets = new ArrayList<>();
info.flags = 0;
info.name_index = 0;
List<Integer> paramTypes = new ArrayList<>();
List<Integer> paramNames = new ArrayList<>();
List<ValueKind> optional = new ArrayList<>();
do {
symb = lexer.yylex();
symb = lexer.lex();
if (Arrays.asList(ParsedSymbol.TYPE_KEYWORD_BODY, ParsedSymbol.TYPE_KEYWORD_CODE, ParsedSymbol.TYPE_KEYWORD_METHOD).contains(symb.type)) {
continue;
}
if (symb.type == ParsedSymbol.TYPE_KEYWORD_TRAIT) {
if (trait == null) {
throw new ParseException("No trait expected", lexer.yyline());
}
symb = lexer.lex();
switch (symb.type) {
case ParsedSymbol.TYPE_KEYWORD_METHOD:
case ParsedSymbol.TYPE_KEYWORD_GETTER:
case ParsedSymbol.TYPE_KEYWORD_SETTER:
if (!(trait instanceof TraitMethodGetterSetter)) {
throw new ParseException("Unxpected trait type", lexer.yyline());
}
TraitMethodGetterSetter tm = (TraitMethodGetterSetter) trait;
switch (symb.type) {
case ParsedSymbol.TYPE_KEYWORD_METHOD:
tm.kindType = Trait.TRAIT_METHOD;
break;
case ParsedSymbol.TYPE_KEYWORD_GETTER:
tm.kindType = Trait.TRAIT_GETTER;
break;
case ParsedSymbol.TYPE_KEYWORD_SETTER:
tm.kindType = Trait.TRAIT_SETTER;
break;
}
tm.name_index = parseMultiName(constants, lexer);
expected(ParsedSymbol.TYPE_KEYWORD_DISPID, "dispid", lexer);
symb = lexer.lex();
expected(symb, ParsedSymbol.TYPE_INTEGER, "Integer");
tm.disp_id = (int) (long) (Long) symb.value;
break;
case ParsedSymbol.TYPE_KEYWORD_FUNCTION:
if (!(trait instanceof TraitFunction)) {
throw new ParseException("Unxpected trait type", lexer.yyline());
}
break;
}
continue;
}
if (symb.type == ParsedSymbol.TYPE_KEYWORD_NAME) {
symb = lexer.lex();
expected(symb, ParsedSymbol.TYPE_STRING, "String");
info.name_index = constants.forceGetStringId((String) symb.value);
continue;
}
if (symb.type == ParsedSymbol.TYPE_KEYWORD_PARAM) {
paramTypes.add(parseMultiName(constants, lexer));
continue;
}
if (symb.type == ParsedSymbol.TYPE_KEYWORD_PARAMNAME) {
symb = lexer.lex();
expected(symb, ParsedSymbol.TYPE_STRING, "String");
paramNames.add(constants.forceGetStringId((String) symb.value));
continue;
}
if (symb.type == ParsedSymbol.TYPE_KEYWORD_OPTIONAL) {
optional.add(parseValue(constants, lexer));
continue;
}
if (symb.type == ParsedSymbol.TYPE_KEYWORD_MAXSTACK) {
symb = lexer.lex();
expected(symb, ParsedSymbol.TYPE_INTEGER, "Integer");
body.max_stack = (int) (long) (Long) symb.value;
continue;
}
if (symb.type == ParsedSymbol.TYPE_KEYWORD_LOCALCOUNT) {
symb = lexer.lex();
expected(symb, ParsedSymbol.TYPE_INTEGER, "Integer");
body.max_regs = (int) (long) (Long) symb.value;
continue;
}
if (symb.type == ParsedSymbol.TYPE_KEYWORD_INITSCOPEDEPTH) {
symb = lexer.lex();
expected(symb, ParsedSymbol.TYPE_INTEGER, "Integer");
body.init_scope_depth = (int) (long) (Long) symb.value;
continue;
}
if (symb.type == ParsedSymbol.TYPE_KEYWORD_MAXSCOPEDEPTH) {
symb = lexer.lex();
expected(symb, ParsedSymbol.TYPE_INTEGER, "Integer");
body.max_scope_depth = (int) (long) (Long) symb.value;
continue;
}
if (symb.type == ParsedSymbol.TYPE_KEYWORD_RETURNS) {
info.ret_type = parseMultiName(constants, lexer);
continue;
}
if (symb.type == ParsedSymbol.TYPE_KEYWORD_FLAG) {
symb = lexer.lex();
switch (symb.type) {
case ParsedSymbol.TYPE_KEYWORD_EXPLICIT:
info.setFlagExplicit();
break;
case ParsedSymbol.TYPE_KEYWORD_HAS_OPTIONAL:
info.setFlagHas_optional();
break;
case ParsedSymbol.TYPE_KEYWORD_HAS_PARAM_NAMES:
info.setFlagHas_paramnames();
break;
case ParsedSymbol.TYPE_KEYWORD_IGNORE_REST:
info.setFlagIgnore_Rest();
break;
case ParsedSymbol.TYPE_KEYWORD_NEED_ACTIVATION:
info.setFlagNeed_activation();
break;
case ParsedSymbol.TYPE_KEYWORD_NEED_ARGUMENTS:
info.setFlagNeed_Arguments();
break;
case ParsedSymbol.TYPE_KEYWORD_NEED_REST:
info.setFlagNeed_rest();
break;
case ParsedSymbol.TYPE_KEYWORD_SET_DXNS:
info.setFlagSetsdxns();
break;
}
continue;
}
if (symb.type == ParsedSymbol.TYPE_KEYWORD_TRY) {
expected(ParsedSymbol.TYPE_KEYWORD_FROM, "From", lexer);
symb = lexer.lex();
expected(symb, ParsedSymbol.TYPE_IDENTIFIER, "Identifier");
exceptionsFrom.add((String) symb.value);
expected(ParsedSymbol.TYPE_KEYWORD_TO, "To", lexer);
symb = lexer.lex();
expected(symb, ParsedSymbol.TYPE_IDENTIFIER, "Identifier");
exceptionsTo.add((String) symb.value);
expected(ParsedSymbol.TYPE_KEYWORD_TARGET, "Target", lexer);
symb = lexer.lex();
expected(symb, ParsedSymbol.TYPE_IDENTIFIER, "Identifier");
exceptionsTargets.add((String) symb.value);
expected(ParsedSymbol.TYPE_KEYWORD_TYPE, "Type", lexer);
ABCException ex = new ABCException();
ex.type_index = parseMultiName(constants, lexer);
expected(ParsedSymbol.TYPE_KEYWORD_NAME, "Name", lexer);
ex.name_index = parseMultiName(constants, lexer);
exceptions.add(ex);
continue;
}
if (symb.type == ParsedSymbol.TYPE_EXCEPTION_START) {
int exIndex = (Integer) symb.value;
int listIndex = exceptionIndices.indexOf(exIndex);
@@ -127,15 +681,15 @@ public class ASM3Parser {
}
if (symb.type == ParsedSymbol.TYPE_INSTRUCTION_NAME) {
if (((String) symb.value).toLowerCase(Locale.ENGLISH).equals("exception")) {
ParsedSymbol exIndex = lexer.yylex();
ParsedSymbol exIndex = lexer.lex();
if (exIndex.type != ParsedSymbol.TYPE_INTEGER) {
throw new ParseException("Index expected", lexer.yyline());
}
ParsedSymbol exName = lexer.yylex();
ParsedSymbol exName = lexer.lex();
if (exName.type != ParsedSymbol.TYPE_MULTINAME) {
throw new ParseException("Multiname expected", lexer.yyline());
}
ParsedSymbol exType = lexer.yylex();
ParsedSymbol exType = lexer.lex();
if (exType.type != ParsedSymbol.TYPE_MULTINAME) {
throw new ParseException("Multiname expected", lexer.yyline());
}
@@ -154,14 +708,16 @@ public class ASM3Parser {
List<Integer> operandsList = new ArrayList<>();
for (int i = 0; i < def.operands.length; i++) {
ParsedSymbol parsedOperand = lexer.yylex();
ParsedSymbol parsedOperand = lexer.lex();
switch (def.operands[i]) {
case AVM2Code.DAT_MULTINAME_INDEX:
if (parsedOperand.type == ParsedSymbol.TYPE_MULTINAME) {
operandsList.add(checkMultinameIndex(constants, (int) (long) (Long) parsedOperand.value, lexer.yyline()));
} else {
throw new ParseException("Multiname expected", lexer.yyline());
}
lexer.pushback(parsedOperand);
operandsList.add(parseMultiName(constants, lexer));
/*if (parsedOperand.type == ParsedSymbol.TYPE_MULTINAME) {
operandsList.add(checkMultinameIndex(constants, (int) (long) (Long) parsedOperand.value, lexer.yyline()));
} else {
throw new ParseException("Multiname expected", lexer.yyline());
}*/
break;
case AVM2Code.DAT_STRING_INDEX:
if (parsedOperand.type == ParsedSymbol.TYPE_STRING) {
@@ -257,7 +813,7 @@ public class ASM3Parser {
operandsList.add(patCount);
for (int c = 0; c <= patCount; c++) {
parsedOperand = lexer.yylex();
parsedOperand = lexer.lex();
if (parsedOperand.type == ParsedSymbol.TYPE_IDENTIFIER) {
offsetItems.add(new CaseOffsetItem((String) parsedOperand.value, code.code.size(), i + (c + 1)));
operandsList.add(0);
@@ -306,6 +862,23 @@ public class ASM3Parser {
} while (symb.type != ParsedSymbol.TYPE_EOF);
code.compact();
for (LabelItem li : labelItems) {
int ind;
ind = exceptionsFrom.indexOf(li.label);
if (ind > -1) {
exceptions.get(ind).start = li.offset;
}
ind = exceptionsTo.indexOf(li.label);
if (ind > -1) {
exceptions.get(ind).end = li.offset;
}
ind = exceptionsTargets.indexOf(li.label);
if (ind > -1) {
exceptions.get(ind).target = li.offset;
}
}
for (OffsetItem oi : offsetItems) {
for (LabelItem li : labelItems) {
@@ -325,6 +898,25 @@ public class ASM3Parser {
for (int e = 0; e < exceptions.size(); e++) {
body.exceptions[e] = exceptions.get(e);
}
info.param_types = new int[paramTypes.size()];
for (int i = 0; i < paramTypes.size(); i++) {
info.param_types[i] = paramTypes.get(i);
}
if (info.flagHas_paramnames()) {
info.paramNames = new int[paramNames.size()];
for (int i = 0; i < paramNames.size(); i++) {
info.paramNames[i] = paramNames.get(i);
}
}
if (info.flagHas_optional()) {
info.optional = new ValueKind[optional.size()];
for (int i = 0; i < optional.size(); i++) {
info.optional[i] = optional.get(i);
}
}
return code;
}
}
File diff suppressed because it is too large Load Diff
@@ -32,6 +32,79 @@ public class ParsedSymbol {
public static final int TYPE_EXCEPTION_START = 10;
public static final int TYPE_EXCEPTION_END = 11;
public static final int TYPE_EXCEPTION_TARGET = 12;
public static final int TYPE_KEYWORD_QNAME = 13;
public static final int TYPE_KEYWORD_QNAMEA = 14;
public static final int TYPE_KEYWORD_RTQNAME = 15;
public static final int TYPE_KEYWORD_RTQNAMEA = 16;
public static final int TYPE_KEYWORD_RTQNAMEL = 17;
public static final int TYPE_KEYWORD_RTQNAMELA = 18;
public static final int TYPE_KEYWORD_MULTINAME = 19;
public static final int TYPE_KEYWORD_MULTINAMEA = 20;
public static final int TYPE_KEYWORD_MULTINAMEL = 21;
public static final int TYPE_KEYWORD_MULTINAMELA = 22;
public static final int TYPE_KEYWORD_TYPENAME = 23;
public static final int TYPE_PARENT_OPEN = 24;
public static final int TYPE_PARENT_CLOSE = 25;
public static final int TYPE_COMMA = 26;
public static final int TYPE_KEYWORD_NULL = 27;
public static final int TYPE_BRACKET_OPEN = 28;
public static final int TYPE_BRACKET_CLOSE = 29;
public static final int TYPE_LOWERTHAN = 30;
public static final int TYPE_GREATERTHAN = 31;
public static final int TYPE_KEYWORD_NAMESPACE = 32;
public static final int TYPE_KEYWORD_PRIVATENAMESPACE = 33;
public static final int TYPE_KEYWORD_PACKAGENAMESPACE = 34;
public static final int TYPE_KEYWORD_PACKAGEINTERNALNS = 35;
public static final int TYPE_KEYWORD_PROTECTEDNAMESPACE = 36;
public static final int TYPE_KEYWORD_EXPLICITNAMESPACE = 37;
public static final int TYPE_KEYWORD_STATICPROTECTEDNS = 38;
public static final int TYPE_KEYWORD_TRY = 39;
public static final int TYPE_KEYWORD_FROM = 40;
public static final int TYPE_KEYWORD_TO = 41;
public static final int TYPE_KEYWORD_TARGET = 42;
public static final int TYPE_KEYWORD_TYPE = 43;
public static final int TYPE_KEYWORD_NAME = 44;
public static final int TYPE_KEYWORD_FLAG = 45;
public static final int TYPE_KEYWORD_EXPLICIT = 46;
public static final int TYPE_KEYWORD_HAS_OPTIONAL = 47;
public static final int TYPE_KEYWORD_HAS_PARAM_NAMES = 48;
public static final int TYPE_KEYWORD_IGNORE_REST = 49;
public static final int TYPE_KEYWORD_NEED_ACTIVATION = 50;
public static final int TYPE_KEYWORD_NEED_ARGUMENTS = 51;
public static final int TYPE_KEYWORD_NEED_REST = 52;
public static final int TYPE_KEYWORD_SET_DXNS = 53;
public static final int TYPE_KEYWORD_PARAM = 54;
public static final int TYPE_KEYWORD_PARAMNAME = 55;
public static final int TYPE_KEYWORD_OPTIONAL = 56;
public static final int TYPE_KEYWORD_RETURNS = 57;
public static final int TYPE_KEYWORD_BODY = 58;
public static final int TYPE_KEYWORD_MAXSTACK = 59;
public static final int TYPE_KEYWORD_LOCALCOUNT = 60;
public static final int TYPE_KEYWORD_INITSCOPEDEPTH = 61;
public static final int TYPE_KEYWORD_MAXSCOPEDEPTH = 62;
public static final int TYPE_KEYWORD_CODE = 63;
public static final int TYPE_KEYWORD_INTEGER = 64;
public static final int TYPE_KEYWORD_UINTEGER = 65;
public static final int TYPE_KEYWORD_DOUBLE = 66;
public static final int TYPE_KEYWORD_DECIMAL = 67;
public static final int TYPE_KEYWORD_UTF8 = 68;
public static final int TYPE_KEYWORD_TRUE = 69;
public static final int TYPE_KEYWORD_FALSE = 70;
public static final int TYPE_KEYWORD_UNDEFINED = 71;
public static final int TYPE_KEYWORD_TRAIT = 72;
public static final int TYPE_KEYWORD_SLOT = 73;
public static final int TYPE_KEYWORD_CONST = 74;
public static final int TYPE_KEYWORD_METHOD = 75;
public static final int TYPE_KEYWORD_GETTER = 76;
public static final int TYPE_KEYWORD_SETTER = 77;
public static final int TYPE_KEYWORD_CLASS = 78;
public static final int TYPE_KEYWORD_FUNCTION = 79;
public static final int TYPE_KEYWORD_DISPID = 80;
public static final int TYPE_KEYWORD_SLOTID = 81;
public static final int TYPE_KEYWORD_VALUE = 82;
public static final int TYPE_KEYWORD_FINAL = 83;
public static final int TYPE_KEYWORD_METADATA = 84;
public static final int TYPE_KEYWORD_OVERRIDE = 85;
public ParsedSymbol(int type, Object value) {
this.type = type;
@@ -2,12 +2,14 @@
package com.jpexs.decompiler.flash.abc.avm2.parser;
import java.util.Stack;
%%
%public
%class Flasm3Lexer
%final
%unicode
%ignorecase
%char
%line
%column
@@ -37,6 +39,26 @@ package com.jpexs.decompiler.flash.abc.avm2.parser;
return yyline+1;
}
private Stack<ParsedSymbol> pushedBack=new Stack<>();
public void pushback(ParsedSymbol symb) {
pushedBack.push(symb);
last = null;
}
ParsedSymbol last;
public ParsedSymbol lex() throws java.io.IOException, ParseException{
ParsedSymbol ret=null;
if(!pushedBack.isEmpty()){
ret = last = pushedBack.pop();
}else{
ret = last = yylex();
}
return ret;
}
%}
/* main character classes */
@@ -107,7 +129,23 @@ ExceptionTarget = "exceptiontarget "{PositiveNumberLiteral}":"
String s=yytext();
return new ParsedSymbol(ParsedSymbol.TYPE_LABEL,s.substring(0,s.length()-1));
}
"name" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_NAME,yytext());}
"try" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_TRY,yytext());}
"flag" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_FLAG,yytext());}
"param" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_PARAM,yytext());}
"paramname" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_PARAMNAME,yytext());}
"optional" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_OPTIONAL,yytext());}
"returns" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_RETURNS,yytext());}
"body" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_BODY,yytext());}
"maxstack" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_MAXSTACK,yytext());}
"localcount" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_LOCALCOUNT,yytext());}
"initscopedepth" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_INITSCOPEDEPTH,yytext());}
"maxscopedepth" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_MAXSCOPEDEPTH,yytext());}
"code" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_CODE,yytext());}
"trait" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_TRAIT,yytext());}
"method" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_METHOD,yytext());}
/* identifiers */
{InstructionName} { yybegin(PARAMETERS);
return new ParsedSymbol(ParsedSymbol.TYPE_INSTRUCTION_NAME,yytext());
@@ -128,7 +166,78 @@ ExceptionTarget = "exceptiontarget "{PositiveNumberLiteral}":"
yybegin(STRING);
string.setLength(0);
}
/* multinames */
"QName" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_QNAME,yytext());}
"QNameA" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_QNAMEA,yytext());}
"RTQName" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_RTQNAME,yytext());}
"RTQNameA" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_RTQNAMEA,yytext());}
"RTQNameL" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_RTQNAMEL,yytext());}
"RTQNameLA" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_RTQNAMELA,yytext());}
"Multiname" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_MULTINAME,yytext());}
"MultinameL" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_MULTINAMEL,yytext());}
"MultinameLA" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_MULTINAMELA,yytext());}
"TypeName" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_TYPENAME,yytext());}
"null" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_NULL,yytext());}
"(" { return new ParsedSymbol(ParsedSymbol.TYPE_PARENT_OPEN,yytext());}
")" { return new ParsedSymbol(ParsedSymbol.TYPE_PARENT_CLOSE,yytext());}
"[" { return new ParsedSymbol(ParsedSymbol.TYPE_BRACKET_OPEN,yytext());}
"]" { return new ParsedSymbol(ParsedSymbol.TYPE_BRACKET_CLOSE,yytext());}
"<" { return new ParsedSymbol(ParsedSymbol.TYPE_LOWERTHAN,yytext());}
">" { return new ParsedSymbol(ParsedSymbol.TYPE_GREATERTHAN,yytext());}
"Namespace" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_NAMESPACE,yytext());}
"PrivateNamespace" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_PRIVATENAMESPACE,yytext());}
"PackageNamespace" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_PACKAGENAMESPACE,yytext());}
"PackageInternalNs" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_PACKAGEINTERNALNS,yytext());}
"ProtectedNamespace" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_PROTECTEDNAMESPACE,yytext());}
"ExplicitNamespace" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_EXPLICITNAMESPACE,yytext());}
"StaticProtectedNs" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_STATICPROTECTEDNS,yytext());}
"," { return new ParsedSymbol(ParsedSymbol.TYPE_COMMA,yytext());}
/*Try*/
"from" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_FROM,yytext());}
"to" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_TO,yytext());}
"target" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_TARGET,yytext());}
"name" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_NAME,yytext());}
"type" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_TYPE,yytext());}
"slot" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_SLOT,yytext());}
"const" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_CONST,yytext());}
"method" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_METHOD,yytext());}
"getter" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_GETTER,yytext());}
"setter" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_SETTER,yytext());}
"class" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_CLASS,yytext());}
"function" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_FUNCTION,yytext());}
"dispid" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_DISPID,yytext());}
"slotid" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_SLOTID,yytext());}
"value" { yybegin(PARAMETERS); return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_VALUE,yytext());}
/*Flags*/
"EXPLICIT" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_EXPLICIT,yytext());}
"HAS_OPTIONAL" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_HAS_OPTIONAL,yytext());}
"HAS_PARAM_NAMES" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_HAS_PARAM_NAMES,yytext());}
"IGNORE_REST" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_IGNORE_REST,yytext());}
"NEED_ACTIVATION" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_NEED_ACTIVATION,yytext());}
"NEED_ARGUMENTS" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_NEED_ARGUMENTS,yytext());}
"NEED_REST" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_NEED_REST,yytext());}
"SET_DXNS" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_SET_DXNS,yytext());}
/* Value types*/
"Integer" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_INTEGER,yytext());}
"UInteger" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_UINTEGER,yytext());}
"Double" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_DOUBLE,yytext());}
"Decimal" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_DECIMAL,yytext());}
"Utf8" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_UTF8,yytext());}
"True" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_TRUE,yytext());}
"False" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_FALSE,yytext());}
"Undefined" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_UNDEFINED,yytext());}
"FINAL" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_FINAL,yytext());}
"OVERRIDE" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_OVERRIDE,yytext());}
"METADATA" { return new ParsedSymbol(ParsedSymbol.TYPE_KEYWORD_METADATA,yytext());}
/* numeric literals */
{NumberLiteral} { return new ParsedSymbol(ParsedSymbol.TYPE_INTEGER,new Long(Long.parseLong((yytext())))); }
@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.CodeStats;
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.helpers.Highlighting;
@@ -70,16 +71,16 @@ public class MethodBody implements Cloneable, Serializable {
return s;
}
public int removeDeadCode(ConstantPool constants) {
return code.removeDeadCode(constants, this);
public int removeDeadCode(ConstantPool constants, Trait trait, MethodInfo info) {
return code.removeDeadCode(constants, trait, info, this);
}
public void restoreControlFlow(ConstantPool constants) {
code.restoreControlFlow(constants, this);
public void restoreControlFlow(ConstantPool constants, Trait trait, MethodInfo info) {
code.restoreControlFlow(constants, trait, info, this);
}
public int removeTraps(ConstantPool constants, ABC abc, int scriptIndex, int classIndex, boolean isStatic, String path) {
return code.removeTraps(constants, this, abc, scriptIndex, classIndex, isStatic, path);
public int removeTraps(ConstantPool constants, ABC abc, Trait trait, int scriptIndex, int classIndex, boolean isStatic, String path) {
return code.removeTraps(constants, trait, abc.method_info[method_info], this, abc, scriptIndex, classIndex, isStatic, path);
}
public HashMap<Integer, String> getLocalRegNames(ABC abc) {
@@ -108,13 +109,13 @@ public class MethodBody implements Cloneable, Serializable {
return ret;
}
public String toString(final String path, boolean pcode, final boolean isStatic, final int scriptIndex, final int classIndex, final ABC abc, final ConstantPool constants, final MethodInfo[] method_info, final Stack<GraphTargetItem> scopeStack, final boolean isStaticInitializer, final boolean hilight, final boolean replaceIndents, final List<String> fullyQualifiedNames, final Traits initTraits) {
public String toString(final String path, boolean pcode, final boolean isStatic, final int scriptIndex, final int classIndex, final ABC abc, final Trait trait, final ConstantPool constants, final MethodInfo[] method_info, final Stack<GraphTargetItem> scopeStack, final boolean isStaticInitializer, final boolean hilight, final boolean replaceIndents, final List<String> fullyQualifiedNames, final Traits initTraits) {
if (debugMode) {
System.err.println("Decompiling " + path);
}
String s = "";
if (pcode) {
s += code.toASMSource(constants, this, false, hilight);
s += code.toASMSource(constants, trait, method_info[this.method_info], this, false, hilight);
} else {
if (!Configuration.getConfig("decompile", true)) {
s = "//Decompilation skipped";
@@ -128,7 +129,7 @@ public class MethodBody implements Cloneable, Serializable {
s += Helper.timedCall(new Callable<String>() {
@Override
public String call() throws Exception {
return toSource(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, scopeStack, isStaticInitializer, hilight, replaceIndents, fullyQualifiedNames, initTraits);
return toSource(path, isStatic, scriptIndex, classIndex, abc, trait, constants, method_info, scopeStack, isStaticInitializer, hilight, replaceIndents, fullyQualifiedNames, initTraits);
}
}, timeout, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException ex) {
@@ -139,14 +140,14 @@ public class MethodBody implements Cloneable, Serializable {
return s;
}
public String toSource(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, ConstantPool constants, MethodInfo[] method_info, Stack<GraphTargetItem> scopeStack, boolean isStaticInitializer, boolean hilight, boolean replaceIndents, List<String> fullyQualifiedNames, Traits initTraits) {
public String toSource(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait, ConstantPool constants, MethodInfo[] method_info, Stack<GraphTargetItem> scopeStack, boolean isStaticInitializer, boolean hilight, boolean replaceIndents, List<String> fullyQualifiedNames, Traits initTraits) {
AVM2Code deobfuscated = null;
MethodBody b = (MethodBody) Helper.deepCopy(this);
deobfuscated = b.code;
deobfuscated.markMappedOffsets();
if (Configuration.getConfig("autoDeobfuscate", true)) {
try {
deobfuscated.removeTraps(constants, b, abc, scriptIndex, classIndex, isStatic, path);
deobfuscated.removeTraps(constants, trait, method_info[this.method_info], b, abc, scriptIndex, classIndex, isStatic, path);
} catch (Exception | StackOverflowError ex) {
Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, "Error during remove traps in " + path, ex);
}
@@ -34,6 +34,18 @@ public class MethodInfo {
public int[] paramNames;
private MethodBody body;
public void setFlagIgnore_Rest() {
flags |= 16;
}
public void setFlagExplicit() {
flags |= 32;
}
public void setFlagNeed_Arguments() {
flags |= 1;
}
public void setFlagSetsdxns() {
flags |= 64;
}
@@ -140,7 +152,7 @@ public class MethodInfo {
return (flags & 8) == 8;
}
public boolean flagIgnore_restHas_optional() {
public boolean flagIgnore_rest() {
return (flags & 16) == 16;
}
@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.abc.types;
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
import com.jpexs.helpers.Helper;
import java.util.List;
public class Multiname {
@@ -135,42 +136,80 @@ public class Multiname {
}
public String toString(ConstantPool constants, List<String> fullyQualifiedNames) {
String kindStr = "?";
for (int k = 0; k < multinameKinds.length; k++) {
if (multinameKinds[k] == kind) {
kindStr = multinameKindNames[k] + " ";
private static String namespaceToString(ConstantPool constants, int index) {
if (index == 0) {
return "null";
}
int type = constants.constant_namespace[index].kind;
String name = constants.constant_namespace[index].getName(constants);
int sub = -1;
for (int n = 1; n < constants.constant_namespace.length; n++) {
if (constants.constant_namespace[n].kind == type && constants.constant_namespace[n].getName(constants).equals(name)) {
sub++;
}
if (n == index) {
break;
}
}
String nameStr = "";
if (name_index > 0) {
nameStr = constants.constant_string[name_index];
}
if (name_index == 0) {
nameStr = "*";
}
String namespaceStr = "";
if (namespace_index > 0) {
namespaceStr = constants.constant_namespace[namespace_index].toString(constants);
}
if (!namespaceStr.equals("")) {
namespaceStr = namespaceStr + ".";
}
if (namespace_index == 0) {
namespaceStr = "*.";
}
String namespaceSetStr = "";
if (namespace_set_index > 0) {
namespaceSetStr = " <NS:" + constants.constant_namespace_set[namespace_set_index].toString(constants) + ">";
}
String typeNameStr = "";
if (kind == TYPENAME) {
typeNameStr = typeNameToStr(constants, fullyQualifiedNames);
}
return constants.constant_namespace[index].getKindStr() + "(" + "\"" + Helper.escapeString(name) + "\"" + (sub > 0 ? ",\"" + sub + "\"" : "") + ")";
}
return namespaceStr + nameStr + namespaceSetStr + typeNameStr;
private static String namespaceSetToString(ConstantPool constants, int index) {
if (index == 0) {
return "null";
}
String ret = "[";
for (int n = 0; n < constants.constant_namespace_set[index].namespaces.length; n++) {
if (n > 0) {
ret += ",";
}
int ns = constants.constant_namespace_set[index].namespaces[n];
ret += namespaceToString(constants, ns);
}
ret += "]";
return ret;
}
private static String multinameToString(ConstantPool constants, int index, List<String> fullyQualifiedNames) {
if (index == 0) {
return "null";
}
return constants.constant_multiname[index].toString(constants, fullyQualifiedNames);
}
public String toString(ConstantPool constants, List<String> fullyQualifiedNames) {
switch (kind) {
case QNAME:
case QNAMEA:
return getKindStr() + "(" + namespaceToString(constants, namespace_index) + "," + "\"" + Helper.escapeString(constants.constant_string[name_index]) + "\"" + ")";
case RTQNAME:
case RTQNAMEA:
return getKindStr() + "(" + "\"" + Helper.escapeString(constants.constant_string[name_index]) + "\"" + ")";
case RTQNAMEL:
case RTQNAMELA:
return getKindStr() + "()";
case MULTINAME:
case MULTINAMEA:
return getKindStr() + "(" + "\"" + Helper.escapeString(constants.constant_string[name_index]) + "\"" + "," + namespaceSetToString(constants, namespace_set_index) + ")";
case MULTINAMEL:
case MULTINAMELA:
return getKindStr() + "(" + namespaceSetToString(constants, namespace_set_index) + ")";
case TYPENAME:
String tret = getKindStr() + "(";
tret += multinameToString(constants, qname_index, fullyQualifiedNames);
tret += "<";
for (int i = 0; i < params.size(); i++) {
if (i > 0) {
tret += ",";
}
tret += multinameToString(constants, params.get(i), fullyQualifiedNames);
}
tret += ">";
tret += ")";
return tret;
}
return null;
}
private String typeNameToStr(ConstantPool constants, List<String> fullyQualifiedNames) {
@@ -29,7 +29,7 @@ public class Namespace {
public static final int KIND_EXPLICIT = 25;
public static final int KIND_STATIC_PROTECTED = 26;
public static final int[] nameSpaceKinds = new int[]{KIND_NAMESPACE, KIND_PRIVATE, KIND_PACKAGE, KIND_PACKAGE_INTERNAL, KIND_PROTECTED, KIND_EXPLICIT, KIND_STATIC_PROTECTED};
public static final String[] nameSpaceKindNames = new String[]{"Namespace", "PrivateNamespace", "PackageNamespace", "PackageInternalNamespace", "ProtectedNamespace", "ExplicitNamespace", "StaticProtectedNamespace"};
public static final String[] nameSpaceKindNames = new String[]{"Namespace", "PrivateNamespace", "PackageNamespace", "PackageInternalNs", "ProtectedNamespace", "ExplicitNamespace", "StaticProtectedNs"};
public static final String[] namePrefixes = new String[]{"", "private", "public", "", "protected", "explicit", "protected"};
public int kind;
public int name_index;
@@ -22,6 +22,13 @@ public class NamespaceSet {
public int[] namespaces;
public NamespaceSet() {
}
public NamespaceSet(int[] namespaces) {
this.namespaces = namespaces;
}
public String toString(ConstantPool constants) {
String s = "";
for (int i = 0; i < this.namespaces.length; i++) {
@@ -38,7 +38,7 @@ public class ValueKind {
public static final int CONSTANT_StaticProtectedNs = 0x1A;// Namespace
public static final int CONSTANT_PrivateNs = 0x05;// namespace
private static final int[] optionalKinds = new int[]{0x03, 0x04, 0x06, 0x02, 0x01, 0x0B, 0x0A, 0x0C, 0x00, 0x08, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x05};
private static final String[] optionalKindNames = new String[]{"Int", "UInt", "Double", "Decimal", "Utf8", "True", "False", "Null", "Undefined", "Namespace", "PackageNamespace", "PackageInternalNs", "ProtectedNamespace", "ExplicitNamespace", "StaticProtectedNs", "PrivateNs"};
private static final String[] optionalKindNames = new String[]{"Int", "UInt", "Double", "Decimal", "Utf8", "True", "False", "Null", "Undefined", "Namespace", "PackageNamespace", "PackageInternalNs", "ProtectedNamespace", "ExplicitNamespace", "StaticProtectedNs", "PrivateNamespace"};
public int value_index;
public int value_kind;
@@ -120,4 +120,46 @@ public class ValueKind {
}
return ret;
}
public String toASMString(ConstantPool constants) {
String ret = "?";
switch (value_kind) {
case CONSTANT_Int:
ret = "Integer(" + constants.constant_int[value_index] + ")";
break;
case CONSTANT_UInt:
ret = "UInteger(" + constants.constant_uint[value_index] + ")";
break;
case CONSTANT_Double:
ret = "Double(" + constants.constant_double[value_index] + ")";
break;
case CONSTANT_Decimal:
ret = "Decimal(" + constants.constant_decimal[value_index] + ")";
break;
case CONSTANT_Utf8:
ret = "Utf8(\"" + Helper.escapeString(constants.constant_string[value_index]) + "\")";
break;
case CONSTANT_True:
ret = "True";
break;
case CONSTANT_False:
ret = "False";
break;
case CONSTANT_Null:
ret = "Null";
break;
case CONSTANT_Undefined:
ret = "Undefined";
break;
case CONSTANT_Namespace:
case CONSTANT_PackageInternalNs:
case CONSTANT_ProtectedNamespace:
case CONSTANT_ExplicitNamespace:
case CONSTANT_StaticProtectedNs:
case CONSTANT_PrivateNs:
ret = constants.constant_namespace[value_index].getKindStr() + "(\"" + constants.constant_namespace[value_index].getName(constants) + "\")";
break;
}
return ret;
}
}
@@ -445,7 +445,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
String bodyStr = "";
bodyIndex = abc.findBodyIndex(abc.class_info[class_info].cinit_index);
if (bodyIndex != -1) {
bodyStr = abc.bodies[bodyIndex].toString(path +/*packageName +*/ "/" + abc.instance_info[class_info].getName(abc.constants).getName(abc.constants, fullyQualifiedNames) + ".staticinitializer", pcode, true, scriptIndex, class_info, abc, abc.constants, abc.method_info, new Stack<GraphTargetItem>(), true, highlight, true, fullyQualifiedNames, abc.class_info[class_info].static_traits);
bodyStr = abc.bodies[bodyIndex].toString(path +/*packageName +*/ "/" + abc.instance_info[class_info].getName(abc.constants).getName(abc.constants, fullyQualifiedNames) + ".staticinitializer", pcode, true, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new Stack<GraphTargetItem>(), true, highlight, true, fullyQualifiedNames, abc.class_info[class_info].static_traits);
}
if (Highlighting.stripHilights(bodyStr).trim().equals("")) {
toPrint = ABC.addTabs(bodyStr + "/*classInitializer*/", 3);
@@ -479,7 +479,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
bodyStr = "";
bodyIndex = abc.findBodyIndex(abc.instance_info[class_info].iinit_index);
if (bodyIndex != -1) {
bodyStr = ABC.addTabs(abc.bodies[bodyIndex].toString(path +/*packageName +*/ "/" + abc.instance_info[class_info].getName(abc.constants).getName(abc.constants, fullyQualifiedNames) + ".initializer", pcode, false, scriptIndex, class_info, abc, abc.constants, abc.method_info, new Stack<GraphTargetItem>(), false, highlight, true, fullyQualifiedNames, abc.instance_info[class_info].instance_traits), 3);
bodyStr = ABC.addTabs(abc.bodies[bodyIndex].toString(path +/*packageName +*/ "/" + abc.instance_info[class_info].getName(abc.constants).getName(abc.constants, fullyQualifiedNames) + ".initializer", pcode, false, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new Stack<GraphTargetItem>(), false, highlight, true, fullyQualifiedNames, abc.instance_info[class_info].instance_traits), 3);
constructorParams = abc.method_info[abc.instance_info[class_info].iinit_index].getParamStr(abc.constants, abc.bodies[bodyIndex], abc, fullyQualifiedNames);
} else {
constructorParams = abc.method_info[abc.instance_info[class_info].iinit_index].getParamStr(abc.constants, null, abc, fullyQualifiedNames);
@@ -548,11 +548,11 @@ public class TraitClass extends Trait implements TraitWithSlot {
int iInitializer = abc.findBodyIndex(abc.instance_info[class_info].iinit_index);
int ret = 0;
if (iInitializer != -1) {
ret += abc.bodies[iInitializer].removeTraps(abc.constants, abc, scriptIndex, class_info, false, path);
ret += abc.bodies[iInitializer].removeTraps(abc.constants, abc, this, scriptIndex, class_info, false, path);
}
int sInitializer = abc.findBodyIndex(abc.class_info[class_info].cinit_index);
if (sInitializer != -1) {
ret += abc.bodies[sInitializer].removeTraps(abc.constants, abc, scriptIndex, class_info, true, path);
ret += abc.bodies[sInitializer].removeTraps(abc.constants, abc, this, scriptIndex, class_info, true, path);
}
ret += abc.instance_info[class_info].instance_traits.removeTraps(scriptIndex, class_info, false, abc, path);
ret += abc.class_info[class_info].static_traits.removeTraps(scriptIndex, class_info, true, abc, path);
@@ -56,7 +56,7 @@ public class TraitFunction extends Trait implements TraitWithSlot {
String bodyStr = "";
int bodyIndex = abc.findBodyIndex(method_info);
if (bodyIndex != -1) {
bodyStr = ABC.addTabs(abc.bodies[bodyIndex].toString(path + "." + abc.constants.constant_multiname[name_index].getName(abc.constants, fullyQualifiedNames), pcode, isStatic, scriptIndex, classIndex, abc, abc.constants, abc.method_info, new Stack<GraphTargetItem>(), false, highlight, true, fullyQualifiedNames, null), 3);
bodyStr = ABC.addTabs(abc.bodies[bodyIndex].toString(path + "." + abc.constants.constant_multiname[name_index].getName(abc.constants, fullyQualifiedNames), pcode, isStatic, scriptIndex, classIndex, abc, this, abc.constants, abc.method_info, new Stack<GraphTargetItem>(), false, highlight, true, fullyQualifiedNames, null), 3);
}
return Graph.INDENT_STRING + Graph.INDENT_STRING + header + (abc.instance_info[classIndex].isInterface() ? ";" : " {\r\n" + bodyStr + "\r\n" + Graph.INDENT_STRING + Graph.INDENT_STRING + "}");
@@ -66,7 +66,7 @@ public class TraitFunction extends Trait implements TraitWithSlot {
public int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) {
int bodyIndex = abc.findBodyIndex(method_info);
if (bodyIndex != -1) {
return abc.bodies[bodyIndex].removeTraps(abc.constants, abc, scriptIndex, classIndex, isStatic, path);
return abc.bodies[bodyIndex].removeTraps(abc.constants, abc, this, scriptIndex, classIndex, isStatic, path);
}
return 0;
}
@@ -60,7 +60,7 @@ public class TraitMethodGetterSetter extends Trait {
String bodyStr = "";
int bodyIndex = abc.findBodyIndex(method_info);
if (bodyIndex != -1) {
bodyStr = ABC.addTabs(abc.bodies[bodyIndex].toString(path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames), pcode, isStatic, scriptIndex, classIndex, abc, abc.constants, abc.method_info, new Stack<GraphTargetItem>(), false, highlight, true, fullyQualifiedNames, null), 3);
bodyStr = ABC.addTabs(abc.bodies[bodyIndex].toString(path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames), pcode, isStatic, scriptIndex, classIndex, abc, this, abc.constants, abc.method_info, new Stack<GraphTargetItem>(), false, highlight, true, fullyQualifiedNames, null), 3);
}
return Graph.INDENT_STRING + Graph.INDENT_STRING + header + ((classIndex != -1 && abc.instance_info[classIndex].isInterface()) ? ";" : " {\r\n" + bodyStr + "\r\n" + Graph.INDENT_STRING + Graph.INDENT_STRING + "}");
}
@@ -69,7 +69,7 @@ public class TraitMethodGetterSetter extends Trait {
public int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) {
int bodyIndex = abc.findBodyIndex(method_info);
if (bodyIndex != -1) {
return abc.bodies[bodyIndex].removeTraps(abc.constants, abc, scriptIndex, classIndex, isStatic, path);
return abc.bodies[bodyIndex].removeTraps(abc.constants, abc, this, scriptIndex, classIndex, isStatic, path);
}
return 0;
}
@@ -127,7 +127,7 @@ public class Traits implements Serializable {
ExecutorService executor = null;
List<Future<String>> futureResults = null;
List<TraitConvertTask> traitConvertTasks = null;
if (parallel) {
executor = Executors.newFixedThreadPool(20);
futureResults = new ArrayList<>();
@@ -81,7 +81,7 @@ public class ActionListReader {
*/
public static List<Action> readActionList(List<DisassemblyListener> listeners, long containerSWFOffset, ReReadableInputStream rri, int version, int ip, int endIp, String path) throws IOException {
boolean deobfuscate = Configuration.getConfig("autoDeobfuscate", true);
ConstantPool cpool = new ConstantPool();
SWFInputStream sis = new SWFInputStream(rri, version);
@@ -89,8 +89,8 @@ public class ActionListReader {
// List of the actions. N. item contains the action which starts in offset N.
List<Action> actionMap = new ArrayList<>();
List<Long> nextOffsets = new ArrayList<>();
Action entryAction = readActionListAtPos(listeners, containerSWFOffset, cpool,
sis, rri,
Action entryAction = readActionListAtPos(listeners, containerSWFOffset, cpool,
sis, rri,
actionMap, nextOffsets,
ip, ip, endIp, version, path, false, new ArrayList<Long>());
@@ -107,7 +107,7 @@ public class ActionListReader {
jump.setJumpOffset((int) (entryAction.getAddress() - size));
actions.add(jump);
}
// remove nulls
index = getNextNotNullIndex(actionMap, index);
while (index > -1) {
@@ -126,7 +126,7 @@ public class ActionListReader {
}
index = nextIndex;
}
// Map for storing the targers of the "jump" actions
// "jump" action can be ActionIf, ActionJump and any ActionStore
Map<Action, Action> jumps = new HashMap<>();
@@ -137,7 +137,7 @@ public class ActionListReader {
updateActionStores(actions, jumps);
updateContainerSizes(actions, containerLastActions);
updateActionLengths(actions, version);
// add end action
Action lastAction = actions.get(actions.size() - 1);
if (!(lastAction instanceof ActionEnd)) {
@@ -153,7 +153,7 @@ public class ActionListReader {
return actions;
}
/**
* Reads list of actions from the stream. Reading ends with
* ActionEndFlag(=0) or end of the stream.
@@ -173,7 +173,7 @@ public class ActionListReader {
byte[] data = Action.actionsToBytes(actions, true, version);
ReReadableInputStream rri = new ReReadableInputStream(new ByteArrayInputStream(data));
int endIp = data.length;
List<Action> retdups = new ArrayList<>();
for (int i = 0; i <= endIp; i++) {
Action a = new ActionNop();
@@ -224,7 +224,7 @@ public class ActionListReader {
}
return reta;
}
private static int getPrevNotNullIndex(List<Action> actionMap, int startIndex) {
startIndex = Math.min(startIndex, actionMap.size() - 1);
for (int i = startIndex; i >= 0; i--) {
@@ -234,7 +234,7 @@ public class ActionListReader {
}
return -1;
}
private static int getNextNotNullIndex(List<Action> actionMap, int startIndex) {
for (int i = startIndex; i < actionMap.size(); i++) {
if (actionMap.get(i) != null) {
@@ -243,7 +243,7 @@ public class ActionListReader {
}
return -1;
}
private static Map<Long, Action> actionListToMap(List<Action> actions) {
Map<Long, Action> map = new HashMap<>(actions.size());
for (Action a : actions) {
@@ -294,7 +294,7 @@ public class ActionListReader {
if (a == null) {
continue;
}
if (a instanceof GraphSourceItemContainer) {
GraphSourceItemContainer container = (GraphSourceItemContainer) a;
List<Long> sizes = container.getContainerSizes();
@@ -313,7 +313,7 @@ public class ActionListReader {
}
}
}
private static long updateAddresses(List<Action> actions, long address, int version) {
for (int i = 0; i < actions.size(); i++) {
Action a = actions.get(i);
@@ -327,7 +327,7 @@ public class ActionListReader {
}
return address;
}
private static void updateActionLengths(List<Action> actions, int version) {
for (int i = 0; i < actions.size(); i++) {
Action a = actions.get(i);
@@ -335,7 +335,7 @@ public class ActionListReader {
a.actionLength = length - 1 - ((a.actionCode >= 0x80) ? 2 : 0);
}
}
private static void updateActionStores(List<Action> actions, Map<Action, Action> jumps) {
Map<Long, Action> actionMap = actionListToMap(actions);
for (int i = 0; i < actions.size(); i++) {
@@ -358,7 +358,7 @@ public class ActionListReader {
}
}
}
private static void updateContainerSizes(List<Action> actions, Map<Action, List<Action>> containerLastActions) {
for (int i = 0; i < actions.size(); i++) {
Action a = actions.get(i);
@@ -383,7 +383,7 @@ public class ActionListReader {
}
}
}
private static void replaceContainerLastActions(Map<Action, List<Action>> containerLastActions, Action oldTarget, Action newTarget) {
for (Action a : containerLastActions.keySet()) {
List<Action> targets = containerLastActions.get(a);
@@ -394,7 +394,7 @@ public class ActionListReader {
}
}
}
private static void updateJumps(List<Action> actions, Map<Action, Action> jumps, Map<Action, List<Action>> containerLastActions, long endAddress, int version) {
if (actions.isEmpty()) {
return;
@@ -432,21 +432,21 @@ public class ActionListReader {
aJump.setJumpOffset((int) offset);
}
}
}
}
@SuppressWarnings("unchecked")
private static Action readActionListAtPos(List<DisassemblyListener> listeners, long containerSWFOffset, ConstantPool cpool,
SWFInputStream sis, ReReadableInputStream rri,
List<Action> actions, List<Long> nextOffsets,
long ip, long startIp, long endIp, int version, String path, boolean indeterminate, List<Long> visitedContainers) throws IOException {
private static Action readActionListAtPos(List<DisassemblyListener> listeners, long containerSWFOffset, ConstantPool cpool,
SWFInputStream sis, ReReadableInputStream rri,
List<Action> actions, List<Long> nextOffsets,
long ip, long startIp, long endIp, int version, String path, boolean indeterminate, List<Long> visitedContainers) throws IOException {
Action entryAction = null;
if (visitedContainers.contains(ip)) {
return null;
}
visitedContainers.add(ip);
Queue<Long> jumpQueue = new LinkedList<>();
jumpQueue.add(ip);
while (!jumpQueue.isEmpty()) {
@@ -458,7 +458,7 @@ public class ActionListReader {
if ((a = sis.readAction(rri, cpool)) == null) {
break;
}
int actionLengthWithHeader = getTotalActionLength(a);
// unknown action, replace with jump
@@ -470,25 +470,25 @@ public class ActionListReader {
a = aJump;
actionLengthWithHeader = getTotalActionLength(a);
}
if (entryAction == null) {
entryAction = a;
}
ensureCapacity(actions, nextOffsets, ip);
Action existingAction = actions.get((int) ip);
if (existingAction != null) {
break;
}
actions.set((int) ip, a);
nextOffsets.set((int) ip, ip + actionLengthWithHeader);
for (int i = 0; i < listeners.size(); i++) {
listeners.get(i).progress("Reading", rri.getCount(), rri.length());
}
a.containerSWFOffset = containerSWFOffset;
a.setAddress(ip, version, false);
@@ -501,7 +501,7 @@ public class ActionListReader {
cpool.setNew(((ActionConstantPool) a).constantPool);
} else if (a instanceof ActionIf) {
ActionIf aIf = (ActionIf) a;
long nIp = ip + actionLengthWithHeader + aIf.getJumpOffset();
long nIp = ip + actionLengthWithHeader + aIf.getJumpOffset();
if (nIp >= 0) {
jumpQueue.add(nIp);
}
@@ -520,17 +520,17 @@ public class ActionListReader {
if (size != 0) {
long ip2 = ip + actionLengthWithHeader;
//long endIp2 = ip + actionLengthWithHeader + size;
readActionListAtPos(listeners, containerSWFOffset, cpool,
sis, rri,
readActionListAtPos(listeners, containerSWFOffset, cpool,
sis, rri,
actions, nextOffsets,
ip2, startIp, endIp, version, newPath, indeterminate, visitedContainers);
actionLengthWithHeader += size;
}
}
}
ip = ip + actionLengthWithHeader;
if (a.isExit()) {
break;
}
@@ -542,7 +542,7 @@ public class ActionListReader {
private static int getTotalActionLength(Action action) {
return action.actionLength + 1 + ((action.actionCode >= 0x80) ? 2 : 0);
}
private static void ensureCapacity(List<Action> actions, List<Long> nextOffsets, long index) {
while (actions.size() <= index) {
actions.add(null);
@@ -635,14 +635,14 @@ public class ActionListReader {
if (deobfuscate) {
top = stack.pop();
}
int nip = (int)rri.getPos() + aif.getJumpOffset();
int nip = (int) rri.getPos() + aif.getJumpOffset();
if (decideBranch) {
System.out.print("newip " + nip + ", ");
System.out.print("Action: jump(j),ignore(i),compute(c)?");
String next = sc.next();
if (next.equals("j")) {
newip = (int)rri.getPos() + aif.getJumpOffset();
newip = (int) rri.getPos() + aif.getJumpOffset();
rri.setPos(newip);
} else if (next.equals("i")) {
@@ -655,7 +655,7 @@ public class ActionListReader {
System.err.print("is compiletime -> ");
}
if (EcmaScript.toBoolean(top.getResult())) {
newip = (int)rri.getPos() + aif.getJumpOffset();
newip = (int) rri.getPos() + aif.getJumpOffset();
aif.jumpUsed = true;
if (aif.ignoreUsed) {
aif.compileTime = false;
@@ -679,7 +679,7 @@ public class ActionListReader {
goaif = true;
}
} else if (a instanceof ActionJump) {
newip = (int)rri.getPos() + ((ActionJump) a).getJumpOffset();
newip = (int) rri.getPos() + ((ActionJump) a).getJumpOffset();
} else if (!(a instanceof GraphSourceItemContainer)) {
if (deobfuscate) {
//return in for..in, TODO:Handle this better way
@@ -793,8 +793,8 @@ public class ActionListReader {
if ((!stateChanged) && curVisited > 1) {
List<Integer> branches = new ArrayList<>();
branches.add((int)rri.getPos() + aif.getJumpOffset());
branches.add((int)rri.getPos());
branches.add((int) rri.getPos() + aif.getJumpOffset());
branches.add((int) rri.getPos());
for (int br : branches) {
int visc = 0;
if (visited.containsKey(br)) {
@@ -811,10 +811,10 @@ public class ActionListReader {
break loopip;
}
int oldPos = (int)rri.getPos();
int oldPos = (int) rri.getPos();
@SuppressWarnings("unchecked")
Stack<GraphTargetItem> substack = (Stack<GraphTargetItem>) stack.clone();
deobfustaceActionListAtPosRecursive(listeners, output, containers, containerSWFOffset, prepareLocalBranch(localData), substack, cpool, sis, rri, (int)rri.getPos() + aif.getJumpOffset(), ret, startIp, endip, path, visited, indeterminate, decisionStates, version);
deobfustaceActionListAtPosRecursive(listeners, output, containers, containerSWFOffset, prepareLocalBranch(localData), substack, cpool, sis, rri, (int) rri.getPos() + aif.getJumpOffset(), ret, startIp, endip, path, visited, indeterminate, decisionStates, version);
rri.setPos(oldPos);
}
prevIp = ip;
@@ -826,7 +826,7 @@ public class ActionListReader {
listener.progress("Deobfuscating", rri.getCount(), rri.length());
}
}
private static List<Object> prepareLocalBranch(List<Object> localData) {
@SuppressWarnings("unchecked")
HashMap<Integer, String> regNames = (HashMap<Integer, String>) localData.get(0);
@@ -49,38 +49,38 @@ public class ActionWaitForFrame extends Action implements ActionStore {
skipCount = sis.readUI8();
skipped = new ArrayList<>();
/*for (int i = 0; i < skipCount; i++) {
Action a = sis.readAction(cpool);
if (a instanceof ActionEnd) {
skipCount = i;
break;
}
if (a == null) {
skipCount = i;
break;
}
if (a instanceof ActionPush) {
if (cpool != null) {
((ActionPush) a).constantPool = cpool.constants;
}
}
skipped.add(a);
}
boolean deobfuscate = 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, "");
if (!skipped.isEmpty()) {
if (skipped.get(skipped.size() - 1) instanceof ActionEnd) {
skipped.remove(skipped.size() - 1);
}
}
skipCount = skipped.size();
}*/
Action a = sis.readAction(cpool);
if (a instanceof ActionEnd) {
skipCount = i;
break;
}
if (a == null) {
skipCount = i;
break;
}
if (a instanceof ActionPush) {
if (cpool != null) {
((ActionPush) a).constantPool = cpool.constants;
}
}
skipped.add(a);
}
boolean deobfuscate = 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, "");
if (!skipped.isEmpty()) {
if (skipped.get(skipped.size() - 1) instanceof ActionEnd) {
skipped.remove(skipped.size() - 1);
}
}
skipCount = skipped.size();
}*/
}
@Override
@@ -63,33 +63,33 @@ public class ActionWaitForFrame2 extends Action implements ActionStore {
skipCount = sis.readUI8();
skipped = new ArrayList<>();
/*for (int i = 0; i < skipCount; i++) {
Action a = sis.readAction(cpool);
if (a instanceof ActionEnd) {
skipCount = i;
break;
}
if (a == null) {
skipCount = i;
break;
}
skipped.add(a);
}
boolean deobfuscate = 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, "");
if (!skipped.isEmpty()) {
if (skipped.get(skipped.size() - 1) instanceof ActionEnd) {
skipped.remove(skipped.size() - 1);
}
}
skipCount = skipped.size();
}*/
Action a = sis.readAction(cpool);
if (a instanceof ActionEnd) {
skipCount = i;
break;
}
if (a == null) {
skipCount = i;
break;
}
skipped.add(a);
}
boolean deobfuscate = 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, "");
if (!skipped.isEmpty()) {
if (skipped.get(skipped.size() - 1) instanceof ActionEnd) {
skipped.remove(skipped.size() - 1);
}
}
skipCount = skipped.size();
}*/
}
public ActionWaitForFrame2(FlasmLexer lexer) throws IOException, ParseException {
@@ -69,7 +69,7 @@ public class ActionDefineFunction extends Action implements GraphSourceItemConta
long endPos = sis.getPos();
//code = new ArrayList<Action>();
hdrSize = endPos - startPos;
int posBef2 = (int)rri.getPos();
int posBef2 = (int) rri.getPos();
//code = sis.readActionList(rri.getPos(), getFileAddress() + hdrSize, rri, codeSize);
//rri.setPos(posBef2 + codeSize);
}
@@ -110,8 +110,7 @@ public class ActionWith extends Action implements GraphSourceItemContainer {
public void setContainerSize(int index, long size) {
if (index == 0) {
codeSize = (int) size;
}
else {
} else {
throw new IllegalArgumentException("Index must be 0.");
}
}
@@ -101,7 +101,7 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont
long posAfter = sis.getPos();
hdrSize = posAfter - posBef;
//code = new ArrayList<Action>();
int posBef2 = (int)rri.getPos();
int posBef2 = (int) rri.getPos();
//code = sis.readActionList(rri.getPos(), getFileAddress() + hdrSize, rri, codeSize);
//rri.setPos(posBef2 + codeSize);
}
@@ -208,7 +208,7 @@ public class ActionTry extends Action implements GraphSourceItemContainer {
public long getTrySize() {
return trySize;
}
@Override
public List<Long> getContainerSizes() {
List<Long> ret = new ArrayList<>();
@@ -105,7 +105,7 @@ public class ImagePanel extends JPanel implements ActionListener, FlashDisplay {
}
public void setDrawable(final DrawableTag drawable, final SWF swf, final HashMap<Integer, CharacterTag> characters, int frameRate) {
pause();
pause();
this.drawable = drawable;
this.swf = swf;
this.characters = characters;
@@ -139,11 +139,11 @@ public class ImagePanel extends JPanel implements ActionListener, FlashDisplay {
if (drawable == null) {
return 0;
}
int ret=(int)Math.ceil(percent * drawable.getNumFrames() / 100.0);
if(ret==0){
int ret = (int) Math.ceil(percent * drawable.getNumFrames() / 100.0);
if (ret == 0) {
ret = 1;
}
return ret;
return ret;
}
@Override
@@ -163,7 +163,7 @@ public class ImagePanel extends JPanel implements ActionListener, FlashDisplay {
}
private void drawFrame() {
if(drawable == null){
if (drawable == null) {
return;
}
int nframe = percent * drawable.getNumFrames() / 100;
@@ -210,9 +210,9 @@ public class ImagePanel extends JPanel implements ActionListener, FlashDisplay {
@Override
public void gotoFrame(int frame) {
if(drawable==null){
if (drawable == null) {
percent = 0;
}else{
} else {
percent = frame * 100 / drawable.getNumFrames();
}
drawFrame();
@@ -31,7 +31,6 @@ import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -41,14 +40,12 @@ import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileFilter;
@@ -178,8 +175,8 @@ public class LoadFromCacheFrame extends AppFrame implements ActionListener {
}
}
filter();
return null;
}
@@ -190,7 +187,6 @@ public class LoadFromCacheFrame extends AppFrame implements ActionListener {
refreshButton.setEnabled(true);
progressBar.setVisible(false);
}
}.execute();
@@ -2,7 +2,6 @@ package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.Configuration;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.LimitedInputStream;
import com.jpexs.helpers.PosMarkedInputStream;
@@ -24,7 +23,6 @@ import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -101,17 +99,17 @@ public class LoadFromMemoryFrame extends AppFrame implements ActionListener {
setProgress(pos * 100 / ret.size());
pos++;
try {
PosMarkedInputStream pmi=new PosMarkedInputStream(ret.get(addr));
PosMarkedInputStream pmi = new PosMarkedInputStream(ret.get(addr));
ReReadableInputStream is = new ReReadableInputStream(pmi);
SWF swf = new SWF(is, null, false, true);
long limit = pmi.getPos();
is.setPos(0);
is.setPos(0);
is = new ReReadableInputStream(new LimitedInputStream(is, limit));
if (swf.fileSize > 0 && swf.version > 0 && !swf.tags.isEmpty() && swf.version < 25/*Needs to be fixed when SWF versions reaches this value*/) {
String p=translate("swfitem").replace("%version%", "" + swf.version).replace("%size%", "" + swf.fileSize);
String p = translate("swfitem").replace("%version%", "" + swf.version).replace("%size%", "" + swf.fileSize);
publish(p);
swfStreams.add(is);
}
}
} catch (OutOfMemoryError ome) {
System.gc();
@@ -292,11 +290,11 @@ public class LoadFromMemoryFrame extends AppFrame implements ActionListener {
JButton openButton = new JButton(translate("button.open"));
openButton.setActionCommand("OPENSWF");
openButton.addActionListener(this);
JButton saveButton = new JButton(translate("button.save"));
saveButton.setActionCommand("SAVE");
saveButton.addActionListener(this);
rightButtonsPanel.add(openButton);
rightButtonsPanel.add(saveButton);
rightPanel.add(rightButtonsPanel, BorderLayout.SOUTH);
@@ -335,7 +333,7 @@ public class LoadFromMemoryFrame extends AppFrame implements ActionListener {
return;
}
int[] selected = listRes.getSelectedIndices();
if (selected.length>0) {
if (selected.length > 0) {
JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new File(Configuration.getConfig("lastSaveDir", ".")));
if (selected.length > 1) {
@@ -362,14 +360,14 @@ public class LoadFromMemoryFrame extends AppFrame implements ActionListener {
File file = Helper.fixDialogFile(fc.getSelectedFile());
try {
if (selected.length == 1) {
ReReadableInputStream bis=foundIs.get(selected[0]);
ReReadableInputStream bis = foundIs.get(selected[0]);
bis.setPos(0);
Helper.saveStream(bis, file);
} else {
for (int sel : selected) {
ReReadableInputStream bis=foundIs.get(sel);
ReReadableInputStream bis = foundIs.get(sel);
bis.setPos(0);
Helper.saveStream(bis, new File(file, "movie"+sel+".swf"));
Helper.saveStream(bis, new File(file, "movie" + sel + ".swf"));
}
}
Configuration.setConfig("lastSaveDir", file.getParentFile().getAbsolutePath());
@@ -325,7 +325,7 @@ public class Main {
} else {
if (inputStream instanceof FileInputStream) {
openFile(file);
} else if(inputStream instanceof ReReadableInputStream){
} else if (inputStream instanceof ReReadableInputStream) {
try {
((ReReadableInputStream) inputStream).setPos(0);
} catch (IOException ex) {
@@ -2794,9 +2794,9 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel
} else {
int bi = abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex();
if (bi != -1) {
abcPanel.abc.bodies[bi].restoreControlFlow(abcPanel.abc.constants);
abcPanel.abc.bodies[bi].restoreControlFlow(abcPanel.abc.constants, abcPanel.decompiledTextArea.getCurrentTrait(), abcPanel.abc.method_info[abcPanel.abc.bodies[bi].method_info]);
}
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abcPanel.abc);
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abcPanel.abc, abcPanel.decompiledTextArea.getCurrentTrait());
}
Main.stopWork();
View.showMessageDialog(null, "Control flow restored");
@@ -2862,17 +2862,18 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel
}
} else {
int bi = abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex();
Trait t = abcPanel.decompiledTextArea.getCurrentTrait();
if (bi != -1) {
if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_DEAD_CODE) {
abcPanel.abc.bodies[bi].removeDeadCode(abcPanel.abc.constants);
abcPanel.abc.bodies[bi].removeDeadCode(abcPanel.abc.constants, t, abcPanel.abc.method_info[abcPanel.abc.bodies[bi].method_info]);
} else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_TRAPS) {
abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, abcPanel.decompiledTextArea.getScriptLeaf().scriptIndex, abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic(), ""/*FIXME*/);
abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, t, abcPanel.decompiledTextArea.getScriptLeaf().scriptIndex, abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic(), ""/*FIXME*/);
} else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_RESTORE_CONTROL_FLOW) {
abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, abcPanel.decompiledTextArea.getScriptLeaf().scriptIndex, abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic(), ""/*FIXME*/);
abcPanel.abc.bodies[bi].restoreControlFlow(abcPanel.abc.constants);
abcPanel.abc.bodies[bi].removeTraps(abcPanel.abc.constants, abcPanel.abc, t, abcPanel.decompiledTextArea.getScriptLeaf().scriptIndex, abcPanel.decompiledTextArea.getClassIndex(), abcPanel.decompiledTextArea.getIsStatic(), ""/*FIXME*/);
abcPanel.abc.bodies[bi].restoreControlFlow(abcPanel.abc.constants, t, abcPanel.abc.method_info[abcPanel.abc.bodies[bi].method_info]);
}
}
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abcPanel.abc);
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abcPanel.abc, t);
}
} catch (Exception ex) {
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, "Deobfuscation error", ex);
@@ -66,7 +66,7 @@ public class SWFPreviwPanel extends JPanel implements FlashDisplay {
@Override
public void run() {
buffering.setVisible(true);
SWF.framesToImage(0, frameImages, 0, swf.frameCount-1, swf.tags, swf.tags, swf.displayRect, swf.frameCount, new Stack<Integer>());
SWF.framesToImage(0, frameImages, 0, swf.frameCount - 1, swf.tags, swf.tags, swf.displayRect, swf.frameCount, new Stack<Integer>());
buffering.setVisible(false);
}
}.start();
@@ -104,8 +104,8 @@ public class SWFPreviwPanel extends JPanel implements FlashDisplay {
}
}, 0, 1000 / swf.frameRate);
}
private void drawFrame(){
private void drawFrame() {
pan.setImage(frameImages.get(frame - 1));
}
@@ -116,7 +116,7 @@ public class SWFPreviwPanel extends JPanel implements FlashDisplay {
@Override
public int getTotalFrames() {
if(swf==null){
if (swf == null) {
return 0;
}
return swf.frameCount;
@@ -124,10 +124,10 @@ public class SWFPreviwPanel extends JPanel implements FlashDisplay {
@Override
public void pause() {
if(timer!=null){
if (timer != null) {
timer.cancel();
timer = null;
}
}
}
@Override
@@ -138,7 +138,7 @@ public class SWFPreviwPanel extends JPanel implements FlashDisplay {
@Override
public boolean isPlaying() {
return timer!=null;
return timer != null;
}
@Override
@@ -149,7 +149,7 @@ public class SWFPreviwPanel extends JPanel implements FlashDisplay {
@Override
public int getFrameRate() {
if(swf==null){
if (swf == null) {
return 1;
}
return swf.frameRate;
@@ -462,7 +462,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Fr
switchAbc(listIndex);
decompiledTextArea.clearScriptCache();
decompiledTextArea.reloadClass();
detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(-1, abc);
detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(-1, abc, decompiledTextArea.getCurrentTrait());
}
@Override
@@ -21,7 +21,9 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2Graph;
import com.jpexs.decompiler.flash.abc.avm2.parser.ASM3Parser;
import com.jpexs.decompiler.flash.abc.avm2.parser.MissingSymbolHandler;
import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.gui.GraphFrame;
import com.jpexs.decompiler.flash.gui.View;
import com.jpexs.decompiler.flash.helpers.Highlighting;
@@ -47,6 +49,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
private String textWithHex = "";
private String textNoHex = "";
private boolean hex = false;
private Trait trait;
public boolean isHex() {
return hex;
@@ -102,14 +105,15 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
return super.getName();
}
public void setBodyIndex(int bodyIndex, ABC abc, String name) {
public void setBodyIndex(int bodyIndex, ABC abc, String name, Trait trait) {
this.bodyIndex = bodyIndex;
this.abc = abc;
this.name = name;
this.trait = trait;
if (bodyIndex == -1) {
return;
}
String textWithHexTags = abc.bodies[bodyIndex].code.toASMSource(abc.constants, abc.bodies[bodyIndex], true, true);
String textWithHexTags = abc.bodies[bodyIndex].code.toASMSource(abc.constants, trait, abc.method_info[abc.bodies[bodyIndex].method_info], abc.bodies[bodyIndex], true, true);
textWithHex = Helper.hexToComments(textWithHexTags);
textNoHex = Helper.stripComments(textWithHexTags);
setText(hex ? textWithHex : textNoHex);
@@ -130,7 +134,28 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
public boolean save(ConstantPool constants) {
try {
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(getText().getBytes("UTF-8")), constants, new DialogMissingSymbolHandler(), abc.bodies[bodyIndex]);
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(getText().getBytes("UTF-8")), constants, trait, new MissingSymbolHandler() {
//no longer ask for adding new constants
@Override
public boolean missingString(String value) {
return true;
}
@Override
public boolean missingInt(long value) {
return true;
}
@Override
public boolean missingUInt(long value) {
return true;
}
@Override
public boolean missingDouble(double value) {
return true;
}
}, abc.bodies[bodyIndex], abc.method_info[abc.bodies[bodyIndex].method_info]);
acode.getBytes(abc.bodies[bodyIndex].codeBytes);
abc.bodies[bodyIndex].code = acode;
} catch (IOException ex) {
@@ -147,6 +172,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
disassembledHilights = Highlighting.getInstrHighlights(t);
t = Highlighting.stripHilights(t);
super.setText(t);
setCaretPosition(0);
}
public void selectInstruction(int pos) {
@@ -23,6 +23,8 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction;
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import static com.jpexs.decompiler.flash.gui.AppStrings.translate;
import com.jpexs.decompiler.flash.gui.View;
@@ -53,6 +55,11 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
private int classIndex = -1;
private boolean isStatic = false;
private Cache cache = Cache.getInstance(true);
private Trait currentTrait = null;
public Trait getCurrentTrait() {
return currentTrait;
}
public ScriptPack getScriptLeaf() {
return script;
@@ -103,11 +110,22 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
public void run() {
}
});
//fix for inner functions:
if (trait instanceof TraitMethodGetterSetter) {
TraitMethodGetterSetter tm = (TraitMethodGetterSetter) trait;
if (tm.method_info != methodIndex) {
trait = null;
}
}
if (trait instanceof TraitFunction) {
TraitFunction tf = (TraitFunction) trait;
if (tf.method_info != methodIndex) {
trait = null;
}
}
abcPanel.detailPanel.showCard(DetailPanel.METHOD_TRAIT_CARD, trait);
if (reset || (abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex() != bi)) {
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abc, name);
abcPanel.detailPanel.methodTraitPanel.methodBodyParamsPanel.loadFromBody(abc.bodies[bi]);
abcPanel.detailPanel.methodTraitPanel.methodInfoPanel.load(abc.bodies[bi].method_info, abc);
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abc, name, trait);
abcPanel.detailPanel.setEditMode(false);
this.isStatic = isStatic;
}
@@ -205,21 +223,21 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
name = abc.instance_info[classIndex].getName(abc.constants).getNameWithNamespace(abc.constants);
}
}
Trait t = null;
currentTrait = null;
for (Highlighting th : traitHighlights) {
if ((pos >= th.startPos) && (pos < th.startPos + th.len)) {
lastTraitIndex = (int) th.offset;
if ((abc != null) && (classIndex != -1)) {
t = abc.findTraitByTraitId(classIndex, lastTraitIndex);
currentTrait = abc.findTraitByTraitId(classIndex, lastTraitIndex);
isStatic = abc.isStaticTraitId(classIndex, lastTraitIndex);
if (t != null) {
name += ":" + t.getName(abc).getName(abc.constants, new ArrayList<String>());
if (currentTrait != null) {
name += ":" + currentTrait.getName(abc).getName(abc.constants, new ArrayList<String>());
}
}
}
}
displayMethod(pos, (int) tm.offset, name, t, isStatic);
displayMethod(pos, (int) tm.offset, name, currentTrait, isStatic);
currentMethodHighlight = tm;
@@ -231,32 +249,33 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
setNoTrait();
return;
}
currentTrait = null;
for (Highlighting th : traitHighlights) {
if ((pos >= th.startPos) && (pos < th.startPos + th.len)) {
lastTraitIndex = (int) th.offset;
Trait tr = abc.findTraitByTraitId(classIndex, (int) th.offset);
if (tr != null) {
if (tr instanceof TraitSlotConst) {
abcPanel.detailPanel.slotConstTraitPanel.load((TraitSlotConst) tr, abc,
currentTrait = abc.findTraitByTraitId(classIndex, (int) th.offset);
if (currentTrait != null) {
if (currentTrait instanceof TraitSlotConst) {
abcPanel.detailPanel.slotConstTraitPanel.load((TraitSlotConst) currentTrait, abc,
abc.isStaticTraitId(classIndex, lastTraitIndex));
abcPanel.detailPanel.showCard(DetailPanel.SLOT_CONST_TRAIT_CARD, tr);
abcPanel.detailPanel.showCard(DetailPanel.SLOT_CONST_TRAIT_CARD, currentTrait);
abcPanel.detailPanel.setEditMode(false);
return;
}
}
currentMethodHighlight = th;
String name = "";
Trait t = null;
currentTrait = null;
if (abc != null) {
name = abc.instance_info[classIndex].getName(abc.constants).getNameWithNamespace(abc.constants);
t = abc.findTraitByTraitId(classIndex, lastTraitIndex);
currentTrait = abc.findTraitByTraitId(classIndex, lastTraitIndex);
isStatic = abc.isStaticTraitId(classIndex, lastTraitIndex);
if (t != null) {
name += ":" + t.getName(abc).getName(abc.constants, new ArrayList<String>());
if (currentTrait != null) {
name += ":" + currentTrait.getName(abc).getName(abc.constants, new ArrayList<String>());
}
}
displayMethod(pos, abc.findMethodIdByTraitId(classIndex, (int) th.offset), name, t, isStatic);
displayMethod(pos, abc.findMethodIdByTraitId(classIndex, (int) th.offset), name, currentTrait, isStatic);
return;
}
}
@@ -391,7 +410,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
View.execInEventDispatch(new Runnable() {
@Override
public void run() {
if (hilightedCode.length() > 1000000) {
if (hilightedCode.length() > 1024 * 1024 * 2/*2MB*/) {
setContentType("text/plain");
} else {
setContentType("text/actionscript");
@@ -421,4 +440,10 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
cache.clear();
setText("");
}
@Override
public void setText(String t) {
super.setText(t);
setCaretPosition(0);
}
}
@@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import static com.jpexs.decompiler.flash.gui.AppStrings.translate;
import com.jpexs.decompiler.flash.gui.HeaderLabel;
import com.jpexs.decompiler.flash.gui.View;
import com.jpexs.helpers.Helper;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.FlowLayout;
@@ -54,7 +53,7 @@ public class DetailPanel extends JPanel implements ActionListener {
private boolean editMode = false;
private JPanel buttonsPanel;
private ABCPanel abcPanel;
private JLabel traitNameLabel;
private JTextArea traitNameLabel;
public DetailPanel(ABCPanel abcPanel) {
this.abcPanel = abcPanel;
@@ -106,7 +105,7 @@ public class DetailPanel extends JPanel implements ActionListener {
selectedLabel.setHorizontalAlignment(SwingConstants.CENTER);
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.add(selectedLabel, BorderLayout.NORTH);
traitNameLabel = new JLabel("");
traitNameLabel = new JTextArea("");
JPanel traitInfoPanel = new JPanel();
traitInfoPanel.setLayout(new BoxLayout(traitInfoPanel, BoxLayout.LINE_AXIS));
traitInfoPanel.add(new JLabel(" " + translate("abc.detail.traitname")));
@@ -156,7 +155,7 @@ public class DetailPanel extends JPanel implements ActionListener {
if (trait == null) {
traitNameLabel.setText("-");
} else {
traitNameLabel.setText(" m[" + trait.name_index + "]\"" + Helper.escapeString(trait.getName(abcPanel.abc).toString(abcPanel.abc.constants, new ArrayList<String>())) + "\"");
traitNameLabel.setText(" " + trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, new ArrayList<String>()) + " Index: " + trait.name_index);
}
}
@@ -1,147 +0,0 @@
/*
* Copyright (C) 2011-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.gui.abc;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import static com.jpexs.decompiler.flash.gui.AppStrings.translate;
import com.jpexs.decompiler.flash.gui.MyFormattedTextField;
import com.jpexs.decompiler.flash.gui.View;
import java.awt.Color;
import java.awt.Dimension;
import java.text.NumberFormat;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
*
* @author JPEXS
*/
public class MethodBodyParamsPanel extends JPanel implements ChangeListener {
public JLabel maxStackLabel;
public JFormattedTextField maxStackField;
public JLabel localCountLabel;
public JFormattedTextField localCountField;
public JLabel initScopeDepthLabel;
public JFormattedTextField initScopeDepthField;
public JLabel maxScopeDepthLabel;
public JFormattedTextField maxScopeDepthField;
public MethodBody body;
public JCheckBox autoFillCheckBox = new JCheckBox(translate("abc.detail.body.params.autofill"));
public JLabel experimentalLabel = new JLabel(translate("abc.detail.body.params.autofill.experimental"));
private ABCPanel abcPanel;
public MethodBodyParamsPanel(ABCPanel abcPanel) {
setLayout(null);
this.abcPanel = abcPanel;
JComponent[][] cmps = new JComponent[][]{
{maxStackLabel = new JLabel(translate("abc.detail.body.params.maxstack"), SwingConstants.RIGHT), maxStackField = new MyFormattedTextField(NumberFormat.getNumberInstance())},
{localCountLabel = new JLabel(translate("abc.detail.body.params.localregcount"), SwingConstants.RIGHT), localCountField = new MyFormattedTextField(NumberFormat.getNumberInstance())},
{initScopeDepthLabel = new JLabel(translate("abc.detail.body.params.minscope"), SwingConstants.RIGHT), initScopeDepthField = new MyFormattedTextField(NumberFormat.getNumberInstance())},
{maxScopeDepthLabel = new JLabel(translate("abc.detail.body.params.maxscope"), SwingConstants.RIGHT), maxScopeDepthField = new MyFormattedTextField(NumberFormat.getNumberInstance())}
};
int maxw = 0;
for (int i = 0; i < cmps.length; i++) {
Dimension d = cmps[i][0].getPreferredSize();
if (d.width > maxw) {
maxw = d.width;
}
}
int top = 0;
for (int i = 0; i < cmps.length; i++) {
cmps[i][0].setBounds(10, top, maxw, cmps[i][1].getPreferredSize().height);
cmps[i][1].setBounds(10 + maxw + 10, top, 75, cmps[i][1].getPreferredSize().height);
add(cmps[i][0]);
add(cmps[i][1]);
top += cmps[i][1].getPreferredSize().height;
}
add(autoFillCheckBox);
autoFillCheckBox.addChangeListener(this);
experimentalLabel.setForeground(Color.red);
autoFillCheckBox.setLocation(0, top);
autoFillCheckBox.setSize(autoFillCheckBox.getPreferredSize());
experimentalLabel.setLocation(20 + autoFillCheckBox.getWidth(), top);
experimentalLabel.setSize(experimentalLabel.getPreferredSize());
add(experimentalLabel);
setPreferredSize(new Dimension(300, 150));
}
public void loadFromBody(MethodBody body) {
this.body = body;
if (body == null) {
maxStackField.setText("0");
localCountField.setText("0");
initScopeDepthField.setText("0");
maxScopeDepthField.setText("0");
return;
}
maxStackField.setText("" + body.max_stack);
localCountField.setText("" + body.max_regs);
initScopeDepthField.setText("" + body.init_scope_depth);
maxScopeDepthField.setText("" + body.max_scope_depth);
}
public boolean save() {
if (body != null) {
body.init_scope_depth = Integer.parseInt(initScopeDepthField.getText());
if (!autoFillCheckBox.isSelected()) {
body.max_stack = Integer.parseInt(maxStackField.getText());
body.max_regs = Integer.parseInt(localCountField.getText());
body.max_scope_depth = Integer.parseInt(maxScopeDepthField.getText());
} else {
if (!body.autoFillStats(abcPanel.abc)) {
View.showMessageDialog(null, translate("message.autofill.failed"), translate("message.warning"), JOptionPane.WARNING_MESSAGE);
}
}
return true;
}
return false;
}
@Override
public void stateChanged(ChangeEvent e) {
if (e.getSource() == autoFillCheckBox) {
if (autoFillCheckBox.isSelected()) {
localCountField.setEnabled(false);
maxScopeDepthField.setEnabled(false);
maxStackField.setEnabled(false);
} else {
localCountField.setEnabled(true);
maxScopeDepthField.setEnabled(true);
maxStackField.setEnabled(true);
}
}
}
public void setEditMode(boolean val) {
maxStackField.setEditable(val);
localCountField.setEditable(val);
initScopeDepthField.setEditable(val);
maxScopeDepthField.setEditable(val);
autoFillCheckBox.setEnabled(val);
}
}
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.gui.abc;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import static com.jpexs.decompiler.flash.gui.AppStrings.translate;
import com.jpexs.decompiler.flash.gui.Main;
import com.jpexs.decompiler.flash.gui.View;
@@ -58,12 +59,12 @@ public class MethodCodePanel extends JPanel implements ActionListener {
sourceTextArea.hilighOffset(offset);
}
public void setBodyIndex(int bodyIndex, ABC abc) {
sourceTextArea.setBodyIndex(bodyIndex, abc, sourceTextArea.getName());
public void setBodyIndex(int bodyIndex, ABC abc, Trait trait) {
sourceTextArea.setBodyIndex(bodyIndex, abc, sourceTextArea.getName(), trait);
}
public void setBodyIndex(int bodyIndex, ABC abc, String name) {
sourceTextArea.setBodyIndex(bodyIndex, abc, name);
public void setBodyIndex(int bodyIndex, ABC abc, String name, Trait trait) {
sourceTextArea.setBodyIndex(bodyIndex, abc, name, trait);
}
public int getBodyIndex() {
@@ -1,140 +0,0 @@
/*
* Copyright (C) 2011-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.gui.abc;
import com.jpexs.decompiler.flash.Configuration;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.methodinfo_parser.MethodInfoParser;
import com.jpexs.decompiler.flash.abc.methodinfo_parser.ParseException;
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
import static com.jpexs.decompiler.flash.gui.AppStrings.translate;
import com.jpexs.decompiler.flash.gui.View;
import com.jpexs.helpers.Helper;
import java.awt.Dimension;
import java.awt.Font;
import java.util.ArrayList;
import javax.swing.*;
import jsyntaxpane.syntaxkits.Flasm3MethodInfoSyntaxKit;
/**
*
* @author JPEXS
*/
public class MethodInfoPanel extends JPanel {
public LineMarkedEditorPane paramEditor;
public JEditorPane returnTypeEditor;
private MethodInfo methodInfo;
private ABC abc;
private JLabel methodIndexLabel;
public MethodInfoPanel() {
returnTypeEditor = new UndoFixedEditorPane();
paramEditor = new LineMarkedEditorPane();
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
JPanel miPanel = new JPanel();
miPanel.setLayout(new BoxLayout(miPanel, BoxLayout.LINE_AXIS));
miPanel.add(new JLabel(translate("abc.detail.methodinfo.methodindex")));
methodIndexLabel = new JLabel(" ");
miPanel.add(methodIndexLabel);
add(miPanel);
add(new JLabel(translate("abc.detail.methodinfo.parameters")));
add(new JScrollPane(paramEditor));
add(new JLabel(translate("abc.detail.methodinfo.returnvalue")));
JScrollPane jsp = new JScrollPane(returnTypeEditor);
add(jsp);
paramEditor.setContentType("text/flasm3_methodinfo");
returnTypeEditor.setContentType("text/flasm3_methodinfo");
paramEditor.setFont(new Font("Monospaced", Font.PLAIN, paramEditor.getFont().getSize()));
returnTypeEditor.setFont(new Font("Monospaced", Font.PLAIN, returnTypeEditor.getFont().getSize()));
jsp.setMaximumSize(new Dimension(1024, 25));
Flasm3MethodInfoSyntaxKit sk = (Flasm3MethodInfoSyntaxKit) returnTypeEditor.getEditorKit();
sk.deinstallComponent(returnTypeEditor, "jsyntaxpane.components.LineNumbersRuler");
}
public void load(int methodInfoIndex, ABC abc) {
this.abc = abc;
if (methodInfoIndex <= 0) {
paramEditor.setText("");
}
methodIndexLabel.setText("" + methodInfoIndex);
this.methodInfo = abc.method_info[methodInfoIndex];
int p = 0;
String ret = "";
int optParPos = 0;
if (methodInfo.flagHas_optional()) {
optParPos = methodInfo.param_types.length - methodInfo.optional.length;
}
for (int ptype : methodInfo.param_types) {
if (p > 0) {
ret += ",\n";
}
if (methodInfo.flagHas_paramnames() && Configuration.PARAM_NAMES_ENABLE) {
ret = ret + abc.constants.constant_string[methodInfo.paramNames[p]];
} else {
ret = ret + "param" + (p + 1);
}
ret += ":";
if (ptype == 0) {
ret += "*";
} else {
ret += "m[" + ptype + "]\"" + Helper.escapeString(abc.constants.constant_multiname[ptype].toString(abc.constants, new ArrayList<String>())) + "\"";
}
if (methodInfo.flagHas_optional()) {
if (p >= optParPos) {
ret += "=" + methodInfo.optional[p - optParPos].toString(abc.constants);
}
}
p++;
}
if (methodInfo.flagNeed_rest()) {
if (p > 0) {
ret += ",\n";
}
ret += "... rest";
}
paramEditor.setText(ret);
if (methodInfo.ret_type == 0) {
returnTypeEditor.setText("*");
} else {
returnTypeEditor.setText("m[" + methodInfo.ret_type + "]\"" + Helper.escapeString(abc.constants.constant_multiname[methodInfo.ret_type].toString(abc.constants, new ArrayList<String>())) + "\"");
}
}
public boolean save() {
try {
MethodInfoParser.parseParams(paramEditor.getText(), methodInfo, abc);
} catch (ParseException ex) {
View.showMessageDialog(paramEditor, ex.text, translate("error.methodinfo.params"), JOptionPane.ERROR_MESSAGE);
return false;
}
try {
MethodInfoParser.parseReturnType(returnTypeEditor.getText(), methodInfo);
} catch (ParseException ex) {
View.showMessageDialog(returnTypeEditor, ex.text, translate("error.methodinfo.returnvalue"), JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
}
public void setEditMode(boolean val) {
returnTypeEditor.setEditable(val);
paramEditor.setEditable(val);
}
}
@@ -16,43 +16,30 @@
*/
package com.jpexs.decompiler.flash.gui.abc;
import static com.jpexs.decompiler.flash.gui.AppStrings.translate;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import java.awt.BorderLayout;
import javax.swing.JPanel;
/**
*
* @author JPEXS
*/
public class MethodTraitDetailPanel extends JTabbedPane implements TraitDetail {
public class MethodTraitDetailPanel extends JPanel implements TraitDetail {
public MethodCodePanel methodCodePanel;
public MethodBodyParamsPanel methodBodyParamsPanel;
public MethodInfoPanel methodInfoPanel;
public ABCPanel abcPanel;
public MethodTraitDetailPanel(ABCPanel abcPanel) {
this.abcPanel = abcPanel;
methodCodePanel = new MethodCodePanel(abcPanel.decompiledTextArea);
methodBodyParamsPanel = new MethodBodyParamsPanel(abcPanel);
methodInfoPanel = new MethodInfoPanel();
addTab(translate("abc.detail.methodinfo"), methodInfoPanel);
addTab(translate("abc.detail.body.code"), methodCodePanel);
addTab(translate("abc.detail.body.params"), new JScrollPane(methodBodyParamsPanel));
setSelectedIndex(1);
setLayout(new BorderLayout());
add(methodCodePanel, BorderLayout.CENTER);
}
@Override
public boolean save() {
if (!methodInfoPanel.save()) {
return false;
}
if (!methodCodePanel.save(abcPanel.abc.constants)) {
return false;
}
if (!methodBodyParamsPanel.save()) {
return false;
}
return true;
}
@@ -60,8 +47,6 @@ public class MethodTraitDetailPanel extends JTabbedPane implements TraitDetail {
@Override
public void setEditMode(boolean val) {
methodCodePanel.setEditMode(val);
methodBodyParamsPanel.setEditMode(val);
methodInfoPanel.setEditMode(val);
}
private boolean active = false;
@@ -17,17 +17,19 @@
package com.jpexs.decompiler.flash.gui.abc;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.methodinfo_parser.MethodInfoParser;
import com.jpexs.decompiler.flash.abc.methodinfo_parser.ParseException;
import com.jpexs.decompiler.flash.abc.avm2.parser.ASM3Parser;
import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException;
import com.jpexs.decompiler.flash.abc.types.ValueKind;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import static com.jpexs.decompiler.flash.gui.AppStrings.translate;
import com.jpexs.decompiler.flash.gui.View;
import com.jpexs.helpers.Helper;
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import jsyntaxpane.syntaxkits.Flasm3MethodInfoSyntaxKit;
/**
*
@@ -41,7 +43,7 @@ public class SlotConstTraitDetailPanel extends JPanel implements TraitDetail {
private boolean showWarning = false;
public SlotConstTraitDetailPanel() {
slotConstEditor = new UndoFixedEditorPane();
slotConstEditor = new LineMarkedEditorPane();
setLayout(new BorderLayout());
add(new JLabel(translate("abc.detail.slotconst.typevalue")), BorderLayout.NORTH);
add(new JScrollPane(slotConstEditor), BorderLayout.CENTER);
@@ -55,27 +57,30 @@ public class SlotConstTraitDetailPanel extends JPanel implements TraitDetail {
//warnLabel.setLineWrap(true);
warnLabel.setFont(new JLabel().getFont().deriveFont(Font.BOLD));
add(warnLabel, BorderLayout.SOUTH);*/
slotConstEditor.setContentType("text/flasm3_methodinfo");
Flasm3MethodInfoSyntaxKit sk = (Flasm3MethodInfoSyntaxKit) slotConstEditor.getEditorKit();
sk.deinstallComponent(slotConstEditor, "jsyntaxpane.components.LineNumbersRuler");
slotConstEditor.setContentType("text/flasm3");
//Flasm3SyntaxKit sk = (Flasm3SyntaxKit) slotConstEditor.getEditorKit();
//sk.deinstallComponent(slotConstEditor, "jsyntaxpane.components.LineNumbersRuler");
}
public void load(TraitSlotConst trait, ABC abc, boolean isStatic) {
this.abc = abc;
this.trait = trait;
String s;
String typeStr;
if (trait.type_index > 0) {
typeStr = "m[" + trait.type_index + "]\"" + Helper.escapeString(abc.constants.constant_multiname[trait.type_index].toString(abc.constants, new ArrayList<String>())) + "\"";
} else {
typeStr = "*";
}
String valueStr = "";
if (trait.value_kind != 0) {
valueStr = " = " + (new ValueKind(trait.value_index, trait.value_kind)).toString(abc.constants);
}
/*String s;
String typeStr;
if (trait.type_index > 0) {
typeStr = "m[" + trait.type_index + "]\"" + Helper.escapeString(abc.constants.constant_multiname[trait.type_index].toString(abc.constants, new ArrayList<String>())) + "\"";
} else {
typeStr = "*";
}
String valueStr = "";
if (trait.value_kind != 0) {
valueStr = " = " + (new ValueKind(trait.value_index, trait.value_kind)).toString(abc.constants);
}
s = typeStr + valueStr;
s = typeStr + valueStr;
* */
String s = "trait " + abc.constants.multinameToString(trait.name_index) + " " + (trait.isConst() ? "const" : "slot") + " slotid " + trait.slot_id + " type " + abc.constants.multinameToString(trait.type_index) + " value " + (new ValueKind(trait.value_index, trait.value_kind).toASMString(abc.constants));
showWarning = trait.isConst() || isStatic;
//warnLabel.setVisible(trait.isConst() || isStatic);
@@ -84,13 +89,19 @@ public class SlotConstTraitDetailPanel extends JPanel implements TraitDetail {
@Override
public boolean save() {
try {
if (!MethodInfoParser.parseSlotConst(slotConstEditor.getText(), trait, abc)) {
try {//(slotConstEditor.getText(), trait, abc)
if (!ASM3Parser.parseSlotConst(new ByteArrayInputStream(slotConstEditor.getText().getBytes("UTF-8")), abc.constants, trait)) {
return false;
}
} catch (ParseException ex) {
View.showMessageDialog(slotConstEditor, ex.text, translate("error.slotconst.typevalue"), JOptionPane.ERROR_MESSAGE);
return false;
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(SlotConstTraitDetailPanel.class.getName()).log(Level.SEVERE, null, ex);
return false;
} catch (IOException ex) {
Logger.getLogger(SlotConstTraitDetailPanel.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
return true;
}
@@ -565,7 +565,7 @@ public class ActionPanel extends JPanel implements ActionListener {
public void setEditMode(boolean val) {
// todo: create UI for editing raw data
final boolean rawEdit = false;
if (val) {
setText(rawEdit ? srcHexOnly : srcNoHex);
editor.setEditable(true);
@@ -667,8 +667,7 @@ public class ActionPanel extends JPanel implements ActionListener {
String text = editor.getText();
if (text.trim().startsWith("#hexdata")) {
src.setActionBytes(getBytesFromHexaText(text));
}
else {
} else {
src.setActions(ASMParser.parse(0, src.getPos(), true, text, SWF.DEFAULT_VERSION, false), SWF.DEFAULT_VERSION);
}
setSource(this.src, false);
@@ -714,7 +713,7 @@ public class ActionPanel extends JPanel implements ActionListener {
line = line.replace(" ", "");
for (int i = 0; i < line.length() / 2; i++) {
String hexStr = line.substring(i * 2, (i + 1) * 2);
byte b = (byte)Integer.parseInt(hexStr, 16);
byte b = (byte) Integer.parseInt(hexStr, 16);
baos.write(b);
}
}
@@ -728,15 +727,15 @@ public class ActionPanel extends JPanel implements ActionListener {
result.append("#hexdata").append(nl);
/* // hex data from decompiled actions
Scanner scanner = new Scanner(srcWithHex);
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.startsWith(";")) {
result.append(line.substring(1).trim()).append(nl);
} else {
result.append(";").append(line).append(nl);
}
}*/
Scanner scanner = new Scanner(srcWithHex);
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.startsWith(";")) {
result.append(line.substring(1).trim()).append(nl);
} else {
result.append(";").append(line).append(nl);
}
}*/
byte[] data = src.getActionBytes();
for (int i = 0; i < data.length; i++) {
@@ -745,10 +744,10 @@ public class ActionPanel extends JPanel implements ActionListener {
}
result.append(String.format("%02x ", data[i]));
}
return result.toString();
}
public void updateSearchPos() {
searchPos.setText((foundPos + 1) + "/" + found.size());
setSource(found.get(foundPos), true);
@@ -91,7 +91,7 @@ message.confirm = Potvrzen\u00ed
message.confirm.autodeobfuscate = Automatick\u00e1 deobfuskace je zp\u016fsob jak dekompilovat obfuskovan\u00fd k\u00f3d.\r\nDeobfuskace vede k pomalej\u0161\u00ed dekompilaci a n\u011bkter\u00fd nepou\u017eit\u00fd k\u00f3d m\u016f\u017ee b\u00fdt odstran\u011bn.\r\nPokud k\u00f3d nen\u00ed obfuskovan\u00fd, je lep\u0161\u00ed autodeobfuskaci vypnout.
message.parallel = parallelismus
message.trait.saved = Vlastnost \u00fasp\u011b\u0161ne ulo\u017eena
message.trait.saved = Vlastnost \u00fasp\u011b\u0161n\u011b ulo\u017eena
message.constant.new.string = \u0158et\u011bzec "%value%" neexistuje v tabulce konstant. Chcete ho p\u0159idat?
@@ -53,31 +53,31 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay {
private int frameRate;
public boolean functionPlayback = false;
public synchronized String call(String callString){
public synchronized String call(String callString) {
if (pipe != null) {
IntByReference ibr = new IntByReference();
Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_CALL}, 1, ibr, null);
int callLen=callString.getBytes().length;
Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte)((callLen>>8) &0xff),(byte)(callLen & 0xff)}, 2, ibr, null);
int callLen = callString.getBytes().length;
Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) ((callLen >> 8) & 0xff), (byte) (callLen & 0xff)}, 2, ibr, null);
Kernel32.INSTANCE.WriteFile(pipe, callString.getBytes(), callLen, ibr, null);
byte res[] = new byte[2];
if (Kernel32.INSTANCE.ReadFile(pipe, res, 2, ibr, null)) {
int retLen = ((res[0] & 0xff) << 8) + (res[1] & 0xff);
res = new byte[retLen];
if (Kernel32.INSTANCE.ReadFile(pipe, res, retLen, ibr, null)) {
String ret=new String(res,0,retLen);
String ret = new String(res, 0, retLen);
return ret;
}else{
} else {
return null;
}
} else {
return null;
}
}
}
return null;
}
private synchronized void resize() {
if (pipe != null) {
IntByReference ibr = new IntByReference();
@@ -49,7 +49,7 @@ public class PlayerControls extends JPanel implements ActionListener {
private JLabel timeLabel;
private JLabel totalTimeLabel;
private static final Icon pauseIcon = View.getIcon("pause16");
private static final Icon playIcon = View.getIcon("play16");
private static final Icon playIcon = View.getIcon("play16");
public PlayerControls(final FlashDisplay display) {
this.display = display;
@@ -81,7 +81,7 @@ public class PlayerControls extends JPanel implements ActionListener {
progress.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
int frame = 1+(int)Math.floor(e.getX() * display.getTotalFrames() / (double)progress.getWidth());
int frame = 1 + (int) Math.floor(e.getX() * display.getTotalFrames() / (double) progress.getWidth());
boolean p = paused;
display.gotoFrame(frame);
if (!p) {
@@ -25,7 +25,6 @@ import com.jpexs.decompiler.flash.types.ALPHABITMAPDATA;
import com.jpexs.decompiler.flash.types.ALPHACOLORMAPDATA;
import com.jpexs.decompiler.flash.types.ARGB;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -186,7 +185,7 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
}
if ((bitmapFormat == DefineBitsLossless2Tag.FORMAT_32BIT_ARGB)) {
c = (multiplyAlpha(bitmapData.bitmapPixelData[pos].toColor()));
}
}
bi.setRGB(x, y, c.getRGB());
pos32aligned++;
pos++;
@@ -26,7 +26,6 @@ import com.jpexs.decompiler.flash.types.COLORMAPDATA;
import com.jpexs.decompiler.flash.types.PIX24;
import com.jpexs.decompiler.flash.types.RGB;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -22,5 +22,4 @@ package com.jpexs.decompiler.flash.tags.base;
* @author JPEXS
*/
public interface ContainerItem {
}
@@ -29,7 +29,7 @@ public class MORPHGRADIENT {
/**
* Interpolation mode. See GRADIENT.INTERPOLATION_* constants
*/
public int interPolationMode;
public int interPolationMode;
public int numGradients;
public MORPHGRADRECORD[] gradientRecords;
@@ -2228,7 +2228,7 @@ public class Graph {
continue;
}
strippedP = Highlighting.stripHilights(parts[p]).trim();
if (replaceIndents) {
if (strippedP.equals(INDENTOPEN)) {
level++;
@@ -37,9 +37,9 @@ public class BlockItem extends GraphTargetItem {
@Override
public String toString(boolean highlight, List<Object> localData) {
return hilight("{", highlight) + "\r\n" + Graph.INDENTOPEN + "\r\n" +
Graph.graphToString(commands, highlight, false, localData) + "\r\n" +
Graph.INDENTCLOSE + "\r\n" + hilight("}", highlight);
return hilight("{", highlight) + "\r\n" + Graph.INDENTOPEN + "\r\n"
+ Graph.graphToString(commands, highlight, false, localData) + "\r\n"
+ Graph.INDENTCLOSE + "\r\n" + hilight("}", highlight);
}
@Override
+7 -7
View File
@@ -552,7 +552,7 @@ public class Helper {
THREAD_POOL.execute(task);
return task.get(timeout, timeUnit);
}
public static boolean contains(int[] array, int value) {
for (int i : array) {
if (i == value) {
@@ -561,15 +561,15 @@ public class Helper {
}
return false;
}
public static void saveStream(InputStream is,File output) throws IOException {
byte[] buf=new byte[1024];
public static void saveStream(InputStream is, File output) throws IOException {
byte[] buf = new byte[1024];
int cnt;
try (FileOutputStream fos = new FileOutputStream(output)) {
while((cnt=is.read(buf))>0){
fos.write(buf,0,cnt);
while ((cnt = is.read(buf)) > 0) {
fos.write(buf, 0, cnt);
fos.flush();
}
}
}
}
}
@@ -31,7 +31,7 @@ public class LimitedInputStream extends InputStream {
public int available() throws IOException {
int avail = is.available();
if (pos + avail > limit) {
avail = (int)(limit - pos);
avail = (int) (limit - pos);
}
return avail;
}
@@ -62,7 +62,7 @@ public class ReReadableInputStream extends InputStream {
if (converted == null) {
converted = baos.toByteArray();
}
int ret = converted[(int)pos] & 0xff;
int ret = converted[(int) pos] & 0xff;
pos++;
return ret;
}
@@ -79,7 +79,7 @@ public class ReReadableInputStream extends InputStream {
@Override
public int available() throws IOException {
return (count + is.available()) - (int)pos;
return (count + is.available()) - (int) pos;
}
public long length() throws IOException {