Issue #63 Globally rename identifier

This commit is contained in:
Jindra Petk
2013-06-23 16:16:44 +02:00
parent 2c94e938cc
commit 65ef206650
14 changed files with 810 additions and 611 deletions

View File

@@ -21,6 +21,7 @@ package com.jpexs.decompiler.flash;
* @author JPEXS
*/
public class PackageNode {
public String packageName;
public PackageNode(String packageName) {
@@ -31,6 +32,4 @@ public class PackageNode {
public String toString() {
return packageName;
}
}

View File

@@ -109,6 +109,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Stack;
import java.util.logging.Level;
@@ -574,8 +575,8 @@ public class SWF {
if (addNode.tag instanceof CharacterIdTag) {
CharacterIdTag cit = (CharacterIdTag) addNode.tag;
String path = cit.getExportName();
if(path==null){
path="";
if (path == null) {
path = "";
}
String pathParts[];
if (path.contains(".")) {
@@ -587,7 +588,7 @@ public class SWF {
int pos = 0;
TagNode selNode = null;
do {
if(pos==pathParts.length-1){
if (pos == pathParts.length - 1) {
break;
}
selNode = null;
@@ -598,19 +599,19 @@ public class SWF {
selNode = node;
break;
}
}
}
}
if (selNode == null) {
items.add(selNode=new TagNode(new PackageNode(pathParts[pos])));
items.add(selNode = new TagNode(new PackageNode(pathParts[pos])));
}
pos++;
if(selNode!=null){
items=selNode.subItems;
if (selNode != null) {
items = selNode.subItems;
}
} while (selNode != null);
items.add(addNode);
}else{
} else {
ret.add(addNode);
}
}
@@ -1196,8 +1197,15 @@ public class SWF {
return ret;
}
public String deobfuscateName(HashMap<String, String> namesMap, String s, boolean firstUppercase, String usageType, RenameType renameType) {
public String deobfuscateName(HashMap<String, String> namesMap, String s, boolean firstUppercase, String usageType, RenameType renameType, Map<String, String> selected) {
boolean isValid = true;
if (selected != null) {
if (selected.containsKey(s)) {
return selected.get(s);
}
}
if (isReserved(s)) {
isValid = false;
}
@@ -1226,7 +1234,7 @@ public class SWF {
cnt = 0;
}
String ret;
String ret = null;
if (renameType == RenameType.TYPENUMBER) {
boolean found;
@@ -1237,7 +1245,7 @@ public class SWF {
found = allVariableNamesStr.contains(ret);
} while (found);
typeCounts.put(usageType, cnt);
} else {
} else if (renameType == RenameType.RANDOMWORD) {
ret = fooString(s, firstUppercase, DEFAULT_FOO_SIZE);
}
return ret;
@@ -1479,22 +1487,32 @@ public class SWF {
}
HashMap<String, Integer> typeCounts = new HashMap<>();
public int deobfuscateIdentifiers(RenameType renameType){
if(fileAttributes==null){
int cnt=0;
cnt+=deobfuscateAS2Identifiers(renameType);
cnt+=deobfuscateAS3Identifiers(renameType);
public int deobfuscateIdentifiers(RenameType renameType) {
if (fileAttributes == null) {
int cnt = 0;
cnt += deobfuscateAS2Identifiers(renameType);
cnt += deobfuscateAS3Identifiers(renameType);
return cnt;
}else{
if(fileAttributes.actionScript3){
} else {
if (fileAttributes.actionScript3) {
return deobfuscateAS3Identifiers(renameType);
}else{
} else {
return deobfuscateAS2Identifiers(renameType);
}
}
}
public void renameAS2Identifier(String identifier, String newname) {
Map<String, String> selected = new HashMap<>();
selected.put(identifier, newname);
renameAS2Identifiers(null, selected);
}
public int deobfuscateAS2Identifiers(RenameType renameType) {
return renameAS2Identifiers(renameType, null);
}
private int renameAS2Identifiers(RenameType renameType, Map<String, String> selected) {
actionsMap = new HashMap<>();
allFunctions = new ArrayList<>();
allVariableNames = new HashMap<>();
@@ -1504,14 +1522,14 @@ public class SWF {
int ret = 0;
objs.addAll(tags);
getVariables(objs, "");
informListeners("deobfuscate", "");
informListeners("rename", "");
int fc = 0;
for (DirectValueTreeItem ti : allVariableNames.keySet()) {
String name = ti.toStringNoH(allVariableNames.get(ti));
allVariableNamesStr.add(name);
}
informListeners("deobfuscate", "classes");
informListeners("rename", "classes");
int classCount = 0;
for (Tag t : tags) {
if (t instanceof DoInitActionTag) {
@@ -1522,7 +1540,7 @@ public class SWF {
for (Tag t : tags) {
if (t instanceof DoInitActionTag) {
cnt++;
informListeners("deobfuscate", "class " + cnt + "/" + classCount);
informListeners("rename", "class " + cnt + "/" + classCount);
DoInitActionTag dia = (DoInitActionTag) t;
String exportName = dia.getExportName();
final String pkgPrefix = "__Packages.";
@@ -1550,7 +1568,7 @@ public class SWF {
if (fun.calculatedFunctionName instanceof DirectValueTreeItem) {
DirectValueTreeItem dvf = (DirectValueTreeItem) fun.calculatedFunctionName;
String fname = dvf.toStringNoH(null);
String changed = deobfuscateName(deobfuscated, fname, false, "method", renameType);
String changed = deobfuscateName(deobfuscated, fname, false, "method", renameType, selected);
if (changed != null) {
deobfuscated.put(fname, changed);
}
@@ -1566,7 +1584,7 @@ public class SWF {
if (gti instanceof DirectValueTreeItem) {
DirectValueTreeItem dvf = (DirectValueTreeItem) gti;
String vname = dvf.toStringNoH(null);
String changed = deobfuscateName(deobfuscated, vname, false, "attribute", renameType);
String changed = deobfuscateName(deobfuscated, vname, false, "attribute", renameType, selected);
if (changed != null) {
deobfuscated.put(vname, changed);
}
@@ -1600,7 +1618,7 @@ public class SWF {
if (classNameParts != null) {
changedNameStr = classNameParts[classNameParts.length - 1 - pos];
}
String changedNameStr2 = deobfuscateName(deobfuscated, changedNameStr, pos == 0, pos == 0 ? "class" : "package", renameType);
String changedNameStr2 = deobfuscateName(deobfuscated, changedNameStr, pos == 0, pos == 0 ? "class" : "package", renameType, selected);
if (changedNameStr2 != null) {
changedNameStr = changedNameStr2;
}
@@ -1623,7 +1641,7 @@ public class SWF {
if (classNameParts != null) {
changedNameStr = classNameParts[classNameParts.length - 1 - pos];
}
String changedNameStr2 = deobfuscateName(deobfuscated, changedNameStr, pos == 0, pos == 0 ? "class" : "package", renameType);
String changedNameStr2 = deobfuscateName(deobfuscated, changedNameStr, pos == 0, pos == 0 ? "class" : "package", renameType, selected);
if (changedNameStr2 != null) {
changedNameStr = changedNameStr2;
}
@@ -1637,17 +1655,17 @@ public class SWF {
for (GraphSourceItem fun : allFunctions) {
fc++;
informListeners("deobfuscate", "function " + fc + "/" + allFunctions.size());
informListeners("rename", "function " + fc + "/" + allFunctions.size());
if (fun instanceof ActionDefineFunction) {
ActionDefineFunction f = (ActionDefineFunction) fun;
String changed = deobfuscateName(deobfuscated, f.functionName, false, "function", renameType);
String changed = deobfuscateName(deobfuscated, f.functionName, false, "function", renameType, selected);
if (changed != null) {
f.replacedFunctionName = changed;
}
}
if (fun instanceof ActionDefineFunction2) {
ActionDefineFunction2 f = (ActionDefineFunction2) fun;
String changed = deobfuscateName(deobfuscated, f.functionName, false, "function", renameType);
String changed = deobfuscateName(deobfuscated, f.functionName, false, "function", renameType, selected);
if (changed != null) {
f.replacedFunctionName = changed;
}
@@ -1664,9 +1682,9 @@ public class SWF {
int vc = 0;
for (DirectValueTreeItem ti : allVariableNames.keySet()) {
vc++;
informListeners("deobfuscate", "variable " + vc + "/" + allVariableNames.size());
informListeners("rename", "variable " + vc + "/" + allVariableNames.size());
String name = ti.toStringNoH(allVariableNames.get(ti));
String changed = deobfuscateName(deobfuscated, name, false, usageTypes.get(ti), renameType);
String changed = deobfuscateName(deobfuscated, name, false, usageTypes.get(ti), renameType, selected);
if (changed != null) {
boolean addNew = false;
String h = System.identityHashCode(allVariableNames.get(ti)) + "_" + name;

View File

@@ -177,6 +177,20 @@ public class ABC {
}
}
public void renameMultiname(int multinameIndex, String newname) {
if (multinameIndex <= 0 || multinameIndex >= constants.constant_multiname.length) {
throw new IllegalArgumentException("Multiname with index " + multinameIndex + " does not exist");
}
Set<Integer> stringUsages = getStringUsages();
int strIndex = constants.constant_multiname[multinameIndex].name_index;
if (stringUsages.contains(strIndex)) { //name is used elsewhere as string literal
strIndex = constants.forceGetStringId(newname);
constants.constant_multiname[multinameIndex].name_index = strIndex;
} else {
constants.constant_string[strIndex] = newname;
}
}
public void deobfuscateIdentifiers(HashMap<String, String> namesMap, RenameType renameType) {
Set<Integer> stringUsages = getStringUsages();
Map<Integer, String> stringUsageTypes = new HashMap<>();

View File

@@ -19,9 +19,12 @@ package com.jpexs.decompiler.flash.abc.gui;
import com.jpexs.decompiler.flash.Configuration;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.ScriptPack;
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
import com.jpexs.decompiler.flash.helpers.Cache;
import com.jpexs.decompiler.flash.helpers.Highlighting;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
@@ -124,6 +127,38 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
reset = false;
}
public int getMultinameUnderCursor() {
int pos = getCaretPosition();
for (Highlighting h : highlights) {
if ((pos >= h.startPos) && (pos < h.startPos + h.len)) {
List<AVM2Instruction> list = abc.bodies[abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex()].code.code;
AVM2Instruction lastIns = null;
long inspos = 0;
AVM2Instruction selIns = null;
for (AVM2Instruction ins : list) {
if (h.offset == ins.getOffset()) {
selIns = ins;
break;
}
if (ins.getOffset() > h.offset) {
inspos = h.offset - lastIns.offset;
selIns = lastIns;
break;
}
lastIns = ins;
}
if (selIns != null) {
for (int i = 0; i < selIns.definition.operands.length; i++) {
if (selIns.definition.operands[i] == AVM2Code.DAT_MULTINAME_INDEX) {
return selIns.operands[i];
}
}
}
}
}
return -1;
}
@Override
public void caretUpdate(CaretEvent e) {
if (abc == null) {

View File

@@ -26,6 +26,8 @@ import com.jpexs.decompiler.flash.action.ActionGraph;
import com.jpexs.decompiler.flash.action.parser.ParseException;
import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser;
import com.jpexs.decompiler.flash.action.parser.script.ActionScriptParser;
import com.jpexs.decompiler.flash.action.swf4.ActionPush;
import com.jpexs.decompiler.flash.action.swf4.ConstantIndex;
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
import com.jpexs.decompiler.flash.gui.GraphFrame;
import com.jpexs.decompiler.flash.gui.Main;
@@ -110,6 +112,45 @@ public class ActionPanel extends JPanel implements ActionListener {
private boolean searchRegexp;
private Cache cache = new Cache(true);
public String getStringUnderCursor() {
int pos = decompiledEditor.getCaretPosition();
for (Highlighting h : decompiledHilights) {
if ((pos >= h.startPos) && (pos < h.startPos + h.len)) {
List<Action> list = lastCode;
Action lastIns = null;
int inspos = 0;
Action selIns = null;
for (Action ins : list) {
if (h.offset == ins.getOffset()) {
selIns = ins;
break;
}
if (ins.getOffset() > h.offset) {
inspos = (int) (h.offset - lastIns.getAddress());
selIns = lastIns;
break;
}
lastIns = ins;
}
if (selIns != null) {
if (selIns instanceof ActionPush) {
ActionPush ap = (ActionPush) selIns;
Object var = ap.values.get(inspos - 1);
String identifier = null;
if (var instanceof String) {
identifier = (String) var;
}
if (var instanceof ConstantIndex) {
identifier = ap.constantPool.get(((ConstantIndex) var).index);
}
return identifier;
}
}
}
}
return null;
}
private CachedScript getCached(ASMSource pack) {
return (CachedScript) cache.get(pack);
}

View File

@@ -262,7 +262,7 @@ public class ActionPush extends Action {
if (pos > 0) {
ret += " ";
}
ret += Highlighting.hilighOffset(toString(i), getAddress()+pos+1);
ret += Highlighting.hilighOffset(toString(i), getAddress() + pos + 1);
pos++;
}
return ret;

View File

@@ -61,7 +61,7 @@ public abstract class GraphTargetItem {
if (src == null) {
return str;
}
return Highlighting.hilighOffset(str, src.getOffset()+pos+1);
return Highlighting.hilighOffset(str, src.getOffset() + pos + 1);
}
public String toStringSemicoloned(List<Object> localData) {

View File

@@ -187,6 +187,9 @@ public class Main {
if (event.equals("deobfuscate")) {
startWork("Deobfuscating..." + (String) data);
}
if (event.equals("rename")) {
startWork("Renaming..." + (String) data);
}
}
});
return locswf;

File diff suppressed because it is too large Load Diff

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.Configuration;
import com.jpexs.decompiler.flash.abc.RenameType;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
@@ -25,6 +26,7 @@ import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
@@ -53,6 +55,7 @@ public class RenameDialog extends JDialog implements ActionListener {
public RenameDialog() {
setSize(300, 150);
setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
int renameType = (Integer) Configuration.getConfig("lastRenameType", (Integer) 1);
ButtonGroup group = new ButtonGroup();
group.add(typeNumberRadioButton);
group.add(randomWordRadioButton);
@@ -60,8 +63,10 @@ public class RenameDialog extends JDialog implements ActionListener {
pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS));
pan.add(typeNumberRadioButton);
pan.add(randomWordRadioButton);
typeNumberRadioButton.setSelected(true);
typeNumberRadioButton.setSelected(renameType == 1);
randomWordRadioButton.setSelected(renameType == 2);
setLayout(new BorderLayout());
add(new JLabel("Rename type:"), BorderLayout.NORTH);
add(pan, BorderLayout.CENTER);
JPanel panButtons = new JPanel(new FlowLayout());
panButtons.add(okButton);
@@ -91,6 +96,7 @@ public class RenameDialog extends JDialog implements ActionListener {
switch (e.getActionCommand()) {
case "OK":
confirmed = true;
Configuration.setConfig("lastRenameType", (Integer) (getRenameType() == RenameType.TYPENUMBER ? 1 : 2));
setVisible(false);
break;
case "CANCEL":

View File

@@ -255,12 +255,10 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
@Override
public String getExportFileName() {
String expName=getExportName();
if((expName==null) || expName.equals("")){
String expName = getExportName();
if ((expName == null) || expName.equals("")) {
return super.getExportFileName();
}
return Helper.makeFileName(super.getExportFileName()+"_"+expName);
return Helper.makeFileName(super.getExportFileName() + "_" + expName);
}
}

View File

@@ -165,35 +165,31 @@ public class DoInitActionTag extends CharacterIdTag implements ASMSource {
@Override
public String getExportFileName() {
String expName=getExportName();
if((expName==null) || expName.equals("")){
String expName = getExportName();
if ((expName == null) || expName.equals("")) {
return super.toString();
}
String pathParts[];
if(expName.contains(".")){
if (expName.contains(".")) {
pathParts = expName.split("\\.");
}else{
} else {
pathParts = new String[]{expName};
}
return Helper.makeFileName(pathParts[pathParts.length-1]);
return Helper.makeFileName(pathParts[pathParts.length - 1]);
}
@Override
public String toString() {
String expName=getExportName();
if((expName==null) || expName.equals("")){
String expName = getExportName();
if ((expName == null) || expName.equals("")) {
return super.toString();
}
String pathParts[];
if(expName.contains(".")){
if (expName.contains(".")) {
pathParts = expName.split("\\.");
}else{
} else {
pathParts = new String[]{expName};
}
return pathParts[pathParts.length-1];
return pathParts[pathParts.length - 1];
}
}

View File

@@ -26,10 +26,11 @@ import java.util.List;
* @author JPEXS
*/
public abstract class CharacterIdTag extends Tag {
public CharacterIdTag(int id, String name, byte[] data, long pos) {
super(id, name, data, pos);
}
public abstract int getCharacterID();
/**
* List of ExportAssetsTag used for converting to String
@@ -38,10 +39,10 @@ public abstract class CharacterIdTag extends Tag {
private String className;
private String exportName;
public void setExportName(String exportName){
public void setExportName(String exportName) {
this.exportName = exportName;
}
public void setClassName(String className) {
this.className = className;
}
@@ -64,16 +65,14 @@ public abstract class CharacterIdTag extends Tag {
@Override
public String getExportFileName() {
return super.getName() + "_" + getCharacterID()+(((exportName!=null) && (!exportName.equals("")))?"_"+exportName:"");
return super.getName() + "_" + getCharacterID() + (((exportName != null) && (!exportName.equals(""))) ? "_" + exportName : "");
}
public String getCharacterExportFileName() {
return getCharacterID()+(((exportName!=null) && (!exportName.equals("")))?"_"+exportName:"");
return getCharacterID() + (((exportName != null) && (!exportName.equals(""))) ? "_" + exportName : "");
}
public String getExportName() {
return exportName;
}
}

View File

@@ -30,6 +30,4 @@ public abstract class CharacterTag extends CharacterIdTag {
public CharacterTag(int id, String name, byte[] data, long pos) {
super(id, name, data, pos);
}
}