Remove AFL Integration by reverting

This commit is contained in:
lazymio
2021-10-26 11:22:21 +02:00
parent 7ac7c23c12
commit e695686c15
56 changed files with 46 additions and 2580 deletions

View File

@ -24,8 +24,8 @@ build:
$(MAKE) -C go gen_const
$(MAKE) -C java gen_const
$(MAKE) -C ruby gen_const
python3 const_generator.py dotnet
python3 const_generator.py pascal
python const_generator.py dotnet
python const_generator.py pascal
install: build
$(MAKE) -C python install

View File

@ -28,7 +28,6 @@ module Common =
let UC_MODE_LITTLE_ENDIAN = 0
let UC_MODE_BIG_ENDIAN = 1073741824
let UC_MODE_AFL = 536870912
let UC_MODE_ARM = 0
let UC_MODE_THUMB = 16
@ -76,10 +75,6 @@ module Common =
let UC_ERR_HOOK_EXIST = 19
let UC_ERR_RESOURCE = 20
let UC_ERR_EXCEPTION = 21
let UC_ERR_AFL_RET_ERROR = 22
let UC_ERR_AFL_RET_NO_AFL = 23
let UC_ERR_AFL_RET_CALLED_TWICE = 24
let UC_ERR_AFL_RET_FINISHED = 25
let UC_MEM_READ = 16
let UC_MEM_WRITE = 17
let UC_MEM_FETCH = 18

View File

@ -6,7 +6,7 @@ all: gen_const
cd unicorn && go build
gen_const:
cd .. && python3 const_generator.py go
cd .. && python const_generator.py go
test: all
cd unicorn && LD_LIBRARY_PATH=../../../ DYLD_LIBRARY_PATH=../../../ go test

View File

@ -23,7 +23,6 @@ const (
MODE_LITTLE_ENDIAN = 0
MODE_BIG_ENDIAN = 1073741824
MODE_AFL = 536870912
MODE_ARM = 0
MODE_THUMB = 16
@ -71,10 +70,6 @@ const (
ERR_HOOK_EXIST = 19
ERR_RESOURCE = 20
ERR_EXCEPTION = 21
ERR_AFL_RET_ERROR = 22
ERR_AFL_RET_NO_AFL = 23
ERR_AFL_RET_CALLED_TWICE = 24
ERR_AFL_RET_FINISHED = 25
MEM_READ = 16
MEM_WRITE = 17
MEM_FETCH = 18

View File

@ -19,7 +19,7 @@ uninstall:
$(MAKE) -f Makefile.build uninstall
gen_const:
cd .. && python3 const_generator.py java
cd .. && python const_generator.py java
clean:
rm -f unicorn/*.class

View File

@ -25,7 +25,6 @@ public interface UnicornConst {
public static final int UC_MODE_LITTLE_ENDIAN = 0;
public static final int UC_MODE_BIG_ENDIAN = 1073741824;
public static final int UC_MODE_AFL = 536870912;
public static final int UC_MODE_ARM = 0;
public static final int UC_MODE_THUMB = 16;
@ -73,10 +72,6 @@ public interface UnicornConst {
public static final int UC_ERR_HOOK_EXIST = 19;
public static final int UC_ERR_RESOURCE = 20;
public static final int UC_ERR_EXCEPTION = 21;
public static final int UC_ERR_AFL_RET_ERROR = 22;
public static final int UC_ERR_AFL_RET_NO_AFL = 23;
public static final int UC_ERR_AFL_RET_CALLED_TWICE = 24;
public static final int UC_ERR_AFL_RET_FINISHED = 25;
public static final int UC_MEM_READ = 16;
public static final int UC_MEM_WRITE = 17;
public static final int UC_MEM_FETCH = 18;

View File

@ -26,7 +26,6 @@ const UC_API_MAJOR = 2;
UC_MODE_LITTLE_ENDIAN = 0;
UC_MODE_BIG_ENDIAN = 1073741824;
UC_MODE_AFL = 536870912;
UC_MODE_ARM = 0;
UC_MODE_THUMB = 16;
@ -74,10 +73,6 @@ const UC_API_MAJOR = 2;
UC_ERR_HOOK_EXIST = 19;
UC_ERR_RESOURCE = 20;
UC_ERR_EXCEPTION = 21;
UC_ERR_AFL_RET_ERROR = 22;
UC_ERR_AFL_RET_NO_AFL = 23;
UC_ERR_AFL_RET_CALLED_TWICE = 24;
UC_ERR_AFL_RET_FINISHED = 25;
UC_MEM_READ = 16;
UC_MEM_WRITE = 17;
UC_MEM_FETCH = 18;

View File

@ -3,16 +3,16 @@
.PHONY: gen_const install install3 clean sdist sdist3 bdist bdist3 sdist_win bdist_win
gen_const:
cd .. && python3 const_generator.py python
cd .. && python const_generator.py python
install:
rm -rf src/ dist/
rm -rf prebuilt/win64/unicorn.dll
rm -rf prebuilt/win32/unicorn.dll
if test -n "${DESTDIR}"; then \
python3 setup.py install --root="${DESTDIR}"; \
python setup.py install --root="${DESTDIR}"; \
else \
python3 setup.py install; \
python setup.py install; \
fi
install3:
@ -30,7 +30,7 @@ sdist:
rm -rf src/ dist/
rm -rf prebuilt/win64/unicorn.dll
rm -rf prebuilt/win32/unicorn.dll
python3 setup.py sdist register upload
python setup.py sdist register upload
# build & upload PyPi package with source code of the core
sdist3:
@ -44,7 +44,7 @@ bdist:
rm -rf src/ dist/
rm -rf prebuilt/win64/unicorn.dll
rm -rf prebuilt/win32/unicorn.dll
python3 setup.py bdist_wheel register upload
python setup.py bdist_wheel register upload
# build & upload PyPi package with precompiled core
bdist3:
@ -57,7 +57,7 @@ bdist3:
# NOTE: be sure to have precompiled core under prebuilt/win*/ beforehand
sdist_win:
rm -rf src/ dist/
python3 setup.py sdist register upload
python setup.py sdist register upload
# build & upload PyPi package with prebuilt core
# NOTE: be sure to have precompiled core under prebuilt/win*/ beforehand

View File

@ -9,7 +9,7 @@ import os.path
import sys
import weakref
import functools
import gc
from . import x86_const, arm64_const, unicorn_const as uc
if not hasattr(sys.modules[__name__], "__file__"):
@ -120,15 +120,6 @@ class _uc_mem_region(ctypes.Structure):
("perms", ctypes.c_uint32),
]
#typedef bool (*uc_afl_cb_place_input_t)(uc_engine *uc, char *input,
# size_t input_len, uint32_t persistent_round, void *data);
AFL_PLACE_INPUT_CB = ctypes.CFUNCTYPE(ctypes.c_bool, uc_engine, ctypes.POINTER(ctypes.c_char),
ctypes.c_size_t, ctypes.c_uint32, ctypes.c_void_p)
#typedef bool (*uc_afl_cb_validate_crash_t)(uc_engine *uc, uc_err unicorn_result, char *input,
# int input_len, int persistent_round, void *data);
AFL_VALIDATE_CRASH_CB = ctypes.CFUNCTYPE(ctypes.c_bool, uc_engine, ucerr, ctypes.POINTER(ctypes.c_char),
ctypes.c_size_t, ctypes.c_uint32, ctypes.c_void_p)
_setup_prototype(_uc, "uc_version", ctypes.c_uint, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
_setup_prototype(_uc, "uc_arch_supported", ctypes.c_bool, ctypes.c_int)
@ -160,7 +151,6 @@ _setup_prototype(_uc, "uc_context_free", ucerr, uc_context)
_setup_prototype(_uc, "uc_mem_regions", ucerr, uc_engine, ctypes.POINTER(ctypes.POINTER(_uc_mem_region)), ctypes.POINTER(ctypes.c_uint32))
# https://bugs.python.org/issue42880
_setup_prototype(_uc, "uc_hook_add", ucerr, uc_engine, ctypes.POINTER(uc_hook_h), ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint64, ctypes.c_uint64)
_setup_prototype(_uc, "uc_afl_fuzz", ucerr, uc_engine, ctypes.c_char_p, ctypes.c_void_p, ctypes.POINTER(ctypes.c_uint64), ctypes.c_size_t, ctypes.c_void_p, ctypes.c_bool, ctypes.c_uint32, ctypes.c_void_p)
UC_HOOK_CODE_CB = ctypes.CFUNCTYPE(None, uc_engine, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_void_p)
UC_HOOK_INSN_INVALID_CB = ctypes.CFUNCTYPE(ctypes.c_bool, uc_engine, ctypes.c_void_p)
@ -421,8 +411,6 @@ class Uc(object):
self._callback_count = 0
self._cleanup.register(self)
self.afl_called_before = False # type: bool
@staticmethod
def release_handle(uch):
if uch:
@ -444,127 +432,6 @@ class Uc(object):
status = _uc.uc_emu_stop(self._uch)
if status != uc.UC_ERR_OK:
raise UcError(status)
def afl_fuzz(
self, # type: Uc
input_file, # type: str
place_input_callback, # type: Callable[[Uc, bytes, int, Any], Optional[bool]]
exits, # type: List[int]
validate_crash_callback=None, # type: Optional[Callable[[Uc, UcError, bytes, int, Any], Optional[bool]]]
always_validate=False, # type: bool
persistent_iters=1, # type: int
data=None, # type: Any
):
# type: (...) -> bool
"""
The main fuzzer.
Starts the forkserver, then beginns a persistent loop.
Reads input, calls the place_input callback, emulates, repeats.
If unicorn errors out, will call the validate_crash_callback, if set.
Will only return in the parent after the whole fuzz thing has been finished and afl died.
The child processes never return from here.
:param input_file: filename/path to the (AFL) inputfile. Usually supplied on the commandline.
:param place_input_callback: Callback function that will be called before each test runs.
This function needs to write the input from afl to the correct position on the unicorn object.
This function is mandatory.
It's purpose is to place the input at the right place in unicorn.
@uc: (Uc) Unicorn instance
@input: (bytes) The current input we're working on. Place this somewhere in unicorn's memory now.
@persistent_round: (int) which round we are currently crashing in, if using persistent mode.
@data: (Any) Data pointer passed to uc_afl_fuzz(...).
@return: (bool)
If you return is True (or None) all is well. Fuzzing starts.
If you return False, the input is rejected; we will continue with the next input.
:param exits: address list of exits where fuzzing should stop
:param persistent_iters:
The amount of loop iterations in persistent mode before restarting with a new forked child.
If your target cannot be fuzzed using persistent mode (global state changes a lot),
set persistent_iters = 1 for the normal fork-server experience.
Else, the default is usually around 1000.
If your target is super stable (and unicorn is, too - not sure about that one),
you may pass persistent_iter = 0 for that an infinite fuzz loop.
:param validate_crash_callback: Optional callback (if not needed, pass NULL), that determines
if a non-OK uc_err is an actual error. If false is returned, the test-case will not crash.
Callback function called after a non-UC_ERR_OK returncode was returned by Unicorn.
This function is not mandatory.
@uc: Unicorn instance
@unicorn_result: The error state returned by the current testcase
@input: The current input we're working with.
@persistent_round: which round we are currently crashing in, if using persistent mode.
@data: Data pointer passed to uc_afl_fuzz(...).
@Return:
If you return false, the crash is considered invalid and not reported to AFL.
-> Next loop iteration begins.
If return is true, the crash is reported // the program crashes.
-> The child will die and the forkserver will spawn a new child.
:param always_validate: If false, validate_crash_callback will only be called for crashes.
:param data: Your very own data pointer. This will passed into every callback.
:return:
True, if we fuzzed.
False, if AFL was not available but we ran once.
raises UcAflException if nothing worked.
"""
if self.afl_called_before:
raise UcError(uc.UC_ERR_AFL_RET_CALLED_TWICE)
self.afl_called_before = True
self._pre_afl()
exit_count = len(exits)
def place_input_wrapper(c_uc, input, input_len, persistent_round, c_data):
# print("Calling back home. :)", c_uc, input, input_len, persistent_round, c_data)
ret = place_input_callback(
self,
ctypes.cast(input, ctypes.POINTER(ctypes.c_char * input_len)).contents,
persistent_round,
data
)
if ret is False:
return False
return True
def validate_crash_wrapper(c_uc, uc_err, input, input_len, persistent_round, c_data):
# print("Calling after crash!", c_uc, input, input_len, persistent_round, c_data)
# assert type(uc_err) == int
ret = validate_crash_callback(
self,
UcError(uc_err),
ctypes.cast(input, ctypes.POINTER(ctypes.c_char * input_len)).contents,
persistent_round,
data
)
if ret is False or (ret is None and uc_err == uc.UC_ERR_OK):
return False
return True
# This only returns in the parent, child processes all die or loop or other things.
status = _uc.uc_afl_fuzz(
self._uch,
input_file.encode('utf-8'),
AFL_PLACE_INPUT_CB(place_input_wrapper),
(ctypes.c_uint64 * exit_count)(*exits),
exit_count, # bad languages, like c, need more params.
AFL_VALIDATE_CRASH_CB(validate_crash_wrapper) if validate_crash_callback else None,
always_validate,
persistent_iters,
None # no need to pass the user data through C as the callback keeps it as closure.
)
if status != uc.UC_ERR_OK:
# Something went wrong.
raise UcError(status)
def _pre_afl(self):
# type: (Uc) -> None
"""
Internal func making sure exits are set and flushing buffers/gc
:param exits: exits
"""
sys.stdout.flush() # otherwise children will inherit the unflushed buffer
gc.collect() # Collect all unneeded memory, No need to clone it on fork.
# return the value of a register
def reg_read(self, reg_id, opt=None):

View File

@ -21,7 +21,6 @@ UC_ARCH_MAX = 9
UC_MODE_LITTLE_ENDIAN = 0
UC_MODE_BIG_ENDIAN = 1073741824
UC_MODE_AFL = 536870912
UC_MODE_ARM = 0
UC_MODE_THUMB = 16
@ -69,10 +68,6 @@ UC_ERR_FETCH_UNALIGNED = 18
UC_ERR_HOOK_EXIST = 19
UC_ERR_RESOURCE = 20
UC_ERR_EXCEPTION = 21
UC_ERR_AFL_RET_ERROR = 22
UC_ERR_AFL_RET_NO_AFL = 23
UC_ERR_AFL_RET_CALLED_TWICE = 24
UC_ERR_AFL_RET_FINISHED = 25
UC_MEM_READ = 16
UC_MEM_WRITE = 17
UC_MEM_FETCH = 18

View File

@ -8,4 +8,4 @@ install: gen_const
cd unicorn_gem && gem install --local pkg/unicorn-engine-1.0.1.gem
gen_const:
cd .. && python3 const_generator.py ruby
cd .. && python const_generator.py ruby

View File

@ -23,7 +23,6 @@ module UnicornEngine
UC_MODE_LITTLE_ENDIAN = 0
UC_MODE_BIG_ENDIAN = 1073741824
UC_MODE_AFL = 536870912
UC_MODE_ARM = 0
UC_MODE_THUMB = 16
@ -71,10 +70,6 @@ module UnicornEngine
UC_ERR_HOOK_EXIST = 19
UC_ERR_RESOURCE = 20
UC_ERR_EXCEPTION = 21
UC_ERR_AFL_RET_ERROR = 22
UC_ERR_AFL_RET_NO_AFL = 23
UC_ERR_AFL_RET_CALLED_TWICE = 24
UC_ERR_AFL_RET_FINISHED = 25
UC_MEM_READ = 16
UC_MEM_WRITE = 17
UC_MEM_FETCH = 18