How to execute x86 commands from a data buffer?

My question is mainly about professors and uses C ++ in a "weird" way. In C ++, there is not much difference between pointers to variables and pointers to functions. We can do something useless:

char* buff = new char[32]; void (*func)() = (void (*)())buff; 

But on all sides we created a function that never existed, right? What if we go further and fill the buff with the x86 command in the file? OS will never know that a function has been created.

 #include <iostream> using namespace std; // no stack push'ing or pop'ing, nothing to return void func(void){cout << "Hello?";} int main() { char* x86_code = new char[6]; x86_code[0] = 0x9A; // call (far) *((__int32*)(x86_code + 1)) = (__int32)func; // load 32-bit address x86_code[5] = 0xC3; // ret void (*x86_func)(void) = (void (*)(void))x86_code; x86_func(); return 0; } 

Calling x86_func () creates a runtime error (read location with error 0xFFFFFFFF). How does the OS load binary files or modules into it, if not? Thank you very much.

+6
source share
1 answer

Indeed, you can populate the array with x86 machine code and try to execute it. It is called shellcode and controls that the application or library executes such code when it was not intended, called the "exploit."

Unfortunately, this is not so simple, since modern hardware and OS usually prevent the execution of code from areas that can be written, for example, non-const char arrays. This is called W ^ X (write or execute permissions, but not both). But you can request a POSIX-compatible OS to disable this protection using the mprotect() function. Here is an example that works because it allows you to allow reading, writing, and executing permissions in an array of corresponding bytes of machine code:

 #include <stdio.h> #include <stdint.h> #include <sys/mman.h> typedef int(*FUNKY_POINTER)(void); char shellcode[] = { 0xb8, 0x2a, 0x00, 0x00, 0x00, //mov $0x2a,%eax 0xc3 //retq }; int main(void){ uintptr_t pageSize = 4096; uintptr_t shellcodeAddr = (uintptr_t)shellcode; uintptr_t pageAlignedAddr = shellcodeAddr & ~(pageSize-1); FUNKY_POINTER shellcodeFn = (FUNKY_POINTER)shellcode; /* Magic */ mprotect((void*)pageAlignedAddr, (shellcodeAddr - pageAlignedAddr) + sizeof(shellcode), PROT_EXEC|PROT_WRITE|PROT_READ); printf("The answer to the ultimate question of life, " "the universe and everything is %d\n", shellcodeFn()); return 0; } 
+3
source

Source: https://habr.com/ru/post/958247/


All Articles