mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-26 01:30:43 +00:00
Added Checkstyle to build process and fixing checkstyle to all com.src.jpexs classes
This commit is contained in:
@@ -29,8 +29,8 @@ import java.util.Set;
|
||||
public abstract class BaseLocalData {
|
||||
|
||||
public GraphSourceItem lineStartInstruction;
|
||||
|
||||
|
||||
public Set<GraphPart> allSwitchParts = new HashSet<>();
|
||||
|
||||
|
||||
public SecondPassData secondPassData = null;
|
||||
}
|
||||
|
||||
@@ -207,8 +207,7 @@ public class DecompilerPool {
|
||||
|
||||
public void shutdown() throws InterruptedException {
|
||||
executor.shutdown();
|
||||
if (!executor.awaitTermination(100, TimeUnit.SECONDS)) {
|
||||
}
|
||||
executor.awaitTermination(100, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public void destroySwf(SWF swf) {
|
||||
|
||||
@@ -21,5 +21,6 @@ package com.jpexs.decompiler.flash;
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface DeobfuscationListener {
|
||||
|
||||
public void itemDeobfuscated();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -67,7 +66,7 @@ public class HarmanDecryption {
|
||||
return ret & 0xffffffffL;
|
||||
}
|
||||
|
||||
private static long unpack(byte data[], int start) {
|
||||
private static long unpack(byte[] data, int start) {
|
||||
return (data[start] & 0xff)
|
||||
+ ((long) (data[start + 1] & 0xff) << 8)
|
||||
+ ((long) (data[start + 2] & 0xff) << 16)
|
||||
@@ -82,7 +81,7 @@ public class HarmanDecryption {
|
||||
//get the length
|
||||
DataInputStream dais = new DataInputStream(is);
|
||||
|
||||
byte encryptedLengthBytes[] = new byte[4];
|
||||
byte[] encryptedLengthBytes = new byte[4];
|
||||
dais.readFully(encryptedLengthBytes);
|
||||
long encryptedLength = unpack(encryptedLengthBytes, 0);
|
||||
int decryptedLength = (int) (encryptedLength ^ key);
|
||||
@@ -91,7 +90,7 @@ public class HarmanDecryption {
|
||||
int paddedLength = (int) (decryptedLength + 0x1F) & ~0x1F;
|
||||
|
||||
//aes iv
|
||||
byte aesIV[] = new byte[16];
|
||||
byte[] aesIV = new byte[16];
|
||||
System.arraycopy(header, 0, aesIV, 0, header.length); //header
|
||||
System.arraycopy(encryptedLengthBytes, 0, aesIV, 8, 4); //encrypted length
|
||||
aesIV[12] = (byte) (key & 0xff);
|
||||
@@ -105,11 +104,11 @@ public class HarmanDecryption {
|
||||
|
||||
// aes key
|
||||
// this one is stored at the end of the file
|
||||
byte aesKey[] = new byte[32];
|
||||
byte data[] = new byte[paddedLength];
|
||||
byte[] aesKey = new byte[32];
|
||||
byte[] data = new byte[paddedLength];
|
||||
dais.readFully(data);
|
||||
|
||||
byte aesKeyData[] = new byte[32];
|
||||
byte[] aesKeyData = new byte[32];
|
||||
dais.readFully(aesKeyData);
|
||||
|
||||
for (int i = 0; i < 32; i += 4) {
|
||||
@@ -129,7 +128,7 @@ public class HarmanDecryption {
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(aesIV));
|
||||
|
||||
byte decryptedData[] = cipher.doFinal(data);
|
||||
byte[] decryptedData = cipher.doFinal(data);
|
||||
return new ByteArrayInputStream(Arrays.copyOfRange(decryptedData, 0, decryptedLength));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ public class IdentifiersDeobfuscation {
|
||||
|
||||
public static boolean isValidNameWithSlash(String s, String... exceptions) {
|
||||
if (s.contains(":")) {
|
||||
String pathVar[] = s.split(":");
|
||||
String[] pathVar = s.split(":");
|
||||
if (!isValidSlashPath(pathVar[0], exceptions)) {
|
||||
return false;
|
||||
}
|
||||
@@ -393,7 +393,7 @@ public class IdentifiersDeobfuscation {
|
||||
* @param s Identifier
|
||||
* @param validExceptions Exceptions which are valid (e.g. some reserved
|
||||
* words)
|
||||
* @return
|
||||
* @return Printable identifier
|
||||
*/
|
||||
public static String printIdentifier(boolean as3, String s, String... validExceptions) {
|
||||
if (s == null || s.isEmpty()) {
|
||||
|
||||
@@ -37,9 +37,9 @@ public class OpenableSourceInfo {
|
||||
private String fileTitle;
|
||||
|
||||
private final boolean detectBundle;
|
||||
|
||||
|
||||
private boolean empty = false;
|
||||
|
||||
|
||||
private OpenableSourceKind kind;
|
||||
|
||||
public OpenableSourceInfo(String fileTitle) {
|
||||
@@ -49,11 +49,12 @@ public class OpenableSourceInfo {
|
||||
|
||||
public boolean isEmpty() {
|
||||
return empty;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public OpenableSourceInfo(InputStream inputStream, String file, String fileTitle) {
|
||||
this(inputStream, file, fileTitle, true);
|
||||
}
|
||||
|
||||
public OpenableSourceInfo(InputStream inputStream, String file, String fileTitle, boolean detectBundle) {
|
||||
this.inputStream = inputStream;
|
||||
this.file = file;
|
||||
@@ -64,7 +65,7 @@ public class OpenableSourceInfo {
|
||||
|
||||
public OpenableSourceKind getKind() {
|
||||
return kind;
|
||||
}
|
||||
}
|
||||
|
||||
private void detectKind() {
|
||||
if (isBundle()) {
|
||||
@@ -75,7 +76,7 @@ public class OpenableSourceInfo {
|
||||
kind = OpenableSourceKind.SWF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return inputStream;
|
||||
}
|
||||
@@ -89,7 +90,7 @@ public class OpenableSourceInfo {
|
||||
detectKind();
|
||||
empty = false;
|
||||
}
|
||||
|
||||
|
||||
public void setFileTitle(String fileTitle) {
|
||||
this.fileTitle = fileTitle;
|
||||
}
|
||||
@@ -110,7 +111,7 @@ public class OpenableSourceInfo {
|
||||
return file;
|
||||
}
|
||||
|
||||
public boolean isBundle() {
|
||||
public boolean isBundle() {
|
||||
if (inputStream == null && file != null) {
|
||||
File fileObj = new File(file);
|
||||
String fileName = fileObj.getName();
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.jpexs.decompiler.flash;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <T>
|
||||
* @param <T> Type of result
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class RunnableIOExResult<T> implements RunnableIOEx {
|
||||
|
||||
@@ -69,7 +69,7 @@ public class SWC extends ZippedBundle {
|
||||
};
|
||||
saxParser.parse(zip, handler);
|
||||
} catch (Exception ex) {
|
||||
|
||||
//ignored
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.FunctionActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetMemberActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.GetVariableActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.SetMemberActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.ClassActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.clauses.InterfaceActionItem;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionEquals;
|
||||
@@ -414,8 +413,8 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
private AbcIndexing abcIndex;
|
||||
|
||||
private int numAbcIndexDependencies = 0;
|
||||
|
||||
private Map<String, Map<String, com.jpexs.decompiler.flash.action.as2.Trait>> uninitializedAs2ClassTraits = null;
|
||||
|
||||
private volatile Map<String, Map<String, com.jpexs.decompiler.flash.action.as2.Trait>> uninitializedAs2ClassTraits = null;
|
||||
|
||||
private static AbcIndexing playerGlobalAbcIndex;
|
||||
|
||||
@@ -1110,7 +1109,6 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* Saves this SWF into new file
|
||||
*
|
||||
* @param os OutputStream to save SWF in
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public void saveTo(OutputStream os) throws IOException {
|
||||
@@ -1165,16 +1163,16 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private byte[] saveToByteArray(boolean includeImported) throws IOException {
|
||||
return saveToByteArray(gfx, includeImported);
|
||||
}
|
||||
|
||||
private void checkCharset() {
|
||||
if (version > 5) {
|
||||
charset = Utf8Helper.charsetName;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] saveToByteArray(boolean includeImported) throws IOException {
|
||||
return saveToByteArray(gfx, includeImported);
|
||||
}
|
||||
|
||||
private byte[] saveToByteArray(boolean gfx, boolean includeImported) throws IOException {
|
||||
byte[] data;
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); SWFOutputStream sos = new SWFOutputStream(baos, version, charset)) {
|
||||
@@ -1201,109 +1199,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress SWF file
|
||||
*
|
||||
* @param is InputStream
|
||||
* @param os OutputStream to save SWF in
|
||||
* @param compression
|
||||
* @param lzmaProperties
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void compress(InputStream is, OutputStream os, SWFCompression compression, byte[] lzmaProperties) throws IOException {
|
||||
byte[] hdr = new byte[8];
|
||||
|
||||
is.mark(8);
|
||||
|
||||
// SWFheader: signature, version and fileSize
|
||||
if (is.read(hdr) != 8) {
|
||||
throw new SwfOpenException("SWF header is too short");
|
||||
}
|
||||
|
||||
boolean uncompressed = hdr[0] == 'F' || hdr[0] == 'G'; // FWS or GFX
|
||||
if (!uncompressed) {
|
||||
// fisrt decompress, then compress to the given format
|
||||
is.reset();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
decompress(is, baos, false);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
compress(bais, os, compression, lzmaProperties);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean gfx = hdr[1] == 'F' && hdr[2] == 'X';
|
||||
int version = hdr[3];
|
||||
long fileSize;
|
||||
try (SWFInputStream sis = new SWFInputStream(null, Arrays.copyOfRange(hdr, 4, 8), 4, 4)) {
|
||||
fileSize = sis.readUI32("fileSize");
|
||||
}
|
||||
|
||||
SWFOutputStream sos = new SWFOutputStream(os, version, Utf8Helper.charsetName);
|
||||
sos.write(getHeaderBytes(compression, gfx));
|
||||
sos.writeUI8(version);
|
||||
sos.writeUI32(fileSize);
|
||||
|
||||
if (compression == SWFCompression.LZMA || compression == SWFCompression.LZMA_ABC) {
|
||||
long uncompressedLength = fileSize - 8;
|
||||
Encoder enc = new Encoder();
|
||||
if (lzmaProperties == null) {
|
||||
// todo: the bytes are from a sample swf
|
||||
lzmaProperties = new byte[]{93, 0, 0, 32, 0};
|
||||
}
|
||||
|
||||
int val = lzmaProperties[0] & 0xFF;
|
||||
int lc = val % 9;
|
||||
int remainder = val / 9;
|
||||
int lp = remainder % 5;
|
||||
int pb = remainder / 5;
|
||||
int dictionarySize = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
dictionarySize += ((int) (lzmaProperties[1 + i]) & 0xFF) << (i * 8);
|
||||
}
|
||||
if (Configuration.lzmaFastBytes.get() > 0) {
|
||||
enc.SetNumFastBytes(Configuration.lzmaFastBytes.get());
|
||||
}
|
||||
enc.SetDictionarySize(dictionarySize);
|
||||
enc.SetLcLpPb(lc, lp, pb);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
enc.SetEndMarkerMode(true);
|
||||
enc.Code(is, baos, -1, -1, null);
|
||||
byte[] data = baos.toByteArray();
|
||||
if (compression == SWFCompression.LZMA) {
|
||||
byte[] udata = new byte[4];
|
||||
udata[0] = (byte) (data.length & 0xFF);
|
||||
udata[1] = (byte) ((data.length >> 8) & 0xFF);
|
||||
udata[2] = (byte) ((data.length >> 16) & 0xFF);
|
||||
udata[3] = (byte) ((data.length >> 24) & 0xFF);
|
||||
os.write(udata);
|
||||
}
|
||||
enc.WriteCoderProperties(os);
|
||||
if (compression == SWFCompression.LZMA_ABC) {
|
||||
byte[] udata = new byte[8];
|
||||
udata[0] = (byte) (uncompressedLength & 0xFF);
|
||||
udata[1] = (byte) ((uncompressedLength >> 8) & 0xFF);
|
||||
udata[2] = (byte) ((uncompressedLength >> 16) & 0xFF);
|
||||
udata[3] = (byte) ((uncompressedLength >> 24) & 0xFF);
|
||||
udata[4] = (byte) ((uncompressedLength >> 32) & 0xFF);
|
||||
udata[5] = (byte) ((uncompressedLength >> 40) & 0xFF);
|
||||
udata[6] = (byte) ((uncompressedLength >> 48) & 0xFF);
|
||||
udata[7] = (byte) ((uncompressedLength >> 56) & 0xFF);
|
||||
os.write(udata);
|
||||
}
|
||||
os.write(data);
|
||||
} else if (compression == SWFCompression.ZLIB) {
|
||||
DeflaterOutputStream dos = new DeflaterOutputStream(os);
|
||||
try {
|
||||
Helper.copyStream(is, dos);
|
||||
} finally {
|
||||
dos.finish();
|
||||
}
|
||||
} else {
|
||||
Helper.copyStream(is, os);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
@@ -1366,8 +1262,6 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
*
|
||||
* @param is Stream to read SWF from
|
||||
* @param parallelRead Use parallel threads?
|
||||
* @throws IOException
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public SWF(InputStream is, boolean parallelRead) throws IOException, InterruptedException {
|
||||
this(is, null, null, null, parallelRead, false, true);
|
||||
@@ -1382,9 +1276,6 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
*
|
||||
* @param is Stream to read SWF from
|
||||
* @param parallelRead Use parallel threads?
|
||||
* @param lazy
|
||||
* @throws IOException
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public SWF(InputStream is, boolean parallelRead, boolean lazy) throws IOException, InterruptedException {
|
||||
this(is, null, null, null, parallelRead, false, lazy);
|
||||
@@ -1401,8 +1292,6 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* @param file Path to the file
|
||||
* @param fileTitle Title of the SWF
|
||||
* @param parallelRead Use parallel threads?
|
||||
* @throws IOException
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public SWF(InputStream is, String file, String fileTitle, boolean parallelRead) throws IOException, InterruptedException {
|
||||
this(is, file, fileTitle, null, parallelRead, false, true);
|
||||
@@ -1416,10 +1305,8 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* Construct SWF from stream
|
||||
*
|
||||
* @param is Stream to read SWF from
|
||||
* @param listener
|
||||
* @param listener Progress listener
|
||||
* @param parallelRead Use parallel threads?
|
||||
* @throws IOException
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public SWF(InputStream is, ProgressListener listener, boolean parallelRead) throws IOException, InterruptedException {
|
||||
this(is, null, null, listener, parallelRead, false, true);
|
||||
@@ -1435,10 +1322,8 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
* @param is Stream to read SWF from
|
||||
* @param file Path to the file
|
||||
* @param fileTitle Title of the SWF
|
||||
* @param listener
|
||||
* @param listener Progress listener
|
||||
* @param parallelRead Use parallel threads?
|
||||
* @throws IOException
|
||||
* @throws java.lang.InterruptedException
|
||||
*/
|
||||
public SWF(InputStream is, String file, String fileTitle, ProgressListener listener, boolean parallelRead) throws IOException, InterruptedException {
|
||||
this(is, file, fileTitle, listener, parallelRead, false, true);
|
||||
@@ -1450,9 +1335,6 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
|
||||
/**
|
||||
* Faster constructor to check SWF only
|
||||
*
|
||||
* @param is
|
||||
* @throws java.io.IOException
|
||||
*/
|
||||
public SWF(InputStream is) throws IOException {
|
||||
decompress(is, new NulStream(), true);
|
||||
@@ -1471,23 +1353,23 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
}
|
||||
|
||||
public SWF(InputStream is, String file, String fileTitle, ProgressListener listener, boolean parallelRead, boolean checkOnly, boolean lazy, UrlResolver resolver, String charset) throws IOException, InterruptedException {
|
||||
this(is, file, fileTitle, listener, parallelRead,checkOnly, lazy, resolver, charset, true);
|
||||
}
|
||||
this(is, file, fileTitle, listener, parallelRead, checkOnly, lazy, resolver, charset, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct SWF from stream
|
||||
*
|
||||
* @param is Stream to read SWF from
|
||||
* @param file Path to the file
|
||||
* @param fileTitle Title of the SWF
|
||||
* @param listener
|
||||
* @param listener Progress listener
|
||||
* @param parallelRead Use parallel threads?
|
||||
* @param checkOnly Check only file validity
|
||||
* @param lazy
|
||||
* @param lazy Lazy load
|
||||
* @param resolver Resolver for imported tags
|
||||
* @param charset Character set for all texts (for older SWF versions)
|
||||
* @param allowRenameIdentifiers Allow auto renaming identifiers when enabled
|
||||
* @throws IOException
|
||||
* @throws java.lang.InterruptedException
|
||||
* @param allowRenameIdentifiers Allow auto renaming identifiers when
|
||||
* enabled
|
||||
*/
|
||||
public SWF(InputStream is, String file, String fileTitle, ProgressListener listener, boolean parallelRead, boolean checkOnly, boolean lazy, UrlResolver resolver, String charset, boolean allowRenameIdentifiers) throws IOException, InterruptedException {
|
||||
this.file = file;
|
||||
@@ -1539,7 +1421,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
assignClassesToSymbols();
|
||||
if (Configuration.autoLoadEmbeddedSwfs.get()) {
|
||||
loadAllEmbeddedSwfs();
|
||||
}
|
||||
}
|
||||
SWFDecompilerPlugin.fireSwfParsed(this);
|
||||
} else {
|
||||
boolean hasNonUnknownTag = false;
|
||||
@@ -1567,8 +1449,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
getASMs(true); // Add scriptNames to ASMs
|
||||
}
|
||||
|
||||
private void loadAllEmbeddedSwfs()
|
||||
{
|
||||
private void loadAllEmbeddedSwfs() {
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof DefineBinaryDataTag) {
|
||||
DefineBinaryDataTag binaryData = (DefineBinaryDataTag) t;
|
||||
@@ -1576,7 +1457,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void resolveImported(UrlResolver resolver) {
|
||||
for (int p = 0; p < tags.size(); p++) {
|
||||
Tag t = tags.get(p);
|
||||
@@ -1835,9 +1716,8 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
|
||||
/**
|
||||
* Gets title of this SWF incuding parent nodes like SwfList and
|
||||
* DefineBinaryData
|
||||
* DefineBinaryData.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getShortPathTitle() {
|
||||
@@ -1854,9 +1734,8 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
|
||||
/**
|
||||
* Gets full path title of this SWF incuding parent nodes like SwfList and
|
||||
* DefineBinaryData
|
||||
* DefineBinaryData.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getFullPathTitle() {
|
||||
@@ -1889,6 +1768,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
}
|
||||
}
|
||||
} catch (SecurityException sex) {
|
||||
//ignored
|
||||
}
|
||||
|
||||
return new Date();
|
||||
@@ -1934,16 +1814,16 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
|
||||
public void assignClassesToSymbols() {
|
||||
HashMap<Integer, LinkedHashSet<String>> classes = new HashMap<>();
|
||||
|
||||
|
||||
for (int ch : importedTagToClassesMapping.keySet()) {
|
||||
classes.put(ch, new LinkedHashSet<>(importedTagToClassesMapping.get(ch)));
|
||||
}
|
||||
|
||||
|
||||
Set<String> uniqueClasses = new HashSet<>();
|
||||
for (Tag t : getTags()) {
|
||||
if (t instanceof SymbolClassTag) {
|
||||
SymbolClassTag sct = (SymbolClassTag) t;
|
||||
for (int i = 0; i < sct.tags.size(); i++) {
|
||||
for (int i = 0; i < sct.tags.size(); i++) {
|
||||
if (!classes.containsKey(sct.tags.get(i))) {
|
||||
classes.put(sct.tags.get(i), new LinkedHashSet<>());
|
||||
}
|
||||
@@ -1964,25 +1844,124 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
continue;
|
||||
}
|
||||
if (classes.containsKey(ct.getCharacterId())) {
|
||||
ct.setClassNames(classes.get((Integer)ct.getCharacterId()));
|
||||
ct.setClassNames(classes.get((Integer) ct.getCharacterId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
classToCharacter.clear();
|
||||
for (int ch : classes.keySet()) {
|
||||
for (String cls:classes.get(ch)) {
|
||||
for (String cls : classes.get(ch)) {
|
||||
classToCharacter.put(cls, ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress SWF file
|
||||
*
|
||||
* @param is InputStream
|
||||
* @param os OutputStream to save SWF in
|
||||
*/
|
||||
private static void compress(InputStream is, OutputStream os, SWFCompression compression, byte[] lzmaProperties) throws IOException {
|
||||
byte[] hdr = new byte[8];
|
||||
|
||||
is.mark(8);
|
||||
|
||||
// SWFheader: signature, version and fileSize
|
||||
if (is.read(hdr) != 8) {
|
||||
throw new SwfOpenException("SWF header is too short");
|
||||
}
|
||||
|
||||
boolean uncompressed = hdr[0] == 'F' || hdr[0] == 'G'; // FWS or GFX
|
||||
if (!uncompressed) {
|
||||
// fisrt decompress, then compress to the given format
|
||||
is.reset();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
decompress(is, baos, false);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
compress(bais, os, compression, lzmaProperties);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean gfx = hdr[1] == 'F' && hdr[2] == 'X';
|
||||
int version = hdr[3];
|
||||
long fileSize;
|
||||
try (SWFInputStream sis = new SWFInputStream(null, Arrays.copyOfRange(hdr, 4, 8), 4, 4)) {
|
||||
fileSize = sis.readUI32("fileSize");
|
||||
}
|
||||
|
||||
SWFOutputStream sos = new SWFOutputStream(os, version, Utf8Helper.charsetName);
|
||||
sos.write(getHeaderBytes(compression, gfx));
|
||||
sos.writeUI8(version);
|
||||
sos.writeUI32(fileSize);
|
||||
|
||||
if (compression == SWFCompression.LZMA || compression == SWFCompression.LZMA_ABC) {
|
||||
long uncompressedLength = fileSize - 8;
|
||||
Encoder enc = new Encoder();
|
||||
if (lzmaProperties == null) {
|
||||
// todo: the bytes are from a sample swf
|
||||
lzmaProperties = new byte[]{93, 0, 0, 32, 0};
|
||||
}
|
||||
|
||||
int val = lzmaProperties[0] & 0xFF;
|
||||
int lc = val % 9;
|
||||
int remainder = val / 9;
|
||||
int lp = remainder % 5;
|
||||
int pb = remainder / 5;
|
||||
int dictionarySize = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
dictionarySize += ((int) (lzmaProperties[1 + i]) & 0xFF) << (i * 8);
|
||||
}
|
||||
if (Configuration.lzmaFastBytes.get() > 0) {
|
||||
enc.SetNumFastBytes(Configuration.lzmaFastBytes.get());
|
||||
}
|
||||
enc.SetDictionarySize(dictionarySize);
|
||||
enc.SetLcLpPb(lc, lp, pb);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
enc.SetEndMarkerMode(true);
|
||||
enc.Code(is, baos, -1, -1, null);
|
||||
byte[] data = baos.toByteArray();
|
||||
if (compression == SWFCompression.LZMA) {
|
||||
byte[] udata = new byte[4];
|
||||
udata[0] = (byte) (data.length & 0xFF);
|
||||
udata[1] = (byte) ((data.length >> 8) & 0xFF);
|
||||
udata[2] = (byte) ((data.length >> 16) & 0xFF);
|
||||
udata[3] = (byte) ((data.length >> 24) & 0xFF);
|
||||
os.write(udata);
|
||||
}
|
||||
enc.WriteCoderProperties(os);
|
||||
if (compression == SWFCompression.LZMA_ABC) {
|
||||
byte[] udata = new byte[8];
|
||||
udata[0] = (byte) (uncompressedLength & 0xFF);
|
||||
udata[1] = (byte) ((uncompressedLength >> 8) & 0xFF);
|
||||
udata[2] = (byte) ((uncompressedLength >> 16) & 0xFF);
|
||||
udata[3] = (byte) ((uncompressedLength >> 24) & 0xFF);
|
||||
udata[4] = (byte) ((uncompressedLength >> 32) & 0xFF);
|
||||
udata[5] = (byte) ((uncompressedLength >> 40) & 0xFF);
|
||||
udata[6] = (byte) ((uncompressedLength >> 48) & 0xFF);
|
||||
udata[7] = (byte) ((uncompressedLength >> 56) & 0xFF);
|
||||
os.write(udata);
|
||||
}
|
||||
os.write(data);
|
||||
} else if (compression == SWFCompression.ZLIB) {
|
||||
DeflaterOutputStream dos = new DeflaterOutputStream(os);
|
||||
try {
|
||||
Helper.copyStream(is, dos);
|
||||
} finally {
|
||||
dos.finish();
|
||||
}
|
||||
} else {
|
||||
Helper.copyStream(is, os);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress SWF file
|
||||
*
|
||||
* @param fis Input stream
|
||||
* @param fos Output stream
|
||||
* @param compression
|
||||
* @param compression Compression type
|
||||
* @return True on success
|
||||
*/
|
||||
public static boolean compress(InputStream fis, OutputStream fos, SWFCompression compression) {
|
||||
@@ -1992,23 +1971,11 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean decompress(InputStream fis, OutputStream fos) {
|
||||
try {
|
||||
decompress(fis, fos, false);
|
||||
return true;
|
||||
} catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts Harman AIR encryption
|
||||
* @param is
|
||||
* @param os
|
||||
* @return
|
||||
* @throws IOException
|
||||
*
|
||||
*/
|
||||
public static boolean decrypt(InputStream is, OutputStream os) throws IOException {
|
||||
byte[] hdr = new byte[8];
|
||||
@@ -2017,9 +1984,9 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
if (is.read(hdr) != 8) {
|
||||
throw new SwfOpenException(AppResources.translate("error.swf.headerTooShort"));
|
||||
}
|
||||
|
||||
|
||||
decodeHeader(hdr);
|
||||
|
||||
|
||||
switch (hdr[0]) {
|
||||
case 'c':
|
||||
case 'z':
|
||||
@@ -2032,7 +1999,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
return true;
|
||||
} catch (IOException | InvalidAlgorithmParameterException | InvalidKeyException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException ex) {
|
||||
throw new SwfOpenException(AppResources.translate("error.swf.decryptionProblem"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2065,6 +2032,15 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
header.gfx = headerData[1] == 'F' && headerData[2] == 'X';
|
||||
return header;
|
||||
}
|
||||
|
||||
public static boolean decompress(InputStream fis, OutputStream fos) {
|
||||
try {
|
||||
decompress(fis, fos, false);
|
||||
return true;
|
||||
} catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static SWFHeader decompress(InputStream is, OutputStream os, boolean allowUncompressed) throws IOException {
|
||||
|
||||
@@ -2344,7 +2320,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
if (treeItem instanceof AS2Package) {
|
||||
AS2Package pkg = (AS2Package) treeItem;
|
||||
if (pkg.isFlat()) {
|
||||
String parts[] = pkg.toString().split("\\.");
|
||||
String[] parts = pkg.toString().split("\\.");
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
parts[i] = Helper.makeFileName(parts[i]);
|
||||
}
|
||||
@@ -2489,7 +2465,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
val >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void createWavFromPcmData(OutputStream fos, int soundRateHz, boolean soundSize, boolean soundType, byte[] data) throws IOException {
|
||||
ByteArrayOutputStream subChunk1Data = new ByteArrayOutputStream();
|
||||
int audioFormat = 1; // PCM
|
||||
@@ -3173,22 +3149,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
return new AffineTransform(mat.getScaleXFloat(), mat.getRotateSkew0Float(),
|
||||
mat.getRotateSkew1Float(), mat.getScaleYFloat(),
|
||||
mat.translateX, mat.translateY);
|
||||
}
|
||||
|
||||
public SerializableImage getFromCache(String key) {
|
||||
if (frameCache.contains(key)) {
|
||||
return frameCache.get(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte[] getFromCache(SOUNDINFO soundInfo, SoundTag soundTag) {
|
||||
SoundInfoSoundCacheEntry key = new SoundInfoSoundCacheEntry(soundInfo, soundTag);
|
||||
if (soundCache.contains(key)) {
|
||||
return soundCache.get(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void putToCache(String key, SerializableImage img) {
|
||||
if (Configuration.useFrameCache.get()) {
|
||||
@@ -3290,6 +3251,17 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
swf.as3Cache.remove(pack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isActionListCached(ASMSource src) {
|
||||
if (src != null) {
|
||||
SWF swf = src.getSwf();
|
||||
if (swf != null) {
|
||||
return swf.as2Cache.isPCodeCached(src);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isCached(ASMSource src) {
|
||||
@@ -3303,17 +3275,6 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isActionListCached(ASMSource src) {
|
||||
if (src != null) {
|
||||
SWF swf = src.getSwf();
|
||||
if (swf != null) {
|
||||
return swf.as2Cache.isPCodeCached(src);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isCached(ScriptPack pack) {
|
||||
if (pack != null) {
|
||||
Openable openable = pack.getOpenable();
|
||||
@@ -3336,18 +3297,22 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ActionList getActionListFromCache(ASMSource src) {
|
||||
if (src != null) {
|
||||
SWF swf = src.getSwf();
|
||||
if (swf != null) {
|
||||
return swf.as2Cache.getPCode(src);
|
||||
}
|
||||
|
||||
public SerializableImage getFromCache(String key) {
|
||||
if (frameCache.contains(key)) {
|
||||
return frameCache.get(key);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte[] getFromCache(SOUNDINFO soundInfo, SoundTag soundTag) {
|
||||
SoundInfoSoundCacheEntry key = new SoundInfoSoundCacheEntry(soundInfo, soundTag);
|
||||
if (soundCache.contains(key)) {
|
||||
return soundCache.get(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static HighlightedText getFromCache(ScriptPack pack) {
|
||||
if (pack != null) {
|
||||
Openable openable = pack.getOpenable();
|
||||
@@ -3360,6 +3325,17 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ActionList getActionListFromCache(ASMSource src) {
|
||||
if (src != null) {
|
||||
SWF swf = src.getSwf();
|
||||
if (swf != null) {
|
||||
return swf.as2Cache.getPCode(src);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ActionList getCachedActionList(ASMSource src, final List<DisassemblyListener> listeners) throws InterruptedException {
|
||||
synchronized (src) {
|
||||
SWF swf = src.getSwf();
|
||||
@@ -3534,6 +3510,14 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean removeCharacterFromTimeline(int characterId, Timeline timeline, TagRemoveListener listener) {
|
||||
Set<Integer> chars = new HashSet<>();
|
||||
chars.add(characterId);
|
||||
return removeTagWithDependenciesFromTimeline(null, timeline, chars, listener);
|
||||
}
|
||||
|
||||
private void removeTagWithDependenciesFromTimeline(Tag toRemove, Timeline timeline, TagRemoveListener listener) {
|
||||
Set<Integer> dependingChars = new HashSet<>();
|
||||
if (toRemove instanceof CharacterTag) {
|
||||
@@ -3546,12 +3530,6 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
removeTagWithDependenciesFromTimeline(toRemove, timeline, dependingChars, listener);
|
||||
}
|
||||
|
||||
public boolean removeCharacterFromTimeline(int characterId, Timeline timeline, TagRemoveListener listener) {
|
||||
Set<Integer> chars = new HashSet<>();
|
||||
chars.add(characterId);
|
||||
return removeTagWithDependenciesFromTimeline(null, timeline, chars, listener);
|
||||
}
|
||||
|
||||
private boolean removeTagWithDependenciesFromTimeline(Tag toRemove, Timeline timeline, Set<Integer> dependingChars, TagRemoveListener listener) {
|
||||
Map<Integer, Integer> stage = new HashMap<>();
|
||||
Timelined timelined = timeline.timelined;
|
||||
@@ -3723,8 +3701,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
timelined.removeTag(tag);
|
||||
timelined.setModified(true);
|
||||
timelined.resetTimeline();
|
||||
} else // timeline should be always the swf here
|
||||
if (removeDependencies) {
|
||||
} else if (removeDependencies) { // timeline should be always the swf here
|
||||
removeTagWithDependenciesFromTimeline(tag, timelined.getTimeline(), listener);
|
||||
timelined.setModified(true);
|
||||
} else {
|
||||
@@ -3756,8 +3733,6 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
|
||||
/**
|
||||
* Adds a tag to the SWF
|
||||
*
|
||||
* @param tag
|
||||
*/
|
||||
@Override
|
||||
public void addTag(Tag tag) {
|
||||
@@ -3768,31 +3743,13 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
|
||||
/**
|
||||
* Adds a tag to the SWF
|
||||
*
|
||||
* @param index
|
||||
* @param tag
|
||||
*/
|
||||
@Override
|
||||
public void addTag(int index, Tag tag) {
|
||||
setModified(true);
|
||||
tags.add(index, tag);
|
||||
updateCharacters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a tag in the SWF
|
||||
*
|
||||
* @param oldTag
|
||||
* @param newTag
|
||||
*/
|
||||
public void replaceTag(Tag oldTag, Tag newTag) {
|
||||
setModified(true);
|
||||
int index = tags.indexOf(oldTag);
|
||||
if (index != -1) {
|
||||
tags.set(index, newTag);
|
||||
updateCharacters();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int indexOfTag(Tag tag) {
|
||||
return tags.indexOf(tag);
|
||||
@@ -3937,39 +3894,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
|
||||
((Tag) tag).setModified(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables debugging. Adds tags to enable debugging and optinally injects
|
||||
* debugline and debugfile instructions to AS3 code by decompiling it first
|
||||
*
|
||||
* @param injectAS3Code Modify AS3 code with debugfile / debugline ?
|
||||
* @param decompileDir Directory to virtual decompile (will affect
|
||||
* debugfile)
|
||||
*/
|
||||
public void enableDebugging(boolean injectAS3Code, File decompileDir) throws InterruptedException {
|
||||
enableDebugging(injectAS3Code, decompileDir, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables debugging. Adds tags to enable debugging.
|
||||
*/
|
||||
public void enableDebugging() throws InterruptedException {
|
||||
enableDebugging(false, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables debugging. Adds tags to enable debugging and injects debugline
|
||||
* and debugfile instructions to AS3 code. Optionally enables Telemetry
|
||||
*
|
||||
* @param injectAS3Code Modify AS3 code with debugfile / debugline ?
|
||||
* @param decompileDir Directory to virtual decompile (will affect
|
||||
* debugfile)
|
||||
* @param telemetry Enable telemetry info?
|
||||
*/
|
||||
public void enableDebugging(boolean injectAS3Code, File decompileDir, boolean telemetry) throws InterruptedException {
|
||||
enableDebugging(injectAS3Code, decompileDir, telemetry, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects debugline and debugfile instructions to AS3 P-code (lines of
|
||||
@@ -4011,6 +3936,38 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables debugging. Adds tags to enable debugging and optinally injects
|
||||
* debugline and debugfile instructions to AS3 code by decompiling it first
|
||||
*
|
||||
* @param injectAS3Code Modify AS3 code with debugfile / debugline ?
|
||||
* @param decompileDir Directory to virtual decompile (will affect
|
||||
* debugfile)
|
||||
*/
|
||||
public void enableDebugging(boolean injectAS3Code, File decompileDir) throws InterruptedException {
|
||||
enableDebugging(injectAS3Code, decompileDir, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables debugging. Adds tags to enable debugging.
|
||||
*/
|
||||
public void enableDebugging() throws InterruptedException {
|
||||
enableDebugging(false, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables debugging. Adds tags to enable debugging and injects debugline
|
||||
* and debugfile instructions to AS3 code. Optionally enables Telemetry
|
||||
*
|
||||
* @param injectAS3Code Modify AS3 code with debugfile / debugline ?
|
||||
* @param decompileDir Directory to virtual decompile (will affect
|
||||
* debugfile)
|
||||
* @param telemetry Enable telemetry info?
|
||||
*/
|
||||
public void enableDebugging(boolean injectAS3Code, File decompileDir, boolean telemetry) throws InterruptedException {
|
||||
enableDebugging(injectAS3Code, decompileDir, telemetry, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables debugging. Adds tags to enable debugging and injects debugline
|
||||
* and debugfile instructions to AS3 code. Optionally enables Telemetry
|
||||
@@ -4481,6 +4438,19 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a tag in the SWF
|
||||
*/
|
||||
@Override
|
||||
public void replaceTag(Tag oldTag, Tag newTag) {
|
||||
setModified(true);
|
||||
int index = tags.indexOf(oldTag);
|
||||
if (index != -1) {
|
||||
tags.set(index, newTag);
|
||||
updateCharacters();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceTag(int index, Tag newTag) {
|
||||
removeTag(index);
|
||||
@@ -4567,7 +4537,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
public OpenableList getOpenableList() {
|
||||
return openableList;
|
||||
}
|
||||
|
||||
|
||||
public void calculateAs2UninitializedClassTraits() {
|
||||
uninitializedAs2ClassTraits = new HashMap<>();
|
||||
UninitializedClassFieldsDetector detector = new UninitializedClassFieldsDetector();
|
||||
@@ -4579,5 +4549,5 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
calculateAs2UninitializedClassTraits();
|
||||
}
|
||||
return uninitializedAs2ClassTraits;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class SWFHeader {
|
||||
* ScaleForm GFx
|
||||
*/
|
||||
public boolean gfx = false;
|
||||
|
||||
|
||||
/**
|
||||
* Harman SWF Encryption
|
||||
*/
|
||||
|
||||
@@ -328,7 +328,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
}
|
||||
return swf.getCharset();
|
||||
}
|
||||
|
||||
|
||||
public void addPercentListener(ProgressListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
@@ -369,7 +369,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
this.swf = swf;
|
||||
this.startingPos = startingPos;
|
||||
this.data = data;
|
||||
this.limit = limit;
|
||||
this.limit = limit;
|
||||
is = new MemoryInputStream(data, 0, limit);
|
||||
}
|
||||
|
||||
@@ -516,7 +516,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
baos.write(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads one netstring (length + string) value from the stream
|
||||
*
|
||||
@@ -608,7 +608,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
}
|
||||
return uval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads one SI16 (Signed 16bit integer) value from the stream
|
||||
*
|
||||
@@ -622,7 +622,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
endDumpLevel(uval);
|
||||
return uval;
|
||||
}
|
||||
|
||||
|
||||
private int readSI16Internal() throws IOException {
|
||||
int uval = readEx() + (readEx() << 8);
|
||||
if (uval >= 0x8000) {
|
||||
@@ -669,7 +669,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
public double readFIXED(String name) throws IOException {
|
||||
newDumpLevel(name, "FIXED");
|
||||
long si = readSI32Internal();
|
||||
double ret = si / (double)(1 << 16);
|
||||
double ret = si / (double) (1 << 16);
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -684,7 +684,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
public float readFIXED8(String name) throws IOException {
|
||||
newDumpLevel(name, "FIXED8");
|
||||
int si = readSI16Internal();
|
||||
float ret = si / (float)(1 << 8);
|
||||
float ret = si / (float) (1 << 8);
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -3089,9 +3089,9 @@ public class SWFInputStream implements AutoCloseable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads one MORPHFOCALGRADIENT value from the stream
|
||||
* Reads one MORPHFOCALGRADIENT value from the stream.
|
||||
*
|
||||
* This is undocumented feature
|
||||
* <p>This is undocumented feature
|
||||
*
|
||||
* @param name
|
||||
* @return MORPHGRADIENT value
|
||||
|
||||
@@ -106,7 +106,7 @@ public class SWFOutputStream extends OutputStream {
|
||||
private int bitPos = 0;
|
||||
|
||||
private int tempByte = 0;
|
||||
|
||||
|
||||
private String charset;
|
||||
|
||||
public long getPos() {
|
||||
@@ -206,7 +206,7 @@ public class SWFOutputStream extends OutputStream {
|
||||
byte[] data = value.getBytes(charset);
|
||||
writeUI8(data.length);
|
||||
write(data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes UI32 (Unsigned 32bit integer) value to the stream
|
||||
@@ -501,31 +501,7 @@ public class SWFOutputStream extends OutputStream {
|
||||
for (Tag tag : tags) {
|
||||
tag.writeTag(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates number of bits needed for representing unsigned value
|
||||
*
|
||||
* @param value Unsigned value
|
||||
* @return Number of bits
|
||||
*/
|
||||
public static int getNeededBitsU(int value) {
|
||||
if (value == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
value = Math.abs(value);
|
||||
long x = 1;
|
||||
int nBits;
|
||||
|
||||
for (nBits = 1; nBits <= 64; nBits++) {
|
||||
x <<= 1;
|
||||
if (x > value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nBits;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates number of bits needed for representing signed value
|
||||
@@ -559,6 +535,30 @@ public class SWFOutputStream extends OutputStream {
|
||||
}
|
||||
return nBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates number of bits needed for representing unsigned value
|
||||
*
|
||||
* @param value Unsigned value
|
||||
* @return Number of bits
|
||||
*/
|
||||
public static int getNeededBitsU(int value) {
|
||||
if (value == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
value = Math.abs(value);
|
||||
long x = 1;
|
||||
int nBits;
|
||||
|
||||
for (nBits = 1; nBits <= 64; nBits++) {
|
||||
x <<= 1;
|
||||
if (x > value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nBits;
|
||||
}
|
||||
|
||||
public static int getNeededBitsU(int first, int... params) {
|
||||
int nBits = 0;
|
||||
@@ -1654,9 +1654,9 @@ public class SWFOutputStream extends OutputStream {
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes MORPHFOCALGRADIENT value to the stream
|
||||
* Writes MORPHFOCALGRADIENT value to the stream.
|
||||
*
|
||||
* Undocumented feature
|
||||
* <p>Undocumented feature
|
||||
*
|
||||
* @param value MORPHGRADIENT value
|
||||
* @param shapeNum 1 in DefineMorphShape, 2 in DefineMorphShape2,...
|
||||
|
||||
@@ -76,7 +76,7 @@ public class SWFSearch {
|
||||
|
||||
@Override
|
||||
public void status(String status) {
|
||||
}
|
||||
}
|
||||
},
|
||||
"FWS".getBytes(), // Uncompressed Flash
|
||||
"CWS".getBytes(), // ZLib compressed Flash
|
||||
@@ -86,8 +86,8 @@ public class SWFSearch {
|
||||
"fWS".getBytes(), //Harman encrypted uncompressed Flash,
|
||||
"cWS".getBytes(), //Harman encrypted ZLib compressed Flash,
|
||||
"zWS".getBytes() //Harman encrypted LZMA compressed Flash
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
int pos = 0;
|
||||
long biggestSize = 0;
|
||||
long smallestSize = Long.MAX_VALUE;
|
||||
@@ -137,6 +137,7 @@ public class SWFSearch {
|
||||
} catch (OutOfMemoryError ome) {
|
||||
Helper.freeMem();
|
||||
} catch (Exception | Error ex) {
|
||||
//ignored
|
||||
}
|
||||
}
|
||||
setProgress(100);
|
||||
|
||||
@@ -69,7 +69,7 @@ public class SourceGeneratorLocalData implements Serializable {
|
||||
public List<GraphTargetItem> scopeStack = new ArrayList<>();
|
||||
|
||||
public ScriptInfo currentScript;
|
||||
|
||||
|
||||
public int scriptIndex;
|
||||
|
||||
public boolean subMethod = false;
|
||||
@@ -84,7 +84,7 @@ public class SourceGeneratorLocalData implements Serializable {
|
||||
|
||||
public List<List<Long>> catchesOpenedLoops = new ArrayList<>();
|
||||
public List<Integer> catchesTempRegs = new ArrayList<>();
|
||||
|
||||
|
||||
public boolean secondRun = false;
|
||||
|
||||
public String getFullClass() {
|
||||
|
||||
@@ -23,5 +23,6 @@ import com.jpexs.decompiler.flash.tags.Tag;
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface TagRemoveListener {
|
||||
|
||||
public void tagRemoved(Tag tag);
|
||||
}
|
||||
|
||||
@@ -21,8 +21,9 @@ package com.jpexs.decompiler.flash;
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ValueTooLargeException extends IllegalArgumentException {
|
||||
|
||||
private final String type;
|
||||
private final Object value;
|
||||
private final Object value;
|
||||
|
||||
public ValueTooLargeException(String type, Object value) {
|
||||
super("Value is too large for " + type + ": " + value);
|
||||
@@ -37,5 +38,5 @@ public class ValueTooLargeException extends IllegalArgumentException {
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -50,13 +50,13 @@ import com.jpexs.decompiler.flash.abc.usages.ClassNameMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.ConstVarNameMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.ConstVarTypeMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.DefinitionUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.SuperClassMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.SuperInterfaceMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.MethodBodyMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.MethodNameMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.MethodParamsMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.MethodReturnTypeMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.MultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.SuperClassMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.SuperInterfaceMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.TraitMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.abc.usages.TypeNameMultinameUsage;
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfo;
|
||||
@@ -72,7 +72,6 @@ import com.jpexs.decompiler.flash.treeitems.Openable;
|
||||
import com.jpexs.decompiler.flash.treeitems.OpenableList;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import com.jpexs.helpers.utf8.Utf8PrintWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -1961,7 +1960,7 @@ public class ABC implements Openable {
|
||||
getSwf().clearScriptCache();
|
||||
getMethodIndexing();
|
||||
getSwf().getAbcIndex().refreshAbc(this);
|
||||
|
||||
|
||||
fireChanged();
|
||||
}
|
||||
|
||||
@@ -2054,17 +2053,17 @@ public class ABC implements Openable {
|
||||
//Method Info
|
||||
for (int i = 0; i < secondABC.method_info.size(); i++) {
|
||||
MethodInfo secondMethodInfo = secondABC.method_info.get(i);
|
||||
int newParamTypes[] = new int[secondMethodInfo.param_types.length];
|
||||
int[] newParamTypes = new int[secondMethodInfo.param_types.length];
|
||||
for (int t = 0; t < secondMethodInfo.param_types.length; t++) {
|
||||
newParamTypes[t] = mergeMultinameMap.get(secondMethodInfo.param_types[t]);
|
||||
}
|
||||
int newParamNames[] = new int[secondMethodInfo.paramNames.length];
|
||||
int[] newParamNames = new int[secondMethodInfo.paramNames.length];
|
||||
for (int n = 0; n < secondMethodInfo.paramNames.length; n++) {
|
||||
newParamNames[n] = mergeStringMap.get(secondMethodInfo.paramNames[n]);
|
||||
}
|
||||
int newRetType = mergeMultinameMap.get(secondMethodInfo.ret_type);
|
||||
int newNameIndex = mergeStringMap.get(secondMethodInfo.name_index);
|
||||
ValueKind newOptional[] = new ValueKind[secondMethodInfo.optional.length];
|
||||
ValueKind[] newOptional = new ValueKind[secondMethodInfo.optional.length];
|
||||
for (int k = 0; k < secondMethodInfo.optional.length; k++) {
|
||||
int vkind = secondMethodInfo.optional[k].value_kind;
|
||||
Map<Integer, Integer> valueMergeMap = null;
|
||||
@@ -2175,7 +2174,7 @@ public class ABC implements Openable {
|
||||
}
|
||||
AVM2Code newCode = newBody.getCode();
|
||||
for (AVM2Instruction newIns : newCode.code) {
|
||||
int newOperands[] = newIns.operands == null ? null : newIns.operands.clone();
|
||||
int[] newOperands = newIns.operands == null ? null : newIns.operands.clone();
|
||||
boolean modified = false;
|
||||
if (newIns.operands != null) {
|
||||
for (int i = 0; i < newIns.definition.operands.length; i++) {
|
||||
|
||||
@@ -34,7 +34,6 @@ import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfo;
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfoSpecial;
|
||||
import com.jpexs.decompiler.flash.dumpview.DumpInfoSpecialType;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -524,7 +523,7 @@ public class ABCInputStream implements AutoCloseable {
|
||||
stringDataBuffer = new byte[newLength];
|
||||
}
|
||||
|
||||
safeRead(length, stringDataBuffer);
|
||||
safeRead(length, stringDataBuffer);
|
||||
String r = Utf8Helper.decode(stringDataBuffer, 0, length);
|
||||
endDumpLevel(r);
|
||||
return r;
|
||||
|
||||
@@ -25,9 +25,9 @@ import java.io.IOException;
|
||||
public class ABCOpenException extends IOException {
|
||||
|
||||
public ABCOpenException(String message) {
|
||||
super(message);
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
public ABCOpenException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
@@ -47,14 +47,14 @@ public class ABCOutputStream extends OutputStream {
|
||||
|
||||
public long getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
os.write(b);
|
||||
position++;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(byte[] data) throws IOException {
|
||||
super.write(data);
|
||||
@@ -66,7 +66,7 @@ public class ABCOutputStream extends OutputStream {
|
||||
super.write(b, off, len);
|
||||
position += len;
|
||||
}
|
||||
|
||||
|
||||
public void writeU30(long value) throws IOException {
|
||||
writeS32(value);
|
||||
/*boolean loop = true;
|
||||
|
||||
@@ -50,19 +50,19 @@ public class AVM2LocalData extends BaseLocalData {
|
||||
public HashMap<Integer, GraphTargetItem> localRegs;
|
||||
|
||||
public ScopeStack scopeStack;
|
||||
|
||||
|
||||
public ScopeStack localScopeStack;
|
||||
|
||||
public MethodBody methodBody;
|
||||
|
||||
|
||||
public List<MethodBody> callStack;
|
||||
|
||||
public ABC abc;
|
||||
|
||||
|
||||
public AbcIndexing abcIndex;
|
||||
|
||||
public HashMap<Integer, String> localRegNames;
|
||||
|
||||
|
||||
public HashMap<Integer, GraphTargetItem> localRegTypes;
|
||||
|
||||
public List<DottedChain> fullyQualifiedNames;
|
||||
@@ -92,11 +92,11 @@ public class AVM2LocalData extends BaseLocalData {
|
||||
public Map<Integer, GraphPart> defaultParts = new HashMap<>();
|
||||
|
||||
public Map<Integer, Integer> switchedRegs = new HashMap<>();
|
||||
|
||||
|
||||
public Map<Integer, GraphPart> pushDefaultPart = new HashMap<>();
|
||||
|
||||
public Map<Integer, Integer> finallyKinds = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* exception index -> switch throw part
|
||||
*/
|
||||
@@ -112,7 +112,7 @@ public class AVM2LocalData extends BaseLocalData {
|
||||
public HashMap<Integer, Integer> localRegAssignmentIps;
|
||||
|
||||
public Integer ip;
|
||||
|
||||
|
||||
public AVM2Code code;
|
||||
|
||||
public boolean thisHasDefaultToPrimitive;
|
||||
@@ -126,7 +126,7 @@ public class AVM2LocalData extends BaseLocalData {
|
||||
public boolean inGetLoops = false;
|
||||
|
||||
public Set<Integer> seenMethods = new HashSet<>();
|
||||
|
||||
|
||||
public AVM2LocalData() {
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitClass;
|
||||
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.Traits;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.ScriptExportSettings;
|
||||
@@ -116,7 +115,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
this.path = path;
|
||||
this.allABCs = allAbcs;
|
||||
}
|
||||
|
||||
|
||||
public DottedChain getPathPackage() {
|
||||
DottedChain packageName = DottedChain.TOPLEVEL;
|
||||
for (int t : traitIndices) {
|
||||
@@ -182,15 +181,14 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
}*/
|
||||
writer.mark();
|
||||
List<MethodBody> callStack = new ArrayList<>();
|
||||
callStack.add(abc.bodies.get(sinit_bodyIndex));
|
||||
abc.bodies.get(sinit_bodyIndex).convert(callStack, abcIndex, convertData, path +/*packageName +*/ "/.scriptinitializer", exportMode, true, sinit_index, scriptIndex, -1, abc, null, new ScopeStack(), GraphTextWriter.TRAIT_SCRIPT_INITIALIZER, writer, new ArrayList<>(), abc.script_info.get(scriptIndex).traits, true, new HashSet<>());
|
||||
scriptInitializerIsEmpty = !writer.getMark();
|
||||
|
||||
callStack.add(abc.bodies.get(sinit_bodyIndex));
|
||||
abc.bodies.get(sinit_bodyIndex).convert(callStack, abcIndex, convertData, path + "/.scriptinitializer", exportMode, true, sinit_index, scriptIndex, -1, abc, null, new ScopeStack(), GraphTextWriter.TRAIT_SCRIPT_INITIALIZER, writer, new ArrayList<>(), abc.script_info.get(scriptIndex).traits, true, new HashSet<>());
|
||||
scriptInitializerIsEmpty = !writer.getMark();
|
||||
|
||||
}
|
||||
ScopeStack scopeStack = new ScopeStack();
|
||||
scopeStack.push(new GlobalAVM2Item(null, null));
|
||||
|
||||
|
||||
|
||||
for (int t : traitIndices) {
|
||||
Trait trait = traits.get(t);
|
||||
Multiname name = trait.getName(abc);
|
||||
@@ -208,8 +206,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
//script initializer
|
||||
int script_init = abc.script_info.get(scriptIndex).init_index;
|
||||
int bodyIndex = abc.findBodyIndex(script_init);
|
||||
|
||||
|
||||
|
||||
if (!isSimple && traitIndices.isEmpty()) {
|
||||
for (Trait t : abc.script_info.get(scriptIndex).traits.traits) {
|
||||
String fullName = t.getName(abc).getNameWithNamespace(abc.constants, false).toPrintableString(true);
|
||||
@@ -217,7 +214,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
}
|
||||
writer.newLine();
|
||||
}
|
||||
|
||||
|
||||
if (bodyIndex != -1 && (isSimple || traitIndices.isEmpty())) {
|
||||
//Note: There must be trait/method highlight even if the initializer is empty to TraitList in GUI to work correctly
|
||||
//TODO: handle this better in GUI(?)
|
||||
@@ -227,8 +224,8 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
if (!scriptInitializerIsEmpty) {
|
||||
writer.startBlock();
|
||||
List<MethodBody> callStack = new ArrayList<>();
|
||||
callStack.add(abc.bodies.get(bodyIndex));
|
||||
abc.bodies.get(bodyIndex).toString(callStack, abcIndex, path +/*packageName +*/ "/.scriptinitializer", exportMode, abc, null, writer, new ArrayList<>(), new HashSet<>());
|
||||
callStack.add(abc.bodies.get(bodyIndex));
|
||||
abc.bodies.get(bodyIndex).toString(callStack, abcIndex, path + "/.scriptinitializer", exportMode, abc, null, writer, new ArrayList<>(), new HashSet<>());
|
||||
writer.endBlock();
|
||||
} else {
|
||||
writer.append("");
|
||||
@@ -239,7 +236,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
if (!scriptInitializerIsEmpty) {
|
||||
writer.newLine();
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int t : traitIndices) {
|
||||
@@ -250,7 +247,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
Trait trait = traits.get(t);
|
||||
|
||||
//if (!(trait instanceof TraitClass)) {
|
||||
writer.startTrait(t);
|
||||
writer.startTrait(t);
|
||||
//}
|
||||
Multiname name = trait.getName(abc);
|
||||
int nskind = name.getSimpleNamespaceKind(abc.constants);
|
||||
@@ -259,8 +256,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
} else {
|
||||
trait.toString(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, false);
|
||||
}
|
||||
if (!(trait instanceof TraitClass))
|
||||
{
|
||||
if (!(trait instanceof TraitClass)) {
|
||||
writer.endTrait();
|
||||
}
|
||||
first = false;
|
||||
@@ -367,7 +363,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
}
|
||||
return abc.script_info.get(scriptIndex).isModified();
|
||||
}
|
||||
|
||||
|
||||
public void clearModified() {
|
||||
if (scriptIndex >= abc.script_info.size()) {
|
||||
return;
|
||||
@@ -376,8 +372,9 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects debugfile, debugline instructions into the code
|
||||
* Injects debugfile, debugline instructions into the code.
|
||||
*
|
||||
* <p>
|
||||
* Based on idea of Jacob Thompson
|
||||
* http://securityevaluators.com/knowledge/flash/
|
||||
*/
|
||||
@@ -396,7 +393,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
|
||||
for (int i = 0; i < txt.length(); i++) {
|
||||
blk:
|
||||
{
|
||||
while (true) {
|
||||
Highlighting sh = Highlighting.searchPos(decompiled.getSpecialHighlights(), i);
|
||||
|
||||
Highlighting cls = Highlighting.searchPos(decompiled.getClassHighlights(), i);
|
||||
@@ -479,6 +476,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
bodyToRegToLine.get(bodyIndex).put(regIndex, line);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (txt.charAt(i) == '\n') {
|
||||
line++;
|
||||
@@ -589,7 +587,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
|
||||
for (int i = 0; i < txt.length(); i++) {
|
||||
blk:
|
||||
{
|
||||
while (true) {
|
||||
Highlighting sh = Highlighting.searchPos(decompiled.getSpecialHighlights(), i);
|
||||
|
||||
Highlighting cls = Highlighting.searchPos(decompiled.getClassHighlights(), i);
|
||||
@@ -618,6 +616,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
}
|
||||
}
|
||||
bodyToIdentifier.put(bodyIndex, "abc:" + abcIndex + ",script:" + scriptIndex + ",class:" + classIndex + ",trait:" + traitIndex + ",method:" + methodIndex + ",body:" + bodyIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
|
||||
@@ -129,6 +129,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal2Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal3Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.BkptIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.BkptLineIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.DeletePropertyIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindDefIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns;
|
||||
@@ -137,6 +139,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetDescendantsIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetGlobalScopeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetGlobalSlotIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetOuterScopeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetScopeObjectIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetSlotIns;
|
||||
@@ -156,55 +159,50 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSlotIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSuperIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.AbsJumpIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.AddDIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.TimestampIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.AddPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.AllocIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.BkptIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.BkptLineIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.CallInterfaceIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.CallSuperIdIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.CodeGenOpIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.deprecated.CoerceBIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.deprecated.CoerceDIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.deprecated.CoerceIIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceOIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.deprecated.CoerceUIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.ConcatIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.floatsupport.ConvertF4Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.floatsupport.ConvertFIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.ConvertMIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.ConvertMPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.DecLocalPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.DecodeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.DecrementPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.DelDescendantsIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.DeletePropertyLateIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.DividePIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.DoubleToAtomIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.FindPropGlobalIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetOuterScopeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.IncLocalPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.IncrementPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.InvalidIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.floatsupport.Lf32x4Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.MarkIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.ModuloPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.MultiplyPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.NegatePIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.PrologueIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.PushConstantIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.PushDNanIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.PushDecimalIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.SubtractPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.deprecated.CoerceBIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.deprecated.CoerceDIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.deprecated.CoerceIIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.deprecated.CoerceUIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.floatsupport.ConvertF4Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.floatsupport.ConvertFIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.floatsupport.Lf32x4Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.floatsupport.PushFloat4Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.floatsupport.PushFloatIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.floatsupport.Sf32x4Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.floatsupport.UnPlusIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.AbsJumpIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.AddDIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.AllocIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.CallInterfaceIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.CallSuperIdIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.CodeGenOpIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.ConcatIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.DecodeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.DelDescendantsIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.DeletePropertyLateIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.DoubleToAtomIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.InvalidIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.MarkIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.PrologueIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.PushConstantIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.SendEnterIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.SetPropertyLateIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.floatsupport.Sf32x4Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.decimalsupport.SubtractPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.SweepIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.TimestampIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.floatsupport.UnPlusIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.VerifyOpIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.VerifyPassIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.unknown.WbIns;
|
||||
@@ -231,6 +229,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeLateIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceAIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceOIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceOrConvertTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceSIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertBIns;
|
||||
@@ -278,7 +277,6 @@ import com.jpexs.decompiler.flash.abc.types.ConvertData;
|
||||
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.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
@@ -442,7 +440,8 @@ public class AVM2Code implements Cloneable {
|
||||
{"setlocal0", "setlocal_0"},
|
||||
{"setlocal1", "setlocal_1"},
|
||||
{"setlocal2", "setlocal_2"},
|
||||
{"setlocal3", "setlocal_3"},};
|
||||
{"setlocal3", "setlocal_3"}
|
||||
};
|
||||
public static final Map<String, String> instructionAliases = new HashMap<>();
|
||||
|
||||
static {
|
||||
@@ -714,7 +713,8 @@ public class AVM2Code implements Cloneable {
|
||||
/*0xFC*/ new SweepIns(),
|
||||
/*0xFD*/ new CodeGenOpIns(),
|
||||
/*0xFE*/ new VerifyOpIns(),
|
||||
/*0xFF*/ new DecodeIns(),};
|
||||
/*0xFF*/ new DecodeIns()
|
||||
};
|
||||
// endoflist
|
||||
|
||||
static {
|
||||
@@ -726,11 +726,9 @@ public class AVM2Code implements Cloneable {
|
||||
instructionSet[opCode] = allInstructionSet[i];
|
||||
} else if (instructionSet[opCode].hasFlag(AVM2InstructionFlag.NO_FLASH_PLAYER) && !allInstructionSet[i].hasFlag(AVM2InstructionFlag.NO_FLASH_PLAYER)) {
|
||||
instructionSet[opCode] = allInstructionSet[i];
|
||||
} //Prefer without decimal:
|
||||
else if (instructionSet[opCode].hasFlag(AVM2InstructionFlag.ES4_NUMERICS_MINOR) && !allInstructionSet[i].hasFlag(AVM2InstructionFlag.ES4_NUMERICS_MINOR)) {
|
||||
} else if (instructionSet[opCode].hasFlag(AVM2InstructionFlag.ES4_NUMERICS_MINOR) && !allInstructionSet[i].hasFlag(AVM2InstructionFlag.ES4_NUMERICS_MINOR)) { //Prefer without decimal:
|
||||
instructionSet[opCode] = allInstructionSet[i];
|
||||
} //Prefer without float:
|
||||
else if (instructionSet[opCode].hasFlag(AVM2InstructionFlag.FLOAT_MAJOR) && !allInstructionSet[i].hasFlag(AVM2InstructionFlag.FLOAT_MAJOR)) {
|
||||
} else if (instructionSet[opCode].hasFlag(AVM2InstructionFlag.FLOAT_MAJOR) && !allInstructionSet[i].hasFlag(AVM2InstructionFlag.FLOAT_MAJOR)) { //Prefer without float:
|
||||
instructionSet[opCode] = allInstructionSet[i];
|
||||
}
|
||||
}
|
||||
@@ -949,8 +947,7 @@ public class AVM2Code implements Cloneable {
|
||||
address = unAdresses.remove(0);
|
||||
handleJumps = false;
|
||||
}
|
||||
if (address < startPos) // no jump outside block
|
||||
{
|
||||
if (address < startPos) { // no jump outside block
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
@@ -1159,6 +1156,7 @@ public class AVM2Code implements Cloneable {
|
||||
cos.write(instruction.getBytes());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
//ignored
|
||||
}
|
||||
return bos.toByteArray();
|
||||
}
|
||||
@@ -1430,14 +1428,14 @@ public class AVM2Code implements Cloneable {
|
||||
|
||||
AVM2Instruction ins = code.get(code.size() - 1);
|
||||
return (int) (ins.getAddress() + ins.getBytesLength());
|
||||
}
|
||||
}
|
||||
|
||||
private int toSourceCount = 0;
|
||||
|
||||
public Map<Integer, String> getLocalRegNamesFromDebug(ABC abc, int maxRegs) {
|
||||
Map<Integer, String> regIndexToName = new HashMap<>();
|
||||
Map<String, Integer> regNameToIndex = new HashMap<>();
|
||||
|
||||
|
||||
Set<String> reservedRegNames = new HashSet<>();
|
||||
for (int i = 0; i < maxRegs; i++) {
|
||||
reservedRegNames.add(String.format(Configuration.registerNameFormat.get(), i));
|
||||
@@ -1447,14 +1445,14 @@ public class AVM2Code implements Cloneable {
|
||||
if (ins.definition instanceof DebugIns) {
|
||||
if (ins.operands[0] == 1) {
|
||||
String v = abc.constants.getString(ins.operands[1]);
|
||||
|
||||
|
||||
if (reservedRegNames.contains(v)) {
|
||||
//do not allow reassigning reserved _loc%d_ format to other local regs
|
||||
continue;
|
||||
}
|
||||
|
||||
int regIndex = ins.operands[2] + 1;
|
||||
|
||||
|
||||
int regIndex = ins.operands[2] + 1;
|
||||
|
||||
// Same name already exists, it may be wrong names inserted by obfuscator
|
||||
if (regNameToIndex.containsKey(v)) {
|
||||
int existingIndex = regNameToIndex.get(v);
|
||||
@@ -1471,7 +1469,7 @@ public class AVM2Code implements Cloneable {
|
||||
|
||||
// TODO: Make this immune to using existing multinames (?)
|
||||
return regIndexToName;
|
||||
}
|
||||
}
|
||||
|
||||
public int getIpThroughJumpAndDebugLine(int ip) {
|
||||
if (code.isEmpty()) {
|
||||
@@ -1625,7 +1623,7 @@ public class AVM2Code implements Cloneable {
|
||||
if (code.get(ip + plus + 4).definition instanceof PopScopeIns) {
|
||||
if (code.get(ip + plus + 3).definition instanceof SetPropertyIns) {
|
||||
functionName = abc.constants.getMultiname(code.get(ip + plus + 3).operands[0]).getName(abc.constants, fullyQualifiedNames, true, true);
|
||||
localScopeStack.pop();// with
|
||||
localScopeStack.pop(); // with
|
||||
output.remove(output.size() - 1); // with
|
||||
ip = ip + plus + 4; // +1 below
|
||||
}
|
||||
@@ -1762,14 +1760,14 @@ public class AVM2Code implements Cloneable {
|
||||
} else if (assignment.value instanceof GetLexAVM2Item) {
|
||||
vtype = assignment.value.returnType();
|
||||
}
|
||||
|
||||
|
||||
boolean isNull = false;
|
||||
if (vtype.equals(new TypeItem(DottedChain.NULL))) {
|
||||
vtype = TypeItem.UNBOUNDED;
|
||||
isNull = true;
|
||||
}
|
||||
|
||||
if (declaredRegisters[reg] == null) {
|
||||
if (declaredRegisters[reg] == null) {
|
||||
declaredRegisters[reg] = new DeclarationAVM2Item(assignment, vtype);
|
||||
if (assignment instanceof SetTypeAVM2Item) {
|
||||
((SetTypeAVM2Item) assignment).setDeclaration(declaredRegisters[reg]);
|
||||
@@ -1782,7 +1780,7 @@ public class AVM2Code implements Cloneable {
|
||||
declaredRegisters[reg].type = vtype;
|
||||
declaredRegisters[reg].typeIsNull = isNull;
|
||||
} else if (declaredRegisters[reg].type == TypeItem.UNBOUNDED) {
|
||||
|
||||
//empty
|
||||
} else if (!declaredRegisters[reg].type.equals(vtype)) { //already declared with different type
|
||||
declaredRegisters[reg].type = TypeItem.UNBOUNDED;
|
||||
}
|
||||
@@ -2088,7 +2086,7 @@ public class AVM2Code implements Cloneable {
|
||||
if ((ss.slotObject instanceof GlobalAVM2Item) && (initializerType == GraphTextWriter.TRAIT_SCRIPT_INITIALIZER)) {
|
||||
for (Trait t : initTraits.traits) {
|
||||
if (t instanceof TraitSlotConst) {
|
||||
TraitSlotConst tsc = (TraitSlotConst)t;
|
||||
TraitSlotConst tsc = (TraitSlotConst) t;
|
||||
if (tsc.slot_id == ss.slotIndex) {
|
||||
GraphTargetItem value = ss.value;
|
||||
if (value != null && !convertData.assignedValues.containsKey(tsc)) {
|
||||
@@ -2173,7 +2171,7 @@ public class AVM2Code implements Cloneable {
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// In obfuscated code, SetLocal instructions comes first
|
||||
@@ -2293,13 +2291,7 @@ public class AVM2Code implements Cloneable {
|
||||
target = ins.getAddress() + ins.operands[k];
|
||||
ins.operands[k] = updater.updateOperandOffset(ins.getAddress(), target, ins.operands[k]);
|
||||
}
|
||||
} else /*for (int j = 0; j < ins.definition.operands.length; j++) {
|
||||
if (ins.definition.operands[j] == AVM2Code.DAT_OFFSET) {
|
||||
long target = ins.offset + ins.getBytes().length + ins.operands[j];
|
||||
ins.operands[j] = updater.updateOperandOffset(target, ins.operands[j]);
|
||||
}
|
||||
}*/ //Faster, but not so universal
|
||||
if (ins.definition instanceof IfTypeIns) {
|
||||
} else if (ins.definition instanceof IfTypeIns) {
|
||||
long target = ins.getTargetAddress();
|
||||
try {
|
||||
ins.operands[0] = updater.updateOperandOffset(ins.getAddress(), target, ins.operands[0]);
|
||||
@@ -2419,20 +2411,7 @@ public class AVM2Code implements Cloneable {
|
||||
}, body);
|
||||
code.remove(pos);
|
||||
//checkValidOffsets(body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts instruction at specified point. Handles offsets properly. Note:
|
||||
* If newinstruction is jump, the offset operand must be handled properly by
|
||||
* caller. All old jump offsets to pos are targeted before new instruction.
|
||||
*
|
||||
* @param pos Position in the list
|
||||
* @param instruction Instruction False means before new instruction
|
||||
* @param body Method body (used for try handling)
|
||||
*/
|
||||
public void insertInstruction(int pos, AVM2Instruction instruction, MethodBody body) {
|
||||
insertInstruction(pos, instruction, false, body);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces instruction by another. Properly handles offsets. Note: If
|
||||
@@ -2475,6 +2454,19 @@ public class AVM2Code implements Cloneable {
|
||||
code.set(pos, instruction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts instruction at specified point. Handles offsets properly. Note:
|
||||
* If newinstruction is jump, the offset operand must be handled properly by
|
||||
* caller. All old jump offsets to pos are targeted before new instruction.
|
||||
*
|
||||
* @param pos Position in the list
|
||||
* @param instruction Instruction False means before new instruction
|
||||
* @param body Method body (used for try handling)
|
||||
*/
|
||||
public void insertInstruction(int pos, AVM2Instruction instruction, MethodBody body) {
|
||||
insertInstruction(pos, instruction, false, body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts instruction at specified point. Handles offsets properly. Note:
|
||||
* If newinstruction is jump, the offset operand must be handled properly by
|
||||
@@ -2745,7 +2737,7 @@ public class AVM2Code implements Cloneable {
|
||||
return stats;
|
||||
}
|
||||
|
||||
private void visitCode(int ip, int lastIp, HashMap<Integer, List<Integer>> refs) throws InterruptedException {
|
||||
private void visitCode(int ip, int lastIp, HashMap<Integer, List<Integer>> refs) throws InterruptedException {
|
||||
Queue<Integer> toVisit = new LinkedList<>();
|
||||
Queue<Integer> toVisitLast = new LinkedList<>();
|
||||
toVisit.add(ip);
|
||||
@@ -2784,6 +2776,7 @@ public class AVM2Code implements Cloneable {
|
||||
ip = adr2pos(pos2adr(ip) + ins.operands[0]);
|
||||
continue;
|
||||
} catch (ConvertException ex) {
|
||||
//ignored
|
||||
}
|
||||
}
|
||||
if (ins.definition instanceof JumpIns) {
|
||||
@@ -2803,10 +2796,10 @@ public class AVM2Code implements Cloneable {
|
||||
}
|
||||
ip++;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<Integer, List<Integer>> visitCode(MethodBody body) throws InterruptedException {
|
||||
public HashMap<Integer, List<Integer>> visitCode(MethodBody body) throws InterruptedException {
|
||||
HashMap<Integer, List<Integer>> refs = new HashMap<>();
|
||||
for (int i = 0; i < code.size(); i++) {
|
||||
refs.put(i, new ArrayList<>());
|
||||
@@ -2836,7 +2829,7 @@ public class AVM2Code implements Cloneable {
|
||||
public int removeDeadCode(MethodBody body) throws InterruptedException {
|
||||
return removeDeadCode(body, new Reference<>(-1));
|
||||
}
|
||||
|
||||
|
||||
public int removeDeadCode(MethodBody body, Reference<Integer> minChangedIpRef) throws InterruptedException {
|
||||
HashMap<Integer, List<Integer>> refs = visitCode(body);
|
||||
int cnt = 0;
|
||||
@@ -2867,7 +2860,7 @@ public class AVM2Code implements Cloneable {
|
||||
removeIgnored(body);
|
||||
|
||||
minChangedIpRef.setVal(minChangedIp);
|
||||
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,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;
|
||||
|
||||
/**
|
||||
@@ -88,27 +87,26 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
|
||||
@Internal
|
||||
public Map<String, DottedChain> dottedChainCache = new HashMap<>();
|
||||
|
||||
|
||||
@Internal
|
||||
public Map<Multiname, DottedChain> multinameWithNamespaceCache = new HashMap<>();
|
||||
|
||||
|
||||
public DottedChain getCachedMultinameWithNamespace(Multiname multiName) {
|
||||
return multinameWithNamespaceCache.get(multiName);
|
||||
}
|
||||
|
||||
|
||||
public void cacheMultinameWithNamespace(Multiname multiName, DottedChain multinameWithNamespace) {
|
||||
multinameWithNamespaceCache.put(multiName, multinameWithNamespace);
|
||||
}
|
||||
|
||||
|
||||
public void clearCachedMultinames() {
|
||||
multinameWithNamespaceCache.clear();
|
||||
}
|
||||
|
||||
|
||||
public void clearCachedDottedChains() {
|
||||
dottedChainCache.clear();
|
||||
}
|
||||
|
||||
|
||||
private void ensureDefault(List<?> list) {
|
||||
if (list.isEmpty()) {
|
||||
list.add(null);
|
||||
@@ -216,7 +214,7 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
|
||||
public synchronized int addUInt(long value) {
|
||||
ensureDefault(constant_uint);
|
||||
value &= 0xffffffffl;
|
||||
value &= 0xffffffffL;
|
||||
constant_uint.add(value);
|
||||
return constant_uint.size() - 1;
|
||||
}
|
||||
@@ -362,14 +360,6 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
return constant_decimal.get(index);
|
||||
}
|
||||
|
||||
public int getDecimalId(Decimal val, boolean add) {
|
||||
int id = getDecimalId(val);
|
||||
if (add && id == -1) {
|
||||
id = addDecimal(val);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public Float getFloat(int index) {
|
||||
return constant_float.get(index);
|
||||
}
|
||||
@@ -472,38 +462,18 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
return getNamespaceId(kind, nameIndex, index, add);
|
||||
}
|
||||
|
||||
private int getIntId(int value) {
|
||||
return constant_int.indexOf(value);
|
||||
}
|
||||
|
||||
private int getUIntId(long value) {
|
||||
return constant_uint.indexOf(value);
|
||||
}
|
||||
|
||||
private int getDoubleId(double value) {
|
||||
return constant_double.indexOf(value);
|
||||
}
|
||||
|
||||
private int getFloatId(float value) {
|
||||
return constant_float.indexOf(value);
|
||||
}
|
||||
|
||||
private int getFloat4Id(Float4 value) {
|
||||
return constant_float4.indexOf(value);
|
||||
public int getDecimalId(Decimal val, boolean add) {
|
||||
int id = getDecimalId(val);
|
||||
if (add && id == -1) {
|
||||
id = addDecimal(val);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
private int getDecimalId(Decimal value) {
|
||||
return constant_decimal.indexOf(value);
|
||||
}
|
||||
|
||||
private int getStringId(String value) {
|
||||
return constant_string.indexOf(value);
|
||||
}
|
||||
|
||||
private int getMultinameId(Multiname value) {
|
||||
return constant_multiname.indexOf(value);
|
||||
}
|
||||
|
||||
public int getQnameId(String name, int namespaceKind, String namespaceName, boolean add) {
|
||||
return getMultinameId(Multiname.createQName(false, getStringId(name, add), getNamespaceId(namespaceKind, namespaceName, 0, add)), add);
|
||||
}
|
||||
@@ -512,6 +482,10 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
return getQnameId(name, Namespace.KIND_PACKAGE, "", add);
|
||||
}
|
||||
|
||||
private int getMultinameId(Multiname value) {
|
||||
return constant_multiname.indexOf(value);
|
||||
}
|
||||
|
||||
public int getMultinameId(Multiname val, boolean add) {
|
||||
int id = getMultinameId(val);
|
||||
if (add && id == -1) {
|
||||
@@ -538,6 +512,10 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int getStringId(String value) {
|
||||
return constant_string.indexOf(value);
|
||||
}
|
||||
|
||||
public int getStringId(String val, boolean add) {
|
||||
if (val == null) {
|
||||
return 0;
|
||||
@@ -557,6 +535,10 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
return getStringId(val.toRawString(), add);
|
||||
}
|
||||
|
||||
private int getIntId(int value) {
|
||||
return constant_int.indexOf(value);
|
||||
}
|
||||
|
||||
public int getIntId(int val, boolean add) {
|
||||
int id = getIntId(val);
|
||||
if (add && id == -1) {
|
||||
@@ -597,6 +579,10 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
return id;
|
||||
}
|
||||
|
||||
private int getUIntId(long value) {
|
||||
return constant_uint.indexOf(value);
|
||||
}
|
||||
|
||||
public int getUIntId(long val, boolean add) {
|
||||
int id = getUIntId(val);
|
||||
if (add && id == -1) {
|
||||
@@ -605,6 +591,10 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
return id;
|
||||
}
|
||||
|
||||
private int getDoubleId(double value) {
|
||||
return constant_double.indexOf(value);
|
||||
}
|
||||
|
||||
public int getDoubleId(double val, boolean add) {
|
||||
int id = getDoubleId(val);
|
||||
if (add && id == -1) {
|
||||
@@ -613,6 +603,10 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
return id;
|
||||
}
|
||||
|
||||
private int getFloatId(float value) {
|
||||
return constant_float.indexOf(value);
|
||||
}
|
||||
|
||||
public int getFloatId(float val, boolean add) {
|
||||
int id = getFloatId(val);
|
||||
if (add && id == -1) {
|
||||
@@ -621,6 +615,10 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
return id;
|
||||
}
|
||||
|
||||
private int getFloat4Id(Float4 value) {
|
||||
return constant_float4.indexOf(value);
|
||||
}
|
||||
|
||||
public int getFloat4Id(Float4 val, boolean add) {
|
||||
int id = getFloat4Id(val);
|
||||
if (add && id == -1) {
|
||||
@@ -796,7 +794,7 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
Namespace secondNamespace = secondPool.constant_namespace.get(i);
|
||||
int mappedId;
|
||||
int newNameIndex = stringMap.get(secondNamespace.name_index);
|
||||
if (secondNamespace.kind == Namespace.KIND_PRIVATE) {//always add, this does not exists in this ABC. Conflicting private namespaces can have same names.
|
||||
if (secondNamespace.kind == Namespace.KIND_PRIVATE) { //always add, this does not exists in this ABC. Conflicting private namespaces can have same names.
|
||||
mappedId = addNamespace(secondNamespace.kind, newNameIndex);
|
||||
} else {
|
||||
mappedId = getNamespaceId(secondNamespace.kind, newNameIndex, 0, true);
|
||||
@@ -806,7 +804,7 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
namespaceSetMap.put(0, 0);
|
||||
for (int i = 1; i < secondPool.constant_namespace_set.size(); i++) {
|
||||
NamespaceSet secondNamespaceSet = secondPool.constant_namespace_set.get(i);
|
||||
int mappedsNss[] = new int[secondNamespaceSet.namespaces.length];
|
||||
int[] mappedsNss = new int[secondNamespaceSet.namespaces.length];
|
||||
for (int n = 0; n < secondNamespaceSet.namespaces.length; n++) {
|
||||
mappedsNss[n] = namespaceMap.get(secondNamespaceSet.namespaces[n]);
|
||||
}
|
||||
@@ -854,7 +852,7 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
break;
|
||||
case Multiname.TYPENAME:
|
||||
int newQnameIndex = multinameMap.get(secondMultiname.qname_index);
|
||||
int newParams[] = new int[secondMultiname.params.length];
|
||||
int[] newParams = new int[secondMultiname.params.length];
|
||||
for (int p = 0; p < secondMultiname.params.length; p++) {
|
||||
newParams[p] = multinameMap.get(secondMultiname.params[p]);
|
||||
}
|
||||
@@ -867,7 +865,7 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void checkCyclicTypeNames() {
|
||||
for (int i = 0; i < constant_multiname.size(); i++) {
|
||||
Multiname.checkTypeNameCyclic(this, i);
|
||||
|
||||
@@ -138,7 +138,7 @@ public class AVM2Deobfuscation {
|
||||
newName = namesMap.get(sChain);
|
||||
return constants.getStringId(newName.toRawString(), true); //constants.setString(strIndex, newName.toRawString());
|
||||
}
|
||||
|
||||
|
||||
List<String> ret = new ArrayList<>();
|
||||
for (int p = 0; p < sChain.size(); p++) {
|
||||
String part = sChain.get(p);
|
||||
@@ -150,7 +150,7 @@ public class AVM2Deobfuscation {
|
||||
}
|
||||
newName = new DottedChain(ret);
|
||||
namesMap.put(sChain, newName);
|
||||
|
||||
|
||||
if (stringUsages.contains(strIndex)) {
|
||||
strIndex = constants.addString(newName.toRawString());
|
||||
} else {
|
||||
@@ -193,15 +193,15 @@ public class AVM2Deobfuscation {
|
||||
newname = namesMap.get(sChain);
|
||||
return constants.getStringId(newname, true);
|
||||
}
|
||||
|
||||
|
||||
String str = fooString(namesMap, constants.getString(strIndex), firstUppercase, stringUsageTypes.get(strIndex), renameType, false);
|
||||
newname = DottedChain.parseNoSuffix(str);
|
||||
|
||||
|
||||
if (stringUsages.contains(strIndex) || namespaceUsages.contains(strIndex)) { // this name is already referenced as String
|
||||
String usageType = stringUsageTypes.get(strIndex);
|
||||
strIndex = constants.addString(s); // add new index
|
||||
stringUsageTypes.put(strIndex, usageType);
|
||||
}
|
||||
stringUsageTypes.put(strIndex, usageType);
|
||||
}
|
||||
constants.setString(strIndex, newname.toRawString());
|
||||
if (!namesMap.containsKey(sChain)) {
|
||||
namesMap.put(sChain, DottedChain.parseNoSuffix(constants.getString(strIndex)));
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ public class AVM2FinalProcessLocalData extends FinalProcessLocalData {
|
||||
this.localRegNames = localRegNames;
|
||||
this.setLocalPosToGetLocalPos = setLocalPosToGetLocalPos;
|
||||
}
|
||||
|
||||
|
||||
public Set<Integer> getSetLocalUsages(int setLocalPos) {
|
||||
if (setLocalPosToGetLocalPos == null) {
|
||||
return new HashSet<>();
|
||||
|
||||
+49
-49
@@ -37,68 +37,68 @@ import java.util.Map;
|
||||
public class AVM2DeobfuscatorGroupParts extends SWFDecompilerAdapter {
|
||||
|
||||
/*
|
||||
blk_1
|
||||
jump A
|
||||
B:
|
||||
blk_2
|
||||
jump C
|
||||
A: blk_3
|
||||
jump B
|
||||
C: blk_4
|
||||
blk_1
|
||||
jump A
|
||||
B:
|
||||
blk_2
|
||||
jump C
|
||||
A: blk_3
|
||||
jump B
|
||||
C: blk_4
|
||||
|
||||
=>
|
||||
jump A
|
||||
A: jump B
|
||||
B: jump C
|
||||
blk_1
|
||||
blk_3
|
||||
blk_2
|
||||
blk_4
|
||||
=>
|
||||
jump A
|
||||
A: jump B
|
||||
B: jump C
|
||||
blk_1
|
||||
blk_3
|
||||
blk_2
|
||||
blk_4
|
||||
|
||||
----------------------
|
||||
|
||||
blk_1
|
||||
jump A
|
||||
B:
|
||||
blk_2
|
||||
jump C
|
||||
A: blk_3
|
||||
if B
|
||||
blk_5
|
||||
C: blk_4
|
||||
blk_1
|
||||
jump A
|
||||
B:
|
||||
blk_2
|
||||
jump C
|
||||
A: blk_3
|
||||
if B
|
||||
blk_5
|
||||
C: blk_4
|
||||
|
||||
=>
|
||||
jump A
|
||||
jump A
|
||||
B:
|
||||
blk_2
|
||||
jump C
|
||||
A: blk_1
|
||||
blk_3
|
||||
if B
|
||||
blk_5
|
||||
blk_2
|
||||
jump C
|
||||
A: blk_1
|
||||
blk_3
|
||||
if B
|
||||
blk_5
|
||||
C:
|
||||
blk_4
|
||||
blk_4
|
||||
|
||||
----------------------
|
||||
blk_1
|
||||
jump A
|
||||
B:
|
||||
blk_2
|
||||
if C
|
||||
A: blk_3
|
||||
jump B
|
||||
C: blk_4
|
||||
blk_1
|
||||
jump A
|
||||
B:
|
||||
blk_2
|
||||
if C
|
||||
A: blk_3
|
||||
jump B
|
||||
C: blk_4
|
||||
|
||||
=>
|
||||
|
||||
blk_1
|
||||
jump A
|
||||
B:
|
||||
blk_3
|
||||
blk_2
|
||||
if C
|
||||
A: jump B
|
||||
C: blk_4
|
||||
blk_1
|
||||
jump A
|
||||
B:
|
||||
blk_3
|
||||
blk_2
|
||||
if C
|
||||
A: jump B
|
||||
C: blk_4
|
||||
|
||||
*/
|
||||
@Override
|
||||
|
||||
+6
-6
@@ -266,7 +266,7 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
if (ins.definition instanceof JumpIns) {
|
||||
|
||||
long address = ins.getTargetAddress();
|
||||
idx = code.adr2pos(address);//code.indexOf(code.getByAddress(address));
|
||||
idx = code.adr2pos(address);
|
||||
if (idx == -1) {
|
||||
throw new TranslateException("Jump target not found: " + address);
|
||||
}
|
||||
@@ -299,17 +299,17 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
public int adr2pos(long adr) {
|
||||
return code.adr2pos(adr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int adr2pos(long adr, boolean nearest) {
|
||||
return code.adr2pos(adr, nearest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long pos2adr(int pos) {
|
||||
return code.pos2adr(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int adr2pos(long adr, boolean nearest) {
|
||||
return code.adr2pos(adr, nearest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getImportantAddresses() {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
|
||||
+7
-7
@@ -273,7 +273,7 @@ public class AVM2DeobfuscatorRegistersOld extends AVM2DeobfuscatorSimpleOld {
|
||||
if (ins.definition instanceof JumpIns) {
|
||||
|
||||
long address = ins.getTargetAddress();
|
||||
idx = code.adr2pos(address);//code.indexOf(code.getByAddress(address));
|
||||
idx = code.adr2pos(address);
|
||||
if (idx == -1) {
|
||||
throw new TranslateException("Jump target not found: " + address);
|
||||
}
|
||||
@@ -306,18 +306,18 @@ public class AVM2DeobfuscatorRegistersOld extends AVM2DeobfuscatorSimpleOld {
|
||||
public int adr2pos(long adr) {
|
||||
return code.adr2pos(adr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long pos2adr(int pos) {
|
||||
return code.pos2adr(pos);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int adr2pos(long adr, boolean nearest) {
|
||||
return code.adr2pos(adr, nearest);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long pos2adr(int pos) {
|
||||
return code.pos2adr(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getImportantAddresses() {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
|
||||
-1
@@ -128,7 +128,6 @@ public class AVM2DeobfuscatorSimple extends AVM2DeobfuscatorZeroJumpsNullPushes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected void initLocalRegs(LocalDataArea localData, int localReservedCount, int maxRegs, boolean executeFromFirst) {
|
||||
for (int i = 0; i < localReservedCount; i++) {
|
||||
localData.localRegisters.put(i, NotCompileTime.INSTANCE);
|
||||
|
||||
+29
-16
@@ -177,7 +177,7 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
|
||||
|
||||
localData.scopeStack.clear();
|
||||
localData.localScopeStack.clear();
|
||||
localData.localRegs.clear();
|
||||
@@ -231,7 +231,7 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
|
||||
FixItemCounterTranslateStack stack = new FixItemCounterTranslateStack("");
|
||||
int instructionsProcessed = 0;
|
||||
|
||||
|
||||
int minChangedIp = Integer.MAX_VALUE;
|
||||
|
||||
endIdx = code.code.size() - 1;
|
||||
@@ -256,7 +256,7 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
}
|
||||
}
|
||||
} else */
|
||||
{
|
||||
if (true) {
|
||||
// do not throw EmptyStackException, much faster
|
||||
int requiredStackSize = ins.getStackPopCount(localData);
|
||||
if (stack.size() < requiredStackSize) {
|
||||
@@ -277,11 +277,15 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
if (fins.definition instanceof NewFunctionIns) {
|
||||
int fidx = code.code.indexOf(fins);
|
||||
code.removeInstruction(fidx, body);
|
||||
if (fidx < minChangedIp) minChangedIp = fidx;
|
||||
if (fidx < minChangedIp) {
|
||||
minChangedIp = fidx;
|
||||
}
|
||||
}
|
||||
int nidx = code.code.indexOf(ins);
|
||||
code.removeInstruction(nidx, body);
|
||||
if (nidx < minChangedIp) minChangedIp = nidx;
|
||||
if (nidx < minChangedIp) {
|
||||
minChangedIp = nidx;
|
||||
}
|
||||
if (nins == null) {
|
||||
idx = code.code.size();
|
||||
} else {
|
||||
@@ -304,7 +308,9 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
int regId = ((SetLocalTypeIns) def).getRegisterId(ins);
|
||||
staticRegs.put(regId, localData.localRegs.get(regId).getNotCoerced());
|
||||
code.replaceInstruction(idx, new AVM2Instruction(0, DeobfuscatePopIns.getInstance(), null), body);
|
||||
if (idx < minChangedIp) minChangedIp = idx;
|
||||
if (idx < minChangedIp) {
|
||||
minChangedIp = idx;
|
||||
}
|
||||
|
||||
importantOffsets.clear();
|
||||
importantOffsets.addAll(code.getImportantOffsets(body, false));
|
||||
@@ -325,7 +331,9 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
}
|
||||
|
||||
code.replaceInstruction(idx, pushins, body);
|
||||
if (idx < minChangedIp) minChangedIp = idx;
|
||||
if (idx < minChangedIp) {
|
||||
minChangedIp = idx;
|
||||
}
|
||||
stack.push(staticRegs.get(regId));
|
||||
ins = pushins;
|
||||
def = ins.definition;
|
||||
@@ -392,8 +400,7 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
|| def instanceof DebugLineIns
|
||||
|| def instanceof DebugFileIns
|
||||
|| def instanceof DebugIns
|
||||
|| def instanceof NopIns
|
||||
) {
|
||||
|| def instanceof NopIns) {
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -429,7 +436,9 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
boolean ifed = false;
|
||||
if (def instanceof PopIns) {
|
||||
code.replaceInstruction(idx, new AVM2Instruction(ins.getAddress(), DeobfuscatePopIns.getInstance(), null), body);
|
||||
if (idx < minChangedIp) minChangedIp = idx;
|
||||
if (idx < minChangedIp) {
|
||||
minChangedIp = idx;
|
||||
}
|
||||
idx++;
|
||||
} else if (def instanceof JumpIns) {
|
||||
long address = ins.getTargetAddress();
|
||||
@@ -451,8 +460,8 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
GraphTargetItem top = stack.pop();
|
||||
Boolean res = top.getResultAsBoolean();
|
||||
long address = ins.getTargetAddress();
|
||||
int nidx = code.adr2pos(address);//code.indexOf(code.getByAddress(address));
|
||||
AVM2Instruction tarIns = code.code.get(nidx);
|
||||
int nidx = code.adr2pos(address);
|
||||
AVM2Instruction tarIns = code.code.get(nidx);
|
||||
|
||||
//Some IfType instructions need more than 1 operand, we must pop out all of them
|
||||
int stackCount = -def.getStackDelta(ins, abc);
|
||||
@@ -461,7 +470,9 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
AVM2Instruction jumpIns = new AVM2Instruction(0, AVM2Instructions.Jump, new int[]{0});
|
||||
//jumpIns.operands[0] = ins.operands[0] /*- ins.getBytes().length*/ + jumpIns.getBytes().length;
|
||||
code.replaceInstruction(idx, jumpIns, body);
|
||||
if (idx < minChangedIp) minChangedIp = idx;
|
||||
if (idx < minChangedIp) {
|
||||
minChangedIp = idx;
|
||||
}
|
||||
jumpIns.operands[0] = (int) (tarIns.getAddress() - jumpIns.getAddress() - jumpIns.getBytesLength());
|
||||
for (int s = 0; s < stackCount; s++) {
|
||||
code.insertInstruction(idx, new AVM2Instruction(ins.getAddress(), DeobfuscatePopIns.getInstance(), null), true, body);
|
||||
@@ -470,7 +481,9 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
idx = code.adr2pos(jumpIns.getTargetAddress());
|
||||
} else {
|
||||
//System.err.println("replacing " + ins + " on " + idx + " with pop");
|
||||
if (idx < minChangedIp) minChangedIp = idx;
|
||||
if (idx < minChangedIp) {
|
||||
minChangedIp = idx;
|
||||
}
|
||||
code.replaceInstruction(idx, new AVM2Instruction(ins.getAddress(), DeobfuscatePopIns.getInstance(), null), body);
|
||||
for (int s = 1 /*first is replaced*/; s < stackCount; s++) {
|
||||
code.insertInstruction(idx, new AVM2Instruction(ins.getAddress(), DeobfuscatePopIns.getInstance(), null), true, body);
|
||||
@@ -482,13 +495,13 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush
|
||||
Reference<Integer> minChangedIp2Ref = new Reference<>(-1);
|
||||
//this might be slow:-(, but makes importantOffsets relevant
|
||||
code.removeDeadCode(body, minChangedIp2Ref);
|
||||
|
||||
|
||||
if (minChangedIp2Ref.getVal() != -1 && minChangedIp2Ref.getVal() < minChangedIp) {
|
||||
minChangedIp = minChangedIp2Ref.getVal();
|
||||
}
|
||||
minChangedIp2Ref.setVal(-1);
|
||||
removeZeroJumps(code, body, minChangedIp2Ref);
|
||||
|
||||
|
||||
if (minChangedIp2Ref.getVal() != -1 && minChangedIp2Ref.getVal() < minChangedIp) {
|
||||
minChangedIp = minChangedIp2Ref.getVal();
|
||||
}
|
||||
|
||||
+1
-1
@@ -46,10 +46,10 @@ import java.util.Set;
|
||||
*/
|
||||
public class AVM2DeobfuscatorZeroJumpsNullPushes extends SWFDecompilerAdapter {
|
||||
|
||||
|
||||
protected boolean removeZeroJumps(AVM2Code code, MethodBody body) throws InterruptedException {
|
||||
return removeZeroJumps(code, body, new Reference<>(-1));
|
||||
}
|
||||
|
||||
protected boolean removeZeroJumps(AVM2Code code, MethodBody body, Reference<Integer> minChangedIpRef) throws InterruptedException {
|
||||
boolean result = false;
|
||||
int minChangedIp = -1;
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ package com.jpexs.decompiler.flash.abc.avm2.deobfuscation;
|
||||
public enum DeobfuscationLevel {
|
||||
|
||||
LEVEL_REMOVE_DEAD_CODE(1),
|
||||
LEVEL_REMOVE_TRAPS(2);
|
||||
LEVEL_REMOVE_TRAPS(2);
|
||||
private final int level;
|
||||
|
||||
public int getLevel() {
|
||||
@@ -35,7 +35,7 @@ public enum DeobfuscationLevel {
|
||||
case 1:
|
||||
return LEVEL_REMOVE_DEAD_CODE;
|
||||
case 2:
|
||||
return LEVEL_REMOVE_TRAPS;
|
||||
return LEVEL_REMOVE_TRAPS;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
+2
-2
@@ -32,8 +32,8 @@ public class AVM2RangeErrorException extends AVM2ExecutionException {
|
||||
|
||||
private static String codeToMessage(int code, boolean debug, Object[] params) {
|
||||
String msg = null;
|
||||
switch (code) {
|
||||
}
|
||||
/*switch (code) {
|
||||
}*/
|
||||
|
||||
String result = "RangeError: Error #" + code;
|
||||
if (debug && msg != null) {
|
||||
|
||||
+2
-2
@@ -32,8 +32,8 @@ public class AVM2TypeErrorException extends AVM2ExecutionException {
|
||||
|
||||
private static String codeToMessage(int code, boolean debug, Object[] params) {
|
||||
String msg = null;
|
||||
switch (code) {
|
||||
}
|
||||
/*switch (code) {
|
||||
}*/
|
||||
|
||||
String result = "TypeError: Error #" + code;
|
||||
if (debug && msg != null) {
|
||||
|
||||
+7
-44
@@ -57,20 +57,14 @@ public class FastAVM2List implements Collection<AVM2InstructionItem> {
|
||||
}
|
||||
|
||||
size = code.size();
|
||||
// getContainerLastActions(avm2code, actionItemMap);
|
||||
getJumps(avm2code, actionItemMap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final AVM2InstructionItem insertItemBefore(AVM2InstructionItem item, AVM2Instruction action) {
|
||||
AVM2InstructionItem newItem = new AVM2InstructionItem(action);
|
||||
return insertItemBefore(item, newItem);
|
||||
}
|
||||
|
||||
public final AVM2InstructionItem insertItemAfter(AVM2InstructionItem item, AVM2Instruction action) {
|
||||
AVM2InstructionItem newItem = new AVM2InstructionItem(action);
|
||||
return insertItemAfter(item, newItem);
|
||||
}
|
||||
|
||||
public final AVM2InstructionItem insertItemBefore(AVM2InstructionItem item, AVM2InstructionItem newItem) {
|
||||
insertItemAfter(item.prev, newItem);
|
||||
if (item == firstItem) {
|
||||
@@ -80,6 +74,11 @@ public class FastAVM2List implements Collection<AVM2InstructionItem> {
|
||||
return newItem;
|
||||
}
|
||||
|
||||
public final AVM2InstructionItem insertItemAfter(AVM2InstructionItem item, AVM2Instruction action) {
|
||||
AVM2InstructionItem newItem = new AVM2InstructionItem(action);
|
||||
return insertItemAfter(item, newItem);
|
||||
}
|
||||
|
||||
public final AVM2InstructionItem insertItemAfter(AVM2InstructionItem item, AVM2InstructionItem newItem) {
|
||||
if (item == null && firstItem == null) {
|
||||
firstItem = newItem;
|
||||
@@ -165,42 +164,6 @@ public class FastAVM2List implements Collection<AVM2InstructionItem> {
|
||||
}
|
||||
}
|
||||
|
||||
// private void getContainerLastActions(AVM2Code actions, Map<AVM2Instruction, AVM2InstructionItem> actionItemMap) {
|
||||
// AVM2InstructionItem item = firstItem;
|
||||
// if (item == null) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// do {
|
||||
// AVM2Instruction action = item.ins;
|
||||
// if (action instanceof GraphSourceItemContainer) {
|
||||
// item.setContainerLastInstructions(getContainerLastActions(actions, action, actionItemMap));
|
||||
// }
|
||||
//
|
||||
// item = item.next;
|
||||
// } while (item != firstItem);
|
||||
// }
|
||||
// private List<AVM2InstructionItem> getContainerLastActions(AVM2Code actions, AVM2Instruction action, Map<AVM2Instruction, AVM2InstructionItem> actionItemMap) {
|
||||
// GraphSourceItemContainer container = (GraphSourceItemContainer) action;
|
||||
// List<Long> sizes = container.getContainerSizes();
|
||||
// long endAddress = action.getAddress() + container.getHeaderSize();
|
||||
// List<AVM2InstructionItem> lasts = new ArrayList<>(sizes.size());
|
||||
// for (long size : sizes) {
|
||||
// endAddress += size;
|
||||
// long lastActionAddress = getNearAddress(actions.code, endAddress - 1, false);
|
||||
// AVM2Instruction lastAction = null;
|
||||
// if (lastActionAddress != -1) {
|
||||
// lastAction = actions.getByAddress(lastActionAddress);
|
||||
// }
|
||||
//
|
||||
// if (lastAction != null) {
|
||||
// lasts.add(actionItemMap.get(lastAction));
|
||||
// } else {
|
||||
// lasts.add(null);
|
||||
// }
|
||||
// }
|
||||
// return lasts;
|
||||
// }
|
||||
private long getNearAddress(List<AVM2Instruction> instructions, long address, boolean next) {
|
||||
int min = 0;
|
||||
int max = instructions.size() - 1;
|
||||
|
||||
@@ -101,7 +101,6 @@ import com.jpexs.decompiler.graph.model.AnyItem;
|
||||
import com.jpexs.decompiler.graph.model.BreakItem;
|
||||
import com.jpexs.decompiler.graph.model.CommaExpressionItem;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.DoWhileItem;
|
||||
import com.jpexs.decompiler.graph.model.ExitItem;
|
||||
import com.jpexs.decompiler.graph.model.FalseItem;
|
||||
import com.jpexs.decompiler.graph.model.GotoItem;
|
||||
@@ -335,11 +334,12 @@ public class AVM2Graph extends Graph {
|
||||
for (int j = prevFinallyEndPart.start; j <= prevFinallyEndPart.end; j++) {
|
||||
AVM2Instruction ins = avm2code.code.get(j);
|
||||
if (ins.definition instanceof NopIns) {
|
||||
|
||||
//empty
|
||||
} else if (ins.definition instanceof PushByteIns) {
|
||||
defaultPushByte = ins.operands[0];
|
||||
localData.pushDefaultPart.put(e, prevFinallyEndPart);
|
||||
} else if (ins.definition instanceof JumpIns) {
|
||||
//empty
|
||||
} else {
|
||||
if (localData.pushDefaultPart.containsKey(e)) {
|
||||
localData.pushDefaultPart.remove(e);
|
||||
@@ -357,7 +357,7 @@ public class AVM2Graph extends Graph {
|
||||
for (int j = prevFinallyEndPart.start; j <= prevFinallyEndPart.end; j++) {
|
||||
AVM2Instruction ins = avm2code.code.get(j);
|
||||
if (ins.definition instanceof NopIns) {
|
||||
|
||||
//empty
|
||||
} else if (ins.definition instanceof PushByteIns) {
|
||||
defaultPushByte = ins.operands[0];
|
||||
localData.pushDefaultPart.put(e, prevFinallyEndPart);
|
||||
@@ -913,11 +913,11 @@ public class AVM2Graph extends Graph {
|
||||
for (int ip = outSideExceptionNonEmptyPart.start; ip <= outSideExceptionNonEmptyPart.end; ip++) {
|
||||
AVM2Instruction ins = avm2code.code.get(outSideExceptionNonEmptyPart.start);
|
||||
if (ins.definition instanceof PushByteIns) {
|
||||
|
||||
//empty
|
||||
} else if (ins.definition instanceof JumpIns) {
|
||||
|
||||
//empty
|
||||
} else if (ins.definition instanceof NopIns) {
|
||||
|
||||
//empty
|
||||
} else {
|
||||
hashPushByteOnly = false;
|
||||
}
|
||||
@@ -1034,9 +1034,8 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
//List<GraphPart> catchedExceptionsAfter = new ArrayList<>();
|
||||
|
||||
List<GraphPart> catchAfterParts = new ArrayList<>();
|
||||
|
||||
|
||||
if (afterPart == null) {
|
||||
|
||||
loope:
|
||||
@@ -1050,7 +1049,7 @@ public class AVM2Graph extends Graph {
|
||||
if (!stopPart.contains(possibleAfter)) {
|
||||
catchAfterParts.add(possibleAfter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1111,7 +1110,7 @@ public class AVM2Graph extends Graph {
|
||||
|
||||
try {
|
||||
//We are assuming Finally target has only 1 part
|
||||
finallyTargetItems = translatePart(localData2, finallyTryTargetPart, st2, staticOperation, path);//printGraph(foundGotos, partCodes, partCodePos, visited, localData2, st2, allParts, null, finallyTryTargetPart, finallyTargetStopPart, loops, throwStates, 0, path);
|
||||
finallyTargetItems = translatePart(localData2, finallyTryTargetPart, st2, staticOperation, path);
|
||||
} catch (GraphPartChangeException ex) { //should not happen
|
||||
finallyTargetItems = new ArrayList<>();
|
||||
}
|
||||
@@ -1130,8 +1129,9 @@ public class AVM2Graph extends Graph {
|
||||
break;
|
||||
}
|
||||
} else if (it instanceof ThrowAVM2Item) {
|
||||
|
||||
//empty
|
||||
} else if (it instanceof IntegerValueAVM2Item) {
|
||||
//empty
|
||||
} else {
|
||||
isEmpty = false;
|
||||
break;
|
||||
@@ -1235,8 +1235,8 @@ public class AVM2Graph extends Graph {
|
||||
stopPart2.add(defaultPart);
|
||||
stopPartKind2.add(StopPartKind.OTHER);
|
||||
}
|
||||
|
||||
for (GraphPart p:catchAfterParts) {
|
||||
|
||||
for (GraphPart p : catchAfterParts) {
|
||||
stopPart2.add(p);
|
||||
stopPartKind2.add(StopPartKind.OTHER);
|
||||
}
|
||||
@@ -1468,29 +1468,29 @@ public class AVM2Graph extends Graph {
|
||||
|
||||
@Override
|
||||
protected boolean checkPartOutput(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos,
|
||||
Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos,
|
||||
Set<GraphPart> visited, GraphSource code,
|
||||
BaseLocalData localData, Set<GraphPart> allParts,
|
||||
TranslateStack stack, GraphPart parent,
|
||||
GraphPart part, List<GraphPart> stopPart,
|
||||
List<StopPartKind> stopPartKind, List<Loop> loops,
|
||||
List<ThrowState> throwStates, Loop currentLoop,
|
||||
int staticOperation, String path,
|
||||
int recursionLevel) throws InterruptedException {
|
||||
Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos,
|
||||
Set<GraphPart> visited, GraphSource code,
|
||||
BaseLocalData localData, Set<GraphPart> allParts,
|
||||
TranslateStack stack, GraphPart parent,
|
||||
GraphPart part, List<GraphPart> stopPart,
|
||||
List<StopPartKind> stopPartKind, List<Loop> loops,
|
||||
List<ThrowState> throwStates, Loop currentLoop,
|
||||
int staticOperation, String path,
|
||||
int recursionLevel) throws InterruptedException {
|
||||
AVM2LocalData aLocalData = (AVM2LocalData) localData;
|
||||
return checkTry(currentRet, foundGotos, partCodes, partCodePos, visited, aLocalData, part, stopPart, stopPartKind, loops, throwStates, allParts, stack, staticOperation, path, recursionLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<GraphTargetItem> check(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos,
|
||||
Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos,
|
||||
Set<GraphPart> visited, GraphSource code,
|
||||
BaseLocalData localData, Set<GraphPart> allParts,
|
||||
TranslateStack stack, GraphPart parent,
|
||||
GraphPart part, List<GraphPart> stopPart,
|
||||
List<StopPartKind> stopPartKind, List<Loop> loops,
|
||||
List<ThrowState> throwStates, List<GraphTargetItem> output,
|
||||
Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos,
|
||||
Set<GraphPart> visited, GraphSource code,
|
||||
BaseLocalData localData, Set<GraphPart> allParts,
|
||||
TranslateStack stack, GraphPart parent,
|
||||
GraphPart part, List<GraphPart> stopPart,
|
||||
List<StopPartKind> stopPartKind, List<Loop> loops,
|
||||
List<ThrowState> throwStates, List<GraphTargetItem> output,
|
||||
Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
List<GraphTargetItem> ret = null;
|
||||
|
||||
/*if (ret != null) {
|
||||
@@ -1620,8 +1620,8 @@ public class AVM2Graph extends Graph {
|
||||
|
||||
@Override
|
||||
protected GraphPart checkPartWithOutput(List<GraphTargetItem> output, TranslateStack stack,
|
||||
BaseLocalData localData, GraphPart prev,
|
||||
GraphPart part, Set<GraphPart> allParts
|
||||
BaseLocalData localData, GraphPart prev,
|
||||
GraphPart part, Set<GraphPart> allParts
|
||||
) {
|
||||
AVM2LocalData aLocalData = (AVM2LocalData) localData;
|
||||
if (aLocalData.finallyJumps == null) {
|
||||
@@ -2051,7 +2051,7 @@ public class AVM2Graph extends Graph {
|
||||
protected void finalProcessAfter(List<GraphTargetItem> list, int level, FinalProcessLocalData localData, String path) {
|
||||
super.finalProcessAfter(list, level, localData, path);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
|
||||
|
||||
//Remove continues from all branches of try...catch block if its continue to parent loop
|
||||
if (list.get(i) instanceof LoopItem) {
|
||||
LoopItem li = (LoopItem) list.get(i);
|
||||
@@ -2193,7 +2193,7 @@ public class AVM2Graph extends Graph {
|
||||
&& (((NotItem) ifi.expression).getOriginal() instanceof HasNextAVM2Item)))) {
|
||||
HasNextAVM2Item hnt;
|
||||
List<GraphTargetItem> body = new ArrayList<>();
|
||||
List<GraphTargetItem> nextbody;//= new ArrayList<>();
|
||||
List<GraphTargetItem> nextbody;
|
||||
if (ifi.expression instanceof NotItem) {
|
||||
hnt = (HasNextAVM2Item) ((NotItem) ifi.expression).getOriginal();
|
||||
body.addAll(ifi.onFalse);
|
||||
@@ -2263,7 +2263,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
}
|
||||
//if (usages.size() <= 1)
|
||||
{
|
||||
if (true) {
|
||||
if (i + 1 < list.size()) {
|
||||
if ((list.get(i + 1) instanceof ReturnValueAVM2Item)
|
||||
&& (list.get(i + 1).value instanceof LocalRegAVM2Item)
|
||||
@@ -2544,7 +2544,7 @@ public class AVM2Graph extends Graph {
|
||||
|
||||
List<ThrowState> ret = new ArrayList<>();
|
||||
for (int e = 0; e < body.exceptions.length; e++) {
|
||||
ThrowState ts = new ThrowState();
|
||||
ThrowState ts = new ThrowState();
|
||||
ts.exceptionId = e;
|
||||
ts.state = 0;
|
||||
ts.targetPart = searchPart(code.adr2pos(body.exceptions[e].target), allParts);
|
||||
@@ -2650,13 +2650,13 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
}
|
||||
|
||||
private void walkCatchParts(CodeStats stats, GraphPart part, int startIp, Set<GraphPart> catchParts, int scopePos, Set<GraphPart> allParts, boolean isFinally) {
|
||||
private void walkCatchParts(CodeStats stats, GraphPart part, int startIp, Set<GraphPart> catchParts, int scopePos, Set<GraphPart> allParts, boolean isFinally) {
|
||||
if (catchParts.contains(part)) {
|
||||
return;
|
||||
}
|
||||
for (int ip = startIp; ip <= part.end; ip++) {
|
||||
if (stats.instructionStats[ip].scopepos_after < scopePos) {
|
||||
|
||||
|
||||
//popscope can be followed by jump (break/continue),
|
||||
//in such case, treat as single block
|
||||
if (ip >= 0 && ip < code.size()) {
|
||||
@@ -2677,22 +2677,22 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
if (onlyKillJump) {
|
||||
catchParts.add(part);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ip < part.end && !isFinally) {
|
||||
//split part into half
|
||||
GraphPart secondPart = new GraphPart(ip + 1, part.end);
|
||||
part.end = ip;
|
||||
part.end = ip;
|
||||
for (GraphPart n : part.nextParts) {
|
||||
n.refs.remove(part);
|
||||
n.refs.add(secondPart);
|
||||
}
|
||||
}
|
||||
secondPart.nextParts.addAll(part.nextParts);
|
||||
part.nextParts.clear();
|
||||
part.nextParts.add(secondPart);
|
||||
secondPart.refs.add(part);
|
||||
|
||||
|
||||
secondPart.type = GraphPart.TYPE_NONE;
|
||||
secondPart.discoveredTime = part.discoveredTime;
|
||||
secondPart.closedTime = part.closedTime;
|
||||
@@ -2705,7 +2705,7 @@ public class AVM2Graph extends Graph {
|
||||
secondPart.path = part.path;
|
||||
secondPart.posX = part.posX;
|
||||
secondPart.posY = part.posY;
|
||||
secondPart.traversed = true;
|
||||
secondPart.traversed = true;
|
||||
allParts.add(secondPart);
|
||||
}
|
||||
catchParts.add(part);
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphSource;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.ScopeStack;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import java.util.ArrayList;
|
||||
@@ -61,7 +60,7 @@ public class AVM2GraphSource extends GraphSource {
|
||||
|
||||
List<DottedChain> fullyQualifiedNames;
|
||||
|
||||
HashMap<Integer, Integer> localRegAssigmentIps;
|
||||
HashMap<Integer, Integer> localRegAssigmentIps;
|
||||
|
||||
public AVM2Code getCode() {
|
||||
return code;
|
||||
@@ -123,14 +122,14 @@ public class AVM2GraphSource extends GraphSource {
|
||||
public int adr2pos(long adr) {
|
||||
return code.adr2pos(adr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long pos2adr(int pos) {
|
||||
return code.pos2adr(pos);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int adr2pos(long adr, boolean nearest) {
|
||||
return code.adr2pos(adr, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long pos2adr(int pos) {
|
||||
return code.pos2adr(pos);
|
||||
}
|
||||
}
|
||||
|
||||
+23
-24
@@ -21,7 +21,6 @@ import com.jpexs.decompiler.flash.abc.ABCOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.AVM2LocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallSuperIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.LookupSwitchIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
|
||||
@@ -173,20 +172,7 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(definition.instructionName);
|
||||
if (operands != null) {
|
||||
for (int i = 0; i < operands.length; i++) {
|
||||
s.append(" ");
|
||||
s.append(operands[i]);
|
||||
}
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public List<Long> getOffsets() {
|
||||
List<Long> ret = new ArrayList<>();
|
||||
@@ -331,7 +317,7 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
s.append(EcmaScript.toString(constants.getDouble(operands[i])));
|
||||
} catch (IndexOutOfBoundsException iob) {
|
||||
s.append("Unknown(").append(operands[i]).append(")");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AVM2Code.DAT_FLOAT_INDEX:
|
||||
@@ -343,7 +329,7 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
s.append(EcmaScript.toString(constants.getFloat(operands[i])));
|
||||
} catch (IndexOutOfBoundsException iob) {
|
||||
s.append("Unknown(").append(operands[i]).append(")");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AVM2Code.DAT_FLOAT4_INDEX:
|
||||
@@ -358,7 +344,7 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
s.append(" ").append(EcmaScript.toString(f4.values[3]));
|
||||
} catch (IndexOutOfBoundsException iob) {
|
||||
s.append(" Unknown(").append(operands[i]).append(")");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AVM2Code.DAT_DECIMAL_INDEX:
|
||||
@@ -370,7 +356,7 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
s.append(constants.getDecimal(operands[i]));
|
||||
} catch (IndexOutOfBoundsException iob) {
|
||||
s.append("Unknown(").append(operands[i]).append(")");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AVM2Code.DAT_OFFSET:
|
||||
@@ -427,6 +413,19 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
return ignored;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(definition.instructionName);
|
||||
if (operands != null) {
|
||||
for (int i = 0; i < operands.length; i++) {
|
||||
s.append(" ");
|
||||
s.append(operands[i]);
|
||||
}
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public GraphTextWriter toString(GraphTextWriter writer, LocalData localData) {
|
||||
writer.appendNoHilight(Helper.formatAddress(address) + " " + String.format("%-30s", Helper.byteArrToString(getBytes())) + getCustomizedInstructionName());
|
||||
writer.appendNoHilight(getParams(localData.constantsAvm2, localData.fullyQualifiedNames) + getComment());
|
||||
@@ -467,16 +466,16 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
return getStackPopCount(aLocalData);
|
||||
}
|
||||
|
||||
public int getStackPopCount(AVM2LocalData aLocalData) {
|
||||
return definition.getStackPopCount(this, aLocalData.abc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackPushCount(BaseLocalData localData, TranslateStack stack) {
|
||||
AVM2LocalData aLocalData = (AVM2LocalData) localData;
|
||||
return getStackPushCount(aLocalData);
|
||||
}
|
||||
|
||||
public int getStackPopCount(AVM2LocalData aLocalData) {
|
||||
return definition.getStackPopCount(this, aLocalData.abc);
|
||||
}
|
||||
|
||||
public int getStackPushCount(AVM2LocalData aLocalData) {
|
||||
return definition.getStackPushCount(this, aLocalData.abc);
|
||||
}
|
||||
@@ -598,7 +597,7 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
* @param code
|
||||
* @param body
|
||||
*/
|
||||
public void setOperands(int operands[], AVM2Code code, MethodBody body) {
|
||||
public void setOperands(int[] operands, AVM2Code code, MethodBody body) {
|
||||
int oldByteCount = getBytesLength();
|
||||
this.operands = operands;
|
||||
int newByteCount = getBytesLength();
|
||||
|
||||
+9
-9
@@ -261,17 +261,17 @@ public class AVM2Instructions {
|
||||
public static final int ConvertO = 0x77;
|
||||
|
||||
public static final int CheckFilter = 0x78;
|
||||
|
||||
|
||||
public static final int ConvertM = 0x79;
|
||||
|
||||
public static final int ConvertF = 0x79;
|
||||
|
||||
public static final int ConvertF = 0x79;
|
||||
|
||||
public static final int ConvertMP = 0x7A;
|
||||
|
||||
|
||||
public static final int UnPlus = 0x7A;
|
||||
|
||||
public static final int ConvertF4 = 0x7B;
|
||||
|
||||
|
||||
public static final int ConvertF4 = 0x7B;
|
||||
|
||||
public static final int Coerce = 0x80;
|
||||
|
||||
public static final int CoerceB = 0x81;
|
||||
@@ -430,10 +430,10 @@ public class AVM2Instructions {
|
||||
|
||||
public static final int Prologue = 0xF9;
|
||||
|
||||
public static final int SendEnter = 0xFA;
|
||||
public static final int SendEnter = 0xFA;
|
||||
|
||||
public static final int DoubleToAtom = 0xFB;
|
||||
|
||||
|
||||
public static final int Sweep = 0xFC;
|
||||
|
||||
public static final int CodeGenOp = 0xFD;
|
||||
|
||||
+6
-7
@@ -29,7 +29,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns;
|
||||
import static com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns.handleCompound;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item;
|
||||
@@ -401,7 +401,7 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void handleSetProperty(boolean init, AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
GraphTargetItem value = stack.pop();
|
||||
@@ -638,18 +638,17 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
Reference<GraphTargetItem> type = new Reference<>(null);
|
||||
Reference<GraphTargetItem> callType = new Reference<>(null);
|
||||
GetPropertyIns.resolvePropertyType(localData, obj, multiname, isStatic, type, callType);
|
||||
|
||||
|
||||
|
||||
SetTypeAVM2Item result;
|
||||
if (init) {
|
||||
result = new InitPropertyAVM2Item(ins, localData.lineStartInstruction, obj, multiname, value, type.getVal(), callType.getVal(), isStatic.getVal());
|
||||
} else {
|
||||
result = new SetPropertyAVM2Item(ins, localData.lineStartInstruction, obj, multiname, value, type.getVal(), callType.getVal(), isStatic.getVal());
|
||||
}
|
||||
handleCompound(localData, obj, multiname, value, output, result);
|
||||
SetTypeIns.handleResult(value, stack, output, localData, (GraphTargetItem)result, -1, type.getVal());
|
||||
SetPropertyIns.handleCompound(localData, obj, multiname, value, output, result);
|
||||
SetTypeIns.handleResult(value, stack, output, localData, (GraphTargetItem) result, -1, type.getVal());
|
||||
}
|
||||
|
||||
|
||||
private GraphTargetItem checkIncDec(boolean standalone, int multinameIndex, AVM2Instruction ins, AVM2LocalData localData, GraphTargetItem item,
|
||||
LocalRegAVM2Item valueLocalReg, LocalRegAVM2Item nameLocalReg, LocalRegAVM2Item objLocalReg) {
|
||||
if (item instanceof SetLocalAVM2Item) {
|
||||
|
||||
+6
-6
@@ -44,7 +44,7 @@ public interface SetTypeIns {
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public static void handleResult(GraphTargetItem value, TranslateStack stack, List<GraphTargetItem> output, AVM2LocalData localData, GraphTargetItem result, int regId, GraphTargetItem type) {
|
||||
GraphTargetItem notCoercedValue = value;
|
||||
if ((value instanceof CoerceAVM2Item) || (value instanceof ConvertAVM2Item)) {
|
||||
@@ -75,8 +75,8 @@ public interface SetTypeIns {
|
||||
stack.push(new LocalRegAVM2Item(null, localData.lineStartInstruction, regId, value, localData.localRegTypes.containsKey(regId) ? localData.localRegTypes.get(regId) : value.returnType()));
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
|
||||
} else {
|
||||
|
||||
if ((value instanceof CoerceAVM2Item) || (value instanceof ConvertAVM2Item)) {
|
||||
value.value = insideDup;
|
||||
} else {
|
||||
@@ -84,9 +84,9 @@ public interface SetTypeIns {
|
||||
}
|
||||
|
||||
result.value = value;
|
||||
|
||||
|
||||
if ((result instanceof SetLocalAVM2Item) && regId > -1) {
|
||||
((SetLocalAVM2Item)result).causedByDup = true;
|
||||
((SetLocalAVM2Item) result).causedByDup = true;
|
||||
}
|
||||
|
||||
if (regId > -1 && AVM2Item.mustStayIntact2(insideDup.getNotCoerced())) { //hack
|
||||
@@ -100,7 +100,7 @@ public interface SetTypeIns {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
output.add(result);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-5
@@ -30,13 +30,10 @@ import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.GetLexAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.GetSlotAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.RegExpAvm2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.XMLAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.SlotAVM2Item;
|
||||
import com.jpexs.decompiler.flash.ecma.ObjectType;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
@@ -85,6 +82,7 @@ public class ConstructIns extends InstructionDefinition {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static boolean walkXMLSub(GraphTargetItem item, List<GraphTargetItem> list) {
|
||||
boolean ret = false;
|
||||
if (item instanceof AddAVM2Item) {
|
||||
@@ -93,14 +91,14 @@ public class ConstructIns extends InstructionDefinition {
|
||||
}
|
||||
if (walkXMLSub(((AddAVM2Item) item).rightSide, list)) {
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
} else if ((item instanceof EscapeXElemAVM2Item) || (item instanceof EscapeXAttrAVM2Item)) {
|
||||
ret = true;
|
||||
list.add(item);
|
||||
} else {
|
||||
list.add(item);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -72,7 +72,6 @@ public class ConstructPropIns extends InstructionDefinition {
|
||||
}
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
GraphTargetItem obj = stack.pop();
|
||||
|
||||
|
||||
if (multiname.isXML(localData.abc, localData.localRegNames, localData.fullyQualifiedNames, localData.seenMethods)) {
|
||||
if (args.size() == 1) {
|
||||
@@ -83,7 +82,7 @@ public class ConstructPropIns extends InstructionDefinition {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}//
|
||||
}
|
||||
boolean isRegExp = false;
|
||||
if (multiname.isTopLevel("RegExp", localData.abc, localData.localRegNames, localData.fullyQualifiedNames, localData.seenMethods)) {
|
||||
isRegExp = true;
|
||||
@@ -97,7 +96,7 @@ public class ConstructPropIns extends InstructionDefinition {
|
||||
stack.push(new RegExpAvm2Item(pattern, modifiers, ins, localData.lineStartInstruction));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference<Boolean> isStatic = new Reference<>(false);
|
||||
Reference<GraphTargetItem> type = new Reference<>(null);
|
||||
Reference<GraphTargetItem> callType = new Reference<>(null);
|
||||
|
||||
+1
-2
@@ -85,8 +85,7 @@ public class CallIns extends InstructionDefinition {
|
||||
if (getProperty.object.value == receiver) {
|
||||
getProperty.object = receiver;
|
||||
}
|
||||
}
|
||||
else if (getProperty.object instanceof SetLocalAVM2Item) {
|
||||
} else if (getProperty.object instanceof SetLocalAVM2Item) {
|
||||
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) getProperty.object;
|
||||
if (receiver instanceof LocalRegAVM2Item) {
|
||||
LocalRegAVM2Item getLocal = (LocalRegAVM2Item) receiver;
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ public class CallPropLexIns extends CallPropertyIns {
|
||||
Reference<GraphTargetItem> type = new Reference<>(null);
|
||||
Reference<GraphTargetItem> callType = new Reference<>(null);
|
||||
GetPropertyIns.resolvePropertyType(localData, obj, multiname, isStatic, type, callType);
|
||||
|
||||
|
||||
stack.push(new CallPropertyAVM2Item(ins, localData.lineStartInstruction, false, obj, multiname, args, callType.getVal(), isStatic.getVal()));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ public class CallPropVoidIns extends InstructionDefinition {
|
||||
}
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
|
||||
GraphTargetItem obj = stack.pop();
|
||||
GraphTargetItem obj = stack.pop();
|
||||
Reference<Boolean> isStatic = new Reference<>(false);
|
||||
Reference<GraphTargetItem> type = new Reference<>(null);
|
||||
Reference<GraphTargetItem> callType = new Reference<>(null);
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ public class CallPropertyIns extends InstructionDefinition {
|
||||
Reference<GraphTargetItem> type = new Reference<>(null);
|
||||
Reference<GraphTargetItem> callType = new Reference<>(null);
|
||||
GetPropertyIns.resolvePropertyType(localData, obj, multiname, isStatic, type, callType);
|
||||
|
||||
|
||||
stack.push(new CallPropertyAVM2Item(ins, localData.lineStartInstruction, false, obj, multiname, args, callType.getVal(), isStatic.getVal()));
|
||||
}
|
||||
|
||||
|
||||
+3
-4
@@ -28,7 +28,6 @@ import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.GlobalAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item;
|
||||
@@ -75,7 +74,7 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
|
||||
if (localData.classIndex == -1) {
|
||||
stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, DottedChain.parseNoSuffix("global"), false, false));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((localData.classIndex >= localData.getInstanceInfo().size())) {
|
||||
stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, DottedChain.OBJECT /*?*/, false, false));
|
||||
return;
|
||||
@@ -137,8 +136,8 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
|
||||
} else if (setItem.value.getNotCoerced() instanceof SetLocalAVM2Item) {
|
||||
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) setItem.value.getNotCoerced();
|
||||
if (setLocal.regIndex == regId) {
|
||||
int setLocalIp = localData.code.adr2pos(setLocal.getSrc().getAddress());
|
||||
if (localData.getSetLocalUsages(setLocalIp).size() == 1) {
|
||||
int setLocalIp = localData.code.adr2pos(setLocal.getSrc().getAddress());
|
||||
if (localData.getSetLocalUsages(setLocalIp).size() == 1) {
|
||||
if ((setItem.value instanceof CoerceAVM2Item) || (setItem.value instanceof ConvertAVM2Item)) {
|
||||
setItem.value.value = setLocal.value;
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class DeletePropertyIns extends InstructionDefinition {
|
||||
Reference<Boolean> isStatic = new Reference<>(false);
|
||||
Reference<GraphTargetItem> type = new Reference<>(null);
|
||||
Reference<GraphTargetItem> callType = new Reference<>(null);
|
||||
GetPropertyIns.resolvePropertyType(localData, obj, multiname, isStatic, type, callType);
|
||||
GetPropertyIns.resolvePropertyType(localData, obj, multiname, isStatic, type, callType);
|
||||
stack.add(new DeletePropertyAVM2Item(ins, localData.lineStartInstruction, obj, multiname, isStatic.getVal()));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ public class GetGlobalSlotIns extends InstructionDefinition {
|
||||
if (obj instanceof NewActivationAVM2Item) {
|
||||
for (Trait t : localData.methodBody.traits.traits) {
|
||||
if (t instanceof TraitSlotConst) {
|
||||
TraitSlotConst tsc = (TraitSlotConst)t;
|
||||
TraitSlotConst tsc = (TraitSlotConst) t;
|
||||
if (tsc.slot_id == slotIndex) {
|
||||
slotType = AbcIndexing.multinameToType(tsc.type_index, localData.abc.constants);
|
||||
break;
|
||||
|
||||
+2
-2
@@ -43,14 +43,14 @@ public class GetOuterScopeIns extends InstructionDefinition {
|
||||
int index = ins.operands[0];
|
||||
GraphTargetItem item = localData.scopeStack.get(index);
|
||||
if (item instanceof ThisAVM2Item) {
|
||||
if (((ThisAVM2Item)item).className.equals(DottedChain.parseNoSuffix("global"))) {
|
||||
if (((ThisAVM2Item) item).className.equals(DottedChain.parseNoSuffix("global"))) {
|
||||
stack.push(new GlobalAVM2Item(null, null));
|
||||
return;
|
||||
}
|
||||
}
|
||||
stack.push(item);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getStackPopCount(AVM2Instruction ins, ABC abc) {
|
||||
return 0;
|
||||
|
||||
+3
-3
@@ -176,8 +176,8 @@ public class GetPropertyIns extends InstructionDefinition {
|
||||
if (currentClassName != null) {
|
||||
localData.abcIndex.findPropertyTypeOrCallType(localData.abc, new TypeItem(currentClassName), multinameStr, localData.abc.constants.getMultiname(multiname.multinameIndex).namespace_index, true, true, true, type, callType);
|
||||
}
|
||||
if (type.getVal().equals(TypeItem.UNKNOWN)) {
|
||||
GraphTargetItem ti = AbcIndexing.multinameToType(multiname.multinameIndex, localData.abc.constants);//new TypeItem(localData.abc.constants.getMultiname(multiname.multinameIndex).getNameWithNamespace(localData.abc.constants, true));
|
||||
if (type.getVal().equals(TypeItem.UNKNOWN)) {
|
||||
GraphTargetItem ti = AbcIndexing.multinameToType(multiname.multinameIndex, localData.abc.constants);
|
||||
if (localData.abcIndex.findClass(ti, localData.abc, localData.scriptIndex) != null) {
|
||||
type.setVal(ti);
|
||||
callType.setVal(ti); //coercion i = int(xx);
|
||||
@@ -255,7 +255,7 @@ public class GetPropertyIns extends InstructionDefinition {
|
||||
localData.abcIndex.findPropertyTypeOrCallType(localData.abc, receiverType, multiname.resolvedMultinameName, localData.abc.constants.getMultiname(multiname.multinameIndex).namespace_index, parentStatic, !parentStatic, false, type, callType);
|
||||
if (receiverType.equals(new TypeItem("XML")) && !type.getVal().equals(new TypeItem("Function"))) {
|
||||
type.setVal(new TypeItem("XMLList"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public class GetSlotIns extends InstructionDefinition {
|
||||
if (obj instanceof NewActivationAVM2Item) {
|
||||
for (Trait t : localData.methodBody.traits.traits) {
|
||||
if (t instanceof TraitSlotConst) {
|
||||
TraitSlotConst tsc = (TraitSlotConst)t;
|
||||
TraitSlotConst tsc = (TraitSlotConst) t;
|
||||
if (tsc.slot_id == slotIndex) {
|
||||
slotType = AbcIndexing.multinameToType(tsc.type_index, localData.abc.constants);
|
||||
break;
|
||||
|
||||
+6
-7
@@ -21,7 +21,6 @@ import com.jpexs.decompiler.flash.abc.AVM2LocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import static com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns.resolvePropertyType;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.GetSuperAVM2Item;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
@@ -33,8 +32,8 @@ import java.util.List;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class GetSuperIns extends InstructionDefinition {
|
||||
|
||||
public class GetSuperIns extends InstructionDefinition {
|
||||
|
||||
public GetSuperIns() {
|
||||
super(0x04, "getsuper", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true);
|
||||
}
|
||||
@@ -44,13 +43,13 @@ public class GetSuperIns extends InstructionDefinition {
|
||||
int multinameIndex = ins.operands[0];
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
GraphTargetItem obj = stack.pop();
|
||||
|
||||
|
||||
Reference<Boolean> isStatic = new Reference<>(false);
|
||||
Reference<GraphTargetItem> type = new Reference<>(null);
|
||||
Reference<GraphTargetItem> callType = new Reference<>(null);
|
||||
resolvePropertyType(localData, obj, multiname, isStatic, type, callType);
|
||||
|
||||
stack.push(new GetSuperAVM2Item(ins, localData.lineStartInstruction, obj, multiname, type.getVal(), callType.getVal(),isStatic.getVal()));
|
||||
GetPropertyIns.resolvePropertyType(localData, obj, multiname, isStatic, type, callType);
|
||||
|
||||
stack.push(new GetSuperAVM2Item(ins, localData.lineStartInstruction, obj, multiname, type.getVal(), callType.getVal(), isStatic.getVal()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
-3
@@ -21,11 +21,8 @@ import com.jpexs.decompiler.flash.abc.AVM2LocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.InitPropertyAVM2Item;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
||||
+1
-2
@@ -25,8 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class LabelIns extends InstructionDefinition {
|
||||
//this can be target of branch
|
||||
public class LabelIns extends InstructionDefinition { //this can be target of branch
|
||||
|
||||
public LabelIns() {
|
||||
super(0x09, "label", new int[]{}, false);
|
||||
|
||||
+2
-16
@@ -22,30 +22,16 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.ConstructAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.GetLexAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.InitVectorAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.SetPropertyAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.SetTypeAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import com.jpexs.decompiler.graph.model.CompoundableBinaryOp;
|
||||
import com.jpexs.decompiler.graph.model.DuplicateItem;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -58,9 +44,9 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
|
||||
public SetPropertyIns() {
|
||||
super(0x61, "setproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
handleSetProperty(false, localData, stack, ins, output, path);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -144,7 +144,7 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
|
||||
if (obj instanceof NewActivationAVM2Item) {
|
||||
for (Trait t : localData.methodBody.traits.traits) {
|
||||
if (t instanceof TraitSlotConst) {
|
||||
TraitSlotConst tsc = (TraitSlotConst)t;
|
||||
TraitSlotConst tsc = (TraitSlotConst) t;
|
||||
if (tsc.slot_id == slotIndex) {
|
||||
slotType = AbcIndexing.multinameToType(tsc.type_index, localData.abc.constants);
|
||||
break;
|
||||
@@ -152,7 +152,7 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SetSlotAVM2Item result = new SetSlotAVM2Item(ins, localData.lineStartInstruction, obj, objnoreg, slotIndex, slotname, value, slotType);
|
||||
|
||||
if (value.getNotCoerced() instanceof CompoundableBinaryOp) {
|
||||
|
||||
+2
-2
@@ -50,12 +50,12 @@ public class SetSuperIns extends InstructionDefinition implements SetTypeIns {
|
||||
|
||||
FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins);
|
||||
GraphTargetItem obj = stack.pop();
|
||||
|
||||
|
||||
Reference<Boolean> isStatic = new Reference<>(false);
|
||||
Reference<GraphTargetItem> type = new Reference<>(null);
|
||||
Reference<GraphTargetItem> callType = new Reference<>(null);
|
||||
GetPropertyIns.resolvePropertyType(localData, obj /*??*/, multiname, isStatic, type, callType);
|
||||
|
||||
|
||||
SetSuperAVM2Item result = new SetSuperAVM2Item(ins, localData.lineStartInstruction, value, obj, multiname, type.getVal(), callType.getVal(), isStatic.getVal());
|
||||
|
||||
if (value.getNotCoercedNoDup() instanceof CompoundableBinaryOp) {
|
||||
|
||||
+2
-2
@@ -44,7 +44,7 @@ public class DecLocalPIns extends InstructionDefinition {
|
||||
|
||||
super.verify(lda, constants, ins);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getStackPopCount(AVM2Instruction ins, ABC abc) {
|
||||
return 0;
|
||||
@@ -53,5 +53,5 @@ public class DecLocalPIns extends InstructionDefinition {
|
||||
@Override
|
||||
public int getStackPushCount(AVM2Instruction ins, ABC abc) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -44,7 +44,7 @@ public class DecrementPIns extends InstructionDefinition {
|
||||
|
||||
super.verify(lda, constants, ins);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getStackPopCount(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
@@ -53,5 +53,5 @@ public class DecrementPIns extends InstructionDefinition {
|
||||
@Override
|
||||
public int getStackPushCount(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -44,7 +44,7 @@ public class IncLocalPIns extends InstructionDefinition {
|
||||
|
||||
super.verify(lda, constants, ins);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getStackPopCount(AVM2Instruction ins, ABC abc) {
|
||||
return 0;
|
||||
@@ -53,5 +53,5 @@ public class IncLocalPIns extends InstructionDefinition {
|
||||
@Override
|
||||
public int getStackPushCount(AVM2Instruction ins, ABC abc) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -53,5 +53,5 @@ public class IncrementPIns extends InstructionDefinition {
|
||||
@Override
|
||||
public int getStackPushCount(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -47,8 +47,8 @@ public class PushDNanIns extends InstructionDefinition {
|
||||
@Override
|
||||
public int getStackPopCount(AVM2Instruction ins, ABC abc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackPushCount(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
|
||||
+2
-2
@@ -48,8 +48,8 @@ public class PushDecimalIns extends InstructionDefinition {
|
||||
@Override
|
||||
public int getStackPopCount(AVM2Instruction ins, ABC abc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackPushCount(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
|
||||
+2
-3
@@ -48,12 +48,11 @@ public class PushFloat4Ins extends InstructionDefinition {
|
||||
@Override
|
||||
public int getStackPopCount(AVM2Instruction ins, ABC abc) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStackPushCount(AVM2Instruction ins, ABC abc) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ public class PushFloatIns extends InstructionDefinition {
|
||||
|
||||
super.verify(lda, constants, ins);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getStackPopCount(AVM2Instruction ins, ABC abc) {
|
||||
return 0;
|
||||
|
||||
+3
-2
@@ -28,8 +28,9 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class AbsJumpIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+3
-2
@@ -28,8 +28,9 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class AddDIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+3
-2
@@ -28,8 +28,9 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class AllocIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class CallInterfaceIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+2
-1
@@ -28,7 +28,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class CallSuperIdIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class CodeGenOpIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class ConcatIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class DecodeIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
*
|
||||
* source: ??
|
||||
*/
|
||||
public class DelDescendantsIns extends InstructionDefinition {
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
*
|
||||
* source: ??
|
||||
*/
|
||||
public class DeletePropertyLateIns extends InstructionDefinition {
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class DoubleToAtomIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+3
-2
@@ -29,8 +29,9 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/adobe-flash/avmplus/blob/65a05927767f3735db37823eebf7d743531f5d37/utils/abcdis/abc/Constants.as
|
||||
*
|
||||
* source:
|
||||
* https://github.com/adobe-flash/avmplus/blob/65a05927767f3735db37823eebf7d743531f5d37/utils/abcdis/abc/Constants.as
|
||||
* (internal only)
|
||||
*/
|
||||
public class FindPropGlobalIns extends InstructionDefinition {
|
||||
|
||||
+4
-3
@@ -29,8 +29,9 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/adobe-flash/avmplus/blob/65a05927767f3735db37823eebf7d743531f5d37/utils/abcdis/abc/Constants.as
|
||||
*
|
||||
* source:
|
||||
* https://github.com/adobe-flash/avmplus/blob/65a05927767f3735db37823eebf7d743531f5d37/utils/abcdis/abc/Constants.as
|
||||
* (internal only)
|
||||
*/
|
||||
public class FindPropGlobalStrictIns extends InstructionDefinition {
|
||||
@@ -47,7 +48,7 @@ public class FindPropGlobalStrictIns extends InstructionDefinition {
|
||||
|
||||
super.verify(lda, constants, ins);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getStackPopCount(AVM2Instruction ins, ABC abc) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
+3
-2
@@ -24,8 +24,9 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/magicalhobo/SWFWire/blob/master/SWFWireDecompiler/src/com/swfwire/decompiler/abc/ABCInstructions.as
|
||||
*
|
||||
* source:
|
||||
* https://github.com/magicalhobo/SWFWire/blob/master/SWFWireDecompiler/src/com/swfwire/decompiler/abc/ABCInstructions.as
|
||||
* collides with getouterscope
|
||||
*/
|
||||
public class GetPropertyLateIns extends InstructionDefinition {
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
*
|
||||
* source: ??
|
||||
*/
|
||||
public class InvalidIns extends InstructionDefinition {
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class MarkIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class PrologueIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
*
|
||||
* source: ??
|
||||
*/
|
||||
public class PushConstantIns extends InstructionDefinition {
|
||||
@@ -37,7 +37,7 @@ public class PushConstantIns extends InstructionDefinition {
|
||||
public PushConstantIns() {
|
||||
super(0x22, "pushconstant", new int[]{AVM2Code.OPT_U30}, false /*?*/, AVM2InstructionFlag.UNDOCUMENTED, AVM2InstructionFlag.UNKNOWN_STACK, AVM2InstructionFlag.NO_FLASH_PLAYER);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void verify(LocalDataArea lda, AVM2ConstantPool constants, AVM2Instruction ins) throws AVM2VerifyErrorException {
|
||||
if (lda.getRuntime() == AVM2Runtime.ADOBE_FLASH) {
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class SendEnterIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
*
|
||||
* source: ??
|
||||
*/
|
||||
public class SetPropertyLateIns extends InstructionDefinition {
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class SweepIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class VerifyOpIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class VerifyPassIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* source: https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
* source:
|
||||
* https://github.com/apache/flex-sdk/blob/414b9a3e55effd243a697e614b702d1fa0b53efe/modules/asc/src/java/macromedia/abc/Opcodes.java
|
||||
*/
|
||||
public class WbIns extends InstructionDefinition {
|
||||
|
||||
|
||||
+6
-6
@@ -51,19 +51,19 @@ public class PushScopeIns extends InstructionDefinition {
|
||||
@Override
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
GraphTargetItem top = stack.pop();
|
||||
|
||||
|
||||
//Hack for catch inside catch to not detect pushscope register as used
|
||||
if (top instanceof LocalRegAVM2Item) {
|
||||
LocalRegAVM2Item getLocal = (LocalRegAVM2Item)top;;
|
||||
if(getLocal.getSrc() != null){
|
||||
LocalRegAVM2Item getLocal = (LocalRegAVM2Item) top;;
|
||||
if (getLocal.getSrc() != null) {
|
||||
int getLocalIp = localData.code.adr2pos(getLocal.getSrc().getAddress());
|
||||
for(int setLocalPos : localData.setLocalPosToGetLocalPos.keySet()){
|
||||
if (localData.setLocalPosToGetLocalPos.get(setLocalPos).contains(getLocalIp)){
|
||||
for (int setLocalPos : localData.setLocalPosToGetLocalPos.keySet()) {
|
||||
if (localData.setLocalPosToGetLocalPos.get(setLocalPos).contains(getLocalIp)) {
|
||||
localData.setLocalPosToGetLocalPos.get(setLocalPos).remove(getLocalIp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
localData.localScopeStack.push(top);
|
||||
}
|
||||
|
||||
+5
-5
@@ -36,11 +36,7 @@ public class CoerceAIns extends InstructionDefinition implements CoerceOrConvert
|
||||
|
||||
public CoerceAIns() {
|
||||
super(0x82, "coerce_a", new int[]{}, true);
|
||||
}
|
||||
|
||||
public String getTargetType() {
|
||||
return "*";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(LocalDataArea lda, AVM2ConstantPool constants, AVM2Instruction ins) {
|
||||
@@ -64,6 +60,10 @@ public class CoerceAIns extends InstructionDefinition implements CoerceOrConvert
|
||||
return 1;
|
||||
}
|
||||
|
||||
public String getTargetType() {
|
||||
return "*";
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphTargetItem getTargetType(AVM2ConstantPool constants, AVM2Instruction ins) {
|
||||
return TypeItem.UNBOUNDED;
|
||||
|
||||
@@ -111,15 +111,15 @@ public abstract class AVM2Item extends GraphTargetItem {
|
||||
if (empty) {
|
||||
return propertyName.toString(writer, localData);
|
||||
}
|
||||
|
||||
|
||||
if (propertyName instanceof FullMultinameAVM2Item) {
|
||||
|
||||
|
||||
HighlightData data = new HighlightData();
|
||||
int multinameIndex = ((FullMultinameAVM2Item) propertyName).multinameIndex;
|
||||
int namespaceIndex = localData.constantsAvm2.getMultiname(multinameIndex).namespace_index;
|
||||
GraphTargetItem returnType = object.returnType();
|
||||
if (returnType instanceof ApplyTypeAVM2Item) {
|
||||
ApplyTypeAVM2Item ati = (ApplyTypeAVM2Item)returnType;
|
||||
ApplyTypeAVM2Item ati = (ApplyTypeAVM2Item) returnType;
|
||||
data.propertyType = ati.object.toString();
|
||||
data.propertySubType = ati.params.get(0).toString();
|
||||
} else {
|
||||
@@ -127,9 +127,9 @@ public abstract class AVM2Item extends GraphTargetItem {
|
||||
}
|
||||
data.namespaceIndex = namespaceIndex;
|
||||
data.isStatic = isStatic;
|
||||
|
||||
|
||||
if (((FullMultinameAVM2Item) propertyName).name != null) {
|
||||
if (((FullMultinameAVM2Item) propertyName).namespace != null) {
|
||||
if (((FullMultinameAVM2Item) propertyName).namespace != null) {
|
||||
//writer.append(".");
|
||||
writer.hilightSpecial(".", HighlightSpecialType.PROPERTY_TYPE, 0, data);
|
||||
}
|
||||
|
||||
+1
-3
@@ -114,7 +114,7 @@ public class ApplyTypeAVM2Item extends AVM2Item {
|
||||
//int qname = AVM2SourceGenerator.resolveType(localData, object, ((AVM2SourceGenerator)generator).abc, ((AVM2SourceGenerator)generator).allABCs);
|
||||
List<GraphSourceItem> nparams = new ArrayList<>();
|
||||
for (GraphTargetItem i : params) {
|
||||
nparams.addAll(i.toSource(localData, generator));//ins(AVM2Instructions.GetLex, AVM2SourceGenerator.resolveType(localData, i, ((AVM2SourceGenerator)generator).abc,((AVM2SourceGenerator)generator).allABCs)));
|
||||
nparams.addAll(i.toSource(localData, generator));
|
||||
}
|
||||
return toSourceMerge(localData, generator,
|
||||
object,
|
||||
@@ -140,7 +140,5 @@ public class ApplyTypeAVM2Item extends AVM2Item {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class CallAVM2Item extends AVM2Item {
|
||||
|
||||
public List<GraphTargetItem> arguments;
|
||||
|
||||
private static abstract class Func implements Callable {
|
||||
private abstract static class Func implements Callable {
|
||||
|
||||
@Override
|
||||
public Object call(String methodName, List<Object> args) {
|
||||
@@ -227,10 +227,10 @@ public class CallAVM2Item extends AVM2Item {
|
||||
@Override
|
||||
public GraphTargetItem returnType() {
|
||||
if (function instanceof GetPropertyAVM2Item) {
|
||||
return ((GetPropertyAVM2Item)function).callType;
|
||||
return ((GetPropertyAVM2Item) function).callType;
|
||||
}
|
||||
if (function instanceof GetLexAVM2Item) {
|
||||
return ((GetLexAVM2Item)function).callType;
|
||||
return ((GetLexAVM2Item) function).callType;
|
||||
}
|
||||
return TypeItem.UNBOUNDED;
|
||||
}
|
||||
|
||||
+2
-2
@@ -43,9 +43,9 @@ public class CallPropertyAVM2Item extends AVM2Item {
|
||||
public List<GraphTargetItem> arguments;
|
||||
|
||||
public boolean isVoid;
|
||||
|
||||
|
||||
public GraphTargetItem type;
|
||||
|
||||
|
||||
public boolean isStatic;
|
||||
|
||||
public CallPropertyAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, boolean isVoid, GraphTargetItem receiver, GraphTargetItem propertyName, List<GraphTargetItem> arguments, GraphTargetItem type, boolean isStatic) {
|
||||
|
||||
@@ -31,14 +31,14 @@ import com.jpexs.decompiler.graph.model.LocalData;
|
||||
public class ClassAVM2Item extends AVM2Item {
|
||||
|
||||
public Multiname className;
|
||||
|
||||
|
||||
public DottedChain classNameAsStr;
|
||||
|
||||
public ClassAVM2Item(Multiname className) {
|
||||
super(null, null, PRECEDENCE_PRIMARY);
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
|
||||
public ClassAVM2Item(DottedChain className) {
|
||||
super(null, null, PRECEDENCE_PRIMARY);
|
||||
this.classNameAsStr = className;
|
||||
|
||||
@@ -127,15 +127,15 @@ public class CoerceAVM2Item extends AVM2Item {
|
||||
return false;
|
||||
}
|
||||
dependencies.add(value);
|
||||
switch(typeObj.toString()) {
|
||||
switch (typeObj.toString()) {
|
||||
case "String":
|
||||
case "Boolean":
|
||||
case "int":
|
||||
case "uint":
|
||||
case "Number":
|
||||
return value.isConvertedCompileTime(dependencies);
|
||||
return value.isConvertedCompileTime(dependencies);
|
||||
}
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user