Skip to content
Browse files

Initial commit

  • Loading branch information...
0 parents commit 37ae4580f008ef2595c78de339f12553701d2e63 @Cr4sh committed Jun 12, 2012
20 MsFontsFuzz.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MsFontsFuzz", "MsFontsFuzz\MsFontsFuzz.vcproj", "{A81B96FC-546B-428C-9F16-5B7950D0CBAF}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A81B96FC-546B-428C-9F16-5B7950D0CBAF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A81B96FC-546B-428C-9F16-5B7950D0CBAF}.Debug|Win32.Build.0 = Debug|Win32
+ {A81B96FC-546B-428C-9F16-5B7950D0CBAF}.Release|Win32.ActiveCfg = Release|Win32
+ {A81B96FC-546B-428C-9F16-5B7950D0CBAF}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
1,097 MsFontsFuzz/MsFontsFuzz.cpp
@@ -0,0 +1,1097 @@
+#include "stdafx.h"
+
+#define USE_INCORRECT_CRC_FIXING
+
+#define WND_CLASS "MsFontsFuzz"
+#define WND_TITLE "MsFontsFuzz"
+
+#define WND_W 500
+#define WND_H 500
+
+#define LOG_FILE_NAME "MsFontsFuzz.log"
+
+#define XALIGN_DOWN(x, align)(x &~ (align - 1))
+#define XALIGN_UP(x, align)((x & (align - 1)) ? XALIGN_DOWN(x, align) + align : x)
+
+#define M_ALLOC(_size_) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, (ULONG)(_size_))
+#define M_FREE(_addr_) LocalFree((_addr_))
+
+char m_szTable[0xff + 0x20];
+LPCTSTR m_lpFontPath = NULL, m_lpFontName = NULL;
+TCHAR m_TmpFontPath[MAX_PATH];
+HINSTANCE m_hInstance = NULL;
+HWND m_hWnd = NULL;
+
+// fuzzer startup options
+BOOL m_bTest = FALSE, m_bResume = FALSE, m_bNoisy = FALSE, m_bFixCrcs = FALSE;
+
+DWORD m_dwCasesProcessed = 0;
+
+#define FONT_TYPE_GENERIC 0
+#define FONT_TYPE_OTF 1
+#define FONT_TYPE_TTF 2
+
+DWORD m_dwFontType = FONT_TYPE_GENERIC;
+
+// data buffers
+DWORD m_dwDataSize = 0, m_dwAlignedDataSize = 0;
+PVOID m_pData = NULL, m_pAlignedData = NULL;
+
+HANDLE m_hDbgFile = NULL, m_hWndEvent = NULL;
+
+#define BIG_BUFFER_LENGTH 0x1000
+
+/**
+ * Data generator global settings
+ */
+DWORD BLOCK_SIZE = 2;
+DWORD FILE_RANGE_START = 0;
+DWORD FILE_RANGE_END = 0;
+DWORD BLOCK_RANGE_START = 0;
+DWORD BLOCK_RANGE_END = 0xFFFF;
+DWORD BLOCK_RANGE_N = 0x100;
+
+typedef struct _ENGINE_PARAM
+{
+ LPCTSTR lpName;
+ PDWORD pdwValue;
+
+} ENGINE_PARAM;
+
+ENGINE_PARAM m_Params[] =
+{
+ { _T("BLOCK_SIZE"), &BLOCK_SIZE },
+ { _T("FILE_RANGE_START"), &FILE_RANGE_START },
+ { _T("FILE_RANGE_END"), &FILE_RANGE_END },
+ { _T("BLOCK_RANGE_START"), &BLOCK_RANGE_START },
+ { _T("BLOCK_RANGE_END"), &BLOCK_RANGE_END },
+ { _T("BLOCK_RANGE_N"), &BLOCK_RANGE_N }
+};
+
+#define MAX_CASES_PER_PROCESS 1000
+//--------------------------------------------------------------------------------------
+LPCTSTR _tGetNameFromFullPath(LPCTSTR lpPath)
+{
+ LPCTSTR lpName = lpPath;
+
+ for (size_t i = 0; i < _tcslen(lpPath); i++)
+ {
+ if (lpPath[i] == '\\' || lpPath[i] == '/')
+ {
+ lpName = lpPath + i + 1;
+ }
+ }
+
+ return lpName;
+}
+//--------------------------------------------------------------------------------------
+char *GetNameFromFullPath(char *lpPath)
+{
+ char *lpName = lpPath;
+
+ for (size_t i = 0; i < strlen(lpPath); i++)
+ {
+ if (lpPath[i] == '\\' || lpPath[i] == '/')
+ {
+ lpName = lpPath + i + 1;
+ }
+ }
+
+ return lpName;
+}
+//--------------------------------------------------------------------------------------
+BOOL DbgInit(char *lpszDbgLogPath)
+{
+ if (m_bResume)
+ {
+ m_hDbgFile = CreateFileA(
+ lpszDbgLogPath,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+
+ SetFilePointer(m_hDbgFile, 0, NULL, FILE_END);
+ }
+ else
+ {
+ m_hDbgFile = CreateFileA(
+ lpszDbgLogPath,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL
+ );
+ }
+
+ if (m_hDbgFile != INVALID_HANDLE_VALUE)
+ {
+ return TRUE;
+ }
+ else
+ {
+ printf("CreateFile() ERROR %d\n", GetLastError());
+ }
+
+ m_hDbgFile = NULL;
+ return FALSE;
+}
+//--------------------------------------------------------------------------------------
+void DbgMsg(char *lpszFile, int Line, char *lpszMsg, ...)
+{
+ va_list mylist;
+ va_start(mylist, lpszMsg);
+
+ size_t len = _vscprintf(lpszMsg, mylist) + 0x100;
+
+ char *lpszBuff = (char *)LocalAlloc(LMEM_FIXED, len);
+ if (lpszBuff == NULL)
+ {
+ va_end(mylist);
+ return;
+ }
+
+ char *lpszOutBuff = (char *)LocalAlloc(LMEM_FIXED, len);
+ if (lpszOutBuff == NULL)
+ {
+ LocalFree(lpszBuff);
+ va_end(mylist);
+ return;
+ }
+
+ vsprintf_s(lpszBuff, len, lpszMsg, mylist);
+ va_end(mylist);
+
+ sprintf_s(
+ lpszOutBuff, len, "[%.5d] .\\%s(%d) : %s",
+ GetCurrentProcessId(), GetNameFromFullPath(lpszFile), Line, lpszBuff
+ );
+
+ OutputDebugStringA(lpszOutBuff);
+
+ HANDLE hStd = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (hStd != INVALID_HANDLE_VALUE)
+ {
+ DWORD dwWritten = 0;
+ WriteFile(hStd, lpszBuff, lstrlenA(lpszBuff), &dwWritten, NULL);
+ }
+
+ if (m_hDbgFile)
+ {
+ DWORD dwWritten = 0;
+ WriteFile(m_hDbgFile, lpszBuff, strlen(lpszBuff), &dwWritten, NULL);
+ }
+
+ LocalFree(lpszOutBuff);
+ LocalFree(lpszBuff);
+}
+//--------------------------------------------------------------------------------------
+BOOL DumpToFile(LPCTSTR lpFileName, PVOID pData, ULONG DataSize)
+{
+ HANDLE hFile = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ DWORD dwWritten = 0;
+ WriteFile(hFile, pData, DataSize, &dwWritten, NULL);
+
+ CloseHandle(hFile);
+
+ return TRUE;
+ }
+ else
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): CreateFile() ERROR %d\n", GetLastError());
+ }
+
+ return FALSE;
+}
+//--------------------------------------------------------------------------------------
+BOOL ReadFromFile(LPCTSTR lpFileName, PVOID *pData, PDWORD lpdwDataSize)
+{
+ BOOL bRet = FALSE;
+ HANDLE hFile = CreateFile(
+ lpFileName,
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL
+ );
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ *lpdwDataSize = GetFileSize(hFile, NULL);
+ if (*pData = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, *lpdwDataSize))
+ {
+ DWORD dwReaded = 0;
+ ReadFile(hFile, *pData, *lpdwDataSize, &dwReaded, NULL);
+
+ bRet = TRUE;
+ }
+ else
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): LocalAlloc() ERROR %d\n", GetLastError());
+ *lpdwDataSize = 0;
+ }
+
+ CloseHandle(hFile);
+ }
+ else
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): CreateFile() ERROR %d\n", GetLastError());
+ }
+
+ return bRet;
+}
+//--------------------------------------------------------------------------------------
+HFONT FAR PASCAL MyCreateFont(void)
+{
+ CHOOSEFONT cf;
+ LOGFONT lf;
+ HFONT hFont;
+
+ // Initialize members of the LOGFONT structure.
+ ZeroMemory(&lf, sizeof(lf));
+ lf.lfHeight = -36;
+ lf.lfWidth = 0;
+ lf.lfEscapement = 0;
+ lf.lfOrientation = 0;
+ lf.lfWeight = 0;
+ lf.lfItalic = 0;
+ lf.lfUnderline = 0;
+ lf.lfStrikeOut = 0;
+ lf.lfCharSet = 0;
+ lf.lfOutPrecision = 0;
+ lf.lfClipPrecision = 0;
+ lf.lfQuality = 0;
+ lf.lfPitchAndFamily = 0;
+ _tcscpy_s(lf.lfFaceName, m_lpFontName);
+
+ // Çàïîëíÿåì CHOOSEFONT
+ ZeroMemory(&cf, sizeof(cf));
+ cf.lStructSize = sizeof(cf);
+ cf.lpLogFont = &lf;
+ cf.rgbColors = 0;
+ cf.Flags = CF_SCREENFONTS | CF_EFFECTS;
+
+ // Create a logical font based on the user's
+ // selection and return a handle identifying
+ // that font.
+ hFont = CreateFontIndirect(&lf);
+ return hFont;
+}
+//--------------------------------------------------------------------------------------
+#define ID_CLOSE 1
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ RECT area;
+
+ HDC hDC = BeginPaint(hWnd, &ps);
+ GetClientRect(hWnd, &area);
+ SetBkMode(hDC, TRANSPARENT);
+
+ // draw caption with the fuzzed font
+ HFONT hFont = MyCreateFont();
+ HFONT hOldFont = (HFONT)SelectObject(hDC, hFont);
+ if (hOldFont)
+ {
+ DrawTextA(hDC, m_szTable, -1, &area, DT_CENTER | DT_VCENTER);
+ SelectObject(hDC, hOldFont);
+ }
+
+ EndPaint(hWnd, &ps);
+
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (wParam)
+ {
+ case ID_CLOSE:
+
+#ifdef TEST_MSG
+ MessageBoxA(0, __FUNCTION__, "ID_CLOSE", MB_ICONINFORMATION);
+#endif
+ // window can be closed now
+ SetEvent(m_hWndEvent);
+ break;
+ }
+
+ break;
+ }
+
+ case WM_DESTROY:
+
+ PostQuitMessage(0);
+ break;
+
+ default:
+
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+
+ return 0;
+}
+//--------------------------------------------------------------------------------------
+DWORD WINAPI FuzzIterationThread(LPVOID lpParam)
+{
+ MSG Msg;
+
+ // load fuzzed font
+ if (AddFontResource(m_TmpFontPath) == 0)
+ {
+ DbgMsg(__FILE__, __LINE__, "AddFontResource() fails\n");
+ return -1;
+ }
+
+#ifdef USE_BOADCAST_MESSAGES
+
+ SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
+
+#endif
+
+ int x = (GetSystemMetrics(SM_CXSCREEN) - WND_W) / 2;
+ int y = (GetSystemMetrics(SM_CYSCREEN) - WND_H) / 2;
+
+ // create new empty window
+ m_hWnd = CreateWindowEx(
+ WS_EX_CLIENTEDGE,
+ _T(WND_CLASS), _T(WND_TITLE),
+ WS_OVERLAPPEDWINDOW,
+ x, y, WND_W, WND_H,
+ NULL, NULL,
+ m_hInstance,
+ NULL
+ );
+ if (m_hWnd)
+ {
+ ShowWindow(m_hWnd, SW_SHOWNORMAL);
+ UpdateWindow(m_hWnd);
+
+ SendMessage(m_hWnd, WM_COMMAND, ID_CLOSE, 0);
+
+ // Main message loop
+ while (GetMessage(&Msg, NULL, 0, 0))
+ {
+ TranslateMessage(&Msg);
+ DispatchMessage(&Msg);
+ }
+ }
+ else
+ {
+ DbgMsg(__FILE__, __LINE__, "CreateWindow() ERROR %d\n", GetLastError());
+ }
+
+ // unload fuzzed font
+ if (!RemoveFontResource(m_TmpFontPath))
+ {
+ DbgMsg(__FILE__, __LINE__, "RemoveFontResource() fails\n");
+ }
+
+#ifdef USE_BOADCAST_MESSAGES
+
+ SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
+
+#endif
+
+ return 0;
+}
+//--------------------------------------------------------------------------------------
+BOOL FuzzIteration(void)
+{
+ ResetEvent(m_hWndEvent);
+
+ // create window in a new thread
+ HANDLE hThread = CreateThread(NULL, 0, FuzzIterationThread, NULL, 0, NULL);
+ if (hThread)
+ {
+ HANDLE Objects[2];
+ Objects[0] = hThread;
+ Objects[1] = m_hWndEvent;
+
+ if (m_bTest)
+ {
+ WaitForSingleObject(hThread, INFINITE);
+ goto end;
+ }
+
+ if (WaitForMultipleObjects(2, Objects, FALSE, INFINITE) == WAIT_OBJECT_0)
+ {
+ // thread has been terminated
+ goto end;
+ }
+
+ // close window
+ SendMessage(m_hWnd, WM_CLOSE, 0, 0);
+ WaitForSingleObject(hThread, INFINITE);
+end:
+ CloseHandle(hThread);
+
+ return TRUE;
+ }
+ else
+ {
+ DbgMsg(__FILE__, __LINE__, "CreateThread() ERROR %d\n");
+ }
+
+ return FALSE;
+}
+//--------------------------------------------------------------------------------------
+typedef struct _OTF_FILE_HEADER
+{
+ ULONG sfntVersion; // 0x00010000 for version 1.0.
+ USHORT numTables; // Number of tables.
+ USHORT searchRange; // (Maximum power of 2 <= numTables) x 16.
+ USHORT entrySelector; // Log2(maximum power of 2 <= numTables).
+ USHORT rangeShift; // NumTables x 16-searchRange.
+
+} OTF_FILE_HEADER,
+*POTF_FILE_HEADER;
+
+typedef struct _OTF_TABLE_HEADER
+{
+ ULONG tag; // 4-byte identifier.
+ ULONG checkSum; // CheckSum for this table.
+ ULONG offset; // Offset from beginning of TrueType font file.
+ ULONG length; // Length of this table.
+
+} OTF_TABLE_HEADER,
+*POTF_TABLE_HEADER;
+
+ULONG OTF_CalcTableChecksum(ULONG *Table, ULONG Length)
+{
+ ULONG Sum = 0;
+ ULONG nLongs = (XALIGN_UP(Length, sizeof(ULONG))) / sizeof(ULONG);
+
+ for (ULONG i = 0; i < nLongs; i++, Table++)
+ {
+ Sum += htonl(*Table);
+ }
+
+ return Sum;
+}
+
+POTF_TABLE_HEADER OTF_TableByOffset(PVOID Data, ULONG ByteOffset)
+{
+ POTF_FILE_HEADER Hdr = (POTF_FILE_HEADER)Data;
+ POTF_TABLE_HEADER Table = (POTF_TABLE_HEADER)((PUCHAR)Data + sizeof(OTF_FILE_HEADER));
+
+ // enumerate tables
+ for (USHORT i = 0; i < htons(Hdr->numTables); i++)
+ {
+ char Tag[5];
+ ULONG Offset = htonl(Table->offset), Length = htonl(Table->length);
+ ULONG Sum = OTF_CalcTableChecksum((ULONG *)((PUCHAR)Data + Offset), Length);
+
+ strncpy(Tag, (char *)&Table->tag, sizeof(ULONG));
+ Tag[sizeof(ULONG)] = 0;
+
+ if (ByteOffset == (ULONG)-1)
+ {
+ DbgMsg(
+ __FILE__, __LINE__,
+ "0x%.8x: %s Offset=0x%.8x Len=0x%.8x Sum=0x%.8x [%s]\n",
+ i, Tag, Offset, Length,
+ Sum, (Sum == htonl(Table->checkSum)) ? "OK" : "ERR"
+ );
+
+#ifdef USE_INCORRECT_CRC_FIXING
+
+ if (Sum != htonl(Table->checkSum))
+ {
+ // fix invalid table checksum
+ Table->checkSum = htonl(Sum);
+ printf("NOTE: Incorrect table CRC was fixed!\n");
+ }
+#endif
+
+ }
+ else
+ {
+ if (ByteOffset >= Offset &&
+ ByteOffset < Offset + Length)
+ {
+ return Table;
+ }
+ }
+
+ Table += 1;
+ }
+
+ return NULL;
+}
+//--------------------------------------------------------------------------------------
+BOOL WriteVal(
+ DWORD Ptr,
+ DWORD Size,
+ DWORD Val_1, DWORD Val_2, DWORD Val_3)
+{
+ ZeroMemory(m_pAlignedData, m_dwAlignedDataSize);
+ memcpy(m_pAlignedData, m_pData, m_dwDataSize);
+
+ if (m_bNoisy)
+ {
+ DbgMsg(
+ __FILE__, __LINE__,
+ __FUNCTION__"(): Probing value 0x%.2x 0x%.4x 0x%.8x\n",
+ (UCHAR)Val_1, (USHORT)Val_2, Val_3
+ );
+ }
+
+ // zero-bytes stuff
+ switch (Size)
+ {
+ case 1:
+ *(PUCHAR)((PUCHAR)m_pAlignedData + Ptr) = (UCHAR)Val_1;
+ break;
+
+ case 2:
+ *(PUSHORT)((PUCHAR)m_pAlignedData + Ptr) = (USHORT)Val_2;
+ break;
+
+ case 4:
+ *(PULONG)((PUCHAR)m_pAlignedData + Ptr) = Val_3;
+ break;
+ }
+
+ POTF_TABLE_HEADER Table = NULL;
+ if (m_dwFontType == FONT_TYPE_OTF || m_dwFontType == FONT_TYPE_TTF)
+ {
+ Table = OTF_TableByOffset(m_pAlignedData, Ptr);
+ }
+
+ if (Table)
+ {
+ // fix OTF/TTF table checksum
+ ULONG Offset = htonl(Table->offset), Length = htonl(Table->length);
+ ULONG Sum = OTF_CalcTableChecksum((ULONG *)((PUCHAR)m_pAlignedData + Offset), Length);
+ Table->checkSum = htonl(Sum);
+ }
+
+ // dump output file
+ if (DumpToFile(m_TmpFontPath, m_pAlignedData, m_dwDataSize))
+ {
+ FuzzIteration();
+ m_dwCasesProcessed++;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+//--------------------------------------------------------------------------------------
+LONG WINAPI UnhandledExceptionError(PEXCEPTION_POINTERS ExceptionInfo)
+{
+ DbgMsg(__FILE__, __LINE__, "Exception 0x%.8x at address 0x%.8x, thread %.4X:%.4X\n",
+ ExceptionInfo->ExceptionRecord->ExceptionCode,
+ ExceptionInfo->ExceptionRecord->ExceptionAddress,
+ GetCurrentProcessId(), GetCurrentThreadId()
+ );
+
+ __asm int 3;
+
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+//--------------------------------------------------------------------------------------
+int _tmain(int argc, _TCHAR* argv[])
+{
+ m_hInstance = (HINSTANCE)GetModuleHandle(NULL);
+
+ if (argc >= 3)
+ {
+ m_lpFontPath = argv[2];
+ m_lpFontName = argv[1];
+ printf(__FUNCTION__"(): Using external font %ws \"%ws\"\n", m_lpFontName, m_lpFontPath);
+ }
+ else
+ {
+ printf("USAGE: MsFontsFuzz.exe <font_name> <font_file> [options]\n");
+ goto end;
+ }
+
+ _stprintf_s(m_TmpFontPath, _T("__TMP__%s"), _tGetNameFromFullPath(m_lpFontPath));
+ DbgMsg(__FILE__, __LINE__, "[+] Temporary font file is \"%ws\"\n", m_TmpFontPath);
+
+ if (_tcslen(m_TmpFontPath) >= 4)
+ {
+ _tcslwr(m_TmpFontPath + _tcslen(m_TmpFontPath) - 4);
+ if (!_tcscmp(m_TmpFontPath + _tcslen(m_TmpFontPath) - 4, _T(".otf")))
+ {
+ m_dwFontType = FONT_TYPE_OTF;
+ DbgMsg(__FILE__, __LINE__, "[+] Font type is .OTF\n");
+ }
+ else if (!_tcscmp(m_TmpFontPath + _tcslen(m_TmpFontPath) - 4, _T(".ttf")))
+ {
+ m_dwFontType = FONT_TYPE_TTF;
+ DbgMsg(__FILE__, __LINE__, "[+] Font type is .TTF\n");
+ }
+ }
+
+ RemoveFontResource(m_TmpFontPath);
+
+#ifdef USE_BOADCAST_MESSAGES
+
+ SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
+
+#endif
+
+ char ch = 0;
+ memset(m_szTable, '.', sizeof(m_szTable) - 1);
+
+ for (int i = 0; i < sizeof(m_szTable); i++)
+ {
+ if (i != 0 && i % 16 == 0)
+ {
+ m_szTable[i] = '\n';
+ continue;
+ }
+
+ if (ch >= 0x20)
+ {
+ m_szTable[i] = ch;
+ }
+
+ if (ch == 0x7f)
+ {
+ m_szTable[i] = 0;
+ break;
+ }
+
+ ch += 1;
+ }
+
+ if (argc > 3)
+ {
+ // enumerate additional parameters
+ for (int i = 3; i < argc; i++)
+ {
+ if (!_tcscmp(argv[i], _T("--test")))
+ {
+ // single launch mode
+ m_bTest = TRUE;
+ }
+ else if (!_tcscmp(argv[i], _T("--resume")))
+ {
+ // resume fuzzing in the new process
+ m_bResume = TRUE;
+ }
+ else if (!_tcscmp(argv[i], _T("--noisy")))
+ {
+ // show lot of output information
+ m_bNoisy = TRUE;
+ }
+ else if (!_tcscmp(argv[i], _T("--text")) && argc - i > 1)
+ {
+#ifdef UNICODE
+ // use caller-specified text for display
+ WideCharToMultiByte(
+ CP_ACP, 0,
+ argv[i + 1],
+ -1,
+ m_szTable,
+ sizeof(m_szTable) - 1,
+ NULL, NULL
+ );
+#else
+ strcpy_s(m_szTable, argv[i + 1]);
+#endif
+ i++;
+ }
+ else if (!_tcscmp(argv[i], _T("--fix-crcs")))
+ {
+ // fix incorrect checksums for the original font file
+ m_bFixCrcs = TRUE;
+ }
+ else if (argc - i > 1 && argv[i][0] == '-')
+ {
+ /**
+ * Process data generation options.
+ */
+
+ LPCTSTR lpParam = argv[i] + 1;
+ DWORD dwValue = 0;
+ BOOL bFound = FALSE;
+
+ if (!StrToIntEx(argv[i + 1], STIF_SUPPORT_HEX, (int *)&dwValue))
+ {
+ DbgMsg(__FILE__, __LINE__, "[!] ERROR: Invalid value for parameter \"%ws\"\n", argv[i]);
+ continue;
+ }
+
+ for (int i_n = 0; i_n < sizeof(m_Params) / sizeof(ENGINE_PARAM); i_n++)
+ {
+ // search parameter by name
+ if (!_tcscmp(m_Params[i_n].lpName, lpParam))
+ {
+ *(m_Params[i_n].pdwValue) = dwValue;
+ bFound = TRUE;
+ break;
+ }
+ }
+
+ if (!bFound)
+ {
+ DbgMsg(__FILE__, __LINE__, "[!] ERROR: Unknown parameter \"%ws\"\n", argv[i]);
+ }
+
+ i++;
+ }
+ }
+ }
+
+ DbgInit(LOG_FILE_NAME);
+
+ // check block size and range
+ if (BLOCK_SIZE == 1)
+ {
+ if (BLOCK_RANGE_START >= 0xFF)
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_START value (it must be <0xFF)\n");
+ goto end;
+ }
+
+ if (BLOCK_RANGE_END > 0xFF)
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_END value (it must be <=0xFF)\n");
+ goto end;
+ }
+ }
+ else if (BLOCK_SIZE == 2)
+ {
+ if (BLOCK_RANGE_START >= 0xFFFF)
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_START value (it must be <0xFFFF)\n");
+ goto end;
+ }
+
+ if (BLOCK_RANGE_END > 0xFFFF)
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_END value (it must be <=0xFFFF)\n");
+ goto end;
+ }
+ }
+ else if (BLOCK_SIZE == 4)
+ {
+ if (BLOCK_RANGE_START >= 0xFFFFFFFF)
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_START value (it must be <0xFFFFFFFF)\n");
+ goto end;
+ }
+
+ if (BLOCK_RANGE_END > 0xFFFFFFFF)
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_END value (it must be <=0xFFFFFFFF)\n");
+ goto end;
+ }
+ }
+ else
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_SIZE value (it must be 1, 2 or 4)\n");
+ goto end;
+ }
+
+ // check step size
+ if (BLOCK_RANGE_N > BLOCK_RANGE_END)
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid BLOCK_RANGE_N value (it must be <=BLOCK_RANGE_END)\n");
+ goto end;
+ }
+
+ WNDCLASSEX wcex;
+ ZeroMemory(&wcex, sizeof(wcex));
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = WndProc;
+ wcex.hInstance = m_hInstance;
+ wcex.lpszClassName = _T(WND_CLASS);
+ wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+
+ m_hWndEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (m_hWndEvent == NULL)
+ {
+ DbgMsg(__FILE__, __LINE__, "CreateEvent() ERROR %d\n", GetLastError());
+ goto end;
+ }
+
+ // register window class
+ if (RegisterClassEx(&wcex) == NULL)
+ {
+ DbgMsg(__FILE__, __LINE__, "RegisterClassEx() ERROR %d\n", GetLastError());
+ goto end;
+ }
+
+ // init random number generator
+ init_genrand(GetTickCount());
+
+ SetUnhandledExceptionFilter(UnhandledExceptionError);
+
+ // read input file
+ if (ReadFromFile(m_lpFontPath, &m_pData, &m_dwDataSize))
+ {
+ if (FILE_RANGE_START >= m_dwDataSize)
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid FILE_RANGE_START value (it must be <=FILE_SIZE)\n");
+ M_FREE(m_pData);
+ return -1;
+ }
+
+ if (FILE_RANGE_END > m_dwDataSize)
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid FILE_RANGE_END value (it must be <FILE_SIZE)\n");
+ M_FREE(m_pData);
+ return -1;
+ }
+
+ if (FILE_RANGE_END == 0)
+ {
+ FILE_RANGE_END = m_dwDataSize;
+ }
+
+ if (FILE_RANGE_START >= FILE_RANGE_END)
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Invalid FILE_RANGE_START/FILE_RANGE_END values\n");
+ M_FREE(m_pData);
+ return -1;
+ }
+
+ DbgMsg(__FILE__, __LINE__, "[+] %d bytes readed from \"%ws\"\n", m_dwDataSize, m_lpFontPath);
+
+ if (!m_bResume && (m_dwFontType == FONT_TYPE_OTF || m_dwFontType == FONT_TYPE_TTF))
+ {
+ OTF_TableByOffset(m_pData, (ULONG)-1);
+ }
+
+ if (m_bFixCrcs)
+ {
+ // write fixed checksums into the original file
+ if (DumpToFile(m_lpFontPath, m_pData, m_dwDataSize))
+ {
+ DbgMsg(__FILE__, __LINE__, "[+] Checksums has been fixed for font file \"%ws\"\n", m_lpFontPath);
+ }
+ }
+ else if (m_bTest)
+ {
+ // single run with the unchanged font file
+ if (DumpToFile(m_TmpFontPath, m_pData, m_dwDataSize))
+ {
+ FuzzIteration();
+ }
+ }
+ else
+ {
+ DbgMsg(__FILE__, __LINE__, "[+] Fuzzing params:\n\n");
+
+ // print parameters values
+ for (int i_n = 0; i_n < sizeof(m_Params) / sizeof(ENGINE_PARAM); i_n++)
+ {
+ DbgMsg(__FILE__, __LINE__, " %20ws = 0x%.8x\n", m_Params[i_n].lpName, *(m_Params[i_n].pdwValue));
+ }
+
+ DbgMsg(__FILE__, __LINE__, "\n");
+ DbgMsg(__FILE__, __LINE__, "[+] Processing cases...\n\n");
+
+ // align buffer size by block size
+ m_dwAlignedDataSize = XALIGN_UP(m_dwDataSize, BLOCK_SIZE);
+
+ // allocate output buffer
+ if (m_pAlignedData = M_ALLOC(m_dwAlignedDataSize))
+ {
+ char *lpszBigBuff = (char *)M_ALLOC(BIG_BUFFER_LENGTH);
+ if (lpszBigBuff)
+ {
+ FillMemory(lpszBigBuff, BIG_BUFFER_LENGTH, 'A');
+ }
+
+ PVOID pBigData = M_ALLOC(m_dwDataSize + BIG_BUFFER_LENGTH);
+
+ // for each byte/word/dword of input file...
+ for (DWORD i = FILE_RANGE_START; i < FILE_RANGE_END; i += BLOCK_SIZE)
+ {
+ DbgMsg(__FILE__, __LINE__, "Offset=0x%.8x TotalSize=0x%.8x File=%.8x\n", i, m_dwDataSize, m_dwCasesProcessed);
+
+ POTF_TABLE_HEADER Table = NULL;
+ if (m_dwFontType == FONT_TYPE_OTF || m_dwFontType == FONT_TYPE_TTF)
+ {
+ Table = OTF_TableByOffset(m_pData, i);
+ if (Table == NULL)
+ {
+ // skip OTF/TTF data outside the tables
+ continue;
+ }
+ }
+
+ if (BLOCK_RANGE_N > 0)
+ {
+ // fuze each value with the step size == BLOCK_RANGE_N
+ for (DWORD n = XALIGN_DOWN(BLOCK_RANGE_START, BLOCK_RANGE_N);
+ n < XALIGN_DOWN(BLOCK_RANGE_END, BLOCK_RANGE_N);
+ n += BLOCK_RANGE_N)
+ {
+ // write plain value
+ WriteVal(i, BLOCK_SIZE, n, n, n);
+
+ if (BLOCK_SIZE > 1)
+ {
+ // write randomized value
+ WriteVal(i, BLOCK_SIZE,
+ n,
+ n + getrand(0, BLOCK_RANGE_N - 1),
+ n + getrand(0, BLOCK_RANGE_N - 1)
+ );
+ }
+ }
+ }
+
+ // zero-bytes stuff
+ WriteVal(i, BLOCK_SIZE, 0x00, 0x0000, 0x00000000);
+
+ // integer overflow stuff
+ WriteVal(i, BLOCK_SIZE, 0xFF, 0xFFFF, 0xFFFFFFFF);
+
+ // invalid user-mode pointers
+ WriteVal(i, BLOCK_SIZE, 0x0D, 0x0D0D, 0x0D0D0D0D);
+
+ if (lpszBigBuff && pBigData)
+ {
+ /**
+ * Write big ASCI data after the each byte.
+ */
+
+ memcpy(pBigData, m_pData, i);
+ memcpy((PUCHAR)pBigData + i, lpszBigBuff, BIG_BUFFER_LENGTH);
+ memcpy((PUCHAR)pBigData + i + BIG_BUFFER_LENGTH, (PUCHAR)m_pData + i, m_dwDataSize - i);
+
+ if (m_dwFontType == FONT_TYPE_OTF || m_dwFontType == FONT_TYPE_TTF)
+ {
+ POTF_FILE_HEADER Hdr = (POTF_FILE_HEADER)pBigData;
+ POTF_TABLE_HEADER Table = (POTF_TABLE_HEADER)((PUCHAR)pBigData + sizeof(OTF_FILE_HEADER));
+ POTF_TABLE_HEADER CurrentTable = NULL;
+
+ for (USHORT t = 0; t < htons(Hdr->numTables); t++)
+ {
+ ULONG Offset = htonl(Table->offset), Length = htonl(Table->length);
+
+ if (i >= Offset &&
+ i < Offset + Length)
+ {
+ // fix OTF/TTF table checksum and length
+ ULONG Sum = OTF_CalcTableChecksum((ULONG *)((PUCHAR)pBigData + Offset), Length);
+
+ Table->checkSum = htonl(Sum);
+ Table->length = htonl(Length);
+ CurrentTable = Table;
+
+ break;
+ }
+
+ Table += 1;
+ }
+
+ if (CurrentTable)
+ {
+ Table = (POTF_TABLE_HEADER)((PUCHAR)pBigData + sizeof(OTF_FILE_HEADER));
+
+ for (USHORT t = 0; t < htons(Hdr->numTables); t++)
+ {
+ ULONG Offset = htonl(Table->offset), Length = htonl(Table->length);
+
+ if (Offset > htonl(CurrentTable->offset))
+ {
+ // fix offsets of the other tables
+ Table->offset = htonl(Offset + BIG_BUFFER_LENGTH);
+ }
+
+ Table += 1;
+ }
+ }
+ }
+
+ if (DumpToFile(m_TmpFontPath, pBigData, m_dwDataSize + BIG_BUFFER_LENGTH))
+ {
+ FuzzIteration();
+ m_dwCasesProcessed++;
+ }
+ }
+
+ if (m_dwCasesProcessed > MAX_CASES_PER_PROCESS)
+ {
+ TCHAR szSelf[MAX_PATH], szCmdLine[MAX_PATH];
+ GetModuleFileName(GetModuleHandle(NULL), szSelf, MAX_PATH);
+
+ _stprintf_s(
+ szCmdLine, MAX_PATH,
+ _T("\"%s\" \"%s\" \"%s\" -BLOCK_SIZE 0x%x -BLOCK_RANGE_START 0x%x -BLOCK_RANGE_END 0x%x -BLOCK_RANGE_N 0x%x -FILE_RANGE_START 0x%x --resume Y"),
+ szSelf, m_lpFontName, m_lpFontPath, BLOCK_SIZE, BLOCK_RANGE_START, BLOCK_RANGE_END, BLOCK_RANGE_N, i
+ );
+
+ if (m_bNoisy)
+ {
+ _tcscat(szCmdLine, _T(" --noisy Y"));
+ }
+
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ ZeroMemory(&pi, sizeof(pi));
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+
+ // create a new fuzzer instance
+ if (!CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
+ {
+ MessageBox(0, _T("CreateProcess() fails"), _T("ERROR"), MB_ICONERROR);
+ }
+
+ ExitProcess(0);
+ }
+ }
+
+ DbgMsg(__FILE__, __LINE__, "Done; %d cases processed\n", m_dwCasesProcessed);
+
+ if (pBigData)
+ {
+ M_FREE(pBigData);
+ }
+
+ if (lpszBigBuff)
+ {
+ M_FREE(lpszBigBuff);
+ }
+
+ M_FREE(m_pAlignedData);
+ }
+ }
+
+ M_FREE(m_pData);
+ }
+ else
+ {
+ DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Error while reading input file\n");
+ }
+
+end:
+
+ if (m_hWndEvent)
+ {
+ CloseHandle(m_hWndEvent);
+ }
+
+ printf("Press any key to quit...\n");
+ _getch();
+
+ return 0;
+}
+//--------------------------------------------------------------------------------------
+// EoF
231 MsFontsFuzz/MsFontsFuzz.vcproj
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="MsFontsFuzz"
+ ProjectGUID="{A81B96FC-546B-428C-9F16-5B7950D0CBAF}"
+ RootNamespace="MsFontsFuzz"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="shlwapi.lib ws2_32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="2"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib shlwapi.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\MsFontsFuzz.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\rng.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\rng.h"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\targetver.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
143 MsFontsFuzz/rng.cpp
@@ -0,0 +1,143 @@
+/*
+ A C-program for MT19937, with initialization improved 2002/1/26.
+ Coded by Takuji Nishimura and Makoto Matsumoto.
+
+ Before using, initialize the state by using init_genrand(seed)
+ or init_by_array(init_key, key_length).
+
+ Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The names of its contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+ Any feedback is very welcome.
+ http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+ email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
+*/
+
+#include "stdafx.h"
+
+/* Period parameters */
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0dfUL /* constant vector a */
+#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
+#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
+
+static unsigned long mt[N]; /* the array for the state vector */
+static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
+
+/* initializes mt[N] with a seed */
+void init_genrand(unsigned long s)
+{
+ mt[0]= s & 0xffffffffUL;
+ for (mti=1; mti<N; mti++) {
+ mt[mti] =
+ (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
+ /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+ /* In the previous versions, MSBs of the seed affect */
+ /* only MSBs of the array mt[]. */
+ /* 2002/01/09 modified by Makoto Matsumoto */
+ mt[mti] &= 0xffffffffUL;
+ /* for >32 bit machines */
+ }
+}
+
+/* initialize by an array with array-length */
+/* init_key is the array for initializing keys */
+/* key_length is its length */
+/* slight change for C++, 2004/2/26 */
+void init_by_array(unsigned long init_key[], int key_length)
+{
+ int i, j, k;
+ init_genrand(19650218UL);
+ i=1; j=0;
+ k = (N>key_length ? N : key_length);
+ for (; k; k--) {
+ mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
+ + init_key[j] + j; /* non linear */
+ mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+ i++; j++;
+ if (i>=N) { mt[0] = mt[N-1]; i=1; }
+ if (j>=key_length) j=0;
+ }
+ for (k=N-1; k; k--) {
+ mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
+ - i; /* non linear */
+ mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+ i++;
+ if (i>=N) { mt[0] = mt[N-1]; i=1; }
+ }
+
+ mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
+}
+
+/* generates a random number on [0,0xffffffff]-interval */
+unsigned long genrand_int32(void)
+{
+ unsigned long y;
+ static unsigned long mag01[2]={0x0UL, MATRIX_A};
+ /* mag01[x] = x * MATRIX_A for x=0,1 */
+
+ if (mti >= N) { /* generate N words at one time */
+ int kk;
+
+ if (mti == N+1) /* if init_genrand() has not been called, */
+ init_genrand(5489UL); /* a default initial seed is used */
+
+ for (kk=0;kk<N-M;kk++) {
+ y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+ mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
+ }
+ for (;kk<N-1;kk++) {
+ y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+ mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
+ }
+ y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
+ mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
+
+ mti = 0;
+ }
+
+ y = mt[mti++];
+
+ /* Tempering */
+ y ^= (y >> 11);
+ y ^= (y << 7) & 0x9d2c5680UL;
+ y ^= (y << 15) & 0xefc60000UL;
+ y ^= (y >> 18);
+
+ return y;
+}
+
+unsigned long getrand(unsigned long min, unsigned long max)
+{
+ /* generate random-in-range long value */
+ return (genrand_int32() % (max - min + 1)) + min;
+}
4 MsFontsFuzz/rng.h
@@ -0,0 +1,4 @@
+void init_genrand(unsigned long s);
+void init_by_array(unsigned long init_key[], int key_length);
+unsigned long genrand_int32(void);
+unsigned long getrand(unsigned long min, unsigned long max);
8 MsFontsFuzz/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// MsFontsFuzz.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
11 MsFontsFuzz/stdafx.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "targetver.h"
+
+#include <stdio.h>
+#include <tchar.h>
+#include <conio.h>
+#include <windows.h>
+#include <shlwapi.h>
+
+#include "rng.h"
13 MsFontsFuzz/targetver.h
@@ -0,0 +1,13 @@
+#pragma once
+
+// The following macros define the minimum required platform. The minimum required platform
+// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
+// your application. The macros work by enabling all features available on platform versions up to and
+// including the version specified.
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
+#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
33 README.TXT
@@ -0,0 +1,33 @@
+
+*********************************************************
+
+ MsFontsFuzz: OpenType font format fuzzer for Windows
+
+ By Oleksiuk Dmytro (aka Cr4sh)
+ http://twitter.com/d_olex
+ http://blog.cr4.sh
+ mailto:cr4sh0@gmail.com
+
+*********************************************************
+
+USAGE:
+
+ > MsFontsFuzz.exe <font_name> <font_file_path> [options]
+
+... where <font_name> and <font_file_path> � Text name of the font and path to the .TTF/.OTF font file.
+
+The [options] can be:
+
+ --test � Just draw font characters and print file information without fuzzing.
+
+ --text � String that will be drawn during fuzzing using the specified font. By default - ASCII �characters string in range 20h � 7Fh.
+
+ --noisy � Print detailed information about each fuzzing iteration.
+
+ --fix-crcs � Fix invalid checksums in specified font file without fuzzing.
+
+
+EXAMPLE:
+
+See Release\BrushScriptStd_Fuzzing.bat - you can run this scenario to start fuzzing with the Brush Script Std Regular font.
+
BIN Release/BrushScriptStd.otf
Binary file not shown.
2 Release/BrushScriptStd_Fuzzing.bat
@@ -0,0 +1,2 @@
+@echo off
+MsFontsFuzz.exe "Brush Script Std" .\BrushScriptStd.otf -BLOCK_SIZE 1 -BLOCK_RANGE_START 0x00 -BLOCK_RANGE_END 0xff -BLOCK_RANGE_N 1 -FILE_RANGE_START 0x298a -FILE_RANGE_END 0x298f
BIN Release/MsFontsFuzz.exe
Binary file not shown.
BIN Release/MsFontsFuzz.pdb
Binary file not shown.

0 comments on commit 37ae458

Please sign in to comment.
Something went wrong with that request. Please try again.