everything

This commit is contained in:
sirjonasxx 2020-12-29 19:16:39 +01:00
parent 63c94891bc
commit 9dbf50c7e1
10 changed files with 100 additions and 140 deletions

View File

@ -1,9 +1,15 @@
package wasm; package wasm;
import wasm.disassembly.InvalidOpCodeException; 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.Module;
import wasm.disassembly.modules.indices.FuncIdx; import wasm.disassembly.modules.indices.FuncIdx;
import wasm.disassembly.modules.indices.TypeIdx; 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.Export;
import wasm.disassembly.modules.sections.export.ExportDesc; import wasm.disassembly.modules.sections.export.ExportDesc;
import wasm.disassembly.modules.sections.imprt.Import; 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.FuncType;
import wasm.disassembly.types.ResultType; import wasm.disassembly.types.ResultType;
import wasm.disassembly.types.ValType; import wasm.disassembly.types.ValType;
import wasm.misc.CodeCompare;
import wasm.misc.Function; import wasm.misc.Function;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class GWasm { 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 { 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));
} }
} }

View File

@ -19,7 +19,9 @@ import wasm.disassembly.modules.sections.start.StartSection;
import wasm.disassembly.modules.sections.table.TableSection; import wasm.disassembly.modules.sections.table.TableSection;
import wasm.disassembly.modules.sections.type.TypeSection; import wasm.disassembly.modules.sections.type.TypeSection;
import wasm.disassembly.types.FuncType; import wasm.disassembly.types.FuncType;
import wasm.misc.CodeCompare;
import wasm.misc.Function; import wasm.misc.Function;
import wasm.misc.StreamReplacement;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
@ -44,37 +46,11 @@ public class Module extends WASMOpCode {
private List<List<CustomSection>> customSectionsList; private List<List<CustomSection>> customSectionsList;
// ACTION TAKEN TO MINIMIZE MEM USAGE: public final List<StreamReplacement> streamReplacements;
// 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 Module(BufferedInputStream in, List<StreamReplacement> streamReplacements) throws IOException, InvalidOpCodeException {
// actiontaken = decides what to do with matches from "searchFunctions", this.streamReplacements = streamReplacements;
// * 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;
customSectionsList = new ArrayList<>(); customSectionsList = new ArrayList<>();
@ -104,12 +80,13 @@ public class Module extends WASMOpCode {
disassembleCustomSections(in); disassembleCustomSections(in);
dataSection = isNextSection(in, 11) ? new DataSection(in, this) : null; dataSection = isNextSection(in, 11) ? new DataSection(in, this) : null;
disassembleCustomSections(in); disassembleCustomSections(in);
exportSection.addShittyExports(this);
in.close(); in.close();
} }
public Module(String fileName, List<Import> newImports, List<FuncType> newImportsFuncTypes, List<Function> searchFunctions, List<String> actionTaken) throws IOException, InvalidOpCodeException { public Module(String fileName, List<StreamReplacement> streamReplacements) throws IOException, InvalidOpCodeException {
this(new BufferedInputStream(new FileInputStream(new File(fileName))), newImports, newImportsFuncTypes, searchFunctions, actionTaken); this(new BufferedInputStream(new FileInputStream(new File(fileName))), streamReplacements);
} }
private void disassembleCustomSections(BufferedInputStream in) throws IOException, InvalidOpCodeException { private void disassembleCustomSections(BufferedInputStream in) throws IOException, InvalidOpCodeException {

View File

@ -22,7 +22,7 @@ public class FuncIdx extends WASMOpCode {
public FuncIdx(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException { public FuncIdx(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
x = WUnsignedInt.read(in, 32) x = WUnsignedInt.read(in, 32)
+ module.newImports.size(); + module.streamReplacements.size();
// ref = CodeSection.currentI; // debugging purpose // ref = CodeSection.currentI; // debugging purpose

View File

@ -39,7 +39,6 @@ public abstract class Section extends WASMOpCode {
ByteArrayOutputStream fakeOutputStream = new ByteArrayOutputStream(); ByteArrayOutputStream fakeOutputStream = new ByteArrayOutputStream();
assemble2(fakeOutputStream); assemble2(fakeOutputStream);
byte[] asbytes = fakeOutputStream.toByteArray(); byte[] asbytes = fakeOutputStream.toByteArray();
System.out.println("section + " + sectionId + ", size: " + asbytes.length);
WUnsignedInt.write(asbytes.length, out, 32); WUnsignedInt.write(asbytes.length, out, 32);
fakeOutputStream.close(); fakeOutputStream.close();
out.write(asbytes); out.write(asbytes);

View File

@ -14,7 +14,9 @@ import wasm.disassembly.modules.indices.LocalIdx;
import wasm.disassembly.modules.sections.Section; import wasm.disassembly.modules.sections.Section;
import wasm.disassembly.modules.sections.data.Data; import wasm.disassembly.modules.sections.data.Data;
import wasm.disassembly.values.WUnsignedInt; import wasm.disassembly.values.WUnsignedInt;
import wasm.misc.CodeCompare;
import wasm.misc.Function; import wasm.misc.Function;
import wasm.misc.StreamReplacement;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -38,7 +40,7 @@ public class CodeSection extends Section {
super(in, module, CODE_SECTION_ID); super(in, module, CODE_SECTION_ID);
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 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); // codesEntries = new Vector<>(in, Code::new, module);
length = WUnsignedInt.read(in, 32); length = WUnsignedInt.read(in, 32);
@ -47,47 +49,37 @@ public class CodeSection extends Section {
Func func = code.getCode(); 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)) { if (module.getFunctionSection().matchesSearchFunctionsTypes.get(j).contains(i)) {
Function search = module.searchFunctions.get(j); CodeCompare comparer = module.streamReplacements.get(j).getCodeCompare();
if (func.getLocalss().equals(search.getLocals()) && func.getExpression().getInstructions().size() == search.getCode().getInstructions().size()) {
boolean failed = false; if (comparer.isEqual(func)) {
for (int k = 0; k < func.getExpression().getInstructions().size(); k++) { StreamReplacement.ReplacementType actionTaken = module.streamReplacements.get(j).getReplacementType();
Instr instr = func.getExpression().getInstructions().get(k); if (actionTaken == StreamReplacement.ReplacementType.HOOK) {
Instr instr2 = search.getCode().getInstructions().get(k);
if (instr.getInstrType() != instr2.getInstrType()) {
failed = true;
break;
}
}
if (!failed) {
String actionTaken = module.actionTaken.get(j);
if (actionTaken.startsWith("0")) {
CallInstr call = new CallInstr(new FuncIdx(j, module)); CallInstr call = new CallInstr(new FuncIdx(j, module));
List<Instr> newInstrs = new ArrayList<>(); List<Instr> newInstrs = new ArrayList<>();
for (int k = 0; k < module.newImportsFuncTypes.get(j).getParameterType().typeList().size(); k++) { 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(new LocalVariableInstr(InstrType.LOCAL_GET, new LocalIdx(k)));
} }
newInstrs.add(call); newInstrs.add(call);
newInstrs.addAll(func.getExpression().getInstructions()); newInstrs.addAll(func.getExpression().getInstructions());
func.getExpression().setInstructions(newInstrs); func.getExpression().setInstructions(newInstrs);
} }
else if (actionTaken.startsWith("1")) { else if (actionTaken == StreamReplacement.ReplacementType.HOOKCOPYEXPORT) {
copies[j] = new Code(new Func(func.getLocalss(), new Expression(func.getExpression().getInstructions()))); copies[j] = new Code(new Func(func.getLocalss(), new Expression(func.getExpression().getInstructions())));
CallInstr call = new CallInstr(new FuncIdx(j, module)); CallInstr call = new CallInstr(new FuncIdx(j, module));
List<Instr> newInstrs = new ArrayList<>(); List<Instr> newInstrs = new ArrayList<>();
for (int k = 0; k < module.newImportsFuncTypes.get(j).getParameterType().typeList().size(); k++) { 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(new LocalVariableInstr(InstrType.LOCAL_GET, new LocalIdx(k)));
} }
newInstrs.add(call); newInstrs.add(call);
func.getExpression().setInstructions(newInstrs); func.getExpression().setInstructions(newInstrs);
} }
} }
}
} }
} }

View File

@ -5,6 +5,7 @@ import wasm.disassembly.conventions.Vector;
import wasm.disassembly.modules.Module; import wasm.disassembly.modules.Module;
import wasm.disassembly.modules.indices.FuncIdx; import wasm.disassembly.modules.indices.FuncIdx;
import wasm.disassembly.modules.sections.Section; import wasm.disassembly.modules.sections.Section;
import wasm.misc.StreamReplacement;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.IOException; import java.io.IOException;
@ -43,11 +44,10 @@ public class ExportSection extends Section {
public void addShittyExports(Module module) { public void addShittyExports(Module module) {
int count = 0; int count = 0;
for (int i = 0; i < module.searchFunctions.size(); i++) { for (int i = 0; i < module.streamReplacements.size(); i++) {
String actionTaken = module.actionTaken.get(i); StreamReplacement.ReplacementType actionTaken = module.streamReplacements.get(i).getReplacementType();
if (actionTaken.startsWith("1")) { if (actionTaken == StreamReplacement.ReplacementType.HOOKCOPYEXPORT) {
String exportName = actionTaken.split("-")[1]; getExports().add(new Export(module.streamReplacements.get(i).getExportName(), new ExportDesc(new FuncIdx(
getExports().add(new Export(exportName, new ExportDesc(new FuncIdx(
module.getCodeSection().length + module.getImportSection().getTotalFuncImports() - module.getCodeSection().length + module.getImportSection().getTotalFuncImports() -
module.getCodeSection().copiesLength + count, module module.getCodeSection().copiesLength + count, module
)))); ))));

View File

@ -9,7 +9,9 @@ import wasm.disassembly.modules.sections.Section;
import wasm.disassembly.modules.sections.code.Code; import wasm.disassembly.modules.sections.code.Code;
import wasm.disassembly.modules.sections.code.Func; import wasm.disassembly.modules.sections.code.Func;
import wasm.disassembly.values.WUnsignedInt; import wasm.disassembly.values.WUnsignedInt;
import wasm.misc.CodeCompare;
import wasm.misc.Function; import wasm.misc.Function;
import wasm.misc.StreamReplacement;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -37,8 +39,8 @@ public class FunctionSection extends Section {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
List<TypeIdx> searchFunctions = new ArrayList<>(); List<TypeIdx> searchFunctions = new ArrayList<>();
for (int i = 0; i < module.searchFunctions.size(); i++) { for (int i = 0; i < module.streamReplacements.size(); i++) {
Function f = module.searchFunctions.get(i); StreamReplacement f = module.streamReplacements.get(i);
searchFunctions.add(module.getTypeSection().getTypeIdxForFuncType(f.getFuncType())); searchFunctions.add(module.getTypeSection().getTypeIdxForFuncType(f.getFuncType()));
matchesSearchFunctionsTypes.add(new HashSet<>()); matchesSearchFunctionsTypes.add(new HashSet<>());
} }
@ -55,10 +57,10 @@ public class FunctionSection extends Section {
typeIdx.assemble(buffer); typeIdx.assemble(buffer);
} }
for (int i = 0; i < module.searchFunctions.size(); i++) { for (int i = 0; i < module.streamReplacements.size(); i++) {
String actionTaken = module.actionTaken.get(i); StreamReplacement.ReplacementType actionTaken = module.streamReplacements.get(i).getReplacementType();
// new function will be created // new function will be created
if (actionTaken.startsWith("1")) { if (actionTaken == StreamReplacement.ReplacementType.HOOKCOPYEXPORT) {
searchFunctions.get(i).assemble(buffer); searchFunctions.get(i).assemble(buffer);
length++; length++;
} }

View File

@ -6,6 +6,9 @@ import wasm.disassembly.conventions.Vector;
import wasm.disassembly.modules.Module; import wasm.disassembly.modules.Module;
import wasm.disassembly.modules.indices.FuncIdx; import wasm.disassembly.modules.indices.FuncIdx;
import wasm.disassembly.modules.sections.Section; 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.BufferedInputStream;
import java.io.IOException; import java.io.IOException;
@ -43,17 +46,25 @@ public class ImportSection extends Section {
} }
} }
for (int i = 0; i < module.newImports.size(); i++) { List<Import> newImports = new ArrayList<>();
module.newImports.get(i).getImportDescription().setImportValue(
module.getTypeSection().getTypeIdxForFuncType(module.newImportsFuncTypes.get(i))
);
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); List<Import> f = new ArrayList<>(imports.getElements().subList(0, first));
f.addAll(module.newImports); f.addAll(newImports);
f.addAll(imports.getElements().subList(first, imports.getElements().size())); f.addAll(imports.getElements().subList(first, imports.getElements().size()));
imports.setElements(f); imports.setElements(f);
totalFuncImports += module.newImports.size(); totalFuncImports += newImports.size();
} }
public ImportSection(Module module, List<Import> imports) { public ImportSection(Module module, List<Import> imports) {

View 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);
}

View 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();
}