├── AFL ├── AFL │ ├── AFL.sln │ ├── AFL.vcxproj │ ├── AFL.vcxproj.filters │ ├── Debug │ │ ├── AFL.exe │ │ ├── afl-showmap.exe │ │ ├── afl-tmin.exe │ │ ├── test_clfs.exe │ │ ├── test_gdiplus.exe │ │ ├── test_hive.exe │ │ ├── test_ioctl.exe │ │ └── test_mdb.exe │ ├── afl-fuzz.cpp │ ├── alloc-inl.h │ ├── config.h │ ├── debug.h │ ├── hash.h │ └── types.h ├── afl-showmap │ ├── afl-showmap.cpp │ ├── afl-showmap.vcxproj │ └── afl-showmap.vcxproj.filters ├── afl-tmin │ ├── afl-tmin.cpp │ ├── afl-tmin.vcxproj │ └── afl-tmin.vcxproj.filters ├── test_clfs │ ├── header.h │ ├── helper.h │ ├── interface.cpp │ ├── main.cpp │ ├── persistent.cpp │ ├── test_clfs.vcxproj │ └── test_clfs.vcxproj.filters ├── test_gdiplus │ ├── header.h │ ├── main.cpp │ ├── persistent.cpp │ ├── test_gdiplus.vcxproj │ └── test_gdiplus.vcxproj.filters ├── test_hive │ ├── header.h │ ├── helper.h │ ├── interface.cpp │ ├── main.cpp │ ├── persistent.cpp │ ├── test_hive.vcxproj │ └── test_hive.vcxproj.filters ├── test_ioctl │ ├── header.h │ ├── helper.h │ ├── interface.cpp │ ├── main.cpp │ ├── persistence.cpp │ ├── test_ioctl.vcxproj │ └── test_ioctl.vcxproj.filters └── test_mdb │ ├── header.h │ ├── main.cpp │ ├── persistence.cpp │ ├── test_mdb.vcxproj │ └── test_mdb.vcxproj.filters ├── README.md ├── afl-cmin.py ├── bin ├── AFL.exe ├── afl-showmap.exe ├── afl-tmin.exe ├── keystone.dll ├── kstool.exe ├── msvcr120d.dll ├── test_clfs.exe ├── test_gdiplus.exe ├── test_hive.exe ├── test_ioctl.exe ├── test_mdb.exe ├── winload.exe └── winload2.exe ├── clear_stub.py ├── demo ├── Demo.c ├── blf │ └── normal.blf ├── calc.exe ├── clfs.pdb ├── clfs.sys ├── clfs.sys.dump.txt ├── demo.sys ├── mdb │ └── normal.mdb ├── msjet40.dll ├── msjet40.dll.dump.txt └── msjet40.pdb ├── disable_dse.bat ├── fix_checksum.py ├── helper ├── Release_win10 │ └── helper.sys ├── Release_win7 │ └── helper.sys ├── helper.inf ├── helper.sln ├── helper.vcxproj ├── helper.vcxproj.filters ├── main.c └── main.h ├── ida_dumper.py ├── install_helper.bat ├── instrument.py ├── lighthouse ├── lighthouse │ ├── __init__.py │ ├── binja_integration.py │ ├── binja_loader.py │ ├── composer │ │ ├── __init__.py │ │ ├── parser.py │ │ └── shell.py │ ├── core.py │ ├── coverage.py │ ├── director.py │ ├── ida_integration.py │ ├── ida_loader.py │ ├── metadata.py │ ├── painting │ │ ├── __init__.py │ │ ├── binja_painter.py │ │ ├── ida_painter.py │ │ └── painter.py │ ├── palette.py │ ├── parsers │ │ ├── __init__.py │ │ └── drcov.py │ ├── ui │ │ ├── __init__.py │ │ ├── coverage_combobox.py │ │ ├── coverage_overview.py │ │ ├── coverage_settings.py │ │ ├── coverage_table.py │ │ └── resources │ │ │ └── icons │ │ │ ├── batch.png │ │ │ ├── delete_coverage.png │ │ │ ├── load.png │ │ │ └── overview.png │ └── util │ │ ├── __init__.py │ │ ├── debug.py │ │ ├── disassembler │ │ ├── __init__.py │ │ ├── api.py │ │ ├── binja_api.py │ │ └── ida_api.py │ │ ├── log.py │ │ ├── misc.py │ │ └── qt │ │ ├── __init__.py │ │ ├── shim.py │ │ ├── util.py │ │ └── waitbox.py └── lighthouse_plugin.py ├── lighthouse_trace.py ├── ordlookup ├── __init__.py ├── oleaut32.py └── ws2_32.py ├── pe-afl.py ├── pefile.py └── remove_certificate.py /AFL/AFL/AFL.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AFL", "AFL.vcxproj", "{02782A55-399C-471B-8470-3132A67563AB}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_gdiplus", "..\test_gdiplus\test_gdiplus.vcxproj", "{8FCF4178-75A9-4EFC-990D-D919308D9987}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_clfs", "..\test_clfs\test_clfs.vcxproj", "{5C84D611-9747-4AC3-B5EF-B9768DB57705}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "afl-showmap", "..\afl-showmap\afl-showmap.vcxproj", "{D70D0D93-EA58-4975-A193-653D74FAEC86}" 13 | EndProject 14 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "afl-tmin", "..\afl-tmin\afl-tmin.vcxproj", "{7D25A2EB-A24F-428A-9B27-316842322240}" 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_ioctl", "..\test_ioctl\test_ioctl.vcxproj", "{78704997-9607-45BD-92B3-DE5E7676FCD8}" 17 | EndProject 18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_hive", "..\test_hive\test_hive.vcxproj", "{32F994A5-D6F7-4E61-A0AB-DDDAD4A20E84}" 19 | EndProject 20 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_mdb", "..\test_mdb\test_mdb.vcxproj", "{3F1B52C6-E521-484D-AA9E-FC092F91BBD6}" 21 | EndProject 22 | Global 23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 24 | Debug|Win32 = Debug|Win32 25 | Release|Win32 = Release|Win32 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {02782A55-399C-471B-8470-3132A67563AB}.Debug|Win32.ActiveCfg = Debug|Win32 29 | {02782A55-399C-471B-8470-3132A67563AB}.Debug|Win32.Build.0 = Debug|Win32 30 | {02782A55-399C-471B-8470-3132A67563AB}.Release|Win32.ActiveCfg = Release|Win32 31 | {02782A55-399C-471B-8470-3132A67563AB}.Release|Win32.Build.0 = Release|Win32 32 | {8FCF4178-75A9-4EFC-990D-D919308D9987}.Debug|Win32.ActiveCfg = Debug|Win32 33 | {8FCF4178-75A9-4EFC-990D-D919308D9987}.Debug|Win32.Build.0 = Debug|Win32 34 | {8FCF4178-75A9-4EFC-990D-D919308D9987}.Release|Win32.ActiveCfg = Release|Win32 35 | {8FCF4178-75A9-4EFC-990D-D919308D9987}.Release|Win32.Build.0 = Release|Win32 36 | {5C84D611-9747-4AC3-B5EF-B9768DB57705}.Debug|Win32.ActiveCfg = Debug|Win32 37 | {5C84D611-9747-4AC3-B5EF-B9768DB57705}.Debug|Win32.Build.0 = Debug|Win32 38 | {5C84D611-9747-4AC3-B5EF-B9768DB57705}.Release|Win32.ActiveCfg = Release|Win32 39 | {5C84D611-9747-4AC3-B5EF-B9768DB57705}.Release|Win32.Build.0 = Release|Win32 40 | {D70D0D93-EA58-4975-A193-653D74FAEC86}.Debug|Win32.ActiveCfg = Debug|Win32 41 | {D70D0D93-EA58-4975-A193-653D74FAEC86}.Debug|Win32.Build.0 = Debug|Win32 42 | {D70D0D93-EA58-4975-A193-653D74FAEC86}.Release|Win32.ActiveCfg = Release|Win32 43 | {D70D0D93-EA58-4975-A193-653D74FAEC86}.Release|Win32.Build.0 = Release|Win32 44 | {7D25A2EB-A24F-428A-9B27-316842322240}.Debug|Win32.ActiveCfg = Debug|Win32 45 | {7D25A2EB-A24F-428A-9B27-316842322240}.Debug|Win32.Build.0 = Debug|Win32 46 | {7D25A2EB-A24F-428A-9B27-316842322240}.Release|Win32.ActiveCfg = Release|Win32 47 | {7D25A2EB-A24F-428A-9B27-316842322240}.Release|Win32.Build.0 = Release|Win32 48 | {78704997-9607-45BD-92B3-DE5E7676FCD8}.Debug|Win32.ActiveCfg = Debug|Win32 49 | {78704997-9607-45BD-92B3-DE5E7676FCD8}.Debug|Win32.Build.0 = Debug|Win32 50 | {78704997-9607-45BD-92B3-DE5E7676FCD8}.Release|Win32.ActiveCfg = Release|Win32 51 | {78704997-9607-45BD-92B3-DE5E7676FCD8}.Release|Win32.Build.0 = Release|Win32 52 | {32F994A5-D6F7-4E61-A0AB-DDDAD4A20E84}.Debug|Win32.ActiveCfg = Debug|Win32 53 | {32F994A5-D6F7-4E61-A0AB-DDDAD4A20E84}.Debug|Win32.Build.0 = Debug|Win32 54 | {32F994A5-D6F7-4E61-A0AB-DDDAD4A20E84}.Release|Win32.ActiveCfg = Release|Win32 55 | {32F994A5-D6F7-4E61-A0AB-DDDAD4A20E84}.Release|Win32.Build.0 = Release|Win32 56 | {3F1B52C6-E521-484D-AA9E-FC092F91BBD6}.Debug|Win32.ActiveCfg = Debug|Win32 57 | {3F1B52C6-E521-484D-AA9E-FC092F91BBD6}.Debug|Win32.Build.0 = Debug|Win32 58 | {3F1B52C6-E521-484D-AA9E-FC092F91BBD6}.Release|Win32.ActiveCfg = Release|Win32 59 | {3F1B52C6-E521-484D-AA9E-FC092F91BBD6}.Release|Win32.Build.0 = Release|Win32 60 | EndGlobalSection 61 | GlobalSection(SolutionProperties) = preSolution 62 | HideSolutionNode = FALSE 63 | EndGlobalSection 64 | EndGlobal 65 | -------------------------------------------------------------------------------- /AFL/AFL/AFL.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {02782A55-399C-471B-8470-3132A67563AB} 15 | AFL 16 | 17 | 18 | 19 | Application 20 | true 21 | v120_xp 22 | MultiByte 23 | 24 | 25 | Application 26 | false 27 | v120 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Level3 45 | Disabled 46 | true 47 | 48 | 49 | true 50 | 51 | 52 | Console 53 | 54 | 55 | 56 | 57 | Level3 58 | MaxSpeed 59 | true 60 | true 61 | true 62 | 63 | 64 | true 65 | true 66 | true 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /AFL/AFL/AFL.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | -------------------------------------------------------------------------------- /AFL/AFL/Debug/AFL.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/AFL/AFL/Debug/AFL.exe -------------------------------------------------------------------------------- /AFL/AFL/Debug/afl-showmap.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/AFL/AFL/Debug/afl-showmap.exe -------------------------------------------------------------------------------- /AFL/AFL/Debug/afl-tmin.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/AFL/AFL/Debug/afl-tmin.exe -------------------------------------------------------------------------------- /AFL/AFL/Debug/test_clfs.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/AFL/AFL/Debug/test_clfs.exe -------------------------------------------------------------------------------- /AFL/AFL/Debug/test_gdiplus.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/AFL/AFL/Debug/test_gdiplus.exe -------------------------------------------------------------------------------- /AFL/AFL/Debug/test_hive.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/AFL/AFL/Debug/test_hive.exe -------------------------------------------------------------------------------- /AFL/AFL/Debug/test_ioctl.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/AFL/AFL/Debug/test_ioctl.exe -------------------------------------------------------------------------------- /AFL/AFL/Debug/test_mdb.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/AFL/AFL/Debug/test_mdb.exe -------------------------------------------------------------------------------- /AFL/AFL/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - debug / error handling macros 3 | -------------------------------------------------- 4 | 5 | Written and maintained by Michal Zalewski 6 | 7 | Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at: 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | */ 16 | 17 | #ifndef _HAVE_DEBUG_H 18 | #define _HAVE_DEBUG_H 19 | 20 | #include 21 | 22 | #include "types.h" 23 | #include "config.h" 24 | 25 | /******************* 26 | * Terminal colors * 27 | *******************/ 28 | 29 | #ifdef USE_COLOR 30 | 31 | # define cBLK "\x1b[0;30m" 32 | # define cRED "\x1b[0;31m" 33 | # define cGRN "\x1b[0;32m" 34 | # define cBRN "\x1b[0;33m" 35 | # define cBLU "\x1b[0;34m" 36 | # define cMGN "\x1b[0;35m" 37 | # define cCYA "\x1b[0;36m" 38 | # define cLGR "\x1b[0;37m" 39 | # define cGRA "\x1b[1;90m" 40 | # define cLRD "\x1b[1;91m" 41 | # define cLGN "\x1b[1;92m" 42 | # define cYEL "\x1b[1;93m" 43 | # define cLBL "\x1b[1;94m" 44 | # define cPIN "\x1b[1;95m" 45 | # define cLCY "\x1b[1;96m" 46 | # define cBRI "\x1b[1;97m" 47 | # define cRST "\x1b[0m" 48 | 49 | # define bgBLK "\x1b[40m" 50 | # define bgRED "\x1b[41m" 51 | # define bgGRN "\x1b[42m" 52 | # define bgBRN "\x1b[43m" 53 | # define bgBLU "\x1b[44m" 54 | # define bgMGN "\x1b[45m" 55 | # define bgCYA "\x1b[46m" 56 | # define bgLGR "\x1b[47m" 57 | # define bgGRA "\x1b[100m" 58 | # define bgLRD "\x1b[101m" 59 | # define bgLGN "\x1b[102m" 60 | # define bgYEL "\x1b[103m" 61 | # define bgLBL "\x1b[104m" 62 | # define bgPIN "\x1b[105m" 63 | # define bgLCY "\x1b[106m" 64 | # define bgBRI "\x1b[107m" 65 | 66 | #else 67 | 68 | # define cBLK "" 69 | # define cRED "" 70 | # define cGRN "" 71 | # define cBRN "" 72 | # define cBLU "" 73 | # define cMGN "" 74 | # define cCYA "" 75 | # define cLGR "" 76 | # define cGRA "" 77 | # define cLRD "" 78 | # define cLGN "" 79 | # define cYEL "" 80 | # define cLBL "" 81 | # define cPIN "" 82 | # define cLCY "" 83 | # define cBRI "" 84 | # define cRST "" 85 | 86 | # define bgBLK "" 87 | # define bgRED "" 88 | # define bgGRN "" 89 | # define bgBRN "" 90 | # define bgBLU "" 91 | # define bgMGN "" 92 | # define bgCYA "" 93 | # define bgLGR "" 94 | # define bgGRA "" 95 | # define bgLRD "" 96 | # define bgLGN "" 97 | # define bgYEL "" 98 | # define bgLBL "" 99 | # define bgPIN "" 100 | # define bgLCY "" 101 | # define bgBRI "" 102 | 103 | #endif /* ^USE_COLOR */ 104 | 105 | /************************* 106 | * Box drawing sequences * 107 | *************************/ 108 | 109 | #ifdef FANCY_BOXES 110 | 111 | # define SET_G1 "\x1b)0" /* Set G1 for box drawing */ 112 | # define RESET_G1 "\x1b)B" /* Reset G1 to ASCII */ 113 | # define bSTART "\x0e" /* Enter G1 drawing mode */ 114 | # define bSTOP "\x0f" /* Leave G1 drawing mode */ 115 | # define bH "q" /* Horizontal line */ 116 | # define bV "x" /* Vertical line */ 117 | # define bLT "l" /* Left top corner */ 118 | # define bRT "k" /* Right top corner */ 119 | # define bLB "m" /* Left bottom corner */ 120 | # define bRB "j" /* Right bottom corner */ 121 | # define bX "n" /* Cross */ 122 | # define bVR "t" /* Vertical, branch right */ 123 | # define bVL "u" /* Vertical, branch left */ 124 | # define bHT "v" /* Horizontal, branch top */ 125 | # define bHB "w" /* Horizontal, branch bottom */ 126 | 127 | #else 128 | 129 | # define SET_G1 "" 130 | # define RESET_G1 "" 131 | # define bSTART "" 132 | # define bSTOP "" 133 | # define bH "-" 134 | # define bV "|" 135 | # define bLT "+" 136 | # define bRT "+" 137 | # define bLB "+" 138 | # define bRB "+" 139 | # define bX "+" 140 | # define bVR "+" 141 | # define bVL "+" 142 | # define bHT "+" 143 | # define bHB "+" 144 | 145 | #endif /* ^FANCY_BOXES */ 146 | 147 | /*********************** 148 | * Misc terminal codes * 149 | ***********************/ 150 | /* 151 | #define TERM_HOME "\x1b[H" 152 | #define TERM_CLEAR TERM_HOME "\x1b[2J" 153 | #define cEOL "\x1b[0K" 154 | #define CURSOR_HIDE "\x1b[?25l" 155 | #define CURSOR_SHOW "\x1b[?25h" 156 | */ 157 | #define TERM_HOME "" 158 | #define TERM_CLEAR "" 159 | #define cEOL "" 160 | #define CURSOR_HIDE "" 161 | #define CURSOR_SHOW "" 162 | 163 | /************************ 164 | * Debug & error macros * 165 | ************************/ 166 | 167 | /* Just print stuff to the appropriate stream. */ 168 | 169 | #ifdef MESSAGES_TO_STDOUT 170 | # define SAYF(...) printf(__VA_ARGS__) 171 | #else 172 | # define SAYF(...) fprintf(stderr, __VA_ARGS__) 173 | #endif /* ^MESSAGES_TO_STDOUT */ 174 | 175 | /* Show a prefixed warning. */ 176 | 177 | #define WARNF(...) do { \ 178 | SAYF(cYEL "[!] " cBRI "WARNING: " cRST __VA_ARGS__); \ 179 | SAYF(cRST "\n"); \ 180 | } while (0) 181 | 182 | /* Show a prefixed "doing something" message. */ 183 | 184 | #define ACTF(...) do { \ 185 | SAYF(cLBL "[*] " cRST __VA_ARGS__); \ 186 | SAYF(cRST "\n"); \ 187 | } while (0) 188 | 189 | /* Show a prefixed "success" message. */ 190 | 191 | #define OKF(...) do { \ 192 | SAYF(cLGN "[+] " cRST __VA_ARGS__); \ 193 | SAYF(cRST "\n"); \ 194 | } while (0) 195 | 196 | /* Show a prefixed fatal error message (not used in afl). */ 197 | 198 | #define BADF(...) do { \ 199 | SAYF(cLRD "\n[-] " cRST __VA_ARGS__); \ 200 | SAYF(cRST "\n"); \ 201 | } while (0) 202 | 203 | /* Die with a verbose non-OS fatal error message. */ 204 | 205 | #define FATAL(...) do { \ 206 | SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] PROGRAM ABORT : " \ 207 | cBRI __VA_ARGS__); \ 208 | SAYF(cLRD "\n Location : " cRST "%s(), %s:%u\n\n", \ 209 | __FUNCTION__, __FILE__, __LINE__); \ 210 | exit(1); \ 211 | } while (0) 212 | 213 | /* Die by calling abort() to provide a core dump. */ 214 | 215 | #define ABORT(...) do { \ 216 | SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] PROGRAM ABORT : " \ 217 | cBRI __VA_ARGS__); \ 218 | SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n\n", \ 219 | __FUNCTION__, __FILE__, __LINE__); \ 220 | abort(); \ 221 | } while (0) 222 | 223 | /* Die while also including the output of perror(). */ 224 | 225 | #define PFATAL(...) do { \ 226 | fflush(stdout); \ 227 | SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] SYSTEM ERROR : " \ 228 | cBRI __VA_ARGS__); \ 229 | SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n", \ 230 | __FUNCTION__, __FILE__, __LINE__); \ 231 | SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \ 232 | exit(1); \ 233 | } while (0) 234 | 235 | /* Die with FAULT() or PFAULT() depending on the value of res (used to 236 | interpret different failure modes for read(), write(), etc). */ 237 | 238 | #define RPFATAL(res, ...) do { \ 239 | if (res < 0) PFATAL(__VA_ARGS__); else FATAL(__VA_ARGS__); \ 240 | } while (0) 241 | 242 | /* Error-checking versions of read() and write() that call RPFATAL() as 243 | appropriate. */ 244 | 245 | #define ck_write(fd, buf, len, fn) do { \ 246 | u32 _len = (len); \ 247 | s32 _res = _write(fd, buf, _len); \ 248 | if (_res != _len) RPFATAL(_res, "Short write to %s", fn); \ 249 | } while (0) 250 | 251 | #define ck_read(fd, buf, len, fn) do { \ 252 | u32 _len = (len); \ 253 | s32 _res = _read(fd, buf, _len); \ 254 | if (_res != _len) RPFATAL(_res, "Short read from %s", fn); \ 255 | } while (0) 256 | 257 | #endif /* ! _HAVE_DEBUG_H */ 258 | -------------------------------------------------------------------------------- /AFL/AFL/hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - hashing function 3 | ------------------------------------- 4 | 5 | The hash32() function is a variant of MurmurHash3, a good 6 | non-cryptosafe hashing function developed by Austin Appleby. 7 | 8 | For simplicity, this variant does *NOT* accept buffer lengths 9 | that are not divisible by 8 bytes. The 32-bit version is otherwise 10 | similar to the original; the 64-bit one is a custom hack with 11 | mostly-unproven properties. 12 | 13 | Austin's original code is public domain. 14 | 15 | Other code written and maintained by Michal Zalewski 16 | 17 | Copyright 2016 Google Inc. All rights reserved. 18 | 19 | Licensed under the Apache License, Version 2.0 (the "License"); 20 | you may not use this file except in compliance with the License. 21 | You may obtain a copy of the License at: 22 | 23 | http://www.apache.org/licenses/LICENSE-2.0 24 | 25 | */ 26 | 27 | #ifndef _HAVE_HASH_H 28 | #define _HAVE_HASH_H 29 | 30 | #include "types.h" 31 | 32 | #ifdef __x86_64__ 33 | 34 | #define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r)))) 35 | 36 | static inline u32 hash32(const void* key, u32 len, u32 seed) { 37 | 38 | const u64* data = (u64*)key; 39 | u64 h1 = seed ^ len; 40 | 41 | len >>= 3; 42 | 43 | while (len--) { 44 | 45 | u64 k1 = *data++; 46 | 47 | k1 *= 0x87c37b91114253d5ULL; 48 | k1 = ROL64(k1, 31); 49 | k1 *= 0x4cf5ad432745937fULL; 50 | 51 | h1 ^= k1; 52 | h1 = ROL64(h1, 27); 53 | h1 = h1 * 5 + 0x52dce729; 54 | 55 | } 56 | 57 | h1 ^= h1 >> 33; 58 | h1 *= 0xff51afd7ed558ccdULL; 59 | h1 ^= h1 >> 33; 60 | h1 *= 0xc4ceb9fe1a85ec53ULL; 61 | h1 ^= h1 >> 33; 62 | 63 | return h1; 64 | 65 | } 66 | 67 | #else 68 | 69 | #define ROL32(_x, _r) ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r)))) 70 | 71 | static inline u32 hash32(const void* key, u32 len, u32 seed) { 72 | 73 | const u32* data = (u32*)key; 74 | u32 h1 = seed ^ len; 75 | 76 | len >>= 2; 77 | 78 | while (len--) { 79 | 80 | u32 k1 = *data++; 81 | 82 | k1 *= 0xcc9e2d51; 83 | k1 = ROL32(k1, 15); 84 | k1 *= 0x1b873593; 85 | 86 | h1 ^= k1; 87 | h1 = ROL32(h1, 13); 88 | h1 = h1 * 5 + 0xe6546b64; 89 | 90 | } 91 | 92 | h1 ^= h1 >> 16; 93 | h1 *= 0x85ebca6b; 94 | h1 ^= h1 >> 13; 95 | h1 *= 0xc2b2ae35; 96 | h1 ^= h1 >> 16; 97 | 98 | return h1; 99 | 100 | } 101 | 102 | #endif /* ^__x86_64__ */ 103 | 104 | #endif /* !_HAVE_HASH_H */ 105 | -------------------------------------------------------------------------------- /AFL/AFL/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | american fuzzy lop - type definitions and minor macros 3 | ------------------------------------------------------ 4 | 5 | Written and maintained by Michal Zalewski 6 | 7 | Copyright 2013, 2014, 2015 Google Inc. All rights reserved. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at: 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | */ 16 | 17 | #ifndef _HAVE_TYPES_H 18 | #define _HAVE_TYPES_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | typedef char u8; 25 | typedef uint16_t u16; 26 | typedef uint32_t u32; 27 | 28 | /* 29 | 30 | Ugh. There is an unintended compiler / glibc #include glitch caused by 31 | combining the u64 type an %llu in format strings, necessitating a workaround. 32 | 33 | In essence, the compiler is always looking for 'unsigned long long' for %llu. 34 | On 32-bit systems, the u64 type (aliased to uint64_t) is expanded to 35 | 'unsigned long long' in , so everything checks out. 36 | 37 | But on 64-bit systems, it is #ifdef'ed in the same file as 'unsigned long'. 38 | Now, it only happens in circumstances where the type happens to have the 39 | expected bit width, *but* the compiler does not know that... and complains 40 | about 'unsigned long' being unsafe to pass to %llu. 41 | 42 | */ 43 | 44 | #ifdef __x86_64__ 45 | typedef unsigned long long u64; 46 | #else 47 | typedef uint64_t u64; 48 | #endif /* ^__x86_64__ */ 49 | 50 | typedef int8_t s8; 51 | typedef int16_t s16; 52 | typedef int32_t s32; 53 | typedef int64_t s64; 54 | 55 | #ifndef MIN 56 | # define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a)) 57 | # define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b)) 58 | #endif /* !MIN */ 59 | 60 | #define SWAP16(x) (((x) >> 8) | ((x) << 8)) 61 | #define SWAP32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24)) 62 | 63 | #define R(x) (random() % (x)) 64 | 65 | #define STRINGIFY_INTERNAL(x) #x 66 | #define STRINGIFY(x) STRINGIFY_INTERNAL(x) 67 | 68 | #define MEM_BARRIER() _ReadWriteBarrier(); MemoryBarrier() 69 | 70 | #define __builtin_expect(exp, c) (exp) 71 | #define likely(_x) __builtin_expect(!!(_x), 1) 72 | #define unlikely(_x) __builtin_expect(!!(_x), 0) 73 | 74 | #endif /* ! _HAVE_TYPES_H */ 75 | -------------------------------------------------------------------------------- /AFL/afl-showmap/afl-showmap.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {D70D0D93-EA58-4975-A193-653D74FAEC86} 15 | aflshowmap 16 | 17 | 18 | 19 | Application 20 | true 21 | v120 22 | MultiByte 23 | 24 | 25 | Application 26 | false 27 | v120 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Level3 45 | Disabled 46 | true 47 | 48 | 49 | true 50 | 51 | 52 | 53 | 54 | Level3 55 | MaxSpeed 56 | true 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /AFL/afl-showmap/afl-showmap.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /AFL/afl-tmin/afl-tmin.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {7D25A2EB-A24F-428A-9B27-316842322240} 15 | afltmin 16 | 17 | 18 | 19 | Application 20 | true 21 | v120 22 | MultiByte 23 | 24 | 25 | Application 26 | false 27 | v120 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Level3 45 | Disabled 46 | true 47 | 48 | 49 | true 50 | 51 | 52 | 53 | 54 | Level3 55 | MaxSpeed 56 | true 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /AFL/afl-tmin/afl-tmin.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /AFL/test_clfs/header.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_H__ 2 | #define __MAIN_H__ 3 | 4 | #define _CRT_SECURE_NO_WARNINGS 5 | #include 6 | #include 7 | #include 8 | 9 | #include "helper.h" 10 | 11 | #define PFATAL_GLE(msg) { _tprintf(_T("%s, GLE=%d\n"), msg, GetLastError()); exit(1); } 12 | #define PFATAL(msg) { _tprintf(_T("%s\n"), msg); exit(1); } 13 | 14 | void INIT(); 15 | void PRE(); 16 | void POST(); 17 | void FINI(); 18 | extern DWORD PERSISTENT_COUNT; 19 | extern HANDLE hHelper; 20 | DWORD HELPER_GetModuleSectionAddress(PTCHAR pBuffer); 21 | DWORD HELPER_ReadMemory(PBYTE dwAddr, PBYTE pRetBuffer, DWORD dwLen); 22 | DWORD HELPER_WriteMemory(PBYTE dwAddr, PBYTE pRetBuffer, DWORD dwLen); 23 | DWORD HELPER_AllocateMemory(DWORD dwPoolType, DWORD dwTag, DWORD dwLen); 24 | DWORD HELPER_FreeMemory(PBYTE dwAddr, DWORD dwTag); 25 | DWORD HELPER_MapMemory(PBYTE dwAddr, DWORD dwLen, PBYTE* ptrUserAddr, PBYTE* ptrMdl); 26 | DWORD HELPER_UnmapMemory(PBYTE ptrUserAddr, PBYTE ptrMdl); 27 | DWORD HELPER_ResetBuffer(); 28 | 29 | static void LOG(TCHAR *fmt, ...) 30 | { 31 | TCHAR szBuf[MAX_PATH] = { 0 }; 32 | 33 | va_list ap; 34 | va_start(ap, fmt); 35 | _vstprintf_s(szBuf, fmt, ap); 36 | va_end(ap); 37 | OutputDebugString(szBuf); 38 | 39 | //_tprintf(L"%s", szBuf); 40 | } 41 | 42 | static void hexDump(char *desc, void *addr, int len) { 43 | int i; 44 | unsigned char buff[17]; 45 | unsigned char *pc = (unsigned char*)addr; 46 | 47 | // Output description if given. 48 | if (desc != NULL) 49 | printf("%s:\n", desc); 50 | 51 | if (len == 0) { 52 | printf(" ZERO LENGTH\n"); 53 | return; 54 | } 55 | if (len < 0) { 56 | printf(" NEGATIVE LENGTH: %i\n", len); 57 | return; 58 | } 59 | 60 | // Process every byte in the data. 61 | for (i = 0; i < len; i++) { 62 | // Multiple of 16 means new line (with line offset). 63 | 64 | if ((i % 16) == 0) { 65 | // Just don't print ASCII for the zeroth line. 66 | if (i != 0) 67 | printf(" %s\n", buff); 68 | 69 | // Output the offset. 70 | printf(" %04x ", i); 71 | } 72 | 73 | // Now the hex code for the specific character. 74 | printf(" %02x", pc[i]); 75 | 76 | // And store a printable ASCII character for later. 77 | if ((pc[i] < 0x20) || (pc[i] > 0x7e)) 78 | buff[i % 16] = '.'; 79 | else 80 | buff[i % 16] = pc[i]; 81 | buff[(i % 16) + 1] = '\0'; 82 | } 83 | 84 | // Pad out last line if not exactly 16 characters. 85 | while ((i % 16) != 0) { 86 | printf(" "); 87 | i++; 88 | } 89 | 90 | // And print the final ASCII bit. 91 | printf(" %s\n", buff); 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /AFL/test_clfs/helper.h: -------------------------------------------------------------------------------- 1 | #ifndef __HELPER_DRIVER_H__ 2 | #define __HELPER_DRIVER_H__ 3 | 4 | #define IOCTL_HELPER_GET_SECTION_ADDRESS CTL_CODE(FILE_DEVICE_UNKNOWN, 801, METHOD_BUFFERED, FILE_ANY_ACCESS) 5 | #define IOCTL_HELPER_READ_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 802, METHOD_BUFFERED, FILE_ANY_ACCESS) 6 | #define IOCTL_HELPER_WRITE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 803, METHOD_BUFFERED, FILE_ANY_ACCESS) 7 | #define IOCTL_HELPER_ALLOCATE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 804, METHOD_BUFFERED, FILE_ANY_ACCESS) 8 | #define IOCTL_HELPER_FREE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 805, METHOD_BUFFERED, FILE_ANY_ACCESS) 9 | #define IOCTL_HELPER_MAP_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 806, METHOD_BUFFERED, FILE_ANY_ACCESS) 10 | #define IOCTL_HELPER_UNMAP_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 807, METHOD_BUFFERED, FILE_ANY_ACCESS) 11 | #define IOCTL_HELPER_DUMP_AND_RESET_CALLBACK CTL_CODE(FILE_DEVICE_UNKNOWN, 808, METHOD_BUFFERED, FILE_ANY_ACCESS) 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /AFL/test_clfs/interface.cpp: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | 3 | DWORD HELPER_GetModuleSectionAddress(PTCHAR pBuffer) 4 | { 5 | DWORD dwRet = 0, dwOutLen = 0, dwInLen = 0; 6 | DWORD dwData = 0; 7 | BOOLEAN bRet = 0; 8 | 9 | dwInLen = (DWORD)_tcsclen(pBuffer) + 1; 10 | dwInLen *= 2; 11 | dwOutLen = sizeof(DWORD); 12 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_GET_SECTION_ADDRESS, pBuffer, dwInLen, &dwData, dwOutLen, &dwRet, NULL); 13 | if (!bRet) { 14 | LOG(_T("HELPER_GetModuleSectionAddress(%s) failed, GLE(%x)\n"), pBuffer, GetLastError()); 15 | } 16 | return dwData; 17 | } 18 | 19 | DWORD HELPER_ReadMemory(PBYTE dwAddr, PBYTE pRetBuffer, DWORD dwLen) 20 | { 21 | DWORD dwRet = 0; 22 | BOOLEAN bRet = 0; 23 | 24 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_READ_MEMORY, &dwAddr, dwLen, pRetBuffer, dwLen, &dwRet, NULL); 25 | if (!bRet) { 26 | LOG(_T("HELPER_ReadMemory(%p, %p, %x) failed, GLE(%x)\n"), dwAddr, pRetBuffer, dwLen, GetLastError()); 27 | } 28 | return dwRet; 29 | } 30 | 31 | DWORD HELPER_WriteMemory(PBYTE dwAddr, PBYTE pRetBuffer, DWORD dwLen) 32 | { 33 | DWORD dwRet = 0; 34 | BOOLEAN bRet = 0; 35 | 36 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_WRITE_MEMORY, &dwAddr, dwLen, pRetBuffer, dwLen, &dwRet, NULL); 37 | if (!bRet) { 38 | LOG(_T("HELPER_WriteMemory(%p, %p, %x) failed, GLE(%x)\n"), dwAddr, pRetBuffer, dwLen, GetLastError()); 39 | } 40 | return dwRet; 41 | } 42 | 43 | DWORD HELPER_AllocateMemory(DWORD dwPoolType, DWORD dwLen, DWORD dwTag) 44 | { 45 | DWORD dwRet = 0; 46 | BOOLEAN bRet = 0; 47 | DWORD dwData = 0; 48 | 49 | DWORD in[] = { dwPoolType, dwLen, dwTag }; 50 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_ALLOCATE_MEMORY, in, sizeof(in), &dwData, sizeof(&dwData), &dwRet, NULL); 51 | if (!bRet) { 52 | LOG(_T("HELPER_AllocateMemory(%x, %x, 0x%x) failed, GLE(%x)\n"), dwPoolType, dwLen, dwTag, GetLastError()); 53 | } 54 | return dwData; 55 | } 56 | 57 | DWORD HELPER_FreeMemory(PBYTE dwAddr, DWORD dwTag) 58 | { 59 | DWORD dwRet = 0; 60 | BOOLEAN bRet = 0; 61 | 62 | DWORD in[] = { (DWORD)dwAddr, dwTag }; 63 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_FREE_MEMORY, in, sizeof(in), NULL, NULL, &dwRet, NULL); 64 | if (!bRet) { 65 | LOG(_T("HELPER_FreeMemory(%p, %x) failed, GLE(%x)\n"), dwAddr, dwTag, GetLastError()); 66 | } 67 | return dwRet; 68 | } 69 | 70 | DWORD HELPER_MapMemory(PBYTE dwAddr, DWORD dwLen, PBYTE *ptrUserAddr, PBYTE *ptrMdl) 71 | { 72 | DWORD dwRet = 0; 73 | BOOLEAN bRet = 0; 74 | 75 | DWORD in[] = { (DWORD)dwAddr, dwLen }; 76 | DWORD out[2] = { 0 }; 77 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_MAP_MEMORY, in, sizeof(in), out, sizeof(out), &dwRet, NULL); 78 | if (!bRet) { 79 | LOG(_T("HELPER_MapMemory(%p, %x, %p, %p) failed, GLE(%x)\n"), dwAddr, dwLen, ptrUserAddr, ptrMdl); 80 | } 81 | *ptrUserAddr = (PBYTE)out[0]; 82 | *ptrMdl = (PBYTE)out[1]; 83 | return dwRet; 84 | } 85 | 86 | DWORD HELPER_UnmapMemory(PBYTE ptrUserAddr, PBYTE ptrMdl) 87 | { 88 | DWORD dwRet = 0; 89 | BOOLEAN bRet = 0; 90 | 91 | DWORD in[] = { (DWORD)ptrUserAddr, (DWORD)ptrMdl }; 92 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_UNMAP_MEMORY, in, sizeof(in), NULL, NULL, &dwRet, NULL); 93 | if (!bRet) { 94 | LOG(_T("HELPER_UnmapMemory(%p, %p) failed, GLE(%x)\n"), ptrUserAddr, ptrMdl); 95 | } 96 | return dwRet; 97 | } 98 | 99 | DWORD HELPER_ResetBuffer() 100 | { 101 | DWORD dwRet = 0; 102 | BOOLEAN bRet = 0; 103 | 104 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_DUMP_AND_RESET_CALLBACK, NULL, NULL, NULL, NULL, &dwRet, NULL); 105 | if (!bRet) { 106 | LOG(_T("HELPER_ResetBuffer() failed, GLE(%x)\n"), GetLastError()); 107 | } 108 | return dwRet; 109 | } -------------------------------------------------------------------------------- /AFL/test_clfs/main.cpp: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | #include 3 | 4 | void process(LPTSTR name) { 5 | 6 | HANDLE rc = CreateTransactionManager(0, name, 0, 0); 7 | 8 | if (rc == INVALID_HANDLE_VALUE) { 9 | _tprintf(_T("GetLastError: %d\n"), GetLastError()); 10 | } 11 | else { 12 | _tprintf(_T("Success\n")); 13 | } 14 | 15 | RecoverTransactionManager(rc); 16 | CloseHandle(rc); 17 | } 18 | 19 | INT _tmain(INT argc, TCHAR* argv[]) { 20 | //SetStdHandle(STD_OUTPUT_HANDLE, CreateFile(_T("CONOUT$"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)); 21 | //SetStdHandle(STD_ERROR_HANDLE, CreateFile(_T("CONERR$"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)); 22 | 23 | #ifndef UNICODE 24 | LOG(_T("Have to compile with unicode\n")); 25 | return 0; 26 | #endif 27 | 28 | TCHAR *pp = _tcsstr(argv[argc - 1], _T(".blf")); 29 | if (pp && pp == (argv[argc-1] + _tcslen(argv[argc - 1]) - _tcslen(_T(".blf")))) { 30 | *pp = 0; 31 | } 32 | 33 | INIT(); 34 | atexit(FINI); 35 | 36 | if (argc != 2) PFATAL(_T("test_clfs.exe [.blf]\nRemember do not add .blf extension")); 37 | 38 | while (PERSISTENT_COUNT--) { 39 | PRE(); 40 | process(argv[1]); 41 | POST(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /AFL/test_clfs/persistent.cpp: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #pragma comment(lib,"ntdll.lib") 8 | 9 | #define SHM_ENV_VAR _T("__AFL_SHM_ID") 10 | #define PIPE_ENV_VAR _T("__AFL_PIPE_ID") 11 | #define MAP_SIZE 0x10000 12 | #define PAGE_SIZE 0x1000 13 | #define MEM_BARRIER() _ReadWriteBarrier(); MemoryBarrier() 14 | #define DRIVER_NAME _T("\\\\.\\helper") 15 | 16 | PUCHAR COV_ADDR = 0; 17 | PUCHAR KCOV_ADDR = 0; 18 | PUCHAR MDL_ADDR = 0; 19 | PUCHAR shared_mem; 20 | HANDLE pipe; 21 | DWORD PERSISTENT_COUNT; 22 | PTCHAR target; 23 | HANDLE hHelper; 24 | DWORD PID; 25 | DWORD CALLBACK_ADDR = 0; 26 | 27 | typedef struct _RTL_PROCESS_MODULE_INFORMATION 28 | { 29 | HANDLE Section; 30 | PVOID MappedBase; 31 | PVOID ImageBase; 32 | ULONG ImageSize; 33 | ULONG Flags; 34 | USHORT LoadOrderIndex; 35 | USHORT InitOrderIndex; 36 | USHORT LoadCount; 37 | USHORT OffsetToFileName; 38 | UCHAR FullPathName[256]; 39 | } RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION; 40 | 41 | typedef struct _RTL_PROCESS_MODULES 42 | { 43 | ULONG NumberOfModules; 44 | RTL_PROCESS_MODULE_INFORMATION Modules[1]; 45 | } RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES; 46 | 47 | typedef enum _SYSTEM_INFORMATION_CLASS 48 | { 49 | SystemBasicInformation = 0, 50 | SystemProcessorInformation = 1, // obsolete...delete 51 | SystemPerformanceInformation = 2, 52 | SystemTimeOfDayInformation = 3, 53 | SystemPathInformation = 4, 54 | SystemProcessInformation = 5, 55 | SystemCallCountInformation = 6, 56 | SystemDeviceInformation = 7, 57 | SystemProcessorPerformanceInformation = 8, 58 | SystemFlagsInformation = 9, 59 | SystemCallTimeInformation = 10, 60 | SystemModuleInformation = 11, 61 | } SYSTEM_INFORMATION_CLASS; 62 | 63 | #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) 64 | 65 | typedef struct _UNICODE_STRING { 66 | USHORT Length; 67 | USHORT MaximumLength; 68 | PWSTR Buffer; 69 | } UNICODE_STRING, *PUNICODE_STRING; 70 | 71 | typedef struct _SYSTEM_PROCESS_INFO 72 | { 73 | ULONG NextEntryOffset; 74 | ULONG NumberOfThreads; 75 | LARGE_INTEGER Reserved[3]; 76 | LARGE_INTEGER CreateTime; 77 | LARGE_INTEGER UserTime; 78 | LARGE_INTEGER KernelTime; 79 | UNICODE_STRING ImageName; 80 | ULONG BasePriority; 81 | HANDLE ProcessId; 82 | HANDLE InheritedFromProcessId; 83 | }SYSTEM_PROCESS_INFO, *PSYSTEM_PROCESS_INFO; 84 | 85 | typedef NTSTATUS(NTAPI * _NtQuerySystemInformation)( 86 | SYSTEM_INFORMATION_CLASS, 87 | PVOID, 88 | ULONG, 89 | PULONG); 90 | 91 | SIZE_T get_driver_address(LPCSTR driver, LPCSTR symbol) { 92 | NTSTATUS status; 93 | ULONG i; 94 | ULONG len; 95 | 96 | PRTL_PROCESS_MODULES ModuleInfo; 97 | 98 | _NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation"); 99 | NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation, NULL, 0, &len); 100 | 101 | ModuleInfo = (PRTL_PROCESS_MODULES)VirtualAlloc(NULL, len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 102 | if (!ModuleInfo) 103 | { 104 | printf("\nUnable to allocate memory for module list (%d)\n", GetLastError()); 105 | return NULL; 106 | } 107 | 108 | if (!NT_SUCCESS(status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation, ModuleInfo, len, &len))) 109 | { 110 | printf("\nError: Unable to query module list (%#x)\n", status); 111 | VirtualFree(ModuleInfo, 0, MEM_RELEASE); 112 | return NULL; 113 | } 114 | 115 | SIZE_T addr = 0; 116 | for (i = 0; iNumberOfModules; i++) 117 | { 118 | if (!_stricmp((CHAR*)ModuleInfo->Modules[i].FullPathName + ModuleInfo->Modules[i].OffsetToFileName, driver)) { 119 | //printf("\nImage base: %#x\n", ModuleInfo->Modules[i].ImageBase); 120 | //printf("\nImage full path: %s\n", ModuleInfo->Modules[i].FullPathName); 121 | 122 | // DONT_RESOLVE_DLL_REFERENCES on some driver return ERROR_MOD_NOT_FOUND 123 | HINSTANCE h = LoadLibraryExA((LPCSTR)ModuleInfo->Modules[i].FullPathName + 4, NULL, DONT_RESOLVE_DLL_REFERENCES); 124 | if (symbol) { 125 | addr = (SIZE_T)ModuleInfo->Modules[i].ImageBase + (SIZE_T)GetProcAddress(h, symbol) - (SIZE_T)h; 126 | } 127 | else { 128 | addr = (SIZE_T)ModuleInfo->Modules[i].ImageBase; 129 | } 130 | break; 131 | } 132 | } 133 | 134 | VirtualFree(ModuleInfo, 0, MEM_RELEASE); 135 | 136 | return addr; 137 | } 138 | 139 | SIZE_T get_helper_value(LPCSTR symbol) { 140 | DWORD v = get_driver_address("helper.sys", symbol); 141 | DWORD v2 = 0; 142 | if (!HELPER_ReadMemory((PBYTE)v, (PBYTE)&v2, sizeof(DWORD))) { 143 | PFATAL(_T("Can't read memory\n")); 144 | } 145 | return v2; 146 | } 147 | 148 | void setup_shmem() { 149 | HANDLE map_file; 150 | 151 | map_file = OpenFileMapping( 152 | FILE_MAP_ALL_ACCESS, // read/write access 153 | FALSE, // do not inherit the name 154 | _tgetenv(SHM_ENV_VAR)); // name of mapping object 155 | 156 | if (map_file == NULL) PFATAL(_T("Error accesing shared memory")); 157 | 158 | shared_mem = (PUCHAR)MapViewOfFile(map_file, // handle to map object 159 | FILE_MAP_ALL_ACCESS, // read/write permission 160 | 0, 161 | 0, 162 | MAP_SIZE); 163 | 164 | if (shared_mem == NULL) PFATAL(_T("Error accesing shared memory")); 165 | LOG(_T("shared_mem @ %p\n"), shared_mem); 166 | } 167 | 168 | void setup_pipe() { 169 | pipe = CreateFile( 170 | _tgetenv(PIPE_ENV_VAR), // pipe name 171 | GENERIC_READ | // read and write access 172 | GENERIC_WRITE, 173 | 0, // no sharing 174 | NULL, // default security attributes 175 | OPEN_EXISTING, // opens existing pipe 176 | 0, // default attributes 177 | NULL); // no template file 178 | 179 | if (pipe == INVALID_HANDLE_VALUE) PFATAL(_T("Error connecting to pipe")); 180 | } 181 | 182 | void PRE() { 183 | 184 | if (!_tgetenv(SHM_ENV_VAR)) return; 185 | 186 | CHAR command = 0; 187 | DWORD num_read; 188 | 189 | ReadFile(pipe, &command, 1, &num_read, NULL); // blocking 190 | if (command != 'R') { 191 | PFATAL(_T("Wrong command @ PRE()")); 192 | } 193 | 194 | BYTE buf[MAP_SIZE + PAGE_SIZE] = { 0 }; 195 | memcpy(buf + MAP_SIZE + 0x10, &PID, sizeof(DWORD)); 196 | 197 | if (CALLBACK_ADDR) { 198 | memcpy(buf + MAP_SIZE + 0x20, &CALLBACK_ADDR, sizeof(DWORD)); 199 | } 200 | if (_tgetenv(_T("DUMP_TRACE"))) HELPER_ResetBuffer(); 201 | 202 | memcpy(COV_ADDR, buf, sizeof(buf)); 203 | } 204 | 205 | void dump_trace_buffer() { 206 | DWORD tbl_idx = get_helper_value("tbl_idx"); 207 | printf("number of basic block = %d\n", tbl_idx); 208 | if (!tbl_idx) return; 209 | 210 | PBYTE base = (PBYTE)get_driver_address(getenv("AFL_TARGET"), NULL); 211 | PBYTE tbl = (PBYTE)get_helper_value("tbl"); 212 | PULONG p = (PULONG)malloc(tbl_idx*sizeof(PULONG)); 213 | if (!HELPER_ReadMemory(tbl, (PBYTE)p, tbl_idx*sizeof(PULONG))) { 214 | PFATAL(_T("Can't read memory\n")); 215 | } 216 | 217 | // convert the address with mapping.txt 218 | PCHAR out_file = "trace.txt"; 219 | _unlink(out_file); 220 | DWORD fd = _open(out_file, O_WRONLY | O_CREAT | O_EXCL, 0600); 221 | if (fd < 0) PFATAL(_T("Unable to create trace file")); 222 | 223 | FILE* f = _fdopen(fd, "w"); 224 | for (DWORD i = 0; i < tbl_idx; i++) { 225 | fprintf(f, "%x\n", (PBYTE)p[i] - (PBYTE)base); 226 | } 227 | fclose(f); 228 | 229 | printf("trace.txt is created\n"); 230 | } 231 | 232 | void POST() { 233 | 234 | if (!_tgetenv(SHM_ENV_VAR)) return; 235 | 236 | memcpy(shared_mem, COV_ADDR, MAP_SIZE); 237 | MEM_BARRIER(); 238 | 239 | if (_tgetenv(_T("DUMP_TRACE"))) dump_trace_buffer(); 240 | 241 | DWORD num_written; 242 | if (PERSISTENT_COUNT) { 243 | WriteFile(pipe, "K", 1, &num_written, NULL); 244 | } 245 | else { 246 | WriteFile(pipe, "Q", 1, &num_written, NULL); 247 | } 248 | 249 | } 250 | 251 | void CRASH() { 252 | // PASS 253 | } 254 | 255 | void INIT() { 256 | 257 | target = _tgetenv(_T("AFL_TARGET")); 258 | if (!target) { 259 | PFATAL(_T("Can not getenv AFL_TARGET\n")); 260 | } 261 | 262 | if (_tgetenv(SHM_ENV_VAR)) { 263 | setup_shmem(); 264 | setup_pipe(); 265 | PERSISTENT_COUNT = 10000; 266 | 267 | hHelper = CreateFile(DRIVER_NAME, MAXIMUM_ALLOWED, 0, NULL, OPEN_EXISTING, 0, NULL); 268 | if (hHelper == INVALID_HANDLE_VALUE) { 269 | PFATAL(_T("Can't create helper driver\n")); 270 | } 271 | 272 | LOG(_T("GetModuleSectionAddress(%s)\n"), target); 273 | KCOV_ADDR = (PUCHAR)HELPER_GetModuleSectionAddress(target); 274 | LOG(_T("Kernel coverage map @ 0x%X\n"), KCOV_ADDR); 275 | if (!KCOV_ADDR) { 276 | PFATAL(_T("Can't get section address\n")); 277 | } 278 | 279 | CALLBACK_ADDR = get_driver_address("helper.sys", "_callback@0"); 280 | PID = _getpid(); 281 | 282 | HELPER_MapMemory(KCOV_ADDR, MAP_SIZE + PAGE_SIZE, (PBYTE*)&COV_ADDR, (PBYTE*)&MDL_ADDR); 283 | LOG(_T("User coverage map @ %p\n"), COV_ADDR); 284 | LOG(_T("MDL @ %p\n"), MDL_ADDR); 285 | 286 | } 287 | else { 288 | PERSISTENT_COUNT = 1; 289 | } 290 | 291 | } 292 | 293 | void FINI() 294 | { 295 | if (COV_ADDR && MDL_ADDR) { 296 | HELPER_UnmapMemory(COV_ADDR, MDL_ADDR); 297 | } 298 | } -------------------------------------------------------------------------------- /AFL/test_clfs/test_clfs.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {5C84D611-9747-4AC3-B5EF-B9768DB57705} 15 | test_clfs 16 | 17 | 18 | 19 | Application 20 | true 21 | v120 22 | Unicode 23 | 24 | 25 | Application 26 | false 27 | v120 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Level3 45 | Disabled 46 | true 47 | 48 | 49 | true 50 | Ktmw32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | true 60 | 61 | 62 | true 63 | true 64 | true 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /AFL/test_clfs/test_clfs.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /AFL/test_gdiplus/header.h: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS 2 | #include 3 | #include 4 | #include 5 | 6 | #define PFATAL_GLE(msg) { printf("%s, GLE=%d\n", msg, GetLastError()); exit(1); } 7 | #define PFATAL(msg) { printf("%s\n", msg); exit(1); } 8 | 9 | void INIT(); 10 | void PRE(); 11 | void POST(); 12 | extern DWORD PERSISTENT_COUNT; 13 | 14 | static void LOG(LPCSTR lpFormat, ...) 15 | { 16 | CHAR buf[1024]; 17 | va_list va; 18 | 19 | va_start(va, lpFormat); 20 | StringCbVPrintfA(buf, sizeof(buf), lpFormat, va); 21 | OutputDebugStringA(buf); 22 | } 23 | -------------------------------------------------------------------------------- /AFL/test_gdiplus/main.cpp: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | #include 3 | 4 | using namespace Gdiplus; 5 | #pragma comment( lib, "gdiplus.lib" ) 6 | 7 | wchar_t* charToWChar(const char* text) { 8 | size_t size = strlen(text) + 1; 9 | wchar_t* wa = new wchar_t[size]; 10 | mbstowcs(wa, text, size); 11 | return wa; 12 | } 13 | 14 | void process_bmp(wchar_t *wcstring) { 15 | GdiplusStartupInput gdiplusStartupInput; 16 | ULONG_PTR gdiplusToken; 17 | GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); 18 | 19 | Image *image = NULL, *thumbnail = NULL; 20 | 21 | image = new Image(wcstring); 22 | if (image && (Ok == image->GetLastStatus())) { 23 | } 24 | //printf("Done\n"); 25 | 26 | if (image) delete image; 27 | if (thumbnail) delete thumbnail; 28 | 29 | GdiplusShutdown(gdiplusToken); 30 | } 31 | 32 | void process_emf(wchar_t *wcstring) { 33 | 34 | GdiplusStartupInput gdiplusStartupInput; 35 | ULONG_PTR gdiplusToken; 36 | GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); 37 | 38 | Bitmap* image = new Bitmap(wcstring); 39 | unsigned int wMax = image->GetWidth(); 40 | unsigned int hMax = image->GetHeight(); 41 | printf("The width of the image is %u.\n", wMax); 42 | printf("The height of the image is %u.\n", hMax); 43 | 44 | PixelFormat pixelFormat1 = image->GetPixelFormat(); 45 | printf("The pixel format of the image is %u.\n", pixelFormat1); 46 | 47 | Color pixelColor; 48 | image->GetPixel(0, 0, &pixelColor); 49 | printf("Pixel (%u, %u) is color %x.\n", 0, 0, pixelColor.GetValue()); // ARGB value 50 | 51 | delete image; 52 | GdiplusShutdown(gdiplusToken); 53 | } 54 | 55 | INT main(INT argc, CHAR* argv[]) 56 | { 57 | INIT(); 58 | 59 | if (argc != 2) PFATAL("test_gdiplus.exe [.emf|.bmp]"); 60 | 61 | wchar_t * wcstring = charToWChar(argv[1]); 62 | 63 | 64 | while (PERSISTENT_COUNT--) { 65 | PRE(); 66 | process_bmp(wcstring); 67 | POST(); 68 | } 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /AFL/test_gdiplus/persistent.cpp: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | #include 3 | 4 | #define SHM_ENV_VAR "__AFL_SHM_ID" 5 | #define PIPE_ENV_VAR "__AFL_PIPE_ID" 6 | #define MAP_SIZE 0x10000 7 | #define PAGE_SIZE 0x1000 8 | #define MEM_BARRIER() _ReadWriteBarrier(); MemoryBarrier() 9 | 10 | PCHAR target; 11 | PCHAR target_addr; 12 | PCHAR afl_area; 13 | HANDLE pipe; 14 | DWORD PERSISTENT_COUNT; 15 | 16 | PCHAR get_section_addr(PCHAR target, PCHAR section) { 17 | ULONG i = 0; 18 | HMODULE ptrBaseAddr = GetModuleHandleA(target); 19 | if (!ptrBaseAddr) return NULL; 20 | 21 | if ((((PUCHAR)ptrBaseAddr)[0] == 'M') && (((PUCHAR)ptrBaseAddr)[1] == 'Z')) { 22 | IMAGE_DOS_HEADER *pDosHeader = (IMAGE_DOS_HEADER*)ptrBaseAddr; 23 | IMAGE_NT_HEADERS *pImageNTHeader = (IMAGE_NT_HEADERS*)((PUCHAR)ptrBaseAddr + pDosHeader->e_lfanew); 24 | IMAGE_FILE_HEADER *pFileheader = &pImageNTHeader->FileHeader; 25 | IMAGE_OPTIONAL_HEADER *pImageOptionalHeader = &pImageNTHeader->OptionalHeader; 26 | IMAGE_SECTION_HEADER *sectionHeader = (IMAGE_SECTION_HEADER*)((PUCHAR)pImageOptionalHeader + pFileheader->SizeOfOptionalHeader); 27 | for (i = 0; iNumberOfSections; i++) { 28 | if (!strcmp((PCHAR)sectionHeader->Name, section)) { 29 | return (PCHAR)ptrBaseAddr + sectionHeader->VirtualAddress; 30 | } 31 | sectionHeader++; 32 | } 33 | } 34 | return NULL; 35 | } 36 | 37 | void setup_shmem() { 38 | HANDLE map_file; 39 | 40 | map_file = OpenFileMapping( 41 | FILE_MAP_ALL_ACCESS, // read/write access 42 | FALSE, // do not inherit the name 43 | getenv(SHM_ENV_VAR)); // name of mapping object 44 | 45 | if (map_file == NULL) PFATAL("Error accesing shared memory"); 46 | 47 | afl_area = (PCHAR)MapViewOfFile(map_file, // handle to map object 48 | FILE_MAP_ALL_ACCESS, // read/write permission 49 | 0, 50 | 0, 51 | MAP_SIZE); 52 | 53 | if (afl_area == NULL) PFATAL("Error accesing shared memory"); 54 | } 55 | 56 | void setup_pipe() { 57 | pipe = CreateFile( 58 | getenv(PIPE_ENV_VAR), // pipe name 59 | GENERIC_READ | // read and write access 60 | GENERIC_WRITE, 61 | 0, // no sharing 62 | NULL, // default security attributes 63 | OPEN_EXISTING, // opens existing pipe 64 | 0, // default attributes 65 | NULL); // no template file 66 | 67 | if (pipe == INVALID_HANDLE_VALUE) PFATAL("Error connecting to pipe"); 68 | } 69 | 70 | void PRE() { 71 | if (!getenv(SHM_ENV_VAR)) return; 72 | 73 | char command = 0; 74 | DWORD num_read; 75 | char buf[256]; 76 | 77 | ReadFile(pipe, &command, 1, &num_read, NULL); // blocking 78 | if (command != 'R') { 79 | sprintf(buf, "Wrong command, %hd", command); 80 | PFATAL(buf); 81 | } 82 | 83 | if (!target_addr) { 84 | target_addr = get_section_addr(target, ".cov"); 85 | } 86 | if (target_addr) { 87 | memset(target_addr, 0, MAP_SIZE + PAGE_SIZE); // clear afl_prev_loc 88 | } 89 | else { 90 | PFATAL("Can not get .cov section"); 91 | } 92 | } 93 | 94 | void POST() { 95 | if (!getenv(SHM_ENV_VAR)) return; 96 | 97 | if (target_addr) { 98 | memcpy(afl_area, target_addr, MAP_SIZE); 99 | MEM_BARRIER(); 100 | } 101 | else { 102 | PFATAL("Can not get .cov section"); 103 | } 104 | 105 | DWORD num_written; 106 | if (PERSISTENT_COUNT) { 107 | WriteFile(pipe, "K", 1, &num_written, NULL); 108 | } 109 | else { 110 | WriteFile(pipe, "Q", 1, &num_written, NULL); 111 | } 112 | } 113 | 114 | void CRASH() { 115 | if (!getenv(SHM_ENV_VAR)) return; 116 | 117 | if (target_addr) { 118 | memcpy(afl_area, target_addr, MAP_SIZE); 119 | MEM_BARRIER(); 120 | } 121 | else { 122 | PFATAL("Can not get .cov section"); 123 | } 124 | 125 | DWORD num_written; 126 | WriteFile(pipe, "C", 1, &num_written, NULL); 127 | } 128 | 129 | LONG WINAPI log_exception(LPEXCEPTION_POINTERS exceptionInfo) 130 | { 131 | 132 | // Send crash signal and update .cov 133 | CRASH(); 134 | 135 | printf("-----EXCEPTION CAUGHT-----\n"); 136 | printf("Exception Code: %#.8x\n", exceptionInfo->ExceptionRecord->ExceptionCode); 137 | printf("Exception Address: %#.8x\n", exceptionInfo->ExceptionRecord->ExceptionAddress); 138 | 139 | ExitProcess(0x1337); 140 | // Never return 141 | 142 | return EXCEPTION_EXECUTE_HANDLER; 143 | } 144 | 145 | void INIT() { 146 | target = getenv("AFL_TARGET"); 147 | if (!target) { 148 | PFATAL("Can not getenv AFL_TARGET\n"); 149 | } 150 | 151 | if (getenv(SHM_ENV_VAR)) { 152 | setup_shmem(); 153 | setup_pipe(); 154 | PERSISTENT_COUNT = 10000; 155 | } 156 | else { 157 | PERSISTENT_COUNT = 1; 158 | } 159 | 160 | SetUnhandledExceptionFilter(log_exception); 161 | } -------------------------------------------------------------------------------- /AFL/test_gdiplus/test_gdiplus.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {8FCF4178-75A9-4EFC-990D-D919308D9987} 15 | test_gdiplus 16 | 17 | 18 | 19 | Application 20 | true 21 | v120 22 | MultiByte 23 | 24 | 25 | Application 26 | false 27 | v120 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Level3 45 | Disabled 46 | true 47 | 48 | 49 | true 50 | 51 | 52 | 53 | 54 | 55 | 56 | Level3 57 | MaxSpeed 58 | true 59 | true 60 | true 61 | 62 | 63 | true 64 | true 65 | true 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /AFL/test_gdiplus/test_gdiplus.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /AFL/test_hive/header.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_H__ 2 | #define __MAIN_H__ 3 | 4 | #define _CRT_SECURE_NO_WARNINGS 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "helper.h" 11 | 12 | #define PFATAL_GLE(msg) { _tprintf(_T("%s, GLE=%d\n"), msg, GetLastError()); exit(1); } 13 | #define PFATAL(msg) { _tprintf(_T("%s\n"), msg); exit(1); } 14 | 15 | void INIT(); 16 | void PRE(); 17 | void POST(); 18 | void FINI(); 19 | extern DWORD PERSISTENT_COUNT; 20 | extern HANDLE hHelper; 21 | DWORD HELPER_GetModuleSectionAddress(PTCHAR pBuffer); 22 | DWORD HELPER_ReadMemory(PBYTE dwAddr, PBYTE pRetBuffer, DWORD dwLen); 23 | DWORD HELPER_WriteMemory(PBYTE dwAddr, PBYTE pRetBuffer, DWORD dwLen); 24 | DWORD HELPER_AllocateMemory(DWORD dwPoolType, DWORD dwTag, DWORD dwLen); 25 | DWORD HELPER_FreeMemory(PBYTE dwAddr, DWORD dwTag); 26 | DWORD HELPER_MapMemory(PBYTE dwAddr, DWORD dwLen, PBYTE* ptrUserAddr, PBYTE* ptrMdl); 27 | DWORD HELPER_UnmapMemory(PBYTE ptrUserAddr, PBYTE ptrMdl); 28 | DWORD HELPER_ResetBuffer(); 29 | 30 | static void LOG(TCHAR *fmt, ...) 31 | { 32 | TCHAR szBuf[MAX_PATH] = { 0 }; 33 | 34 | va_list ap; 35 | va_start(ap, fmt); 36 | _vstprintf_s(szBuf, fmt, ap); 37 | va_end(ap); 38 | OutputDebugString(szBuf); 39 | 40 | //_tprintf(L"%s", szBuf); 41 | } 42 | 43 | static void hexDump(char *desc, void *addr, int len) { 44 | int i; 45 | unsigned char buff[17]; 46 | unsigned char *pc = (unsigned char*)addr; 47 | 48 | // Output description if given. 49 | if (desc != NULL) 50 | printf("%s:\n", desc); 51 | 52 | if (len == 0) { 53 | printf(" ZERO LENGTH\n"); 54 | return; 55 | } 56 | if (len < 0) { 57 | printf(" NEGATIVE LENGTH: %i\n", len); 58 | return; 59 | } 60 | 61 | // Process every byte in the data. 62 | for (i = 0; i < len; i++) { 63 | // Multiple of 16 means new line (with line offset). 64 | 65 | if ((i % 16) == 0) { 66 | // Just don't print ASCII for the zeroth line. 67 | if (i != 0) 68 | printf(" %s\n", buff); 69 | 70 | // Output the offset. 71 | printf(" %04x ", i); 72 | } 73 | 74 | // Now the hex code for the specific character. 75 | printf(" %02x", pc[i]); 76 | 77 | // And store a printable ASCII character for later. 78 | if ((pc[i] < 0x20) || (pc[i] > 0x7e)) 79 | buff[i % 16] = '.'; 80 | else 81 | buff[i % 16] = pc[i]; 82 | buff[(i % 16) + 1] = '\0'; 83 | } 84 | 85 | // Pad out last line if not exactly 16 characters. 86 | while ((i % 16) != 0) { 87 | printf(" "); 88 | i++; 89 | } 90 | 91 | // And print the final ASCII bit. 92 | printf(" %s\n", buff); 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /AFL/test_hive/helper.h: -------------------------------------------------------------------------------- 1 | #ifndef __HELPER_DRIVER_H__ 2 | #define __HELPER_DRIVER_H__ 3 | 4 | #define IOCTL_HELPER_GET_SECTION_ADDRESS CTL_CODE(FILE_DEVICE_UNKNOWN, 801, METHOD_BUFFERED, FILE_ANY_ACCESS) 5 | #define IOCTL_HELPER_READ_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 802, METHOD_BUFFERED, FILE_ANY_ACCESS) 6 | #define IOCTL_HELPER_WRITE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 803, METHOD_BUFFERED, FILE_ANY_ACCESS) 7 | #define IOCTL_HELPER_ALLOCATE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 804, METHOD_BUFFERED, FILE_ANY_ACCESS) 8 | #define IOCTL_HELPER_FREE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 805, METHOD_BUFFERED, FILE_ANY_ACCESS) 9 | #define IOCTL_HELPER_MAP_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 806, METHOD_BUFFERED, FILE_ANY_ACCESS) 10 | #define IOCTL_HELPER_UNMAP_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 807, METHOD_BUFFERED, FILE_ANY_ACCESS) 11 | #define IOCTL_HELPER_DUMP_AND_RESET_CALLBACK CTL_CODE(FILE_DEVICE_UNKNOWN, 808, METHOD_BUFFERED, FILE_ANY_ACCESS) 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /AFL/test_hive/interface.cpp: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | 3 | DWORD HELPER_GetModuleSectionAddress(PTCHAR pBuffer) 4 | { 5 | DWORD dwRet = 0, dwOutLen = 0, dwInLen = 0; 6 | DWORD dwData = 0; 7 | BOOLEAN bRet = 0; 8 | 9 | dwInLen = (DWORD)_tcsclen(pBuffer) + 1; 10 | dwInLen *= 2; 11 | dwOutLen = sizeof(DWORD); 12 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_GET_SECTION_ADDRESS, pBuffer, dwInLen, &dwData, dwOutLen, &dwRet, NULL); 13 | if (!bRet) { 14 | LOG(_T("HELPER_GetModuleSectionAddress(%s) failed, GLE(%x)\n"), pBuffer, GetLastError()); 15 | } 16 | return dwData; 17 | } 18 | 19 | DWORD HELPER_ReadMemory(PBYTE dwAddr, PBYTE pRetBuffer, DWORD dwLen) 20 | { 21 | DWORD dwRet = 0; 22 | BOOLEAN bRet = 0; 23 | 24 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_READ_MEMORY, &dwAddr, dwLen, pRetBuffer, dwLen, &dwRet, NULL); 25 | if (!bRet) { 26 | LOG(_T("HELPER_ReadMemory(%p, %p, %x) failed, GLE(%x)\n"), dwAddr, pRetBuffer, dwLen, GetLastError()); 27 | } 28 | return dwRet; 29 | } 30 | 31 | DWORD HELPER_WriteMemory(PBYTE dwAddr, PBYTE pRetBuffer, DWORD dwLen) 32 | { 33 | DWORD dwRet = 0; 34 | BOOLEAN bRet = 0; 35 | 36 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_WRITE_MEMORY, &dwAddr, dwLen, pRetBuffer, dwLen, &dwRet, NULL); 37 | if (!bRet) { 38 | LOG(_T("HELPER_WriteMemory(%p, %p, %x) failed, GLE(%x)\n"), dwAddr, pRetBuffer, dwLen, GetLastError()); 39 | } 40 | return dwRet; 41 | } 42 | 43 | DWORD HELPER_AllocateMemory(DWORD dwPoolType, DWORD dwLen, DWORD dwTag) 44 | { 45 | DWORD dwRet = 0; 46 | BOOLEAN bRet = 0; 47 | DWORD dwData = 0; 48 | 49 | DWORD in[] = { dwPoolType, dwLen, dwTag }; 50 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_ALLOCATE_MEMORY, in, sizeof(in), &dwData, sizeof(&dwData), &dwRet, NULL); 51 | if (!bRet) { 52 | LOG(_T("HELPER_AllocateMemory(%x, %x, 0x%x) failed, GLE(%x)\n"), dwPoolType, dwLen, dwTag, GetLastError()); 53 | } 54 | return dwData; 55 | } 56 | 57 | DWORD HELPER_FreeMemory(PBYTE dwAddr, DWORD dwTag) 58 | { 59 | DWORD dwRet = 0; 60 | BOOLEAN bRet = 0; 61 | 62 | DWORD in[] = { (DWORD)dwAddr, dwTag }; 63 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_FREE_MEMORY, in, sizeof(in), NULL, NULL, &dwRet, NULL); 64 | if (!bRet) { 65 | LOG(_T("HELPER_FreeMemory(%p, %x) failed, GLE(%x)\n"), dwAddr, dwTag, GetLastError()); 66 | } 67 | return dwRet; 68 | } 69 | 70 | DWORD HELPER_MapMemory(PBYTE dwAddr, DWORD dwLen, PBYTE *ptrUserAddr, PBYTE *ptrMdl) 71 | { 72 | DWORD dwRet = 0; 73 | BOOLEAN bRet = 0; 74 | 75 | DWORD in[] = { (DWORD)dwAddr, dwLen }; 76 | DWORD out[2] = { 0 }; 77 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_MAP_MEMORY, in, sizeof(in), out, sizeof(out), &dwRet, NULL); 78 | if (!bRet) { 79 | LOG(_T("HELPER_MapMemory(%p, %x, %p, %p) failed, GLE(%x)\n"), dwAddr, dwLen, ptrUserAddr, ptrMdl); 80 | } 81 | *ptrUserAddr = (PBYTE)out[0]; 82 | *ptrMdl = (PBYTE)out[1]; 83 | return dwRet; 84 | } 85 | 86 | DWORD HELPER_UnmapMemory(PBYTE ptrUserAddr, PBYTE ptrMdl) 87 | { 88 | DWORD dwRet = 0; 89 | BOOLEAN bRet = 0; 90 | 91 | DWORD in[] = { (DWORD)ptrUserAddr, (DWORD)ptrMdl }; 92 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_UNMAP_MEMORY, in, sizeof(in), NULL, NULL, &dwRet, NULL); 93 | if (!bRet) { 94 | LOG(_T("HELPER_UnmapMemory(%p, %p) failed, GLE(%x)\n"), ptrUserAddr, ptrMdl); 95 | } 96 | return dwRet; 97 | } 98 | 99 | DWORD HELPER_ResetBuffer() 100 | { 101 | DWORD dwRet = 0; 102 | BOOLEAN bRet = 0; 103 | 104 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_DUMP_AND_RESET_CALLBACK, NULL, NULL, NULL, NULL, &dwRet, NULL); 105 | if (!bRet) { 106 | LOG(_T("HELPER_ResetBuffer() failed, GLE(%x)\n"), GetLastError()); 107 | } 108 | return dwRet; 109 | } -------------------------------------------------------------------------------- /AFL/test_hive/main.cpp: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | 3 | void process(LPTSTR name) { 4 | HKEY hKey; 5 | DWORD rc = RegLoadAppKey(name, &hKey, KEY_ALL_ACCESS, 0, 0); 6 | if (rc) { 7 | LOG(_T("Unable to load the hive with RegLoadAppKey(), rc = %d\n"), rc); 8 | _tprintf(_T("Unable to load the hive with RegLoadAppKey(), rc = %d\n"), rc); 9 | } 10 | else { 11 | RegCloseKey(hKey); 12 | LOG(_T("Done\n")); 13 | _tprintf(_T("Done\n")); 14 | } 15 | } 16 | 17 | INT _tmain(INT argc, TCHAR* argv[]) { 18 | 19 | #ifndef UNICODE 20 | LOG(_T("Have to compile with unicode\n")); 21 | return 0; 22 | #endif 23 | 24 | INIT(); 25 | 26 | if (argc != 2) PFATAL(_T("test_hive.exe [.hiv]")); 27 | 28 | while (PERSISTENT_COUNT--) { 29 | PRE(); 30 | process(argv[1]); 31 | POST(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /AFL/test_hive/test_hive.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {32F994A5-D6F7-4E61-A0AB-DDDAD4A20E84} 15 | test_hive 16 | 17 | 18 | 19 | Application 20 | true 21 | v120 22 | Unicode 23 | 24 | 25 | Application 26 | false 27 | v120 28 | true 29 | Unicode 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Level3 45 | Disabled 46 | true 47 | 48 | 49 | true 50 | 51 | 52 | 53 | 54 | Level3 55 | MaxSpeed 56 | true 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /AFL/test_hive/test_hive.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /AFL/test_ioctl/header.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_H__ 2 | #define __MAIN_H__ 3 | 4 | #define _CRT_SECURE_NO_WARNINGS 5 | #include // winsock2 MUST include before windows 6 | #include 7 | #include 8 | #include 9 | 10 | #include "helper.h" 11 | 12 | #define PFATAL_GLE(msg) { _tprintf(_T("%s, GLE=%d\n"), msg, GetLastError()); exit(1); } 13 | #define PFATAL(msg) { _tprintf(_T("%s\n"), msg); exit(1); } 14 | 15 | void INIT(); 16 | void PRE(); 17 | void POST(); 18 | void FINI(); 19 | extern DWORD PERSISTENT_COUNT; 20 | extern HANDLE hHelper; 21 | DWORD HELPER_GetModuleSectionAddress(PTCHAR pBuffer); 22 | DWORD HELPER_ReadMemory(PBYTE dwAddr, PBYTE pRetBuffer, DWORD dwLen); 23 | DWORD HELPER_WriteMemory(PBYTE dwAddr, PBYTE pRetBuffer, DWORD dwLen); 24 | DWORD HELPER_AllocateMemory(DWORD dwPoolType, DWORD dwTag, DWORD dwLen); 25 | DWORD HELPER_FreeMemory(PBYTE dwAddr, DWORD dwTag); 26 | DWORD HELPER_MapMemory(PBYTE dwAddr, DWORD dwLen, PBYTE* ptrUserAddr, PBYTE* ptrMdl); 27 | DWORD HELPER_UnmapMemory(PBYTE ptrUserAddr, PBYTE ptrMdl); 28 | DWORD HELPER_ResetBuffer(); 29 | 30 | static void LOG(TCHAR *fmt, ...) 31 | { 32 | TCHAR szBuf[MAX_PATH] = { 0 }; 33 | 34 | va_list ap; 35 | va_start(ap, fmt); 36 | _vstprintf_s(szBuf, fmt, ap); 37 | va_end(ap); 38 | OutputDebugString(szBuf); 39 | 40 | //_tprintf(L"%s", szBuf); 41 | } 42 | 43 | static void hexDump(char *desc, void *addr, int len) { 44 | int i; 45 | unsigned char buff[17]; 46 | unsigned char *pc = (unsigned char*)addr; 47 | 48 | // Output description if given. 49 | if (desc != NULL) 50 | printf("%s:\n", desc); 51 | 52 | if (len == 0) { 53 | printf(" ZERO LENGTH\n"); 54 | return; 55 | } 56 | if (len < 0) { 57 | printf(" NEGATIVE LENGTH: %i\n", len); 58 | return; 59 | } 60 | 61 | // Process every byte in the data. 62 | for (i = 0; i < len; i++) { 63 | // Multiple of 16 means new line (with line offset). 64 | 65 | if ((i % 16) == 0) { 66 | // Just don't print ASCII for the zeroth line. 67 | if (i != 0) 68 | printf(" %s\n", buff); 69 | 70 | // Output the offset. 71 | printf(" %04x ", i); 72 | } 73 | 74 | // Now the hex code for the specific character. 75 | printf(" %02x", pc[i]); 76 | 77 | // And store a printable ASCII character for later. 78 | if ((pc[i] < 0x20) || (pc[i] > 0x7e)) 79 | buff[i % 16] = '.'; 80 | else 81 | buff[i % 16] = pc[i]; 82 | buff[(i % 16) + 1] = '\0'; 83 | } 84 | 85 | // Pad out last line if not exactly 16 characters. 86 | while ((i % 16) != 0) { 87 | printf(" "); 88 | i++; 89 | } 90 | 91 | // And print the final ASCII bit. 92 | printf(" %s\n", buff); 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /AFL/test_ioctl/helper.h: -------------------------------------------------------------------------------- 1 | #ifndef __HELPER_DRIVER_H__ 2 | #define __HELPER_DRIVER_H__ 3 | 4 | #define IOCTL_HELPER_GET_SECTION_ADDRESS CTL_CODE(FILE_DEVICE_UNKNOWN, 801, METHOD_BUFFERED, FILE_ANY_ACCESS) 5 | #define IOCTL_HELPER_READ_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 802, METHOD_BUFFERED, FILE_ANY_ACCESS) 6 | #define IOCTL_HELPER_WRITE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 803, METHOD_BUFFERED, FILE_ANY_ACCESS) 7 | #define IOCTL_HELPER_ALLOCATE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 804, METHOD_BUFFERED, FILE_ANY_ACCESS) 8 | #define IOCTL_HELPER_FREE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 805, METHOD_BUFFERED, FILE_ANY_ACCESS) 9 | #define IOCTL_HELPER_MAP_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 806, METHOD_BUFFERED, FILE_ANY_ACCESS) 10 | #define IOCTL_HELPER_UNMAP_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 807, METHOD_BUFFERED, FILE_ANY_ACCESS) 11 | #define IOCTL_HELPER_DUMP_AND_RESET_CALLBACK CTL_CODE(FILE_DEVICE_UNKNOWN, 808, METHOD_BUFFERED, FILE_ANY_ACCESS) 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /AFL/test_ioctl/interface.cpp: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | 3 | DWORD HELPER_GetModuleSectionAddress(PTCHAR pBuffer) 4 | { 5 | DWORD dwRet = 0, dwOutLen = 0, dwInLen = 0; 6 | DWORD dwData = 0; 7 | BOOLEAN bRet = 0; 8 | 9 | dwInLen = (DWORD)_tcsclen(pBuffer) + 1; 10 | dwInLen *= 2; 11 | dwOutLen = sizeof(DWORD); 12 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_GET_SECTION_ADDRESS, pBuffer, dwInLen, &dwData, dwOutLen, &dwRet, NULL); 13 | if (!bRet) { 14 | LOG(_T("HELPER_GetModuleSectionAddress(%s) failed, GLE(%x)\n"), pBuffer, GetLastError()); 15 | } 16 | return dwData; 17 | } 18 | 19 | DWORD HELPER_ReadMemory(PBYTE dwAddr, PBYTE pRetBuffer, DWORD dwLen) 20 | { 21 | DWORD dwRet = 0; 22 | BOOLEAN bRet = 0; 23 | 24 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_READ_MEMORY, &dwAddr, dwLen, pRetBuffer, dwLen, &dwRet, NULL); 25 | if (!bRet) { 26 | LOG(_T("HELPER_ReadMemory(%p, %p, %x) failed, GLE(%x)\n"), dwAddr, pRetBuffer, dwLen, GetLastError()); 27 | } 28 | return dwRet; 29 | } 30 | 31 | DWORD HELPER_WriteMemory(PBYTE dwAddr, PBYTE pRetBuffer, DWORD dwLen) 32 | { 33 | DWORD dwRet = 0; 34 | BOOLEAN bRet = 0; 35 | 36 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_WRITE_MEMORY, &dwAddr, dwLen, pRetBuffer, dwLen, &dwRet, NULL); 37 | if (!bRet) { 38 | LOG(_T("HELPER_WriteMemory(%p, %p, %x) failed, GLE(%x)\n"), dwAddr, pRetBuffer, dwLen, GetLastError()); 39 | } 40 | return dwRet; 41 | } 42 | 43 | DWORD HELPER_AllocateMemory(DWORD dwPoolType, DWORD dwLen, DWORD dwTag) 44 | { 45 | DWORD dwRet = 0; 46 | BOOLEAN bRet = 0; 47 | DWORD dwData = 0; 48 | 49 | DWORD in[] = { dwPoolType, dwLen, dwTag }; 50 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_ALLOCATE_MEMORY, in, sizeof(in), &dwData, sizeof(&dwData), &dwRet, NULL); 51 | if (!bRet) { 52 | LOG(_T("HELPER_AllocateMemory(%x, %x, 0x%x) failed, GLE(%x)\n"), dwPoolType, dwLen, dwTag, GetLastError()); 53 | } 54 | return dwData; 55 | } 56 | 57 | DWORD HELPER_FreeMemory(PBYTE dwAddr, DWORD dwTag) 58 | { 59 | DWORD dwRet = 0; 60 | BOOLEAN bRet = 0; 61 | 62 | DWORD in[] = { (DWORD)dwAddr, dwTag }; 63 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_FREE_MEMORY, in, sizeof(in), NULL, NULL, &dwRet, NULL); 64 | if (!bRet) { 65 | LOG(_T("HELPER_FreeMemory(%p, %x) failed, GLE(%x)\n"), dwAddr, dwTag, GetLastError()); 66 | } 67 | return dwRet; 68 | } 69 | 70 | DWORD HELPER_MapMemory(PBYTE dwAddr, DWORD dwLen, PBYTE *ptrUserAddr, PBYTE *ptrMdl) 71 | { 72 | DWORD dwRet = 0; 73 | BOOLEAN bRet = 0; 74 | 75 | DWORD in[] = { (DWORD)dwAddr, dwLen }; 76 | DWORD out[2] = { 0 }; 77 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_MAP_MEMORY, in, sizeof(in), out, sizeof(out), &dwRet, NULL); 78 | if (!bRet) { 79 | LOG(_T("HELPER_MapMemory(%p, %x, %p, %p) failed, GLE(%x)\n"), dwAddr, dwLen, ptrUserAddr, ptrMdl); 80 | } 81 | *ptrUserAddr = (PBYTE)out[0]; 82 | *ptrMdl = (PBYTE)out[1]; 83 | return dwRet; 84 | } 85 | 86 | DWORD HELPER_UnmapMemory(PBYTE ptrUserAddr, PBYTE ptrMdl) 87 | { 88 | DWORD dwRet = 0; 89 | BOOLEAN bRet = 0; 90 | 91 | DWORD in[] = { (DWORD)ptrUserAddr, (DWORD)ptrMdl }; 92 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_UNMAP_MEMORY, in, sizeof(in), NULL, NULL, &dwRet, NULL); 93 | if (!bRet) { 94 | LOG(_T("HELPER_UnmapMemory(%p, %p) failed, GLE(%x)\n"), ptrUserAddr, ptrMdl); 95 | } 96 | return dwRet; 97 | } 98 | 99 | DWORD HELPER_ResetBuffer() 100 | { 101 | DWORD dwRet = 0; 102 | BOOLEAN bRet = 0; 103 | 104 | bRet = DeviceIoControl(hHelper, IOCTL_HELPER_DUMP_AND_RESET_CALLBACK, NULL, NULL, NULL, NULL, &dwRet, NULL); 105 | if (!bRet) { 106 | LOG(_T("HELPER_ResetBuffer() failed, GLE(%x)\n"), GetLastError()); 107 | } 108 | return dwRet; 109 | } -------------------------------------------------------------------------------- /AFL/test_ioctl/main.cpp: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | 3 | DWORD g_szFile; 4 | HANDLE g_hDev; 5 | 6 | struct _LSA_UNICODE_STRING { 7 | USHORT Length; 8 | USHORT MaximumLength; 9 | const wchar_t* Buffer; 10 | }; 11 | 12 | struct _OBJECT_ATTRIBUTES { 13 | ULONG Length; 14 | HANDLE RootDirectory; 15 | _LSA_UNICODE_STRING* ObjectName; 16 | ULONG Attributes; 17 | PVOID SecurityDescriptor; 18 | PVOID SecurityQualityOfService; 19 | }; 20 | 21 | BOOL analyze_potential_leaks(PVOID buffer, UINT size) { 22 | BOOL result = FALSE; 23 | UINT i; 24 | if (size < 8) { 25 | return FALSE; 26 | } 27 | 28 | for (i = 0; i < size; i += 8) { 29 | if (i > size) 30 | break; 31 | DWORD64 content = ((DWORD64 *)buffer)[i]; 32 | if ((content >= 0xFFFF800000000000 && content <= 0xFFFFFFFFFFFFFFFF) && content != 0xFFFFFFFFFFFFFFFF) { 33 | printf("LEAK? %i: %p\n", i, content); 34 | } 35 | result = TRUE; 36 | } 37 | 38 | return result; 39 | } 40 | 41 | PVOID mapInputFile(TCHAR* filepath) 42 | { 43 | HANDLE hFile, hMap; 44 | PVOID pView = NULL; 45 | 46 | g_szFile = 0; 47 | 48 | // Open file 49 | hFile = CreateFile(filepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 50 | if (hFile != INVALID_HANDLE_VALUE) { 51 | 52 | // Create the file mapping object 53 | hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); 54 | if (hMap) { 55 | pView = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0); 56 | if (pView) { 57 | _tprintf(_T("Successfully mapped view of file %s as input\n"), filepath); 58 | 59 | g_szFile = GetFileSize(hFile, NULL); 60 | if (g_szFile == INVALID_FILE_SIZE) { 61 | _tprintf(_T("Failed to get file size with error %x\n"), GetLastError()); 62 | } 63 | } 64 | else { 65 | _tprintf(_T("Failed to map view of file %s with error %x\n"), filepath, GetLastError()); 66 | } 67 | CloseHandle(hMap); 68 | } 69 | else { 70 | _tprintf(_T("Failed to create file mapping for %s with error %x\n"), filepath, GetLastError()); 71 | } 72 | CloseHandle(hFile); 73 | } 74 | else { 75 | _tprintf(_T("Failed to open file %s with error %#.8x\n"), filepath, GetLastError()); 76 | } 77 | return pView; 78 | } 79 | HANDLE openDev(LPCTSTR deviceName) { 80 | HANDLE hDev; 81 | 82 | if (!_tcsncmp(deviceName, _T("\\\\.\\"), 4)) { 83 | hDev = CreateFile(deviceName, MAXIMUM_ALLOWED, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 84 | if (hDev == INVALID_HANDLE_VALUE) { 85 | _tprintf(_T("Device file %s open failed with GetLastError %#x\n"), deviceName, GetLastError()); 86 | exit(EOF); 87 | } 88 | } 89 | else { 90 | 91 | NTSTATUS 92 | (NTAPI 93 | *ntCreateFile)( 94 | _Out_ PHANDLE FileHandle, 95 | _In_ ACCESS_MASK DesiredAccess, 96 | _In_ _OBJECT_ATTRIBUTES* ObjectAttributes, 97 | _Out_ PVOID IoStatusBlock, 98 | _In_opt_ PLARGE_INTEGER AllocationSize, 99 | _In_ ULONG FileAttributes, 100 | _In_ ULONG ShareAccess, 101 | _In_ ULONG CreateDisposition, 102 | _In_ ULONG CreateOptions, 103 | _In_ PVOID EaBuffer, 104 | _In_ ULONG EaLength 105 | ); 106 | 107 | HMODULE ntdll = GetModuleHandleA("ntdll"); 108 | *(void**)&ntCreateFile = GetProcAddress(ntdll, "NtCreateFile"); 109 | 110 | _LSA_UNICODE_STRING name; 111 | name.Buffer = deviceName; 112 | name.Length = name.MaximumLength = _tcslen(deviceName) * 2; 113 | 114 | _OBJECT_ATTRIBUTES attr; 115 | attr.Length = sizeof(attr); 116 | attr.RootDirectory = 0; 117 | attr.ObjectName = &name; 118 | attr.Attributes = 64; 119 | attr.SecurityDescriptor = 0; 120 | attr.SecurityQualityOfService = 0; 121 | 122 | UINT64 tmp[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 123 | 124 | NTSTATUS ns = ntCreateFile(&hDev, MAXIMUM_ALLOWED, &attr, tmp, 0, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, 0, 0, 0); 125 | if (ns) { 126 | _tprintf(_T("Device file %s open failed with NTSTATUS %#x\n"), deviceName, ns); 127 | exit(EOF); 128 | } 129 | } 130 | 131 | _tprintf(_T("Device file %s opened successfully\n"), deviceName); 132 | return hDev; 133 | } 134 | 135 | DWORD sendIoctl(HANDLE hDev, DWORD iocode, PVOID inbuf, DWORD inlen, PVOID outbuf, DWORD outlen) 136 | { 137 | BOOL bResult, bSent = FALSE, bAddress = FALSE; 138 | LPTSTR errormessage; 139 | DWORD bytesreturned = 0; 140 | DWORD error; 141 | 142 | if (!iocode) return 0; 143 | 144 | if (inbuf) { 145 | _tprintf(_T("Sending ioctl %#.8x\n"), iocode); 146 | bResult = DeviceIoControl(hDev, iocode, inbuf, inlen, outbuf, outlen, &bytesreturned, NULL); 147 | error = bResult ? ERROR_SUCCESS : GetLastError(); 148 | bSent = TRUE; 149 | } 150 | 151 | if (bSent) { 152 | if (error == ERROR_SUCCESS) { 153 | _tprintf(_T("IOCTL completed SUCCESSFULLY, returned %u bytes\n"), bytesreturned); 154 | } 155 | else { 156 | // Verbose error 157 | FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 0, error, 0, (LPTSTR)&errormessage, 4, NULL); 158 | _tprintf(_T("IOCTL FAILED with error %x: %s\n"), error, errormessage); 159 | LocalFree(errormessage); 160 | } 161 | } 162 | 163 | if (bSent) { 164 | //hexDump(NULL, outbuf, bytesreturned); 165 | //analyze_potential_leaks(outbuf, bytesreturned); 166 | } 167 | 168 | return bytesreturned; 169 | } 170 | 171 | void init_device(TCHAR* name) { 172 | g_hDev = openDev(name); 173 | } 174 | 175 | void process(HANDLE hDev, DWORD iocode, PTCHAR input_path) { 176 | TCHAR outbuf[0x10000]; 177 | 178 | PVOID inbuf = mapInputFile(input_path); 179 | 180 | if (g_szFile) { 181 | sendIoctl(hDev, iocode, inbuf, g_szFile, outbuf, g_szFile); 182 | } 183 | UnmapViewOfFile(inbuf); 184 | } 185 | 186 | 187 | 188 | 189 | 190 | INT _tmain(INT argc, TCHAR* argv[]) { 191 | 192 | #ifndef UNICODE 193 | _tprintf(_T("Have to compile with unicode\n")); 194 | return 0; 195 | #endif 196 | 197 | if (argc == 2) { 198 | // Test permission 199 | sendIoctl(openDev(argv[1]), 0, 0, 0, 0, 0); 200 | return 0; 201 | } 202 | 203 | if (argc != 4) { 204 | PFATAL(_T("test_ioctl.exe [device name] [ioctl code] [input buffer]\ntest_ioctl.exe [device name]")); 205 | } 206 | TCHAR *stop; 207 | DWORD ioctl = _tcstoul(argv[2], &stop, 0); 208 | 209 | INIT(); 210 | atexit(FINI); 211 | init_device(argv[1]); 212 | 213 | while (PERSISTENT_COUNT--) { 214 | PRE(); 215 | process(g_hDev, ioctl, argv[3]); 216 | POST(); 217 | } 218 | 219 | } 220 | -------------------------------------------------------------------------------- /AFL/test_ioctl/test_ioctl.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {78704997-9607-45BD-92B3-DE5E7676FCD8} 15 | test_ioctl 16 | 17 | 18 | 19 | Application 20 | true 21 | v120 22 | Unicode 23 | 24 | 25 | Application 26 | false 27 | v120 28 | true 29 | Unicode 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Level3 45 | Disabled 46 | true 47 | 48 | 49 | true 50 | 51 | 52 | 53 | 54 | Level3 55 | MaxSpeed 56 | true 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /AFL/test_ioctl/test_ioctl.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /AFL/test_mdb/header.h: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS 2 | 3 | // VC++ Directory += $(ProgramFiles)\Common Files\System\ado\; 4 | #import "msado15.dll" no_namespace rename("EOF", "EndOfFile") 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define PFATAL_GLE(msg) { _tprintf(_T("%s, GLE=%d\n"), msg, GetLastError()); exit(1); } 12 | #define PFATAL(msg) { _tprintf(_T("%s\n"), msg); exit(1); } 13 | #define PFATAL2_GLE(msg) { printf("%s, GLE=%d\n", msg, GetLastError()); exit(1); } 14 | #define PFATAL2(msg) { printf("%s\n", msg); exit(1); } 15 | 16 | void INIT(); 17 | void PRE(); 18 | void POST(); 19 | extern DWORD PERSISTENT_COUNT; 20 | 21 | static void LOG(LPCSTR lpFormat, ...) 22 | { 23 | CHAR buf[1024]; 24 | va_list va; 25 | 26 | va_start(va, lpFormat); 27 | StringCbVPrintfA(buf, sizeof(buf), lpFormat, va); 28 | OutputDebugStringA(buf); 29 | 30 | _tprintf(_T("%s\n"), buf); 31 | } 32 | -------------------------------------------------------------------------------- /AFL/test_mdb/main.cpp: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | #include 3 | 4 | inline void TESTHR(HRESULT x) { if FAILED(x) _com_issue_error(x); }; 5 | 6 | void PrintProviderError(_ConnectionPtr pConnection) { 7 | // Print Provider Errors from Connection object. 8 | // pErr is a record object in the Connection's Error collection. 9 | ErrorPtr pErr = NULL; 10 | 11 | if ((pConnection->Errors->Count) > 0) { 12 | long nCount = pConnection->Errors->Count; 13 | 14 | // Collection ranges from 0 to nCount -1. 15 | for (long i = 0; i < nCount; i++) { 16 | pErr = pConnection->Errors->GetItem(i); 17 | _tprintf(_T("Error number: %x\t%s\n"), pErr->Number, (LPTSTR)pErr->Description); 18 | } 19 | } 20 | } 21 | 22 | void PrintComError(_com_error &e) { 23 | _bstr_t bstrSource(e.Source()); 24 | _bstr_t bstrDescription(e.Description()); 25 | 26 | // Print Com errors. 27 | _tprintf(_T("Error\n")); 28 | _tprintf(_T("\tCode = %08lx\n"), e.Error()); 29 | _tprintf(_T("\tCode meaning = %s\n"), e.ErrorMessage()); 30 | _tprintf(_T("\tSource = %s\n"), (LPTSTR)bstrSource); 31 | _tprintf(_T("\tDescription = %s\n"), (LPTSTR)bstrDescription); 32 | } 33 | 34 | void JetConnection(TCHAR *db_path) { 35 | HRESULT hr = S_OK; 36 | _ConnectionPtr m_pConnection = NULL; 37 | 38 | CHAR path[MAX_PATH] = { 0 }; 39 | wcstombs(path, db_path, MAX_PATH); 40 | 41 | CHAR data_src[0x1000]; 42 | sprintf(data_src, "Provider='Microsoft.JET.OLEDB.4.0';Data source = %s", path); 43 | 44 | try { 45 | TESTHR(m_pConnection.CreateInstance(__uuidof (Connection))); 46 | m_pConnection->Open(data_src, "", "", NULL); 47 | _tprintf(_T("OK\n")); 48 | } 49 | catch (_com_error &e) { 50 | PrintProviderError(m_pConnection); 51 | PrintComError(e); 52 | _tprintf(_T("NOT OK\n")); 53 | } 54 | 55 | if (m_pConnection) { 56 | if (m_pConnection->State == adStateOpen) m_pConnection->Close(); 57 | } 58 | 59 | } 60 | 61 | void JET_PROCESS(TCHAR *db_path) { 62 | // if (FAILED(::CoInitialize(NULL))) 63 | // return; 64 | 65 | JetConnection(db_path); 66 | 67 | // ::CoUninitialize(); 68 | } 69 | 70 | INT _tmain(INT argc, TCHAR* argv[]) { 71 | 72 | #ifndef UNICODE 73 | _tprintf(_T("Have to compile with unicode, due to RtlCompareUnicodeString in helper.sys\n")); 74 | return 0; 75 | #endif 76 | 77 | INIT(); 78 | 79 | if (argc != 2) PFATAL(_T("test_mdb.exe [.mdb]")); 80 | 81 | TCHAR fullFilename[MAX_PATH]; 82 | if (!GetFullPathName(argv[1], MAX_PATH, fullFilename, nullptr)) { 83 | PFATAL(_T("GetFullPathName failed\n")); 84 | } 85 | if (!PathFileExists(fullFilename)) PFATAL(_T("test_mdb.exe [.mdb]")); 86 | 87 | if (FAILED(::CoInitialize(NULL))) 88 | return EOF; 89 | JetConnection(fullFilename); 90 | 91 | while (PERSISTENT_COUNT--) { 92 | PRE(); 93 | JET_PROCESS(fullFilename); 94 | POST(); 95 | } 96 | 97 | ::CoUninitialize(); 98 | } -------------------------------------------------------------------------------- /AFL/test_mdb/persistence.cpp: -------------------------------------------------------------------------------- 1 | #include "header.h" 2 | #include 3 | 4 | #define SHM_ENV_VAR _T("__AFL_SHM_ID") 5 | #define PIPE_ENV_VAR _T("__AFL_PIPE_ID") 6 | #define MAP_SIZE 0x10000 7 | #define PAGE_SIZE 0x1000 8 | #define MEM_BARRIER() _ReadWriteBarrier(); MemoryBarrier() 9 | //#pragma warning(disable : 4995) 10 | 11 | PCHAR target; 12 | PCHAR cov_addr; 13 | PCHAR afl_area; 14 | HANDLE pipe; 15 | DWORD PERSISTENT_COUNT; 16 | 17 | void get_section(PCHAR target, PCHAR section, PCHAR *addr, PDWORD len) { 18 | ULONG i = 0; 19 | HMODULE ptrBaseAddr = GetModuleHandleA(target); 20 | if (!ptrBaseAddr) return; 21 | 22 | if ((((PUCHAR)ptrBaseAddr)[0] == 'M') && (((PUCHAR)ptrBaseAddr)[1] == 'Z')) { 23 | IMAGE_DOS_HEADER *pDosHeader = (IMAGE_DOS_HEADER*)ptrBaseAddr; 24 | IMAGE_NT_HEADERS *pImageNTHeader = (IMAGE_NT_HEADERS*)((PUCHAR)ptrBaseAddr + pDosHeader->e_lfanew); 25 | IMAGE_FILE_HEADER *pFileheader = &pImageNTHeader->FileHeader; 26 | IMAGE_OPTIONAL_HEADER *pImageOptionalHeader = &pImageNTHeader->OptionalHeader; 27 | IMAGE_SECTION_HEADER *sectionHeader = (IMAGE_SECTION_HEADER*)((PUCHAR)pImageOptionalHeader + pFileheader->SizeOfOptionalHeader); 28 | for (i = 0; iNumberOfSections; i++) { 29 | if (!strcmp((PCHAR)sectionHeader->Name, section)) { 30 | if (addr) *addr = (PCHAR)ptrBaseAddr + sectionHeader->VirtualAddress; 31 | if (len) *len = sectionHeader->Misc.VirtualSize; 32 | return; 33 | } 34 | sectionHeader++; 35 | } 36 | } 37 | } 38 | 39 | void setup_shmem() { 40 | HANDLE map_file; 41 | 42 | map_file = OpenFileMapping( 43 | FILE_MAP_ALL_ACCESS, // read/write access 44 | FALSE, // do not inherit the name 45 | _tgetenv(SHM_ENV_VAR)); // name of mapping object 46 | 47 | if (map_file == NULL) PFATAL2("Error accesing shared memory\n"); 48 | 49 | afl_area = (PCHAR)MapViewOfFile(map_file, // handle to map object 50 | FILE_MAP_ALL_ACCESS, // read/write permission 51 | 0, 52 | 0, 53 | MAP_SIZE); 54 | 55 | if (afl_area == NULL) PFATAL2("Error accesing shared memory\n"); 56 | } 57 | 58 | void setup_pipe() { 59 | pipe = CreateFile( 60 | _tgetenv(PIPE_ENV_VAR), // pipe name 61 | GENERIC_READ | // read and write access 62 | GENERIC_WRITE, 63 | 0, // no sharing 64 | NULL, // default security attributes 65 | OPEN_EXISTING, // opens existing pipe 66 | 0, // default attributes 67 | NULL); // no template file 68 | 69 | if (pipe == INVALID_HANDLE_VALUE) PFATAL2("Error connecting to pipe\n"); 70 | } 71 | 72 | void PRE() { 73 | if (!_tgetenv(SHM_ENV_VAR)) return; 74 | 75 | char command = 0; 76 | DWORD num_read; 77 | char buf[256]; 78 | 79 | ReadFile(pipe, &command, 1, &num_read, NULL); // blocking 80 | if (command != 'R') { 81 | sprintf(buf, "Wrong command, %hd\n", command); 82 | PFATAL2(buf); 83 | } 84 | 85 | if (!cov_addr) { 86 | get_section(target, ".cov", &cov_addr, NULL); 87 | } 88 | if (cov_addr) { 89 | memset(cov_addr, 0, MAP_SIZE + PAGE_SIZE); // clear afl_prev_loc 90 | } 91 | else { 92 | PFATAL2("Can not get .cov section\n"); 93 | } 94 | 95 | } 96 | 97 | void POST() { 98 | if (!_tgetenv(SHM_ENV_VAR)) return; 99 | 100 | if (cov_addr) { 101 | memcpy(afl_area, cov_addr, MAP_SIZE); 102 | MEM_BARRIER(); 103 | } 104 | else { 105 | PFATAL2("Can not get .cov section\n"); 106 | } 107 | 108 | DWORD num_written; 109 | if (PERSISTENT_COUNT) { 110 | WriteFile(pipe, "K", 1, &num_written, NULL); 111 | } 112 | else { 113 | WriteFile(pipe, "Q", 1, &num_written, NULL); 114 | } 115 | } 116 | 117 | void CRASH() { 118 | if (!_tgetenv(SHM_ENV_VAR)) return; 119 | 120 | if (cov_addr) { 121 | memcpy(afl_area, cov_addr, MAP_SIZE); 122 | MEM_BARRIER(); 123 | } 124 | else { 125 | PFATAL2("Can not get .cov section\n"); 126 | } 127 | 128 | DWORD num_written; 129 | WriteFile(pipe, "C", 1, &num_written, NULL); 130 | } 131 | 132 | LONG WINAPI log_exception(LPEXCEPTION_POINTERS exceptionInfo) 133 | { 134 | 135 | // Send crash signal and update .cov 136 | CRASH(); 137 | 138 | printf("-----EXCEPTION CAUGHT-----\n"); 139 | printf("Exception Code: %#.8x\n", exceptionInfo->ExceptionRecord->ExceptionCode); 140 | printf("Exception Address: %#.8x\n", exceptionInfo->ExceptionRecord->ExceptionAddress); 141 | 142 | ExitProcess(0x1337); 143 | // Never return 144 | 145 | return EXCEPTION_EXECUTE_HANDLER; 146 | } 147 | 148 | void INIT() { 149 | target = getenv("AFL_TARGET"); 150 | if (!target) { 151 | PFATAL2("Can not getenv AFL_TARGET\n"); 152 | } 153 | 154 | if (_tgetenv(SHM_ENV_VAR)) { 155 | setup_shmem(); 156 | setup_pipe(); 157 | PERSISTENT_COUNT = 10000; 158 | } 159 | else { 160 | PERSISTENT_COUNT = 1; 161 | } 162 | 163 | SetUnhandledExceptionFilter(log_exception); 164 | } -------------------------------------------------------------------------------- /AFL/test_mdb/test_mdb.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {3F1B52C6-E521-484D-AA9E-FC092F91BBD6} 15 | test_mdb 16 | 17 | 18 | 19 | Application 20 | true 21 | v120 22 | Unicode 23 | 24 | 25 | Application 26 | false 27 | v120 28 | true 29 | MultiByte 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProgramFiles)\Common Files\System\ado\; 43 | 44 | 45 | 46 | Level3 47 | Disabled 48 | true 49 | _UNICODE;UNICODE;%(PreprocessorDefinitions) 50 | 51 | 52 | true 53 | Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 54 | 55 | 56 | 57 | 58 | Level3 59 | MaxSpeed 60 | true 61 | true 62 | true 63 | 64 | 65 | true 66 | true 67 | true 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /AFL/test_mdb/test_mdb.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | pe-afl combines static binary instrumentation on PE binary and WinAFL 2 | 3 | so that it can fuzz on windows user-mode application and kernel-mode driver without source or full symbols or hardware support 4 | 5 | details, benchmark and some kernel-mode case study can be found on [slide](https://www.slideshare.net/wmliang/make-static-instrumentation-great-again-high-performance-fuzzing-for-windows-system) and [video](https://www.youtube.com/watch?v=OipNF8v2His), which is presented on BluehatIL 2019 6 | 7 | it is not so reliable and dirty, but it works and high-performance 8 | 9 | i reported bugs on office,gdiplus,jet,lnk,clfs,cng,hid by using this tool 10 | 11 | the instrumentation part on PE can be reused on many purpose 12 | 13 | ps1. if you feel slow on instrumenting, you can run the script on ubuntu 14 | 15 | ps2. the instrument is based on microsoft binary and the binary compiled by visual studio, so it may fail on non-microsoft compiler 16 | 17 | ## How-to instrument 18 | 19 | **example to instrument 2 NOP on entry point of calc.exe** 20 | 21 | ``` 22 | ida.exe demo\calc.exe 23 | # loading with pdb is more reliable if pdb is available 24 | 25 | File->script file->ida_dump.py 26 | 27 | python instrument.py -i"{0x1012d6c:'9090'}" demo\calc.exe demo\calc.exe.dump.txt 28 | # 0x1012d6c is entry point address, you can instrument from command-line or from __main__ in instrument.py 29 | ``` 30 | 31 | ## How-to fuzz 32 | 33 | you have to implement the wrapper/harness (AFL\test_XXX\) depends on target 34 | 35 | and add anything you want, such page heap, etc 36 | 37 | **instrument JetDB for fuzzing** 38 | 39 | ``` 40 | ida.exe demo\msjet40.dll 41 | 42 | File->script file->ida_dump.py 43 | 44 | python pe-afl.py -m demo\msjet40.dll demo\msjet40.dll.dump.txt 45 | # msjet40 is multi-thread, so -m is here 46 | ``` 47 | 48 | **fuzz JetDB on win7** 49 | 50 | ``` 51 | copy /Y msjet40.instrumented.dll C:\Windows\System32\msjet40.dll 52 | 53 | bin\afl-showmap.exe -o NUL -p msjet40.dll -- bin\test_mdb.exe demo\mdb\normal.mdb 54 | # make sure that capture is OK 55 | 56 | bin\AFL.exe -i demo\mdb -o out -t 5000 -m none -p msjet40.dll -- bin\test_mdb.exe @@ 57 | ``` 58 | 59 | **instrument CLFS for fuzzing** 60 | 61 | ``` 62 | ida.exe demo\clfs.sys 63 | File->script file->ida_dump.py 64 | 65 | python pe-afl.py demo\clfs.sys demo\clfs.sys.dump.txt 66 | ``` 67 | 68 | **fuzz CLFS on win10** 69 | 70 | ``` 71 | install_helper.bat 72 | disable_dse.bat 73 | copy /Y clfs.instrumented.sys C:\Windows\System32\drivers\clfs.sys 74 | # reboot if necessary 75 | 76 | bin\afl-showmap.exe -o NUL -p clfs.sys -- bin\test_clfs.exe demo\blf\normal.blf 77 | # make sure that capture is OK 78 | 79 | bin\AFL.exe -i demo\blf -o out -t 5000 -m none -p clfs.sys -- bin\test_clfs.exe @@ 80 | ``` 81 | 82 | ## How-to trace 83 | 84 | **example to log driver execution trace and import into lighthouse** 85 | 86 | ``` 87 | ida.exe demo\clfs.sys 88 | File->script file->ida_dump.py 89 | 90 | python pe-afl.py -cb demo\clfs.sys demo\clfs.sys.dump.txt 91 | copy /Y clfs.instrumented.sys C:\Windows\System32\drivers\clfs.sys 92 | # reboot if necessary 93 | 94 | bin\afl-showmap.exe -o NUL -p clfs.sys -d -- bin\test_clfs.exe demo\blf\normal.blf 95 | # output is trace.txt 96 | 97 | python lighthouse_trace.py demo\clfs.sys demo\clfs.sys.mapping.txt trace.txt > trace2.txt 98 | 99 | # install lighthouse 100 | xcopy /y /e lighthouse [IDA folder]\plugins\ 101 | 102 | ida.exe demo\clfs.sys 103 | File->Load File->Code coverage file->trace2.txt 104 | ``` 105 | 106 | ## TODO 107 | 108 | support x64 109 | -------------------------------------------------------------------------------- /bin/AFL.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/AFL.exe -------------------------------------------------------------------------------- /bin/afl-showmap.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/afl-showmap.exe -------------------------------------------------------------------------------- /bin/afl-tmin.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/afl-tmin.exe -------------------------------------------------------------------------------- /bin/keystone.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/keystone.dll -------------------------------------------------------------------------------- /bin/kstool.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/kstool.exe -------------------------------------------------------------------------------- /bin/msvcr120d.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/msvcr120d.dll -------------------------------------------------------------------------------- /bin/test_clfs.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/test_clfs.exe -------------------------------------------------------------------------------- /bin/test_gdiplus.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/test_gdiplus.exe -------------------------------------------------------------------------------- /bin/test_hive.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/test_hive.exe -------------------------------------------------------------------------------- /bin/test_ioctl.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/test_ioctl.exe -------------------------------------------------------------------------------- /bin/test_mdb.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/test_mdb.exe -------------------------------------------------------------------------------- /bin/winload.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/winload.exe -------------------------------------------------------------------------------- /bin/winload2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/bin/winload2.exe -------------------------------------------------------------------------------- /clear_stub.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import pefile 3 | import struct 4 | import sys 5 | 6 | p32 = lambda v: struct.pack('') 23 | quit() 24 | go(sys.argv[1]) 25 | -------------------------------------------------------------------------------- /demo/Demo.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | NTSTATUS TriggerDemo(IN PCHAR UserBuffer, IN SIZE_T Size); 4 | NTSTATUS DemoIoctlHandler(IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp); 5 | 6 | #ifdef ALLOC_PRAGMA 7 | #pragma alloc_text(PAGE, TriggerDemo) 8 | #pragma alloc_text(PAGE, DemoIoctlHandler) 9 | #endif // ALLOC_PRAGMA 10 | 11 | #pragma auto_inline(off) 12 | 13 | 14 | NTSTATUS TriggerDemo(IN PCHAR UserBuffer, IN SIZE_T Size) { 15 | //PVOID KernelBuffer = NULL; 16 | //UCHAR KernelBuffer2[10]; 17 | NTSTATUS Status = STATUS_SUCCESS; 18 | 19 | PAGED_CODE(); 20 | 21 | __try { 22 | 23 | // Verify if the buffer resides in user mode 24 | ProbeForRead(UserBuffer, 0x10, (ULONG)__alignof(UCHAR)); 25 | 26 | DbgPrint("[+] UserBuffer: 0x%p\n", UserBuffer); 27 | DbgPrint("[+] UserBuffer Size: 0x%X\n", Size); 28 | 29 | if (UserBuffer[0] == 'B') { 30 | if (UserBuffer[1] == 'L') { 31 | if (UserBuffer[2] == 'U') { 32 | if (UserBuffer[3] == 'E') { 33 | KeBugCheck(0x1337); 34 | if (UserBuffer[4] == 'H') { 35 | if (UserBuffer[5] == 'A') { 36 | if (UserBuffer[6] == 'T') { 37 | DbgPrint("[-] @_wmliang_\n"); 38 | } 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } 45 | 46 | } 47 | __except (EXCEPTION_EXECUTE_HANDLER) { 48 | Status = GetExceptionCode(); 49 | DbgPrint("[-] Exception Code: 0x%X\n", Status); 50 | } 51 | 52 | return Status; 53 | } 54 | 55 | NTSTATUS DemoIoctlHandler(IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp) { 56 | SIZE_T Size = 0; 57 | PVOID UserBuffer = NULL; 58 | NTSTATUS Status = STATUS_UNSUCCESSFUL; 59 | 60 | UNREFERENCED_PARAMETER(Irp); 61 | PAGED_CODE(); 62 | 63 | UserBuffer = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; 64 | Size = IrpSp->Parameters.DeviceIoControl.InputBufferLength; 65 | 66 | if (UserBuffer) { 67 | Status = TriggerDemo(UserBuffer, Size); 68 | } 69 | 70 | return Status; 71 | } 72 | 73 | #pragma auto_inline() 74 | -------------------------------------------------------------------------------- /demo/blf/normal.blf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/demo/blf/normal.blf -------------------------------------------------------------------------------- /demo/calc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/demo/calc.exe -------------------------------------------------------------------------------- /demo/clfs.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/demo/clfs.pdb -------------------------------------------------------------------------------- /demo/clfs.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/demo/clfs.sys -------------------------------------------------------------------------------- /demo/demo.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/demo/demo.sys -------------------------------------------------------------------------------- /demo/mdb/normal.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/demo/mdb/normal.mdb -------------------------------------------------------------------------------- /demo/msjet40.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/demo/msjet40.dll -------------------------------------------------------------------------------- /demo/msjet40.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/demo/msjet40.pdb -------------------------------------------------------------------------------- /disable_dse.bat: -------------------------------------------------------------------------------- 1 | copy bin\winload2.exe C:\Windows\system32\winload2.exe 2 | bcdedit /set recoveryenabled no 3 | bcdedit /set nointegritychecks on 4 | bcdedit /set path \Windows\system32\winload2.exe 5 | 6 | rem it would be better to patch winload yourself, due to different version 7 | -------------------------------------------------------------------------------- /fix_checksum.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import pefile 3 | import sys 4 | 5 | def fix(fname): 6 | pe = pefile.PE(fname) 7 | pe.OPTIONAL_HEADER.CheckSum = pe.generate_checksum() 8 | pe.write(filename=fname) 9 | 10 | if __name__ == '__main__': 11 | if len(sys.argv) != 2: 12 | print('Usage:', sys.argv[0], '') 13 | quit() 14 | fix(sys.argv[1]) 15 | -------------------------------------------------------------------------------- /helper/Release_win10/helper.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/helper/Release_win10/helper.sys -------------------------------------------------------------------------------- /helper/Release_win7/helper.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/helper/Release_win7/helper.sys -------------------------------------------------------------------------------- /helper/helper.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; helper.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=Sample ; TODO: edit Class 8 | ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=helper.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | 13 | [DestinationDirs] 14 | DefaultDestDir = 12 15 | 16 | ; ================= Class section ===================== 17 | 18 | [ClassInstall32] 19 | Addreg=SampleClassReg 20 | 21 | [SampleClassReg] 22 | HKR,,,0,%ClassName% 23 | HKR,,Icon,,-5 24 | 25 | [SourceDisksNames] 26 | 1 = %DiskName%,,,"" 27 | 28 | [SourceDisksFiles] 29 | helper.sys = 1,, 30 | 31 | ;***************************************** 32 | ; Install Section 33 | ;***************************************** 34 | 35 | [Manufacturer] 36 | %ManufacturerName%=Standard,NT$ARCH$ 37 | 38 | [Standard.NT$ARCH$] 39 | %helper.DeviceDesc%=helper_Device, Root\helper ; TODO: edit hw-id 40 | 41 | [helper_Device.NT] 42 | CopyFiles=Drivers_Dir 43 | 44 | [Drivers_Dir] 45 | helper.sys 46 | 47 | ;-------------- Service installation 48 | [helper_Device.NT.Services] 49 | AddService = helper,%SPSVCINST_ASSOCSERVICE%, helper_Service_Inst 50 | 51 | ; -------------- helper driver install sections 52 | [helper_Service_Inst] 53 | DisplayName = %helper.SVCDESC% 54 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 55 | StartType = 3 ; SERVICE_DEMAND_START 56 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 57 | ServiceBinary = %12%\helper.sys 58 | 59 | ; 60 | ;--- helper_Device Coinstaller installation ------ 61 | ; 62 | 63 | [DestinationDirs] 64 | helper_Device_CoInstaller_CopyFiles = 11 65 | 66 | [helper_Device.NT.CoInstallers] 67 | AddReg=helper_Device_CoInstaller_AddReg 68 | CopyFiles=helper_Device_CoInstaller_CopyFiles 69 | 70 | [helper_Device_CoInstaller_AddReg] 71 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 72 | 73 | [helper_Device_CoInstaller_CopyFiles] 74 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 75 | 76 | [SourceDisksFiles] 77 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 78 | 79 | [helper_Device.NT.Wdf] 80 | KmdfService = helper, helper_wdfsect 81 | [helper_wdfsect] 82 | KmdfLibraryVersion = $KMDFVERSION$ 83 | 84 | [Strings] 85 | SPSVCINST_ASSOCSERVICE= 0x00000002 86 | ManufacturerName="" ;TODO: Replace with your manufacturer name 87 | ClassName="Samples" ; TODO: edit ClassName 88 | DiskName = "helper Installation Disk" 89 | helper.DeviceDesc = "helper Device" 90 | helper.SVCDESC = "helper Service" 91 | -------------------------------------------------------------------------------- /helper/helper.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "helper", "helper.vcxproj", "{2B52103C-0BDD-445A-A274-1D91F7139477}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|ARM64 = Debug|ARM64 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|ARM = Release|ARM 15 | Release|ARM64 = Release|ARM64 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Debug|ARM.ActiveCfg = Release|Win32 21 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Debug|ARM.Build.0 = Release|Win32 22 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Debug|ARM.Deploy.0 = Release|Win32 23 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Debug|x64.ActiveCfg = Debug|x64 27 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Debug|x64.Build.0 = Debug|x64 28 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Debug|x64.Deploy.0 = Debug|x64 29 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Debug|x86.ActiveCfg = Release|Win32 30 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Debug|x86.Build.0 = Release|Win32 31 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Debug|x86.Deploy.0 = Release|Win32 32 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Release|ARM.ActiveCfg = Release|ARM 33 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Release|ARM.Build.0 = Release|ARM 34 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Release|ARM.Deploy.0 = Release|ARM 35 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Release|ARM64.Build.0 = Release|ARM64 37 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Release|x64.ActiveCfg = Release|x64 39 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Release|x64.Build.0 = Release|x64 40 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Release|x64.Deploy.0 = Release|x64 41 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Release|x86.ActiveCfg = Release|Win32 42 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Release|x86.Build.0 = Release|Win32 43 | {2B52103C-0BDD-445A-A274-1D91F7139477}.Release|x86.Deploy.0 = Release|Win32 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | EndGlobal 49 | -------------------------------------------------------------------------------- /helper/helper.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | {2B52103C-0BDD-445A-A274-1D91F7139477} 39 | {1bc93793-694f-48fe-9372-81e2b05556fd} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | helper 45 | 46 | 47 | 48 | Windows10 49 | true 50 | WindowsKernelModeDriver10.0 51 | Driver 52 | KMDF 53 | Universal 54 | 1 55 | 9 56 | 57 | 58 | Windows10 59 | false 60 | WindowsKernelModeDriver10.0 61 | Driver 62 | KMDF 63 | Universal 64 | 1 65 | 9 66 | 67 | 68 | Windows10 69 | true 70 | WindowsKernelModeDriver10.0 71 | Driver 72 | KMDF 73 | Universal 74 | 75 | 76 | Windows10 77 | false 78 | WindowsKernelModeDriver10.0 79 | Driver 80 | KMDF 81 | Universal 82 | 83 | 84 | Windows10 85 | true 86 | WindowsKernelModeDriver10.0 87 | Driver 88 | KMDF 89 | Universal 90 | 91 | 92 | Windows10 93 | false 94 | WindowsKernelModeDriver10.0 95 | Driver 96 | KMDF 97 | Universal 98 | 99 | 100 | Windows10 101 | true 102 | WindowsKernelModeDriver10.0 103 | Driver 104 | KMDF 105 | Universal 106 | 107 | 108 | Windows10 109 | false 110 | WindowsKernelModeDriver10.0 111 | Driver 112 | KMDF 113 | Universal 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | DbgengKernelDebugger 125 | true 126 | 127 | 128 | DbgengKernelDebugger 129 | true 130 | 131 | 132 | DbgengKernelDebugger 133 | 134 | 135 | DbgengKernelDebugger 136 | 137 | 138 | DbgengKernelDebugger 139 | 140 | 141 | DbgengKernelDebugger 142 | 143 | 144 | DbgengKernelDebugger 145 | 146 | 147 | DbgengKernelDebugger 148 | 149 | 150 | 151 | true 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /helper/helper.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /helper/main.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_H__ 2 | #define __MAIN_H__ 3 | 4 | #define IOCTL_HELPER_GET_SECTION_ADDRESS CTL_CODE(FILE_DEVICE_UNKNOWN, 801, METHOD_BUFFERED, FILE_ANY_ACCESS) 5 | #define IOCTL_HELPER_READ_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 802, METHOD_BUFFERED, FILE_ANY_ACCESS) 6 | #define IOCTL_HELPER_WRITE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 803, METHOD_BUFFERED, FILE_ANY_ACCESS) 7 | #define IOCTL_HELPER_ALLOCATE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 804, METHOD_BUFFERED, FILE_ANY_ACCESS) 8 | #define IOCTL_HELPER_FREE_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 805, METHOD_BUFFERED, FILE_ANY_ACCESS) 9 | #define IOCTL_HELPER_MAP_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 806, METHOD_BUFFERED, FILE_ANY_ACCESS) 10 | #define IOCTL_HELPER_UNMAP_MEMORY CTL_CODE(FILE_DEVICE_UNKNOWN, 807, METHOD_BUFFERED, FILE_ANY_ACCESS) 11 | #define IOCTL_HELPER_DUMP_AND_RESET_CALLBACK CTL_CODE(FILE_DEVICE_UNKNOWN, 808, METHOD_BUFFERED, FILE_ANY_ACCESS) 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /ida_dumper.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | H = lambda addr: hex(addr).strip('L') 4 | 5 | def parse_relative(ea): 6 | buf = idc.GetManyBytes(ea, ItemSize(ea)) 7 | idx = 0 8 | mpx_candidate = False 9 | 10 | # call (e8), http://x86.renejeschke.de/html/file_module_x86_id_26.html 11 | # jmp (eb/e9), http://x86.renejeschke.de/html/file_module_x86_id_147.html 12 | # jxx (0F 80/0F 81/0F 82/0F 83/0F 84/0F 85/0F 86/0F 87/0F 88/0F 89/0F 8A/0F 8B/0F 8C/0F 8D/0F 8E/0F 8F/70/71/72/73/74/75/76/77/78/79/7A/7B/7C/7D/7E/7F), http://x86.renejeschke.de/html/file_module_x86_id_146.html 13 | # jcxz/jecxz (67 e3/e3) 14 | # loop/loope/loopz/loopne/loopnz (e0/e1/e2), http://x86.renejeschke.de/html/file_module_x86_id_161.html 15 | if ord(buf[idx]) == 0xf2: 16 | idx += 1 17 | mpx_candidate = True 18 | 19 | if ord(buf[idx]) in [0xe0, 0xe1, 0xe2, 0xe3, 0xe8, 0xe9, 0xeb]: 20 | idx += 1 21 | elif ord(buf[idx]) == 0x0f and (ord(buf[idx+1]) >= 0x80 and ord(buf[idx+1]) <= 0x8f): 22 | idx += 2 23 | elif (ord(buf[idx]) >= 0x70 and ord(buf[idx]) <= 0x7f): 24 | idx += 1 25 | elif ord(buf[idx]) == 0x67 and ord(buf[idx+1]) == 0xe3: 26 | idx += 2 27 | 28 | if mpx_candidate and idx == 1: 29 | idx = 0 30 | 31 | if idx: 32 | return buf[0:idx], buf[idx:] 33 | else: 34 | return None, None 35 | 36 | def add_relative(ea): 37 | # need operand length, so parse it manually 38 | op, operand = parse_relative(ea) 39 | if op and operand: 40 | assert len(idc.GetOpnd(ea, 1)) == 0, 'more than 1 operand' 41 | assert len(operand) == 1 or len(operand) == 4, 'operand is not rel32' 42 | relative[ea] = [idc.GetOperandValue(ea,0), op.encode('hex'), len(operand), len(op+operand)] 43 | 44 | possible_data = [] 45 | def add_basic_block(ea): 46 | op = idc.GetMnem(ea) 47 | if not(op in ['call'] or op.startswith('j') or op.startswith('loop')): 48 | return 49 | 50 | # validing branch, ie. jmp near ptr dword_1007F84+1 51 | operand = idc.GetOperandValue(ea,0) 52 | if PrevHead(NextHead(operand)) != operand and idc.GetOpType(ea, 0) in [idc.o_imm, idc.o_far, idc.o_near]: 53 | possible_data.append(H(ea)) 54 | return 55 | 56 | # skip non-conditional branch 57 | if op in ['call', 'jmp']: 58 | return 59 | 60 | # identify as basic block, jxx/loop true/false target 61 | bb.append(idc.NextHead(ea)) 62 | bb.append(operand) 63 | 64 | def set_color(): 65 | for ea in bb: 66 | SetColor(ea, CIC_ITEM, 0x6699ff) 67 | 68 | def check_unicode(ea): 69 | if GetType(ea) in ['const WCHAR', 'WCHAR', 'wchar_t']: 70 | idaapi.make_ascii_string(ea, 0, ASCSTR_UNICODE); Wait(); 71 | if GetStringType(ea) and GetStringType(ea)&0xFF != ASCSTR_UNICODE and Word(ea) != 0: 72 | print '[WARN] Possible unicode @', H(ea) 73 | 74 | def check_guid(ea): 75 | if GetType(ea) in ['CLSID', 'IID']: 76 | print '[INFO] Fixed', GetType(ea), '@', H(ea) 77 | MakeUnknown(ea, 10, DOUNK_SIMPLE); Wait(); 78 | SetType(ea, GetType(ea)) 79 | t = idc.get_cmt(ea, 0).upper()[1:] if idc.get_cmt(ea, 0) else '' 80 | if t in ['CLSID', 'IID']: 81 | l = idc.GetOperandValue(ea, 0) 82 | if idaapi.getseg(l) and idaapi.getseg(l).perm and idaapi.SEGPERM_EXEC and (not GetType(l)): 83 | print '[INFO] Fixed', t, '@', H(l) 84 | MakeUnknown(l, 10, DOUNK_SIMPLE); Wait(); 85 | SetType(l, t) 86 | 87 | def check_stack_frame(ea): 88 | snip = ['mov edi, edi', 89 | 'push ebp', 90 | 'mov ebp, esp', 91 | 'sub esp, '] # TODO: add/and esp 92 | if idc.GetDisasm(ea) != snip[0] or idc.GetDisasm(NextHead(ea)) != snip[1] or idc.GetDisasm(NextHead(NextHead(ea))) != snip[2]: 93 | return 94 | line = idc.GetDisasm(NextHead(NextHead(NextHead(ea)))) 95 | if line.startswith(snip[3]): 96 | stk_frame[ea] = ((NextHead(ea+5)-(ea+5)), int(line.split(',')[-1].strip('h'), 16)) 97 | 98 | possible_code = [] 99 | def check_suspicious_data(segea): 100 | ff = [FindFuncEnd(funcea) for funcea in Functions(segea, SegEnd(segea))] 101 | for i,j in enumerate(ff): 102 | ofs = j 103 | while Byte(ofs) == 0xCC or Byte(ofs) == 0x90: 104 | ofs = ofs + 1 105 | if Word(ofs) == 0xff8b: # mov edi, edi 106 | MakeCode(ofs) 107 | continue 108 | for h in range(ofs, ofs+0x80): 109 | if (isCode(GetFlags(h)) or 110 | (GetStringType(h) != None) or # string 111 | (GetType(h) != None) or # struct 112 | ('offset' in GetDisasm(h) or 'rva' in GetDisasm(h)) or # valid data 113 | ('.' in GetDisasm(h)) or # floating point 114 | (Dword(h) == 0xfffffffe or Dword(h) == 0xFFFFFFE4) or # GSCookieOffset 115 | ((Dword(h) >> 8) == 0) or # integer 116 | ('align' in GetDisasm(h)) # alignment 117 | ): 118 | break 119 | if (Byte(h) in [0xe0, 0xe1, 0xe2, 0xe3, 0xe8, 0xe9, 0xeb] or # search for branch 120 | (0x70 <= Byte(h) <= 0x7f) or 121 | (Byte(h) == 0x67 and Byte(h+1) == 0xe3) or 122 | (Byte(h) == 0x0f and (0x80 <= Byte(h+1) <= 0x8f))): 123 | possible_code.append(H(h)) 124 | break 125 | Wait() 126 | 127 | def add_rip_relative_inst(head): 128 | return 129 | # TODO, 64-bit use rip-relative rather than relocation 130 | 131 | def output_file(): 132 | ida_dump = {'bb': bb, 'relative': relative, 'rip_inst': rip_inst, 'idata': idata, 'stk_frame': stk_frame, 'code_loc': code_loc} 133 | print '[INFO]', str(len(bb)), 'blocks' 134 | print '[INFO]', str(len(relative)), 'branches' 135 | print '[INFO]', idc.GetInputFilePath()+'.dump.txt is created' 136 | with open(idc.GetInputFilePath()+'.dump.txt', 'w+') as f: 137 | f.write(repr(ida_dump)+'\n') 138 | 139 | def partial_exclude(start, end=None): 140 | if end is None: 141 | # clear whole function 142 | start = NextFunction(PrevFunction(start)) 143 | end = FindFuncEnd(start) 144 | for h in Heads(start, end): 145 | if h in bb: 146 | SetColor(h, CIC_ITEM, 0xffffff) 147 | bb.remove(h) 148 | output_file() 149 | 150 | def partial_include(expr): 151 | global bb 152 | func = lambda x: re.search(expr, GetFunctionName(x)) 153 | bbb = filter(func, bb) 154 | for h in list(set(bb)-set(bbb)): 155 | SetColor(h, CIC_ITEM, 0xffffff) 156 | bb = bbb 157 | output_file() 158 | 159 | code_loc = {} 160 | def process(text): 161 | global code_loc 162 | check_suspicious_data(text) 163 | code_start = None 164 | for h in Heads(text, SegEnd(text)): 165 | check_unicode(h) 166 | if isCode(GetFlags(h)): 167 | if not code_start: 168 | code_start = h 169 | check_stack_frame(h) 170 | check_guid(h) 171 | # add_rip_relative_inst(h) 172 | add_basic_block(h) 173 | add_relative(h) 174 | else: 175 | if code_start: 176 | code_loc[code_start] = h 177 | code_start = None 178 | 179 | ################################# 180 | # partial_include() and partial_exclude() provides manual partial instrumentation 181 | # 182 | # partial_include('(_?Cm|_Hv[^il])') 183 | # partial_exclude(ScreenEA()) 184 | # partial_exclude(0x401020, 0x401040) 185 | # 186 | 187 | Wait() 188 | bb = [] 189 | relative = {} 190 | rip_inst = [] 191 | idata = [] 192 | stk_frame = {} 193 | 194 | idata = [[x, SegEnd(x)] for x in Segments() if (idaapi.getseg(x).perm & idaapi.SEGPERM_EXEC) and idc.SegName(x) == '.idata'] 195 | seg = [[x, SegEnd(x)] for x in Segments() if (idaapi.getseg(x).perm & idaapi.SEGPERM_EXEC) and idc.SegName(x) != '.idata'] 196 | for ea,_ in seg: 197 | process(ea) 198 | 199 | bb = sorted(list(set(bb))) 200 | set_color() 201 | 202 | # dump result 203 | if len(possible_code): 204 | print '[WARN]',str(len(possible_code)),'possible code ?', str(possible_code) 205 | if len(possible_data): 206 | print '[WARN]',str(len(possible_data)),'possible data ?', str(possible_data) 207 | if not idaapi.get_inf_structure().is_64bit() and len(rip_inst): 208 | print '[WARN] rip-relative addressing mode on x86 ?' 209 | print '[INFO] re-run this script if you have fixed any [WARN] message manually in IDA' 210 | print '[INFO] partial instrumentation with partial_include() or partial_exclude() if necessary' 211 | output_file() 212 | 213 | -------------------------------------------------------------------------------- /install_helper.bat: -------------------------------------------------------------------------------- 1 | copy helper\Release_win10\helper.sys C:\Windows\system32\drivers\helper.sys 2 | sc create helper binPath= "C:\Windows\system32\drivers\helper.sys" type= "kernel" start= "system" error= "normal" Displayname= "helper" 3 | sc start helper 4 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/lighthouse/lighthouse/__init__.py -------------------------------------------------------------------------------- /lighthouse/lighthouse/binja_integration.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from binaryninja import PluginCommand 4 | from lighthouse.core import Lighthouse 5 | from lighthouse.util.disassembler import disassembler 6 | 7 | logger = logging.getLogger("Lighthouse.Binja.Integration") 8 | 9 | #------------------------------------------------------------------------------ 10 | # Lighthouse Binja Integration 11 | #------------------------------------------------------------------------------ 12 | 13 | class LighthouseBinja(Lighthouse): 14 | """ 15 | Lighthouse UI Integration for Binary Ninja. 16 | """ 17 | 18 | def __init__(self): 19 | super(LighthouseBinja, self).__init__() 20 | 21 | def interactive_load_file(self, bv): 22 | disassembler.bv = bv 23 | super(LighthouseBinja, self).interactive_load_file() 24 | 25 | def interactive_load_batch(self, bv): 26 | disassembler.bv = bv 27 | super(LighthouseBinja, self).interactive_load_batch() 28 | 29 | def interactive_load_batch(self, bv): 30 | disassembler.bv = bv 31 | super(LighthouseBinja, self).open_coverage_overview() 32 | 33 | def _install_load_file(self): 34 | PluginCommand.register( 35 | r"Lighthouse\Load code coverage file...", 36 | "Load individual code coverage file(s)", 37 | self.interactive_load_file 38 | ) 39 | logger.info("Installed the 'Code coverage file' menu entry") 40 | 41 | def _install_load_batch(self): 42 | PluginCommand.register( 43 | r"Lighthouse\Load code coverage batch...", 44 | "Load and aggregate code coverage files", 45 | self.interactive_load_batch 46 | ) 47 | logger.info("Installed the 'Code coverage batch' menu entry") 48 | 49 | def _install_open_coverage_overview(self): 50 | PluginCommand.register( 51 | r"Lighthouse\Coverage Overview", 52 | "Open the database code coverage overview", 53 | self.interactive_load_batch 54 | ) 55 | logger.info("Installed the 'Coverage Overview' menu entry") 56 | 57 | # TODO/V35: No good signals to unload (core) plugin on 58 | def _uninstall_load_file(self): 59 | pass 60 | 61 | def _uninstall_load_batch(self): 62 | pass 63 | 64 | def _uninstall_open_coverage_overview(self): 65 | pass 66 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/binja_loader.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from lighthouse.util.log import lmsg 4 | from lighthouse.binja_integration import LighthouseBinja 5 | 6 | logger = logging.getLogger("Lighthouse.Binja.Loader") 7 | 8 | #------------------------------------------------------------------------------ 9 | # Lighthouse Binja Loader 10 | #------------------------------------------------------------------------------ 11 | # 12 | # The Binary Ninja plugin loading process is less involved compared to IDA. 13 | # 14 | # When Binary Ninja is starting up, it will import all python files placed 15 | # in its root plugin folder. It will then attempt to import any *directory* 16 | # in the plugin folder as a python module. 17 | # 18 | # For this reason, you may see Binary Ninja attempting to load 'lighthouse' 19 | # and 'lighthouse_plugin' in your console. This is normal due to the way 20 | # we have structured Lighthouse and its loading process. 21 | # 22 | # In practice, lighthouse_plugin.py will import the contents of this file, 23 | # when Binary Ninja is starting up. As such, this is our only opportunity 24 | # to load & integrate Lighthouse. 25 | # 26 | # TODO/V35: it would be nice load/unload plugins with BNDB's like IDA 27 | # 28 | 29 | try: 30 | lighthouse = LighthouseBinja() 31 | lighthouse.load() 32 | except Exception as e: 33 | lmsg("Failed to initialize Lighthouse") 34 | logger.exception("Exception details:") 35 | 36 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/composer/__init__.py: -------------------------------------------------------------------------------- 1 | from .shell import ComposingShell 2 | from .parser import CompositionParser 3 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/ida_loader.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | import idaapi 4 | from lighthouse.util.log import lmsg 5 | from lighthouse.ida_integration import LighthouseIDA 6 | 7 | logger = logging.getLogger("Lighthouse.IDA.Loader") 8 | 9 | #------------------------------------------------------------------------------ 10 | # Lighthouse IDA Loader 11 | #------------------------------------------------------------------------------ 12 | # 13 | # This file contains a stub 'plugin' class for Lighthouse as required by 14 | # IDA Pro. Practically speaking, there should be little to *no* logic placed 15 | # in this file because it is disassembler-specific. 16 | # 17 | # When IDA Pro is starting up, it will import all python files placed in its 18 | # root plugin folder. It will then attempt to call PLUGIN_ENTRY() on each of 19 | # the imported 'plugins'. We import PLUGIN_ENTRY into lighthouse_plugin.py 20 | # so that IDA can see it. 21 | # 22 | # PLUGIN_ENTRY() is expected to return a plugin object (LighthouseIDAPlugin) 23 | # derived from idaapi.plugin_t. IDA will register the plugin, and interface 24 | # with the plugin object to load / unload the plugin at certain times, per 25 | # its configuration (flags, hotkeys). 26 | # 27 | # There should be virtually no reason for you to modify this file. 28 | # 29 | 30 | def PLUGIN_ENTRY(): 31 | """ 32 | Required plugin entry point for IDAPython Plugins. 33 | """ 34 | return LighthouseIDAPlugin() 35 | 36 | class LighthouseIDAPlugin(idaapi.plugin_t): 37 | """ 38 | The IDA plugin stub for Lighthouse. 39 | """ 40 | 41 | # 42 | # Plugin flags: 43 | # - PLUGIN_MOD: Lighthouse is a plugin that may modify the database 44 | # - PLUGIN_PROC: Load/unload Lighthouse when an IDB opens / closes 45 | # - PLUGIN_HIDE: Hide Lighthouse from the IDA plugin menu 46 | # 47 | 48 | flags = idaapi.PLUGIN_PROC | idaapi.PLUGIN_MOD | idaapi.PLUGIN_HIDE 49 | comment = "Code Coverage Explorer" 50 | help = "" 51 | wanted_name = "Lighthouse" 52 | wanted_hotkey = "" 53 | 54 | #-------------------------------------------------------------------------- 55 | # IDA Plugin Overloads 56 | #-------------------------------------------------------------------------- 57 | 58 | def init(self): 59 | """ 60 | This is called by IDA when it is loading the plugin. 61 | """ 62 | try: 63 | self._lighthouse = LighthouseIDA() 64 | self._lighthouse.load() 65 | except Exception as e: 66 | lmsg("Failed to initialize Lighthouse") 67 | logger.exception("Exception details:") 68 | return idaapi.PLUGIN_SKIP 69 | 70 | # tell IDA to keep the plugin loaded (everything is okay) 71 | return idaapi.PLUGIN_KEEP 72 | 73 | def run(self, arg): 74 | """ 75 | This is called by IDA when this file is loaded as a script. 76 | """ 77 | idaapi.warning("Lighthouse cannot be run as a script in IDA.") 78 | 79 | def term(self): 80 | """ 81 | This is called by IDA when it is unloading the plugin. 82 | """ 83 | try: 84 | self._lighthouse.unload() 85 | self._lighthouse = None 86 | except Exception as e: 87 | logger.exception("Failed to cleanly unload Lighthouse from IDA.") 88 | 89 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/painting/__init__.py: -------------------------------------------------------------------------------- 1 | from .painter import DatabasePainter 2 | from lighthouse.util.disassembler import disassembler 3 | 4 | if disassembler.NAME == "IDA": 5 | from .ida_painter import IDAPainter as CoveragePainter 6 | elif disassembler.NAME == "BINJA": 7 | from .binja_painter import BinjaPainter as CoveragePainter 8 | else: 9 | raise NotImplementedError("DISASSEMBLER-SPECIFIC SHIM MISSING") 10 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/painting/binja_painter.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | import binaryninja 4 | from binaryninja import HighlightStandardColor 5 | from binaryninja.highlight import HighlightColor 6 | 7 | from lighthouse.palette import to_rgb 8 | from lighthouse.painting import DatabasePainter 9 | from lighthouse.util.disassembler import disassembler 10 | 11 | logger = logging.getLogger("Lighthouse.Painting.Binja") 12 | 13 | #------------------------------------------------------------------------------ 14 | # Binary Ninja Painter 15 | #------------------------------------------------------------------------------ 16 | 17 | class BinjaPainter(DatabasePainter): 18 | """ 19 | Asynchronous Binary Ninja database painter. 20 | """ 21 | PAINTER_SLEEP = 0.01 22 | 23 | def __init__(self, director, palette): 24 | super(BinjaPainter, self).__init__(director, palette) 25 | 26 | #-------------------------------------------------------------------------- 27 | # Paint Primitives 28 | #-------------------------------------------------------------------------- 29 | 30 | # 31 | # NOTE: 32 | # due to the manner in which Binary Ninja implements basic block 33 | # (node) highlighting, I am not sure it is worth it to paint individual 34 | # instructions. for now we, will simply make the instruction 35 | # painting functions no-op's 36 | # 37 | 38 | def _paint_instructions(self, instructions): 39 | self._action_complete.set() 40 | 41 | def _clear_instructions(self, instructions): 42 | self._action_complete.set() 43 | 44 | def _paint_nodes(self, nodes_coverage): 45 | bv = disassembler.bv 46 | b, g, r = to_rgb(self.palette.coverage_paint) 47 | color = HighlightColor(red=r, green=g, blue=b) 48 | for node_coverage in nodes_coverage: 49 | node_metadata = node_coverage.database._metadata.nodes[node_coverage.address] 50 | for node in bv.get_basic_blocks_starting_at(node_metadata.address): 51 | node.highlight = color 52 | self._painted_nodes.add(node_metadata.address) 53 | self._action_complete.set() 54 | 55 | def _clear_nodes(self, nodes_metadata): 56 | bv = disassembler.bv 57 | for node_metadata in nodes_metadata: 58 | for node in bv.get_basic_blocks_starting_at(node_metadata.address): 59 | node.highlight = HighlightStandardColor.NoHighlightColor 60 | self._painted_nodes.discard(node_metadata.address) 61 | self._action_complete.set() 62 | 63 | def _refresh_ui(self): 64 | pass 65 | 66 | def _cancel_action(self, job): 67 | pass 68 | 69 | #-------------------------------------------------------------------------- 70 | # Priority Painting 71 | #-------------------------------------------------------------------------- 72 | 73 | def _priority_paint(self): 74 | current_address = disassembler.get_current_address() 75 | current_function = disassembler.bv.get_function_at(current_address) 76 | if current_function: 77 | self._paint_function(current_function.start) 78 | return True 79 | 80 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/parsers/__init__.py: -------------------------------------------------------------------------------- 1 | from drcov import DrcovData 2 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/parsers/drcov.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os 4 | import sys 5 | import mmap 6 | import idaapi 7 | import struct 8 | from ctypes import * 9 | from collections import Counter 10 | 11 | # this version is for pe-afl 12 | 13 | #------------------------------------------------------------------------------ 14 | # drcov log parser 15 | #------------------------------------------------------------------------------ 16 | 17 | class DrcovData(object): 18 | """ 19 | A drcov log parser. 20 | """ 21 | def __init__(self, filepath=None): 22 | 23 | self.filepath = filepath 24 | self.buf = [int(i, 16) for i in open(filepath).read().strip().split()] 25 | self.base = idaapi.get_imagebase() 26 | 27 | #-------------------------------------------------------------------------- 28 | # Public 29 | #-------------------------------------------------------------------------- 30 | 31 | def get_bb_and_size(self, graph, ea): 32 | for block in graph: 33 | if block.startEA <= ea and block.endEA > ea: 34 | return (block.startEA-self.base, block.endEA-block.startEA) 35 | 36 | def get_blocks_by_module(self, module_name): 37 | """ 38 | Extract coverage blocks pertaining to the named module. 39 | """ 40 | 41 | coverage_blocks = [] 42 | for addr in self.buf: 43 | x = addr 44 | f = idaapi.get_func(x) 45 | g = idaapi.FlowChart(f) 46 | coverage_blocks.append(self.get_bb_and_size(g, x)) 47 | first_block = (g[0].startEA-self.base, g[0].endEA-g[0].startEA) 48 | if first_block not in coverage_blocks: 49 | coverage_blocks.append(first_block) 50 | 51 | c = Counter(coverage_blocks) 52 | for k in c: 53 | addr = k[0]+self.base 54 | print hex(addr).strip('L'), c[k] 55 | 56 | return coverage_blocks 57 | 58 | #------------------------------------------------------------------------------ 59 | # Command Line Testing 60 | #------------------------------------------------------------------------------ 61 | 62 | if __name__ == "__main__": 63 | 64 | # for testing 65 | trace_file = 'C:\\Users\\wmliang\\winafl\\test_ioctl\\bin\\trace2.log' 66 | 67 | # attempt file parse 68 | x = DrcovData(trace_file) 69 | print x.get_blocks_by_module('') 70 | 71 | 72 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/ui/__init__.py: -------------------------------------------------------------------------------- 1 | from .coverage_overview import CoverageOverview 2 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/ui/coverage_settings.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from lighthouse.util.qt import * 3 | from lighthouse.util.disassembler import disassembler 4 | 5 | logger = logging.getLogger("Lighthouse.UI.Settings") 6 | 7 | class TableSettingsMenu(QtWidgets.QMenu): 8 | """ 9 | A quick-access settings menu for Lighthouse. 10 | """ 11 | 12 | def __init__(self, parent=None): 13 | super(TableSettingsMenu, self).__init__(parent) 14 | self._visible_action = None 15 | self._ui_init_actions() 16 | 17 | if USING_PYQT5: 18 | self.setToolTipsVisible(True) 19 | 20 | #-------------------------------------------------------------------------- 21 | # QMenu Overloads 22 | #-------------------------------------------------------------------------- 23 | 24 | def event(self, event): 25 | """ 26 | Hook the QMenu event stream. 27 | """ 28 | action = self.activeAction() 29 | 30 | # swallow clicks to checkbox/radiobutton actions to keep qmenu open 31 | if event.type() == QtCore.QEvent.MouseButtonRelease: 32 | if action and action.isEnabled() and action.isCheckable(): 33 | action.trigger() 34 | event.accept() 35 | return True 36 | 37 | # show action tooltips (for Qt < 5.1) 38 | elif event.type() == QtCore.QEvent.ToolTip and not USING_PYQT5: 39 | if action and self._visible_action != action: 40 | QtWidgets.QToolTip.showText(event.globalPos(), action.toolTip()) 41 | self._visible_action = action 42 | event.accept() 43 | return True 44 | 45 | # clear tooltips (for Qt < 5.1) 46 | if not (action or USING_PYQT5): 47 | QtWidgets.QToolTip.hideText() 48 | self._visible_action = None 49 | 50 | # handle any other events as wee normally should 51 | return super(TableSettingsMenu, self).event(event) 52 | 53 | #-------------------------------------------------------------------------- 54 | # Initialization - UI 55 | #-------------------------------------------------------------------------- 56 | 57 | def _ui_init_actions(self): 58 | """ 59 | Initialize the menu actions. 60 | """ 61 | 62 | # lighthouse colors 63 | self._action_colors = QtWidgets.QAction("Colors", None) 64 | self._action_colors.setToolTip("Lighthouse color & theme customization") 65 | #self.addAction(self._action_colors) 66 | #self.addSeparator() 67 | 68 | # painting 69 | self._action_pause_paint = QtWidgets.QAction("Pause painting", None) 70 | self._action_pause_paint.setCheckable(True) 71 | self._action_pause_paint.setToolTip("Disable coverage painting") 72 | self.addAction(self._action_pause_paint) 73 | 74 | # misc 75 | self._action_clear_paint = QtWidgets.QAction("Clear paint", None) 76 | self._action_clear_paint.setToolTip("Forcefully clear all paint") 77 | self.addAction(self._action_clear_paint) 78 | self.addSeparator() 79 | 80 | # table actions 81 | self._action_refresh_metadata = QtWidgets.QAction("Full table refresh", None) 82 | self._action_refresh_metadata.setToolTip("Refresh metadata & coverage for db") 83 | self.addAction(self._action_refresh_metadata) 84 | 85 | self._action_export_html = QtWidgets.QAction("Export to HTML", None) 86 | self._action_export_html.setToolTip("Export the coverage table to HTML") 87 | self.addAction(self._action_export_html) 88 | 89 | self._action_hide_zero = QtWidgets.QAction("Hide 0% coverage", None) 90 | self._action_hide_zero.setToolTip("Hide table entries with no coverage data") 91 | self._action_hide_zero.setCheckable(True) 92 | self.addAction(self._action_hide_zero) 93 | 94 | def connect_signals(self, controller, core): 95 | """ 96 | Connect UI signals. 97 | """ 98 | self._action_refresh_metadata.triggered.connect(controller.refresh_metadata) 99 | self._action_hide_zero.triggered[bool].connect(controller._model.filter_zero_coverage) 100 | self._action_pause_paint.triggered[bool].connect(lambda x: core.painter.set_enabled(not x)) 101 | self._action_clear_paint.triggered.connect(core.painter.clear_paint) 102 | self._action_export_html.triggered.connect(controller.export_to_html) 103 | core.painter.status_changed(self._ui_painter_changed_status) 104 | 105 | #-------------------------------------------------------------------------- 106 | # Signal Handlers 107 | #-------------------------------------------------------------------------- 108 | 109 | @disassembler.execute_ui 110 | def _ui_painter_changed_status(self, painter_enabled): 111 | """ 112 | Handle an event from the painter being enabled/disabled. 113 | """ 114 | self._action_pause_paint.setChecked(not painter_enabled) 115 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/ui/resources/icons/batch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/lighthouse/lighthouse/ui/resources/icons/batch.png -------------------------------------------------------------------------------- /lighthouse/lighthouse/ui/resources/icons/delete_coverage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/lighthouse/lighthouse/ui/resources/icons/delete_coverage.png -------------------------------------------------------------------------------- /lighthouse/lighthouse/ui/resources/icons/load.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/lighthouse/lighthouse/ui/resources/icons/load.png -------------------------------------------------------------------------------- /lighthouse/lighthouse/ui/resources/icons/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wmliang/pe-afl/4036d2f41da20ff12ecac43a076de5d60ce68bd9/lighthouse/lighthouse/ui/resources/icons/overview.png -------------------------------------------------------------------------------- /lighthouse/lighthouse/util/__init__.py: -------------------------------------------------------------------------------- 1 | from .misc import * 2 | from .debug import * 3 | from .log import lmsg, logging_started, start_logging 4 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/util/debug.py: -------------------------------------------------------------------------------- 1 | import cProfile 2 | 3 | #------------------------------------------------------------------------------ 4 | # Debug 5 | #------------------------------------------------------------------------------ 6 | # 7 | # This file contains random snippets of code that I frequently use while 8 | # developing and debugging parts of lighthouse. I don't expect any of this 9 | # code to be active or in use for major releases. 10 | # 11 | 12 | #------------------------------------------------------------------------------ 13 | # Call Profiling 14 | #------------------------------------------------------------------------------ 15 | 16 | pr = cProfile.Profile() 17 | 18 | def profile(func): 19 | """ 20 | A simple function profiling decorator. 21 | """ 22 | def wrap(*args, **kwargs): 23 | global pr 24 | pr.enable() 25 | result = func(*args, **kwargs) 26 | pr.disable() 27 | pr.print_stats(sort="tottime") 28 | return result 29 | return wrap 30 | 31 | #------------------------------------------------------------------------------ 32 | # Function Line Profiling 33 | #------------------------------------------------------------------------------ 34 | 35 | # from: https://gist.github.com/sibelius/3920b3eb5adab482b105 36 | try: 37 | from line_profiler import LineProfiler 38 | def line_profile(func): 39 | def profiled_func(*args, **kwargs): 40 | try: 41 | profiler = LineProfiler() 42 | profiler.add_function(func) 43 | profiler.enable_by_count() 44 | return func(*args, **kwargs) 45 | finally: 46 | profiler.print_stats() 47 | return profiled_func 48 | 49 | except ImportError: 50 | def line_profile(func): 51 | def nothing(*args, **kwargs): 52 | return func(*args, **kwargs) 53 | return nothing 54 | 55 | #------------------------------------------------------------------------------ 56 | # Module Line Profiling 57 | #------------------------------------------------------------------------------ 58 | 59 | if False: 60 | from line_profiler import LineProfiler 61 | lpr = LineProfiler() 62 | 63 | # change this to the target file / module to profile 64 | import lighthouse.metadata as metadata 65 | lpr.add_module(metadata) 66 | 67 | # put this code somewhere to dump results: 68 | #global lpr 69 | #lpr.enable_by_count() 70 | #lpr.disable_by_count() 71 | #lpr.print_stats(stripzeros=True) 72 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/util/disassembler/__init__.py: -------------------------------------------------------------------------------- 1 | #-------------------------------------------------------------------------- 2 | # Disassembler API Selector 3 | #-------------------------------------------------------------------------- 4 | # 5 | # this file will select and load the shimmed disassembler API for the 6 | # appropriate (current) disassembler platform. 7 | # 8 | # see api.py for more details regarding this API shim layer 9 | # 10 | 11 | disassembler = None 12 | 13 | #-------------------------------------------------------------------------- 14 | # IDA API Shim 15 | #-------------------------------------------------------------------------- 16 | 17 | if disassembler == None: 18 | try: 19 | from ida_api import IDAAPI, DockableWindow 20 | disassembler = IDAAPI() 21 | except ImportError: 22 | pass 23 | 24 | #-------------------------------------------------------------------------- 25 | # Binary Ninja API Shim 26 | #-------------------------------------------------------------------------- 27 | 28 | if disassembler == None: 29 | try: 30 | from binja_api import BinjaAPI, DockableWindow 31 | disassembler = BinjaAPI() 32 | except ImportError: 33 | pass 34 | 35 | #-------------------------------------------------------------------------- 36 | # Unknown Disassembler 37 | #-------------------------------------------------------------------------- 38 | 39 | if disassembler == None: 40 | raise NotImplementedError("Unknown or unsupported disassembler!") 41 | 42 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/util/log.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import logging 4 | 5 | from .disassembler import disassembler 6 | 7 | #------------------------------------------------------------------------------ 8 | # Log / Print helpers 9 | #------------------------------------------------------------------------------ 10 | 11 | def lmsg(message): 12 | """ 13 | Print a message to the disassembler output window, prefixed with [Lighthouse] 14 | """ 15 | 16 | # prefix the message 17 | prefix_message = "[Lighthouse] %s" % message 18 | 19 | # only print to disassembler if its output window is alive 20 | if disassembler.is_msg_inited(): 21 | print prefix_message 22 | else: 23 | logger.info(message) 24 | 25 | def get_log_dir(): 26 | """ 27 | Return the Lighthouse log directory. 28 | """ 29 | log_directory = os.path.join( 30 | disassembler.get_disassembler_user_directory(), 31 | "lighthouse_logs" 32 | ) 33 | return log_directory 34 | 35 | def logging_started(): 36 | """ 37 | Check if logging has been started. 38 | """ 39 | return 'logger' in globals() 40 | 41 | #------------------------------------------------------------------------------ 42 | # Logger Proxy 43 | #------------------------------------------------------------------------------ 44 | 45 | class LoggerProxy(object): 46 | """ 47 | Fake file-like stream object that redirects writes to a logger instance. 48 | """ 49 | def __init__(self, logger, stream, log_level=logging.INFO): 50 | self._logger = logger 51 | self._log_level = log_level 52 | self._stream = stream 53 | 54 | def write(self, buf): 55 | for line in buf.rstrip().splitlines(): 56 | self._logger.log(self._log_level, line.rstrip()) 57 | self._stream.write(buf) 58 | 59 | def flush(self): 60 | pass 61 | 62 | def isatty(self): 63 | pass 64 | 65 | #------------------------------------------------------------------------------ 66 | # Initialize Logging 67 | #------------------------------------------------------------------------------ 68 | 69 | MAX_LOGS = 5 70 | def cleanup_log_directory(log_directory): 71 | """ 72 | Retain only the last 15 logs. 73 | """ 74 | filetimes = {} 75 | 76 | # build a map of all the files in the directory, and their last modified time 77 | for log_name in os.listdir(log_directory): 78 | filepath = os.path.join(log_directory, log_name) 79 | if os.path.isfile(filepath): 80 | filetimes[os.path.getmtime(filepath)] = filepath 81 | 82 | # get the filetimes and check if there's enough to warrant cleanup 83 | times = filetimes.keys() 84 | if len(times) < MAX_LOGS: 85 | return 86 | 87 | logger.debug("Cleaning logs directory") 88 | 89 | # discard the newest 15 logs 90 | times.sort(reverse=True) 91 | times = times[MAX_LOGS:] 92 | 93 | # loop through the remaining older logs, and delete them 94 | for log_time in times: 95 | try: 96 | os.remove(filetimes[log_time]) 97 | except Exception as e: 98 | logger.error("Failed to delete log %s" % filetimes[log_time]) 99 | logger.error(e) 100 | 101 | def start_logging(): 102 | global logger 103 | 104 | # create the Lighthouse logger 105 | logger = logging.getLogger("Lighthouse") 106 | 107 | # 108 | # only enable logging if the LIGHTHOUSE_LOGGING environment variable is 109 | # present. we simply return a stub logger to sinkhole messages. 110 | # 111 | 112 | if os.getenv("LIGHTHOUSE_LOGGING") == None: 113 | logger.disabled = True 114 | return logger 115 | 116 | # create a directory for lighthouse logs if it does not exist 117 | log_dir = get_log_dir() 118 | if not os.path.exists(log_dir): 119 | os.makedirs(log_dir) 120 | 121 | # construct the full log path 122 | log_path = os.path.join(log_dir, "lighthouse.%s.log" % os.getpid()) 123 | 124 | # config the logger 125 | logging.basicConfig( 126 | filename=log_path, 127 | format='%(asctime)s | %(name)28s | %(levelname)7s: %(message)s', 128 | datefmt='%m-%d-%Y %H:%M:%S', 129 | level=logging.DEBUG 130 | ) 131 | 132 | # proxy STDOUT/STDERR to the log files too 133 | stdout_logger = logging.getLogger('Lighthouse.STDOUT') 134 | stderr_logger = logging.getLogger('Lighthouse.STDERR') 135 | sys.stdout = LoggerProxy(stdout_logger, sys.stdout, logging.INFO) 136 | sys.stderr = LoggerProxy(stderr_logger, sys.stderr, logging.ERROR) 137 | 138 | # limit the number of logs we keep 139 | cleanup_log_directory(log_dir) 140 | 141 | return logger 142 | 143 | #------------------------------------------------------------------------------ 144 | # Log Helpers 145 | #------------------------------------------------------------------------------ 146 | 147 | def log_config_warning(self, logger, section, field): 148 | logger.warning("Config missing field '%s' in section '%s", field, section) 149 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/util/misc.py: -------------------------------------------------------------------------------- 1 | import os 2 | import weakref 3 | import threading 4 | import collections 5 | 6 | #------------------------------------------------------------------------------ 7 | # Plugin Util 8 | #------------------------------------------------------------------------------ 9 | 10 | PLUGIN_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) 11 | 12 | def plugin_resource(resource_name): 13 | """ 14 | Return the full path for a given plugin resource file. 15 | """ 16 | return os.path.join( 17 | PLUGIN_PATH, 18 | "ui", 19 | "resources", 20 | resource_name 21 | ) 22 | 23 | #------------------------------------------------------------------------------ 24 | # Thread Util 25 | #------------------------------------------------------------------------------ 26 | 27 | def is_mainthread(): 28 | """ 29 | Return a bool that indicates if this is the main application thread. 30 | """ 31 | return isinstance(threading.current_thread(), threading._MainThread) 32 | 33 | def mainthread(f): 34 | """ 35 | A debug decorator to ensure that a function is always called from the main thread. 36 | """ 37 | def wrapper(*args, **kwargs): 38 | assert is_mainthread() 39 | return f(*args, **kwargs) 40 | return wrapper 41 | 42 | def not_mainthread(f): 43 | """ 44 | A debug decorator to ensure that a function is never called from the main thread. 45 | """ 46 | def wrapper(*args, **kwargs): 47 | assert not is_mainthread() 48 | return f(*args, **kwargs) 49 | return wrapper 50 | 51 | #------------------------------------------------------------------------------ 52 | # Python Util 53 | #------------------------------------------------------------------------------ 54 | 55 | def chunks(l, n): 56 | """ 57 | Yield successive n-sized chunks from a list (l). 58 | 59 | From http://stackoverflow.com/a/312464 60 | """ 61 | for i in xrange(0, len(l), n): 62 | yield l[i:i + n] 63 | 64 | def hex_list(items): 65 | """ 66 | Return a string of a python-like list, with hex numbers. 67 | 68 | [0, 5420, 1942512] --> '[0x0, 0x152C, 0x1DA30]' 69 | """ 70 | return '[{}]'.format(', '.join('0x%X' % x for x in items)) 71 | 72 | #------------------------------------------------------------------------------ 73 | # Python Callback / Signals 74 | #------------------------------------------------------------------------------ 75 | 76 | def register_callback(callback_list, callback): 77 | """ 78 | Register a callable function to the given callback_list. 79 | 80 | Adapted from http://stackoverflow.com/a/21941670 81 | """ 82 | 83 | # create a weakref callback to an object method 84 | try: 85 | callback_ref = weakref.ref(callback.__func__), weakref.ref(callback.__self__) 86 | 87 | # create a wweakref callback to a stand alone function 88 | except AttributeError: 89 | callback_ref = weakref.ref(callback), None 90 | 91 | # 'register' the callback 92 | callback_list.append(callback_ref) 93 | 94 | def notify_callback(callback_list, *args): 95 | """ 96 | Notify the given list of registered callbacks of an event. 97 | 98 | The given list (callback_list) is a list of weakref'd callables 99 | registered through the register_callback() function. To notify the 100 | callbacks of an event, this function will simply loop through the list 101 | and call them. 102 | 103 | This routine self-heals by removing dead callbacks for deleted objects as 104 | it encounters them. 105 | 106 | Adapted from http://stackoverflow.com/a/21941670 107 | """ 108 | cleanup = [] 109 | 110 | # 111 | # loop through all the registered callbacks in the given callback_list, 112 | # notifying active callbacks, and removing dead ones. 113 | # 114 | 115 | for callback_ref in callback_list: 116 | callback, obj_ref = callback_ref[0](), callback_ref[1] 117 | 118 | # 119 | # if the callback is an instance method, deference the instance 120 | # (an object) first to check that it is still alive 121 | # 122 | 123 | if obj_ref: 124 | obj = obj_ref() 125 | 126 | # if the object instance is gone, mark this callback for cleanup 127 | if obj is None: 128 | cleanup.append(callback_ref) 129 | continue 130 | 131 | # call the object instance callback 132 | try: 133 | callback(obj, *args) 134 | 135 | # assume a Qt cleanup/deletion occurred 136 | except RuntimeError as e: 137 | cleanup.append(callback_ref) 138 | continue 139 | 140 | # if the callback is a static method... 141 | else: 142 | 143 | # if the static method is deleted, mark this callback for cleanup 144 | if callback is None: 145 | cleanup.append(callback_ref) 146 | continue 147 | 148 | # call the static callback 149 | callback(*args) 150 | 151 | # remove the deleted callbacks 152 | for callback_ref in cleanup: 153 | callback_list.remove(callback_ref) 154 | 155 | #------------------------------------------------------------------------------ 156 | # Coverage Util 157 | #------------------------------------------------------------------------------ 158 | 159 | def coalesce_blocks(blocks): 160 | """ 161 | Coalesce a list of (address, size) blocks. 162 | 163 | eg: 164 | blocks = [ 165 | (4100, 10), 166 | (4200, 100), 167 | (4300, 10), 168 | (4310, 20), 169 | (4400, 10), 170 | ] 171 | 172 | returns: 173 | coalesced = [(4100, 10), (4200, 130), (4400, 10)] 174 | 175 | """ 176 | 177 | # nothing to do 178 | if not blocks: 179 | return [] 180 | elif len(blocks) == 1: 181 | return blocks 182 | 183 | # before we can operate on the blocks, we must ensure they are sorted 184 | blocks = sorted(blocks) 185 | 186 | # 187 | # coalesce the list of given blocks 188 | # 189 | 190 | coalesced = [blocks.pop(0)] 191 | while blocks: 192 | 193 | block_start, block_size = blocks.pop(0) 194 | 195 | # 196 | # compute the end address of the current coalescing block. if the 197 | # blocks do not overlap, create a new block to start coalescing from 198 | # 199 | 200 | if sum(coalesced[-1]) < block_start: 201 | coalesced.append((block_start, block_size)) 202 | continue 203 | 204 | # 205 | # the blocks overlap, so update the current coalescing block 206 | # 207 | 208 | coalesced[-1] = (coalesced[-1][0], (block_start+block_size) - coalesced[-1][0]) 209 | 210 | # return the list of coalesced blocks 211 | return coalesced 212 | 213 | def rebase_blocks(base, basic_blocks): 214 | """ 215 | Rebase a list of basic block offsets (offset, size) to the given imagebase. 216 | """ 217 | return map(lambda x: (base + x[0], x[1]), basic_blocks) 218 | 219 | def build_hitmap(data): 220 | """ 221 | Build a hitmap from the given list of address. 222 | 223 | A hitmap is a map of address --> number of executions. 224 | 225 | The list of input addresses can be any sort of runtime trace, coverage, 226 | or profiling data that one would like to build a hitmap for. 227 | """ 228 | output = collections.defaultdict(int) 229 | 230 | # if there is no input data, simply return an empty hitmap 231 | if not data: 232 | return output 233 | 234 | # 235 | # walk through the given list of given addresses and build a 236 | # corresponding hitmap for them 237 | # 238 | 239 | for address in data: 240 | output[address] += 1 241 | 242 | # return the hitmap 243 | return output 244 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/util/qt/__init__.py: -------------------------------------------------------------------------------- 1 | from .shim import * 2 | 3 | if QT_AVAILABLE: 4 | from .util import * 5 | from .waitbox import WaitBox 6 | 7 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/util/qt/shim.py: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # this global is used to indicate whether Qt bindings for python are present 4 | # and available for use by Lighthouse. 5 | # 6 | 7 | QT_AVAILABLE = False 8 | 9 | #------------------------------------------------------------------------------ 10 | # PyQt5 <--> PySide (Qt4) Interoperability 11 | #------------------------------------------------------------------------------ 12 | # 13 | # from Qt4 --> Qt5, a number of objects / modules have changed places 14 | # within the Qt codebase. we use this file to shim/re-alias a few of these 15 | # changes to reduce the number of compatibility checks / code churn in the 16 | # plugin code that consumes them. 17 | # 18 | # this makes the plugin codebase compatible with both PySide & PyQt5, a 19 | # necessary requirement to maintain compatibility with IDA 6.8 --> 7.x 20 | # 21 | # additionally, the 'USING_PYQT5' global can be used to check if we are 22 | # running in a PyQt5 context (versus PySide/Qt4). This may be used in a few 23 | # places throughout the project that could not be covered by our shims. 24 | # 25 | 26 | USING_PYQT5 = False 27 | 28 | #------------------------------------------------------------------------------ 29 | # PyQt5 Compatibility 30 | #------------------------------------------------------------------------------ 31 | 32 | # attempt to load PyQt5 33 | if QT_AVAILABLE == False: 34 | try: 35 | import PyQt5.QtGui as QtGui 36 | import PyQt5.QtCore as QtCore 37 | import PyQt5.QtWidgets as QtWidgets 38 | 39 | # importing went okay, PyQt5 must be available for use 40 | QT_AVAILABLE = True 41 | USING_PYQT5 = True 42 | 43 | # import failed, PyQt5 is not available 44 | except ImportError: 45 | pass 46 | 47 | #------------------------------------------------------------------------------ 48 | # PySide Compatibility 49 | #------------------------------------------------------------------------------ 50 | 51 | # if PyQt5 did not import, try to load PySide 52 | if QT_AVAILABLE == False: 53 | try: 54 | import PySide.QtGui as QtGui 55 | import PySide.QtCore as QtCore 56 | 57 | # alias for less PySide <--> PyQt5 shimming 58 | QtWidgets = QtGui 59 | QtCore.pyqtSignal = QtCore.Signal 60 | QtCore.pyqtSlot = QtCore.Slot 61 | 62 | # importing went okay, PySide must be available for use 63 | QT_AVAILABLE = True 64 | 65 | # import failed. No Qt / UI bindings available... 66 | except ImportError: 67 | pass 68 | 69 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/util/qt/util.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | import Queue 4 | import logging 5 | 6 | from .shim import * 7 | from ..misc import is_mainthread 8 | from ..disassembler import disassembler 9 | 10 | logger = logging.getLogger("Lighthouse.Qt.Util") 11 | 12 | #------------------------------------------------------------------------------ 13 | # Qt Fonts 14 | #------------------------------------------------------------------------------ 15 | 16 | def MonospaceFont(): 17 | """ 18 | Convenience alias for creating a monospace Qt font object. 19 | """ 20 | font = QtGui.QFont("Courier New") 21 | font.setStyleHint(QtGui.QFont.TypeWriter) 22 | return font 23 | 24 | #------------------------------------------------------------------------------ 25 | # Qt Util 26 | #------------------------------------------------------------------------------ 27 | 28 | def color_text(text, color): 29 | """ 30 | Return a colorized (HTML) version of the given string. 31 | """ 32 | return "%s" % (color.name(), text) 33 | 34 | def copy_to_clipboard(data): 35 | """ 36 | Copy the given data (a string) to the system clipboard. 37 | """ 38 | cb = QtWidgets.QApplication.clipboard() 39 | cb.clear(mode=cb.Clipboard) 40 | cb.setText(data, mode=cb.Clipboard) 41 | 42 | def flush_qt_events(): 43 | """ 44 | Flush the Qt event pipeline. 45 | """ 46 | app = QtCore.QCoreApplication.instance() 47 | app.processEvents() 48 | 49 | def get_qt_icon(name): 50 | """ 51 | Get a standard Qt icon by name. 52 | """ 53 | icon_type = getattr(QtWidgets.QStyle, name) 54 | return QtWidgets.QApplication.style().standardIcon(icon_type) 55 | 56 | def get_qt_main_window(): 57 | """ 58 | Get the QMainWindow instance for the current Qt runtime. 59 | """ 60 | app = QtCore.QCoreApplication.instance() 61 | return [x for x in app.allWidgets() if x.__class__ is QtWidgets.QMainWindow][0] 62 | 63 | def get_default_font_size(): 64 | """ 65 | Get the default font size for this QApplication. 66 | """ 67 | return QtGui.QFont().pointSizeF() 68 | 69 | def get_dpi_scale(): 70 | """ 71 | Get a DPI-afflicted value useful for consistent UI scaling. 72 | """ 73 | font = MonospaceFont() 74 | font.setPointSize(normalize_to_dpi(120)) 75 | fm = QtGui.QFontMetricsF(font) 76 | 77 | # xHeight is expected to be 40.0 at normal DPI 78 | return fm.height() / 173.0 79 | 80 | def move_mouse_event(mouse_event, position): 81 | """ 82 | Move the given mouse event to a different position. 83 | """ 84 | new_event = QtGui.QMouseEvent( 85 | mouse_event.type(), 86 | position, 87 | mouse_event.button(), 88 | mouse_event.buttons(), 89 | mouse_event.modifiers() 90 | ) 91 | return new_event 92 | 93 | def normalize_to_dpi(font_size): 94 | """ 95 | Normalize the given font size based on the system DPI. 96 | """ 97 | if sys.platform == "darwin": # macos is lame 98 | return font_size + 3 99 | return font_size 100 | 101 | def prompt_string(label, title, default=""): 102 | """ 103 | Prompt the user with a dialog to enter a string. 104 | 105 | This does not block the IDA main thread (unlike idaapi.askstr) 106 | """ 107 | dpi_scale = get_dpi_scale() 108 | dlg = QtWidgets.QInputDialog(None) 109 | dlg.setWindowFlags(dlg.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint) 110 | dlg.setInputMode(QtWidgets.QInputDialog.TextInput) 111 | dlg.setLabelText(label) 112 | dlg.setWindowTitle(title) 113 | dlg.setTextValue(default) 114 | dlg.resize( 115 | dpi_scale*400, 116 | dpi_scale*50 117 | ) 118 | ok = dlg.exec_() 119 | text = str(dlg.textValue()) 120 | return (ok, text) 121 | 122 | def predict_bg_color(image): 123 | """ 124 | Predict the 'background color' of a given image. 125 | 126 | This function takes an image, and analyzes its first row of pixels. It 127 | will return the color that it believes to be the 'background color' based 128 | on the longest sequence of identical pixels. 129 | """ 130 | assert image.width() and image.height() 131 | 132 | # the details for the longest known color streak will be saved in these 133 | longest = 1 134 | speculative_bg = image.pixel(0, 0) 135 | 136 | # this will be the computed length of the current color streak 137 | sequence = 1 138 | 139 | # find the longest streak of color in a single pixel slice 140 | for x in xrange(1, image.width()): 141 | 142 | # the color of this pixel matches the last pixel, extend the streak count 143 | if image.pixel(x, 0) == image.pixel(x-1,0): 144 | sequence += 1 145 | 146 | # 147 | # this catches the case where the longest color streak is in fact 148 | # the last one. this ensures the streak color will get saved. 149 | # 150 | 151 | if x != image.width(): 152 | continue 153 | 154 | # color change, determine if this was the longest continuous color streak 155 | if sequence > longest: 156 | 157 | # save the last pixel as the longest sequence / most likely BG color 158 | longest = sequence 159 | speculative_bg = image.pixel(x-1, 0) 160 | 161 | # reset the sequence counter 162 | sequence = 1 163 | 164 | # return the color we speculate to be the background color 165 | return speculative_bg 166 | 167 | def remap_key_event(event, new_key): 168 | """ 169 | Change a given KeyPress QEvent to a different key. 170 | """ 171 | return QtGui.QKeyEvent( 172 | QtCore.QEvent.KeyPress, 173 | new_key, 174 | event.modifiers(), 175 | event.text(), 176 | event.isAutoRepeat(), 177 | event.count() 178 | ) 179 | 180 | def singleshot(ms, function=None): 181 | """ 182 | A Qt Singleshot timer that can be stopped. 183 | """ 184 | timer = QtCore.QTimer() 185 | timer.setInterval(ms) 186 | timer.setSingleShot(True) 187 | timer.timeout.connect(function) 188 | return timer 189 | 190 | #------------------------------------------------------------------------------ 191 | # Async Util 192 | #------------------------------------------------------------------------------ 193 | 194 | def await_future(future): 195 | """ 196 | Wait for a queue (future) message without blocking the main (Qt) thread. 197 | 198 | This is effectively a technique I use to get around completely blocking 199 | IDA's mainthread while waiting for a threaded result that may need to make 200 | use of the execute_sync operators. 201 | 202 | Waiting for a 'future' thread result to come through via this function 203 | lets other execute_sync actions to slip through (at least Read, Fast). 204 | """ 205 | interval = 0.02 # the interval which we wait for a response 206 | 207 | # run until the message arrives through the future (a queue) 208 | while True: 209 | 210 | # block for a brief period to see if the future completes 211 | try: 212 | return future.get(timeout=interval) 213 | 214 | # 215 | # the future timed out, so perhaps it is blocked on a request 216 | # to the mainthread. flush the requests now and try again 217 | # 218 | 219 | except Queue.Empty as e: 220 | pass 221 | 222 | logger.debug("Awaiting future...") 223 | 224 | # 225 | # if we are executing (well, blocking) as the main thread, we need 226 | # to flush the event loop so IDA does not hang 227 | # 228 | 229 | if QT_AVAILABLE and is_mainthread(): 230 | flush_qt_events() 231 | 232 | def await_lock(lock): 233 | """ 234 | Wait for a lock without blocking the main (Qt) thread. 235 | 236 | See await_future() for more details. 237 | """ 238 | 239 | elapsed = 0 # total time elapsed waiting for the lock 240 | interval = 0.02 # the interval (in seconds) between acquire attempts 241 | timeout = 60.0 # the total time allotted to acquiring the lock 242 | end_time = time.time() + timeout 243 | 244 | # wait until the lock is available 245 | while time.time() < end_time: 246 | 247 | # 248 | # attempt to acquire the given lock without blocking (via 'False'). 249 | # if we successfully acquire the lock, then we can return (success) 250 | # 251 | 252 | if lock.acquire(False): 253 | logger.debug("Acquired lock!") 254 | return 255 | 256 | # 257 | # the lock is not available yet. we need to sleep so we don't choke 258 | # the cpu, and try to acquire the lock again next time through... 259 | # 260 | 261 | logger.debug("Awaiting lock...") 262 | time.sleep(interval) 263 | 264 | # 265 | # if we are executing (well, blocking) as the main thread, we need 266 | # to flush the event loop so IDA does not hang 267 | # 268 | 269 | if QT_AVAILABLE and is_mainthread(): 270 | flush_qt_events() 271 | 272 | # 273 | # we spent 60 seconds trying to acquire the lock, but never got it... 274 | # to avoid hanging IDA indefinitely (or worse), we abort via signal 275 | # 276 | 277 | raise RuntimeError("Failed to acquire lock after %f seconds!" % timeout) 278 | -------------------------------------------------------------------------------- /lighthouse/lighthouse/util/qt/waitbox.py: -------------------------------------------------------------------------------- 1 | from .shim import * 2 | from .util import get_dpi_scale 3 | 4 | import logging 5 | logger = logging.getLogger("Lighthouse.Qt.WaitBox") 6 | 7 | #-------------------------------------------------------------------------- 8 | # Qt WaitBox 9 | #-------------------------------------------------------------------------- 10 | 11 | class WaitBox(QtWidgets.QDialog): 12 | """ 13 | A Generic Qt WaitBox Dialog. 14 | """ 15 | 16 | def __init__(self, text, title="Please wait...", abort=None): 17 | super(WaitBox, self).__init__() 18 | 19 | # dialog text & window title 20 | self._text = text 21 | self._title = title 22 | 23 | # abort routine (optional) 24 | self._abort = abort 25 | 26 | # initialize the dialog UI 27 | self._ui_init() 28 | 29 | def set_text(self, text): 30 | """ 31 | Change the waitbox text. 32 | """ 33 | self._text = text 34 | self._text_label.setText(text) 35 | qta = QtCore.QCoreApplication.instance() 36 | qta.processEvents() 37 | 38 | #-------------------------------------------------------------------------- 39 | # Initialization - UI 40 | #-------------------------------------------------------------------------- 41 | 42 | def _ui_init(self): 43 | """ 44 | Initialize UI elements. 45 | """ 46 | self.setWindowFlags( 47 | self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint 48 | ) 49 | self.setWindowFlags( 50 | self.windowFlags() | QtCore.Qt.MSWindowsFixedSizeDialogHint 51 | ) 52 | self.setWindowFlags( 53 | self.windowFlags() & ~QtCore.Qt.WindowCloseButtonHint 54 | ) 55 | 56 | # configure the main widget / form 57 | self.setSizeGripEnabled(False) 58 | self.setModal(True) 59 | self._dpi_scale = get_dpi_scale()*5.0 60 | 61 | # initialize abort button 62 | self._abort_button = QtWidgets.QPushButton("Cancel") 63 | 64 | # layout the populated UI just before showing it 65 | self._ui_layout() 66 | 67 | def _ui_layout(self): 68 | """ 69 | Layout the major UI elements of the widget. 70 | """ 71 | self.setWindowTitle(self._title) 72 | self._text_label = QtWidgets.QLabel(self._text) 73 | self._text_label.setAlignment(QtCore.Qt.AlignHCenter) 74 | 75 | # vertical layout (whole widget) 76 | v_layout = QtWidgets.QVBoxLayout() 77 | v_layout.setAlignment(QtCore.Qt.AlignCenter) 78 | v_layout.addWidget(self._text_label) 79 | if self._abort: 80 | self._abort_button.clicked.connect(abort) 81 | v_layout.addWidget(self._abort_button) 82 | 83 | v_layout.setSpacing(self._dpi_scale*3) 84 | v_layout.setContentsMargins( 85 | self._dpi_scale*5, 86 | self._dpi_scale, 87 | self._dpi_scale*5, 88 | self._dpi_scale 89 | ) 90 | 91 | # scale widget dimensions based on DPI 92 | height = self._dpi_scale * 15 93 | self.setMinimumHeight(height) 94 | 95 | # compute the dialog layout 96 | self.setLayout(v_layout) 97 | -------------------------------------------------------------------------------- /lighthouse/lighthouse_plugin.py: -------------------------------------------------------------------------------- 1 | from lighthouse.util.log import logging_started, start_logging 2 | from lighthouse.util.disassembler import disassembler 3 | 4 | if not logging_started(): 5 | logger = start_logging() 6 | 7 | #------------------------------------------------------------------------------ 8 | # Disassembler Agnonstic Plugin Loader 9 | #------------------------------------------------------------------------------ 10 | 11 | logger.debug("Resolving disassembler platform for plugin...") 12 | 13 | if disassembler.headless: 14 | logger.info("Disassembler '%s' is running headlessly" % disassembler.NAME) 15 | logger.info(" - Lighthouse is not supported in headless modes (yet!)") 16 | 17 | elif disassembler.NAME == "IDA": 18 | logger.info("Selecting IDA loader...") 19 | from lighthouse.ida_loader import * 20 | 21 | elif disassembler.NAME == "BINJA": 22 | logger.info("Selecting Binary Ninja loader...") 23 | from lighthouse.binja_loader import * 24 | 25 | else: 26 | raise NotImplementedError("DISASSEMBLER-SPECIFIC SHIM MISSING") 27 | 28 | -------------------------------------------------------------------------------- /lighthouse_trace.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import sys 3 | import bisect 4 | import pefile 5 | 6 | def readfile(p): 7 | r = [] 8 | for l in open(p).read().strip().split('\n'): 9 | r.append(l.strip()) 10 | return r 11 | 12 | if __name__ == '__main__': 13 | if len(sys.argv) != 4: 14 | print('Usage: {} [XXX.sys] [XXX.sys.mapping.txt] [trace.txt]'.format(sys.argv[0])) 15 | quit() 16 | 17 | trace = readfile(sys.argv[3]) 18 | mapping = readfile(sys.argv[2]) 19 | pe = pefile.PE(sys.argv[1]) 20 | base = pe.OPTIONAL_HEADER.ImageBase 21 | trace = [ int(c, 16)+base-0x21 for c in trace ] 22 | get_last = lambda seq, val: seq[bisect.bisect_right(seq, val) - 1] 23 | 24 | mm = {} 25 | for m in mapping: 26 | (x,y) = m.split() 27 | mm[int(y,16)] = int(x,16) 28 | kk = sorted(mm.keys()) 29 | for c in trace: 30 | print(hex(mm[get_last(kk, c)])) 31 | -------------------------------------------------------------------------------- /ordlookup/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from . import ws2_32 3 | from . import oleaut32 4 | 5 | ''' 6 | A small module for keeping a database of ordinal to symbol 7 | mappings for DLLs which frequently get linked without symbolic 8 | infoz. 9 | ''' 10 | 11 | ords = { 12 | b'ws2_32.dll':ws2_32.ord_names, 13 | b'wsock32.dll':ws2_32.ord_names, 14 | b'oleaut32.dll':oleaut32.ord_names, 15 | } 16 | 17 | def ordLookup(libname, ord, make_name=False): 18 | ''' 19 | Lookup a name for the given ordinal if it's in our 20 | database. 21 | ''' 22 | names = ords.get(libname.lower()) 23 | if names == None: 24 | if make_name is True: 25 | return 'ord%d' % ord 26 | return None 27 | name = names.get(ord) 28 | if name == None: 29 | return 'ord%d' % ord 30 | return name 31 | 32 | 33 | -------------------------------------------------------------------------------- /ordlookup/ws2_32.py: -------------------------------------------------------------------------------- 1 | 2 | ord_names = { 3 | 1: b'accept', 4 | 2: b'bind', 5 | 3: b'closesocket', 6 | 4: b'connect', 7 | 5: b'getpeername', 8 | 6: b'getsockname', 9 | 7: b'getsockopt', 10 | 8: b'htonl', 11 | 9: b'htons', 12 | 10: b'ioctlsocket', 13 | 11: b'inet_addr', 14 | 12: b'inet_ntoa', 15 | 13: b'listen', 16 | 14: b'ntohl', 17 | 15: b'ntohs', 18 | 16: b'recv', 19 | 17: b'recvfrom', 20 | 18: b'select', 21 | 19: b'send', 22 | 20: b'sendto', 23 | 21: b'setsockopt', 24 | 22: b'shutdown', 25 | 23: b'socket', 26 | 24: b'GetAddrInfoW', 27 | 25: b'GetNameInfoW', 28 | 26: b'WSApSetPostRoutine', 29 | 27: b'FreeAddrInfoW', 30 | 28: b'WPUCompleteOverlappedRequest', 31 | 29: b'WSAAccept', 32 | 30: b'WSAAddressToStringA', 33 | 31: b'WSAAddressToStringW', 34 | 32: b'WSACloseEvent', 35 | 33: b'WSAConnect', 36 | 34: b'WSACreateEvent', 37 | 35: b'WSADuplicateSocketA', 38 | 36: b'WSADuplicateSocketW', 39 | 37: b'WSAEnumNameSpaceProvidersA', 40 | 38: b'WSAEnumNameSpaceProvidersW', 41 | 39: b'WSAEnumNetworkEvents', 42 | 40: b'WSAEnumProtocolsA', 43 | 41: b'WSAEnumProtocolsW', 44 | 42: b'WSAEventSelect', 45 | 43: b'WSAGetOverlappedResult', 46 | 44: b'WSAGetQOSByName', 47 | 45: b'WSAGetServiceClassInfoA', 48 | 46: b'WSAGetServiceClassInfoW', 49 | 47: b'WSAGetServiceClassNameByClassIdA', 50 | 48: b'WSAGetServiceClassNameByClassIdW', 51 | 49: b'WSAHtonl', 52 | 50: b'WSAHtons', 53 | 51: b'gethostbyaddr', 54 | 52: b'gethostbyname', 55 | 53: b'getprotobyname', 56 | 54: b'getprotobynumber', 57 | 55: b'getservbyname', 58 | 56: b'getservbyport', 59 | 57: b'gethostname', 60 | 58: b'WSAInstallServiceClassA', 61 | 59: b'WSAInstallServiceClassW', 62 | 60: b'WSAIoctl', 63 | 61: b'WSAJoinLeaf', 64 | 62: b'WSALookupServiceBeginA', 65 | 63: b'WSALookupServiceBeginW', 66 | 64: b'WSALookupServiceEnd', 67 | 65: b'WSALookupServiceNextA', 68 | 66: b'WSALookupServiceNextW', 69 | 67: b'WSANSPIoctl', 70 | 68: b'WSANtohl', 71 | 69: b'WSANtohs', 72 | 70: b'WSAProviderConfigChange', 73 | 71: b'WSARecv', 74 | 72: b'WSARecvDisconnect', 75 | 73: b'WSARecvFrom', 76 | 74: b'WSARemoveServiceClass', 77 | 75: b'WSAResetEvent', 78 | 76: b'WSASend', 79 | 77: b'WSASendDisconnect', 80 | 78: b'WSASendTo', 81 | 79: b'WSASetEvent', 82 | 80: b'WSASetServiceA', 83 | 81: b'WSASetServiceW', 84 | 82: b'WSASocketA', 85 | 83: b'WSASocketW', 86 | 84: b'WSAStringToAddressA', 87 | 85: b'WSAStringToAddressW', 88 | 86: b'WSAWaitForMultipleEvents', 89 | 87: b'WSCDeinstallProvider', 90 | 88: b'WSCEnableNSProvider', 91 | 89: b'WSCEnumProtocols', 92 | 90: b'WSCGetProviderPath', 93 | 91: b'WSCInstallNameSpace', 94 | 92: b'WSCInstallProvider', 95 | 93: b'WSCUnInstallNameSpace', 96 | 94: b'WSCUpdateProvider', 97 | 95: b'WSCWriteNameSpaceOrder', 98 | 96: b'WSCWriteProviderOrder', 99 | 97: b'freeaddrinfo', 100 | 98: b'getaddrinfo', 101 | 99: b'getnameinfo', 102 | 101: b'WSAAsyncSelect', 103 | 102: b'WSAAsyncGetHostByAddr', 104 | 103: b'WSAAsyncGetHostByName', 105 | 104: b'WSAAsyncGetProtoByNumber', 106 | 105: b'WSAAsyncGetProtoByName', 107 | 106: b'WSAAsyncGetServByPort', 108 | 107: b'WSAAsyncGetServByName', 109 | 108: b'WSACancelAsyncRequest', 110 | 109: b'WSASetBlockingHook', 111 | 110: b'WSAUnhookBlockingHook', 112 | 111: b'WSAGetLastError', 113 | 112: b'WSASetLastError', 114 | 113: b'WSACancelBlockingCall', 115 | 114: b'WSAIsBlocking', 116 | 115: b'WSAStartup', 117 | 116: b'WSACleanup', 118 | 151: b'__WSAFDIsSet', 119 | 500: b'WEP', 120 | } 121 | -------------------------------------------------------------------------------- /pe-afl.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import instrument 3 | import argparse 4 | import os 5 | import re 6 | 7 | if os.name == 'nt': 8 | import subprocess 9 | import struct 10 | def asm(code): 11 | kstool_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'bin', 'kstool.exe') 12 | if not os.path.isfile(kstool_path): 13 | print('kstool.exe not found') 14 | quit() 15 | l = ';'.join([ l if '#' not in l else l.split('#')[0] for l in code.strip().split('\n')]) 16 | output = subprocess.check_output(kstool_path+' x32 "'+l+'"', shell=True) 17 | assert 'ERROR' not in output, 'wrong assembly: ' + l 18 | c = output.split('=')[1].replace('[', '').replace(']', '').replace(' ', '').strip() 19 | return c.decode('hex') 20 | p32 = lambda v: struct.pack('>1)&0xFFFF)) 125 | 126 | def stk_snippet(count): 127 | if count % 4: 128 | return asm(''' 129 | pushad 130 | mov ecx, {} 131 | mov edi, esp 132 | add edi, 32 133 | xor eax, eax 134 | mov al, 0xdd 135 | rep stosd 136 | mov ecx, {} 137 | rep stosb 138 | popad 139 | '''.format(count >> 2, count & 3)) 140 | else: 141 | return asm(''' 142 | pushad 143 | mov ecx, {} 144 | mov edi, esp 145 | add edi, 32 146 | xor eax, eax 147 | mov al, 0xdd 148 | rep stosd 149 | popad 150 | '''.format(count >> 2)) 151 | 152 | def parse_arg(): 153 | parser = argparse.ArgumentParser() 154 | parser.add_argument('-n', '--nop', help='Instrument NOP only for testing', action='store_true') 155 | parser.add_argument('-m', '--multi', help='Support multi-thread target', action='store_true') 156 | parser.add_argument('-v', '--verbose', help='Print debug log', action='store_true') 157 | parser.add_argument('-cb', '--callback', help='Instrument with callback, which is in helper driver and written in C', action='store_true') 158 | parser.add_argument('-s', '--stack', help='Enable stack frame poisoning', action='store_true') 159 | parser.add_argument('-e', '--entry', help='Inject code on entry point, ie. -e9090') 160 | parser.add_argument('-l', '--enlarge', help='Enlarge section size, default=4') 161 | parser.add_argument('PE', help='Target PE for instrument') 162 | parser.add_argument('IDA_DUMP', help='dump.txt from IDA') 163 | return parser.parse_args() 164 | 165 | if __name__ == '__main__': 166 | args = parse_arg() 167 | args.pe_afl = True 168 | if args.multi and instrument.is_driver(args.PE): 169 | assert False, 'TODO: -m support user application only' 170 | if args.callback and not instrument.is_driver(args.PE): 171 | assert False, 'TODO: -cb support kernel driver only' 172 | args.filter = False 173 | if instrument.is_driver(args.PE) and not args.callback: 174 | args.filter = True 175 | 176 | if instrument.is_driver(args.PE): 177 | instrument.INFO('kernel-mode driver is instrumenting') 178 | if args.callback: 179 | instrument.INFO('callback instrument is on') 180 | else: 181 | instrument.INFO('user-mode binary is instrumenting') 182 | if args.multi: 183 | instrument.INFO('multi-thread instrument is on') 184 | else: 185 | instrument.INFO('single-thread instrument is on') 186 | if args.stack: 187 | instrument.INFO('stack frame poisoning is on') 188 | 189 | pe,ida=instrument.start(args) 190 | init_snip() 191 | 192 | # stack frame poison instrument 193 | if args.stack: 194 | stk=ida['stk_frame'] 195 | for i in stk: 196 | ofs = i+0xb if stk[i][0] == 6 else i+8 197 | instrument.inject_code(ofs, stk_snippet(stk[i][1])) 198 | 199 | # basic block instrument 200 | for i in ida['bb']: 201 | instrument.inject_code(i, bb_snippet(i-pe.OPTIONAL_HEADER.ImageBase)) 202 | 203 | # entry point instrument 204 | if args.entry: 205 | instrument.inject_code(pe.OPTIONAL_HEADER.AddressOfEntryPoint+pe.OPTIONAL_HEADER.ImageBase, args.entry.decode('hex')) 206 | 207 | instrument.end() 208 | 209 | -------------------------------------------------------------------------------- /remove_certificate.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import pefile 3 | import sys 4 | 5 | def go(fname): 6 | pe = pefile.PE(fname) 7 | d = pe.get_directory_by_name('IMAGE_DIRECTORY_ENTRY_SECURITY') 8 | assert d.VirtualAddress + d.Size == pe.get_length(), 'some overlays behind certificate' 9 | s = d.Size 10 | d.VirtualAddress = 0 11 | d.Size = 0 12 | name = fname[:-4]+'.no_certificate'+fname[-4:] 13 | pe.write(filename=name, cut=s) 14 | pe.close() 15 | return name 16 | 17 | if __name__ == '__main__': 18 | if len(sys.argv) != 2: 19 | print('Usage:', sys.argv[0], '') 20 | quit() 21 | go(sys.argv[1]) 22 | --------------------------------------------------------------------------------