From 8300860bdc3af55dcc6dee56c4963bb5e8f274ec Mon Sep 17 00:00:00 2001 From: Andrew Guschin Date: Mon, 19 Feb 2024 20:44:55 +0400 Subject: initial commit --- .gitignore | 17 ++++++ elf-layout.py | 96 ++++++++++++++++++++++++++++++ executable-password/Cargo.lock | 103 ++++++++++++++++++++++++++++++++ executable-password/Cargo.toml | 10 ++++ executable-password/rustfmt.toml | 1 + executable-password/src/main.rs | 125 +++++++++++++++++++++++++++++++++++++++ hello.c | 5 ++ 7 files changed, 357 insertions(+) create mode 100644 .gitignore create mode 100644 elf-layout.py create mode 100644 executable-password/Cargo.lock create mode 100644 executable-password/Cargo.toml create mode 100644 executable-password/rustfmt.toml create mode 100644 executable-password/src/main.rs create mode 100644 hello.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..43b1cdf --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +.* +!.gitignore +target +control_file + +*.aux +*.fls +*.log +*.out +*.fdb_latexmk +*.gz +*.thm +*.toc +*.bbl +*.blg +*.md +_minted* diff --git a/elf-layout.py b/elf-layout.py new file mode 100644 index 0000000..ee8530b --- /dev/null +++ b/elf-layout.py @@ -0,0 +1,96 @@ +import sys + +if len(sys.argv) < 2: + print("First arg should be name of the binary") + exit() + +with open(sys.argv[1], "rb") as f: + data = f.read() + +def toi(val): + res = 0 + shift = 0 + for i in val: + res += i << shift + shift += 8 + return res + + +def field(offset, size): + return data[offset:offset + size] + +magic = field(0x00, 4) +plat_bit = field(0x04, 1) +endian = field(0x05, 1) +ver = field(0x06, 1) +abi = field(0x07, 1) +abi_ver = field(0x08, 1) +padding = field(0x09, 7) +obj_t = field(0x10, 2) +isa = field(0x12, 2) +orig_ver = field(0x14, 4) + +bit32 = toi(plat_bit) == 1 +bit64 = toi(plat_bit) == 2 + +# expect 64-bit +entry = field(0x18, 8) +phoff = field(0x20, 8) +shoff = field(0x28, 8) +flags = field(0x30, 4) +ehsize = field(0x34, 2) + +phentsize = field(0x36, 2) +phnum = field(0x38, 2) + +shentsize = field(0x3a, 2) +shnum = field(0x3c, 2) +shstrndx = field(0x3e, 2) + +print(data[0x3e]) +print(list(shstrndx)) +shstrndx = toi(shstrndx) +shnum = toi(shnum) +shoff = toi(shoff) + +strshtab_off = 0 + +for i in range(shnum): + sh_name = toi(field(shoff + 0x40 * i + 0x00, 4)) + sh_type = toi(field(shoff + 0x40 * i + 0x04, 4)) + sh_flags = toi(field(shoff + 0x40 * i + 0x08, 8)) + sh_addr = toi(field(shoff + 0x40 * i + 0x10, 8)) + sh_offset = toi(field(shoff + 0x40 * i + 0x18, 8)) + sh_size = toi(field(shoff + 0x40 * i + 0x20, 8)) + sh_link = toi(field(shoff + 0x40 * i + 0x28, 4)) + sh_info = toi(field(shoff + 0x40 * i + 0x2c, 4)) + sh_addralign = toi(field(shoff + 0x40 * i + 0x30, 8)) + sh_entsize = toi(field(shoff + 0x40 * i + 0x38, 8)) + + if i == shstrndx: + strshtab_off = sh_offset + break + +for i in range(shnum): + sh_name = toi(field(shoff + 0x40 * i + 0x00, 4)) + sh_type = toi(field(shoff + 0x40 * i + 0x04, 4)) + sh_flags = toi(field(shoff + 0x40 * i + 0x08, 8)) + sh_addr = toi(field(shoff + 0x40 * i + 0x10, 8)) + sh_offset = toi(field(shoff + 0x40 * i + 0x18, 8)) + sh_size = toi(field(shoff + 0x40 * i + 0x20, 8)) + sh_link = toi(field(shoff + 0x40 * i + 0x28, 4)) + sh_info = toi(field(shoff + 0x40 * i + 0x2c, 4)) + sh_addralign = toi(field(shoff + 0x40 * i + 0x30, 8)) + sh_entsize = toi(field(shoff + 0x40 * i + 0x38, 8)) + + if sh_type == 0: + continue + # print(sh_name) + name = [] + name_idx = strshtab_off + sh_name + while data[name_idx] != 0: + name.append(data[name_idx]) + name_idx += 1 + name = bytes(name).decode() + # print(name) + diff --git a/executable-password/Cargo.lock b/executable-password/Cargo.lock new file mode 100644 index 0000000..3710ef0 --- /dev/null +++ b/executable-password/Cargo.lock @@ -0,0 +1,103 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cpufeatures" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "executable-password" +version = "0.1.0" +dependencies = [ + "memmap2", + "sha2", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "libc" +version = "0.2.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" diff --git a/executable-password/Cargo.toml b/executable-password/Cargo.toml new file mode 100644 index 0000000..be450bf --- /dev/null +++ b/executable-password/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "executable-password" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +memmap2 = "0.5.10" +sha2 = "0.10.6" diff --git a/executable-password/rustfmt.toml b/executable-password/rustfmt.toml new file mode 100644 index 0000000..df99c69 --- /dev/null +++ b/executable-password/rustfmt.toml @@ -0,0 +1 @@ +max_width = 80 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 { + 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}"); +} diff --git a/hello.c b/hello.c new file mode 100644 index 0000000..d7ffcbc --- /dev/null +++ b/hello.c @@ -0,0 +1,5 @@ +#include + +int main() { + puts("Hello, world\n"); +} -- cgit v1.2.3