1

I'm trying to execute some x86 machine code that execute jmp $ (\xeb\xfe) directly from Rust but the executable just crashes.

I successfully did it in C with the GCC compiler but it also crashes with Clang:

#include <stdio.h>

char code[] = "\xeb\xfe";

int main(int argc, char **argv){
    int (*func)();
    func = (int (*)()) code;
    (int)(*func)();
}

To do it in pure Rust, I converted my byte array into a void pointer (*const ()) then converted it into a unsafe extern "C" fn () -> ! with std::mem::transmute:

static shellcode: [u8; 73] = *b"\xeb\xfe";
fn main() -> std::io::Result<()> {
    let raw: unsafe extern "C" fn() -> ! =
        unsafe { std::mem::transmute(&shellcode.as_ptr() as *const _ as *const ()) };
    unsafe { raw() };
    return Ok(());
}

I already read How to execute raw instructions from a memory buffer in Rust? and the answer is basically what I did so I'm kind of confused...

I have compiled the Rust code for x86/x64 and both crashed, I think that the "shellcode" isn't compatible with LLVM.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
centipede_
  • 79
  • 9
  • Are your bytes marked as executable? I'd expect not, if they are `static`. – Shepmaster Sep 30 '19 at 18:18
  • What do you mean by "marked as executable" ? I also tried to declare `shellcode` as a common variable and logically it crashed too. – centipede_ Sep 30 '19 at 18:21
  • What is your experience with shellcode and other types of exploits in this family? You may be missing a large amount of background information that would be immensely useful before trying it in a language like Rust. – Shepmaster Sep 30 '19 at 18:23
  • And dare I ask *why* you want to do this? There are legitimate reasons and not-so-legitimate reasons. – Shepmaster Sep 30 '19 at 18:24
  • Here are the first results I found [How to alloc a executable memory buffer?](https://stackoverflow.com/q/40936534/155423); [Allocate executable ram in c on linux](https://stackoverflow.com/q/3125756/155423); [How can i execute an executable from memory?](https://stackoverflow.com/q/44653960/155423). – Shepmaster Sep 30 '19 at 18:26
  • 1
    Are you using Clang to compile the C with the same settings and compile target as for the Rust? I don't know much about Windows and even less about Rust/Windows, but I believe there are at least 2 common toolchains and I see `msvcrt.dll` embedded in the "executable". Using the same toolchain (except the LLVM frontend) would be a logical way to rule out a bunch of possible issues. – trent Sep 30 '19 at 18:26
  • *the answer is basically what I did* — it would be worth paying attention to the parts of the answer which are different. I would assume that if your code doesn't work and theirs does, then the differing aspects would play a large part in that. – Shepmaster Sep 30 '19 at 18:27
  • Well, if you want to know why. I mostly work on assembly, I code viruses, reverse them and learn how to recognize them. I'm doing that because I just wanted to know how can I execute raw bytes before doing some process hollowing in Rust. But you're free to tell me what kind of background of informations I'm missing if it will help me to execute those raw bytes in Rust (it works fine with other languages) – centipede_ Sep 30 '19 at 18:30
  • In the other post they convert a `*mut u8` (by the function `map.data()`) to an `unsafe extern "C" fn`. I tried to convert my array to a `*mut u8` then to `unsafe extern "C" fn` and guess what ? It still crashes :( – centipede_ Sep 30 '19 at 18:35
  • Yes the both programs are targeting the same architecture. `gcc [...] -m32` for C and `rustc [...] --target=i686-pc-windows-msvc` for Rust. And yes they're both using `msvcrt.dll`, the "shellcode" call `printf` by it's address from that DLL. – centipede_ Sep 30 '19 at 18:43
  • 1
    The other question also creates an executable (`MapOption::MapExecutable`) memory buffer using mmap, copies all the data to it, then executes it from that space. See also [Disabling stack protection in GCC not working](https://stackoverflow.com/q/39737813/155423) – Shepmaster Sep 30 '19 at 18:50
  • Thanks :) but I saw that it use a crate when I read the topic and I would like to know if ther's a way to do it in pure Rust ? – centipede_ Sep 30 '19 at 18:52
  • You should include those requirements **in your question**, otherwise you will get answers that aren't what you want. – Shepmaster Sep 30 '19 at 18:54
  • And why would I need to disable the stack protection of my C program ? I'm not doing stack buffer overflow or others – centipede_ Sep 30 '19 at 18:55
  • You may also want to define "pure Rust". Does calling FFI functions count as "pure Rust"? What prevents you from just copy-pasting the contents of the crates you want into the program you need — hooray no more crates... except for all of the crates that build the standard library. Should those be disregarded as well? – Shepmaster Sep 30 '19 at 18:55
  • That comment about C was to indicate that you might want to try opting **in** to the stack protection in C — that might give you the same kinds of errors. – Shepmaster Sep 30 '19 at 18:56
  • I edited the question. I just thought that I will be able to execute some raw bytes in a system oriented programming language as Rust without any extrenal crates. And I prefer understanding what I'm doing, I don't like just calling functions when I can do it by myself – centipede_ Sep 30 '19 at 19:01
  • 2
    I'd like to try this out. Will it install a virus, steal my passwords or crash my computer? – Aloso Sep 30 '19 at 21:26
  • @Aloso that’s the correct mindset for this type of question. Unfortunately, the OP has not provided instructions to produce the shellcode or even what platform it targets, so this question should likely be closed as it does not have a [MRE]. – Shepmaster Sep 30 '19 at 21:42
  • How do you know that `gcc -m32` generates code that uses the same `"C"` calling convention as `--target=i686-pc-windows-msvc`? Again, I suggest you try compiling the C code with Clang. – trent Sep 30 '19 at 22:03
  • The "shellcode" just print "yop" at the screen but it will not work on an other computer because the shellcode contain the address of printf in `msvcrt.dll` in my computer. I tried to just execute a `jmp $` -> `\xeb\xfe` and it crashed too. I literally can't execute raw bytes in Rust – centipede_ Oct 01 '19 at 05:49
  • @Shepmaster you can reproduce what I did by replacing my shellcode by a simple `xor eax, eax` or whatever you want, yes I should have only put a simple instruction as my shellcode I didn't thought about that. – centipede_ Oct 01 '19 at 06:00
  • @trentcl Thanks for the help, I compiled my C code with `Clang` and yeah it didn't worked for a `jmp $`. So I think my final question might be "_How to execute raw bytes on a LLVM program_". Should I edit all my question or post an other one with the `C` and `LLVM` flag ? – centipede_ Oct 01 '19 at 06:47
  • I'd post a new one, if it were me. – trent Oct 01 '19 at 10:30
  • @trentcl I will do that in a few hours. Thanks for the help :). – centipede_ Oct 01 '19 at 13:59
  • Besides [tag:c] and [tag:llvm], also consider [tag:windows] as this pertains to platform-and toolchain-specific conventions – trent Oct 01 '19 at 14:49
  • @trentcl okay I'll do that. – centipede_ Oct 01 '19 at 15:29
  • Here is the new topic if you would like to take a look for any reason: [How do I execute raw bytes of machine code compatible with LLVM frontend](https://stackoverflow.com/questions/58188815/how-do-i-execute-raw-bytes-of-machine-code-compatible-with-llvm-frontend) – centipede_ Oct 01 '19 at 16:20
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/200272/discussion-on-question-by-centipede-how-do-i-execute-raw-bytes-of-machine-shell). – Samuel Liew Oct 02 '19 at 02:53

1 Answers1

0

i think is because the buffer doesnt have the execute flag, im not sure but you can try using mprotect to add the executable flag to the buffer.

Jôsùå
  • 1
  • 1
  • 3