commit c78df563063aaf9fa843de31d9c9d157f20e6609 Author: Lyle Mantooth Date: Sun May 22 12:31:39 2022 -0400 Initial commit. BinComp ported to Rust. diff --git a/.github/workflows/build_nix.yml b/.github/workflows/build_nix.yml new file mode 100644 index 0000000..2f684e1 --- /dev/null +++ b/.github/workflows/build_nix.yml @@ -0,0 +1,13 @@ +name: "Build legacy Nix package on Ubuntu" + +on: + push: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: cachix/install-nix-action@v12 + - name: Building package + run: nix-build . -A defaultPackage.x86_64-linux diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..16d8175 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +members = [ + "enemize", + "bin_comp", +] diff --git a/bin_comp/Cargo.toml b/bin_comp/Cargo.toml new file mode 100644 index 0000000..a8bc1ba --- /dev/null +++ b/bin_comp/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "bin_comp" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +tempfile = "3" diff --git a/bin_comp/src/main.rs b/bin_comp/src/main.rs new file mode 100644 index 0000000..f52c93a --- /dev/null +++ b/bin_comp/src/main.rs @@ -0,0 +1,105 @@ +use std::env::args; +use std::io::{self, Read, Write}; +use std::iter::zip; +use std::process::Command; + +use serde::Serialize; +use tempfile::NamedTempfile; + +#[derive(Serialize)] +struct Patch { + pub address: usize, + pub patch_data: Vec, +} + +impl Patch { + fn new() -> Patch { + Patch { + address: 0, + patch_data: vec![], + } + } +} + +fn main() -> Result<(), anyhow::Error> { + println!("BinComp ---- "); + + let mut args = args(); + + let symbols_fn = args.next_back().expect("No symbols filename"); + let base_patch = args.next_back().expect("No basePatch filename"); + let asm_fn = args.next_back().expect("No input ASM filename"); + + let mut zeroes_patch = vec![]; + + let (mut zeroes_file, zeroes_path) = NamedTempfile::new()?; + let (mut ones_file, ones_path) NamedTempfile::new()?; + + println!("temp file (zeros): {}", zeroes_file.path()); + println!("temp file (0xFF): {}", ones_file.path()); + + run_asar(&asm_fn, zeroes_file.path(), &symbols); + + println!("Reading all 0x00 file."); + zeroes_file.read(&mut zeroes_patch)?; + println!("Read all 0x00 file."); + + println!("Generating all 0xFF file."); + let mut all_ones = vec![0xff; zeroes_patch.len()]; + ones_file.write_all(&all_ones)?; + ones_file.flush()?; + println!("Generated all 0xFF file."); + + run_asar(&asm_fn, ones_file.path(), &symbols); + + println!("Reading all 0xFF patched file."); + let mut ones_patch = vec![]; + ones_file.rewind()?.read_to_end(&mut ones_patch)?; + println!("Read all 0xFF patched file."); + + assert!(zeroes_patch.len() == ones_patch.len(), "File lengths don't match! Aborting."); + + println!(""); + + let list = zip(zeroes_patch, ones_patch).enumerate().fold((true, Vec::new()), |(start, list), &(i, (zero, ff))| { + if zero == ff { + if start { + println!("New patch data found at address {:X}", i); + let patch = Patch { address: i, patch_data: vec![] }; + list.push(patch); + } + list.last_mut().and_then(|p| p.patch_data.push(zero)); + + (false, list) + } else { + assert!(zero == 0x00 && ff == 0xff, "Something went wrong. Zero file has non-zero or FF file has non-FF where files do not match!"); + + (true, list) + } + }); + + println!("Writing patch data file."); + let mut bp_file = File::create(&base_patch)?; + serde_json::to_writer(bp_file, &list)?; + + println!("Cleaning up temp files."); + println!("BinComp finished ----"); +} + +fn run_asar(asm: &AsRef, rom: &AsRef, symbols: &AsRef) { + println!("---- Running asar --no-title-check --fix-checksum=off --symbols=wla --symbols-path={} {} {} ----", symbols, asm, rom); + + let status = Command::new("asar") + .arg("--no-title-check") + .arg("--fix-checksum=off") + .arg("--symbols=wla") + .arg(format!("--symbols-path={}", symbols)) + .arg(asm) + .arg(rom) + .status() + .expect("Failed to run asar"); + + assert!(status.success(), "asar threw errors"); + + println!("---- asar finished ----"); +} diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..39bacff --- /dev/null +++ b/default.nix @@ -0,0 +1,7 @@ +(import ( + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/99f1c2157fba4bfe6211a321fd0ee43199025dbf.tar.gz"; + sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2"; } +) { + src = ./.; +}).defaultNix diff --git a/enemize/Cargo.toml b/enemize/Cargo.toml new file mode 100644 index 0000000..311d346 --- /dev/null +++ b/enemize/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "enemize-rs" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +md5 = "0.7.0" diff --git a/enemize/src/main.rs b/enemize/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/enemize/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..a718f77 --- /dev/null +++ b/flake.lock @@ -0,0 +1,77 @@ +{ + "nodes": { + "naersk": { + "inputs": { + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1651574473, + "narHash": "sha256-wQhFORvRjo8LB2hTmETmv6cbyKGDPbfWqvZ/0chnDE4=", + "owner": "nix-community", + "repo": "naersk", + "rev": "f21309b38e1da0d61b881b6b6d41b81c1aed4e1d", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "master", + "repo": "naersk", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1652574577, + "narHash": "sha256-MoSWPtue4Wi9+kRDxUbLWEBCL8Bswaa8kVMh2JYpSJg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "118ec238bfb788a34f1d53c4d95931fadfa70367", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1652574577, + "narHash": "sha256-MoSWPtue4Wi9+kRDxUbLWEBCL8Bswaa8kVMh2JYpSJg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "118ec238bfb788a34f1d53c4d95931fadfa70367", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "naersk": "naersk", + "nixpkgs": "nixpkgs_2", + "utils": "utils" + } + }, + "utils": { + "locked": { + "lastModified": 1652557277, + "narHash": "sha256-jSes9DaIVMdmwBB78KkFUVrlDzawmD62vrUg0GS2500=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "12806d31a381e7cd169a6bac35590e7b36dc5fe5", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..a19358c --- /dev/null +++ b/flake.nix @@ -0,0 +1,27 @@ +{ + inputs = { + asar.url = "file:/home/lyle/projects/asar"; + naersk.url = "github:nix-community/naersk/master"; + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, utils, asar, naersk }: + utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { inherit system; }; + naersk-lib = pkgs.callPackage naersk { }; + in + { + defaultPackage = naersk-lib.buildPackage ./.; + + defaultApp = utils.lib.mkApp { + drv = self.defaultPackage."${system}"; + }; + + devShell = with pkgs; mkShell { + buildInputs = [ asar cargo rustc rustfmt pre-commit rustPackages.clippy ]; + RUST_SRC_PATH = rustPlatform.rustLibSrc; + }; + }); +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..77db547 --- /dev/null +++ b/shell.nix @@ -0,0 +1,7 @@ +(import ( + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/99f1c2157fba4bfe6211a321fd0ee43199025dbf.tar.gz"; + sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2"; } +) { + src = ./.; +}).shellNix