当前位置:  开发笔记 > 编程语言 > 正文

从vc ++调用存储在堆中的代码

如何解决《从vc++调用存储在堆中的代码》经验,为你挑选了3个好方法。

想象一下,我正在做这样的事情:

void *p = malloc (1000);
*((char*)p) = some_opcode;
*((char*)p+1) = another_opcode; // for the sake of the example: the opcodes are ok

....
etc...

如何定义一个函数指针来调用p,好像它是一个函数?(我使用的是VC++ 2008 express).

谢谢



1> jmucchiello..:

实际上,malloc可能不会削减它.在Windows上,您可能需要调用类似[VirtualAlloc](http://msdn.microsoft.com/en-us/library/aa366887 ( VS.85).aspx)的内容才能获得可执行的内存页面.

从小开始:

void main(void)
{
    char* p = (char*)VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    p[0] = (char)0xC3;  // ret

    typedef void (*functype)();
    functype func = (functype)p;
    (*func)();
}

使用代码的下一步是保留EBP寄存器.这是一个练习.:-)

写完之后,我用malloc运行它,它也有效.这可能是因为我在Windows 2000 Server上运行管理员帐户.其他版本的Windows实际上可能需要VirtualAlloc调用.谁知道.



2> Foredecker..:

评论的空间不够.Joe_Muc是对的.你不应该将代码填入由malloc或获得的内存中new.如果更改Windows分配的页面的页面属性,则会遇到问题.

这不是问题,因为使用VirtualAlloc()并且相关的WIn32 API非常简单:调用VirtualAlloc()并将其设置flProtect[PAGE_EXECUTE_READWRITE][2]

请注意,您可能应该执行三个分配,一个保护页面,代码所需的页面,然后是另一个保护页面.这将为您提供一些不良代码保护.

还使用结构化异常处理来包装对生成的代码的调用.

接下来,Windows X86 ABI(调用约定)没有很好的文档记录(我知道,我看过).有一些信息在这里,这里,这里 看到的东西如何工作是看编译器生成代码的最好方法.这很容易用\FA开关(有四个).

您可以在此处找到64位调用约定.

此外,您仍然可以在此处获取Microsoft的宏汇编程序MASM.我建议在MASM中编写机器代码并查看其输出,然后让机器代码生成器执行类似的操作.

英特尔和AMD的处理器手册都是很好的参考 - 如果你没有它们就可以获得它们.



3> Eclipse..:

如果你有正确的操作码,调用就像转换为函数指针并调用它一样简单.

typedef void (*voidFunc)();

char *p = malloc (1000);
p[0] = some_opcode;
p[1] = another_opcode; // for the sake of the example: the opcodes are ok
p[n] = // return opcode...

((voidFunc)p)();

请注意,除非您将页面标记为可执行文件,否则您的处理器可能无法执行堆上生成的代码.

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有