3

Problem:

run a non-trivial c program stored on the heap or data section of another c program as asm instructions.

My progress:

Ran a set of simple instructions that print something to stdout. The instructions are stored on the heap and I allowed the page containing the instructions to be executed and then calling into the raw data as though it was a function. This worked fine.

Next up, I want given any statically linked c program, to just read it's binary and be able to run it's main function while it is in memory from another c program.

I believe the issues are: * jumping to where the main function code is * changing the binary file's addresses which were created when linking so they are relative to where the code lies now in memory

Please let me know if my approach is good or whether I missed something important and what is the best way to go about it.

Thank you

trincot
  • 317,000
  • 35
  • 244
  • 286
dandroid
  • 395
  • 1
  • 3
  • 12
  • 2
    The issues are exactly the ones that you enumerated. The first one is called "jump to entry point", the second one is "relocation". You may want to consult the source code of the binary loader of your operating system. –  May 18 '13 at 19:50
  • If you already have the other program statically linked, can you not just use `exec`? – Kerrek SB May 18 '13 at 19:50
  • Yes, you missed something: Consider that in other programming languages, you'd be performing essentially the same steps, and for other OSes those steps would change. Can you now see that this problem has very little to do with C, and virtually everything to do with your implementation? You might want to find out what "implementation" means, by the way... – autistic May 18 '13 at 20:09

1 Answers1

2

Modern OSes try not to let you execute code in your data exactly because it's a security nightmare. http://en.wikipedia.org/wiki/No-execute_bit

Even if you get past that, there will be lots more 'gotchas' because both programs will think that they 'own' the stack/heap/etc. Once the new program executes, it's various bits of RAM from the old program will get stomped on. (exec exists just for this reason, to cleanly go from one program to another.)

If you really need to load code, you should make the first one a library, then use dlopen to run it. (You can use objcopy to extract just the subroutine you want and turn it into a library.)

Alternately, you can start the program (in another process) and use strace to inject a little bit of your code into their process to control it.

(If you're really trying to get into shell code, you should have said so. That's a whole 'nother can of worms.)

BraveNewCurrency
  • 12,654
  • 2
  • 42
  • 50
  • 1
    You missed the "and I allowed the page containing the instructions to be executed" part in the question. –  May 18 '13 at 20:26
  • oops, you're right, I missed that. You would still have to manually re-link. It will be easier to let objcopy and dlopen do that for you. – BraveNewCurrency May 18 '13 at 20:36
  • For testing out shellcode under *Linux*, see [How to get c code to execute hex machine code?](https://stackoverflow.com/q/9960721) (`-z execstack` no longer applies to `.data` and `.rodata`, so you need your machine code either actually on the stack (a local array), or mprotect or mmap, or Windows VirtualProtect / VirtualAlloc.) – Peter Cordes Jul 19 '21 at 21:51