fixed deobfuscation

Issue #151 option for caching in memory instead of temp files
This commit is contained in:
Jindra Petk
2013-07-08 20:39:02 +02:00
parent 5ed314d0eb
commit 8bfc8ad30f
14 changed files with 135 additions and 39 deletions

View File

@@ -2013,7 +2013,7 @@ public class SWF {
mat.getRotateSkew1Float(), mat.getScaleYFloat(),
mat.translateX, mat.translateY);
}
private static Cache cache = new Cache(false);
private static Cache cache = Cache.getInstance(false);
public void clearImageCache() {
cache.clear();

View File

@@ -1445,7 +1445,7 @@ public class AVM2Code implements Serializable {
localData.add(abc.method_info);
localData.add(body);
localData.add(abc);
localData.add(new HashMap<Integer, String>()); //localRegNames
localData.add(body.getLocalRegNames(abc)); //localRegNames
localData.add(new ArrayList<String>()); //fullyQualifiedNames
localData.add(new ArrayList<ABCException>());
localData.add(new ArrayList<Integer>());

View File

@@ -39,7 +39,7 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
GraphTargetItem computedValue = localRegs.get(getRegisterId(ins));
if (computedValue == null) {
if (!localRegNames.containsKey(getRegisterId(ins))) {
computedValue = new UndefinedTreeItem(null);
computedValue = new UndefinedTreeItem(null); //In some obfuscated code there seems to be reading of undefined registers
}
}
stack.push(new LocalRegTreeItem(ins, getRegisterId(ins), computedValue));

View File

@@ -31,6 +31,7 @@ import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinReg;
import com.jpexs.decompiler.flash.gui.jna.platform.win32.WinUser;
import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel;
import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame;
import com.jpexs.decompiler.flash.helpers.Cache;
import com.jpexs.decompiler.flash.helpers.Helper;
import com.sun.jna.Platform;
import com.sun.jna.WString;
@@ -467,6 +468,12 @@ public class Main {
View.setLookAndFeel();
Configuration.loadFromFile(getConfigFile(), getReplacementsFile());
if ((Boolean) Configuration.getConfig("cacheOnDisk", Boolean.TRUE)) {
Cache.setStorageType(Cache.STORAGE_FILES);
} else {
Cache.setStorageType(Cache.STORAGE_MEMORY);
}
int pos = 0;
if (args.length > 0) {
if (args[0].equals("-debug")) {

View File

@@ -35,6 +35,7 @@ import com.jpexs.decompiler.flash.gui.abc.LineMarkedEditorPane;
import com.jpexs.decompiler.flash.gui.abc.TreeElement;
import com.jpexs.decompiler.flash.gui.action.ActionPanel;
import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel;
import com.jpexs.decompiler.flash.helpers.Cache;
import com.jpexs.decompiler.flash.helpers.Helper;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
@@ -224,6 +225,7 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection
private JCheckBoxMenuItem miParallelSpeedUp;
private JCheckBoxMenuItem miAssociate;
private JCheckBoxMenuItem miDecompile;
private JCheckBoxMenuItem miCacheDisk;
public void setPercent(int percent) {
progressBar.setValue(percent);
@@ -482,11 +484,18 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection
miDecompile.setActionCommand("DISABLEDECOMPILATION");
miDecompile.addActionListener(this);
miCacheDisk = new JCheckBoxMenuItem(translate("menu.settings.cacheOnDisk"));
miCacheDisk.setSelected((Boolean) Configuration.getConfig("cacheOnDisk", Boolean.TRUE));
miCacheDisk.setActionCommand("CACHEONDISK");
miCacheDisk.addActionListener(this);
JMenu menuSettings = new JMenu(translate("menu.settings"));
menuSettings.add(autoDeobfuscateMenuItem);
menuSettings.add(miInternalViewer);
menuSettings.add(miParallelSpeedUp);
menuSettings.add(miDecompile);
menuSettings.add(miCacheDisk);
miAssociate = new JCheckBoxMenuItem(translate("menu.settings.addtocontextmenu"));
@@ -1566,6 +1575,14 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection
@Override
public void actionPerformed(ActionEvent e) {
switch (e.getActionCommand()) {
case "CACHEONDISK":
Configuration.setConfig("cacheOnDisk", miCacheDisk.isSelected());
if (miCacheDisk.isSelected()) {
Cache.setStorageType(Cache.STORAGE_FILES);
} else {
Cache.setStorageType(Cache.STORAGE_MEMORY);
}
break;
case "SETLANGUAGE":
String newLanguage = new SelectLanguageDialog().display();
if (newLanguage != null) {

View File

@@ -50,7 +50,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
private ABCPanel abcPanel;
private int classIndex = -1;
private boolean isStatic = false;
private Cache cache = new Cache(true);
private Cache cache = Cache.getInstance(true);
public ScriptPack getScriptLeaf() {
return script;
@@ -254,6 +254,9 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
}
private CachedDecompilation getCached(ScriptPack pack) {
if (!cache.contains(pack)) {
cacheScriptPack(pack, abcList);
}
return (CachedDecompilation) cache.get(pack);
}

View File

@@ -107,7 +107,7 @@ public class ActionPanel extends JPanel implements ActionListener {
private String searchFor;
private boolean searchIgnoreCase;
private boolean searchRegexp;
private Cache cache = new Cache(true);
private Cache cache = Cache.getInstance(true);
public void clearCache() {
cache.clear();

View File

@@ -39,6 +39,7 @@ menu.settings.parallelspeedup = Parallel SpeedUp
menu.settings.disabledecompilation = Disable decompilation (Disassemble only)
menu.settings.addtocontextmenu = Add FFDec to SWF files context menu
menu.settings.language = Change language
menu.settings.cacheOnDisk = Use caching on disk
menu.help = Help
menu.help.checkupdates = Check for updates...

View File

@@ -40,6 +40,7 @@ menu.settings.parallelspeedup = Paraleln\u00ed zrychlen\u00ed
menu.settings.disabledecompilation = Zak\u00e1zat dekompilaci (Pouze P-k\u00f3d)
menu.settings.addtocontextmenu = P\u0159idat FFDec do kontextov\u00e9ho menu SWF
menu.settings.language = Zm\u011bnit jazyk
menu.settings.cacheOnDisk = Pou\u017e\u00edvat cache na disku
menu.help = N\u00e1pov\u011bda
menu.help.checkupdates = Zkontrolovat novou verzi...

View File

@@ -22,7 +22,9 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.logging.Level;
@@ -35,12 +37,52 @@ import java.util.logging.Logger;
public class Cache {
private Map<Object, File> cacheFiles;
private Map<Object, Object> cacheMemory;
private static List<Cache> instances = new ArrayList<>();
public static final int STORAGE_FILES = 1;
public static final int STORAGE_MEMORY = 2;
public Cache(boolean weak) {
public static Cache getInstance(boolean weak) {
Cache instance = new Cache(weak);
instances.add(instance);
return instance;
}
private static int storageType = STORAGE_FILES;
public static void clearAll() {
for (Cache c : instances) {
c.clear();
}
}
public static void setStorageType(int storageType) {
if (storageType == Cache.storageType) {
return;
}
switch (storageType) {
case STORAGE_FILES:
case STORAGE_MEMORY:
break;
default:
throw new IllegalArgumentException("storageType must be one of STORAGE_FILES or STORAGE_MEMORY");
}
if (storageType != Cache.storageType) {
clearAll();
}
Cache.storageType = storageType;
}
public static int getStorageType() {
return storageType;
}
private Cache(boolean weak) {
if (weak) {
cacheFiles = new WeakHashMap<>();
cacheMemory = new WeakHashMap<>();
} else {
cacheFiles = new HashMap<>();
cacheMemory = new HashMap<>();
}
}
@@ -49,6 +91,7 @@ public class Cache {
}
public void clear() {
cacheMemory.clear();
for (File f : cacheFiles.values()) {
f.delete();
}
@@ -56,43 +99,67 @@ public class Cache {
}
public void remove(Object key) {
if (cacheFiles.containsKey(key)) {
File f = cacheFiles.get(key);
f.delete();
cacheFiles.remove(key);
if (storageType == STORAGE_FILES) {
if (cacheFiles.containsKey(key)) {
File f = cacheFiles.get(key);
f.delete();
cacheFiles.remove(key);
}
} else if (storageType == STORAGE_MEMORY) {
if (cacheMemory.containsKey(key)) {
cacheMemory.remove(key);
}
}
}
public Object get(Object key) {
if (!cacheFiles.containsKey(key)) {
if (storageType == STORAGE_FILES) {
if (!cacheFiles.containsKey(key)) {
return null;
}
File f = cacheFiles.get(key);
try (FileInputStream fis = new FileInputStream(f)) {
ObjectInputStream ois = new ObjectInputStream(fis);
return ois.readObject();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Helper.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
} else if (storageType == STORAGE_MEMORY) {
if (!cacheMemory.containsKey(key)) {
return cacheMemory.get(key);
}
return null;
}
File f = cacheFiles.get(key);
try (FileInputStream fis = new FileInputStream(f)) {
ObjectInputStream ois = new ObjectInputStream(fis);
return ois.readObject();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Helper.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public void put(Object key, Object value) {
File temp = null;
try {
temp = File.createTempFile("ffdec_cache", ".tmp");
} catch (IOException ex) {
Logger.getLogger(Cache.class.getName()).log(Level.SEVERE, null, ex);
return;
}
temp.deleteOnExit();
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(temp))) {
oos.writeObject(value);
oos.flush();
if (storageType == STORAGE_FILES) {
File temp = null;
try {
temp = File.createTempFile("ffdec_cache", ".tmp");
} catch (IOException ex) {
Logger.getLogger(Cache.class
.getName()).log(Level.SEVERE, null, ex);
cacheFiles.put(key, temp);
} catch (IOException ex) {
Logger.getLogger(Helper.class.getName()).log(Level.SEVERE, null, ex);
return;
}
temp.deleteOnExit();
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(temp))) {
oos.writeObject(value);
oos.flush();
cacheFiles.put(key, temp);
} catch (IOException ex) {
Logger.getLogger(Helper.class
.getName()).log(Level.SEVERE, null, ex);
}
} else if (storageType == STORAGE_MEMORY) {
cacheMemory.put(key, value);
}
}
}

View File

@@ -72,7 +72,7 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
bitmapData.bitmapPixelDataPix24[pos] = new PIX24();
bitmapData.bitmapPixelDataPix24[pos].red = r;
bitmapData.bitmapPixelDataPix24[pos].green = g;
bitmapData.bitmapPixelDataPix24[pos].blue = b;
bitmapData.bitmapPixelDataPix24[pos].blue = b;
bitmapData.bitmapPixelDataPix24[pos].reserved = 0xff; //documentation says 0, but image is sometimes broken with 0, so there is 0xff, which works (maybe alpha?)
pos++;
}
@@ -86,7 +86,7 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
zlibBitmapData = zlibOS.toByteArray();
decompressed = false;
}
@Override
public BufferedImage getImage(List<Tag> tags) {
BufferedImage bi = new BufferedImage(bitmapWidth, bitmapHeight, BufferedImage.TYPE_INT_RGB);
@@ -168,8 +168,8 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
bitmapColorTableSize = sis.readUI8();
}
zlibBitmapData = sis.readBytes(sis.available());
}
}
/**
* Gets data bytes
*

View File

@@ -201,7 +201,7 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
}
return needed;
}
private static Cache rectCache = new Cache(true);
private static Cache rectCache = Cache.getInstance(true);
@Override
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {

View File

@@ -204,7 +204,7 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
}
return needed;
}
private static Cache rectCache = new Cache(true);
private static Cache rectCache = Cache.getInstance(true);
@Override
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {

View File

@@ -100,7 +100,7 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
}
return ret;
}
private static Cache rectCache = new Cache(true);
private static Cache rectCache = Cache.getInstance(true);
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {