mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 13:10:46 +00:00
hexedit AS3 code
This commit is contained in:
@@ -19,10 +19,12 @@ package com.jpexs.decompiler.flash.gui.abc;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2Graph;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.ASM3Parser;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.MissingSymbolHandler;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.gui.GraphFrame;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
@@ -86,9 +88,11 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
|
||||
setText(textWithHex);
|
||||
} else {
|
||||
if (textHexOnly == null) {
|
||||
textHexOnly = new HilightedText(Helper.byteArrToString(abc.bodies[bodyIndex].code.getBytes()));
|
||||
HilightedTextWriter writer = new HilightedTextWriter(true);
|
||||
Helper.byteArrayToHex(writer, abc.bodies[bodyIndex].code.getBytes());
|
||||
textHexOnly = new HilightedText(writer);
|
||||
}
|
||||
setText(textWithHex);
|
||||
setText(textHexOnly);
|
||||
}
|
||||
hilighOffset(oldOffset);
|
||||
}
|
||||
@@ -176,30 +180,44 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
|
||||
|
||||
public boolean save(ConstantPool constants) {
|
||||
try {
|
||||
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(getText().getBytes("UTF-8")), constants, trait, new MissingSymbolHandler() {
|
||||
//no longer ask for adding new constants
|
||||
@Override
|
||||
public boolean missingString(String value) {
|
||||
return true;
|
||||
String text = getText();
|
||||
if (text.trim().startsWith("#hexdata")) {
|
||||
byte[] data = Helper.getBytesFromHexaText(text);
|
||||
MethodBody mb = abc.bodies[bodyIndex];
|
||||
mb.codeBytes = data;
|
||||
try {
|
||||
mb.code = new AVM2Code(new ByteArrayInputStream(mb.codeBytes));
|
||||
} catch (UnknownInstructionCode re) {
|
||||
mb.code = new AVM2Code();
|
||||
Logger.getLogger(ABC.class.getName()).log(Level.SEVERE, null, re);
|
||||
}
|
||||
mb.code.compact();
|
||||
} else {
|
||||
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(text.getBytes("UTF-8")), constants, trait, new MissingSymbolHandler() {
|
||||
//no longer ask for adding new constants
|
||||
@Override
|
||||
public boolean missingString(String value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean missingInt(long value) {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean missingInt(long value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean missingUInt(long value) {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean missingUInt(long value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean missingDouble(double value) {
|
||||
return true;
|
||||
}
|
||||
}, abc.bodies[bodyIndex], abc.method_info[abc.bodies[bodyIndex].method_info]);
|
||||
acode.getBytes(abc.bodies[bodyIndex].codeBytes);
|
||||
abc.bodies[bodyIndex].code = acode;
|
||||
@Override
|
||||
public boolean missingDouble(double value) {
|
||||
return true;
|
||||
}
|
||||
}, abc.bodies[bodyIndex], abc.method_info[abc.bodies[bodyIndex].method_info]);
|
||||
acode.getBytes(abc.bodies[bodyIndex].codeBytes);
|
||||
abc.bodies[bodyIndex].code = acode;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
} catch (ParseException ex) {
|
||||
View.showMessageDialog(this, (ex.text + " on line " + ex.line));
|
||||
|
||||
@@ -108,14 +108,12 @@ public class MethodCodePanel extends JPanel implements ActionListener {
|
||||
hexButton.setToolTipText(AppStrings.translate("button.viewhex"));
|
||||
hexButton.setMargin(new Insets(3, 3, 3, 3));
|
||||
|
||||
// todo: find icon, and set visible
|
||||
// todo: find icon
|
||||
hexOnlyButton = new JToggleButton(View.getIcon("hex16"));
|
||||
hexOnlyButton.setActionCommand("HEXONLY");
|
||||
hexOnlyButton.addActionListener(this);
|
||||
hexOnlyButton.setToolTipText(AppStrings.translate("button.viewhex"));
|
||||
hexOnlyButton.setMargin(new Insets(3, 3, 3, 3));
|
||||
hexOnlyButton.setVisible(false);
|
||||
|
||||
|
||||
buttonsPanel.add(graphButton);
|
||||
buttonsPanel.add(hexButton);
|
||||
@@ -137,6 +135,11 @@ public class MethodCodePanel extends JPanel implements ActionListener {
|
||||
}
|
||||
|
||||
if (e.getActionCommand().equals("HEX") || e.getActionCommand().equals("HEXONLY")) {
|
||||
if (e.getActionCommand().equals("HEX")) {
|
||||
hexOnlyButton.setSelected(false);
|
||||
} else {
|
||||
hexButton.setSelected(false);
|
||||
}
|
||||
sourceTextArea.setHex(getExportMode(), false);
|
||||
}
|
||||
}
|
||||
@@ -148,10 +151,10 @@ public class MethodCodePanel extends JPanel implements ActionListener {
|
||||
}
|
||||
|
||||
public void setEditMode(boolean val) {
|
||||
ExportMode exportMode = getExportMode();
|
||||
if (val) {
|
||||
sourceTextArea.setHex(ExportMode.PCODE, false);
|
||||
sourceTextArea.setHex(exportMode == ExportMode.HEX ? ExportMode.HEX : ExportMode.PCODE, false);
|
||||
} else {
|
||||
ExportMode exportMode = getExportMode();
|
||||
if (exportMode != ExportMode.PCODE) {
|
||||
sourceTextArea.setHex(exportMode, false);
|
||||
}
|
||||
|
||||
@@ -306,7 +306,9 @@ public class ActionPanel extends JPanel implements ActionListener {
|
||||
}
|
||||
} else {
|
||||
if (srcHexOnly == null) {
|
||||
srcHexOnly = new HilightedText(Helper.byteArrToString(src.getActionBytes()));
|
||||
HilightedTextWriter writer = new HilightedTextWriter(true);
|
||||
Helper.byteArrayToHex(writer, src.getActionBytes());
|
||||
srcHexOnly = new HilightedText(writer);
|
||||
}
|
||||
setText(srcHexOnly);
|
||||
}
|
||||
@@ -443,13 +445,12 @@ public class ActionPanel extends JPanel implements ActionListener {
|
||||
hexButton.setToolTipText(AppStrings.translate("button.viewhex"));
|
||||
hexButton.setMargin(new Insets(3, 3, 3, 3));
|
||||
|
||||
// todo: find icon, and set visible
|
||||
// todo: find icon
|
||||
hexOnlyButton = new JToggleButton(View.getIcon("hex16"));
|
||||
hexOnlyButton.setActionCommand("HEXONLY");
|
||||
hexOnlyButton.addActionListener(this);
|
||||
hexOnlyButton.setToolTipText(AppStrings.translate("button.viewhex"));
|
||||
hexOnlyButton.setMargin(new Insets(3, 3, 3, 3));
|
||||
//hexOnlyButton.setVisible(false);
|
||||
|
||||
topButtonsPan = new JPanel();
|
||||
topButtonsPan.setLayout(new BoxLayout(topButtonsPan, BoxLayout.X_AXIS));
|
||||
@@ -618,8 +619,7 @@ public class ActionPanel extends JPanel implements ActionListener {
|
||||
}
|
||||
|
||||
public void setEditMode(boolean val) {
|
||||
// todo: create UI for editing raw data
|
||||
final boolean rawEdit = false;
|
||||
boolean rawEdit = hexOnlyButton.isSelected();
|
||||
|
||||
if (val) {
|
||||
setText(rawEdit ? srcHexOnly : srcNoHex);
|
||||
@@ -630,7 +630,7 @@ public class ActionPanel extends JPanel implements ActionListener {
|
||||
editor.getCaret().setVisible(true);
|
||||
asmLabel.setIcon(View.getIcon("editing16"));
|
||||
} else {
|
||||
setText(hexButton.isSelected() ? srcWithHex : srcNoHex);
|
||||
setHex(getExportMode());
|
||||
editor.setEditable(false);
|
||||
saveButton.setVisible(false);
|
||||
editButton.setVisible(true);
|
||||
@@ -714,6 +714,11 @@ public class ActionPanel extends JPanel implements ActionListener {
|
||||
} else if (e.getActionCommand().equals("EDITACTION")) {
|
||||
setEditMode(true);
|
||||
} else if (e.getActionCommand().equals("HEX") || e.getActionCommand().equals("HEXONLY")) {
|
||||
if (e.getActionCommand().equals("HEX")) {
|
||||
hexOnlyButton.setSelected(false);
|
||||
} else {
|
||||
hexButton.setSelected(false);
|
||||
}
|
||||
setHex(getExportMode());
|
||||
} else if (e.getActionCommand().equals("CANCELACTION")) {
|
||||
setEditMode(false);
|
||||
@@ -722,7 +727,7 @@ public class ActionPanel extends JPanel implements ActionListener {
|
||||
try {
|
||||
String text = editor.getText();
|
||||
if (text.trim().startsWith("#hexdata")) {
|
||||
src.setActionBytes(getBytesFromHexaText(text));
|
||||
src.setActionBytes(Helper.getBytesFromHexaText(text));
|
||||
} else {
|
||||
src.setActions(ASMParser.parse(0, src.getPos(), true, text, SWF.DEFAULT_VERSION, false), SWF.DEFAULT_VERSION);
|
||||
}
|
||||
@@ -763,26 +768,6 @@ public class ActionPanel extends JPanel implements ActionListener {
|
||||
return exportMode;
|
||||
}
|
||||
|
||||
public byte[] getBytesFromHexaText(String text) {
|
||||
Scanner scanner = new Scanner(text);
|
||||
scanner.nextLine(); // ignore first line
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine().trim();
|
||||
if (line.startsWith(";")) {
|
||||
continue;
|
||||
}
|
||||
line = line.replace(" ", "");
|
||||
for (int i = 0; i < line.length() / 2; i++) {
|
||||
String hexStr = line.substring(i * 2, (i + 1) * 2);
|
||||
byte b = (byte) Integer.parseInt(hexStr, 16);
|
||||
baos.write(b);
|
||||
}
|
||||
}
|
||||
byte[] data = baos.toByteArray();
|
||||
return data;
|
||||
}
|
||||
|
||||
public void updateSearchPos() {
|
||||
searchPos.setText((foundPos + 1) + "/" + found.size());
|
||||
setSource(found.get(foundPos), true);
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.helpers;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -61,5 +62,10 @@ public class HilightedText implements Serializable {
|
||||
|
||||
public HilightedText(String text) {
|
||||
this.text = text;
|
||||
this.traitHilights = new ArrayList<>();
|
||||
this.classHilights = new ArrayList<>();
|
||||
this.methodHilights = new ArrayList<>();
|
||||
this.instructionHilights = new ArrayList<>();
|
||||
this.specialHilights = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -604,6 +604,26 @@ public class Helper {
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
public static byte[] getBytesFromHexaText(String text) {
|
||||
Scanner scanner = new Scanner(text);
|
||||
scanner.nextLine(); // ignore first line
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine().trim();
|
||||
if (line.startsWith(";")) {
|
||||
continue;
|
||||
}
|
||||
line = line.replace(" ", "");
|
||||
for (int i = 0; i < line.length() / 2; i++) {
|
||||
String hexStr = line.substring(i * 2, (i + 1) * 2);
|
||||
byte b = (byte) Integer.parseInt(hexStr, 16);
|
||||
baos.write(b);
|
||||
}
|
||||
}
|
||||
byte[] data = baos.toByteArray();
|
||||
return data;
|
||||
}
|
||||
|
||||
public static <T> T timedCall(Callable<T> c, long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
FutureTask<T> task = new FutureTask<>(c);
|
||||
THREAD_POOL.execute(task);
|
||||
|
||||
Reference in New Issue
Block a user