c – 如何从数据缓冲区执行x86命令?

前端之家收集整理的这篇文章主要介绍了c – 如何从数据缓冲区执行x86命令?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的问题主要是专注于教授,并且是以“奇怪”的方式使用C.在C中,指向变量的指针和指向函数的指针之间没有太大区别.我们可以做一些像这样无用的事情:
char* buff     = new char[32];
void (*func)() = (void (*)())buff;

但我们所有人都创造了一个从未存在的功能,对吧?如果我们进一步用文件中的x86命令stord填充buff怎么办?操作系统永远不会知道创建了一个函数.

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

调用x86_func()会产生运行时错误(违反读取位置0xFFFFFFFF).如果不以这种方式操作系统如何在RAM中加载它的二进制文件或模块?非常感谢.

解决方法

实际上,您可以使用x86机器代码填充数组并尝试执行它.它被称为shellcode并且管理使应用程序或库在不打算被称为“漏洞利用”时执行这样的代码.

不幸的是,它并不那么容易,因为现代硬件和操作系统通常会阻止您从可写区域执行代码,例如非const char数组.这称为W ^ X(写入或执行权限,但不是两者)但是可以通过mprotect()函数请求符合POSIX的操作系统禁用此类保护.这是一个有效的示例,因为它在相关的机器代码字节数组上启用读取,写入和执行权限:

#include <stdio.h>
#include <stdint.h>
#include <sys/mman.h>


typedef int(*FUNKY_POINTER)(void);


char shellcode[] = {
    0xb8,0x2a,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;
}

猜你在找的C&C++相关文章