作为一个实验,我试图编写以下程序,它允许我在运行时生成代码。即我做以下事情:
1。使用我想要执行的指令的操作码填充缓冲区 2。声明一个函数指针并使其指向缓冲区的开头 3。使用上面的func-ptr。调用该函数
代码如下: (按照以下AndreyT的说明更新。)
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
//#include <sys/mman.h>
int main(int argc, char *argv[])
{
int u32;
int (*ptr)(void);
uint8_t *buf = malloc(1000);
//uint8_t *buf = mmap(NULL, 1000, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
buf[0] = 0xb8;
u32= 42;
memcpy(buf + 1, &u32, 4);
buf[5] = 0xc3;
ptr = (int (*)(void)) buf;
printf("return is %d\n", ptr());
return 0;
}
这个代码在使用gcc的linux机器上编译很好 现在我正在将它迁移到windows(visual-studio-2010)。
AFAIK, mmap 功能由Windows上的 virtualAlloc 和 virtualProtect 提供。
我在网上通过MSDN和其他文档,
但我仍然无法找到一种方法让这个程序在Windows上的VS-2010上运行。
更新
@AndreyT谢谢。它似乎现在正在运作。虽然我收到以下错误:
1>MSVCRTD.lib(crtexew.obj) :
error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup
1>file.exe : fatal error LNK1120: 1 unresolved externals
Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped
我想我现在需要将mmap()
电话换成virtualAlloc()
非常感谢大家。接下来我需要深入研究MSDN virtualAlloc()
我猜。
答案 0 :(得分:2)
您收到此错误是因为您试图在阻止中间声明ptr
。
经典ANSI C语言(C89 / 90)不允许在块的中间进行声明。声明必须位于块的开头。仅在C99中允许在中间声明变量。
即使在C89 / 90模式下,GCC编译器也允许将中间的变量声明为非标准扩展。 MSVC编译器是一个严格的C89 / 90编译器,它不允许这样的声明。