Compare commits

...

184 Commits
4.01c ... 4.04c

Author SHA1 Message Date
cbfa5207ba Merge pull request #1551 from AFLplusplus/dev
push to stable
2022-10-11 15:40:55 +02:00
bac6ba8907 v4.04c 2022-10-11 15:39:27 +02:00
de9d1ff4a0 doc fixes 2022-10-11 12:43:06 +02:00
e6e82948bf fastexit + code format 2022-10-11 08:53:49 +02:00
c5008362c6 Merge pull request #1543 from quinox/feat-make-on-gentoo
Support building LTO on Gentoo
2022-10-10 17:08:01 +02:00
db4fa9319d Fix #1548 2022-10-10 14:37:16 +02:00
680e6e91a1 Support building LTO on Gentoo 2022-10-08 09:51:26 +02:00
2107ece114 auto shmem fuzzing (#1541)
* auto shmem fuzzing

* print warning when forcing shmem fuzzing

* typos

* Shmem always

* typo fix

* fixes

Co-authored-by: Dominik Maier <dmnk@google.com>
2022-10-07 15:40:04 +02:00
5e04c9693b fix qemu_mode speed bug 2022-10-04 08:39:07 +02:00
9e4137a3eb Enabled tricore arch for unicornafl 2022-10-03 22:58:21 +02:00
jma
97fb0b5099 fix Rust speedtest example dependency (#1542) 2022-10-03 12:06:43 +02:00
9c6aebba05 typos 2022-10-03 11:04:23 +02:00
3e0fe86465 Merge pull request #1539 from devnexen/reallocarr
libdislocator adding netbsd's reallocarr
2022-10-01 18:27:02 +02:00
0eeddda2c8 libdislocator adding netbsd's reallocarr 2022-10-01 16:12:32 +01:00
586aec7116 Fixed typo in README.llvm.md (#1538)
Co-authored-by: van Hauser <vh@thc.org>
2022-09-29 12:42:04 +02:00
7e0171006a Merge pull request #1537 from AFLplusplus/dev
push to stable
2022-09-28 22:56:28 +02:00
96b7742611 enhancements to afl-persistent-config and afl-system-config 2022-09-28 21:36:25 +02:00
3c21e9f0d1 another attempt at stand-alone map fix 2022-09-27 15:51:16 +02:00
0f72a7473f Fix docs for fuzz_count in python 2022-09-27 13:45:39 +00:00
1ce0dcac3f fix standalone running with shared libs 2022-09-26 11:55:03 +02:00
77f253c1b9 fix custom mutator build scripts 2022-09-26 03:43:45 +02:00
ed54532f29 make gcc_plugin compilable for gcc 3.6.0 2022-09-23 23:19:10 +02:00
6ed40d5a08 4.04a init 2022-09-20 18:12:37 +02:00
ad4b727476 Merge pull request #1527 from AFLplusplus/dev
push to stable
2022-09-20 17:37:20 +02:00
41fe8b6ab9 update qemuafl 2022-09-20 12:58:20 +02:00
38ab1eda6e 4.03c 2022-09-19 12:15:10 +02:00
6afca4f073 fix help links 2022-09-17 14:05:24 +02:00
9cfe1d1394 afl-cmin -A 2022-09-17 13:44:34 +02:00
badd9694d2 Merge pull request #1525 from AFLplusplus/dev
push to stable
2022-09-17 11:58:41 +02:00
0623a73a5c fix docs 2022-09-17 11:56:39 +02:00
2e8a459d0b Merge pull request #1523 from lszekeres/stable
Fix null pointers.
2022-09-17 11:53:54 +02:00
02db8685f1 Fix null pointers. 2022-09-16 23:04:47 -04:00
2f0cc088b5 Merge pull request #1522 from AFLplusplus/dev
fix unicornafl
2022-09-16 14:42:07 +02:00
05b1e49bc2 fix unicornafl 2022-09-16 12:29:45 +02:00
9d45e8d810 Merge pull request #1521 from AFLplusplus/dev
update unicorn
2022-09-16 11:54:37 +02:00
5435d5c175 update unicorn 2022-09-16 11:54:12 +02:00
869138aa41 Merge pull request #1519 from AFLplusplus/dev
push to stable
2022-09-16 11:51:17 +02:00
5bf8bffd4a changelog 2022-09-16 10:57:54 +02:00
af5e8370af fix LLVMFuzzerRunDriver 2022-09-16 10:57:13 +02:00
9d9d2cada9 Typo 2022-09-16 10:53:53 +02:00
4e73828645 Added unicorn changes to changelog 2022-09-15 18:24:26 +02:00
d610821679 Re-enabled unicorn for aarch64 2022-09-15 18:23:07 +02:00
453d554fb5 Correctly multi-process unicorn builds 2022-09-15 17:33:07 +02:00
9a0cee6ce1 add temporary fix for uc until unicorn publishes a new release 2022-09-15 17:15:15 +02:00
2125950a81 undo tmp changes in unicorn_mode 2022-09-15 15:50:51 +02:00
8e3aee8a1a Fixed unicorn_mode for aarch64, update unicorn 2022-09-15 15:43:00 +02:00
636025df9a forgot correct callback 2022-09-15 10:32:34 +02:00
b7a2c7e698 try LLVMFuzzerRunDriver support 2022-09-15 10:13:46 +02:00
a7877416a8 update changelog 2022-09-15 10:00:05 +02:00
061bd75953 Merge pull request #1518 from nikic/fix-lto
Fix LTO with LLVM 15
2022-09-15 09:58:03 +02:00
b27a4a3689 Fix loading and registeration of LTO pass for new pass manager 2022-09-14 15:54:29 +02:00
a194a82bcd Fixed typo in README.lto.md (#1517)
typo fixed
2022-09-14 15:05:30 +02:00
5452d4652b Fix naming clash between AFL's sancov LTO pass and upstream sancov pass
There was some confusion here due to name reuse. The
initializeModuleSanitizerCoverageLegacyPassPass() function was
actually calling the initialization of the upstream pass (which
no longer supports legacy PM and thus fails to build on LLVM 15).
The intention was to call the LTO initialization here.

Fix this by renaming symbols to avoid collision.
2022-09-14 11:36:05 +02:00
9b6ad933cd Allow building LTO component with LLVM 15 2022-09-14 11:35:55 +02:00
36c46b9579 Fix LLVM 15 build
By removing ModuleSanitizerCoverageLegacyPass, which is completely
unused.

There was some confusing between the initialization function for
the upstream sancov pass and AFLs own implementation.
2022-09-14 10:58:22 +02:00
08f44f4e5d code format 2022-09-10 19:09:32 +02:00
f12ee5c7d2 Merge pull request #1512 from devnexen/libdislocator_attrs
libdislocator apply few attributes for few compiler optimisations.
2022-09-10 18:45:47 +02:00
258f4ee529 libdislocator apply few attributes for few compiler optimisations. 2022-09-10 11:43:19 +01:00
c06c297933 Merge pull request #1511 from tocic/fix/docs_typos
Fix typos in docs
2022-09-10 10:06:20 +02:00
ffad6f3f09 Fix typos in docs 2022-09-10 07:41:19 +03:00
3e30b700dd Dockerfile enhancements 2022-09-09 10:20:30 +02:00
05ac236a6b update changelog 2022-09-07 17:10:03 +02:00
6bb2500707 Merge pull request #1509 from CodeLogicError/stable
analyze_run_target return dataconversion
2022-09-07 17:07:15 +02:00
d06f8b2a93 analyze_run_target return dataconversion
analyze_run_target create u64 data and return u32
2022-09-07 19:59:20 +08:00
0fe39e4768 egrep -> grep -e 2022-09-05 13:57:32 +02:00
0c122aeee6 Merge pull request #1505 from tokatoka/stable
Fix my name in Changelog.md
2022-08-31 10:45:47 +02:00
3a31c5c985 update qemuafl 2022-08-30 16:07:35 +02:00
644b544bc0 fix my name 2022-08-30 13:05:22 +02:00
147654f871 Merge pull request #1504 from AFLplusplus/dev
pcguard off-by-one fix
2022-08-26 23:52:44 +02:00
2775271b17 pcguard off-by-one fix 2022-08-26 18:27:38 +02:00
413e68ab6d Merge pull request #1499 from AFLplusplus/dev
push to stable
2022-08-25 15:56:36 +02:00
eb5a914ef6 fix pizza mode 2022-08-25 15:52:46 +02:00
88ff8aa81e fix gcc_mode cmplog 2022-08-25 08:47:30 +02:00
804e845a94 Merge pull request #1500 from kobrineli/fix-dummy-mapsize
Change map size dummy value.
2022-08-19 13:46:15 +02:00
47d5dbbead Fix. 2022-08-19 14:33:15 +03:00
4ebde72f28 Change map size dummy value. 2022-08-19 14:33:15 +03:00
b4cb3784a5 add malloc check 2022-08-19 13:17:01 +02:00
7b2145b914 shorter calibration 2022-08-19 09:16:17 +02:00
361263b0f2 better no dry run 2022-08-18 08:06:17 +02:00
eeab1afd57 alt no cal 2022-08-17 12:50:15 +02:00
843ef46b21 fix docs 2022-08-16 10:05:52 +02:00
d7abf6936c fix afl-cmin 2022-08-16 09:46:11 +02:00
2462c61df9 fix new map size extraction for afl-gcc 2022-08-15 19:22:46 +02:00
ba14c353c0 get map size from binaries within afl-cmin* 2022-08-15 18:31:45 +02:00
f00d83afbc filter pipe in gcc_mode 2022-08-15 17:38:53 +02:00
4e98071385 better handling of -fsanitize=..,...,.. lists 2022-08-14 14:40:26 +02:00
1a3b463c4c add build report 2022-08-14 13:00:55 +02:00
dae5843b0e Merge pull request #1496 from devnexen/libtokencap_update_hotsummer
libtokencap annotate overriden calls to pyt them together in a special
2022-08-14 12:49:52 +02:00
3200e6515b add AFL_NO_STARTUP_CALIBRATION feature 2022-08-14 12:30:23 +02:00
130b1f7864 libtokencap annotate overriden calls to pyt them together in a special
elf (sub)section and improve their locality.
2022-08-13 07:23:34 +01:00
89d6e306f2 Merge pull request #1494 from WorksButNotTested/armhf
Armhf
2022-08-11 20:19:28 +02:00
2c8228dbe4 Changes to allow cross-compilation of pngtest 2022-08-11 17:55:23 +01:00
b5002d74b4 Fixed warnings about format strings 2022-08-11 17:55:23 +01:00
ddea91de1d Fixed makefile formatting 2022-08-11 17:55:23 +01:00
39dadab065 fix qemu_mode 2022-08-10 09:05:13 +02:00
e377ee3c57 Merge pull request #1491 from WorksButNotTested/unstable
Fix unstable test makefile
2022-08-09 10:51:07 +02:00
38fba71546 add env var 2022-08-09 10:49:05 +02:00
3c811de917 update qemuafl 2022-08-09 10:19:16 +02:00
63b12c5f86 Fix unstable test makefile 2022-08-09 08:25:00 +01:00
79a69b14ef 4.03a 2022-08-08 15:30:48 +02:00
3e2986dd78 Merge pull request #1489 from AFLplusplus/dev
push to stable
2022-08-08 15:27:07 +02:00
1f06b55a8b 4.02c 2022-08-08 15:26:56 +02:00
7b6ee28291 code format 2022-08-06 09:07:49 +02:00
94fe62ad8d Merge pull request #1467 from WorksButNotTested/droid
Android Fixes
2022-08-06 09:02:02 +02:00
608ea5f8ab Add support for Android SHM 2022-08-05 20:57:54 +01:00
00b5d3792d Changes to abstract shared memory 2022-08-05 20:56:14 +01:00
e9cb939956 Fixes to formatting 2022-08-05 20:56:14 +01:00
7b6743f14c Android fixes 2022-08-05 20:56:14 +01:00
4b9c560b07 Merge pull request #1486 from WorksButNotTested/be8
Be8
2022-08-04 21:36:59 +02:00
9d5a2d1b8e Add support for using hook on ARM32 2022-08-04 18:46:29 +01:00
1e524d1f43 Added support for ARM32 inline assembly 2022-08-04 18:46:29 +01:00
7c50ec5d05 Added support for ARM32 persistent mode 2022-08-04 18:46:29 +01:00
7bdb22c70c Added build of FRIDA mode shared library to enable embedding 2022-08-04 18:46:29 +01:00
3562de440e Changes to add option for absolute coverage data 2022-08-04 18:46:29 +01:00
98e8838755 Fix formatting 2022-08-04 18:46:29 +01:00
a2f3c3ee51 Merge pull request #1478 from AFLplusplus/dev
Push to stable
2022-08-03 11:08:10 +02:00
6056d4b140 fix pcguard vector select instrumentation 2022-08-03 10:06:52 +02:00
d745da0c93 Merge pull request #1484 from WorksButNotTested/regs
Regs
2022-07-29 22:50:25 +02:00
4fdd64d6d6 Added framework for logging register contents at the end of each basic block 2022-07-29 19:33:31 +01:00
f2b7104cd6 Fix endianness of coverage data on big endian systems 2022-07-29 17:23:30 +01:00
c6af98bc35 fix 2022-07-25 11:49:49 +02:00
67fabcb0be update compile options 2022-07-25 11:15:14 +02:00
7b7914e1d6 code format 2022-07-25 09:09:29 +02:00
9551be3f8e Merge pull request #1482 from yuawn/fix_usage_message
Fix usage message
2022-07-25 08:47:48 +02:00
f22d28333b code format with clang-format-14 2022-07-24 10:41:50 +00:00
d8d6ea93cf fix sentence & code format 2022-07-24 10:30:21 +00:00
0540d30274 fix message overflow 2022-07-24 10:23:33 +00:00
9657b700b1 Fix some OSX incompatibilities on AARCH64 (#1479)
Co-authored-by: Your Name <you@example.com>
2022-07-21 19:48:21 +02:00
6c26434a63 fix pizza mode 2022-07-21 13:41:43 +02:00
42c677aa7b fix compilation for llvm 10.0 2022-07-19 23:03:20 +02:00
0373628adf fix custom mutator examples 2022-07-19 17:28:57 +02:00
d090232452 remove debug 2022-07-19 17:06:23 +02:00
4d20b2d28b fix 2022-07-19 17:04:53 +02:00
c67f98865e fix 2022-07-19 14:53:43 +02:00
ca4a8c0f92 post_process 0/NULL return support 2022-07-19 12:24:03 +02:00
c57988e672 Merge pull request #1469 from AFLplusplus/dev
push to stable
2022-07-15 10:12:35 +02:00
b847e0f414 clang format 14 2022-07-12 09:04:54 +02:00
338f1ae2f8 fix mawk bug 2022-07-11 21:42:03 +02:00
1f4b45b5bf nit 2022-07-11 12:32:17 +02:00
30736ab7d6 nit 2022-07-11 12:16:33 +02:00
46fed1f43f Merge pull request #1472 from llzmb/docs_quality_assurance_5
Fix formatting, punctuation, and typos of docs
2022-07-11 11:53:03 +02:00
662662c15d Fix formatting, punctuation, and typos 2022-07-11 11:33:51 +02:00
d088c26045 Merge pull request #1470 from WorksButNotTested/frida
Updated FRIDA version
2022-07-08 19:47:53 +02:00
3d2a095f2e Updated FRIDA version 2022-07-08 18:22:05 +01:00
9abae56a37 Merge pull request #1453 from rhtenhove/dev
improve CI and container image build
2022-07-08 18:46:21 +02:00
1f17aa082d Dont codeql submodules 2022-07-08 08:32:17 -04:00
c7c7476453 disable formatter 2022-07-07 17:10:42 +00:00
b883faa942 Merge branch 'dev' of https://github.com/AFLplusplus/AFLplusplus into dev 2022-07-07 17:07:57 +00:00
b1e0d6e640 fix macos ci 2022-07-07 18:39:21 +02:00
ada61204f3 Merge pull request #1468 from waugustus/add-missing-dependencies
add missing dependencies for "make source-only"
2022-07-07 15:17:35 +02:00
72344a2f5f move the apt call 2022-07-07 18:48:02 +08:00
0bb8cc46b4 build nyx in docker 2022-07-07 12:47:12 +02:00
05080f32ee fixes 2022-07-07 11:10:12 +02:00
32c4be4773 add missing dependencies for "make source-only" 2022-07-07 17:01:36 +08:00
1759859ae2 fix double free on exit for -c 0 on src cmplog 2022-07-07 09:03:46 +02:00
e6f27c2645 add missing laf compare split predicates 2022-07-07 00:34:30 +02:00
c90dd00fc9 no longer need this line 2022-07-04 22:38:28 +00:00
0da935183f allow unset env var 2022-07-04 22:36:06 +00:00
4848c8d24c use env as base 2022-07-04 22:30:03 +00:00
250000ee79 simpler format bin selector 2022-07-04 22:27:55 +00:00
fc520a2bde fix 2022-07-04 21:57:42 +02:00
6c9c8fdc65 check code formatting (#5) 2022-07-04 14:32:48 -04:00
24458ae285 nits 2022-07-04 18:13:21 +02:00
36a0ab1193 Merge pull request #1466 from rhtenhove/cpubind
feat: show bound cpu
2022-07-04 10:01:39 +02:00
1334851e7c cmplog support for gcc_plugin by adacore 2022-07-04 09:59:47 +02:00
b077a7963b feat: show bound cpu 2022-06-30 21:11:22 +00:00
3e65e1a029 fix test using test specific build 2022-06-28 15:59:56 +00:00
e21738a248 init new dev release 2022-06-28 14:30:03 +02:00
b3edb657c2 check python too 2022-06-28 01:50:39 +00:00
a1889db9bf simpler jobs 2022-06-27 16:17:02 -04:00
5fa7861149 no need for that line anymore 2022-06-27 15:37:15 +00:00
e969972c97 gcta 2022-06-27 15:35:41 +00:00
80e829f79d revert more and global replace 2022-06-27 15:30:35 +00:00
73db4fe993 use actor 2022-06-27 15:13:16 +00:00
22c3b519fa reverts, fixes and even smaller image (#3) 2022-06-27 11:05:17 -04:00
1dac69b1eb use container; more is built + tested; use make -i (#2) 2022-06-24 09:26:09 -04:00
0da7ddb738 concurrency and caching (#1)
* use concurrency

* run here too

* allow test failure

* only push on push

* fix coresight mode build

* support but disable coresight

* woops

* no unicorn for arm

* update codeql and fix makefile

* forgot those

* disable forward cache

* fix needing buildx

Co-authored-by: Ruben ten Hove <ruben.tenhove@tno.nl>
2022-06-22 06:36:35 -04:00
6e960f78d6 arm needs qemu indeed 2022-06-21 22:01:30 +02:00
3282023047 check for package instead of if in docker 2022-06-21 21:36:02 +02:00
c7db5b67f9 just disable nyx 2022-06-21 21:30:43 +02:00
fc98d53e27 separate platforms 2022-06-21 18:54:54 +02:00
a5822c7c2f various changes 2022-06-21 18:52:43 +02:00
01cb84051a secure apt key; fix multilib 2022-06-21 16:54:47 +02:00
d9c2487c3e reduce layers, size and complexity 2022-06-21 10:30:30 -04:00
171 changed files with 4402 additions and 2088 deletions

View File

@ -19,40 +19,22 @@ import subprocess
import sys import sys
import os import os
import re import re
import shutil
# string_re = re.compile('(\\"(\\\\.|[^"\\\\])*\\")') # future use # string_re = re.compile('(\\"(\\\\.|[^"\\\\])*\\")') # future use
with open(".clang-format") as f: with open(".clang-format") as f:
fmt = f.read() fmt = f.read()
CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN") CURRENT_LLVM = os.getenv('LLVM_VERSION', 14)
if CLANG_FORMAT_BIN is None: CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN", "")
o = 0
try: if shutil.which(CLANG_FORMAT_BIN) is None:
p = subprocess.Popen(["clang-format-11", "--version"], stdout=subprocess.PIPE) CLANG_FORMAT_BIN = f"clang-format-{CURRENT_LLVM}"
o, _ = p.communicate()
o = str(o, "utf-8") if shutil.which(CLANG_FORMAT_BIN) is None:
o = re.sub(r".*ersion ", "", o) print(f"[!] clang-format-{CURRENT_LLVM} is needed. Aborted.")
# o = o[len("clang-format version "):].strip() exit(1)
o = o[: o.find(".")]
o = int(o)
except:
print("clang-format-11 is needed. Aborted.")
exit(1)
# if o < 7:
# if subprocess.call(['which', 'clang-format-7'], stdout=subprocess.PIPE) == 0:
# CLANG_FORMAT_BIN = 'clang-format-7'
# elif subprocess.call(['which', 'clang-format-8'], stdout=subprocess.PIPE) == 0:
# CLANG_FORMAT_BIN = 'clang-format-8'
# elif subprocess.call(['which', 'clang-format-9'], stdout=subprocess.PIPE) == 0:
# CLANG_FORMAT_BIN = 'clang-format-9'
# elif subprocess.call(['which', 'clang-format-11'], stdout=subprocess.PIPE) == 0:
# CLANG_FORMAT_BIN = 'clang-format-11'
# else:
# print ("clang-format 7 or above is needed. Aborted.")
# exit(1)
else:
CLANG_FORMAT_BIN = "clang-format-11"
COLUMN_LIMIT = 80 COLUMN_LIMIT = 80
for line in fmt.split("\n"): for line in fmt.split("\n"):

View File

@ -1,65 +1,75 @@
!/coresight_mode
*.dSYM
*.o
*.pyc
*.so
.sync_tmp
.test .test
.test2 .test2
.sync_tmp .git
*.o .dockerignore
*.so .github
*.pyc CITATION.cff
*.dSYM CONTRIBUTING.md
as Changelog.md
ld Dockerfile
in LICENSE
out TODO.md
core*
afl-analyze afl-analyze
afl-as
afl-clang
afl-clang\+\+
afl-clang-fast
afl-clang-fast\+\+
afl-clang-lto
afl-clang-lto\+\+
afl-fuzz
afl-g\+\+
afl-gcc
afl-gcc-fast
afl-g\+\+-fast
afl-gotcpu
afl-ld
afl-ld-lto
afl-qemu-trace
afl-showmap
afl-tmin
afl-analyze.8 afl-analyze.8
afl-as
afl-as.8 afl-as.8
afl-clang-fast\+\+.8 afl-clang
afl-clang-fast
afl-clang-fast.8 afl-clang-fast.8
afl-clang-fast\+\+
afl-clang-fast\+\+.8
afl-clang-lto
afl-clang-lto.8 afl-clang-lto.8
afl-clang-lto\+\+
afl-clang-lto\+\+.8 afl-clang-lto\+\+.8
afl-clang\+\+
afl-cmin.8 afl-cmin.8
afl-cmin.bash.8 afl-cmin.bash.8
afl-fuzz
afl-fuzz.8 afl-fuzz.8
afl-gcc.8 afl-g\+\+
afl-gcc-fast.8 afl-g\+\+-fast
afl-g\+\+-fast.8 afl-g\+\+-fast.8
afl-gcc
afl-gcc-fast
afl-gcc-fast.8
afl-gcc.8
afl-gotcpu
afl-gotcpu.8 afl-gotcpu.8
afl-ld
afl-ld-lto
afl-plot.8 afl-plot.8
afl-qemu-trace
afl-showmap
afl-showmap.8 afl-showmap.8
afl-system-config.8 afl-system-config.8
afl-tmin
afl-tmin.8 afl-tmin.8
afl-whatsup.8 afl-whatsup.8
as
core*
examples/afl_frida/afl-frida
examples/afl_frida/frida-gum-example.c
examples/afl_frida/frida-gum.h
examples/afl_frida/libtestinstr.so
examples/afl_network_proxy/afl-network-client
examples/afl_network_proxy/afl-network-server
in
ld
out
qemu_mode/libcompcov/compcovtest qemu_mode/libcompcov/compcovtest
qemu_mode/qemu-* qemu_mode/qemu-*
test/unittests/unit_hash
test/unittests/unit_list
test/unittests/unit_maybe_alloc
test/unittests/unit_preallocable
test/unittests/unit_rand
unicorn_mode/samples/*/\.test-* unicorn_mode/samples/*/\.test-*
unicorn_mode/samples/*/output unicorn_mode/samples/*/output
unicorn_mode/unicornafl unicorn_mode/unicornafl
test/unittests/unit_maybe_alloc
test/unittests/unit_preallocable
test/unittests/unit_list
test/unittests/unit_rand
test/unittests/unit_hash
examples/afl_network_proxy/afl-network-server
examples/afl_network_proxy/afl-network-client
examples/afl_frida/afl-frida
examples/afl_frida/libtestinstr.so
examples/afl_frida/frida-gum-example.c
examples/afl_frida/frida-gum.h

View File

@ -1,49 +0,0 @@
name: Publish Docker Images
on:
push:
branches:
- stable
- dev
tags:
- '*'
jobs:
push_to_registry:
name: Push Docker images to Dockerhub
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Dockerhub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Publish dev as dev to docker.io registry
uses: docker/build-push-action@v3
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: aflplusplus/aflplusplus:${{ github.ref_name }}
if: ${{ github.ref_name == 'dev' }}
- name: Publish stable as stable and latest to docker.io registry
uses: docker/build-push-action@v3
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: aflplusplus/aflplusplus:${{ github.ref_name }},aflplusplus/aflplusplus:latest
if: ${{ github.ref_name == 'stable' }}
- name: Publish tagged release to docker.io registry
uses: docker/build-push-action@v3
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: aflplusplus/aflplusplus:${{ github.ref_name }}
if: ${{ github.ref_type == 'tag' }}

View File

@ -2,13 +2,16 @@ name: CI
on: on:
push: push:
branches: [ stable, dev ] branches:
- stable
- dev
pull_request: pull_request:
branches: [ stable, dev ] branches:
- dev # No need for stable-pull-request, as that equals dev-push
jobs: jobs:
linux: linux:
runs-on: '${{ matrix.os }}' runs-on: "${{ matrix.os }}"
strategy: strategy:
matrix: matrix:
os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04] os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04]
@ -16,7 +19,7 @@ jobs:
AFL_SKIP_CPUFREQ: 1 AFL_SKIP_CPUFREQ: 1
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1 AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: debug - name: debug
run: apt-cache search plugin-dev | grep gcc-; echo; apt-cache search clang-format- | grep clang-format- run: apt-cache search plugin-dev | grep gcc-; echo; apt-cache search clang-format- | grep clang-format-
- name: update - name: update
@ -38,9 +41,9 @@ jobs:
AFL_SKIP_CPUFREQ: 1 AFL_SKIP_CPUFREQ: 1
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1 AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: install - name: install
run: brew install make gcc run: brew install make gcc llvm
- name: fix install - name: fix install
run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
- name: build - name: build

33
.github/workflows/code-format.yml vendored Normal file
View File

@ -0,0 +1,33 @@
name: Formatting
on:
push:
branches:
- stable
- dev
pull_request:
branches:
- dev # No need for stable-pull-request, as that equals dev-push
jobs:
code-format-check:
name: Check code format
if: ${{ 'false' == 'true' }} # Disable the job
runs-on: ubuntu-22.04
container: docker.io/aflplusplus/aflplusplus:dev
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Format
run: |
git config --global --add safe.directory /__w/AFLplusplus/AFLplusplus
apt-get update
apt-get install -y clang-format-${LLVM_VERSION}
make code-format
- name: Check if code needed formatting
run: |
git --no-pager -c color.ui=always diff HEAD
if ! git diff HEAD --quiet; then
echo "[!] Please run 'make code-format' and push its changes."
exit 1
fi

View File

@ -2,31 +2,32 @@ name: "CodeQL"
on: on:
push: push:
branches: [ stable, dev ] branches:
- stable
- dev
pull_request: pull_request:
branches: [ stable, dev ] branches:
- dev # No need for stable-pull-request, as that equals dev-push
jobs: jobs:
analyze: analyze:
name: Analyze name: Analyze
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: # We use a previous image as it's expected to have all the dependencies
strategy: image: docker.io/aflplusplus/aflplusplus:dev
fail-fast: false
matrix:
language: [ 'cpp' ]
steps: steps:
- name: Checkout repository - name: Fix for using external repo in container build # https://github.com/actions/checkout/issues/760
uses: actions/checkout@v2 run: git config --global --add safe.directory /__w/AFLplusplus/AFLplusplus
- name: Checkout
- name: Initialize CodeQL uses: actions/checkout@v3
uses: github/codeql-action/init@v1 - name: Initialize CodeQL
with: uses: github/codeql-action/init@v2
languages: ${{ matrix.language }} with:
languages: cpp, python
- name: Autobuild - name: Build AFLplusplus # Rebuild because CodeQL needs to monitor the build process
uses: github/codeql-action/autobuild@v1 env:
CC: gcc # These are symlinked to the version used in the container build
- name: Perform CodeQL Analysis CXX: g++
uses: github/codeql-action/analyze@v1 run: make -i all # Best effort using -i
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

75
.github/workflows/container.yml vendored Normal file
View File

@ -0,0 +1,75 @@
name: Container
on:
push:
branches:
- stable
- dev
tags:
- "*"
pull_request:
branches:
- dev # No need for stable-pull-request, as that equals dev-push
jobs:
build-and-test-amd64:
name: Test amd64 image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build amd64
uses: docker/build-push-action@v3
with:
context: .
tags: aflplusplus:test-amd64
load: true
cache-to: type=gha,mode=max
build-args: |
TEST_BUILD=1
- name: Test amd64
run: >
docker run --rm aflplusplus:test-amd64 bash -c "
apt-get update &&
apt-get install -y libcmocka-dev &&
make -i tests
"
push:
name: Push amd64 and arm64 images
runs-on: ubuntu-latest
needs:
- build-and-test-amd64
if: ${{ github.event_name == 'push' && github.repository == 'AFLplusplus/AFLplusplus' }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
with:
platforms: arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to docker.io
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Set tags to push
id: push-tags
run: |
PUSH_TAGS=docker.io/aflplusplus/aflplusplus:${GITHUB_REF_NAME}
if [ "${GITHUB_REF_NAME}" = "stable" ]; then
PUSH_TAGS=${PUSH_TAGS},docker.io/aflplusplus/aflplusplus:latest
fi
export PUSH_TAGS
echo "::set-output name=PUSH_TAGS::${PUSH_TAGS}"
- name: Push to docker.io registry
uses: docker/build-push-action@v3
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.push-tags.outputs.PUSH_TAGS }}
cache-from: type=gha

View File

@ -2,9 +2,12 @@ name: Rust Custom Mutators
on: on:
push: push:
branches: [ stable, dev ] branches:
- stable
- dev
pull_request: pull_request:
branches: [ stable, dev ] branches:
- dev # No need for stable-pull-request, as that equals dev-push
jobs: jobs:
test: test:
@ -17,7 +20,7 @@ jobs:
matrix: matrix:
os: [ubuntu-22.04, ubuntu-20.04] os: [ubuntu-22.04, ubuntu-20.04]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Install Rust Toolchain - name: Install Rust Toolchain
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
@ -27,4 +30,4 @@ jobs:
- name: Run General Tests - name: Run General Tests
run: cargo test run: cargo test
- name: Run Tests for afl_internals feature flag - name: Run Tests for afl_internals feature flag
run: cd custom_mutator && cargo test --features=afl_internals run: cd custom_mutator && cargo test --features=afl_internals

View File

@ -1,81 +1,95 @@
# #
# This Dockerfile for AFLplusplus uses Ubuntu 22.04 jammy and # This Dockerfile for AFLplusplus uses Ubuntu 22.04 jammy and
# installs LLVM 14 for afl-clang-lto support :-) # installs LLVM 14 for afl-clang-lto support.
#
# GCC 11 is used instead of 12 because genhtml for afl-cov doesn't like it.
# #
FROM ubuntu:22.04 AS aflplusplus FROM ubuntu:22.04 AS aflplusplus
LABEL "maintainer"="afl++ team <afl@aflplus.plus>" LABEL "maintainer"="afl++ team <afl@aflplus.plus>"
LABEL "about"="AFLplusplus docker image" LABEL "about"="AFLplusplus container image"
### Comment out to enable these features
# Only available on specific ARM64 boards
ENV NO_CORESIGHT=1
# Possible but unlikely in a docker container
ENV NO_NYX=1
### Only change these if you know what you are doing:
# LLVM 15 does not look good so we stay at 14 to still have LTO
ENV LLVM_VERSION=14
# GCC 12 is producing compile errors for some targets so we stay at GCC 11
ENV GCC_VERSION=11
### No changes beyond the point unless you know what you are doing :)
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
env NO_ARCH_OPT 1 ENV NO_ARCH_OPT=1
ENV IS_DOCKER=1
RUN apt-get update && \
apt-get -y install --no-install-suggests --no-install-recommends \
automake \
cmake \
meson \
ninja-build \
bison flex \
build-essential \
git \
python3 python3-dev python3-setuptools python-is-python3 \
libtool libtool-bin \
libglib2.0-dev \
wget vim jupp nano bash-completion less \
apt-utils apt-transport-https ca-certificates gnupg dialog \
libpixman-1-dev \
gnuplot-nox \
&& rm -rf /var/lib/apt/lists/*
# TODO: reactivate in timely manner
#RUN echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main" >> /etc/apt/sources.list && \
# wget -qO - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
RUN echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu jammy main" >> /etc/apt/sources.list && \
apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 1E9377A2BA9EF27F
RUN apt-get update && apt-get full-upgrade -y && \ RUN apt-get update && apt-get full-upgrade -y && \
apt-get -y install --no-install-suggests --no-install-recommends \ apt-get install -y --no-install-recommends wget ca-certificates apt-utils && \
gcc-12 g++-12 gcc-12-plugin-dev gdb lcov \ rm -rf /var/lib/apt/lists/*
clang-14 clang-tools-14 libc++1-14 libc++-14-dev \
libc++abi1-14 libc++abi-14-dev libclang1-14 libclang-14-dev \
libclang-common-14-dev libclang-cpp14 libclang-cpp14-dev liblld-14 \
liblld-14-dev liblldb-14 liblldb-14-dev libllvm14 libomp-14-dev \
libomp5-14 lld-14 lldb-14 llvm-14 llvm-14-dev llvm-14-runtime llvm-14-tools
# arm64 doesn't have gcc-multilib, and it's only used for -m32 support on x86 RUN echo "deb [signed-by=/etc/apt/keyrings/llvm-snapshot.gpg.key] http://apt.llvm.org/jammy/ llvm-toolchain-jammy-${LLVM_VERSION} main" > /etc/apt/sources.list.d/llvm.list && \
ARG TARGETPLATFORM wget -qO /etc/apt/keyrings/llvm-snapshot.gpg.key https://apt.llvm.org/llvm-snapshot.gpg.key
RUN [ "$TARGETPLATFORM" = "linux/amd64" ] && \
apt-get -y install --no-install-suggests --no-install-recommends \
gcc-10-multilib gcc-multilib || true
RUN rm -rf /var/lib/apt/lists/* RUN apt-get update && \
apt-get -y install --no-install-recommends \
make cmake automake meson ninja-build bison flex \
git xz-utils bzip2 wget jupp nano bash-completion less vim joe ssh psmisc \
python3 python3-dev python3-setuptools python-is-python3 \
libtool libtool-bin libglib2.0-dev \
apt-transport-https gnupg dialog \
gnuplot-nox libpixman-1-dev \
gcc-${GCC_VERSION} g++-${GCC_VERSION} gcc-${GCC_VERSION}-plugin-dev gdb lcov \
clang-${LLVM_VERSION} clang-tools-${LLVM_VERSION} libc++1-${LLVM_VERSION} \
libc++-${LLVM_VERSION}-dev libc++abi1-${LLVM_VERSION} libc++abi-${LLVM_VERSION}-dev \
libclang1-${LLVM_VERSION} libclang-${LLVM_VERSION}-dev \
libclang-common-${LLVM_VERSION}-dev libclang-cpp${LLVM_VERSION} \
libclang-cpp${LLVM_VERSION}-dev liblld-${LLVM_VERSION} \
liblld-${LLVM_VERSION}-dev liblldb-${LLVM_VERSION} liblldb-${LLVM_VERSION}-dev \
libllvm${LLVM_VERSION} libomp-${LLVM_VERSION}-dev libomp5-${LLVM_VERSION} \
lld-${LLVM_VERSION} lldb-${LLVM_VERSION} llvm-${LLVM_VERSION} \
llvm-${LLVM_VERSION}-dev llvm-${LLVM_VERSION}-runtime llvm-${LLVM_VERSION}-tools \
$([ "$(dpkg --print-architecture)" = "amd64" ] && echo gcc-${GCC_VERSION}-multilib gcc-multilib) \
$([ "$(dpkg --print-architecture)" = "arm64" ] && echo libcapstone-dev) && \
rm -rf /var/lib/apt/lists/*
# gcc-multilib is only used for -m32 support on x86
# libcapstone-dev is used for coresight_mode on arm64
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 0 RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_VERSION} 0 && \
RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 0 update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${GCC_VERSION} 0 && \
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${LLVM_VERSION} 0 && \
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-${LLVM_VERSION} 0
ENV LLVM_CONFIG=llvm-config-14 RUN wget -qO- https://sh.rustup.rs | CARGO_HOME=/etc/cargo sh -s -- -y -q --no-modify-path
ENV PATH=$PATH:/etc/cargo/bin
ENV LLVM_CONFIG=llvm-config-${LLVM_VERSION}
ENV AFL_SKIP_CPUFREQ=1 ENV AFL_SKIP_CPUFREQ=1
ENV AFL_TRY_AFFINITY=1 ENV AFL_TRY_AFFINITY=1
ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
RUN git clone --depth=1 https://github.com/vanhauser-thc/afl-cov /afl-cov RUN git clone --depth=1 https://github.com/vanhauser-thc/afl-cov && \
RUN cd /afl-cov && make install && cd .. (cd afl-cov && make install) && rm -rf afl-cov
COPY . /AFLplusplus
WORKDIR /AFLplusplus WORKDIR /AFLplusplus
COPY . .
RUN export CC=gcc-12 && export CXX=g++-12 && make clean && \ ARG CC=gcc-$GCC_VERSION
make distrib && make install && make clean ARG CXX=g++-$GCC_VERSION
RUN sh -c 'echo set encoding=utf-8 > /root/.vimrc' # Used in CI to prevent a 'make clean' which would remove the binaries to be tested
RUN echo '. /etc/bash_completion' >> ~/.bashrc ARG TEST_BUILD
RUN echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc
RUN echo "export PS1='"'[afl++ \h] \w$(__git_ps1) \$ '"'" >> ~/.bashrc
ENV IS_DOCKER="1"
# Disabled as there are now better alternatives RUN sed -i.bak 's/^ -/ /g' GNUmakefile && \
#COPY --from=aflplusplus/afl-dyninst /usr/local/lib/libdyninstAPI_RT.so /usr/local/lib/libdyninstAPI_RT.so make clean && make distrib && \
#COPY --from=aflplusplus/afl-dyninst /afl-dyninst/libAflDyninst.so /usr/local/lib/libAflDyninst.so ([ "${TEST_BUILD}" ] || (make install && make clean)) && \
mv GNUmakefile.bak GNUmakefile
RUN echo "set encoding=utf-8" > /root/.vimrc && \
echo ". /etc/bash_completion" >> ~/.bashrc && \
echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc && \
echo "export PS1='"'[afl++ \h] \w$(__git_ps1) \$ '"'" >> ~/.bashrc

View File

@ -309,10 +309,21 @@ endif
.PHONY: all .PHONY: all
all: test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_build all_done all: test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_build all_done
-$(MAKE) -C utils/aflpp_driver -$(MAKE) -C utils/aflpp_driver
@echo
@echo
@echo Build Summary:
@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
@test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be build, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
@test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be build, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be build, it is optional, if you want it, please install LLVM 11-14. More information at instrumentation/README.lto.md on how to build it"
ifneq "$(SYS)" "Darwin"
@test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
endif
@echo
.PHONY: llvm .PHONY: llvm
llvm: llvm:
-$(MAKE) -j4 -f GNUmakefile.llvm -$(MAKE) -j$(nproc) -f GNUmakefile.llvm
@test -e afl-cc || { echo "[-] Compiling afl-cc failed. You seem not to have a working compiler." ; exit 1; } @test -e afl-cc || { echo "[-] Compiling afl-cc failed. You seem not to have a working compiler." ; exit 1; }
.PHONY: gcc_plugin .PHONY: gcc_plugin
@ -367,15 +378,18 @@ help:
@echo Known build environment options: @echo Known build environment options:
@echo "==========================================" @echo "=========================================="
@echo STATIC - compile AFL++ static @echo STATIC - compile AFL++ static
@echo ASAN_BUILD - compiles with memory sanitizer for debug purposes @echo ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
@echo UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
@echo DEBUG - no optimization, -ggdb3, all warnings and -Werror @echo DEBUG - no optimization, -ggdb3, all warnings and -Werror
@echo PROFILING - compile afl-fuzz with profiling information @echo PROFILING - compile afl-fuzz with profiling information
@echo INTROSPECTION - compile afl-fuzz with mutation introspection @echo INTROSPECTION - compile afl-fuzz with mutation introspection
@echo NO_PYTHON - disable python support @echo NO_PYTHON - disable python support
@echo NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing @echo NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
@echo NO_NYX - disable building nyx mode dependencies @echo NO_NYX - disable building nyx mode dependencies
@echo "NO_CORESIGHT - disable building coresight (arm64 only)"
@echo NO_UNICORN_ARM64 - disable building unicorn on arm64
@echo AFL_NO_X86 - if compiling on non-intel/amd platforms @echo AFL_NO_X86 - if compiling on non-intel/amd platforms
@echo "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g. Debian)" @echo "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)"
@echo "==========================================" @echo "=========================================="
@echo e.g.: make ASAN_BUILD=1 @echo e.g.: make ASAN_BUILD=1
@ -572,12 +586,13 @@ clean:
-$(MAKE) -f GNUmakefile.gcc_plugin clean -$(MAKE) -f GNUmakefile.gcc_plugin clean
-$(MAKE) -C utils/libdislocator clean -$(MAKE) -C utils/libdislocator clean
-$(MAKE) -C utils/libtokencap clean -$(MAKE) -C utils/libtokencap clean
$(MAKE) -C utils/aflpp_driver clean -$(MAKE) -C utils/aflpp_driver clean
-$(MAKE) -C utils/afl_network_proxy clean -$(MAKE) -C utils/afl_network_proxy clean
-$(MAKE) -C utils/socket_fuzzing clean -$(MAKE) -C utils/socket_fuzzing clean
-$(MAKE) -C utils/argv_fuzzing clean -$(MAKE) -C utils/argv_fuzzing clean
-$(MAKE) -C utils/plot_ui clean -$(MAKE) -C utils/plot_ui clean
-$(MAKE) -C qemu_mode/unsigaction clean -$(MAKE) -C qemu_mode/unsigaction clean
-$(MAKE) -C qemu_mode/fastexit clean
-$(MAKE) -C qemu_mode/libcompcov clean -$(MAKE) -C qemu_mode/libcompcov clean
-$(MAKE) -C qemu_mode/libqasan clean -$(MAKE) -C qemu_mode/libqasan clean
-$(MAKE) -C frida_mode clean -$(MAKE) -C frida_mode clean
@ -610,7 +625,7 @@ endif
.PHONY: distrib .PHONY: distrib
distrib: all distrib: all
-$(MAKE) -j4 -f GNUmakefile.llvm -$(MAKE) -j$(nproc) -f GNUmakefile.llvm
ifneq "$(SYS)" "Darwin" ifneq "$(SYS)" "Darwin"
-$(MAKE) -f GNUmakefile.gcc_plugin -$(MAKE) -f GNUmakefile.gcc_plugin
endif endif
@ -623,15 +638,23 @@ endif
-$(MAKE) -C frida_mode -$(MAKE) -C frida_mode
ifneq "$(SYS)" "Darwin" ifneq "$(SYS)" "Darwin"
ifeq "$(ARCH)" "aarch64" ifeq "$(ARCH)" "aarch64"
ifndef NO_CORESIGHT
-$(MAKE) -C coresight_mode -$(MAKE) -C coresight_mode
endif
endif endif
ifeq "$(SYS)" "Linux" ifeq "$(SYS)" "Linux"
ifndef NO_NYX ifndef NO_NYX
-cd nyx_mode && ./build_nyx_support.sh -cd nyx_mode && ./build_nyx_support.sh
endif endif
endif endif
-cd qemu_mode && sh ./build_qemu_support.sh -cd qemu_mode && sh ./build_qemu_support.sh
ifeq "$(ARCH)" "aarch64"
ifndef NO_UNICORN_ARM64
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh -cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
endif
else
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
endif
endif endif
.PHONY: binary-only .PHONY: binary-only
@ -645,7 +668,9 @@ binary-only: test_shm test_python ready $(PROGS)
-$(MAKE) -C frida_mode -$(MAKE) -C frida_mode
ifneq "$(SYS)" "Darwin" ifneq "$(SYS)" "Darwin"
ifeq "$(ARCH)" "aarch64" ifeq "$(ARCH)" "aarch64"
ifndef NO_CORESIGHT
-$(MAKE) -C coresight_mode -$(MAKE) -C coresight_mode
endif
endif endif
ifeq "$(SYS)" "Linux" ifeq "$(SYS)" "Linux"
ifndef NO_NYX ifndef NO_NYX
@ -653,12 +678,43 @@ ifndef NO_NYX
endif endif
endif endif
-cd qemu_mode && sh ./build_qemu_support.sh -cd qemu_mode && sh ./build_qemu_support.sh
ifeq "$(ARCH)" "aarch64"
ifndef NO_UNICORN_ARM64
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh -cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
endif
else
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
endif
endif endif
@echo
@echo
@echo Build Summary:
@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
ifneq "$(SYS)" "Darwin"
ifeq "$(ARCH)" "aarch64"
ifndef NO_CORESIGHT
@test -e afl-cs-proxy && echo "[+] coresight_mode successfully built" || echo "[-] coresight_mode could not be built, it is optional and experimental, see coresight_mode/README.md for what is needed"
endif
endif
ifeq "$(SYS)" "Linux"
ifndef NO_NYX
@test -e libnyx.so && echo "[+] nyx_mode successfully built" || echo "[-] nyx_mode could not be built, it is optional, see nyx_mode/README.md for what is needed"
endif
endif
@test -e afl-qemu-trace && echo "[+] qemu_mode successfully built" || echo "[-] qemu_mode could not be built, see docs/INSTALL.md for what is needed"
ifeq "$(ARCH)" "aarch64"
ifndef NO_UNICORN_ARM64
@test -e unicorn_mode/unicornafl/build_python/libunicornafl.so && echo "[+] unicorn_mode successfully built" || echo "[-] unicorn_mode could not be built, it is optional, see unicorn_mode/README.md for what is needed"
endif
else
@test -e unicorn_mode/unicornafl/build_python/libunicornafl.so && echo "[+] unicorn_mode successfully built" || echo "[-] unicorn_mode could not be built, it is optional, see unicorn_mode/README.md for what is needed"
endif
endif
@echo
.PHONY: source-only .PHONY: source-only
source-only: all source-only: all
-$(MAKE) -j4 -f GNUmakefile.llvm -$(MAKE) -j$(nproc) -f GNUmakefile.llvm
ifneq "$(SYS)" "Darwin" ifneq "$(SYS)" "Darwin"
-$(MAKE) -f GNUmakefile.gcc_plugin -$(MAKE) -f GNUmakefile.gcc_plugin
endif endif
@ -670,6 +726,22 @@ ifndef NO_NYX
-cd nyx_mode && ./build_nyx_support.sh -cd nyx_mode && ./build_nyx_support.sh
endif endif
endif endif
@echo
@echo
@echo Build Summary:
@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
@test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be build, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
@test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be build, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be build, it is optional, if you want it, please install LLVM 11-14. More information at instrumentation/README.lto.md on how to build it"
ifneq "$(SYS)" "Darwin"
test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
endif
ifeq "$(SYS)" "Linux"
ifndef NO_NYX
@test -e libnyx.so && echo "[+] nyx_mode successfully built" || echo "[-] nyx_mode could not be built, it is optional, see nyx_mode/README.md for what is needed"
endif
endif
@echo
%.8: % %.8: %
@echo .TH $* 8 $(BUILD_DATE) "afl++" > $@ @echo .TH $* 8 $(BUILD_DATE) "afl++" > $@

View File

@ -100,7 +100,9 @@ ifeq "$(SYS)" "SunOS"
endif endif
PROGS = ./afl-gcc-pass.so ./afl-compiler-rt.o ./afl-compiler-rt-32.o ./afl-compiler-rt-64.o PASSES = ./afl-gcc-pass.so ./afl-gcc-cmplog-pass.so ./afl-gcc-cmptrs-pass.so
PROGS = $(PASSES) ./afl-compiler-rt.o ./afl-compiler-rt-32.o ./afl-compiler-rt-64.o
.PHONY: all .PHONY: all
all: test_shm test_deps $(PROGS) test_build all_done all: test_shm test_deps $(PROGS) test_build all_done
@ -141,6 +143,8 @@ afl-common.o: ./src/afl-common.c
@printf "[*] Building 64-bit variant of the runtime (-m64)... " @printf "[*] Building 64-bit variant of the runtime (-m64)... "
@$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi @$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
$(PASSES): instrumentation/afl-gcc-common.h
./afl-gcc-pass.so: instrumentation/afl-gcc-pass.so.cc | test_deps ./afl-gcc-pass.so: instrumentation/afl-gcc-pass.so.cc | test_deps
$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@ $(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
ln -sf afl-cc afl-gcc-fast ln -sf afl-cc afl-gcc-fast
@ -148,6 +152,12 @@ afl-common.o: ./src/afl-common.c
ln -sf afl-cc.8 afl-gcc-fast.8 ln -sf afl-cc.8 afl-gcc-fast.8
ln -sf afl-cc.8 afl-g++-fast.8 ln -sf afl-cc.8 afl-g++-fast.8
./afl-gcc-cmplog-pass.so: instrumentation/afl-gcc-cmplog-pass.so.cc | test_deps
$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
./afl-gcc-cmptrs-pass.so: instrumentation/afl-gcc-cmptrs-pass.so.cc | test_deps
$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
.PHONY: test_build .PHONY: test_build
test_build: $(PROGS) test_build: $(PROGS)
@echo "[*] Testing the CC wrapper and instrumentation output..." @echo "[*] Testing the CC wrapper and instrumentation output..."
@ -190,6 +200,8 @@ install: all
ln -sf afl-c++ $${DESTDIR}$(BIN_PATH)/afl-g++-fast ln -sf afl-c++ $${DESTDIR}$(BIN_PATH)/afl-g++-fast
ln -sf afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH)/afl-gcc-rt.o ln -sf afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH)/afl-gcc-rt.o
install -m 755 ./afl-gcc-pass.so $${DESTDIR}$(HELPER_PATH) install -m 755 ./afl-gcc-pass.so $${DESTDIR}$(HELPER_PATH)
install -m 755 ./afl-gcc-cmplog-pass.so $${DESTDIR}$(HELPER_PATH)
install -m 755 ./afl-gcc-cmptrs-pass.so $${DESTDIR}$(HELPER_PATH)
install -m 644 -T instrumentation/README.gcc_plugin.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md install -m 644 -T instrumentation/README.gcc_plugin.md $${DESTDIR}$(DOC_PATH)/README.gcc_plugin.md
.PHONY: clean .PHONY: clean

View File

@ -45,11 +45,11 @@ endif
LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' | sed 's/svn//' ) LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' | sed 's/svn//' )
LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//' ) LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//' )
LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' ) LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' )
LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^[0-2]\.|^3.[0-7]\.' && echo 1 || echo 0 ) LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[0-2]\.|^3.[0-7]\.' && echo 1 || echo 0 )
LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[5-9]' && echo 1 || echo 0 ) LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[5-9]' && echo 1 || echo 0 )
LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 ) LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[0-9]' && echo 1 || echo 0 )
LLVM_10_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[1-9]|^10\.[1-9]|^10\.0.[1-9]' && echo 1 || echo 0 ) LLVM_10_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[1-9]|^10\.[1-9]|^10\.0.[1-9]' && echo 1 || echo 0 )
LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[1-9]' && echo 1 || echo 0 ) LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[1-9]' && echo 1 || echo 0 )
LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null) LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
LLVM_LIBDIR = $(shell $(LLVM_CONFIG) --libdir 2>/dev/null) LLVM_LIBDIR = $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
LLVM_STDCXX = gnu++11 LLVM_STDCXX = gnu++11
@ -86,12 +86,6 @@ ifeq "$(LLVM_TOO_OLD)" "1"
$(shell sleep 1) $(shell sleep 1)
endif endif
ifeq "$(LLVM_MAJOR)" "15"
$(info [!] llvm_mode detected llvm 15, which is currently broken for LTO plugins.)
LLVM_LTO = 0
LLVM_HAVE_LTO = 0
endif
ifeq "$(LLVM_HAVE_LTO)" "1" ifeq "$(LLVM_HAVE_LTO)" "1"
$(info [+] llvm_mode detected llvm 11+, enabling afl-lto LTO implementation) $(info [+] llvm_mode detected llvm 11+, enabling afl-lto LTO implementation)
LLVM_LTO = 1 LLVM_LTO = 1
@ -99,7 +93,7 @@ ifeq "$(LLVM_HAVE_LTO)" "1"
endif endif
ifeq "$(LLVM_LTO)" "0" ifeq "$(LLVM_LTO)" "0"
$(info [+] llvm_mode detected llvm < 11 or llvm 15, afl-lto LTO will not be build.) $(info [+] llvm_mode detected llvm < 11, afl-lto LTO will not be build.)
endif endif
ifeq "$(LLVM_APPLE_XCODE)" "1" ifeq "$(LLVM_APPLE_XCODE)" "1"
@ -220,6 +214,17 @@ ifeq "$(LLVM_LTO)" "1"
ifeq "$(AFL_REAL_LD)" "" ifeq "$(AFL_REAL_LD)" ""
ifneq "$(shell readlink $(LLVM_BINDIR)/ld.lld 2>&1)" "" ifneq "$(shell readlink $(LLVM_BINDIR)/ld.lld 2>&1)" ""
AFL_REAL_LD = $(LLVM_BINDIR)/ld.lld AFL_REAL_LD = $(LLVM_BINDIR)/ld.lld
else ifneq "$(shell command -v ld.lld 2>/dev/null)" ""
AFL_REAL_LD = $(shell command -v ld.lld)
TMP_LDLDD_VERSION = $(shell $(AFL_REAL_LD) --version | awk '{ print $$2 }')
ifeq "$(LLVMVER)" "$(TMP_LDLDD_VERSION)"
$(warning ld.lld found in a weird location ($(AFL_REAL_LD)), but its the same version as LLVM so we will allow it)
else
$(warning ld.lld found in a weird location ($(AFL_REAL_LD)) and its of a different version than LLMV ($(TMP_LDLDD_VERSION) vs. $(LLVMVER)) - cannot enable LTO mode)
AFL_REAL_LD=
LLVM_LTO = 0
endif
undefine TMP_LDLDD_VERSION
else else
$(warning ld.lld not found, cannot enable LTO mode) $(warning ld.lld not found, cannot enable LTO mode)
LLVM_LTO = 0 LLVM_LTO = 0
@ -235,7 +240,7 @@ AFL_CLANG_FUSELD=
ifeq "$(LLVM_LTO)" "1" ifeq "$(LLVM_LTO)" "1"
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=`command -v ld` -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
AFL_CLANG_FUSELD=1 AFL_CLANG_FUSELD=1
ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=ld.lld --ld-path=$(LLVM_BINDIR)/ld.lld -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" ifeq "$(shell echo 'int main() {return 0; }' | $(CLANG_BIN) -x c - -fuse-ld=ld.lld --ld-path=$(AFL_REAL_LD) -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
AFL_CLANG_LDPATH=1 AFL_CLANG_LDPATH=1
endif endif
else else

View File

@ -2,9 +2,9 @@
<img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/master/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250"> <img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/master/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250">
Release version: [4.01c](https://github.com/AFLplusplus/AFLplusplus/releases) Release version: [4.04c](https://github.com/AFLplusplus/AFLplusplus/releases)
GitHub version: 4.02a GitHub version: 4.04a
Repository: Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)

View File

@ -2,7 +2,6 @@
## Should ## Should
- makefiles should show provide a build summary success/failure
- better documentation for custom mutators - better documentation for custom mutators
- better autodetection of shifting runtime timeout values - better autodetection of shifting runtime timeout values
- Update afl->pending_not_fuzzed for MOpt - Update afl->pending_not_fuzzed for MOpt

View File

@ -105,12 +105,13 @@ function usage() {
"Execution control settings:\n" \ "Execution control settings:\n" \
" -f file - location read by the fuzzed program (stdin)\n" \ " -f file - location read by the fuzzed program (stdin)\n" \
" -m megs - memory limit for child process ("mem_limit" MB)\n" \ " -m megs - memory limit for child process ("mem_limit" MB)\n" \
" -t msec - run time limit for child process (none)\n" \ " -t msec - run time limit for child process (default: none)\n" \
" -O - use binary-only instrumentation (FRIDA mode)\n" \ " -O - use binary-only instrumentation (FRIDA mode)\n" \
" -Q - use binary-only instrumentation (QEMU mode)\n" \ " -Q - use binary-only instrumentation (QEMU mode)\n" \
" -U - use unicorn-based instrumentation (unicorn mode)\n" \ " -U - use unicorn-based instrumentation (unicorn mode)\n" \
"\n" \ "\n" \
"Minimization settings:\n" \ "Minimization settings:\n" \
" -A - allow crashes and timeouts (not recommended)\n" \
" -C - keep crashing inputs, reject everything else\n" \ " -C - keep crashing inputs, reject everything else\n" \
" -e - solve for edge coverage only, ignore hit counts\n" \ " -e - solve for edge coverage only, ignore hit counts\n" \
"\n" \ "\n" \
@ -123,6 +124,7 @@ function usage() {
"AFL_KEEP_TRACES: leave the temporary <out_dir>/.traces directory\n" \ "AFL_KEEP_TRACES: leave the temporary <out_dir>/.traces directory\n" \
"AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL)\n" \ "AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL)\n" \
"AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" \ "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" \
"AFL_CMIN_ALLOW_ANY: write tuples for crashing inputs also\n" \
"AFL_PATH: path for the afl-showmap binary if not found anywhere in PATH\n" \ "AFL_PATH: path for the afl-showmap binary if not found anywhere in PATH\n" \
"AFL_PRINT_FILENAMES: If set, the filename currently processed will be " \ "AFL_PRINT_FILENAMES: If set, the filename currently processed will be " \
"printed to stdout\n" \ "printed to stdout\n" \
@ -146,11 +148,12 @@ BEGIN {
# defaults # defaults
extra_par = "" extra_par = ""
AFL_CMIN_CRASHES_ONLY = "" AFL_CMIN_CRASHES_ONLY = ""
AFL_CMIN_ALLOW_ANY = ""
# process options # process options
Opterr = 1 # default is to diagnose Opterr = 1 # default is to diagnose
Optind = 1 # skip ARGV[0] Optind = 1 # skip ARGV[0]
while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eCOQU?")) != -1) { while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQU?")) != -1) {
if (_go_c == "i") { if (_go_c == "i") {
if (!Optarg) usage() if (!Optarg) usage()
if (in_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} if (in_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
@ -186,6 +189,10 @@ BEGIN {
AFL_CMIN_CRASHES_ONLY = "AFL_CMIN_CRASHES_ONLY=1 " AFL_CMIN_CRASHES_ONLY = "AFL_CMIN_CRASHES_ONLY=1 "
continue continue
} else } else
if (_go_c == "A") {
AFL_CMIN_ALLOW_ANY = "AFL_CMIN_ALLOW_ANY=1 "
continue
} else
if (_go_c == "e") { if (_go_c == "e") {
extra_par = extra_par " -e" extra_par = extra_par " -e"
continue continue
@ -291,6 +298,16 @@ BEGIN {
target_bin = tnew target_bin = tnew
} }
if (0 == system ( "grep -aq AFL_DUMP_MAP_SIZE " target_bin )) {
echo "[!] Trying to obtain the map size of the target ..."
get_map_size = "AFL_DUMP_MAP_SIZE=1 " target_bin
get_map_size | getline mapsize
if (mapsize && mapsize > 65535 && mapsize < 100000000) {
AFL_MAP_SIZE = "AFL_MAP_SIZE="mapsize" "
print "[+] Setting "AFL_MAP_SIZE
}
}
if (!ENVIRON["AFL_SKIP_BIN_CHECK"] && !qemu_mode && !frida_mode && !unicorn_mode) { if (!ENVIRON["AFL_SKIP_BIN_CHECK"] && !qemu_mode && !frida_mode && !unicorn_mode) {
if (0 != system( "grep -q __AFL_SHM_ID "target_bin )) { if (0 != system( "grep -q __AFL_SHM_ID "target_bin )) {
print "[-] Error: binary '"target_bin"' doesn't appear to be instrumented." > "/dev/stderr" print "[-] Error: binary '"target_bin"' doesn't appear to be instrumented." > "/dev/stderr"
@ -399,10 +416,10 @@ BEGIN {
print "[*] Testing the target binary..." print "[*] Testing the target binary..."
if (!stdin_file) { if (!stdin_file) {
system( "AFL_CMIN_ALLOW_ANY=1 "AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"/.run_test\" -Z "extra_par" -- \""target_bin"\" "prog_args_string" <\""in_dir"/"first_file"\"") system(AFL_MAP_SIZE "AFL_CMIN_ALLOW_ANY=1 "AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"/.run_test\" -Z "extra_par" -- \""target_bin"\" "prog_args_string" <\""in_dir"/"first_file"\"")
} else { } else {
system("cp \""in_dir"/"first_file"\" "stdin_file) system("cp \""in_dir"/"first_file"\" "stdin_file)
system( "AFL_CMIN_ALLOW_ANY=1 "AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"/.run_test\" -Z "extra_par" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null") system(AFL_MAP_SIZE "AFL_CMIN_ALLOW_ANY=1 "AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"/.run_test\" -Z "extra_par" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null")
} }
first_count = 0 first_count = 0
@ -435,15 +452,15 @@ BEGIN {
if (!stdin_file) { if (!stdin_file) {
print " Processing "in_count" files (forkserver mode)..." print " Processing "in_count" files (forkserver mode)..."
# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string # print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string
retval = system( AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string) retval = system(AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string)
} else { } else {
print " Processing "in_count" files (forkserver mode)..." print " Processing "in_count" files (forkserver mode)..."
# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null" # print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null"
retval = system( AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null") retval = system(AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null")
} }
if (retval && !AFL_CMIN_CRASHES_ONLY) { if (retval && (!AFL_CMIN_CRASHES_ONLY && !AFL_CMIN_ALLOW_ANY)) {
print "[!] Exit code "retval" != 0 received from afl-showmap, terminating..." print "[!] Exit code "retval" != 0 received from afl-showmap (this means a crashing or timeout input is likely present), terminating..."
if (!ENVIRON["AFL_KEEP_TRACES"]) { if (!ENVIRON["AFL_KEEP_TRACES"]) {
system("rm -rf "trace_dir" 2>/dev/null") system("rm -rf "trace_dir" 2>/dev/null")
@ -534,7 +551,6 @@ BEGIN {
} }
} }
close(sortedKeys) close(sortedKeys)
print ""
print "[+] Found "tuple_count" unique tuples across "in_count" files." print "[+] Found "tuple_count" unique tuples across "in_count" files."
if (out_count == 1) { if (out_count == 1) {

View File

@ -53,7 +53,7 @@ unset IN_DIR OUT_DIR STDIN_FILE EXTRA_PAR MEM_LIMIT_GIVEN \
export AFL_QUIET=1 export AFL_QUIET=1
while getopts "+i:o:f:m:t:eOQUCh" opt; do while getopts "+i:o:f:m:t:eOQUACh" opt; do
case "$opt" in case "$opt" in
@ -80,6 +80,9 @@ while getopts "+i:o:f:m:t:eOQUCh" opt; do
"e") "e")
EXTRA_PAR="$EXTRA_PAR -e" EXTRA_PAR="$EXTRA_PAR -e"
;; ;;
"A")
export AFL_CMIN_ALLOW_ANY=1
;;
"C") "C")
export AFL_CMIN_CRASHES_ONLY=1 export AFL_CMIN_CRASHES_ONLY=1
;; ;;
@ -128,6 +131,7 @@ Execution control settings:
Minimization settings: Minimization settings:
-A - allow crashing and timeout inputs
-C - keep crashing inputs, reject everything else -C - keep crashing inputs, reject everything else
-e - solve for edge coverage only, ignore hit counts -e - solve for edge coverage only, ignore hit counts
@ -215,6 +219,15 @@ if [ ! -f "$TARGET_BIN" -o ! -x "$TARGET_BIN" ]; then
fi fi
grep -aq AFL_DUMP_MAP_SIZE "./$TARGET_BIN" && {
echo "[!] Trying to obtain the map size of the target ..."
MAPSIZE=`AFL_DUMP_MAP_SIZE=1 "./$TARGET_BIN" 2>/dev/null`
test -n "$MAPSIZE" && {
export AFL_MAP_SIZE=$MAPSIZE
echo "[+] Setting AFL_MAP_SIZE=$MAPSIZE"
}
}
if [ "$AFL_SKIP_BIN_CHECK" = "" -a "$QEMU_MODE" = "" -a "$FRIDA_MODE" = "" -a "$UNICORN_MODE" = "" ]; then if [ "$AFL_SKIP_BIN_CHECK" = "" -a "$QEMU_MODE" = "" -a "$FRIDA_MODE" = "" -a "$UNICORN_MODE" = "" ]; then
if ! grep -qF "__AFL_SHM_ID" "$TARGET_BIN"; then if ! grep -qF "__AFL_SHM_ID" "$TARGET_BIN"; then

View File

@ -111,12 +111,12 @@ kernel.sched_latency_ns=250000000
EOF EOF
} }
egrep -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub 2>/dev/null || echo Error: /etc/default/grub with GRUB_CMDLINE_LINUX_DEFAULT is not present, cannot set boot options grep -E -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub 2>/dev/null || echo Error: /etc/default/grub with GRUB_CMDLINE_LINUX_DEFAULT is not present, cannot set boot options
egrep -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub 2>/dev/null && { grep -E -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub 2>/dev/null && {
egrep '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | egrep -q hardened_usercopy=off || { grep -E '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | grep -E -q 'noibrs pcid nopti' || {
echo "Configuring performance boot options" echo "Configuring performance boot options"
LINE=`egrep '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | sed 's/^GRUB_CMDLINE_LINUX_DEFAULT=//' | tr -d '"'` LINE=`grep -E '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | sed 's/^GRUB_CMDLINE_LINUX_DEFAULT=//' | tr -d '"'`
OPTIONS="$LINE ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx=on tsx_async_abort=off mitigations=off audit=0 hardened_usercopy=off ssbd=force-off" OPTIONS="$LINE ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs pcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=on pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx=on tsx_async_abort=off mitigations=off audit=0 hardened_usercopy=off ssbd=force-off"
echo Setting boot options in /etc/default/grub to GRUB_CMDLINE_LINUX_DEFAULT=\"$OPTIONS\" echo Setting boot options in /etc/default/grub to GRUB_CMDLINE_LINUX_DEFAULT=\"$OPTIONS\"
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT=\"$OPTIONS\"|" /etc/default/grub sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT=\"$OPTIONS\"|" /etc/default/grub
} }

View File

@ -47,9 +47,9 @@ if [ "$PLATFORM" = "Linux" ] ; then
} > /dev/null } > /dev/null
echo Settings applied. echo Settings applied.
echo echo
dmesg | egrep -q 'nospectre_v2|spectre_v2=off' || { dmesg | grep -E -q 'noibrs pcid nopti' || {
echo It is recommended to boot the kernel with lots of security off - if you are running a machine that is in a secured network - so set this: echo It is recommended to boot the kernel with lots of security off - if you are running a machine that is in a secured network - so set this:
echo ' /etc/default/grub:GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=0 l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx_async_abort=off arm64.nopauth audit=0 hardened_usercopy=off ssbd=force-off"' echo ' /etc/default/grub:GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=0 l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs pcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=on pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx_async_abort=off arm64.nopauth audit=0 hardened_usercopy=off ssbd=force-off"'
echo echo
} }
echo If you run fuzzing instances in docker, run them with \"--security-opt seccomp=unconfined\" for more speed. echo If you run fuzzing instances in docker, run them with \"--security-opt seccomp=unconfined\" for more speed.

View File

@ -54,7 +54,7 @@ $(GLIBC_LDSO): | $(GLIBC_NAME).tar.xz
$(MAKE) install $(MAKE) install
$(GLIBC_NAME).tar.xz: $(GLIBC_NAME).tar.xz:
wget -O $@ $(GLIBC_URL_BASE)/$@ wget -qO $@ $(GLIBC_URL_BASE)/$@
clean: clean:
$(MAKE) -C $(CS_TRACE) clean $(MAKE) -C $(CS_TRACE) clean

View File

@ -352,7 +352,7 @@ uint8_t afl_custom_queue_get(my_mutator_t *data, const uint8_t *filename) {
* @return if the file contents was modified return 1 (True), 0 (False) * @return if the file contents was modified return 1 (True), 0 (False)
* otherwise * otherwise
*/ */
uint8_t afl_custom_queue_new_entry(my_mutator_t * data, uint8_t afl_custom_queue_new_entry(my_mutator_t *data,
const uint8_t *filename_new_queue, const uint8_t *filename_new_queue,
const uint8_t *filename_orig_queue) { const uint8_t *filename_orig_queue) {

View File

@ -72,6 +72,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "alloc-inl.h"
/* Header that must be present at the beginning of every test case: */ /* Header that must be present at the beginning of every test case: */
@ -127,9 +128,11 @@ size_t afl_custom_post_process(post_state_t *data, unsigned char *in_buf,
} }
/* Allocate memory for new buffer, reusing previous allocation if /* Allocate memory for new buffer, reusing previous allocation if
possible. */ possible. Note we have to use afl-fuzz's own realloc!
Note that you should only do this if you need to grow the buffer,
otherwise work with in_buf, and assign it to *out_buf instead. */
*out_buf = realloc(data->buf, len); *out_buf = afl_realloc(out_buf, len);
/* If we're out of memory, the most graceful thing to do is to return the /* If we're out of memory, the most graceful thing to do is to return the
original buffer and give up on modifying it. Let AFL handle OOM on its original buffer and give up on modifying it. Let AFL handle OOM on its
@ -142,9 +145,9 @@ size_t afl_custom_post_process(post_state_t *data, unsigned char *in_buf,
} }
/* Copy the original data to the new location. */ if (len > strlen(HEADER))
memcpy(*out_buf + strlen(HEADER), in_buf + strlen(HEADER),
memcpy(*out_buf, in_buf, len); len - strlen(HEADER));
/* Insert the new header. */ /* Insert the new header. */

View File

@ -29,8 +29,8 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <zlib.h> #include <zlib.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "alloc-inl.h"
/* A macro to round an integer up to 4 kB. */ /* A macro to round an integer up to 4 kB. */
@ -70,9 +70,6 @@ size_t afl_custom_post_process(post_state_t *data, const unsigned char *in_buf,
unsigned int len, unsigned int len,
const unsigned char **out_buf) { const unsigned char **out_buf) {
unsigned char *new_buf = (unsigned char *)in_buf;
unsigned int pos = 8;
/* Don't do anything if there's not enough room for the PNG header /* Don't do anything if there's not enough room for the PNG header
(8 bytes). */ (8 bytes). */
@ -83,6 +80,22 @@ size_t afl_custom_post_process(post_state_t *data, const unsigned char *in_buf,
} }
/* This is not a good way to do it, if you do not need to grow the buffer
then just work with in_buf instead for speed reasons.
But we want to show how to grow a buffer, so this is how it's done: */
unsigned int pos = 8;
unsigned char *new_buf = afl_realloc(out_buf, UP4K(len));
if (!new_buf) {
*out_buf = in_buf;
return len;
}
memcpy(new_buf, in_buf, len);
/* Minimum size of a zero-length PNG chunk is 12 bytes; if we /* Minimum size of a zero-length PNG chunk is 12 bytes; if we
don't have that, we can bail out. */ don't have that, we can bail out. */
@ -111,33 +124,6 @@ size_t afl_custom_post_process(post_state_t *data, const unsigned char *in_buf,
if (real_cksum != file_cksum) { if (real_cksum != file_cksum) {
/* First modification? Make a copy of the input buffer. Round size
up to 4 kB to minimize the number of reallocs needed. */
if (new_buf == in_buf) {
if (len <= data->size) {
new_buf = data->buf;
} else {
new_buf = realloc(data->buf, UP4K(len));
if (!new_buf) {
*out_buf = in_buf;
return len;
}
data->buf = new_buf;
data->size = UP4K(len);
memcpy(new_buf, in_buf, len);
}
}
*(uint32_t *)(new_buf + pos + 8 + chunk_len) = real_cksum; *(uint32_t *)(new_buf + pos + 8 + chunk_len) = real_cksum;
} }

View File

@ -125,7 +125,7 @@ else
} }
fi fi
test -d json-c/.git || { echo "[-] not checked out, please install git or check your internet connection." ; exit 1 ; } test -e json-c/.git || { echo "[-] not checked out, please install git or check your internet connection." ; exit 1 ; }
echo "[+] Got json-c." echo "[+] Got json-c."
test -e json-c/.libs/libjson-c.a || { test -e json-c/.libs/libjson-c.a || {

View File

@ -119,7 +119,7 @@ else
} }
fi fi
test -f grammar_mutator/.git || { echo "[-] not checked out, please install git or check your internet connection." ; exit 1 ; } test -e grammar_mutator/.git || { echo "[-] not checked out, please install git or check your internet connection." ; exit 1 ; }
echo "[+] Got grammar mutator." echo "[+] Got grammar mutator."
cd "grammar_mutator" || exit 1 cd "grammar_mutator" || exit 1
@ -128,7 +128,7 @@ git pull >/dev/null 2>&1
sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null
git checkout "$GRAMMAR_VERSION" || exit 1 git checkout "$GRAMMAR_VERSION" || exit 1
echo "[*] Downloading antlr..." echo "[*] Downloading antlr..."
wget -c https://www.antlr.org/download/antlr-4.8-complete.jar wget -q https://www.antlr.org/download/antlr-4.8-complete.jar
cd .. cd ..
echo echo

View File

@ -3,10 +3,70 @@
This is the list of all noteworthy changes made in every public This is the list of all noteworthy changes made in every public
release of the tool. See README.md for the general instruction manual. release of the tool. See README.md for the general instruction manual.
## Staying informed
Want to stay in the loop on major new features? Join our mailing list by ### Version ++4.04c (release)
sending a mail to <afl-users+subscribe@googlegroups.com>. - fix gramatron and grammar_mutator build scripts
- enhancements to the afl-persistent-config and afl-system-config
scripts
- afl-fuzz:
- force writing all stats on exit
- afl-cc:
- make gcc_mode (afl-gcc-fast) work with gcc down to version 3.6
- qemu_mode:
- fixed 10x speed degredation in v4.03c, thanks to @ele7enxxh for
reporting!
- added qemu_mode/fastexit helper library
- unicorn_mode:
- Enabled tricore arch (by @jma-qb)
- Updated Capstone version in Rust bindings
- llvm-mode:
- AFL runtime will always pass inputs via shared memory, when possible,
ignoring the command line.
### Version ++4.03c (release)
- Building now gives a build summary what succeeded and what not
- afl-fuzz:
- added AFL_NO_STARTUP_CALIBRATION to start fuzzing at once instead
of calibrating all initial seeds first. Good for large queues
and long execution times, especially in CIs.
- default calibration cycles set to 7 from 8, and only add 5 cycles
to variables queue items instead of 12.
- afl-cc:
- fixed off-by-one bug in our pcguard implemenation, thanks for
@tokatoka for reporting
- fix for llvm 15 and reenabling LTO, thanks to nikic for the PR!
- better handling of -fsanitize=..,...,.. lists
- support added for LLVMFuzzerRunDriver()
- fix gcc_mode cmplog
- obtain the map size of a target with setting AFL_DUMP_MAP_SIZE=1
note that this will exit the target before main()
- qemu_mode:
- added AFL_QEMU_TRACK_UNSTABLE to log the addresses of unstable
edges (together with AFL_DEBUG=1 afl-fuzz). thanks to
worksbutnottested!
- afl-analyze broke at some point, fix by CodeLogicError, thank you!
- afl-cmin/afl-cmin.bash now have an -A option to allow also crashing
and timeout inputs
- unicorn_mode:
- updated upstream unicorn version
- fixed builds for aarch64
- build now uses all available cores
### Version ++4.02c (release)
- afl-cc:
- important fix for the default pcguard mode when LLVM IR vector
selects are produced, thanks to @juppytt for reporting!
- gcc_plugin:
- Adacore submitted CMPLOG support to the gcc_plugin! :-)
- llvm_mode:
- laf cmp splitting fixed for more comparison types
- frida_mode:
- now works on Android!
- afl-fuzz:
- change post_process hook to allow returning NULL and 0 length to
tell afl-fuzz to skip this mutated input
### Version ++4.01c (release) ### Version ++4.01c (release)
- fixed */build_...sh scripts to work outside of git - fixed */build_...sh scripts to work outside of git

View File

@ -255,3 +255,18 @@ If you find an interesting or important question missing, submit it via
Solution: `git pull ; make clean install` of AFL++. Solution: `git pull ; make clean install` of AFL++.
</p></details> </p></details>
<details>
<summary id="afl-map-size-warning">AFL++ map size warning.</summary><p>
When you run a large instrumented program stand-alone or via afl-showmap
you might see a warning like the following:
```
Warning: AFL++ tools might need to set AFL_MAP_SIZE to 223723 to be able to run this instrumented program if this crashes!
```
Depending how the target works it might also crash afterwards.
Solution: just do an `export AFL_MAP_SIZE=(the value in the warning)`.
</p></details>

View File

@ -21,12 +21,12 @@ development state of AFL++.
If you want to build AFL++ yourself, you have many options. The easiest choice If you want to build AFL++ yourself, you have many options. The easiest choice
is to build and install everything: is to build and install everything:
NOTE: depending on your Debian/Ubuntu/Kali/... version replease `-12` with NOTE: depending on your Debian/Ubuntu/Kali/... release, replace `-12` with
whatever llvm version is available! whatever llvm version is available. We recommend llvm 12, 13 or 14.
```shell ```shell
sudo apt-get update sudo apt-get update
sudo apt-get install -y build-essential python3-dev automake cmake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools sudo apt-get install -y build-essential python3-dev automake cmake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools cargo libgtk-3-dev
# try to install llvm 12 and install the distro default if that fails # try to install llvm 12 and install the distro default if that fails
sudo apt-get install -y lld-12 llvm-12 llvm-12-dev clang-12 || sudo apt-get install -y lld llvm llvm-dev clang sudo apt-get install -y lld-12 llvm-12 llvm-12-dev clang-12 || sudo apt-get install -y lld llvm llvm-dev clang
sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-dev sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-dev
@ -79,19 +79,23 @@ make STATIC=1
These build options exist: These build options exist:
* STATIC - compile AFL++ static * STATIC - compile AFL++ static
* ASAN_BUILD - compiles with memory sanitizer for debug purposes * ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for
debug purposes
* DEBUG - no optimization, -ggdb3, all warnings and -Werror * DEBUG - no optimization, -ggdb3, all warnings and -Werror
* PROFILING - compile with profiling information (gprof) * PROFILING - compile afl-fuzz with profiling information
* INTROSPECTION - compile afl-fuzz with mutation introspection * INTROSPECTION - compile afl-fuzz with mutation introspection
* NO_PYTHON - disable python support * NO_PYTHON - disable python support
* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for * NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for
normal fuzzing normal fuzzing
* NO_NYX - disable building nyx mode dependencies * NO_NYX - disable building nyx mode dependencies
* NO_CORESIGHT - disable building coresight (arm64 only)
* NO_UNICORN_ARM64 - disable building unicorn on arm64
* AFL_NO_X86 - if compiling on non-intel/amd platforms * AFL_NO_X86 - if compiling on non-intel/amd platforms
* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config * LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config
(e.g., Debian) (e.g., Debian)
e.g.: `make ASAN_BUILD=1` e.g.: `make LLVM_CONFIG=llvm-config-14`
## MacOS X on x86 and arm64 (M1) ## MacOS X on x86 and arm64 (M1)
@ -148,7 +152,7 @@ and definitely don't look POSIX-compliant. This means two things:
environment before starting afl-fuzz. environment before starting afl-fuzz.
User emulation mode of QEMU does not appear to be supported on MacOS X, so User emulation mode of QEMU does not appear to be supported on MacOS X, so
black-box instrumentation mode (`-Q`) will not work. However, Frida mode (`-O`) black-box instrumentation mode (`-Q`) will not work. However, FRIDA mode (`-O`)
works on both x86 and arm64 MacOS boxes. works on both x86 and arm64 MacOS boxes.
MacOS X supports SYSV shared memory used by AFL's instrumentation, but the MacOS X supports SYSV shared memory used by AFL's instrumentation, but the

View File

@ -38,6 +38,11 @@ performed with the custom mutator.
## 2) APIs ## 2) APIs
**IMPORTANT NOTE**: If you use our C/C++ API and you want to increase the size
of an **out_buf buffer, you have to use `afl_realloc()` for this, so include
`include/alloc-inl.h` - otherwise afl-fuzz will crash when trying to free
your buffers.
C/C++: C/C++:
```c ```c
@ -63,7 +68,7 @@ Python:
def init(seed): def init(seed):
pass pass
def fuzz_count(buf, add_buf, max_size): def fuzz_count(buf):
return cnt return cnt
def fuzz(buf, add_buf, max_size): def fuzz(buf, add_buf, max_size):
@ -159,6 +164,10 @@ def deinit(): # optional for Python
This can return any python object that implements the buffer protocol and This can return any python object that implements the buffer protocol and
supports PyBUF_SIMPLE. These include bytes, bytearray, etc. supports PyBUF_SIMPLE. These include bytes, bytearray, etc.
You can decide in the post_process mutator to not send the mutated data
to the target, e.g. if it is too short, too corrupted, etc. If so,
return a NULL buffer and zero length (or a 0 length string in Python).
- `queue_new_entry` (optional): - `queue_new_entry` (optional):
This methods is called after adding a new test case to the queue. If the This methods is called after adding a new test case to the queue. If the

View File

@ -160,6 +160,8 @@ Available options:
Setting `AFL_LLVM_CMPLOG=1` during compilation will tell afl-clang-fast to Setting `AFL_LLVM_CMPLOG=1` during compilation will tell afl-clang-fast to
produce a CmpLog binary. produce a CmpLog binary.
For afl-gcc-fast, set `AFL_GCC_CMPLOG=1` instead.
For more information, see For more information, see
[instrumentation/README.cmplog.md](../instrumentation/README.cmplog.md). [instrumentation/README.cmplog.md](../instrumentation/README.cmplog.md).
@ -453,14 +455,17 @@ checks or alter some of the more exotic semantics of the tool:
normally done when starting up the forkserver and causes a pretty normally done when starting up the forkserver and causes a pretty
significant performance drop. significant performance drop.
- `AFL_NO_SNAPSHOT` will advice afl-fuzz not to use the snapshot feature if - `AFL_NO_SNAPSHOT` will advise afl-fuzz not to use the snapshot feature if
the snapshot lkm is loaded. the snapshot lkm is loaded.
- Setting `AFL_NO_UI` inhibits the UI altogether and just periodically prints - Setting `AFL_NO_UI` inhibits the UI altogether and just periodically prints
some basic stats. This behavior is also automatically triggered when the some basic stats. This behavior is also automatically triggered when the
output from afl-fuzz is redirected to a file or to a pipe. output from afl-fuzz is redirected to a file or to a pipe.
- In QEMU mode (-Q) and Frida mode (-O), `AFL_PATH` will be searched for - Setting `AFL_NO_STARTUP_CALIBRATION` will skip the initial calibration
of all starting seeds, and start fuzzing at once.
- In QEMU mode (-Q) and FRIDA mode (-O), `AFL_PATH` will be searched for
afl-qemu-trace and afl-frida-trace.so. afl-qemu-trace and afl-frida-trace.so.
- If you are using persistent mode (you should, see - If you are using persistent mode (you should, see
@ -468,7 +473,7 @@ checks or alter some of the more exotic semantics of the tool:
some targets keep inherent state due which a detected crash test case does some targets keep inherent state due which a detected crash test case does
not crash the target again when the test case is given. To be able to still not crash the target again when the test case is given. To be able to still
re-trigger these crashes, you can use the `AFL_PERSISTENT_RECORD` variable re-trigger these crashes, you can use the `AFL_PERSISTENT_RECORD` variable
with a value of how many previous fuzz cases to keep prio a crash. If set to with a value of how many previous fuzz cases to keep prior a crash. If set to
e.g., 10, then the 9 previous inputs are written to out/default/crashes as e.g., 10, then the 9 previous inputs are written to out/default/crashes as
RECORD:000000,cnt:000000 to RECORD:000000,cnt:000008 and RECORD:000000,cnt:000000 to RECORD:000000,cnt:000008 and
RECORD:000000,cnt:000009 being the crash case. NOTE: This option needs to be RECORD:000000,cnt:000009 being the crash case. NOTE: This option needs to be
@ -553,10 +558,10 @@ checks or alter some of the more exotic semantics of the tool:
in the target binary in the target binary
- If you need an early forkserver in your target because of early - If you need an early forkserver in your target because of early
constructors in your target you can set `AFL_EARLY_FORKSERVER`. constructors in your target, you can set `AFL_EARLY_FORKSERVER`.
Note that this is not a compile time option but a runtime option :-) Note that this is not a compile time option but a runtime option :-)
- set `AFL_PIZZA_MODE` to 1 to enable the April 1st stats menu, set to 0 - Set `AFL_PIZZA_MODE` to 1 to enable the April 1st stats menu, set to 0
to disable although it is 1st of April. to disable although it is 1st of April.
## 5) Settings for afl-qemu-trace ## 5) Settings for afl-qemu-trace
@ -689,8 +694,8 @@ support.
* `AFL_FRIDA_STALKER_ADJACENT_BLOCKS` - Configure the number of adjacent blocks * `AFL_FRIDA_STALKER_ADJACENT_BLOCKS` - Configure the number of adjacent blocks
to fetch when generating instrumented code. By fetching blocks in the same to fetch when generating instrumented code. By fetching blocks in the same
order they appear in the original program, rather than the order of execution order they appear in the original program, rather than the order of execution
should help reduce locallity and adjacency. This includes allowing us to should help reduce locality and adjacency. This includes allowing us to
vector between adjancent blocks using a NOP slide rather than an immediate vector between adjacent blocks using a NOP slide rather than an immediate
branch. branch.
* `AFL_FRIDA_STALKER_IC_ENTRIES` - Configure the number of inline cache entries * `AFL_FRIDA_STALKER_IC_ENTRIES` - Configure the number of inline cache entries
stored along-side branch instructions which provide a cache to avoid having to stored along-side branch instructions which provide a cache to avoid having to

View File

@ -12,7 +12,7 @@ QEMU 5.1 with laf-intel and Redqueen, FRIDA mode, unicorn mode, gcc plugin, full
| NeverZero [B] | x86[_64] | x(1) | x | x | x | x | | | | NeverZero [B] | x86[_64] | x(1) | x | x | x | x | | |
| Persistent Mode [C] | | x | x | x86[_64]/arm64 | x86[_64]/arm[64] | x | | | | Persistent Mode [C] | | x | x | x86[_64]/arm64 | x86[_64]/arm[64] | x | | |
| LAF-Intel / CompCov [D] | | x | | | x86[_64]/arm[64] | x86[_64]/arm[64] | x86[_64] | | | LAF-Intel / CompCov [D] | | x | | | x86[_64]/arm[64] | x86[_64]/arm[64] | x86[_64] | |
| CmpLog [E] | | x | | x86[_64]/arm64 | x86[_64]/arm[64] | | | | | CmpLog [E] | | x | x | x86[_64]/arm64 | x86[_64]/arm[64] | | | |
| Selective Instrumentation [F] | | x | x | x | x | | | | | Selective Instrumentation [F] | | x | x | x | x | | | |
| Non-Colliding Coverage [G] | | x(4) | | | (x)(5) | | | | | Non-Colliding Coverage [G] | | x(4) | | | (x)(5) | | | |
| Ngram prev_loc Coverage [H] | | x(6) | | | | | | | | Ngram prev_loc Coverage [H] | | x(6) | | | | | | |

View File

@ -291,7 +291,7 @@ its IPT performance is just 6%!
There are many binary-only fuzzing frameworks. Some are great for CTFs but don't There are many binary-only fuzzing frameworks. Some are great for CTFs but don't
work with large binaries, others are very slow but have good path discovery, work with large binaries, others are very slow but have good path discovery,
some are very hard to set-up... some are very hard to set up...
* Jackalope: * Jackalope:
[https://github.com/googleprojectzero/Jackalope](https://github.com/googleprojectzero/Jackalope) [https://github.com/googleprojectzero/Jackalope](https://github.com/googleprojectzero/Jackalope)

View File

@ -523,7 +523,7 @@ mode!) and switch the input directory with a dash (`-`):
afl-fuzz -i - -o output -- bin/target -someopt @@ afl-fuzz -i - -o output -- bin/target -someopt @@
``` ```
Adding a dictionary is helpful. You have to following options: Adding a dictionary is helpful. You have the following options:
* See the directory * See the directory
[dictionaries/](../dictionaries/), if something is already included for your [dictionaries/](../dictionaries/), if something is already included for your
@ -626,6 +626,9 @@ from other fuzzers in the campaign first.
If you have a large corpus, a corpus from a previous run or are fuzzing in a CI, If you have a large corpus, a corpus from a previous run or are fuzzing in a CI,
then also set `export AFL_CMPLOG_ONLY_NEW=1` and `export AFL_FAST_CAL=1`. then also set `export AFL_CMPLOG_ONLY_NEW=1` and `export AFL_FAST_CAL=1`.
If the queue in the CI is huge and/or the execution time is slow then you can
also add `AFL_NO_STARTUP_CALIBRATION=1` to skip the initial queue calibration
phase and start fuzzing at once.
You can also use different fuzzers. If you are using AFL spinoffs or AFL You can also use different fuzzers. If you are using AFL spinoffs or AFL
conforming fuzzers, then just use the same -o directory and give it a unique conforming fuzzers, then just use the same -o directory and give it a unique
@ -669,7 +672,7 @@ The syncing process itself is very simple. As the `-M main-$HOSTNAME` instance
syncs to all `-S` secondaries as well as to other fuzzers, you have to copy only syncs to all `-S` secondaries as well as to other fuzzers, you have to copy only
this directory to the other machines. this directory to the other machines.
Lets say all servers have the `-o out` directory in /target/foo/out, and you Let's say all servers have the `-o out` directory in /target/foo/out, and you
created a file `servers.txt` which contains the hostnames of all participating created a file `servers.txt` which contains the hostnames of all participating
servers, plus you have an ssh key deployed to all of them, then run: servers, plus you have an ssh key deployed to all of them, then run:
@ -838,9 +841,10 @@ Here are some of the most important caveats for AFL++:
- There is no direct support for fuzzing network services, background daemons, - There is no direct support for fuzzing network services, background daemons,
or interactive apps that require UI interaction to work. You may need to make or interactive apps that require UI interaction to work. You may need to make
simple code changes to make them behave in a more traditional way. Preeny or libdesock may simple code changes to make them behave in a more traditional way. Preeny or
offer a relatively simple option, too - see: libdesock may offer a relatively simple option, too - see:
[https://github.com/zardus/preeny](https://github.com/zardus/preeny) or [https://github.com/fkie-cad/libdesock](https://github.com/fkie-cad/libdesock) [https://github.com/zardus/preeny](https://github.com/zardus/preeny) or
[https://github.com/fkie-cad/libdesock](https://github.com/fkie-cad/libdesock)
Some useful tips for modifying network-based services can be also found at: Some useful tips for modifying network-based services can be also found at:
[https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop](https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop) [https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop](https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop)
@ -901,6 +905,10 @@ complex file formats.
Some notes on continuous integration (CI) fuzzing - this fuzzing is different to Some notes on continuous integration (CI) fuzzing - this fuzzing is different to
normal fuzzing campaigns as these are much shorter runnings. normal fuzzing campaigns as these are much shorter runnings.
If the queue in the CI is huge and/or the execution time is slow then you can
also add `AFL_NO_STARTUP_CALIBRATION=1` to skip the initial queue calibration
phase and start fuzzing at once.
1. Always: 1. Always:
* LTO has a much longer compile time which is diametrical to short fuzzing - * LTO has a much longer compile time which is diametrical to short fuzzing -
hence use afl-clang-fast instead. hence use afl-clang-fast instead.

View File

@ -19,18 +19,18 @@ Mentor: vanhauser-thc
## WASM Instrumentation ## WASM Instrumentation
Currently, AFL++ can be used for source code fuzzing and traditional binaries. Currently, AFL++ can be used for source code fuzzing and traditional binaries.
With the rise of WASM as a compile target, however, a novel way of instrumentation With the rise of WASM as a compile target, however, a novel way of
needs to be implemented for binaries compiled to Webassembly. This can either be instrumentation needs to be implemented for binaries compiled to Webassembly.
done by inserting instrumentation directly into the WASM AST, or by patching This can either be done by inserting instrumentation directly into the WASM AST,
feedback into a WASM VM of choice, similar to the current Unicorn or by patching feedback into a WASM VM of choice, similar to the current Unicorn
instrumentation. instrumentation.
Mentor: any Mentor: any
## Support other programming languages ## Support other programming languages
Other programming languages also use llvm hence they could be (easily?) supported Other programming languages also use llvm hence they could be (easily?)
for fuzzing, e.g., mono, swift, go, kotlin native, fortran, ... supported for fuzzing, e.g., mono, swift, go, kotlin native, fortran, ...
GCC also supports: Objective-C, Fortran, Ada, Go, and D (according to GCC also supports: Objective-C, Fortran, Ada, Go, and D (according to
[Gcc homepage](https://gcc.gnu.org/)) [Gcc homepage](https://gcc.gnu.org/))

View File

@ -1,11 +1,13 @@
# Tools that help fuzzing with AFL++ # Tools that help fuzzing with AFL++
Speeding up fuzzing: ## Speeding up fuzzing
* [libfiowrapper](https://github.com/marekzmyslowski/libfiowrapper) - if the * [libfiowrapper](https://github.com/marekzmyslowski/libfiowrapper) - if the
function you want to fuzz requires loading a file, this allows using the function you want to fuzz requires loading a file, this allows using the
shared memory test case feature :-) - recommended. shared memory test case feature :-) - recommended.
Minimization of test cases: ## Minimization of test cases
* [afl-pytmin](https://github.com/ilsani/afl-pytmin) - a wrapper for afl-tmin * [afl-pytmin](https://github.com/ilsani/afl-pytmin) - a wrapper for afl-tmin
that tries to speed up the process of minimization of a single test case by that tries to speed up the process of minimization of a single test case by
using many CPU cores. using many CPU cores.
@ -14,7 +16,8 @@ Minimization of test cases:
* [halfempty](https://github.com/googleprojectzero/halfempty) - is a fast * [halfempty](https://github.com/googleprojectzero/halfempty) - is a fast
utility for minimizing test cases by Tavis Ormandy based on parallelization. utility for minimizing test cases by Tavis Ormandy based on parallelization.
Distributed execution: ## Distributed execution
* [disfuzz-afl](https://github.com/MartijnB/disfuzz-afl) - distributed fuzzing * [disfuzz-afl](https://github.com/MartijnB/disfuzz-afl) - distributed fuzzing
for AFL. for AFL.
* [AFLDFF](https://github.com/quantumvm/AFLDFF) - AFL distributed fuzzing * [AFLDFF](https://github.com/quantumvm/AFLDFF) - AFL distributed fuzzing
@ -26,7 +29,8 @@ Distributed execution:
* [afl-in-the-cloud](https://github.com/abhisek/afl-in-the-cloud) - another * [afl-in-the-cloud](https://github.com/abhisek/afl-in-the-cloud) - another
script for running AFL in AWS. script for running AFL in AWS.
Deployment, management, monitoring, reporting ## Deployment, management, monitoring, reporting
* [afl-utils](https://gitlab.com/rc0r/afl-utils) - a set of utilities for * [afl-utils](https://gitlab.com/rc0r/afl-utils) - a set of utilities for
automatic processing/analysis of crashes and reducing the number of test automatic processing/analysis of crashes and reducing the number of test
cases. cases.
@ -44,7 +48,8 @@ Deployment, management, monitoring, reporting
* [afl-extras](https://github.com/fekir/afl-extras) - shell scripts to * [afl-extras](https://github.com/fekir/afl-extras) - shell scripts to
parallelize afl-tmin, startup, and data collection. parallelize afl-tmin, startup, and data collection.
Crash processing ## Crash processing
* [AFLTriage](https://github.com/quic/AFLTriage) - * [AFLTriage](https://github.com/quic/AFLTriage) -
triage crashing input files using gdb. triage crashing input files using gdb.
* [afl-crash-analyzer](https://github.com/floyd-fuh/afl-crash-analyzer) - * [afl-crash-analyzer](https://github.com/floyd-fuh/afl-crash-analyzer) -

View File

@ -33,6 +33,7 @@ structure is), these links have you covered (some are outdated though):
[https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator) [https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator)
## Video Tutorials ## Video Tutorials
* [Install AFL++ Ubuntu](https://www.youtube.com/watch?v=5dCvhkbi3RA) * [Install AFL++ Ubuntu](https://www.youtube.com/watch?v=5dCvhkbi3RA)
* [[Fuzzing with AFLplusplus] Installing AFLPlusplus and fuzzing a simple C program](https://www.youtube.com/watch?v=9wRVo0kYSlc) * [[Fuzzing with AFLplusplus] Installing AFLPlusplus and fuzzing a simple C program](https://www.youtube.com/watch?v=9wRVo0kYSlc)
* [[Fuzzing with AFLplusplus] How to fuzz a binary with no source code on Linux in persistent mode](https://www.youtube.com/watch?v=LGPJdEO02p4) * [[Fuzzing with AFLplusplus] How to fuzz a binary with no source code on Linux in persistent mode](https://www.youtube.com/watch?v=LGPJdEO02p4)

View File

@ -13,6 +13,16 @@ JS_SRC:=$(BUILD_DIR)api.c
JS_OBJ:=$(BUILD_DIR)api.o JS_OBJ:=$(BUILD_DIR)api.o
SOURCES:=$(wildcard $(SRC_DIR)**/*.c) $(wildcard $(SRC_DIR)*.c) SOURCES:=$(wildcard $(SRC_DIR)**/*.c) $(wildcard $(SRC_DIR)*.c)
OBJS:=$(foreach src,$(SOURCES),$(OBJ_DIR)$(notdir $(patsubst %.c, %.o, $(src)))) OBJS:=$(foreach src,$(SOURCES),$(OBJ_DIR)$(notdir $(patsubst %.c, %.o, $(src))))
TARGET_CC?=$(CC)
TARGET_CXX?=$(CXX)
HOST_CC?=$(CC)
HOST_CXX?=$(CXX)
IS_ANDROID:=$(findstring android, $(shell $(TARGET_CC) --version 2>/dev/null))
IS_x86:=$(findstring i686, $(shell $(TARGET_CC) --version 2>/dev/null))
IS_x86_64:=$(findstring x86_64, $(shell $(TARGET_CC) --version 2>/dev/null))
IS_ARM:=$(findstring arm, $(shell $(TARGET_CC) --version 2>/dev/null))
IS_ARM64:=$(findstring aarch64, $(shell $(TARGET_CC) --version 2>/dev/null))
CFLAGS+=-fPIC \ CFLAGS+=-fPIC \
-D_GNU_SOURCE \ -D_GNU_SOURCE \
-D_FORTIFY_SOURCE=2 \ -D_FORTIFY_SOURCE=2 \
@ -21,6 +31,10 @@ CFLAGS+=-fPIC \
-funroll-loops \ -funroll-loops \
-ffunction-sections \ -ffunction-sections \
ifdef IS_ANDROID
CFLAGS+=-DANDROID
endif
AFL_CFLAGS:=-Wno-unused-parameter \ AFL_CFLAGS:=-Wno-unused-parameter \
-Wno-sign-compare \ -Wno-sign-compare \
-Wno-unused-function \ -Wno-unused-function \
@ -28,9 +42,16 @@ AFL_CFLAGS:=-Wno-unused-parameter \
-Wno-int-to-pointer-cast \ -Wno-int-to-pointer-cast \
-Wno-pointer-sign -Wno-pointer-sign
ifdef IS_ANDROID
LDFLAGS+= -static-libstdc++ \
-DANDROID \
-llog \
-shared
else
LDFLAGS+=-shared \ LDFLAGS+=-shared \
-lpthread \ -lpthread \
-lresolv -lresolv
endif
ifdef DEBUG ifdef DEBUG
CFLAGS+=-Werror \ CFLAGS+=-Werror \
@ -43,10 +64,12 @@ endif
FRIDA_BUILD_DIR:=$(BUILD_DIR)frida/ FRIDA_BUILD_DIR:=$(BUILD_DIR)frida/
FRIDA_TRACE:=$(BUILD_DIR)afl-frida-trace.so FRIDA_TRACE:=$(BUILD_DIR)afl-frida-trace.so
FRIDA_TRACE_LIB:=$(BUILD_DIR)libafl-frida-trace.a
FRIDA_TRACE_EMBEDDED:=$(BUILD_DIR)afl-frida-trace-embedded FRIDA_TRACE_EMBEDDED:=$(BUILD_DIR)afl-frida-trace-embedded
TARGET_CC?=$(CC) TARGET_CC?=$(CC)
TARGET_CXX?=$(CXX) TARGET_CXX?=$(CXX)
TARGET_AR?=$(AR)
HOST_CC?=$(CC) HOST_CC?=$(CC)
HOST_CXX?=$(CXX) HOST_CXX?=$(CXX)
@ -76,11 +99,11 @@ else
ifdef DEBUG ifdef DEBUG
AFL_CFLAGS:=$(AFL_CFLAGS) -Wno-prio-ctor-dtor AFL_CFLAGS:=$(AFL_CFLAGS) -Wno-prio-ctor-dtor
endif endif
LDFLAGS+= -z noexecstack \ LDFLAGS+= -z noexecstack \
-Wl,--gc-sections \ -Wl,--gc-sections \
-Wl,--exclude-libs,ALL \ -Wl,--exclude-libs,ALL \
-ldl \ -ldl
-lrt
LDSCRIPT:=-Wl,--version-script=$(PWD)frida.map LDSCRIPT:=-Wl,--version-script=$(PWD)frida.map
endif endif
@ -91,32 +114,35 @@ ifeq "$(shell uname)" "Linux"
endif endif
endif endif
ifneq "$(findstring android, $(shell $(CC) --version 2>/dev/null))" ""
ifdef IS_ANDROID
OS:=android OS:=android
ifneq "$(findstring aarch64, $(shell $(CC) --version 2>/dev/null))" "" ifdef IS_x86
ARCH:=arm64 ARCH:=x86
endif endif
ifneq "$(findstring arm, $(shell $(CC) --version 2>/dev/null))" "" ifdef IS_x86
ARCH:=x86_64
endif
ifdef IS_ARM
ARCH:=arm ARCH:=arm
endif endif
ifneq "$(findstring x86_64, $(shell $(CC) --version 2>/dev/null))" "" ifdef IS_ARM64
ARCH:=x86_64 ARCH:=arm64
endif
ifneq "$(findstring i686, $(shell $(CC) --version 2>/dev/null))" ""
ARCH:=x86
endif endif
endif endif
ifeq "$(ARCH)" "armhf" ifeq "$(ARCH)" "armhf"
TARGET_CC:=arm-linux-gnueabihf-gcc TARGET_CC:=arm-linux-gnueabihf-gcc
TARGET_CXX:=arm-linux-gnueabihf-g++ TARGET_CXX:=arm-linux-gnueabihf-g++
TARGET_AR:=arm-linux-gnueabihf-ar
endif endif
ifndef OS ifndef OS
$(error "Operating system unsupported") $(error "Operating system unsupported")
endif endif
GUM_DEVKIT_VERSION=15.1.22 GUM_DEVKIT_VERSION=15.2.1
GUM_DEVKIT_FILENAME=frida-gumjs-devkit-$(GUM_DEVKIT_VERSION)-$(OS)-$(ARCH).tar.xz GUM_DEVKIT_FILENAME=frida-gumjs-devkit-$(GUM_DEVKIT_VERSION)-$(OS)-$(ARCH).tar.xz
GUM_DEVKIT_URL="https://github.com/frida/frida/releases/download/$(GUM_DEVKIT_VERSION)/$(GUM_DEVKIT_FILENAME)" GUM_DEVKIT_URL="https://github.com/frida/frida/releases/download/$(GUM_DEVKIT_VERSION)/$(GUM_DEVKIT_FILENAME)"
@ -157,7 +183,7 @@ BIN2C_SRC:=$(PWD)util/bin2c.c
############################## ALL ############################################# ############################## ALL #############################################
all: $(FRIDA_TRACE) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) $(ADDR_BIN) all: $(FRIDA_TRACE) $(FRIDA_TRACE_LIB) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) $(ADDR_BIN)
32: 32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all
@ -225,6 +251,18 @@ CFLAGS+=-I $(FRIDA_DIR)build/frida_thin-$(OS)-$(ARCH)/include/frida-1.0 \
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/capstone/ \ -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/capstone/ \
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \ -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \
ifeq "$(OS)" "android"
CFLAGS += -static-libstdc++
endif
else
CFLAGS+=-I $(FRIDA_DIR)build/frida_thin-$(OS)-$(ARCH)/include/frida-1.0 \
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/glib-2.0/ \
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/capstone/ \
-I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \
endif
TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \ TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \
@ -242,13 +280,15 @@ TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/liblzma.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/liblzma.a \
$(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libz.a \ $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libz.a \
else
CFLAGS+=-I $(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/include/frida-1.0 \ CFLAGS+=-I $(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/include/frida-1.0 \
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \ -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \ -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/capstone/ \ -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/capstone/ \
-I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \ -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/json-glib-1.0/
ifeq "$(OS)" "android"
CFLAGS += -static-libstdc++
endif
TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \ TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \ $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \
@ -267,15 +307,10 @@ TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/liblzma.a \ $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/liblzma.a \
$(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libz.a \ $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libz.a \
endif
else else
$(GUM_DEVKIT_TARBALL): | $(FRIDA_BUILD_DIR) $(GUM_DEVKIT_TARBALL): | $(FRIDA_BUILD_DIR)
wget -O $@ $(GUM_DEVKIT_URL) || curl -L -o $@ $(GUM_DEVKIT_URL) wget -qO $@ $(GUM_DEVKIT_URL) || curl -L -o $@ $(GUM_DEVKIT_URL)
$(GUM_DEVIT_LIBRARY): $(GUM_DEVKIT_TARBALL) $(GUM_DEVIT_LIBRARY): $(GUM_DEVKIT_TARBALL)
tar Jxvfm $(GUM_DEVKIT_TARBALL) -C $(FRIDA_BUILD_DIR) tar Jxvfm $(GUM_DEVKIT_TARBALL) -C $(FRIDA_BUILD_DIR)
@ -353,6 +388,15 @@ $(FRIDA_TRACE): $(GUM_DEVIT_LIBRARY) $(GUM_DEVIT_HEADER) $(OBJS) $(JS_OBJ) $(AFL
cp -v $(FRIDA_TRACE) $(ROOT) cp -v $(FRIDA_TRACE) $(ROOT)
$(FRIDA_TRACE_LIB): $(GUM_DEVIT_LIBRARY) $(GUM_DEVIT_HEADER) $(OBJS) $(JS_OBJ) $(AFL_COMPILER_RT_OBJ) $(AFL_PERFORMANCE_OBJ) GNUmakefile | $(BUILD_DIR)
$(TARGET_AR) \
-rcs \
$@ \
$(OBJS) \
$(JS_OBJ) \
$(AFL_COMPILER_RT_OBJ) \
$(AFL_PERFORMANCE_OBJ) \
############################# HOOK ############################################# ############################# HOOK #############################################
$(AFLPP_FRIDA_DRIVER_HOOK_OBJ): $(AFLPP_FRIDA_DRIVER_HOOK_SRC) $(GUM_DEVIT_HEADER) | $(BUILD_DIR) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ): $(AFLPP_FRIDA_DRIVER_HOOK_SRC) $(GUM_DEVIT_HEADER) | $(BUILD_DIR)
@ -364,6 +408,7 @@ $(AFLPP_QEMU_DRIVER_HOOK_OBJ): $(AFLPP_QEMU_DRIVER_HOOK_SRC) | $(BUILD_DIR)
hook: $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QEMU_DRIVER_HOOK_OBJ) hook: $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QEMU_DRIVER_HOOK_OBJ)
############################# ADDR ############################################# ############################# ADDR #############################################
ifneq "$(OS)" "android"
$(ADDR_BIN): $(ADDR_SRC) | $(BUILD_DIR) $(ADDR_BIN): $(ADDR_SRC) | $(BUILD_DIR)
-$(TARGET_CC) \ -$(TARGET_CC) \
$(CFLAGS) \ $(CFLAGS) \
@ -377,7 +422,20 @@ $(ADDR_BIN): $(ADDR_SRC) | $(BUILD_DIR)
-ldl \ -ldl \
-lrt \ -lrt \
$< -o $@ $< -o $@
else
$(ADDR_BIN): $(ADDR_SRC) | $(BUILD_DIR)
-$(TARGET_CC) \
$(CFLAGS) \
-Werror \
-Wall \
-Wextra \
-Wpointer-arith \
-z noexecstack \
-Wl,--gc-sections \
-Wl,--exclude-libs,ALL \
-ldl \
$< -o $@
endif
addr: $(ADDR_BIN) addr: $(ADDR_BIN)
############################# CLEAN ############################################ ############################# CLEAN ############################################

View File

@ -86,7 +86,7 @@ To enable the powerful CMPLOG mechanism, set `-c 0` for `afl-fuzz`.
## Scripting ## Scripting
One of the more powerful features of FRIDA mode is it's support for One of the more powerful features of FRIDA mode is its support for
configuration by JavaScript, rather than using environment variables. For configuration by JavaScript, rather than using environment variables. For
details of how this works, see [Scripting.md](Scripting.md). details of how this works, see [Scripting.md](Scripting.md).
@ -146,11 +146,14 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent
QEMU driver to provide a `main` loop for a user provided QEMU driver to provide a `main` loop for a user provided
`LLVMFuzzerTestOneInput`, this option configures the driver to read input from `LLVMFuzzerTestOneInput`, this option configures the driver to read input from
`stdin` rather than using in-memory test cases. `stdin` rather than using in-memory test cases.
* `AFL_FRIDA_INST_COVERAGE_ABSOLUTE` - Generate coverage files using absolute
virtual addresses rather than relative virtual addresses.
* `AFL_FRIDA_INST_COVERAGE_FILE` - File to write DynamoRIO format coverage * `AFL_FRIDA_INST_COVERAGE_FILE` - File to write DynamoRIO format coverage
information (e.g., to be loaded within IDA lighthouse). information (e.g., to be loaded within IDA lighthouse).
* `AFL_FRIDA_INST_DEBUG_FILE` - File to write raw assembly of original blocks * `AFL_FRIDA_INST_DEBUG_FILE` - File to write raw assembly of original blocks
and their instrumented counterparts during block compilation. and their instrumented counterparts during block compilation.
```
Creating block for 0x7ffff7953313: Creating block for 0x7ffff7953313:
0x7ffff7953313 mov qword ptr [rax], 0 0x7ffff7953313 mov qword ptr [rax], 0
0x7ffff795331a add rsp, 8 0x7ffff795331a add rsp, 8
@ -166,7 +169,7 @@ Generated block 0x7ffff75e98e2
*** ***
``` ```
* `AFL_FRIDA_INST_CACHE_SIZE` - Set the size of the instrumentation cache used * `AFL_FRIDA_INST_CACHE_SIZE` - Set the size of the instrumentation cache used
as a look-up table to cache real to instrumented address block translations. as a look-up table to cache real to instrumented address block translations.
Default is 256Mb. Default is 256Mb.
@ -177,6 +180,8 @@ Default is 256Mb.
a file. a file.
* `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage * `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage
instrumentation (the default where available). Required to use instrumentation (the default where available). Required to use
* `AFL_FRIDA_INST_REGS_FILE` - File to write raw register contents at the start
of each block.
`AFL_FRIDA_INST_TRACE`. `AFL_FRIDA_INST_TRACE`.
* `AFL_FRIDA_INST_NO_CACHE` - Don't use a look-up table to cache real to * `AFL_FRIDA_INST_NO_CACHE` - Don't use a look-up table to cache real to
instrumented address block translations. instrumented address block translations.

View File

@ -2,7 +2,7 @@
FRIDA now supports the ability to configure itself using JavaScript. This allows FRIDA now supports the ability to configure itself using JavaScript. This allows
the user to make use of the convenience of FRIDA's scripting engine (along with the user to make use of the convenience of FRIDA's scripting engine (along with
it's support for debug symbols and exports) to configure all of the things which its support for debug symbols and exports) to configure all of the things which
were traditionally configured using environment variables. were traditionally configured using environment variables.
By default, FRIDA mode will look for the file `afl.js` in the current working By default, FRIDA mode will look for the file `afl.js` in the current working
@ -95,7 +95,7 @@ Afl.print("done");
## Stripped binaries ## Stripped binaries
Lastly, if the binary you attempting to fuzz has no symbol information and no Lastly, if the binary you're attempting to fuzz has no symbol information and no
exports, then the following approach can be used. exports, then the following approach can be used.
```js ```js
@ -850,6 +850,14 @@ class Afl {
static setInstrumentNoOptimize() { static setInstrumentNoOptimize() {
Afl.jsApiSetInstrumentNoOptimize(); Afl.jsApiSetInstrumentNoOptimize();
} }
/**
* See `AFL_FRIDA_INST_REGS_FILE`. This function takes a single `string` as
* an argument.
*/
public static setInstrumentRegsFile(file: string): void {
const buf = Memory.allocUtf8String(file);
Afl.jsApiSetInstrumentRegsFile(buf);
}
/* /*
* See `AFL_FRIDA_INST_SEED` * See `AFL_FRIDA_INST_SEED`
*/ */

View File

@ -13,12 +13,14 @@
js_api_set_debug_maps; js_api_set_debug_maps;
js_api_set_entrypoint; js_api_set_entrypoint;
js_api_set_instrument_cache_size; js_api_set_instrument_cache_size;
js_api_set_instrument_coverage_absolute;
js_api_set_instrument_coverage_file; js_api_set_instrument_coverage_file;
js_api_set_instrument_debug_file; js_api_set_instrument_debug_file;
js_api_set_instrument_jit; js_api_set_instrument_jit;
js_api_set_instrument_libraries; js_api_set_instrument_libraries;
js_api_set_instrument_instructions; js_api_set_instrument_instructions;
js_api_set_instrument_no_optimize; js_api_set_instrument_no_optimize;
js_api_set_instrument_regs_file;
js_api_set_instrument_seed; js_api_set_instrument_seed;
js_api_set_instrument_trace; js_api_set_instrument_trace;
js_api_set_instrument_trace_unique; js_api_set_instrument_trace_unique;

View File

@ -31,7 +31,7 @@ __attribute__((visibility("default"))) void afl_persistent_hook(
// do a length check matching the target! // do a length check matching the target!
void **esp = (void **)regs->esp; void **esp = (void **)regs->esp;
void * arg1 = esp[0]; void *arg1 = esp[0];
void **arg2 = &esp[1]; void **arg2 = &esp[1];
memcpy(arg1, input_buf, input_buf_len); memcpy(arg1, input_buf, input_buf_len);
*arg2 = (void *)input_buf_len; *arg2 = (void *)input_buf_len;
@ -50,6 +50,16 @@ __attribute__((visibility("default"))) void afl_persistent_hook(
} }
#elif defined(__arm__)
__attribute__((visibility("default"))) void afl_persistent_hook(
GumCpuContext *regs, uint8_t *input_buf, uint32_t input_buf_len) {
// do a length check matching the target!
memcpy((void *)regs->r[0], input_buf, input_buf_len);
regs->r[1] = input_buf_len;
}
#else #else
#pragma error "Unsupported architecture" #pragma error "Unsupported architecture"
#endif #endif

View File

@ -5,14 +5,16 @@
#include "config.h" #include "config.h"
extern char * instrument_debug_filename; extern char *instrument_debug_filename;
extern char * instrument_coverage_filename; extern char *instrument_coverage_filename;
extern bool instrument_coverage_absolute;
extern gboolean instrument_tracing; extern gboolean instrument_tracing;
extern gboolean instrument_optimize; extern gboolean instrument_optimize;
extern gboolean instrument_unique; extern gboolean instrument_unique;
extern guint64 instrument_hash_zero; extern guint64 instrument_hash_zero;
extern char * instrument_coverage_unstable_filename; extern char *instrument_coverage_unstable_filename;
extern gboolean instrument_coverage_insn; extern gboolean instrument_coverage_insn;
extern char *instrument_regs_filename;
extern gboolean instrument_use_fixed_seed; extern gboolean instrument_use_fixed_seed;
extern guint64 instrument_fixed_seed; extern guint64 instrument_fixed_seed;
@ -35,9 +37,9 @@ GumStalkerTransformer *instrument_get_transformer(void);
gboolean instrument_is_coverage_optimize_supported(void); gboolean instrument_is_coverage_optimize_supported(void);
void instrument_coverage_optimize_init(void); void instrument_coverage_optimize_init(void);
void instrument_coverage_optimize(const cs_insn * instr, void instrument_coverage_optimize(const cs_insn *instr,
GumStalkerOutput *output); GumStalkerOutput *output);
void instrument_coverage_optimize_insn(const cs_insn * instr, void instrument_coverage_optimize_insn(const cs_insn *instr,
GumStalkerOutput *output); GumStalkerOutput *output);
void instrument_debug_config(void); void instrument_debug_config(void);
@ -66,6 +68,8 @@ void instrument_cache_config(void);
void instrument_cache_init(void); void instrument_cache_init(void);
void instrument_cache_insert(gpointer real_address, gpointer code_address); void instrument_cache_insert(gpointer real_address, gpointer code_address);
void instrument_cache(const cs_insn *instr, GumStalkerOutput *output); void instrument_cache(const cs_insn *instr, GumStalkerOutput *output);
void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data);
void instrument_regs_format(int fd, char *format, ...);
#endif #endif

View File

@ -13,7 +13,7 @@ typedef void (*afl_persistent_hook_fn)(api_regs *regs, uint64_t guest_base,
extern int __afl_persistent_loop(unsigned int max_cnt); extern int __afl_persistent_loop(unsigned int max_cnt);
extern unsigned int * __afl_fuzz_len; extern unsigned int *__afl_fuzz_len;
extern unsigned char *__afl_fuzz_ptr; extern unsigned char *__afl_fuzz_ptr;
extern guint64 persistent_start; extern guint64 persistent_start;

View File

@ -1,7 +1,7 @@
#ifndef _SECCOMP_H #ifndef _SECCOMP_H
#define _SECCOMP_H #define _SECCOMP_H
#ifndef __APPLE__ #if !defined(__APPLE__) && !defined(__ANDROID__)
#include <stdint.h> #include <stdint.h>
#include <linux/filter.h> #include <linux/filter.h>
@ -401,9 +401,9 @@ enum {
typedef void (*seccomp_child_func_t)(int event_fd, void *ctx); typedef void (*seccomp_child_func_t)(int event_fd, void *ctx);
typedef void (*seccomp_filter_callback_t)(struct seccomp_notif * req, typedef void (*seccomp_filter_callback_t)(struct seccomp_notif *req,
struct seccomp_notif_resp *resp, struct seccomp_notif_resp *resp,
GumReturnAddressArray * frames); GumReturnAddressArray *frames);
void seccomp_atomic_set(volatile bool *ptr, bool val); void seccomp_atomic_set(volatile bool *ptr, bool val);
bool seccomp_atomic_try_set(volatile bool *ptr, bool val); bool seccomp_atomic_try_set(volatile bool *ptr, bool val);

9
frida_mode/include/shm.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef _SHM_H
#define _SHM_H
#include <stddef.h>
void *shm_create(size_t size);
#endif

View File

@ -43,7 +43,7 @@ typedef struct {
G_DECLARE_FINAL_TYPE(GumAflStalkerStats, gum_afl_stalker_stats, GUM, G_DECLARE_FINAL_TYPE(GumAflStalkerStats, gum_afl_stalker_stats, GUM,
AFL_STALKER_STATS, GObject) AFL_STALKER_STATS, GObject)
extern char * stats_filename; extern char *stats_filename;
extern guint64 stats_interval; extern guint64 stats_interval;
void stats_config(void); void stats_config(void);

View File

@ -30,12 +30,21 @@ void asan_init(void) {
static gboolean asan_exclude_module(const GumModuleDetails *details, static gboolean asan_exclude_module(const GumModuleDetails *details,
gpointer user_data) { gpointer user_data) {
gchar * symbol_name = (gchar *)user_data; gchar *symbol_name = (gchar *)user_data;
GumAddress address; GumAddress address;
address = gum_module_find_export_by_name(details->name, symbol_name); address = gum_module_find_export_by_name(details->name, symbol_name);
if (address == 0) { return TRUE; } if (address == 0) { return TRUE; }
/* If the reported address of the symbol is outside of the range of the module
* then ignore it */
if (address < details->range->base_address) { return TRUE; }
if (address > (details->range->base_address + details->range->size)) {
return TRUE;
}
ranges_add_exclude((GumMemoryRange *)details->range); ranges_add_exclude((GumMemoryRange *)details->range);
return FALSE; return FALSE;

View File

@ -22,8 +22,8 @@ asan_storeN_t asan_storeN = NULL;
static void asan_callout(GumCpuContext *ctx, gpointer user_data) { static void asan_callout(GumCpuContext *ctx, gpointer user_data) {
asan_ctx_t * asan_ctx = (asan_ctx_t *)user_data; asan_ctx_t *asan_ctx = (asan_ctx_t *)user_data;
cs_arm64_op * operand = &asan_ctx->operand; cs_arm64_op *operand = &asan_ctx->operand;
arm64_op_mem *mem = &operand->mem; arm64_op_mem *mem = &operand->mem;
gsize base = 0; gsize base = 0;
gsize index = 0; gsize index = 0;
@ -59,7 +59,7 @@ void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
cs_arm64 arm64 = instr->detail->arm64; cs_arm64 arm64 = instr->detail->arm64;
cs_arm64_op *operand; cs_arm64_op *operand;
asan_ctx_t * ctx; asan_ctx_t *ctx;
if (!asan_initialized) return; if (!asan_initialized) return;

View File

@ -17,7 +17,7 @@ static void asan_callout(GumCpuContext *ctx, gpointer user_data) {
UNUSED_PARAMETER(user_data); UNUSED_PARAMETER(user_data);
cs_x86_op * operand = (cs_x86_op *)user_data; cs_x86_op *operand = (cs_x86_op *)user_data;
x86_op_mem *mem = &operand->mem; x86_op_mem *mem = &operand->mem;
gsize base = 0; gsize base = 0;
gsize index = 0; gsize index = 0;
@ -48,9 +48,9 @@ void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
UNUSED_PARAMETER(iterator); UNUSED_PARAMETER(iterator);
cs_x86 x86 = instr->detail->x86; cs_x86 x86 = instr->detail->x86;
cs_x86_op * operand; cs_x86_op *operand;
x86_op_mem *mem; x86_op_mem *mem;
cs_x86_op * ctx; cs_x86_op *ctx;
if (!asan_initialized) return; if (!asan_initialized) return;

View File

@ -17,7 +17,7 @@ static void asan_callout(GumCpuContext *ctx, gpointer user_data) {
UNUSED_PARAMETER(user_data); UNUSED_PARAMETER(user_data);
cs_x86_op * operand = (cs_x86_op *)user_data; cs_x86_op *operand = (cs_x86_op *)user_data;
x86_op_mem *mem = &operand->mem; x86_op_mem *mem = &operand->mem;
gsize base = 0; gsize base = 0;
gsize index = 0; gsize index = 0;
@ -48,9 +48,9 @@ void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
UNUSED_PARAMETER(iterator); UNUSED_PARAMETER(iterator);
cs_x86 x86 = instr->detail->x86; cs_x86 x86 = instr->detail->x86;
cs_x86_op * operand; cs_x86_op *operand;
x86_op_mem *mem; x86_op_mem *mem;
cs_x86_op * ctx; cs_x86_op *ctx;
if (!asan_initialized) return; if (!asan_initialized) return;

View File

@ -13,9 +13,9 @@
#define MAX_MEMFD_SIZE (64UL << 10) #define MAX_MEMFD_SIZE (64UL << 10)
extern struct cmp_map *__afl_cmp_map; extern struct cmp_map *__afl_cmp_map;
static GArray * cmplog_ranges = NULL; static GArray *cmplog_ranges = NULL;
static GHashTable * hash_yes = NULL; static GHashTable *hash_yes = NULL;
static GHashTable * hash_no = NULL; static GHashTable *hash_no = NULL;
static long page_size = 0; static long page_size = 0;
static long page_offset_mask = 0; static long page_offset_mask = 0;
@ -24,7 +24,7 @@ static long page_mask = 0;
static gboolean cmplog_range(const GumRangeDetails *details, static gboolean cmplog_range(const GumRangeDetails *details,
gpointer user_data) { gpointer user_data) {
GArray * cmplog_ranges = (GArray *)user_data; GArray *cmplog_ranges = (GArray *)user_data;
GumMemoryRange range = *details->range; GumMemoryRange range = *details->range;
g_array_append_val(cmplog_ranges, range); g_array_append_val(cmplog_ranges, range);
return TRUE; return TRUE;
@ -118,7 +118,7 @@ gboolean cmplog_test_addr(guint64 addr, size_t size) {
if (g_hash_table_contains(hash_yes, GSIZE_TO_POINTER(addr))) { return true; } 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; } if (g_hash_table_contains(hash_no, GSIZE_TO_POINTER(addr))) { return false; }
void * page_addr = GSIZE_TO_POINTER(addr & page_mask); void *page_addr = GSIZE_TO_POINTER(addr & page_mask);
size_t page_offset = addr & page_offset_mask; size_t page_offset = addr & page_offset_mask;
/* If it spans a page, then bail */ /* If it spans a page, then bail */

View File

@ -148,7 +148,7 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
} }
static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx, static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx,
cs_arm64_op * operand) { cs_arm64_op *operand) {
ctx->type = operand->type; ctx->type = operand->type;
switch (operand->type) { switch (operand->type) {
@ -169,7 +169,7 @@ static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx,
} }
static void cmplog_instrument_call(const cs_insn * instr, static void cmplog_instrument_call(const cs_insn *instr,
GumStalkerIterator *iterator) { GumStalkerIterator *iterator) {
cs_arm64 arm64 = instr->detail->arm64; cs_arm64 arm64 = instr->detail->arm64;
@ -247,8 +247,8 @@ static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) {
} }
static void cmplog_instrument_cmp_sub_put_callout(GumStalkerIterator *iterator, static void cmplog_instrument_cmp_sub_put_callout(GumStalkerIterator *iterator,
cs_arm64_op * operand1, cs_arm64_op *operand1,
cs_arm64_op * operand2, cs_arm64_op *operand2,
size_t size) { size_t size) {
cmplog_pair_ctx_t *ctx = g_malloc(sizeof(cmplog_pair_ctx_t)); cmplog_pair_ctx_t *ctx = g_malloc(sizeof(cmplog_pair_ctx_t));
@ -263,7 +263,7 @@ static void cmplog_instrument_cmp_sub_put_callout(GumStalkerIterator *iterator,
} }
static void cmplog_instrument_cmp_sub(const cs_insn * instr, static void cmplog_instrument_cmp_sub(const cs_insn *instr,
GumStalkerIterator *iterator) { GumStalkerIterator *iterator) {
cs_arm64 arm64 = instr->detail->arm64; cs_arm64 arm64 = instr->detail->arm64;

View File

@ -141,7 +141,7 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
} }
static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx, static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx,
cs_x86_op * operand) { cs_x86_op *operand) {
ctx->type = operand->type; ctx->type = operand->type;
ctx->size = operand->size; ctx->size = operand->size;
@ -163,7 +163,7 @@ static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx,
} }
static void cmplog_instrument_call(const cs_insn * instr, static void cmplog_instrument_call(const cs_insn *instr,
GumStalkerIterator *iterator) { GumStalkerIterator *iterator) {
cs_x86 x86 = instr->detail->x86; cs_x86 x86 = instr->detail->x86;
@ -230,7 +230,7 @@ static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) {
} }
static void cmplog_instrument_cmp_sub_put_callout(GumStalkerIterator *iterator, static void cmplog_instrument_cmp_sub_put_callout(GumStalkerIterator *iterator,
cs_x86_op * operand1, cs_x86_op *operand1,
cs_x86_op *operand2) { cs_x86_op *operand2) {
cmplog_pair_ctx_t *ctx = g_malloc(sizeof(cmplog_pair_ctx_t)); cmplog_pair_ctx_t *ctx = g_malloc(sizeof(cmplog_pair_ctx_t));
@ -244,7 +244,7 @@ static void cmplog_instrument_cmp_sub_put_callout(GumStalkerIterator *iterator,
} }
static void cmplog_instrument_cmp_sub(const cs_insn * instr, static void cmplog_instrument_cmp_sub(const cs_insn *instr,
GumStalkerIterator *iterator) { GumStalkerIterator *iterator) {
cs_x86 x86 = instr->detail->x86; cs_x86 x86 = instr->detail->x86;

View File

@ -146,7 +146,7 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
} }
static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx, static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx,
cs_x86_op * operand) { cs_x86_op *operand) {
ctx->type = operand->type; ctx->type = operand->type;
ctx->size = operand->size; ctx->size = operand->size;
@ -168,7 +168,7 @@ static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx,
} }
static void cmplog_instrument_call(const cs_insn * instr, static void cmplog_instrument_call(const cs_insn *instr,
GumStalkerIterator *iterator) { GumStalkerIterator *iterator) {
cs_x86 x86 = instr->detail->x86; cs_x86 x86 = instr->detail->x86;
@ -238,7 +238,7 @@ static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) {
} }
static void cmplog_instrument_cmp_sub_put_callout(GumStalkerIterator *iterator, static void cmplog_instrument_cmp_sub_put_callout(GumStalkerIterator *iterator,
cs_x86_op * operand1, cs_x86_op *operand1,
cs_x86_op *operand2) { cs_x86_op *operand2) {
cmplog_pair_ctx_t *ctx = g_malloc(sizeof(cmplog_pair_ctx_t)); cmplog_pair_ctx_t *ctx = g_malloc(sizeof(cmplog_pair_ctx_t));
@ -252,7 +252,7 @@ static void cmplog_instrument_cmp_sub_put_callout(GumStalkerIterator *iterator,
} }
static void cmplog_instrument_cmp_sub(const cs_insn * instr, static void cmplog_instrument_cmp_sub(const cs_insn *instr,
GumStalkerIterator *iterator) { GumStalkerIterator *iterator) {
cs_x86 x86 = instr->detail->x86; cs_x86 x86 = instr->detail->x86;

View File

@ -1,6 +1,5 @@
#include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include "frida-gumjs.h" #include "frida-gumjs.h"
@ -16,10 +15,13 @@
#include "persistent.h" #include "persistent.h"
#include "prefetch.h" #include "prefetch.h"
#include "ranges.h" #include "ranges.h"
#include "shm.h"
#include "stalker.h" #include "stalker.h"
#include "stats.h" #include "stats.h"
#include "util.h" #include "util.h"
#define FRIDA_DEFAULT_MAP_SIZE (64UL << 10)
gboolean instrument_tracing = false; gboolean instrument_tracing = false;
gboolean instrument_optimize = false; gboolean instrument_optimize = false;
gboolean instrument_unique = false; gboolean instrument_unique = false;
@ -28,14 +30,17 @@ guint64 instrument_hash_seed = 0;
gboolean instrument_use_fixed_seed = FALSE; gboolean instrument_use_fixed_seed = FALSE;
guint64 instrument_fixed_seed = 0; guint64 instrument_fixed_seed = 0;
char * instrument_coverage_unstable_filename = NULL; char *instrument_coverage_unstable_filename = NULL;
gboolean instrument_coverage_insn = FALSE; gboolean instrument_coverage_insn = FALSE;
char *instrument_regs_filename = NULL;
static GumStalkerTransformer *transformer = NULL; static GumStalkerTransformer *transformer = NULL;
static GumAddress previous_rip = 0; static GumAddress previous_rip = 0;
static GumAddress previous_end = 0; static GumAddress previous_end = 0;
static u8 * edges_notified = NULL; static u8 *edges_notified = NULL;
static int regs_fd = -1;
__thread guint64 instrument_previous_pc; __thread guint64 instrument_previous_pc;
__thread guint64 *instrument_previous_pc_addr = NULL; __thread guint64 *instrument_previous_pc_addr = NULL;
@ -149,7 +154,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context,
} }
static void instrument_basic_block(GumStalkerIterator *iterator, static void instrument_basic_block(GumStalkerIterator *iterator,
GumStalkerOutput * output, GumStalkerOutput *output,
gpointer user_data) { gpointer user_data) {
UNUSED_PARAMETER(user_data); UNUSED_PARAMETER(user_data);
@ -157,7 +162,7 @@ static void instrument_basic_block(GumStalkerIterator *iterator,
const cs_insn *instr; const cs_insn *instr;
gboolean begin = TRUE; gboolean begin = TRUE;
gboolean excluded; gboolean excluded;
block_ctx_t * ctx = NULL; block_ctx_t *ctx = NULL;
while (gum_stalker_iterator_next(iterator, &instr)) { while (gum_stalker_iterator_next(iterator, &instr)) {
@ -230,6 +235,13 @@ static void instrument_basic_block(GumStalkerIterator *iterator,
} }
if (unlikely(instrument_regs_filename != NULL)) {
gum_stalker_iterator_put_callout(iterator, instrument_write_regs,
(void *)(size_t)regs_fd, NULL);
}
} }
} }
@ -240,8 +252,6 @@ static void instrument_basic_block(GumStalkerIterator *iterator,
} }
instrument_debug_instruction(instr->address, instr->size, output);
if (likely(!excluded)) { if (likely(!excluded)) {
asan_instrument(instr, iterator); asan_instrument(instr, iterator);
@ -279,6 +289,7 @@ void instrument_config(void) {
instrument_coverage_unstable_filename = instrument_coverage_unstable_filename =
(getenv("AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE")); (getenv("AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE"));
instrument_coverage_insn = (getenv("AFL_FRIDA_INST_INSN") != NULL); instrument_coverage_insn = (getenv("AFL_FRIDA_INST_INSN") != NULL);
instrument_regs_filename = getenv("AFL_FRIDA_INST_REGS_FILE");
instrument_debug_config(); instrument_debug_config();
instrument_coverage_config(); instrument_coverage_config();
@ -290,6 +301,8 @@ void instrument_config(void) {
void instrument_init(void) { void instrument_init(void) {
if (__afl_map_size == MAP_SIZE) __afl_map_size = FRIDA_DEFAULT_MAP_SIZE;
if (!instrument_is_coverage_optimize_supported()) instrument_optimize = false; if (!instrument_is_coverage_optimize_supported()) instrument_optimize = false;
FOKF(cBLU "Instrumentation" cRST " - " cGRN "optimize:" cYEL " [%c]", FOKF(cBLU "Instrumentation" cRST " - " cGRN "optimize:" cYEL " [%c]",
@ -334,29 +347,7 @@ void instrument_init(void) {
transformer = gum_stalker_transformer_make_from_callback( transformer = gum_stalker_transformer_make_from_callback(
instrument_basic_block, NULL, NULL); instrument_basic_block, NULL, NULL);
if (instrument_unique) { if (instrument_unique) { edges_notified = shm_create(__afl_map_size); }
int shm_id =
shmget(IPC_PRIVATE, __afl_map_size, IPC_CREAT | IPC_EXCL | 0600);
if (shm_id < 0) { FATAL("shm_id < 0 - errno: %d\n", errno); }
edges_notified = shmat(shm_id, NULL, 0);
g_assert(edges_notified != MAP_FAILED);
/*
* Configure the shared memory region to be removed once the process
* dies.
*/
if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
FATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
}
/* Clear it, not sure it's necessary, just seems like good practice */
memset(edges_notified, '\0', __afl_map_size);
}
if (instrument_use_fixed_seed) { if (instrument_use_fixed_seed) {
@ -390,6 +381,25 @@ void instrument_init(void) {
instrument_hash_seed); instrument_hash_seed);
instrument_hash_zero = instrument_get_offset_hash(0); instrument_hash_zero = instrument_get_offset_hash(0);
FOKF(cBLU "Instrumentation" cRST " - " cGRN "regs:" cYEL " [%s]",
instrument_regs_filename == NULL ? " " : instrument_regs_filename);
if (instrument_regs_filename != NULL) {
char *path =
g_canonicalize_filename(instrument_regs_filename, g_get_current_dir());
FOKF(cBLU "Instrumentation" cRST " - " cGRN "path:" cYEL " [%s]", path);
regs_fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (regs_fd < 0) { FFATAL("Failed to open regs file '%s'", path); }
g_free(path);
}
asan_init(); asan_init();
cmplog_init(); cmplog_init();
instrument_coverage_init(); instrument_coverage_init();
@ -416,3 +426,22 @@ void instrument_on_fork() {
} }
void instrument_regs_format(int fd, char *format, ...) {
va_list ap;
char buffer[4096] = {0};
int ret;
int len;
va_start(ap, format);
ret = vsnprintf(buffer, sizeof(buffer) - 1, format, ap);
va_end(ap);
if (ret < 0) { return; }
len = strnlen(buffer, sizeof(buffer));
IGNORED_RETURN(write(fd, buffer, len));
}

View File

@ -5,36 +5,193 @@
#if defined(__arm__) #if defined(__arm__)
#define PAGE_MASK (~(GUM_ADDRESS(0xfff)))
#define PAGE_ALIGNED(x) ((GUM_ADDRESS(x) & PAGE_MASK) == GUM_ADDRESS(x))
gboolean instrument_cache_enabled = FALSE; gboolean instrument_cache_enabled = FALSE;
gsize instrument_cache_size = 0; gsize instrument_cache_size = 0;
extern __thread guint64 instrument_previous_pc;
__attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[MAP_SIZE];
#pragma pack(push, 1)
typedef struct {
// cur_location = (block_address >> 4) ^ (block_address << 8);
// shared_mem[cur_location ^ prev_location]++;
// prev_location = cur_location >> 1;
/* We can remove this branch when we add support for branch suppression */
uint32_t b_code; /* b imm */
uint8_t *shared_mem;
uint64_t *prev_location;
/* code */
/* save regs */
uint32_t str_r0_sp_rz; /* str r0, [sp - RED_ZONE] */
uint32_t str_r1_sp_rz_4; /* str r1, [sp - (RED_ZONE + 4)] */
/* load prev */
uint32_t ldr_r0_pprev; /* ldr r0, [pc-x] */
uint32_t ldrh_r1_r0; /* ldrh r1, [r0] */
/* load curr */
uint32_t mov_r0_block_id; /* mov r0, #imm16 */
/* calculate new */
uint32_t eor_r0_r0_r1; /* eor r0, r0, r1 */
/* load map */
uint32_t ldr_r1_pmap; /* ldr r1, [pc-x] */
/* calculate offset */
uint32_t add_r1_r1_r0; /* add r1, r1, r0 */
/* Load the value */
uint32_t ldrb_r0_r1; /* ldrb r0, [r1] */
/* Increment the value */
uint32_t add_r0_r0_1; /* add r0, r0, #1 */
uint32_t add_r0_r0_r0_lsr_8; /* add r0, r0, r0, lsr #8 */
/* Save the value */
uint32_t strb_r0_r1; /* strb r0, [r1] */
/* load curr shifted */
uint32_t mov_r0_block_id_shr_1; /* mov r0, #imm16 >> 1*/
/* Update prev */
uint32_t ldr_r1_pprev; /* ldr r1, [pc-x] */
uint32_t strh_r0_r1; /* strh r0, [r1] */
/* restore regs */
uint32_t ldr_r1_sp_rz_4; /* ldr r1, [sp - (RED_ZONE + 4)] */
uint32_t ldr_r0_sp_rz; /* ldr r0, [sp - RED_ZONE] */
} afl_log_code_asm_t;
typedef union {
afl_log_code_asm_t code;
uint8_t bytes[0];
} afl_log_code;
#pragma pack(pop)
static const afl_log_code_asm_t template =
{
.b_code = GUINT32_TO_LE(0xea000001),
.shared_mem = (uint8_t *)GUINT32_TO_LE(0xcefaadde),
.prev_location = (uint64_t *)GUINT32_TO_LE(0xadba0df0),
.str_r0_sp_rz = GUINT32_TO_LE(0xe50d0080),
.str_r1_sp_rz_4 = GUINT32_TO_LE(0xe50d1084),
.ldr_r0_pprev = GUINT32_TO_LE(0xe51f0014),
.ldrh_r1_r0 = GUINT32_TO_LE(0xe1d010b0),
.mov_r0_block_id = GUINT32_TO_LE(0xe3000000),
.eor_r0_r0_r1 = GUINT32_TO_LE(0xe0200001),
.ldr_r1_pmap = GUINT32_TO_LE(0xe51f1028),
.add_r1_r1_r0 = GUINT32_TO_LE(0xe0811000),
.ldrb_r0_r1 = GUINT32_TO_LE(0xe5d10000),
.add_r0_r0_1 = GUINT32_TO_LE(0xe2800001),
.add_r0_r0_r0_lsr_8 = GUINT32_TO_LE(0xe0800420),
.strb_r0_r1 = GUINT32_TO_LE(0xe5c10000),
.mov_r0_block_id_shr_1 = GUINT32_TO_LE(0xe3000000),
.ldr_r1_pprev = GUINT32_TO_LE(0xe51f1040),
.strh_r0_r1 = GUINT32_TO_LE(0xe1c100b0),
.ldr_r1_sp_rz_4 = GUINT32_TO_LE(0xe51d1084),
.ldr_r0_sp_rz = GUINT32_TO_LE(0xe51d0080),
}
;
gboolean instrument_is_coverage_optimize_supported(void) { gboolean instrument_is_coverage_optimize_supported(void) {
return false; return true;
} }
void instrument_coverage_optimize(const cs_insn * instr, static void patch_t3_insn(uint32_t *insn, uint16_t val) {
uint32_t orig = GUINT32_FROM_LE(*insn);
uint32_t imm12 = (val & 0xfff);
uint32_t imm4 = (val >> 12);
orig |= imm12;
orig |= (imm4 << 16);
*insn = GUINT32_TO_LE(orig);
}
void instrument_coverage_optimize(const cs_insn *instr,
GumStalkerOutput *output) { GumStalkerOutput *output) {
UNUSED_PARAMETER(instr); afl_log_code code = {0};
UNUSED_PARAMETER(output); GumArmWriter *cw = output->writer.arm;
FFATAL("Optimized coverage not supported on this architecture"); gpointer block_start;
guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
gsize map_size_pow2;
gsize area_offset_ror;
GumAddress code_addr = 0;
// gum_arm64_writer_put_brk_imm(cw, 0x0);
code_addr = cw->pc;
block_start = GSIZE_TO_POINTER(GUM_ADDRESS(cw->code));
code.code = template;
g_assert(PAGE_ALIGNED(__afl_area_ptr));
map_size_pow2 = util_log2(__afl_map_size);
area_offset_ror = util_rotate(area_offset, 1, map_size_pow2);
code.code.shared_mem = __afl_area_ptr;
code.code.prev_location = instrument_previous_pc_addr;
patch_t3_insn(&code.code.mov_r0_block_id, (uint16_t)area_offset);
patch_t3_insn(&code.code.mov_r0_block_id_shr_1, (uint16_t)area_offset_ror);
// gum_arm_writer_put_breakpoint(cw);
gum_arm_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
} }
void instrument_coverage_optimize_insn(const cs_insn * instr, void instrument_coverage_optimize_insn(const cs_insn *instr,
GumStalkerOutput *output) { GumStalkerOutput *output) {
UNUSED_PARAMETER(instr); UNUSED_PARAMETER(instr);
UNUSED_PARAMETER(output); UNUSED_PARAMETER(output);
FFATAL("Optimized coverage not supported on this architecture");
} }
void instrument_coverage_optimize_init(void) { void instrument_coverage_optimize_init(void) {
FWARNF("Optimized coverage not supported on this architecture"); char *shm_env = getenv(SHM_ENV_VAR);
FVERBOSE("SHM_ENV_VAR: %s", shm_env);
if (shm_env == NULL) {
FWARNF("SHM_ENV_VAR not set, using dummy for debugging purposes");
__afl_area_ptr = area_ptr_dummy;
memset(area_ptr_dummy, '\0', sizeof(area_ptr_dummy));
}
FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr);
if (instrument_previous_pc_addr == NULL) {
instrument_previous_pc_addr = &instrument_previous_pc;
*instrument_previous_pc_addr = instrument_hash_zero;
FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
}
} }
@ -80,5 +237,26 @@ void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) {
} }
void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) {
int fd = (int)user_data;
instrument_regs_format(fd,
"r0 : 0x%08x, r1 : 0x%08x, r2 : 0x%08x, r3 : 0x%08x\n",
cpu_context->r[0], cpu_context->r[2],
cpu_context->r[1], cpu_context->r[3]);
instrument_regs_format(fd,
"r4 : 0x%08x, r5 : 0x%08x, r6 : 0x%08x, r7 : 0x%08x\n",
cpu_context->r[4], cpu_context->r[5],
cpu_context->r[6], cpu_context->r[7]);
instrument_regs_format(
fd, "r8 : 0x%08x, r9 : 0x%08x, r10: 0x%08x, r11: 0x%08x\n",
cpu_context->r8, cpu_context->r9, cpu_context->r10, cpu_context->r11);
instrument_regs_format(
fd, "r12: 0x%08x, sp : 0x%08x, lr : 0x%08x, pc : 0x%08x\n",
cpu_context->r12, cpu_context->sp, cpu_context->lr, cpu_context->pc);
instrument_regs_format(fd, "cpsr: 0x%08x\n\n", cpu_context->cpsr);
}
#endif #endif

View File

@ -159,8 +159,8 @@ static gboolean instrument_is_deterministic(const cs_insn *from_insn) {
static void instrument_coverage_switch(GumStalkerObserver *self, static void instrument_coverage_switch(GumStalkerObserver *self,
gpointer from_address, gpointer from_address,
gpointer start_address, gpointer start_address,
const cs_insn * from_insn, const cs_insn *from_insn,
gpointer * target) { gpointer *target) {
UNUSED_PARAMETER(self); UNUSED_PARAMETER(self);
UNUSED_PARAMETER(from_address); UNUSED_PARAMETER(from_address);
@ -218,7 +218,7 @@ static void instrument_coverage_suppress_init(void) {
if (initialized) { return; } if (initialized) { return; }
initialized = true; initialized = true;
GumStalkerObserver * observer = stalker_get_observer(); GumStalkerObserver *observer = stalker_get_observer();
GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer); GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer);
iface->switch_callback = instrument_coverage_switch; iface->switch_callback = instrument_coverage_switch;
@ -257,7 +257,7 @@ static void instrument_patch_ardp(guint32 *patch, GumAddress insn,
} }
void instrument_coverage_optimize(const cs_insn * instr, void instrument_coverage_optimize(const cs_insn *instr,
GumStalkerOutput *output) { GumStalkerOutput *output) {
afl_log_code code = {0}; afl_log_code code = {0};
@ -272,9 +272,10 @@ void instrument_coverage_optimize(const cs_insn * instr,
GumAddressSpec spec = {.near_address = cw->code, GumAddressSpec spec = {.near_address = cw->code,
.max_distance = 1ULL << 30}; .max_distance = 1ULL << 30};
guint page_size = gum_query_page_size();
instrument_previous_pc_addr = gum_memory_allocate_near( instrument_previous_pc_addr = gum_memory_allocate_near(
&spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE); &spec, sizeof(guint64), page_size, GUM_PAGE_READ | GUM_PAGE_WRITE);
*instrument_previous_pc_addr = instrument_hash_zero; *instrument_previous_pc_addr = instrument_hash_zero;
FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr); FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
FVERBOSE("code_addr: %p", cw->code); FVERBOSE("code_addr: %p", cw->code);
@ -345,7 +346,7 @@ void instrument_coverage_optimize(const cs_insn * instr,
} }
void instrument_coverage_optimize_insn(const cs_insn * instr, void instrument_coverage_optimize_insn(const cs_insn *instr,
GumStalkerOutput *output) { GumStalkerOutput *output) {
UNUSED_PARAMETER(instr); UNUSED_PARAMETER(instr);
@ -405,5 +406,43 @@ void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) {
} }
void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) {
int fd = (int)(size_t)user_data;
instrument_regs_format(
fd, "x0 : 0x%016x, x1 : 0x%016x, x2 : 0x%016x, x3 : 0x%016x\n",
cpu_context->x[0], cpu_context->x[1], cpu_context->x[2],
cpu_context->x[3]);
instrument_regs_format(
fd, "x4 : 0x%016x, x5 : 0x%016x, x6 : 0x%016x, x7 : 0x%016x\n",
cpu_context->x[4], cpu_context->x[5], cpu_context->x[6],
cpu_context->x[7]);
instrument_regs_format(
fd, "x8 : 0x%016x, x9 : 0x%016x, x10: 0x%016x, x11: 0x%016x\n",
cpu_context->x[8], cpu_context->x[9], cpu_context->x[10],
cpu_context->x[11]);
instrument_regs_format(
fd, "x12: 0x%016x, x13: 0x%016x, x14: 0x%016x, x15: 0x%016x\n",
cpu_context->x[12], cpu_context->x[13], cpu_context->x[14],
cpu_context->x[15]);
instrument_regs_format(
fd, "x16: 0x%016x, x17: 0x%016x, x18: 0x%016x, x19: 0x%016x\n",
cpu_context->x[16], cpu_context->x[17], cpu_context->x[18],
cpu_context->x[19]);
instrument_regs_format(
fd, "x20: 0x%016x, x21: 0x%016x, x22: 0x%016x, x23: 0x%016x\n",
cpu_context->x[20], cpu_context->x[21], cpu_context->x[22],
cpu_context->x[23]);
instrument_regs_format(
fd, "x24: 0x%016x, x25: 0x%016x, x26: 0x%016x, x27: 0x%016x\n",
cpu_context->x[24], cpu_context->x[25], cpu_context->x[26],
cpu_context->x[27]);
instrument_regs_format(
fd, "x28: 0x%016x, fp : 0x%016x, lr : 0x%016x, sp : 0x%016x\n",
cpu_context->x[28], cpu_context->fp, cpu_context->lr, cpu_context->sp);
instrument_regs_format(fd, "pc : 0x%016x\n\n", cpu_context->pc);
}
#endif #endif

View File

@ -9,6 +9,7 @@
#include "util.h" #include "util.h"
char *instrument_coverage_filename = NULL; char *instrument_coverage_filename = NULL;
bool instrument_coverage_absolute = false;
static int normal_coverage_fd = -1; static int normal_coverage_fd = -1;
static int normal_coverage_pipes[2] = {-1, -1}; static int normal_coverage_pipes[2] = {-1, -1};
@ -17,7 +18,7 @@ static int unstable_coverage_fd = -1;
static int unstable_coverage_pipes[2] = {-1, -1}; static int unstable_coverage_pipes[2] = {-1, -1};
static uint64_t normal_coverage_last_start = 0; static uint64_t normal_coverage_last_start = 0;
static gchar * unstable_coverage_fuzzer_stats = NULL; static gchar *unstable_coverage_fuzzer_stats = NULL;
typedef struct { typedef struct {
@ -68,7 +69,7 @@ typedef struct {
static gboolean coverage_range(const GumRangeDetails *details, static gboolean coverage_range(const GumRangeDetails *details,
gpointer user_data) { gpointer user_data) {
GArray * coverage_ranges = (GArray *)user_data; GArray *coverage_ranges = (GArray *)user_data;
coverage_range_t coverage = {0}; coverage_range_t coverage = {0};
if (details->file == NULL) { return TRUE; } if (details->file == NULL) { return TRUE; }
@ -210,8 +211,8 @@ static GArray *coverage_get_modules(void) {
static void instrument_coverage_mark(void *key, void *value, void *user_data) { static void instrument_coverage_mark(void *key, void *value, void *user_data) {
UNUSED_PARAMETER(key); UNUSED_PARAMETER(key);
coverage_mark_ctx_t * ctx = (coverage_mark_ctx_t *)user_data; coverage_mark_ctx_t *ctx = (coverage_mark_ctx_t *)user_data;
GArray * coverage_modules = ctx->modules; GArray *coverage_modules = ctx->modules;
normal_coverage_data_t *val = (normal_coverage_data_t *)value; normal_coverage_data_t *val = (normal_coverage_data_t *)value;
guint i; guint i;
@ -237,6 +238,18 @@ static void instrument_coverage_mark(void *key, void *value, void *user_data) {
} }
static void instrument_coverage_mark_first(void *key, void *value,
void *user_data) {
UNUSED_PARAMETER(key);
coverage_range_t *module = (coverage_range_t *)user_data;
normal_coverage_data_t *val = (normal_coverage_data_t *)value;
val->module = module;
module->count++;
}
static void coverage_write(int fd, void *data, size_t size) { static void coverage_write(int fd, void *data, size_t size) {
ssize_t written; ssize_t written;
@ -289,9 +302,9 @@ static void coverage_write_modules(int fd, GArray *coverage_modules) {
coverage_format(fd, "%016" G_GINT64_MODIFIER "X, ", module->base_address); coverage_format(fd, "%016" G_GINT64_MODIFIER "X, ", module->base_address);
coverage_format(fd, "%016" G_GINT64_MODIFIER "X, ", module->limit); coverage_format(fd, "%016" G_GINT64_MODIFIER "X, ", module->limit);
/* entry */ /* entry */
coverage_format(fd, "%016" G_GINT64_MODIFIER "X, ", 0); coverage_format(fd, "%016" G_GINT64_MODIFIER "X, ", 0UL);
/* checksum */ /* checksum */
coverage_format(fd, "%016" G_GINT64_MODIFIER "X, ", 0); coverage_format(fd, "%016" G_GINT64_MODIFIER "X, ", 0UL);
/* timestamp */ /* timestamp */
coverage_format(fd, "%08" G_GINT32_MODIFIER "X, ", 0); coverage_format(fd, "%08" G_GINT32_MODIFIER "X, ", 0);
coverage_format(fd, "%s\n", module->path); coverage_format(fd, "%s\n", module->path);
@ -317,6 +330,12 @@ static void coverage_write_events(void *key, void *value, void *user_data) {
}; };
#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
evt.offset = __builtin_bswap32(evt.offset);
evt.length = __builtin_bswap16(evt.length);
evt.module = __builtin_bswap16(evt.module);
#endif
coverage_write(fd, &evt, sizeof(coverage_event_t)); coverage_write(fd, &evt, sizeof(coverage_event_t));
} }
@ -398,35 +417,76 @@ static void instrument_coverage_normal_run() {
instrument_coverage_print("Coverage - Preparing\n"); instrument_coverage_print("Coverage - Preparing\n");
GArray *coverage_modules = coverage_get_modules(); if (instrument_coverage_absolute) {
guint size = g_hash_table_size(coverage_hash); guint size = g_hash_table_size(coverage_hash);
instrument_coverage_print("Coverage - Total Entries: %u\n", size); instrument_coverage_print("Coverage - Total Entries: %u\n", size);
coverage_mark_ctx_t ctx = {.modules = coverage_modules, .count = 0}; coverage_range_t module = {
g_hash_table_foreach(coverage_hash, instrument_coverage_mark, &ctx); .base_address = GUM_ADDRESS(0),
instrument_coverage_print("Coverage - Marked Entries: %u\n", ctx.count); .limit = GUM_ADDRESS(-1),
.size = GUM_ADDRESS(-1),
.path = "absolute",
.offset = 0,
.is_executable = true,
.count = size,
.id = 0,
guint coverage_marked_modules = coverage_mark_modules(coverage_modules); };
instrument_coverage_print("Coverage - Marked Modules: %u\n",
coverage_marked_modules);
coverage_write_header(normal_coverage_fd, coverage_marked_modules); instrument_coverage_print("Coverage Module - 0x%016" G_GINT64_MODIFIER
coverage_write_modules(normal_coverage_fd, coverage_modules); "X - 0x%016" G_GINT64_MODIFIER "X (%s)\n",
coverage_format(normal_coverage_fd, "BB Table: %u bbs\n", ctx.count); module.base_address, module.limit, module.path);
g_hash_table_foreach(coverage_hash, coverage_write_events,
&normal_coverage_fd); GArray *coverage_modules =
g_array_sized_new(false, false, sizeof(coverage_range_t), 1);
g_array_append_val(coverage_modules, module);
g_hash_table_foreach(coverage_hash, instrument_coverage_mark_first,
&module);
coverage_write_header(normal_coverage_fd, 1);
coverage_write_modules(normal_coverage_fd, coverage_modules);
coverage_format(normal_coverage_fd, "BB Table: %u bbs\n", size);
g_hash_table_foreach(coverage_hash, coverage_write_events,
&normal_coverage_fd);
} else {
GArray *coverage_modules = coverage_get_modules();
guint size = g_hash_table_size(coverage_hash);
instrument_coverage_print("Coverage - Total Entries: %u\n", size);
coverage_mark_ctx_t ctx = {.modules = coverage_modules, .count = 0};
/* For each coverage event in the hashtable associate it with a module and
* count the number of entries per module */
g_hash_table_foreach(coverage_hash, instrument_coverage_mark, &ctx);
instrument_coverage_print("Coverage - Marked Entries: %u\n", ctx.count);
/* For each module with coverage events assign it an incrementing number */
guint coverage_marked_modules = coverage_mark_modules(coverage_modules);
instrument_coverage_print("Coverage - Marked Modules: %u\n",
coverage_marked_modules);
coverage_write_header(normal_coverage_fd, coverage_marked_modules);
coverage_write_modules(normal_coverage_fd, coverage_modules);
coverage_format(normal_coverage_fd, "BB Table: %u bbs\n", ctx.count);
g_hash_table_foreach(coverage_hash, coverage_write_events,
&normal_coverage_fd);
}
g_hash_table_unref(coverage_hash); g_hash_table_unref(coverage_hash);
instrument_coverage_print("Coverage - Completed\n"); instrument_coverage_print("Coverage - Completed\n");
} }
static GArray *instrument_coverage_unstable_read_unstable_ids(void) { static GArray *instrument_coverage_unstable_read_unstable_ids(void) {
gchar * contents = NULL; gchar *contents = NULL;
gsize length = 0; gsize length = 0;
GArray *unstable_edge_ids = GArray *unstable_edge_ids =
g_array_sized_new(false, false, sizeof(gpointer), 100); g_array_sized_new(false, false, sizeof(gpointer), 100);
@ -533,7 +593,7 @@ static GHashTable *instrument_collect_unstable_blocks(
while (g_hash_table_iter_next(&iter, NULL, &value)) { while (g_hash_table_iter_next(&iter, NULL, &value)) {
unstable_coverage_data_t *unstable = (unstable_coverage_data_t *)value; unstable_coverage_data_t *unstable = (unstable_coverage_data_t *)value;
normal_coverage_data_t * from = normal_coverage_data_t *from =
gum_malloc0(sizeof(normal_coverage_data_t)); gum_malloc0(sizeof(normal_coverage_data_t));
normal_coverage_data_t *to = gum_malloc0(sizeof(normal_coverage_data_t)); normal_coverage_data_t *to = gum_malloc0(sizeof(normal_coverage_data_t));
from->start = unstable->from; from->start = unstable->from;
@ -616,8 +676,6 @@ static void instrument_coverage_unstable_run(void) {
instrument_coverage_print("Coverage - Preparing\n"); instrument_coverage_print("Coverage - Preparing\n");
GArray *coverage_modules = coverage_get_modules();
instrument_coverage_print("Found edges: %u\n", edges); instrument_coverage_print("Found edges: %u\n", edges);
GArray *unstable_edge_ids = instrument_coverage_unstable_read_unstable_ids(); GArray *unstable_edge_ids = instrument_coverage_unstable_read_unstable_ids();
@ -628,20 +686,60 @@ static void instrument_coverage_unstable_run(void) {
guint size = g_hash_table_size(unstable_blocks); guint size = g_hash_table_size(unstable_blocks);
instrument_coverage_print("Unstable blocks: %u\n", size); instrument_coverage_print("Unstable blocks: %u\n", size);
coverage_mark_ctx_t ctx = {.modules = coverage_modules, .count = 0}; if (instrument_coverage_absolute) {
g_hash_table_foreach(unstable_blocks, instrument_coverage_mark, &ctx); instrument_coverage_print("Coverage - Total Entries: %u\n", size);
instrument_coverage_print("Coverage - Marked Entries: %u\n", ctx.count);
guint coverage_marked_modules = coverage_mark_modules(coverage_modules); coverage_range_t module = {
instrument_coverage_print("Coverage - Marked Modules: %u\n",
coverage_marked_modules);
coverage_write_header(unstable_coverage_fd, coverage_marked_modules); .base_address = GUM_ADDRESS(0),
coverage_write_modules(unstable_coverage_fd, coverage_modules); .limit = GUM_ADDRESS(-1),
coverage_format(unstable_coverage_fd, "BB Table: %u bbs\n", ctx.count); .size = GUM_ADDRESS(-1),
g_hash_table_foreach(unstable_blocks, coverage_write_events, .path = "absolute",
&unstable_coverage_fd); .offset = 0,
.is_executable = true,
.count = size,
.id = 0,
};
instrument_coverage_print("Coverage Module - 0x%016" G_GINT64_MODIFIER
"X - 0x%016" G_GINT64_MODIFIER "X (%s)\n",
module.base_address, module.limit, module.path);
GArray *coverage_modules =
g_array_sized_new(false, false, sizeof(coverage_range_t), 1);
g_array_append_val(coverage_modules, module);
g_hash_table_foreach(unstable_blocks, instrument_coverage_mark_first,
&module);
coverage_write_header(unstable_coverage_fd, 1);
coverage_write_modules(unstable_coverage_fd, coverage_modules);
coverage_format(unstable_coverage_fd, "BB Table: %u bbs\n", size);
g_hash_table_foreach(unstable_blocks, coverage_write_events,
&unstable_coverage_fd);
} else {
GArray *coverage_modules = coverage_get_modules();
coverage_mark_ctx_t ctx = {.modules = coverage_modules, .count = 0};
g_hash_table_foreach(unstable_blocks, instrument_coverage_mark, &ctx);
instrument_coverage_print("Coverage - Marked Entries: %u\n", ctx.count);
guint coverage_marked_modules = coverage_mark_modules(coverage_modules);
instrument_coverage_print("Coverage - Marked Modules: %u\n",
coverage_marked_modules);
coverage_write_header(unstable_coverage_fd, coverage_marked_modules);
coverage_write_modules(unstable_coverage_fd, coverage_modules);
coverage_format(unstable_coverage_fd, "BB Table: %u bbs\n", ctx.count);
g_hash_table_foreach(unstable_blocks, coverage_write_events,
&unstable_coverage_fd);
}
g_hash_table_unref(unstable_blocks); g_hash_table_unref(unstable_blocks);
g_array_free(unstable_edge_ids, TRUE); g_array_free(unstable_edge_ids, TRUE);
@ -654,6 +752,8 @@ static void instrument_coverage_unstable_run(void) {
void instrument_coverage_config(void) { void instrument_coverage_config(void) {
instrument_coverage_filename = getenv("AFL_FRIDA_INST_COVERAGE_FILE"); instrument_coverage_filename = getenv("AFL_FRIDA_INST_COVERAGE_FILE");
instrument_coverage_absolute =
(getenv("AFL_FRIDA_INST_COVERAGE_ABSOLUTE") != NULL);
} }

View File

@ -66,7 +66,7 @@ static void instrument_disasm(guint8 *start, guint8 *end,
instrument_debug("\t0x%" G_GINT64_MODIFIER "x\t* 0x%016" G_GSIZE_MODIFIER instrument_debug("\t0x%" G_GINT64_MODIFIER "x\t* 0x%016" G_GSIZE_MODIFIER
"x\n", "x\n",
curr, *(size_t *)curr); (uint64_t)(size_t)curr, *(size_t *)curr);
len += sizeof(size_t); len += sizeof(size_t);
continue; continue;

View File

@ -174,13 +174,13 @@ void instrument_coverage_optimize_init(void) {
static void instrument_coverage_switch(GumStalkerObserver *self, static void instrument_coverage_switch(GumStalkerObserver *self,
gpointer from_address, gpointer from_address,
gpointer start_address, gpointer start_address,
const cs_insn * from_insn, const cs_insn *from_insn,
gpointer * target) { gpointer *target) {
UNUSED_PARAMETER(self); UNUSED_PARAMETER(self);
UNUSED_PARAMETER(from_address); UNUSED_PARAMETER(from_address);
cs_x86 * x86; cs_x86 *x86;
cs_x86_op *op; cs_x86_op *op;
if (from_insn == NULL) { return; } if (from_insn == NULL) { return; }
@ -230,7 +230,7 @@ static void instrument_coverage_suppress_init(void) {
if (initialized) { return; } if (initialized) { return; }
initialized = true; initialized = true;
GumStalkerObserver * observer = stalker_get_observer(); GumStalkerObserver *observer = stalker_get_observer();
GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer); GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer);
iface->switch_callback = instrument_coverage_switch; iface->switch_callback = instrument_coverage_switch;
@ -333,19 +333,18 @@ static void instrument_coverage_write(GumAddress address,
} }
void instrument_coverage_optimize(const cs_insn * instr, void instrument_coverage_optimize(const cs_insn *instr,
GumStalkerOutput *output) { GumStalkerOutput *output) {
GumX86Writer *cw = output->writer.x86; GumX86Writer *cw = output->writer.x86;
/* guint64 area_offset =
* instrument_get_offset_hash(GUM_ADDRESS(instr->address)); */
if (instrument_previous_pc_addr == NULL) { if (instrument_previous_pc_addr == NULL) {
GumAddressSpec spec = {.near_address = cw->code, GumAddressSpec spec = {.near_address = cw->code,
.max_distance = 1ULL << 30}; .max_distance = 1ULL << 30};
guint page_size = gum_query_page_size();
instrument_previous_pc_addr = gum_memory_allocate_near( instrument_previous_pc_addr = gum_memory_allocate_near(
&spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE); &spec, sizeof(guint64), page_size, GUM_PAGE_READ | GUM_PAGE_WRITE);
*instrument_previous_pc_addr = instrument_hash_zero; *instrument_previous_pc_addr = instrument_hash_zero;
FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr); FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
FVERBOSE("code_addr: %p", cw->code); FVERBOSE("code_addr: %p", cw->code);
@ -364,7 +363,7 @@ void instrument_coverage_optimize(const cs_insn * instr,
} }
void instrument_coverage_optimize_insn(const cs_insn * instr, void instrument_coverage_optimize_insn(const cs_insn *instr,
GumStalkerOutput *output) { GumStalkerOutput *output) {
GumX86Writer *cw = output->writer.x86; GumX86Writer *cw = output->writer.x86;
@ -469,5 +468,24 @@ gpointer instrument_cur(GumStalkerOutput *output) {
} }
void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) {
int fd = (int)(size_t)user_data;
instrument_regs_format(
fd, "rax: 0x%016x, rbx: 0x%016x, rcx: 0x%016x, rdx: 0x%016x\n",
cpu_context->rax, cpu_context->rbx, cpu_context->rcx, cpu_context->rdx);
instrument_regs_format(
fd, "rdi: 0x%016x, rsi: 0x%016x, rbp: 0x%016x, rsp: 0x%016x\n",
cpu_context->rdi, cpu_context->rsi, cpu_context->rbp, cpu_context->rsp);
instrument_regs_format(
fd, "r8 : 0x%016x, r9 : 0x%016x, r10: 0x%016x, r11: 0x%016x\n",
cpu_context->r8, cpu_context->r9, cpu_context->r10, cpu_context->r11);
instrument_regs_format(
fd, "r12: 0x%016x, r13: 0x%016x, r14: 0x%016x, r15: 0x%016x\n",
cpu_context->r12, cpu_context->r13, cpu_context->r14, cpu_context->r15);
instrument_regs_format(fd, "rip: 0x%016x\n\n", cpu_context->rip);
}
#endif #endif

View File

@ -105,11 +105,11 @@ static gboolean instrument_cache_relocate(GumAddress old_pc, GumAddress new_pc,
} }
static void instrument_cache_rewrite_branch_insn(const cs_insn * instr, static void instrument_cache_rewrite_branch_insn(const cs_insn *instr,
GumStalkerOutput *output) { GumStalkerOutput *output) {
GumX86Writer *cw = output->writer.x86; GumX86Writer *cw = output->writer.x86;
cs_x86 * x86 = &instr->detail->x86; cs_x86 *x86 = &instr->detail->x86;
guint8 modified[sizeof(instr->bytes)] = {0}; guint8 modified[sizeof(instr->bytes)] = {0};
guint8 offset = 0; guint8 offset = 0;
guint8 skip = 0; guint8 skip = 0;
@ -225,8 +225,8 @@ static void instrument_cache_rewrite_branch_insn(const cs_insn * instr,
} else { } else {
GumAddress target = instr->address + old_offset; GumAddress target = instr->address + old_offset;
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, target); gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX, target);
gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_RAX, GUM_REG_RAX); gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_X86_RAX, GUM_X86_RAX);
return; return;
} }
@ -249,29 +249,29 @@ static void instrument_cache_rewrite_branch_insn(const cs_insn * instr,
static void instrument_cache_write_push_frame(GumX86Writer *cw) { static void instrument_cache_write_push_frame(GumX86Writer *cw) {
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer))), cw, GUM_X86_XSP, -(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer))),
GUM_REG_XAX); GUM_X86_XAX);
gum_x86_writer_put_lahf(cw); gum_x86_writer_put_lahf(cw);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (2 * sizeof(gpointer))), cw, GUM_X86_XSP, -(GUM_RED_ZONE_SIZE + (2 * sizeof(gpointer))),
GUM_REG_XAX); GUM_X86_XAX);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (3 * sizeof(gpointer))), cw, GUM_X86_XSP, -(GUM_RED_ZONE_SIZE + (3 * sizeof(gpointer))),
GUM_REG_XBX); GUM_X86_XBX);
} }
static void instrument_cache_write_pop_frame(GumX86Writer *cw) { static void instrument_cache_write_pop_frame(GumX86Writer *cw) {
gum_x86_writer_put_mov_reg_reg_offset_ptr( gum_x86_writer_put_mov_reg_reg_offset_ptr(
cw, GUM_REG_XBX, GUM_REG_XSP, cw, GUM_X86_XBX, GUM_X86_XSP,
-(GUM_RED_ZONE_SIZE + (3 * sizeof(gpointer)))); -(GUM_RED_ZONE_SIZE + (3 * sizeof(gpointer))));
gum_x86_writer_put_mov_reg_reg_offset_ptr( gum_x86_writer_put_mov_reg_reg_offset_ptr(
cw, GUM_REG_XAX, GUM_REG_XSP, cw, GUM_X86_XAX, GUM_X86_XSP,
-(GUM_RED_ZONE_SIZE + (2 * sizeof(gpointer)))); -(GUM_RED_ZONE_SIZE + (2 * sizeof(gpointer))));
gum_x86_writer_put_sahf(cw); gum_x86_writer_put_sahf(cw);
gum_x86_writer_put_mov_reg_reg_offset_ptr( gum_x86_writer_put_mov_reg_reg_offset_ptr(
cw, GUM_REG_XAX, GUM_REG_XSP, cw, GUM_X86_XAX, GUM_X86_XSP,
-(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer)))); -(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer))));
} }
@ -281,21 +281,21 @@ static void instrument_cache_write_lookup(GumX86Writer *cw) {
/* &map_base[GPOINTER_TO_SIZE(addr) & MAP_MASK]; */ /* &map_base[GPOINTER_TO_SIZE(addr) & MAP_MASK]; */
gsize mask = (instrument_cache_size / sizeof(gpointer)) - 1; gsize mask = (instrument_cache_size / sizeof(gpointer)) - 1;
gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_XBX, mask); gum_x86_writer_put_mov_reg_u64(cw, GUM_X86_XBX, mask);
gum_x86_writer_put_and_reg_reg(cw, GUM_REG_XAX, GUM_REG_XBX); gum_x86_writer_put_and_reg_reg(cw, GUM_X86_XAX, GUM_X86_XBX);
gum_x86_writer_put_shl_reg_u8(cw, GUM_REG_XAX, util_log2(sizeof(gpointer))); gum_x86_writer_put_shl_reg_u8(cw, GUM_X86_XAX, util_log2(sizeof(gpointer)));
gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_XBX, GPOINTER_TO_SIZE(map_base)); gum_x86_writer_put_mov_reg_u64(cw, GUM_X86_XBX, GPOINTER_TO_SIZE(map_base));
gum_x86_writer_put_add_reg_reg(cw, GUM_REG_XAX, GUM_REG_XBX); gum_x86_writer_put_add_reg_reg(cw, GUM_X86_XAX, GUM_X86_XBX);
/* Read the return address lookup */ /* Read the return address lookup */
gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_XAX, GUM_REG_XAX); gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_X86_XAX, GUM_X86_XAX);
} }
void instrument_cache_jmp_call(const cs_insn *instr, GumStalkerOutput *output) { void instrument_cache_jmp_call(const cs_insn *instr, GumStalkerOutput *output) {
GumX86Writer *cw = output->writer.x86; GumX86Writer *cw = output->writer.x86;
cs_x86 * x86 = &instr->detail->x86; cs_x86 *x86 = &instr->detail->x86;
if (x86->op_count != 1) { FFATAL("Unexpected operand count"); } if (x86->op_count != 1) { FFATAL("Unexpected operand count"); }
@ -315,7 +315,7 @@ void instrument_cache_jmp_call(const cs_insn *instr, GumStalkerOutput *output) {
* red-zone. * red-zone.
*/ */
gum_x86_writer_put_mov_reg_reg_offset_ptr( gum_x86_writer_put_mov_reg_reg_offset_ptr(
cw, GUM_REG_XAX, GUM_REG_XSP, cw, GUM_X86_XAX, GUM_X86_XSP,
-(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer)))); -(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer))));
instrument_cache_rewrite_branch_insn(instr, output); instrument_cache_rewrite_branch_insn(instr, output);
@ -323,33 +323,33 @@ void instrument_cache_jmp_call(const cs_insn *instr, GumStalkerOutput *output) {
instrument_cache_write_lookup(cw); instrument_cache_write_lookup(cw);
/* Test if its set*/ /* Test if its set*/
gum_x86_writer_put_cmp_reg_i32(cw, GUM_REG_XAX, INVALID); gum_x86_writer_put_cmp_reg_i32(cw, GUM_X86_XAX, INVALID);
gum_x86_writer_put_jcc_short_label(cw, X86_INS_JLE, null, GUM_UNLIKELY); gum_x86_writer_put_jcc_short_label(cw, X86_INS_JLE, null, GUM_UNLIKELY);
/* If it's set, then stash the address beyond the red-zone */ /* If it's set, then stash the address beyond the red-zone */
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (4 * sizeof(gpointer))), cw, GUM_X86_XSP, -(GUM_RED_ZONE_SIZE + (4 * sizeof(gpointer))),
GUM_REG_XAX); GUM_X86_XAX);
if (instr->id == X86_INS_JMP) { if (instr->id == X86_INS_JMP) {
instrument_cache_write_pop_frame(cw); instrument_cache_write_pop_frame(cw);
gum_x86_writer_put_jmp_reg_offset_ptr( gum_x86_writer_put_jmp_reg_offset_ptr(
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (4 * sizeof(gpointer)))); cw, GUM_X86_XSP, -(GUM_RED_ZONE_SIZE + (4 * sizeof(gpointer))));
} else { } else {
gum_x86_writer_put_mov_reg_address( gum_x86_writer_put_mov_reg_address(
cw, GUM_REG_XAX, GUM_ADDRESS(instr->address + instr->size)); cw, GUM_X86_XAX, GUM_ADDRESS(instr->address + instr->size));
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_XSP, gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_X86_XSP,
-sizeof(gpointer), GUM_REG_XAX); -sizeof(gpointer), GUM_X86_XAX);
instrument_cache_write_pop_frame(cw); instrument_cache_write_pop_frame(cw);
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_XSP, GUM_REG_XSP, gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_XSP, GUM_X86_XSP,
-sizeof(gpointer)); -sizeof(gpointer));
gum_x86_writer_put_jmp_reg_offset_ptr( gum_x86_writer_put_jmp_reg_offset_ptr(
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + ((4 - 1) * sizeof(gpointer)))); cw, GUM_X86_XSP, -(GUM_RED_ZONE_SIZE + ((4 - 1) * sizeof(gpointer))));
} }
@ -362,7 +362,7 @@ void instrument_cache_jmp_call(const cs_insn *instr, GumStalkerOutput *output) {
void instrument_cache_ret(const cs_insn *instr, GumStalkerOutput *output) { void instrument_cache_ret(const cs_insn *instr, GumStalkerOutput *output) {
GumX86Writer *cw = output->writer.x86; GumX86Writer *cw = output->writer.x86;
cs_x86 * x86 = &instr->detail->x86; cs_x86 *x86 = &instr->detail->x86;
guint16 n = 0; guint16 n = 0;
if (x86->op_count != 0) { if (x86->op_count != 0) {
@ -381,16 +381,16 @@ void instrument_cache_ret(const cs_insn *instr, GumStalkerOutput *output) {
instrument_cache_write_push_frame(cw); instrument_cache_write_push_frame(cw);
gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_XAX, GUM_REG_XSP); gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_X86_XAX, GUM_X86_XSP);
instrument_cache_write_lookup(cw); instrument_cache_write_lookup(cw);
/* Test if its set*/ /* Test if its set*/
gum_x86_writer_put_cmp_reg_i32(cw, GUM_REG_XAX, INVALID); gum_x86_writer_put_cmp_reg_i32(cw, GUM_X86_XAX, INVALID);
gum_x86_writer_put_jcc_short_label(cw, X86_INS_JLE, null, GUM_UNLIKELY); gum_x86_writer_put_jcc_short_label(cw, X86_INS_JLE, null, GUM_UNLIKELY);
/* If it's set, then overwrite our return address and return */ /* If it's set, then overwrite our return address and return */
gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_REG_XSP, GUM_REG_XAX); gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_X86_XSP, GUM_X86_XAX);
instrument_cache_write_pop_frame(cw); instrument_cache_write_pop_frame(cw);
if (n == 0) { if (n == 0) {

View File

@ -86,14 +86,14 @@ gboolean instrument_is_coverage_optimize_supported(void) {
static void instrument_coverage_switch(GumStalkerObserver *self, static void instrument_coverage_switch(GumStalkerObserver *self,
gpointer from_address, gpointer from_address,
gpointer start_address, gpointer start_address,
const cs_insn * from_insn, const cs_insn *from_insn,
gpointer * target) { gpointer *target) {
UNUSED_PARAMETER(self); UNUSED_PARAMETER(self);
UNUSED_PARAMETER(from_address); UNUSED_PARAMETER(from_address);
UNUSED_PARAMETER(start_address); UNUSED_PARAMETER(start_address);
cs_x86 * x86; cs_x86 *x86;
cs_x86_op *op; cs_x86_op *op;
if (from_insn == NULL) { return; } if (from_insn == NULL) { return; }
@ -136,7 +136,7 @@ static void instrument_coverage_suppress_init(void) {
if (initialized) { return; } if (initialized) { return; }
initialized = true; initialized = true;
GumStalkerObserver * observer = stalker_get_observer(); GumStalkerObserver *observer = stalker_get_observer();
GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer); GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer);
iface->switch_callback = instrument_coverage_switch; iface->switch_callback = instrument_coverage_switch;
@ -149,7 +149,7 @@ static void instrument_coverage_suppress_init(void) {
} }
void instrument_coverage_optimize(const cs_insn * instr, void instrument_coverage_optimize(const cs_insn *instr,
GumStalkerOutput *output) { GumStalkerOutput *output) {
afl_log_code code = {0}; afl_log_code code = {0};
@ -162,9 +162,10 @@ void instrument_coverage_optimize(const cs_insn * instr,
GumAddressSpec spec = {.near_address = cw->code, GumAddressSpec spec = {.near_address = cw->code,
.max_distance = 1ULL << 30}; .max_distance = 1ULL << 30};
guint page_size = gum_query_page_size();
instrument_previous_pc_addr = gum_memory_allocate_near( instrument_previous_pc_addr = gum_memory_allocate_near(
&spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE); &spec, sizeof(guint64), page_size, GUM_PAGE_READ | GUM_PAGE_WRITE);
*instrument_previous_pc_addr = instrument_hash_zero; *instrument_previous_pc_addr = instrument_hash_zero;
FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr); FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
FVERBOSE("code_addr: %p", cw->code); FVERBOSE("code_addr: %p", cw->code);
@ -223,7 +224,7 @@ void instrument_coverage_optimize(const cs_insn * instr,
} }
void instrument_coverage_optimize_insn(const cs_insn * instr, void instrument_coverage_optimize_insn(const cs_insn *instr,
GumStalkerOutput *output) { GumStalkerOutput *output) {
UNUSED_PARAMETER(instr); UNUSED_PARAMETER(instr);
@ -269,5 +270,18 @@ void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) {
} }
void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) {
int fd = (int)(size_t)user_data;
instrument_regs_format(
fd, "eax: 0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x\n",
cpu_context->eax, cpu_context->ebx, cpu_context->ecx, cpu_context->edx);
instrument_regs_format(
fd, "esi: 0x%08x, edi: 0x%08x, ebp: 0x%08x, esp: 0x%08x\n",
cpu_context->esi, cpu_context->edi, cpu_context->ebp, cpu_context->esp);
instrument_regs_format(fd, "eip: 0x%08x\n\n", cpu_context->eip);
}
#endif #endif

View File

@ -7,8 +7,8 @@ void intercept_hook(void *address, gpointer replacement, gpointer user_data) {
GumInterceptor *interceptor = gum_interceptor_obtain(); GumInterceptor *interceptor = gum_interceptor_obtain();
gum_interceptor_begin_transaction(interceptor); gum_interceptor_begin_transaction(interceptor);
GumReplaceReturn ret = GumReplaceReturn ret = gum_interceptor_replace(interceptor, address,
gum_interceptor_replace(interceptor, address, replacement, user_data); replacement, user_data, NULL);
if (ret != GUM_REPLACE_OK) { FFATAL("gum_interceptor_attach: %d", ret); } if (ret != GUM_REPLACE_OK) { FFATAL("gum_interceptor_attach: %d", ret); }
gum_interceptor_end_transaction(interceptor); gum_interceptor_end_transaction(interceptor);

View File

@ -104,6 +104,12 @@ class Afl {
static setInstrumentCacheSize(size) { static setInstrumentCacheSize(size) {
Afl.jsApiSetInstrumentCacheSize(size); Afl.jsApiSetInstrumentCacheSize(size);
} }
/**
* See `AFL_FRIDA_INST_COVERAGE_ABSOLUTE`.
*/
static setInstrumentCoverageAbsolute() {
Afl.jsApiSetInstrumentCoverageAbsolute();
}
/** /**
* See `AFL_FRIDA_INST_COVERAGE_FILE`. This function takes a single `string` * See `AFL_FRIDA_INST_COVERAGE_FILE`. This function takes a single `string`
* as an argument. * as an argument.
@ -150,6 +156,14 @@ class Afl {
static setInstrumentNoOptimize() { static setInstrumentNoOptimize() {
Afl.jsApiSetInstrumentNoOptimize(); Afl.jsApiSetInstrumentNoOptimize();
} }
/**
* See `AFL_FRIDA_INST_REGS_FILE`. This function takes a single `string` as
* an argument.
*/
static setInstrumentRegsFile(file) {
const buf = Memory.allocUtf8String(file);
Afl.jsApiSetInstrumentRegsFile(buf);
}
/* /*
* See `AFL_FRIDA_INST_SEED` * See `AFL_FRIDA_INST_SEED`
*/ */
@ -316,12 +330,14 @@ Afl.jsApiSetCacheDisable = Afl.jsApiGetFunction("js_api_set_cache_disable", "voi
Afl.jsApiSetDebugMaps = Afl.jsApiGetFunction("js_api_set_debug_maps", "void", []); Afl.jsApiSetDebugMaps = Afl.jsApiGetFunction("js_api_set_debug_maps", "void", []);
Afl.jsApiSetEntryPoint = Afl.jsApiGetFunction("js_api_set_entrypoint", "void", ["pointer"]); Afl.jsApiSetEntryPoint = Afl.jsApiGetFunction("js_api_set_entrypoint", "void", ["pointer"]);
Afl.jsApiSetInstrumentCacheSize = Afl.jsApiGetFunction("js_api_set_instrument_cache_size", "void", ["size_t"]); Afl.jsApiSetInstrumentCacheSize = Afl.jsApiGetFunction("js_api_set_instrument_cache_size", "void", ["size_t"]);
Afl.jsApiSetInstrumentCoverageAbsolute = Afl.jsApiGetFunction("js_api_set_instrument_coverage_absolute", "void", []);
Afl.jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument_coverage_file", "void", ["pointer"]); Afl.jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument_coverage_file", "void", ["pointer"]);
Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]); Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]);
Afl.jsApiSetInstrumentInstructions = Afl.jsApiGetFunction("js_api_set_instrument_instructions", "void", []); Afl.jsApiSetInstrumentInstructions = Afl.jsApiGetFunction("js_api_set_instrument_instructions", "void", []);
Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []); Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []);
Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []); Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []);
Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []); Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []);
Afl.jsApiSetInstrumentRegsFile = Afl.jsApiGetFunction("js_api_set_instrument_regs_file", "void", ["pointer"]);
Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]); Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]);
Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []); Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []);
Afl.jsApiSetInstrumentTraceUnique = Afl.jsApiGetFunction("js_api_set_instrument_trace_unique", "void", []); Afl.jsApiSetInstrumentTraceUnique = Afl.jsApiGetFunction("js_api_set_instrument_trace_unique", "void", []);

View File

@ -7,16 +7,16 @@ gboolean js_done = FALSE;
js_api_stalker_callback_t js_user_callback = NULL; js_api_stalker_callback_t js_user_callback = NULL;
js_main_hook_t js_main_hook = NULL; js_main_hook_t js_main_hook = NULL;
static char * js_script = NULL; static char *js_script = NULL;
static gchar * filename = "afl.js"; static gchar *filename = "afl.js";
static gchar * contents; static gchar *contents;
static GumScriptBackend * backend; static GumScriptBackend *backend;
static GCancellable * cancellable = NULL; static GCancellable *cancellable = NULL;
static GError * error = NULL; static GError *error = NULL;
static GumScript * script; static GumScript *script;
static GumScriptScheduler *scheduler; static GumScriptScheduler *scheduler;
static GMainContext * context; static GMainContext *context;
static GMainLoop * main_loop; static GMainLoop *main_loop;
static void js_msg(GumScript *script, const gchar *message, GBytes *data, static void js_msg(GumScript *script, const gchar *message, GBytes *data,
gpointer user_data) { gpointer user_data) {

View File

@ -115,6 +115,13 @@ __attribute__((visibility("default"))) void js_api_set_instrument_libraries() {
} }
__attribute__((visibility("default"))) void
js_api_set_instrument_coverage_absolute(void) {
instrument_coverage_absolute = true;
}
__attribute__((visibility("default"))) void js_api_set_instrument_coverage_file( __attribute__((visibility("default"))) void js_api_set_instrument_coverage_file(
char *path) { char *path) {
@ -156,6 +163,13 @@ __attribute__((visibility("default"))) void js_api_set_instrument_no_optimize(
} }
__attribute__((visibility("default"))) void js_api_set_instrument_regs_file(
char *path) {
instrument_regs_filename = g_strdup(path);
}
__attribute__((visibility("default"))) void js_api_set_instrument_seed( __attribute__((visibility("default"))) void js_api_set_instrument_seed(
guint64 seed) { guint64 seed) {

View File

@ -69,8 +69,8 @@ static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) {
Elf_Addr preferred_base; Elf_Addr preferred_base;
Elf_Shdr *shdr; Elf_Shdr *shdr;
Elf_Shdr *shstrtab; Elf_Shdr *shstrtab;
char * shstr; char *shstr;
char * section_name; char *section_name;
Elf_Shdr *curr; Elf_Shdr *curr;
char text_name[] = ".text"; char text_name[] = ".text";

View File

@ -16,9 +16,9 @@ static gboolean lib_get_main_module(const GumModuleDetails *details,
gpointer user_data) { gpointer user_data) {
GumDarwinModule **ret = (GumDarwinModule **)user_data; GumDarwinModule **ret = (GumDarwinModule **)user_data;
GumDarwinModule * module = gum_darwin_module_new_from_memory( GumDarwinModule *module = gum_darwin_module_new_from_memory(
details->path, mach_task_self(), details->range->base_address, details->path, mach_task_self(), details->range->base_address,
GUM_DARWIN_MODULE_FLAGS_NONE, NULL); GUM_DARWIN_MODULE_FLAGS_NONE, NULL);
FVERBOSE("Found main module: %s", module->name); FVERBOSE("Found main module: %s", module->name);

View File

@ -36,6 +36,18 @@
#ifdef __APPLE__ #ifdef __APPLE__
extern mach_port_t mach_task_self(); extern mach_port_t mach_task_self();
extern GumAddress gum_darwin_find_entrypoint(mach_port_t task); extern GumAddress gum_darwin_find_entrypoint(mach_port_t task);
#elif defined(__ANDROID__)
typedef struct {
void (**preinit_array)(void);
void (**init_array)(void);
void (**fini_array)(void);
} structors_array_t;
extern void __libc_init(void *raw_args, void (*onexit)(void) __unused,
int (*slingshot)(int, char **, char **),
structors_array_t const *const structors);
#else #else
extern int __libc_start_main(int (*main)(int, char **, char **), int argc, extern int __libc_start_main(int (*main)(int, char **, char **), int argc,
char **ubp_av, void (*init)(void), char **ubp_av, void (*init)(void),
@ -69,7 +81,11 @@ static void on_main_os(int argc, char **argv, char **envp) {
GumInterceptor *interceptor = gum_interceptor_obtain(); GumInterceptor *interceptor = gum_interceptor_obtain();
gum_interceptor_begin_transaction(interceptor); gum_interceptor_begin_transaction(interceptor);
#if defined(__ANDROID__)
gum_interceptor_revert(interceptor, __libc_init);
#else
gum_interceptor_revert(interceptor, __libc_start_main); gum_interceptor_revert(interceptor, __libc_start_main);
#endif
gum_interceptor_end_transaction(interceptor); gum_interceptor_end_transaction(interceptor);
gum_interceptor_flush(interceptor); gum_interceptor_flush(interceptor);
@ -92,7 +108,7 @@ static void embedded_init(void) {
static void afl_print_cmdline(void) { static void afl_print_cmdline(void) {
#if defined(__linux__) #if defined(__linux__)
char * buffer = g_malloc0(PROC_MAX); char *buffer = g_malloc0(PROC_MAX);
gchar *fname = g_strdup_printf("/proc/%d/cmdline", getppid()); gchar *fname = g_strdup_printf("/proc/%d/cmdline", getppid());
int fd = open(fname, O_RDONLY); int fd = open(fname, O_RDONLY);
@ -144,7 +160,7 @@ static void afl_print_cmdline(void) {
static void afl_print_env(void) { static void afl_print_env(void) {
char * buffer = g_malloc0(PROC_MAX); char *buffer = g_malloc0(PROC_MAX);
gchar *fname = g_strdup_printf("/proc/%d/environ", getppid()); gchar *fname = g_strdup_printf("/proc/%d/environ", getppid());
int fd = open(fname, O_RDONLY); int fd = open(fname, O_RDONLY);
@ -277,6 +293,24 @@ static void intercept_main(void) {
} }
#elif defined(__ANDROID__)
static void on_libc_init(void *raw_args, void (*onexit)(void) __unused,
int (*slingshot)(int, char **, char **),
structors_array_t const *const structors) {
main_fn = slingshot;
intercept_unhook_self();
intercept_hook(slingshot, on_main, NULL);
return __libc_init(raw_args, onexit, slingshot, structors);
}
static void intercept_main(void) {
intercept_hook(__libc_init, on_libc_init, NULL);
}
#else #else
static int on_libc_start_main(int (*main)(int, char **, char **), int argc, static int on_libc_start_main(int (*main)(int, char **, char **), int argc,
char **ubp_av, void (*init)(void), char **ubp_av, void (*init)(void),

View File

@ -31,7 +31,7 @@ typedef struct {
gboolean found_range(const GumRangeDetails *details, gpointer user_data) { gboolean found_range(const GumRangeDetails *details, gpointer user_data) {
gum_range_t range = {0}; gum_range_t range = {0};
GArray * ranges = (GArray *)user_data; GArray *ranges = (GArray *)user_data;
range.range = *details->range; range.range = *details->range;
range.protection = details->protection; range.protection = details->protection;
@ -45,9 +45,9 @@ gboolean found_range(const GumRangeDetails *details, gpointer user_data) {
#if defined(__linux__) && !defined(__ANDROID__) #if defined(__linux__) && !defined(__ANDROID__)
static int on_dlclose(void *handle) { static int on_dlclose(void *handle) {
GArray * ranges = NULL; GArray *ranges = NULL;
struct link_map *lm = NULL; struct link_map *lm = NULL;
gum_range_t * range = NULL; gum_range_t *range = NULL;
GumAddress base; GumAddress base;
GumAddress limit; GumAddress limit;
gpointer mem; gpointer mem;
@ -77,7 +77,9 @@ static int on_dlclose(void *handle) {
range = &g_array_index(ranges, gum_range_t, i); range = &g_array_index(ranges, gum_range_t, i);
base = range->range.base_address; base = range->range.base_address;
limit = base + range->range.size; limit = base + range->range.size;
FVERBOSE("Reserving range: 0x%016lx, 0x%016lX", base, limit); FVERBOSE("Reserving range: 0x%016" G_GINT64_MODIFIER
"x, 0x%016" G_GINT64_MODIFIER "X",
base, limit);
mem = gum_memory_allocate(GSIZE_TO_POINTER(base), range->range.size, mem = gum_memory_allocate(GSIZE_TO_POINTER(base), range->range.size,
page_size, GUM_PAGE_NO_ACCESS); page_size, GUM_PAGE_NO_ACCESS);
if (mem == NULL) { FATAL("Failed to allocate %p (%d)", mem, errno); } if (mem == NULL) { FATAL("Failed to allocate %p (%d)", mem, errno); }

View File

@ -1,75 +1,294 @@
#include "frida-gumjs.h" #include "frida-gumjs.h"
#include "instrument.h"
#include "persistent.h" #include "persistent.h"
#include "util.h" #include "util.h"
#if defined(__arm__) #if defined(__arm__)
struct arm_regs { // struct _GumArmCpuContext {
uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10; // guint32 pc;
// guint32 sp;
// guint32 cpsr;
union { // guint32 r8;
// guint32 r9;
// guint32 r10;
// guint32 r11;
// guint32 r12;
uint32_t r11; // GumArmVectorReg v[16];
uint32_t fp;
}; // guint32 _padding;
union { // guint32 r[8];
// guint32 lr;
// };
uint32_t r12; // r11 - fp
uint32_t ip; // r12 - ip
// r13 - sp
// r14 - lr
// r15 - pc
}; static GumCpuContext saved_regs = {0};
static gpointer saved_lr = NULL;
union {
uint32_t r13;
uint32_t sp;
};
union {
uint32_t r14;
uint32_t lr;
};
union {
uint32_t r15;
uint32_t pc;
};
uint32_t cpsr;
uint8_t vfp_zregs[32][16];
uint32_t vfp_xregs[16];
};
typedef struct arm_regs arch_api_regs;
gboolean persistent_is_supported(void) { gboolean persistent_is_supported(void) {
return false; return true;
}
static void instrument_persitent_save_regs(GumArmWriter *cw,
GumCpuContext *regs) {
/* Save Regs */
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_SP,
GUM_RED_ZONE_SIZE + sizeof(guint32));
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(regs));
/* Save r1-r7 */
for (size_t i = ARM_REG_R1; i < ARM_REG_R8; i++) {
gum_arm_writer_put_str_reg_reg_offset(
cw, i, ARM_REG_R0, offsetof(GumCpuContext, r[i - ARM_REG_R0]));
}
/* Save r8-r12 */
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R8, ARM_REG_R0,
offsetof(GumCpuContext, r8));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R9, ARM_REG_R0,
offsetof(GumCpuContext, r9));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R10, ARM_REG_R0,
offsetof(GumCpuContext, r10));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R11, ARM_REG_R0,
offsetof(GumCpuContext, r11));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R12, ARM_REG_R0,
offsetof(GumCpuContext, r12));
/* Save sp & lr */
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_SP, ARM_REG_R0,
offsetof(GumCpuContext, sp));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_LR, ARM_REG_R0,
offsetof(GumCpuContext, lr));
/* Save r0 (load from stack into r1) */
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_R0,
offsetof(GumCpuContext, r[0]));
/* Save CPSR */
gum_arm_writer_put_mov_reg_cpsr(cw, ARM_REG_R1);
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_R0,
offsetof(GumCpuContext, cpsr));
/* Save PC */
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R1,
GUM_ADDRESS(persistent_start));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_R0,
offsetof(GumCpuContext, pc));
/* Restore Regs */
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_SP,
GUM_RED_ZONE_SIZE + sizeof(guint32));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
}
static void instrument_persitent_restore_regs(GumArmWriter *cw,
GumCpuContext *regs) {
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(regs));
/* Restore CPSR */
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_R0,
offsetof(GumCpuContext, cpsr));
gum_arm_writer_put_mov_cpsr_reg(cw, ARM_REG_R1);
/* Restore sp & lr */
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_SP, ARM_REG_R0,
offsetof(GumCpuContext, sp));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_LR, ARM_REG_R0,
offsetof(GumCpuContext, lr));
/* Restore r8-r12 */
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R8, ARM_REG_R0,
offsetof(GumCpuContext, r8));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R9, ARM_REG_R0,
offsetof(GumCpuContext, r9));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R10, ARM_REG_R0,
offsetof(GumCpuContext, r10));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R11, ARM_REG_R0,
offsetof(GumCpuContext, r11));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R12, ARM_REG_R0,
offsetof(GumCpuContext, r12));
/* Restore r7-r0 */
for (size_t i = ARM_REG_R7; i >= ARM_REG_R0; i--) {
gum_arm_writer_put_ldr_reg_reg_offset(
cw, i, ARM_REG_R0, offsetof(GumCpuContext, r[i - ARM_REG_R0]));
}
}
static void instrument_exit(GumArmWriter *cw) {
gum_arm_writer_put_sub_reg_reg_reg(cw, ARM_REG_R0, ARM_REG_R0, ARM_REG_R0);
gum_arm_writer_put_call_address_with_arguments(cw, GUM_ADDRESS(_exit), 1,
GUM_ARG_REGISTER, ARM_REG_R0);
}
static int instrument_afl_persistent_loop_func(void) {
int ret = __afl_persistent_loop(persistent_count);
if (instrument_previous_pc_addr == NULL) {
FATAL("instrument_previous_pc_addr uninitialized");
}
*instrument_previous_pc_addr = instrument_hash_zero;
return ret;
}
static void instrument_afl_persistent_loop(GumArmWriter *cw) {
gum_arm_writer_put_sub_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
gum_arm_writer_put_call_address_with_arguments(
cw, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0);
gum_arm_writer_put_add_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
}
static void persistent_prologue_hook(GumArmWriter *cw, GumCpuContext *regs) {
if (persistent_hook == NULL) return;
gum_arm_writer_put_sub_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R2,
GUM_ADDRESS(&__afl_fuzz_len));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R2, ARM_REG_R2, 0);
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R2, ARM_REG_R2, 0);
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R1,
GUM_ADDRESS(&__afl_fuzz_ptr));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R1, ARM_REG_R1, 0);
gum_arm_writer_put_call_address_with_arguments(
cw, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS, GUM_ADDRESS(regs),
GUM_ARG_REGISTER, ARM_REG_R1, GUM_ARG_REGISTER, ARM_REG_R2);
gum_arm_writer_put_add_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
}
static void instrument_persitent_save_lr(GumArmWriter *cw) {
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(&saved_lr));
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_LR, ARM_REG_R0, 0);
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
GUM_RED_ZONE_SIZE);
} }
void persistent_prologue_arch(GumStalkerOutput *output) { void persistent_prologue_arch(GumStalkerOutput *output) {
UNUSED_PARAMETER(output); /*
FFATAL("Persistent mode not supported on this architecture"); * SAVE REGS
* SAVE RET
* POP RET
* loop:
* CALL instrument_afl_persistent_loop
* TEST EAX, EAX
* JZ end:
* call hook (optionally)
* RESTORE REGS
* call original
* jmp loop:
*
* end:
* JMP SAVED RET
*
* original:
* INSTRUMENTED PERSISTENT FUNC
*/
GumArmWriter *cw = output->writer.arm;
gconstpointer loop = cw->code + 1;
FVERBOSE("Persistent loop reached");
instrument_persitent_save_regs(cw, &saved_regs);
/* loop: */
gum_arm_writer_put_label(cw, loop);
/* call instrument_prologue_func */
instrument_afl_persistent_loop(cw);
/* jz done */
gconstpointer done = cw->code + 1;
gum_arm_writer_put_cmp_reg_imm(cw, ARM_REG_R0, 0);
gum_arm_writer_put_b_cond_label(cw, ARM_CC_EQ, done);
/* Optionally call the persistent hook */
persistent_prologue_hook(cw, &saved_regs);
instrument_persitent_restore_regs(cw, &saved_regs);
gconstpointer original = cw->code + 1;
/* call original */
gum_arm_writer_put_bl_label(cw, original);
/* jmp loop */
gum_arm_writer_put_b_label(cw, loop);
/* done: */
gum_arm_writer_put_label(cw, done);
instrument_exit(cw);
/* original: */
gum_arm_writer_put_label(cw, original);
instrument_persitent_save_lr(cw);
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
} }
void persistent_epilogue_arch(GumStalkerOutput *output) { void persistent_epilogue_arch(GumStalkerOutput *output) {
UNUSED_PARAMETER(output); GumArmWriter *cw = output->writer.arm;
FFATAL("Persistent mode not supported on this architecture");
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(&saved_lr));
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_R0, 0);
gum_arm_writer_put_bx_reg(cw, ARM_REG_R0);
} }

View File

@ -24,7 +24,7 @@ gboolean persistent_is_supported(void) {
} }
static void instrument_persitent_save_regs(GumArm64Writer * cw, static void instrument_persitent_save_regs(GumArm64Writer *cw,
persistent_ctx_t *regs) { persistent_ctx_t *regs) {
GumAddress regs_address = GUM_ADDRESS(regs); GumAddress regs_address = GUM_ADDRESS(regs);
@ -105,18 +105,13 @@ static void instrument_persitent_save_regs(GumArm64Writer * cw,
offsetof(persistent_ctx_t, rflags)); offsetof(persistent_ctx_t, rflags));
/* Q */ /* Q */
gum_arm64_writer_put_stp_reg_reg_reg_offset( for (int i = 0; i < 16; i++) {
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(
gum_arm64_writer_put_stp_reg_reg_reg_offset( cw, ARM64_REG_Q0 + (i * 2), ARM64_REG_Q0 + (i * 2) + 1, ARM64_REG_X0,
cw, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_X0, offsetof(GumCpuContext, v[i]), GUM_INDEX_SIGNED_OFFSET);
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 */ /* x0 & x1 */
gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3, gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3,
@ -136,7 +131,7 @@ static void instrument_persitent_save_regs(GumArm64Writer * cw,
} }
static void instrument_persitent_restore_regs(GumArm64Writer * cw, static void instrument_persitent_restore_regs(GumArm64Writer *cw,
persistent_ctx_t *regs) { persistent_ctx_t *regs) {
GumAddress regs_address = GUM_ADDRESS(regs); GumAddress regs_address = GUM_ADDRESS(regs);
@ -201,18 +196,14 @@ static void instrument_persitent_restore_regs(GumArm64Writer * cw,
offsetof(persistent_ctx_t, rflags)); offsetof(persistent_ctx_t, rflags));
gum_arm64_writer_put_instruction(cw, msr_nzcv_x1); gum_arm64_writer_put_instruction(cw, msr_nzcv_x1);
gum_arm64_writer_put_ldp_reg_reg_reg_offset( /* Q */
cw, ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_X0, for (int i = 0; i < 16; i++) {
offsetof(GumCpuContext, q[0]), GUM_INDEX_SIGNED_OFFSET);
gum_arm64_writer_put_ldp_reg_reg_reg_offset( gum_arm64_writer_put_ldp_reg_reg_reg_offset(
cw, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_X0, cw, ARM64_REG_Q0 + (i * 2), ARM64_REG_Q0 + (i * 2) + 1, ARM64_REG_X0,
offsetof(GumCpuContext, q[16]), GUM_INDEX_SIGNED_OFFSET); offsetof(GumCpuContext, v[i]), 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 */ /* x2 & x3 */
gum_arm64_writer_put_ldp_reg_reg_reg_offset( gum_arm64_writer_put_ldp_reg_reg_reg_offset(
@ -258,7 +249,7 @@ static void instrument_afl_persistent_loop(GumArm64Writer *cw) {
} }
static void persistent_prologue_hook(GumArm64Writer * cw, static void persistent_prologue_hook(GumArm64Writer *cw,
persistent_ctx_t *regs) { persistent_ctx_t *regs) {
if (persistent_hook == NULL) return; if (persistent_hook == NULL) return;

View File

@ -25,148 +25,148 @@ gboolean persistent_is_supported(void) {
} }
static void instrument_persitent_save_regs(GumX86Writer * cw, static void instrument_persitent_save_regs(GumX86Writer *cw,
persistent_ctx_t *regs) { persistent_ctx_t *regs) {
GumAddress regs_address = GUM_ADDRESS(regs); GumAddress regs_address = GUM_ADDRESS(regs);
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP,
-(GUM_RED_ZONE_SIZE)); -(GUM_RED_ZONE_SIZE));
/* Should be pushing FPU here, but meh */ /* Should be pushing FPU here, but meh */
gum_x86_writer_put_pushfx(cw); gum_x86_writer_put_pushfx(cw);
gum_x86_writer_put_push_reg(cw, GUM_REG_RAX); gum_x86_writer_put_push_reg(cw, GUM_X86_RAX);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, regs_address); gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX, regs_address);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, rbx), GUM_REG_RBX); cw, GUM_X86_RAX, offsetof(GumCpuContext, rbx), GUM_X86_RBX);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, rcx), GUM_REG_RCX); cw, GUM_X86_RAX, offsetof(GumCpuContext, rcx), GUM_X86_RCX);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, rdx), GUM_REG_RDX); cw, GUM_X86_RAX, offsetof(GumCpuContext, rdx), GUM_X86_RDX);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, rdi), GUM_REG_RDI); cw, GUM_X86_RAX, offsetof(GumCpuContext, rdi), GUM_X86_RDI);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, rsi), GUM_REG_RSI); cw, GUM_X86_RAX, offsetof(GumCpuContext, rsi), GUM_X86_RSI);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, rbp), GUM_REG_RBP); cw, GUM_X86_RAX, offsetof(GumCpuContext, rbp), GUM_X86_RBP);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, r8), GUM_REG_R8); cw, GUM_X86_RAX, offsetof(GumCpuContext, r8), GUM_X86_R8);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, r9), GUM_REG_R9); cw, GUM_X86_RAX, offsetof(GumCpuContext, r9), GUM_X86_R9);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, r10), GUM_REG_R10); cw, GUM_X86_RAX, offsetof(GumCpuContext, r10), GUM_X86_R10);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, r11), GUM_REG_R11); cw, GUM_X86_RAX, offsetof(GumCpuContext, r11), GUM_X86_R11);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, r12), GUM_REG_R12); cw, GUM_X86_RAX, offsetof(GumCpuContext, r12), GUM_X86_R12);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, r13), GUM_REG_R13); cw, GUM_X86_RAX, offsetof(GumCpuContext, r13), GUM_X86_R13);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, r14), GUM_REG_R14); cw, GUM_X86_RAX, offsetof(GumCpuContext, r14), GUM_X86_R14);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, r15), GUM_REG_R15); cw, GUM_X86_RAX, offsetof(GumCpuContext, r15), GUM_X86_R15);
/* Store RIP */ /* Store RIP */
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RBX, gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RBX,
GUM_ADDRESS(persistent_start)); GUM_ADDRESS(persistent_start));
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, rip), GUM_REG_RBX); cw, GUM_X86_RAX, offsetof(GumCpuContext, rip), GUM_X86_RBX);
/* Store adjusted RSP */ /* Store adjusted RSP */
gum_x86_writer_put_mov_reg_reg(cw, GUM_REG_RBX, GUM_REG_RSP); gum_x86_writer_put_mov_reg_reg(cw, GUM_X86_RBX, GUM_X86_RSP);
/* RED_ZONE + Saved flags, RAX, alignment */ /* RED_ZONE + Saved flags, RAX, alignment */
gum_x86_writer_put_add_reg_imm(cw, GUM_REG_RBX, gum_x86_writer_put_add_reg_imm(cw, GUM_X86_RBX,
GUM_RED_ZONE_SIZE + (0x8 * 2)); GUM_RED_ZONE_SIZE + (0x8 * 2));
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, rsp), GUM_REG_RBX); cw, GUM_X86_RAX, offsetof(GumCpuContext, rsp), GUM_X86_RBX);
/* Save the flags */ /* 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_reg_offset_ptr(cw, GUM_X86_RBX, GUM_X86_RSP, 0x8);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(persistent_ctx_t, rflags), GUM_REG_RBX); cw, GUM_X86_RAX, offsetof(persistent_ctx_t, rflags), GUM_X86_RBX);
/* Save the RAX */ /* 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_reg_offset_ptr(cw, GUM_X86_RBX, GUM_X86_RSP, 0x0);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_RAX, offsetof(GumCpuContext, rax), GUM_REG_RBX); cw, GUM_X86_RAX, offsetof(GumCpuContext, rax), GUM_X86_RBX);
/* Pop the saved values */ /* Pop the saved values */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 0x10); gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP, 0x10);
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP,
(GUM_RED_ZONE_SIZE)); (GUM_RED_ZONE_SIZE));
} }
static void instrument_persitent_restore_regs(GumX86Writer * cw, static void instrument_persitent_restore_regs(GumX86Writer *cw,
persistent_ctx_t *regs) { persistent_ctx_t *regs) {
GumAddress regs_address = GUM_ADDRESS(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_address(cw, GUM_X86_RAX, regs_address);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RCX, GUM_X86_RAX,
offsetof(GumCpuContext, rcx)); offsetof(GumCpuContext, rcx));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RDX, GUM_X86_RAX,
offsetof(GumCpuContext, rdx)); offsetof(GumCpuContext, rdx));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDI, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RDI, GUM_X86_RAX,
offsetof(GumCpuContext, rdi)); offsetof(GumCpuContext, rdi));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSI, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RSI, GUM_X86_RAX,
offsetof(GumCpuContext, rsi)); offsetof(GumCpuContext, rsi));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBP, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RBP, GUM_X86_RAX,
offsetof(GumCpuContext, rbp)); offsetof(GumCpuContext, rbp));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R8, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_R8, GUM_X86_RAX,
offsetof(GumCpuContext, r8)); offsetof(GumCpuContext, r8));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R9, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_R9, GUM_X86_RAX,
offsetof(GumCpuContext, r9)); offsetof(GumCpuContext, r9));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R10, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_R10, GUM_X86_RAX,
offsetof(GumCpuContext, r10)); offsetof(GumCpuContext, r10));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R11, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_R11, GUM_X86_RAX,
offsetof(GumCpuContext, r11)); offsetof(GumCpuContext, r11));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R12, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_R12, GUM_X86_RAX,
offsetof(GumCpuContext, r12)); offsetof(GumCpuContext, r12));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R13, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_R13, GUM_X86_RAX,
offsetof(GumCpuContext, r13)); offsetof(GumCpuContext, r13));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R14, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_R14, GUM_X86_RAX,
offsetof(GumCpuContext, r14)); offsetof(GumCpuContext, r14));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R15, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_R15, GUM_X86_RAX,
offsetof(GumCpuContext, r15)); offsetof(GumCpuContext, r15));
/* Don't restore RIP */ /* Don't restore RIP */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSP, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RSP, GUM_X86_RAX,
offsetof(GumCpuContext, rsp)); offsetof(GumCpuContext, rsp));
/* Restore RBX, RAX & Flags */ /* Restore RBX, RAX & Flags */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP,
-(GUM_RED_ZONE_SIZE)); -(GUM_RED_ZONE_SIZE));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RBX, GUM_X86_RAX,
offsetof(GumCpuContext, rbx)); offsetof(GumCpuContext, rbx));
gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); gum_x86_writer_put_push_reg(cw, GUM_X86_RBX);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RBX, GUM_X86_RAX,
offsetof(GumCpuContext, rax)); offsetof(GumCpuContext, rax));
gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); gum_x86_writer_put_push_reg(cw, GUM_X86_RBX);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RBX, GUM_X86_RAX,
offsetof(persistent_ctx_t, rflags)); offsetof(persistent_ctx_t, rflags));
gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); gum_x86_writer_put_push_reg(cw, GUM_X86_RBX);
gum_x86_writer_put_popfx(cw); gum_x86_writer_put_popfx(cw);
gum_x86_writer_put_pop_reg(cw, GUM_REG_RAX); gum_x86_writer_put_pop_reg(cw, GUM_X86_RAX);
gum_x86_writer_put_pop_reg(cw, GUM_REG_RBX); gum_x86_writer_put_pop_reg(cw, GUM_X86_RBX);
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP,
(GUM_RED_ZONE_SIZE)); (GUM_RED_ZONE_SIZE));
} }
static void instrument_exit(GumX86Writer *cw) { static void instrument_exit(GumX86Writer *cw) {
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, GUM_ADDRESS(_exit)); gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX, GUM_ADDRESS(_exit));
gum_x86_writer_put_mov_reg_u32(cw, GUM_REG_RDI, 0); gum_x86_writer_put_mov_reg_u32(cw, GUM_X86_RDI, 0);
gum_x86_writer_put_call_reg(cw, GUM_REG_RAX); gum_x86_writer_put_call_reg(cw, GUM_X86_RAX);
} }
@ -186,13 +186,13 @@ static int instrument_afl_persistent_loop_func(void) {
static void instrument_afl_persistent_loop(GumX86Writer *cw) { static void instrument_afl_persistent_loop(GumX86Writer *cw) {
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP,
-(GUM_RED_ZONE_SIZE)); -(GUM_RED_ZONE_SIZE));
gum_x86_writer_put_call_address_with_arguments( gum_x86_writer_put_call_address_with_arguments(
cw, GUM_CALL_CAPI, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0); cw, GUM_CALL_CAPI, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0);
gum_x86_writer_put_test_reg_reg(cw, GUM_REG_RAX, GUM_REG_RAX); gum_x86_writer_put_test_reg_reg(cw, GUM_X86_RAX, GUM_X86_RAX);
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP,
(GUM_RED_ZONE_SIZE)); (GUM_RED_ZONE_SIZE));
} }
@ -200,26 +200,26 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) {
static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) { static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) {
if (persistent_hook == NULL) return; if (persistent_hook == NULL) return;
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP,
-(GUM_RED_ZONE_SIZE)); -(GUM_RED_ZONE_SIZE));
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDX, gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RDX,
GUM_ADDRESS(&__afl_fuzz_len)); GUM_ADDRESS(&__afl_fuzz_len));
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_X86_RDX, GUM_X86_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_reg_offset_ptr(cw, GUM_X86_RDX, GUM_X86_RDX, 0);
gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_RDI, 0xffffffff); gum_x86_writer_put_mov_reg_u64(cw, GUM_X86_RDI, 0xffffffff);
gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RDX, GUM_REG_RDI); gum_x86_writer_put_and_reg_reg(cw, GUM_X86_RDX, GUM_X86_RDI);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RSI, gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RSI,
GUM_ADDRESS(&__afl_fuzz_ptr)); GUM_ADDRESS(&__afl_fuzz_ptr));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSI, GUM_REG_RSI, 0); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RSI, GUM_X86_RSI, 0);
gum_x86_writer_put_call_address_with_arguments( gum_x86_writer_put_call_address_with_arguments(
cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS, 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_ADDRESS(&regs->ctx), GUM_ARG_REGISTER, GUM_X86_RSI, GUM_ARG_REGISTER,
GUM_REG_RDX); GUM_X86_RDX);
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP,
(GUM_RED_ZONE_SIZE)); (GUM_RED_ZONE_SIZE));
} }
@ -228,23 +228,23 @@ static void instrument_persitent_save_ret(GumX86Writer *cw) {
/* Stack usage by this function */ /* Stack usage by this function */
gssize offset = GUM_RED_ZONE_SIZE + (3 * 8); gssize offset = GUM_RED_ZONE_SIZE + (3 * 8);
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP,
-(GUM_RED_ZONE_SIZE)); -(GUM_RED_ZONE_SIZE));
gum_x86_writer_put_pushfx(cw); gum_x86_writer_put_pushfx(cw);
gum_x86_writer_put_push_reg(cw, GUM_REG_RAX); gum_x86_writer_put_push_reg(cw, GUM_X86_RAX);
gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); gum_x86_writer_put_push_reg(cw, GUM_X86_RBX);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, GUM_ADDRESS(&saved_ret)); gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX, GUM_ADDRESS(&saved_ret));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RBX, GUM_X86_RSP,
offset); offset);
gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_REG_RAX, GUM_REG_RBX); gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_X86_RAX, GUM_X86_RBX);
gum_x86_writer_put_pop_reg(cw, GUM_REG_RBX); gum_x86_writer_put_pop_reg(cw, GUM_X86_RBX);
gum_x86_writer_put_pop_reg(cw, GUM_REG_RAX); gum_x86_writer_put_pop_reg(cw, GUM_X86_RAX);
gum_x86_writer_put_popfx(cw); gum_x86_writer_put_popfx(cw);
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP,
(GUM_RED_ZONE_SIZE)); (GUM_RED_ZONE_SIZE));
} }
@ -278,7 +278,7 @@ void persistent_prologue_arch(GumStalkerOutput *output) {
FVERBOSE("Persistent loop reached"); FVERBOSE("Persistent loop reached");
/* Pop the return value */ /* Pop the return value */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 8); gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP, 8);
instrument_persitent_save_regs(cw, &saved_regs); instrument_persitent_save_regs(cw, &saved_regs);
@ -326,13 +326,13 @@ void persistent_epilogue_arch(GumStalkerOutput *output) {
/* The stack should be aligned when we re-enter our loop */ /* The stack should be aligned when we re-enter our loop */
gconstpointer zero = cw->code + 1; gconstpointer zero = cw->code + 1;
gum_x86_writer_put_test_reg_u32(cw, GUM_REG_RSP, 0xF); gum_x86_writer_put_test_reg_u32(cw, GUM_X86_RSP, 0xF);
gum_x86_writer_put_jcc_near_label(cw, X86_INS_JE, zero, GUM_NO_HINT); gum_x86_writer_put_jcc_near_label(cw, X86_INS_JE, zero, GUM_NO_HINT);
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, -8); gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_RSP, GUM_X86_RSP, -8);
gum_x86_writer_put_label(cw, zero); gum_x86_writer_put_label(cw, zero);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, GUM_ADDRESS(&saved_ret)); gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX, GUM_ADDRESS(&saved_ret));
gum_x86_writer_put_jmp_reg_ptr(cw, GUM_REG_RAX); gum_x86_writer_put_jmp_reg_ptr(cw, GUM_X86_RAX);
} }

View File

@ -25,105 +25,105 @@ gboolean persistent_is_supported(void) {
} }
static void instrument_persitent_save_regs(GumX86Writer * cw, static void instrument_persitent_save_regs(GumX86Writer *cw,
persistent_ctx_t *regs) { persistent_ctx_t *regs) {
GumAddress regs_address = GUM_ADDRESS(regs); GumAddress regs_address = GUM_ADDRESS(regs);
/* Should be pushing FPU here, but meh */ /* Should be pushing FPU here, but meh */
gum_x86_writer_put_pushfx(cw); gum_x86_writer_put_pushfx(cw);
gum_x86_writer_put_push_reg(cw, GUM_REG_EAX); gum_x86_writer_put_push_reg(cw, GUM_X86_EAX);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, regs_address); gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, regs_address);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_EAX, offsetof(GumCpuContext, ebx), GUM_REG_EBX); cw, GUM_X86_EAX, offsetof(GumCpuContext, ebx), GUM_X86_EBX);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_EAX, offsetof(GumCpuContext, ecx), GUM_REG_ECX); cw, GUM_X86_EAX, offsetof(GumCpuContext, ecx), GUM_X86_ECX);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_EAX, offsetof(GumCpuContext, edx), GUM_REG_EDX); cw, GUM_X86_EAX, offsetof(GumCpuContext, edx), GUM_X86_EDX);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_EAX, offsetof(GumCpuContext, edi), GUM_REG_EDI); cw, GUM_X86_EAX, offsetof(GumCpuContext, edi), GUM_X86_EDI);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_EAX, offsetof(GumCpuContext, esi), GUM_REG_ESI); cw, GUM_X86_EAX, offsetof(GumCpuContext, esi), GUM_X86_ESI);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_EAX, offsetof(GumCpuContext, ebp), GUM_REG_EBP); cw, GUM_X86_EAX, offsetof(GumCpuContext, ebp), GUM_X86_EBP);
/* Store RIP */ /* Store RIP */
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EBX, gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EBX,
GUM_ADDRESS(persistent_start)); GUM_ADDRESS(persistent_start));
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_EAX, offsetof(GumCpuContext, eip), GUM_REG_EBX); cw, GUM_X86_EAX, offsetof(GumCpuContext, eip), GUM_X86_EBX);
/* Store adjusted RSP */ /* Store adjusted RSP */
gum_x86_writer_put_mov_reg_reg(cw, GUM_REG_EBX, GUM_REG_ESP); gum_x86_writer_put_mov_reg_reg(cw, GUM_X86_EBX, GUM_X86_ESP);
/* RED_ZONE + Saved flags, RAX */ /* RED_ZONE + Saved flags, RAX */
gum_x86_writer_put_add_reg_imm(cw, GUM_REG_EBX, (0x4 * 2)); gum_x86_writer_put_add_reg_imm(cw, GUM_X86_EBX, (0x4 * 2));
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_EAX, offsetof(GumCpuContext, esp), GUM_REG_EBX); cw, GUM_X86_EAX, offsetof(GumCpuContext, esp), GUM_X86_EBX);
/* Save the flags */ /* 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_reg_offset_ptr(cw, GUM_X86_EBX, GUM_X86_ESP, 0x4);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_EAX, offsetof(persistent_ctx_t, eflags), GUM_REG_EBX); cw, GUM_X86_EAX, offsetof(persistent_ctx_t, eflags), GUM_X86_EBX);
/* Save the RAX */ /* 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_reg_offset_ptr(cw, GUM_X86_EBX, GUM_X86_ESP, 0x0);
gum_x86_writer_put_mov_reg_offset_ptr_reg( gum_x86_writer_put_mov_reg_offset_ptr_reg(
cw, GUM_REG_EAX, offsetof(GumCpuContext, eax), GUM_REG_EBX); cw, GUM_X86_EAX, offsetof(GumCpuContext, eax), GUM_X86_EBX);
/* Pop the saved values */ /* Pop the saved values */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 0x8); gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_ESP, GUM_X86_ESP, 0x8);
} }
static void instrument_persitent_restore_regs(GumX86Writer * cw, static void instrument_persitent_restore_regs(GumX86Writer *cw,
persistent_ctx_t *regs) { persistent_ctx_t *regs) {
GumAddress regs_address = GUM_ADDRESS(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_address(cw, GUM_X86_EAX, regs_address);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ECX, GUM_REG_EAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_ECX, GUM_X86_EAX,
offsetof(GumCpuContext, ecx)); offsetof(GumCpuContext, ecx));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDX, GUM_REG_EAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EDX, GUM_X86_EAX,
offsetof(GumCpuContext, edx)); offsetof(GumCpuContext, edx));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDI, GUM_REG_EAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EDI, GUM_X86_EAX,
offsetof(GumCpuContext, edi)); offsetof(GumCpuContext, edi));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESI, GUM_REG_EAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_ESI, GUM_X86_EAX,
offsetof(GumCpuContext, esi)); offsetof(GumCpuContext, esi));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBP, GUM_REG_EAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EBP, GUM_X86_EAX,
offsetof(GumCpuContext, ebp)); offsetof(GumCpuContext, ebp));
/* Don't restore RIP */ /* Don't restore RIP */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESP, GUM_REG_EAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_ESP, GUM_X86_EAX,
offsetof(GumCpuContext, esp)); offsetof(GumCpuContext, esp));
/* Restore RBX, RAX & Flags */ /* Restore RBX, RAX & Flags */
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EBX, GUM_X86_EAX,
offsetof(GumCpuContext, ebx)); offsetof(GumCpuContext, ebx));
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); gum_x86_writer_put_push_reg(cw, GUM_X86_EBX);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EBX, GUM_X86_EAX,
offsetof(GumCpuContext, eax)); offsetof(GumCpuContext, eax));
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); gum_x86_writer_put_push_reg(cw, GUM_X86_EBX);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EBX, GUM_X86_EAX,
offsetof(persistent_ctx_t, eflags)); offsetof(persistent_ctx_t, eflags));
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); gum_x86_writer_put_push_reg(cw, GUM_X86_EBX);
gum_x86_writer_put_popfx(cw); gum_x86_writer_put_popfx(cw);
gum_x86_writer_put_pop_reg(cw, GUM_REG_EAX); gum_x86_writer_put_pop_reg(cw, GUM_X86_EAX);
gum_x86_writer_put_pop_reg(cw, GUM_REG_EBX); gum_x86_writer_put_pop_reg(cw, GUM_X86_EBX);
} }
static void instrument_exit(GumX86Writer *cw) { static void instrument_exit(GumX86Writer *cw) {
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, GUM_ADDRESS(_exit)); gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(_exit));
gum_x86_writer_put_mov_reg_u32(cw, GUM_REG_EDI, 0); gum_x86_writer_put_mov_reg_u32(cw, GUM_X86_EDI, 0);
gum_x86_writer_put_push_reg(cw, GUM_REG_EDI); gum_x86_writer_put_push_reg(cw, GUM_X86_EDI);
gum_x86_writer_put_call_reg(cw, GUM_REG_EAX); gum_x86_writer_put_call_reg(cw, GUM_X86_EAX);
} }
@ -145,7 +145,7 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) {
gum_x86_writer_put_call_address_with_arguments( gum_x86_writer_put_call_address_with_arguments(
cw, GUM_CALL_CAPI, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0); cw, GUM_CALL_CAPI, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0);
gum_x86_writer_put_test_reg_reg(cw, GUM_REG_EAX, GUM_REG_EAX); gum_x86_writer_put_test_reg_reg(cw, GUM_X86_EAX, GUM_X86_EAX);
} }
@ -153,20 +153,20 @@ static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) {
if (persistent_hook == NULL) return; if (persistent_hook == NULL) return;
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_ECX, gum_x86_writer_put_mov_reg_address(cw, GUM_X86_ECX,
GUM_ADDRESS(&__afl_fuzz_len)); GUM_ADDRESS(&__afl_fuzz_len));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ECX, GUM_REG_ECX, 0); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_ECX, GUM_X86_ECX, 0);
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ECX, GUM_REG_ECX, 0); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_ECX, GUM_X86_ECX, 0);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EDX, gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EDX,
GUM_ADDRESS(&__afl_fuzz_ptr)); GUM_ADDRESS(&__afl_fuzz_ptr));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDX, GUM_REG_EDX, 0); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EDX, GUM_X86_EDX, 0);
/* Base address is 64-bits (hence two zero arguments) */ /* Base address is 64-bits (hence two zero arguments) */
gum_x86_writer_put_call_address_with_arguments( gum_x86_writer_put_call_address_with_arguments(
cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS, 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_ADDRESS(&regs->ctx), GUM_ARG_REGISTER, GUM_X86_EDX, GUM_ARG_REGISTER,
GUM_REG_ECX); GUM_X86_ECX);
} }
@ -176,16 +176,16 @@ static void instrument_persitent_save_ret(GumX86Writer *cw) {
gssize offset = (3 * 4); gssize offset = (3 * 4);
gum_x86_writer_put_pushfx(cw); gum_x86_writer_put_pushfx(cw);
gum_x86_writer_put_push_reg(cw, GUM_REG_EAX); gum_x86_writer_put_push_reg(cw, GUM_X86_EAX);
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); gum_x86_writer_put_push_reg(cw, GUM_X86_EBX);
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, GUM_ADDRESS(&saved_ret)); gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(&saved_ret));
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EBX, GUM_X86_ESP,
offset); offset);
gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_REG_EAX, GUM_REG_EBX); gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_X86_EAX, GUM_X86_EBX);
gum_x86_writer_put_pop_reg(cw, GUM_REG_EBX); gum_x86_writer_put_pop_reg(cw, GUM_X86_EBX);
gum_x86_writer_put_pop_reg(cw, GUM_REG_EAX); gum_x86_writer_put_pop_reg(cw, GUM_X86_EAX);
gum_x86_writer_put_popfx(cw); gum_x86_writer_put_popfx(cw);
} }
@ -219,7 +219,7 @@ void persistent_prologue_arch(GumStalkerOutput *output) {
FVERBOSE("Persistent loop reached"); FVERBOSE("Persistent loop reached");
/* Pop the return value */ /* Pop the return value */
gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 4); gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_ESP, GUM_X86_ESP, 4);
instrument_persitent_save_regs(cw, &saved_regs); instrument_persitent_save_regs(cw, &saved_regs);
@ -263,8 +263,8 @@ void persistent_epilogue_arch(GumStalkerOutput *output) {
if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); }
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, GUM_ADDRESS(&saved_ret)); gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(&saved_ret));
gum_x86_writer_put_jmp_reg_ptr(cw, GUM_REG_EAX); gum_x86_writer_put_jmp_reg_ptr(cw, GUM_X86_EAX);
} }

View File

@ -1,12 +1,11 @@
#include <errno.h> #include <errno.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include "frida-gumjs.h" #include "frida-gumjs.h"
#include "entry.h" #include "entry.h"
#include "intercept.h" #include "intercept.h"
#include "prefetch.h" #include "prefetch.h"
#include "shm.h"
#include "stalker.h" #include "stalker.h"
#include "util.h" #include "util.h"
@ -19,7 +18,7 @@
typedef struct { typedef struct {
size_t count; size_t count;
void * entry[PREFETCH_ENTRIES]; void *entry[PREFETCH_ENTRIES];
guint8 backpatch_data[BP_SIZE]; guint8 backpatch_data[BP_SIZE];
gsize backpatch_size; gsize backpatch_size;
@ -173,7 +172,7 @@ static void prefetch_read_blocks(void) {
static void prefetch_read_patches(void) { static void prefetch_read_patches(void) {
gsize offset = 0; gsize offset = 0;
GumStalker * stalker = stalker_get(); GumStalker *stalker = stalker_get();
GumBackpatch *backpatch = NULL; GumBackpatch *backpatch = NULL;
for (gsize remaining = prefetch_data->backpatch_size - offset; for (gsize remaining = prefetch_data->backpatch_size - offset;
@ -285,28 +284,7 @@ void prefetch_init(void) {
* with the coverage bitmap region and fork will take care of ensuring both * with the coverage bitmap region and fork will take care of ensuring both
* the parent and child see the same consistent memory region. * the parent and child see the same consistent memory region.
*/ */
prefetch_shm_id = prefetch_data = shm_create(sizeof(prefetch_data_t));
shmget(IPC_PRIVATE, sizeof(prefetch_data_t), IPC_CREAT | IPC_EXCL | 0600);
if (prefetch_shm_id < 0) {
FFATAL("prefetch_shm_id < 0 - errno: %d\n", errno);
}
prefetch_data = shmat(prefetch_shm_id, NULL, 0);
g_assert(prefetch_data != MAP_FAILED);
/*
* Configure the shared memory region to be removed once the process dies.
*/
if (shmctl(prefetch_shm_id, IPC_RMID, NULL) < 0) {
FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
}
/* Clear it, not sure it's necessary, just seems like good practice */
memset(prefetch_data, '\0', sizeof(prefetch_data_t));
prefetch_hook_fork(); prefetch_hook_fork();
@ -319,7 +297,7 @@ void prefetch_init(void) {
if (!prefetch_backpatch) { return; } if (!prefetch_backpatch) { return; }
GumStalkerObserver * observer = stalker_get_observer(); GumStalkerObserver *observer = stalker_get_observer();
GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer); GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer);
iface->notify_backpatch = gum_afl_stalker_backpatcher_notify; iface->notify_backpatch = gum_afl_stalker_backpatcher_notify;

View File

@ -9,7 +9,7 @@
typedef struct { typedef struct {
gchar * suffix; gchar *suffix;
GumMemoryRange *range; GumMemoryRange *range;
gboolean done; gboolean done;
@ -135,7 +135,7 @@ static gboolean convert_name_token_for_module(const GumModuleDetails *details,
static void convert_name_token(gchar *token, GumMemoryRange *range) { static void convert_name_token(gchar *token, GumMemoryRange *range) {
gchar * suffix = g_strconcat("/", token, NULL); gchar *suffix = g_strconcat("/", token, NULL);
convert_name_ctx_t ctx = {.suffix = suffix, .range = range, .done = false}; convert_name_ctx_t ctx = {.suffix = suffix, .range = range, .done = false};
gum_process_enumerate_modules(convert_name_token_for_module, &ctx); gum_process_enumerate_modules(convert_name_token_for_module, &ctx);
@ -235,7 +235,7 @@ static void print_ranges(char *key, GArray *ranges) {
static gboolean collect_module_ranges_callback(const GumRangeDetails *details, static gboolean collect_module_ranges_callback(const GumRangeDetails *details,
gpointer user_data) { gpointer user_data) {
GArray * ranges = (GArray *)user_data; GArray *ranges = (GArray *)user_data;
GumMemoryRange range = *details->range; GumMemoryRange range = *details->range;
g_array_append_val(ranges, range); g_array_append_val(ranges, range);
return TRUE; return TRUE;
@ -292,12 +292,12 @@ void ranges_add_exclude(GumMemoryRange *range) {
static GArray *collect_ranges(char *env_key) { static GArray *collect_ranges(char *env_key) {
char * env_val; char *env_val;
gchar ** tokens; gchar **tokens;
int token_count; int token_count;
GumMemoryRange range; GumMemoryRange range;
int i; int i;
GArray * result; GArray *result;
result = g_array_new(false, false, sizeof(GumMemoryRange)); result = g_array_new(false, false, sizeof(GumMemoryRange));
@ -330,7 +330,7 @@ static GArray *collect_ranges(char *env_key) {
static GArray *collect_libs_ranges(void) { static GArray *collect_libs_ranges(void) {
GArray * result; GArray *result;
GumMemoryRange range; GumMemoryRange range;
result = g_array_new(false, false, sizeof(GumMemoryRange)); result = g_array_new(false, false, sizeof(GumMemoryRange));
@ -422,7 +422,7 @@ static gboolean intersect_range(GumMemoryRange *rr, GumMemoryRange *ra,
static GArray *intersect_ranges(GArray *a, GArray *b) { static GArray *intersect_ranges(GArray *a, GArray *b) {
GArray * result; GArray *result;
GumMemoryRange *ra; GumMemoryRange *ra;
GumMemoryRange *rb; GumMemoryRange *rb;
GumMemoryRange ri; GumMemoryRange ri;
@ -452,7 +452,7 @@ static GArray *intersect_ranges(GArray *a, GArray *b) {
static GArray *subtract_ranges(GArray *a, GArray *b) { static GArray *subtract_ranges(GArray *a, GArray *b) {
GArray * result; GArray *result;
GumMemoryRange *ra; GumMemoryRange *ra;
GumAddress ral; GumAddress ral;
GumMemoryRange *rb; GumMemoryRange *rb;
@ -528,7 +528,7 @@ static GArray *subtract_ranges(GArray *a, GArray *b) {
static GArray *merge_ranges(GArray *a) { static GArray *merge_ranges(GArray *a) {
GArray * result; GArray *result;
GumMemoryRange rp; GumMemoryRange rp;
GumMemoryRange *r; GumMemoryRange *r;
@ -585,11 +585,11 @@ void ranges_config(void) {
void ranges_init(void) { void ranges_init(void) {
GumMemoryRange ri; GumMemoryRange ri;
GArray * step1; GArray *step1;
GArray * step2; GArray *step2;
GArray * step3; GArray *step3;
GArray * step4; GArray *step4;
GArray * step5; GArray *step5;
FOKF(cBLU "Ranges" cRST " - " cGRN "instrument jit:" cYEL " [%c]", FOKF(cBLU "Ranges" cRST " - " cGRN "instrument jit:" cYEL " [%c]",
ranges_inst_jit ? 'X' : ' '); ranges_inst_jit ? 'X' : ' ');
@ -669,7 +669,7 @@ gboolean range_is_excluded(GumAddress address) {
void ranges_exclude() { void ranges_exclude() {
GumMemoryRange *r; GumMemoryRange *r;
GumStalker * stalker = stalker_get(); GumStalker *stalker = stalker_get();
FVERBOSE("Excluding ranges"); FVERBOSE("Excluding ranges");

View File

@ -11,6 +11,8 @@ void seccomp_on_fork(void) {
#ifdef __APPLE__ #ifdef __APPLE__
FFATAL("Seccomp not supported on OSX"); FFATAL("Seccomp not supported on OSX");
#elif defined(__ANDROID__)
FFATAL("Seccomp not supported on Android");
#else #else
seccomp_callback_parent(); seccomp_callback_parent();
#endif #endif
@ -32,6 +34,8 @@ void seccomp_init(void) {
#ifdef __APPLE__ #ifdef __APPLE__
FFATAL("Seccomp not supported on OSX"); FFATAL("Seccomp not supported on OSX");
#elif defined(__ANDROID__)
FFATAL("Seccomp not supported on Android");
#else #else
seccomp_callback_initialize(); seccomp_callback_initialize();
#endif #endif

View File

@ -8,9 +8,9 @@
#include "seccomp.h" #include "seccomp.h"
#include "util.h" #include "util.h"
static void seccomp_callback_filter(struct seccomp_notif * req, static void seccomp_callback_filter(struct seccomp_notif *req,
struct seccomp_notif_resp *resp, struct seccomp_notif_resp *resp,
GumReturnAddressArray * frames) { GumReturnAddressArray *frames) {
GumDebugSymbolDetails details = {0}; GumDebugSymbolDetails details = {0};
if (req->data.nr == SYS_OPENAT) { if (req->data.nr == SYS_OPENAT) {
@ -54,7 +54,7 @@ static void seccomp_callback_filter(struct seccomp_notif * req,
free(syms); free(syms);
#else #else
void **syms = (void **)__builtin_frame_address(0); void **syms = (void **)__builtin_frame_address(0);
void * framep = __builtin_frame_address(1); void *framep = __builtin_frame_address(1);
int i = 0; int i = 0;
syms = framep; syms = framep;

View File

@ -21,7 +21,7 @@ typedef struct {
seccomp_child_func_t func; seccomp_child_func_t func;
int event_fd; int event_fd;
void * ctx; void *ctx;
} seccomp_child_func_ctx_t; } seccomp_child_func_ctx_t;

View File

@ -129,7 +129,7 @@ static volatile bool seccomp_filter_child_done = false;
static pid_t seccomp_filter_child = -1; static pid_t seccomp_filter_child = -1;
static GumCpuContext seccomp_filter_cpu_context = {0}; static GumCpuContext seccomp_filter_cpu_context = {0};
static GumReturnAddressArray seccomp_filter_frames = {.len = 0, .items = {0}}; static GumReturnAddressArray seccomp_filter_frames = {.len = 0, .items = {0}};
static GumBacktracer * seccomp_filter_backtracer = NULL; static GumBacktracer *seccomp_filter_backtracer = NULL;
static void seccomp_filter_child_handler(int sig, siginfo_t *info, static void seccomp_filter_child_handler(int sig, siginfo_t *info,
void *ucontext) { void *ucontext) {
@ -209,7 +209,7 @@ int seccomp_filter_install(pid_t child) {
void seccomp_filter_run(int fd, seccomp_filter_callback_t callback) { void seccomp_filter_run(int fd, seccomp_filter_callback_t callback) {
struct seccomp_notif * req = NULL; struct seccomp_notif *req = NULL;
struct seccomp_notif_resp *resp = NULL; struct seccomp_notif_resp *resp = NULL;
struct seccomp_notif_sizes sizes; struct seccomp_notif_sizes sizes;

View File

@ -59,9 +59,9 @@ void seccomp_socket_send(int sockfd, int fd) {
struct iovec iov = {.iov_base = &data, .iov_len = sizeof(data)}; struct iovec iov = {.iov_base = &data, .iov_len = sizeof(data)};
union cmsg control_msg = {.hdr = { union cmsg control_msg = {.hdr = {
.cmsg_len = CMSG_LEN(sizeof(int)), .cmsg_len = CMSG_LEN(sizeof(int)),
.cmsg_level = SOL_SOCKET, .cmsg_level = SOL_SOCKET,
.cmsg_type = SCM_RIGHTS, .cmsg_type = SCM_RIGHTS,
}}; }};

87
frida_mode/src/shm.c Normal file
View File

@ -0,0 +1,87 @@
#include "shm.h"
#include "util.h"
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/mman.h>
#include <sys/shm.h>
#ifdef __ANDROID__
#include <linux/ashmem.h>
#include <sys/ioctl.h>
#endif
#ifdef __ANDROID__
#define ASHMEM_DEVICE "/dev/ashmem"
void *shm_create(size_t size) {
int fd = -1;
char ourkey[11] = {0};
void *addr = MAP_FAILED;
struct ashmem_pin pin = {0, size};
fd = open(ASHMEM_DEVICE, O_RDWR);
if (fd < 0) { FFATAL("Failed open /dev/ashmem: %d", errno); }
if (snprintf(ourkey, sizeof(ourkey) - 1, "%d", IPC_PRIVATE) < 0) {
FFATAL("Failed to generate key: %d", errno);
}
if (ioctl(fd, ASHMEM_SET_NAME, ourkey) < 0) {
FFATAL("ioctl(ASHMEM_SET_NAME) errno: %d\n", errno);
}
if (ioctl(fd, ASHMEM_SET_SIZE, size) < 0) {
FFATAL("ioctl(ASHMEM_SET_SIZE) errno: %d\n", errno);
}
addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) { FFATAL("mmap failed: %d\n", errno); }
/* Shared memory pinning has been deprecated. So if the ioctl fails, then
just assume we are running on a version where it has been. Worst case, we
will leak the shared memory region.*/
ioctl(fd, ASHMEM_UNPIN, &pin);
close(fd);
return addr;
}
#else
void *shm_create(size_t size) {
int shm_id =
shmget(IPC_PRIVATE, size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
if (shm_id < 0) { FFATAL("shm_id < 0 - errno: %d\n", errno); }
void *addr = shmat(shm_id, NULL, 0);
if (addr == MAP_FAILED) { FFATAL("addr == MAP_FAILED - errno: %d\n", errno); }
/*
* Configure the shared memory region to be removed once the process
* dies.
*/
if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
}
/* Clear it, not sure it's necessary, just seems like good practice */
memset(addr, '\0', size);
return addr;
}
#endif

View File

@ -74,7 +74,7 @@ static gboolean stalker_exclude_self(const GumRangeDetails *details,
gpointer user_data) { gpointer user_data) {
UNUSED_PARAMETER(user_data); UNUSED_PARAMETER(user_data);
gchar * name; gchar *name;
gboolean found; gboolean found;
GumStalker *stalker; GumStalker *stalker;
if (details->file == NULL) { return TRUE; } if (details->file == NULL) { return TRUE; }

View File

@ -2,21 +2,20 @@
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <sys/shm.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "frida-gumjs.h" #include "frida-gumjs.h"
#include "config.h" #include "config.h"
#include "util.h"
#include "entry.h" #include "entry.h"
#include "shm.h"
#include "stalker.h" #include "stalker.h"
#include "stats.h" #include "stats.h"
#include "util.h"
#define MICRO_TO_SEC 1000000 #define MICRO_TO_SEC 1000000
char * stats_filename = NULL; char *stats_filename = NULL;
guint64 stats_interval = 0; guint64 stats_interval = 0;
static guint64 stats_interval_us = 0; static guint64 stats_interval_us = 0;
static int stats_fd = -1; static int stats_fd = -1;
@ -41,8 +40,8 @@ void stats_write(void) {
stats_data->curr.stats_time = current_time; stats_data->curr.stats_time = current_time;
GDateTime *date_time = g_date_time_new_now_local(); GDateTime *date_time = g_date_time_new_now_local();
char * date_string = g_date_time_format(date_time, "%Y-%m-%d"); char *date_string = g_date_time_format(date_time, "%Y-%m-%d");
char * time_string = g_date_time_format(date_time, "%H:%M:%S"); char *time_string = g_date_time_format(date_time, "%H:%M:%S");
guint elapsed = (stats_data->curr.stats_time - stats_data->prev.stats_time) / guint elapsed = (stats_data->curr.stats_time - stats_data->prev.stats_time) /
MICRO_TO_SEC; MICRO_TO_SEC;
@ -360,27 +359,10 @@ void stats_init(void) {
g_free(path); g_free(path);
int shm_id =
shmget(IPC_PRIVATE, sizeof(stats_data_t), IPC_CREAT | IPC_EXCL | 0600);
if (shm_id < 0) { FFATAL("shm_id < 0 - errno: %d\n", errno); }
stats_data = shmat(shm_id, NULL, 0);
g_assert(stats_data != MAP_FAILED);
GumStalkerObserver *observer = stalker_get_observer(); GumStalkerObserver *observer = stalker_get_observer();
stats_observer_init(observer); stats_observer_init(observer);
/* stats_data = shm_create(sizeof(stats_data_t));
* Configure the shared memory region to be removed once the process dies.
*/
if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
}
/* Clear it, not sure it's necessary, just seems like good practice */
memset(stats_data, '\0', sizeof(stats_data_t));
starts_arch_init(); starts_arch_init();

View File

@ -1,9 +1,9 @@
#include <sys/shm.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "frida-gumjs.h" #include "frida-gumjs.h"
#include "ranges.h" #include "ranges.h"
#include "shm.h"
#include "stats.h" #include "stats.h"
#include "util.h" #include "util.h"
@ -44,24 +44,7 @@ static stats_data_arch_t *stats_data_arch = NULL;
void starts_arch_init(void) { void starts_arch_init(void) {
int shm_id = shmget(IPC_PRIVATE, sizeof(stats_data_arch_t), stats_data_arch = shm_create(sizeof(stats_data_arch_t));
IPC_CREAT | IPC_EXCL | 0600);
if (shm_id < 0) { FFATAL("shm_id < 0 - errno: %d\n", errno); }
stats_data_arch = shmat(shm_id, NULL, 0);
g_assert(stats_data_arch != MAP_FAILED);
/*
* Configure the shared memory region to be removed once the process dies.
*/
if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
}
/* Clear it, not sure it's necessary, just seems like good practice */
memset(stats_data_arch, '\0', sizeof(stats_data_arch_t));
} }

View File

@ -1,9 +1,9 @@
#include <sys/shm.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "frida-gumjs.h" #include "frida-gumjs.h"
#include "ranges.h" #include "ranges.h"
#include "shm.h"
#include "stats.h" #include "stats.h"
#include "util.h" #include "util.h"
@ -46,24 +46,7 @@ static stats_data_arch_t *stats_data_arch = NULL;
void starts_arch_init(void) { void starts_arch_init(void) {
int shm_id = shmget(IPC_PRIVATE, sizeof(stats_data_arch_t), stats_data_arch = shm_create(sizeof(stats_data_arch_t));
IPC_CREAT | IPC_EXCL | 0600);
if (shm_id < 0) { FFATAL("shm_id < 0 - errno: %d\n", errno); }
stats_data_arch = shmat(shm_id, NULL, 0);
g_assert(stats_data_arch != MAP_FAILED);
/*
* Configure the shared memory region to be removed once the process dies.
*/
if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
}
/* Clear it, not sure it's necessary, just seems like good practice */
memset(stats_data_arch, '\0', sizeof(stats_data_arch_t));
} }
@ -248,7 +231,7 @@ void stats_write_arch(stats_data_t *data) {
static x86_op_type stats_get_operand_type(const cs_insn *instr) { static x86_op_type stats_get_operand_type(const cs_insn *instr) {
cs_x86 * x86 = &instr->detail->x86; cs_x86 *x86 = &instr->detail->x86;
cs_x86_op *operand; cs_x86_op *operand;
if (x86->op_count != 1) { if (x86->op_count != 1) {
@ -266,7 +249,7 @@ static x86_op_type stats_get_operand_type(const cs_insn *instr) {
static void stats_collect_call_imm_excluded_arch(const cs_insn *instr) { static void stats_collect_call_imm_excluded_arch(const cs_insn *instr) {
cs_x86 * x86 = &instr->detail->x86; cs_x86 *x86 = &instr->detail->x86;
cs_x86_op *operand = &x86->operands[0]; cs_x86_op *operand = &x86->operands[0];
if (range_is_excluded(GUM_ADDRESS(operand->imm))) { if (range_is_excluded(GUM_ADDRESS(operand->imm))) {

View File

@ -2,10 +2,17 @@ PWD:=$(shell pwd)/
ROOT:=$(PWD)../../../ ROOT:=$(PWD)../../../
BUILD_DIR:=$(PWD)build/ BUILD_DIR:=$(PWD)build/
LIBZ_BUILD_DIR:=$(BUILD_DIR)libz/
LIBPNG_BUILD_DIR:=$(BUILD_DIR)libpng/ LIBPNG_BUILD_DIR:=$(BUILD_DIR)libpng/
HARNESS_BUILD_DIR:=$(BUILD_DIR)harness/ HARNESS_BUILD_DIR:=$(BUILD_DIR)harness/
PNGTEST_BUILD_DIR:=$(BUILD_DIR)pngtest/ PNGTEST_BUILD_DIR:=$(BUILD_DIR)pngtest/
LIBZ_FILE:=$(LIBZ_BUILD_DIR)zlib-1.2.12.tar.gz
LIBZ_URL:=http://www.zlib.net/zlib-1.2.12.tar.gz
LIBZ_DIR:=$(LIBZ_BUILD_DIR)zlib-1.2.12/
LIBZ_PC:=$(ZLIB_DIR)zlib.pc
LIBZ_LIB:=$(LIBZ_DIR)libz.a
LIBPNG_FILE:=$(LIBPNG_BUILD_DIR)libpng-1.2.56.tar.gz LIBPNG_FILE:=$(LIBPNG_BUILD_DIR)libpng-1.2.56.tar.gz
LIBPNG_URL:=https://downloads.sourceforge.net/project/libpng/libpng12/older-releases/1.2.56/libpng-1.2.56.tar.gz LIBPNG_URL:=https://downloads.sourceforge.net/project/libpng/libpng12/older-releases/1.2.56/libpng-1.2.56.tar.gz
LIBPNG_DIR:=$(LIBPNG_BUILD_DIR)libpng-1.2.56/ LIBPNG_DIR:=$(LIBPNG_BUILD_DIR)libpng-1.2.56/
@ -32,11 +39,16 @@ FRIDA_OUT:=$(BUILD_DIR)frida-out
.PHONY: all clean qemu frida .PHONY: all clean qemu frida
ARCH?=""
all: $(TEST_BIN) all: $(TEST_BIN)
make -C $(ROOT)frida_mode/ make -C $(ROOT)frida_mode/
32: 32:
CFLAGS="-m32" LDFLAGS="-m32" ARCH="x86" make all CFLAGS="-m32" LDFLAGS="-m32" make $(TEST_BIN)
arm:
ARCH="arm" CC="arm-linux-gnueabihf-gcc" CXX="arm-linux-gnueabihf-g++" make $(TEST_BIN)
$(BUILD_DIR): $(BUILD_DIR):
mkdir -p $@ mkdir -p $@
@ -51,6 +63,8 @@ $(HARNESS_FILE): | $(HARNESS_BUILD_DIR)
$(HARNESS_OBJ): $(HARNESS_FILE) $(HARNESS_OBJ): $(HARNESS_FILE)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -c $< $(CC) $(CFLAGS) $(LDFLAGS) -o $@ -c $<
harness: $(HARNESS_OBJ)
######### PNGTEST ######## ######### PNGTEST ########
$(PNGTEST_BUILD_DIR): | $(BUILD_DIR) $(PNGTEST_BUILD_DIR): | $(BUILD_DIR)
@ -62,6 +76,34 @@ $(PNGTEST_FILE): | $(PNGTEST_BUILD_DIR)
$(PNGTEST_OBJ): $(PNGTEST_FILE) | $(LIBPNG_DIR) $(PNGTEST_OBJ): $(PNGTEST_FILE) | $(LIBPNG_DIR)
$(CXX) $(CFLAGS) $(LDFLAGS) -std=c++11 -I $(LIBPNG_DIR) -o $@ -c $< $(CXX) $(CFLAGS) $(LDFLAGS) -std=c++11 -I $(LIBPNG_DIR) -o $@ -c $<
pngtest: $(PNGTEST_OBJ)
######### LIBZ ########
$(LIBZ_BUILD_DIR): | $(BUILD_DIR)
mkdir -p $@
$(LIBZ_FILE): | $(LIBZ_BUILD_DIR)
wget -O $@ $(LIBZ_URL)
$(LIBZ_DIR): $(LIBZ_FILE)
tar zxvf $(LIBZ_FILE) -C $(LIBZ_BUILD_DIR)
$(LIBZ_PC): | $(LIBZ_DIR)
cd $(LIBZ_DIR) && \
CFLAGS="$(CFLAGS) -fPIC" \
./configure \
--static \
--archs="$(ARCH)"
$(LIBZ_LIB): $(LIBZ_PC)
CFLAGS="$(CFLAGS) -fPIC" \
make \
-C $(LIBZ_DIR) \
-j
libz: $(LIBZ_LIB)
######### LIBPNG ######## ######### LIBPNG ########
$(LIBPNG_BUILD_DIR): | $(BUILD_DIR) $(LIBPNG_BUILD_DIR): | $(BUILD_DIR)
@ -73,11 +115,21 @@ $(LIBPNG_FILE): | $(LIBPNG_BUILD_DIR)
$(LIBPNG_DIR): $(LIBPNG_FILE) $(LIBPNG_DIR): $(LIBPNG_FILE)
tar zxvf $(LIBPNG_FILE) -C $(LIBPNG_BUILD_DIR) tar zxvf $(LIBPNG_FILE) -C $(LIBPNG_BUILD_DIR)
$(LIBPNG_MAKEFILE): | $(LIBPNG_DIR) $(LIBPNG_MAKEFILE): $(LIBZ_LIB) | $(LIBPNG_DIR)
cd $(LIBPNG_DIR) && ./configure cd $(LIBPNG_DIR) && \
CFLAGS="$(CFLAGS) -I$(LIBZ_DIR)" \
LDFLAGS="-L$(LIBZ_DIR)" \
./configure \
--host="$(ARCH)"
$(LIBPNG_LIB): $(LIBPNG_MAKEFILE) $(LIBPNG_LIB): $(LIBPNG_MAKEFILE)
make -C $(LIBPNG_DIR) CFLAGS="$(CFLAGS) -I$(LIBZ_DIR)" \
LDFLAGS="-L$(LIBZ_DIR)" \
make \
-C $(LIBPNG_DIR) \
-j
png: $(LIBPNG_LIB)
######### TEST ######## ######### TEST ########
@ -86,11 +138,21 @@ $(TEST_BIN): $(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB)
$(CFLAGS) \ $(CFLAGS) \
$(LDFLAGS) \ $(LDFLAGS) \
-o $@ \ -o $@ \
$(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB) \ $(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB) $(LIBZ_LIB) \
-lz \
$(TEST_BIN_LDFLAGS) \ $(TEST_BIN_LDFLAGS) \
test_bin: $(TEST_BIN)
dowload: $(LIBZ_FILE) $(LIBPNG_FILE) $(HARNESS_FILE) $(PNGTEST_FILE)
clean: clean:
rm -rf $(LIBZ_DIR)
rm -rf $(LIBPNG_DIR)
rm -f $(HARNESS_OBJ)
rm -f $(PNGTEST_OBJ)
rm -f $(TEST_BIN)
clean_all:
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)
qemu: $(TEST_BIN) qemu: $(TEST_BIN)

View File

@ -4,7 +4,7 @@ BUILD_DIR:=$(PWD)build/
UNSTABLE_DATA_DIR:=$(BUILD_DIR)in/ UNSTABLE_DATA_DIR:=$(BUILD_DIR)in/
UNSTABLE_DATA_FILE:=$(UNSTABLE_DATA_DIR)in UNSTABLE_DATA_FILE:=$(UNSTABLE_DATA_DIR)in
UNSTABLE_BIN:=$(BUILD_DIR)unstable TEST_BIN:=$(BUILD_DIR)unstable
UNSTABLE_SRC:=$(PWD)unstable.c UNSTABLE_SRC:=$(PWD)unstable.c
QEMU_OUT:=$(BUILD_DIR)qemu-out QEMU_OUT:=$(BUILD_DIR)qemu-out
@ -42,7 +42,7 @@ endif
.PHONY: all 32 clean qemu frida .PHONY: all 32 clean qemu frida
all: $(UNSTABLE_BIN) all: $(TEST_BIN)
make -C $(ROOT)frida_mode/ make -C $(ROOT)frida_mode/
32: 32:
@ -57,14 +57,14 @@ $(UNSTABLE_DATA_DIR): | $(BUILD_DIR)
$(UNSTABLE_DATA_FILE): | $(UNSTABLE_DATA_DIR) $(UNSTABLE_DATA_FILE): | $(UNSTABLE_DATA_DIR)
echo -n "000" > $@ echo -n "000" > $@
$(UNSTABLE_BIN): $(UNSTABLE_SRC) | $(BUILD_DIR) $(TEST_BIN): $(UNSTABLE_SRC) | $(BUILD_DIR)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
clean: clean:
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)
qemu: $(UNSTABLE_BIN) $(UNSTABLE_DATA_FILE) qemu: $(TEST_BIN) $(UNSTABLE_DATA_FILE)
AFL_QEMU_PERSISTENT_ADDR=$(AFL_QEMU_PERSISTENT_ADDR) \ AFL_QEMU_PERSISTENT_ADDR=$(AFL_QEMU_PERSISTENT_ADDR) \
$(ROOT)afl-fuzz \ $(ROOT)afl-fuzz \
-D \ -D \
@ -72,9 +72,9 @@ qemu: $(UNSTABLE_BIN) $(UNSTABLE_DATA_FILE)
-i $(UNSTABLE_DATA_DIR) \ -i $(UNSTABLE_DATA_DIR) \
-o $(QEMU_OUT) \ -o $(QEMU_OUT) \
-- \ -- \
$(UNSTABLE_BIN) @@ $(TEST_BIN) @@
frida: $(UNSTABLE_BIN) $(UNSTABLE_DATA_FILE) frida: $(TEST_BIN) $(UNSTABLE_DATA_FILE)
AFL_DEBUG=1 \ AFL_DEBUG=1 \
AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \
AFL_FRIDA_INST_TRACE_UNIQUE=1 \ AFL_FRIDA_INST_TRACE_UNIQUE=1 \
@ -85,9 +85,9 @@ frida: $(UNSTABLE_BIN) $(UNSTABLE_DATA_FILE)
-i $(UNSTABLE_DATA_DIR) \ -i $(UNSTABLE_DATA_DIR) \
-o $(FRIDA_OUT) \ -o $(FRIDA_OUT) \
-- \ -- \
$(UNSTABLE_BIN) @@ $(TEST_BIN) @@
frida_coverage: $(UNSTABLE_BIN) $(UNSTABLE_DATA_FILE) frida_coverage: $(TEST_BIN) $(UNSTABLE_DATA_FILE)
AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \
AFL_FRIDA_OUTPUT_STDOUT=/tmp/stdout.txt \ AFL_FRIDA_OUTPUT_STDOUT=/tmp/stdout.txt \
AFL_FRIDA_OUTPUT_STDERR=/tmp/stderr.txt \ AFL_FRIDA_OUTPUT_STDERR=/tmp/stderr.txt \
@ -98,9 +98,9 @@ frida_coverage: $(UNSTABLE_BIN) $(UNSTABLE_DATA_FILE)
-i $(UNSTABLE_DATA_DIR) \ -i $(UNSTABLE_DATA_DIR) \
-o $(FRIDA_OUT) \ -o $(FRIDA_OUT) \
-- \ -- \
$(UNSTABLE_BIN) @@ $(TEST_BIN) @@
frida_unstable: $(UNSTABLE_BIN) $(UNSTABLE_DATA_FILE) frida_unstable: $(TEST_BIN) $(UNSTABLE_DATA_FILE)
AFL_DEBUG=1 \ AFL_DEBUG=1 \
AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \ AFL_FRIDA_PERSISTENT_ADDR=$(AFL_FRIDA_PERSISTENT_ADDR) \
AFL_FRIDA_OUTPUT_STDOUT=/tmp/stdout.txt \ AFL_FRIDA_OUTPUT_STDOUT=/tmp/stdout.txt \
@ -112,10 +112,10 @@ frida_unstable: $(UNSTABLE_BIN) $(UNSTABLE_DATA_FILE)
-i $(UNSTABLE_DATA_DIR) \ -i $(UNSTABLE_DATA_DIR) \
-o $(FRIDA_OUT) \ -o $(FRIDA_OUT) \
-- \ -- \
$(UNSTABLE_BIN) @@ $(TEST_BIN) @@
debug: debug:
gdb \ gdb \
--ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \ --ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \
--ex 'set disassembly-flavor intel' \ --ex 'set disassembly-flavor intel' \
--args $(UNSTABLE_BIN) $(UNSTABLE_DATA_FILE) --args $(TEST_BIN) $(UNSTABLE_DATA_FILE)

View File

@ -14,6 +14,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/time.h>
#ifdef __APPLE__ #ifdef __APPLE__
#define TESTINSTR_SECTION #define TESTINSTR_SECTION
@ -25,8 +26,10 @@ void LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size < 1) return; if (size < 1) return;
int r = rand(); struct timeval tv = {0};
if ((r % 2) == 0) { if (gettimeofday(&tv, NULL) < 0) return;
if ((tv.tv_usec % 2) == 0) {
printf ("Hooray all even\n"); printf ("Hooray all even\n");
} else { } else {
printf ("Hmm that's odd\n"); printf ("Hmm that's odd\n");

View File

@ -125,6 +125,13 @@ class Afl {
Afl.jsApiSetInstrumentCacheSize(size); Afl.jsApiSetInstrumentCacheSize(size);
} }
/**
* See `AFL_FRIDA_INST_COVERAGE_ABSOLUTE`.
*/
public static setInstrumentCoverageAbsolute(): void {
Afl.jsApiSetInstrumentCoverageAbsolute();
}
/** /**
* See `AFL_FRIDA_INST_COVERAGE_FILE`. This function takes a single `string` * See `AFL_FRIDA_INST_COVERAGE_FILE`. This function takes a single `string`
* as an argument. * as an argument.
@ -178,6 +185,15 @@ class Afl {
Afl.jsApiSetInstrumentNoOptimize(); Afl.jsApiSetInstrumentNoOptimize();
} }
/**
* See `AFL_FRIDA_INST_REGS_FILE`. This function takes a single `string` as
* an argument.
*/
public static setInstrumentRegsFile(file: string): void {
const buf = Memory.allocUtf8String(file);
Afl.jsApiSetInstrumentRegsFile(buf);
}
/* /*
* See `AFL_FRIDA_INST_SEED` * See `AFL_FRIDA_INST_SEED`
*/ */
@ -389,6 +405,12 @@ class Afl {
"void", "void",
["size_t"]); ["size_t"]);
private static readonly jsApiSetInstrumentCoverageAbsolute = Afl.jsApiGetFunction(
"js_api_set_instrument_coverage_absolute",
"void",
[]
);
private static readonly jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction( private static readonly jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction(
"js_api_set_instrument_coverage_file", "js_api_set_instrument_coverage_file",
"void", "void",
@ -419,6 +441,11 @@ class Afl {
"void", "void",
[]); []);
private static readonly jsApiSetInstrumentRegsFile = Afl.jsApiGetFunction(
"js_api_set_instrument_regs_file",
"void",
["pointer"]);
private static readonly jsApiSetInstrumentSeed = Afl.jsApiGetFunction( private static readonly jsApiSetInstrumentSeed = Afl.jsApiGetFunction(
"js_api_set_instrument_seed", "js_api_set_instrument_seed",
"void", "void",

View File

@ -1,8 +1,8 @@
#!/bin/sh #!/bin/sh
test -n "$1" && { echo This script has no options. It updates the referenced Frida version in GNUmakefile to the most current one. ; exit 1 ; } test -n "$1" && { echo This script has no options. It updates the referenced Frida version in GNUmakefile to the most current one. ; exit 1 ; }
OLD=$(egrep '^GUM_DEVKIT_VERSION=' GNUmakefile 2>/dev/null|awk -F= '{print$2}') OLD=$(grep -E '^GUM_DEVKIT_VERSION=' GNUmakefile 2>/dev/null|awk -F= '{print$2}')
NEW=$(curl https://github.com/frida/frida/releases/ 2>/dev/null|egrep 'frida-gum-devkit-[0-9.]*-linux-x86_64'|head -n 1|sed 's/.*frida-gum-devkit-//'|sed 's/-linux.*//') NEW=$(curl https://github.com/frida/frida/releases/ 2>/dev/null|grep -E 'frida-gum-devkit-[0-9.]*-linux-x86_64'|head -n 1|sed 's/.*frida-gum-devkit-//'|sed 's/-linux.*//')
echo Current set version: $OLD echo Current set version: $OLD
echo Newest available version: $NEW echo Newest available version: $NEW

View File

@ -188,7 +188,7 @@ struct queue_entry {
u8 *testcase_buf; /* The testcase buffer, if loaded. */ u8 *testcase_buf; /* The testcase buffer, if loaded. */
u8 * cmplog_colorinput; /* the result buf of colorization */ u8 *cmplog_colorinput; /* the result buf of colorization */
struct tainted *taint; /* Taint information from CmpLog */ struct tainted *taint; /* Taint information from CmpLog */
struct queue_entry *mother; /* queue entry this based on */ struct queue_entry *mother; /* queue entry this based on */
@ -341,18 +341,18 @@ typedef struct py_mutator {
PyObject *py_module; PyObject *py_module;
PyObject *py_functions[PY_FUNC_COUNT]; PyObject *py_functions[PY_FUNC_COUNT];
void * afl_state; void *afl_state;
void * py_data; void *py_data;
u8 * fuzz_buf; u8 *fuzz_buf;
size_t fuzz_size; size_t fuzz_size;
Py_buffer post_process_buf; Py_buffer post_process_buf;
u8 * trim_buf; u8 *trim_buf;
size_t trim_size; size_t trim_size;
u8 * havoc_buf; u8 *havoc_buf;
size_t havoc_size; size_t havoc_size;
} py_mutator_t; } py_mutator_t;
@ -361,13 +361,13 @@ typedef struct py_mutator {
typedef struct MOpt_globals { typedef struct MOpt_globals {
u64 * finds; u64 *finds;
u64 * finds_v2; u64 *finds_v2;
u64 * cycles; u64 *cycles;
u64 * cycles_v2; u64 *cycles_v2;
u64 * cycles_v3; u64 *cycles_v3;
u32 is_pilot_mode; u32 is_pilot_mode;
u64 * pTime; u64 *pTime;
u64 period; u64 period;
char *havoc_stagename; char *havoc_stagename;
char *splice_stageformat; char *splice_stageformat;
@ -386,7 +386,8 @@ typedef struct afl_env_vars {
afl_bench_until_crash, afl_debug_child, afl_autoresume, afl_cal_fast, afl_bench_until_crash, afl_debug_child, afl_autoresume, afl_cal_fast,
afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new, afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new,
afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems, afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems,
afl_keep_timeouts, afl_pizza_mode, afl_no_crash_readme; afl_keep_timeouts, afl_pizza_mode, afl_no_crash_readme,
afl_no_startup_calibration;
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
@ -406,7 +407,7 @@ struct afl_pass_stat {
struct foreign_sync { struct foreign_sync {
u8 * dir; u8 *dir;
time_t mtime; time_t mtime;
}; };
@ -418,7 +419,7 @@ typedef struct afl_state {
afl_forkserver_t fsrv; afl_forkserver_t fsrv;
sharedmem_t shm; sharedmem_t shm;
sharedmem_t * shm_fuzz; sharedmem_t *shm_fuzz;
afl_env_vars_t afl_env; afl_env_vars_t afl_env;
char **argv; /* argv if needed */ char **argv; /* argv if needed */
@ -529,7 +530,7 @@ typedef struct afl_state {
*virgin_crash; /* Bits we haven't seen in crashes */ *virgin_crash; /* Bits we haven't seen in crashes */
double *alias_probability; /* alias weighted probabilities */ double *alias_probability; /* alias weighted probabilities */
u32 * alias_table; /* alias weighted random lookup table */ u32 *alias_table; /* alias weighted random lookup table */
u32 active_items; /* enabled entries in the queue */ u32 active_items; /* enabled entries in the queue */
u8 *var_bytes; /* Bytes that appear to be variable */ u8 *var_bytes; /* Bytes that appear to be variable */
@ -643,7 +644,7 @@ typedef struct afl_state {
/* CmpLog */ /* CmpLog */
char * cmplog_binary; char *cmplog_binary;
afl_forkserver_t cmplog_fsrv; /* cmplog has its own little forkserver */ afl_forkserver_t cmplog_fsrv; /* cmplog has its own little forkserver */
/* Custom mutators */ /* Custom mutators */
@ -658,7 +659,7 @@ typedef struct afl_state {
u8 cmplog_enable_arith, cmplog_enable_transform; u8 cmplog_enable_arith, cmplog_enable_transform;
struct afl_pass_stat *pass_stats; struct afl_pass_stat *pass_stats;
struct cmp_map * orig_cmp_map; struct cmp_map *orig_cmp_map;
u8 describe_op_buf_256[256]; /* describe_op will use this to return a string u8 describe_op_buf_256[256]; /* describe_op will use this to return a string
up to 256 */ up to 256 */
@ -690,9 +691,9 @@ typedef struct afl_state {
u64 statsd_last_send_ms; u64 statsd_last_send_ms;
struct sockaddr_in statsd_server; struct sockaddr_in statsd_server;
int statsd_sock; int statsd_sock;
char * statsd_tags_flavor; char *statsd_tags_flavor;
char * statsd_tags_format; char *statsd_tags_format;
char * statsd_metric_format; char *statsd_metric_format;
int statsd_metric_format_type; int statsd_metric_format_type;
double stats_avg_exec; double stats_avg_exec;
@ -770,9 +771,9 @@ typedef struct afl_state {
struct custom_mutator { struct custom_mutator {
const char *name; const char *name;
char * name_short; char *name_short;
void * dh; void *dh;
u8 * post_process_buf; u8 *post_process_buf;
u8 stacked_custom_prob, stacked_custom; u8 stacked_custom_prob, stacked_custom;
void *data; /* custom mutator data ptr */ void *data; /* custom mutator data ptr */

View File

@ -49,7 +49,7 @@ void argv_cpy_free(char **argv);
char **get_cs_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv); char **get_cs_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv); char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv); char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
char * get_afl_env(char *env); char *get_afl_env(char *env);
/* Extract env vars from input string and set them using setenv() /* Extract env vars from input string and set them using setenv()
For use with AFL_TARGET_ENV, ... */ For use with AFL_TARGET_ENV, ... */

View File

@ -26,7 +26,7 @@
/* Version string: */ /* Version string: */
// c = release, a = volatile github dev, e = experimental branch // c = release, a = volatile github dev, e = experimental branch
#define VERSION "++4.01c" #define VERSION "++4.04c"
/****************************************************** /******************************************************
* * * *
@ -153,8 +153,9 @@
/* Number of calibration cycles per every new test case (and for test /* Number of calibration cycles per every new test case (and for test
cases that show variable behavior): */ cases that show variable behavior): */
#define CAL_CYCLES 8U #define CAL_CYCLES_FAST 3U
#define CAL_CYCLES_LONG 20U #define CAL_CYCLES 7U
#define CAL_CYCLES_LONG 12U
/* Number of subsequent timeouts before abandoning an input file: */ /* Number of subsequent timeouts before abandoning an input file: */

View File

@ -192,7 +192,7 @@ static inline const char *colorfilter(const char *x) {
if (likely(disabled)) return x; if (likely(disabled)) return x;
static char monochromestring[4096]; static char monochromestring[4096];
char * d = monochromestring; char *d = monochromestring;
int in_seq = 0; int in_seq = 0;
while (*x) { while (*x) {

View File

@ -58,6 +58,7 @@ static char *afl_environment_variables[] = {
"AFL_FRIDA_DRIVER_NO_HOOK", "AFL_FRIDA_DRIVER_NO_HOOK",
"AFL_FRIDA_EXCLUDE_RANGES", "AFL_FRIDA_EXCLUDE_RANGES",
"AFL_FRIDA_INST_CACHE_SIZE", "AFL_FRIDA_INST_CACHE_SIZE",
"AFL_FRIDA_INST_COVERAGE_ABSOLUTE",
"AFL_FRIDA_INST_COVERAGE_FILE", "AFL_FRIDA_INST_COVERAGE_FILE",
"AFL_FRIDA_INST_DEBUG_FILE", "AFL_FRIDA_INST_DEBUG_FILE",
"AFL_FRIDA_INST_INSN", "AFL_FRIDA_INST_INSN",
@ -67,6 +68,7 @@ static char *afl_environment_variables[] = {
"AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH",
"AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH",
"AFL_FRIDA_INST_RANGES", "AFL_FRIDA_INST_RANGES",
"AFL_FRIDA_INST_REGS_FILE",
"AFL_FRIDA_INST_SEED", "AFL_FRIDA_INST_SEED",
"AFL_FRIDA_INST_TRACE", "AFL_FRIDA_INST_TRACE",
"AFL_FRIDA_INST_TRACE_UNIQUE", "AFL_FRIDA_INST_TRACE_UNIQUE",
@ -163,6 +165,7 @@ static char *afl_environment_variables[] = {
"AFL_NO_FORKSRV", "AFL_NO_FORKSRV",
"AFL_NO_UI", "AFL_NO_UI",
"AFL_NO_PYTHON", "AFL_NO_PYTHON",
"AFL_NO_STARTUP_CALIBRATION",
"AFL_UNTRACER_FILE", "AFL_UNTRACER_FILE",
"AFL_LLVM_USE_TRACE_PC", "AFL_LLVM_USE_TRACE_PC",
"AFL_MAP_SIZE", "AFL_MAP_SIZE",
@ -195,6 +198,7 @@ static char *afl_environment_variables[] = {
"AFL_QEMU_INST_RANGES", "AFL_QEMU_INST_RANGES",
"AFL_QEMU_EXCLUDE_RANGES", "AFL_QEMU_EXCLUDE_RANGES",
"AFL_QEMU_SNAPSHOT", "AFL_QEMU_SNAPSHOT",
"AFL_QEMU_TRACK_UNSTABLE",
"AFL_QUIET", "AFL_QUIET",
"AFL_RANDOM_ALLOC_CANARY", "AFL_RANDOM_ALLOC_CANARY",
"AFL_REAL_PATH", "AFL_REAL_PATH",

View File

@ -150,7 +150,7 @@ typedef struct afl_forkserver {
#ifdef AFL_PERSISTENT_RECORD #ifdef AFL_PERSISTENT_RECORD
u32 persistent_record_idx; /* persistent replay cache ptr */ u32 persistent_record_idx; /* persistent replay cache ptr */
u32 persistent_record_cnt; /* persistent replay counter */ u32 persistent_record_cnt; /* persistent replay counter */
u8 * persistent_record_dir; u8 *persistent_record_dir;
u8 **persistent_record_data; u8 **persistent_record_data;
u32 *persistent_record_len; u32 *persistent_record_len;
s32 persistent_record_pid; s32 persistent_record_pid;
@ -168,14 +168,14 @@ typedef struct afl_forkserver {
#ifdef __linux__ #ifdef __linux__
nyx_plugin_handler_t *nyx_handlers; nyx_plugin_handler_t *nyx_handlers;
char * out_dir_path; /* path to the output directory */ char *out_dir_path; /* path to the output directory */
u8 nyx_mode; /* if running in nyx mode or not */ u8 nyx_mode; /* if running in nyx mode or not */
bool nyx_parent; /* create initial snapshot */ bool nyx_parent; /* create initial snapshot */
bool nyx_standalone; /* don't serialize the snapshot */ bool nyx_standalone; /* don't serialize the snapshot */
void * nyx_runner; /* nyx runner object */ void *nyx_runner; /* nyx runner object */
u32 nyx_id; /* nyx runner id (0 -> master) */ u32 nyx_id; /* nyx runner id (0 -> master) */
u32 nyx_bind_cpu_id; /* nyx runner cpu id */ u32 nyx_bind_cpu_id; /* nyx runner cpu id */
char * nyx_aux_string; char *nyx_aux_string;
#endif #endif
} afl_forkserver_t; } afl_forkserver_t;

View File

@ -43,7 +43,7 @@ typedef struct list_element {
struct list_element *prev; struct list_element *prev;
struct list_element *next; struct list_element *next;
void * data; void *data;
} element_t; } element_t;
@ -102,7 +102,7 @@ static inline void list_append(list_t *list, void *el) {
#define LIST_FOREACH(list, type, block) \ #define LIST_FOREACH(list, type, block) \
do { \ do { \
\ \
list_t * li = (list); \ list_t *li = (list); \
element_t *head = get_head((li)); \ element_t *head = get_head((li)); \
element_t *el_box = (head)->next; \ element_t *el_box = (head)->next; \
if (!el_box) FATAL("foreach over uninitialized list"); \ if (!el_box) FATAL("foreach over uninitialized list"); \

View File

@ -56,7 +56,7 @@ typedef struct sharedmem {
} sharedmem_t; } sharedmem_t;
u8 * afl_shm_init(sharedmem_t *, size_t, unsigned char non_instrumented_mode); u8 *afl_shm_init(sharedmem_t *, size_t, unsigned char non_instrumented_mode);
void afl_shm_deinit(sharedmem_t *); void afl_shm_deinit(sharedmem_t *);
#endif #endif

View File

@ -57,7 +57,7 @@ typedef uint128_t u128;
#define FS_OPT_SHDMEM_FUZZ 0x01000000 #define FS_OPT_SHDMEM_FUZZ 0x01000000
#define FS_OPT_NEWCMPLOG 0x02000000 #define FS_OPT_NEWCMPLOG 0x02000000
#define FS_OPT_OLD_AFLPP_WORKAROUND 0x0f000000 #define FS_OPT_OLD_AFLPP_WORKAROUND 0x0f000000
// FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 22 // FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 23
#define FS_OPT_MAX_MAPSIZE ((0x00fffffeU >> 1) + 1) #define FS_OPT_MAX_MAPSIZE ((0x00fffffeU >> 1) + 1)
#define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1) #define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1)
#define FS_OPT_SET_MAPSIZE(x) \ #define FS_OPT_SET_MAPSIZE(x) \

View File

@ -510,7 +510,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t *statePtr);
* @pre * @pre
* @p dst_state and @p src_state must not be `NULL` and must not overlap. * @p dst_state and @p src_state must not be `NULL` and must not overlap.
*/ */
XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t * dst_state, XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t *dst_state,
const XXH32_state_t *src_state); const XXH32_state_t *src_state);
/*! /*!
@ -742,10 +742,10 @@ XXH_PUBLIC_API XXH64_hash_t XXH64(const void *input, size_t length,
* *
* @see XXH64_state_s for details. * @see XXH64_state_s for details.
*/ */
typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
XXH_PUBLIC_API XXH64_state_t *XXH64_createState(void); XXH_PUBLIC_API XXH64_state_t *XXH64_createState(void);
XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t *statePtr); XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t *statePtr);
XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t * dst_state, XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t *dst_state,
const XXH64_state_t *src_state); const XXH64_state_t *src_state);
XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t *statePtr, XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t *statePtr,
@ -870,10 +870,10 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void *data, size_t len,
* *
* @see XXH3_state_s for details. * @see XXH3_state_s for details.
*/ */
typedef struct XXH3_state_s XXH3_state_t; typedef struct XXH3_state_s XXH3_state_t;
XXH_PUBLIC_API XXH3_state_t *XXH3_createState(void); XXH_PUBLIC_API XXH3_state_t *XXH3_createState(void);
XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t *statePtr); XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t *statePtr);
XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t * dst_state, XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t *dst_state,
const XXH3_state_t *src_state); const XXH3_state_t *src_state);
/* /*
@ -902,7 +902,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(
XXH3_state_t *statePtr, const void *secret, size_t secretSize); XXH3_state_t *statePtr, const void *secret, size_t secretSize);
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update(XXH3_state_t *statePtr, XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update(XXH3_state_t *statePtr,
const void * input, const void *input,
size_t length); size_t length);
XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest(const XXH3_state_t *statePtr); XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest(const XXH3_state_t *statePtr);
@ -955,7 +955,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(
XXH3_state_t *statePtr, const void *secret, size_t secretSize); XXH3_state_t *statePtr, const void *secret, size_t secretSize);
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update(XXH3_state_t *statePtr, XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update(XXH3_state_t *statePtr,
const void * input, const void *input,
size_t length); size_t length);
XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest(const XXH3_state_t *statePtr); XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest(const XXH3_state_t *statePtr);
@ -1229,7 +1229,7 @@ struct XXH3_state_s {
* `secretBuffer`. When customSeedSize > 0, supplying NULL as customSeed is * `secretBuffer`. When customSeedSize > 0, supplying NULL as customSeed is
* undefined behavior. * undefined behavior.
*/ */
XXH_PUBLIC_API void XXH3_generateSecret(void * secretBuffer, XXH_PUBLIC_API void XXH3_generateSecret(void *secretBuffer,
const void *customSeed, const void *customSeed,
size_t customSeedSize); size_t customSeedSize);
@ -1951,7 +1951,7 @@ static xxh_u32 XXH_readBE32(const void *ptr) {
#endif #endif
XXH_FORCE_INLINE xxh_u32 XXH_readLE32_align(const void * ptr, XXH_FORCE_INLINE xxh_u32 XXH_readLE32_align(const void *ptr,
XXH_alignment align) { XXH_alignment align) {
if (align == XXH_unaligned) { if (align == XXH_unaligned) {
@ -2317,7 +2317,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t *statePtr) {
} }
/*! @ingroup xxh32_family */ /*! @ingroup xxh32_family */
XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t * dstState, XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t *dstState,
const XXH32_state_t *srcState) { const XXH32_state_t *srcState) {
memcpy(dstState, srcState, sizeof(*dstState)); memcpy(dstState, srcState, sizeof(*dstState));
@ -2355,7 +2355,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_update(XXH32_state_t *state,
{ {
const xxh_u8 * p = (const xxh_u8 *)input; const xxh_u8 *p = (const xxh_u8 *)input;
const xxh_u8 *const bEnd = p + len; const xxh_u8 *const bEnd = p + len;
state->total_len_32 += (XXH32_hash_t)len; state->total_len_32 += (XXH32_hash_t)len;
@ -2625,7 +2625,7 @@ static xxh_u64 XXH_readBE64(const void *ptr) {
#endif #endif
XXH_FORCE_INLINE xxh_u64 XXH_readLE64_align(const void * ptr, XXH_FORCE_INLINE xxh_u64 XXH_readLE64_align(const void *ptr,
XXH_alignment align) { XXH_alignment align) {
if (align == XXH_unaligned) if (align == XXH_unaligned)
@ -2852,7 +2852,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t *statePtr) {
} }
/*! @ingroup xxh64_family */ /*! @ingroup xxh64_family */
XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t * dstState, XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t *dstState,
const XXH64_state_t *srcState) { const XXH64_state_t *srcState) {
memcpy(dstState, srcState, sizeof(*dstState)); memcpy(dstState, srcState, sizeof(*dstState));
@ -2890,7 +2890,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_update(XXH64_state_t *state,
{ {
const xxh_u8 * p = (const xxh_u8 *)input; const xxh_u8 *p = (const xxh_u8 *)input;
const xxh_u8 *const bEnd = p + len; const xxh_u8 *const bEnd = p + len;
state->total_len += len; state->total_len += len;
@ -4268,7 +4268,7 @@ XXH_FORCE_INLINE XXH_TARGET_AVX512 void XXH3_initCustomSecret_avx512(
union { union {
const __m512i *cp; const __m512i *cp;
void * p; void *p;
} remote_const_void; } remote_const_void;
@ -4385,7 +4385,7 @@ XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(
(xxh_i64)(0U - seed64), (xxh_i64)seed64); (xxh_i64)(0U - seed64), (xxh_i64)seed64);
const __m256i *const src = (const __m256i *)((const void *)XXH3_kSecret); const __m256i *const src = (const __m256i *)((const void *)XXH3_kSecret);
__m256i * dest = (__m256i *)customSecret; __m256i *dest = (__m256i *)customSecret;
#if defined(__GNUC__) || defined(__clang__) #if defined(__GNUC__) || defined(__clang__)
/* /*
@ -4519,7 +4519,7 @@ XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_initCustomSecret_sse2(
int i; int i;
const void *const src16 = XXH3_kSecret; const void *const src16 = XXH3_kSecret;
__m128i * dst16 = (__m128i *)customSecret; __m128i *dst16 = (__m128i *)customSecret;
#if defined(__GNUC__) || defined(__clang__) #if defined(__GNUC__) || defined(__clang__)
/* /*
* On GCC & Clang, marking 'dest' as modified will cause the compiler: * On GCC & Clang, marking 'dest' as modified will cause the compiler:
@ -4594,7 +4594,7 @@ XXH_FORCE_INLINE void XXH3_scrambleAcc_neon(void *XXH_RESTRICT acc,
{ {
uint64x2_t * xacc = (uint64x2_t *)acc; uint64x2_t *xacc = (uint64x2_t *)acc;
uint8_t const *xsecret = (uint8_t const *)secret; uint8_t const *xsecret = (uint8_t const *)secret;
uint32x2_t prime = vdup_n_u32(XXH_PRIME32_1); uint32x2_t prime = vdup_n_u32(XXH_PRIME32_1);
@ -5106,7 +5106,7 @@ XXH_FORCE_INLINE XXH64_hash_t XXH3_hashLong_64b_withSeed_internal(
/* /*
* It's important for performance that XXH3_hashLong is not inlined. * It's important for performance that XXH3_hashLong is not inlined.
*/ */
XXH_NO_INLINE XXH64_hash_t XXH3_hashLong_64b_withSeed(const void * input, XXH_NO_INLINE XXH64_hash_t XXH3_hashLong_64b_withSeed(const void *input,
size_t len, size_t len,
XXH64_hash_t seed, XXH64_hash_t seed,
const xxh_u8 *secret, const xxh_u8 *secret,
@ -5277,7 +5277,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t *statePtr) {
} }
/*! @ingroup xxh3_family */ /*! @ingroup xxh3_family */
XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t * dst_state, XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t *dst_state,
const XXH3_state_t *src_state) { const XXH3_state_t *src_state) {
memcpy(dst_state, src_state, sizeof(*dst_state)); memcpy(dst_state, src_state, sizeof(*dst_state));
@ -5482,8 +5482,8 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update(XXH3_state_t *state,
} }
XXH_FORCE_INLINE void XXH3_digest_long(XXH64_hash_t * acc, XXH_FORCE_INLINE void XXH3_digest_long(XXH64_hash_t *acc,
const XXH3_state_t * state, const XXH3_state_t *state,
const unsigned char *secret) { const unsigned char *secret) {
/* /*
@ -5545,7 +5545,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest(const XXH3_state_t *state) {
#define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x)) #define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x))
/*! @ingroup xxh3_family */ /*! @ingroup xxh3_family */
XXH_PUBLIC_API void XXH3_generateSecret(void * secretBuffer, XXH_PUBLIC_API void XXH3_generateSecret(void *secretBuffer,
const void *customSeed, const void *customSeed,
size_t customSeedSize) { size_t customSeedSize) {
@ -6081,7 +6081,7 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void *input,
} }
/*! @ingroup xxh3_family */ /*! @ingroup xxh3_family */
XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void * input, XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void *input,
size_t len, size_t len,
XXH64_hash_t seed) { XXH64_hash_t seed) {
@ -6142,7 +6142,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t *statePtr,
/*! @ingroup xxh3_family */ /*! @ingroup xxh3_family */
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update(XXH3_state_t *state, XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update(XXH3_state_t *state,
const void * input, const void *input,
size_t len) { size_t len) {
return XXH3_update(state, (const xxh_u8 *)input, len, XXH3_accumulate_512, return XXH3_update(state, (const xxh_u8 *)input, len, XXH3_accumulate_512,

Some files were not shown because too many files have changed in this diff Show More