1

Suppose I have some arbitrary x86 instructions that I want to have executed in the context of some program, and I convert these instructions automatically or manually into shellcode. For example, the following instructions.

movq 1, %rax
cpuid

There are various questions, such as here and here, about casting shellcode to a function pointer and executing it by using a standard function invocation. However, arbitrary asm will generally not have the instructions to return to the caller after all the instructions have been completed.

I am interesting in writing an "interpreter" of sorts for arbitrary shellcode, so that it can execute a bunch of instructions (perhaps they are in a file somewhere), read out the value of certain registers, and return control to the main C program. I assume the shell code does not do something like exec and change the process, but merely runs instructions like rdpmc or cpuid.

I imagine something that looks like this, but I am not sure how I can patch the shellcode so that it returns control to the right place.

void executeAndReadRegisters(char* shellcode, int length, uint64_t* rax, uint64_t* rbx, uint64_t* rbx) {
    // Modify the shellcode in some way so that it returns control to the
    // current program's code after execution, right after "read out registers".
    char* modifiedShellCode = malloc((length + EXTRA_NEEDED) * sizeof(char));

    // How do I modify the shellcode to return to "Read out registers?"

    int (*func)();
    func = (int (*)()) modifiedShellCode;
    (int)(*func)();

    // Read out registers
    asm("\t movq %%rax,%0" : "=r"(*rax));
    asm("\t movq %%rbx,%0" : "=r"(*rbx));
    asm("\t movq %%rcx,%0" : "=r"(*rcx));
}
int main(int argc, char **argv)
{

    // Suppose this comes from a file somewhere
    char shellcode[] = "...";
    int length = ; // Get from external source

    uint64_t rax,rbx,rcx;
    executeAndReadRegisters(shellcode, length, &rax,&rbx, &rcx);
    printf("%lu %lu %lu\n", rax,rbx,rcx);
}
Community
  • 1
  • 1
merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • I assume C does regular calling, so can't you just append a `ret` instruction. Assuming of course there's no changes to the stack pointer or other things – PeterT Mar 14 '14 at 18:44
  • 1
    Usually, 'shellcode' executes a shell; the `exec` part means there isn't a way back because 'exec' means 'replace original process with new program'. – Jonathan Leffler Mar 14 '14 at 18:50
  • @JonathanLeffler, Well you can always fork and execute the shell, so theoretically it is possible. Hoever, since an exploit usually attacks the stack, I don't see how you would know where to get back to. – Devolus Mar 14 '14 at 19:46
  • You could run the code in question in a ptrace context which executes one instruction at a time; then you can stop when you reach the end of the user-supplied code. – Kerrek SB Mar 15 '14 at 00:26
  • @JonathanLeffler, I am using the term `shellcode` to refer more generally to `asm` in binary form, rather than actual code for opening a shell. – merlin2011 Mar 15 '14 at 01:03
  • The normal way to do it is first forking then if the returned PID is zero (= child process) do exec-family system call. If a non-zero PID is returned from fork, it's the parent process getting the child process' PID. The call returns what the program main returns, and it can be used in the program doing the fork-exec. The parent process waits until the child process finishes unless a parameter is given to indicate not to wait. It's shell code if the program run via exec is a shell. – turboscrew Mar 15 '14 at 07:28

0 Answers0