Changeset 4830


Ignore:
Timestamp:
Jul 12, 2012, 4:26:10 PM (7 years ago)
Author:
wisk
Message:

start to implement hotpatch hook on win32 port, but some API don't look to use it for some reason (e.g. kernel32ReadFile)

Location:
zzuf/trunk/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • zzuf/trunk/src/libzzuf/sys.c

    r4826 r4830  
    7373{
    7474#if defined HAVE_WINDOWS_H
     75
    7576    MEMORY_BASIC_INFORMATION mbi;
    7677    MODULEENTRY32 entry;
     
    9192    }
    9293    CloseHandle(list);
     94
    9395#elif defined HAVE_DLFCN_H
    9496    /* If glibc is recent enough, we use dladdr() to get its address. This
     
    111113
    112114#if defined HAVE_WINDOWS_H
     115
     116#define MK_JMP_JD(dst, src) ((dst) - ((src) + 5))
     117
     118/*
     119 * This function hooks a windows API using the hotpatch method
     120 *     old_api must point to the original windows API.
     121 *     new_api must point to the hook function
     122 *     trampoline_api is filled by the function and contains the
     123 *     function to call to call the original API.
     124 *
     125 * Windows API should start with the following instructions
     126 * mov edi, edi
     127 * push ebp
     128 * mov ebp, esp
     129 * which makes a 5 bytes, the perfect size to insert a jmp to the new api
     130 */
     131static int hook_hotpatch(uint8_t *old_api, uint8_t *new_api, uint8_t **trampoline_api)
     132{
     133    int res = -1;
     134    uint8_t prolog[5];
     135    uint8_t jmp_prolog[5];
     136    static uint8_t const hotpatch_prolog[] = "\x8b\xff\x55\x8b\xec";
     137    uint8_t *trampoline;
     138    DWORD old_prot;
     139
     140    *trampoline_api = NULL;
     141
     142    /* Check if the targeted API contains the hotpatch feature */
     143    memcpy(prolog, old_api, sizeof(prolog));
     144    if (memcmp(prolog, hotpatch_prolog, sizeof(prolog))) goto _out;
     145
     146    jmp_prolog[0] = '\xe9'; /* jmp Jd */
     147    *(uint32_t *)(&jmp_prolog[1]) = MK_JMP_JD(new_api, old_api);
     148
     149    trampoline = malloc(10); /* size of hotpatch_prolog + sizeof of jmp Jd */
     150    memcpy(trampoline, hotpatch_prolog, sizeof(hotpatch_prolog) - 1);
     151    trampoline[5] = '\xe9'; /* jmp Jd */
     152    *(uint32_t *)&trampoline[6] = MK_JMP_JD(old_api + sizeof(hotpatch_prolog) - 1, trampoline + sizeof(hotpatch_prolog) - 1);
     153
     154    /* We must make the trampoline executable, this line is required because of DEP */
     155    /* NOTE: We _must_ set the write protection, otherwise the heap allocator will crash ! */
     156    if (!VirtualProtect(trampoline, 10, PAGE_EXECUTE_READWRITE, &old_prot)) goto _out;
     157
     158    /* We patch the targeted API, so we must set it as writable */
     159    if (!VirtualProtect(old_api, sizeof(jmp_prolog), PAGE_EXECUTE_READWRITE, &old_prot)) goto _out;
     160    memcpy(old_api, jmp_prolog, sizeof(jmp_prolog));
     161    VirtualProtect(old_api, sizeof(jmp_prolog), old_prot, &old_prot); /* we don't care if this functon fails */
     162
     163    *trampoline_api = trampoline;
     164
     165    res = 0;
     166
     167_out:
     168    if (res < 0)
     169    {
     170        if (*trampoline_api)
     171        {
     172            free(*trampoline_api);
     173            trampoline_api = NULL;
     174        }
     175    }
     176
     177    return res;
     178}
     179
     180/*
     181 * Even if hook_hotpatch is working, it's look that some API don't use it anymore (kernel32!ReadFile)
     182 * So we stay with IAT hook at this time
     183 */
     184#if 0
     185static void insert_funcs(void *module)
     186{
     187    static zzuf_table_t *list[] =
     188    {
     189        table_win32,
     190    };
     191
     192    zzuf_table_t *diversion;
     193    HMODULE lib;
     194
     195    for (diversion = *list; diversion->lib; diversion++)
     196    {
     197        uint8_t *old_api;
     198        uint8_t *trampoline_api;
     199
     200        /* most of the time, the dll is already loaded */
     201        if ((lib = GetModuleHandleA(diversion->lib)) == NULL)
     202        {
     203           if ((lib = LoadLibraryA(diversion->lib)) == NULL)
     204           {
     205               fprintf(stderr, "unable to load %s\n", diversion->lib);
     206               return;
     207           }
     208        }
     209        if ((old_api = (uint8_t *)GetProcAddress(lib, diversion->name)) == NULL)
     210        {
     211            fprintf(stderr, "unable to get pointer to %s\n", diversion->name);
     212            return;
     213        }
     214        if (hook_hotpatch(old_api, diversion->new, &trampoline_api) < 0)
     215        {
     216            fprintf(stderr, "hook_hotpatch failed while hooking %s!%s\n", diversion->lib, diversion->name);
     217            return;
     218        }
     219        *diversion->old = trampoline_api;
     220    }
     221
     222    (void)module; /* not needed anymore */
     223
     224}
     225#endif
     226
    113227static void insert_funcs(void *module)
    114228{
  • zzuf/trunk/src/myfork.c

    r4828 r4830  
    378378    }
    379379
     380    /* insert your breakpoint here to have a chance to attach a debugger to libzzuf.dll */
    380381    ret = ResumeThread(pinfo.hThread);
    381382    if(ret < 0)
Note: See TracChangeset for help on using the changeset viewer.