diff --git a/Cargo.toml b/Cargo.toml index 2c44fc6..beb8a63 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "microcorruption-wasm" -version = "0.1.0" +version = "0.0.3" authors = ["Kitlith "] edition = "2018" @@ -27,6 +27,7 @@ wee_alloc = { version = "0.4.2", optional = true } target-lexicon = "0.9.0" goblin = "0.1" scroll = "0.10" +byteorder = "1.3.2" serde = "^1.0.59" serde_json = "^1.0.40" diff --git a/README.md b/README.md index f96520d..bc7c1b4 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,20 @@ _Liberate yourself from the microcorruption website_ ## Usage -You'll need a userscript manager to use this. This userscript was tested with Violentmonkey. +You'll need a userscript manager to use this. +This userscript was tested with Violentmonkey. Grab the userscript from [jsDelivr](https://cdn.jsdelivr.net/gh/kitlith/microcorruption-dumper/pkg/mcorrupt.user.js). To dump a microcorruption level, type `dump` in the on-page debugger. This script will perform a memory dump and parse the page for symbols, providing an ELF file suitable for viewing in Ghidra for download. +Additionally, the `dumpbin` command just performs a memory dump and downloads +it, for use with tools like +[msp430-emu-uctf](https://github.com/cemeyer/msp430-emu-uctf) that don't +support the elf file format. + + ## Hacking Build the wasm component with: ```sh diff --git a/pkg/mcorrupt.user.js b/pkg/mcorrupt.user.js index 0de3a86..f835431 100644 --- a/pkg/mcorrupt.user.js +++ b/pkg/mcorrupt.user.js @@ -3,8 +3,9 @@ // @namespace Kitlith // @match https://*.microcorruption.com/cpu/debugger // @grant GM_getResourceURL -// @version 0.0.1 +// @version 0.0.3 // @author Kitlith +// @require https://cdn.jsdelivr.net/npm/file-saver@2.0.2/dist/FileSaver.min.js // @require microcorruption_wasm.js // @resource wasm microcorruption_wasm_bg.wasm // @description Adds a command (dump) to the debugger that performs a memory dump (w/ symbols!) and downloads it as ".elf" @@ -14,35 +15,38 @@ // For now, this works without too much modification. wasm_bindgen(GM_getResourceURL('wasm')); -unsafeWindow.cpu._dump = (function () { - // File download code from: https://stackoverflow.com/a/19328891 - var a = document.createElement("a"); - a.style = "display: none"; - document.body.appendChild(a); - return function (e) { - // cpu.memory is a sparse js 'array', let's convert it to a full 64KiB array before downloading - var memory = new Uint8Array(0x10000); - for (key in cpu.memory) { - memory[key] = cpu.memory[key]; - } +function getMemory() { + // cpu.memory is a sparse js 'array', let's convert it to a full 64KiB array before downloading + var memory = new Uint8Array(0x10000); + for (key in cpu.memory) { + memory[key] = cpu.memory[key]; + } + + return memory; +} - var symbols = {}; - for (elem of document.getElementsByClassName("insnlabel")) { - let addr = parseInt(elem.innerText.slice(0, 4), 16); // first four characters are address in hex - let name = elem.textContent.slice(7, -2); // skip the addr, skip ' <', and leave out '>' - symbols[name] = addr; +unsafeWindow.cpu._dump = function (e) { + var symbols = {}; + for (elem of document.getElementsByClassName("insnlabel")) { + let addr = parseInt(elem.innerText.slice(0, 4), 16); // first four characters are address in hex + if (isNaN(addr)) { + continue; } + let name = elem.textContent.slice(7, -2); // skip the addr, skip ' <', and leave out '>' + symbols[name] = addr; + } - console.log(symbols); + // By querying whoami, we can get the current level name. woo! + cpu.get('/whoami', function(e) { + var memory = getMemory(); + let elf = wasm_bindgen.gen_elf(e.level, memory, symbols); + saveAs(new Blob([elf], {type: "application/octet-stream"}), e.level + ".elf"); + }); +}; - // By querying whoami, we can get the current level name. woo! - cpu.get('/whoami', function(e) { - let elf = wasm_bindgen.gen_elf(e.level, memory, symbols); - var url = unsafeWindow.URL.createObjectURL(new Blob([elf], {type: "application/octet-stream"})); - a.href = url; - a.download = e.level + ".elf"; - a.click(); - unsafeWindow.URL.revokeObjectURL(url); - }); - }; -}()); +unsafeWindow.cpu._dumpbin = function () { + cpu.get('/whoami', function(e) { + var memory = getMemory(); + saveAs(new Blob([memory], {type: "application/octet-stream"}), e.level + ".bin"); + }); +} diff --git a/src/lib.rs b/src/lib.rs index 17d1605..1f9e289 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ use goblin::{elf, container::{Ctx, Endian, Container}}; use scroll::{Pread, Pwrite}; use target_lexicon::{Architecture, BinaryFormat, Environment, OperatingSystem, Triple, Vendor}; use std::collections::BTreeMap; +use byteorder::{ByteOrder, LE}; // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global // allocator. @@ -29,6 +30,8 @@ pub fn gen_elf(name: &str, memory: Box<[u8]>, symbols: &JsValue) -> Result, symbols: &JsValue) -> Result