C ++在内存中运行字节数组

时间:2015-01-11 03:03:43

标签: c++ memory

我正在努力研究我认为被称为发射器的东西?概念是将所有二进制文件写入缓冲区,然后将缓冲区加载到内存中。我已经看到这个代码反复蹦蹦跳跳(我已经编写了exe,所以我可以访问其中的代码。):

//HardCoded Binary For testing Reason, reading to launch didn't work neither did this
char RawCode[11414] = {
0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0xFF, 0xFF, ............................................... 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}


//Main Function
int main(int argc, char* argv[])
{
    int(*f)();
    f = (int(*)())&RawCode;
    (int)(*f)();
}

我的原始想法可能是空字节影响执行导致访问冲突,所以经过一些研究我发现一个消息框shellcode格式为“/x41/x41/.......x41/”与没有空字节,但仍然没有用。由于没有太多关于此的信息,我有点迷茫。有没有人对一些好的文章或有用的教程有一些参考,因为我找不到任何帮助。谢谢大家的时间!

3 个答案:

答案 0 :(得分:6)

现在很长一段时间以来,所有现代操作系统都实现了某种形式的data execution prevention。这意味着您不能只将代码放在内存中并运行它;必须标记内存区域以允许首先执行。原因是安全性 - 它使得利用远程代码执行漏洞更加困难。

这也意味着你在尝试像这样愚蠢的事情之前应该长时间地思考,因为它会破坏你操作系统中的巨大漏洞并试图保护你。

因此,在从内存运行代码之前,必须将有问题的区域标记为可执行文件。

在Windows下,可以使用VirtualProtect功能完成此操作。但是,对于任意存储区域都无法做到;它必须在页面边界处对齐,并且页面必须使用相同的VirtualAlloc调用进行分配。所以最终,你最终会

DWORD old_protect;
LPVOID executable_area = VirtualAlloc(NULL, 11414, MEM_RESERVE, PAGE_READWRITE);

memcpy(executable_area, Rawcode, 11414);
VirtualProtect(executable_area, 11414, PAGE_EXECUTE, &old_protect);

int(*f)() = (int(*)()) executable_area;
f();

// Note: RAII this in C++. Restore old flags, free memory.
VirtualProtect(executable_area, 11414, old_protect, &old_protect);
VirtualFree(executable_area, 11414, MEM_RELEASE);

答案 1 :(得分:1)

首先,您的数组是否包含可执行文件的表示,或者它是否包含可执行的机器代码?如果是前者,它可能不起作用:大多数可执行文件格式以操作系统用来加载程序的各种元数据开始;可执行机器代码稍后会出现在文件中。

其次,您的系统是否使用类似DEP的东西?您的操作系统可能将数组标记为不可执行,因此尝试执行它将失败。

答案 2 :(得分:-1)

(对不起,迟到的答案)

从数组执行字节是一个坏主意。它不是跨平台,而且会带来巨大的安全风险。

更安全的执行外部代码的方法是字节码解释器。您可以限制程序的访问权限,只触及它需要的东西。缺点是您要么编写自己的编译器,要么自己编写原始字节代码。

这里有一个很好的教程:http://gameprogrammingpatterns.com/bytecode.html

另一个不太安全的解决方案是使用DLL。 (动态链接库)这样您就不必编写自己的编译器。