mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-27 03:00:51 +00:00
Added: AS2 - show deobfuscated class/package names in the class tree
This commit is contained in:
@@ -622,6 +622,63 @@ public class IdentifiersDeobfuscation {
|
||||
return writer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unescapes deobfuscated identifier
|
||||
* @param s String
|
||||
* @return Unescaped string
|
||||
*/
|
||||
public static String unescapeOIdentifier(String s) {
|
||||
StringBuilder ret = new StringBuilder(s.length());
|
||||
if (s.length() < 2) {
|
||||
return s;
|
||||
}
|
||||
if (!(s.startsWith("\u00A7") && s.endsWith("\u00A7"))) {
|
||||
return s;
|
||||
}
|
||||
for (int i = 1; i < s.length() - 1; i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c == '\\') {
|
||||
if (i + 1 < s.length() - 1) {
|
||||
i++;
|
||||
c = s.charAt(i);
|
||||
if (c == 'n') {
|
||||
ret.append("\n");
|
||||
} else if (c == 'r') {
|
||||
ret.append("\r");
|
||||
} else if (c == 't') {
|
||||
ret.append("\t");
|
||||
} else if (c == 'b') {
|
||||
ret.append("\b");
|
||||
} else if (c == 'f') {
|
||||
ret.append("\f");
|
||||
} else if (c == '\\') {
|
||||
ret.append("\\");
|
||||
} else if (c == '\u00A7') {
|
||||
ret.append("\u00A7");
|
||||
} else if (c == 'x' && i + 2 < s.length() - 1) {
|
||||
ret.append((char) Integer.parseInt(s.substring(i + 1, i + 3), 16));
|
||||
i += 2;
|
||||
} else if (c == '{') {
|
||||
int endPos = s.indexOf("}", i);
|
||||
if (endPos != -1) {
|
||||
int numRepeat = Integer.parseInt(s.substring(i + 1, endPos));
|
||||
i = endPos + 1;
|
||||
c = s.charAt(i);
|
||||
for (int j = 0; j < numRepeat; j++) {
|
||||
ret.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes obfuscated identifier.
|
||||
*
|
||||
|
||||
@@ -3349,7 +3349,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
if (treeItem instanceof AS2Package) {
|
||||
AS2Package pkg = (AS2Package) treeItem;
|
||||
if (pkg.isFlat()) {
|
||||
String[] parts = pkg.toString().split("\\.");
|
||||
String[] parts = pkg.getName().split("\\.");
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
parts[i] = Helper.makeFileName(parts[i]);
|
||||
}
|
||||
|
||||
@@ -21,10 +21,12 @@ import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.SymbolClassTypeTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.DottedIdentifier;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFArray;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Table;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -56,6 +58,7 @@ public class ExportAssetsTag extends SymbolClassTypeTag {
|
||||
|
||||
@SWFArray(value = "name", countField = "count")
|
||||
@Table(value = "assets", itemName = "asset")
|
||||
@DottedIdentifier
|
||||
public List<String> names;
|
||||
|
||||
/**
|
||||
@@ -161,7 +164,7 @@ public class ExportAssetsTag extends SymbolClassTypeTag {
|
||||
Map<String, String> ret = super.getNameProperties();
|
||||
if (names.size() == 1) {
|
||||
ret.put("chid", "" + tags.get(0));
|
||||
ret.put("ex", "" + names.get(0));
|
||||
ret.put("ex", "" + DottedChain.parseNoSuffix(names.get(0)).toPrintableString(false));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.jpexs.decompiler.flash.types.annotations.SWFArray;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Table;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.IOException;
|
||||
@@ -161,7 +162,7 @@ public class ImportAssets2Tag extends Tag implements ImportTag {
|
||||
Map<String, String> ret = super.getNameProperties();
|
||||
if (names.size() == 1) {
|
||||
ret.put("chid", "" + tags.get(0));
|
||||
ret.put("im", "" + names.get(0));
|
||||
ret.put("im", "" + DottedChain.parseNoSuffix(names.get(0)).toPrintableString(false));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.types.annotations.SWFArray;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Table;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -137,7 +138,7 @@ public class ImportAssetsTag extends Tag implements ImportTag {
|
||||
Map<String, String> ret = super.getNameProperties();
|
||||
if (names.size() == 1) {
|
||||
ret.put("chid", "" + tags.get(0));
|
||||
ret.put("im", "" + names.get(0));
|
||||
ret.put("im", "" + DottedChain.parseNoSuffix(names.get(0)).toPrintableString(false));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.tags.base.SymbolClassTypeTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.DottedIdentifier;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFArray;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
@@ -53,6 +54,7 @@ public class SymbolClassTag extends SymbolClassTypeTag {
|
||||
|
||||
@SWFArray(value = "name", countField = "numSymbols")
|
||||
@Table(value = "symbols", itemName = "symbol")
|
||||
@DottedIdentifier(as3 = true)
|
||||
public List<String> names;
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.flash.tags.DefineScalingGridTag;
|
||||
import com.jpexs.decompiler.flash.tags.DoInitActionTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
@@ -98,10 +99,14 @@ public abstract class CharacterTag extends Tag implements CharacterIdTag {
|
||||
ret.put("chid", "" + chid);
|
||||
}
|
||||
if (exportName != null) {
|
||||
ret.put("exp", Helper.escapePCodeString(exportName));
|
||||
ret.put("exp", DottedChain.parseNoSuffix(exportName).toPrintableString(false));
|
||||
}
|
||||
if (!classNames.isEmpty()) {
|
||||
ret.put("cls", Helper.joinEscapePCodeString(", ", classNames));
|
||||
List<String> escapedList = new ArrayList<>();
|
||||
for (String className : classNames) {
|
||||
escapedList.add(DottedChain.parseNoSuffix(className).toPrintableString(true));
|
||||
}
|
||||
ret.put("cls", String.join(", ", escapedList));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.timeline;
|
||||
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.treeitems.Openable;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -187,7 +189,10 @@ public class AS2Package implements TreeItem {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
if (defaultPackage) {
|
||||
return name;
|
||||
}
|
||||
return DottedChain.parseNoSuffix(name).toPrintableString(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2025 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.types.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Field is dotted identifier.
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface DottedIdentifier {
|
||||
boolean as3() default false;
|
||||
}
|
||||
@@ -149,7 +149,31 @@ public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a dotted chain from a deobfuscated string.
|
||||
*
|
||||
* @param name Name
|
||||
* @return Dotted chain
|
||||
*/
|
||||
public static final DottedChain parsePrintable(String name) {
|
||||
if (name == null) {
|
||||
return DottedChain.EMPTY;
|
||||
} else if (name.isEmpty()) {
|
||||
return DottedChain.TOPLEVEL;
|
||||
} else {
|
||||
String[] parts = name.split("\\.");
|
||||
List<PathPart> newParts = new ArrayList<>();
|
||||
for (String part : parts) {
|
||||
newParts.add(new PathPart(IdentifiersDeobfuscation.unescapeOIdentifier(part), false, ""));
|
||||
}
|
||||
|
||||
DottedChain ret = new DottedChain();
|
||||
ret.parts = newParts;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new dotted chain.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user