diff options
| author | Andrew Guschin <guschin@altlinux.org> | 2024-02-19 20:44:55 +0400 |
|---|---|---|
| committer | Andrew Guschin <guschin@altlinux.org> | 2024-02-19 20:44:55 +0400 |
| commit | 8300860bdc3af55dcc6dee56c4963bb5e8f274ec (patch) | |
| tree | 056ec80dd00e86399c0f601340ae9c3f79a1e7c8 /executable-password/src | |
Diffstat (limited to 'executable-password/src')
| -rw-r--r-- | executable-password/src/main.rs | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/executable-password/src/main.rs b/executable-password/src/main.rs new file mode 100644 index 0000000..612cef5 --- /dev/null +++ b/executable-password/src/main.rs @@ -0,0 +1,125 @@ +use memmap2::Mmap; +use sha2::{Digest, Sha256}; +use std::arch::asm; +use std::fs::OpenOptions; + +#[derive(Debug)] +#[repr(C)] +struct SectionHeader { + name_offset: u32, + header_type: u32, + flags: u64, + virtual_addr: u64, + offset: u64, + size: u64, + link: u32, + info: u32, + addralign: u64, + entry_size: u64, +} + +fn password_check() { + println!("Hello!"); + unsafe { + asm!("jmp 0"); + }; +} + +fn field(data: &Mmap, offset: usize, size: usize) -> Vec<u8> { + Vec::from(&data[offset..offset + size]) +} + +fn toi(data: Vec<u8>) -> u64 { + let mut res: u64 = 0; + for (i, byte) in data.iter().enumerate() { + res |= (*byte as u64) << (i * 8); + } + res +} + +fn _compute_digest( + data: &Mmap, + skip_offset: usize, + skip_size: usize, +) -> Vec<u8> { + let mut hasher = Sha256::new(); + let mut offset = 0; + while offset != data.len() { + let end = std::cmp::min(offset + 1024, data.len()); + let sz = end - offset; + let mut buf = [0; 1024]; + buf[..sz].clone_from_slice(&data[offset..end]); + + let skip_end = skip_offset + skip_size; + if skip_offset >= offset && skip_offset <= end { + for i in skip_offset..std::cmp::min(end, skip_end) { + buf[i - skip_offset] = 0; + } + } + if skip_end >= offset && skip_end <= end { + for i in offset..skip_end { + buf[i - offset] = 0; + } + } + hasher.update(buf); + offset = end; + } + Vec::from(&hasher.finalize()[..]) +} + +fn get_checksum_field(data: &Mmap) -> Option<(usize, usize)> { + // TODO: Учитывать битность бинарника + let shoff = toi(field(data, 0x28, 8)) as usize; + let section_header_num = toi(field(data, 0x3C, 2)) as usize; + let names_idx = toi(field(data, 0x3E, 2)) as usize; + let names_table_offset = + toi(field(data, shoff + 0x40 * names_idx + 0x18, 8)) as u32; + + for i in 0..section_header_num { + let header: SectionHeader = unsafe { + const SIZE: usize = std::mem::size_of::<SectionHeader>(); + let offset = shoff + SIZE * i; + let header_raw: [u8; SIZE] = + data[offset..offset + SIZE].try_into().unwrap(); + std::mem::transmute(header_raw) + }; + if header.header_type == 0 { + continue; + } + let mut name = Vec::new(); + let mut name_idx = (names_table_offset + header.name_offset) as usize; + while data[name_idx] != 0 { + name.push(data[name_idx] as char); + name_idx += 1; + } + let name: String = name.into_iter().collect(); + if name == ".text" { + println!(".text offset = {}", header.offset); + } + } + None +} + +fn main() { + let exe_path = std::env::args().nth(1).unwrap(); + println!("Запускается программа по следующему пути:"); + println!("{exe_path}"); + + let file = OpenOptions::new() + .read(true) + .write(false) + .create(false) + .open(&exe_path) + .unwrap(); + let mmap = unsafe { Mmap::map(&file).unwrap() }; + + let o = std::mem::size_of_val(&password_check); + println!("size of password_check(): {o}"); + + // let (checksum_offset, checksum_size) = get_checksum_field(&mmap).unwrap(); + // let checksum = &mmap[checksum_offset..checksum_offset + checksum_size]; + let entrypoint: [u8; 8] = mmap[0x18..0x18 + 8].try_into().unwrap(); + let entrypoint: u64 = unsafe { std::mem::transmute(entrypoint) }; + let _ = get_checksum_field(&mmap); + println!("{entrypoint}"); +} |