diff --git a/pom.xml b/pom.xml index 5359267..edf3689 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ G-Earth G-Wasm - 1.0-SNAPSHOT + 1.0 diff --git a/src/main/java/wasm/GWasm.java b/src/main/java/wasm/GWasm.java index fd1d33d..a187b2a 100644 --- a/src/main/java/wasm/GWasm.java +++ b/src/main/java/wasm/GWasm.java @@ -11,6 +11,7 @@ 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.Function; import java.io.*; import java.util.ArrayList; @@ -21,40 +22,41 @@ import java.util.stream.Collectors; public class GWasm { public static void extractMethods(Module module) { - List typesFromImports = new ArrayList<>(); - for (Import imp : module.getImportSection().getImports()) { - if (imp.getImportDescription().getImportType() == 0) { - typesFromImports.add((TypeIdx)imp.getImportDescription().getImportValue()); - } - } - - List 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(" ")) + ")" - )); - } - } +// List typesFromImports = new ArrayList<>(); +// for (Import imp : module.getImportSection().getImports()) { +// if (imp.getImportDescription().getImportType() == 0) { +// typesFromImports.add((TypeIdx)imp.getImportDescription().getImportValue()); +// } +// } +// +// List 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"); + 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)); diff --git a/src/main/java/wasm/disassembly/modules/Module.java b/src/main/java/wasm/disassembly/modules/Module.java index cf12baa..6a4e92e 100644 --- a/src/main/java/wasm/disassembly/modules/Module.java +++ b/src/main/java/wasm/disassembly/modules/Module.java @@ -12,11 +12,14 @@ import wasm.disassembly.modules.sections.element.ElementSection; import wasm.disassembly.modules.sections.export.ExportSection; import wasm.disassembly.modules.sections.function.FunctionSection; import wasm.disassembly.modules.sections.global.GlobalSection; +import wasm.disassembly.modules.sections.imprt.Import; import wasm.disassembly.modules.sections.imprt.ImportSection; import wasm.disassembly.modules.sections.memory.MemorySection; 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.Function; import java.io.*; import java.util.ArrayList; @@ -40,9 +43,39 @@ public class Module extends WASMOpCode { private DataSection dataSection; private List> customSectionsList; - private List allFuncIdxs = new ArrayList<>(); - public Module(BufferedInputStream in) throws IOException, InvalidOpCodeException { + // 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 + + + + // 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 newImports; + public final List searchFunctions; + public final List actionTaken; + public final List newImportsFuncTypes; + + + public Module(BufferedInputStream in, List newImports, List newImportsFuncTypes, List searchFunctions, List actionTaken) throws IOException, InvalidOpCodeException { + this.newImports = newImports; + this.searchFunctions = searchFunctions; + this.actionTaken = actionTaken; + this.newImportsFuncTypes = newImportsFuncTypes; + customSectionsList = new ArrayList<>(); magic = new Magic(in); @@ -75,33 +108,8 @@ public class Module extends WASMOpCode { in.close(); } - public Module(String fileName) throws IOException, InvalidOpCodeException { - this(new BufferedInputStream(new FileInputStream(new File(fileName)))); - } - - public Module(Magic magic, Version version, TypeSection typeSection, ImportSection importSection, FunctionSection functionSection, TableSection tableSection, MemorySection memorySection, GlobalSection globalSection, ExportSection exportSection, StartSection startSection, ElementSection elementSection, CodeSection codeSection, DataSection dataSection) { - this.magic = magic; - this.version = version; - this.typeSection = typeSection; - this.importSection = importSection; - this.functionSection = functionSection; - this.tableSection = tableSection; - this.memorySection = memorySection; - this.globalSection = globalSection; - this.exportSection = exportSection; - this.startSection = startSection; - this.elementSection = elementSection; - this.codeSection = codeSection; - this.dataSection = dataSection; - - this.customSectionsList = new ArrayList<>(); - for (int i = 0; i < 12; i++) { - customSectionsList.add(new ArrayList<>()); - } - } - public Module(TypeSection typeSection, ImportSection importSection, FunctionSection functionSection, TableSection tableSection, MemorySection memorySection, GlobalSection globalSection, ExportSection exportSection, StartSection startSection, ElementSection elementSection, CodeSection codeSection, DataSection dataSection, List> customSectionsList) { - this(new Magic(), new Version(), typeSection, importSection, functionSection, tableSection, memorySection, - globalSection, exportSection, startSection, elementSection, codeSection, dataSection); + public Module(String fileName, List newImports, List newImportsFuncTypes, List searchFunctions, List actionTaken) throws IOException, InvalidOpCodeException { + this(new BufferedInputStream(new FileInputStream(new File(fileName))), newImports, newImportsFuncTypes, searchFunctions, actionTaken); } private void disassembleCustomSections(BufferedInputStream in) throws IOException, InvalidOpCodeException { @@ -140,6 +148,7 @@ public class Module extends WASMOpCode { } } assembleCustomSections(out, 11); + out.close(); } private void assembleCustomSections(OutputStream out, int location) throws IOException, InvalidOpCodeException { @@ -149,9 +158,7 @@ public class Module extends WASMOpCode { } public void assembleToFile(String fileName) throws IOException, InvalidOpCodeException { - FileOutputStream habAssembled = new FileOutputStream(fileName); - assemble(habAssembled); - habAssembled.close(); + assemble(new FileOutputStream(fileName)); } public Magic getMagic() { @@ -265,8 +272,4 @@ public class Module extends WASMOpCode { public void setCustomSectionsList(List> customSectionsList) { this.customSectionsList = customSectionsList; } - - public List getAllFuncIdxs() { - return allFuncIdxs; - } } diff --git a/src/main/java/wasm/disassembly/modules/indices/FuncIdx.java b/src/main/java/wasm/disassembly/modules/indices/FuncIdx.java index c95d0be..8eb1e94 100644 --- a/src/main/java/wasm/disassembly/modules/indices/FuncIdx.java +++ b/src/main/java/wasm/disassembly/modules/indices/FuncIdx.java @@ -4,6 +4,7 @@ import com.sun.org.apache.xpath.internal.functions.FuncId; import wasm.disassembly.InvalidOpCodeException; import wasm.disassembly.WASMOpCode; import wasm.disassembly.modules.Module; +import wasm.disassembly.modules.sections.code.CodeSection; import wasm.disassembly.values.WUnsignedInt; import java.io.BufferedInputStream; @@ -16,14 +17,19 @@ public class FuncIdx extends WASMOpCode { private long x; + +// public int ref; // debugging purpose + public FuncIdx(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException { - x = WUnsignedInt.read(in, 32); - module.getAllFuncIdxs().add(this); + x = WUnsignedInt.read(in, 32) + + module.newImports.size(); + + +// ref = CodeSection.currentI; // debugging purpose } public FuncIdx(long x, Module module) { this.x = x; - module.getAllFuncIdxs().add(this); } @Override @@ -38,4 +44,9 @@ public class FuncIdx extends WASMOpCode { public void setX(long x) { this.x = x; } + + @Override + public boolean equals(Object obj) { + return (obj instanceof FuncIdx && ((FuncIdx)obj).getX() == x); + } } diff --git a/src/main/java/wasm/disassembly/modules/sections/Section.java b/src/main/java/wasm/disassembly/modules/sections/Section.java index 8eab590..1cda563 100644 --- a/src/main/java/wasm/disassembly/modules/sections/Section.java +++ b/src/main/java/wasm/disassembly/modules/sections/Section.java @@ -39,7 +39,9 @@ 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); } diff --git a/src/main/java/wasm/disassembly/modules/sections/code/Code.java b/src/main/java/wasm/disassembly/modules/sections/code/Code.java index dce7894..3f91bd5 100644 --- a/src/main/java/wasm/disassembly/modules/sections/code/Code.java +++ b/src/main/java/wasm/disassembly/modules/sections/code/Code.java @@ -30,6 +30,7 @@ public class Code extends WASMOpCode { byte[] codeInBytes = codeBuffer.toByteArray(); WUnsignedInt.write(codeInBytes.length, out, 32); out.write(codeInBytes); + codeBuffer.close(); } public Func getCode() { diff --git a/src/main/java/wasm/disassembly/modules/sections/code/CodeSection.java b/src/main/java/wasm/disassembly/modules/sections/code/CodeSection.java index 80907ff..d44c9d4 100644 --- a/src/main/java/wasm/disassembly/modules/sections/code/CodeSection.java +++ b/src/main/java/wasm/disassembly/modules/sections/code/CodeSection.java @@ -1,51 +1,137 @@ package wasm.disassembly.modules.sections.code; import wasm.disassembly.InvalidOpCodeException; +import wasm.disassembly.conventions.Creator; import wasm.disassembly.conventions.Vector; +import wasm.disassembly.instructions.Expression; +import wasm.disassembly.instructions.Instr; +import wasm.disassembly.instructions.InstrType; +import wasm.disassembly.instructions.control.CallInstr; +import wasm.disassembly.instructions.variable.LocalVariableInstr; import wasm.disassembly.modules.Module; import wasm.disassembly.modules.indices.FuncIdx; +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.Function; import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; import java.util.List; public class CodeSection extends Section { public static final int CODE_SECTION_ID = 10; +// public static int currentI = 0; - private Vector codesEntries; + public final byte[] asBytes; + public long length; + public int copiesLength; +// private Vector codesEntries; public CodeSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException { super(in, module, CODE_SECTION_ID); - codesEntries = new Vector<>(in, Code::new, module); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + Code[] copies = new Code[module.searchFunctions.size()]; + +// codesEntries = new Vector<>(in, Code::new, module); + length = WUnsignedInt.read(in, 32); + for (int i = 0; i < length; i++) { + Code code = new Code(in, module); + + + Func func = code.getCode(); + for (int j = 0; j < module.searchFunctions.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()) { + + 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 (!failed) { + String actionTaken = module.actionTaken.get(j); + if (actionTaken.startsWith("0")) { + CallInstr call = new CallInstr(new FuncIdx(j, module)); + + List 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 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); + } + } + } + } + } + + + code.assemble(buffer); + } + + for (Code code : copies) { + if (code != null) { + code.assemble(buffer); + length++; + copiesLength++; + } + } + + asBytes = buffer.toByteArray(); } - public CodeSection(Module module, List codesEntries) { - super(module, CODE_SECTION_ID); - this.codesEntries = new Vector<>(codesEntries); - } +// public CodeSection(Module module, List codesEntries) { +// super(module, CODE_SECTION_ID); +// this.codesEntries = new Vector<>(codesEntries); +// } @Override protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException { - codesEntries.assemble(out); +// codesEntries.assemble(out); + + WUnsignedInt.write(length, out, 32); + out.write(asBytes); } - public Code getCodeByIdx(FuncIdx funcIdx) { - return codesEntries.getElements().get((int)(funcIdx.getX()) - module.getImportSection().getTotalFuncImports()); - } - - public Func getByIdx(FuncIdx funcIdx) { - return getCodeByIdx(funcIdx).getCode(); - } - - public List getCodesEntries() { - return codesEntries.getElements(); - } - - public void setCodesEntries(List codesEntries) { - this.codesEntries = new Vector<>(codesEntries); - } +// public Code getCodeByIdx(FuncIdx funcIdx) { +// return codesEntries.getElements().get((int)(funcIdx.getX()) - module.getImportSection().getTotalFuncImports()); +// } +// +// public Func getByIdx(FuncIdx funcIdx) { +// return getCodeByIdx(funcIdx).getCode(); +// } +// +// public List getCodesEntries() { +// return codesEntries.getElements(); +// } +// +// public void setCodesEntries(List codesEntries) { +// this.codesEntries = new Vector<>(codesEntries); +// } } diff --git a/src/main/java/wasm/disassembly/modules/sections/data/DataSection.java b/src/main/java/wasm/disassembly/modules/sections/data/DataSection.java index 2475a89..9fa347d 100644 --- a/src/main/java/wasm/disassembly/modules/sections/data/DataSection.java +++ b/src/main/java/wasm/disassembly/modules/sections/data/DataSection.java @@ -4,8 +4,11 @@ import wasm.disassembly.InvalidOpCodeException; import wasm.disassembly.conventions.Vector; import wasm.disassembly.modules.Module; import wasm.disassembly.modules.sections.Section; +import wasm.disassembly.modules.sections.element.Elem; +import wasm.disassembly.values.WUnsignedInt; import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; @@ -13,31 +16,42 @@ import java.util.List; public class DataSection extends Section { public static final int DATA_SECTION_ID = 11; + private final byte[] asBytes; + private long length; - - private Vector dataSegments; +// private Vector dataSegments; public DataSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException { super(in, module, DATA_SECTION_ID); - dataSegments = new Vector<>(in, Data::new, module); +// dataSegments = new Vector<>(in, Data::new, module); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + length = WUnsignedInt.read(in, 32); + for (int i = 0; i < length; i++) { + new Data(in, module).assemble(buffer); + } + asBytes = buffer.toByteArray(); } - public DataSection(Module module, List dataSegments) { - super(module, DATA_SECTION_ID); - this.dataSegments = new Vector<>(dataSegments); - } +// public DataSection(Module module, List dataSegments) { +// super(module, DATA_SECTION_ID); +// this.dataSegments = new Vector<>(dataSegments); +// } @Override protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException { - dataSegments.assemble(out); +// dataSegments.assemble(out); + + WUnsignedInt.write(length, out, 32); + out.write(asBytes); } - - public List getDataSegments() { - return dataSegments.getElements(); - } - - public void setDataSegments(List dataSegments) { - this.dataSegments = new Vector<>(dataSegments); - } +// +// public List getDataSegments() { +// return dataSegments.getElements(); +// } +// +// public void setDataSegments(List dataSegments) { +// this.dataSegments = new Vector<>(dataSegments); +// } } diff --git a/src/main/java/wasm/disassembly/modules/sections/element/ElementSection.java b/src/main/java/wasm/disassembly/modules/sections/element/ElementSection.java index 3588817..6fb0c89 100644 --- a/src/main/java/wasm/disassembly/modules/sections/element/ElementSection.java +++ b/src/main/java/wasm/disassembly/modules/sections/element/ElementSection.java @@ -3,9 +3,12 @@ package wasm.disassembly.modules.sections.element; import wasm.disassembly.InvalidOpCodeException; import wasm.disassembly.conventions.Vector; import wasm.disassembly.modules.Module; +import wasm.disassembly.modules.indices.TypeIdx; import wasm.disassembly.modules.sections.Section; +import wasm.disassembly.values.WUnsignedInt; import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; @@ -14,28 +17,41 @@ public class ElementSection extends Section { public static final int ELEMENT_SECTION_ID = 9; - private Vector elementSegments; +// private Vector elementSegments; + + private final byte[] asBytes; + private long length; public ElementSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException { super(in, module, ELEMENT_SECTION_ID); - elementSegments = new Vector<>(in, Elem::new, module); +// elementSegments = new Vector<>(in, Elem::new, module); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + length = WUnsignedInt.read(in, 32); + for (int i = 0; i < length; i++) { + new Elem(in, module).assemble(buffer); + } + + asBytes = buffer.toByteArray(); } - public ElementSection(Module module, List elementSegments) { - super(module, ELEMENT_SECTION_ID); - this.elementSegments = new Vector<>(elementSegments); - } +// public ElementSection(Module module, List elementSegments) { +// super(module, ELEMENT_SECTION_ID); +// this.elementSegments = new Vector<>(elementSegments); +// } @Override protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException { - elementSegments.assemble(out); +// elementSegments.assemble(out); + + WUnsignedInt.write(length, out, 32); + out.write(asBytes); } - public List getElementSegments() { - return elementSegments.getElements(); - } - - public void setElementSegments(List elementSegments) { - this.elementSegments = new Vector<>(elementSegments); - } +// public List getElementSegments() { +// return elementSegments.getElements(); +// } +// +// public void setElementSegments(List elementSegments) { +// this.elementSegments = new Vector<>(elementSegments); +// } } diff --git a/src/main/java/wasm/disassembly/modules/sections/export/ExportDesc.java b/src/main/java/wasm/disassembly/modules/sections/export/ExportDesc.java index e26e9d4..c866e43 100644 --- a/src/main/java/wasm/disassembly/modules/sections/export/ExportDesc.java +++ b/src/main/java/wasm/disassembly/modules/sections/export/ExportDesc.java @@ -21,7 +21,7 @@ public class ExportDesc extends WASMOpCode { public ExportDesc(BufferedInputStream in, Module module) throws InvalidOpCodeException, IOException { exportType = in.read(); if (exportType < 0x00 || exportType > 0x03) { - throw new InvalidOpCodeException("invalid importdesc type"); + throw new InvalidOpCodeException("invalid exportdesc type"); } exportValue = exportType == 0x00 ? new FuncIdx(in, module) : diff --git a/src/main/java/wasm/disassembly/modules/sections/export/ExportSection.java b/src/main/java/wasm/disassembly/modules/sections/export/ExportSection.java index f9b75e6..6679cb4 100644 --- a/src/main/java/wasm/disassembly/modules/sections/export/ExportSection.java +++ b/src/main/java/wasm/disassembly/modules/sections/export/ExportSection.java @@ -3,6 +3,7 @@ package wasm.disassembly.modules.sections.export; import wasm.disassembly.InvalidOpCodeException; import wasm.disassembly.conventions.Vector; import wasm.disassembly.modules.Module; +import wasm.disassembly.modules.indices.FuncIdx; import wasm.disassembly.modules.sections.Section; import java.io.BufferedInputStream; @@ -38,4 +39,20 @@ public class ExportSection extends Section { public void setExports(List exports) { this.exports = new Vector<>(exports); } + + + 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( + module.getCodeSection().length + module.getImportSection().getTotalFuncImports() - + module.getCodeSection().copiesLength + count, module + )))); + count++; + } + } + } } diff --git a/src/main/java/wasm/disassembly/modules/sections/function/FunctionSection.java b/src/main/java/wasm/disassembly/modules/sections/function/FunctionSection.java index e9398bf..2fe52c2 100644 --- a/src/main/java/wasm/disassembly/modules/sections/function/FunctionSection.java +++ b/src/main/java/wasm/disassembly/modules/sections/function/FunctionSection.java @@ -8,44 +8,87 @@ import wasm.disassembly.modules.indices.TypeIdx; 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.Function; import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class FunctionSection extends Section { public static final int FUNCTION_SECTION_ID = 3; - private Vector typeIdxVector; +// private Vector typeIdxVector; + private final byte[] asBytes; + private long length; + + public List> matchesSearchFunctionsTypes = new ArrayList<>(); public FunctionSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException { super(in, module, FUNCTION_SECTION_ID); - typeIdxVector = new Vector<>(in, TypeIdx::new, module); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + List searchFunctions = new ArrayList<>(); + for (int i = 0; i < module.searchFunctions.size(); i++) { + Function f = module.searchFunctions.get(i); + searchFunctions.add(module.getTypeSection().getTypeIdxForFuncType(f.getFuncType())); + matchesSearchFunctionsTypes.add(new HashSet<>()); + } + +// typeIdxVector = new Vector<>(in, TypeIdx::new, module); + length = WUnsignedInt.read(in, 32); + for (int i = 0; i < length; i++) { + TypeIdx typeIdx = new TypeIdx(in, module); + for (int j = 0; j < searchFunctions.size(); j++) { + if (typeIdx.equals(searchFunctions.get(j))) { + matchesSearchFunctionsTypes.get(j).add(i); + } + } + typeIdx.assemble(buffer); + } + + for (int i = 0; i < module.searchFunctions.size(); i++) { + String actionTaken = module.actionTaken.get(i); + // new function will be created + if (actionTaken.startsWith("1")) { + searchFunctions.get(i).assemble(buffer); + length++; + } + } + + asBytes = buffer.toByteArray(); } - public FunctionSection(Module module, List typeIdxList) { - super(module, FUNCTION_SECTION_ID); - this.typeIdxVector = new Vector<>(typeIdxList); - } +// public FunctionSection(Module module, List typeIdxList) { +// super(module, FUNCTION_SECTION_ID); +// this.typeIdxVector = new Vector<>(typeIdxList); +// } @Override protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException { - typeIdxVector.assemble(out); +// typeIdxVector.assemble(out); + WUnsignedInt.write(length, out, 32); + out.write(asBytes); } - public TypeIdx getByIdx(FuncIdx funcIdx) { - return typeIdxVector.getElements().get((int)(funcIdx.getX()) - module.getImportSection().getTotalFuncImports()); - } - - public List getTypeIdxVector() { - return typeIdxVector.getElements(); - } - - public void setTypeIdxVector(List typeIdxVector) { - this.typeIdxVector = new Vector<>(typeIdxVector); - } +// public TypeIdx getByIdx(FuncIdx funcIdx) { +// return typeIdxVector.getElements().get((int)(funcIdx.getX()) - module.getImportSection().getTotalFuncImports()); +// } +// +// public List getTypeIdxVector() { +// return typeIdxVector.getElements(); +// } +// +// public void setTypeIdxVector(List typeIdxVector) { +// this.typeIdxVector = new Vector<>(typeIdxVector); +// } } diff --git a/src/main/java/wasm/disassembly/modules/sections/imprt/ImportSection.java b/src/main/java/wasm/disassembly/modules/sections/imprt/ImportSection.java index 0f49f20..8900252 100644 --- a/src/main/java/wasm/disassembly/modules/sections/imprt/ImportSection.java +++ b/src/main/java/wasm/disassembly/modules/sections/imprt/ImportSection.java @@ -30,11 +30,30 @@ public class ImportSection extends Section { imports = new Vector<>(in, Import::new, module); totalFuncImports = 0; - for (Import imprt : imports.getElements()) { + + int first = -1; + for (int i = 0; i < imports.getElements().size(); i++) { + Import imprt = imports.getElements().get(i); + if (imprt.getImportDescription().getImportType() == 0) { + if (totalFuncImports == 0) { + first = i; + } totalFuncImports++; } } + + for (int i = 0; i < module.newImports.size(); i++) { + module.newImports.get(i).getImportDescription().setImportValue( + module.getTypeSection().getTypeIdxForFuncType(module.newImportsFuncTypes.get(i)) + ); + } + + List f = imports.getElements().subList(0, first); + f.addAll(module.newImports); + f.addAll(imports.getElements().subList(first, imports.getElements().size())); + imports.setElements(f); + totalFuncImports += module.newImports.size(); } public ImportSection(Module module, List imports) { @@ -55,30 +74,30 @@ public class ImportSection extends Section { this.imports = new Vector<>(imports); } - public List importFunctions(List functions) throws InvalidOpCodeException { - for (Import imprt : functions) { - if (imprt.getImportDescription().getImportType() != 0) { - throw new InvalidOpCodeException("Tried to import non-function as function"); - } - } +// public List importFunctions(List functions) throws InvalidOpCodeException { +// for (Import imprt : functions) { +// if (imprt.getImportDescription().getImportType() != 0) { +// throw new InvalidOpCodeException("Tried to import non-function as function"); +// } +// } +// +// for (FuncIdx funcIdx : module.getAllFuncIdxs()) { +// if (funcIdx.getX() >= totalFuncImports) { +// funcIdx.setX(funcIdx.getX() + functions.size()); +// } +// } +// List newFuncIdxs = new ArrayList<>(); +// for (long i = totalFuncImports; i < totalFuncImports + functions.size(); i++) { +// newFuncIdxs.add(new FuncIdx(i, module)); +// } +// imports.getElements().addAll(functions); +// totalFuncImports += functions.size(); +// return newFuncIdxs; +// } - for (FuncIdx funcIdx : module.getAllFuncIdxs()) { - if (funcIdx.getX() >= totalFuncImports) { - funcIdx.setX(funcIdx.getX() + functions.size()); - } - } - List newFuncIdxs = new ArrayList<>(); - for (long i = totalFuncImports; i < totalFuncImports + functions.size(); i++) { - newFuncIdxs.add(new FuncIdx(i, module)); - } - imports.getElements().addAll(functions); - totalFuncImports += functions.size(); - return newFuncIdxs; - } - - public FuncIdx importFunction(Import function) throws InvalidOpCodeException { - return importFunctions(Collections.singletonList(function)).get(0); - } +// public FuncIdx importFunction(Import function) throws InvalidOpCodeException { +// return importFunctions(Collections.singletonList(function)).get(0); +// } public Import getByIdx(FuncIdx funcIdx) { return imports.getElements().get((int)funcIdx.getX()); diff --git a/src/main/java/wasm/disassembly/modules/sections/type/TypeSection.java b/src/main/java/wasm/disassembly/modules/sections/type/TypeSection.java index 11a8fa1..c0f7ca9 100644 --- a/src/main/java/wasm/disassembly/modules/sections/type/TypeSection.java +++ b/src/main/java/wasm/disassembly/modules/sections/type/TypeSection.java @@ -35,9 +35,9 @@ public class TypeSection extends Section { functionTypes.assemble(out); } - public FuncType getByFuncIdx(FuncIdx funcIdx) { - return getByTypeIdx(module.getFunctionSection().getByIdx(funcIdx)); - } +// public FuncType getByFuncIdx(FuncIdx funcIdx) { +// return getByTypeIdx(module.getFunctionSection().getByIdx(funcIdx)); +// } public List getFunctionTypes() { return functionTypes.getElements(); diff --git a/src/main/java/wasm/misc/Function.java b/src/main/java/wasm/misc/Function.java index d1245d0..cdad937 100644 --- a/src/main/java/wasm/misc/Function.java +++ b/src/main/java/wasm/misc/Function.java @@ -26,25 +26,25 @@ public class Function { this.code = code; } - public Function(Module module, FuncIdx funcIdx) { - funcType = module.getTypeSection().getByFuncIdx(funcIdx); +// public Function(Module module, FuncIdx funcIdx) { +// funcType = module.getTypeSection().getByFuncIdx(funcIdx); +// +// Func code = module.getCodeSection().getByIdx(funcIdx); +// this.code = code.getExpression(); +// locals = code.getLocalss(); +// } - Func code = module.getCodeSection().getByIdx(funcIdx); - this.code = code.getExpression(); - locals = code.getLocalss(); - } - - public FuncIdx addToModule(Module module) { - TypeIdx typeIdx = module.getTypeSection().getTypeIdxForFuncType(funcType); - Func func = new Func(locals, code); - - module.getFunctionSection().getTypeIdxVector().add(typeIdx); - module.getCodeSection().getCodesEntries().add(new Code(func)); - return new FuncIdx( - module.getImportSection().getTotalFuncImports() + module.getCodeSection().getCodesEntries().size() - 1, - module - ); - } +// public FuncIdx addToModule(Module module) { +// TypeIdx typeIdx = module.getTypeSection().getTypeIdxForFuncType(funcType); +// Func func = new Func(locals, code); +// +// module.getFunctionSection().getTypeIdxVector().add(typeIdx); +// module.getCodeSection().getCodesEntries().add(new Code(func)); +// return new FuncIdx( +// module.getImportSection().getTotalFuncImports() + module.getCodeSection().getCodesEntries().size() - 1, +// module +// ); +// } public FuncType getFuncType() {