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 { Vec::from(&data[offset..offset + size]) } fn toi(data: Vec) -> 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 { 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::(); 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}"); }