source: zzuf/trunk/src/libzzuf/lib-win32.c @ 4839

Last change on this file since 4839 was 4839, checked in by Sam Hocevar, 7 years ago

win32: add some console handling function diversions.

File size: 14.9 KB
Line 
1/*
2 *  zzuf - general purpose fuzzer
3 *  Copyright (c) 2006-2012 Sam Hocevar <sam@hocevar.net>
4 *                2012 Kévin Szkudłapski <kszkudlapski@quarkslab.com>
5 *                All Rights Reserved
6 *
7 *  This program is free software. It comes without any warranty, to
8 *  the extent permitted by applicable law. You can redistribute it
9 *  and/or modify it under the terms of the Do What The Fuck You Want
10 *  To Public License, Version 2, as published by Sam Hocevar. See
11 *  http://sam.zoy.org/wtfpl/COPYING for more details.
12 */
13
14/*
15 *  load-win32.c: loaded Win32 functions
16 */
17
18#include "config.h"
19
20#if defined HAVE_STDINT_H
21#   include <stdint.h>
22#elif defined HAVE_INTTYPES_H
23#   include <inttypes.h>
24#endif
25
26#include <stdio.h>
27
28#if defined HAVE_WINDOWS_H
29#   include <windows.h>
30#endif
31#if defined HAVE_IO_H
32#   include <io.h>
33#endif
34
35#include "common.h"
36#include "libzzuf.h"
37#include "lib-load.h"
38#include "debug.h"
39#include "fuzz.h"
40#include "fd.h"
41
42/* Kernel functions that we divert */
43#if defined HAVE_CREATEFILEA
44static HANDLE (__stdcall *ORIG(CreateFileA))(LPCSTR, DWORD, DWORD,
45                                             LPSECURITY_ATTRIBUTES,
46                                             DWORD, DWORD, HANDLE);
47#endif
48#if defined HAVE_CREATEFILEW
49static HANDLE (__stdcall *ORIG(CreateFileW))(LPCWSTR, DWORD, DWORD,
50                                             LPSECURITY_ATTRIBUTES,
51                                             DWORD, DWORD, HANDLE);
52#endif
53#if defined HAVE_REOPENFILE
54static HANDLE (__stdcall *ORIG(ReOpenFile))(HANDLE, DWORD,
55                                            DWORD, DWORD);
56#endif
57#if defined HAVE_READFILE
58static BOOL (__stdcall *ORIG(ReadFile))(HANDLE, LPVOID, DWORD, LPDWORD,
59                                        LPOVERLAPPED);
60#endif
61#if defined HAVE_READFILEEX
62static BOOL (__stdcall *ORIG(ReadFileEx))(HANDLE, LPVOID, DWORD, LPDWORD,
63    LPOVERLAPPED, LPOVERLAPPED_COMPLETION_ROUTINE);
64#endif
65#if defined HAVE_CREATEIOCOMPLETIONPORT
66static HANDLE (__stdcall *ORIG(CreateIoCompletionPort))(HANDLE, HANDLE, ULONG_PTR, DWORD);
67#endif
68#if defined HAVE_GETQUEUEDCOMPLETIONSTATUS
69static BOOL (__stdcall *ORIG(GetQueuedCompletionStatus))(HANDLE, LPDWORD, PULONG_PTR, LPOVERLAPPED *, DWORD);
70#endif
71#if defined HAVE_GETOVERLAPPEDRESULT
72static BOOL (__stdcall *ORIG(GetOverlappedResult))(HANDLE, LPOVERLAPPED, LPDWORD, BOOL);
73#endif
74#if defined HAVE_CREATEFILEMAPPINGA
75static HANDLE (__stdcall *ORIG(CreateFileMappingA))(HANDLE, LPSECURITY_ATTRIBUTES,
76                                                   DWORD, DWORD, DWORD, LPCSTR);
77#endif
78#if defined HAVE_CREATEFILEMAPPINGW
79static HANDLE (__stdcall *ORIG(CreateFileMappingW))(HANDLE, LPSECURITY_ATTRIBUTES,
80                                                   DWORD, DWORD, DWORD, LPCWSTR);
81#endif
82#ifdef HAVE_MAPVIEWOFFILE
83static LPVOID (__stdcall *ORIG(MapViewOfFile))(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
84#endif
85#if defined HAVE_CLOSEHANDLE
86static BOOL (__stdcall *ORIG(CloseHandle))(HANDLE);
87#endif
88#if defined HAVE_ALLOCCONSOLE
89static BOOL (__stdcall *ORIG(AllocConsole))();
90#endif
91#if defined HAVE_ATTACHCONSOLE
92static BOOL (__stdcall *ORIG(AttachConsole))(DWORD dwProcessId);
93#endif
94#if defined HAVE_SETCONSOLEMODE
95static BOOL (__stdcall *ORIG(SetConsoleMode))(HANDLE hConsoleHandle,
96                                              DWORD dwMode);
97#endif
98#if defined HAVE_WRITECONSOLEOUTPUTA
99static BOOL (__stdcall *ORIG(WriteConsoleOutputA))(HANDLE hConsoleOutput,
100                 CONST CHAR_INFO *lpBuffer, COORD dwBufferSize,
101                 COORD dwBufferCoord, PSMALL_RECT lpWriteRegion);
102#endif
103#if defined HAVE_WRITECONSOLEOUTPUTW
104static BOOL (__stdcall *ORIG(WriteConsoleOutputW))(HANDLE hConsoleOutput,
105                 CONST CHAR_INFO *lpBuffer, COORD dwBufferSize,
106                 COORD dwBufferCoord, PSMALL_RECT lpWriteRegion);
107#endif
108
109/*
110 * CreateFileA, CreateFileW
111 */
112
113#if defined HAVE_CREATEFILEA
114HANDLE __stdcall NEW(CreateFileA)(LPCSTR lpFileName, DWORD dwDesiredAccess,
115           DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
116           DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
117           HANDLE hTemplateFile)
118{
119    HANDLE ret;
120
121    ret = ORIG(CreateFileA)(lpFileName, dwDesiredAccess, dwShareMode,
122                            lpSecurityAttributes, dwCreationDisposition,
123                            dwFlagsAndAttributes, hTemplateFile);
124    debug("CreateFileA(\"%s\", 0x%x, 0x%x, {...}, 0x%x, 0x%x, {...}) = %#08x",
125          lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition,
126          dwFlagsAndAttributes, (int)ret);
127
128    if(!_zz_ready || _zz_islocked(-1)) return ret;
129    if (ret != INVALID_HANDLE_VALUE && dwCreationDisposition == OPEN_EXISTING && _zz_mustwatch(lpFileName))
130    {
131        _zz_register(ret);
132    }
133
134    return ret;
135}
136#endif
137
138#if defined HAVE_CREATEFILEW
139HANDLE __stdcall NEW(CreateFileW)(LPCWSTR lpFileName, DWORD dwDesiredAccess,
140           DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
141           DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
142           HANDLE hTemplateFile)
143{
144    HANDLE ret;
145    ret = ORIG(CreateFileW)(lpFileName, dwDesiredAccess, dwShareMode,
146                            lpSecurityAttributes, dwCreationDisposition,
147                            dwFlagsAndAttributes, hTemplateFile);
148    debug("CreateFileW(\"%S\", 0x%x, 0x%x, {...}, 0x%x, 0x%x, {...}) = %#08x",
149          lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition,
150          dwFlagsAndAttributes, (int)ret);
151
152    if(!_zz_ready || _zz_islocked(-1)) return ret;
153    if (ret != INVALID_HANDLE_VALUE && dwCreationDisposition == OPEN_EXISTING && _zz_mustwatchw(lpFileName))
154    {
155        debug("handle %#08x is registered", ret);
156        _zz_register(ret);
157    }
158
159
160    return ret;
161}
162#endif
163
164#if defined HAVE_REOPENFILE
165HANDLE __stdcall NEW(ReOpenFile)(HANDLE hOriginalFile, DWORD dwDesiredAccess,
166                                 DWORD dwShareMode, DWORD dwFlags)
167{
168    HANDLE ret;
169    ret = ORIG(ReOpenFile)(hOriginalFile, dwDesiredAccess,
170                           dwShareMode, dwFlags);
171    debug("ReOpenFile(%#08x, 0x%x, 0x%x, 0x%x) = %#08x", (int)hOriginalFile,
172          dwDesiredAccess, dwShareMode, dwFlags, (int)ret);
173    return ret;
174}
175#endif
176
177/*
178 * ReadFile
179 */
180
181#if defined HAVE_READFILE
182BOOL __stdcall NEW(ReadFile)(HANDLE hFile, LPVOID lpBuffer,
183           DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
184           LPOVERLAPPED lpOverlapped)
185{
186    BOOL ret;
187    ret = ORIG(ReadFile)(hFile, lpBuffer, nNumberOfBytesToRead,
188                          lpNumberOfBytesRead, lpOverlapped);
189    debug("ReadFile(%#08x, %p, %#08x, %#08x, %p) = %s",
190        hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped, (ret ? "TRUE" : "FALSE"));
191
192    if (!_zz_ready || !_zz_iswatched(hFile) /*|| !_zz_hostwatched(hFile)*/ || _zz_islocked(hFile) || !_zz_isactive(hFile))
193        return ret;
194
195    if (ret)
196    {
197        DWORD bytes_read = lpNumberOfBytesRead ? *lpNumberOfBytesRead : nNumberOfBytesToRead;
198        debug("fuzzing file %#08x\n", hFile);
199        _zz_fuzz(hFile, lpBuffer, bytes_read);
200        _zz_addpos(hFile, bytes_read);
201    }
202    return ret;
203}
204#endif
205
206#if defined HAVE_READFILEEX
207BOOL __stdcall NEW(ReadFileEx)(HANDLE hFile, LPVOID lpBuffer,
208    DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
209    LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
210{
211    BOOL ret;
212
213    ret = ORIG(ReadFileEx)(hFile, lpBuffer, nNumberOfBytesToRead,
214        lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine);
215
216    debug("ReadFileEx(%#08x, %p, %#08x, %p, %p, %p) = %s",
217        hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine, (ret ? "TRUE" : "FALSE"));
218
219    if (!_zz_ready || !_zz_iswatched(hFile) /*|| !_zz_hostwatched(hFile)*/ || _zz_islocked(hFile) || !_zz_isactive(hFile))
220        return ret;
221
222    if (ret)
223    {
224        DWORD bytes_read = lpNumberOfBytesRead ? *lpNumberOfBytesRead : nNumberOfBytesToRead;
225        debug("fuzzing file %#08x\n", hFile);
226        _zz_fuzz(hFile, lpBuffer, bytes_read);
227        _zz_addpos(hFile, bytes_read);
228    }
229    return ret;
230}
231#endif
232
233#if defined HAVE_CREATEIOCOMPLETIONPORT
234HANDLE __stdcall NEW(CreateIoCompletionPort)(HANDLE FileHandle, HANDLE ExistingCompletionPort, ULONG_PTR CompletionKey, DWORD NumberOfConcurrentThreads)
235{
236    HANDLE ret;
237
238    ret = ORIG(CreateIoCompletionPort)(FileHandle, ExistingCompletionPort,
239                                   CompletionKey, NumberOfConcurrentThreads);
240
241    debug("GetQueuedCompletionStatus(0x%08x, 0x%08x, 0x%08x, %d) = 0x%08x",
242          FileHandle, ExistingCompletionPort, CompletionKey,
243          NumberOfConcurrentThreads, ret);
244
245    if (!_zz_ready || !_zz_iswatched(FileHandle) /*|| !_zz_hostwatched(hFile)*/ || _zz_islocked(FileHandle) || !_zz_isactive(FileHandle))
246        return ret;
247
248    if (ret != NULL)
249    {
250        debug("handle %#08x is registered", ret);
251        _zz_register(ret);
252    }
253
254    return ret;
255}
256#endif
257
258#if defined HAVE_GETQUEUEDCOMPLETIONSTATUS
259BOOL __stdcall NEW(GetQueuedCompletionStatus)(HANDLE CompletionPort, LPDWORD lpNumberOfBytes, PULONG_PTR lpCompletion, LPOVERLAPPED *lpOverlapped, DWORD dwMilliseconds)
260{
261    BOOL ret;
262
263    ret = ORIG(GetQueuedCompletionStatus)(CompletionPort, lpNumberOfBytes, lpCompletion, lpOverlapped, dwMilliseconds);
264
265    debug("GetQueuedCompletionStatus(0x%08x, { %d }, %p, %p, %d) = %s",
266        CompletionPort, *lpNumberOfBytes, lpCompletion, lpOverlapped, dwMilliseconds, (ret ? "TRUE" : "FALSE"));
267
268    return ret;
269}
270#endif
271
272#if defined HAVE_GETOVERLAPPEDRESULT
273BOOL __stdcall NEW(GetOverlappedResult)(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, BOOL bWait)
274{
275    BOOL ret;
276
277    ret = ORIG(GetOverlappedResult)(hFile, lpOverlapped, lpNumberOfBytesTransferred, bWait);
278
279    debug("GetOverlappedResult(0x%#08x, %p, %p, %s) = %s",
280        hFile, lpOverlapped, lpNumberOfBytesTransferred, (bWait ? "TRUE" : "FALSE"), (ret ? "TRUE" : "FALSE"));
281
282    return ret;
283}
284#endif
285
286#if defined HAVE_CREATEFILEMAPPINGA
287HANDLE __stdcall NEW(CreateFileMappingA)(HANDLE hFile, LPSECURITY_ATTRIBUTES lpAttributes,
288            DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow,
289            LPCSTR lpName)
290{
291    HANDLE ret;
292    ret = ORIG(CreateFileMappingA)(hFile, lpAttributes,
293        flProtect, dwMaximumSizeHigh, dwMaximumSizeLow,
294        lpName);
295
296    debug("CreateFileMappingA(%#08x, %#08x, %#08x, %#08x, %#08x, %s) = %#08x",
297        hFile, lpAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName, ret);
298
299    if (ret == NULL) return ret;
300
301    if (!_zz_ready || !_zz_iswatched(hFile) /*|| !_zz_hostwatched(hFile)*/ || _zz_islocked(hFile) || !_zz_isactive(hFile) || _zz_islocked(-1))
302        return ret;
303
304    debug("handle %#08x is registered", ret);
305    _zz_register(ret);
306
307    return ret;
308}
309#endif
310
311#if defined HAVE_CREATEFILEMAPPINGW
312HANDLE __stdcall NEW(CreateFileMappingW)(HANDLE hFile, LPSECURITY_ATTRIBUTES lpAttributes,
313            DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow,
314            LPCWSTR lpName)
315{
316    HANDLE ret;
317    ret = ORIG(CreateFileMappingW)(hFile, lpAttributes,
318        flProtect, dwMaximumSizeHigh, dwMaximumSizeLow,
319        lpName);
320
321    debug("CreateFileMappingW(%#08x, %#08x, %#08x, %#08x, %#08x, %S) = %#08x",
322        hFile, lpAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName, ret);
323
324    if (ret == NULL) return ret;
325
326    if (!_zz_ready || !_zz_iswatched(hFile) /*|| !_zz_hostwatched(hFile)*/ || _zz_islocked(hFile) || !_zz_isactive(hFile) || _zz_islocked(-1))
327        return ret;
328
329    debug("handle %#08x is registered", ret);
330    _zz_register(ret);
331
332    return ret;
333}
334#endif
335
336#ifdef HAVE_MAPVIEWOFFILE
337LPVOID __stdcall NEW(MapViewOfFile)(HANDLE hFileMappingObject, DWORD dwDesiredAccess,
338    DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow,
339    SIZE_T dwNumberOfBytesToMap)
340{
341    LPVOID ret;
342    ret = ORIG(MapViewOfFile)(hFileMappingObject, dwDesiredAccess,
343        dwFileOffsetHigh, dwFileOffsetLow,
344        dwNumberOfBytesToMap);
345
346    debug("MapViewOfFile(%#08x, %#08x, %#08x, %#08x, %#08x) = %p",
347        hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap, ret);
348
349    return ret;
350}
351#endif
352
353/*
354 * CloseHandle
355 */
356
357#if defined HAVE_CLOSEHANDLE
358BOOL __stdcall NEW(CloseHandle)(HANDLE hObject)
359{
360    BOOL ret;
361
362    /* TODO: Check if fuzzed application tries to close our debug channel */
363
364    ret = ORIG(CloseHandle)(hObject);
365    debug("CloseHandle(%#08x) = %s", (int)hObject, (ret ? "TRUE" : "FALSE"));
366    if (!_zz_ready || !_zz_iswatched(hObject) || _zz_islocked(hObject))
367        return ret;
368    _zz_unregister(hObject);
369    return ret;
370}
371#endif
372
373#if defined HAVE_ALLOCCONSOLE
374BOOL __stdcall NEW(AllocConsole)()
375{
376    debug("AllocConsole()");
377    return ORIG(AllocConsole)();
378}
379#endif
380
381#if defined HAVE_ATTACHCONSOLE
382BOOL __stdcall NEW(AttachConsole)(DWORD dwProcessId)
383{
384    debug("AttachConsole(%#08x)");
385    return ORIG(AttachConsole)(dwProcessId);
386}
387#endif
388
389#if defined HAVE_SETCONSOLEMODE
390BOOL __stdcall NEW(SetConsoleMode)(HANDLE hConsoleHandle, DWORD dwMode)
391{
392    debug("SetConsoleMode(%#08x, %#08x)", (int)hConsoleHandle, dwMode);
393    return ORIG(SetConsoleMode)(hConsoleHandle, dwMode);
394}
395#endif
396
397#if defined HAVE_WRITECONSOLEOUTPUTA
398BOOL __stdcall NEW(WriteConsoleOutputA)(HANDLE hConsoleOutput,
399                               CONST CHAR_INFO *lpBuffer, COORD dwBufferSize,
400                               COORD dwBufferCoord, PSMALL_RECT lpWriteRegion)
401{
402    debug("WriteConsoleOutputA(%#08x, %p, ...)", (int)hConsoleOutput, lpBuffer);
403    return ORIG(WriteConsoleOutputA)(hConsoleOutput, lpBuffer, dwBufferSize,
404                                     dwBufferCoord, lpWriteRegion);
405}
406#endif
407
408#if defined HAVE_WRITECONSOLEOUTPUTW
409BOOL __stdcall NEW(WriteConsoleOutputW)(HANDLE hConsoleOutput,
410                               CONST CHAR_INFO *lpBuffer, COORD dwBufferSize,
411                               COORD dwBufferCoord, PSMALL_RECT lpWriteRegion)
412{
413    debug("WriteConsoleOutputW(%#08x, %p, ...)", (int)hConsoleOutput, lpBuffer);
414    return ORIG(WriteConsoleOutputW)(hConsoleOutput, lpBuffer, dwBufferSize,
415                                     dwBufferCoord, lpWriteRegion);
416}
417#endif
418
419/* Win32 function table */
420#if defined HAVE_WINDOWS_H
421#   define DIVERT(x) { "kernel32.dll", #x, \
422                      (void **)&x##_orig, (void *)x##_new }
423#   define DIVERT_END { NULL, NULL, NULL, NULL }
424
425zzuf_table_t table_win32[] =
426{
427    DIVERT(CloseHandle),
428    DIVERT(CreateFileA),
429    DIVERT(CreateFileW),
430    DIVERT(ReadFile),
431    DIVERT(ReadFileEx),
432    DIVERT(CreateIoCompletionPort),
433    DIVERT(GetQueuedCompletionStatus),
434    DIVERT(GetOverlappedResult),
435    DIVERT(CreateFileMappingA),
436    DIVERT(CreateFileMappingW),
437    DIVERT(MapViewOfFile),
438
439#if defined HAVE_ALLOCCONSOLE
440    DIVERT(AllocConsole),
441#endif
442#if defined HAVE_ATTACHCONSOLE
443    DIVERT(AttachConsole),
444#endif
445#if defined HAVE_SETCONSOLEMODE
446    DIVERT(SetConsoleMode),
447#endif
448#if defined HAVE_WRITECONSOLEOUTPUTA
449    DIVERT(WriteConsoleOutputA),
450#endif
451#if defined HAVE_WRITECONSOLEOUTPUTW
452    DIVERT(WriteConsoleOutputW),
453#endif
454
455    DIVERT_END
456};
457#endif
458
Note: See TracBrowser for help on using the repository browser.