- AS1 slash syntax support (decompilation, direct editation)

- AS1/2 Using eval, set functions on obfuscated names instead of §§ syntax where applicable
This commit is contained in:
Jindra Petřík
2018-05-27 16:52:55 +02:00
parent 6ec124f71a
commit d138c61072
21 changed files with 2408 additions and 2521 deletions
@@ -238,6 +238,46 @@ public class IdentifiersDeobfuscation {
return null;
}
private static boolean isValidSlashPath(String s, String... exceptions) {
String[] slashParts = s.split("\\/");
if (s.isEmpty()) {
return false;
}
for (int p = 0; p < slashParts.length; p++) {
String part = slashParts[p];
if (p == 0 && part.isEmpty()) {
continue;
}
if (part.isEmpty() && p < slashParts.length - 1) { // two slashesh xx//yy
return false;
}
if ("..".equals(part)) {
continue; //okay
}
if (!isValidName(false, part, exceptions)) {
return false;
}
}
return true;
}
public static boolean isValidNameWithSlash(String s, String... exceptions) {
if (s.contains(":")) {
String pathVar[] = s.split(":");
if (!isValidSlashPath(pathVar[0], exceptions)) {
return false;
}
for (int i = 1; i < pathVar.length; i++) {
if (!isValidName(false, pathVar[i], exceptions)) {
return false;
}
}
return true;
} else {
return isValidName(false, s, exceptions);
}
}
public static boolean isValidNameWithDot(boolean as3, String s, String... exceptions) {
for (String e : exceptions) {
if (e.equals(s)) {
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.action.model;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
@@ -60,7 +61,14 @@ public class CallFunctionActionItem extends ActionItem {
srcData.localName = functionName.toStringNoQuotes(localData);
if (functionName instanceof DirectValueActionItem) {
writer.append(IdentifiersDeobfuscation.printIdentifier(false, (functionName).toStringNoQuotes(localData)));
if (!IdentifiersDeobfuscation.isValidName(false, (functionName).toStringNoQuotes(localData))) {
writer.append("eval(");
functionName.toString(writer, localData);
writer.append(")");
} else {
functionName.toStringNoQuotes(writer, localData);
}
//writer.append(IdentifiersDeobfuscation.printIdentifier(false, (functionName).toStringNoQuotes(localData)));
} else {
functionName.appendTry(writer, localData);
}
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.action.model;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
@@ -57,8 +58,20 @@ public class GetPropertyActionItem extends ActionItem {
if (isEmptyString(target)) {
return writer.append(Action.propertyNames[propertyIndex]);
}
target.toString(writer, localData);
return writer.append(".").append(Action.propertyNames[propertyIndex]);
if ((target instanceof DirectValueActionItem) && ((DirectValueActionItem) target).isString()) {
target.toStringNoQuotes(writer, localData);
return writer.append(":" + Action.propertyNames[propertyIndex]);
}
writer.append("getProperty");
writer.spaceBeforeCallParenthesies(2);
writer.append("(");
target.appendTo(writer, localData);
writer.append(", ");
writer.append(Action.propertyNames[propertyIndex]);
writer.append(")");
return writer;
}
@Override
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.action.model;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
@@ -66,20 +67,17 @@ public class GetVariableActionItem extends ActionItem {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
if (((name instanceof DirectValueActionItem)) && (((DirectValueActionItem) name).isString()) && (!IdentifiersDeobfuscation.isValidNameWithDot(false, ((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super"))) {
if ((name instanceof DirectValueActionItem) && (((DirectValueActionItem) name).isString()) && (IdentifiersDeobfuscation.isValidNameWithDot(false, ((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super")
|| IdentifiersDeobfuscation.isValidNameWithSlash(((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super"))) {
HighlightData srcData = getSrcData();
srcData.localName = name.toStringNoQuotes(localData);
return IdentifiersDeobfuscation.appendObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData), writer);
} else if ((!(name instanceof DirectValueActionItem)) || (!((DirectValueActionItem) name).isString())) {
return stripQuotes(name, localData, writer);
} else {
writer.append("eval(");
name.appendTry(writer, localData);
return writer.append(")");
}
HighlightData srcData = getSrcData();
srcData.localName = name.toStringNoQuotes(localData);
return stripQuotes(name, localData, writer);
//IdentifiersDeobfuscation.appendObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData), writer);
}
@Override
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.action.model;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
@@ -81,9 +82,23 @@ public class SetPropertyActionItem extends ActionItem implements SetTypeActionIt
writer.append(Action.propertyNames[propertyIndex]).append(" = ");
return value.toString(writer, localData);
}
target.toString(writer, localData);
writer.append("." + Action.propertyNames[propertyIndex]).append(" = ");
return value.toString(writer, localData);
if ((target instanceof DirectValueActionItem) && ((DirectValueActionItem) target).isString()) {
target.toStringNoQuotes(writer, localData);
writer.append(":" + Action.propertyNames[propertyIndex]).append(" = ");
return value.toString(writer, localData);
}
writer.append("setProperty");
writer.spaceBeforeCallParenthesies(3);
writer.append("(");
target.appendTo(writer, localData);
writer.append(", ");
writer.append(Action.propertyNames[propertyIndex]);
writer.append(", ");
value.appendTo(writer, localData);
writer.append(")");
return writer;
}
@Override
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.action.model;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
@@ -76,14 +77,15 @@ public class SetVariableActionItem extends ActionItem implements SetTypeActionIt
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
if (((name instanceof DirectValueActionItem)) && (((DirectValueActionItem) name).isString()) && (!IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super"))) {
if (((name instanceof DirectValueActionItem)) && (((DirectValueActionItem) name).isString())
&& (IdentifiersDeobfuscation.isValidName(false, ((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super")
|| IdentifiersDeobfuscation.isValidNameWithSlash(((DirectValueActionItem) name).toStringNoQuotes(localData), "this", "super"))) {
HighlightData srcData = getSrcData();
srcData.localName = name.toStringNoQuotes(localData);
IdentifiersDeobfuscation.appendObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData), writer);
stripQuotes(name, localData, writer);
writer.append(" = ");
return value.toString(writer, localData);
} else if ((!(name instanceof DirectValueActionItem)) || (!((DirectValueActionItem) name).isString())) {
} else {
writer.append("set");
writer.spaceBeforeCallParenthesies(2);
writer.append("(");
@@ -92,12 +94,7 @@ public class SetVariableActionItem extends ActionItem implements SetTypeActionIt
value.toString(writer, localData);
return writer.append(")");
}
HighlightData srcData = getSrcData();
srcData.localName = name.toStringNoQuotes(localData);
stripQuotes(name, localData, writer);
writer.append(" = ");
return value.toString(writer, localData);
//IdentifiersDeobfuscation.appendObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData), writer);
}
@Override
@@ -33,6 +33,7 @@ import com.jpexs.decompiler.flash.action.model.EvalActionItem;
import com.jpexs.decompiler.flash.action.model.FSCommandActionItem;
import com.jpexs.decompiler.flash.action.model.FunctionActionItem;
import com.jpexs.decompiler.flash.action.model.GetMemberActionItem;
import com.jpexs.decompiler.flash.action.model.GetPropertyActionItem;
import com.jpexs.decompiler.flash.action.model.GetTimeActionItem;
import com.jpexs.decompiler.flash.action.model.GetURL2ActionItem;
import com.jpexs.decompiler.flash.action.model.GetVariableActionItem;
@@ -63,6 +64,7 @@ import com.jpexs.decompiler.flash.action.model.RandomNumberActionItem;
import com.jpexs.decompiler.flash.action.model.RemoveSpriteActionItem;
import com.jpexs.decompiler.flash.action.model.ReturnActionItem;
import com.jpexs.decompiler.flash.action.model.SetMemberActionItem;
import com.jpexs.decompiler.flash.action.model.SetPropertyActionItem;
import com.jpexs.decompiler.flash.action.model.SetVariableActionItem;
import com.jpexs.decompiler.flash.action.model.StartDragActionItem;
import com.jpexs.decompiler.flash.action.model.StopActionItem;
@@ -1784,10 +1786,18 @@ public class ActionScript2Parser {
case IDENTIFIER:
case THIS:
case SUPER:
case PATH:
if (s.value.equals("not")) {
ret = new NotItem(null, null, expressionPrimary(false, inFunction, inMethod, false, variables, functions));
} else {
ret = new VariableActionItem(s.value.toString(), null, false);
if (s.type == SymbolType.PATH) {
expectedType(SymbolType.COLON);
ParsedSymbol s2 = lex();
expected(s2, lexer.yyline(), SymbolType.IDENTIFIER);
ret = new VariableActionItem(s.value.toString() + ":" + s2.value.toString(), null, false);
} else {
ret = new VariableActionItem(s.value.toString(), null, false);
}
variables.add((VariableActionItem) ret);
allowMemberOrCall = true;
}
@@ -1877,10 +1887,34 @@ public class ActionScript2Parser {
for (VariableActionItem v : vars) {
String varName = v.getVariableName();
GraphTargetItem stored = v.getStoreValue();
int propIndex = -1;
boolean hasSubVars = false;
if (varName.contains(":")) {
hasSubVars = true;
String lowerNameStr = varName.toLowerCase();
for (int p = 0; p < Action.propertyNames.length; p++) {
String prop = Action.propertyNames[p];
if (lowerNameStr.endsWith(":" + prop.toLowerCase())) {
propIndex = p;
varName = varName.substring(0, varName.lastIndexOf(":"));
break;
}
}
}
if (v.isDefinition()) {
if (hasSubVars) {
throw new ActionParseException("Invalid : character in variable definition", lexer.yyline());
}
v.setBoxedValue(new DefineLocalActionItem(null, null, pushConst(varName), stored));
} else if (stored != null) {
v.setBoxedValue(new SetVariableActionItem(null, null, pushConst(varName), stored));
if (propIndex > -1) {
v.setBoxedValue(new SetPropertyActionItem(null, null, pushConst(varName), propIndex, stored));
} else {
v.setBoxedValue(new SetVariableActionItem(null, null, pushConst(varName), stored));
}
} else if (propIndex > -1) {
v.setBoxedValue(new GetPropertyActionItem(null, null, pushConst(varName), propIndex));
} else {
v.setBoxedValue(new GetVariableActionItem(null, null, pushConst(varName)));
}
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.action.parser.script;
/**
@@ -25,7 +26,6 @@ public enum SymbolGroup {
KEYWORD,
STRING,
COMMENT,
XML,
IDENTIFIER,
INTEGER,
DOUBLE,
@@ -33,5 +33,6 @@ public enum SymbolGroup {
EOF,
GLOBALFUNC,
GLOBALCONST,
PREPROCESSOR
PREPROCESSOR,
PATH
}
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.action.parser.script;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -129,7 +130,6 @@ public enum SymbolType {
//Other
STRING(GraphTargetItem.PRECEDENCE_PRIMARY, false),
COMMENT,
XML,
IDENTIFIER(GraphTargetItem.PRECEDENCE_PRIMARY, false),
INTEGER(GraphTargetItem.PRECEDENCE_PRIMARY, false),
DOUBLE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
@@ -183,7 +183,8 @@ public enum SymbolType {
UNLOADMOVIE(GraphTargetItem.PRECEDENCE_PRIMARY, false),
UNLOADMOVIENUM(GraphTargetItem.PRECEDENCE_PRIMARY, false),
FSCOMMAND(GraphTargetItem.PRECEDENCE_PRIMARY, false),
PREPROCESSOR(GraphTargetItem.PRECEDENCE_PRIMARY, false);
PREPROCESSOR(GraphTargetItem.PRECEDENCE_PRIMARY, false),
PATH(GraphTargetItem.PRECEDENCE_PRIMARY, false);
private int precedence = GraphTargetItem.NOPRECEDENCE;