()
| 6 | use std::io::BufWriter; |
| 7 | |
| 8 | fn main() -> Result<()> { |
| 9 | let src_path = "shellcode\\target\\x86_64-pc-windows-msvc\\release\\shellcode.exe"; |
| 10 | let mut file = File::open(src_path)?; |
| 11 | let mut buffer = Vec::new(); |
| 12 | file.read_to_end(&mut buffer)?; |
| 13 | let pe = PE::parse(&mut buffer)?; |
| 14 | let standard_fileds = pe.header.optional_header.unwrap().standard_fields; |
| 15 | let entry_offset = standard_fileds.address_of_entry_point - standard_fileds.base_of_code; |
| 16 | for section in pe.sections { |
| 17 | let name = String::from_utf8(section.name.to_vec())?; |
| 18 | if !name.starts_with(".text") { |
| 19 | continue; |
| 20 | } |
| 21 | let start = section.pointer_to_raw_data as usize; |
| 22 | let size = section.size_of_raw_data as usize; |
| 23 | let dst_path = "shellcode\\target\\x86_64-pc-windows-msvc\\release\\shellcode.bin"; |
| 24 | let shellcode = File::create(dst_path)?; |
| 25 | let mut buf_writer = BufWriter::new(shellcode); |
| 26 | println!("[*] section text addr: 0x{:x}, size: 0x{:x}", start, size); |
| 27 | println!("[*] entry offset: 0x{:x}", entry_offset); |
| 28 | println!("== before patch =="); |
| 29 | show_disassemble(&buffer[start..start + size], 5); |
| 30 | if entry_offset >= 0x100 { |
| 31 | buffer[0 + start] = 0xe9; |
| 32 | let hi = (entry_offset - 2) / 0x100; |
| 33 | let li = (entry_offset - 2) % 0x100; |
| 34 | dbg!(hi, li); |
| 35 | buffer[1 + start] = li as _; |
| 36 | buffer[2 + start] = hi as _; |
| 37 | buffer[3 + start] = 0 as _; |
| 38 | buffer[4 + start] = 0 as _; |
| 39 | } else if entry_offset >= 0x80 { |
| 40 | buffer[0 + start] = 0xe9; |
| 41 | buffer[1 + start] = (entry_offset - 5) as _; |
| 42 | buffer[2 + start] = 0 as _; |
| 43 | buffer[3 + start] = 0 as _; |
| 44 | buffer[4 + start] = 0 as _; |
| 45 | } else { |
| 46 | buffer[0 + start] = 0xeb; |
| 47 | buffer[1 + start] = (entry_offset - 2) as _; |
| 48 | } |
| 49 | println!("== after patch =="); |
| 50 | show_disassemble(&buffer[start..start + size], 5); |
| 51 | for i in start..start + size { |
| 52 | buf_writer.write(&[buffer[i]])?; |
| 53 | } |
| 54 | buf_writer.flush().unwrap(); |
| 55 | println!("done! shellcode saved in {}", dst_path); |
| 56 | } |
| 57 | Ok(()) |
| 58 | } |
| 59 | pub fn show_disassemble(bytes: &[u8], max_line: u32) { |
| 60 | let mut decoder = Decoder::new(EXAMPLE_CODE_BITNESS, bytes, DecoderOptions::NONE); |
| 61 | decoder.set_ip(EXAMPLE_CODE_RIP); |
nothing calls this directly
no test coverage detected