mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 20:31:01 +00:00
Issue #153 Better deobfuscation
This commit is contained in:
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (C) 2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.ecma;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class EcmaScript {
|
||||
|
||||
public static Double toNumber(Object o) {
|
||||
if (o == null) {
|
||||
return 0.0;
|
||||
}
|
||||
if (o instanceof Undefined) {
|
||||
return Double.NaN;
|
||||
}
|
||||
if (o instanceof Null) {
|
||||
return 0.0;
|
||||
}
|
||||
if (o instanceof Boolean) {
|
||||
return (Boolean) o ? 1.0 : 0.0;
|
||||
}
|
||||
if (o instanceof Double) {
|
||||
return (Double) o;
|
||||
}
|
||||
if (o instanceof Long) {
|
||||
return (double) (long) (Long) o;
|
||||
}
|
||||
if (o instanceof Integer) {
|
||||
return (double) (int) (Integer) o;
|
||||
}
|
||||
if (o instanceof String) {
|
||||
try {
|
||||
return Double.parseDouble((String) o);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return Double.NaN;
|
||||
}
|
||||
}
|
||||
//TODO:ToPrimitive
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public static EcmaType type(Object o) {
|
||||
if (o == null) {
|
||||
return EcmaType.NULL;
|
||||
}
|
||||
if (o.getClass() == String.class) {
|
||||
return EcmaType.STRING;
|
||||
}
|
||||
if (o.getClass() == Integer.class) {
|
||||
return EcmaType.NUMBER;
|
||||
}
|
||||
if (o.getClass() == Double.class) {
|
||||
return EcmaType.NUMBER;
|
||||
}
|
||||
if (o.getClass() == Long.class) {
|
||||
return EcmaType.NUMBER;
|
||||
}
|
||||
|
||||
if (o.getClass() == Null.class) {
|
||||
return EcmaType.NULL;
|
||||
}
|
||||
if (o.getClass() == Undefined.class) {
|
||||
return EcmaType.UNDEFINED;
|
||||
}
|
||||
return EcmaType.OBJECT;
|
||||
}
|
||||
|
||||
public static Object compare(Object x, Object y) {
|
||||
Object px = x;
|
||||
Object py = y;
|
||||
/*if (leftFirst) {
|
||||
px = x; //toPrimitive
|
||||
py = y; //toPrimitive
|
||||
} else {
|
||||
py = y; //toPrimitive
|
||||
px = x; //toPrimitive
|
||||
}*/
|
||||
if (type(px) != EcmaType.STRING || type(py) != EcmaType.STRING) {
|
||||
Double nx = toNumber(px);
|
||||
Double ny = toNumber(py);
|
||||
if (nx.isNaN()) {
|
||||
return new Undefined();
|
||||
}
|
||||
if (ny.isNaN()) {
|
||||
return new Undefined();
|
||||
}
|
||||
if (((Double) nx).compareTo((Double) ny) == 0) {
|
||||
return false;
|
||||
}
|
||||
if ((Double.compare((Double) nx, -0.0) == 0) && (Double.compare((Double) ny, 0.0) == 0)) {
|
||||
return false;
|
||||
}
|
||||
if ((Double.compare((Double) nx, 0.0) == 0) && (Double.compare((Double) ny, -0.0) == 0)) {
|
||||
return false;
|
||||
}
|
||||
if (nx.isInfinite() && nx > 0) {
|
||||
return false;
|
||||
}
|
||||
if (ny.isInfinite() && ny > 0) {
|
||||
return true;
|
||||
}
|
||||
if (nx.isInfinite() && nx < 0) {
|
||||
return false;
|
||||
}
|
||||
if (ny.isInfinite() && ny < 0) {
|
||||
return true;
|
||||
}
|
||||
if (nx.compareTo(ny) < 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else {//Both are STRING
|
||||
String sx = (String) px;
|
||||
String sy = (String) py;
|
||||
|
||||
if (sx.startsWith(sy)) {
|
||||
return false;
|
||||
}
|
||||
if (sy.startsWith(sx)) {
|
||||
return true;
|
||||
}
|
||||
int len = sx.length() > sy.length() ? sx.length() : sy.length();
|
||||
for (int k = 0; k < len; k++) {
|
||||
int m = 0;
|
||||
int n = 0;
|
||||
if (sx.length() > k) {
|
||||
m = sx.charAt(k);
|
||||
}
|
||||
if (sy.length() > k) {
|
||||
n = sy.charAt(k);
|
||||
}
|
||||
if (m != n) {
|
||||
if (m < n) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean equals(Object x, Object y) {
|
||||
EcmaType typeX = type(x);
|
||||
EcmaType typeY = type(y);
|
||||
if (typeX == typeY) {
|
||||
if (typeX == null) {
|
||||
return true;
|
||||
}
|
||||
if (typeX == EcmaType.NULL) {
|
||||
return true;
|
||||
}
|
||||
if (typeX == EcmaType.UNDEFINED) {
|
||||
return true;
|
||||
}
|
||||
if (typeX == EcmaType.NUMBER) {
|
||||
if (x instanceof Integer) {
|
||||
x = Double.valueOf((Integer) x);
|
||||
}
|
||||
if (x instanceof Long) {
|
||||
x = Double.valueOf((Long) x);
|
||||
}
|
||||
if (y instanceof Integer) {
|
||||
y = Double.valueOf((Integer) y);
|
||||
}
|
||||
if (y instanceof Long) {
|
||||
y = Double.valueOf((Long) y);
|
||||
}
|
||||
if (((Double) x).isNaN()) {
|
||||
return false;
|
||||
}
|
||||
if (((Double) y).isNaN()) {
|
||||
return false;
|
||||
}
|
||||
if (((Double) x).compareTo((Double) y) == 0) {
|
||||
return true;
|
||||
}
|
||||
if ((Double.compare((Double) x, -0.0) == 0) && (Double.compare((Double) y, 0.0) == 0)) {
|
||||
return true;
|
||||
}
|
||||
if ((Double.compare((Double) x, 0.0) == 0) && (Double.compare((Double) y, -0.0) == 0)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (typeX == EcmaType.STRING) {
|
||||
return ((String) x).equals((String) y);
|
||||
}
|
||||
if (typeX == EcmaType.BOOLEAN) {
|
||||
return x == y;
|
||||
}
|
||||
return x == y;
|
||||
}
|
||||
if ((typeX == EcmaType.NULL) && (typeY == EcmaType.UNDEFINED)) {
|
||||
return true;
|
||||
}
|
||||
if ((typeX == EcmaType.UNDEFINED) && (typeY == EcmaType.NULL)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((typeX == EcmaType.NUMBER) && (typeY == EcmaType.STRING)) {
|
||||
return equals(x, toNumber(y));
|
||||
}
|
||||
if ((typeX == EcmaType.STRING) && (typeY == EcmaType.NUMBER)) {
|
||||
return equals(toNumber(x), y);
|
||||
}
|
||||
if (typeX == EcmaType.BOOLEAN) {
|
||||
return equals(toNumber(x), y);
|
||||
}
|
||||
if (typeY == EcmaType.BOOLEAN) {
|
||||
return equals(x, toNumber(y));
|
||||
}
|
||||
if (typeX == EcmaType.STRING || typeX == EcmaType.NUMBER) {
|
||||
//y is object
|
||||
//return ecmaEquals(ecmaToPrimitive(x), y);
|
||||
}
|
||||
if (typeY == EcmaType.STRING || typeY == EcmaType.NUMBER) {
|
||||
//x is object
|
||||
//return ecmaEquals(x, ecmaToPrimitive(y));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean toBoolean(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
if (o instanceof Undefined) {
|
||||
return false;
|
||||
}
|
||||
if (o instanceof Null) {
|
||||
return false;
|
||||
}
|
||||
if (o instanceof Boolean) {
|
||||
return (Boolean) o;
|
||||
}
|
||||
if (o instanceof Long) {
|
||||
return ((Long) o) != 0;
|
||||
}
|
||||
if (o instanceof Integer) {
|
||||
return ((Integer) o) != 0;
|
||||
}
|
||||
if (o instanceof Double) {
|
||||
Double d = (Double) o;
|
||||
if (d.isNaN()) {
|
||||
return false;
|
||||
}
|
||||
if (Double.compare(d, 0) == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (o instanceof String) {
|
||||
String s = (String) o;
|
||||
return !s.equals("");
|
||||
}
|
||||
return true; //other Object
|
||||
}
|
||||
|
||||
public static Long toUint32(Object o) {
|
||||
Double n = toNumber(o);
|
||||
if (n.isNaN()) {
|
||||
return 0L;
|
||||
}
|
||||
if (Double.compare(n, 0.0) == 0) {
|
||||
return 0L;
|
||||
}
|
||||
if (Double.compare(n, -0.0) == 0) {
|
||||
return 0L;
|
||||
}
|
||||
if (Double.isInfinite(n)) {
|
||||
return 0L;
|
||||
}
|
||||
Long posInt = (long) (double) (Math.signum(n) * Math.floor(Math.abs(n)));
|
||||
posInt = posInt % (1 << 32);
|
||||
return posInt;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user