mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
js: fix deobfuscator, use new ES2015 module builder
This commit is contained in:
parent
055d5df367
commit
32ae1ab8f0
|
@ -151,6 +151,17 @@ final class JS {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> JSArray<T> wrap(T[] array) {
|
||||||
|
if (array == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var result = new JSArray<T>(array.length);
|
||||||
|
for (int i = 0; i < array.length; ++i) {
|
||||||
|
result.set(i, array[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public static <T extends JSObject> WrapFunction<T[], JSArray<T>> arrayWrapper() {
|
public static <T extends JSObject> WrapFunction<T[], JSArray<T>> arrayWrapper() {
|
||||||
return JS::wrap;
|
return JS::wrap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,7 @@ final class JSMethods {
|
||||||
String.class, JSObject.class);
|
String.class, JSObject.class);
|
||||||
|
|
||||||
public static final ValueType JS_OBJECT = ValueType.object(JSObject.class.getName());
|
public static final ValueType JS_OBJECT = ValueType.object(JSObject.class.getName());
|
||||||
|
public static final ValueType OBJECT = ValueType.object("java.lang.Object");
|
||||||
public static final ValueType JS_ARRAY = ValueType.object(JSArray.class.getName());
|
public static final ValueType JS_ARRAY = ValueType.object(JSArray.class.getName());
|
||||||
private static final MethodReference[] INVOKE_METHODS = new MethodReference[13];
|
private static final MethodReference[] INVOKE_METHODS = new MethodReference[13];
|
||||||
private static final MethodReference[] CONSTRUCT_METHODS = new MethodReference[13];
|
private static final MethodReference[] CONSTRUCT_METHODS = new MethodReference[13];
|
||||||
|
|
|
@ -205,8 +205,10 @@ class JSValueMarshaller {
|
||||||
} else if (type instanceof ValueType.Object) {
|
} else if (type instanceof ValueType.Object) {
|
||||||
if (type.isObject(String.class)) {
|
if (type.isObject(String.class)) {
|
||||||
return type;
|
return type;
|
||||||
} else {
|
} else if (typeHelper.isJavaScriptClass(((ValueType.Object) type).getClassName())) {
|
||||||
return JSMethods.JS_OBJECT;
|
return JSMethods.JS_OBJECT;
|
||||||
|
} else {
|
||||||
|
return JSMethods.OBJECT;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return type;
|
return type;
|
||||||
|
|
|
@ -18,9 +18,6 @@
|
||||||
|
|
||||||
let logging = false;
|
let logging = false;
|
||||||
let deobfuscation = false;
|
let deobfuscation = false;
|
||||||
if (typeof deobfuscator !== 'undefined') {
|
|
||||||
deobfuscator();
|
|
||||||
}
|
|
||||||
|
|
||||||
function tryConnect() {
|
function tryConnect() {
|
||||||
let ws = new WebSocket("ws://localhost:{{PORT}}/ws");
|
let ws = new WebSocket("ws://localhost:{{PORT}}/ws");
|
||||||
|
@ -82,7 +79,7 @@ function runSingleTest(test, callback) {
|
||||||
console.log("Running test " + test.name);
|
console.log("Running test " + test.name);
|
||||||
}
|
}
|
||||||
if (deobfuscation) {
|
if (deobfuscation) {
|
||||||
const fileName = test.file + ".teavmdbg";
|
const fileName = test.file.path + ".teavmdbg";
|
||||||
if (lastDeobfuscatorFile === fileName) {
|
if (lastDeobfuscatorFile === fileName) {
|
||||||
if (lastDeobfuscatorPromise === null) {
|
if (lastDeobfuscatorPromise === null) {
|
||||||
runSingleTestWithDeobfuscator(test, lastDeobfuscator, callback);
|
runSingleTestWithDeobfuscator(test, lastDeobfuscator, callback);
|
||||||
|
@ -100,7 +97,7 @@ function runSingleTest(test, callback) {
|
||||||
xhr.onreadystatechange = () => {
|
xhr.onreadystatechange = () => {
|
||||||
if (xhr.readyState === 4) {
|
if (xhr.readyState === 4) {
|
||||||
const newDeobfuscator = xhr.status === 200
|
const newDeobfuscator = xhr.status === 200
|
||||||
? deobfuscator.create(xhr.response, "http://localhost:{{PORT}}/" + test.file)
|
? createDeobfuscator(xhr.response, "http://localhost:{{PORT}}/" + test.file.path)
|
||||||
: null;
|
: null;
|
||||||
if (lastDeobfuscatorFile === fileName) {
|
if (lastDeobfuscatorFile === fileName) {
|
||||||
lastDeobfuscator = newDeobfuscator;
|
lastDeobfuscator = newDeobfuscator;
|
||||||
|
@ -139,7 +136,9 @@ function runSingleTestWithDeobfuscator(test, deobfuscator, callback) {
|
||||||
};
|
};
|
||||||
window.addEventListener("message", listener);
|
window.addEventListener("message", listener);
|
||||||
|
|
||||||
iframe.contentWindow.$rt_decodeStack = deobfuscator;
|
iframe.contentWindow.$rt_decodeStack = deobfuscator != null
|
||||||
|
? deobfuscator.deobfuscate.bind(deobfuscator)
|
||||||
|
: null;
|
||||||
iframe.contentWindow.postMessage(test, "*");
|
iframe.contentWindow.postMessage(test, "*");
|
||||||
};
|
};
|
||||||
window.addEventListener("message", handshakeListener);
|
window.addEventListener("message", handshakeListener);
|
||||||
|
|
|
@ -18,7 +18,10 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<script src="deobfuscator.js"></script>
|
<script type="module">
|
||||||
|
import { create } from './deobfuscator.js'
|
||||||
|
window.createDeobfuscator = create;
|
||||||
|
</script>
|
||||||
<script src="client.js"></script>
|
<script src="client.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -44,7 +44,8 @@ val generateJs by tasks.register<JavaExec>("generateJs") {
|
||||||
"org.teavm.tooling.deobfuscate.js.Deobfuscator",
|
"org.teavm.tooling.deobfuscate.js.Deobfuscator",
|
||||||
"\$teavm_deobfuscator",
|
"\$teavm_deobfuscator",
|
||||||
layout.buildDirectory.dir("teavm").get().asFile.absolutePath,
|
layout.buildDirectory.dir("teavm").get().asFile.absolutePath,
|
||||||
"deobfuscator.js"
|
"deobfuscator.js",
|
||||||
|
"none"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ val generateLibJs by tasks.register<JavaExec>("generateLibJs") {
|
||||||
"deobfuscator",
|
"deobfuscator",
|
||||||
layout.buildDirectory.dir("teavm-lib").get().asFile.absolutePath,
|
layout.buildDirectory.dir("teavm-lib").get().asFile.absolutePath,
|
||||||
"deobfuscator-lib.js",
|
"deobfuscator-lib.js",
|
||||||
|
"es2015"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.tooling.deobfuscate.js;
|
package org.teavm.tooling.deobfuscate.js;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import org.teavm.backend.javascript.JSModuleType;
|
||||||
import org.teavm.tooling.ConsoleTeaVMToolLog;
|
import org.teavm.tooling.ConsoleTeaVMToolLog;
|
||||||
import org.teavm.tooling.TeaVMProblemRenderer;
|
import org.teavm.tooling.TeaVMProblemRenderer;
|
||||||
import org.teavm.tooling.TeaVMTargetType;
|
import org.teavm.tooling.TeaVMTargetType;
|
||||||
|
@ -35,6 +36,7 @@ public final class Compiler {
|
||||||
tool.setEntryPointName(args[1]);
|
tool.setEntryPointName(args[1]);
|
||||||
tool.setTargetDirectory(new File(args[2]));
|
tool.setTargetDirectory(new File(args[2]));
|
||||||
tool.setTargetFileName(args[3]);
|
tool.setTargetFileName(args[3]);
|
||||||
|
tool.setJsModuleType(JSModuleType.valueOf(args[4].toUpperCase()));
|
||||||
tool.setObfuscated(true);
|
tool.setObfuscated(true);
|
||||||
tool.setOptimizationLevel(TeaVMOptimizationLevel.ADVANCED);
|
tool.setOptimizationLevel(TeaVMOptimizationLevel.ADVANCED);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ import org.teavm.debugging.information.DebugInformation;
|
||||||
import org.teavm.debugging.information.GeneratedLocation;
|
import org.teavm.debugging.information.GeneratedLocation;
|
||||||
import org.teavm.debugging.information.SourceLocation;
|
import org.teavm.debugging.information.SourceLocation;
|
||||||
import org.teavm.jso.JSBody;
|
import org.teavm.jso.JSBody;
|
||||||
|
import org.teavm.jso.JSClass;
|
||||||
|
import org.teavm.jso.JSExport;
|
||||||
import org.teavm.jso.ajax.XMLHttpRequest;
|
import org.teavm.jso.ajax.XMLHttpRequest;
|
||||||
import org.teavm.jso.core.JSArray;
|
import org.teavm.jso.core.JSArray;
|
||||||
import org.teavm.jso.core.JSObjects;
|
import org.teavm.jso.core.JSObjects;
|
||||||
|
@ -33,6 +35,7 @@ import org.teavm.jso.typedarrays.ArrayBuffer;
|
||||||
import org.teavm.jso.typedarrays.Int8Array;
|
import org.teavm.jso.typedarrays.Int8Array;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
@JSClass
|
||||||
public final class Deobfuscator {
|
public final class Deobfuscator {
|
||||||
private static final JSRegExp FRAME_PATTERN = new JSRegExp(""
|
private static final JSRegExp FRAME_PATTERN = new JSRegExp(""
|
||||||
+ "(^ +at ([^(]+) *\\((.+):([0-9]+):([0-9]+)\\) *$)|"
|
+ "(^ +at ([^(]+) *\\((.+):([0-9]+):([0-9]+)\\) *$)|"
|
||||||
|
@ -60,6 +63,7 @@ public final class Deobfuscator {
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JSExport
|
||||||
public Frame[] deobfuscate(String stack) {
|
public Frame[] deobfuscate(String stack) {
|
||||||
List<Frame> frames = new ArrayList<>();
|
List<Frame> frames = new ArrayList<>();
|
||||||
for (String line : splitLines(stack)) {
|
for (String line : splitLines(stack)) {
|
||||||
|
@ -125,14 +129,16 @@ public final class Deobfuscator {
|
||||||
decodedFileName = decodedFileName.substring(decodedFileName.lastIndexOf('/') + 1);
|
decodedFileName = decodedFileName.substring(decodedFileName.lastIndexOf('/') + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame frame = createEmptyFrame();
|
var javaLineNumber = -1;
|
||||||
frame.setClassName(method.getClassName());
|
|
||||||
frame.setMethodName(method.getName());
|
|
||||||
frame.setFileName(decodedFileName);
|
|
||||||
if (location != null) {
|
if (location != null) {
|
||||||
frame.setLineNumber(location.getLine());
|
javaLineNumber = location.getLine();
|
||||||
}
|
}
|
||||||
result.add(frame);
|
result.add(new Frame(
|
||||||
|
method.getClassName(),
|
||||||
|
method.getName(),
|
||||||
|
decodedFileName,
|
||||||
|
javaLineNumber
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
|
@ -143,12 +149,12 @@ public final class Deobfuscator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Frame createDefaultFrame(String fileName, String functionName, int lineNumber) {
|
private static Frame createDefaultFrame(String fileName, String functionName, int lineNumber) {
|
||||||
Frame frame = createEmptyFrame();
|
return new Frame(
|
||||||
frame.setFileName(fileName);
|
"<JS>",
|
||||||
frame.setMethodName(functionName != null ? functionName : "<unknown function>");
|
functionName != null ? functionName : "<unknown function>",
|
||||||
frame.setClassName("<JS>");
|
fileName,
|
||||||
frame.setLineNumber(lineNumber);
|
lineNumber
|
||||||
return frame;
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String[] splitLines(String text) {
|
private static String[] splitLines(String text) {
|
||||||
|
@ -165,9 +171,6 @@ public final class Deobfuscator {
|
||||||
return result.toArray(new String[0]);
|
return result.toArray(new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@JSBody(script = "return {};")
|
|
||||||
private static native Frame createEmptyFrame();
|
|
||||||
|
|
||||||
@JSBody(params = "f", script = "window.$rt_decodeStack = f;")
|
@JSBody(params = "f", script = "window.$rt_decodeStack = f;")
|
||||||
private static native void setDeobfuscateFunction(DeobfuscateFunction f);
|
private static native void setDeobfuscateFunction(DeobfuscateFunction f);
|
||||||
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Alexey Andreev.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.teavm.tooling.deobfuscate.js;
|
|
||||||
|
|
||||||
import org.teavm.jso.JSObject;
|
|
||||||
import org.teavm.jso.typedarrays.ArrayBuffer;
|
|
||||||
|
|
||||||
public interface DeobfuscatorJs extends JSObject {
|
|
||||||
DeobfuscateFunction create(ArrayBuffer buffer, String classesFileName);
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,31 +16,20 @@
|
||||||
package org.teavm.tooling.deobfuscate.js;
|
package org.teavm.tooling.deobfuscate.js;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import org.teavm.jso.JSBody;
|
import org.teavm.jso.JSExport;
|
||||||
import org.teavm.jso.typedarrays.ArrayBuffer;
|
import org.teavm.jso.typedarrays.ArrayBuffer;
|
||||||
|
|
||||||
public final class DeobfuscatorLib implements DeobfuscatorJs {
|
public final class DeobfuscatorLib {
|
||||||
private DeobfuscatorLib() {
|
private DeobfuscatorLib() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@JSExport
|
||||||
public DeobfuscateFunction create(ArrayBuffer buffer, String classesFileName) {
|
public static Deobfuscator create(ArrayBuffer buffer, String classesFileName) {
|
||||||
try {
|
try {
|
||||||
return new Deobfuscator(buffer, classesFileName)::deobfuscate;
|
return new Deobfuscator(buffer, classesFileName);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
install(new DeobfuscatorLib());
|
|
||||||
}
|
|
||||||
|
|
||||||
@JSBody(params = "instance", script =
|
|
||||||
"deobfuscator.create = function(buffer, classesFileName) {"
|
|
||||||
+ "return instance.create(buffer, classesFileName);"
|
|
||||||
+ "}"
|
|
||||||
)
|
|
||||||
private static native void install(DeobfuscatorJs js);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,19 +15,43 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.tooling.deobfuscate.js;
|
package org.teavm.tooling.deobfuscate.js;
|
||||||
|
|
||||||
import org.teavm.jso.JSObject;
|
import org.teavm.jso.JSExport;
|
||||||
import org.teavm.jso.JSProperty;
|
import org.teavm.jso.JSProperty;
|
||||||
|
|
||||||
public interface Frame extends JSObject {
|
public class Frame {
|
||||||
@JSProperty
|
private String className;
|
||||||
void setClassName(String className);
|
private String fileName;
|
||||||
|
private String methodName;
|
||||||
|
private int lineNumber;
|
||||||
|
|
||||||
@JSProperty
|
public Frame(String className, String methodName, String fileName, int lineNumber) {
|
||||||
void setFileName(String fileName);
|
this.className = className;
|
||||||
|
this.methodName = methodName;
|
||||||
|
this.fileName = fileName;
|
||||||
|
this.lineNumber = lineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSExport
|
||||||
@JSProperty
|
@JSProperty
|
||||||
void setMethodName(String methodName);
|
public String getClassName() {
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSExport
|
||||||
@JSProperty
|
@JSProperty
|
||||||
void setLineNumber(int lineNumber);
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSExport
|
||||||
|
@JSProperty
|
||||||
|
public String getMethodName() {
|
||||||
|
return methodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSExport
|
||||||
|
@JSProperty
|
||||||
|
public int getLineNumber() {
|
||||||
|
return lineNumber;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user