mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-18 13:38:26 +00:00
show abc data in dumpview (right click in the treenode to load it)
This commit is contained in:
@@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Deobfuscation;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
@@ -56,8 +55,8 @@ import com.jpexs.decompiler.flash.abc.usages.MultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.TypeNameMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import com.jpexs.helpers.utf8.Utf8PrintWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
@@ -336,189 +335,232 @@ public class ABC {
|
||||
}
|
||||
}
|
||||
|
||||
public ABC(SWFInputStream is, SWF swf, ABCContainerTag tag) throws IOException {
|
||||
public ABC(ABCInputStream ais, SWF swf, ABCContainerTag tag) throws IOException {
|
||||
this.swf = swf;
|
||||
this.parentTag = tag;
|
||||
ABCInputStream ais = new ABCInputStream(is.getBaseStream());
|
||||
// put it to the dumpview:
|
||||
is.readBytesEx(is.available(), "abcBytes");
|
||||
minor_version = ais.readU16();
|
||||
major_version = ais.readU16();
|
||||
minor_version = ais.readU16("minor_version");
|
||||
major_version = ais.readU16("major_version");
|
||||
logger.log(Level.FINE, "ABC minor_version: {0}, major_version: {1}", new Object[]{minor_version, major_version});
|
||||
|
||||
constants = new ConstantPool();
|
||||
deobfuscation = new AVM2Deobfuscation(constants);
|
||||
ais.newDumpLevel("constant_pool", "cpool_info");
|
||||
|
||||
//constant integers
|
||||
int constant_int_pool_count = ais.readU30();
|
||||
int constant_int_pool_count = ais.readU30("int_count");
|
||||
constants.constant_int = new ArrayList<>(constant_int_pool_count);
|
||||
if (constant_int_pool_count > 0) {
|
||||
constants.addInt(0);
|
||||
}
|
||||
for (int i = 1; i < constant_int_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addInt(ais.readS32());
|
||||
if (constant_int_pool_count > 1) {
|
||||
ais.newDumpLevel("integers", "integer[]");
|
||||
for (int i = 1; i < constant_int_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addInt(ais.readS32("int"));
|
||||
}
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
|
||||
//constant unsigned integers
|
||||
int constant_uint_pool_count = ais.readU30();
|
||||
int constant_uint_pool_count = ais.readU30("uint_count");
|
||||
constants.constant_uint = new ArrayList<>(constant_uint_pool_count);
|
||||
if (constant_uint_pool_count > 0) {
|
||||
constants.addUInt(0);
|
||||
}
|
||||
for (int i = 1; i < constant_uint_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addUInt(ais.readU32());
|
||||
if (constant_uint_pool_count > 1) {
|
||||
ais.newDumpLevel("uintegers", "uinteger[]");
|
||||
for (int i = 1; i < constant_uint_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addUInt(ais.readU32("uint"));
|
||||
}
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
|
||||
//constant double
|
||||
int constant_double_pool_count = ais.readU30();
|
||||
int constant_double_pool_count = ais.readU30("double_count");
|
||||
constants.constant_double = new ArrayList<>(constant_double_pool_count);
|
||||
if (constant_double_pool_count > 0) {
|
||||
constants.addDouble(0);
|
||||
}
|
||||
for (int i = 1; i < constant_double_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addDouble(ais.readDouble());
|
||||
if (constant_double_pool_count > 1) {
|
||||
ais.newDumpLevel("doubles", "double[]");
|
||||
for (int i = 1; i < constant_double_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addDouble(ais.readDouble("double"));
|
||||
}
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
|
||||
//constant decimal
|
||||
if (minor_version >= MINORwithDECIMAL) {
|
||||
int constant_decimal_pool_count = ais.readU30();
|
||||
int constant_decimal_pool_count = ais.readU30("decimal_count");
|
||||
constants.constant_decimal = new ArrayList<>(constant_decimal_pool_count);
|
||||
if (constant_decimal_pool_count > 0) {
|
||||
constants.addDecimal(null);
|
||||
}
|
||||
for (int i = 1; i < constant_decimal_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addDecimal(ais.readDecimal());
|
||||
if (constant_decimal_pool_count > 1) {
|
||||
ais.newDumpLevel("decimals", "decimal[]");
|
||||
for (int i = 1; i < constant_decimal_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addDecimal(ais.readDecimal("decimal"));
|
||||
}
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
} else {
|
||||
constants.constant_decimal = new ArrayList<>(0);
|
||||
}
|
||||
|
||||
//constant string
|
||||
int constant_string_pool_count = ais.readU30();
|
||||
int constant_string_pool_count = ais.readU30("string_count");
|
||||
constants.constant_string = new ArrayList<>(constant_string_pool_count);
|
||||
stringOffsets = new long[constant_string_pool_count];
|
||||
if (constant_string_pool_count > 0) {
|
||||
constants.addString("");
|
||||
}
|
||||
for (int i = 1; i < constant_string_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
long pos = ais.getPosition();
|
||||
constants.addString(ais.readString());
|
||||
stringOffsets[i] = pos;
|
||||
if (constant_string_pool_count > 1) {
|
||||
ais.newDumpLevel("strings", "string[]");
|
||||
for (int i = 1; i < constant_string_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
long pos = ais.getPosition();
|
||||
constants.addString(ais.readString("string"));
|
||||
stringOffsets[i] = pos;
|
||||
}
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
|
||||
//constant namespace
|
||||
int constant_namespace_pool_count = ais.readU30();
|
||||
int constant_namespace_pool_count = ais.readU30("namespace_count");
|
||||
constants.constant_namespace = new ArrayList<>(constant_namespace_pool_count);
|
||||
if (constant_namespace_pool_count > 0) {
|
||||
constants.addNamespace(null);
|
||||
}
|
||||
for (int i = 1; i < constant_namespace_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addNamespace(ais.readNamespace());
|
||||
if (constant_namespace_pool_count > 1) {
|
||||
ais.newDumpLevel("namespaces", "namespace[]");
|
||||
for (int i = 1; i < constant_namespace_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addNamespace(ais.readNamespace("namespace"));
|
||||
}
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
|
||||
//constant namespace set
|
||||
int constant_namespace_set_pool_count = ais.readU30();
|
||||
int constant_namespace_set_pool_count = ais.readU30("ns_set_count");
|
||||
constants.constant_namespace_set = new ArrayList<>(constant_namespace_set_pool_count);
|
||||
if (constant_namespace_set_pool_count > 0) {
|
||||
constants.addNamespaceSet(null);
|
||||
}
|
||||
for (int i = 1; i < constant_namespace_set_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addNamespaceSet(new NamespaceSet());
|
||||
int namespace_count = ais.readU30();
|
||||
constants.getNamespaceSet(i).namespaces = new int[namespace_count];
|
||||
for (int j = 0; j < namespace_count; j++) {
|
||||
constants.getNamespaceSet(i).namespaces[j] = ais.readU30();
|
||||
if (constant_namespace_set_pool_count > 1) {
|
||||
ais.newDumpLevel("ns_sets", "ns_set[]");
|
||||
for (int i = 1; i < constant_namespace_set_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
ais.newDumpLevel("ns_set_infos", "ns_set_info[]");
|
||||
constants.addNamespaceSet(new NamespaceSet());
|
||||
int namespace_count = ais.readU30("count");
|
||||
constants.getNamespaceSet(i).namespaces = new int[namespace_count];
|
||||
for (int j = 0; j < namespace_count; j++) {
|
||||
constants.getNamespaceSet(i).namespaces[j] = ais.readU30("ns");
|
||||
}
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
|
||||
//constant multiname
|
||||
int constant_multiname_pool_count = ais.readU30();
|
||||
int constant_multiname_pool_count = ais.readU30("multiname_count");
|
||||
constants.constant_multiname = new ArrayList<>(constant_multiname_pool_count);
|
||||
if (constant_multiname_pool_count > 0) {
|
||||
constants.addMultiname(null);
|
||||
}
|
||||
for (int i = 1; i < constant_multiname_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addMultiname(ais.readMultiname());
|
||||
if (constant_multiname_pool_count > 1) {
|
||||
ais.newDumpLevel("multiname", "multinames[]");
|
||||
for (int i = 1; i < constant_multiname_pool_count; i++) { //index 0 not used. Values 1..n-1
|
||||
constants.addMultiname(ais.readMultiname("multiname"));
|
||||
}
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
|
||||
ais.endDumpLevel(); //cpool_info
|
||||
|
||||
//method info
|
||||
int methods_count = ais.readU30();
|
||||
method_info = new ArrayList<>();//MethodInfo[methods_count];
|
||||
bodyIdxFromMethodIdx = new ArrayList<>(); //[methods_count];
|
||||
int methods_count = ais.readU30("methods_count");
|
||||
method_info = new ArrayList<>(methods_count); //MethodInfo[methods_count];
|
||||
bodyIdxFromMethodIdx = new ArrayList<>(methods_count); //[methods_count];
|
||||
for (int i = 0; i < methods_count; i++) {
|
||||
method_info.add(ais.readMethodInfo());
|
||||
method_info.add(ais.readMethodInfo("method"));
|
||||
bodyIdxFromMethodIdx.add(-1);
|
||||
}
|
||||
|
||||
//metadata info
|
||||
int metadata_count = ais.readU30();
|
||||
metadata_info = new ArrayList<>();
|
||||
int metadata_count = ais.readU30("metadata_count");
|
||||
metadata_info = new ArrayList<>(metadata_count);
|
||||
for (int i = 0; i < metadata_count; i++) {
|
||||
int name_index = ais.readU30();
|
||||
int values_count = ais.readU30();
|
||||
int name_index = ais.readU30("name_index");
|
||||
int values_count = ais.readU30("values_count");
|
||||
int[] keys = new int[values_count];
|
||||
for (int v = 0; v < values_count; v++) {
|
||||
keys[v] = ais.readU30();
|
||||
keys[v] = ais.readU30("key");
|
||||
}
|
||||
int[] values = new int[values_count];
|
||||
for (int v = 0; v < values_count; v++) {
|
||||
values[v] = ais.readU30();
|
||||
values[v] = ais.readU30("value");
|
||||
}
|
||||
metadata_info.add(new MetadataInfo(name_index, keys, values));
|
||||
}
|
||||
|
||||
int class_count = ais.readU30();
|
||||
instance_info = new ArrayList<>(); //InstanceInfo[class_count];
|
||||
int class_count = ais.readU30("class_count");
|
||||
instance_info = new ArrayList<>(class_count); //InstanceInfo[class_count];
|
||||
for (int i = 0; i < class_count; i++) {
|
||||
instance_info.add(ais.readInstanceInfo());
|
||||
instance_info.add(ais.readInstanceInfo("instance"));
|
||||
}
|
||||
class_info = new ArrayList<>(); //ClassInfo[class_count];
|
||||
class_info = new ArrayList<>(class_count); //ClassInfo[class_count];
|
||||
for (int i = 0; i < class_count; i++) {
|
||||
ais.newDumpLevel("class", "class_info");
|
||||
ClassInfo ci = new ClassInfo();
|
||||
ci.cinit_index = ais.readU30();
|
||||
ci.static_traits = ais.readTraits();
|
||||
ci.cinit_index = ais.readU30("cinit_index");
|
||||
ci.static_traits = ais.readTraits("static_traits");
|
||||
class_info.add(ci);
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
int script_count = ais.readU30();
|
||||
script_info = new ArrayList<>(); //ScriptInfo[script_count];
|
||||
int script_count = ais.readU30("script_count");
|
||||
script_info = new ArrayList<>(script_count); //ScriptInfo[script_count];
|
||||
for (int i = 0; i < script_count; i++) {
|
||||
ais.newDumpLevel("script", "script_info");
|
||||
ScriptInfo si = new ScriptInfo();
|
||||
si.init_index = ais.readU30();
|
||||
si.traits = ais.readTraits();
|
||||
si.init_index = ais.readU30("init_index");
|
||||
si.traits = ais.readTraits("traits");
|
||||
script_info.add(si);
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
|
||||
int bodies_count = ais.readU30();
|
||||
bodies = new ArrayList<>(); //MethodBody[bodies_count];
|
||||
int bodies_count = ais.readU30("bodies_count");
|
||||
bodies = new ArrayList<>(bodies_count); //MethodBody[bodies_count];
|
||||
for (int i = 0; i < bodies_count; i++) {
|
||||
ais.newDumpLevel("method_body", "method_body_info");
|
||||
MethodBody mb = new MethodBody();
|
||||
mb.method_info = ais.readU30();
|
||||
mb.max_stack = ais.readU30();
|
||||
mb.max_regs = ais.readU30();
|
||||
mb.init_scope_depth = ais.readU30();
|
||||
mb.max_scope_depth = ais.readU30();
|
||||
int code_length = ais.readU30();
|
||||
mb.codeBytes = ais.readBytes(code_length);
|
||||
mb.method_info = ais.readU30("method_info");
|
||||
mb.max_stack = ais.readU30("max_stack");
|
||||
mb.max_regs = ais.readU30("max_regs");
|
||||
mb.init_scope_depth = ais.readU30("init_scope_depth");
|
||||
mb.max_scope_depth = ais.readU30("max_scope_depth");
|
||||
int code_length = ais.readU30("code_length");
|
||||
mb.codeBytes = ais.readBytes(code_length, "code");
|
||||
try {
|
||||
mb.code = new AVM2Code(new ByteArrayInputStream(mb.codeBytes));
|
||||
ABCInputStream ais2 = new ABCInputStream(new MemoryInputStream(mb.codeBytes));
|
||||
mb.code = new AVM2Code(ais2);
|
||||
} catch (UnknownInstructionCode re) {
|
||||
mb.code = new AVM2Code();
|
||||
Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, re);
|
||||
}
|
||||
mb.code.compact();
|
||||
int ex_count = ais.readU30();
|
||||
int ex_count = ais.readU30("ex_count");
|
||||
mb.exceptions = new ABCException[ex_count];
|
||||
for (int j = 0; j < ex_count; j++) {
|
||||
ABCException abce = new ABCException();
|
||||
abce.start = ais.readU30();
|
||||
abce.end = ais.readU30();
|
||||
abce.target = ais.readU30();
|
||||
abce.type_index = ais.readU30();
|
||||
abce.name_index = ais.readU30();
|
||||
abce.start = ais.readU30("start");
|
||||
abce.end = ais.readU30("end");
|
||||
abce.target = ais.readU30("target");
|
||||
abce.type_index = ais.readU30("type_index");
|
||||
abce.name_index = ais.readU30("name_index");
|
||||
mb.exceptions[j] = abce;
|
||||
}
|
||||
mb.traits = ais.readTraits();
|
||||
mb.traits = ais.readTraits("traits");
|
||||
bodies.add(mb);
|
||||
method_info.get(mb.method_info).setBody(mb);
|
||||
bodyIdxFromMethodIdx.set(mb.method_info, i);
|
||||
ais.endDumpLevel();
|
||||
}
|
||||
loadNamespaceMap();
|
||||
/*for(int i=0;i<script_count;i++){
|
||||
|
||||
@@ -28,21 +28,23 @@ 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.dumpview.DumpInfo;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ABCInputStream extends InputStream {
|
||||
public class ABCInputStream {
|
||||
|
||||
private static final int CLASS_PROTECTED_NS = 8;
|
||||
private static final int ATTR_METADATA = 4;
|
||||
private final InputStream is;
|
||||
private final MemoryInputStream is;
|
||||
private long bytesRead = 0;
|
||||
private ByteArrayOutputStream bufferOs = null;
|
||||
public static final boolean DEBUG_READ = false;
|
||||
public DumpInfo dumpInfo;
|
||||
|
||||
public void startBuffer() {
|
||||
if (bufferOs == null) {
|
||||
@@ -61,12 +63,45 @@ public class ABCInputStream extends InputStream {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ABCInputStream(InputStream is) {
|
||||
public ABCInputStream(MemoryInputStream is) {
|
||||
this.is = is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
/**
|
||||
* Sets position in bytes in the stream
|
||||
*
|
||||
* @param pos Number of bytes
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public void seek(long pos) throws IOException {
|
||||
is.seek(pos);
|
||||
}
|
||||
|
||||
public DumpInfo newDumpLevel(String name, String type) {
|
||||
if (dumpInfo != null) {
|
||||
long startByte = is.getPos();
|
||||
DumpInfo di = new DumpInfo(name, type, null, startByte, 0, 0, 0);
|
||||
di.parent = dumpInfo;
|
||||
dumpInfo.getChildInfos().add(di);
|
||||
dumpInfo = di;
|
||||
}
|
||||
|
||||
return dumpInfo;
|
||||
}
|
||||
|
||||
public void endDumpLevel() {
|
||||
endDumpLevel(null);
|
||||
}
|
||||
|
||||
public void endDumpLevel(Object value) {
|
||||
if (dumpInfo != null) {
|
||||
dumpInfo.lengthBytes = is.getPos() - dumpInfo.startByte;
|
||||
dumpInfo.previewValue = value;
|
||||
dumpInfo = dumpInfo.parent;
|
||||
}
|
||||
}
|
||||
|
||||
private int readInternal() throws IOException {
|
||||
bytesRead++;
|
||||
int i = is.read();
|
||||
if (DEBUG_READ) {
|
||||
@@ -79,9 +114,15 @@ public class ABCInputStream extends InputStream {
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
public int read(String name) throws IOException {
|
||||
newDumpLevel(name, "byte");
|
||||
int ret = readInternal();
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
private int read(byte[] b) throws IOException {
|
||||
int currBytesRead = is.read(b);
|
||||
bytesRead += currBytesRead;
|
||||
if (DEBUG_READ) {
|
||||
@@ -105,20 +146,21 @@ public class ABCInputStream extends InputStream {
|
||||
return currBytesRead;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
public int readU8() throws IOException {
|
||||
return read();
|
||||
public int readU8(String name) throws IOException {
|
||||
newDumpLevel(name, "U8");
|
||||
int ret = readInternal();
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public long readU32() throws IOException {
|
||||
private long readU32Internal() throws IOException {
|
||||
int i;
|
||||
long ret = 0;
|
||||
int bytePos = 0;
|
||||
int byteCount = 0;
|
||||
boolean nextByte;
|
||||
do {
|
||||
i = read();
|
||||
i = readInternal();
|
||||
nextByte = (i >> 7) == 1;
|
||||
i &= 0x7f;
|
||||
ret += (((long) i) << bytePos);
|
||||
@@ -128,32 +170,52 @@ public class ABCInputStream extends InputStream {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int readU30() throws IOException {
|
||||
return (int) readU32();
|
||||
public long readU32(String name) throws IOException {
|
||||
newDumpLevel(name, "U32");
|
||||
long ret = readU32Internal();
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int readS24() throws IOException {
|
||||
int ret = (read()) + (read() << 8) + (read() << 16);
|
||||
private int readU30Internal() throws IOException {
|
||||
return (int) readU32Internal();
|
||||
}
|
||||
|
||||
public int readU30(String name) throws IOException {
|
||||
newDumpLevel(name, "U30");
|
||||
int ret = readU30Internal();
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int readS24(String name) throws IOException {
|
||||
newDumpLevel(name, "S24");
|
||||
int ret = (readInternal()) + (readInternal() << 8) + (readInternal() << 16);
|
||||
|
||||
if ((ret >> 23) == 1) {
|
||||
ret |= 0xff000000;
|
||||
}
|
||||
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int readU16() throws IOException {
|
||||
return (read()) + (read() << 8);
|
||||
public int readU16(String name) throws IOException {
|
||||
newDumpLevel(name, "U16");
|
||||
int ret = (readInternal()) + (readInternal() << 8);
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public long readS32() throws IOException {
|
||||
public long readS32(String name) throws IOException {
|
||||
int i;
|
||||
long ret = 0;
|
||||
int bytePos = 0;
|
||||
int byteCount = 0;
|
||||
boolean nextByte;
|
||||
newDumpLevel(name, "S32");
|
||||
do {
|
||||
i = read();
|
||||
i = readInternal();
|
||||
nextByte = (i >> 7) == 1;
|
||||
i &= 0x7f;
|
||||
ret += (i << bytePos);
|
||||
@@ -166,15 +228,15 @@ public class ABCInputStream extends InputStream {
|
||||
break;
|
||||
}
|
||||
} while (nextByte);
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return is.available();
|
||||
}
|
||||
|
||||
public final long readLong() throws IOException {
|
||||
private final long readLong() throws IOException {
|
||||
byte[] readBuffer = safeRead(8);
|
||||
return (((long) readBuffer[7] << 56)
|
||||
+ ((long) (readBuffer[6] & 255) << 48)
|
||||
@@ -186,99 +248,109 @@ public class ABCInputStream extends InputStream {
|
||||
+ ((readBuffer[0] & 255)));
|
||||
}
|
||||
|
||||
public double readDouble() throws IOException {
|
||||
public double readDouble(String name) throws IOException {
|
||||
newDumpLevel(name, "Double");
|
||||
long el = readLong();
|
||||
double ret = Double.longBitsToDouble(el);
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private byte[] safeRead(int count) throws IOException {
|
||||
byte[] ret = new byte[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = (byte) read();
|
||||
ret[i] = (byte) readInternal();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Namespace readNamespace() throws IOException {
|
||||
int kind = read();
|
||||
public Namespace readNamespace(String name) throws IOException {
|
||||
newDumpLevel(name, "Namespace");
|
||||
int kind = read("kind");
|
||||
int name_index = 0;
|
||||
for (int k = 0; k < Namespace.nameSpaceKinds.length; k++) {
|
||||
if (Namespace.nameSpaceKinds[k] == kind) {
|
||||
name_index = readU30();
|
||||
name_index = readU30("name_index");
|
||||
break;
|
||||
}
|
||||
}
|
||||
endDumpLevel();
|
||||
return new Namespace(kind, name_index);
|
||||
}
|
||||
|
||||
public Multiname readMultiname() throws IOException {
|
||||
int kind = readU8();
|
||||
public Multiname readMultiname(String name) throws IOException {
|
||||
int kind = readU8("kind");
|
||||
int namespace_index = 0;
|
||||
int name_index = 0;
|
||||
int namespace_set_index = 0;
|
||||
int qname_index = 0;
|
||||
List<Integer> params = new ArrayList<>();
|
||||
|
||||
newDumpLevel(name, "Multiname");
|
||||
if ((kind == Multiname.QNAME) || (kind == Multiname.QNAMEA)) {
|
||||
namespace_index = readU30();
|
||||
name_index = readU30();
|
||||
namespace_index = readU30("namespace_index");
|
||||
name_index = readU30("name_index");
|
||||
} else if ((kind == Multiname.RTQNAME) || (kind == Multiname.RTQNAMEA)) {
|
||||
name_index = readU30();
|
||||
name_index = readU30("name_index");
|
||||
} else if ((kind == Multiname.RTQNAMEL) || (kind == Multiname.RTQNAMELA)) {
|
||||
|
||||
} else if ((kind == Multiname.MULTINAME) || (kind == Multiname.MULTINAMEA)) {
|
||||
name_index = readU30();
|
||||
namespace_set_index = readU30();
|
||||
name_index = readU30("name_index");
|
||||
namespace_set_index = readU30("namespace_set_index");
|
||||
} else if ((kind == Multiname.MULTINAMEL) || (kind == Multiname.MULTINAMELA)) {
|
||||
namespace_set_index = readU30();
|
||||
namespace_set_index = readU30("namespace_set_index");
|
||||
} else if (kind == Multiname.TYPENAME) {
|
||||
qname_index = readU30(); //Multiname index!!!
|
||||
int paramsLength = readU30();
|
||||
qname_index = readU30("qname_index"); //Multiname index!!!
|
||||
int paramsLength = readU30("paramsLength");
|
||||
for (int i = 0; i < paramsLength; i++) {
|
||||
params.add(readU30()); //multiname indices!
|
||||
params.add(readU30("param")); //multiname indices!
|
||||
}
|
||||
} else {
|
||||
throw new IOException("Unknown kind of Multiname:0x" + Integer.toHexString(kind));
|
||||
}
|
||||
|
||||
endDumpLevel();
|
||||
return new Multiname(kind, name_index, namespace_index, namespace_set_index, qname_index, params);
|
||||
}
|
||||
|
||||
public MethodInfo readMethodInfo() throws IOException {
|
||||
int param_count = readU30();
|
||||
int ret_type = readU30();
|
||||
public MethodInfo readMethodInfo(String name) throws IOException {
|
||||
newDumpLevel(name, "method_info");
|
||||
int param_count = readU30("param_count");
|
||||
int ret_type = readU30("ret_type");
|
||||
int[] param_types = new int[param_count];
|
||||
for (int i = 0; i < param_count; i++) {
|
||||
param_types[i] = readU30();
|
||||
param_types[i] = readU30("param_type");
|
||||
}
|
||||
int name_index = readU30();
|
||||
int flags = read();
|
||||
int name_index = readU30("name_index");
|
||||
int flags = readInternal();
|
||||
|
||||
//// 1=need_arguments, 2=need_activation, 4=need_rest 8=has_optional (16=ignore_rest, 32=explicit,) 64=setsdxns, 128=has_paramnames
|
||||
ValueKind[] optional = new ValueKind[0];
|
||||
if ((flags & 8) == 8) { //if has_optional
|
||||
int optional_count = readU30();
|
||||
int optional_count = readU30("optional_count");
|
||||
optional = new ValueKind[optional_count];
|
||||
for (int i = 0; i < optional_count; i++) {
|
||||
optional[i] = new ValueKind(readU30(), read());
|
||||
optional[i] = new ValueKind(readU30("value_index"), read("value_kind"));
|
||||
}
|
||||
}
|
||||
|
||||
int[] param_names = new int[param_count];
|
||||
if ((flags & 128) == 128) { //if has_paramnames
|
||||
for (int i = 0; i < param_count; i++) {
|
||||
param_names[i] = readU30();
|
||||
param_names[i] = readU30("param_name");
|
||||
}
|
||||
}
|
||||
|
||||
endDumpLevel();
|
||||
return new MethodInfo(param_types, ret_type, name_index, flags, optional, param_names);
|
||||
}
|
||||
|
||||
public Trait readTrait() throws IOException {
|
||||
public Trait readTrait(String name) throws IOException {
|
||||
newDumpLevel(name, "Trait");
|
||||
long pos = getPosition();
|
||||
startBuffer();
|
||||
int name_index = readU30();
|
||||
int kind = read();
|
||||
int name_index = readU30("name_index");
|
||||
int kind = readInternal();
|
||||
int kindType = 0xf & kind;
|
||||
int kindFlags = kind >> 4;
|
||||
Trait trait;
|
||||
@@ -287,11 +359,11 @@ public class ABCInputStream extends InputStream {
|
||||
case 0: //slot
|
||||
case 6: //const
|
||||
TraitSlotConst t1 = new TraitSlotConst();
|
||||
t1.slot_id = readU30();
|
||||
t1.type_index = readU30();
|
||||
t1.value_index = readU30();
|
||||
t1.slot_id = readU30("slot_id");
|
||||
t1.type_index = readU30("type_index");
|
||||
t1.value_index = readU30("value_index");
|
||||
if (t1.value_index != 0) {
|
||||
t1.value_kind = read();
|
||||
t1.value_kind = readInternal();
|
||||
}
|
||||
trait = t1;
|
||||
break;
|
||||
@@ -299,20 +371,20 @@ public class ABCInputStream extends InputStream {
|
||||
case 2: //getter
|
||||
case 3: //setter
|
||||
TraitMethodGetterSetter t2 = new TraitMethodGetterSetter();
|
||||
t2.disp_id = readU30();
|
||||
t2.method_info = readU30();
|
||||
t2.disp_id = readU30("disp_id");
|
||||
t2.method_info = readU30("method_info");
|
||||
trait = t2;
|
||||
break;
|
||||
case 4: //class
|
||||
TraitClass t3 = new TraitClass();
|
||||
t3.slot_id = readU30();
|
||||
t3.class_info = readU30();
|
||||
t3.slot_id = readU30("slot_id");
|
||||
t3.class_info = readU30("class_info");
|
||||
trait = t3;
|
||||
break;
|
||||
case 5: //function
|
||||
TraitFunction t4 = new TraitFunction();
|
||||
t4.slot_id = readU30();
|
||||
t4.method_info = readU30();
|
||||
t4.slot_id = readU30("slot_id");
|
||||
t4.method_info = readU30("method_info");
|
||||
trait = t4;
|
||||
break;
|
||||
default:
|
||||
@@ -323,61 +395,77 @@ public class ABCInputStream extends InputStream {
|
||||
trait.kindFlags = kindFlags;
|
||||
trait.name_index = name_index;
|
||||
if ((kindFlags & ATTR_METADATA) != 0) {
|
||||
int metadata_count = readU30();
|
||||
int metadata_count = readU30("metadata_count");
|
||||
trait.metadata = new int[metadata_count];
|
||||
for (int i = 0; i < metadata_count; i++) {
|
||||
trait.metadata[i] = readU30();
|
||||
trait.metadata[i] = readU30("metadata");
|
||||
}
|
||||
}
|
||||
trait.bytes = stopBuffer();
|
||||
endDumpLevel();
|
||||
return trait;
|
||||
}
|
||||
|
||||
public Traits readTraits() throws IOException {
|
||||
int count = readU30();
|
||||
public Traits readTraits(String name) throws IOException {
|
||||
newDumpLevel(name, "Traits");
|
||||
int count = readU30("count");
|
||||
Traits traits = new Traits();
|
||||
traits.traits = new ArrayList<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
traits.traits.add(readTrait());
|
||||
traits.traits.add(readTrait("trait"));
|
||||
}
|
||||
endDumpLevel();
|
||||
return traits;
|
||||
}
|
||||
|
||||
public byte[] readBytes(int count) throws IOException {
|
||||
public byte[] readBytesInternal(int count) throws IOException {
|
||||
byte[] ret = new byte[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
ret[i] = (byte) read();
|
||||
ret[i] = (byte) readInternal();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Decimal readDecimal() throws IOException {
|
||||
byte[] data = readBytes(16);
|
||||
public byte[] readBytes(int count, String name) throws IOException {
|
||||
newDumpLevel(name, "Bytes");
|
||||
byte[] ret = readBytesInternal(count);
|
||||
endDumpLevel();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Decimal readDecimal(String name) throws IOException {
|
||||
newDumpLevel(name, "Decimal");
|
||||
byte[] data = readBytesInternal(16);
|
||||
endDumpLevel();
|
||||
return new Decimal(data);
|
||||
}
|
||||
|
||||
public InstanceInfo readInstanceInfo() throws IOException {
|
||||
public InstanceInfo readInstanceInfo(String name) throws IOException {
|
||||
newDumpLevel(name, "instance_info");
|
||||
InstanceInfo ret = new InstanceInfo();
|
||||
ret.name_index = readU30();
|
||||
ret.super_index = readU30();
|
||||
ret.flags = read();
|
||||
ret.name_index = readU30("name_index");
|
||||
ret.super_index = readU30("super_index");
|
||||
ret.flags = readInternal();
|
||||
if ((ret.flags & CLASS_PROTECTED_NS) != 0) {
|
||||
ret.protectedNS = readU30();
|
||||
ret.protectedNS = readU30("protectedNS");
|
||||
}
|
||||
int interfaces_count = readU30();
|
||||
int interfaces_count = readU30("interfaces_count");
|
||||
ret.interfaces = new int[interfaces_count];
|
||||
for (int i = 0; i < interfaces_count; i++) {
|
||||
ret.interfaces[i] = readU30();
|
||||
ret.interfaces[i] = readU30("interface");
|
||||
}
|
||||
ret.iinit_index = readU30();
|
||||
ret.instance_traits = readTraits();
|
||||
ret.iinit_index = readU30("iinit_index");
|
||||
ret.instance_traits = readTraits("instance_traits");
|
||||
endDumpLevel();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String readString() throws IOException {
|
||||
int length = readU30();
|
||||
public String readString(String name) throws IOException {
|
||||
newDumpLevel(name, "String");
|
||||
int length = readU30Internal();
|
||||
byte[] b = safeRead(length);
|
||||
String r = new String(b, Utf8Helper.charset);
|
||||
endDumpLevel(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -214,6 +214,7 @@ 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.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfo;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
@@ -231,7 +232,6 @@ import com.jpexs.helpers.Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
@@ -784,46 +784,51 @@ public class AVM2Code implements Serializable {
|
||||
return null;
|
||||
}
|
||||
|
||||
public AVM2Code(InputStream is) throws IOException {
|
||||
ABCInputStream ais = new ABCInputStream(is);
|
||||
public AVM2Code(ABCInputStream ais) throws IOException {
|
||||
while (ais.available() > 0) {
|
||||
DumpInfo di = ais.newDumpLevel("instruction", "instruction");
|
||||
long startOffset = ais.getPosition();
|
||||
ais.startBuffer();
|
||||
int instructionCode = ais.read();
|
||||
int instructionCode = ais.read("instructionCode");
|
||||
InstructionDefinition instr = instructionSetByCode[instructionCode];
|
||||
if (di != null) {
|
||||
di.name = instr.instructionName;
|
||||
}
|
||||
if (instr != null) {
|
||||
int[] actualOperands;
|
||||
if (instructionCode == 0x1b) { //switch
|
||||
int firstOperand = ais.readS24();
|
||||
int case_count = ais.readU30();
|
||||
int firstOperand = ais.readS24("firstOperand");
|
||||
int case_count = ais.readU30("case_count");
|
||||
actualOperands = new int[case_count + 3];
|
||||
actualOperands[0] = firstOperand;
|
||||
actualOperands[1] = case_count;
|
||||
for (int c = 0; c < case_count + 1; c++) {
|
||||
actualOperands[2 + c] = ais.readS24();
|
||||
actualOperands[2 + c] = ais.readS24("actualOperand");
|
||||
}
|
||||
} else {
|
||||
actualOperands = new int[instr.operands.length];
|
||||
for (int op = 0; op < instr.operands.length; op++) {
|
||||
switch (instr.operands[op] & 0xff00) {
|
||||
case OPT_U30:
|
||||
actualOperands[op] = ais.readU30();
|
||||
actualOperands[op] = ais.readU30("operand");
|
||||
break;
|
||||
case OPT_U8:
|
||||
actualOperands[op] = ais.read();
|
||||
actualOperands[op] = ais.read("operand");
|
||||
break;
|
||||
case OPT_BYTE:
|
||||
actualOperands[op] = (byte) ais.read();
|
||||
actualOperands[op] = (byte) ais.read("operand");
|
||||
break;
|
||||
case OPT_S24:
|
||||
actualOperands[op] = ais.readS24();
|
||||
actualOperands[op] = ais.readS24("operand");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
code.add(new AVM2Instruction(startOffset, instr, actualOperands, ais.stopBuffer()));
|
||||
ais.endDumpLevel(instr.instructionCode);
|
||||
} else {
|
||||
ais.endDumpLevel(instr.instructionCode);
|
||||
break; // Unknown instructions are ignored (Some of the obfuscators add unknown instructions)
|
||||
//throw new UnknownInstructionCode(instructionCode);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.gui.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ABCInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode;
|
||||
@@ -36,7 +37,7 @@ import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
@@ -194,7 +195,8 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
|
||||
MethodBody mb = abc.bodies.get(bodyIndex);
|
||||
mb.codeBytes = data;
|
||||
try {
|
||||
mb.code = new AVM2Code(new ByteArrayInputStream(mb.codeBytes));
|
||||
ABCInputStream ais = new ABCInputStream(new MemoryInputStream(mb.codeBytes));
|
||||
mb.code = new AVM2Code(ais);
|
||||
} catch (UnknownInstructionCode re) {
|
||||
mb.code = new AVM2Code();
|
||||
Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, re);
|
||||
|
||||
@@ -18,6 +18,9 @@ package com.jpexs.decompiler.flash.gui.dumpview;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ABCInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionListReader;
|
||||
import com.jpexs.decompiler.flash.action.model.ConstantPool;
|
||||
@@ -28,6 +31,7 @@ import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.decompiler.flash.gui.MainPanel;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
@@ -64,6 +68,8 @@ public class DumpTree extends JTree implements ActionListener {
|
||||
private static final String ACTION_EXPAND_RECURSIVE = "EXPANDRECURSIVE";
|
||||
private static final String ACTION_SAVE_TO_FILE = "SAVETOFILE";
|
||||
private static final String ACTION_PARSE_ACTIONS = "PARSEACTIONS";
|
||||
private static final String ACTION_PARSE_ABC = "PARSEABC";
|
||||
private static final String ACTION_PARSE_INSTRUCTIONS = "PARSEINSTRUCTIONS";
|
||||
|
||||
private final MainPanel mainPanel;
|
||||
|
||||
@@ -131,6 +137,16 @@ public class DumpTree extends JTree implements ActionListener {
|
||||
parseActionsMenuItem.addActionListener(this);
|
||||
contextPopupMenu.add(parseActionsMenuItem);
|
||||
|
||||
final JMenuItem parseAbcMenuItem = new JMenuItem(mainPanel.translate("contextmenu.parseABC"));
|
||||
parseAbcMenuItem.setActionCommand(ACTION_PARSE_ABC);
|
||||
parseAbcMenuItem.addActionListener(this);
|
||||
contextPopupMenu.add(parseAbcMenuItem);
|
||||
|
||||
final JMenuItem parseInstructionsMenuItem = new JMenuItem(mainPanel.translate("contextmenu.parseInstructions"));
|
||||
parseInstructionsMenuItem.setActionCommand(ACTION_PARSE_INSTRUCTIONS);
|
||||
parseInstructionsMenuItem.addActionListener(this);
|
||||
contextPopupMenu.add(parseInstructionsMenuItem);
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
@@ -150,6 +166,8 @@ public class DumpTree extends JTree implements ActionListener {
|
||||
expandRecursiveMenuItem.setVisible(false);
|
||||
saveToFileMenuItem.setVisible(false);
|
||||
parseActionsMenuItem.setVisible(false);
|
||||
parseAbcMenuItem.setVisible(false);
|
||||
parseInstructionsMenuItem.setVisible(false);
|
||||
|
||||
if (paths.length == 1) {
|
||||
DumpInfo treeNode = (DumpInfo) paths[0].getLastPathComponent();
|
||||
@@ -162,10 +180,19 @@ public class DumpTree extends JTree implements ActionListener {
|
||||
saveToFileMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
// todo honfika: do not use string names, because it has conflicts e.g with DefineFont.code
|
||||
if (treeNode.name.equals("actionBytes") && treeNode.getChildCount() == 0) {
|
||||
parseActionsMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
if (treeNode.name.equals("abcBytes") && treeNode.getChildCount() == 0) {
|
||||
parseAbcMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
if (treeNode.name.equals("code") && treeNode.parent.name.equals("method_body") && treeNode.getChildCount() == 0) {
|
||||
parseInstructionsMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
TreeModel model = getModel();
|
||||
expandRecursiveMenuItem.setVisible(model.getChildCount(treeNode) > 0);
|
||||
}
|
||||
@@ -229,11 +256,46 @@ public class DumpTree extends JTree implements ActionListener {
|
||||
rri.readAction(new ConstantPool());
|
||||
dumpInfo.getChildInfos().add(di);
|
||||
}
|
||||
repaint();
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
Logger.getLogger(DumpTree.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_PARSE_ABC: {
|
||||
TreePath[] paths = getSelectionPaths();
|
||||
DumpInfo dumpInfo = (DumpInfo) paths[0].getLastPathComponent();
|
||||
SWF swf = DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf();
|
||||
byte[] data = swf.uncompressedData;
|
||||
int prevLength = (int) dumpInfo.startByte;
|
||||
try {
|
||||
ABCInputStream ais = new ABCInputStream(new MemoryInputStream(data, 0, prevLength + (int) dumpInfo.lengthBytes));
|
||||
ais.seek(prevLength);
|
||||
ais.dumpInfo = dumpInfo;
|
||||
new ABC(ais, swf, null);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DumpTree.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
break;
|
||||
case ACTION_PARSE_INSTRUCTIONS: {
|
||||
TreePath[] paths = getSelectionPaths();
|
||||
DumpInfo dumpInfo = (DumpInfo) paths[0].getLastPathComponent();
|
||||
SWF swf = DumpInfoSwfNode.getSwfNode(dumpInfo).getSwf();
|
||||
byte[] data = swf.uncompressedData;
|
||||
int prevLength = (int) dumpInfo.startByte;
|
||||
try {
|
||||
ABCInputStream ais = new ABCInputStream(new MemoryInputStream(data, 0, prevLength + (int) dumpInfo.lengthBytes));
|
||||
ais.seek(prevLength);
|
||||
ais.dumpInfo = dumpInfo;
|
||||
new AVM2Code(ais);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DumpTree.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
break;
|
||||
case ACTION_CLOSE_SWF: {
|
||||
Main.closeFile(mainPanel.getCurrentSwfList());
|
||||
}
|
||||
|
||||
@@ -511,3 +511,5 @@ header.displayrect.value.pixels = %xmin%,%ymin% => %xmax%,%ymax% pixels
|
||||
|
||||
contextmenu.saveToFile = Save to File
|
||||
contextmenu.parseActions = Parse actions
|
||||
contextmenu.parseABC = Parse ABC
|
||||
contextmenu.parseInstructions = Parse AVM2 Instrctions
|
||||
|
||||
@@ -511,3 +511,5 @@ header.displayrect.value.pixels = %xmin%,%ymin% => %xmax%,%ymax% k\u00e9ppont
|
||||
|
||||
contextmenu.saveToFile = Ment\u00e9s f\u00e1jlba
|
||||
contextmenu.parseActions = Action-\u00f6k elemz\u00e9se
|
||||
contextmenu.parseABC = ABC elemz\u00e9se
|
||||
contextmenu.parseInstructions = AVM2 utas\u00edt\u00e1sok elemz\u00e9se
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ABCInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
@@ -74,7 +75,11 @@ public class DoABCDefineTag extends Tag implements ABCContainerTag {
|
||||
super(sis.getSwf(), ID, "DoABCDefine", data);
|
||||
flags = sis.readUI32("flags");
|
||||
name = sis.readString("name");
|
||||
abc = new ABC(sis, swf, this);
|
||||
|
||||
ABCInputStream ais = new ABCInputStream(sis.getBaseStream());
|
||||
// put it to the dumpview:
|
||||
sis.readBytesEx(sis.available(), "abcBytes");
|
||||
abc = new ABC(ais, swf, this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ABCInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
@@ -59,7 +60,11 @@ public class DoABCTag extends Tag implements ABCContainerTag {
|
||||
*/
|
||||
public DoABCTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, "DoABC", data);
|
||||
abc = new ABC(sis, swf, this);
|
||||
|
||||
ABCInputStream ais = new ABCInputStream(sis.getBaseStream());
|
||||
// put it to the dumpview:
|
||||
sis.readBytesEx(sis.available(), "abcBytes");
|
||||
abc = new ABC(ais, swf, this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user