Add rainbowutils to parse ranbow table files
parent
dd781209ff
commit
019ccce1cd
@ -1,2 +1,3 @@
|
|||||||
pub mod crypt;
|
pub mod crypt;
|
||||||
pub mod hash;
|
pub mod hash;
|
||||||
|
pub mod rainbowutils;
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
use byteorder::{BigEndian, ByteOrder, ReadBytesExt};
|
||||||
|
use rand::AsByteSliceMut;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufReader, Read};
|
||||||
|
use std::io::{Error, ErrorKind};
|
||||||
|
|
||||||
|
pub const BDF_HDR: &[u8; 11] = b"BDF\x01RAINBOW";
|
||||||
|
pub const NULL_BYTES: &[u8; 4] = &[0u8; 4];
|
||||||
|
|
||||||
|
pub struct BinaryDictionaryFile {
|
||||||
|
name: String,
|
||||||
|
reader: BufReader<File>,
|
||||||
|
metadata: Option<MetaChunk>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct GenericChunk {
|
||||||
|
length: u32,
|
||||||
|
name: String,
|
||||||
|
data: Vec<u8>,
|
||||||
|
crc: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct MetaChunk {
|
||||||
|
chunk_count: u32,
|
||||||
|
entries_per_chunk: u32,
|
||||||
|
entry_count: u32,
|
||||||
|
compression_method: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct HashEntry {
|
||||||
|
id: u32,
|
||||||
|
output_length: u32,
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct DataEntry {
|
||||||
|
plain: String,
|
||||||
|
hashes: HashMap<String, Vec<u8>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BinaryDictionaryFile {
|
||||||
|
fn new(reader: BufReader<File>) -> Self {
|
||||||
|
Self {
|
||||||
|
name: "".to_string(),
|
||||||
|
metadata: None,
|
||||||
|
reader,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_metadata(&mut self) -> Result<MetaChunk, Error> {
|
||||||
|
if !self.validate_header() {
|
||||||
|
return Err(Error::new(ErrorKind::InvalidData, "Invalid BDF Header!"));
|
||||||
|
}
|
||||||
|
let meta_chunk = self.next_chunk().as_meta_chunk();
|
||||||
|
self.metadata = Some(meta_chunk.clone());
|
||||||
|
|
||||||
|
Ok(meta_chunk)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validate_header(&mut self) -> bool {
|
||||||
|
let mut header = [0u8; 11];
|
||||||
|
let _ = self.reader.read(&mut header);
|
||||||
|
|
||||||
|
header == BDF_HDR.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_chunk(&mut self) -> GenericChunk {
|
||||||
|
let mut length_raw = [0u8; 4];
|
||||||
|
let _ = self.reader.read(&mut length_raw);
|
||||||
|
let length = BigEndian::read_u32(&mut length_raw);
|
||||||
|
let mut name_raw = [0u8; 4];
|
||||||
|
let _ = self.reader.read(&mut name_raw);
|
||||||
|
let name =
|
||||||
|
String::from_utf8(name_raw.to_vec()).expect("Failed to parse chunk name to string!");
|
||||||
|
let mut data = vec![0u8; length as usize];
|
||||||
|
let _ = self.reader.read(&mut data);
|
||||||
|
let mut crc_raw = [0u8; 4];
|
||||||
|
let _ = self.reader.read(&mut crc_raw);
|
||||||
|
let crc = BigEndian::read_u32(&mut crc_raw);
|
||||||
|
|
||||||
|
GenericChunk {
|
||||||
|
length,
|
||||||
|
name,
|
||||||
|
data,
|
||||||
|
crc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenericChunk {
|
||||||
|
fn as_meta_chunk(&self) -> MetaChunk {
|
||||||
|
let mut chunk_count_raw = self.data[0..4].to_vec();
|
||||||
|
let mut entries_per_chunk = self.data[4..8].to_vec();
|
||||||
|
let mut total_number_of_entries = self.data[8..12].to_vec();
|
||||||
|
let mut compression_method_raw = self.data[12..16].to_vec();
|
||||||
|
let chunk_count = BigEndian::read_u32(&mut chunk_count_raw);
|
||||||
|
let entries_per_chunk = BigEndian::read_u32(&mut entries_per_chunk);
|
||||||
|
let entry_count = BigEndian::read_u32(&mut total_number_of_entries);
|
||||||
|
let compression_method = if &compression_method_raw != NULL_BYTES {
|
||||||
|
Some(
|
||||||
|
String::from_utf8(compression_method_raw.to_vec())
|
||||||
|
.expect("Failed to parse compression method from meta string"),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
MetaChunk {
|
||||||
|
chunk_count,
|
||||||
|
entries_per_chunk,
|
||||||
|
entry_count,
|
||||||
|
compression_method,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue