mirror of
https://github.com/sirjonasxx/G-Wasm.git
synced 2024-11-26 18:30:52 +01:00
everything
This commit is contained in:
parent
63c94891bc
commit
9dbf50c7e1
@ -1,9 +1,15 @@
|
||||
package wasm;
|
||||
|
||||
import wasm.disassembly.InvalidOpCodeException;
|
||||
import wasm.disassembly.instructions.Expression;
|
||||
import wasm.disassembly.instructions.Instr;
|
||||
import wasm.disassembly.instructions.InstrType;
|
||||
import wasm.disassembly.instructions.misc.SingleByteInstr;
|
||||
import wasm.disassembly.modules.Module;
|
||||
import wasm.disassembly.modules.indices.FuncIdx;
|
||||
import wasm.disassembly.modules.indices.TypeIdx;
|
||||
import wasm.disassembly.modules.sections.code.Func;
|
||||
import wasm.disassembly.modules.sections.code.Locals;
|
||||
import wasm.disassembly.modules.sections.export.Export;
|
||||
import wasm.disassembly.modules.sections.export.ExportDesc;
|
||||
import wasm.disassembly.modules.sections.imprt.Import;
|
||||
@ -11,74 +17,19 @@ import wasm.disassembly.modules.sections.imprt.ImportDesc;
|
||||
import wasm.disassembly.types.FuncType;
|
||||
import wasm.disassembly.types.ResultType;
|
||||
import wasm.disassembly.types.ValType;
|
||||
import wasm.misc.CodeCompare;
|
||||
import wasm.misc.Function;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GWasm {
|
||||
|
||||
public static void extractMethods(Module module) {
|
||||
// List<TypeIdx> typesFromImports = new ArrayList<>();
|
||||
// for (Import imp : module.getImportSection().getImports()) {
|
||||
// if (imp.getImportDescription().getImportType() == 0) {
|
||||
// typesFromImports.add((TypeIdx)imp.getImportDescription().getImportValue());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// List<Export> exportList = module.getExportSection().getExports();
|
||||
// for(Export export : exportList) {
|
||||
// ExportDesc desc = export.getExportDesc();
|
||||
// if (desc.getExportType() == 0) {
|
||||
// FuncIdx funcIdx = (FuncIdx) desc.getExportValue();
|
||||
// TypeIdx typeIdx;
|
||||
// if (funcIdx.getX() < typesFromImports.size()) {
|
||||
// typeIdx = typesFromImports.get((int)(funcIdx.getX()));
|
||||
// }
|
||||
// else {
|
||||
// typeIdx = module.getFunctionSection().getTypeIdxVector().get((int)(funcIdx.getX()) - typesFromImports.size());
|
||||
// }
|
||||
// FuncType funcType = module.getTypeSection().getFunctionTypes().get((int)(typeIdx.getX()));
|
||||
//
|
||||
// System.out.println(String.format("%s ::= %s -> %s",
|
||||
// export.getName(),
|
||||
// "(" + funcType.getParameterType().typeList().stream().map(Enum::name).collect(Collectors.joining(" ")) + ")",
|
||||
// "(" + funcType.getResultType().typeList().stream().map(Enum::name).collect(Collectors.joining(" ")) + ")"
|
||||
// ));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException, InvalidOpCodeException {
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
Module module = new Module("C:\\Users\\jonas\\Desktop\\Projects\\Jznnp\\S\\habbo2020\\rawfiles\\0.6.0_(7)\\habbo2020-global-prod.wasm.code.unityweb",
|
||||
new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
|
||||
long end = System.currentTimeMillis();
|
||||
|
||||
System.out.println("Assembly time: " + (end - start));
|
||||
|
||||
// extractMethods(module);
|
||||
//
|
||||
// module.getImportSection().importFunctions(Collections.singletonList(
|
||||
// new Import(
|
||||
// "env",
|
||||
// "consoleLog",
|
||||
// new ImportDesc(module.getTypeSection().getTypeIdxForFuncType(new FuncType(
|
||||
// new ResultType(Collections.singletonList(ValType.I32)),
|
||||
// new ResultType(Collections.emptyList())
|
||||
// )))
|
||||
// )
|
||||
// ));
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
module.assembleToFile("C:\\Users\\jonas\\Desktop\\Projects\\Jznnp\\S\\habbo2020\\rawfiles\\0.6.0_(7)\\out\\habbo2020-global-prod.wasm.code.unityweb");
|
||||
end = System.currentTimeMillis();
|
||||
|
||||
System.out.println("Disassembly time: " + (end - start));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,9 @@ import wasm.disassembly.modules.sections.start.StartSection;
|
||||
import wasm.disassembly.modules.sections.table.TableSection;
|
||||
import wasm.disassembly.modules.sections.type.TypeSection;
|
||||
import wasm.disassembly.types.FuncType;
|
||||
import wasm.misc.CodeCompare;
|
||||
import wasm.misc.Function;
|
||||
import wasm.misc.StreamReplacement;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
@ -44,37 +46,11 @@ public class Module extends WASMOpCode {
|
||||
|
||||
private List<List<CustomSection>> customSectionsList;
|
||||
|
||||
// ACTION TAKEN TO MINIMIZE MEM USAGE:
|
||||
// everything in the function section (3) will be (on-the-go) assembled into 1 byte array
|
||||
// same for element section (9)
|
||||
// same for code section (10)
|
||||
// same for data section (11)
|
||||
|
||||
// APPROACH:
|
||||
// (1) import section - add imports in front of import section. (remember funcidx)
|
||||
// Every matched FuncIdx will go +len(newImports)
|
||||
// In code, take action if needed, and cache the functions that need copying
|
||||
// Add cached functions to the end, remember their FuncIdx
|
||||
// Export section - add the 3 funcidx
|
||||
public final List<StreamReplacement> streamReplacements;
|
||||
|
||||
|
||||
|
||||
// actiontaken = decides what to do with matches from "searchFunctions",
|
||||
// * if 0: calls function with same index in newImports
|
||||
// * if 1-Y: calls function with same index in newImports, clears the rest of the function,
|
||||
// copies the function and exports the copy to name Y
|
||||
|
||||
public final List<Import> newImports;
|
||||
public final List<Function> searchFunctions;
|
||||
public final List<String> actionTaken;
|
||||
public final List<FuncType> newImportsFuncTypes;
|
||||
|
||||
|
||||
public Module(BufferedInputStream in, List<Import> newImports, List<FuncType> newImportsFuncTypes, List<Function> searchFunctions, List<String> actionTaken) throws IOException, InvalidOpCodeException {
|
||||
this.newImports = newImports;
|
||||
this.searchFunctions = searchFunctions;
|
||||
this.actionTaken = actionTaken;
|
||||
this.newImportsFuncTypes = newImportsFuncTypes;
|
||||
public Module(BufferedInputStream in, List<StreamReplacement> streamReplacements) throws IOException, InvalidOpCodeException {
|
||||
this.streamReplacements = streamReplacements;
|
||||
|
||||
customSectionsList = new ArrayList<>();
|
||||
|
||||
@ -104,12 +80,13 @@ public class Module extends WASMOpCode {
|
||||
disassembleCustomSections(in);
|
||||
dataSection = isNextSection(in, 11) ? new DataSection(in, this) : null;
|
||||
disassembleCustomSections(in);
|
||||
exportSection.addShittyExports(this);
|
||||
|
||||
in.close();
|
||||
}
|
||||
|
||||
public Module(String fileName, List<Import> newImports, List<FuncType> newImportsFuncTypes, List<Function> searchFunctions, List<String> actionTaken) throws IOException, InvalidOpCodeException {
|
||||
this(new BufferedInputStream(new FileInputStream(new File(fileName))), newImports, newImportsFuncTypes, searchFunctions, actionTaken);
|
||||
public Module(String fileName, List<StreamReplacement> streamReplacements) throws IOException, InvalidOpCodeException {
|
||||
this(new BufferedInputStream(new FileInputStream(new File(fileName))), streamReplacements);
|
||||
}
|
||||
|
||||
private void disassembleCustomSections(BufferedInputStream in) throws IOException, InvalidOpCodeException {
|
||||
|
@ -22,7 +22,7 @@ public class FuncIdx extends WASMOpCode {
|
||||
|
||||
public FuncIdx(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||
x = WUnsignedInt.read(in, 32)
|
||||
+ module.newImports.size();
|
||||
+ module.streamReplacements.size();
|
||||
|
||||
|
||||
// ref = CodeSection.currentI; // debugging purpose
|
||||
|
@ -39,7 +39,6 @@ public abstract class Section extends WASMOpCode {
|
||||
ByteArrayOutputStream fakeOutputStream = new ByteArrayOutputStream();
|
||||
assemble2(fakeOutputStream);
|
||||
byte[] asbytes = fakeOutputStream.toByteArray();
|
||||
System.out.println("section + " + sectionId + ", size: " + asbytes.length);
|
||||
WUnsignedInt.write(asbytes.length, out, 32);
|
||||
fakeOutputStream.close();
|
||||
out.write(asbytes);
|
||||
|
@ -14,7 +14,9 @@ import wasm.disassembly.modules.indices.LocalIdx;
|
||||
import wasm.disassembly.modules.sections.Section;
|
||||
import wasm.disassembly.modules.sections.data.Data;
|
||||
import wasm.disassembly.values.WUnsignedInt;
|
||||
import wasm.misc.CodeCompare;
|
||||
import wasm.misc.Function;
|
||||
import wasm.misc.StreamReplacement;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@ -38,7 +40,7 @@ public class CodeSection extends Section {
|
||||
super(in, module, CODE_SECTION_ID);
|
||||
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
Code[] copies = new Code[module.searchFunctions.size()];
|
||||
Code[] copies = new Code[module.streamReplacements.size()];
|
||||
|
||||
// codesEntries = new Vector<>(in, Code::new, module);
|
||||
length = WUnsignedInt.read(in, 32);
|
||||
@ -47,47 +49,37 @@ public class CodeSection extends Section {
|
||||
|
||||
|
||||
Func func = code.getCode();
|
||||
for (int j = 0; j < module.searchFunctions.size(); j++) {
|
||||
for (int j = 0; j < module.streamReplacements.size(); j++) {
|
||||
|
||||
if (module.getFunctionSection().matchesSearchFunctionsTypes.get(j).contains(i)) {
|
||||
Function search = module.searchFunctions.get(j);
|
||||
if (func.getLocalss().equals(search.getLocals()) && func.getExpression().getInstructions().size() == search.getCode().getInstructions().size()) {
|
||||
CodeCompare comparer = module.streamReplacements.get(j).getCodeCompare();
|
||||
|
||||
boolean failed = false;
|
||||
for (int k = 0; k < func.getExpression().getInstructions().size(); k++) {
|
||||
Instr instr = func.getExpression().getInstructions().get(k);
|
||||
Instr instr2 = search.getCode().getInstructions().get(k);
|
||||
if (instr.getInstrType() != instr2.getInstrType()) {
|
||||
failed = true;
|
||||
break;
|
||||
if (comparer.isEqual(func)) {
|
||||
StreamReplacement.ReplacementType actionTaken = module.streamReplacements.get(j).getReplacementType();
|
||||
if (actionTaken == StreamReplacement.ReplacementType.HOOK) {
|
||||
CallInstr call = new CallInstr(new FuncIdx(j, module));
|
||||
|
||||
List<Instr> newInstrs = new ArrayList<>();
|
||||
for (int k = 0; k < module.streamReplacements.get(j).getFuncType().getParameterType().typeList().size(); k++) {
|
||||
newInstrs.add(new LocalVariableInstr(InstrType.LOCAL_GET, new LocalIdx(k)));
|
||||
}
|
||||
newInstrs.add(call);
|
||||
newInstrs.addAll(func.getExpression().getInstructions());
|
||||
func.getExpression().setInstructions(newInstrs);
|
||||
}
|
||||
if (!failed) {
|
||||
String actionTaken = module.actionTaken.get(j);
|
||||
if (actionTaken.startsWith("0")) {
|
||||
CallInstr call = new CallInstr(new FuncIdx(j, module));
|
||||
else if (actionTaken == StreamReplacement.ReplacementType.HOOKCOPYEXPORT) {
|
||||
copies[j] = new Code(new Func(func.getLocalss(), new Expression(func.getExpression().getInstructions())));
|
||||
|
||||
List<Instr> newInstrs = new ArrayList<>();
|
||||
for (int k = 0; k < module.newImportsFuncTypes.get(j).getParameterType().typeList().size(); k++) {
|
||||
newInstrs.add(new LocalVariableInstr(InstrType.LOCAL_GET, new LocalIdx(k)));
|
||||
}
|
||||
newInstrs.add(call);
|
||||
newInstrs.addAll(func.getExpression().getInstructions());
|
||||
func.getExpression().setInstructions(newInstrs);
|
||||
}
|
||||
else if (actionTaken.startsWith("1")) {
|
||||
copies[j] = new Code(new Func(func.getLocalss(), new Expression(func.getExpression().getInstructions())));
|
||||
|
||||
CallInstr call = new CallInstr(new FuncIdx(j, module));
|
||||
List<Instr> newInstrs = new ArrayList<>();
|
||||
for (int k = 0; k < module.newImportsFuncTypes.get(j).getParameterType().typeList().size(); k++) {
|
||||
newInstrs.add(new LocalVariableInstr(InstrType.LOCAL_GET, new LocalIdx(k)));
|
||||
}
|
||||
newInstrs.add(call);
|
||||
func.getExpression().setInstructions(newInstrs);
|
||||
CallInstr call = new CallInstr(new FuncIdx(j, module));
|
||||
List<Instr> newInstrs = new ArrayList<>();
|
||||
for (int k = 0; k < module.streamReplacements.get(j).getFuncType().getParameterType().typeList().size(); k++) {
|
||||
newInstrs.add(new LocalVariableInstr(InstrType.LOCAL_GET, new LocalIdx(k)));
|
||||
}
|
||||
newInstrs.add(call);
|
||||
func.getExpression().setInstructions(newInstrs);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import wasm.disassembly.conventions.Vector;
|
||||
import wasm.disassembly.modules.Module;
|
||||
import wasm.disassembly.modules.indices.FuncIdx;
|
||||
import wasm.disassembly.modules.sections.Section;
|
||||
import wasm.misc.StreamReplacement;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
@ -43,11 +44,10 @@ public class ExportSection extends Section {
|
||||
|
||||
public void addShittyExports(Module module) {
|
||||
int count = 0;
|
||||
for (int i = 0; i < module.searchFunctions.size(); i++) {
|
||||
String actionTaken = module.actionTaken.get(i);
|
||||
if (actionTaken.startsWith("1")) {
|
||||
String exportName = actionTaken.split("-")[1];
|
||||
getExports().add(new Export(exportName, new ExportDesc(new FuncIdx(
|
||||
for (int i = 0; i < module.streamReplacements.size(); i++) {
|
||||
StreamReplacement.ReplacementType actionTaken = module.streamReplacements.get(i).getReplacementType();
|
||||
if (actionTaken == StreamReplacement.ReplacementType.HOOKCOPYEXPORT) {
|
||||
getExports().add(new Export(module.streamReplacements.get(i).getExportName(), new ExportDesc(new FuncIdx(
|
||||
module.getCodeSection().length + module.getImportSection().getTotalFuncImports() -
|
||||
module.getCodeSection().copiesLength + count, module
|
||||
))));
|
||||
|
@ -9,7 +9,9 @@ import wasm.disassembly.modules.sections.Section;
|
||||
import wasm.disassembly.modules.sections.code.Code;
|
||||
import wasm.disassembly.modules.sections.code.Func;
|
||||
import wasm.disassembly.values.WUnsignedInt;
|
||||
import wasm.misc.CodeCompare;
|
||||
import wasm.misc.Function;
|
||||
import wasm.misc.StreamReplacement;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@ -37,8 +39,8 @@ public class FunctionSection extends Section {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
|
||||
List<TypeIdx> searchFunctions = new ArrayList<>();
|
||||
for (int i = 0; i < module.searchFunctions.size(); i++) {
|
||||
Function f = module.searchFunctions.get(i);
|
||||
for (int i = 0; i < module.streamReplacements.size(); i++) {
|
||||
StreamReplacement f = module.streamReplacements.get(i);
|
||||
searchFunctions.add(module.getTypeSection().getTypeIdxForFuncType(f.getFuncType()));
|
||||
matchesSearchFunctionsTypes.add(new HashSet<>());
|
||||
}
|
||||
@ -55,10 +57,10 @@ public class FunctionSection extends Section {
|
||||
typeIdx.assemble(buffer);
|
||||
}
|
||||
|
||||
for (int i = 0; i < module.searchFunctions.size(); i++) {
|
||||
String actionTaken = module.actionTaken.get(i);
|
||||
for (int i = 0; i < module.streamReplacements.size(); i++) {
|
||||
StreamReplacement.ReplacementType actionTaken = module.streamReplacements.get(i).getReplacementType();
|
||||
// new function will be created
|
||||
if (actionTaken.startsWith("1")) {
|
||||
if (actionTaken == StreamReplacement.ReplacementType.HOOKCOPYEXPORT) {
|
||||
searchFunctions.get(i).assemble(buffer);
|
||||
length++;
|
||||
}
|
||||
|
@ -6,6 +6,9 @@ import wasm.disassembly.conventions.Vector;
|
||||
import wasm.disassembly.modules.Module;
|
||||
import wasm.disassembly.modules.indices.FuncIdx;
|
||||
import wasm.disassembly.modules.sections.Section;
|
||||
import wasm.disassembly.types.FuncType;
|
||||
import wasm.disassembly.types.ResultType;
|
||||
import wasm.misc.StreamReplacement;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
@ -43,17 +46,25 @@ public class ImportSection extends Section {
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < module.newImports.size(); i++) {
|
||||
module.newImports.get(i).getImportDescription().setImportValue(
|
||||
module.getTypeSection().getTypeIdxForFuncType(module.newImportsFuncTypes.get(i))
|
||||
);
|
||||
List<Import> newImports = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
for (StreamReplacement streamReplacement : module.streamReplacements) {
|
||||
newImports.add(new Import("env", streamReplacement.getImportName(), new ImportDesc(
|
||||
module.getTypeSection().getTypeIdxForFuncType(new FuncType(
|
||||
streamReplacement.getFuncType().getParameterType(),
|
||||
streamReplacement.getReplacementType() == StreamReplacement.ReplacementType.HOOK ? new ResultType(Collections.emptyList()) :
|
||||
streamReplacement.getFuncType().getResultType()
|
||||
))
|
||||
)));
|
||||
}
|
||||
|
||||
List<Import> f = imports.getElements().subList(0, first);
|
||||
f.addAll(module.newImports);
|
||||
List<Import> f = new ArrayList<>(imports.getElements().subList(0, first));
|
||||
f.addAll(newImports);
|
||||
f.addAll(imports.getElements().subList(first, imports.getElements().size()));
|
||||
imports.setElements(f);
|
||||
totalFuncImports += module.newImports.size();
|
||||
totalFuncImports += newImports.size();
|
||||
}
|
||||
|
||||
public ImportSection(Module module, List<Import> imports) {
|
||||
|
10
src/main/java/wasm/misc/CodeCompare.java
Normal file
10
src/main/java/wasm/misc/CodeCompare.java
Normal file
@ -0,0 +1,10 @@
|
||||
package wasm.misc;
|
||||
|
||||
import wasm.disassembly.modules.sections.code.Func;
|
||||
import wasm.disassembly.types.FuncType;
|
||||
|
||||
public interface CodeCompare {
|
||||
|
||||
boolean isEqual(Func code);
|
||||
|
||||
}
|
18
src/main/java/wasm/misc/StreamReplacement.java
Normal file
18
src/main/java/wasm/misc/StreamReplacement.java
Normal file
@ -0,0 +1,18 @@
|
||||
package wasm.misc;
|
||||
|
||||
import wasm.disassembly.types.FuncType;
|
||||
|
||||
public interface StreamReplacement {
|
||||
|
||||
|
||||
enum ReplacementType {
|
||||
HOOK,
|
||||
HOOKCOPYEXPORT
|
||||
}
|
||||
|
||||
FuncType getFuncType();
|
||||
ReplacementType getReplacementType();
|
||||
String getImportName();
|
||||
String getExportName();
|
||||
CodeCompare getCodeCompare();
|
||||
}
|
Loading…
Reference in New Issue
Block a user