1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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}");
}
|