source: zzuf/trunk/src/libzzuf/sys.c @ 4648

Last change on this file since 4648 was 4648, checked in by Sam Hocevar, 11 years ago

Improve the DLL injection code. Now seems to work rather
well under Windows. But it needs a lot of polishing.

  • Property svn:keywords set to Id
File size: 3.2 KB
Line 
1/*
2 *  zzuf - general purpose fuzzer
3 *  Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
4 *                All Rights Reserved
5 *
6 *  This program is free software. It comes without any warranty, to
7 *  the extent permitted by applicable law. You can redistribute it
8 *  and/or modify it under the terms of the Do What The Fuck You Want
9 *  To Public License, Version 2, as published by Sam Hocevar. See
10 *  http://sam.zoy.org/wtfpl/COPYING for more details.
11 */
12
13/*
14 *  sys.c: system-dependent initialisation
15 */
16
17#include "config.h"
18
19#if defined HAVE_STDINT_H
20#   include <stdint.h>
21#elif defined HAVE_INTTYPES_H
22#   include <inttypes.h>
23#endif
24
25#if defined HAVE_WINDOWS_H
26#   include <windows.h>
27#   include <imagehlp.h>
28#   include <tlhelp32.h>
29#   define import_t PIMAGE_IMPORT_DESCRIPTOR
30#   define thunk_t PIMAGE_THUNK_DATA
31#endif
32
33#include <stdio.h>
34
35#include "sys.h"
36
37#if defined HAVE_WINDOWS_H
38static void insert_func(void *, void *, void *);
39
40/* TODO: get rid of this later */
41HINSTANCE (WINAPI *LoadLibraryA_orig)(LPCSTR);
42HINSTANCE WINAPI LoadLibraryA_new(LPCSTR path)
43{
44    void *ret;
45    fprintf(stderr, "If you see this message, DLL preloading worked\n");
46    ret = LoadLibraryA_orig(path);
47    fprintf(stderr, "If you see this message, function diversion worked\n");
48    return ret;
49}
50#endif
51
52void _zz_sys_init(void)
53{
54#if defined HAVE_WINDOWS_H
55    MEMORY_BASIC_INFORMATION mbi;
56    MODULEENTRY32 entry;
57    void *list, *kernel32;
58    int k;
59
60    kernel32 = GetModuleHandleA("kernel32.dll");
61    LoadLibraryA_orig = (void *)GetProcAddress(kernel32, "LoadLibraryA");
62
63    VirtualQuery(_zz_sys_init, &mbi, sizeof(mbi));
64    list = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
65    entry.dwSize = sizeof(entry);
66    for(k = Module32First(list, &entry); k; k = Module32Next(list, &entry))
67    {
68        if(entry.hModule == mbi.AllocationBase)
69            continue; /* Don't replace our own functions */
70
71        insert_func(entry.hModule, LoadLibraryA_orig, LoadLibraryA_new);
72    }
73    CloseHandle(list);
74#else
75    /* Nothing to do on our platform */
76#endif
77}
78
79#if defined HAVE_WINDOWS_H
80static void insert_func(void *module, void *old, void *new)
81{
82    unsigned long dummy;
83    import_t import;
84    thunk_t thunk;
85    int j, i;
86
87    import = (import_t)
88        ImageDirectoryEntryToData(module, TRUE,
89                                  IMAGE_DIRECTORY_ENTRY_IMPORT, &dummy);
90    if(!import)
91        return;
92
93    for(j = 0; import[j].Name; j++)
94    {
95        char *name = (char *)module + import[j].Name;
96        if(lstrcmpiA(name, "kernel32.dll") != 0)
97            continue;
98
99        thunk = (thunk_t)((char *)module + import->FirstThunk);
100        for(i = 0; thunk[i].u1.Function; i++)
101        {
102            void **func = (void **)&thunk[i].u1.Function;
103            if(*func != old)
104                continue;
105
106            /* FIXME: The StarCraft 2 hack uses two methods for function
107             * diversion. See HookSsdt() and HookHotPatch(). */
108            VirtualProtect(func, sizeof(func), PAGE_EXECUTE_READWRITE, &dummy);
109            WriteProcessMemory(GetCurrentProcess(), func, &new,
110                               sizeof(new), NULL);
111            return;
112        }
113    }
114}
115#endif
116
Note: See TracBrowser for help on using the repository browser.