├── 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 |
--------------------------------------------------------------------------------