How to execute x86 commands from data buffer?

旧巷老猫 提交于 2021-02-18 22:48:37

问题


My question is dedicated mostly to profs and is about using C++ in "strange" way. In C++ there isn't really big difference between pointers to variables and pointers to functions. We can do something useless like this:

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

But we allmost created a function that never existed, right? What if we go further and fill buff with x86 commands stord in a file? OS will never know that a function was 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() makes a runtime error (violation reading location 0xFFFFFFFF). How does OS loads it's binaries or modules in RAM if not in this manner? Many thanks.


回答1:


Indeed you can fill an array with x86 machine code and attempt to execute it. It's called shellcode and managing to make an application or library execute such code when it wasn't intended to is called an "exploit".

Unfortunately it's not that easy, since modern hardware and OSes normally prevent you from executing code from areas that are writable, such as non-const char arrays. This is called W^X (write or execute permissions, but not both) But one can request POSIX-compliant OSes to disable such protection with the mprotect() function. Here's an example that works, because it enables read, write and execute permissions on the array of machine code bytes concerned:

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


来源:https://stackoverflow.com/questions/20028892/how-to-execute-x86-commands-from-data-buffer

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!