mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-27 18:25:33 +00:00
Debugger stub - TODO
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# ---- Run parameters
|
||||
run.params =
|
||||
run.params =
|
||||
|
||||
# ------------------------
|
||||
|
||||
|
||||
BIN
lib/flashdebugger.jar
Normal file
BIN
lib/flashdebugger.jar
Normal file
Binary file not shown.
@@ -3095,13 +3095,13 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
*
|
||||
* @param injectCode Modify AS3 code with debugfile / debugline ?
|
||||
*/
|
||||
public void enableDebugging(boolean injectCode) {
|
||||
public void enableDebugging(boolean injectCode, File decompileDir) {
|
||||
|
||||
if (injectCode) {
|
||||
List<ScriptPack> packs = getAS3Packs();
|
||||
for (ScriptPack s : packs) {
|
||||
if (s.isSimple) {
|
||||
s.injectDebugInfo();
|
||||
s.injectDebugInfo(decompileDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -315,7 +316,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
* Based on idea of Jacob Thompson
|
||||
* http://securityevaluators.com/knowledge/flash/
|
||||
*/
|
||||
public void injectDebugInfo() {
|
||||
public void injectDebugInfo(File directoryPath) {
|
||||
Map<Integer, Map<Integer, Integer>> bodyToPosToLine = new HashMap<>();
|
||||
try {
|
||||
CachedDecompilation decompiled = SWF.getCached(this);
|
||||
@@ -358,7 +359,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
}
|
||||
int pos = -1;
|
||||
try {
|
||||
abc.bodies.get(bodyIndex).getCode().adr2pos(instrOffset);
|
||||
pos = abc.bodies.get(bodyIndex).getCode().adr2pos(instrOffset);
|
||||
} catch (ConvertException cex) {
|
||||
//ignore
|
||||
}
|
||||
@@ -375,7 +376,10 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
Logger.getLogger(ScriptPack.class.getName()).log(Level.SEVERE, "Cannot decompile", ex);
|
||||
}
|
||||
|
||||
String filename = path.toString().replace('.', '/') + ".as";
|
||||
//String filepath = path.toString().replace('.', '/') + ".as";
|
||||
String pkg = path.packageStr.toString();
|
||||
String cls = path.className;
|
||||
String filename = new File(directoryPath, path.packageStr.toFilePath()) + ";" + pkg + ";" + cls + ".as";
|
||||
|
||||
for (int bodyIndex : bodyToPosToLine.keySet()) {
|
||||
MethodBody b = abc.bodies.get(bodyIndex);
|
||||
@@ -383,11 +387,19 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
List<Integer> pos = new ArrayList<>(bodyToPosToLine.get(bodyIndex).keySet());
|
||||
Collections.sort(pos);
|
||||
Collections.reverse(pos);
|
||||
Set<Integer> addedLines = new HashSet<>();
|
||||
for (int i : pos) {
|
||||
int line = bodyToPosToLine.get(bodyIndex).get(i);
|
||||
if (addedLines.contains(line)) {
|
||||
continue;
|
||||
}
|
||||
addedLines.add(line);
|
||||
Logger.getLogger(ScriptPack.class.getName()).log(Level.WARNING, "Script " + path + ": Insert debugline(" + line + ") at pos " + i + " to body " + bodyIndex);
|
||||
b.insertInstruction(i, new AVM2Instruction(0, AVM2Instructions.DebugLine, new int[]{line}));
|
||||
}
|
||||
b.setModified();
|
||||
}
|
||||
|
||||
((Tag) abc.parentTag).setModified(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +117,10 @@ public final class MethodBody implements Cloneable {
|
||||
this.code = null;
|
||||
}
|
||||
|
||||
public void setModified() {
|
||||
this.codeBytes = null;
|
||||
}
|
||||
|
||||
public synchronized byte[] getCodeBytes() {
|
||||
if (codeBytes != null) {
|
||||
return codeBytes;
|
||||
|
||||
@@ -308,7 +308,7 @@
|
||||
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4">
|
||||
<compilation-unit>
|
||||
<package-root>src</package-root>
|
||||
<classpath mode="compile">lib/LZMA.jar;lib/jna-3.5.1.jar;lib/jpproxy.jar;lib/trident-6.2.jar;lib/substance-flamingo-6.2.jar;lib/flamingo-6.2.jar;lib/substance-6.2.jar;lib/jl1.0.1.jar;lib/nellymoser.jar;lib/gif.jar;lib/avi.jar;lib/ttf.jar;lib/jpacker.jar;lib/sfntly.jar;lib/gnujpdf.jar;libsrc/ffdec_lib/src;lib/tablelayout.jar;lib/jsyntaxpane-0.9.5.jar;lib/JavactiveX.jar</classpath>
|
||||
<classpath mode="compile">lib/LZMA.jar;lib/jna-3.5.1.jar;lib/jpproxy.jar;lib/trident-6.2.jar;lib/substance-flamingo-6.2.jar;lib/flamingo-6.2.jar;lib/substance-6.2.jar;lib/jl1.0.1.jar;lib/nellymoser.jar;lib/gif.jar;lib/avi.jar;lib/ttf.jar;lib/jpacker.jar;lib/sfntly.jar;lib/gnujpdf.jar;libsrc/ffdec_lib/src;lib/tablelayout.jar;lib/jsyntaxpane-0.9.5.jar;lib/JavactiveX.jar;lib/flashdebugger.jar</classpath>
|
||||
<built-to>build</built-to>
|
||||
<built-to>javadoc</built-to>
|
||||
<built-to>reports</built-to>
|
||||
|
||||
@@ -2802,7 +2802,7 @@ public class CommandLineArgumentParser {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
SWF swf = new SWF(fis, Configuration.parallelSpeedUp.get());
|
||||
fis.close();
|
||||
swf.enableDebugging(injectas3);
|
||||
swf.enableDebugging(injectas3, new File(outfile).getParentFile());
|
||||
FileOutputStream fos = new FileOutputStream(outfile);
|
||||
swf.saveTo(fos);
|
||||
fos.close();
|
||||
|
||||
104
src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java
Normal file
104
src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2015 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.debugger.flash.DebugConnectionListener;
|
||||
import com.jpexs.debugger.flash.DebugMessageListener;
|
||||
import com.jpexs.debugger.flash.Debugger;
|
||||
import com.jpexs.debugger.flash.DebuggerCommands;
|
||||
import com.jpexs.debugger.flash.DebuggerConnection;
|
||||
import com.jpexs.debugger.flash.messages.in.InAskBreakpoints;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakAt;
|
||||
import com.jpexs.debugger.flash.messages.in.InNumScript;
|
||||
import com.jpexs.debugger.flash.messages.in.InScript;
|
||||
import com.jpexs.debugger.flash.messages.in.InSwfInfo;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jindra
|
||||
*/
|
||||
public class DebuggerHandler implements DebugConnectionListener {
|
||||
|
||||
@Override
|
||||
public void connected(DebuggerConnection con) {
|
||||
|
||||
Level level = Level.FINER;
|
||||
|
||||
Logger rootLog = Logger.getLogger(Debugger.class.getName());
|
||||
rootLog.setLevel(level);
|
||||
ConsoleHandler ch = new ConsoleHandler();
|
||||
ch.setLevel(level);
|
||||
rootLog.addHandler(ch);
|
||||
//rootLog.getHandlers()[0].setLevel(level);
|
||||
|
||||
final DebuggerCommands dc = new DebuggerCommands(con);
|
||||
dc.stopWarning();
|
||||
dc.setStopOnFault();
|
||||
dc.setEnumerateOverride();
|
||||
dc.setNotifyFailure();
|
||||
dc.setInvokeSetters();
|
||||
dc.setSwfLoadNotify();
|
||||
dc.setGetterTimeout(1500);
|
||||
dc.setSetterTimeout(5000);
|
||||
dc.squelch(true);
|
||||
List<InSwfInfo.SwfInfo> swfs = dc.getSwfInfo(1);
|
||||
int numScript = con.getMessage(InNumScript.class).num;
|
||||
final Map<Integer, String> moduleNames = new HashMap<>();
|
||||
for (int i = 0; i < numScript; i++) {
|
||||
InScript sc = con.getMessage(InScript.class);
|
||||
System.out.println("" + sc.module + ":" + sc.name);
|
||||
moduleNames.put(sc.module, sc.name);
|
||||
}
|
||||
|
||||
final Map<Integer, ClassPath> modulePaths = new HashMap<>();
|
||||
|
||||
for (int mname : moduleNames.keySet()) {
|
||||
String name = moduleNames.get(mname);
|
||||
String[] parts = name.split(";");
|
||||
|
||||
if (parts.length == 3) {
|
||||
String clsName = parts[2].replace(".as", "");
|
||||
String pkg = parts[1];
|
||||
modulePaths.put(mname, new ClassPath(DottedChain.parse(pkg), clsName));
|
||||
}
|
||||
}
|
||||
|
||||
con.getMessage(InAskBreakpoints.class);
|
||||
//dc.addBreakPoint(15, 14);
|
||||
dc.addBreakPoint(9, 26);
|
||||
con.addMessageListener(new DebugMessageListener<InBreakAt>() {
|
||||
|
||||
@Override
|
||||
public void message(InBreakAt message) {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.WARNING, "break at {0}:{1}", new Object[]{moduleNames.get(message.file), message.line});
|
||||
String cls = modulePaths.get(message.file).toString();
|
||||
Main.getMainFrame().getPanel().debuggerBreakAt(Main.getMainFrame().getPanel().getCurrentSwf(), cls, message.line);
|
||||
//dc.sendContinue();
|
||||
}
|
||||
});
|
||||
dc.sendContinue();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,16 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.debugger.flash.DebugConnectionListener;
|
||||
import com.jpexs.debugger.flash.DebugMessageListener;
|
||||
import com.jpexs.debugger.flash.Debugger;
|
||||
import com.jpexs.debugger.flash.DebuggerCommands;
|
||||
import com.jpexs.debugger.flash.DebuggerConnection;
|
||||
import com.jpexs.debugger.flash.messages.in.InAskBreakpoints;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakAt;
|
||||
import com.jpexs.debugger.flash.messages.in.InNumScript;
|
||||
import com.jpexs.debugger.flash.messages.in.InScript;
|
||||
import com.jpexs.debugger.flash.messages.in.InSwfInfo;
|
||||
import com.jpexs.decompiler.flash.ApplicationInfo;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -79,8 +89,10 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@@ -137,6 +149,8 @@ public class Main {
|
||||
|
||||
public static boolean shouldCloseWhenClosingLoadingDialog;
|
||||
|
||||
private static Debugger flashDebugger;
|
||||
|
||||
public static void ensureMainFrame() {
|
||||
if (mainFrame == null) {
|
||||
synchronized (Main.class) {
|
||||
@@ -1001,6 +1015,22 @@ public class Main {
|
||||
public void onFinish(String clientId) {
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
|
||||
/*Level level = Level.FINE;
|
||||
|
||||
Logger rootLog = Logger.getLogger("");
|
||||
rootLog.setLevel(level);
|
||||
rootLog.getHandlers()[0].setLevel(level);
|
||||
*/
|
||||
flashDebugger = new Debugger();
|
||||
flashDebugger.addConnectionListener(new DebuggerHandler());
|
||||
flashDebugger.start();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void showModeFrame() {
|
||||
@@ -1203,7 +1233,6 @@ public class Main {
|
||||
* @throws IOException On error
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
clearTemp();
|
||||
|
||||
try {
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFBundle;
|
||||
import com.jpexs.decompiler.flash.SWFSourceInfo;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
import com.jpexs.decompiler.flash.abc.RenameType;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
|
||||
@@ -1526,6 +1527,32 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
}
|
||||
}
|
||||
|
||||
public void gotoClassLine(SWF swf, String cls, int line) {
|
||||
gotoClass(swf, cls);
|
||||
if (abcPanel != null) {
|
||||
abcPanel.decompiledTextArea.selectLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
public void debuggerBreakAt(SWF swf, String cls, int line) {
|
||||
gotoClassLine(swf, cls, line);
|
||||
if (abcPanel != null) {
|
||||
abcPanel.decompiledTextArea.setLineColor(line, Color.green);
|
||||
}
|
||||
}
|
||||
|
||||
public void gotoClass(SWF swf, String cls) {
|
||||
if (swf == null) {
|
||||
return;
|
||||
}
|
||||
List<ABCContainerTag> abcList = swf.getAbcList();
|
||||
if (!abcList.isEmpty()) {
|
||||
ABCPanel abcPanel = getABCPanel();
|
||||
abcPanel.setAbc(abcList.get(0).getABC());
|
||||
abcPanel.hilightScript(swf, cls);
|
||||
}
|
||||
}
|
||||
|
||||
public void gotoDocumentClass(SWF swf) {
|
||||
if (swf == null) {
|
||||
return;
|
||||
|
||||
@@ -32,6 +32,8 @@ import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
import javax.swing.plaf.TextUI;
|
||||
@@ -65,6 +67,15 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan
|
||||
|
||||
private LinkHandler linkHandler = this;
|
||||
|
||||
private Map<Integer, Color> lineColors = new HashMap<>();
|
||||
|
||||
public void setLineColor(int line, Color color) {
|
||||
lineColors.remove(line);
|
||||
if (color != null) {
|
||||
lineColors.put(line, color);
|
||||
}
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return lastLine;
|
||||
}
|
||||
@@ -358,10 +369,11 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan
|
||||
public void paint(Graphics g) {
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
FontMetrics fontMetrics = g.getFontMetrics();
|
||||
int lh = fontMetrics.getHeight();
|
||||
int d = fontMetrics.getDescent();
|
||||
|
||||
if (lastLine > 0) {
|
||||
FontMetrics fontMetrics = g.getFontMetrics();
|
||||
int lh = fontMetrics.getHeight();
|
||||
int d = fontMetrics.getDescent();
|
||||
if (error) {
|
||||
g.setColor(new Color(255, 200, 200));
|
||||
} else {
|
||||
@@ -369,6 +381,10 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan
|
||||
}
|
||||
g.fillRect(0, d + lh * lastLine - 1, getWidth(), lh);
|
||||
}
|
||||
for (int line : lineColors.keySet()) {
|
||||
g.setColor(lineColors.get(line));
|
||||
g.fillRect(0, d + lh * line - 1, getWidth(), lh);
|
||||
}
|
||||
super.paint(g);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user