diff --git a/src/main.rs b/src/main.rs index 1b336f2..60010db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -226,7 +226,8 @@ fn main() { println!("\n==== Applying Patch To Binary ====\n"); patcher::patch_binary( - bytes, + bytes.to_vec(), + file_path.to_string(), &patch_file_path ); } diff --git a/src/patcher.rs b/src/patcher.rs index cd1944b..2b9aa42 100644 --- a/src/patcher.rs +++ b/src/patcher.rs @@ -4,23 +4,45 @@ // Description: Houses binary rewriting and patching functionality for chisel. use std::path; +use std::collections::HashMap; +use std::io::Write; use crate::util; -pub fn patch_binary(binary_contents: &Vec, patch_file_path: &String) { - parse_patch_file(patch_file_path); +pub fn patch_binary(binary_contents: Vec, binary_name: String, patch_file_path: &String) { - // If valid - // Apply patch - // else - // err + let patch_data: HashMap> = parse_patch_file(patch_file_path); + let mut bytes: Vec = binary_contents; + println!("Patch data read successfully, applying..."); + for patch in patch_data { + let start_offset = patch.0; + let mut i: usize = 0; + while i < (patch.1.len()) { + bytes[(start_offset + i) as usize] = patch.1[i]; + i += 1; + } + } + + println!("Done!"); + + let patched_file_name: String = binary_name + "_patched"; + + println!("Writing '{}' to disk...", patched_file_name); + + let mut file = std::fs::File::create(patched_file_name) + .expect("[Error] Could not write patched binary to disk"); + + file.write_all(&bytes) + .expect("[Error] Could not write to patched binary file"); + + file.flush(); } -fn parse_patch_file(patch_path: &String) { +fn parse_patch_file(patch_path: &String) -> HashMap>{ // Load the file from patch_binary() arg // Iterate through file, if line starts with # ignore // Otherwise, parse as such @@ -31,6 +53,7 @@ fn parse_patch_file(patch_path: &String) { println!("Patch file exists, reading '{}'...", patch_path); let contents = util::read_lines(patch_path.to_string()); + let mut patch_data: HashMap> = HashMap::new(); for line in contents { let unwrapped = line.unwrap(); @@ -38,14 +61,14 @@ fn parse_patch_file(patch_path: &String) { } else { let mut statement = unwrapped.split(":"); - let address: i32 = statement.next().unwrap().trim().parse::().unwrap(); + let address: usize = statement.next().unwrap().trim().parse::().unwrap(); let data: &str = statement.next().unwrap().trim(); if !data.is_empty() { if data.contains("\"") { // Value is a string literal let cleaned = data.replace("\"", ""); - let bytes = cleaned.as_bytes(); + let bytes: Vec = cleaned.as_bytes().to_vec(); print!("{}: ", address); @@ -56,11 +79,13 @@ fn parse_patch_file(patch_path: &String) { } println!(); + + patch_data.insert(address, bytes); } else { // Data is comma seperated list or a single value let byte_str: String = data.replace(",", ""); - let mut bytes: Vec = util::decode_hex(&byte_str).unwrap(); + let bytes: Vec = util::decode_hex(&byte_str).unwrap(); print!("{}: ", address); @@ -71,25 +96,17 @@ fn parse_patch_file(patch_path: &String) { } println!(); + + patch_data.insert(address, bytes); } } } } + + return patch_data; + } else { println!("[Error] Patch file '{}' is invalid or cannot be read, exiting...", patch_path); std::process::exit(0); } - - std::process::exit(0); -} - - -fn apply_patch() { - // Iterate through parsed patch information - // Find the address at start of line, then apply following data to section - // Make sure within size limits of data, otherwise boundary problems - - // Strings -> Iterate through characters specifically and parse them as individual ASCII chars -} - - +} \ No newline at end of file diff --git a/testing/hello_patched b/testing/hello_patched new file mode 100755 index 0000000..7cf478a Binary files /dev/null and b/testing/hello_patched differ diff --git a/testing/patches/hello.patch b/testing/patches/hello.patch index 7d1cd92..04a869b 100644 --- a/testing/patches/hello.patch +++ b/testing/patches/hello.patch @@ -1,3 +1,3 @@ -2002 : "Hello, World!" -20041 : DE,AD,BE,EF -45620 : 00,01,02,03 \ No newline at end of file +8196 : "Hello, Patch!" +#20041 : DE,AD,BE,EF +#45620 : 00,01,02,03 \ No newline at end of file diff --git a/testrun b/testrun new file mode 100644 index 0000000..b66834f --- /dev/null +++ b/testrun @@ -0,0 +1,508 @@ +File exists, reading 'testing/hello'... +Found ELF Magic Number... +Parsing File Header... + - Found 13 program header entries 56 bytes in length + - Found 31 section header entries 64 bytes in length + - Found .shstrtab section at index 30 + +==== File Header ==== +- Architecture: X86_64 +- Endian: Little +- ABI: System V +- Type: Shared object +- ISA: AMD x86-64 +- Entry Point: 0x1060 +- Program Offset: 0x40 +- Program Entry Size: 56 +- Number Program Entries: 13 +- Section Offset: 0x3698 +- Section Entry Size: 64 +- Number Section Entries: 31 + +Parsing Section Headers... + - Found .shstrtab section + +==== Sections ==== +[0] + - Type: SHT_NULL + - Flags: UNKNOWN + - Address: 0x00 + - Offset: 0x00 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[1] .interp + - Type: SHT_PROGBITS + - Flags: SHF_ALLOC + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[2] .note.gnu.property + - Type: SHT_NOTE + - Flags: SHF_ALLOC + - Address: 0x07 + - Offset: 0x07 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[3] .note.gnu.build-id + - Type: SHT_NOTE + - Flags: SHF_ALLOC + - Address: 0x07 + - Offset: 0x07 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[4] .note.ABI-tag + - Type: SHT_NOTE + - Flags: SHF_ALLOC + - Address: 0x07 + - Offset: 0x07 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[5] .gnu.hash + - Type: UNKNOWN + - Flags: SHF_ALLOC + - Address: 0x6ffffff6 + - Offset: 0x6ffffff6 + - Link Index: 6 + - Info Bytes: 0 + - Alignment: 0 + +[6] .dynsym + - Type: SHT_DYNSYM + - Flags: SHF_ALLOC + - Address: 0x0b + - Offset: 0x0b + - Link Index: 7 + - Info Bytes: 1 + - Alignment: 1 + +[7] .dynstr + - Type: SHT_STRTAB + - Flags: SHF_ALLOC + - Address: 0x03 + - Offset: 0x03 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[8] .gnu.version + - Type: UNKNOWN + - Flags: SHF_ALLOC + - Address: 0x6fffffff + - Offset: 0x6fffffff + - Link Index: 6 + - Info Bytes: 0 + - Alignment: 0 + +[9] .gnu.version_r + - Type: UNKNOWN + - Flags: SHF_ALLOC + - Address: 0x6ffffffe + - Offset: 0x6ffffffe + - Link Index: 7 + - Info Bytes: 1 + - Alignment: 1 + +[10] .rela.dyn + - Type: SHT_RELA + - Flags: SHF_ALLOC + - Address: 0x04 + - Offset: 0x04 + - Link Index: 6 + - Info Bytes: 0 + - Alignment: 0 + +[11] .rela.plt + - Type: SHT_RELA + - Flags: UNKNOWN + - Address: 0x04 + - Offset: 0x04 + - Link Index: 6 + - Info Bytes: 24 + - Alignment: 24 + +[12] .init + - Type: SHT_PROGBITS + - Flags: UNKNOWN + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[13] .plt + - Type: SHT_PROGBITS + - Flags: UNKNOWN + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[14] .plt.got + - Type: SHT_PROGBITS + - Flags: UNKNOWN + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[15] .plt.sec + - Type: SHT_PROGBITS + - Flags: UNKNOWN + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[16] .text + - Type: SHT_PROGBITS + - Flags: UNKNOWN + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[17] .fini + - Type: SHT_PROGBITS + - Flags: UNKNOWN + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[18] .rodata + - Type: SHT_PROGBITS + - Flags: SHF_ALLOC + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[19] .eh_frame_hdr + - Type: SHT_PROGBITS + - Flags: SHF_ALLOC + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[20] .eh_frame + - Type: SHT_PROGBITS + - Flags: SHF_ALLOC + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[21] .init_array + - Type: SHT_INIT_ARRAY + - Flags: UNKNOWN + - Address: 0x0e + - Offset: 0x0e + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[22] .fini_array + - Type: SHT_FINI_ARRAY + - Flags: UNKNOWN + - Address: 0x0f + - Offset: 0x0f + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[23] .dynamic + - Type: SHT_DYNAMIC + - Flags: UNKNOWN + - Address: 0x06 + - Offset: 0x06 + - Link Index: 7 + - Info Bytes: 0 + - Alignment: 0 + +[24] .got + - Type: SHT_PROGBITS + - Flags: UNKNOWN + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[25] .data + - Type: SHT_PROGBITS + - Flags: UNKNOWN + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[26] .bss + - Type: SHT_NOBITS + - Flags: UNKNOWN + - Address: 0x08 + - Offset: 0x08 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[27] .comment + - Type: SHT_PROGBITS + - Flags: UNKNOWN + - Address: 0x01 + - Offset: 0x01 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[28] .symtab + - Type: SHT_SYMTAB + - Flags: UNKNOWN + - Address: 0x02 + - Offset: 0x02 + - Link Index: 29 + - Info Bytes: 18 + - Alignment: 18 + +[29] .strtab + - Type: SHT_STRTAB + - Flags: UNKNOWN + - Address: 0x03 + - Offset: 0x03 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + +[30] .shstrtab + - Type: SHT_STRTAB + - Flags: UNKNOWN + - Address: 0x03 + - Offset: 0x03 + - Link Index: 0 + - Info Bytes: 0 + - Alignment: 0 + + +Parsing Program Segments... + +==== Program Segments ==== +[0] PT_PHDR + - Type: SHT_DYNAMIC + - Flags: 4 + - Offset: 0x40 + - Virtual Address: 0x40 + - Physical Address: 0x40 + - File Size: 728 + - Memory Size: 728 + - Alignment: 8 + +[1] PT_INTERP + - Type: SHT_STRTAB + - Flags: 4 + - Offset: 0x318 + - Virtual Address: 0x318 + - Physical Address: 0x318 + - File Size: 28 + - Memory Size: 28 + - Alignment: 1 + +[2] PT_LOAD + - Type: SHT_PROGBITS + - Flags: 4 + - Offset: 0x00 + - Virtual Address: 0x00 + - Physical Address: 0x00 + - File Size: 1576 + - Memory Size: 1576 + - Alignment: 4096 + +[3] PT_LOAD + - Type: SHT_PROGBITS + - Flags: 5 + - Offset: 0x1000 + - Virtual Address: 0x1000 + - Physical Address: 0x1000 + - File Size: 377 + - Memory Size: 377 + - Alignment: 4096 + +[4] PT_LOAD + - Type: SHT_PROGBITS + - Flags: 4 + - Offset: 0x2000 + - Virtual Address: 0x2000 + - Physical Address: 0x2000 + - File Size: 244 + - Memory Size: 244 + - Alignment: 4096 + +[5] PT_LOAD + - Type: SHT_PROGBITS + - Flags: 6 + - Offset: 0x2db8 + - Virtual Address: 0x3db8 + - Physical Address: 0x3db8 + - File Size: 600 + - Memory Size: 608 + - Alignment: 4096 + +[6] PT_DYNAMIC + - Type: SHT_SYMTAB + - Flags: 6 + - Offset: 0x2dc8 + - Virtual Address: 0x3dc8 + - Physical Address: 0x3dc8 + - File Size: 496 + - Memory Size: 496 + - Alignment: 8 + +[7] PT_NOTE + - Type: SHT_RELA + - Flags: 4 + - Offset: 0x338 + - Virtual Address: 0x338 + - Physical Address: 0x338 + - File Size: 48 + - Memory Size: 48 + - Alignment: 8 + +[8] PT_NOTE + - Type: SHT_RELA + - Flags: 4 + - Offset: 0x368 + - Virtual Address: 0x368 + - Physical Address: 0x368 + - File Size: 68 + - Memory Size: 68 + - Alignment: 4 + +[9] UNKNOWN + - Type: UNKNOWN + - Flags: 4 + - Offset: 0x338 + - Virtual Address: 0x338 + - Physical Address: 0x338 + - File Size: 48 + - Memory Size: 48 + - Alignment: 8 + +[10] UNKNOWN + - Type: UNKNOWN + - Flags: 4 + - Offset: 0x2014 + - Virtual Address: 0x2014 + - Physical Address: 0x2014 + - File Size: 52 + - Memory Size: 52 + - Alignment: 4 + +[11] UNKNOWN + - Type: UNKNOWN + - Flags: 6 + - Offset: 0x00 + - Virtual Address: 0x00 + - Physical Address: 0x00 + - File Size: 0 + - Memory Size: 0 + - Alignment: 16 + +[12] UNKNOWN + - Type: UNKNOWN + - Flags: 4 + - Offset: 0x2db8 + - Virtual Address: 0x3db8 + - Physical Address: 0x3db8 + - File Size: 584 + - Memory Size: 584 + - Alignment: 1 + +==== Text Section Analysis ==== + +0000000000001060 endbr64 +0000000000001064 xor ebp,ebp +0000000000001066 mov r9,rdx +0000000000001069 pop rsi +000000000000106A mov rdx,rsp +000000000000106D and rsp,0`FFFF`FFFF`FFFF`FFF0h +0000000000001071 push rax +0000000000001072 push rsp +0000000000001073 xor r8d,r8d +0000000000001076 xor ecx,ecx +0000000000001078 lea rdi,[rel 1149h] +000000000000107F call qword [rel 3FD8h] +0000000000001085 hlt +0000000000001086 nop word [rax+rax] +0000000000001090 lea rdi,[rel 4010h] +0000000000001097 lea rax,[rel 4010h] +000000000000109E cmp rax,rdi +00000000000010A1 je short 0000`0000`0000`10B8h +00000000000010A3 mov rax,[rel 3FE0h] +00000000000010AA test rax,rax +00000000000010AD je short 0000`0000`0000`10B8h +00000000000010AF jmp rax +00000000000010B1 nop dword [rax] +00000000000010B8 ret +00000000000010B9 nop dword [rax] +00000000000010C0 lea rdi,[rel 4010h] +00000000000010C7 lea rsi,[rel 4010h] +00000000000010CE sub rsi,rdi +00000000000010D1 mov rax,rsi +00000000000010D4 shr rsi,3Fh +00000000000010D8 sar rax,3 +00000000000010DC add rsi,rax +00000000000010DF sar rsi,1 +00000000000010E2 je short 0000`0000`0000`10F8h +00000000000010E4 mov rax,[rel 3FF0h] +00000000000010EB test rax,rax +00000000000010EE je short 0000`0000`0000`10F8h +00000000000010F0 jmp rax +00000000000010F2 nop word [rax+rax] +00000000000010F8 ret +00000000000010F9 nop dword [rax] +0000000000001100 endbr64 +0000000000001104 cmp byte [rel 4010h],0 +000000000000110B jne short 0000`0000`0000`1138h +000000000000110D push rbp +000000000000110E cmp qword [rel 3FF8h],0 +0000000000001116 mov rbp,rsp +0000000000001119 je short 0000`0000`0000`1127h +000000000000111B mov rdi,[rel 4008h] +0000000000001122 call 0000`0000`0000`1040h +0000000000001127 call 0000`0000`0000`1090h +000000000000112C mov byte [rel 4010h],1 +0000000000001133 pop rbp +0000000000001134 ret +0000000000001135 nop dword [rax] +0000000000001138 ret +0000000000001139 nop dword [rax] +0000000000001140 endbr64 +0000000000001144 jmp 0000`0000`0000`10C0h +0000000000001149 endbr64 +000000000000114D push rbp +000000000000114E mov rbp,rsp +0000000000001151 lea rax,[rel 2004h] +0000000000001158 mov rdi,rax +000000000000115B mov eax,0 +0000000000001160 call 0000`0000`0000`1050h +0000000000001165 mov eax,0 +000000000000116A pop rbp