From ab0f273cd907ef43077e3f57b23942eaf846a1b7 Mon Sep 17 00:00:00 2001 From: Garrett Dickinson Date: Thu, 27 Apr 2023 11:08:54 -0500 Subject: [PATCH] Add support for ELF code injection --- notes/code_injection.md | 6 + notes/todo.md | 10 +- src/elf.rs | 8 +- src/main.rs | 36 +++-- src/patcher.rs | 173 +++++++++++++---------- src/patcher.rs.bak | 111 +++++++++++++++ src/util.rs | 163 ++++++++++++++++----- testing/elfpatching/hello_patch.bin | Bin 0 -> 70 bytes testing/elfpatching/hello_patch.s | 32 +++++ testing/elfpatching/login | Bin 0 -> 52976 bytes testing/{hello_patched => hello.patched} | Bin 15960 -> 16030 bytes testing/hello32 | Bin 14940 -> 0 bytes testing/patches/hello.patch | 14 -- testing/src/functions.c | 12 -- testing/src/hello.s | 46 ------ 15 files changed, 413 insertions(+), 198 deletions(-) create mode 100644 notes/code_injection.md create mode 100644 src/patcher.rs.bak create mode 100644 testing/elfpatching/hello_patch.bin create mode 100644 testing/elfpatching/hello_patch.s create mode 100755 testing/elfpatching/login rename testing/{hello_patched => hello.patched} (96%) delete mode 100755 testing/hello32 delete mode 100644 testing/patches/hello.patch delete mode 100644 testing/src/functions.c delete mode 100644 testing/src/hello.s diff --git a/notes/code_injection.md b/notes/code_injection.md new file mode 100644 index 0000000..dd35642 --- /dev/null +++ b/notes/code_injection.md @@ -0,0 +1,6 @@ +# ELF Code injection notes + +- Locate PT_NOTE segments in binary +- Locate a suitable `.note.*` section for replacing code +- Modify the injection code section type from `SHT_NOTE` to `SHT_PROGBITS` +- Update relevant start, offset, and end addresses for new section \ No newline at end of file diff --git a/notes/todo.md b/notes/todo.md index 013aa18..361ef3e 100644 --- a/notes/todo.md +++ b/notes/todo.md @@ -1,9 +1,9 @@ -To Do +# To Do -Code injection - - Have a script with 3 functions, (main, funcA, funcB), and replace refs to funcA with funcB - - Trampoline definitions of a function to a new modified function that gets places in memory - - +## Code injection +- Have a script with 3 functions, (main, funcA, funcB), and replace refs to funcA with funcB +- Trampoline definitions of a function to a new modified function that gets places in memory Injected code: 0x680 + Call: 0x1160 \ No newline at end of file diff --git a/src/elf.rs b/src/elf.rs index 0b495b0..81431e9 100644 --- a/src/elf.rs +++ b/src/elf.rs @@ -121,8 +121,9 @@ pub struct FileHeader { } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ProgramHeader { + pub id: u16, pub program_type: u32, pub flags: u32, pub offset: u64, @@ -134,9 +135,10 @@ pub struct ProgramHeader { } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct SectionHeader { - pub name: u32, + pub id: u16, + pub name_idx: u32, pub section_type: u32, pub flags: u64, pub addr: u64, diff --git a/src/main.rs b/src/main.rs index 60010db..564da70 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,7 @@ mod patcher; fn main() { // Collect our execution args let args: Vec = env::args().collect(); - let mut patch_mode: bool = false; + let mut inject_mode: bool = false; let mut patch_file_path: &String = &"".to_string(); // Grab our filepath from our options @@ -34,7 +34,7 @@ fn main() { if &args.len() > &2 { if &args[2] == "-p" { if &args.len() >= &4 { - patch_mode = true; + inject_mode = true; patch_file_path = &args[3]; } else { util::print_help(); @@ -87,6 +87,7 @@ fn main() { let shstrtab_section: elf::SectionHeader = util::build_section_header( bytes, shstrtab_offset as usize, + file_header.shstrndx, file_header.is_x86_64 ); @@ -104,17 +105,18 @@ fn main() { let mut section_table_count: i32 = 0; // Iterate through number of section headers - for _ in 0..file_header.shnum { + for i in 0..file_header.shnum { // Build section header data structure let section_header: elf::SectionHeader = util::build_section_header( bytes, section_table_offset as usize, + i, file_header.is_x86_64 ); // Determine the section name for each section using the shstrtab data - let section_name: String = util::parse_section_name(&shstrtab_data, section_header.name as usize); + let section_name: String = util::parse_section_name(&shstrtab_data, section_header.name_idx as usize); util::pp_section_header(§ion_header, section_table_count, §ion_name); @@ -131,19 +133,25 @@ fn main() { let mut program_table_offset = file_header.phoff; let mut program_table_count: i32 = 0; + let mut pt_note_offset: usize = 0; // Iterate through number of Program Headers - for _ in 0..file_header.phnum { + for i in 0..file_header.phnum { // Build Program Header data structure let program_header: elf::ProgramHeader = util::build_program_header( bytes, program_table_offset as usize, + i, file_header.is_x86_64 ); // Parse the program name using the program type let program_name: String = util::parse_program_segment_type(program_header.program_type); + if (program_name == "PT_NOTE") && (pt_note_offset == 0) { + pt_note_offset = program_table_offset as usize; + } + util::pp_program_header(&program_header, program_table_count, &program_name); // Update the program header table offset counter based on the program header size @@ -151,6 +159,13 @@ fn main() { program_table_count += 1; } + let note_segment: elf::ProgramHeader = util::build_program_header( + bytes, + pt_note_offset, + 0, + file_header.is_x86_64 + ); + // Now that we have all the sections, spit out the .text section and start a linear disassembly let text_section: &elf::SectionHeader = section_table_map.get(".text").unwrap(); @@ -221,14 +236,17 @@ fn main() { } - if patch_mode { + if inject_mode { - println!("\n==== Applying Patch To Binary ====\n"); + println!("\n==== Injecting Payload To Binary ====\n"); patcher::patch_binary( bytes.to_vec(), file_path.to_string(), - &patch_file_path + &patch_file_path, + &file_header, + section_table_map, + note_segment ); } @@ -238,7 +256,7 @@ fn main() { } } } else { - println!("[Error] '{}' does not exist", file_path); + println!("[Error] File '{}' does not exist", file_path); exit(-1); } diff --git a/src/patcher.rs b/src/patcher.rs index dd30245..b0df2d4 100644 --- a/src/patcher.rs +++ b/src/patcher.rs @@ -4,105 +4,124 @@ // Description: Houses binary rewriting and patching functionality for chisel. use std::path; +use std::fs; use std::collections::HashMap; use std::io::Write; +use std::io::Error; use crate::util; +use crate::elf; -pub fn patch_binary(binary_contents: Vec, binary_name: String, patch_file_path: &String) { +pub fn patch_binary( + binary_contents: Vec, + binary_name: String, + patch_file_path: &String, + file_header: &elf::FileHeader, + section_header_map: HashMap, + note_segment: elf::ProgramHeader) { - let patch_data: HashMap> = parse_patch_file(patch_file_path); - let mut bytes: Vec = binary_contents; - println!("Patch data read successfully, applying..."); + let patch_result: Result,Error> = read_patch_file(patch_file_path); + let patch_data: &Vec = &patch_result.as_ref().unwrap(); + + let mut program_data: Vec = binary_contents; - 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!"); + // Apply patch to end of binary + println!("Patch data read successfully, injecting at end of binary..."); - let patched_file_name: String = binary_name + "_patched"; + let injection_offset: usize = program_data.len(); + let injection_size: usize = patch_data.len(); + let injection_addr: usize = injection_offset; - println!("Writing '{}' to disk...", patched_file_name); + program_data.extend_from_slice(patch_data); - let mut file = std::fs::File::create(patched_file_name) + print!("Done!"); + + + // Locate a note segment + println!("Pulling .note.ABI-tag segment data..."); + let note_section: &elf::SectionHeader = section_header_map.get(".note.ABI-tag") + .expect("[Error] Failed to pull ABI-tag section from binary!"); + print!("Done!\n"); + + println!("Note section address: {:#04x}", note_section.addr); + println!("Note section offset: {:#04x}", note_section.offset); + println!("Note section size: {}", note_section.size); + println!(""); + println!("Injected address: {:#04x}", injection_addr); + println!("Injected section offset: {:#04x}", injection_offset); + println!("Injected section size: {}", injection_size); + + + // Rewrite the section header + let mut injected_section: elf::SectionHeader = elf::SectionHeader::from(note_section.clone()); + + injected_section.section_type = 1; + injected_section.addr = injection_addr as u64; + injected_section.offset = injection_offset as u64; + injected_section.size = injection_size as u64; + + util::overwrite_section_header( + &mut program_data, + file_header.shoff as usize, + file_header.shentsize as usize, + injected_section.id as usize, + &injected_section, + file_header.is_x86_64 + ); + + + // + // Rewrite the section header + let mut injected_segment: elf::ProgramHeader = elf::ProgramHeader::from(note_segment.clone()); + + injected_segment.program_type = 1; + injected_segment.offset = injection_offset as u64; + injected_segment.vaddr = injection_offset as u64; + injected_segment.paddr = injection_offset as u64; + injected_segment.filesz = injection_size as u64; + injected_segment.memsz = injection_size as u64; + injected_segment.flags = 5; + injected_segment.align = 0x1000; + + util::overwrite_segment_header( + &mut program_data, + file_header.shoff as usize, + file_header.shentsize as usize, + injected_section.id as usize, + &injected_section, + file_header.is_x86_64 + ); + + + + + util::overwrite_entrypoint(&mut program_data, injection_offset); + + + // Spit everything back out + let out_file_name: String = binary_name + ".patched"; + + println!("Writing '{}' to disk...", out_file_name); + + let mut file = std::fs::File::create(out_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.write_all(&program_data) + .expect("[Error] Could not write to patched binary data file"); } -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 - // [ADDRESS] [SPACE] [HEX],[HEX],[HEX],.... - // [ADDRESS] [SPACE] [STRING] +fn read_patch_file(patch_path: &String) -> Result, std::io::Error> { - if path::Path::new(patch_path).exists() && patch_path.ends_with(".patch") { + if path::Path::new(patch_path).exists() && patch_path.ends_with(".bin") { println!("Patch file exists, reading '{}'...", patch_path); - let contents = util::read_lines(patch_path.to_string()); - let mut patch_data: HashMap> = HashMap::new(); + let contents: Result, std::io::Error> = fs::read(patch_path); - for line in contents { - let unwrapped = line.unwrap(); - if unwrapped.trim().starts_with("#") || unwrapped.is_empty() { - //Skip - } else { - let mut statement = unwrapped.split(":"); - let address: usize = util::hex_to_int(statement.next().unwrap().trim()).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: Vec = cleaned.as_bytes().to_vec(); - - print!("{}: ", address); - - let mut i = 0; - while i < bytes.len() { - print!("{} ", bytes[i]); - i = i + 1; - } - - println!(); - - patch_data.insert(address, bytes); - - } else { - // Data is comma seperated list or a single value - let byte_str: String = data.replace(",", ""); - let bytes: Vec = util::hex_to_buff(&byte_str).unwrap(); - - print!("{}: ", address); - - let mut i = 0; - while i < bytes.len() { - print!("{} ", bytes[i]); - i = i + 1; - } - - println!(); - - patch_data.insert(address, bytes); - } - } - } - } - - return patch_data; + return contents; } else { println!("[Error] Patch file '{}' is invalid or cannot be read, exiting...", patch_path); diff --git a/src/patcher.rs.bak b/src/patcher.rs.bak new file mode 100644 index 0000000..dd30245 --- /dev/null +++ b/src/patcher.rs.bak @@ -0,0 +1,111 @@ +// patcher.rs +// Author: Garrett Dickinson +// Created: 04/06/2023 +// 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, binary_name: String, patch_file_path: &String) { + + 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"); + +} + + +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 + // [ADDRESS] [SPACE] [HEX],[HEX],[HEX],.... + // [ADDRESS] [SPACE] [STRING] + + if path::Path::new(patch_path).exists() && patch_path.ends_with(".patch") { + 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(); + if unwrapped.trim().starts_with("#") || unwrapped.is_empty() { + //Skip + } else { + let mut statement = unwrapped.split(":"); + let address: usize = util::hex_to_int(statement.next().unwrap().trim()).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: Vec = cleaned.as_bytes().to_vec(); + + print!("{}: ", address); + + let mut i = 0; + while i < bytes.len() { + print!("{} ", bytes[i]); + i = i + 1; + } + + println!(); + + patch_data.insert(address, bytes); + + } else { + // Data is comma seperated list or a single value + let byte_str: String = data.replace(",", ""); + let bytes: Vec = util::hex_to_buff(&byte_str).unwrap(); + + print!("{}: ", address); + + let mut i = 0; + while i < bytes.len() { + print!("{} ", bytes[i]); + i = i + 1; + } + + 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); + } +} \ No newline at end of file diff --git a/src/util.rs b/src/util.rs index cf47695..9b9f5f4 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,9 +5,9 @@ // functions. use std::mem; -use std::io::{self, BufReader, BufRead}; -use std::fs::File; -use std::num::ParseIntError; +// use std::io::{self, BufReader, BufRead}; +// use std::fs::File; +// use std::num::ParseIntError; use crate::elf::{self, EndianType, ArchitectureType}; @@ -43,7 +43,7 @@ pub fn build_file_header(data: &Vec) -> elf::FileHeader { } -pub fn build_program_header(data: &Vec, phoffset: usize, is_x86_64: bool) -> elf::ProgramHeader { +pub fn build_program_header(data: &Vec, phoffset: usize, id: u16, is_x86_64: bool) -> elf::ProgramHeader { // Cast the supplied is_x86_64 bool to an array offset // 0 : x86 @@ -51,6 +51,7 @@ pub fn build_program_header(data: &Vec, phoffset: usize, is_x86_64: bool) -> let arch: usize = is_x86_64.into(); let program_header: elf::ProgramHeader = elf::ProgramHeader { + id: id, program_type: u32_from_buffer(data, phoffset + elf::PH_TYPE_OFFSET as usize), flags: u32_from_buffer(data, phoffset + elf::PH_FLAGS_OFFSET[arch] as usize), offset: u64_from_buffer(data, phoffset + elf::PH_OFFSET_OFFSET[arch] as usize), @@ -65,7 +66,48 @@ pub fn build_program_header(data: &Vec, phoffset: usize, is_x86_64: bool) -> } -pub fn build_section_header(data: &Vec, shoffset: usize, is_x86_64: bool) -> elf::SectionHeader { +pub fn overwrite_segment_header(program_data: &mut Vec, + stoffset: usize, + shentsize: usize, + shentidx: usize, + new_section: &elf::SectionHeader, + is_x86_64: bool) { + +// Cast the supplied is_x86_64 bool to an array offset +// 0 : x86 +// 1 : x64 +let arch: usize = is_x86_64.into(); + +println!("stoffset {}", stoffset); +println!("shentsize {}", shentsize); +println!("shentidx {}", shentidx); + +let section_addr_offset: usize = stoffset + (shentsize * shentidx) + elf::SH_ADDR_OFFSET[arch] as usize; +let section_offset_offset: usize = stoffset + (shentsize * shentidx) + elf::SH_OFFSET_OFFSET[arch] as usize; +let section_size_offset: usize = stoffset + (shentsize * shentidx) + elf::SH_SIZE_OFFSET[arch] as usize; +let section_type_offset: usize = stoffset + (shentsize * shentidx) + elf::SH_TYPE_OFFSET as usize; + +program_data[section_addr_offset..section_addr_offset+8].copy_from_slice( +&new_section.addr.to_ne_bytes().to_vec()); +println!("Overwriting section addr with {:#04x}", new_section.addr); + +program_data[section_offset_offset..section_offset_offset+8].copy_from_slice( +&new_section.offset.to_ne_bytes().to_vec()); +println!("Overwriting section offset with {:#04x}", new_section.offset as usize); + +program_data[section_size_offset..section_size_offset+8].copy_from_slice( +&new_section.size.to_ne_bytes().to_vec()); +println!("Overwriting section size with {:#04x}", new_section.size as usize); + +program_data[section_type_offset..section_type_offset+4].copy_from_slice( +&new_section.section_type.to_ne_bytes().to_vec()); +println!("Overwriting section type with {:#04x}", new_section.section_type as usize); + +// return section_header; +} + + +pub fn build_section_header(data: &Vec, stoffset: usize, id: u16, is_x86_64: bool) -> elf::SectionHeader { // Cast the supplied is_x86_64 bool to an array offset // 0 : x86 @@ -73,22 +115,74 @@ pub fn build_section_header(data: &Vec, shoffset: usize, is_x86_64: bool) -> let arch: usize = is_x86_64.into(); let section_header: elf::SectionHeader = elf::SectionHeader { - name: u32_from_buffer(data, shoffset + elf::SH_NAME_OFFSET as usize), - section_type: u32_from_buffer(data, shoffset + elf::SH_TYPE_OFFSET as usize), - flags: u64_from_buffer(data, shoffset + elf::SH_FLAGS_OFFSET as usize), - addr: u64_from_buffer(data, shoffset + elf::SH_ADDR_OFFSET[arch] as usize), - offset: u64_from_buffer(data, shoffset + elf::SH_OFFSET_OFFSET[arch] as usize), - size: u64_from_buffer(data, shoffset + elf::SH_SIZE_OFFSET[arch] as usize), - link: u32_from_buffer(data, shoffset + elf::SH_LINK_OFFSET[arch] as usize), - info: u32_from_buffer(data, shoffset + elf::SH_INFO_OFFSET[arch] as usize), - addralign: u64_from_buffer(data, shoffset + elf::SH_ADDRALIGN_OFFSET[arch] as usize), - entsize: u64_from_buffer(data, shoffset + elf::SH_ENTSIZE_OFFSET[arch] as usize) + id: id, + name_idx: u32_from_buffer(data, stoffset + elf::SH_NAME_OFFSET as usize), + section_type: u32_from_buffer(data, stoffset + elf::SH_TYPE_OFFSET as usize), + flags: u64_from_buffer(data, stoffset + elf::SH_FLAGS_OFFSET as usize), + addr: u64_from_buffer(data, stoffset + elf::SH_ADDR_OFFSET[arch] as usize), + offset: u64_from_buffer(data, stoffset + elf::SH_OFFSET_OFFSET[arch] as usize), + size: u64_from_buffer(data, stoffset + elf::SH_SIZE_OFFSET[arch] as usize), + link: u32_from_buffer(data, stoffset + elf::SH_LINK_OFFSET[arch] as usize), + info: u32_from_buffer(data, stoffset + elf::SH_INFO_OFFSET[arch] as usize), + addralign: u64_from_buffer(data, stoffset + elf::SH_ADDRALIGN_OFFSET[arch] as usize), + entsize: u64_from_buffer(data, stoffset + elf::SH_ENTSIZE_OFFSET[arch] as usize) }; return section_header; } +pub fn overwrite_section_header(program_data: &mut Vec, + stoffset: usize, + shentsize: usize, + shentidx: usize, + new_section: &elf::SectionHeader, + is_x86_64: bool) { + + // Cast the supplied is_x86_64 bool to an array offset + // 0 : x86 + // 1 : x64 + let arch: usize = is_x86_64.into(); + + println!("stoffset {}", stoffset); + println!("shentsize {}", shentsize); + println!("shentidx {}", shentidx); + + let section_addr_offset: usize = stoffset + (shentsize * shentidx) + elf::SH_ADDR_OFFSET[arch] as usize; + let section_offset_offset: usize = stoffset + (shentsize * shentidx) + elf::SH_OFFSET_OFFSET[arch] as usize; + let section_size_offset: usize = stoffset + (shentsize * shentidx) + elf::SH_SIZE_OFFSET[arch] as usize; + let section_type_offset: usize = stoffset + (shentsize * shentidx) + elf::SH_TYPE_OFFSET as usize; + + program_data[section_addr_offset..section_addr_offset+8].copy_from_slice( + &new_section.addr.to_ne_bytes().to_vec()); + println!("Overwriting section addr with {:#04x}", new_section.addr); + + program_data[section_offset_offset..section_offset_offset+8].copy_from_slice( + &new_section.offset.to_ne_bytes().to_vec()); + println!("Overwriting section offset with {:#04x}", new_section.offset as usize); + + program_data[section_size_offset..section_size_offset+8].copy_from_slice( + &new_section.size.to_ne_bytes().to_vec()); + println!("Overwriting section size with {:#04x}", new_section.size as usize); + + program_data[section_type_offset..section_type_offset+4].copy_from_slice( + &new_section.section_type.to_ne_bytes().to_vec()); + println!("Overwriting section type with {:#04x}", new_section.section_type as usize); + + // return section_header; +} + + +pub fn overwrite_entrypoint(program_data: &mut Vec, + new_entry_point: usize) { + + let offset: usize = elf::ENTRYPOINT_OFFSET as usize; + program_data[offset..offset+8].copy_from_slice( + &new_entry_point.to_ne_bytes().to_vec() + ); +} + + pub fn parse_endian(endian: u8) -> elf::EndianType { match endian { 0x00 => return EndianType::Big, @@ -339,23 +433,28 @@ pub fn print_help() { } -pub fn read_lines(filename: String) -> io::Lines> { - // Open the file in read-only mode. - let file = File::open(filename).unwrap(); - // Read the file line by line, and return an iterator of the lines of the file. - return io::BufReader::new(file).lines(); -} +// pub fn read_lines(filename: String) -> io::Lines> { +// // Open the file in read-only mode. +// let file = File::open(filename).unwrap(); +// // Read the file line by line, and return an iterator of the lines of the file. +// return io::BufReader::new(file).lines(); +// } -// Borrowed from the following Stack Overflow post -// https://stackoverflow.com/questions/52987181/how-can-i-convert-a-hex-string-to-a-u8-slice -pub fn hex_to_buff(s: &str) -> Result, ParseIntError> { - (0..s.len()) - .step_by(2) - .map(|i| u8::from_str_radix(&s[i..i + 2], 16)) - .collect() -} +// // Borrowed from the following Stack Overflow post +// // https://stackoverflow.com/questions/52987181/how-can-i-convert-a-hex-string-to-a-u8-slice +// pub fn hex_to_buff(s: &str) -> Result, ParseIntError> { +// (0..s.len()) +// .step_by(2) +// .map(|i| u8::from_str_radix(&s[i..i + 2], 16)) +// .collect() +// } -pub fn hex_to_int(s: &str) -> Result { - return usize::from_str_radix(s, 16) -} \ No newline at end of file +// pub fn hex_to_usize(s: &str) -> Result { +// return usize::from_str_radix(s, 16) +// } + + +// pub fn usize_to_hex(i: usize) -> String { +// return format!("{:X}", i).to_string(); +// } \ No newline at end of file diff --git a/testing/elfpatching/hello_patch.bin b/testing/elfpatching/hello_patch.bin new file mode 100644 index 0000000000000000000000000000000000000000..68005b5fc3d01a490057b2c0fb4bcda4b9619daa GIT binary patch literal 70 zcmWFt3-&*~T*9~TuF;hdP0lbM&UkeQd2np~2a SqL7@QlB!^5rO71)R0aS{R1pgR literal 0 HcmV?d00001 diff --git a/testing/elfpatching/hello_patch.s b/testing/elfpatching/hello_patch.s new file mode 100644 index 0000000..0aae9a3 --- /dev/null +++ b/testing/elfpatching/hello_patch.s @@ -0,0 +1,32 @@ +BITS 64 + +SECTION .text +global main + +main: + push rax + push rcx + push rdx + push rsi + push rdi + push r11 + + mov rax,1 + mov rdi,1 + lea rsi,[rel $+hello-$] + mov rdx,[rel $+len-$] + syscall + + pop r11 + pop rdi + pop rsi + pop rdx + pop rcx + pop rax + + ;push 0x1060 ; jump to original entry point + ; ; could be replaced dynamically? + ;ret + +hello: db "Calling injected code >:)",10 +len: dd 26 \ No newline at end of file diff --git a/testing/elfpatching/login b/testing/elfpatching/login new file mode 100755 index 0000000000000000000000000000000000000000..cbb7884cb110b3b97b3e5119935a6315bd2c6535 GIT binary patch literal 52976 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 literal 0 HcmV?d00001 diff --git a/testing/hello_patched b/testing/hello.patched similarity index 96% rename from testing/hello_patched rename to testing/hello.patched index 899b49d7cb1d3ad235d0ed823468cca1da7dfe9e..c4c23382584df461ace97d0f5d01b325c8aa9b1b 100755 GIT binary patch delta 142 zcmcanGp}}n1XG0FMyWEv%?|_>_$C{$1x!-lW)06T%1PNQpwJ^O%gDgMzy!n~5MhT( zyKUZSKA+7kATTH_+%b3uNa=nM;n8a<0HV4@m4OsLt7CM0TvTL)b7D?TW?s5NW?oim Va!G26LUMjes)C)BCYKaY833IGA!h&p delta 129 zcmbPNd!uH81XF^*MyWDETaV)h7#SECJdPiSP{$4kf_R5`fr1&?K=xrE0||Jf=H%q- zD1_%1<)kQXZWJ`;o20@m1^|R` B9hCq8 diff --git a/testing/hello32 b/testing/hello32 deleted file mode 100755 index 12bb70c14922467944a46eeb86b2d86d00094af8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14940 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 diff --git a/testing/patches/hello.patch b/testing/patches/hello.patch deleted file mode 100644 index 9334b7d..0000000 --- a/testing/patches/hello.patch +++ /dev/null @@ -1,14 +0,0 @@ -# Trampoline segment -# Pushes and returns to 0x116b -#3f80 : 48C7C00100000048C7C70100000048C7C68007000048C7C20D0000000F05686B110000C3 -# No syscall -1190 : 48C7C00100000048C7C70100000048C7C6C011000048C7C20D000000686B110000C3 - -# String data to print from trampoline instruction -11C0 : "Hello, World!" - -# Initial jump to trampoline -#1160 : 6880060000C3 -#1160 : 6890110000C3 - -2004 : "Hello, Patch!" \ No newline at end of file diff --git a/testing/src/functions.c b/testing/src/functions.c deleted file mode 100644 index ecd0424..0000000 --- a/testing/src/functions.c +++ /dev/null @@ -1,12 +0,0 @@ -int main() { - - return 0; -} - -int my_function() { - return 0; -} - -int another_function() { - return 0; -} \ No newline at end of file diff --git a/testing/src/hello.s b/testing/src/hello.s deleted file mode 100644 index 2edc149..0000000 --- a/testing/src/hello.s +++ /dev/null @@ -1,46 +0,0 @@ - .file "main.c" - .text - .section .rodata -.LC0: - .string "Hello, World!" - .text - .globl main - .type main, @function -main: -.LFB0: - .cfi_startproc - endbr64 - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset 6, -16 - movq %rsp, %rbp - .cfi_def_cfa_register 6 - leaq .LC0(%rip), %rax - movq %rax, %rdi - movl $0, %eax - call printf@PLT - movl $0, %eax - popq %rbp - .cfi_def_cfa 7, 8 - ret - .cfi_endproc -.LFE0: - .size main, .-main - .ident "GCC: (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0" - .section .note.GNU-stack,"",@progbits - .section .note.gnu.property,"a" - .align 8 - .long 1f - 0f - .long 4f - 1f - .long 5 -0: - .string "GNU" -1: - .align 8 - .long 0xc0000002 - .long 3f - 2f -2: - .long 0x3 -3: - .align 8 -4: