mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-05 10:45:07 +00:00
Replacements table in AS1/2,
not much useful since eval() is used in most cases
This commit is contained in:
@@ -17,12 +17,22 @@
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.RenameType;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Deobfuscation;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScriptLexer;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.ParsedSymbol;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.SymbolType;
|
||||
import com.jpexs.decompiler.flash.asdoc.ActionScriptDocParser;
|
||||
import com.jpexs.decompiler.flash.asdoc.AsDocComment;
|
||||
import com.jpexs.decompiler.flash.asdoc.AsDocTag;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.decompiler.graph.model.DocCommentItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.util.ArrayList;
|
||||
@@ -34,6 +44,7 @@ import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import natorder.NaturalOrderComparator;
|
||||
|
||||
/**
|
||||
* Identifiers deobfuscation.
|
||||
@@ -42,6 +53,11 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class IdentifiersDeobfuscation {
|
||||
|
||||
/**
|
||||
* Prefix to be put instead of obfuscated name. It will by suffixed with a number.
|
||||
*/
|
||||
public static final String SAFE_STR_PREFIX = "_SafeStr_";
|
||||
|
||||
/**
|
||||
* Random number generator.
|
||||
*/
|
||||
@@ -528,11 +544,27 @@ public class IdentifiersDeobfuscation {
|
||||
/**
|
||||
* Appends obfuscated identifier.
|
||||
*
|
||||
* @param s String
|
||||
* @param swf SWF
|
||||
* @param used Used deobfuscations
|
||||
* @param s String
|
||||
* @param writer Writer
|
||||
* @return Writer
|
||||
*/
|
||||
public static GraphTextWriter appendObfuscatedIdentifier(String s, GraphTextWriter writer) {
|
||||
public static GraphTextWriter appendObfuscatedIdentifier(SWF swf, Set<String> used, String s, GraphTextWriter writer) {
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
if (Configuration.useSafeStr.get() && swf != null) {
|
||||
map = swf.getObfuscatedIdentifiersMap();
|
||||
used.add(s);
|
||||
if (map.containsKey(s)) {
|
||||
writer.append(map.get(s));
|
||||
} else {
|
||||
String ret = IdentifiersDeobfuscation.SAFE_STR_PREFIX + map.size();
|
||||
map.put(s, ret);
|
||||
writer.append(ret);
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
|
||||
writer.append("\u00A7");
|
||||
escapeOIdentifier(s, writer);
|
||||
return writer.append("\u00A7");
|
||||
@@ -554,15 +586,22 @@ public class IdentifiersDeobfuscation {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (Configuration.useSafeStr.get() && as3) {
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
if (Configuration.useSafeStr.get()) {
|
||||
|
||||
if (swf != null) {
|
||||
map = swf.getObfuscatedIdentifiersMap();
|
||||
}
|
||||
|
||||
Map<String, String> map = swf == null ? new LinkedHashMap<>() : swf.getAs3ObfuscatedIdentifiers();
|
||||
if (map.containsKey(s)) {
|
||||
used.add(s);
|
||||
return map.get(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (s.startsWith("\u00A7") && s.endsWith("\u00A7")) { // Assuming already printed - TODO:detect better
|
||||
return s;
|
||||
}
|
||||
@@ -584,6 +623,13 @@ public class IdentifiersDeobfuscation {
|
||||
return s;
|
||||
}
|
||||
|
||||
if (Configuration.useSafeStr.get()) {
|
||||
String ret = IdentifiersDeobfuscation.SAFE_STR_PREFIX + map.size();
|
||||
map.put(s, ret);
|
||||
used.add(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
String ret = "\u00A7" + escapeOIdentifier(s) + "\u00A7";
|
||||
nameCache.put(s, ret);
|
||||
return ret;
|
||||
@@ -744,4 +790,55 @@ public class IdentifiersDeobfuscation {
|
||||
as2NameCache.clear();
|
||||
as3NameCache.clear();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static GraphTextWriter writeCurrentScriptReplacements(GraphTextWriter writer, Set<String> usedDeobfuscations, SWF swf) {
|
||||
if (!usedDeobfuscations.isEmpty()) {
|
||||
writer.newLine();
|
||||
List<String> commentLines = new ArrayList<>();
|
||||
Map<String, String> fullMap = swf.getObfuscatedIdentifiersMap();
|
||||
int i = 0;
|
||||
for (String obfuscated : usedDeobfuscations) {
|
||||
String deobfuscated = fullMap.get(obfuscated);
|
||||
commentLines.add("@identifier " + deobfuscated + " = \"" + Helper.escapePCodeString(obfuscated) + "\"");
|
||||
i++;
|
||||
}
|
||||
commentLines.sort(new NaturalOrderComparator());
|
||||
commentLines.add(0, AppResources.translate("decompilationWarning.obfuscatedIdentifiers"));
|
||||
commentLines.add(1, AppResources.translate("decompilationWarning.replacementsFollow"));
|
||||
String[] commentLinesArr = commentLines.toArray(new String[commentLines.size()]);
|
||||
new DocCommentItem(commentLinesArr).appendTo(writer, LocalData.empty);
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
|
||||
public static Map<String, String> getReplacementsFromDoc(String s) throws Exception {
|
||||
ActionScriptDocParser asd = new ActionScriptDocParser();
|
||||
List<AsDocComment> comments = asd.parse(s);
|
||||
Map<String, String> replacements = new LinkedHashMap<>();
|
||||
for (AsDocComment comment:comments) {
|
||||
for (AsDocTag tag : comment.tags) {
|
||||
if ("identifier".equals(tag.tagName)) {
|
||||
String tagText = tag.tagText;
|
||||
if (tagText != null && !tagText.isEmpty()) {
|
||||
ActionScriptLexer lexer = new ActionScriptLexer(tagText);
|
||||
ParsedSymbol symb = lexer.yylex();
|
||||
if (symb.type != SymbolType.IDENTIFIER) {
|
||||
throw new Exception("Invalid @identifier AsDoc tag value. Identifier expected.");
|
||||
}
|
||||
ParsedSymbol symb2 = lexer.yylex();
|
||||
if (symb2.type != SymbolType.ASSIGN) {
|
||||
throw new Exception("Invalid @identifier AsDoc tag value. Assign expected.");
|
||||
}
|
||||
ParsedSymbol symb3 = lexer.yylex();
|
||||
if (symb3.type != SymbolType.STRING) {
|
||||
throw new Exception("Invalid @identifier AsDoc tag value. String expected.");
|
||||
}
|
||||
replacements.put(symb.value.toString(), symb3.value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return replacements;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -672,7 +672,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
/**
|
||||
* AS3 obfuscated identifiers map
|
||||
*/
|
||||
private transient Map<String, String> as3ObfuscatedIdentifiersMap = null;
|
||||
private transient Map<String, String> obfuscatedIdentifiersMap = null;
|
||||
|
||||
/**
|
||||
* Lock for characters synchronization
|
||||
@@ -4002,21 +4002,23 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all AS3 obfuscated identifiers in this SWF and their suggested SafeStr replacement
|
||||
* Gets obfuscated identifiers map in this SWF and their suggested SafeStr replacement.
|
||||
* For AS3 it calculates all replacements on first call.
|
||||
* For AS1/2 it adds new items as they are opened in FFDec
|
||||
* @return Map source identifier to SafeStr replacement
|
||||
*/
|
||||
public synchronized Map<String, String> getAs3ObfuscatedIdentifiers() {
|
||||
if (as3ObfuscatedIdentifiersMap != null) {
|
||||
return as3ObfuscatedIdentifiersMap;
|
||||
public synchronized Map<String, String> getObfuscatedIdentifiersMap() {
|
||||
if (obfuscatedIdentifiersMap != null) {
|
||||
return obfuscatedIdentifiersMap;
|
||||
}
|
||||
Map<String, String> ret = new LinkedHashMap<>();
|
||||
Map<String, String> ret = Collections.synchronizedMap(new LinkedHashMap<>());
|
||||
for (Tag tag : getTags()) {
|
||||
if (tag instanceof ABCContainerTag) {
|
||||
ABCContainerTag abcTag = (ABCContainerTag) tag;
|
||||
abcTag.getABC().getObfuscatedIdentifiers(ret);
|
||||
}
|
||||
}
|
||||
return as3ObfuscatedIdentifiersMap = ret;
|
||||
return obfuscatedIdentifiersMap = ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4535,7 +4537,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
asmsCache = null;
|
||||
asmsCacheExportFilenames = null;
|
||||
synchronized (this) {
|
||||
as3ObfuscatedIdentifiersMap = null;
|
||||
obfuscatedIdentifiersMap = null;
|
||||
}
|
||||
|
||||
IdentifiersDeobfuscation.clearCache();
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.AppResources;
|
||||
import com.jpexs.decompiler.flash.DeobfuscationListener;
|
||||
import com.jpexs.decompiler.flash.EndOfStreamException;
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
|
||||
@@ -658,7 +659,7 @@ public class ABC implements Openable {
|
||||
return;
|
||||
}
|
||||
|
||||
ret.put(s, AVM2Deobfuscation.SAFE_STR_PREFIX + ret.size());
|
||||
ret.put(s, IdentifiersDeobfuscation.SAFE_STR_PREFIX + ret.size());
|
||||
}
|
||||
|
||||
private void getObfuscatedPackageIdentifier(int strIndex, Map<String, String> ret) {
|
||||
@@ -680,8 +681,8 @@ public class ABC implements Openable {
|
||||
List<String> deobfuscatedList = new ArrayList<>();
|
||||
for (String part : parts) {
|
||||
if (!deobfuscation.isValidNSPart(part)) {
|
||||
deobfuscatedList.add(AVM2Deobfuscation.SAFE_STR_PREFIX + ret.size());
|
||||
ret.put(part, AVM2Deobfuscation.SAFE_STR_PREFIX + ret.size());
|
||||
deobfuscatedList.add(IdentifiersDeobfuscation.SAFE_STR_PREFIX + ret.size());
|
||||
ret.put(part, IdentifiersDeobfuscation.SAFE_STR_PREFIX + ret.size());
|
||||
} else {
|
||||
deobfuscatedList.add(part);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.ConvertException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
@@ -466,21 +467,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!usedDeobfuscations.isEmpty()) {
|
||||
writer.newLine();
|
||||
List<String> commentLines = new ArrayList<>();
|
||||
Map<String, String> fullMap = abc.getSwf().getAs3ObfuscatedIdentifiers();
|
||||
int i = 0;
|
||||
for (String obfuscated : usedDeobfuscations) {
|
||||
String deobfuscated = fullMap.get(obfuscated);
|
||||
commentLines.add("@identifier " + deobfuscated + " = \"" + Helper.escapePCodeString(obfuscated) + "\"");
|
||||
i++;
|
||||
}
|
||||
commentLines.sort(new NaturalOrderComparator());
|
||||
commentLines.add(0, "The original code has obfuscated identifiers. List of replacements follows:");
|
||||
String[] commentLinesArr = commentLines.toArray(new String[commentLines.size()]);
|
||||
new DocCommentItem(commentLinesArr).appendTo(writer, LocalData.empty);
|
||||
}
|
||||
IdentifiersDeobfuscation.writeCurrentScriptReplacements(writer, usedDeobfuscations, abc.getSwf());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,9 +33,7 @@ import java.util.regex.Pattern;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class AVM2Deobfuscation {
|
||||
|
||||
public static final String SAFE_STR_PREFIX = "_SafeStr_";
|
||||
public class AVM2Deobfuscation {
|
||||
|
||||
/**
|
||||
* Default size of random word.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
|
||||
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
@@ -3023,33 +3024,11 @@ public class ActionScript3Parser {
|
||||
* @throws CompilationException On compilation error
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
public void addScript(String s, String fileName, int classPos, int scriptIndex, String documentClass, ABC abc) throws AVM2ParseException, IOException, CompilationException, InterruptedException {
|
||||
|
||||
replacements.clear();
|
||||
ActionScriptDocParser asd = new ActionScriptDocParser();
|
||||
List<AsDocComment> comments = asd.parse(s);
|
||||
for (AsDocComment comment:comments) {
|
||||
for (AsDocTag tag : comment.tags) {
|
||||
if ("identifier".equals(tag.tagName)) {
|
||||
String tagText = tag.tagText;
|
||||
if (tagText != null && !tagText.isEmpty()) {
|
||||
ActionScriptLexer lexer = new ActionScriptLexer(tagText);
|
||||
ParsedSymbol symb = lexer.yylex();
|
||||
if (symb.type != SymbolType.IDENTIFIER) {
|
||||
throw new AVM2ParseException("Invalid @identifier AsDoc tag value. Identifier expected.", 0);
|
||||
}
|
||||
ParsedSymbol symb2 = lexer.yylex();
|
||||
if (symb2.type != SymbolType.ASSIGN) {
|
||||
throw new AVM2ParseException("Invalid @identifier AsDoc tag value. Assign expected.", 0);
|
||||
}
|
||||
ParsedSymbol symb3 = lexer.yylex();
|
||||
if (symb3.type != SymbolType.STRING) {
|
||||
throw new AVM2ParseException("Invalid @identifier AsDoc tag value. String expected.", 0);
|
||||
}
|
||||
replacements.put(symb.value.toString(), symb3.value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
public void addScript(String s, String fileName, int classPos, int scriptIndex, String documentClass, ABC abc) throws AVM2ParseException, IOException, CompilationException, InterruptedException {
|
||||
try {
|
||||
replacements = IdentifiersDeobfuscation.getReplacementsFromDoc(s);
|
||||
} catch (Exception ex) {
|
||||
throw new AVM2ParseException(ex.getMessage(), -1);
|
||||
}
|
||||
List<List<NamespaceItem>> allOpenedNamespaces = new ArrayList<>();
|
||||
Reference<Integer> numberContextRef = new Reference<>(null);
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.action;
|
||||
import com.jpexs.decompiler.flash.AppResources;
|
||||
import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.ValueTooLargeException;
|
||||
@@ -1002,7 +1003,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
new ActionDeobfuscator().actionTreeCreated(tree, swf);
|
||||
}
|
||||
|
||||
Graph.graphToString(tree, new NulWriter(), new LocalData());
|
||||
Graph.graphToString(tree, new NulWriter(), LocalData.create(new ConstantPool(), swf, usedDeobfuscations));
|
||||
return tree;
|
||||
}
|
||||
}, timeout, TimeUnit.SECONDS);
|
||||
@@ -1031,7 +1032,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
asm.getActionSourcePrefix(writer);
|
||||
}
|
||||
if (convertException == null) {
|
||||
Graph.graphToString(tree, writer, new LocalData());
|
||||
Graph.graphToString(tree, writer, LocalData.create(new ConstantPool(), swf, usedDeobfuscations));
|
||||
} else if (convertException instanceof TimeoutException) {
|
||||
Helper.appendTimeoutCommentAs2(writer, timeout, actions.size());
|
||||
} else {
|
||||
@@ -1041,7 +1042,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
asm.getActionSourceSuffix(writer);
|
||||
}
|
||||
|
||||
//TODO: write the actual used deobfuscations !!!
|
||||
IdentifiersDeobfuscation.writeCurrentScriptReplacements(writer, usedDeobfuscations, swf);
|
||||
|
||||
return writer;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ public class DefineLocalActionItem extends ActionItem implements SetTypeActionIt
|
||||
srcData.declaration = true;
|
||||
if (((name instanceof DirectValueActionItem)) && (((DirectValueActionItem) name).isString()) && (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) name).toStringNoQuotes(localData),
|
||||
"this", "super", "true", "false", "NaN", "null", "newline", "Infinity", "undefined", "get", "set", "each"))) {
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData), writer);
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(localData.swf, localData.usedDeobfuscations, ((DirectValueActionItem) name).toStringNoQuotes(localData), writer);
|
||||
} else {
|
||||
stripQuotes(name, localData, writer);
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ public class FunctionActionItem extends ActionItem implements BranchStackResista
|
||||
}
|
||||
|
||||
if (!IdentifiersDeobfuscation.isValidName(false, fname)) {
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(fname, writer);
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(localData.swf, localData.usedDeobfuscations, fname, writer);
|
||||
} else {
|
||||
writer.append(fname);
|
||||
//calculatedFunctionName.appendToNoQuotes(writer, localData);
|
||||
@@ -265,7 +265,7 @@ public class FunctionActionItem extends ActionItem implements BranchStackResista
|
||||
}
|
||||
writer.append(" ");
|
||||
if (!IdentifiersDeobfuscation.isValidName(false, fname)) {
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(fname, writer);
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(localData.swf, localData.usedDeobfuscations, fname, writer);
|
||||
} else {
|
||||
writer.append(fname);
|
||||
}
|
||||
@@ -298,7 +298,7 @@ public class FunctionActionItem extends ActionItem implements BranchStackResista
|
||||
d.declaration = true;
|
||||
|
||||
if (!IdentifiersDeobfuscation.isValidName(false, pname)) {
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(pname, writer);
|
||||
IdentifiersDeobfuscation.appendObfuscatedIdentifier(localData.swf, localData.usedDeobfuscations, pname, writer);
|
||||
} else {
|
||||
writer.append(pname);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.parser.script;
|
||||
|
||||
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
@@ -173,6 +174,7 @@ import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -259,6 +261,11 @@ public class ActionScript2Parser {
|
||||
* SWF
|
||||
*/
|
||||
private SWF swf;
|
||||
|
||||
/**
|
||||
* Obfuscation identifiers replacements
|
||||
*/
|
||||
private Map<String, String> replacements = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -381,6 +388,11 @@ public class ActionScript2Parser {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
ParsedSymbol ret = lexer.lex();
|
||||
if (ret.type == SymbolType.IDENTIFIER) {
|
||||
if (replacements.containsKey(ret.value.toString())) {
|
||||
ret.value = replacements.get(ret.value.toString());
|
||||
}
|
||||
}
|
||||
if (debugMode) {
|
||||
System.out.println(ret);
|
||||
}
|
||||
@@ -1129,7 +1141,7 @@ public class ActionScript2Parser {
|
||||
expectedType(SymbolType.CURLY_CLOSE);
|
||||
break;
|
||||
case FUNCTION:
|
||||
s = lexer.lex();
|
||||
s = lex();
|
||||
expectedIdentifier(s, lexer.yyline());
|
||||
ret = (function(true, s.value.toString(), false, variables, functions, inTellTarget, hasEval));
|
||||
break;
|
||||
@@ -1799,7 +1811,7 @@ public class ActionScript2Parser {
|
||||
//AS 1/2:
|
||||
//AS2:
|
||||
case "constant":
|
||||
s = lexer.lex();
|
||||
s = lex();
|
||||
expected(s, lexer.yyline(), SymbolType.INTEGER);
|
||||
ret = new UnresolvedConstantActionItem((int) (long) (Long) s.value);
|
||||
break;
|
||||
@@ -1819,7 +1831,7 @@ public class ActionScript2Parser {
|
||||
allowMemberOrCall = true;
|
||||
break;
|
||||
case "strict":
|
||||
s = lexer.lex();
|
||||
s = lex();
|
||||
expected(s, lexer.yyline(), SymbolType.INTEGER);
|
||||
ret = new StrictModeActionItem(null, null, (int) (long) (Long) s.value);
|
||||
break;
|
||||
@@ -2198,6 +2210,13 @@ public class ActionScript2Parser {
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
public List<GraphTargetItem> treeFromString(String str, List<String> constantPool) throws ActionParseException, IOException, InterruptedException {
|
||||
|
||||
try {
|
||||
replacements = IdentifiersDeobfuscation.getReplacementsFromDoc(str);
|
||||
} catch (Exception ex) {
|
||||
throw new ActionParseException(ex.getMessage(), -1);
|
||||
}
|
||||
|
||||
List<GraphTargetItem> retTree = new ArrayList<>();
|
||||
this.constantPool = constantPool;
|
||||
lexer = new ActionScriptLexer(new StringReader(str));
|
||||
@@ -2208,12 +2227,12 @@ public class ActionScript2Parser {
|
||||
BUTTONCONDACTION newButtonCond = new BUTTONCONDACTION();
|
||||
|
||||
if (targetSource instanceof BUTTONCONDACTION) {
|
||||
ParsedSymbol symb = lexer.lex();
|
||||
ParsedSymbol symb = lex();
|
||||
if (symb.type != SymbolType.IDENTIFIER || !"on".equals(symb.value)) {
|
||||
throw new ActionParseException("on keyword expected but " + symb + " found", lexer.yyline());
|
||||
}
|
||||
expectedType(SymbolType.PARENT_OPEN);
|
||||
symb = lexer.lex();
|
||||
symb = lex();
|
||||
boolean condEmpty = true;
|
||||
while (symb.type == SymbolType.IDENTIFIER) {
|
||||
condEmpty = false;
|
||||
@@ -2240,7 +2259,7 @@ public class ActionScript2Parser {
|
||||
newButtonCond.condOutDownToOverDown = true;
|
||||
break;
|
||||
case "keyPress":
|
||||
symb = lexer.lex();
|
||||
symb = lex();
|
||||
expected(symb, lexer.yyline(), SymbolType.STRING);
|
||||
Integer key = CLIPACTIONRECORD.stringToKey((String) symb.value);
|
||||
if (key == null) {
|
||||
@@ -2251,12 +2270,12 @@ public class ActionScript2Parser {
|
||||
default:
|
||||
throw new ActionParseException("Unrecognized event type", lexer.yyline());
|
||||
}
|
||||
symb = lexer.lex();
|
||||
symb = lex();
|
||||
if (symb.type == SymbolType.PARENT_CLOSE) {
|
||||
break;
|
||||
}
|
||||
expected(symb, lexer.yyline(), SymbolType.COMMA);
|
||||
symb = lexer.lex();
|
||||
symb = lex();
|
||||
}
|
||||
expected(symb, lexer.yyline(), SymbolType.PARENT_CLOSE);
|
||||
if (condEmpty) {
|
||||
@@ -2268,13 +2287,13 @@ public class ActionScript2Parser {
|
||||
CLIPEVENTFLAGS newClipEventFlags = new CLIPEVENTFLAGS();
|
||||
int newClipActionRecordKey = 0;
|
||||
if (targetSource instanceof CLIPACTIONRECORD) {
|
||||
ParsedSymbol symb = lexer.lex();
|
||||
ParsedSymbol symb = lex();
|
||||
if (symb.type != SymbolType.IDENTIFIER || (!"on".equals(symb.value) && !"onClipEvent".equals(symb.value))) {
|
||||
throw new ActionParseException("on or onClipEvent keyword expected but " + symb + " found", lexer.yyline());
|
||||
}
|
||||
expectedType(SymbolType.PARENT_OPEN);
|
||||
if ("on".equals(symb.value)) {
|
||||
symb = lexer.lex();
|
||||
symb = lex();
|
||||
boolean condEmpty = true;
|
||||
while (symb.type == SymbolType.IDENTIFIER) {
|
||||
condEmpty = false;
|
||||
@@ -2308,7 +2327,7 @@ public class ActionScript2Parser {
|
||||
break;
|
||||
|
||||
case "keyPress":
|
||||
symb = lexer.lex();
|
||||
symb = lex();
|
||||
expected(symb, lexer.yyline(), SymbolType.STRING);
|
||||
Integer key = CLIPACTIONRECORD.stringToKey((String) symb.value);
|
||||
if (key == null) {
|
||||
@@ -2320,19 +2339,19 @@ public class ActionScript2Parser {
|
||||
default:
|
||||
throw new ActionParseException("Unrecognized event type", lexer.yyline());
|
||||
}
|
||||
symb = lexer.lex();
|
||||
symb = lex();
|
||||
if (symb.type == SymbolType.PARENT_CLOSE) {
|
||||
break;
|
||||
}
|
||||
expected(symb, lexer.yyline(), SymbolType.COMMA);
|
||||
symb = lexer.lex();
|
||||
symb = lex();
|
||||
}
|
||||
expected(symb, lexer.yyline(), SymbolType.PARENT_CLOSE);
|
||||
if (condEmpty) {
|
||||
throw new ActionParseException("condition must be non empty", lexer.yyline());
|
||||
}
|
||||
} else if ("onClipEvent".equals(symb.value)) {
|
||||
symb = lexer.lex();
|
||||
symb = lex();
|
||||
expected(symb, lexer.yyline(), SymbolType.IDENTIFIER);
|
||||
|
||||
switch ((String) symb.value) {
|
||||
@@ -2404,7 +2423,7 @@ public class ActionScript2Parser {
|
||||
expectedType(SymbolType.CURLY_CLOSE);
|
||||
}
|
||||
|
||||
if (lexer.lex().type != SymbolType.EOF) {
|
||||
if (lex().type != SymbolType.EOF) {
|
||||
throw new ActionParseException("Parsing finished before end of the file", lexer.yyline());
|
||||
}
|
||||
if (targetSource instanceof BUTTONCONDACTION) {
|
||||
|
||||
@@ -64,3 +64,5 @@ configuration.removed = WARNING: This configuration was REMOVED. It is unused.
|
||||
|
||||
#after 24.0.1
|
||||
decompilationWarning.as2.noUninitializedClassFieldsDetection = WARNING: This class was decompiled without detecting uninitialized class fields.
|
||||
decompilationWarning.obfuscatedIdentifiers = WARNING: The original code has obfuscated identifiers.
|
||||
decompilationWarning.replacementsFollow = List of replacements follows:
|
||||
@@ -65,3 +65,5 @@ configuration.removed = VAROV\u00c1N\u00cd: Tato konfigurace byla ODSTRAN\u011aN
|
||||
|
||||
#after 24.0.1
|
||||
decompilationWarning.as2.noUninitializedClassFieldsDetection = VAROV\u00c1N\u00cd: Tato t\u0159\u00edda byla dekompilov\u00e1na bez detekce neinicializovan\u00fdch pol\u00ed t\u0159\u00edd.
|
||||
decompilationWarning.obfuscatedIdentifiers = VAROV\u00c1N\u00cd: P\u016fvodn\u00ed k\u00f3d m\u00e1 obfuskovan\u00e9 identifik\u00e1tory.
|
||||
decompilationWarning.replacementsFollow = N\u00e1sleduje seznam n\u00e1hrad:
|
||||
@@ -101,6 +101,11 @@ public class LocalData {
|
||||
* SWF version
|
||||
*/
|
||||
public int swfVersion;
|
||||
|
||||
private LocalData() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new local data
|
||||
|
||||
Reference in New Issue
Block a user