Issue #42, AS3 - displaying hex

Graph button changed to icon
This commit is contained in:
Jindra Pet��k
2013-03-20 22:01:52 +01:00
parent dfd9bfae3c
commit 50cce00fe0
10 changed files with 105 additions and 64 deletions
@@ -441,14 +441,6 @@ public class Main {
fos.close();
}
public static final void printASM(AVM2Code code) {
String s = Highlighting.stripHilights(code.toASMSource(null, new MethodBody()));
String ss[] = s.split("\n");
for (int i = 0; i < ss.length; i++) {
System.out.println("" + i + ":" + ss[i]);
}
}
/**
* @param args the command line arguments
*/
@@ -692,11 +692,11 @@ public class AVM2Code implements Serializable {
return null;
}
public String toASMSource(ConstantPool constants, MethodBody body) {
return toASMSource(constants, body, new ArrayList<Integer>());
public String toASMSource(ConstantPool constants, MethodBody body, boolean hex) {
return toASMSource(constants, body, new ArrayList<Integer>(), hex);
}
public String toASMSource(ConstantPool constants, MethodBody body, List<Integer> outputMap) {
public String toASMSource(ConstantPool constants, MethodBody body, List<Integer> outputMap, boolean hex) {
invalidateCache();
StringBuffer ret = new StringBuffer();
String t = "";
@@ -725,6 +725,11 @@ public class AVM2Code implements Serializable {
int largeLimit = 20000;
boolean markOffsets = code.size() <= largeLimit;
for (AVM2Instruction ins : code) {
if(hex){
ret.append("<ffdec:hex>");
ret.append(Helper.bytesToHexString(ins.getBytes()));
ret.append("</ffdec:hex>\n");
}
if (ins.labelname != null) {
ret.append(ins.labelname + ":");
} else if (offsets.contains(ofs)) {
@@ -2252,7 +2257,7 @@ public class AVM2Code implements Serializable {
invalidateCache();
try {
List<Integer> outputMap = new ArrayList<Integer>();
String src = Highlighting.stripHilights(toASMSource(constants, body, outputMap));
String src = Highlighting.stripHilights(toASMSource(constants, body, outputMap,false));
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(src.getBytes()), constants, null, body);
for (int i = 0; i < acode.code.size(); i++) {
@@ -2292,7 +2297,7 @@ public class AVM2Code implements Serializable {
public void removeIgnored(ConstantPool constants, MethodBody body) {
try {
List<Integer> outputMap = new ArrayList<Integer>();
String src = toASMSource(constants, body, outputMap);
String src = toASMSource(constants, body, outputMap,false);
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(src.getBytes()), constants, body);
for (int i = 0; i < acode.code.size(); i++) {
if (outputMap.size() > i) {
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.tags.DoABCTag;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
@@ -216,6 +217,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener {
JPanel navIconsPanel = new JPanel();
navIconsPanel.setLayout(new BoxLayout(navIconsPanel, BoxLayout.X_AXIS));
final JToggleButton sortButton = new JToggleButton(View.getIcon("sort16"));
sortButton.setMargin(new Insets(3, 3, 3, 3));
navIconsPanel.add(sortButton);
navPanel.add(navIconsPanel, BorderLayout.SOUTH);
navPanel.add(new JScrollPane(navigator), BorderLayout.CENTER);
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.abc.avm2.parser.ASM3Parser;
import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import com.jpexs.decompiler.flash.gui.GraphFrame;
import com.jpexs.decompiler.flash.helpers.Helper;
import com.jpexs.decompiler.flash.helpers.Highlighting;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -43,6 +44,33 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
private DecompiledEditorPane decompiledEditor;
private boolean ignoreCarret = false;
private String name;
private String textWithHex="";
private String textNoHex="";
private boolean hex=false;
public boolean isHex() {
return hex;
}
public void switchHex(){
setHex(!hex);
}
public void setHex(boolean hex) {
if(this.hex==hex){
return;
}
this.hex = hex;
long oldOffset=getSelectedOffset();
if(hex){
setText(textWithHex);
}else{
setText(textNoHex);
}
hilighOffset(oldOffset);
}
public void setIgnoreCarret(boolean ignoreCarret) {
this.ignoreCarret = ignoreCarret;
@@ -77,7 +105,10 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
this.bodyIndex = bodyIndex;
this.abc = abc;
this.name = name;
setText(abc.bodies[bodyIndex].code.toASMSource(abc.constants, abc.bodies[bodyIndex]));
String textWithHexTags=abc.bodies[bodyIndex].code.toASMSource(abc.constants, abc.bodies[bodyIndex],true);
textWithHex=Helper.hexToComments(textWithHexTags);
textNoHex=Helper.stripComments(textWithHexTags);
setText(hex?textWithHex:textNoHex);
}
public void graph() {
@@ -112,24 +143,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
disassembledHilights = Highlighting.getInstrHighlights(t);
t = Highlighting.stripHilights(t);
super.setText(t);
}
public void verify(ConstantPool constants, ABC abc) {
try {
AVM2Code acode = ASM3Parser.parse(new ByteArrayInputStream(getText().getBytes()), constants, new DialogMissingSymbolHandler(), abc.bodies[bodyIndex]);
//acode.clearSecureSWF(abc.constants, abc.bodies[bodyIndex]);
setText(acode.toASMSource(constants, abc.bodies[bodyIndex]));
//Main.mainFrame.decompiledTextArea.setBody(mb, abc);
} catch (IOException ex) {
} catch (ParseException ex) {
JOptionPane.showMessageDialog(this, (ex.text + " on line " + ex.line));
selectLine((int) ex.line);
return;
}
JOptionPane.showMessageDialog(this, ("Code OK"));
}
}
public void selectInstruction(int pos) {
String text = getText();
@@ -186,6 +200,20 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
requestFocus();
}
public long getSelectedOffset(){
int pos = getCaretPosition();
Highlighting lastH = new Highlighting(0, 0, 0);
for (Highlighting h : disassembledHilights) {
if (pos < h.startPos) {
break;
}
lastH = h;
}
return lastH.offset;
}
@Override
public void caretUpdate(CaretEvent e) {
if (isEditable()) {
@@ -195,14 +223,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
return;
}
getCaret().setVisible(true);
int pos = getCaretPosition();
Highlighting lastH = new Highlighting(0, 0, 0);
for (Highlighting h : disassembledHilights) {
if (pos < h.startPos) {
break;
}
lastH = h;
}
decompiledEditor.hilightOffset(lastH.offset);
decompiledEditor.hilightOffset(getSelectedOffset());
}
}
@@ -19,14 +19,18 @@ package com.jpexs.decompiler.flash.abc.gui;
import com.jpexs.decompiler.flash.Main;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
import com.jpexs.decompiler.flash.gui.View;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
/**
*
@@ -36,6 +40,7 @@ public class MethodCodePanel extends JPanel implements ActionListener {
private ASMSourceEditorPane sourceTextArea;
public JPanel buttonsPanel;
private JToggleButton hexButton;
public void focusEditor() {
sourceTextArea.requestFocusInWindow();
@@ -82,26 +87,37 @@ public class MethodCodePanel extends JPanel implements ActionListener {
sourceTextArea.setFont(new Font("Monospaced", Font.PLAIN, sourceTextArea.getFont().getSize()));
buttonsPanel = new JPanel();
buttonsPanel.setLayout(new FlowLayout());
buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
JButton verifyButton = new JButton("Verify");
verifyButton.setActionCommand("VERIFYBODY");
verifyButton.addActionListener(this);
JButton graphButton = new JButton("Graph");
JButton graphButton = new JButton(View.getIcon("graph16"));
graphButton.setActionCommand("GRAPH");
graphButton.addActionListener(this);
graphButton.setToolTipText("View Graph");
graphButton.setMargin(new Insets(3, 3, 3, 3));
hexButton = new JToggleButton(View.getIcon("hex16"));
hexButton.setActionCommand("HEX");
hexButton.addActionListener(this);
hexButton.setToolTipText("View Hex");
hexButton.setMargin(new Insets(3, 3, 3, 3));
JButton execButton = new JButton("Execute");
execButton.setActionCommand("EXEC");
execButton.addActionListener(this);
buttonsPanel.add(graphButton);
buttonsPanel.add(hexButton);
buttonsPanel.add(new JPanel());
// buttonsPanel.add(saveButton);
// buttonsPan.add(execButton);
add(buttonsPanel, BorderLayout.SOUTH);
add(buttonsPanel, BorderLayout.NORTH);
}
@Override
public void actionPerformed(ActionEvent e) {
if (Main.isWorking()) {
return;
@@ -110,16 +126,26 @@ public class MethodCodePanel extends JPanel implements ActionListener {
sourceTextArea.graph();
}
if (e.getActionCommand().equals("HEX")) {
sourceTextArea.setHex(hexButton.isSelected());
}
if (e.getActionCommand().equals("EXEC")) {
sourceTextArea.exec();
}
if (e.getActionCommand().equals("VERIFYBODY")) {
sourceTextArea.verify(Main.mainFrame.abcPanel.abc.constants, Main.mainFrame.abcPanel.abc);
}
}
public void setEditMode(boolean val) {
if (val) {
sourceTextArea.setHex(false);
} else {
if (hexButton.isSelected()) {
sourceTextArea.setHex(true);
}
}
sourceTextArea.setEditable(val);
sourceTextArea.getCaret().setVisible(true);
buttonsPanel.setVisible(!val);
}
}
@@ -109,7 +109,7 @@ public class MethodBody implements Cloneable, Serializable {
return s;
}
if (pcode) {
s += code.toASMSource(constants, this);
s += code.toASMSource(constants, this, false);
} else {
AVM2Code deobfuscated = null;
MethodBody b = (MethodBody) Helper.deepCopy(this);
@@ -22,22 +22,6 @@ import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
/*
* Copyright (C) 2010-2011 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
public class ImagePanel extends JPanel {
public JLabel label = new JLabel();
Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

@@ -185,6 +185,9 @@ public class Helper {
return ret;
}
public static String bytesToHexString(byte bytes[]){
return bytesToHexString(bytes,0);
}
public static String bytesToHexString(byte bytes[], int start) {
StringBuilder sb = new StringBuilder();
if (start < bytes.length) {
@@ -320,4 +323,12 @@ public class Helper {
} catch (Exception ex) {
}
}
public static String stripComments(String str){
return str.replaceAll("<ffdec:hex>[^\r\n]*</ffdec:hex>\r?\n", "");
}
public static String hexToComments(String str){
return str.replaceAll("<ffdec:hex>([^\r\n]*)</ffdec:hex>(\r?\n)", "; $1$2");
}
}