Deobfuscate assets identifiers

This commit is contained in:
Jindra Petřík
2025-07-27 01:26:58 +02:00
parent 5024cefaba
commit da140c09b8
15 changed files with 78 additions and 8 deletions

View File

@@ -129,7 +129,7 @@ public class SourceGeneratorLocalData implements Serializable {
/**
* Current script index
*/
public int scriptIndex;
public Integer scriptIndex = null;
/**
* Is in sub method

View File

@@ -2415,7 +2415,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
* @param names Names
* @param namespaces Namespaces
*/
public static void parentNamesAddNames(AbcIndexing abc, int scriptIndex, int name_index, List<Integer> indices, List<String> names, List<String> namespaces) {
public static void parentNamesAddNames(AbcIndexing abc, Integer scriptIndex, int name_index, List<Integer> indices, List<String> names, List<String> namespaces) {
List<Integer> cindices = new ArrayList<>();
List<ABC> outABCs = new ArrayList<>();
@@ -2557,7 +2557,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
* @param namespaces Namespaces
* @param outABCs Out ABCs
*/
public static void parentNames(AbcIndexing abc, int scriptIndex, int name_index, List<Integer> indices, List<String> names, List<String> namespaces, List<ABC> outABCs) {
public static void parentNames(AbcIndexing abc, Integer scriptIndex, int name_index, List<Integer> indices, List<String> names, List<String> namespaces, List<ABC> outABCs) {
AbcIndexing.ClassIndex ci = abc.findClass(new TypeItem(abc.getSelectedAbc().constants.getMultiname(name_index).getNameWithNamespace(new LinkedHashSet<>(), abc.getSelectedAbc(), abc.getSelectedAbc().constants, true /*FIXME!!*/)), abc.getSelectedAbc(), scriptIndex);
while (ci != null) {
int ni = ci.abc.instance_info.get(ci.index).name_index;

View File

@@ -1219,7 +1219,7 @@ public class ActionScript3Parser {
List<String> names = new ArrayList<>();
List<String> namespaces = new ArrayList<>();
//FIXME for Private classes in script (?)
AVM2SourceGenerator.parentNamesAddNames(abcIndex, scriptIndex, AVM2SourceGenerator.resolveType(new SourceGeneratorLocalData(new HashMap<>(), 0, false, 0), ((TypeItem) ((UnresolvedAVM2Item) extendsTypeStr)
AVM2SourceGenerator.parentNamesAddNames(abcIndex, null, AVM2SourceGenerator.resolveType(new SourceGeneratorLocalData(new HashMap<>(), 0, false, 0), ((TypeItem) ((UnresolvedAVM2Item) extendsTypeStr)
.resolve(null, pkgName.addWithSuffix(subNameStr).toRawString(), null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>())), abcIndex), indices, names, namespaces);
for (int i = 0; i < names.size(); i++) {
if (namespaces.get(i) == null || namespaces.get(i).isEmpty()) {

View File

@@ -35,6 +35,7 @@ import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.Helper;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -176,8 +177,12 @@ public class InstanceInfo {
if (ct != null) {
String fileName = ct.getCharacterExportFileName();
if (Configuration.as3ExportNamesUseClassNamesOnly.get()) {
fileName = getName(abc.constants).getNameWithNamespace(usedDeobfuscations, abc, abc.constants, false).toRawString();
}
if (Configuration.autoDeobfuscateIdentifiers.get()) {
fileName = getName(abc.constants).getNameWithNamespace(usedDeobfuscations, abc, abc.constants, false).toPrintableString(new LinkedHashSet<>(), abc.getSwf(), true);
} else {
fileName = getName(abc.constants).getNameWithNamespace(usedDeobfuscations, abc, abc.constants, false).toRawString();
}
}
String ext = "";
if (ct instanceof DefineBinaryDataTag) {

View File

@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.exporters;
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
import com.jpexs.decompiler.flash.EventListener;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
import com.jpexs.decompiler.flash.ReadOnlyTagList;
import com.jpexs.decompiler.flash.RetryTask;
import com.jpexs.decompiler.flash.SWFInputStream;
@@ -26,6 +27,7 @@ import com.jpexs.decompiler.flash.exporters.modes.Font4ExportMode;
import com.jpexs.decompiler.flash.exporters.settings.Font4ExportSettings;
import com.jpexs.decompiler.flash.tags.DefineFont4Tag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.CancellableWorker;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.Path;
@@ -37,6 +39,7 @@ import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
@@ -93,6 +96,9 @@ public class Font4Exporter {
Set<String> classNames = st.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
if (Configuration.autoDeobfuscateIdentifiers.get()) {
className = DottedChain.parseNoSuffix(className).toPrintableString(new LinkedHashSet<>(), st.getSwf(), true);
}
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + ext));
new RetryTask(() -> {
Files.copy(file.toPath(), classFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

View File

@@ -35,6 +35,7 @@ import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.CancellableWorker;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.Path;
@@ -52,6 +53,7 @@ import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
@@ -108,6 +110,9 @@ public class FontExporter {
Set<String> classNames = st.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
if (Configuration.autoDeobfuscateIdentifiers.get()) {
className = DottedChain.parseNoSuffix(className).toPrintableString(new LinkedHashSet<>(), st.getSwf(), true);
}
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + ext));
new RetryTask(() -> {
Files.copy(file.toPath(), classFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

View File

@@ -57,6 +57,7 @@ import com.jpexs.decompiler.flash.types.filters.FILTER;
import com.jpexs.decompiler.flash.types.filters.GLOWFILTER;
import com.jpexs.decompiler.flash.types.filters.GRADIENTBEVELFILTER;
import com.jpexs.decompiler.flash.types.filters.GRADIENTGLOWFILTER;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.CancellableWorker;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.Path;
@@ -84,6 +85,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -272,6 +274,9 @@ public class FrameExporter {
Set<String> classNames = swf.getCharacter(containerId).getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
if (Configuration.autoDeobfuscateIdentifiers.get()) {
className = DottedChain.parseNoSuffix(className).toPrintableString(new LinkedHashSet<>(), swf, true);
}
paths.add(File.separator + Helper.makeFileName(className) + subPath);
}
} else {

View File

@@ -29,6 +29,7 @@ import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.HasSeparateAlphaChannel;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.CancellableWorker;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.Path;
@@ -43,6 +44,7 @@ import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.imageio.ImageIO;
@@ -153,6 +155,9 @@ public class ImageExporter {
Set<String> classNames = imageTag.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
if (Configuration.autoDeobfuscateIdentifiers.get()) {
className = DottedChain.parseNoSuffix(className).toPrintableString(new LinkedHashSet<>(), imageTag.getSwf(), true);
}
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + "." + ImageHelper.getImageFormatString(fileFormat)));
File classAlphaPngFile = new File(outdir + File.separator + Helper.makeFileName(className + ".alpha.png"));
new RetryTask(() -> {

View File

@@ -42,6 +42,7 @@ import com.jpexs.decompiler.flash.timeline.Timeline;
import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.RGB;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.CancellableWorker;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.Path;
@@ -58,6 +59,7 @@ import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
@@ -233,6 +235,9 @@ public class MorphShapeExporter {
Set<String> classNames = mst.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
if (Configuration.autoDeobfuscateIdentifiers.get()) {
className = DottedChain.parseNoSuffix(className).toPrintableString(new LinkedHashSet<>(), mst.getSwf(), true);
}
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + settings.getFileExtension()));
File classFileStart = new File(outdir + File.separator + Helper.makeFileName(className + ".start" + settings.getFileExtension()));
File classFileEnd = new File(outdir + File.separator + Helper.makeFileName(className + ".end" + settings.getFileExtension()));

View File

@@ -33,6 +33,7 @@ import com.jpexs.decompiler.flash.flv.VIDEODATA;
import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.VideoFrameTag;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.CancellableWorker;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.Path;
@@ -47,6 +48,7 @@ import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -99,6 +101,9 @@ public class MovieExporter {
Set<String> classNames = videoStream.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
if (Configuration.autoDeobfuscateIdentifiers.get()) {
className = DottedChain.parseNoSuffix(className).toPrintableString(new LinkedHashSet<>(), videoStream.getSwf(), true);
}
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + ".flv"));
new RetryTask(() -> {
Files.copy(file.toPath(), classFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

View File

@@ -40,6 +40,7 @@ import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.RGB;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.CancellableWorker;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.Path;
@@ -56,6 +57,7 @@ import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
@@ -170,6 +172,9 @@ public class ShapeExporter {
Set<String> classNames = st.getClassNames();
if (Configuration.as3ExportNamesUseClassNamesOnly.get() && !classNames.isEmpty()) {
for (String className : classNames) {
if (Configuration.autoDeobfuscateIdentifiers.get()) {
className = DottedChain.parseNoSuffix(className).toPrintableString(new LinkedHashSet<>(), st.getSwf(), true);
}
File classFile = new File(outdir + File.separator + Helper.makeFileName(className + settings.getFileExtension()));
new RetryTask(() -> {
Files.copy(file.toPath(), classFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

View File

@@ -35,6 +35,7 @@ import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.Reserved;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.ByteArrayInputStream;
@@ -42,6 +43,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.LinkedHashSet;
/**
* DefineBinaryData tag - Contains binary data.
@@ -286,6 +288,10 @@ public class DefineBinaryDataTag extends CharacterTag implements BinaryDataInter
@Override
public String getClassExportFileName(String className) {
if (Configuration.autoDeobfuscateIdentifiers.get()) {
return DottedChain.parseNoSuffix(className).toPrintableString(new LinkedHashSet<>(), swf, true);
}
return className;
}

View File

@@ -16,12 +16,14 @@
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.action.ActionTreeOperation;
import com.jpexs.decompiler.flash.action.model.CallMethodActionItem;
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
import com.jpexs.decompiler.flash.action.model.GetMemberActionItem;
import com.jpexs.decompiler.flash.action.model.GetVariableActionItem;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.NulWriter;
import com.jpexs.decompiler.flash.tags.DefineScalingGridTag;
@@ -131,10 +133,18 @@ public abstract class CharacterTag extends Tag implements CharacterIdTag {
public String getCharacterExportFileName() {
String result = "" + getCharacterId();
if (exportName != null) {
result += "_" + exportName;
if (Configuration.autoDeobfuscateIdentifiers.get()) {
result += "_" + Helper.escapeExportname(swf, result, false);
} else {
result += "_" + exportName;
}
}
if (classNames.size() == 1) {
result += "_" + classNames.iterator().next();
if (Configuration.autoDeobfuscateIdentifiers.get()) {
result += "_" + DottedChain.parseNoSuffix(classNames.iterator().next()).toPrintableString(new LinkedHashSet<>(), swf, true);
} else {
result += "_" + classNames.iterator().next();
}
}
return result;
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import com.jpexs.decompiler.flash.types.sound.SoundExportFormat;
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
@@ -158,4 +159,10 @@ public interface SoundTag extends TreeItem {
* @return Initial latency
*/
public int getInitialLatency();
/**
* Gets SWF
* @return SWF
*/
public SWF getSwf();
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.timeline;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
@@ -219,4 +220,9 @@ public class SoundStreamFrameRange implements TreeItem, SoundTag {
public int getInitialLatency() {
return 0;
}
@Override
public SWF getSwf() {
return head.getSwf();
}
}