Skip to content

Commit

Permalink
Public release 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
Bad3r committed Apr 4, 2023
1 parent a8da49f commit 67d527b
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "bin_int_compare"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# bin_int_compare

bin_int_compare is a Rust utility that compares two binary files based on hexadecimal representations of input integers. The script takes two binary files and two integers as input and returns the output in JSON format.

## Features

- Reads binary files and converts them to hexadecimal representation
- Compares addresses based on given integer values
- Outputs comparison results in JSON format

## build Instructions

To build and install the bin_int_compare tool, make sure you have Rust installed on your machine. Then, follow these steps:

Clone the repository:

```sh
git clone https://github.com/bad3r/bin_int_compare.git
```

Change to the bin_int_compare directory:

```sh
cd bin_int_compare
```

Build the project:

```sh
cargo build --release
```

The binary will be generated in the `target/release` directory.

## Usage

To use the bin_int_compare tool, run the following command:

```sh
bin_int_compare file0.dat file1.dat int1 int2
```

Replace file0.dat and file1.dat with the paths to your binary files, and int1 and int with the integer values you want to compare.

The output will be a JSON array containing objects with the following structure:

```json
{
"address": "00000001",
"data0": "00000001: 0400 05ca 000
0 0d4s 034c 340c 50e5 3040",
"data1": "00000001: 00c2 056a 580b dfe0 0000 0055 a627 e540"
}
```

Each object in the array represents a match found between the two files, with:

- `address`: The hexadecimal address offset where the match occurred.
- `data0`: The line from the first file containing `int0` in hexadecimal format.
- `data1`: The line from the second file containing `int1` in hexadecimal format.

## Technical Breakdown

The `bin_int_compare` performs the following steps:

1. Reads the binary files using the `read_binary_file` function, which reads the contents of the files into `Vec<u8>` buffers.
2. Converts the binary data into hexadecimal representation using the `binary_to_hex` function, which processes the binary data in chunks and creates a vector of tuples containing the address offsets and the corresponding hexadecimal lines.
3. Compares the files using the `compare_files` function, which takes the paths to the two files and the integer values to compare as arguments. The function creates hashmaps from the vectors of tuples generated in step 2 and iterates through the first hashmap, checking if the lines contain the given integer values (converted to hexadecimal). If a match is found, the relevant information is stored in a vector.
4. Outputs the comparison results in JSON format using the `serde_json` crate.

The main function handles command-line arguments, error handling, and output formatting. The tool uses Rust's efficient memory handling and processing capabilities to provide fast file reading and comparison.

## License

`bin_int_compare` is released under the MIT License. Please see the [LICENSE](./LICENSE) file for more information.
90 changes: 90 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/// A script that compares two binary files based on hexadecimal representations of input integers.
/// The script takes two binary files and two integers as input, and returns the output in JSON format.

use serde_json;
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::{self, Read};

/// Read the binary file at the given file path and return its contents as a Vec<u8>.
fn read_binary_file(file_path: &str) -> io::Result<Vec<u8>> {
let mut file = File::open(file_path)?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
Ok(buffer)
}

/// Convert the binary data into a vector of tuples containing the address and the corresponding
/// hexadecimal data.
fn binary_to_hex(binary_data: &[u8]) -> Vec<(String, String)> {
binary_data
.chunks(16)
.enumerate()
.map(|(i, chunk)| {
let address = format!("{:08x}", i * 16);
let hex_ln = chunk
.iter()
.map(|byte| format!("{:02x}", byte))
.collect::<Vec<_>>()
.join(" ");
(address, hex_ln)
})
.collect()
}

/// Compare two binary files based on the hexadecimal representations of the input integers.
fn compare_files(
fp0_path: &str,
fp1_path: &str,
v0: u32,
v1: u32,
) -> io::Result<Vec<HashMap<String, String>>> {
let v0_hex = format!("{:02x}", v0);
let v1_hex = format!("{:02x}", v1);

let fp0_data = read_binary_file(fp0_path)?;
let fp1_data = read_binary_file(fp1_path)?;

let fp0_hex = binary_to_hex(&fp0_data);
let fp1_hex = binary_to_hex(&fp1_data);

let fp0_dict: HashMap<_, _> = fp0_hex.into_iter().collect();
let fp1_dict: HashMap<_, _> = fp1_hex.into_iter().collect();

let mut matches = vec![];

for (address, ln0) in &fp0_dict {
if let Some(ln1) = fp1_dict.get(address) {
if ln0.contains(&v0_hex) && ln1.contains(&v1_hex) {
let mut match_info = HashMap::new();
match_info.insert("address".to_string(), address.clone());
match_info.insert("data0".to_string(), ln0.clone());
match_info.insert("data1".to_string(), ln1.clone());
matches.push(match_info);
}
}
}

Ok(matches)
}

fn main() -> io::Result<()> {
let args: Vec<String> = env::args().collect();

if args.len() != 5 {
eprintln!("Usage: compare_files fp0.bin fp1.bin v0 v1");
return Ok(());
}

let fp0_path = &args[1];
let fp1_path = &args[2];
let v0 = args[3].parse::<u32>().expect("Invalid value for v0");
let v1 = args[4].parse::<u32>().expect("Invalid value for v1");

let matches = compare_files(fp0_path, fp1_path, v0, v1)?;
let output_json = serde_json::to_string_pretty(&matches).expect("Failed to serialize output");
println!("{}", output_json);

Ok(())
}

0 comments on commit 67d527b

Please sign in to comment.