mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-27 23:40:45 +00:00
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:
+2
-2
@@ -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
@@ -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;
|
||||
|
||||
+3
-4
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<>();
|
||||
|
||||
@@ -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(" \"");
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user