mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-08-02 15:32:15 +00:00
Open loaded SWFs during playback feature
This commit is contained in:
@@ -12,17 +12,30 @@
|
||||
private static var first:Boolean = true;
|
||||
private static var inited:Boolean = false;
|
||||
private static var name:String;
|
||||
public static const DEBUG_VERSION_MAJOR = 1;
|
||||
public static const DEBUG_VERSION_MINOR = 1;
|
||||
|
||||
public static const MSG_STRING = 0;
|
||||
public static const MSG_LOADER_URL = 1;
|
||||
public static const MSG_LOADER_BYTES = 2;
|
||||
|
||||
|
||||
|
||||
private static function sendQueue(){
|
||||
var qo = q;
|
||||
q = [];
|
||||
for each(var m in qo){
|
||||
writeMsg(m);
|
||||
writeMsg(m.data,m.type);
|
||||
}
|
||||
}
|
||||
|
||||
private static function writeStringNull(msg){
|
||||
var b:ByteArray = new ByteArray();
|
||||
b.writeUTFBytes(msg);
|
||||
s.writeBytes(b,0,b.length);
|
||||
s.writeByte(0);
|
||||
}
|
||||
|
||||
private static function writeString(msg){
|
||||
var b:ByteArray = new ByteArray();
|
||||
b.writeUTFBytes(msg);
|
||||
@@ -31,6 +44,14 @@
|
||||
s.writeBytes(b,0,b.length);
|
||||
}
|
||||
|
||||
private static function writeBytes(b:ByteArray){
|
||||
s.writeByte((b.length>>24) & 0xff);
|
||||
s.writeByte((b.length>>16) & 0xff);
|
||||
s.writeByte((b.length>>8) & 0xff);
|
||||
s.writeByte(b.length & 0xff);
|
||||
s.writeBytes(b,0,b.length);
|
||||
}
|
||||
|
||||
public static function initClient(sname){
|
||||
if(inited){
|
||||
return;
|
||||
@@ -47,19 +68,43 @@
|
||||
inited = true;
|
||||
}
|
||||
|
||||
public static function writeMsg(msg){
|
||||
|
||||
public static function writeLoaderURL(url){
|
||||
writeMsg(url,MSG_LOADER_URL);
|
||||
}
|
||||
|
||||
|
||||
public static function writeLoaderBytes(data:ByteArray){
|
||||
writeMsg(data,MSG_LOADER_BYTES);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function writeMsg(msg,msgType=0){
|
||||
if(!inited){
|
||||
initClient("");
|
||||
}
|
||||
if(s.connected){
|
||||
if(first){
|
||||
s.writeByte(0);
|
||||
//s.writeByte(0);
|
||||
writeStringNull("debug.version.major="+DEBUG_VERSION_MAJOR+";debug.version.minor="+DEBUG_VERSION_MINOR);
|
||||
writeString(name);
|
||||
first = false;
|
||||
}
|
||||
s.writeByte(msgType);
|
||||
switch(msgType){
|
||||
case MSG_STRING:
|
||||
writeString(msg);
|
||||
break;
|
||||
case MSG_LOADER_URL:
|
||||
writeString(msg);
|
||||
break;
|
||||
case MSG_LOADER_BYTES:
|
||||
writeBytes(msg);
|
||||
break;
|
||||
}
|
||||
writeString(msg);
|
||||
}else{
|
||||
q.push(msg);
|
||||
q.push({type:msgType,data:msg});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.jpexs.decompiler.flash.debugger {
|
||||
|
||||
import flash.display.Loader;
|
||||
import flash.net.URLRequest;
|
||||
import flash.system.LoaderContext;
|
||||
import flash.utils.ByteArray;
|
||||
|
||||
public class DebugLoader extends Loader {
|
||||
|
||||
|
||||
public override function load(request:URLRequest, context:LoaderContext = null):void {
|
||||
DebugConnection.writeLoaderURL(request.url);
|
||||
super.load(request,context);
|
||||
}
|
||||
|
||||
public override function loadBytes(bytes:ByteArray, context:LoaderContext = null):void {
|
||||
DebugConnection.writeLoaderBytes(bytes);
|
||||
super.loadBytes(bytes,context);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
debugConsole("test console");
|
||||
debugSocket("test proxy");
|
||||
debugTrace("test trace");
|
||||
var loader:DebugLoader = new DebugLoader();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
import flash.external.ExternalInterface;
|
||||
|
||||
public function debugAlert(msg):*{
|
||||
if(ExternalInterface.available)
|
||||
ExternalInterface.call("alert",""+msg);
|
||||
return msg;
|
||||
public function debugAlert(...msg):void{
|
||||
for each(var n in msg){
|
||||
if(ExternalInterface.available)
|
||||
ExternalInterface.call("alert",""+n);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
import flash.external.ExternalInterface;
|
||||
|
||||
public function debugConsole(msg):*{
|
||||
if(ExternalInterface.available)
|
||||
ExternalInterface.call("console.log",""+msg);
|
||||
return msg;
|
||||
public function debugConsole(...msg):*{
|
||||
for each(var n in msg){
|
||||
if(ExternalInterface.available)
|
||||
ExternalInterface.call("console.log",""+n);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package com.jpexs.decompiler.flash.debugger {
|
||||
import flash.system.Capabilities;
|
||||
|
||||
public function debugSocket(msg):*{
|
||||
//only on webpages or activex
|
||||
if(Capabilities.playerType == 'PlugIn'
|
||||
|| Capabilities.playerType == 'ActiveX'){
|
||||
DebugConnection.writeMsg(msg);
|
||||
public function debugSocket(...msg):*{
|
||||
for each(var n in msg){
|
||||
//only on webpages or activex
|
||||
if(Capabilities.playerType == 'PlugIn'
|
||||
|| Capabilities.playerType == 'ActiveX'){
|
||||
DebugConnection.writeMsg(n);
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.jpexs.decompiler.flash.debugger {
|
||||
|
||||
|
||||
public function debugTrace(name){
|
||||
debugConsole(name);
|
||||
debugSocket(name);
|
||||
public function debugTrace(...msg){
|
||||
for each(var n in msg){
|
||||
debugConsole(n);
|
||||
debugSocket(n);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -494,6 +494,10 @@ public class Configuration {
|
||||
@ConfigurationCategory("script")
|
||||
public static final ConfigurationItem<Boolean> enableScriptInitializerDisplay = null;
|
||||
|
||||
@ConfigurationDefaultBoolean(false)
|
||||
@ConfigurationCategory("ui")
|
||||
public static final ConfigurationItem<Boolean> autoOpenLoadedSWFs = null;
|
||||
|
||||
private enum OSId {
|
||||
|
||||
WINDOWS, OSX, UNIX
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWFSourceInfo;
|
||||
import com.jpexs.decompiler.flash.gui.debugger.DebugListener;
|
||||
import com.jpexs.decompiler.flash.gui.debugger.Debugger;
|
||||
import java.awt.BorderLayout;
|
||||
@@ -24,6 +25,7 @@ import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
@@ -61,6 +63,16 @@ public class DebugLogDialog extends AppDialog {
|
||||
public void onFinish(String clientId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderURL(String clientId, String url) {
|
||||
log(translate("msg.header").replace("%clientid%", clientId) + " LOADURL:" + url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderBytes(String clientId, byte[] data) {
|
||||
log(translate("msg.header").replace("%clientid%", clientId) + " LOADBYTES: " + data.length + "B");
|
||||
}
|
||||
});
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
|
||||
@@ -30,6 +30,8 @@ import com.jpexs.decompiler.flash.configuration.SwfSpecificConfiguration;
|
||||
import com.jpexs.decompiler.flash.console.CommandLineArgumentParser;
|
||||
import com.jpexs.decompiler.flash.console.ContextMenuTools;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ExeExportMode;
|
||||
import com.jpexs.decompiler.flash.gui.debugger.DebugListener;
|
||||
import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools;
|
||||
import com.jpexs.decompiler.flash.gui.pipes.FirstInstance;
|
||||
import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame;
|
||||
import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
|
||||
@@ -60,6 +62,7 @@ import java.awt.event.MouseEvent;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -77,9 +80,11 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
@@ -910,6 +915,20 @@ public class Main {
|
||||
ErrorLogFrame.getInstance().setVisible(true);
|
||||
}
|
||||
|
||||
private static String md5(byte data[]) {
|
||||
try {
|
||||
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
|
||||
byte[] array = md.digest(data);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (java.security.NoSuchAlgorithmException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void initGui() {
|
||||
if (GraphicsEnvironment.isHeadless()) {
|
||||
System.err.println("Error: Your system does not support Graphic User Interface");
|
||||
@@ -942,6 +961,41 @@ public class Main {
|
||||
autoCheckForUpdates();
|
||||
offerAssociation();
|
||||
loadingDialog = new LoadingDialog();
|
||||
|
||||
DebuggerTools.initDebugger().addMessageListener(new DebugListener() {
|
||||
|
||||
@Override
|
||||
public void onMessage(String clientId, String msg) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderURL(String clientId, String url) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderBytes(String clientId, byte[] data) {
|
||||
String hash = md5(data);
|
||||
for (SWFList sl : Main.getMainFrame().getPanel().getSwfs()) {
|
||||
for (int s = 0; s < sl.size(); s++) {
|
||||
String t = sl.get(s).getFileTitle();
|
||||
if (t == null) {
|
||||
t = "";
|
||||
}
|
||||
if (t.endsWith(":" + hash)) { //this one is already opened
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
SWF swf = Main.getMainFrame().getPanel().getCurrentSwf();
|
||||
|
||||
String title = swf == null ? "?" : swf.getFileTitle();
|
||||
openFile(new SWFSourceInfo(new ByteArrayInputStream(data), null, title + ":" + hash));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish(String clientId) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void showModeFrame() {
|
||||
|
||||
@@ -374,6 +374,11 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
DebuggerTools.debuggerShowLog();
|
||||
}
|
||||
|
||||
protected void debuggerInjectLoader(ActionEvent evt) {
|
||||
DebuggerTools.injectDebugLoader(swf);
|
||||
refreshDecompiled();
|
||||
}
|
||||
|
||||
protected void debuggerReplaceTraceCallsActionPerformed(ActionEvent evt) {
|
||||
ReplaceTraceDialog rtd = new ReplaceTraceDialog(Configuration.lastDebuggerReplaceFunction.get());
|
||||
rtd.setVisible(true);
|
||||
@@ -518,6 +523,13 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
Configuration.gotoMainClassOnStartup.set(selected);
|
||||
}
|
||||
|
||||
protected void autoOpenLoadedSWFsActionPerformed(ActionEvent evt) {
|
||||
AbstractButton button = (AbstractButton) evt.getSource();
|
||||
boolean selected = button.isSelected();
|
||||
|
||||
Configuration.autoOpenLoadedSWFs.set(selected);
|
||||
}
|
||||
|
||||
protected void autoRenameIdentifiersActionPerformed(ActionEvent evt) {
|
||||
AbstractButton button = (AbstractButton) evt.getSource();
|
||||
boolean selected = button.isSelected();
|
||||
@@ -672,6 +684,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
setMenuEnabled("/tools/debugger/debuggerSwitch", hasAbc);
|
||||
setMenuChecked("/tools/debugger/debuggerSwitch", hasDebugger);
|
||||
setMenuEnabled("/tools/debugger/debuggerReplaceTrace", hasAbc && hasDebugger);
|
||||
//setMenuEnabled("/tools/debugger/debuggerInjectLoader", hasAbc && hasDebugger);
|
||||
|
||||
setMenuEnabled("_/checkUpdates", !isWorking);
|
||||
setMenuEnabled("/help/checkUpdates", !isWorking);
|
||||
@@ -780,6 +793,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
addMenuItem("/tools/debugger", translate("menu.debugger"), null, null, 0, null, false);
|
||||
addToggleMenuItem("/tools/debugger/debuggerSwitch", translate("menu.debugger.switch"), null, "debugger32", this::debuggerSwitchActionPerformed, PRIORITY_TOP);
|
||||
addMenuItem("/tools/debugger/debuggerReplaceTrace", translate("menu.debugger.replacetrace"), "debuggerreplace16", this::debuggerReplaceTraceCallsActionPerformed, PRIORITY_MEDIUM, null, true);
|
||||
//addMenuItem("/tools/debugger/debuggerInjectLoader", "Inject Loader", "debuggerreplace16", this::debuggerInjectLoader, PRIORITY_MEDIUM, null, true);
|
||||
addMenuItem("/tools/debugger/debuggerShowLog", translate("menu.debugger.showlog"), "debuggerlog16", this::debuggerShowLogActionPerformed, PRIORITY_MEDIUM, null, true);
|
||||
finishMenu("/tools/debugger");
|
||||
|
||||
@@ -796,7 +810,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
addToggleMenuItem("/settings/cacheOnDisk", translate("menu.settings.cacheOnDisk"), null, null, this::cacheOnDiskActionPerformed, 0);
|
||||
addToggleMenuItem("/settings/gotoMainClassOnStartup", translate("menu.settings.gotoMainClassOnStartup"), null, null, this::gotoDucumentClassOnStartupActionPerformed, 0);
|
||||
addToggleMenuItem("/settings/autoRenameIdentifiers", translate("menu.settings.autoRenameIdentifiers"), null, null, this::autoRenameIdentifiersActionPerformed, 0);
|
||||
|
||||
addToggleMenuItem("/settings/autoOpenLoadedSWFs", translate("menu.settings.autoOpenLoadedSWFs"), null, null, this::autoOpenLoadedSWFsActionPerformed, 0);
|
||||
if (Platform.isWindows()) {
|
||||
addToggleMenuItem("/settings/associate", translate("menu.settings.addtocontextmenu"), null, null, this::associateActionPerformed, 0);
|
||||
}
|
||||
@@ -858,6 +872,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
|
||||
if (externalFlashPlayerUnavailable) {
|
||||
setMenuEnabled("/settings/internalViewer", false);
|
||||
setMenuEnabled("/settings/autoOpenLoadedSWFs", false);
|
||||
}
|
||||
|
||||
/*int deobfuscationMode = Configuration.deobfuscationMode.get();
|
||||
@@ -954,6 +969,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
setMenuChecked("/tools/debugger/debuggerSwitch", false);
|
||||
}
|
||||
setMenuEnabled("/tools/debugger/debuggerReplaceTrace", isMenuChecked("/tools/debugger/debuggerSwitch"));
|
||||
//setMenuEnabled("/tools/debugger/debuggerInjectLoader", isMenuChecked("/tools/debugger/debuggerSwitch"));
|
||||
}
|
||||
|
||||
private void timelineActionPerformed(ActionEvent evt) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.gui.controls.JPersistentSplitPane;
|
||||
import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools;
|
||||
import com.jpexs.decompiler.flash.gui.editor.LineMarkedEditorPane;
|
||||
import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel;
|
||||
import com.jpexs.decompiler.flash.gui.player.MediaDisplay;
|
||||
@@ -79,6 +80,7 @@ import java.awt.event.ActionEvent;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
@@ -1072,9 +1074,25 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile))) {
|
||||
swf.saveTo(fos);
|
||||
}
|
||||
//Inject Loader
|
||||
if (swf.isAS3() && Configuration.autoOpenLoadedSWFs.get() && !Configuration.internalFlashViewer.get() && !DebuggerTools.hasDebugger(swf)) {
|
||||
SWF instrSWF = null;
|
||||
try (FileInputStream fis = new FileInputStream(tempFile)) {
|
||||
instrSWF = new SWF(fis, false, false);
|
||||
}
|
||||
if (instrSWF != null) {
|
||||
DebuggerTools.switchDebugger(instrSWF);
|
||||
DebuggerTools.injectDebugLoader(instrSWF);
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile))) {
|
||||
instrSWF.saveTo(fos);
|
||||
}
|
||||
}
|
||||
}
|
||||
flashPanel.displaySWF(tempFile.getAbsolutePath(), backgroundColor, swf.frameRate);
|
||||
} catch (IOException iex) {
|
||||
Logger.getLogger(PreviewPanel.class.getName()).log(Level.SEVERE, "Cannot create tempfile", iex);
|
||||
} catch (InterruptedException ex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,5 +24,9 @@ public interface DebugListener {
|
||||
|
||||
public void onMessage(String clientId, String msg);
|
||||
|
||||
public void onLoaderURL(String clientId, String url);
|
||||
|
||||
public void onLoaderBytes(String clientId, byte data[]);
|
||||
|
||||
public void onFinish(String clientId);
|
||||
}
|
||||
|
||||
@@ -25,10 +25,12 @@ import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -57,6 +59,30 @@ public class Debugger {
|
||||
private final int id;
|
||||
|
||||
public boolean finished = false;
|
||||
private final Map<String, String> parameters = new HashMap<>();
|
||||
|
||||
public static final int MSG_STRING = 0;
|
||||
public static final int MSG_LOADER_URL = 1;
|
||||
public static final int MSG_LOADER_BYTES = 2;
|
||||
|
||||
public String getParameter(String name, String defValue) {
|
||||
if (parameters.containsKey(name)) {
|
||||
return parameters.get(name);
|
||||
}
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public int getVersionMajor() {
|
||||
return Integer.parseInt(getParameter("debug.version.major", "1"));
|
||||
}
|
||||
|
||||
public int getVersionMinor() {
|
||||
return Integer.parseInt(getParameter("debug.version.major", "0"));
|
||||
}
|
||||
|
||||
public boolean hasMsgType() {
|
||||
return getVersionMajor() > 1 || getVersionMinor() > 0;
|
||||
}
|
||||
|
||||
public DebugHandler(int serverPort, Socket s) {
|
||||
this.s = s;
|
||||
@@ -72,6 +98,42 @@ public class Debugger {
|
||||
}
|
||||
}
|
||||
|
||||
private int readType(InputStream is) throws IOException {
|
||||
int type = is.read();
|
||||
if (type == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private byte[] readBytes(InputStream is) throws IOException {
|
||||
int len = is.read();
|
||||
if (len == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
int len2 = is.read();
|
||||
if (len2 == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
int len3 = is.read();
|
||||
if (len3 == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
int len4 = is.read();
|
||||
if (len4 == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
len = (len << 24) + (len2 << 16) + (len3 << 8) + len4;
|
||||
byte data[] = new byte[len];
|
||||
int cnt;
|
||||
int off = 0;
|
||||
while (len > 0 && (cnt = is.read(data, off, len)) > 0) {
|
||||
len -= cnt;
|
||||
off += cnt;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private String readString(InputStream is) throws IOException {
|
||||
int len = is.read();
|
||||
if (len == -1) {
|
||||
@@ -115,14 +177,47 @@ public class Debugger {
|
||||
os.write(("<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"" + serverPort + "\" /></cross-domain-policy>").getBytes("UTF-8"));
|
||||
}
|
||||
} else {
|
||||
if (!ret.isEmpty()) {
|
||||
String param[] = (ret.contains(";") ? ret.split(";") : new String[]{ret});
|
||||
for (String p : param) {
|
||||
if (p.contains("=")) {
|
||||
String key = p.substring(0, p.indexOf("="));
|
||||
String val = p.substring(p.indexOf("=") + 1);
|
||||
parameters.put(key, val);
|
||||
} else {
|
||||
parameters.put(p, "true");
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean hasType = hasMsgType();
|
||||
String name = readString(is);
|
||||
if (!name.isEmpty()) {
|
||||
clientName = name;
|
||||
}
|
||||
while (true) {
|
||||
ret = readString(is);
|
||||
for (DebugListener l : listeners) {
|
||||
l.onMessage(clientName, ret);
|
||||
int type = 0;
|
||||
if (hasType) {
|
||||
type = readType(is);
|
||||
}
|
||||
switch (type) {
|
||||
case MSG_STRING:
|
||||
ret = readString(is);
|
||||
for (DebugListener l : listeners) {
|
||||
l.onMessage(clientName, ret);
|
||||
}
|
||||
break;
|
||||
case MSG_LOADER_URL:
|
||||
ret = readString(is);
|
||||
for (DebugListener l : listeners) {
|
||||
l.onLoaderURL(clientName, ret);
|
||||
}
|
||||
break;
|
||||
case MSG_LOADER_BYTES:
|
||||
byte retB[] = readBytes(is);
|
||||
for (DebugListener l : listeners) {
|
||||
l.onLoaderBytes(clientName, retB);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,27 @@ public class DebuggerTools {
|
||||
return tested.matches(Pattern.quote(DEBUGGER_PACKAGE) + "(\\.pkg[a-f0-9]+)?" + cls);
|
||||
}
|
||||
|
||||
public static void injectDebugLoader(SWF swf) {
|
||||
if (hasDebugger(swf)) {
|
||||
ScriptPack dsp = getDebuggerScriptPack(swf);
|
||||
String debuggerPkg = dsp.getClassPath().packageStr.toRawString();
|
||||
for (ABCContainerTag ct : swf.getAbcList()) {
|
||||
ABC a = ct.getABC();
|
||||
if (dsp.abc == a) { //do not replace Loader in debugger itself
|
||||
continue;
|
||||
}
|
||||
for (int i = 1; i < a.constants.constant_multiname.size(); i++) {
|
||||
Multiname m = a.constants.constant_multiname.get(i);
|
||||
if ("flash.display.Loader".equals(m.getNameWithNamespace(a.constants).toRawString())) {
|
||||
m.namespace_index = a.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, a.constants.getStringId(debuggerPkg, true)), 0, true);
|
||||
m.name_index = a.constants.getStringId("DebugLoader", true);
|
||||
((Tag) ct).setModified(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void replaceTraceCalls(SWF swf, String fname) {
|
||||
if (hasDebugger(swf)) {
|
||||
String debuggerPkg = getDebuggerScriptPack(swf).getClassPath().packageStr.toRawString();
|
||||
@@ -111,7 +132,7 @@ public class DebuggerTools {
|
||||
swf.tags.remove((Tag) tag);
|
||||
swf.getAbcList().remove(tag);
|
||||
|
||||
//Change all debugger calls to normal trace
|
||||
//Change all debugger calls to normal trace / Loader
|
||||
for (ABCContainerTag ct : swf.getAbcList()) {
|
||||
ABC a = ct.getABC();
|
||||
for (int i = 1; i < a.constants.constant_multiname.size(); i++) {
|
||||
@@ -124,6 +145,9 @@ public class DebuggerTools {
|
||||
m.name_index = a.constants.getStringId("trace", true);
|
||||
m.namespace_index = a.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, a.constants.getStringId("", true)), 0, true);
|
||||
((Tag) ct).setModified(true);
|
||||
} else if (isDebuggerClass(packageStr, "DebugLoader")) {
|
||||
m.name_index = a.constants.getStringId("Loader", true);
|
||||
m.namespace_index = a.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, a.constants.getStringId("flash.display", true)), 0, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,7 +160,11 @@ public class DebuggerTools {
|
||||
//load debug swf
|
||||
SWF debugSWF = new SWF(Main.class.getClassLoader().getResourceAsStream("com/jpexs/decompiler/flash/gui/debugger/debug.swf"), false);
|
||||
|
||||
ABCContainerTag firstAbc = swf.getAbcList().get(0);
|
||||
List<ABCContainerTag> al = swf.getAbcList();
|
||||
ABCContainerTag firstAbc = al.isEmpty() ? null : al.get(0);
|
||||
if (firstAbc == null) { //nothing to instrument?
|
||||
return;
|
||||
}
|
||||
String newdebuggerpkg = DEBUGGER_PACKAGE;
|
||||
|
||||
if (Configuration.randomDebuggerPackage.get()) {
|
||||
@@ -174,7 +202,7 @@ public class DebuggerTools {
|
||||
initDebugger();
|
||||
}
|
||||
|
||||
private static void initDebugger() {
|
||||
public static Debugger initDebugger() {
|
||||
if (debugger == null) {
|
||||
synchronized (Main.class) {
|
||||
if (debugger == null) {
|
||||
@@ -184,6 +212,7 @@ public class DebuggerTools {
|
||||
}
|
||||
}
|
||||
}
|
||||
return debugger;
|
||||
}
|
||||
|
||||
public static void debuggerShowLog() {
|
||||
|
||||
Binary file not shown.
@@ -377,3 +377,6 @@ config.description.smartNumberFormatting = Format special numbers (for example c
|
||||
|
||||
config.name.enableScriptInitializerDisplay = Display script initializers
|
||||
config.description.enableScriptInitializerDisplay = Enable script initializers display and editation. This setting may add one newline to each class file for highlighting.
|
||||
|
||||
config.name.autoOpenLoadedSWFs = Open loaded SWFs during run (External viewer = WIN only)
|
||||
config.description.autoOpenLoadedSWFs = Opens automatically all SWFs loaded by AS3 class Loader by running SWF when played in FFDec external player. This feature is Windows only.
|
||||
|
||||
@@ -357,3 +357,6 @@ config.description.cacheImages = Ke\u0161ovat dek\u00f3dovan\u00e9 objekty obr\u
|
||||
|
||||
config.name.swfSpecificConfigs = Konfigurace specifick\u00e9 pro jednotliv\u00e1 SWF
|
||||
config.description.swfSpecificConfigs = Obsahuje konfigurace pro jednotliv\u00e1 SWF
|
||||
|
||||
config.name.autoOpenLoadedSWFs = Otev\u00edrat na\u010d\u00edtan\u00e1 SWF b\u011bhem p\u0159ehr\u00e1v\u00e1n\u00ed (Extern\u00ed p\u0159ehr\u00e1va\u010d = jen WIN)
|
||||
config.description.autoOpenLoadedSWFs = Otev\u00edr\u00e1 automaticky v\u0161echna SWF na\u010d\u00edtan\u00e1 AS3 t\u0159\u00eddou Loader b\u011bhem p\u0159ehr\u00e1v\u00e1n\u00ed v extern\u00edm p\u0159ehr\u00e1va\u010di v FFDec. Toto funguje pouze ve Windows.
|
||||
|
||||
@@ -629,4 +629,5 @@ error.image.alpha.invalid = Invalid alpha channel data.
|
||||
|
||||
#after version 6.0.2
|
||||
contextmenu.saveUncompressedToFile = Save to Uncompressed File
|
||||
abc.traitslist.scriptinitializer = script initializer
|
||||
abc.traitslist.scriptinitializer = script initializer
|
||||
menu.settings.autoOpenLoadedSWFs = Open loaded SWFs while playing
|
||||
@@ -628,4 +628,5 @@ error.image.alpha.invalid = Neplatn\u00e1 data alpha kan\u00e1lu.
|
||||
|
||||
#after version 6.0.2
|
||||
contextmenu.saveUncompressedToFile = Ulo\u017eit nekomprimovan\u011b
|
||||
abc.traitslist.scriptinitializer = inicializ\u00e1tor skriptu
|
||||
abc.traitslist.scriptinitializer = inicializ\u00e1tor skriptu
|
||||
menu.settings.autoOpenLoadedSWFs = Otev\u00edrat na\u010d\u00edtan\u00e1 SWF b\u011bhem p\u0159ehr\u00e1v\u00e1n\u00ed
|
||||
Reference in New Issue
Block a user