3

I have written a simple binary app to produce a c source file, I feed it a memory address and split the string to print final source. I am new to Rust, how can this be improved? I also did some search and replace which gives me "" at the end, I am unsure of why this is given the replace.

Here is app output:

~/Research/split_mem_mk_src(master*) » cargo run                                                                                
   Compiling split_mem_mk_src v0.1.0 (/Users/RSRCH/Research/split_mem_mk_src)
    Finished dev [unoptimized + debuginfo] target(s) in 0.46s
     Running `target/debug/split_mem_mk_src`
int main(int argc, char *argv[]) {
  __asm__(".byte "0x62, 0x02, 0x55, 0xd4, 0x7f, 0xb5, 0xb1, 0x8e, 0xbf, 0xcd\"")
}

I want to end up with this...

int main(int argc, char *argv[]) {
  __asm__(".byte 0x62, 0x02, 0x55, 0xd4, 0x7f, 0xb5, 0xb1, 0x8e, 0xbf, 0xcd");
}

I would eventually like to just execute asm in rust and run though gdb, so any idea on this would be great. Happy to read docs. I found this https://doc.rust-lang.org/beta/unstable-book/library-features/asm.html but didn't see execute byte statement like C.

App Source

fn main() {
    let n = 2;
    let text = "620255d47fb5b18ebfcd".to_string();
    let mem_addr = text.chars()
    .enumerate()
    .flat_map(|(i, c)| {
        if i != 0 && i % n == 0 {
            Some(' ')
        } else {
            None
        }
        .into_iter()
        .chain(std::iter::once(c))
    })
    .collect::<String>();
    let final_str = format!("0x{:?}", mem_addr.replace(" ", ", 0x"));
    println!("int main(int argc, char *argv[]) {{");
    println!("  __asm__(\".byte {:?})", final_str.replace("0x\"", "0x"));
    println!("}}");
}
```
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366

1 Answers1

2

You're using {:?}. This uses the Debug trait, which is only meant for debugging, always includes quotes around the string and escapes special characters, such as ". Debug isn't meant to be used to produce any kind of exact output.

What you want is the Display trait, which is the default trait when nothing is specified, therefore you can simply use {}.

mcarton
  • 27,633
  • 5
  • 85
  • 95
  • Perfect, exactly what I needed! Realise I got into bad habits with {:?}. Output now: __asm__(".byte 0x62, 0x02, 0x55, 0xd4, 0x7f, 0xb5, 0xb1, 0x8e, 0xbf, 0xcd"); – Security Researcher Dec 28 '20 at 11:53
  • Do you know anyway I can execute an x86 asm instruction directly with Rust in this format? ".byte 0x62, 0x02, 0x55, 0xd4, 0x7f, 0xb5, 0xb1, 0x8e, 0xbf, 0xcd" – Security Researcher Dec 28 '20 at 11:58
  • @SecurityResearcher: You can if you use nightly and the `asm` feature gate: [playground](https://play.rust-lang.org/?version=nightly&mode=release&edition=2018&gist=ffe0204fbeeb8fbe5bf7d3ed9a6c103b) – rodrigo Dec 28 '20 at 12:37
  • 1
    @Rodrigo Except this won't actually work because asm! Is compile time, while OP seems to want to generate assembly from a string. – Ivan C Dec 28 '20 at 13:00
  • @IvanC: Ah, I thought OP just wanted to output Rust source code instead of C. – rodrigo Dec 28 '20 at 13:02
  • @IvanC is correct I do wish to execute assembly from string. I am thinking I will have to write to file, build and then run with gdb - that's the best I have right now. At the moment I pipe to file, gcc and then run with gdb. – Security Researcher Dec 28 '20 at 14:10
  • 1
    @SecurityResearcher this question might be useful to you: https://stackoverflow.com/questions/55856247/how-to-execute-raw-instructions-from-a-memory-buffer-in-rust – Ivan C Dec 28 '20 at 14:22