Changeset 4837 for zzuf


Ignore:
Timestamp:
Aug 20, 2012, 2:27:26 PM (7 years ago)
Author:
wisk
Message:

add relocate_hook to improve api hooking, fix dll name string comparison (no case sensitive), fix used after free on win32, add more hooks related to async file access

Location:
zzuf/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • zzuf/trunk/msvc/config.h

    r4836 r4837  
    5454/* #undef HAVE_GETDELIM */
    5555/* #undef HAVE_GETLINE */
     56#define HAVE_CREATEIOCOMPLETIONPORT 1
     57#define HAVE_GETQUEUEDCOMPLETIONSTATUS 1
     58#define HAVE_GETOVERLAPPEDRESULT 1
    5659#define HAVE_GETPAGESIZE 1
    5760/* #undef HAVE_GETTIMEOFDAY */
  • zzuf/trunk/src/libzzuf/lib-win32.c

    r4834 r4837  
    6262    LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE);
    6363#endif
     64#if defined HAVE_CREATEIOCOMPLETIONPORT
     65static HANDLE (__stdcall *ORIG(CreateIoCompletionPort))(HANDLE, HANDLE, ULONG_PTR, DWORD);
     66#endif
     67#if defined HAVE_GETQUEUEDCOMPLETIONSTATUS
     68static BOOL (__stdcall *ORIG(GetQueuedCompletionStatus))(HANDLE, LPDWORD, PULONG_PTR, LPOVERLAPPED *, DWORD);
     69#endif
     70#if defined HAVE_GETOVERLAPPEDRESULT
     71static BOOL (__stdcall *ORIG(GetOverlappedResult))(HANDLE, LPOVERLAPPED, LPDWORD, BOOL);
     72#endif
    6473#if defined HAVE_CREATEFILEMAPPINGA
    6574static HANDLE (__stdcall *ORIG(CreateFileMappingA))(HANDLE, LPSECURITY_ATTRIBUTES,
     
    201210#endif
    202211
     212#if defined HAVE_CREATEIOCOMPLETIONPORT
     213HANDLE __stdcall NEW(CreateIoCompletionPort)(HANDLE FileHandle, HANDLE ExistingCompletionPort, ULONG_PTR CompletionKey, DWORD NumberOfConcurrentThreads)
     214{
     215        HANDLE ret;
     216
     217        ret = ORIG(CreateIoCompletionPort)(FileHandle, ExistingCompletionPort, CompletionKey, NumberOfConcurrentThreads);
     218
     219        debug("GetQueuedCompletionStatus(0x%08x, 0x%08x, 0x%08x, %d) = 0x%08x",
     220                FileHandle, ExistingCompletionPort, CompletionKey, NumberOfConcurrentThreads, ret);
     221
     222    if (!_zz_ready || !_zz_iswatched(FileHandle) /*|| !_zz_hostwatched(hFile)*/ || _zz_islocked(FileHandle) || !_zz_isactive(FileHandle))
     223        return ret;
     224
     225    if (ret != NULL)
     226    {
     227        debug("handle %#08x is registered", ret);
     228        _zz_register(ret);
     229    }
     230
     231        return ret;
     232}
     233#endif
     234
     235#if defined HAVE_GETQUEUEDCOMPLETIONSTATUS
     236BOOL __stdcall NEW(GetQueuedCompletionStatus)(HANDLE CompletionPort, LPDWORD lpNumberOfBytes, PULONG_PTR lpCompletion, LPOVERLAPPED *lpOverlapped, DWORD dwMilliseconds)
     237{
     238    BOOL ret;
     239
     240    ret = ORIG(GetQueuedCompletionStatus)(CompletionPort, lpNumberOfBytes, lpCompletion, lpOverlapped, dwMilliseconds);
     241
     242        debug("GetQueuedCompletionStatus(0x%08x, { %d }, %p, %p, %d) = %s",
     243        CompletionPort, *lpNumberOfBytes, lpCompletion, lpOverlapped, dwMilliseconds, (ret ? "TRUE" : "FALSE"));
     244
     245    return ret;
     246}
     247#endif
     248
     249#if defined HAVE_GETOVERLAPPEDRESULT
     250BOOL __stdcall NEW(GetOverlappedResult)(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, BOOL bWait)
     251{
     252    BOOL ret;
     253
     254    ret = ORIG(GetOverlappedResult)(hFile, lpOverlapped, lpNumberOfBytesTransferred, bWait);
     255
     256    debug("GetOverlappedResult(0x%#08x, %p, %p, %s) = %s",
     257        hFile, lpOverlapped, lpNumberOfBytesTransferred, (bWait ? "TRUE" : "FALSE"), (ret ? "TRUE" : "FALSE"));
     258
     259    return ret;
     260}
     261#endif
     262
    203263#if defined HAVE_CREATEFILEMAPPINGA
    204264HANDLE __stdcall NEW(CreateFileMappingA)(HANDLE hFile, LPSECURITY_ATTRIBUTES lpAttributes,
     
    299359    DIVERT(CreateFileA),
    300360    DIVERT(CreateFileW),
     361    DIVERT(ReadFile),
     362    DIVERT(ReadFileEx),
     363        DIVERT(CreateIoCompletionPort),
     364    DIVERT(GetQueuedCompletionStatus),
     365    DIVERT(GetOverlappedResult),
    301366    DIVERT(CreateFileMappingA),
    302367    DIVERT(CreateFileMappingW),
    303368    DIVERT(MapViewOfFile),
    304     DIVERT(ReadFile),
    305     DIVERT(ReadFileEx),
    306369    DIVERT_END
    307370};
  • zzuf/trunk/src/libzzuf/libzzuf.c

    r4827 r4837  
    234234            break;
    235235        case DLL_PROCESS_DETACH:
    236             _zz_fini();
     236            //_zz_fini();
    237237            DeleteCriticalSection(&_zz_pipe_cs);
    238238            break;
  • zzuf/trunk/src/libzzuf/sys.c

    r4833 r4837  
    106106    if (modrm == 0x05) /* [(rip) + sdword] */ return 1 + 4;
    107107
    108     /* Does the instruciton have a SIB byte ? */
     108    /* Does this instruction have a SIB byte ? */
    109109    return 1 + (!!(((modrm & 0x7) == 0x4) && ((modrm >> 6) != 0x3))) + modrm_size[modrm >> 6];
    110110}
    111111
    112 /* zz_lde is a _very_ simple length disassemble engine.
    113  * x64 is not tested and should not work. */
     112/* zz_lde is a _very_ simple length disassemble engine. */
    114113static int zz_lde(uint8_t *code)
    115114{
     
    131130    switch (opcd)
    132131    {
    133     case 0x68: insn_size += 4; break; /* PUSH Iv */
    134     case 0x6a: insn_size += 1; break; /* PUSH Ib */
     132    case 0x68: return (insn_size + 4); /* PUSH Iv */
     133    case 0x6a: return (insn_size + 1); /* PUSH Ib */
     134    case 0x90: return insn_size;       /* NOP     */
    135135    default: break;
    136136    }
     
    144144    case 0x89: /* mov Ev, Gv */
    145145    case 0x8b: /* mov Gv, Ev */
    146         insn_size += modrm_sib_size(code + insn_size);
    147         break;
     146        return (insn_size + modrm_sib_size(code + insn_size));
    148147
    149148    case 0x80: /* Group#1 Eb, Ib */
    150149    case 0x82: /* Group#1 Eb, Ib */
    151150    case 0x83: /* Group#1 Ev, Ib */
    152         insn_size += (modrm_sib_size(code + insn_size) + 1);
    153         break;
     151        return (insn_size + (modrm_sib_size(code + insn_size) + 1));
    154152
    155153    case 0x81: /* Group#1 Ev, Iz */
    156         insn_size += (modrm_sib_size(code + insn_size) + 4);
    157         break;
     154        return (insn_size + (modrm_sib_size(code + insn_size) + 4));
    158155
    159156    case 0xff:
    160157        if ((code[insn_size] & 0x38) == 0x30) /* PUSH Ev */
    161             insn_size += modrm_sib_size(code + insn_size);
     158            return (insn_size + modrm_sib_size(code + insn_size));
    162159        break;
    163160
     
    165162    }
    166163
    167     return insn_size;
     164    return 0;
    168165}
    169166
     
    261258}
    262259
     260/*
     261 * Sometimes Windows APIs are a stub and contain only a JMP to the real function.
     262 * To avoid to relocate a JMP, we use the destination address.
     263 */
     264static int relocate_hook(uint8_t **code)
     265{
     266        uint8_t *cur_code = *code;
     267
     268#ifdef _M_AMD64
     269    // we ignore the REX prefix
     270    if ((*cur_code & 0xf8) == 0x48)
     271                ++cur_code;
     272#endif
     273
     274    /* JMP Jd */
     275    if (*cur_code == 0xe9)
     276    {
     277        *cur_code += (5 + *(uint32_t *)(cur_code + 1));
     278        return 0;
     279    }
     280
     281    /* JMP [(rip)+addr] */
     282    else if (!memcmp(cur_code, "\xff\x25", 2))
     283    {
     284#ifdef _M_AMD64
     285        uint8_t **dst_addr = (uint8_t **)(cur_code + 6 + *(uint32_t *)(cur_code + 2));
     286        *code = *dst_addr;
     287#elif _M_IX86
     288        /* UNTESTED ! */
     289        uint8_t **dst_addr = *(uint32_t *)(*cur_code + 2);
     290        *code = *dst_addr;
     291#else
     292#   error Unsupported architecture !
     293#endif
     294        return 0;
     295    }
     296
     297    return -1;
     298}
     299
    263300/* This function allows to hook any API. To do so, it disassembles the beginning of the
    264301 * targeted function and looks for, at least, 5 bytes (size of JMP Jd).
     
    274311    size_t trampoline_size  = 0;
    275312    DWORD old_prot;
     313    uint8_t *reloc_old_api  = old_api;
     314
     315    while ((relocate_hook(&reloc_old_api)) >= 0)
     316        old_api = reloc_old_api;
    276317
    277318    *trampoline_api = NULL;
     
    345386           {
    346387               fprintf(stderr, "unable to load %s\n", diversion->lib);
    347                return;
     388               continue;
    348389           }
    349390        }
     
    351392        {
    352393            fprintf(stderr, "unable to get pointer to %s\n", diversion->name);
    353             return;
     394            continue;
    354395        }
    355396        if (hook_inline(old_api, diversion->new, &trampoline_api) < 0)
    356397        {
    357398            fprintf(stderr, "hook_inline failed while hooking %s!%s\n", diversion->lib, diversion->name);
    358             return;
     399            continue;
    359400        }
    360401        *diversion->old = trampoline_api;
  • zzuf/trunk/src/myfork.c

    r4835 r4837  
    486486
    487487    /* Resolve LoadLibraryA from the target process memory context */
    488     rldlib = get_proc_address(process, pid, "LoadLibraryA");
     488    if ((rldlib = get_proc_address(process, pid, "LoadLibraryA")) == NULL) goto _return;
    489489
    490490    if ((rpl = VirtualAllocEx(process, NULL, pl_len, MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == NULL) goto _return;
     
    545545        uint8_t *base = entry.modBaseAddr;
    546546
    547         if (strcmp("kernel32.dll", entry.szModule))
     547        if (stricmp("kernel32.dll", entry.szModule))
    548548            continue;
    549549
Note: See TracChangeset for help on using the changeset viewer.