Added Checkstyle to build process and fixing checkstyle to all com.src.jpexs classes

This commit is contained in:
Jindra Petřík
2023-10-16 09:36:06 +02:00
parent b6e8ca0d67
commit dc5e50813f
789 changed files with 23773 additions and 22843 deletions
@@ -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)));
@@ -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<>();
@@ -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
@@ -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.
@@ -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.
@@ -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);
@@ -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();
}
@@ -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;
@@ -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;
@@ -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) {
@@ -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) {
@@ -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);
}
}
@@ -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();
@@ -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;
@@ -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) {
@@ -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);
}
}
@@ -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;
}
@@ -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);
@@ -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;
@@ -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()));
}
@@ -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);
@@ -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()));
}
@@ -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 {
@@ -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()));
}
@@ -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;
@@ -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;
@@ -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"));
}
}
}
}
}
@@ -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;
@@ -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
@@ -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;
/**
@@ -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);
@@ -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);
}
@@ -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) {
@@ -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) {
@@ -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;
}
}
}
@@ -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;
}
}
}
@@ -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;
}
}
}
@@ -53,5 +53,5 @@ public class IncrementPIns extends InstructionDefinition {
@Override
public int getStackPushCount(AVM2Instruction ins, ABC abc) {
return 1;
}
}
}
@@ -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;
@@ -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;
@@ -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;
}
}
@@ -44,7 +44,7 @@ public class PushFloatIns extends InstructionDefinition {
super.verify(lda, constants, ins);
}
@Override
public int getStackPopCount(AVM2Instruction ins, ABC abc) {
return 0;
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -29,7 +29,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
/**
*
* @author JPEXS
*
*
* source: ??
*/
public class DelDescendantsIns extends InstructionDefinition {
@@ -28,7 +28,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
/**
*
* @author JPEXS
*
*
* source: ??
*/
public class DeletePropertyLateIns extends InstructionDefinition {
@@ -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 {
@@ -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 {
@@ -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();
@@ -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 {
@@ -27,7 +27,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
/**
*
* @author JPEXS
*
*
* source: ??
*/
public class InvalidIns extends InstructionDefinition {
@@ -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 {
@@ -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 {
@@ -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) {
@@ -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 {
@@ -28,7 +28,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
/**
*
* @author JPEXS
*
*
* source: ??
*/
public class SetPropertyLateIns extends InstructionDefinition {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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);
}
@@ -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);
}
@@ -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;
}
@@ -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