about summary refs log tree commit diff
path: root/frida_mode/src
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2021-06-28 09:14:00 +0200
committerGitHub <noreply@github.com>2021-06-28 09:14:00 +0200
commitcda62bab0837f1cbec2a1245de32b04a09e61af5 (patch)
treeea6df93d3c002ecc2e33c8b761fe5263eeb978e0 /frida_mode/src
parent7bcd4e290111ca81d6d58d1b70696e9e9aaa5ac1 (diff)
downloadafl++-cda62bab0837f1cbec2a1245de32b04a09e61af5.tar.gz
push to stable (#987)
* use atomic read-modify-write increment for LLVM CLASSIC

* Change other LLVM modes to atomic increments

* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* work in progress: not working correctly yet

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* still not working

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* first working NeverZero implementation

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382cab75832721d859c3e731da071435d.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382cab75832721d859c3e731da071435d commit that was
reverted.

* add some comments

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

* github workflow for qemu

* OSX-specific improvements (#912)

* Fix afl-cc to work correctly by default on OSX using xcode

- CLANG_ENV_VAR must be set for afl-as to work
- Use clang mode by default if no specific compiler selected

* Add OSX-specific documentation for configuring shared memory

* Fixes to memory operands for complog (#916)

Co-authored-by: Your Name <you@example.com>

* fix a few cur_time uses

* added bounds check to pivot_inputs (fixes #921)

* additional safety checks for restarts

* restrict afl-showmap in_file size

* fix seed crash disable

* add warning for afl-showmap partial read

* no core dumps

* AFL_PRINT_FILENAMES added

* more documentation for AFL_EXIT_ON_TIME

* Flushing for AFL_PRINT_FILENAMES

* FASAN Support (#918)

* FASAN Support

* Fix handling of Address Sanitizer DSO

* Changes to identification of Address Sanitizer DSO

Co-authored-by: Your Name <you@example.com>

* Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>

* Update frida_mode readme (#925)

* libqasan: use syscalls for read and write

* update readme

* Minor integration tweaks (#926)

Co-authored-by: Your Name <you@example.com>

* merge

* fix afl-fuzz.c frida preload

* cleaned up AFL_PRINT_FILENAMES env

* Changes to have persistent mode exit at the end of the loop (#928)

Co-authored-by: Your Name <you@example.com>

* fix llvm-dict2file

* push to stable (#931) (#932)

* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382cab75832721d859c3e731da071435d.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382cab75832721d859c3e731da071435d commit that was
reverted.

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

* github workflow for qemu

* OSX-specific improvements (#912)

* Fix afl-cc to work correctly by default on OSX using xcode

- CLANG_ENV_VAR must be set for afl-as to work
- Use clang mode by default if no specific compiler selected

* Add OSX-specific documentation for configuring shared memory

* Fixes to memory operands for complog (#916)

Co-authored-by: Your Name <you@example.com>

* fix a few cur_time uses

* added bounds check to pivot_inputs (fixes #921)

* additional safety checks for restarts

* restrict afl-showmap in_file size

* fix seed crash disable

* add warning for afl-showmap partial read

* no core dumps

* AFL_PRINT_FILENAMES added

* more documentation for AFL_EXIT_ON_TIME

* Flushing for AFL_PRINT_FILENAMES

* FASAN Support (#918)

* FASAN Support

* Fix handling of Address Sanitizer DSO

* Changes to identification of Address Sanitizer DSO

Co-authored-by: Your Name <you@example.com>

* Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>

* Update frida_mode readme (#925)

* libqasan: use syscalls for read and write

* update readme

* Minor integration tweaks (#926)

Co-authored-by: Your Name <you@example.com>

* merge

* fix afl-fuzz.c frida preload

* cleaned up AFL_PRINT_FILENAMES env

* Changes to have persistent mode exit at the end of the loop (#928)

Co-authored-by: Your Name <you@example.com>

* fix llvm-dict2file

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>

* improve error msg

* Added documentation for wine LoadLibrary workaround (#933)

* Fix cmake target compilation command example (#934)

- Fix typo DCMAKE_C_COMPILERC -> DCMAKE_C_COMPILER.
- Add `cd build` after `mkdir build`.

* showmap passes queue items in alphabetical order

* added tmp files to gitignore

* lenient dict parsing, no map size enum for binary fuzzing

* added info about showmap queue directions

* update binary-only doc

* turn off map size detection if skip_bin_check is set

* Typo

* update docs

* update afl-system-config

* Set kill signal before using it in afl-showmap (#935)

* fix afl-cc help output

* add libafl to binary-only doc

* update docs

* less executions on variable paths

* AFL_SKIP_CRASHES is obsolete since 3.0

* add AFL_TRY_AFFINITY

* Typo

* Typo

* Typo/wording

* tweaks

* typos

* fix afl-whatsup help output

* fix afl-plot output

* fix for MacOS

* fix cmpcov doc for qemu

* fix tmpfile removal

* update dockerfile

* Frida (#940)

* Added re2 test

* Added libpcap test

* Fix validation of setting of ADDR_NO_RANDOMIZE

* Added support for printing original and instrumented code

Co-authored-by: Your Name <you@example.com>

* Support for AFL_FRIDA_PERSISTENT_RET (#941)

Co-authored-by: Your Name <you@example.com>

* Changes to add missing exclusion of ranges (#943)

Co-authored-by: Your Name <you@example.com>

* add --afl-noopt to afl-cc

* docs: fix link to README in QuickStartGuide (#946)

* Support writing Stalker stats (#945)

* Support writing Stalker stats

* Fixed string handling in print functions

Co-authored-by: Your Name <you@example.com>

* afl-cmin help fix, aflpp_driver - + @@ support

* fix for afl-showmap

* support new env var AFL_LLVM_THREADSAFE_INST to enable atomic counters.
add new test case for that.

* add documentation for AFL_LLVM_THREADSAFE_INST

* add support for AFL_LLVM_THREADSAFE_INST to other LLVM passes

* add missing include for _exit()

* threadsafe doc fixes, code format

* Wording: "never zero" -> NeverZero

* fix afl_custom_post_process with multiple custom mutators

* fix docs

* debug ck_write

* fixed potential diff by 0

* fixes

* fix classic threadsafe counters

* v3.13c release

* back push (#952)

* Dev (#949)

* use atomic read-modify-write increment for LLVM CLASSIC

* Change other LLVM modes to atomic increments

* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* work in progress: not working correctly yet

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* still not working

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* first working NeverZero implementation

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382cab75832721d859c3e731da071435d.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382cab75832721d859c3e731da071435d commit that was
reverted.

* add some comments

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

* github workflow for qemu

* OSX-specific improvements (#912)

* Fix afl-cc to work correctly by default on OSX using xcode

- CLANG_ENV_VAR must be set for afl-as to work
- Use clang mode by default if no specific compiler selected

* Add OSX-specific documentation for configuring shared memory

* Fixes to memory operands for complog (#916)

Co-authored-by: Your Name <you@example.com>

* fix a few cur_time uses

* added bounds check to pivot_inputs (fixes #921)

* additional safety checks for restarts

* restrict afl-showmap in_file size

* fix seed crash disable

* add warning for afl-showmap partial read

* no core dumps

* AFL_PRINT_FILENAMES added

* more documentation for AFL_EXIT_ON_TIME

* Flushing for AFL_PRINT_FILENAMES

* FASAN Support (#918)

* FASAN Support

* Fix handling of Address Sanitizer DSO

* Changes to identification of Address Sanitizer DSO

Co-authored-by: Your Name <you@example.com>

* Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>

* Update frida_mode readme (#925)

* libqasan: use syscalls for read and write

* update readme

* Minor integration tweaks (#926)

Co-authored-by: Your Name <you@example.com>

* merge

* fix afl-fuzz.c frida preload

* cleaned up AFL_PRINT_FILENAMES env

* Changes to have persistent mode exit at the end of the loop (#928)

Co-authored-by: Your Name <you@example.com>

* fix llvm-dict2file

* push to stable (#931) (#932)

* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382cab75832721d859c3e731da071435d.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382cab75832721d859c3e731da071435d commit that was
reverted.

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

* github workflow for qemu

* OSX-specific improvements (#912)

* Fix afl-cc to work correctly by default on OSX using xcode

- CLANG_ENV_VAR must be set for afl-as to work
- Use clang mode by default if no specific compiler selected

* Add OSX-specific documentation for configuring shared memory

* Fixes to memory operands for complog (#916)

Co-authored-by: Your Name <you@example.com>

* fix a few cur_time uses

* added bounds check to pivot_inputs (fixes #921)

* additional safety checks for restarts

* restrict afl-showmap in_file size

* fix seed crash disable

* add warning for afl-showmap partial read

* no core dumps

* AFL_PRINT_FILENAMES added

* more documentation for AFL_EXIT_ON_TIME

* Flushing for AFL_PRINT_FILENAMES

* FASAN Support (#918)

* FASAN Support

* Fix handling of Address Sanitizer DSO

* Changes to identification of Address Sanitizer DSO

Co-authored-by: Your Name <you@example.com>

* Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>

* Update frida_mode readme (#925)

* libqasan: use syscalls for read and write

* update readme

* Minor integration tweaks (#926)

Co-authored-by: Your Name <you@example.com>

* merge

* fix afl-fuzz.c frida preload

* cleaned up AFL_PRINT_FILENAMES env

* Changes to have persistent mode exit at the end of the loop (#928)

Co-authored-by: Your Name <you@example.com>

* fix llvm-dict2file

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>

* improve error msg

* Added documentation for wine LoadLibrary workaround (#933)

* Fix cmake target compilation command example (#934)

- Fix typo DCMAKE_C_COMPILERC -> DCMAKE_C_COMPILER.
- Add `cd build` after `mkdir build`.

* showmap passes queue items in alphabetical order

* added tmp files to gitignore

* lenient dict parsing, no map size enum for binary fuzzing

* added info about showmap queue directions

* update binary-only doc

* turn off map size detection if skip_bin_check is set

* Typo

* update docs

* update afl-system-config

* Set kill signal before using it in afl-showmap (#935)

* fix afl-cc help output

* add libafl to binary-only doc

* update docs

* less executions on variable paths

* AFL_SKIP_CRASHES is obsolete since 3.0

* add AFL_TRY_AFFINITY

* Typo

* Typo

* Typo/wording

* tweaks

* typos

* fix afl-whatsup help output

* fix afl-plot output

* fix for MacOS

* fix cmpcov doc for qemu

* fix tmpfile removal

* update dockerfile

* Frida (#940)

* Added re2 test

* Added libpcap test

* Fix validation of setting of ADDR_NO_RANDOMIZE

* Added support for printing original and instrumented code

Co-authored-by: Your Name <you@example.com>

* Support for AFL_FRIDA_PERSISTENT_RET (#941)

Co-authored-by: Your Name <you@example.com>

* Changes to add missing exclusion of ranges (#943)

Co-authored-by: Your Name <you@example.com>

* add --afl-noopt to afl-cc

* docs: fix link to README in QuickStartGuide (#946)

* Support writing Stalker stats (#945)

* Support writing Stalker stats

* Fixed string handling in print functions

Co-authored-by: Your Name <you@example.com>

* afl-cmin help fix, aflpp_driver - + @@ support

* fix for afl-showmap

* support new env var AFL_LLVM_THREADSAFE_INST to enable atomic counters.
add new test case for that.

* add documentation for AFL_LLVM_THREADSAFE_INST

* add support for AFL_LLVM_THREADSAFE_INST to other LLVM passes

* add missing include for _exit()

* threadsafe doc fixes, code format

* Wording: "never zero" -> NeverZero

* fix afl_custom_post_process with multiple custom mutators

* fix docs

* debug ck_write

* fixed potential diff by 0

* fixes

* fix classic threadsafe counters

Co-authored-by: van Hauser <vh@thc.org>
Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>
Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com>
Co-authored-by: Tommy Chiang <oToToT@users.noreply.github.com>
Co-authored-by: buherator <buherator@silentsignal.hu>
Co-authored-by: Dag Heyman Kajevic <dag.heyman@gmail.com>

* v3.13c release (#950)

* use atomic read-modify-write increment for LLVM CLASSIC

* Change other LLVM modes to atomic increments

* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* work in progress: not working correctly yet

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* still not working

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* first working NeverZero implementation

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382cab75832721d859c3e731da071435d.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382cab75832721d859c3e731da071435d commit that was
reverted.

* add some comments

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

* github workflow for qemu

* OSX-specific improvements (#912)

* Fix afl-cc to work correctly by default on OSX using xcode

- CLANG_ENV_VAR must be set for afl-as to work
- Use clang mode by default if no specific compiler selected

* Add OSX-specific documentation for configuring shared memory

* Fixes to memory operands for complog (#916)

Co-authored-by: Your Name <you@example.com>

* fix a few cur_time uses

* added bounds check to pivot_inputs (fixes #921)

* additional safety checks for restarts

* restrict afl-showmap in_file size

* fix seed crash disable

* add warning for afl-showmap partial read

* no core dumps

* AFL_PRINT_FILENAMES added

* more documentation for AFL_EXIT_ON_TIME

* Flushing for AFL_PRINT_FILENAMES

* FASAN Support (#918)

* FASAN Support

* Fix handling of Address Sanitizer DSO

* Changes to identification of Address Sanitizer DSO

Co-authored-by: Your Name <you@example.com>

* Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>

* Update frida_mode readme (#925)

* libqasan: use syscalls for read and write

* update readme

* Minor integration tweaks (#926)

Co-authored-by: Your Name <you@example.com>

* merge

* fix afl-fuzz.c frida preload

* cleaned up AFL_PRINT_FILENAMES env

* Changes to have persistent mode exit at the end of the loop (#928)

Co-authored-by: Your Name <you@example.com>

* fix llvm-dict2file

* push to stable (#931) (#932)

* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382cab75832721d859c3e731da071435d.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382cab75832721d859c3e731da071435d commit that was
reverted.

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

* github workflow for qemu

* OSX-specific improvements (#912)

* Fix afl-cc to work correctly by default on OSX using xcode

- CLANG_ENV_VAR must be set for afl-as to work
- Use clang mode by default if no specific compiler selected

* Add OSX-specific documentation for configuring shared memory

* Fixes to memory operands for complog (#916)

Co-authored-by: Your Name <you@example.com>

* fix a few cur_time uses

* added bounds check to pivot_inputs (fixes #921)

* additional safety checks for restarts

* restrict afl-showmap in_file size

* fix seed crash disable

* add warning for afl-showmap partial read

* no core dumps

* AFL_PRINT_FILENAMES added

* more documentation for AFL_EXIT_ON_TIME

* Flushing for AFL_PRINT_FILENAMES

* FASAN Support (#918)

* FASAN Support

* Fix handling of Address Sanitizer DSO

* Changes to identification of Address Sanitizer DSO

Co-authored-by: Your Name <you@example.com>

* Support for x86 (#920)

Co-authored-by: Your Name <you@example.com>

* Update frida_mode readme (#925)

* libqasan: use syscalls for read and write

* update readme

* Minor integration tweaks (#926)

Co-authored-by: Your Name <you@example.com>

* merge

* fix afl-fuzz.c frida preload

* cleaned up AFL_PRINT_FILENAMES env

* Changes to have persistent mode exit at the end of the loop (#928)

Co-authored-by: Your Name <you@example.com>

* fix llvm-dict2file

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>

* improve error msg

* Added documentation for wine LoadLibrary workaround (#933)

* Fix cmake target compilation command example (#934)

- Fix typo DCMAKE_C_COMPILERC -> DCMAKE_C_COMPILER.
- Add `cd build` after `mkdir build`.

* showmap passes queue items in alphabetical order

* added tmp files to gitignore

* lenient dict parsing, no map size enum for binary fuzzing

* added info about showmap queue directions

* update binary-only doc

* turn off map size detection if skip_bin_check is set

* Typo

* update docs

* update afl-system-config

* Set kill signal before using it in afl-showmap (#935)

* fix afl-cc help output

* add libafl to binary-only doc

* update docs

* less executions on variable paths

* AFL_SKIP_CRASHES is obsolete since 3.0

* add AFL_TRY_AFFINITY

* Typo

* Typo

* Typo/wording

* tweaks

* typos

* fix afl-whatsup help output

* fix afl-plot output

* fix for MacOS

* fix cmpcov doc for qemu

* fix tmpfile removal

* update dockerfile

* Frida (#940)

* Added re2 test

* Added libpcap test

* Fix validation of setting of ADDR_NO_RANDOMIZE

* Added support for printing original and instrumented code

Co-authored-by: Your Name <you@example.com>

* Support for AFL_FRIDA_PERSISTENT_RET (#941)

Co-authored-by: Your Name <you@example.com>

* Changes to add missing exclusion of ranges (#943)

Co-authored-by: Your Name <you@example.com>

* add --afl-noopt to afl-cc

* docs: fix link to README in QuickStartGuide (#946)

* Support writing Stalker stats (#945)

* Support writing Stalker stats

* Fixed string handling in print functions

Co-authored-by: Your Name <you@example.com>

* afl-cmin help fix, aflpp_driver - + @@ support

* fix for afl-showmap

* support new env var AFL_LLVM_THREADSAFE_INST to enable atomic counters.
add new test case for that.

* add documentation for AFL_LLVM_THREADSAFE_INST

* add support for AFL_LLVM_THREADSAFE_INST to other LLVM passes

* add missing include for _exit()

* threadsafe doc fixes, code format

* Wording: "never zero" -> NeverZero

* fix afl_custom_post_process with multiple custom mutators

* fix docs

* debug ck_write

* fixed potential diff by 0

* fixes

* fix classic threadsafe counters

* v3.13c release

Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>
Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com>
Co-authored-by: Tommy Chiang <oToToT@users.noreply.github.com>
Co-authored-by: buherator <buherator@silentsignal.hu>
Co-authored-by: Dag Heyman Kajevic <dag.heyman@gmail.com>

Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>
Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com>
Co-authored-by: Tommy Chiang <oToToT@users.noreply.github.com>
Co-authored-by: buherator <buherator@silentsignal.hu>
Co-authored-by: Dag Heyman Kajevic <dag.heyman@gmail.com>
Co-authored-by: hexcoder- <heiko@hexco.de>

* v3.14a init

* remove redundant unsetenv (#947)

* update MacOS Install information

* add missing clean action for frida_mode

* ensure memory is there before free

* adapt to incompatible LLVM 13 API

* fix stupid typos

* add fix info

* build afl-compiler-rt even with broken llvm

* fix -F with slash option

* dynamic_list and afl-compiler-rt rework

* detect partial linking in afl-cc

* partial linking with -Wl

* Add proper name and URL for Zafl (#959)

* move link

* add known frontends for supported compiler infrastructures

* add Rust

* fix ui fuzzing stage index (#960)

* fix overflowing UI fields 'now processing'

* restored timeout handling (with SIGALRM for now)

* On non-Linux systems make clean may fail for frida_mode

* give hint how to set env var for path to llvm-config tool

* setting AFL_CC for test-llvm.sh on FreeBSD is not necessary anymore

* remove -D from -M

* write target errors to out_dir/error.txt

* add changelog entry

* add changelog

* format

* more info for error logging

* Forkserver for afl-analyze (#963)

* afl-analyze forkserver

* added missing vars to forkserver

* synchronized a bit more with afl-tmin

* more debugging, runs now, but need to suppress target output

* fix dev/null setting

* afl-analyze info:

Co-authored-by: hexcoder- <heiko@hexco.de>

* proper newlines

* reenable LLVM 3.8 ( Ubuntu 16.04 )

* FRIDA AARCH64 support (#965)

Co-authored-by: Your Name <you@example.com>

* adapt docs to minimum LLVM version

* adapt to minimum llvm version

* remove warning regarding core_pattern (was wrong/unnecessary anyway)

* avoid code duplication, symlink header file

* clippy fixes

* add test cases for splitting integer comparisons

* Revert "add test cases for splitting integer comparisons"

This reverts commit e0aa411647e1a525a3a0488d929ec71611388d54.

* add test cases for splitting integer comparisons

* FRIDA - Remove need for AFL_FRIDA_PERSISTENT_RETADDR_OFFSET (#970)

Co-authored-by: Your Name <you@example.com>

* fix AFL_CAL_FAST

* fix cmplog screen update crash

* Frida complog fix (#971)

* Fix complog issue with changing address space

* Added support for printing command line and environment during startup

* Review fixes

Co-authored-by: Your Name <you@example.com>

* Improve tracing support to include real addresses and edge ids and also support logging edges only once (#972)

Co-authored-by: Your Name <you@example.com>

* split-comparison llvm pass refactor for smaller compilation times (and a small bug fix) (#964)

* Refactored split compare pass to be more efficient in LTO usage and allow splitting to other minimum bitwidths.

Efficiency: avoid looping over the whole llvm module N times, when once is also enough.

Bitwidth: Previously, due to fallthrough in switch-case, all comparisons were split to 8-bit, which might not be desirable e.g., 16 or 32 bit might be enough. So now all comparison are split until they are smaller or equal to the target bitwidth, which is controlled through the `AFL_LLVM_LAF_SPLIT_COMPARES_BITW` environment variable.

* fixed miscompilation due to incorrectly trying to split a signed comparison operator

* minor formatting updates and use IRBuilder when inserting multiple instructions

* added @hexcoder-'s test-int_cases.c to make test

* Avoid recursion; switch to smallvector in splitAndSimplify; use switch case for icmp type;

* Fixed issue when splitting < where the inverse comparison was not further split

* some cleanup

* code format

* fix to instrument global c++ namespace functions

* update changelog

* document frida changes

* Fix typo in README.md (#974)

* adapt for LLVM 3.8.0

* fix README

* little inline

* Add debug output to alert user to calibration progress/issues (#969)

* aflppdriver help output

* code format

* afl-cmin/afl-cmin.bash/afl-showmap -i descend into subdirectories

* make afl-cmin actually work with subdirectories

* correct map size for small targets

* Perf regression4 (#979)

* Added test for libjpeg

* Added proj4 test

* Added missing members to x86/64 context

* Changes to use memfd and hashtable cache

* Removed redundant check

Co-authored-by: Your Name <you@example.com>

* improve documentation

* typo

* reverse read the queue n resumes

* frida fix

* cmplog fix for qemu and frida

* Misc (#986)

* Changes to fix accidental ranges deletion and add support for SCAS/CMPS

* Fix syscall issues on OSX

* Changes to more closely match QEMU mode

* Changes to use double hashing on cmplog

* Changes to use msync

* Review changes

Co-authored-by: Your Name <you@example.com>

* force disable llvm instrumentation for frida

* non-unix compat

* fix afl-showmap

* frida fix

* fix frida

* rust bindings update

* rust bindings update

* Added JS support (#992)

* Added JS support

* Added some documentation

Co-authored-by: Your Name <you@example.com>

* unicorn rust bindings improvements

* typo

* updated uc rust bindings

* test laf splitting: set default for char type explicitly to signed

* Improved FRIDA mode scripting support (#994)

Co-authored-by: Your Name <you@example.com>

* Select (#995)

* favor unfuzzed

* fix

* reinit table after a new fuzz

Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Co-authored-by: Dustin Spicuzza <dustin@virtualroadside.com>
Co-authored-by: 0x4d5a-ctf <51098072+0x4d5a-ctf@users.noreply.github.com>
Co-authored-by: Tommy Chiang <oToToT@users.noreply.github.com>
Co-authored-by: buherator <buherator@silentsignal.hu>
Co-authored-by: Dag Heyman Kajevic <dag.heyman@gmail.com>
Co-authored-by: terrynini <terrynini38514@gmail.com>
Co-authored-by: jdhiser <hiser@virginia.edu>
Co-authored-by: yuan <ssspeed00@gmail.com>
Co-authored-by: Michael Rodler <michael.rodler@paluno.uni-due.de>
Co-authored-by: Artis <32833063+Artis24106@users.noreply.github.com>
Diffstat (limited to 'frida_mode/src')
-rw-r--r--frida_mode/src/asan/asan.c21
-rw-r--r--frida_mode/src/asan/asan_arm32.c2
-rw-r--r--frida_mode/src/asan/asan_arm64.c2
-rw-r--r--frida_mode/src/asan/asan_x64.c2
-rw-r--r--frida_mode/src/asan/asan_x86.c2
-rw-r--r--frida_mode/src/cmplog/cmplog.c156
-rw-r--r--frida_mode/src/cmplog/cmplog_arm32.c2
-rw-r--r--frida_mode/src/cmplog/cmplog_arm64.c2
-rw-r--r--frida_mode/src/cmplog/cmplog_x64.c24
-rw-r--r--frida_mode/src/cmplog/cmplog_x86.c2
-rw-r--r--frida_mode/src/ctx/ctx_arm32.c2
-rw-r--r--frida_mode/src/ctx/ctx_arm64.c2
-rw-r--r--frida_mode/src/ctx/ctx_x64.c24
-rw-r--r--frida_mode/src/ctx/ctx_x86.c8
-rw-r--r--frida_mode/src/entry.c20
-rw-r--r--frida_mode/src/instrument/instrument.c77
-rw-r--r--frida_mode/src/instrument/instrument_arm32.c2
-rw-r--r--frida_mode/src/instrument/instrument_arm64.c4
-rw-r--r--frida_mode/src/instrument/instrument_debug.c23
-rw-r--r--frida_mode/src/instrument/instrument_x64.c4
-rw-r--r--frida_mode/src/instrument/instrument_x86.c4
-rw-r--r--frida_mode/src/intercept.c (renamed from frida_mode/src/interceptor.c)12
-rw-r--r--frida_mode/src/js/api.js243
-rw-r--r--frida_mode/src/js/js.c122
-rw-r--r--frida_mode/src/js/js_api.c152
-rw-r--r--frida_mode/src/lib/lib.c6
-rw-r--r--frida_mode/src/lib/lib_apple.c6
-rw-r--r--frida_mode/src/main.c59
-rw-r--r--frida_mode/src/output.c28
-rw-r--r--frida_mode/src/persistent/persistent.c65
-rw-r--r--frida_mode/src/persistent/persistent_arm32.c2
-rw-r--r--frida_mode/src/persistent/persistent_arm64.c405
-rw-r--r--frida_mode/src/persistent/persistent_x64.c180
-rw-r--r--frida_mode/src/persistent/persistent_x86.c117
-rw-r--r--frida_mode/src/prefetch.c37
-rw-r--r--frida_mode/src/ranges.c120
-rw-r--r--frida_mode/src/stalker.c31
-rw-r--r--frida_mode/src/stats/stats.c33
-rw-r--r--frida_mode/src/stats/stats_arm32.c2
-rw-r--r--frida_mode/src/stats/stats_arm64.c2
-rw-r--r--frida_mode/src/stats/stats_x64.c2
-rw-r--r--frida_mode/src/stats/stats_x86.c2
42 files changed, 1283 insertions, 728 deletions
diff --git a/frida_mode/src/asan/asan.c b/frida_mode/src/asan/asan.c
index f78f690c..b2e763ca 100644
--- a/frida_mode/src/asan/asan.c
+++ b/frida_mode/src/asan/asan.c
@@ -1,18 +1,18 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
 #include "asan.h"
 
-gboolean asan_initialized = FALSE;
+static gboolean asan_enabled = FALSE;
+gboolean        asan_initialized = FALSE;
 
-void asan_init(void) {
+void asan_config(void) {
 
   if (getenv("AFL_USE_FASAN") != NULL) {
 
     OKF("Frida ASAN mode enabled");
-    asan_arch_init();
-    asan_initialized = TRUE;
+    asan_enabled = TRUE;
 
   } else {
 
@@ -22,3 +22,14 @@ void asan_init(void) {
 
 }
 
+void asan_init(void) {
+
+  if (asan_enabled) {
+
+    asan_arch_init();
+    asan_initialized = TRUE;
+
+  }
+
+}
+
diff --git a/frida_mode/src/asan/asan_arm32.c b/frida_mode/src/asan/asan_arm32.c
index 79475ced..f5fa4713 100644
--- a/frida_mode/src/asan/asan_arm32.c
+++ b/frida_mode/src/asan/asan_arm32.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
diff --git a/frida_mode/src/asan/asan_arm64.c b/frida_mode/src/asan/asan_arm64.c
index 66138e42..65524e03 100644
--- a/frida_mode/src/asan/asan_arm64.c
+++ b/frida_mode/src/asan/asan_arm64.c
@@ -1,5 +1,5 @@
 #include <dlfcn.h>
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
diff --git a/frida_mode/src/asan/asan_x64.c b/frida_mode/src/asan/asan_x64.c
index a2eabe3c..5c12669f 100644
--- a/frida_mode/src/asan/asan_x64.c
+++ b/frida_mode/src/asan/asan_x64.c
@@ -1,5 +1,5 @@
 #include <dlfcn.h>
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
diff --git a/frida_mode/src/asan/asan_x86.c b/frida_mode/src/asan/asan_x86.c
index 8490b490..6d2f9e2b 100644
--- a/frida_mode/src/asan/asan_x86.c
+++ b/frida_mode/src/asan/asan_x86.c
@@ -1,5 +1,5 @@
 #include <dlfcn.h>
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
diff --git a/frida_mode/src/cmplog/cmplog.c b/frida_mode/src/cmplog/cmplog.c
index 3df7d13d..a2609c8e 100644
--- a/frida_mode/src/cmplog/cmplog.c
+++ b/frida_mode/src/cmplog/cmplog.c
@@ -1,27 +1,32 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
-#include <syscall.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <unistd.h>
 
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
 #include "util.h"
 
 #define DEFAULT_MMAP_MIN_ADDR (32UL << 10)
-#define FD_TMP_MAX_SIZE 65536
+#define MAX_MEMFD_SIZE (64UL << 10)
 
 extern struct cmp_map *__afl_cmp_map;
+static GArray *        cmplog_ranges = NULL;
+static GHashTable *    hash_yes = NULL;
+static GHashTable *    hash_no = NULL;
 
-static GArray *cmplog_ranges = NULL;
-static int     fd_tmp = -1;
-static ssize_t fd_tmp_size = 0;
+static long page_size = 0;
+static long page_offset_mask = 0;
+static long page_mask = 0;
 
 static gboolean cmplog_range(const GumRangeDetails *details,
                              gpointer               user_data) {
 
-  UNUSED_PARAMETER(user_data);
+  GArray *       cmplog_ranges = (GArray *)user_data;
   GumMemoryRange range = *details->range;
   g_array_append_val(cmplog_ranges, range);
   return TRUE;
@@ -35,70 +40,98 @@ static gint cmplog_sort(gconstpointer a, gconstpointer b) {
 
 }
 
-static int cmplog_create_temp(void) {
+static void cmplog_get_ranges(void) {
 
-  const char *tmpdir = g_get_tmp_dir();
-  OKF("CMPLOG Temporary directory: %s", tmpdir);
-  gchar *fname = g_strdup_printf("%s/frida-cmplog-XXXXXX", tmpdir);
-  OKF("CMPLOG Temporary file template: %s", fname);
-  int fd = mkstemp(fname);
-  OKF("CMPLOG Temporary file: %s", fname);
+  OKF("CMPLOG - Collecting ranges");
 
-  if (fd < 0) {
+  cmplog_ranges = g_array_sized_new(false, false, sizeof(GumMemoryRange), 100);
+  gum_process_enumerate_ranges(GUM_PAGE_READ, cmplog_range, cmplog_ranges);
+  g_array_sort(cmplog_ranges, cmplog_sort);
 
-    FATAL("Failed to create temp file: %s, errno: %d", fname, errno);
+}
 
-  }
+void cmplog_config(void) {
 
-  if (unlink(fname) < 0) {
+}
+
+void cmplog_init(void) {
 
-    FATAL("Failed to unlink temp file: %s (%d), errno: %d", fname, fd, errno);
+  if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); }
+
+  cmplog_get_ranges();
+
+  for (guint i = 0; i < cmplog_ranges->len; i++) {
+
+    GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i);
+    OKF("CMPLOG Range - %3u: 0x%016" G_GINT64_MODIFIER
+        "X - 0x%016" G_GINT64_MODIFIER "X",
+        i, range->base_address, range->base_address + range->size);
 
   }
 
-  if (ftruncate(fd, 0) < 0) {
+  page_size = sysconf(_SC_PAGE_SIZE);
+  page_offset_mask = page_size - 1;
+  page_mask = ~(page_offset_mask);
+
+  hash_yes = g_hash_table_new(g_direct_hash, g_direct_equal);
+  if (hash_yes == NULL) {
 
-    FATAL("Failed to ftruncate temp file: %s (%d), errno: %d", fname, fd,
-          errno);
+    FATAL("Failed to g_hash_table_new, errno: %d", errno);
 
   }
 
-  g_free(fname);
+  hash_no = g_hash_table_new(g_direct_hash, g_direct_equal);
+  if (hash_no == NULL) {
+
+    FATAL("Failed to g_hash_table_new, errno: %d", errno);
 
-  return fd;
+  }
 
 }
 
-void cmplog_init(void) {
+static gboolean cmplog_contains(GumAddress inner_base, GumAddress inner_limit,
+                                GumAddress outer_base, GumAddress outer_limit) {
 
-  if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); }
+  return (inner_base >= outer_base && inner_limit <= outer_limit);
 
-  cmplog_ranges = g_array_sized_new(false, false, sizeof(GumMemoryRange), 100);
-  gum_process_enumerate_ranges(GUM_PAGE_READ, cmplog_range, NULL);
-  g_array_sort(cmplog_ranges, cmplog_sort);
+}
 
-  for (guint i = 0; i < cmplog_ranges->len; i++) {
+gboolean cmplog_test_addr(guint64 addr, size_t size) {
 
-    GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i);
-    OKF("CMPLOG Range - 0x%016" G_GINT64_MODIFIER "X - 0x%016" G_GINT64_MODIFIER
-        "X",
-        range->base_address, range->base_address + range->size);
+  if (g_hash_table_contains(hash_yes, GSIZE_TO_POINTER(addr))) { return true; }
+  if (g_hash_table_contains(hash_no, GSIZE_TO_POINTER(addr))) { return false; }
 
-  }
+  void * page_addr = GSIZE_TO_POINTER(addr & page_mask);
+  size_t page_offset = addr & page_offset_mask;
+
+  /* If it spans a page, then bail */
+  if (page_size - page_offset < size) { return false; }
 
   /*
-   * We can't use /dev/null or /dev/zero for this since it appears that they
-   * don't validate the input buffer. Persumably as an optimization because they
-   * don't actually write any data. The file will be deleted on close.
+   * Our address map can change (e.g. stack growth), use msync as a fallback to
+   * validate our address.
    */
-  fd_tmp = cmplog_create_temp();
+  if (msync(page_addr, page_offset + size, MS_ASYNC) < 0) {
 
-}
+    if (!g_hash_table_add(hash_no, GSIZE_TO_POINTER(addr))) {
 
-static gboolean cmplog_contains(GumAddress inner_base, GumAddress inner_limit,
-                                GumAddress outer_base, GumAddress outer_limit) {
+      FATAL("Failed - g_hash_table_add");
 
-  return (inner_base >= outer_base && inner_limit <= outer_limit);
+    }
+
+    return false;
+
+  } else {
+
+    if (!g_hash_table_add(hash_yes, GSIZE_TO_POINTER(addr))) {
+
+      FATAL("Failed - g_hash_table_add");
+
+    }
+
+    return true;
+
+  }
 
 }
 
@@ -125,45 +158,16 @@ gboolean cmplog_is_readable(guint64 addr, size_t size) {
   for (guint i = 0; i < cmplog_ranges->len; i++) {
 
     GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i);
-    GumAddress      outer_base = range->base_address;
-    GumAddress      outer_limit = outer_base + range->size;
+
+    GumAddress outer_base = range->base_address;
+    GumAddress outer_limit = outer_base + range->size;
 
     if (cmplog_contains(inner_base, inner_limit, outer_base, outer_limit))
       return true;
 
   }
 
-  /*
-   * Our address map can change (e.g. stack growth), use write as a fallback to
-   * validate our address.
-   */
-  ssize_t written = syscall(__NR_write, fd_tmp, (void *)addr, size);
-
-  /*
-   * If the write succeeds, then the buffer must be valid otherwise it would
-   * return EFAULT
-   */
-  if (written > 0) {
-
-    fd_tmp_size += written;
-    if (fd_tmp_size > FD_TMP_MAX_SIZE) {
-
-      /*
-       * Truncate the file, we don't want our temp file to continue growing!
-       */
-      if (ftruncate(fd_tmp, 0) < 0) {
-
-        FATAL("Failed to truncate fd_tmp (%d), errno: %d", fd_tmp, errno);
-
-      }
-
-      fd_tmp_size = 0;
-
-    }
-
-    if ((size_t)written == size) { return true; }
-
-  }
+  if (cmplog_test_addr(addr, size)) { return true; }
 
   return false;
 
diff --git a/frida_mode/src/cmplog/cmplog_arm32.c b/frida_mode/src/cmplog/cmplog_arm32.c
index 5af28f3f..ac703408 100644
--- a/frida_mode/src/cmplog/cmplog_arm32.c
+++ b/frida_mode/src/cmplog/cmplog_arm32.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
diff --git a/frida_mode/src/cmplog/cmplog_arm64.c b/frida_mode/src/cmplog/cmplog_arm64.c
index 04631ff8..dd97f38d 100644
--- a/frida_mode/src/cmplog/cmplog_arm64.c
+++ b/frida_mode/src/cmplog/cmplog_arm64.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 #include "cmplog.h"
diff --git a/frida_mode/src/cmplog/cmplog_x64.c b/frida_mode/src/cmplog/cmplog_x64.c
index 9f56c32a..0d18767a 100644
--- a/frida_mode/src/cmplog/cmplog_x64.c
+++ b/frida_mode/src/cmplog/cmplog_x64.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 #include "cmplog.h"
@@ -177,7 +177,7 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
   register uintptr_t k = (uintptr_t)address;
 
   k = (k >> 4) ^ (k << 8);
-  k &= CMP_MAP_W - 1;
+  k &= CMP_MAP_W - 7;
 
   __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
 
@@ -198,8 +198,6 @@ static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) {
   gsize              operand1;
   gsize              operand2;
 
-  if (ctx->operand1.size != ctx->operand2.size) FATAL("Operand size mismatch");
-
   if (!cmplog_get_operand_value(context, &ctx->operand1, &operand1)) { return; }
   if (!cmplog_get_operand_value(context, &ctx->operand2, &operand2)) { return; }
 
@@ -233,6 +231,15 @@ static void cmplog_instrument_cmp_sub(const cs_insn *     instr,
 
     case X86_INS_CMP:
     case X86_INS_SUB:
+    case X86_INS_SCASB:
+    case X86_INS_SCASD:
+    case X86_INS_SCASQ:
+    case X86_INS_SCASW:
+    case X86_INS_CMPSB:
+    case X86_INS_CMPSD:
+    case X86_INS_CMPSQ:
+    case X86_INS_CMPSS:
+    case X86_INS_CMPSW:
       break;
     default:
       return;
@@ -247,13 +254,8 @@ static void cmplog_instrument_cmp_sub(const cs_insn *     instr,
   if (operand1->type == X86_OP_INVALID) return;
   if (operand2->type == X86_OP_INVALID) return;
 
-  if ((operand1->type == X86_OP_MEM) &&
-      (operand1->mem.segment != X86_REG_INVALID))
-    return;
-
-  if ((operand2->type == X86_OP_MEM) &&
-      (operand2->mem.segment != X86_REG_INVALID))
-    return;
+  /* Both operands are the same size */
+  if (operand1->size == 1) { return; }
 
   cmplog_instrument_cmp_sub_put_callout(iterator, operand1, operand2);
 
diff --git a/frida_mode/src/cmplog/cmplog_x86.c b/frida_mode/src/cmplog/cmplog_x86.c
index a27df0af..dd666c34 100644
--- a/frida_mode/src/cmplog/cmplog_x86.c
+++ b/frida_mode/src/cmplog/cmplog_x86.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 #include "cmplog.h"
diff --git a/frida_mode/src/ctx/ctx_arm32.c b/frida_mode/src/ctx/ctx_arm32.c
index a5c6f6d4..a354c117 100644
--- a/frida_mode/src/ctx/ctx_arm32.c
+++ b/frida_mode/src/ctx/ctx_arm32.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
diff --git a/frida_mode/src/ctx/ctx_arm64.c b/frida_mode/src/ctx/ctx_arm64.c
index d09896af..a735401b 100644
--- a/frida_mode/src/ctx/ctx_arm64.c
+++ b/frida_mode/src/ctx/ctx_arm64.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
diff --git a/frida_mode/src/ctx/ctx_x64.c b/frida_mode/src/ctx/ctx_x64.c
index c5900533..da5cb13a 100644
--- a/frida_mode/src/ctx/ctx_x64.c
+++ b/frida_mode/src/ctx/ctx_x64.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
@@ -49,9 +49,18 @@ gsize ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg) {
     X86_REG_8L(X86_REG_BL, ctx->rbx)
     X86_REG_8L(X86_REG_CL, ctx->rcx)
     X86_REG_8L(X86_REG_DL, ctx->rdx)
+    X86_REG_8L(X86_REG_SPL, ctx->rsp)
     X86_REG_8L(X86_REG_BPL, ctx->rbp)
     X86_REG_8L(X86_REG_SIL, ctx->rsi)
     X86_REG_8L(X86_REG_DIL, ctx->rdi)
+    X86_REG_8L(X86_REG_R8B, ctx->r8)
+    X86_REG_8L(X86_REG_R9B, ctx->r9)
+    X86_REG_8L(X86_REG_R10B, ctx->r10)
+    X86_REG_8L(X86_REG_R11B, ctx->r11)
+    X86_REG_8L(X86_REG_R12B, ctx->r12)
+    X86_REG_8L(X86_REG_R13B, ctx->r13)
+    X86_REG_8L(X86_REG_R14B, ctx->r14)
+    X86_REG_8L(X86_REG_R15B, ctx->r15)
 
     X86_REG_8H(X86_REG_AH, ctx->rax)
     X86_REG_8H(X86_REG_BH, ctx->rbx)
@@ -62,14 +71,23 @@ gsize ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg) {
     X86_REG_16(X86_REG_BX, ctx->rbx)
     X86_REG_16(X86_REG_CX, ctx->rcx)
     X86_REG_16(X86_REG_DX, ctx->rdx)
+    X86_REG_16(X86_REG_SP, ctx->rsp)
+    X86_REG_16(X86_REG_BP, ctx->rbp)
     X86_REG_16(X86_REG_DI, ctx->rdi)
     X86_REG_16(X86_REG_SI, ctx->rsi)
-    X86_REG_16(X86_REG_BP, ctx->rbp)
+    X86_REG_16(X86_REG_R8W, ctx->r8)
+    X86_REG_16(X86_REG_R9W, ctx->r9)
+    X86_REG_16(X86_REG_R10W, ctx->r10)
+    X86_REG_16(X86_REG_R11W, ctx->r11)
+    X86_REG_16(X86_REG_R12W, ctx->r12)
+    X86_REG_16(X86_REG_R13W, ctx->r13)
+    X86_REG_16(X86_REG_R14W, ctx->r14)
+    X86_REG_16(X86_REG_R15W, ctx->r15)
 
     X86_REG_32(X86_REG_EAX, ctx->rax)
+    X86_REG_32(X86_REG_EBX, ctx->rbx)
     X86_REG_32(X86_REG_ECX, ctx->rcx)
     X86_REG_32(X86_REG_EDX, ctx->rdx)
-    X86_REG_32(X86_REG_EBX, ctx->rbx)
     X86_REG_32(X86_REG_ESP, ctx->rsp)
     X86_REG_32(X86_REG_EBP, ctx->rbp)
     X86_REG_32(X86_REG_ESI, ctx->rsi)
diff --git a/frida_mode/src/ctx/ctx_x86.c b/frida_mode/src/ctx/ctx_x86.c
index 45308272..1a587702 100644
--- a/frida_mode/src/ctx/ctx_x86.c
+++ b/frida_mode/src/ctx/ctx_x86.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
@@ -42,6 +42,7 @@ gsize ctx_read_reg(GumIA32CpuContext *ctx, x86_reg reg) {
     X86_REG_8L(X86_REG_BL, ctx->ebx)
     X86_REG_8L(X86_REG_CL, ctx->ecx)
     X86_REG_8L(X86_REG_DL, ctx->edx)
+    X86_REG_8L(X86_REG_SPL, ctx->esp)
     X86_REG_8L(X86_REG_BPL, ctx->ebp)
     X86_REG_8L(X86_REG_SIL, ctx->esi)
     X86_REG_8L(X86_REG_DIL, ctx->edi)
@@ -55,14 +56,15 @@ gsize ctx_read_reg(GumIA32CpuContext *ctx, x86_reg reg) {
     X86_REG_16(X86_REG_BX, ctx->ebx)
     X86_REG_16(X86_REG_CX, ctx->ecx)
     X86_REG_16(X86_REG_DX, ctx->edx)
+    X86_REG_16(X86_REG_SP, ctx->esp)
+    X86_REG_16(X86_REG_BP, ctx->ebp)
     X86_REG_16(X86_REG_DI, ctx->edi)
     X86_REG_16(X86_REG_SI, ctx->esi)
-    X86_REG_16(X86_REG_BP, ctx->ebp)
 
     X86_REG_32(X86_REG_EAX, ctx->eax)
+    X86_REG_32(X86_REG_EBX, ctx->ebx)
     X86_REG_32(X86_REG_ECX, ctx->ecx)
     X86_REG_32(X86_REG_EDX, ctx->edx)
-    X86_REG_32(X86_REG_EBX, ctx->ebx)
     X86_REG_32(X86_REG_ESP, ctx->esp)
     X86_REG_32(X86_REG_EBP, ctx->ebp)
     X86_REG_32(X86_REG_ESI, ctx->esi)
diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c
index e71386a0..e95b923b 100644
--- a/frida_mode/src/entry.c
+++ b/frida_mode/src/entry.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
@@ -9,27 +9,33 @@
 
 extern void __afl_manual_init();
 
-guint64 entry_start = 0;
+guint64 entry_point = 0;
 
 static void entry_launch(void) {
 
+  OKF("Entry point reached");
   __afl_manual_init();
 
   /* Child here */
-  previous_pc = 0;
+  instrument_previous_pc = 0;
+
+}
+
+void entry_config(void) {
+
+  entry_point = util_read_address("AFL_ENTRYPOINT");
 
 }
 
 void entry_init(void) {
 
-  entry_start = util_read_address("AFL_ENTRYPOINT");
-  OKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_start);
+  OKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_point);
 
 }
 
-void entry_run(void) {
+void entry_start(void) {
 
-  if (entry_start == 0) { entry_launch(); }
+  if (entry_point == 0) { entry_launch(); }
 
 }
 
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index ba82b89f..2a217d96 100644
--- a/frida_mode/src/instrument/instrument.c
+++ b/frida_mode/src/instrument/instrument.c
@@ -2,7 +2,7 @@
 #include <sys/shm.h>
 #include <sys/mman.h>
 
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "config.h"
 #include "debug.h"
@@ -11,6 +11,7 @@
 #include "entry.h"
 #include "frida_cmplog.h"
 #include "instrument.h"
+#include "js.h"
 #include "persistent.h"
 #include "prefetch.h"
 #include "ranges.h"
@@ -18,12 +19,13 @@
 #include "stats.h"
 #include "util.h"
 
-static gboolean               tracing = false;
-static gboolean               optimize = false;
-static gboolean               unique = false;
+gboolean instrument_tracing = false;
+gboolean instrument_optimize = false;
+gboolean instrument_unique = false;
+
 static GumStalkerTransformer *transformer = NULL;
 
-__thread uint64_t previous_pc = 0;
+__thread uint64_t instrument_previous_pc = 0;
 
 static GumAddress previous_rip = 0;
 static u8 *       edges_notified = NULL;
@@ -61,7 +63,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context,
   current_pc = (current_rip >> 4) ^ (current_rip << 8);
   current_pc &= MAP_SIZE - 1;
 
-  edge = current_pc ^ previous_pc;
+  edge = current_pc ^ instrument_previous_pc;
 
   cursor = &__afl_area_ptr[edge];
   value = *cursor;
@@ -77,11 +79,11 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context,
   }
 
   *cursor = value;
-  previous_pc = current_pc >> 1;
+  instrument_previous_pc = current_pc >> 1;
 
-  if (unlikely(tracing)) {
+  if (unlikely(instrument_tracing)) {
 
-    if (!unique || edges_notified[edge] == 0) {
+    if (!instrument_unique || edges_notified[edge] == 0) {
 
       trace_debug("TRACE: edge: %10" G_GINT64_MODIFIER
                   "d, current_rip: 0x%016" G_GINT64_MODIFIER
@@ -90,7 +92,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context,
 
     }
 
-    if (unique) { edges_notified[edge] = 1; }
+    if (instrument_unique) { edges_notified[edge] = 1; }
 
     previous_rip = current_rip;
 
@@ -98,8 +100,9 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context,
 
 }
 
-static void instr_basic_block(GumStalkerIterator *iterator,
-                              GumStalkerOutput *output, gpointer user_data) {
+static void instrument_basic_block(GumStalkerIterator *iterator,
+                                   GumStalkerOutput *  output,
+                                   gpointer            user_data) {
 
   UNUSED_PARAMETER(user_data);
 
@@ -111,7 +114,7 @@ static void instr_basic_block(GumStalkerIterator *iterator,
 
     if (unlikely(begin)) { instrument_debug_start(instr->address, output); }
 
-    if (instr->address == entry_start) { entry_prologue(iterator, output); }
+    if (instr->address == entry_point) { entry_prologue(iterator, output); }
     if (instr->address == persistent_start) { persistent_prologue(output); }
     if (instr->address == persistent_ret) { persistent_epilogue(output); }
 
@@ -150,7 +153,7 @@ static void instr_basic_block(GumStalkerIterator *iterator,
 
       if (likely(!excluded)) {
 
-        if (likely(optimize)) {
+        if (likely(instrument_optimize)) {
 
           instrument_coverage_optimize(instr, output);
 
@@ -163,8 +166,6 @@ static void instr_basic_block(GumStalkerIterator *iterator,
 
       }
 
-      begin = FALSE;
-
     }
 
     instrument_debug_instruction(instr->address, instr->size);
@@ -176,7 +177,13 @@ static void instr_basic_block(GumStalkerIterator *iterator,
 
     }
 
-    gum_stalker_iterator_keep(iterator);
+    if (js_stalker_callback(instr, begin, excluded, output)) {
+
+      gum_stalker_iterator_keep(iterator);
+
+    }
+
+    begin = FALSE;
 
   }
 
@@ -185,31 +192,39 @@ static void instr_basic_block(GumStalkerIterator *iterator,
 
 }
 
-void instrument_init(void) {
+void instrument_config(void) {
+
+  instrument_optimize = (getenv("AFL_FRIDA_INST_NO_OPTIMIZE") == NULL);
+  instrument_tracing = (getenv("AFL_FRIDA_INST_TRACE") != NULL);
+  instrument_unique = (getenv("AFL_FRIDA_INST_TRACE_UNIQUE") != NULL);
+
+  instrument_debug_config();
+  asan_config();
+  cmplog_config();
 
-  optimize = (getenv("AFL_FRIDA_INST_NO_OPTIMIZE") == NULL);
-  tracing = (getenv("AFL_FRIDA_INST_TRACE") != NULL);
-  unique = (getenv("AFL_FRIDA_INST_TRACE_UNIQUE") != NULL);
+}
+
+void instrument_init(void) {
 
-  if (!instrument_is_coverage_optimize_supported()) optimize = false;
+  if (!instrument_is_coverage_optimize_supported()) instrument_optimize = false;
 
-  OKF("Instrumentation - optimize [%c]", optimize ? 'X' : ' ');
-  OKF("Instrumentation - tracing [%c]", tracing ? 'X' : ' ');
-  OKF("Instrumentation - unique [%c]", unique ? 'X' : ' ');
+  OKF("Instrumentation - optimize [%c]", instrument_optimize ? 'X' : ' ');
+  OKF("Instrumentation - tracing [%c]", instrument_tracing ? 'X' : ' ');
+  OKF("Instrumentation - unique [%c]", instrument_unique ? 'X' : ' ');
 
-  if (tracing && optimize) {
+  if (instrument_tracing && instrument_optimize) {
 
     FATAL("AFL_FRIDA_INST_TRACE requires AFL_FRIDA_INST_NO_OPTIMIZE");
 
   }
 
-  if (unique && optimize) {
+  if (instrument_unique && instrument_optimize) {
 
     FATAL("AFL_FRIDA_INST_TRACE_UNIQUE requires AFL_FRIDA_INST_NO_OPTIMIZE");
 
   }
 
-  if (unique) { tracing = TRUE; }
+  if (instrument_unique) { instrument_tracing = TRUE; }
 
   if (__afl_map_size != 0x10000) {
 
@@ -217,10 +232,10 @@ void instrument_init(void) {
 
   }
 
-  transformer =
-      gum_stalker_transformer_make_from_callback(instr_basic_block, NULL, NULL);
+  transformer = gum_stalker_transformer_make_from_callback(
+      instrument_basic_block, NULL, NULL);
 
-  if (unique) {
+  if (instrument_unique) {
 
     int shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);
     if (shm_id < 0) { FATAL("shm_id < 0 - errno: %d\n", errno); }
diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c
index 450a69a3..0e15940a 100644
--- a/frida_mode/src/instrument/instrument_arm32.c
+++ b/frida_mode/src/instrument/instrument_arm32.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c
index 49ee86a2..17f97c97 100644
--- a/frida_mode/src/instrument/instrument_arm64.c
+++ b/frida_mode/src/instrument/instrument_arm64.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "config.h"
 #include "debug.h"
@@ -72,7 +72,7 @@ void instrument_coverage_optimize(const cs_insn *   instr,
     gum_arm64_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code));
 
     uint8_t **afl_area_ptr_ptr = &__afl_area_ptr;
-    uint64_t *afl_prev_loc_ptr = &previous_pc;
+    uint64_t *afl_prev_loc_ptr = &instrument_previous_pc;
     gum_arm64_writer_put_bytes(cw, (const guint8 *)&afl_area_ptr_ptr,
                                sizeof(afl_area_ptr_ptr));
     gum_arm64_writer_put_bytes(cw, (const guint8 *)&afl_prev_loc_ptr,
diff --git a/frida_mode/src/instrument/instrument_debug.c b/frida_mode/src/instrument/instrument_debug.c
index 0ce26a1c..b8cca634 100644
--- a/frida_mode/src/instrument/instrument_debug.c
+++ b/frida_mode/src/instrument/instrument_debug.c
@@ -3,7 +3,7 @@
 #include <stdio.h>
 #include <unistd.h>
 
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
@@ -13,6 +13,8 @@
 static int      debugging_fd = -1;
 static gpointer instrument_gen_start = NULL;
 
+char *instrument_debug_filename = NULL;
+
 static void instrument_debug(char *format, ...) {
 
   va_list ap;
@@ -79,18 +81,25 @@ static void instrument_disasm(guint8 *start, guint8 *end) {
 
 }
 
+void instrument_debug_config(void) {
+
+  instrument_debug_filename = getenv("AFL_FRIDA_INST_DEBUG_FILE");
+
+}
+
 void instrument_debug_init(void) {
 
-  char *filename = getenv("AFL_FRIDA_INST_DEBUG_FILE");
-  OKF("Instrumentation debugging - enabled [%c]", filename == NULL ? ' ' : 'X');
+  OKF("Instrumentation debugging - enabled [%c]",
+      instrument_debug_filename == NULL ? ' ' : 'X');
 
-  if (filename == NULL) { return; }
+  if (instrument_debug_filename == NULL) { return; }
 
-  OKF("Instrumentation debugging - file [%s]", filename);
+  OKF("Instrumentation debugging - file [%s]", instrument_debug_filename);
 
-  if (filename == NULL) { return; }
+  if (instrument_debug_filename == NULL) { return; }
 
-  char *path = g_canonicalize_filename(filename, g_get_current_dir());
+  char *path =
+      g_canonicalize_filename(instrument_debug_filename, g_get_current_dir());
 
   OKF("Instrumentation debugging - path [%s]", path);
 
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index 7000e65d..a38b5b14 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "config.h"
 
@@ -68,7 +68,7 @@ void instrument_coverage_optimize(const cs_insn *   instr,
     current_log_impl = cw->pc;
     gum_x86_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code));
 
-    uint64_t *afl_prev_loc_ptr = &previous_pc;
+    uint64_t *afl_prev_loc_ptr = &instrument_previous_pc;
     gum_x86_writer_put_bytes(cw, (const guint8 *)&__afl_area_ptr,
                              sizeof(__afl_area_ptr));
     gum_x86_writer_put_bytes(cw, (const guint8 *)&afl_prev_loc_ptr,
diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c
index 04a19e08..3c3dc272 100644
--- a/frida_mode/src/instrument/instrument_x86.c
+++ b/frida_mode/src/instrument/instrument_x86.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
@@ -16,7 +16,7 @@ static void instrument_coverage_function(GumX86Writer *cw) {
   gum_x86_writer_put_push_reg(cw, GUM_REG_EDX);
 
   gum_x86_writer_put_mov_reg_address(cw, GUM_REG_ECX,
-                                     GUM_ADDRESS(&previous_pc));
+                                     GUM_ADDRESS(&instrument_previous_pc));
   gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_EDX, GUM_REG_ECX);
   gum_x86_writer_put_xor_reg_reg(cw, GUM_REG_EDX, GUM_REG_EDI);
 
diff --git a/frida_mode/src/interceptor.c b/frida_mode/src/intercept.c
index d2802752..ed8d27bd 100644
--- a/frida_mode/src/interceptor.c
+++ b/frida_mode/src/intercept.c
@@ -1,10 +1,10 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
-#include "interceptor.h"
+#include "intercept.h"
 
-void intercept(void *address, gpointer replacement, gpointer user_data) {
+void intercept_hook(void *address, gpointer replacement, gpointer user_data) {
 
   GumInterceptor *interceptor = gum_interceptor_obtain();
   gum_interceptor_begin_transaction(interceptor);
@@ -15,7 +15,7 @@ void intercept(void *address, gpointer replacement, gpointer user_data) {
 
 }
 
-void unintercept(void *address) {
+void intercept_unhook(void *address) {
 
   GumInterceptor *interceptor = gum_interceptor_obtain();
 
@@ -26,10 +26,10 @@ void unintercept(void *address) {
 
 }
 
-void unintercept_self(void) {
+void intercept_unhook_self(void) {
 
   GumInvocationContext *ctx = gum_interceptor_get_current_invocation();
-  unintercept(ctx->function);
+  intercept_unhook(ctx->function);
 
 }
 
diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js
new file mode 100644
index 00000000..4cb04704
--- /dev/null
+++ b/frida_mode/src/js/api.js
@@ -0,0 +1,243 @@
+"use strict";
+class Afl {
+    /**
+     * This is equivalent to setting a value in `AFL_FRIDA_EXCLUDE_RANGES`,
+     * it takes as arguments a `NativePointer` and a `number`. It can be
+     * called multiple times to exclude several ranges.
+     */
+    static addExcludedRange(addressess, size) {
+        Afl.jsApiAddExcludeRange(addressess, size);
+    }
+    /**
+     * This is equivalent to setting a value in `AFL_FRIDA_INST_RANGES`,
+     * it takes as arguments a `NativePointer` and a `number`. It can be
+     * called multiple times to include several ranges.
+     */
+    static addIncludedRange(addressess, size) {
+        Afl.jsApiAddIncludeRange(addressess, size);
+    }
+    /**
+     * This must always be called at the end of your script. This lets
+     * FRIDA mode know that your configuration is finished and that
+     * execution has reached the end of your script. Failure to call
+     * this will result in a fatal error.
+     */
+    static done() {
+        Afl.jsApiDone();
+    }
+    /**
+     * This function can be called within your script to cause FRIDA
+     * mode to trigger a fatal error. This is useful if for example you
+     * discover a problem you weren't expecting and want everything to
+     * stop. The user will need to enable `AFL_DEBUG_CHILD=1` to view
+     * this error message.
+     */
+    static error(msg) {
+        const buf = Memory.allocUtf8String(msg);
+        Afl.jsApiError(buf);
+    }
+    /**
+     * Function used to provide access to `__afl_fuzz_ptr`, which contains the length of
+     * fuzzing data when using in-memory test case fuzzing.
+     */
+    static getAflFuzzLen() {
+        return Afl.jsApiGetSymbol("__afl_fuzz_len");
+    }
+    /**
+     * Function used to provide access to `__afl_fuzz_ptr`, which contains the fuzzing
+     * data when using in-memory test case fuzzing.
+     */
+    static getAflFuzzPtr() {
+        return Afl.jsApiGetSymbol("__afl_fuzz_ptr");
+    }
+    /**
+     * Print a message to the STDOUT. This should be preferred to
+     * FRIDA's `console.log` since FRIDA will queue it's log messages.
+     * If `console.log` is used in a callback in particular, then there
+     * may no longer be a thread running to service this queue.
+     */
+    static print(msg) {
+        const STDOUT_FILENO = 2;
+        const log = `${msg}\n`;
+        const buf = Memory.allocUtf8String(log);
+        Afl.jsApiWrite(STDOUT_FILENO, buf, log.length);
+    }
+    /**
+     * See `AFL_FRIDA_DEBUG_MAPS`.
+     */
+    static setDebugMaps() {
+        Afl.jsApiSetDebugMaps();
+    }
+    /**
+     * This has the same effect as setting `AFL_ENTRYPOINT`, but has the
+     * convenience of allowing you to use FRIDAs APIs to determine the
+     * address you would like to configure, rather than having to grep
+     * the output of `readelf` or something similarly ugly. This
+     * function should be called with a `NativePointer` as its
+     * argument.
+     */
+    static setEntryPoint(address) {
+        Afl.jsApiSetEntryPoint(address);
+    }
+    /**
+     * Function used to enable in-memory test cases for fuzzing.
+     */
+    static setInMemoryFuzzing() {
+        Afl.jsApiAflSharedMemFuzzing.writeInt(1);
+    }
+    /**
+     * See `AFL_FRIDA_INST_DEBUG_FILE`. This function takes a single `string` as
+     * an argument.
+     */
+    static setInstrumentDebugFile(file) {
+        const buf = Memory.allocUtf8String(file);
+        Afl.jsApiSetInstrumentDebugFile(buf);
+    }
+    /**
+     * See `AFL_FRIDA_INST_TRACE`.
+     */
+    static setInstrumentEnableTracing() {
+        Afl.jsApiSetInstrumentTrace();
+    }
+    /**
+     * See `AFL_INST_LIBS`.
+     */
+    static setInstrumentLibraries() {
+        Afl.jsApiSetInstrumentLibraries();
+    }
+    /**
+     * See `AFL_FRIDA_INST_NO_OPTIMIZE`
+     */
+    static setInstrumentNoOptimize() {
+        Afl.jsApiSetInstrumentNoOptimize();
+    }
+    /**
+     * See `AFL_FRIDA_INST_TRACE_UNIQUE`.
+     */
+    static setInstrumentTracingUnique() {
+        Afl.jsApiSetInstrumentTraceUnique();
+    }
+    /**
+     * This is equivalent to setting `AFL_FRIDA_PERSISTENT_ADDR`, again a
+     * `NativePointer` should be provided as it's argument.
+     */
+    static setPersistentAddress(address) {
+        Afl.jsApiSetPersistentAddress(address);
+    }
+    /**
+     * This is equivalent to setting `AFL_FRIDA_PERSISTENT_CNT`, a
+     * `number` should be provided as it's argument.
+     */
+    static setPersistentCount(count) {
+        Afl.jsApiSetPersistentCount(count);
+    }
+    /**
+     * See `AFL_FRIDA_PERSISTENT_DEBUG`.
+     */
+    static setPersistentDebug() {
+        Afl.jsApiSetPersistentDebug();
+    }
+    /**
+     * See `AFL_FRIDA_PERSISTENT_ADDR`. This function takes a NativePointer as an
+     * argument. See above for examples of use.
+     */
+    static setPersistentHook(address) {
+        Afl.jsApiSetPersistentHook(address);
+    }
+    /**
+     * This is equivalent to setting `AFL_FRIDA_PERSISTENT_RET`, again a
+     * `NativePointer` should be provided as it's argument.
+     */
+    static setPersistentReturn(address) {
+        Afl.jsApiSetPersistentReturn(address);
+    }
+    /**
+     * See `AFL_FRIDA_INST_NO_PREFETCH`.
+     */
+    static setPrefetchDisable() {
+        Afl.jsApiSetPrefetchDisable();
+    }
+    /*
+     * Set a function to be called for each instruction which is instrumented
+     * by AFL FRIDA mode.
+     */
+    static setStalkerCallback(callback) {
+        Afl.jsApiSetStalkerCallback(callback);
+    }
+    /**
+     * See `AFL_FRIDA_STATS_FILE`. This function takes a single `string` as
+     * an argument.
+     */
+    static setStatsFile(file) {
+        const buf = Memory.allocUtf8String(file);
+        Afl.jsApiSetStatsFile(buf);
+    }
+    /**
+     * See `AFL_FRIDA_STATS_INTERVAL`. This function takes a `number` as an
+     * argument
+     */
+    static setStatsInterval(interval) {
+        Afl.jsApiSetStatsInterval(interval);
+    }
+    /**
+     * See `AFL_FRIDA_STATS_TRANSITIONS`
+     */
+    static setStatsTransitions() {
+        Afl.jsApiSetStatsTransitions();
+    }
+    /**
+     * See `AFL_FRIDA_OUTPUT_STDERR`. This function takes a single `string` as
+     * an argument.
+     */
+    static setStdErr(file) {
+        const buf = Memory.allocUtf8String(file);
+        Afl.jsApiSetStdErr(buf);
+    }
+    /**
+     * See `AFL_FRIDA_OUTPUT_STDOUT`. This function takes a single `string` as
+     * an argument.
+     */
+    static setStdOut(file) {
+        const buf = Memory.allocUtf8String(file);
+        Afl.jsApiSetStdOut(buf);
+    }
+    static jsApiGetFunction(name, retType, argTypes) {
+        const addr = Afl.module.getExportByName(name);
+        return new NativeFunction(addr, retType, argTypes);
+    }
+    static jsApiGetSymbol(name) {
+        return Afl.module.getExportByName(name);
+    }
+}
+/**
+ * Field containing the `Module` object for `afl-frida-trace.so` (the FRIDA mode
+ * implementation).
+ */
+Afl.module = Process.getModuleByName("afl-frida-trace.so");
+Afl.jsApiAddExcludeRange = Afl.jsApiGetFunction("js_api_add_exclude_range", "void", ["pointer", "size_t"]);
+Afl.jsApiAddIncludeRange = Afl.jsApiGetFunction("js_api_add_include_range", "void", ["pointer", "size_t"]);
+Afl.jsApiAflSharedMemFuzzing = Afl.jsApiGetSymbol("__afl_sharedmem_fuzzing");
+Afl.jsApiDone = Afl.jsApiGetFunction("js_api_done", "void", []);
+Afl.jsApiError = Afl.jsApiGetFunction("js_api_error", "void", ["pointer"]);
+Afl.jsApiSetDebugMaps = Afl.jsApiGetFunction("js_api_set_debug_maps", "void", []);
+Afl.jsApiSetEntryPoint = Afl.jsApiGetFunction("js_api_set_entrypoint", "void", ["pointer"]);
+Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]);
+Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []);
+Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []);
+Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []);
+Afl.jsApiSetInstrumentTraceUnique = Afl.jsApiGetFunction("js_api_set_instrument_trace_unique", "void", []);
+Afl.jsApiSetPersistentAddress = Afl.jsApiGetFunction("js_api_set_persistent_address", "void", ["pointer"]);
+Afl.jsApiSetPersistentCount = Afl.jsApiGetFunction("js_api_set_persistent_count", "void", ["uint64"]);
+Afl.jsApiSetPersistentDebug = Afl.jsApiGetFunction("js_api_set_persistent_debug", "void", []);
+Afl.jsApiSetPersistentHook = Afl.jsApiGetFunction("js_api_set_persistent_hook", "void", ["pointer"]);
+Afl.jsApiSetPersistentReturn = Afl.jsApiGetFunction("js_api_set_persistent_return", "void", ["pointer"]);
+Afl.jsApiSetPrefetchDisable = Afl.jsApiGetFunction("js_api_set_prefetch_disable", "void", []);
+Afl.jsApiSetStalkerCallback = Afl.jsApiGetFunction("js_api_set_stalker_callback", "void", ["pointer"]);
+Afl.jsApiSetStatsFile = Afl.jsApiGetFunction("js_api_set_stats_file", "void", ["pointer"]);
+Afl.jsApiSetStatsInterval = Afl.jsApiGetFunction("js_api_set_stats_interval", "void", ["uint64"]);
+Afl.jsApiSetStatsTransitions = Afl.jsApiGetFunction("js_api_set_stats_transitions", "void", []);
+Afl.jsApiSetStdErr = Afl.jsApiGetFunction("js_api_set_stderr", "void", ["pointer"]);
+Afl.jsApiSetStdOut = Afl.jsApiGetFunction("js_api_set_stdout", "void", ["pointer"]);
+Afl.jsApiWrite = new NativeFunction(
+/* tslint:disable-next-line:no-null-keyword */
+Module.getExportByName(null, "write"), "int", ["int", "pointer", "int"]);
diff --git a/frida_mode/src/js/js.c b/frida_mode/src/js/js.c
new file mode 100644
index 00000000..ed378d2c
--- /dev/null
+++ b/frida_mode/src/js/js.c
@@ -0,0 +1,122 @@
+#include "frida-gumjs.h"
+
+#include "debug.h"
+
+#include "js.h"
+#include "util.h"
+
+static char *             js_script = NULL;
+gboolean                  js_done = FALSE;
+js_api_stalker_callback_t js_user_callback = NULL;
+
+static gchar *           filename = "afl.js";
+static gchar *           contents;
+static GumScriptBackend *backend;
+static GCancellable *    cancellable = NULL;
+static GError *          error = NULL;
+static GumScript *       script;
+
+static void js_msg(GumScript *script, const gchar *message, GBytes *data,
+                   gpointer user_data) {
+
+  UNUSED_PARAMETER(script);
+  UNUSED_PARAMETER(data);
+  UNUSED_PARAMETER(user_data);
+  OKF("%s", message);
+
+}
+
+void js_config(void) {
+
+  js_script = getenv("AFL_FRIDA_JS_SCRIPT");
+
+}
+
+static gchar *js_get_script() {
+
+  gsize length;
+  if (js_script != NULL) { filename = js_script; }
+
+  filename = g_canonicalize_filename(filename, g_get_current_dir());
+
+  if (!g_file_get_contents(filename, &contents, &length, NULL)) {
+
+    if (js_script == NULL) {
+
+      return NULL;
+
+    } else {
+
+      FATAL("Could not load script file: %s", filename);
+
+    }
+
+  } else {
+
+    OKF("Loaded AFL script: %s, %" G_GSIZE_MODIFIER "d bytes", filename,
+        length);
+
+    gchar *source = g_malloc0(api_js_len + length + 1);
+    memcpy(source, api_js, api_js_len);
+    memcpy(&source[api_js_len], contents, length);
+
+    return source;
+
+  }
+
+}
+
+static void js_print_script(gchar *source) {
+
+  gchar **split = g_strsplit(source, "\n", 0);
+
+  for (size_t i = 0; split[i] != NULL; i++) {
+
+    OKF("%3" G_GSIZE_MODIFIER "d. %s", i + 1, split[i]);
+
+  }
+
+  g_strfreev(split);
+
+}
+
+void js_start(void) {
+
+  GMainContext *context;
+
+  gchar *source = js_get_script();
+  if (source == NULL) { return; }
+  js_print_script(source);
+
+  backend = gum_script_backend_obtain_qjs();
+
+  script = gum_script_backend_create_sync(backend, "example", source,
+                                          cancellable, &error);
+
+  if (error != NULL) {
+
+    g_printerr("%s\n", error->message);
+    FATAL("Error processing script");
+
+  }
+
+  gum_script_set_message_handler(script, js_msg, NULL, NULL);
+
+  gum_script_load_sync(script, cancellable);
+
+  context = g_main_context_get_thread_default();
+  while (g_main_context_pending(context))
+    g_main_context_iteration(context, FALSE);
+
+  if (!js_done) { FATAL("Script didn't call Afl.done()"); }
+
+}
+
+gboolean js_stalker_callback(const cs_insn *insn, gboolean begin,
+                             gboolean excluded, GumStalkerOutput *output) {
+
+  if (js_user_callback == NULL) { return TRUE; }
+  return js_user_callback(insn, begin, excluded, output);
+
+}
+
diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c
new file mode 100644
index 00000000..91dccab2
--- /dev/null
+++ b/frida_mode/src/js/js_api.c
@@ -0,0 +1,152 @@
+#include "debug.h"
+
+#include "entry.h"
+#include "instrument.h"
+#include "js.h"
+#include "output.h"
+#include "persistent.h"
+#include "prefetch.h"
+#include "ranges.h"
+#include "stats.h"
+#include "util.h"
+
+void js_api_done() {
+
+  js_done = TRUE;
+
+}
+
+void js_api_error(char *msg) {
+
+  FATAL("%s", msg);
+
+}
+
+void js_api_set_entrypoint(void *address) {
+
+  entry_point = GPOINTER_TO_SIZE(address);
+
+}
+
+void js_api_set_persistent_address(void *address) {
+
+  persistent_start = GPOINTER_TO_SIZE(address);
+
+}
+
+void js_api_set_persistent_return(void *address) {
+
+  persistent_ret = GPOINTER_TO_SIZE(address);
+
+}
+
+void js_api_set_persistent_count(uint64_t count) {
+
+  persistent_count = count;
+
+}
+
+void js_api_set_persistent_debug() {
+
+  persistent_debug = TRUE;
+
+}
+
+void js_api_set_debug_maps() {
+
+  ranges_debug_maps = TRUE;
+
+}
+
+void js_api_add_include_range(void *address, gsize size) {
+
+  GumMemoryRange range = {.base_address = GUM_ADDRESS(address), .size = size};
+  ranges_add_include(&range);
+
+}
+
+void js_api_add_exclude_range(void *address, gsize size) {
+
+  GumMemoryRange range = {.base_address = GUM_ADDRESS(address), .size = size};
+  ranges_add_exclude(&range);
+
+}
+
+void js_api_set_instrument_libraries() {
+
+  ranges_inst_libs = TRUE;
+
+}
+
+void js_api_set_instrument_debug_file(char *path) {
+
+  instrument_debug_filename = g_strdup(path);
+
+}
+
+void js_api_set_prefetch_disable(void) {
+
+  prefetch_enable = FALSE;
+
+}
+
+void js_api_set_instrument_no_optimize(void) {
+
+  instrument_optimize = FALSE;
+
+}
+
+void js_api_set_instrument_trace(void) {
+
+  instrument_tracing = TRUE;
+
+}
+
+void js_api_set_instrument_trace_unique(void) {
+
+  instrument_unique = TRUE;
+
+}
+
+void js_api_set_stdout(char *file) {
+
+  output_stdout = g_strdup(file);
+
+}
+
+void js_api_set_stderr(char *file) {
+
+  output_stderr = g_strdup(file);
+
+}
+
+void js_api_set_stats_file(char *file) {
+
+  stats_filename = g_strdup(file);
+
+}
+
+void js_api_set_stats_interval(uint64_t interval) {
+
+  stats_interval = interval;
+
+}
+
+void js_api_set_stats_transitions() {
+
+  stats_transitions = TRUE;
+
+}
+
+void js_api_set_persistent_hook(void *address) {
+
+  persistent_hook = address;
+
+}
+
+void js_api_set_stalker_callback(const js_api_stalker_callback_t callback) {
+
+  js_user_callback = callback;
+
+}
+
diff --git a/frida_mode/src/lib/lib.c b/frida_mode/src/lib/lib.c
index 13a7d1e7..59a3fcf9 100644
--- a/frida_mode/src/lib/lib.c
+++ b/frida_mode/src/lib/lib.c
@@ -6,7 +6,7 @@
   #include <sys/mman.h>
   #include <unistd.h>
 
-  #include "frida-gum.h"
+  #include "frida-gumjs.h"
 
   #include "debug.h"
 
@@ -151,6 +151,10 @@ static void lib_get_text_section(lib_details_t *details) {
 
 }
 
+void lib_config(void) {
+
+}
+
 void lib_init(void) {
 
   lib_details_t lib_details;
diff --git a/frida_mode/src/lib/lib_apple.c b/frida_mode/src/lib/lib_apple.c
index 8f863861..2aa48a13 100644
--- a/frida_mode/src/lib/lib_apple.c
+++ b/frida_mode/src/lib/lib_apple.c
@@ -1,5 +1,5 @@
 #ifdef __APPLE__
-  #include "frida-gum.h"
+  #include "frida-gumjs.h"
 
   #include "debug.h"
 
@@ -56,6 +56,10 @@ gboolean lib_get_text_section(const GumDarwinSectionDetails *details,
 
 }
 
+void lib_config(void) {
+
+}
+
 void lib_init(void) {
 
   GumDarwinModule *module = NULL;
diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c
index 7ff23755..85b0bbf3 100644
--- a/frida_mode/src/main.c
+++ b/frida_mode/src/main.c
@@ -11,14 +11,15 @@
   #include <sys/personality.h>
 #endif
 
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "config.h"
 #include "debug.h"
 
 #include "entry.h"
 #include "instrument.h"
-#include "interceptor.h"
+#include "intercept.h"
+#include "js.h"
 #include "lib.h"
 #include "output.h"
 #include "persistent.h"
@@ -44,13 +45,6 @@ typedef int *(*main_fn_t)(int argc, char **argv, char **envp);
 
 static main_fn_t main_fn = NULL;
 
-static int on_fork(void) {
-
-  prefetch_read();
-  return fork();
-
-}
-
 #ifdef __APPLE__
 static void on_main_os(int argc, char **argv, char **envp) {
 
@@ -101,7 +95,8 @@ static void afl_print_cmdline(void) {
 
   if (fd < 0) {
 
-    FATAL("Failed to open /proc/self/cmdline, errno: (%d)", errno);
+    WARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno);
+    return;
 
   }
 
@@ -138,7 +133,8 @@ static void afl_print_env(void) {
 
   if (fd < 0) {
 
-    FATAL("Failed to open /proc/self/cmdline, errno: (%d)", errno);
+    WARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno);
+    return;
 
   }
 
@@ -172,23 +168,36 @@ void afl_frida_start(void) {
   afl_print_cmdline();
   afl_print_env();
 
+  /* Configure */
+  entry_config();
+  instrument_config();
+  js_config();
+  lib_config();
+  output_config();
+  persistent_config();
+  prefetch_config();
+  ranges_config();
+  stalker_config();
+  stats_config();
+
+  js_start();
+
+  /* Initialize */
+  output_init();
+
   embedded_init();
-  stalker_init();
-  lib_init();
   entry_init();
   instrument_init();
-  output_init();
+  lib_init();
   persistent_init();
   prefetch_init();
+  stalker_init();
   ranges_init();
   stats_init();
 
-  void *fork_addr =
-      GSIZE_TO_POINTER(gum_module_find_export_by_name(NULL, "fork"));
-  intercept(fork_addr, on_fork, NULL);
-
+  /* Start */
   stalker_start();
-  entry_run();
+  entry_start();
 
 }
 
@@ -196,7 +205,7 @@ static int *on_main(int argc, char **argv, char **envp) {
 
   on_main_os(argc, argv, envp);
 
-  unintercept_self();
+  intercept_unhook_self();
 
   afl_frida_start();
 
@@ -210,7 +219,7 @@ extern int *main(int argc, char **argv, char **envp);
 static void intercept_main(void) {
 
   main_fn = main;
-  intercept(main, on_main, NULL);
+  intercept_hook(main, on_main, NULL);
 
 }
 
@@ -223,7 +232,7 @@ static void intercept_main(void) {
   OKF("Entry Point: 0x%016" G_GINT64_MODIFIER "x", entry);
   void *main = GSIZE_TO_POINTER(entry);
   main_fn = main;
-  intercept(main, on_main, NULL);
+  intercept_hook(main, on_main, NULL);
 
 }
 
@@ -234,8 +243,8 @@ static int on_libc_start_main(int *(main)(int, char **, char **), int argc,
                               void(*stack_end)) {
 
   main_fn = main;
-  unintercept_self();
-  intercept(main, on_main, NULL);
+  intercept_unhook_self();
+  intercept_hook(main, on_main, NULL);
   return __libc_start_main(main, argc, ubp_av, init, fini, rtld_fini,
                            stack_end);
 
@@ -243,7 +252,7 @@ static int on_libc_start_main(int *(main)(int, char **, char **), int argc,
 
 static void intercept_main(void) {
 
-  intercept(__libc_start_main, on_libc_start_main, NULL);
+  intercept_hook(__libc_start_main, on_libc_start_main, NULL);
 
 }
 
diff --git a/frida_mode/src/output.c b/frida_mode/src/output.c
index 8a222b25..e2b744e7 100644
--- a/frida_mode/src/output.c
+++ b/frida_mode/src/output.c
@@ -2,17 +2,17 @@
 #include <fcntl.h>
 #include <unistd.h>
 
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
 #include "output.h"
 
-static int output_fd = -1;
+char *output_stdout = NULL;
+char *output_stderr = NULL;
 
-static void output_redirect(int fd, char *variable) {
+static void output_redirect(int fd, char *filename) {
 
-  char *filename = getenv(variable);
   char *path = NULL;
 
   if (filename == NULL) { return; }
@@ -21,8 +21,8 @@ static void output_redirect(int fd, char *variable) {
 
   OKF("Redirect %d -> '%s'", fd, path);
 
-  output_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
-                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+  int output_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
+                       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
 
   g_free(path);
 
@@ -34,12 +34,24 @@ static void output_redirect(int fd, char *variable) {
 
   }
 
+  close(output_fd);
+
+}
+
+void output_config(void) {
+
+  output_stdout = getenv("AFL_FRIDA_OUTPUT_STDOUT");
+  output_stderr = getenv("AFL_FRIDA_OUTPUT_STDERR");
+
 }
 
 void output_init(void) {
 
-  output_redirect(STDOUT_FILENO, "AFL_FRIDA_OUTPUT_STDOUT");
-  output_redirect(STDERR_FILENO, "AFL_FRIDA_OUTPUT_STDERR");
+  OKF("Output - StdOut: %s", output_stdout);
+  OKF("Output - StdErr: %s", output_stderr);
+
+  output_redirect(STDOUT_FILENO, output_stdout);
+  output_redirect(STDERR_FILENO, output_stderr);
 
 }
 
diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c
index 243d501d..bcc59ea7 100644
--- a/frida_mode/src/persistent/persistent.c
+++ b/frida_mode/src/persistent/persistent.c
@@ -1,6 +1,6 @@
 #include <dlfcn.h>
 
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "config.h"
 #include "debug.h"
@@ -8,17 +8,18 @@
 #include "persistent.h"
 #include "util.h"
 
-int                    __afl_sharedmem_fuzzing = 0;
-afl_persistent_hook_fn hook = NULL;
+int          __afl_sharedmem_fuzzing = 0;
+static char *hook_name = NULL;
+
+afl_persistent_hook_fn persistent_hook = NULL;
 guint64                persistent_start = 0;
 guint64                persistent_count = 0;
 guint64                persistent_ret = 0;
 gboolean               persistent_debug = FALSE;
 
-void persistent_init(void) {
-
-  char *hook_name = getenv("AFL_FRIDA_PERSISTENT_HOOK");
+void persistent_config(void) {
 
+  hook_name = getenv("AFL_FRIDA_PERSISTENT_HOOK");
   persistent_start = util_read_address("AFL_FRIDA_PERSISTENT_ADDR");
   persistent_count = util_read_num("AFL_FRIDA_PERSISTENT_CNT");
   persistent_ret = util_read_address("AFL_FRIDA_PERSISTENT_RET");
@@ -33,6 +34,11 @@ void persistent_init(void) {
 
   }
 
+  if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000;
+
+  if (persistent_start != 0 && !persistent_is_supported())
+    FATAL("Persistent mode not supported on this architecture");
+
   if (persistent_ret != 0 && persistent_start == 0) {
 
     FATAL(
@@ -41,13 +47,28 @@ void persistent_init(void) {
 
   }
 
-  if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000;
+  if (hook_name == NULL) { return; }
 
-  if (persistent_count != 0 && persistent_count < 100)
-    WARNF("Persistent count out of recommended range (<100)");
+  void *hook_obj = dlopen(hook_name, RTLD_NOW);
+  if (hook_obj == NULL)
+    FATAL("Failed to load AFL_FRIDA_PERSISTENT_HOOK (%s)", hook_name);
 
-  if (persistent_start != 0 && !persistent_is_supported())
-    FATAL("Persistent mode not supported on this architecture");
+  int (*afl_persistent_hook_init_ptr)(void) =
+      dlsym(hook_obj, "afl_persistent_hook_init");
+  if (afl_persistent_hook_init_ptr == NULL)
+    FATAL("Failed to find afl_persistent_hook_init in %s", hook_name);
+
+  if (afl_persistent_hook_init_ptr() == 0)
+    FATAL("afl_persistent_hook_init returned a failure");
+
+  persistent_hook =
+      (afl_persistent_hook_fn)dlsym(hook_obj, "afl_persistent_hook");
+  if (persistent_hook == NULL)
+    FATAL("Failed to find afl_persistent_hook in %s", hook_name);
+
+}
+
+void persistent_init(void) {
 
   OKF("Instrumentation - persistent mode [%c] (0x%016" G_GINT64_MODIFIER "X)",
       persistent_start == 0 ? ' ' : 'X', persistent_start);
@@ -58,27 +79,7 @@ void persistent_init(void) {
   OKF("Instrumentation - persistent ret [%c] (0x%016" G_GINT64_MODIFIER "X)",
       persistent_ret == 0 ? ' ' : 'X', persistent_ret);
 
-  if (hook_name != NULL) {
-
-    void *hook_obj = dlopen(hook_name, RTLD_NOW);
-    if (hook_obj == NULL)
-      FATAL("Failed to load AFL_FRIDA_PERSISTENT_HOOK (%s)", hook_name);
-
-    int (*afl_persistent_hook_init_ptr)(void) =
-        dlsym(hook_obj, "afl_persistent_hook_init");
-    if (afl_persistent_hook_init_ptr == NULL)
-      FATAL("Failed to find afl_persistent_hook_init in %s", hook_name);
-
-    if (afl_persistent_hook_init_ptr() == 0)
-      FATAL("afl_persistent_hook_init returned a failure");
-
-    hook = (afl_persistent_hook_fn)dlsym(hook_obj, "afl_persistent_hook");
-    if (hook == NULL)
-      FATAL("Failed to find afl_persistent_hook in %s", hook_name);
-
-    __afl_sharedmem_fuzzing = 1;
-
-  }
+  if (persistent_hook != NULL) { __afl_sharedmem_fuzzing = 1; }
 
 }
 
diff --git a/frida_mode/src/persistent/persistent_arm32.c b/frida_mode/src/persistent/persistent_arm32.c
index 6a3c06fa..f12f1af8 100644
--- a/frida_mode/src/persistent/persistent_arm32.c
+++ b/frida_mode/src/persistent/persistent_arm32.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c
index d7c6c76b..003f058a 100644
--- a/frida_mode/src/persistent/persistent_arm64.c
+++ b/frida_mode/src/persistent/persistent_arm64.c
@@ -1,5 +1,5 @@
 #include <unistd.h>
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "config.h"
 #include "debug.h"
@@ -9,99 +9,15 @@
 #include "util.h"
 
 #if defined(__aarch64__)
+typedef struct {
 
-struct arm64_regs {
+  GumCpuContext ctx;
+  uint64_t      rflags;
 
-  uint64_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10;
+} persistent_ctx_t;
 
-  union {
-
-    uint64_t x11;
-    uint32_t fp_32;
-
-  };
-
-  union {
-
-    uint64_t x12;
-    uint32_t ip_32;
-
-  };
-
-  union {
-
-    uint64_t x13;
-    uint32_t sp_32;
-
-  };
-
-  union {
-
-    uint64_t x14;
-    uint32_t lr_32;
-
-  };
-
-  union {
-
-    uint64_t x15;
-    uint32_t pc_32;
-
-  };
-
-  union {
-
-    uint64_t x16;
-    uint64_t ip0;
-
-  };
-
-  union {
-
-    uint64_t x17;
-    uint64_t ip1;
-
-  };
-
-  uint64_t x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28;
-
-  union {
-
-    uint64_t x29;
-    uint64_t fp;
-
-  };
-
-  union {
-
-    uint64_t x30;
-    uint64_t lr;
-
-  };
-
-  union {
-
-    uint64_t x31;
-    uint64_t sp;
-
-  };
-
-  // the zero register is not saved here ofc
-
-  uint64_t pc;
-
-  uint32_t cpsr;
-
-  uint8_t  vfp_zregs[32][16 * 16];
-  uint8_t  vfp_pregs[17][32];
-  uint32_t vfp_xregs[16];
-
-};
-
-typedef struct arm64_regs arch_api_regs;
-
-static arch_api_regs saved_regs = {0};
-static gpointer      saved_lr = NULL;
+static persistent_ctx_t saved_regs = {0};
+static gpointer         saved_lr = NULL;
 
 gboolean persistent_is_supported(void) {
 
@@ -109,8 +25,8 @@ gboolean persistent_is_supported(void) {
 
 }
 
-static void instrument_persitent_save_regs(GumArm64Writer *   cw,
-                                           struct arm64_regs *regs) {
+static void instrument_persitent_save_regs(GumArm64Writer *  cw,
+                                           persistent_ctx_t *regs) {
 
   GumAddress    regs_address = GUM_ADDRESS(regs);
   const guint32 mrs_x1_nzcv = 0xd53b4201;
@@ -129,83 +45,87 @@ static void instrument_persitent_save_regs(GumArm64Writer *   cw,
 
   /* Skip x0 & x1 we'll do that later */
 
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3,
-                                              ARM64_REG_X0, (16 * 1),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X4, ARM64_REG_X5,
-                                              ARM64_REG_X0, (16 * 2),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X6, ARM64_REG_X7,
-                                              ARM64_REG_X0, (16 * 3),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X8, ARM64_REG_X9,
-                                              ARM64_REG_X0, (16 * 4),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X10, ARM64_REG_X11,
-                                              ARM64_REG_X0, (16 * 5),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X12, ARM64_REG_X13,
-                                              ARM64_REG_X0, (16 * 6),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X14, ARM64_REG_X15,
-                                              ARM64_REG_X0, (16 * 7),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X16, ARM64_REG_X17,
-                                              ARM64_REG_X0, (16 * 8),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X18, ARM64_REG_X19,
-                                              ARM64_REG_X0, (16 * 9),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X20, ARM64_REG_X21,
-                                              ARM64_REG_X0, (16 * 10),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X22, ARM64_REG_X23,
-                                              ARM64_REG_X0, (16 * 11),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X24, ARM64_REG_X25,
-                                              ARM64_REG_X0, (16 * 12),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X26, ARM64_REG_X27,
-                                              ARM64_REG_X0, (16 * 13),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X28, ARM64_REG_X29,
-                                              ARM64_REG_X0, (16 * 14),
-                                              GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[2]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X4, ARM64_REG_X5, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[4]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X6, ARM64_REG_X7, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[6]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X8, ARM64_REG_X9, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[8]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[10]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[12]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X14, ARM64_REG_X15, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[14]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X16, ARM64_REG_X17, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[16]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X18, ARM64_REG_X19, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[18]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X20, ARM64_REG_X21, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[20]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X22, ARM64_REG_X23, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[22]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X24, ARM64_REG_X25, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[24]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X26, ARM64_REG_X27, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[26]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X28, ARM64_REG_X29, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[28]), GUM_INDEX_SIGNED_OFFSET);
 
-  /* LR & Adjusted SP */
-  gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_X2, ARM64_REG_SP,
-                                       (GUM_RED_ZONE_SIZE + 32));
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X2,
-                                              ARM64_REG_X0, (16 * 15),
-                                              GUM_INDEX_SIGNED_OFFSET);
+  /* LR (x30) */
+  gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X0,
+                                          offsetof(GumCpuContext, x[30]));
 
-  /* PC & CPSR */
+  /* PC & Adjusted SP (31) */
   gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2,
                                        GUM_ADDRESS(persistent_start));
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X1,
-                                              ARM64_REG_X0, (16 * 16),
-                                              GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_X3, ARM64_REG_SP,
+                                       (GUM_RED_ZONE_SIZE + 32));
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0, offsetof(GumCpuContext, pc),
+      GUM_INDEX_SIGNED_OFFSET);
 
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q0, ARM64_REG_Q1,
-                                              ARM64_REG_X0, (16 * 17),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q2, ARM64_REG_Q3,
-                                              ARM64_REG_X0, (16 * 18),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q4, ARM64_REG_Q5,
-                                              ARM64_REG_X0, (16 * 19),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q6, ARM64_REG_Q7,
-                                              ARM64_REG_X0, (16 * 20),
-                                              GUM_INDEX_SIGNED_OFFSET);
+  /* CPSR */
+  gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0,
+                                          offsetof(persistent_ctx_t, rflags));
+
+  /* Q */
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_X0,
+      offsetof(GumCpuContext, q[0]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_X0,
+      offsetof(GumCpuContext, q[16]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_X0,
+      offsetof(GumCpuContext, q[32]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_Q6, ARM64_REG_Q7, ARM64_REG_X0,
+      offsetof(GumCpuContext, q[48]), GUM_INDEX_SIGNED_OFFSET);
 
   /* x0 & x1 */
   gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3,
                                               ARM64_REG_SP, 16,
                                               GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3,
-                                              ARM64_REG_X0, (16 * 0),
-                                              GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_stp_reg_reg_reg_offset(
+      cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[0]), GUM_INDEX_SIGNED_OFFSET);
 
   /* Pop the saved values */
   gum_arm64_writer_put_ldp_reg_reg_reg_offset(
@@ -217,8 +137,8 @@ static void instrument_persitent_save_regs(GumArm64Writer *   cw,
 
 }
 
-static void instrument_persitent_restore_regs(GumArm64Writer *   cw,
-                                              struct arm64_regs *regs) {
+static void instrument_persitent_restore_regs(GumArm64Writer *  cw,
+                                              persistent_ctx_t *regs) {
 
   GumAddress    regs_address = GUM_ADDRESS(regs);
   const guint32 msr_nzcv_x1 = 0xd51b4201;
@@ -228,82 +148,81 @@ static void instrument_persitent_restore_regs(GumArm64Writer *   cw,
 
   /* Skip x0 - x3 we'll do that last */
 
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X4, ARM64_REG_X5,
-                                              ARM64_REG_X0, (16 * 2),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X6, ARM64_REG_X7,
-                                              ARM64_REG_X0, (16 * 3),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X8, ARM64_REG_X9,
-                                              ARM64_REG_X0, (16 * 4),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X10, ARM64_REG_X11,
-                                              ARM64_REG_X0, (16 * 5),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X12, ARM64_REG_X13,
-                                              ARM64_REG_X0, (16 * 6),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X14, ARM64_REG_X15,
-                                              ARM64_REG_X0, (16 * 7),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X16, ARM64_REG_X17,
-                                              ARM64_REG_X0, (16 * 8),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X18, ARM64_REG_X19,
-                                              ARM64_REG_X0, (16 * 9),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X20, ARM64_REG_X21,
-                                              ARM64_REG_X0, (16 * 10),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X22, ARM64_REG_X23,
-                                              ARM64_REG_X0, (16 * 11),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X24, ARM64_REG_X25,
-                                              ARM64_REG_X0, (16 * 12),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X26, ARM64_REG_X27,
-                                              ARM64_REG_X0, (16 * 13),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X28, ARM64_REG_X29,
-                                              ARM64_REG_X0, (16 * 14),
-                                              GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X4, ARM64_REG_X5, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[4]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X6, ARM64_REG_X7, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[6]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X8, ARM64_REG_X9, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[8]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[10]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[12]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X14, ARM64_REG_X15, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[14]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X16, ARM64_REG_X17, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[16]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X18, ARM64_REG_X19, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[18]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X20, ARM64_REG_X21, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[20]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X22, ARM64_REG_X23, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[22]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X24, ARM64_REG_X25, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[24]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X26, ARM64_REG_X27, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[26]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X28, ARM64_REG_X29, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[28]), GUM_INDEX_SIGNED_OFFSET);
 
-  /* LR & Adjusted SP (use x1 as clobber) */
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X1,
-                                              ARM64_REG_X0, (16 * 15),
-                                              GUM_INDEX_SIGNED_OFFSET);
+  /* LR (x30) */
+  gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X0,
+                                          offsetof(GumCpuContext, x[30]));
 
+  /* Adjusted SP (31) (use x1 as clobber)*/
+  gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0,
+                                          offsetof(GumCpuContext, sp));
   gum_arm64_writer_put_mov_reg_reg(cw, ARM64_REG_SP, ARM64_REG_X1);
 
-  /* Don't restore RIP use x1-x3 as clobber */
-
-  /* PC (x2) & CPSR (x1) */
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X1,
-                                              ARM64_REG_X0, (16 * 16),
-                                              GUM_INDEX_SIGNED_OFFSET);
+  /* CPSR */
+  gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0,
+                                          offsetof(persistent_ctx_t, rflags));
   gum_arm64_writer_put_instruction(cw, msr_nzcv_x1);
 
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q0, ARM64_REG_Q1,
-                                              ARM64_REG_X0, (16 * 17),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q2, ARM64_REG_Q3,
-                                              ARM64_REG_X0, (16 * 18),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q4, ARM64_REG_Q5,
-                                              ARM64_REG_X0, (16 * 19),
-                                              GUM_INDEX_SIGNED_OFFSET);
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q6, ARM64_REG_Q7,
-                                              ARM64_REG_X0, (16 * 20),
-                                              GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_X0,
+      offsetof(GumCpuContext, q[0]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_X0,
+      offsetof(GumCpuContext, q[16]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_X0,
+      offsetof(GumCpuContext, q[32]), GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_Q6, ARM64_REG_Q7, ARM64_REG_X0,
+      offsetof(GumCpuContext, q[48]), GUM_INDEX_SIGNED_OFFSET);
 
   /* x2 & x3 */
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3,
-                                              ARM64_REG_X0, (16 * 1),
-                                              GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[2]), GUM_INDEX_SIGNED_OFFSET);
   /* x0 & x1 */
-  gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X0, ARM64_REG_X1,
-                                              ARM64_REG_X0, (16 * 0),
-                                              GUM_INDEX_SIGNED_OFFSET);
+  gum_arm64_writer_put_ldp_reg_reg_reg_offset(
+      cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_X0,
+      offsetof(GumCpuContext, x[0]), GUM_INDEX_SIGNED_OFFSET);
 
 }
 
@@ -318,7 +237,7 @@ static void instrument_exit(GumArm64Writer *cw) {
 static int instrument_afl_persistent_loop_func(void) {
 
   int ret = __afl_persistent_loop(persistent_count);
-  previous_pc = 0;
+  instrument_previous_pc = 0;
   return ret;
 
 }
@@ -334,29 +253,29 @@ static void instrument_afl_persistent_loop(GumArm64Writer *cw) {
 
 }
 
-static void persistent_prologue_hook(GumArm64Writer *   cw,
-                                     struct arm64_regs *regs) {
+static void persistent_prologue_hook(GumArm64Writer *  cw,
+                                     persistent_ctx_t *regs) {
 
-  if (hook == NULL) return;
+  if (persistent_hook == NULL) return;
 
   gum_arm64_writer_put_sub_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP,
                                        GUM_RED_ZONE_SIZE);
-  gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X3,
+  gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2,
                                        GUM_ADDRESS(&__afl_fuzz_len));
-  gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X3, ARM64_REG_X3, 0);
-  gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X3, ARM64_REG_X3, 0);
+  gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0);
+  gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0);
 
-  gum_arm64_writer_put_and_reg_reg_imm(cw, ARM64_REG_X3, ARM64_REG_X3,
+  gum_arm64_writer_put_and_reg_reg_imm(cw, ARM64_REG_X2, ARM64_REG_X2,
                                        G_MAXULONG);
 
-  gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2,
+  gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X1,
                                        GUM_ADDRESS(&__afl_fuzz_ptr));
-  gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0);
+  gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X1, 0);
 
   gum_arm64_writer_put_call_address_with_arguments(
-      cw, GUM_ADDRESS(hook), 4, GUM_ARG_ADDRESS, GUM_ADDRESS(regs),
-      GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_REGISTER, ARM64_REG_X2,
-      GUM_ARG_REGISTER, ARM64_REG_X3);
+      cw, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS,
+      GUM_ADDRESS(&regs->ctx), GUM_ARG_REGISTER, ARM64_REG_X1, GUM_ARG_REGISTER,
+      ARM64_REG_X2);
 
   gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP,
                                        GUM_RED_ZONE_SIZE);
@@ -406,6 +325,8 @@ void persistent_prologue(GumStalkerOutput *output) {
 
   gconstpointer loop = cw->code + 1;
 
+  OKF("Persistent loop reached");
+
   instrument_persitent_save_regs(cw, &saved_regs);
 
   /* loop: */
diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c
index 653acefe..b2186db1 100644
--- a/frida_mode/src/persistent/persistent_x64.c
+++ b/frida_mode/src/persistent/persistent_x64.c
@@ -1,5 +1,5 @@
 #include <unistd.h>
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "config.h"
 #include "debug.h"
@@ -10,40 +10,15 @@
 
 #if defined(__x86_64__)
 
-struct x86_64_regs {
+typedef struct {
 
-  uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, r8, r9, r10, r11, r12, r13, r14,
-      r15;
+  GumCpuContext ctx;
+  uint64_t      rflags;
 
-  union {
+} persistent_ctx_t;
 
-    uint64_t rip;
-    uint64_t pc;
-
-  };
-
-  union {
-
-    uint64_t rsp;
-    uint64_t sp;
-
-  };
-
-  union {
-
-    uint64_t rflags;
-    uint64_t flags;
-
-  };
-
-  uint8_t zmm_regs[32][64];
-
-};
-
-typedef struct x86_64_regs arch_api_regs;
-
-static arch_api_regs saved_regs = {0};
-static gpointer      saved_ret = NULL;
+static persistent_ctx_t saved_regs = {0};
+static gpointer         saved_ret = NULL;
 
 gboolean persistent_is_supported(void) {
 
@@ -51,8 +26,8 @@ gboolean persistent_is_supported(void) {
 
 }
 
-static void instrument_persitent_save_regs(GumX86Writer *      cw,
-                                           struct x86_64_regs *regs) {
+static void instrument_persitent_save_regs(GumX86Writer *    cw,
+                                           persistent_ctx_t *regs) {
 
   GumAddress regs_address = GUM_ADDRESS(regs);
   gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP,
@@ -64,41 +39,41 @@ static void instrument_persitent_save_regs(GumX86Writer *      cw,
 
   gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, regs_address);
 
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 1),
-                                            GUM_REG_RBX);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 2),
-                                            GUM_REG_RCX);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 3),
-                                            GUM_REG_RDX);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 4),
-                                            GUM_REG_RDI);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 5),
-                                            GUM_REG_RSI);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 6),
-                                            GUM_REG_RBP);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 7),
-                                            GUM_REG_R8);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 8),
-                                            GUM_REG_R9);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 9),
-                                            GUM_REG_R10);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 10),
-                                            GUM_REG_R11);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 11),
-                                            GUM_REG_R12);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 12),
-                                            GUM_REG_R13);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 13),
-                                            GUM_REG_R14);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 14),
-                                            GUM_REG_R15);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, rbx), GUM_REG_RBX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, rcx), GUM_REG_RCX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, rdx), GUM_REG_RDX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, rdi), GUM_REG_RDI);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, rsi), GUM_REG_RSI);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, rbp), GUM_REG_RBP);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, r8), GUM_REG_R8);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, r9), GUM_REG_R9);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, r10), GUM_REG_R10);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, r11), GUM_REG_R11);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, r12), GUM_REG_R12);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, r13), GUM_REG_R13);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, r14), GUM_REG_R14);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, r15), GUM_REG_R15);
 
   /* Store RIP */
   gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RBX,
                                      GUM_ADDRESS(persistent_start));
 
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 15),
-                                            GUM_REG_RBX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, rip), GUM_REG_RBX);
 
   /* Store adjusted RSP */
   gum_x86_writer_put_mov_reg_reg(cw, GUM_REG_RBX, GUM_REG_RSP);
@@ -106,18 +81,18 @@ static void instrument_persitent_save_regs(GumX86Writer *      cw,
   /* RED_ZONE + Saved flags, RAX, alignment */
   gum_x86_writer_put_add_reg_imm(cw, GUM_REG_RBX,
                                  GUM_RED_ZONE_SIZE + (0x8 * 2));
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 16),
-                                            GUM_REG_RBX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, rsp), GUM_REG_RBX);
 
   /* Save the flags */
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, 0x8);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 17),
-                                            GUM_REG_RBX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(persistent_ctx_t, rflags), GUM_REG_RBX);
 
   /* Save the RAX */
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, 0x0);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 0),
-                                            GUM_REG_RBX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_RAX, offsetof(GumCpuContext, rax), GUM_REG_RBX);
 
   /* Pop the saved values */
   gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 0x10);
@@ -127,56 +102,56 @@ static void instrument_persitent_save_regs(GumX86Writer *      cw,
 
 }
 
-static void instrument_persitent_restore_regs(GumX86Writer *      cw,
-                                              struct x86_64_regs *regs) {
+static void instrument_persitent_restore_regs(GumX86Writer *    cw,
+                                              persistent_ctx_t *regs) {
 
   GumAddress regs_address = GUM_ADDRESS(regs);
   gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, regs_address);
 
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RAX,
-                                            (0x8 * 2));
+                                            offsetof(GumCpuContext, rcx));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RAX,
-                                            (0x8 * 3));
+                                            offsetof(GumCpuContext, rdx));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDI, GUM_REG_RAX,
-                                            (0x8 * 4));
+                                            offsetof(GumCpuContext, rdi));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSI, GUM_REG_RAX,
-                                            (0x8 * 5));
+                                            offsetof(GumCpuContext, rsi));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBP, GUM_REG_RAX,
-                                            (0x8 * 6));
+                                            offsetof(GumCpuContext, rbp));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R8, GUM_REG_RAX,
-                                            (0x8 * 7));
+                                            offsetof(GumCpuContext, r8));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R9, GUM_REG_RAX,
-                                            (0x8 * 8));
+                                            offsetof(GumCpuContext, r9));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R10, GUM_REG_RAX,
-                                            (0x8 * 9));
+                                            offsetof(GumCpuContext, r10));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R11, GUM_REG_RAX,
-                                            (0x8 * 10));
+                                            offsetof(GumCpuContext, r11));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R12, GUM_REG_RAX,
-                                            (0x8 * 11));
+                                            offsetof(GumCpuContext, r12));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R13, GUM_REG_RAX,
-                                            (0x8 * 12));
+                                            offsetof(GumCpuContext, r13));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R14, GUM_REG_RAX,
-                                            (0x8 * 13));
+                                            offsetof(GumCpuContext, r14));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R15, GUM_REG_RAX,
-                                            (0x8 * 14));
+                                            offsetof(GumCpuContext, r15));
 
   /* Don't restore RIP */
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSP, GUM_REG_RAX,
-                                            (0x8 * 16));
+                                            offsetof(GumCpuContext, rsp));
 
   /* Restore RBX, RAX & Flags */
   gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP,
                                         -(GUM_RED_ZONE_SIZE));
 
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX,
-                                            (0x8 * 1));
+                                            offsetof(GumCpuContext, rbx));
   gum_x86_writer_put_push_reg(cw, GUM_REG_RBX);
 
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX,
-                                            (0x8 * 0));
+                                            offsetof(GumCpuContext, rax));
   gum_x86_writer_put_push_reg(cw, GUM_REG_RBX);
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX,
-                                            (0x8 * 17));
+                                            offsetof(persistent_ctx_t, rflags));
   gum_x86_writer_put_push_reg(cw, GUM_REG_RBX);
 
   gum_x86_writer_put_popfx(cw);
@@ -199,7 +174,7 @@ static void instrument_exit(GumX86Writer *cw) {
 static int instrument_afl_persistent_loop_func(void) {
 
   int ret = __afl_persistent_loop(persistent_count);
-  previous_pc = 0;
+  instrument_previous_pc = 0;
   return ret;
 
 }
@@ -217,28 +192,27 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) {
 
 }
 
-static void persistent_prologue_hook(GumX86Writer *      cw,
-                                     struct x86_64_regs *regs) {
+static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) {
 
-  if (hook == NULL) return;
+  if (persistent_hook == NULL) return;
   gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP,
                                         -(GUM_RED_ZONE_SIZE));
 
-  gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RCX,
+  gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDX,
                                      GUM_ADDRESS(&__afl_fuzz_len));
-  gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RCX, 0);
-  gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RCX, 0);
+  gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0);
+  gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0);
   gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_RDI, 0xffffffff);
-  gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RCX, GUM_REG_RDI);
+  gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RDX, GUM_REG_RDI);
 
-  gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDX,
+  gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RSI,
                                      GUM_ADDRESS(&__afl_fuzz_ptr));
-  gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0);
+  gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSI, GUM_REG_RSI, 0);
 
   gum_x86_writer_put_call_address_with_arguments(
-      cw, GUM_CALL_CAPI, GUM_ADDRESS(hook), 4, GUM_ARG_ADDRESS,
-      GUM_ADDRESS(regs), GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_REGISTER,
-      GUM_REG_RDX, GUM_ARG_REGISTER, GUM_REG_RCX);
+      cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS,
+      GUM_ADDRESS(&regs->ctx), GUM_ARG_REGISTER, GUM_REG_RSI, GUM_ARG_REGISTER,
+      GUM_REG_RDX);
 
   gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP,
                                         (GUM_RED_ZONE_SIZE));
@@ -296,6 +270,8 @@ void persistent_prologue(GumStalkerOutput *output) {
 
   gconstpointer loop = cw->code + 1;
 
+  OKF("Persistent loop reached");
+
   /* Pop the return value */
   gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 8);
 
diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c
index 7add6e99..f50bccb0 100644
--- a/frida_mode/src/persistent/persistent_x86.c
+++ b/frida_mode/src/persistent/persistent_x86.c
@@ -1,45 +1,23 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "config.h"
+#include "debug.h"
 
 #include "instrument.h"
 #include "persistent.h"
 
 #if defined(__i386__)
 
-struct x86_regs {
+typedef struct {
 
-  uint32_t eax, ebx, ecx, edx, edi, esi, ebp;
+  GumCpuContext ctx;
+  uint32_t      eflags;
 
-  union {
+} persistent_ctx_t;
 
-    uint32_t eip;
-    uint32_t pc;
+static persistent_ctx_t saved_regs = {0};
 
-  };
-
-  union {
-
-    uint32_t esp;
-    uint32_t sp;
-
-  };
-
-  union {
-
-    uint32_t eflags;
-    uint32_t flags;
-
-  };
-
-  uint8_t xmm_regs[8][16];
-
-};
-
-typedef struct x86_regs arch_api_regs;
-
-static arch_api_regs saved_regs = {0};
-static gpointer      saved_ret = NULL;
+static gpointer saved_ret = NULL;
 
 gboolean persistent_is_supported(void) {
 
@@ -47,8 +25,8 @@ gboolean persistent_is_supported(void) {
 
 }
 
-static void instrument_persitent_save_regs(GumX86Writer *   cw,
-                                           struct x86_regs *regs) {
+static void instrument_persitent_save_regs(GumX86Writer *    cw,
+                                           persistent_ctx_t *regs) {
 
   GumAddress regs_address = GUM_ADDRESS(regs);
 
@@ -58,80 +36,80 @@ static void instrument_persitent_save_regs(GumX86Writer *   cw,
 
   gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, regs_address);
 
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 1),
-                                            GUM_REG_EBX);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 2),
-                                            GUM_REG_ECX);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 3),
-                                            GUM_REG_EDX);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 4),
-                                            GUM_REG_EDI);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 5),
-                                            GUM_REG_ESI);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 6),
-                                            GUM_REG_EBP);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_EAX, offsetof(GumCpuContext, ebx), GUM_REG_EBX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_EAX, offsetof(GumCpuContext, ecx), GUM_REG_ECX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_EAX, offsetof(GumCpuContext, edx), GUM_REG_EDX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_EAX, offsetof(GumCpuContext, edi), GUM_REG_EDI);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_EAX, offsetof(GumCpuContext, esi), GUM_REG_ESI);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_EAX, offsetof(GumCpuContext, ebp), GUM_REG_EBP);
 
   /* Store RIP */
   gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EBX,
                                      GUM_ADDRESS(persistent_start));
 
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 7),
-                                            GUM_REG_EBX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_EAX, offsetof(GumCpuContext, eip), GUM_REG_EBX);
 
   /* Store adjusted RSP */
   gum_x86_writer_put_mov_reg_reg(cw, GUM_REG_EBX, GUM_REG_ESP);
 
   /* RED_ZONE + Saved flags, RAX */
   gum_x86_writer_put_add_reg_imm(cw, GUM_REG_EBX, (0x4 * 2));
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 8),
-                                            GUM_REG_EBX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_EAX, offsetof(GumCpuContext, esp), GUM_REG_EBX);
 
   /* Save the flags */
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x4);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 9),
-                                            GUM_REG_EBX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_EAX, offsetof(persistent_ctx_t, eflags), GUM_REG_EBX);
 
   /* Save the RAX */
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x0);
-  gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 0),
-                                            GUM_REG_EBX);
+  gum_x86_writer_put_mov_reg_offset_ptr_reg(
+      cw, GUM_REG_EAX, offsetof(GumCpuContext, eax), GUM_REG_EBX);
 
   /* Pop the saved values */
   gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 0x8);
 
 }
 
-static void instrument_persitent_restore_regs(GumX86Writer *   cw,
-                                              struct x86_regs *regs) {
+static void instrument_persitent_restore_regs(GumX86Writer *    cw,
+                                              persistent_ctx_t *regs) {
 
   GumAddress regs_address = GUM_ADDRESS(regs);
   gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, regs_address);
 
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ECX, GUM_REG_EAX,
-                                            (0x4 * 2));
+                                            offsetof(GumCpuContext, ecx));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDX, GUM_REG_EAX,
-                                            (0x4 * 3));
+                                            offsetof(GumCpuContext, edx));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDI, GUM_REG_EAX,
-                                            (0x4 * 4));
+                                            offsetof(GumCpuContext, edi));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESI, GUM_REG_EAX,
-                                            (0x4 * 5));
+                                            offsetof(GumCpuContext, esi));
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBP, GUM_REG_EAX,
-                                            (0x4 * 6));
+                                            offsetof(GumCpuContext, ebp));
 
   /* Don't restore RIP */
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESP, GUM_REG_EAX,
-                                            (0x4 * 8));
+                                            offsetof(GumCpuContext, esp));
 
   /* Restore RBX, RAX & Flags */
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX,
-                                            (0x4 * 1));
+                                            offsetof(GumCpuContext, ebx));
   gum_x86_writer_put_push_reg(cw, GUM_REG_EBX);
 
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX,
-                                            (0x4 * 0));
+                                            offsetof(GumCpuContext, eax));
   gum_x86_writer_put_push_reg(cw, GUM_REG_EBX);
   gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX,
-                                            (0x4 * 9));
+                                            offsetof(persistent_ctx_t, eflags));
   gum_x86_writer_put_push_reg(cw, GUM_REG_EBX);
 
   gum_x86_writer_put_popfx(cw);
@@ -152,7 +130,7 @@ static void instrument_exit(GumX86Writer *cw) {
 static int instrument_afl_persistent_loop_func(void) {
 
   int ret = __afl_persistent_loop(persistent_count);
-  previous_pc = 0;
+  instrument_previous_pc = 0;
   return ret;
 
 }
@@ -165,9 +143,9 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) {
 
 }
 
-static void persistent_prologue_hook(GumX86Writer *cw, struct x86_regs *regs) {
+static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) {
 
-  if (hook == NULL) return;
+  if (persistent_hook == NULL) return;
 
   gum_x86_writer_put_mov_reg_address(cw, GUM_REG_ECX,
                                      GUM_ADDRESS(&__afl_fuzz_len));
@@ -180,9 +158,8 @@ static void persistent_prologue_hook(GumX86Writer *cw, struct x86_regs *regs) {
 
   /* Base address is 64-bits (hence two zero arguments) */
   gum_x86_writer_put_call_address_with_arguments(
-      cw, GUM_CALL_CAPI, GUM_ADDRESS(hook), 5, GUM_ARG_ADDRESS,
-      GUM_ADDRESS(regs), GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_ADDRESS,
-      GUM_ADDRESS(0), GUM_ARG_REGISTER, GUM_REG_EDX, GUM_ARG_REGISTER,
+      cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS,
+      GUM_ADDRESS(&regs->ctx), GUM_ARG_REGISTER, GUM_REG_EDX, GUM_ARG_REGISTER,
       GUM_REG_ECX);
 
 }
@@ -233,6 +210,8 @@ void persistent_prologue(GumStalkerOutput *output) {
 
   gconstpointer loop = cw->code + 1;
 
+  OKF("Persistent loop reached");
+
   /* Pop the return value */
   gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 4);
 
diff --git a/frida_mode/src/prefetch.c b/frida_mode/src/prefetch.c
index 65c09fba..50d10c9e 100644
--- a/frida_mode/src/prefetch.c
+++ b/frida_mode/src/prefetch.c
@@ -2,10 +2,11 @@
 #include <sys/shm.h>
 #include <sys/mman.h>
 
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
+#include "intercept.h"
 #include "prefetch.h"
 #include "stalker.h"
 
@@ -20,9 +21,10 @@ typedef struct {
 
 } prefetch_data_t;
 
-static prefetch_data_t *prefetch_data = NULL;
+gboolean prefetch_enable = TRUE;
 
-static int prefetch_shm_id = -1;
+static prefetch_data_t *prefetch_data = NULL;
+static int              prefetch_shm_id = -1;
 
 /*
  * We do this from the transformer since we need one anyway for coverage, this
@@ -72,14 +74,33 @@ void prefetch_read(void) {
 
 }
 
+void prefetch_config(void) {
+
+  prefetch_enable = (getenv("AFL_FRIDA_INST_NO_PREFETCH") == NULL);
+
+}
+
+static int prefetch_on_fork(void) {
+
+  prefetch_read();
+  return fork();
+
+}
+
+static void prefetch_hook_fork(void) {
+
+  void *fork_addr =
+      GSIZE_TO_POINTER(gum_module_find_export_by_name(NULL, "fork"));
+  intercept_hook(fork_addr, prefetch_on_fork, NULL);
+
+}
+
 void prefetch_init(void) {
 
   g_assert_cmpint(sizeof(prefetch_data_t), ==, PREFETCH_SIZE);
-  gboolean prefetch = (getenv("AFL_FRIDA_INST_NO_PREFETCH") == NULL);
+  OKF("Instrumentation - prefetch [%c]", prefetch_enable ? 'X' : ' ');
 
-  OKF("Instrumentation - prefetch [%c]", prefetch ? 'X' : ' ');
-
-  if (!prefetch) { return; }
+  if (!prefetch_enable) { return; }
   /*
    * Make our shared memory, we can attach before we fork, just like AFL does
    * with the coverage bitmap region and fork will take care of ensuring both
@@ -108,5 +129,7 @@ void prefetch_init(void) {
   /* Clear it, not sure it's necessary, just seems like good practice */
   memset(prefetch_data, '\0', sizeof(prefetch_data_t));
 
+  prefetch_hook_fork();
+
 }
 
diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c
index ef25b371..534f202b 100644
--- a/frida_mode/src/ranges.c
+++ b/frida_mode/src/ranges.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
@@ -17,11 +17,14 @@ typedef struct {
 
 } convert_name_ctx_t;
 
-GArray *module_ranges = NULL;
-GArray *libs_ranges = NULL;
-GArray *include_ranges = NULL;
-GArray *exclude_ranges = NULL;
-GArray *ranges = NULL;
+gboolean ranges_debug_maps = FALSE;
+gboolean ranges_inst_libs = FALSE;
+
+static GArray *module_ranges = NULL;
+static GArray *libs_ranges = NULL;
+static GArray *include_ranges = NULL;
+static GArray *exclude_ranges = NULL;
+static GArray *ranges = NULL;
 
 static void convert_address_token(gchar *token, GumMemoryRange *range) {
 
@@ -225,6 +228,43 @@ static GArray *collect_module_ranges(void) {
 
 }
 
+static void check_for_overlaps(GArray *array) {
+
+  for (guint i = 1; i < array->len; i++) {
+
+    GumMemoryRange *prev = &g_array_index(array, GumMemoryRange, i - 1);
+    GumMemoryRange *curr = &g_array_index(array, GumMemoryRange, i);
+    GumAddress      prev_limit = prev->base_address + prev->size;
+    GumAddress      curr_limit = curr->base_address + curr->size;
+    if (prev_limit > curr->base_address) {
+
+      FATAL("OVerlapping ranges 0x%016" G_GINT64_MODIFIER
+            "x-0x%016" G_GINT64_MODIFIER "x 0x%016" G_GINT64_MODIFIER
+            "x-0x%016" G_GINT64_MODIFIER "x",
+            prev->base_address, prev_limit, curr->base_address, curr_limit);
+
+    }
+
+  }
+
+}
+
+void ranges_add_include(GumMemoryRange *range) {
+
+  g_array_append_val(include_ranges, *range);
+  g_array_sort(include_ranges, range_sort);
+  check_for_overlaps(include_ranges);
+
+}
+
+void ranges_add_exclude(GumMemoryRange *range) {
+
+  g_array_append_val(exclude_ranges, *range);
+  g_array_sort(exclude_ranges, range_sort);
+  check_for_overlaps(exclude_ranges);
+
+}
+
 static GArray *collect_ranges(char *env_key) {
 
   char *         env_val;
@@ -253,23 +293,7 @@ static GArray *collect_ranges(char *env_key) {
 
   g_array_sort(result, range_sort);
 
-  /* Check for overlaps */
-  for (i = 1; i < token_count; i++) {
-
-    GumMemoryRange *prev = &g_array_index(result, GumMemoryRange, i - 1);
-    GumMemoryRange *curr = &g_array_index(result, GumMemoryRange, i);
-    GumAddress      prev_limit = prev->base_address + prev->size;
-    GumAddress      curr_limit = curr->base_address + curr->size;
-    if (prev_limit > curr->base_address) {
-
-      FATAL("OVerlapping ranges 0x%016" G_GINT64_MODIFIER
-            "x-0x%016" G_GINT64_MODIFIER "x 0x%016" G_GINT64_MODIFIER
-            "x-0x%016" G_GINT64_MODIFIER "x",
-            prev->base_address, prev_limit, curr->base_address, curr_limit);
-
-    }
-
-  }
+  check_for_overlaps(result);
 
   print_ranges(env_key, result);
 
@@ -285,15 +309,15 @@ static GArray *collect_libs_ranges(void) {
   GumMemoryRange range;
   result = g_array_new(false, false, sizeof(GumMemoryRange));
 
-  if (getenv("AFL_INST_LIBS") == NULL) {
+  if (ranges_inst_libs) {
 
-    range.base_address = lib_get_text_base();
-    range.size = lib_get_text_limit() - lib_get_text_base();
+    range.base_address = 0;
+    range.size = G_MAXULONG;
 
   } else {
 
-    range.base_address = 0;
-    range.size = G_MAXULONG;
+    range.base_address = lib_get_text_base();
+    range.size = lib_get_text_limit() - lib_get_text_base();
 
   }
 
@@ -480,30 +504,13 @@ static GArray *merge_ranges(GArray *a) {
 
 }
 
-static gboolean exclude_ranges_callback(const GumRangeDetails *details,
-                                        gpointer               user_data) {
+void ranges_config(void) {
 
-  UNUSED_PARAMETER(user_data);
-  gchar *     name;
-  gboolean    found;
-  GumStalker *stalker;
-  if (details->file == NULL) { return TRUE; }
-  name = g_path_get_basename(details->file->path);
-
-  found = (g_strcmp0(name, "afl-frida-trace.so") == 0);
-  g_free(name);
-  if (!found) { return TRUE; }
-
-  stalker = stalker_get();
-  gum_stalker_exclude(stalker, details->range);
-
-  return FALSE;
+  if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) { ranges_debug_maps = TRUE; }
+  if (getenv("AFL_INST_LIBS") != NULL) { ranges_inst_libs = TRUE; }
 
-}
-
-static void ranges_exclude_self(void) {
-
-  gum_process_enumerate_ranges(GUM_PAGE_EXECUTE, exclude_ranges_callback, NULL);
+  include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES");
+  exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES");
 
 }
 
@@ -515,16 +522,20 @@ void ranges_init(void) {
   GArray *       step3;
   GArray *       step4;
 
-  if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) {
+  if (ranges_debug_maps) {
 
     gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback,
                                  NULL);
 
   }
 
+  OKF("Ranges - Instrument libraries [%c]", ranges_inst_libs ? 'X' : ' ');
+
+  print_ranges("AFL_FRIDA_INST_RANGES", include_ranges);
+  print_ranges("AFL_FRIDA_EXCLUDE_RANGES", exclude_ranges);
+
   module_ranges = collect_module_ranges();
   libs_ranges = collect_libs_ranges();
-  include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES");
 
   /* If include ranges is empty, then assume everything is included */
   if (include_ranges->len == 0) {
@@ -535,8 +546,6 @@ void ranges_init(void) {
 
   }
 
-  exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES");
-
   /* Intersect with .text section of main executable unless AFL_INST_LIBS */
   step1 = intersect_ranges(module_ranges, libs_ranges);
   print_ranges("step1", step1);
@@ -565,9 +574,6 @@ void ranges_init(void) {
   g_array_free(step2, TRUE);
   g_array_free(step1, TRUE);
 
-  /* *NEVER* stalk the stalker, only bad things will ever come of this! */
-  ranges_exclude_self();
-
   ranges_exclude();
 
 }
diff --git a/frida_mode/src/stalker.c b/frida_mode/src/stalker.c
index 63f3c529..98483cde 100644
--- a/frida_mode/src/stalker.c
+++ b/frida_mode/src/stalker.c
@@ -2,18 +2,47 @@
 
 #include "instrument.h"
 #include "stalker.h"
+#include "util.h"
 
 static GumStalker *stalker = NULL;
 
-void stalker_init(void) {
+void stalker_config(void) {
 
   if (!gum_stalker_is_supported()) { FATAL("Failed to initialize embedded"); }
 
+}
+
+static gboolean stalker_exclude_self(const GumRangeDetails *details,
+                                     gpointer               user_data) {
+
+  UNUSED_PARAMETER(user_data);
+  gchar *     name;
+  gboolean    found;
+  GumStalker *stalker;
+  if (details->file == NULL) { return TRUE; }
+  name = g_path_get_basename(details->file->path);
+
+  found = (g_strcmp0(name, "afl-frida-trace.so") == 0);
+  g_free(name);
+  if (!found) { return TRUE; }
+
+  stalker = stalker_get();
+  gum_stalker_exclude(stalker, details->range);
+
+  return FALSE;
+
+}
+
+void stalker_init(void) {
+
   stalker = gum_stalker_new();
   if (stalker == NULL) { FATAL("Failed to initialize stalker"); }
 
   gum_stalker_set_trust_threshold(stalker, 0);
 
+  /* *NEVER* stalk the stalker, only bad things will ever come of this! */
+  gum_process_enumerate_ranges(GUM_PAGE_EXECUTE, stalker_exclude_self, NULL);
+
 }
 
 GumStalker *stalker_get(void) {
diff --git a/frida_mode/src/stats/stats.c b/frida_mode/src/stats/stats.c
index 0d7b9fb0..0dd8be70 100644
--- a/frida_mode/src/stats/stats.c
+++ b/frida_mode/src/stats/stats.c
@@ -5,7 +5,7 @@
 #include <sys/shm.h>
 #include <sys/mman.h>
 
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "config.h"
 #include "debug.h"
@@ -17,15 +17,16 @@
 
 stats_data_header_t *stats_data = NULL;
 
-static int      stats_parent_pid = -1;
-static int      stats_fd = -1;
-static gboolean stats_transitions = FALSE;
-static guint64  stats_interval = 0;
+static int stats_parent_pid = -1;
+static int stats_fd = -1;
 
-void stats_init(void) {
+char *   stats_filename = NULL;
+guint64  stats_interval = 0;
+gboolean stats_transitions = FALSE;
 
-  stats_parent_pid = getpid();
-  char *filename = getenv("AFL_FRIDA_STATS_FILE");
+void stats_config(void) {
+
+  stats_filename = getenv("AFL_FRIDA_STATS_FILE");
   stats_interval = util_read_num("AFL_FRIDA_STATS_INTERVAL");
   if (getenv("AFL_FRIDA_STATS_TRANSITIONS") != NULL) {
 
@@ -33,10 +34,16 @@ void stats_init(void) {
 
   }
 
-  OKF("Stats - file [%s]", filename);
+}
+
+void stats_init(void) {
+
+  stats_parent_pid = getpid();
+
+  OKF("Stats - file [%s]", stats_filename);
   OKF("Stats - interval [%" G_GINT64_MODIFIER "u]", stats_interval);
 
-  if (stats_interval != 0 && filename == NULL) {
+  if (stats_interval != 0 && stats_filename == NULL) {
 
     FATAL(
         "AFL_FRIDA_STATS_FILE must be specified if "
@@ -46,7 +53,7 @@ void stats_init(void) {
 
   if (stats_interval == 0) { stats_interval = 10; }
 
-  if (filename == NULL) { return; }
+  if (stats_filename == NULL) { return; }
 
   if (!stats_is_supported_arch()) {
 
@@ -56,11 +63,11 @@ void stats_init(void) {
 
   char *path = NULL;
 
-  if (filename == NULL) { return; }
+  if (stats_filename == NULL) { return; }
 
   if (stats_transitions) { gum_stalker_set_counters_enabled(TRUE); }
 
-  path = g_canonicalize_filename(filename, g_get_current_dir());
+  path = g_canonicalize_filename(stats_filename, g_get_current_dir());
 
   OKF("Stats - path [%s]", path);
 
diff --git a/frida_mode/src/stats/stats_arm32.c b/frida_mode/src/stats/stats_arm32.c
index 7eea7f91..71953af3 100644
--- a/frida_mode/src/stats/stats_arm32.c
+++ b/frida_mode/src/stats/stats_arm32.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
diff --git a/frida_mode/src/stats/stats_arm64.c b/frida_mode/src/stats/stats_arm64.c
index 592af87a..d9d374a4 100644
--- a/frida_mode/src/stats/stats_arm64.c
+++ b/frida_mode/src/stats/stats_arm64.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
diff --git a/frida_mode/src/stats/stats_x64.c b/frida_mode/src/stats/stats_x64.c
index c3e8742a..7c3a90d7 100644
--- a/frida_mode/src/stats/stats_x64.c
+++ b/frida_mode/src/stats/stats_x64.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"
 
diff --git a/frida_mode/src/stats/stats_x86.c b/frida_mode/src/stats/stats_x86.c
index 1906e809..d9c4f652 100644
--- a/frida_mode/src/stats/stats_x86.c
+++ b/frida_mode/src/stats/stats_x86.c
@@ -1,4 +1,4 @@
-#include "frida-gum.h"
+#include "frida-gumjs.h"
 
 #include "debug.h"