// generated by dump2func 0.2 of Luigi Auriemma

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#ifdef WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif



/*static*/ int (__stdcall *ffce)(void *source, void *destination, int unused) = NULL;



// 0x000001a2 bytes
static const int ffce_function_size = -1;
static const unsigned char ffce_function[] =
    "VWSU\x8bt$\x14\x8b|$\x18\xfc\x8b\x1e\x83\xc6\x04\x85\xdb\x0f\x84{\x01\x00\x00\xba\x00\x00\x00\x80\x03\xdf\x8a\x06\x83\xc6\x01\x88\a\x83\xc7\x01\xb9\x03\x00\x00\x00\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x0f\x83\xdc\xff\xff\xff;\xfb\x0f\x83H\x01\x00\x00SUW\xbb\x01\x00\x00\x00""3\xed\x8b\xc3\x8d|\x1d\x00\x8b\xeb\x8b\xdf\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x0f\x83\xe3\xff\xff\xff\x8d\\=\x00\x03\xc7\x8b\xef\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x0f\x83\xc6\xff\xff\xff_][+\xc1\x0f\x83>\x00\x00\x00\xb9\x01\x00\x00\x00\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x13\xc9\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x0f\x82\xda\xff\xff\xffV\x8b\xf7+\xf5\xf3\xa4^\xb9\x02\x00\x00\x00\x90\xe9T\xff\xff\xff\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x13\xc0\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x13\xc0\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x13\xc0\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x13\xc0\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x13\xc0\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x13\xc0\xb9\x01\x00\x00\x00\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x13\xc9\x03\xd2\x0f\x85\a\x00\x00\x00\x8b\x16\x8dv\x04\x13\xd2\x0f\x82\xda\xff\xff\xff\x83\xc0\x01\x8b\xe8=\x01\x80\x00\x00\x83\xd9\xff=\x81\a\x00\x00\x83\xd9\xffV\x8b\xf7+\xf0\xf3\xa4^\xb9\x02\x00\x00\x00\x90\xe9\x9b\xfe\xff\xff\x8b\xc7+D$\x18][_^\xc2\f\x00";



void *ffce_alloc(const void *dump, int zdumpsz, int dumpsz, int exec, int *ret_alloc_size) {
    static int    page_size = 0;
    int     alloc_size;
    void    *ret;
    #ifdef WIN32
    SYSTEM_INFO sSysInfo;
    #endif

    if(!page_size) {
        #ifdef WIN32
        GetSystemInfo(&sSysInfo);
        page_size = sSysInfo.dwPageSize;
        #else
        page_size = getpagesize();
        #endif
        if(!page_size) page_size = 4096;
    }

    if(ret_alloc_size) *ret_alloc_size = 0;

    dumpsz = zdumpsz;

        alloc_size = (dumpsz + (page_size - 1)) & (~(page_size - 1));
        if(alloc_size < dumpsz) return NULL;

        #ifdef WIN32
        ret = VirtualAlloc(NULL, alloc_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        #else
        ret = valloc(alloc_size);
        mprotect(ret, alloc_size, PROT_READ | PROT_WRITE); 
        #endif
        if(!ret) return NULL;
        memset(ret, exec ? 0xcc : 0x00, alloc_size);

        memcpy(ret, dump, dumpsz);

    if(ret_alloc_size) *ret_alloc_size = alloc_size;
    return ret;
}



int ffce_init(void) {
    static int ffce_initialized = 0;

    static int            func_buff_size   = 0;
    static unsigned char *func_buff        = NULL;

    if(!func_buff) {
        func_buff = ffce_alloc(ffce_function, sizeof(ffce_function) - 1, ffce_function_size, 1, &func_buff_size);
        if(!func_buff) return -1;
    }

    if(!ffce_initialized) {

        ffce = (void *)(func_buff + 0x00000000);

        #ifdef WIN32
        DWORD tmp;
        VirtualProtect(func_buff, func_buff_size, PAGE_EXECUTE_READ, &tmp);
        #else
        mprotect(func_buff, func_buff_size, PROT_EXEC | PROT_READ);
        #endif

        ffce_initialized = 1;
    }

    return 0;
}


