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

Last change on this file since 4656 was 4656, checked in by Sam Hocevar, 10 years ago

CreateFile?() diversion proof of concept.

  • Property svn:keywords set to Id
File size: 3.9 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#include "lib-load.h"
37
38#if defined HAVE_WINDOWS_H
39static void insert_funcs(void *);
40
41/* TODO: get rid of this later */
42HINSTANCE (WINAPI *LoadLibraryA_orig)(LPCSTR);
43HINSTANCE WINAPI LoadLibraryA_new(LPCSTR path)
44{
45    void *ret;
46    fprintf(stderr, "This is the diverted LoadLibraryA\n");
47    ret = LoadLibraryA_orig(path);
48    fprintf(stderr, "Now the real LoadLibraryA was called\n");
49    return ret;
50}
51
52BOOL (WINAPI *AllocConsole_orig)(void);
53BOOL WINAPI AllocConsole_new(void)
54{
55    fprintf(stderr, "Allocating console\n");
56    return AllocConsole_orig();
57}
58
59BOOL (WINAPI *AttachConsole_orig)(DWORD);
60BOOL WINAPI AttachConsole_new(DWORD d)
61{
62    fprintf(stderr, "Attaching console\n");
63    return AttachConsole_orig(d);
64}
65#endif
66
67void _zz_sys_init(void)
68{
69#if defined HAVE_WINDOWS_H
70    MEMORY_BASIC_INFORMATION mbi;
71    MODULEENTRY32 entry;
72    void *list;
73    int k;
74
75    VirtualQuery(_zz_sys_init, &mbi, sizeof(mbi));
76    list = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
77    entry.dwSize = sizeof(entry);
78    for(k = Module32First(list, &entry); k; k = Module32Next(list, &entry))
79    {
80        if(entry.hModule == mbi.AllocationBase)
81            continue; /* Don't replace our own functions */
82
83        insert_funcs(entry.hModule);
84    }
85    CloseHandle(list);
86#else
87    /* Nothing to do on our platform */
88#endif
89}
90
91#if defined HAVE_WINDOWS_H
92static void insert_funcs(void *module)
93{
94    static zzuf_table_t *list[] =
95    {
96        table_stream,
97        table_win32,
98    };
99
100    zzuf_table_t *diversion;
101    void *lib;
102    unsigned long dummy;
103    import_t import;
104    thunk_t thunk;
105    int k, j, i;
106
107    import = (import_t)
108        ImageDirectoryEntryToData(module, TRUE,
109                                  IMAGE_DIRECTORY_ENTRY_IMPORT, &dummy);
110    if(!import)
111        return;
112
113    for (k = 0, diversion = NULL; k < sizeof(list) / sizeof(*list); )
114    {
115        if (!diversion)
116            diversion = list[k];
117
118        if (!diversion->lib)
119        {
120            k++;
121            diversion = NULL;
122            continue;
123        }
124
125        lib = GetModuleHandleA(diversion->lib);
126        *diversion->old = (void *)GetProcAddress(lib, diversion->name);
127
128        for(j = 0; import[j].Name; j++)
129        {
130            char *name = (char *)module + import[j].Name;
131            if(lstrcmpiA(name, diversion->lib) != 0)
132                continue;
133
134            thunk = (thunk_t)((char *)module + import->FirstThunk);
135            for(i = 0; thunk[i].u1.Function; i++)
136            {
137                void **func = (void **)&thunk[i].u1.Function;
138                if(*func != *diversion->old)
139                    continue;
140
141                /* FIXME: The StarCraft 2 hack uses two methods for function
142                    * diversion. See HookSsdt() and HookHotPatch(). */
143                VirtualProtect(func, sizeof(func), PAGE_EXECUTE_READWRITE, &dummy);
144                WriteProcessMemory(GetCurrentProcess(), func, &diversion->new,
145                                    sizeof(diversion->new), NULL);
146            }
147        }
148
149        diversion++;
150    }
151}
152#endif
153
Note: See TracBrowser for help on using the repository browser.