Помогите с С кодом

О знатоки этого великого и могучего! Склоняюсь перед вами в этой просьбе:есть код на С, но не хочет компилироваться в С++ Builder 2007.
#include <windows.h>#include <stdio.h>#include "patches.h"#define DLLEXPORT __declspec(dllexport)//#define DEBUG /* undef to disable logging */#define DEBUG_FILE "debug.log"#define GAME_DLL_NAME "Game.dll"#define GAME_MAIN "GameMain"#define GAME_DLL_SIZE 0xb80000 /* size of real "Game.dll" in memory */#define SUCCESS 0#define ERR_GAME_DLL_LOAD 1#define ERR_GAME_MAIN 2#define ERR_SIG_NOT_FOUND 3#define ERR_MEM_WRITE 3#define GAME_DLL_LOAD_ERROR "Could not open " ## GAME_DLL_NAME#define GAME_MAIN_ERROR "Could not locate procedure " ## GAME_MAIN#define SIG_NOT_FOUND_ERROR "Could not find location to patch."#define MEMORY_WRITE_ERROR "Could not write to process memory."#define LPH_HASH_INIT_CALL_OFFSET 0x9 /* offset of hash_init call in the logon proof password hashing routine */#define LPH_DO_HASH_CALL_OFFSET 0x42  /* offset of do_hash call */int called; /* used to stop multiple calls to DLL entry point */FARPROC real_game_main; /* pointer to the real "Game.dll" GameMain function */HMODULE game_dll_base; /* pointer to base of the real "Game.dll" */HANDLE app_process; /* handle to the war3.exe process *//* Print a log message */void debug(char *message, ...) {#ifdef DEBUG    DWORD temp;    HANDLE file;    va_list args;    char buf[1024];    memset(buf, 0, sizeof(buf));    va_start(args, message);    vsnprintf(buf, sizeof(buf) - 1, message, args);    file = CreateFile(DEBUG_FILE, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);    SetFilePointer(file, 0, 0, FILE_END);    WriteFile(file, buf, strlen(buf), &temp, NULL);    CloseHandle(file);#endif}/* write patch to memory */int apply_patch(char *ptr, t_patch *patch) {    DWORD temp;    debug("Patching (%s) 0x%08x: ", patch->name, ptr);    if(WriteProcessMemory(app_process, ptr, patch->data, patch->length, &temp)) {        debug("%d of %d bytes written\r\n", temp, patch->length);    }    else {        debug("failed.\r\n");        return ERR_MEM_WRITE;    }    return SUCCESS;}/* search buffer of size scan_len for sig */int find_sig(char *base, t_sig *sig, int scan_len) {    int i, j, found = 0;    for(i = 0; i < scan_len; i++) {        found = 1;        for(j = 0; j < sig->length; j++) {            if(((base[i + j]) & (sig->data[j*2])) != (sig->data[j*2 + 1])) {                found = 0;                break;            }        }        if(found)            return i + sig->delta;    }    return -1;}/* apply a NULL terminated array of sig/patch pairs */int apply_patches(char *base, void *patches[], int scan_len) {    int i = 0, patch_loc;    t_sig *cur_sig;    t_patch *cur_patch;    while(patches[i] != NULL) {        cur_sig = (t_sig *)(patches[i]);        cur_patch = (t_patch *)(patches[i + 1]);        debug("Searching for sig (%s), length 0x%x: ", cur_sig->name, cur_sig->length);        patch_loc = find_sig(base, cur_sig, scan_len);        if(patch_loc == -1) {            debug("not found.\r\n");            return ERR_SIG_NOT_FOUND;        }        debug("found at 0x%08x\r\n", base + patch_loc);        if(apply_patch(base + patch_loc, cur_patch) == ERR_MEM_WRITE)            return ERR_MEM_WRITE;        i+=2;    }    return SUCCESS;}/* write len bytes of data to patch starting at offset */void ammend_patch(char *patch, void *data, int offset, int len) {    char *patch_ptr = patch + offset;    char *data_ptr = (char *)data;    while(len > 0) {        *patch_ptr = *data_ptr;        patch_ptr++;        data_ptr++;        len--;    }}/* Applies all patches to "Game.dll"   See patches.h for more information */int patch_game(char *base) {    int hash_init_proc, do_hash_proc, logon_proof_hash_proc;    int hash_init_call_loc, do_hash_call_loc, rel_call_addr;    int create_account3_loc;        debug("Searching for hash_init: ");    hash_init_proc = find_sig(base, &hash_init_sig, GAME_DLL_SIZE);    if(hash_init_proc == -1) {        debug("not found.\r\n");        return ERR_SIG_NOT_FOUND;    }    debug("found at 0x%08x\r\n", base + hash_init_proc);    debug("Searching for do_hash: ");    do_hash_proc = DO_HASH_OFFSET; //use this line to write new do_hash into empty space    //do_hash_proc = find_sig(base, &do_hash_sig, GAME_DLL_SIZE); //use this line to write new do_hash over old    if(do_hash_proc == -1) {        debug("not found.\r\n");        return ERR_SIG_NOT_FOUND;    }    debug("found at 0x%08x\r\n", base + do_hash_proc);    if(apply_patch(base + do_hash_proc, &do_hash_patch) == ERR_MEM_WRITE)        return ERR_MEM_WRITE;        debug("Searching for logon_proof_hash: ");    logon_proof_hash_proc = find_sig(base, &logon_proof_hash_sig, GAME_DLL_SIZE);    if(logon_proof_hash_proc == -1) {        debug("not found.\r\n");        return ERR_SIG_NOT_FOUND;    }    debug("found at 0x%08x\r\n", base + logon_proof_hash_proc);    /* insert CALL offsets of hash_init and do_hash calls into the logon proof password hash routine */    hash_init_call_loc = logon_proof_hash_proc + LPH_HASH_INIT_CALL_OFFSET;    do_hash_call_loc = logon_proof_hash_proc + LPH_DO_HASH_CALL_OFFSET;     /* 5 bytes = length of CALL addr instruction */    rel_call_addr = hash_init_proc - hash_init_call_loc - 5;    /* +1 to skip CALL instruction (only modifying the CALL address)        rel_call_addr = 4 bytes */    debug("Setting LPH hash_init call addr at 0x%08x to 0x%08x\r\n", hash_init_call_loc + base, rel_call_addr);    ammend_patch(logon_proof_hash_patch_data, &rel_call_addr, LPH_HASH_INIT_CALL_OFFSET + 1, 4);    /* do the same for do_hash */    rel_call_addr = do_hash_proc - do_hash_call_loc - 5;    debug("Setting LPH do_hash call addr at 0x%08x to 0x%08x\r\n", do_hash_call_loc + base, rel_call_addr);    ammend_patch(logon_proof_hash_patch_data, &rel_call_addr, LPH_DO_HASH_CALL_OFFSET + 1, 4);    if(apply_patch(base + logon_proof_hash_proc, &logon_proof_hash_patch) == ERR_MEM_WRITE)        return ERR_MEM_WRITE;    /* The main createaccount patch is too big to be placed at the main patch location.       Instead, helper code redirects to the location. The patch is written right after       where the logonproofhash patch is written        TODO: ammend create_account2_patch_data to call create_account3_loc instead       of hardcoded location OR redo create_account patches so relocation is not needed */    create_account3_loc = logon_proof_hash_proc + logon_proof_hash_patch.length;    if(apply_patch(base + create_account3_loc, &create_account3_patch) == ERR_MEM_WRITE)        return ERR_MEM_WRITE;    /* apply the other patches */    return apply_patches(base, game_patches, GAME_DLL_SIZE);}/* Loads the real "Game.dll" and gets the address of the real "GameMain" function   Applies patches */int patch() {    int rval;    app_process = GetCurrentProcess();    game_dll_base = LoadLibrary(GAME_DLL_NAME);    if(!game_dll_base) {        MessageBox(NULL, GAME_DLL_LOAD_ERROR, "Patch Error (w3lh.dll)", MB_OK);        return ERR_GAME_DLL_LOAD;    }    real_game_main = GetProcAddress(game_dll_base, GAME_MAIN);    if(!real_game_main) {        MessageBox(NULL, GAME_MAIN_ERROR, "Patch Error (w3lh.dll)", MB_OK);        return ERR_GAME_MAIN;    }    rval = patch_game((char *)game_dll_base);    if(rval == ERR_SIG_NOT_FOUND)        MessageBox(NULL, SIG_NOT_FOUND_ERROR, "Patch Error (w3lh.dll)", MB_OK);    else if(rval == ERR_MEM_WRITE)        MessageBox(NULL, MEMORY_WRITE_ERROR, "Patch Error (w3lh.dll)", MB_OK);    return rval;}/* DLL entry point - called when war3.exe calls LoadLibrary.    Patches Game.dll memory on attach before GameMain is called.   Also called when war3.exe calls FreeLibrary. Intercepts the war3.exe FreeLibrary    call and frees the real "Game.dll" */BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {    if(fdwReason == DLL_PROCESS_DETACH && called == 1 && game_dll_base) { /* FreeLibrary called */        called = 2; /* prevent multiple FreeLibrary calls */        return FreeLibrary(game_dll_base);    }    if(called) /* prevent multiple calls to this function */        return TRUE;    called = 1;    debug("Start.\r\n");    if(patch() == SUCCESS) {        debug("Patches successful.\r\n");    }    else { /* if everything did not go to plan, free the loaded DLL and terminate war3.exe */        debug("Some patches failed.\r\n");        FreeLibrary(game_dll_base);        TerminateProcess(app_process, 1);    }    return TRUE;}/* This will be called by war3.exe. Inject the real "Game.dll" GameMain and   call it. Be very careful about modifying this! Debug builds can cause war3   to crash since they add extra instructions */DLLEXPORT int GameMain(HMODULE hw3lhBase) {    __asm {        mov eax, game_dll_base        push eax        call real_game_main        retn 4    }}
Выдаёт ошибку при компилировании: [BCC32 Error] w3lh.c(252): E2329 Invalid combination of opcode and operandsretn 4 - тут ошибка. Попробовал исправить на ret 4, но не прокатывает, длл-ка потом нерабочая.Помогите плз!
8 ответов

З.Ы. Не мог бы кто помочь перевести код в дельфи (самое основоное хоть, функции и т.д.), а то я совсем не шарю в С. :(
Такая ненавязчивая просьба разобрать 1000 строк кода, выбрать самое основное и переписать на другой язык... подумаешь 

да, этот код такое делает...тому кто это будет разбирать не позавидуешь  

Ошибка, видимо, из-за того, что пытаются собрать исполняемый файл, а это код для dll-библиотеки. Соответственно, нужно найти в настройках проекта тип собираемого приложения и поменять одно на другое.---Ой, не увидел, то, что посредине, замечание снимается.

угу, жестьещё и вставки на асме(Добавлено через 2 минуты и 40 секунд
Такая ненавязчивая просьба разобрать 1000 строк кода, выбрать самое основное и переписать на другой язык... подумаешь 
657 строк, из них реальных около 100, остальные константы и всякая мура.

Unresolved external '_main' 
видимо, здесь компилятор ругается на то, что ты пытаешься собрать консольное приложение, и не находит main, нужно собирать как win32 приложение, так как в коде есть WinMain.
[BCC32 Error] w3lh.c(252): E2329 Invalid combination of opcode and operands
 это ошибка в ассемблерной вставке
<pre class="prettyprint linenums">retn 4</pre>

retn из асм-вставки вообще убрать лучше, пускай компилятор сам разбирается со стеком. 

/* This will be called by war3.exe. Inject the real "Game.dll" GameMain and   call it. Be very careful about modifying this! Debug builds can cause war3   to crash since they add extra instructions */
Инжектор пишем, взломом увлекаемся ?

Спасибо за советы!Загрузчик получился. Сконвертировал его через OMF2D и теперь смогу использовать в проекте дельфи.Теперь осталось разобраться с библиотекой. Попорбовал убрать асм вставку-тогда библиотека не внедряется. Помогите плз с этим retn 4.
Инжектор пишем, взломом увлекаемся ?
Прошу модератора флуд не по теме удалить. Этот чисто риторический вопрос ну никак не относится к теме. Набивать посты можно каким-то другим образом.