产生在运行时函数用C [英] Generating functions at runtime in C

查看:129
本文介绍了产生在运行时函数用C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想生成在运行时C.一个函数,我的意思是我想基本上是想在它分配一些内存,点,通过函数指针执行它。我意识到这是一个非常复杂的话题,我的问题是幼稚的。我也意识到有一些非常强大的图书馆,在那里,做到这一点(如 nanojit )。

不过,我想学的技术,从最基本的开始。可能有人懂行的给我一个很简单的例子用C?

编辑: 下面的答案是伟大的,但这里是Windows的同一个例子:

 的#include<&WINDOWS.H GT;MEMSIZE的#define 100 * 1024 * 1024
无效的typedef(* func_t)(无效);诠释主(){    HANDLE PROC = GetCurrentProcess();
    LPVOID P =的VirtualAlloc(
        空值,
        MEMSIZE,
        MEM_RESERVE | MEM_COMMIT,
        PAGE_EXECUTE_READWRITE);    func_t FUNC =(func_t)P;
    PDWORD code =(PDWORD)P;
    code [0] = 0xC3; // RET    如果(FlushInstructionCache(
        PROC,
        空值,
        0))
    {
        FUNC();
    }    CloseHandle的(PROC);
    VirtualFree(对,0,MEM_RELEASE);
    返回0;
}


解决方案

正如所说previously其他的海报,你需要知道你的平台pretty好。

忽略铸造对象指向一个函数指针存在的问题,在技术上,UB,这里是对于在x86 / x64 OS X(以及可能的Linux太)工作的例子。所有生成code不被返回给调用者。

 的#include<&unistd.h中GT;
#包括LT&; SYS / mman.h>无效的typedef(* func_t)(无效);诠释主(){
    / *
     *获取的内存RWX位。
     *我们不能只用malloc因为它返回的存储可能不
     *是可执行的。
     * /
    无符号字符* code = MMAP(NULL,为getpagesize()
            PROT_READ | PROT_EXEC | PROT_WRITE,
            MAP_SHARED | MAP_ANON,0,0);    / *技术上未定义的行为* /
    func_t FUNC =(func_t)code;    code [0] = 0xC3; / * 86RET指令* /    FUNC();    返回0;
}

显然,这将是在不同的平台不同,但它概述所需的基本知识:获取可执行内存部分,写指令,执行指令

I would like to generate a function at runtime in C. And by this I mean I would essentially like to allocate some memory, point at it and execute it via function pointer. I realize this is a very complex topic and my question is naïve. I also realize there are some very robust libraries out there that do this (e.g. nanojit).

But I would like to learn the technique, starting with the basics. Could someone knowledgeable give me a very simple example in C?

EDIT: The answer below is great but here is the same example for Windows:

#include <Windows.h>

#define MEMSIZE 100*1024*1024
typedef void (*func_t)(void);

int main() {

    HANDLE proc = GetCurrentProcess();
    LPVOID p = VirtualAlloc(
        NULL,
        MEMSIZE,
        MEM_RESERVE|MEM_COMMIT,
        PAGE_EXECUTE_READWRITE);

    func_t func = (func_t)p;
    PDWORD code = (PDWORD)p;
    code[0] = 0xC3; // ret

    if(FlushInstructionCache(
        proc,
        NULL,
        0))
    {
        func();
    }

    CloseHandle(proc);
    VirtualFree(p, 0, MEM_RELEASE);
    return 0;
}

解决方案

As said previously by other posters, you'll need to know your platform pretty well.

Ignoring the issue of casting a object pointer to a function pointer being, technically, UB, here's an example that works for x86/x64 OS X (and possibly Linux too). All the generated code does is return to the caller.

#include <unistd.h>
#include <sys/mman.h>

typedef void (*func_t)(void);

int main() {
    /*
     * Get a RWX bit of memory.
     * We can't just use malloc because the memory it returns might not
     * be executable.
     */
    unsigned char *code = mmap(NULL, getpagesize(),
            PROT_READ|PROT_EXEC|PROT_WRITE,
            MAP_SHARED|MAP_ANON, 0, 0);

    /* Technically undefined behaviour */
    func_t func = (func_t) code;

    code[0] = 0xC3; /* x86 'ret' instruction */

    func();

    return 0;
}

Obviously, this will be different across different platforms but it outlines the basics needed: get executable section of memory, write instructions, execute instructions.

这篇关于产生在运行时函数用C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆