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

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

Divert AttachConsole?() and AllocConsole?() for debugging purposes.

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