|
3 | 3 | Main (Unicorn-)Harness, used alongside AFL.
|
4 | 4 | """
|
5 | 5 | import argparse
|
| 6 | +import gc |
6 | 7 | import os
|
7 | 8 | import sys
|
8 | 9 | import time
|
9 | 10 | from typing import Optional, Tuple, Dict, List
|
10 | 11 |
|
11 | 12 | from capstone import Cs
|
12 | 13 | from unicorn import *
|
13 |
| -from unicorn.x86_const import * |
14 | 14 |
|
15 | 15 | from unicorefuzz import x64utils
|
16 | 16 | from unicorefuzz.unicorefuzz import (
|
@@ -102,13 +102,21 @@ def harness(self, input_file: str, wait: bool, debug: bool, trace: bool) -> None
|
102 | 102 | :param debug: if we should enable unicorn debugger
|
103 | 103 | :param trace: trace or not
|
104 | 104 | """
|
| 105 | + |
| 106 | + # Exit without clean python vm shutdown: |
| 107 | + # "The os._exit() function can be used if it is absolutely positively necessary to exit immediately" |
| 108 | + # Many times faster! |
| 109 | + # noinspection PyProtectedMember |
| 110 | + exit_func = os._exit if not os.getenv("UCF_DEBUG_CLEAN_SHUTDOWN") else exit |
| 111 | + |
105 | 112 | uc, entry, exits = self.uc_init(
|
106 | 113 | input_file, wait, trace, verbose=(debug or trace)
|
107 | 114 | )
|
108 | 115 | if debug:
|
109 | 116 | self.uc_debug(uc, entry_point=entry, exit_point=exits[0])
|
110 | 117 | else:
|
111 | 118 | self.uc_run(uc, entry, exits[0])
|
| 119 | + exit_func(0) |
112 | 120 |
|
113 | 121 | def uc_init(
|
114 | 122 | self, input_file, wait: bool = False, trace: bool = False, verbose: bool = False
|
@@ -161,13 +169,25 @@ def uc_init(
|
161 | 169 | # On error: map memory, add exits.
|
162 | 170 | uc.hook_add(UC_HOOK_MEM_UNMAPPED, unicorn_debug_mem_invalid_access, self)
|
163 | 171 |
|
| 172 | + # import gc |
| 173 | + # gc.collect() |
| 174 | + if os.getenv("UCF_DEBUG_MEMORY"): |
| 175 | + from pympler import muppy, summary |
| 176 | + |
| 177 | + all_objects = muppy.get_objects() |
| 178 | + sum1 = summary.summarize(all_objects) |
| 179 | + summary.print_(sum1) |
| 180 | + |
164 | 181 | # Last chance to hook before forkserver starts (if running as afl child)
|
165 | 182 | debug_sleep = os.getenv("UCF_DEBUG_SLEEP_BEFORE_FORK")
|
166 | 183 | if debug_sleep:
|
167 | 184 | print(
|
168 | 185 | "[d] Sleeping. Forkserver will start in {} seconds.".format(debug_sleep)
|
169 | 186 | )
|
170 | 187 | time.sleep(float(debug_sleep))
|
| 188 | + |
| 189 | + gc.collect() |
| 190 | + |
171 | 191 | # starts the afl forkserver. Won't fork if afl is not around.
|
172 | 192 | self.uc_start_forkserver(uc, exits)
|
173 | 193 |
|
@@ -237,10 +257,6 @@ def uc_run(self, uc: Uc, entry_point: int, exit_point: int) -> None:
|
237 | 257 | )
|
238 | 258 | )
|
239 | 259 | self.force_crash(e)
|
240 |
| - # Exit without clean python vm shutdown: |
241 |
| - # "The os._exit() function can be used if it is absolutely positively necessary to exit immediately" |
242 |
| - # Many times faster! |
243 |
| - os._exit(0) |
244 | 260 |
|
245 | 261 | def map_known_mem(self, uc: Uc):
|
246 | 262 | """
|
|
0 commit comments