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);
}