mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-10 17:21:33 +00:00
commit
c57988e672
@ -19,40 +19,22 @@ import subprocess
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
|
||||
# string_re = re.compile('(\\"(\\\\.|[^"\\\\])*\\")') # future use
|
||||
|
||||
with open(".clang-format") as f:
|
||||
fmt = f.read()
|
||||
|
||||
CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN")
|
||||
if CLANG_FORMAT_BIN is None:
|
||||
o = 0
|
||||
try:
|
||||
p = subprocess.Popen(["clang-format-11", "--version"], stdout=subprocess.PIPE)
|
||||
o, _ = p.communicate()
|
||||
o = str(o, "utf-8")
|
||||
o = re.sub(r".*ersion ", "", o)
|
||||
# o = o[len("clang-format version "):].strip()
|
||||
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"
|
||||
CURRENT_LLVM = os.getenv('LLVM_VERSION', 14)
|
||||
CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN", "")
|
||||
|
||||
if shutil.which(CLANG_FORMAT_BIN) is None:
|
||||
CLANG_FORMAT_BIN = f"clang-format-{CURRENT_LLVM}"
|
||||
|
||||
if shutil.which(CLANG_FORMAT_BIN) is None:
|
||||
print(f"[!] clang-format-{CURRENT_LLVM} is needed. Aborted.")
|
||||
exit(1)
|
||||
|
||||
COLUMN_LIMIT = 80
|
||||
for line in fmt.split("\n"):
|
||||
|
@ -1,65 +1,75 @@
|
||||
!/coresight_mode
|
||||
*.dSYM
|
||||
*.o
|
||||
*.pyc
|
||||
*.so
|
||||
.sync_tmp
|
||||
.test
|
||||
.test2
|
||||
.sync_tmp
|
||||
*.o
|
||||
*.so
|
||||
*.pyc
|
||||
*.dSYM
|
||||
as
|
||||
ld
|
||||
in
|
||||
out
|
||||
core*
|
||||
.git
|
||||
.dockerignore
|
||||
.github
|
||||
CITATION.cff
|
||||
CONTRIBUTING.md
|
||||
Changelog.md
|
||||
Dockerfile
|
||||
LICENSE
|
||||
TODO.md
|
||||
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-as
|
||||
afl-as.8
|
||||
afl-clang-fast\+\+.8
|
||||
afl-clang
|
||||
afl-clang-fast
|
||||
afl-clang-fast.8
|
||||
afl-clang-fast\+\+
|
||||
afl-clang-fast\+\+.8
|
||||
afl-clang-lto
|
||||
afl-clang-lto.8
|
||||
afl-clang-lto\+\+
|
||||
afl-clang-lto\+\+.8
|
||||
afl-clang\+\+
|
||||
afl-cmin.8
|
||||
afl-cmin.bash.8
|
||||
afl-fuzz
|
||||
afl-fuzz.8
|
||||
afl-gcc.8
|
||||
afl-gcc-fast.8
|
||||
afl-g\+\+
|
||||
afl-g\+\+-fast
|
||||
afl-g\+\+-fast.8
|
||||
afl-gcc
|
||||
afl-gcc-fast
|
||||
afl-gcc-fast.8
|
||||
afl-gcc.8
|
||||
afl-gotcpu
|
||||
afl-gotcpu.8
|
||||
afl-ld
|
||||
afl-ld-lto
|
||||
afl-plot.8
|
||||
afl-qemu-trace
|
||||
afl-showmap
|
||||
afl-showmap.8
|
||||
afl-system-config.8
|
||||
afl-tmin
|
||||
afl-tmin.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/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/*/output
|
||||
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
|
49
.github/workflows/build_aflplusplus_docker.yaml
vendored
49
.github/workflows/build_aflplusplus_docker.yaml
vendored
@ -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' }}
|
15
.github/workflows/ci.yml
vendored
15
.github/workflows/ci.yml
vendored
@ -2,13 +2,16 @@ name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ stable, dev ]
|
||||
branches:
|
||||
- stable
|
||||
- dev
|
||||
pull_request:
|
||||
branches: [ stable, dev ]
|
||||
branches:
|
||||
- dev # No need for stable-pull-request, as that equals dev-push
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: "${{ matrix.os }}"
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04]
|
||||
@ -16,7 +19,7 @@ jobs:
|
||||
AFL_SKIP_CPUFREQ: 1
|
||||
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: debug
|
||||
run: apt-cache search plugin-dev | grep gcc-; echo; apt-cache search clang-format- | grep clang-format-
|
||||
- name: update
|
||||
@ -38,9 +41,9 @@ jobs:
|
||||
AFL_SKIP_CPUFREQ: 1
|
||||
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: install
|
||||
run: brew install make gcc
|
||||
run: brew install make gcc llvm
|
||||
- name: fix install
|
||||
run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
|
||||
- name: build
|
||||
|
33
.github/workflows/code-format.yml
vendored
Normal file
33
.github/workflows/code-format.yml
vendored
Normal 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
|
43
.github/workflows/codeql-analysis.yml
vendored
43
.github/workflows/codeql-analysis.yml
vendored
@ -2,31 +2,32 @@ name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ stable, dev ]
|
||||
branches:
|
||||
- stable
|
||||
- dev
|
||||
pull_request:
|
||||
branches: [ stable, dev ]
|
||||
branches:
|
||||
- dev # No need for stable-pull-request, as that equals dev-push
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
|
||||
container: # We use a previous image as it's expected to have all the dependencies
|
||||
image: docker.io/aflplusplus/aflplusplus:dev
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
- name: Fix for using external repo in container build # https://github.com/actions/checkout/issues/760
|
||||
run: git config --global --add safe.directory /__w/AFLplusplus/AFLplusplus
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: cpp, python
|
||||
- name: Build AFLplusplus # Rebuild because CodeQL needs to monitor the build process
|
||||
env:
|
||||
CC: gcc # These are symlinked to the version used in the container build
|
||||
CXX: g++
|
||||
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
75
.github/workflows/container.yml
vendored
Normal 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
|
11
.github/workflows/rust_custom_mutator.yml
vendored
11
.github/workflows/rust_custom_mutator.yml
vendored
@ -2,9 +2,12 @@ name: Rust Custom Mutators
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ stable, dev ]
|
||||
branches:
|
||||
- stable
|
||||
- dev
|
||||
pull_request:
|
||||
branches: [ stable, dev ]
|
||||
branches:
|
||||
- dev # No need for stable-pull-request, as that equals dev-push
|
||||
|
||||
jobs:
|
||||
test:
|
||||
@ -17,7 +20,7 @@ jobs:
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-20.04]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
@ -27,4 +30,4 @@ jobs:
|
||||
- name: Run General Tests
|
||||
run: cargo test
|
||||
- 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
|
||||
|
121
Dockerfile
121
Dockerfile
@ -1,81 +1,88 @@
|
||||
#
|
||||
# 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
|
||||
LABEL "maintainer"="afl++ team <afl@aflplus.plus>"
|
||||
LABEL "about"="AFLplusplus docker image"
|
||||
LABEL "about"="AFLplusplus container image"
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
env NO_ARCH_OPT 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
|
||||
ENV NO_ARCH_OPT=1
|
||||
ENV IS_DOCKER=1
|
||||
|
||||
RUN apt-get update && apt-get full-upgrade -y && \
|
||||
apt-get -y install --no-install-suggests --no-install-recommends \
|
||||
gcc-12 g++-12 gcc-12-plugin-dev gdb lcov \
|
||||
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
|
||||
apt-get install -y --no-install-recommends wget ca-certificates && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# arm64 doesn't have gcc-multilib, and it's only used for -m32 support on x86
|
||||
ARG TARGETPLATFORM
|
||||
RUN [ "$TARGETPLATFORM" = "linux/amd64" ] && \
|
||||
apt-get -y install --no-install-suggests --no-install-recommends \
|
||||
gcc-10-multilib gcc-multilib || true
|
||||
ENV LLVM_VERSION=14
|
||||
ENV GCC_VERSION=11
|
||||
|
||||
RUN rm -rf /var/lib/apt/lists/*
|
||||
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 && \
|
||||
wget -qO /etc/apt/keyrings/llvm-snapshot.gpg.key https://apt.llvm.org/llvm-snapshot.gpg.key
|
||||
|
||||
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 0
|
||||
RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 0
|
||||
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-utils 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
|
||||
|
||||
ENV LLVM_CONFIG=llvm-config-14
|
||||
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_VERSION} 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
|
||||
|
||||
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_TRY_AFFINITY=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 cd /afl-cov && make install && cd ..
|
||||
RUN git clone --depth=1 https://github.com/vanhauser-thc/afl-cov && \
|
||||
(cd afl-cov && make install) && rm -rf afl-cov
|
||||
|
||||
# Build currently broken
|
||||
ENV NO_CORESIGHT=1
|
||||
ENV NO_UNICORN_ARM64=1
|
||||
|
||||
COPY . /AFLplusplus
|
||||
WORKDIR /AFLplusplus
|
||||
COPY . .
|
||||
|
||||
RUN export CC=gcc-12 && export CXX=g++-12 && make clean && \
|
||||
make distrib && make install && make clean
|
||||
ARG CC=gcc-$GCC_VERSION
|
||||
ARG CXX=g++-$GCC_VERSION
|
||||
|
||||
RUN sh -c 'echo set encoding=utf-8 > /root/.vimrc'
|
||||
RUN echo '. /etc/bash_completion' >> ~/.bashrc
|
||||
RUN echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc
|
||||
RUN echo "export PS1='"'[afl++ \h] \w$(__git_ps1) \$ '"'" >> ~/.bashrc
|
||||
ENV IS_DOCKER="1"
|
||||
# Used in CI to prevent a 'make clean' which would remove the binaries to be tested
|
||||
ARG TEST_BUILD
|
||||
|
||||
# Disabled as there are now better alternatives
|
||||
#COPY --from=aflplusplus/afl-dyninst /usr/local/lib/libdyninstAPI_RT.so /usr/local/lib/libdyninstAPI_RT.so
|
||||
#COPY --from=aflplusplus/afl-dyninst /afl-dyninst/libAflDyninst.so /usr/local/lib/libAflDyninst.so
|
||||
RUN sed -i.bak 's/^ -/ /g' GNUmakefile && \
|
||||
make clean && make distrib && \
|
||||
([ "${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
|
||||
|
28
GNUmakefile
28
GNUmakefile
@ -312,7 +312,7 @@ all: test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_bu
|
||||
|
||||
.PHONY: 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; }
|
||||
|
||||
.PHONY: gcc_plugin
|
||||
@ -572,7 +572,7 @@ clean:
|
||||
-$(MAKE) -f GNUmakefile.gcc_plugin clean
|
||||
-$(MAKE) -C utils/libdislocator 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/socket_fuzzing clean
|
||||
-$(MAKE) -C utils/argv_fuzzing clean
|
||||
@ -610,7 +610,7 @@ endif
|
||||
|
||||
.PHONY: distrib
|
||||
distrib: all
|
||||
-$(MAKE) -j4 -f GNUmakefile.llvm
|
||||
-$(MAKE) -j$(nproc) -f GNUmakefile.llvm
|
||||
ifneq "$(SYS)" "Darwin"
|
||||
-$(MAKE) -f GNUmakefile.gcc_plugin
|
||||
endif
|
||||
@ -623,15 +623,23 @@ endif
|
||||
-$(MAKE) -C frida_mode
|
||||
ifneq "$(SYS)" "Darwin"
|
||||
ifeq "$(ARCH)" "aarch64"
|
||||
ifndef NO_CORESIGHT
|
||||
-$(MAKE) -C coresight_mode
|
||||
endif
|
||||
endif
|
||||
ifeq "$(SYS)" "Linux"
|
||||
ifndef NO_NYX
|
||||
ifndef NO_NYX
|
||||
-cd nyx_mode && ./build_nyx_support.sh
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
-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
|
||||
endif
|
||||
else
|
||||
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: binary-only
|
||||
@ -645,7 +653,9 @@ binary-only: test_shm test_python ready $(PROGS)
|
||||
-$(MAKE) -C frida_mode
|
||||
ifneq "$(SYS)" "Darwin"
|
||||
ifeq "$(ARCH)" "aarch64"
|
||||
ifndef NO_CORESIGHT
|
||||
-$(MAKE) -C coresight_mode
|
||||
endif
|
||||
endif
|
||||
ifeq "$(SYS)" "Linux"
|
||||
ifndef NO_NYX
|
||||
@ -653,12 +663,18 @@ ifndef NO_NYX
|
||||
endif
|
||||
endif
|
||||
-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
|
||||
endif
|
||||
else
|
||||
-cd unicorn_mode && unset CFLAGS && sh ./build_unicorn_support.sh
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: source-only
|
||||
source-only: all
|
||||
-$(MAKE) -j4 -f GNUmakefile.llvm
|
||||
-$(MAKE) -j$(nproc) -f GNUmakefile.llvm
|
||||
ifneq "$(SYS)" "Darwin"
|
||||
-$(MAKE) -f GNUmakefile.gcc_plugin
|
||||
endif
|
||||
|
@ -100,7 +100,9 @@ ifeq "$(SYS)" "SunOS"
|
||||
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
|
||||
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)... "
|
||||
@$(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
|
||||
$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
|
||||
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-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
|
||||
test_build: $(PROGS)
|
||||
@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-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-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
|
||||
|
||||
.PHONY: clean
|
||||
|
1
afl-cmin
1
afl-cmin
@ -534,7 +534,6 @@ BEGIN {
|
||||
}
|
||||
}
|
||||
close(sortedKeys)
|
||||
print ""
|
||||
print "[+] Found "tuple_count" unique tuples across "in_count" files."
|
||||
|
||||
if (out_count == 1) {
|
||||
|
@ -54,7 +54,7 @@ $(GLIBC_LDSO): | $(GLIBC_NAME).tar.xz
|
||||
$(MAKE) install
|
||||
|
||||
$(GLIBC_NAME).tar.xz:
|
||||
wget -O $@ $(GLIBC_URL_BASE)/$@
|
||||
wget -qO $@ $(GLIBC_URL_BASE)/$@
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(CS_TRACE) clean
|
||||
|
@ -128,7 +128,7 @@ git pull >/dev/null 2>&1
|
||||
sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null
|
||||
git checkout "$GRAMMAR_VERSION" || exit 1
|
||||
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 ..
|
||||
|
||||
echo
|
||||
|
@ -8,6 +8,13 @@
|
||||
Want to stay in the loop on major new features? Join our mailing list by
|
||||
sending a mail to <afl-users+subscribe@googlegroups.com>.
|
||||
|
||||
### Version ++4.02a (dev)
|
||||
- gcc_plugin:
|
||||
- Adacore submitted CMPLOG support to the gcc_plugin! :-)
|
||||
- llvm_mode:
|
||||
- laf cmp splitting fixed for more comparison types
|
||||
|
||||
|
||||
### Version ++4.01c (release)
|
||||
- fixed */build_...sh scripts to work outside of git
|
||||
- new custom_mutator: libafl with token fuzzing :)
|
||||
|
@ -21,12 +21,12 @@ development state of AFL++.
|
||||
If you want to build AFL++ yourself, you have many options. The easiest choice
|
||||
is to build and install everything:
|
||||
|
||||
NOTE: depending on your Debian/Ubuntu/Kali/... version replease `-12` with
|
||||
NOTE: depending on your Debian/Ubuntu/Kali/... version release `-12` with
|
||||
whatever llvm version is available!
|
||||
|
||||
```shell
|
||||
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
|
||||
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
|
||||
@ -148,7 +148,7 @@ and definitely don't look POSIX-compliant. This means two things:
|
||||
environment before starting afl-fuzz.
|
||||
|
||||
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.
|
||||
|
||||
MacOS X supports SYSV shared memory used by AFL's instrumentation, but the
|
||||
|
@ -160,6 +160,8 @@ Available options:
|
||||
Setting `AFL_LLVM_CMPLOG=1` during compilation will tell afl-clang-fast to
|
||||
produce a CmpLog binary.
|
||||
|
||||
For afl-gcc-fast, set `AFL_GCC_CMPLOG=1` instead.
|
||||
|
||||
For more information, see
|
||||
[instrumentation/README.cmplog.md](../instrumentation/README.cmplog.md).
|
||||
|
||||
@ -460,7 +462,7 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
some basic stats. This behavior is also automatically triggered when the
|
||||
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
|
||||
- In QEMU mode (-Q) and FRIDA mode (-O), `AFL_PATH` will be searched for
|
||||
afl-qemu-trace and afl-frida-trace.so.
|
||||
|
||||
- If you are using persistent mode (you should, see
|
||||
@ -553,10 +555,10 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
in the target binary
|
||||
|
||||
- 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 :-)
|
||||
|
||||
- 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.
|
||||
|
||||
## 5) Settings for afl-qemu-trace
|
||||
|
@ -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 | | |
|
||||
| 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] | |
|
||||
| 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 | | | |
|
||||
| Non-Colliding Coverage [G] | | x(4) | | | (x)(5) | | | |
|
||||
| Ngram prev_loc Coverage [H] | | x(6) | | | | | | |
|
||||
|
@ -838,9 +838,10 @@ Here are some of the most important caveats for AFL++:
|
||||
|
||||
- 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
|
||||
simple code changes to make them behave in a more traditional way. Preeny or 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)
|
||||
simple code changes to make them behave in a more traditional way. Preeny or
|
||||
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)
|
||||
|
||||
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)
|
||||
|
@ -19,18 +19,18 @@ Mentor: vanhauser-thc
|
||||
## WASM Instrumentation
|
||||
|
||||
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
|
||||
needs to be implemented for binaries compiled to Webassembly. This can either be
|
||||
done by inserting instrumentation directly into the WASM AST, or by patching
|
||||
feedback into a WASM VM of choice, similar to the current Unicorn
|
||||
With the rise of WASM as a compile target, however, a novel way of
|
||||
instrumentation needs to be implemented for binaries compiled to Webassembly.
|
||||
This can either be done by inserting instrumentation directly into the WASM AST,
|
||||
or by patching feedback into a WASM VM of choice, similar to the current Unicorn
|
||||
instrumentation.
|
||||
|
||||
Mentor: any
|
||||
|
||||
## Support other programming languages
|
||||
|
||||
Other programming languages also use llvm hence they could be (easily?) supported
|
||||
for fuzzing, e.g., mono, swift, go, kotlin native, fortran, ...
|
||||
Other programming languages also use llvm hence they could be (easily?)
|
||||
supported for fuzzing, e.g., mono, swift, go, kotlin native, fortran, ...
|
||||
|
||||
GCC also supports: Objective-C, Fortran, Ada, Go, and D (according to
|
||||
[Gcc homepage](https://gcc.gnu.org/))
|
||||
|
@ -1,11 +1,13 @@
|
||||
# Tools that help fuzzing with AFL++
|
||||
|
||||
Speeding up fuzzing:
|
||||
## Speeding up fuzzing
|
||||
|
||||
* [libfiowrapper](https://github.com/marekzmyslowski/libfiowrapper) - if the
|
||||
function you want to fuzz requires loading a file, this allows using the
|
||||
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
|
||||
that tries to speed up the process of minimization of a single test case by
|
||||
using many CPU cores.
|
||||
@ -14,7 +16,8 @@ Minimization of test cases:
|
||||
* [halfempty](https://github.com/googleprojectzero/halfempty) - is a fast
|
||||
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
|
||||
for AFL.
|
||||
* [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
|
||||
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
|
||||
automatic processing/analysis of crashes and reducing the number of test
|
||||
cases.
|
||||
@ -44,7 +48,8 @@ Deployment, management, monitoring, reporting
|
||||
* [afl-extras](https://github.com/fekir/afl-extras) - shell scripts to
|
||||
parallelize afl-tmin, startup, and data collection.
|
||||
|
||||
Crash processing
|
||||
## Crash processing
|
||||
|
||||
* [AFLTriage](https://github.com/quic/AFLTriage) -
|
||||
triage crashing input files using gdb.
|
||||
* [afl-crash-analyzer](https://github.com/floyd-fuh/afl-crash-analyzer) -
|
||||
|
@ -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)
|
||||
|
||||
## Video Tutorials
|
||||
|
||||
* [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] How to fuzz a binary with no source code on Linux in persistent mode](https://www.youtube.com/watch?v=LGPJdEO02p4)
|
||||
|
@ -116,7 +116,7 @@ ifndef OS
|
||||
$(error "Operating system unsupported")
|
||||
endif
|
||||
|
||||
GUM_DEVKIT_VERSION=15.1.22
|
||||
GUM_DEVKIT_VERSION=15.1.27
|
||||
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)"
|
||||
|
||||
@ -275,7 +275,7 @@ endif
|
||||
|
||||
else
|
||||
$(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)
|
||||
tar Jxvfm $(GUM_DEVKIT_TARBALL) -C $(FRIDA_BUILD_DIR)
|
||||
|
@ -5,13 +5,13 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
extern char * instrument_debug_filename;
|
||||
extern char * instrument_coverage_filename;
|
||||
extern char *instrument_debug_filename;
|
||||
extern char *instrument_coverage_filename;
|
||||
extern gboolean instrument_tracing;
|
||||
extern gboolean instrument_optimize;
|
||||
extern gboolean instrument_unique;
|
||||
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_use_fixed_seed;
|
||||
@ -35,9 +35,9 @@ GumStalkerTransformer *instrument_get_transformer(void);
|
||||
gboolean instrument_is_coverage_optimize_supported(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);
|
||||
void instrument_coverage_optimize_insn(const cs_insn * instr,
|
||||
void instrument_coverage_optimize_insn(const cs_insn *instr,
|
||||
GumStalkerOutput *output);
|
||||
|
||||
void instrument_debug_config(void);
|
||||
|
@ -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 unsigned int * __afl_fuzz_len;
|
||||
extern unsigned int *__afl_fuzz_len;
|
||||
extern unsigned char *__afl_fuzz_ptr;
|
||||
|
||||
extern guint64 persistent_start;
|
||||
|
@ -401,9 +401,9 @@ enum {
|
||||
|
||||
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,
|
||||
GumReturnAddressArray * frames);
|
||||
GumReturnAddressArray *frames);
|
||||
|
||||
void seccomp_atomic_set(volatile bool *ptr, bool val);
|
||||
bool seccomp_atomic_try_set(volatile bool *ptr, bool val);
|
||||
|
@ -43,7 +43,7 @@ typedef struct {
|
||||
G_DECLARE_FINAL_TYPE(GumAflStalkerStats, gum_afl_stalker_stats, GUM,
|
||||
AFL_STALKER_STATS, GObject)
|
||||
|
||||
extern char * stats_filename;
|
||||
extern char *stats_filename;
|
||||
extern guint64 stats_interval;
|
||||
|
||||
void stats_config(void);
|
||||
|
@ -30,7 +30,7 @@ void asan_init(void) {
|
||||
static gboolean asan_exclude_module(const GumModuleDetails *details,
|
||||
gpointer user_data) {
|
||||
|
||||
gchar * symbol_name = (gchar *)user_data;
|
||||
gchar *symbol_name = (gchar *)user_data;
|
||||
GumAddress address;
|
||||
|
||||
address = gum_module_find_export_by_name(details->name, symbol_name);
|
||||
|
@ -22,8 +22,8 @@ asan_storeN_t asan_storeN = NULL;
|
||||
|
||||
static void asan_callout(GumCpuContext *ctx, gpointer user_data) {
|
||||
|
||||
asan_ctx_t * asan_ctx = (asan_ctx_t *)user_data;
|
||||
cs_arm64_op * operand = &asan_ctx->operand;
|
||||
asan_ctx_t *asan_ctx = (asan_ctx_t *)user_data;
|
||||
cs_arm64_op *operand = &asan_ctx->operand;
|
||||
arm64_op_mem *mem = &operand->mem;
|
||||
gsize base = 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_op *operand;
|
||||
asan_ctx_t * ctx;
|
||||
asan_ctx_t *ctx;
|
||||
|
||||
if (!asan_initialized) return;
|
||||
|
||||
|
@ -17,7 +17,7 @@ static void asan_callout(GumCpuContext *ctx, gpointer 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;
|
||||
gsize base = 0;
|
||||
gsize index = 0;
|
||||
@ -48,9 +48,9 @@ void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
|
||||
UNUSED_PARAMETER(iterator);
|
||||
|
||||
cs_x86 x86 = instr->detail->x86;
|
||||
cs_x86_op * operand;
|
||||
cs_x86_op *operand;
|
||||
x86_op_mem *mem;
|
||||
cs_x86_op * ctx;
|
||||
cs_x86_op *ctx;
|
||||
|
||||
if (!asan_initialized) return;
|
||||
|
||||
|
@ -17,7 +17,7 @@ static void asan_callout(GumCpuContext *ctx, gpointer 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;
|
||||
gsize base = 0;
|
||||
gsize index = 0;
|
||||
@ -48,9 +48,9 @@ void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
|
||||
UNUSED_PARAMETER(iterator);
|
||||
|
||||
cs_x86 x86 = instr->detail->x86;
|
||||
cs_x86_op * operand;
|
||||
cs_x86_op *operand;
|
||||
x86_op_mem *mem;
|
||||
cs_x86_op * ctx;
|
||||
cs_x86_op *ctx;
|
||||
|
||||
if (!asan_initialized) return;
|
||||
|
||||
|
@ -13,9 +13,9 @@
|
||||
#define MAX_MEMFD_SIZE (64UL << 10)
|
||||
|
||||
extern struct cmp_map *__afl_cmp_map;
|
||||
static GArray * cmplog_ranges = NULL;
|
||||
static GHashTable * hash_yes = NULL;
|
||||
static GHashTable * hash_no = NULL;
|
||||
static GArray *cmplog_ranges = NULL;
|
||||
static GHashTable *hash_yes = NULL;
|
||||
static GHashTable *hash_no = NULL;
|
||||
|
||||
static long page_size = 0;
|
||||
static long page_offset_mask = 0;
|
||||
@ -24,7 +24,7 @@ static long page_mask = 0;
|
||||
static gboolean cmplog_range(const GumRangeDetails *details,
|
||||
gpointer user_data) {
|
||||
|
||||
GArray * cmplog_ranges = (GArray *)user_data;
|
||||
GArray *cmplog_ranges = (GArray *)user_data;
|
||||
GumMemoryRange range = *details->range;
|
||||
g_array_append_val(cmplog_ranges, range);
|
||||
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_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;
|
||||
|
||||
/* If it spans a page, then bail */
|
||||
|
@ -148,7 +148,7 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
|
||||
}
|
||||
|
||||
static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx,
|
||||
cs_arm64_op * operand) {
|
||||
cs_arm64_op *operand) {
|
||||
|
||||
ctx->type = 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) {
|
||||
|
||||
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,
|
||||
cs_arm64_op * operand1,
|
||||
cs_arm64_op * operand2,
|
||||
cs_arm64_op *operand1,
|
||||
cs_arm64_op *operand2,
|
||||
size_t size) {
|
||||
|
||||
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) {
|
||||
|
||||
cs_arm64 arm64 = instr->detail->arm64;
|
||||
|
@ -141,7 +141,7 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
|
||||
}
|
||||
|
||||
static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx,
|
||||
cs_x86_op * operand) {
|
||||
cs_x86_op *operand) {
|
||||
|
||||
ctx->type = operand->type;
|
||||
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) {
|
||||
|
||||
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,
|
||||
cs_x86_op * operand1,
|
||||
cs_x86_op *operand1,
|
||||
cs_x86_op *operand2) {
|
||||
|
||||
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) {
|
||||
|
||||
cs_x86 x86 = instr->detail->x86;
|
||||
|
@ -146,7 +146,7 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
|
||||
}
|
||||
|
||||
static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx,
|
||||
cs_x86_op * operand) {
|
||||
cs_x86_op *operand) {
|
||||
|
||||
ctx->type = operand->type;
|
||||
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) {
|
||||
|
||||
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,
|
||||
cs_x86_op * operand1,
|
||||
cs_x86_op *operand1,
|
||||
cs_x86_op *operand2) {
|
||||
|
||||
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) {
|
||||
|
||||
cs_x86 x86 = instr->detail->x86;
|
||||
|
@ -28,14 +28,14 @@ guint64 instrument_hash_seed = 0;
|
||||
|
||||
gboolean instrument_use_fixed_seed = FALSE;
|
||||
guint64 instrument_fixed_seed = 0;
|
||||
char * instrument_coverage_unstable_filename = NULL;
|
||||
char *instrument_coverage_unstable_filename = NULL;
|
||||
gboolean instrument_coverage_insn = FALSE;
|
||||
|
||||
static GumStalkerTransformer *transformer = NULL;
|
||||
|
||||
static GumAddress previous_rip = 0;
|
||||
static GumAddress previous_end = 0;
|
||||
static u8 * edges_notified = NULL;
|
||||
static u8 *edges_notified = NULL;
|
||||
|
||||
__thread guint64 instrument_previous_pc;
|
||||
__thread guint64 *instrument_previous_pc_addr = NULL;
|
||||
@ -149,7 +149,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context,
|
||||
}
|
||||
|
||||
static void instrument_basic_block(GumStalkerIterator *iterator,
|
||||
GumStalkerOutput * output,
|
||||
GumStalkerOutput *output,
|
||||
gpointer user_data) {
|
||||
|
||||
UNUSED_PARAMETER(user_data);
|
||||
@ -157,7 +157,7 @@ static void instrument_basic_block(GumStalkerIterator *iterator,
|
||||
const cs_insn *instr;
|
||||
gboolean begin = TRUE;
|
||||
gboolean excluded;
|
||||
block_ctx_t * ctx = NULL;
|
||||
block_ctx_t *ctx = NULL;
|
||||
|
||||
while (gum_stalker_iterator_next(iterator, &instr)) {
|
||||
|
||||
|
@ -14,7 +14,7 @@ gboolean instrument_is_coverage_optimize_supported(void) {
|
||||
|
||||
}
|
||||
|
||||
void instrument_coverage_optimize(const cs_insn * instr,
|
||||
void instrument_coverage_optimize(const cs_insn *instr,
|
||||
GumStalkerOutput *output) {
|
||||
|
||||
UNUSED_PARAMETER(instr);
|
||||
@ -23,7 +23,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) {
|
||||
|
||||
UNUSED_PARAMETER(instr);
|
||||
|
@ -159,8 +159,8 @@ static gboolean instrument_is_deterministic(const cs_insn *from_insn) {
|
||||
static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
gpointer from_address,
|
||||
gpointer start_address,
|
||||
const cs_insn * from_insn,
|
||||
gpointer * target) {
|
||||
const cs_insn *from_insn,
|
||||
gpointer *target) {
|
||||
|
||||
UNUSED_PARAMETER(self);
|
||||
UNUSED_PARAMETER(from_address);
|
||||
@ -218,7 +218,7 @@ static void instrument_coverage_suppress_init(void) {
|
||||
if (initialized) { return; }
|
||||
initialized = true;
|
||||
|
||||
GumStalkerObserver * observer = stalker_get_observer();
|
||||
GumStalkerObserver *observer = stalker_get_observer();
|
||||
GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer);
|
||||
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) {
|
||||
|
||||
afl_log_code code = {0};
|
||||
@ -345,7 +345,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) {
|
||||
|
||||
UNUSED_PARAMETER(instr);
|
||||
|
@ -17,7 +17,7 @@ static int unstable_coverage_fd = -1;
|
||||
static int unstable_coverage_pipes[2] = {-1, -1};
|
||||
|
||||
static uint64_t normal_coverage_last_start = 0;
|
||||
static gchar * unstable_coverage_fuzzer_stats = NULL;
|
||||
static gchar *unstable_coverage_fuzzer_stats = NULL;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@ -68,7 +68,7 @@ typedef struct {
|
||||
static gboolean coverage_range(const GumRangeDetails *details,
|
||||
gpointer user_data) {
|
||||
|
||||
GArray * coverage_ranges = (GArray *)user_data;
|
||||
GArray *coverage_ranges = (GArray *)user_data;
|
||||
coverage_range_t coverage = {0};
|
||||
|
||||
if (details->file == NULL) { return TRUE; }
|
||||
@ -210,8 +210,8 @@ static GArray *coverage_get_modules(void) {
|
||||
static void instrument_coverage_mark(void *key, void *value, void *user_data) {
|
||||
|
||||
UNUSED_PARAMETER(key);
|
||||
coverage_mark_ctx_t * ctx = (coverage_mark_ctx_t *)user_data;
|
||||
GArray * coverage_modules = ctx->modules;
|
||||
coverage_mark_ctx_t *ctx = (coverage_mark_ctx_t *)user_data;
|
||||
GArray *coverage_modules = ctx->modules;
|
||||
normal_coverage_data_t *val = (normal_coverage_data_t *)value;
|
||||
guint i;
|
||||
|
||||
@ -289,9 +289,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->limit);
|
||||
/* entry */
|
||||
coverage_format(fd, "%016" G_GINT64_MODIFIER "X, ", 0);
|
||||
coverage_format(fd, "%016" G_GINT64_MODIFIER "X, ", 0UL);
|
||||
/* checksum */
|
||||
coverage_format(fd, "%016" G_GINT64_MODIFIER "X, ", 0);
|
||||
coverage_format(fd, "%016" G_GINT64_MODIFIER "X, ", 0UL);
|
||||
/* timestamp */
|
||||
coverage_format(fd, "%08" G_GINT32_MODIFIER "X, ", 0);
|
||||
coverage_format(fd, "%s\n", module->path);
|
||||
@ -426,7 +426,7 @@ static void instrument_coverage_normal_run() {
|
||||
|
||||
static GArray *instrument_coverage_unstable_read_unstable_ids(void) {
|
||||
|
||||
gchar * contents = NULL;
|
||||
gchar *contents = NULL;
|
||||
gsize length = 0;
|
||||
GArray *unstable_edge_ids =
|
||||
g_array_sized_new(false, false, sizeof(gpointer), 100);
|
||||
@ -533,7 +533,7 @@ static GHashTable *instrument_collect_unstable_blocks(
|
||||
while (g_hash_table_iter_next(&iter, NULL, &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));
|
||||
normal_coverage_data_t *to = gum_malloc0(sizeof(normal_coverage_data_t));
|
||||
from->start = unstable->from;
|
||||
|
@ -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
|
||||
"x\n",
|
||||
curr, *(size_t *)curr);
|
||||
(uint64_t)curr, *(size_t *)curr);
|
||||
|
||||
len += sizeof(size_t);
|
||||
continue;
|
||||
|
@ -174,13 +174,13 @@ void instrument_coverage_optimize_init(void) {
|
||||
static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
gpointer from_address,
|
||||
gpointer start_address,
|
||||
const cs_insn * from_insn,
|
||||
gpointer * target) {
|
||||
const cs_insn *from_insn,
|
||||
gpointer *target) {
|
||||
|
||||
UNUSED_PARAMETER(self);
|
||||
UNUSED_PARAMETER(from_address);
|
||||
|
||||
cs_x86 * x86;
|
||||
cs_x86 *x86;
|
||||
cs_x86_op *op;
|
||||
if (from_insn == NULL) { return; }
|
||||
|
||||
@ -230,7 +230,7 @@ static void instrument_coverage_suppress_init(void) {
|
||||
if (initialized) { return; }
|
||||
initialized = true;
|
||||
|
||||
GumStalkerObserver * observer = stalker_get_observer();
|
||||
GumStalkerObserver *observer = stalker_get_observer();
|
||||
GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer);
|
||||
iface->switch_callback = instrument_coverage_switch;
|
||||
|
||||
@ -333,7 +333,7 @@ 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) {
|
||||
|
||||
GumX86Writer *cw = output->writer.x86;
|
||||
@ -364,7 +364,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) {
|
||||
|
||||
GumX86Writer *cw = output->writer.x86;
|
||||
|
@ -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) {
|
||||
|
||||
GumX86Writer *cw = output->writer.x86;
|
||||
cs_x86 * x86 = &instr->detail->x86;
|
||||
cs_x86 *x86 = &instr->detail->x86;
|
||||
guint8 modified[sizeof(instr->bytes)] = {0};
|
||||
guint8 offset = 0;
|
||||
guint8 skip = 0;
|
||||
@ -225,8 +225,8 @@ static void instrument_cache_rewrite_branch_insn(const cs_insn * instr,
|
||||
} else {
|
||||
|
||||
GumAddress target = instr->address + old_offset;
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, target);
|
||||
gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_RAX, GUM_REG_RAX);
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX, target);
|
||||
gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_X86_RAX, GUM_X86_RAX);
|
||||
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) {
|
||||
|
||||
gum_x86_writer_put_mov_reg_offset_ptr_reg(
|
||||
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer))),
|
||||
GUM_REG_XAX);
|
||||
cw, GUM_X86_XSP, -(GUM_RED_ZONE_SIZE + (1 * sizeof(gpointer))),
|
||||
GUM_X86_XAX);
|
||||
gum_x86_writer_put_lahf(cw);
|
||||
gum_x86_writer_put_mov_reg_offset_ptr_reg(
|
||||
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (2 * sizeof(gpointer))),
|
||||
GUM_REG_XAX);
|
||||
cw, GUM_X86_XSP, -(GUM_RED_ZONE_SIZE + (2 * sizeof(gpointer))),
|
||||
GUM_X86_XAX);
|
||||
gum_x86_writer_put_mov_reg_offset_ptr_reg(
|
||||
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (3 * sizeof(gpointer))),
|
||||
GUM_REG_XBX);
|
||||
cw, GUM_X86_XSP, -(GUM_RED_ZONE_SIZE + (3 * sizeof(gpointer))),
|
||||
GUM_X86_XBX);
|
||||
|
||||
}
|
||||
|
||||
static void instrument_cache_write_pop_frame(GumX86Writer *cw) {
|
||||
|
||||
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_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_x86_writer_put_sahf(cw);
|
||||
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))));
|
||||
|
||||
}
|
||||
@ -281,21 +281,21 @@ static void instrument_cache_write_lookup(GumX86Writer *cw) {
|
||||
/* &map_base[GPOINTER_TO_SIZE(addr) & MAP_MASK]; */
|
||||
|
||||
gsize mask = (instrument_cache_size / sizeof(gpointer)) - 1;
|
||||
gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_XBX, mask);
|
||||
gum_x86_writer_put_and_reg_reg(cw, GUM_REG_XAX, GUM_REG_XBX);
|
||||
gum_x86_writer_put_shl_reg_u8(cw, GUM_REG_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_add_reg_reg(cw, GUM_REG_XAX, GUM_REG_XBX);
|
||||
gum_x86_writer_put_mov_reg_u64(cw, GUM_X86_XBX, mask);
|
||||
gum_x86_writer_put_and_reg_reg(cw, GUM_X86_XAX, GUM_X86_XBX);
|
||||
gum_x86_writer_put_shl_reg_u8(cw, GUM_X86_XAX, util_log2(sizeof(gpointer)));
|
||||
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_X86_XAX, GUM_X86_XBX);
|
||||
|
||||
/* 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) {
|
||||
|
||||
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"); }
|
||||
|
||||
@ -315,7 +315,7 @@ void instrument_cache_jmp_call(const cs_insn *instr, GumStalkerOutput *output) {
|
||||
* red-zone.
|
||||
*/
|
||||
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))));
|
||||
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* If it's set, then stash the address beyond the red-zone */
|
||||
gum_x86_writer_put_mov_reg_offset_ptr_reg(
|
||||
cw, GUM_REG_XSP, -(GUM_RED_ZONE_SIZE + (4 * sizeof(gpointer))),
|
||||
GUM_REG_XAX);
|
||||
cw, GUM_X86_XSP, -(GUM_RED_ZONE_SIZE + (4 * sizeof(gpointer))),
|
||||
GUM_X86_XAX);
|
||||
|
||||
if (instr->id == X86_INS_JMP) {
|
||||
|
||||
instrument_cache_write_pop_frame(cw);
|
||||
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 {
|
||||
|
||||
gum_x86_writer_put_mov_reg_address(
|
||||
cw, GUM_REG_XAX, GUM_ADDRESS(instr->address + instr->size));
|
||||
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_XSP,
|
||||
-sizeof(gpointer), GUM_REG_XAX);
|
||||
cw, GUM_X86_XAX, GUM_ADDRESS(instr->address + instr->size));
|
||||
gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_X86_XSP,
|
||||
-sizeof(gpointer), GUM_X86_XAX);
|
||||
|
||||
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));
|
||||
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) {
|
||||
|
||||
GumX86Writer *cw = output->writer.x86;
|
||||
cs_x86 * x86 = &instr->detail->x86;
|
||||
cs_x86 *x86 = &instr->detail->x86;
|
||||
guint16 n = 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);
|
||||
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
if (n == 0) {
|
||||
|
@ -86,14 +86,14 @@ gboolean instrument_is_coverage_optimize_supported(void) {
|
||||
static void instrument_coverage_switch(GumStalkerObserver *self,
|
||||
gpointer from_address,
|
||||
gpointer start_address,
|
||||
const cs_insn * from_insn,
|
||||
gpointer * target) {
|
||||
const cs_insn *from_insn,
|
||||
gpointer *target) {
|
||||
|
||||
UNUSED_PARAMETER(self);
|
||||
UNUSED_PARAMETER(from_address);
|
||||
UNUSED_PARAMETER(start_address);
|
||||
|
||||
cs_x86 * x86;
|
||||
cs_x86 *x86;
|
||||
cs_x86_op *op;
|
||||
if (from_insn == NULL) { return; }
|
||||
|
||||
@ -136,7 +136,7 @@ static void instrument_coverage_suppress_init(void) {
|
||||
if (initialized) { return; }
|
||||
initialized = true;
|
||||
|
||||
GumStalkerObserver * observer = stalker_get_observer();
|
||||
GumStalkerObserver *observer = stalker_get_observer();
|
||||
GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer);
|
||||
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) {
|
||||
|
||||
afl_log_code code = {0};
|
||||
@ -223,7 +223,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) {
|
||||
|
||||
UNUSED_PARAMETER(instr);
|
||||
|
@ -7,16 +7,16 @@ gboolean js_done = FALSE;
|
||||
js_api_stalker_callback_t js_user_callback = NULL;
|
||||
js_main_hook_t js_main_hook = NULL;
|
||||
|
||||
static char * js_script = NULL;
|
||||
static gchar * filename = "afl.js";
|
||||
static gchar * contents;
|
||||
static GumScriptBackend * backend;
|
||||
static GCancellable * cancellable = NULL;
|
||||
static GError * error = NULL;
|
||||
static GumScript * script;
|
||||
static char *js_script = NULL;
|
||||
static gchar *filename = "afl.js";
|
||||
static gchar *contents;
|
||||
static GumScriptBackend *backend;
|
||||
static GCancellable *cancellable = NULL;
|
||||
static GError *error = NULL;
|
||||
static GumScript *script;
|
||||
static GumScriptScheduler *scheduler;
|
||||
static GMainContext * context;
|
||||
static GMainLoop * main_loop;
|
||||
static GMainContext *context;
|
||||
static GMainLoop *main_loop;
|
||||
|
||||
static void js_msg(GumScript *script, const gchar *message, GBytes *data,
|
||||
gpointer user_data) {
|
||||
|
@ -69,8 +69,8 @@ static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) {
|
||||
Elf_Addr preferred_base;
|
||||
Elf_Shdr *shdr;
|
||||
Elf_Shdr *shstrtab;
|
||||
char * shstr;
|
||||
char * section_name;
|
||||
char *shstr;
|
||||
char *section_name;
|
||||
Elf_Shdr *curr;
|
||||
char text_name[] = ".text";
|
||||
|
||||
|
@ -16,9 +16,9 @@ static gboolean lib_get_main_module(const GumModuleDetails *details,
|
||||
gpointer user_data) {
|
||||
|
||||
GumDarwinModule **ret = (GumDarwinModule **)user_data;
|
||||
GumDarwinModule * module = gum_darwin_module_new_from_memory(
|
||||
details->path, mach_task_self(), details->range->base_address,
|
||||
GUM_DARWIN_MODULE_FLAGS_NONE, NULL);
|
||||
GumDarwinModule *module = gum_darwin_module_new_from_memory(
|
||||
details->path, mach_task_self(), details->range->base_address,
|
||||
GUM_DARWIN_MODULE_FLAGS_NONE, NULL);
|
||||
|
||||
FVERBOSE("Found main module: %s", module->name);
|
||||
|
||||
|
@ -92,7 +92,7 @@ static void embedded_init(void) {
|
||||
static void afl_print_cmdline(void) {
|
||||
|
||||
#if defined(__linux__)
|
||||
char * buffer = g_malloc0(PROC_MAX);
|
||||
char *buffer = g_malloc0(PROC_MAX);
|
||||
gchar *fname = g_strdup_printf("/proc/%d/cmdline", getppid());
|
||||
int fd = open(fname, O_RDONLY);
|
||||
|
||||
@ -144,7 +144,7 @@ static void afl_print_cmdline(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());
|
||||
int fd = open(fname, O_RDONLY);
|
||||
|
||||
|
@ -31,7 +31,7 @@ typedef struct {
|
||||
gboolean found_range(const GumRangeDetails *details, gpointer user_data) {
|
||||
|
||||
gum_range_t range = {0};
|
||||
GArray * ranges = (GArray *)user_data;
|
||||
GArray *ranges = (GArray *)user_data;
|
||||
|
||||
range.range = *details->range;
|
||||
range.protection = details->protection;
|
||||
@ -45,9 +45,9 @@ gboolean found_range(const GumRangeDetails *details, gpointer user_data) {
|
||||
#if defined(__linux__) && !defined(__ANDROID__)
|
||||
static int on_dlclose(void *handle) {
|
||||
|
||||
GArray * ranges = NULL;
|
||||
GArray *ranges = NULL;
|
||||
struct link_map *lm = NULL;
|
||||
gum_range_t * range = NULL;
|
||||
gum_range_t *range = NULL;
|
||||
GumAddress base;
|
||||
GumAddress limit;
|
||||
gpointer mem;
|
||||
|
@ -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) {
|
||||
|
||||
GumAddress regs_address = GUM_ADDRESS(regs);
|
||||
@ -105,18 +105,13 @@ static void instrument_persitent_save_regs(GumArm64Writer * cw,
|
||||
offsetof(persistent_ctx_t, rflags));
|
||||
|
||||
/* Q */
|
||||
gum_arm64_writer_put_stp_reg_reg_reg_offset(
|
||||
cw, ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_X0,
|
||||
offsetof(GumCpuContext, q[0]), GUM_INDEX_SIGNED_OFFSET);
|
||||
gum_arm64_writer_put_stp_reg_reg_reg_offset(
|
||||
cw, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_X0,
|
||||
offsetof(GumCpuContext, q[16]), GUM_INDEX_SIGNED_OFFSET);
|
||||
gum_arm64_writer_put_stp_reg_reg_reg_offset(
|
||||
cw, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_X0,
|
||||
offsetof(GumCpuContext, q[32]), GUM_INDEX_SIGNED_OFFSET);
|
||||
gum_arm64_writer_put_stp_reg_reg_reg_offset(
|
||||
cw, ARM64_REG_Q6, ARM64_REG_Q7, ARM64_REG_X0,
|
||||
offsetof(GumCpuContext, q[48]), GUM_INDEX_SIGNED_OFFSET);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
|
||||
gum_arm64_writer_put_stp_reg_reg_reg_offset(
|
||||
cw, ARM64_REG_Q0 + (i * 2), ARM64_REG_Q0 + (i * 2) + 1, ARM64_REG_X0,
|
||||
offsetof(GumCpuContext, v[i]), GUM_INDEX_SIGNED_OFFSET);
|
||||
|
||||
}
|
||||
|
||||
/* x0 & x1 */
|
||||
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) {
|
||||
|
||||
GumAddress regs_address = GUM_ADDRESS(regs);
|
||||
@ -201,18 +196,14 @@ static void instrument_persitent_restore_regs(GumArm64Writer * cw,
|
||||
offsetof(persistent_ctx_t, rflags));
|
||||
gum_arm64_writer_put_instruction(cw, msr_nzcv_x1);
|
||||
|
||||
gum_arm64_writer_put_ldp_reg_reg_reg_offset(
|
||||
cw, ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_X0,
|
||||
offsetof(GumCpuContext, q[0]), GUM_INDEX_SIGNED_OFFSET);
|
||||
gum_arm64_writer_put_ldp_reg_reg_reg_offset(
|
||||
cw, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_X0,
|
||||
offsetof(GumCpuContext, q[16]), GUM_INDEX_SIGNED_OFFSET);
|
||||
gum_arm64_writer_put_ldp_reg_reg_reg_offset(
|
||||
cw, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_X0,
|
||||
offsetof(GumCpuContext, q[32]), GUM_INDEX_SIGNED_OFFSET);
|
||||
gum_arm64_writer_put_ldp_reg_reg_reg_offset(
|
||||
cw, ARM64_REG_Q6, ARM64_REG_Q7, ARM64_REG_X0,
|
||||
offsetof(GumCpuContext, q[48]), GUM_INDEX_SIGNED_OFFSET);
|
||||
/* Q */
|
||||
for (int i = 0; i < 16; i++) {
|
||||
|
||||
gum_arm64_writer_put_ldp_reg_reg_reg_offset(
|
||||
cw, ARM64_REG_Q0 + (i * 2), ARM64_REG_Q0 + (i * 2) + 1, ARM64_REG_X0,
|
||||
offsetof(GumCpuContext, v[i]), GUM_INDEX_SIGNED_OFFSET);
|
||||
|
||||
}
|
||||
|
||||
/* x2 & x3 */
|
||||
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) {
|
||||
|
||||
if (persistent_hook == NULL) return;
|
||||
|
@ -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) {
|
||||
|
||||
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));
|
||||
|
||||
/* Should be pushing FPU here, but meh */
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
cw, GUM_REG_RAX, offsetof(GumCpuContext, r15), GUM_REG_R15);
|
||||
cw, GUM_X86_RAX, offsetof(GumCpuContext, r15), GUM_X86_R15);
|
||||
|
||||
/* 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_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 */
|
||||
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 */
|
||||
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_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 */
|
||||
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(
|
||||
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 */
|
||||
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(
|
||||
cw, GUM_REG_RAX, offsetof(GumCpuContext, rax), GUM_REG_RBX);
|
||||
cw, GUM_X86_RAX, offsetof(GumCpuContext, rax), GUM_X86_RBX);
|
||||
|
||||
/* 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));
|
||||
|
||||
}
|
||||
|
||||
static void instrument_persitent_restore_regs(GumX86Writer * cw,
|
||||
static void instrument_persitent_restore_regs(GumX86Writer *cw,
|
||||
persistent_ctx_t *regs) {
|
||||
|
||||
GumAddress regs_address = GUM_ADDRESS(regs);
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, regs_address);
|
||||
gum_x86_writer_put_mov_reg_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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
|
||||
/* 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));
|
||||
|
||||
/* 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_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));
|
||||
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));
|
||||
gum_x86_writer_put_push_reg(cw, GUM_REG_RBX);
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX,
|
||||
gum_x86_writer_put_push_reg(cw, GUM_X86_RBX);
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_RBX, GUM_X86_RAX,
|
||||
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_pop_reg(cw, GUM_REG_RAX);
|
||||
gum_x86_writer_put_pop_reg(cw, GUM_REG_RBX);
|
||||
gum_x86_writer_put_pop_reg(cw, GUM_X86_RAX);
|
||||
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));
|
||||
|
||||
}
|
||||
|
||||
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_u32(cw, GUM_REG_RDI, 0);
|
||||
gum_x86_writer_put_call_reg(cw, GUM_REG_RAX);
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX, GUM_ADDRESS(_exit));
|
||||
gum_x86_writer_put_mov_reg_u32(cw, GUM_X86_RDI, 0);
|
||||
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) {
|
||||
|
||||
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_x86_writer_put_call_address_with_arguments(
|
||||
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));
|
||||
|
||||
}
|
||||
@ -200,26 +200,26 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) {
|
||||
static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) {
|
||||
|
||||
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_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_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0);
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0);
|
||||
gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_RDI, 0xffffffff);
|
||||
gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RDX, GUM_REG_RDI);
|
||||
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_X86_RDX, GUM_X86_RDX, 0);
|
||||
gum_x86_writer_put_mov_reg_u64(cw, GUM_X86_RDI, 0xffffffff);
|
||||
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_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(
|
||||
cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS,
|
||||
GUM_ADDRESS(®s->ctx), GUM_ARG_REGISTER, GUM_REG_RSI, GUM_ARG_REGISTER,
|
||||
GUM_REG_RDX);
|
||||
GUM_ADDRESS(®s->ctx), GUM_ARG_REGISTER, GUM_X86_RSI, GUM_ARG_REGISTER,
|
||||
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));
|
||||
|
||||
}
|
||||
@ -228,23 +228,23 @@ static void instrument_persitent_save_ret(GumX86Writer *cw) {
|
||||
|
||||
/* Stack usage by this function */
|
||||
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_x86_writer_put_pushfx(cw);
|
||||
gum_x86_writer_put_push_reg(cw, GUM_REG_RAX);
|
||||
gum_x86_writer_put_push_reg(cw, GUM_REG_RBX);
|
||||
gum_x86_writer_put_push_reg(cw, GUM_X86_RAX);
|
||||
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_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP,
|
||||
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_X86_RBX, GUM_X86_RSP,
|
||||
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_REG_RAX);
|
||||
gum_x86_writer_put_pop_reg(cw, GUM_X86_RBX);
|
||||
gum_x86_writer_put_pop_reg(cw, GUM_X86_RAX);
|
||||
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));
|
||||
|
||||
}
|
||||
@ -278,7 +278,7 @@ void persistent_prologue_arch(GumStalkerOutput *output) {
|
||||
FVERBOSE("Persistent loop reached");
|
||||
|
||||
/* 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);
|
||||
|
||||
@ -326,13 +326,13 @@ void persistent_epilogue_arch(GumStalkerOutput *output) {
|
||||
|
||||
/* The stack should be aligned when we re-enter our loop */
|
||||
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_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_mov_reg_address(cw, GUM_REG_RAX, GUM_ADDRESS(&saved_ret));
|
||||
gum_x86_writer_put_jmp_reg_ptr(cw, GUM_REG_RAX);
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_RAX, GUM_ADDRESS(&saved_ret));
|
||||
gum_x86_writer_put_jmp_reg_ptr(cw, GUM_X86_RAX);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
||||
GumAddress regs_address = GUM_ADDRESS(regs);
|
||||
|
||||
/* Should be pushing FPU here, but meh */
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
cw, GUM_REG_EAX, offsetof(GumCpuContext, ebp), GUM_REG_EBP);
|
||||
cw, GUM_X86_EAX, offsetof(GumCpuContext, ebp), GUM_X86_EBP);
|
||||
|
||||
/* 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_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 */
|
||||
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 */
|
||||
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(
|
||||
cw, GUM_REG_EAX, offsetof(GumCpuContext, esp), GUM_REG_EBX);
|
||||
cw, GUM_X86_EAX, offsetof(GumCpuContext, esp), GUM_X86_EBX);
|
||||
|
||||
/* Save the flags */
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x4);
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EBX, GUM_X86_ESP, 0x4);
|
||||
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 */
|
||||
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(
|
||||
cw, GUM_REG_EAX, offsetof(GumCpuContext, eax), GUM_REG_EBX);
|
||||
cw, GUM_X86_EAX, offsetof(GumCpuContext, eax), GUM_X86_EBX);
|
||||
|
||||
/* 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) {
|
||||
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
|
||||
/* 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));
|
||||
|
||||
/* 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));
|
||||
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));
|
||||
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX);
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX,
|
||||
gum_x86_writer_put_push_reg(cw, GUM_X86_EBX);
|
||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EBX, GUM_X86_EAX,
|
||||
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_pop_reg(cw, GUM_REG_EAX);
|
||||
gum_x86_writer_put_pop_reg(cw, GUM_REG_EBX);
|
||||
gum_x86_writer_put_pop_reg(cw, GUM_X86_EAX);
|
||||
gum_x86_writer_put_pop_reg(cw, GUM_X86_EBX);
|
||||
|
||||
}
|
||||
|
||||
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_u32(cw, GUM_REG_EDI, 0);
|
||||
gum_x86_writer_put_push_reg(cw, GUM_REG_EDI);
|
||||
gum_x86_writer_put_call_reg(cw, GUM_REG_EAX);
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(_exit));
|
||||
gum_x86_writer_put_mov_reg_u32(cw, GUM_X86_EDI, 0);
|
||||
gum_x86_writer_put_push_reg(cw, GUM_X86_EDI);
|
||||
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(
|
||||
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;
|
||||
|
||||
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_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_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_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_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) */
|
||||
gum_x86_writer_put_call_address_with_arguments(
|
||||
cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS,
|
||||
GUM_ADDRESS(®s->ctx), GUM_ARG_REGISTER, GUM_REG_EDX, GUM_ARG_REGISTER,
|
||||
GUM_REG_ECX);
|
||||
GUM_ADDRESS(®s->ctx), GUM_ARG_REGISTER, GUM_X86_EDX, GUM_ARG_REGISTER,
|
||||
GUM_X86_ECX);
|
||||
|
||||
}
|
||||
|
||||
@ -176,16 +176,16 @@ static void instrument_persitent_save_ret(GumX86Writer *cw) {
|
||||
gssize offset = (3 * 4);
|
||||
|
||||
gum_x86_writer_put_pushfx(cw);
|
||||
gum_x86_writer_put_push_reg(cw, GUM_REG_EAX);
|
||||
gum_x86_writer_put_push_reg(cw, GUM_REG_EBX);
|
||||
gum_x86_writer_put_push_reg(cw, GUM_X86_EAX);
|
||||
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_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP,
|
||||
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_X86_EBX, GUM_X86_ESP,
|
||||
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_REG_EAX);
|
||||
gum_x86_writer_put_pop_reg(cw, GUM_X86_EBX);
|
||||
gum_x86_writer_put_pop_reg(cw, GUM_X86_EAX);
|
||||
gum_x86_writer_put_popfx(cw);
|
||||
|
||||
}
|
||||
@ -219,7 +219,7 @@ void persistent_prologue_arch(GumStalkerOutput *output) {
|
||||
FVERBOSE("Persistent loop reached");
|
||||
|
||||
/* 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);
|
||||
|
||||
@ -263,8 +263,8 @@ void persistent_epilogue_arch(GumStalkerOutput *output) {
|
||||
|
||||
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_jmp_reg_ptr(cw, GUM_REG_EAX);
|
||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(&saved_ret));
|
||||
gum_x86_writer_put_jmp_reg_ptr(cw, GUM_X86_EAX);
|
||||
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
typedef struct {
|
||||
|
||||
size_t count;
|
||||
void * entry[PREFETCH_ENTRIES];
|
||||
void *entry[PREFETCH_ENTRIES];
|
||||
|
||||
guint8 backpatch_data[BP_SIZE];
|
||||
gsize backpatch_size;
|
||||
@ -173,7 +173,7 @@ static void prefetch_read_blocks(void) {
|
||||
static void prefetch_read_patches(void) {
|
||||
|
||||
gsize offset = 0;
|
||||
GumStalker * stalker = stalker_get();
|
||||
GumStalker *stalker = stalker_get();
|
||||
GumBackpatch *backpatch = NULL;
|
||||
|
||||
for (gsize remaining = prefetch_data->backpatch_size - offset;
|
||||
@ -319,7 +319,7 @@ void prefetch_init(void) {
|
||||
|
||||
if (!prefetch_backpatch) { return; }
|
||||
|
||||
GumStalkerObserver * observer = stalker_get_observer();
|
||||
GumStalkerObserver *observer = stalker_get_observer();
|
||||
GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer);
|
||||
iface->notify_backpatch = gum_afl_stalker_backpatcher_notify;
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
typedef struct {
|
||||
|
||||
gchar * suffix;
|
||||
gchar *suffix;
|
||||
GumMemoryRange *range;
|
||||
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) {
|
||||
|
||||
gchar * suffix = g_strconcat("/", token, NULL);
|
||||
gchar *suffix = g_strconcat("/", token, NULL);
|
||||
convert_name_ctx_t ctx = {.suffix = suffix, .range = range, .done = false};
|
||||
|
||||
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,
|
||||
gpointer user_data) {
|
||||
|
||||
GArray * ranges = (GArray *)user_data;
|
||||
GArray *ranges = (GArray *)user_data;
|
||||
GumMemoryRange range = *details->range;
|
||||
g_array_append_val(ranges, range);
|
||||
return TRUE;
|
||||
@ -292,12 +292,12 @@ void ranges_add_exclude(GumMemoryRange *range) {
|
||||
|
||||
static GArray *collect_ranges(char *env_key) {
|
||||
|
||||
char * env_val;
|
||||
gchar ** tokens;
|
||||
char *env_val;
|
||||
gchar **tokens;
|
||||
int token_count;
|
||||
GumMemoryRange range;
|
||||
int i;
|
||||
GArray * result;
|
||||
GArray *result;
|
||||
|
||||
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) {
|
||||
|
||||
GArray * result;
|
||||
GArray *result;
|
||||
GumMemoryRange range;
|
||||
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) {
|
||||
|
||||
GArray * result;
|
||||
GArray *result;
|
||||
GumMemoryRange *ra;
|
||||
GumMemoryRange *rb;
|
||||
GumMemoryRange ri;
|
||||
@ -452,7 +452,7 @@ static GArray *intersect_ranges(GArray *a, GArray *b) {
|
||||
|
||||
static GArray *subtract_ranges(GArray *a, GArray *b) {
|
||||
|
||||
GArray * result;
|
||||
GArray *result;
|
||||
GumMemoryRange *ra;
|
||||
GumAddress ral;
|
||||
GumMemoryRange *rb;
|
||||
@ -528,7 +528,7 @@ static GArray *subtract_ranges(GArray *a, GArray *b) {
|
||||
|
||||
static GArray *merge_ranges(GArray *a) {
|
||||
|
||||
GArray * result;
|
||||
GArray *result;
|
||||
GumMemoryRange rp;
|
||||
GumMemoryRange *r;
|
||||
|
||||
@ -585,11 +585,11 @@ void ranges_config(void) {
|
||||
void ranges_init(void) {
|
||||
|
||||
GumMemoryRange ri;
|
||||
GArray * step1;
|
||||
GArray * step2;
|
||||
GArray * step3;
|
||||
GArray * step4;
|
||||
GArray * step5;
|
||||
GArray *step1;
|
||||
GArray *step2;
|
||||
GArray *step3;
|
||||
GArray *step4;
|
||||
GArray *step5;
|
||||
|
||||
FOKF(cBLU "Ranges" cRST " - " cGRN "instrument jit:" cYEL " [%c]",
|
||||
ranges_inst_jit ? 'X' : ' ');
|
||||
@ -669,7 +669,7 @@ gboolean range_is_excluded(GumAddress address) {
|
||||
void ranges_exclude() {
|
||||
|
||||
GumMemoryRange *r;
|
||||
GumStalker * stalker = stalker_get();
|
||||
GumStalker *stalker = stalker_get();
|
||||
|
||||
FVERBOSE("Excluding ranges");
|
||||
|
||||
|
@ -8,9 +8,9 @@
|
||||
#include "seccomp.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,
|
||||
GumReturnAddressArray * frames) {
|
||||
GumReturnAddressArray *frames) {
|
||||
|
||||
GumDebugSymbolDetails details = {0};
|
||||
if (req->data.nr == SYS_OPENAT) {
|
||||
@ -54,7 +54,7 @@ static void seccomp_callback_filter(struct seccomp_notif * req,
|
||||
free(syms);
|
||||
#else
|
||||
void **syms = (void **)__builtin_frame_address(0);
|
||||
void * framep = __builtin_frame_address(1);
|
||||
void *framep = __builtin_frame_address(1);
|
||||
int i = 0;
|
||||
|
||||
syms = framep;
|
||||
|
@ -21,7 +21,7 @@ typedef struct {
|
||||
|
||||
seccomp_child_func_t func;
|
||||
int event_fd;
|
||||
void * ctx;
|
||||
void *ctx;
|
||||
|
||||
} seccomp_child_func_ctx_t;
|
||||
|
||||
|
@ -129,7 +129,7 @@ static volatile bool seccomp_filter_child_done = false;
|
||||
static pid_t seccomp_filter_child = -1;
|
||||
static GumCpuContext seccomp_filter_cpu_context = {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,
|
||||
void *ucontext) {
|
||||
@ -209,7 +209,7 @@ int seccomp_filter_install(pid_t child) {
|
||||
|
||||
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_sizes sizes;
|
||||
|
||||
|
@ -59,9 +59,9 @@ void seccomp_socket_send(int sockfd, int fd) {
|
||||
struct iovec iov = {.iov_base = &data, .iov_len = sizeof(data)};
|
||||
union cmsg control_msg = {.hdr = {
|
||||
|
||||
.cmsg_len = CMSG_LEN(sizeof(int)),
|
||||
.cmsg_level = SOL_SOCKET,
|
||||
.cmsg_type = SCM_RIGHTS,
|
||||
.cmsg_len = CMSG_LEN(sizeof(int)),
|
||||
.cmsg_level = SOL_SOCKET,
|
||||
.cmsg_type = SCM_RIGHTS,
|
||||
|
||||
}};
|
||||
|
||||
|
@ -74,7 +74,7 @@ static gboolean stalker_exclude_self(const GumRangeDetails *details,
|
||||
gpointer user_data) {
|
||||
|
||||
UNUSED_PARAMETER(user_data);
|
||||
gchar * name;
|
||||
gchar *name;
|
||||
gboolean found;
|
||||
GumStalker *stalker;
|
||||
if (details->file == NULL) { return TRUE; }
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#define MICRO_TO_SEC 1000000
|
||||
|
||||
char * stats_filename = NULL;
|
||||
char *stats_filename = NULL;
|
||||
guint64 stats_interval = 0;
|
||||
static guint64 stats_interval_us = 0;
|
||||
static int stats_fd = -1;
|
||||
@ -41,8 +41,8 @@ void stats_write(void) {
|
||||
stats_data->curr.stats_time = current_time;
|
||||
|
||||
GDateTime *date_time = g_date_time_new_now_local();
|
||||
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 *date_string = g_date_time_format(date_time, "%Y-%m-%d");
|
||||
char *time_string = g_date_time_format(date_time, "%H:%M:%S");
|
||||
guint elapsed = (stats_data->curr.stats_time - stats_data->prev.stats_time) /
|
||||
MICRO_TO_SEC;
|
||||
|
||||
|
@ -248,7 +248,7 @@ void stats_write_arch(stats_data_t *data) {
|
||||
|
||||
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;
|
||||
|
||||
if (x86->op_count != 1) {
|
||||
@ -266,7 +266,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) {
|
||||
|
||||
cs_x86 * x86 = &instr->detail->x86;
|
||||
cs_x86 *x86 = &instr->detail->x86;
|
||||
cs_x86_op *operand = &x86->operands[0];
|
||||
|
||||
if (range_is_excluded(GUM_ADDRESS(operand->imm))) {
|
||||
|
@ -188,7 +188,7 @@ struct queue_entry {
|
||||
|
||||
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 queue_entry *mother; /* queue entry this based on */
|
||||
@ -341,18 +341,18 @@ typedef struct py_mutator {
|
||||
|
||||
PyObject *py_module;
|
||||
PyObject *py_functions[PY_FUNC_COUNT];
|
||||
void * afl_state;
|
||||
void * py_data;
|
||||
void *afl_state;
|
||||
void *py_data;
|
||||
|
||||
u8 * fuzz_buf;
|
||||
u8 *fuzz_buf;
|
||||
size_t fuzz_size;
|
||||
|
||||
Py_buffer post_process_buf;
|
||||
|
||||
u8 * trim_buf;
|
||||
u8 *trim_buf;
|
||||
size_t trim_size;
|
||||
|
||||
u8 * havoc_buf;
|
||||
u8 *havoc_buf;
|
||||
size_t havoc_size;
|
||||
|
||||
} py_mutator_t;
|
||||
@ -361,13 +361,13 @@ typedef struct py_mutator {
|
||||
|
||||
typedef struct MOpt_globals {
|
||||
|
||||
u64 * finds;
|
||||
u64 * finds_v2;
|
||||
u64 * cycles;
|
||||
u64 * cycles_v2;
|
||||
u64 * cycles_v3;
|
||||
u64 *finds;
|
||||
u64 *finds_v2;
|
||||
u64 *cycles;
|
||||
u64 *cycles_v2;
|
||||
u64 *cycles_v3;
|
||||
u32 is_pilot_mode;
|
||||
u64 * pTime;
|
||||
u64 *pTime;
|
||||
u64 period;
|
||||
char *havoc_stagename;
|
||||
char *splice_stageformat;
|
||||
@ -406,7 +406,7 @@ struct afl_pass_stat {
|
||||
|
||||
struct foreign_sync {
|
||||
|
||||
u8 * dir;
|
||||
u8 *dir;
|
||||
time_t mtime;
|
||||
|
||||
};
|
||||
@ -418,7 +418,7 @@ typedef struct afl_state {
|
||||
|
||||
afl_forkserver_t fsrv;
|
||||
sharedmem_t shm;
|
||||
sharedmem_t * shm_fuzz;
|
||||
sharedmem_t *shm_fuzz;
|
||||
afl_env_vars_t afl_env;
|
||||
|
||||
char **argv; /* argv if needed */
|
||||
@ -529,7 +529,7 @@ typedef struct afl_state {
|
||||
*virgin_crash; /* Bits we haven't seen in crashes */
|
||||
|
||||
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 */
|
||||
|
||||
u8 *var_bytes; /* Bytes that appear to be variable */
|
||||
@ -643,7 +643,7 @@ typedef struct afl_state {
|
||||
|
||||
/* CmpLog */
|
||||
|
||||
char * cmplog_binary;
|
||||
char *cmplog_binary;
|
||||
afl_forkserver_t cmplog_fsrv; /* cmplog has its own little forkserver */
|
||||
|
||||
/* Custom mutators */
|
||||
@ -658,7 +658,7 @@ typedef struct afl_state {
|
||||
u8 cmplog_enable_arith, cmplog_enable_transform;
|
||||
|
||||
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
|
||||
up to 256 */
|
||||
@ -690,9 +690,9 @@ typedef struct afl_state {
|
||||
u64 statsd_last_send_ms;
|
||||
struct sockaddr_in statsd_server;
|
||||
int statsd_sock;
|
||||
char * statsd_tags_flavor;
|
||||
char * statsd_tags_format;
|
||||
char * statsd_metric_format;
|
||||
char *statsd_tags_flavor;
|
||||
char *statsd_tags_format;
|
||||
char *statsd_metric_format;
|
||||
int statsd_metric_format_type;
|
||||
|
||||
double stats_avg_exec;
|
||||
@ -770,9 +770,9 @@ typedef struct afl_state {
|
||||
struct custom_mutator {
|
||||
|
||||
const char *name;
|
||||
char * name_short;
|
||||
void * dh;
|
||||
u8 * post_process_buf;
|
||||
char *name_short;
|
||||
void *dh;
|
||||
u8 *post_process_buf;
|
||||
u8 stacked_custom_prob, stacked_custom;
|
||||
|
||||
void *data; /* custom mutator data ptr */
|
||||
|
@ -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_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_afl_env(char *env);
|
||||
char *get_afl_env(char *env);
|
||||
|
||||
/* Extract env vars from input string and set them using setenv()
|
||||
For use with AFL_TARGET_ENV, ... */
|
||||
|
@ -26,7 +26,7 @@
|
||||
/* Version string: */
|
||||
|
||||
// c = release, a = volatile github dev, e = experimental branch
|
||||
#define VERSION "++4.01c"
|
||||
#define VERSION "++4.02a"
|
||||
|
||||
/******************************************************
|
||||
* *
|
||||
|
@ -192,7 +192,7 @@ static inline const char *colorfilter(const char *x) {
|
||||
if (likely(disabled)) return x;
|
||||
|
||||
static char monochromestring[4096];
|
||||
char * d = monochromestring;
|
||||
char *d = monochromestring;
|
||||
int in_seq = 0;
|
||||
|
||||
while (*x) {
|
||||
|
@ -150,7 +150,7 @@ typedef struct afl_forkserver {
|
||||
#ifdef AFL_PERSISTENT_RECORD
|
||||
u32 persistent_record_idx; /* persistent replay cache ptr */
|
||||
u32 persistent_record_cnt; /* persistent replay counter */
|
||||
u8 * persistent_record_dir;
|
||||
u8 *persistent_record_dir;
|
||||
u8 **persistent_record_data;
|
||||
u32 *persistent_record_len;
|
||||
s32 persistent_record_pid;
|
||||
@ -168,14 +168,14 @@ typedef struct afl_forkserver {
|
||||
|
||||
#ifdef __linux__
|
||||
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 */
|
||||
bool nyx_parent; /* create initial 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_bind_cpu_id; /* nyx runner cpu id */
|
||||
char * nyx_aux_string;
|
||||
char *nyx_aux_string;
|
||||
#endif
|
||||
|
||||
} afl_forkserver_t;
|
||||
|
@ -43,7 +43,7 @@ typedef struct list_element {
|
||||
|
||||
struct list_element *prev;
|
||||
struct list_element *next;
|
||||
void * data;
|
||||
void *data;
|
||||
|
||||
} element_t;
|
||||
|
||||
@ -102,7 +102,7 @@ static inline void list_append(list_t *list, void *el) {
|
||||
#define LIST_FOREACH(list, type, block) \
|
||||
do { \
|
||||
\
|
||||
list_t * li = (list); \
|
||||
list_t *li = (list); \
|
||||
element_t *head = get_head((li)); \
|
||||
element_t *el_box = (head)->next; \
|
||||
if (!el_box) FATAL("foreach over uninitialized list"); \
|
||||
|
@ -56,7 +56,7 @@ typedef struct sharedmem {
|
||||
|
||||
} 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 *);
|
||||
|
||||
#endif
|
||||
|
@ -510,7 +510,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t *statePtr);
|
||||
* @pre
|
||||
* @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);
|
||||
|
||||
/*!
|
||||
@ -742,10 +742,10 @@ XXH_PUBLIC_API XXH64_hash_t XXH64(const void *input, size_t length,
|
||||
*
|
||||
* @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 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);
|
||||
|
||||
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.
|
||||
*/
|
||||
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 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);
|
||||
|
||||
/*
|
||||
@ -902,7 +902,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(
|
||||
XXH3_state_t *statePtr, const void *secret, size_t secretSize);
|
||||
|
||||
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update(XXH3_state_t *statePtr,
|
||||
const void * input,
|
||||
const void *input,
|
||||
size_t length);
|
||||
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);
|
||||
|
||||
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update(XXH3_state_t *statePtr,
|
||||
const void * input,
|
||||
const void *input,
|
||||
size_t length);
|
||||
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
|
||||
* undefined behavior.
|
||||
*/
|
||||
XXH_PUBLIC_API void XXH3_generateSecret(void * secretBuffer,
|
||||
XXH_PUBLIC_API void XXH3_generateSecret(void *secretBuffer,
|
||||
const void *customSeed,
|
||||
size_t customSeedSize);
|
||||
|
||||
@ -1951,7 +1951,7 @@ static xxh_u32 XXH_readBE32(const void *ptr) {
|
||||
|
||||
#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) {
|
||||
|
||||
if (align == XXH_unaligned) {
|
||||
@ -2317,7 +2317,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t *statePtr) {
|
||||
}
|
||||
|
||||
/*! @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) {
|
||||
|
||||
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;
|
||||
|
||||
state->total_len_32 += (XXH32_hash_t)len;
|
||||
@ -2625,7 +2625,7 @@ static xxh_u64 XXH_readBE64(const void *ptr) {
|
||||
|
||||
#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) {
|
||||
|
||||
if (align == XXH_unaligned)
|
||||
@ -2852,7 +2852,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t *statePtr) {
|
||||
}
|
||||
|
||||
/*! @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) {
|
||||
|
||||
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;
|
||||
|
||||
state->total_len += len;
|
||||
@ -4268,7 +4268,7 @@ XXH_FORCE_INLINE XXH_TARGET_AVX512 void XXH3_initCustomSecret_avx512(
|
||||
union {
|
||||
|
||||
const __m512i *cp;
|
||||
void * p;
|
||||
void *p;
|
||||
|
||||
} remote_const_void;
|
||||
|
||||
@ -4385,7 +4385,7 @@ XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(
|
||||
(xxh_i64)(0U - seed64), (xxh_i64)seed64);
|
||||
|
||||
const __m256i *const src = (const __m256i *)((const void *)XXH3_kSecret);
|
||||
__m256i * dest = (__m256i *)customSecret;
|
||||
__m256i *dest = (__m256i *)customSecret;
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
/*
|
||||
@ -4519,7 +4519,7 @@ XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_initCustomSecret_sse2(
|
||||
int i;
|
||||
|
||||
const void *const src16 = XXH3_kSecret;
|
||||
__m128i * dst16 = (__m128i *)customSecret;
|
||||
__m128i *dst16 = (__m128i *)customSecret;
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
/*
|
||||
* 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;
|
||||
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.
|
||||
*/
|
||||
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,
|
||||
XXH64_hash_t seed,
|
||||
const xxh_u8 *secret,
|
||||
@ -5277,7 +5277,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t *statePtr) {
|
||||
}
|
||||
|
||||
/*! @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) {
|
||||
|
||||
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,
|
||||
const XXH3_state_t * state,
|
||||
XXH_FORCE_INLINE void XXH3_digest_long(XXH64_hash_t *acc,
|
||||
const XXH3_state_t *state,
|
||||
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))
|
||||
|
||||
/*! @ingroup xxh3_family */
|
||||
XXH_PUBLIC_API void XXH3_generateSecret(void * secretBuffer,
|
||||
XXH_PUBLIC_API void XXH3_generateSecret(void *secretBuffer,
|
||||
const void *customSeed,
|
||||
size_t customSeedSize) {
|
||||
|
||||
@ -6081,7 +6081,7 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void *input,
|
||||
}
|
||||
|
||||
/*! @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,
|
||||
XXH64_hash_t seed) {
|
||||
|
||||
@ -6142,7 +6142,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t *statePtr,
|
||||
|
||||
/*! @ingroup xxh3_family */
|
||||
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update(XXH3_state_t *state,
|
||||
const void * input,
|
||||
const void *input,
|
||||
size_t len) {
|
||||
|
||||
return XXH3_update(state, (const xxh_u8 *)input, len, XXH3_accumulate_512,
|
||||
|
@ -99,4 +99,11 @@ See
|
||||
## 6) Bonus feature #3: selective instrumentation
|
||||
|
||||
It can be more effective to fuzzing to only instrument parts of the code. For
|
||||
details, see [README.instrument_list.md](README.instrument_list.md).
|
||||
details, see [README.instrument_list.md](README.instrument_list.md).
|
||||
|
||||
## 7) Bonus feature #4: CMPLOG
|
||||
|
||||
The gcc_plugin also support CMPLOG/Redqueen, just set `AFL_GCC_CMPLOG` before
|
||||
instrumenting the target.
|
||||
Read more about this in the llvm document.
|
||||
|
||||
|
@ -182,7 +182,7 @@ class ModuleSanitizerCoverageLTO
|
||||
private:
|
||||
void instrumentFunction(Function &F, DomTreeCallback DTCallback,
|
||||
PostDomTreeCallback PDTCallback);
|
||||
void InjectCoverageForIndirectCalls(Function & F,
|
||||
void InjectCoverageForIndirectCalls(Function &F,
|
||||
ArrayRef<Instruction *> IndirCalls);
|
||||
bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
|
||||
bool IsLeafFunc = true);
|
||||
@ -211,10 +211,10 @@ class ModuleSanitizerCoverageLTO
|
||||
FunctionCallee SanCovTracePC /*, SanCovTracePCGuard*/;
|
||||
Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
|
||||
*Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty, *Int1PtrTy;
|
||||
Module * CurModule;
|
||||
Module *CurModule;
|
||||
std::string CurModuleUniqueId;
|
||||
Triple TargetTriple;
|
||||
LLVMContext * C;
|
||||
LLVMContext *C;
|
||||
const DataLayout *DL;
|
||||
|
||||
GlobalVariable *FunctionGuardArray; // for trace-pc-guard.
|
||||
@ -235,20 +235,20 @@ class ModuleSanitizerCoverageLTO
|
||||
uint32_t unhandled = 0;
|
||||
uint32_t select_cnt = 0;
|
||||
uint64_t map_addr = 0;
|
||||
const char * skip_nozero = NULL;
|
||||
const char * use_threadsafe_counters = nullptr;
|
||||
const char *skip_nozero = NULL;
|
||||
const char *use_threadsafe_counters = nullptr;
|
||||
std::vector<BasicBlock *> BlockList;
|
||||
DenseMap<Value *, std::string *> valueMap;
|
||||
std::vector<std::string> dictionary;
|
||||
IntegerType * Int8Tyi = NULL;
|
||||
IntegerType * Int32Tyi = NULL;
|
||||
IntegerType * Int64Tyi = NULL;
|
||||
ConstantInt * Zero = NULL;
|
||||
ConstantInt * One = NULL;
|
||||
LLVMContext * Ct = NULL;
|
||||
Module * Mo = NULL;
|
||||
GlobalVariable * AFLMapPtr = NULL;
|
||||
Value * MapPtrFixed = NULL;
|
||||
IntegerType *Int8Tyi = NULL;
|
||||
IntegerType *Int32Tyi = NULL;
|
||||
IntegerType *Int64Tyi = NULL;
|
||||
ConstantInt *Zero = NULL;
|
||||
ConstantInt *One = NULL;
|
||||
LLVMContext *Ct = NULL;
|
||||
Module *Mo = NULL;
|
||||
GlobalVariable *AFLMapPtr = NULL;
|
||||
Value *MapPtrFixed = NULL;
|
||||
std::ofstream dFile;
|
||||
size_t found = 0;
|
||||
// afl++ END
|
||||
@ -330,12 +330,12 @@ llvmGetPassPluginInfo() {
|
||||
|
||||
}
|
||||
|
||||
PreservedAnalyses ModuleSanitizerCoverageLTO::run(Module & M,
|
||||
PreservedAnalyses ModuleSanitizerCoverageLTO::run(Module &M,
|
||||
ModuleAnalysisManager &MAM) {
|
||||
|
||||
ModuleSanitizerCoverageLTO ModuleSancov(Options);
|
||||
auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
|
||||
auto DTCallback = [&FAM](Function &F) -> const DominatorTree * {
|
||||
auto DTCallback = [&FAM](Function &F) -> const DominatorTree *{
|
||||
|
||||
return &FAM.getResult<DominatorTreeAnalysis>(F);
|
||||
|
||||
@ -380,7 +380,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
||||
FunctionPCsArray = nullptr;
|
||||
IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
|
||||
IntptrPtrTy = PointerType::getUnqual(IntptrTy);
|
||||
Type * VoidTy = Type::getVoidTy(*C);
|
||||
Type *VoidTy = Type::getVoidTy(*C);
|
||||
IRBuilder<> IRB(*C);
|
||||
Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty());
|
||||
Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
|
||||
@ -393,7 +393,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
||||
Int1Ty = IRB.getInt1Ty();
|
||||
|
||||
/* afl++ START */
|
||||
char * ptr;
|
||||
char *ptr;
|
||||
LLVMContext &Ctx = M.getContext();
|
||||
Ct = &Ctx;
|
||||
Int8Tyi = IntegerType::getInt8Ty(Ctx);
|
||||
@ -499,11 +499,11 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
||||
for (auto &IN : BB) {
|
||||
|
||||
CallInst *callInst = nullptr;
|
||||
CmpInst * cmpInst = nullptr;
|
||||
CmpInst *cmpInst = nullptr;
|
||||
|
||||
if ((cmpInst = dyn_cast<CmpInst>(&IN))) {
|
||||
|
||||
Value * op = cmpInst->getOperand(1);
|
||||
Value *op = cmpInst->getOperand(1);
|
||||
ConstantInt *ilen = dyn_cast<ConstantInt>(op);
|
||||
|
||||
if (ilen && ilen->uge(0xffffffffffffffff) == false) {
|
||||
@ -759,7 +759,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
||||
|
||||
if (HasStr2 == true) {
|
||||
|
||||
Value * op2 = callInst->getArgOperand(2);
|
||||
Value *op2 = callInst->getArgOperand(2);
|
||||
ConstantInt *ilen = dyn_cast<ConstantInt>(op2);
|
||||
if (ilen) {
|
||||
|
||||
@ -866,7 +866,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
||||
|
||||
if (isMemcmp || isStrncmp || isStrncasecmp) {
|
||||
|
||||
Value * op2 = callInst->getArgOperand(2);
|
||||
Value *op2 = callInst->getArgOperand(2);
|
||||
ConstantInt *ilen = dyn_cast<ConstantInt>(op2);
|
||||
|
||||
if (ilen) {
|
||||
@ -921,7 +921,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
||||
std::string outstring;
|
||||
fprintf(stderr, "%s: length %zu/%zu \"", FuncName.c_str(), optLen,
|
||||
thestring.length());
|
||||
for (uint8_t i = 0; i < thestring.length(); i++) {
|
||||
for (uint16_t i = 0; i < (uint16_t)thestring.length(); i++) {
|
||||
|
||||
uint8_t c = thestring[i];
|
||||
if (c <= 32 || c >= 127)
|
||||
@ -1017,7 +1017,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
||||
GlobalVariable *AFLMapAddrFixed = new GlobalVariable(
|
||||
M, Int64Tyi, true, GlobalValue::ExternalLinkage, 0, "__afl_map_addr");
|
||||
ConstantInt *MapAddr = ConstantInt::get(Int64Tyi, map_addr);
|
||||
StoreInst * StoreMapAddr = IRB.CreateStore(MapAddr, AFLMapAddrFixed);
|
||||
StoreInst *StoreMapAddr = IRB.CreateStore(MapAddr, AFLMapAddrFixed);
|
||||
ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreMapAddr);
|
||||
|
||||
}
|
||||
@ -1032,7 +1032,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
||||
new GlobalVariable(M, Int32Tyi, true, GlobalValue::ExternalLinkage, 0,
|
||||
"__afl_final_loc");
|
||||
ConstantInt *const_loc = ConstantInt::get(Int32Tyi, write_loc);
|
||||
StoreInst * StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc);
|
||||
StoreInst *StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc);
|
||||
ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreFinalLoc);
|
||||
|
||||
}
|
||||
@ -1159,7 +1159,7 @@ static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
|
||||
}
|
||||
|
||||
// True if block has predecessors and it postdominates all of them.
|
||||
static bool isFullPostDominator(const BasicBlock * BB,
|
||||
static bool isFullPostDominator(const BasicBlock *BB,
|
||||
const PostDominatorTree *PDT) {
|
||||
|
||||
if (pred_begin(BB) == pred_end(BB)) return false;
|
||||
@ -1175,8 +1175,8 @@ static bool isFullPostDominator(const BasicBlock * BB,
|
||||
}
|
||||
|
||||
static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
|
||||
const DominatorTree * DT,
|
||||
const PostDominatorTree * PDT,
|
||||
const DominatorTree *DT,
|
||||
const PostDominatorTree *PDT,
|
||||
const SanitizerCoverageOptions &Options) {
|
||||
|
||||
// Don't insert coverage for blocks containing nothing but unreachable: we
|
||||
@ -1246,7 +1246,7 @@ void ModuleSanitizerCoverageLTO::instrumentFunction(
|
||||
SmallVector<Instruction *, 8> IndirCalls;
|
||||
SmallVector<BasicBlock *, 16> BlocksToInstrument;
|
||||
|
||||
const DominatorTree * DT = DTCallback(F);
|
||||
const DominatorTree *DT = DTCallback(F);
|
||||
const PostDominatorTree *PDT = PDTCallback(F);
|
||||
bool IsLeafFunc = true;
|
||||
uint32_t skip_next = 0;
|
||||
@ -1294,8 +1294,8 @@ void ModuleSanitizerCoverageLTO::instrumentFunction(
|
||||
if (!skip_next && (selectInst = dyn_cast<SelectInst>(&IN))) {
|
||||
|
||||
uint32_t vector_cnt = 0;
|
||||
Value * condition = selectInst->getCondition();
|
||||
Value * result;
|
||||
Value *condition = selectInst->getCondition();
|
||||
Value *result;
|
||||
auto t = condition->getType();
|
||||
IRBuilder<> IRB(selectInst->getNextNode());
|
||||
|
||||
@ -1451,8 +1451,8 @@ GlobalVariable *ModuleSanitizerCoverageLTO::CreateFunctionLocalArrayInSection(
|
||||
|
||||
ArrayType *ArrayTy = ArrayType::get(Ty, NumElements);
|
||||
auto Array = new GlobalVariable(
|
||||
*CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
|
||||
Constant::getNullValue(ArrayTy), "__sancov_gen_");
|
||||
*CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
|
||||
Constant::getNullValue(ArrayTy), "__sancov_gen_");
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 13
|
||||
if (TargetTriple.supportsCOMDAT() &&
|
||||
@ -1584,8 +1584,8 @@ void ModuleSanitizerCoverageLTO::InjectCoverageForIndirectCalls(
|
||||
for (auto I : IndirCalls) {
|
||||
|
||||
IRBuilder<> IRB(I);
|
||||
CallBase & CB = cast<CallBase>(*I);
|
||||
Value * Callee = CB.getCalledOperand();
|
||||
CallBase &CB = cast<CallBase>(*I);
|
||||
Value *Callee = CB.getCalledOperand();
|
||||
if (isa<InlineAsm>(Callee)) continue;
|
||||
IRB.CreateCall(SanCovTracePCIndir, IRB.CreatePointerCast(Callee, IntptrTy));
|
||||
|
||||
@ -1593,7 +1593,7 @@ void ModuleSanitizerCoverageLTO::InjectCoverageForIndirectCalls(
|
||||
|
||||
}
|
||||
|
||||
void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function & F,
|
||||
void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function &F,
|
||||
BasicBlock &BB,
|
||||
size_t Idx,
|
||||
bool IsLeafFunc) {
|
||||
|
@ -142,14 +142,14 @@ class ModuleSanitizerCoverageAFL
|
||||
private:
|
||||
void instrumentFunction(Function &F, DomTreeCallback DTCallback,
|
||||
PostDomTreeCallback PDTCallback);
|
||||
void InjectCoverageForIndirectCalls(Function & F,
|
||||
void InjectCoverageForIndirectCalls(Function &F,
|
||||
ArrayRef<Instruction *> IndirCalls);
|
||||
void InjectTraceForCmp(Function &F, ArrayRef<Instruction *> CmpTraceTargets);
|
||||
void InjectTraceForDiv(Function & F,
|
||||
void InjectTraceForDiv(Function &F,
|
||||
ArrayRef<BinaryOperator *> DivTraceTargets);
|
||||
void InjectTraceForGep(Function & F,
|
||||
void InjectTraceForGep(Function &F,
|
||||
ArrayRef<GetElementPtrInst *> GepTraceTargets);
|
||||
void InjectTraceForSwitch(Function & F,
|
||||
void InjectTraceForSwitch(Function &F,
|
||||
ArrayRef<Instruction *> SwitchTraceTargets);
|
||||
bool InjectCoverage(Function &F, ArrayRef<BasicBlock *> AllBlocks,
|
||||
bool IsLeafFunc = true);
|
||||
@ -187,10 +187,10 @@ class ModuleSanitizerCoverageAFL
|
||||
GlobalVariable *SanCovLowestStack;
|
||||
Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
|
||||
*Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty, *Int1PtrTy;
|
||||
Module * CurModule;
|
||||
Module *CurModule;
|
||||
std::string CurModuleUniqueId;
|
||||
Triple TargetTriple;
|
||||
LLVMContext * C;
|
||||
LLVMContext *C;
|
||||
const DataLayout *DL;
|
||||
|
||||
GlobalVariable *FunctionGuardArray; // for trace-pc-guard.
|
||||
@ -204,8 +204,8 @@ class ModuleSanitizerCoverageAFL
|
||||
|
||||
uint32_t instr = 0, selects = 0, unhandled = 0;
|
||||
GlobalVariable *AFLMapPtr = NULL;
|
||||
ConstantInt * One = NULL;
|
||||
ConstantInt * Zero = NULL;
|
||||
ConstantInt *One = NULL;
|
||||
ConstantInt *Zero = NULL;
|
||||
|
||||
};
|
||||
|
||||
@ -287,12 +287,12 @@ llvmGetPassPluginInfo() {
|
||||
|
||||
#endif
|
||||
|
||||
PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module & M,
|
||||
PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
|
||||
ModuleAnalysisManager &MAM) {
|
||||
|
||||
ModuleSanitizerCoverageAFL ModuleSancov(Options);
|
||||
auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
|
||||
auto DTCallback = [&FAM](Function &F) -> const DominatorTree * {
|
||||
auto DTCallback = [&FAM](Function &F) -> const DominatorTree *{
|
||||
|
||||
return &FAM.getResult<DominatorTreeAnalysis>(F);
|
||||
|
||||
@ -433,7 +433,7 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
|
||||
FunctionPCsArray = nullptr;
|
||||
IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
|
||||
IntptrPtrTy = PointerType::getUnqual(IntptrTy);
|
||||
Type * VoidTy = Type::getVoidTy(*C);
|
||||
Type *VoidTy = Type::getVoidTy(*C);
|
||||
IRBuilder<> IRB(*C);
|
||||
Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty());
|
||||
Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
|
||||
@ -612,8 +612,8 @@ bool isFullPostDominator(const BasicBlock *BB, const PostDominatorTree *PDT) {
|
||||
}
|
||||
|
||||
bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
|
||||
const DominatorTree * DT,
|
||||
const PostDominatorTree * PDT,
|
||||
const DominatorTree *DT,
|
||||
const PostDominatorTree *PDT,
|
||||
const SanitizerCoverageOptions &Options) {
|
||||
|
||||
// Don't insert coverage for blocks containing nothing but unreachable: we
|
||||
@ -704,7 +704,7 @@ void ModuleSanitizerCoverageAFL::instrumentFunction(
|
||||
SmallVector<BinaryOperator *, 8> DivTraceTargets;
|
||||
SmallVector<GetElementPtrInst *, 8> GepTraceTargets;
|
||||
|
||||
const DominatorTree * DT = DTCallback(F);
|
||||
const DominatorTree *DT = DTCallback(F);
|
||||
const PostDominatorTree *PDT = PDTCallback(F);
|
||||
bool IsLeafFunc = true;
|
||||
|
||||
@ -761,8 +761,8 @@ GlobalVariable *ModuleSanitizerCoverageAFL::CreateFunctionLocalArrayInSection(
|
||||
|
||||
ArrayType *ArrayTy = ArrayType::get(Ty, NumElements);
|
||||
auto Array = new GlobalVariable(
|
||||
*CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
|
||||
Constant::getNullValue(ArrayTy), "__sancov_gen_");
|
||||
*CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
|
||||
Constant::getNullValue(ArrayTy), "__sancov_gen_");
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 13
|
||||
if (TargetTriple.supportsCOMDAT() &&
|
||||
@ -971,8 +971,8 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
||||
if (!skip_next && (selectInst = dyn_cast<SelectInst>(&IN))) {
|
||||
|
||||
uint32_t vector_cnt = 0;
|
||||
Value * condition = selectInst->getCondition();
|
||||
Value * result;
|
||||
Value *condition = selectInst->getCondition();
|
||||
Value *result;
|
||||
auto t = condition->getType();
|
||||
IRBuilder<> IRB(selectInst->getNextNode());
|
||||
|
||||
@ -1113,7 +1113,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
|
||||
|
||||
/* Get CurLoc */
|
||||
LoadInst *CurLoc = nullptr;
|
||||
Value * MapPtrIdx = nullptr;
|
||||
Value *MapPtrIdx = nullptr;
|
||||
|
||||
/* Load counter for CurLoc */
|
||||
if (!vector_cnt) {
|
||||
@ -1212,8 +1212,8 @@ void ModuleSanitizerCoverageAFL::InjectCoverageForIndirectCalls(
|
||||
for (auto I : IndirCalls) {
|
||||
|
||||
IRBuilder<> IRB(I);
|
||||
CallBase & CB = cast<CallBase>(*I);
|
||||
Value * Callee = CB.getCalledOperand();
|
||||
CallBase &CB = cast<CallBase>(*I);
|
||||
Value *Callee = CB.getCalledOperand();
|
||||
if (isa<InlineAsm>(Callee)) continue;
|
||||
IRB.CreateCall(SanCovTracePCIndir, IRB.CreatePointerCast(Callee, IntptrTy));
|
||||
|
||||
@ -1234,7 +1234,7 @@ void ModuleSanitizerCoverageAFL::InjectTraceForSwitch(
|
||||
|
||||
IRBuilder<> IRB(I);
|
||||
SmallVector<Constant *, 16> Initializers;
|
||||
Value * Cond = SI->getCondition();
|
||||
Value *Cond = SI->getCondition();
|
||||
if (Cond->getType()->getScalarSizeInBits() >
|
||||
Int64Ty->getScalarSizeInBits())
|
||||
continue;
|
||||
@ -1282,7 +1282,7 @@ void ModuleSanitizerCoverageAFL::InjectTraceForDiv(
|
||||
for (auto BO : DivTraceTargets) {
|
||||
|
||||
IRBuilder<> IRB(BO);
|
||||
Value * A1 = BO->getOperand(1);
|
||||
Value *A1 = BO->getOperand(1);
|
||||
if (isa<ConstantInt>(A1)) continue;
|
||||
if (!A1->getType()->isIntegerTy()) continue;
|
||||
uint64_t TypeSize = DL->getTypeStoreSizeInBits(A1->getType());
|
||||
@ -1319,8 +1319,8 @@ void ModuleSanitizerCoverageAFL::InjectTraceForCmp(
|
||||
if (ICmpInst *ICMP = dyn_cast<ICmpInst>(I)) {
|
||||
|
||||
IRBuilder<> IRB(ICMP);
|
||||
Value * A0 = ICMP->getOperand(0);
|
||||
Value * A1 = ICMP->getOperand(1);
|
||||
Value *A0 = ICMP->getOperand(0);
|
||||
Value *A1 = ICMP->getOperand(1);
|
||||
if (!A0->getType()->isIntegerTy()) continue;
|
||||
uint64_t TypeSize = DL->getTypeStoreSizeInBits(A0->getType());
|
||||
int CallbackIdx = TypeSize == 8 ? 0
|
||||
@ -1353,7 +1353,7 @@ void ModuleSanitizerCoverageAFL::InjectTraceForCmp(
|
||||
|
||||
}
|
||||
|
||||
void ModuleSanitizerCoverageAFL::InjectCoverageAtBlock(Function & F,
|
||||
void ModuleSanitizerCoverageAFL::InjectCoverageAtBlock(Function &F,
|
||||
BasicBlock &BB,
|
||||
size_t Idx,
|
||||
bool IsLeafFunc) {
|
||||
@ -1472,7 +1472,7 @@ void ModuleSanitizerCoverageAFL::InjectCoverageAtBlock(Function & F,
|
||||
if (Options.StackDepth && IsEntryBB && !IsLeafFunc) {
|
||||
|
||||
// Check stack depth. If it's the deepest so far, record it.
|
||||
Module * M = F.getParent();
|
||||
Module *M = F.getParent();
|
||||
Function *GetFrameAddr = Intrinsic::getDeclaration(
|
||||
M, Intrinsic::frameaddress,
|
||||
IRB.getInt8PtrTy(M->getDataLayout().getAllocaAddrSpace()));
|
||||
|
@ -92,11 +92,11 @@ static u8 __afl_area_initial[MAP_INITIAL_SIZE];
|
||||
static u8 *__afl_area_ptr_dummy = __afl_area_initial;
|
||||
static u8 *__afl_area_ptr_backup = __afl_area_initial;
|
||||
|
||||
u8 * __afl_area_ptr = __afl_area_initial;
|
||||
u8 * __afl_dictionary;
|
||||
u8 * __afl_fuzz_ptr;
|
||||
u8 *__afl_area_ptr = __afl_area_initial;
|
||||
u8 *__afl_dictionary;
|
||||
u8 *__afl_fuzz_ptr;
|
||||
static u32 __afl_fuzz_len_dummy;
|
||||
u32 * __afl_fuzz_len = &__afl_fuzz_len_dummy;
|
||||
u32 *__afl_fuzz_len = &__afl_fuzz_len_dummy;
|
||||
|
||||
u32 __afl_final_loc;
|
||||
u32 __afl_map_size = MAP_SIZE;
|
||||
@ -399,7 +399,7 @@ static void __afl_map_shm(void) {
|
||||
}
|
||||
|
||||
#ifdef USEMMAP
|
||||
const char * shm_file_path = id_str;
|
||||
const char *shm_file_path = id_str;
|
||||
int shm_fd = -1;
|
||||
unsigned char *shm_base = NULL;
|
||||
|
||||
@ -450,11 +450,11 @@ static void __afl_map_shm(void) {
|
||||
|
||||
if (__afl_map_size && __afl_map_size > MAP_SIZE) {
|
||||
|
||||
u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
|
||||
if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
|
||||
u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
|
||||
if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
|
||||
|
||||
send_forkserver_error(FS_ERROR_MAP_SIZE);
|
||||
_exit(1);
|
||||
send_forkserver_error(FS_ERROR_MAP_SIZE);
|
||||
_exit(1);
|
||||
|
||||
}
|
||||
|
||||
@ -466,13 +466,13 @@ static void __afl_map_shm(void) {
|
||||
|
||||
if (!__afl_area_ptr || __afl_area_ptr == (void *)-1) {
|
||||
|
||||
if (__afl_map_addr)
|
||||
if (__afl_map_addr)
|
||||
send_forkserver_error(FS_ERROR_MAP_ADDR);
|
||||
else
|
||||
send_forkserver_error(FS_ERROR_SHMAT);
|
||||
|
||||
perror("shmat for map");
|
||||
_exit(1);
|
||||
_exit(1);
|
||||
|
||||
}
|
||||
|
||||
@ -583,7 +583,7 @@ static void __afl_map_shm(void) {
|
||||
}
|
||||
|
||||
#ifdef USEMMAP
|
||||
const char * shm_file_path = id_str;
|
||||
const char *shm_file_path = id_str;
|
||||
int shm_fd = -1;
|
||||
struct cmp_map *shm_base = NULL;
|
||||
|
||||
@ -689,7 +689,7 @@ static void __afl_unmap_shm(void) {
|
||||
|
||||
void write_error_with_location(char *text, char *filename, int linenumber) {
|
||||
|
||||
u8 * o = getenv("__AFL_OUT_DIR");
|
||||
u8 *o = getenv("__AFL_OUT_DIR");
|
||||
char *e = strerror(errno);
|
||||
|
||||
if (o) {
|
||||
|
404
instrumentation/afl-gcc-cmplog-pass.so.cc
Normal file
404
instrumentation/afl-gcc-cmplog-pass.so.cc
Normal file
@ -0,0 +1,404 @@
|
||||
/* GCC plugin for cmplog instrumentation of code for AFL++.
|
||||
|
||||
Copyright 2014-2019 Free Software Foundation, Inc
|
||||
Copyright 2015, 2016 Google Inc. All rights reserved.
|
||||
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2022 AdaCore
|
||||
|
||||
Written by Alexandre Oliva <oliva@adacore.com>, based on the AFL++
|
||||
LLVM CmpLog pass by Andrea Fioraldi <andreafioraldi@gmail.com>, and
|
||||
on the AFL GCC pass.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "afl-gcc-common.h"
|
||||
|
||||
/* This plugin, being under the same license as GCC, satisfies the
|
||||
"GPL-compatible Software" definition in the GCC RUNTIME LIBRARY
|
||||
EXCEPTION, so it can be part of an "Eligible" "Compilation
|
||||
Process". */
|
||||
int plugin_is_GPL_compatible = 1;
|
||||
|
||||
namespace {
|
||||
|
||||
static const struct pass_data afl_cmplog_pass_data = {
|
||||
|
||||
.type = GIMPLE_PASS,
|
||||
.name = "aflcmplog",
|
||||
.optinfo_flags = OPTGROUP_NONE,
|
||||
.tv_id = TV_NONE,
|
||||
.properties_required = 0,
|
||||
.properties_provided = 0,
|
||||
.properties_destroyed = 0,
|
||||
.todo_flags_start = 0,
|
||||
.todo_flags_finish = (TODO_update_ssa | TODO_cleanup_cfg | TODO_verify_il |
|
||||
TODO_rebuild_cgraph_edges),
|
||||
|
||||
};
|
||||
|
||||
struct afl_cmplog_pass : afl_base_pass {
|
||||
|
||||
afl_cmplog_pass(bool quiet)
|
||||
: afl_base_pass(quiet, /*debug=*/false, afl_cmplog_pass_data),
|
||||
t8u(),
|
||||
cmplog_hooks() {
|
||||
|
||||
}
|
||||
|
||||
/* An unsigned 8-bit integral type. */
|
||||
tree t8u;
|
||||
|
||||
/* Declarations for the various cmplog hook functions, allocated on demand..
|
||||
[0] is for __cmplog_ins_hookN, that accepts non-power-of-2 sizes.
|
||||
[n in 1..5] are for unsigned ints of 2^{n-1} bytes. */
|
||||
tree cmplog_hooks[6];
|
||||
|
||||
tree cmplog_hook(unsigned i) {
|
||||
|
||||
tree t, fnt;
|
||||
|
||||
if (!t8u) {
|
||||
|
||||
if (BITS_PER_UNIT == 8)
|
||||
t8u = unsigned_char_type_node;
|
||||
else
|
||||
t8u = build_nonstandard_integer_type(8, 1);
|
||||
|
||||
}
|
||||
|
||||
if (i <= ARRAY_SIZE(cmplog_hooks) && cmplog_hooks[i])
|
||||
return cmplog_hooks[i];
|
||||
|
||||
switch (i) {
|
||||
|
||||
case 0:
|
||||
#ifdef uint128_type_node
|
||||
t = uint128_type_node;
|
||||
#else
|
||||
t = build_nonstandard_integer_type(128, 1);
|
||||
#endif
|
||||
fnt =
|
||||
build_function_type_list(void_type_node, t, t, t8u, t8u, NULL_TREE);
|
||||
t = cmplog_hooks[0] = build_fn_decl("__cmplog_ins_hookN", fnt);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
t = t8u;
|
||||
fnt = build_function_type_list(void_type_node, t, t, t8u, NULL_TREE);
|
||||
t = cmplog_hooks[1] = build_fn_decl("__cmplog_ins_hook1", fnt);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
t = uint16_type_node;
|
||||
fnt = build_function_type_list(void_type_node, t, t, t8u, NULL_TREE);
|
||||
t = cmplog_hooks[2] = build_fn_decl("__cmplog_ins_hook2", fnt);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
t = uint32_type_node;
|
||||
fnt = build_function_type_list(void_type_node, t, t, t8u, NULL_TREE);
|
||||
t = cmplog_hooks[3] = build_fn_decl("__cmplog_ins_hook4", fnt);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
t = uint64_type_node;
|
||||
fnt = build_function_type_list(void_type_node, t, t, t8u, NULL_TREE);
|
||||
t = cmplog_hooks[4] = build_fn_decl("__cmplog_ins_hook8", fnt);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
#ifdef uint128_type_node
|
||||
t = uint128_type_node;
|
||||
#else
|
||||
t = build_nonstandard_integer_type(128, 1);
|
||||
#endif
|
||||
fnt = build_function_type_list(void_type_node, t, t, t8u, NULL_TREE);
|
||||
t = cmplog_hooks[5] = build_fn_decl("__cmplog_ins_hook16", fnt);
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable();
|
||||
|
||||
}
|
||||
|
||||
/* Mark the newly-created decl as non-throwing, so that we can
|
||||
insert call within basic blocks. */
|
||||
TREE_NOTHROW(t) = 1;
|
||||
|
||||
return t;
|
||||
|
||||
}
|
||||
|
||||
/* Insert a cmplog hook call before GSI for a CODE compare between
|
||||
LHS and RHS. */
|
||||
void insert_cmplog_call(gimple_stmt_iterator gsi, tree_code code, tree lhs,
|
||||
tree rhs) {
|
||||
|
||||
gcc_checking_assert(TYPE_MAIN_VARIANT(TREE_TYPE(lhs)) ==
|
||||
TYPE_MAIN_VARIANT(TREE_TYPE(rhs)));
|
||||
|
||||
tree fn;
|
||||
bool pass_n = false;
|
||||
|
||||
/* Obtain the compare operand size as a constant. */
|
||||
tree st = TREE_TYPE(lhs);
|
||||
tree szt = TYPE_SIZE(st);
|
||||
|
||||
if (!tree_fits_uhwi_p(szt)) return;
|
||||
|
||||
unsigned HOST_WIDE_INT sz = tree_to_uhwi(szt);
|
||||
|
||||
/* Round it up. */
|
||||
if (sz % 8) sz = (((sz - 1) / 8) + 1) * 8;
|
||||
|
||||
/* Select the hook function to call, based on the size. */
|
||||
switch (sz) {
|
||||
|
||||
default:
|
||||
fn = cmplog_hook(0);
|
||||
pass_n = true;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
fn = cmplog_hook(1);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
fn = cmplog_hook(2);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
fn = cmplog_hook(3);
|
||||
break;
|
||||
|
||||
case 64:
|
||||
fn = cmplog_hook(4);
|
||||
break;
|
||||
|
||||
case 128:
|
||||
fn = cmplog_hook(5);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* Set attr according to the compare operation. */
|
||||
unsigned char attr = 0;
|
||||
|
||||
switch (code) {
|
||||
|
||||
case UNORDERED_EXPR:
|
||||
case ORDERED_EXPR:
|
||||
/* ??? */
|
||||
/* Fallthrough. */
|
||||
case NE_EXPR:
|
||||
case LTGT_EXPR:
|
||||
break;
|
||||
|
||||
case EQ_EXPR:
|
||||
case UNEQ_EXPR:
|
||||
attr += 1;
|
||||
break;
|
||||
|
||||
case GT_EXPR:
|
||||
case UNGT_EXPR:
|
||||
attr += 2;
|
||||
break;
|
||||
|
||||
case GE_EXPR:
|
||||
case UNGE_EXPR:
|
||||
attr += 3;
|
||||
break;
|
||||
|
||||
case LT_EXPR:
|
||||
case UNLT_EXPR:
|
||||
attr += 4;
|
||||
break;
|
||||
|
||||
case LE_EXPR:
|
||||
case UNLE_EXPR:
|
||||
attr += 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable();
|
||||
|
||||
}
|
||||
|
||||
if (FLOAT_TYPE_P(TREE_TYPE(lhs))) {
|
||||
|
||||
attr += 8;
|
||||
|
||||
tree t = build_nonstandard_integer_type(sz, 1);
|
||||
|
||||
tree s = make_ssa_name(t);
|
||||
gimple *g = gimple_build_assign(s, VIEW_CONVERT_EXPR,
|
||||
build1(VIEW_CONVERT_EXPR, t, lhs));
|
||||
lhs = s;
|
||||
gsi_insert_before(&gsi, g, GSI_SAME_STMT);
|
||||
|
||||
s = make_ssa_name(t);
|
||||
g = gimple_build_assign(s, VIEW_CONVERT_EXPR,
|
||||
build1(VIEW_CONVERT_EXPR, t, rhs));
|
||||
rhs = s;
|
||||
gsi_insert_before(&gsi, g, GSI_SAME_STMT);
|
||||
|
||||
}
|
||||
|
||||
/* Convert the operands to the hook arg type, if needed. */
|
||||
tree t = TREE_VALUE(TYPE_ARG_TYPES(TREE_TYPE(fn)));
|
||||
|
||||
lhs = fold_convert_loc(UNKNOWN_LOCATION, t, lhs);
|
||||
if (!is_gimple_val(lhs)) {
|
||||
|
||||
tree s = make_ssa_name(t);
|
||||
gimple *g = gimple_build_assign(s, lhs);
|
||||
lhs = s;
|
||||
gsi_insert_before(&gsi, g, GSI_SAME_STMT);
|
||||
|
||||
}
|
||||
|
||||
rhs = fold_convert_loc(UNKNOWN_LOCATION, t, rhs);
|
||||
if (!is_gimple_val(rhs)) {
|
||||
|
||||
tree s = make_ssa_name(t);
|
||||
gimple *g = gimple_build_assign(s, rhs);
|
||||
rhs = s;
|
||||
gsi_insert_before(&gsi, g, GSI_SAME_STMT);
|
||||
|
||||
}
|
||||
|
||||
/* Insert the call. */
|
||||
tree att = build_int_cst(t8u, attr);
|
||||
gimple *call;
|
||||
if (pass_n)
|
||||
call = gimple_build_call(fn, 4, lhs, rhs, att,
|
||||
build_int_cst(t8u, sz / 8 - 1));
|
||||
else
|
||||
call = gimple_build_call(fn, 3, lhs, rhs, att);
|
||||
|
||||
gsi_insert_before(&gsi, call, GSI_SAME_STMT);
|
||||
|
||||
}
|
||||
|
||||
virtual unsigned int execute(function *fn) {
|
||||
|
||||
if (!isInInstrumentList(fn)) return 0;
|
||||
|
||||
basic_block bb;
|
||||
FOR_EACH_BB_FN(bb, fn) {
|
||||
|
||||
/* A GIMPLE_COND or GIMPLE_SWITCH will always be the last stmt
|
||||
in a BB. */
|
||||
gimple_stmt_iterator gsi = gsi_last_bb(bb);
|
||||
if (gsi_end_p(gsi)) continue;
|
||||
|
||||
gimple *stmt = gsi_stmt(gsi);
|
||||
|
||||
if (gimple_code(stmt) == GIMPLE_COND) {
|
||||
|
||||
tree_code code = gimple_cond_code(stmt);
|
||||
tree lhs = gimple_cond_lhs(stmt);
|
||||
tree rhs = gimple_cond_rhs(stmt);
|
||||
|
||||
insert_cmplog_call(gsi, code, lhs, rhs);
|
||||
|
||||
} else if (gimple_code(stmt) == GIMPLE_SWITCH) {
|
||||
|
||||
gswitch *sw = as_a<gswitch *>(stmt);
|
||||
tree lhs = gimple_switch_index(sw);
|
||||
|
||||
for (int i = 0, e = gimple_switch_num_labels(sw); i < e; i++) {
|
||||
|
||||
tree clx = gimple_switch_label(sw, i);
|
||||
tree rhsl = CASE_LOW(clx);
|
||||
/* Default case labels exprs don't have a CASE_LOW. */
|
||||
if (!rhsl) continue;
|
||||
tree rhsh = CASE_HIGH(clx);
|
||||
/* If there is a CASE_HIGH, issue range compares. */
|
||||
if (rhsh) {
|
||||
|
||||
insert_cmplog_call(gsi, GE_EXPR, lhs, rhsl);
|
||||
insert_cmplog_call(gsi, LE_EXPR, lhs, rhsh);
|
||||
|
||||
}
|
||||
|
||||
/* Otherwise, use a single equality compare. */
|
||||
else
|
||||
insert_cmplog_call(gsi, EQ_EXPR, lhs, rhsl);
|
||||
|
||||
}
|
||||
|
||||
} else
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static struct plugin_info afl_cmplog_plugin = {
|
||||
|
||||
.version = "20220420",
|
||||
.help = G_("AFL gcc cmplog plugin\n\
|
||||
\n\
|
||||
Set AFL_QUIET in the environment to silence it.\n\
|
||||
"),
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
/* This is the function GCC calls when loading a plugin. Initialize
|
||||
and register further callbacks. */
|
||||
int plugin_init(struct plugin_name_args *info,
|
||||
struct plugin_gcc_version *version) {
|
||||
|
||||
if (!plugin_default_version_check(version, &gcc_version))
|
||||
FATAL(G_("GCC and plugin have incompatible versions, expected GCC %s, "
|
||||
"is %s"),
|
||||
gcc_version.basever, version->basever);
|
||||
|
||||
/* Show a banner. */
|
||||
bool quiet = false;
|
||||
if (isatty(2) && !getenv("AFL_QUIET"))
|
||||
SAYF(cCYA "afl-gcc-cmplog-pass " cBRI VERSION cRST
|
||||
" by <oliva@adacore.com>\n");
|
||||
else
|
||||
quiet = true;
|
||||
|
||||
const char *name = info->base_name;
|
||||
register_callback(name, PLUGIN_INFO, NULL, &afl_cmplog_plugin);
|
||||
|
||||
afl_cmplog_pass *aflp = new afl_cmplog_pass(quiet);
|
||||
struct register_pass_info pass_info = {
|
||||
|
||||
.pass = aflp,
|
||||
.reference_pass_name = "ssa",
|
||||
.ref_pass_instance_number = 1,
|
||||
.pos_op = PASS_POS_INSERT_AFTER,
|
||||
|
||||
};
|
||||
|
||||
register_callback(name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
366
instrumentation/afl-gcc-cmptrs-pass.so.cc
Normal file
366
instrumentation/afl-gcc-cmptrs-pass.so.cc
Normal file
@ -0,0 +1,366 @@
|
||||
/* GCC plugin for cmplog routines instrumentation of code for AFL++.
|
||||
|
||||
Copyright 2014-2019 Free Software Foundation, Inc
|
||||
Copyright 2015, 2016 Google Inc. All rights reserved.
|
||||
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
|
||||
Copyright 2019-2022 AdaCore
|
||||
|
||||
Written by Alexandre Oliva <oliva@adacore.com>, based on the AFL++
|
||||
LLVM CmpLog Routines pass by Andrea Fioraldi
|
||||
<andreafioraldi@gmail.com>, and on the AFL GCC CmpLog pass.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "afl-gcc-common.h"
|
||||
|
||||
/* This plugin, being under the same license as GCC, satisfies the
|
||||
"GPL-compatible Software" definition in the GCC RUNTIME LIBRARY
|
||||
EXCEPTION, so it can be part of an "Eligible" "Compilation
|
||||
Process". */
|
||||
int plugin_is_GPL_compatible = 1;
|
||||
|
||||
namespace {
|
||||
|
||||
static const struct pass_data afl_cmptrs_pass_data = {
|
||||
|
||||
.type = GIMPLE_PASS,
|
||||
.name = "aflcmptrs",
|
||||
.optinfo_flags = OPTGROUP_NONE,
|
||||
.tv_id = TV_NONE,
|
||||
.properties_required = 0,
|
||||
.properties_provided = 0,
|
||||
.properties_destroyed = 0,
|
||||
.todo_flags_start = 0,
|
||||
.todo_flags_finish = (TODO_update_ssa | TODO_cleanup_cfg | TODO_verify_il |
|
||||
TODO_rebuild_cgraph_edges),
|
||||
|
||||
};
|
||||
|
||||
struct afl_cmptrs_pass : afl_base_pass {
|
||||
|
||||
afl_cmptrs_pass(bool quiet)
|
||||
: afl_base_pass(quiet, /*debug=*/false, afl_cmptrs_pass_data),
|
||||
tp8u(),
|
||||
cmptrs_hooks() {
|
||||
|
||||
}
|
||||
|
||||
/* A pointer type to a unsigned 8-bit integral type. */
|
||||
tree tp8u;
|
||||
|
||||
/* Declarations for the various cmptrs hook functions, allocated on
|
||||
demand.. [0] is for compares between any pointers, [1] is for
|
||||
compares between G++ std::string, [2] is for compares between G++
|
||||
std::string and GCC C strings, [3] and [4] are analogous to [1]
|
||||
and [2] but for LLVM C++ strings. */
|
||||
tree cmptrs_hooks[5];
|
||||
|
||||
tree cmptrs_hook(unsigned i) {
|
||||
|
||||
if (!tp8u) {
|
||||
|
||||
tree t8u;
|
||||
if (BITS_PER_UNIT == 8)
|
||||
t8u = unsigned_char_type_node;
|
||||
else
|
||||
t8u = build_nonstandard_integer_type(8, 1);
|
||||
tp8u = build_pointer_type(t8u);
|
||||
|
||||
}
|
||||
|
||||
if (i <= ARRAY_SIZE(cmptrs_hooks) && cmptrs_hooks[i])
|
||||
return cmptrs_hooks[i];
|
||||
|
||||
const char *n = NULL;
|
||||
|
||||
switch (i) {
|
||||
|
||||
case 0:
|
||||
n = "__cmplog_rtn_hook";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
n = "__cmplog_rtn_gcc_stdstring_stdstring";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
n = "__cmplog_rtn_gcc_stdstring_cstring";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
n = "__cmplog_rtn_llvm_stdstring_stdstring";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
n = "__cmplog_rtn_llvm_stdstring_cstring";
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable();
|
||||
|
||||
}
|
||||
|
||||
tree fnt = build_function_type_list(void_type_node, tp8u, tp8u, NULL_TREE);
|
||||
tree t = cmptrs_hooks[i] = build_fn_decl(n, fnt);
|
||||
|
||||
/* Mark the newly-created decl as non-throwing, so that we can
|
||||
insert call within basic blocks. */
|
||||
TREE_NOTHROW(t) = 1;
|
||||
|
||||
return t;
|
||||
|
||||
}
|
||||
|
||||
/* Return true if T is the char* type. */
|
||||
bool is_c_string(tree t) {
|
||||
|
||||
return (POINTER_TYPE_P(t) &&
|
||||
TYPE_MAIN_VARIANT(TREE_TYPE(t)) == char_type_node);
|
||||
|
||||
}
|
||||
|
||||
/* Return true if T is an indirect std::string type. The LLVM pass
|
||||
tests portions of the mangled name of the callee. We could do
|
||||
that in GCC too, but computing the mangled name may cause
|
||||
template instantiations and get symbols defined that could
|
||||
otherwise be considered unused. We check for compatible layout,
|
||||
and class, namespace, and field names. These have been unchanged
|
||||
since at least GCC 7, probably longer, up to GCC 11. Odds are
|
||||
that, if it were to change in significant ways, mangling would
|
||||
also change to flag the incompatibility, and we'd have to use a
|
||||
different hook anyway. */
|
||||
bool is_gxx_std_string(tree t) {
|
||||
|
||||
/* We need a pointer or reference type. */
|
||||
if (!POINTER_TYPE_P(t)) return false;
|
||||
|
||||
/* Get to the pointed-to type. */
|
||||
t = TREE_TYPE(t);
|
||||
if (!t) return false;
|
||||
|
||||
/* Select the main variant, so that can compare types with pointers. */
|
||||
t = TYPE_MAIN_VARIANT(t);
|
||||
|
||||
/* We expect it to be a record type. */
|
||||
if (TREE_CODE(t) != RECORD_TYPE) return false;
|
||||
|
||||
/* The type of the template is basic_string. */
|
||||
if (strcmp(IDENTIFIER_POINTER(TYPE_IDENTIFIER(t)), "basic_string") != 0)
|
||||
return false;
|
||||
|
||||
/* It's declared in an internal namespace named __cxx11. */
|
||||
tree c = DECL_CONTEXT(TYPE_NAME(t));
|
||||
if (!c || TREE_CODE(c) != NAMESPACE_DECL ||
|
||||
strcmp(IDENTIFIER_POINTER(DECL_NAME(c)), "__cxx11") != 0)
|
||||
return false;
|
||||
|
||||
/* The __cxx11 namespace is a member of namespace std. */
|
||||
c = DECL_CONTEXT(c);
|
||||
if (!c || TREE_CODE(c) != NAMESPACE_DECL ||
|
||||
strcmp(IDENTIFIER_POINTER(DECL_NAME(c)), "std") != 0)
|
||||
return false;
|
||||
|
||||
/* And the std namespace is in the global namespace. */
|
||||
c = DECL_CONTEXT(c);
|
||||
if (c && TREE_CODE(c) != TRANSLATION_UNIT_DECL) return false;
|
||||
|
||||
/* Check that the first nonstatic data member of the record type
|
||||
is named _M_dataplus. */
|
||||
for (c = TYPE_FIELDS(t); c; c = DECL_CHAIN(c))
|
||||
if (TREE_CODE(c) == FIELD_DECL) break;
|
||||
if (!c || !integer_zerop(DECL_FIELD_BIT_OFFSET(c)) ||
|
||||
strcmp(IDENTIFIER_POINTER(DECL_NAME(c)), "_M_dataplus") != 0)
|
||||
return false;
|
||||
|
||||
/* Check that the second nonstatic data member of the record type
|
||||
is named _M_string_length. */
|
||||
tree f2;
|
||||
for (f2 = DECL_CHAIN(c); f2; f2 = DECL_CHAIN(f2))
|
||||
if (TREE_CODE(f2) == FIELD_DECL) break;
|
||||
if (!f2 /* No need to check this field's offset. */
|
||||
|| strcmp(IDENTIFIER_POINTER(DECL_NAME(f2)), "_M_string_length") != 0)
|
||||
return false;
|
||||
|
||||
/* The type of the second data member is size_t. */
|
||||
if (!TREE_TYPE(f2) || TYPE_MAIN_VARIANT(TREE_TYPE(f2)) != size_type_node)
|
||||
return false;
|
||||
|
||||
/* Now go back to the first data member. Its type should be a
|
||||
record type named _Alloc_hider. */
|
||||
c = TREE_TYPE(c);
|
||||
if (!c || TREE_CODE(c) != RECORD_TYPE ||
|
||||
strcmp(IDENTIFIER_POINTER(TYPE_IDENTIFIER(c)), "_Alloc_hider") != 0)
|
||||
return false;
|
||||
|
||||
/* And its first data member is named _M_p. */
|
||||
for (c = TYPE_FIELDS(c); c; c = DECL_CHAIN(c))
|
||||
if (TREE_CODE(c) == FIELD_DECL) break;
|
||||
if (!c || !integer_zerop(DECL_FIELD_BIT_OFFSET(c)) ||
|
||||
strcmp(IDENTIFIER_POINTER(DECL_NAME(c)), "_M_p") != 0)
|
||||
return false;
|
||||
|
||||
/* For the basic_string<char> type we're interested in, the type
|
||||
of the data member is the C string type. */
|
||||
if (!is_c_string(TREE_TYPE(c))) return false;
|
||||
|
||||
/* This might not be the real thing, but the bits that matter for
|
||||
the hook are there. */
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/* ??? This is not implemented. What would the point be of
|
||||
recognizing LLVM's string type in GCC? */
|
||||
bool is_llvm_std_string(tree t) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
virtual unsigned int execute(function *fn) {
|
||||
|
||||
if (!isInInstrumentList(fn)) return 0;
|
||||
|
||||
basic_block bb;
|
||||
FOR_EACH_BB_FN(bb, fn) {
|
||||
|
||||
for (gimple_stmt_iterator gsi = gsi_after_labels(bb); !gsi_end_p(gsi);
|
||||
gsi_next(&gsi)) {
|
||||
|
||||
gimple *stmt = gsi_stmt(gsi);
|
||||
|
||||
/* We're only interested in GIMPLE_CALLs. */
|
||||
if (gimple_code(stmt) != GIMPLE_CALL) continue;
|
||||
|
||||
if (gimple_call_num_args(stmt) < 2) continue;
|
||||
|
||||
gcall *c = as_a<gcall *>(stmt);
|
||||
|
||||
tree callee_type = gimple_call_fntype(c);
|
||||
|
||||
if (!callee_type || !TYPE_ARG_TYPES(callee_type) ||
|
||||
!TREE_CHAIN(TYPE_ARG_TYPES(callee_type)))
|
||||
continue;
|
||||
|
||||
tree arg_type[2] = {
|
||||
|
||||
TYPE_MAIN_VARIANT(TREE_VALUE(TYPE_ARG_TYPES(callee_type))),
|
||||
TYPE_MAIN_VARIANT(
|
||||
TREE_VALUE(TREE_CHAIN(TYPE_ARG_TYPES(callee_type))))};
|
||||
|
||||
tree fn = NULL;
|
||||
/* Callee arglist starts with two GCC std::string arguments. */
|
||||
if (arg_type[0] == arg_type[1] && is_gxx_std_string(arg_type[0]))
|
||||
fn = cmptrs_hook(1);
|
||||
/* Callee arglist starts with GCC std::string and C string. */
|
||||
else if (is_gxx_std_string(arg_type[0]) && is_c_string(arg_type[1]))
|
||||
fn = cmptrs_hook(2);
|
||||
/* Callee arglist starts with two LLVM std::string arguments. */
|
||||
else if (arg_type[0] == arg_type[1] && is_llvm_std_string(arg_type[0]))
|
||||
fn = cmptrs_hook(3);
|
||||
/* Callee arglist starts with LLVM std::string and C string. */
|
||||
else if (is_llvm_std_string(arg_type[0]) && is_c_string(arg_type[1]))
|
||||
fn = cmptrs_hook(4);
|
||||
/* Callee arglist starts with two pointers to the same type,
|
||||
and callee returns a value. */
|
||||
else if (arg_type[0] == arg_type[1] && POINTER_TYPE_P(arg_type[0]) &&
|
||||
(TYPE_MAIN_VARIANT(gimple_call_return_type(c)) !=
|
||||
void_type_node))
|
||||
fn = cmptrs_hook(0);
|
||||
else
|
||||
continue;
|
||||
|
||||
tree arg[2] = {gimple_call_arg(c, 0), gimple_call_arg(c, 1)};
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(arg); i++) {
|
||||
|
||||
tree c = fold_convert_loc(UNKNOWN_LOCATION, tp8u, arg[i]);
|
||||
if (!is_gimple_val(c)) {
|
||||
|
||||
tree s = make_ssa_name(tp8u);
|
||||
gimple *g = gimple_build_assign(s, c);
|
||||
c = s;
|
||||
gsi_insert_before(&gsi, g, GSI_SAME_STMT);
|
||||
|
||||
}
|
||||
|
||||
arg[i] = c;
|
||||
|
||||
}
|
||||
|
||||
gimple *call = gimple_build_call(fn, 2, arg[0], arg[1]);
|
||||
gsi_insert_before(&gsi, call, GSI_SAME_STMT);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static struct plugin_info afl_cmptrs_plugin = {
|
||||
|
||||
.version = "20220420",
|
||||
.help = G_("AFL gcc cmptrs plugin\n\
|
||||
\n\
|
||||
Set AFL_QUIET in the environment to silence it.\n\
|
||||
"),
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
/* This is the function GCC calls when loading a plugin. Initialize
|
||||
and register further callbacks. */
|
||||
int plugin_init(struct plugin_name_args *info,
|
||||
struct plugin_gcc_version *version) {
|
||||
|
||||
if (!plugin_default_version_check(version, &gcc_version))
|
||||
FATAL(G_("GCC and plugin have incompatible versions, expected GCC %s, "
|
||||
"is %s"),
|
||||
gcc_version.basever, version->basever);
|
||||
|
||||
/* Show a banner. */
|
||||
bool quiet = false;
|
||||
if (isatty(2) && !getenv("AFL_QUIET"))
|
||||
SAYF(cCYA "afl-gcc-cmptrs-pass " cBRI VERSION cRST
|
||||
" by <oliva@adacore.com>\n");
|
||||
else
|
||||
quiet = true;
|
||||
|
||||
const char *name = info->base_name;
|
||||
register_callback(name, PLUGIN_INFO, NULL, &afl_cmptrs_plugin);
|
||||
|
||||
afl_cmptrs_pass *aflp = new afl_cmptrs_pass(quiet);
|
||||
struct register_pass_info pass_info = {
|
||||
|
||||
.pass = aflp,
|
||||
.reference_pass_name = "ssa",
|
||||
.ref_pass_instance_number = 1,
|
||||
.pos_op = PASS_POS_INSERT_AFTER,
|
||||
|
||||
};
|
||||
|
||||
register_callback(name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
500
instrumentation/afl-gcc-common.h
Normal file
500
instrumentation/afl-gcc-common.h
Normal file
@ -0,0 +1,500 @@
|
||||
/* GCC plugin common infrastructure for AFL++ instrumentation passes.
|
||||
|
||||
Copyright 2014-2019 Free Software Foundation, Inc
|
||||
Copyright 2015, 2016 Google Inc. All rights reserved.
|
||||
Copyright 2019-2022 AdaCore
|
||||
|
||||
Written by Alexandre Oliva <oliva@adacore.com>, based on the AFL++
|
||||
GCC plugin.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "../include/config.h"
|
||||
#include "../include/debug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef likely
|
||||
#undef likely
|
||||
#endif
|
||||
#ifdef unlikely
|
||||
#undef unlikely
|
||||
#endif
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include <algorithm>
|
||||
#include <fnmatch.h>
|
||||
|
||||
#include <gcc-plugin.h>
|
||||
#include <plugin-version.h>
|
||||
#include <toplev.h>
|
||||
#include <tree-pass.h>
|
||||
#include <context.h>
|
||||
#include <tree.h>
|
||||
#include <gimplify.h>
|
||||
#include <basic-block.h>
|
||||
#include <tree-ssa-alias.h>
|
||||
#include <gimple-expr.h>
|
||||
#include <gimple.h>
|
||||
#include <gimple-iterator.h>
|
||||
#include <stringpool.h>
|
||||
#include <gimple-ssa.h>
|
||||
#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \
|
||||
60200 /* >= version 6.2.0 */
|
||||
#include <tree-vrp.h>
|
||||
#endif
|
||||
#include <tree-ssanames.h>
|
||||
#include <tree-phinodes.h>
|
||||
#include <ssa-iterators.h>
|
||||
|
||||
#include <intl.h>
|
||||
|
||||
namespace {
|
||||
|
||||
struct afl_base_pass : gimple_opt_pass {
|
||||
|
||||
afl_base_pass(bool quiet, bool debug, struct pass_data const &pd)
|
||||
: gimple_opt_pass(pd, g), be_quiet(quiet), debug(debug) {
|
||||
|
||||
initInstrumentList();
|
||||
|
||||
}
|
||||
|
||||
/* Are we outputting to a non-terminal, or running with AFL_QUIET
|
||||
set? */
|
||||
const bool be_quiet;
|
||||
|
||||
/* Are we running with AFL_DEBUG set? */
|
||||
const bool debug;
|
||||
|
||||
#define report_fatal_error(msg) BADF(msg)
|
||||
|
||||
std::list<std::string> allowListFiles;
|
||||
std::list<std::string> allowListFunctions;
|
||||
std::list<std::string> denyListFiles;
|
||||
std::list<std::string> denyListFunctions;
|
||||
|
||||
/* Note: this ignore check is also called in isInInstrumentList() */
|
||||
bool isIgnoreFunction(function *F) {
|
||||
|
||||
// Starting from "LLVMFuzzer" these are functions used in libfuzzer based
|
||||
// fuzzing campaign installations, e.g. oss-fuzz
|
||||
|
||||
static constexpr const char *ignoreList[] = {
|
||||
|
||||
"asan.",
|
||||
"llvm.",
|
||||
"sancov.",
|
||||
"__ubsan_",
|
||||
"ign.",
|
||||
"__afl_",
|
||||
"_fini",
|
||||
"__libc_csu",
|
||||
"__asan",
|
||||
"__msan",
|
||||
"__cmplog",
|
||||
"__sancov",
|
||||
"msan.",
|
||||
"LLVMFuzzerM",
|
||||
"LLVMFuzzerC",
|
||||
"LLVMFuzzerI",
|
||||
"__decide_deferred",
|
||||
"maybe_duplicate_stderr",
|
||||
"discard_output",
|
||||
"close_stdout",
|
||||
"dup_and_close_stderr",
|
||||
"maybe_close_fd_mask",
|
||||
"ExecuteFilesOnyByOne"
|
||||
|
||||
};
|
||||
|
||||
const char *name = IDENTIFIER_POINTER(DECL_NAME(F->decl));
|
||||
int len = IDENTIFIER_LENGTH(DECL_NAME(F->decl));
|
||||
|
||||
for (auto const &ignoreListFunc : ignoreList) {
|
||||
|
||||
if (strncmp(name, ignoreListFunc, len) == 0) { return true; }
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void initInstrumentList() {
|
||||
|
||||
char *allowlist = getenv("AFL_GCC_ALLOWLIST");
|
||||
if (!allowlist) allowlist = getenv("AFL_GCC_INSTRUMENT_FILE");
|
||||
if (!allowlist) allowlist = getenv("AFL_GCC_WHITELIST");
|
||||
if (!allowlist) allowlist = getenv("AFL_LLVM_ALLOWLIST");
|
||||
if (!allowlist) allowlist = getenv("AFL_LLVM_INSTRUMENT_FILE");
|
||||
if (!allowlist) allowlist = getenv("AFL_LLVM_WHITELIST");
|
||||
char *denylist = getenv("AFL_GCC_DENYLIST");
|
||||
if (!denylist) denylist = getenv("AFL_GCC_BLOCKLIST");
|
||||
if (!denylist) denylist = getenv("AFL_LLVM_DENYLIST");
|
||||
if (!denylist) denylist = getenv("AFL_LLVM_BLOCKLIST");
|
||||
|
||||
if (allowlist && denylist)
|
||||
FATAL(
|
||||
"You can only specify either AFL_GCC_ALLOWLIST or AFL_GCC_DENYLIST "
|
||||
"but not both!");
|
||||
|
||||
if (allowlist) {
|
||||
|
||||
std::string line;
|
||||
std::ifstream fileStream;
|
||||
fileStream.open(allowlist);
|
||||
if (!fileStream) report_fatal_error("Unable to open AFL_GCC_ALLOWLIST");
|
||||
getline(fileStream, line);
|
||||
|
||||
while (fileStream) {
|
||||
|
||||
int is_file = -1;
|
||||
std::size_t npos;
|
||||
std::string original_line = line;
|
||||
|
||||
line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
|
||||
line.end());
|
||||
|
||||
// remove # and following
|
||||
if ((npos = line.find("#")) != std::string::npos)
|
||||
line = line.substr(0, npos);
|
||||
|
||||
if (line.compare(0, 4, "fun:") == 0) {
|
||||
|
||||
is_file = 0;
|
||||
line = line.substr(4);
|
||||
|
||||
} else if (line.compare(0, 9, "function:") == 0) {
|
||||
|
||||
is_file = 0;
|
||||
line = line.substr(9);
|
||||
|
||||
} else if (line.compare(0, 4, "src:") == 0) {
|
||||
|
||||
is_file = 1;
|
||||
line = line.substr(4);
|
||||
|
||||
} else if (line.compare(0, 7, "source:") == 0) {
|
||||
|
||||
is_file = 1;
|
||||
line = line.substr(7);
|
||||
|
||||
}
|
||||
|
||||
if (line.find(":") != std::string::npos) {
|
||||
|
||||
FATAL("invalid line in AFL_GCC_ALLOWLIST: %s", original_line.c_str());
|
||||
|
||||
}
|
||||
|
||||
if (line.length() > 0) {
|
||||
|
||||
// if the entry contains / or . it must be a file
|
||||
if (is_file == -1)
|
||||
if (line.find("/") != std::string::npos ||
|
||||
line.find(".") != std::string::npos)
|
||||
is_file = 1;
|
||||
// otherwise it is a function
|
||||
|
||||
if (is_file == 1)
|
||||
allowListFiles.push_back(line);
|
||||
else
|
||||
allowListFunctions.push_back(line);
|
||||
|
||||
}
|
||||
|
||||
getline(fileStream, line);
|
||||
|
||||
}
|
||||
|
||||
if (debug)
|
||||
DEBUGF("loaded allowlist with %zu file and %zu function entries\n",
|
||||
allowListFiles.size(), allowListFunctions.size());
|
||||
|
||||
}
|
||||
|
||||
if (denylist) {
|
||||
|
||||
std::string line;
|
||||
std::ifstream fileStream;
|
||||
fileStream.open(denylist);
|
||||
if (!fileStream) report_fatal_error("Unable to open AFL_GCC_DENYLIST");
|
||||
getline(fileStream, line);
|
||||
|
||||
while (fileStream) {
|
||||
|
||||
int is_file = -1;
|
||||
std::size_t npos;
|
||||
std::string original_line = line;
|
||||
|
||||
line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
|
||||
line.end());
|
||||
|
||||
// remove # and following
|
||||
if ((npos = line.find("#")) != std::string::npos)
|
||||
line = line.substr(0, npos);
|
||||
|
||||
if (line.compare(0, 4, "fun:") == 0) {
|
||||
|
||||
is_file = 0;
|
||||
line = line.substr(4);
|
||||
|
||||
} else if (line.compare(0, 9, "function:") == 0) {
|
||||
|
||||
is_file = 0;
|
||||
line = line.substr(9);
|
||||
|
||||
} else if (line.compare(0, 4, "src:") == 0) {
|
||||
|
||||
is_file = 1;
|
||||
line = line.substr(4);
|
||||
|
||||
} else if (line.compare(0, 7, "source:") == 0) {
|
||||
|
||||
is_file = 1;
|
||||
line = line.substr(7);
|
||||
|
||||
}
|
||||
|
||||
if (line.find(":") != std::string::npos) {
|
||||
|
||||
FATAL("invalid line in AFL_GCC_DENYLIST: %s", original_line.c_str());
|
||||
|
||||
}
|
||||
|
||||
if (line.length() > 0) {
|
||||
|
||||
// if the entry contains / or . it must be a file
|
||||
if (is_file == -1)
|
||||
if (line.find("/") != std::string::npos ||
|
||||
line.find(".") != std::string::npos)
|
||||
is_file = 1;
|
||||
// otherwise it is a function
|
||||
|
||||
if (is_file == 1)
|
||||
denyListFiles.push_back(line);
|
||||
else
|
||||
denyListFunctions.push_back(line);
|
||||
|
||||
}
|
||||
|
||||
getline(fileStream, line);
|
||||
|
||||
}
|
||||
|
||||
if (debug)
|
||||
DEBUGF("loaded denylist with %zu file and %zu function entries\n",
|
||||
denyListFiles.size(), denyListFunctions.size());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Returns the source file name attached to the function declaration F. If
|
||||
there is no source location information, returns an empty string. */
|
||||
std::string getSourceName(function *F) {
|
||||
|
||||
return DECL_SOURCE_FILE(F->decl) ? DECL_SOURCE_FILE(F->decl) : "";
|
||||
|
||||
}
|
||||
|
||||
bool isInInstrumentList(function *F) {
|
||||
|
||||
bool return_default = true;
|
||||
|
||||
// is this a function with code? If it is external we don't instrument it
|
||||
// anyway and it can't be in the instrument file list. Or if it is it is
|
||||
// ignored.
|
||||
if (isIgnoreFunction(F)) return false;
|
||||
|
||||
if (!denyListFiles.empty() || !denyListFunctions.empty()) {
|
||||
|
||||
if (!denyListFunctions.empty()) {
|
||||
|
||||
std::string instFunction = IDENTIFIER_POINTER(DECL_NAME(F->decl));
|
||||
|
||||
for (std::list<std::string>::iterator it = denyListFunctions.begin();
|
||||
it != denyListFunctions.end(); ++it) {
|
||||
|
||||
/* We don't check for filename equality here because
|
||||
* filenames might actually be full paths. Instead we
|
||||
* check that the actual filename ends in the filename
|
||||
* specified in the list. We also allow UNIX-style pattern
|
||||
* matching */
|
||||
|
||||
if (instFunction.length() >= it->length()) {
|
||||
|
||||
if (fnmatch(("*" + *it).c_str(), instFunction.c_str(), 0) == 0) {
|
||||
|
||||
if (debug)
|
||||
DEBUGF(
|
||||
"Function %s is in the deny function list, not "
|
||||
"instrumenting ... \n",
|
||||
instFunction.c_str());
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!denyListFiles.empty()) {
|
||||
|
||||
std::string source_file = getSourceName(F);
|
||||
|
||||
if (!source_file.empty()) {
|
||||
|
||||
for (std::list<std::string>::iterator it = denyListFiles.begin();
|
||||
it != denyListFiles.end(); ++it) {
|
||||
|
||||
/* We don't check for filename equality here because
|
||||
* filenames might actually be full paths. Instead we
|
||||
* check that the actual filename ends in the filename
|
||||
* specified in the list. We also allow UNIX-style pattern
|
||||
* matching */
|
||||
|
||||
if (source_file.length() >= it->length()) {
|
||||
|
||||
if (fnmatch(("*" + *it).c_str(), source_file.c_str(), 0) == 0) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// we could not find out the location. in this case we say it is not
|
||||
// in the instrument file list
|
||||
if (!be_quiet)
|
||||
WARNF(
|
||||
"No debug information found for function %s, will be "
|
||||
"instrumented (recompile with -g -O[1-3]).",
|
||||
IDENTIFIER_POINTER(DECL_NAME(F->decl)));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if we do not have a instrument file list return true
|
||||
if (!allowListFiles.empty() || !allowListFunctions.empty()) {
|
||||
|
||||
return_default = false;
|
||||
|
||||
if (!allowListFunctions.empty()) {
|
||||
|
||||
std::string instFunction = IDENTIFIER_POINTER(DECL_NAME(F->decl));
|
||||
|
||||
for (std::list<std::string>::iterator it = allowListFunctions.begin();
|
||||
it != allowListFunctions.end(); ++it) {
|
||||
|
||||
/* We don't check for filename equality here because
|
||||
* filenames might actually be full paths. Instead we
|
||||
* check that the actual filename ends in the filename
|
||||
* specified in the list. We also allow UNIX-style pattern
|
||||
* matching */
|
||||
|
||||
if (instFunction.length() >= it->length()) {
|
||||
|
||||
if (fnmatch(("*" + *it).c_str(), instFunction.c_str(), 0) == 0) {
|
||||
|
||||
if (debug)
|
||||
DEBUGF(
|
||||
"Function %s is in the allow function list, instrumenting "
|
||||
"... \n",
|
||||
instFunction.c_str());
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!allowListFiles.empty()) {
|
||||
|
||||
std::string source_file = getSourceName(F);
|
||||
|
||||
if (!source_file.empty()) {
|
||||
|
||||
for (std::list<std::string>::iterator it = allowListFiles.begin();
|
||||
it != allowListFiles.end(); ++it) {
|
||||
|
||||
/* We don't check for filename equality here because
|
||||
* filenames might actually be full paths. Instead we
|
||||
* check that the actual filename ends in the filename
|
||||
* specified in the list. We also allow UNIX-style pattern
|
||||
* matching */
|
||||
|
||||
if (source_file.length() >= it->length()) {
|
||||
|
||||
if (fnmatch(("*" + *it).c_str(), source_file.c_str(), 0) == 0) {
|
||||
|
||||
if (debug)
|
||||
DEBUGF(
|
||||
"Function %s is in the allowlist (%s), instrumenting ... "
|
||||
"\n",
|
||||
IDENTIFIER_POINTER(DECL_NAME(F->decl)),
|
||||
source_file.c_str());
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// we could not find out the location. In this case we say it is not
|
||||
// in the instrument file list
|
||||
if (!be_quiet)
|
||||
WARNF(
|
||||
"No debug information found for function %s, will not be "
|
||||
"instrumented (recompile with -g -O[1-3]).",
|
||||
IDENTIFIER_POINTER(DECL_NAME(F->decl)));
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return return_default;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -124,50 +124,8 @@
|
||||
entry edge for the entry block.
|
||||
*/
|
||||
|
||||
#include "../include/config.h"
|
||||
#include "../include/debug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef likely
|
||||
#undef likely
|
||||
#endif
|
||||
#ifdef unlikely
|
||||
#undef unlikely
|
||||
#endif
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include <algorithm>
|
||||
#include <fnmatch.h>
|
||||
|
||||
#include <gcc-plugin.h>
|
||||
#include <plugin-version.h>
|
||||
#include <toplev.h>
|
||||
#include <tree-pass.h>
|
||||
#include <context.h>
|
||||
#include <tree.h>
|
||||
#include <gimplify.h>
|
||||
#include <basic-block.h>
|
||||
#include <tree-ssa-alias.h>
|
||||
#include <gimple-expr.h>
|
||||
#include <gimple.h>
|
||||
#include <gimple-iterator.h>
|
||||
#include <stringpool.h>
|
||||
#include <gimple-ssa.h>
|
||||
#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \
|
||||
60200 /* >= version 6.2.0 */
|
||||
#include <tree-vrp.h>
|
||||
#endif
|
||||
#include <tree-ssanames.h>
|
||||
#include <tree-phinodes.h>
|
||||
#include <ssa-iterators.h>
|
||||
|
||||
#include <intl.h>
|
||||
#include "afl-gcc-common.h"
|
||||
#include "memmodel.h"
|
||||
|
||||
/* This plugin, being under the same license as GCC, satisfies the
|
||||
"GPL-compatible Software" definition in the GCC RUNTIME LIBRARY
|
||||
@ -191,12 +149,10 @@ static constexpr struct pass_data afl_pass_data = {
|
||||
|
||||
};
|
||||
|
||||
struct afl_pass : gimple_opt_pass {
|
||||
struct afl_pass : afl_base_pass {
|
||||
|
||||
afl_pass(bool quiet, unsigned int ratio)
|
||||
: gimple_opt_pass(afl_pass_data, g),
|
||||
be_quiet(quiet),
|
||||
debug(!!getenv("AFL_DEBUG")),
|
||||
: afl_base_pass(quiet, !!getenv("AFL_DEBUG"), afl_pass_data),
|
||||
inst_ratio(ratio),
|
||||
#ifdef AFL_GCC_OUT_OF_LINE
|
||||
out_of_line(!!(AFL_GCC_OUT_OF_LINE)),
|
||||
@ -210,13 +166,6 @@ struct afl_pass : gimple_opt_pass {
|
||||
|
||||
}
|
||||
|
||||
/* Are we outputting to a non-terminal, or running with AFL_QUIET
|
||||
set? */
|
||||
const bool be_quiet;
|
||||
|
||||
/* Are we running with AFL_DEBUG set? */
|
||||
const bool debug;
|
||||
|
||||
/* How likely (%) is a block to be instrumented? */
|
||||
const unsigned int inst_ratio;
|
||||
|
||||
@ -297,21 +246,22 @@ struct afl_pass : gimple_opt_pass {
|
||||
gimple_build_assign(ntry, POINTER_PLUS_EXPR, map_ptr, indx);
|
||||
gimple_seq_add_stmt(&seq, idx_map);
|
||||
|
||||
/* Increment the counter in idx_map. */
|
||||
tree memref = build2(MEM_REF, TREE_TYPE(TREE_TYPE(ntry)), ntry,
|
||||
build_zero_cst(TREE_TYPE(ntry)));
|
||||
if (blocks == 0)
|
||||
cntr = create_tmp_var(TREE_TYPE(memref), ".afl_edge_count");
|
||||
|
||||
/* Load the count from the entry. */
|
||||
auto load_cntr = gimple_build_assign(cntr, memref);
|
||||
gimple_seq_add_stmt(&seq, load_cntr);
|
||||
|
||||
/* Prepare to add constant 1 to it. */
|
||||
tree incrv = build_one_cst(TREE_TYPE(cntr));
|
||||
tree incrv = build_one_cst(TREE_TYPE(TREE_TYPE(ntry)));
|
||||
|
||||
if (neverZero) {
|
||||
|
||||
/* Increment the counter in idx_map. */
|
||||
tree memref = build2(MEM_REF, TREE_TYPE(TREE_TYPE(ntry)), ntry,
|
||||
build_zero_cst(TREE_TYPE(ntry)));
|
||||
|
||||
if (blocks == 0)
|
||||
cntr = create_tmp_var(TREE_TYPE(memref), ".afl_edge_count");
|
||||
|
||||
/* Load the count from the entry. */
|
||||
auto load_cntr = gimple_build_assign(cntr, memref);
|
||||
gimple_seq_add_stmt(&seq, load_cntr);
|
||||
|
||||
/* NeverZero: if count wrapped around to zero, advance to
|
||||
one. */
|
||||
if (blocks == 0) {
|
||||
@ -348,16 +298,25 @@ struct afl_pass : gimple_opt_pass {
|
||||
in xincr. */
|
||||
incrv = xincr;
|
||||
|
||||
/* Add the increment (1 or the overflow bit) to count. */
|
||||
auto incr_cntr = gimple_build_assign(cntr, PLUS_EXPR, cntr, incrv);
|
||||
gimple_seq_add_stmt(&seq, incr_cntr);
|
||||
|
||||
/* Store count in the map entry. */
|
||||
auto store_cntr = gimple_build_assign(unshare_expr(memref), cntr);
|
||||
gimple_seq_add_stmt(&seq, store_cntr);
|
||||
|
||||
} else {
|
||||
|
||||
/* Use a serialized memory model. */
|
||||
tree memmod = build_int_cst(integer_type_node, MEMMODEL_SEQ_CST);
|
||||
|
||||
tree fadd = builtin_decl_explicit(BUILT_IN_ATOMIC_FETCH_ADD_1);
|
||||
auto incr_cntr = gimple_build_call(fadd, 3, ntry, incrv, memmod);
|
||||
gimple_seq_add_stmt(&seq, incr_cntr);
|
||||
|
||||
}
|
||||
|
||||
/* Add the increment (1 or the overflow bit) to count. */
|
||||
auto incr_cntr = gimple_build_assign(cntr, PLUS_EXPR, cntr, incrv);
|
||||
gimple_seq_add_stmt(&seq, incr_cntr);
|
||||
|
||||
/* Store count in the map entry. */
|
||||
auto store_cntr = gimple_build_assign(unshare_expr(memref), cntr);
|
||||
gimple_seq_add_stmt(&seq, store_cntr);
|
||||
|
||||
/* Store bid >> 1 in __afl_prev_loc. */
|
||||
auto shift_loc =
|
||||
gimple_build_assign(ploc, build_int_cst(TREE_TYPE(ploc), bid >> 1));
|
||||
@ -456,6 +415,8 @@ struct afl_pass : gimple_opt_pass {
|
||||
thread-local variable. */
|
||||
static inline tree get_afl_area_ptr_decl() {
|
||||
|
||||
/* If type changes, the size N in FETCH_ADD_<N> must be adjusted
|
||||
in builtin calls above. */
|
||||
tree type = build_pointer_type(unsigned_char_type_node);
|
||||
tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
|
||||
get_identifier("__afl_area_ptr"), type);
|
||||
@ -490,420 +451,11 @@ struct afl_pass : gimple_opt_pass {
|
||||
|
||||
}
|
||||
|
||||
#define report_fatal_error(msg) BADF(msg)
|
||||
|
||||
std::list<std::string> allowListFiles;
|
||||
std::list<std::string> allowListFunctions;
|
||||
std::list<std::string> denyListFiles;
|
||||
std::list<std::string> denyListFunctions;
|
||||
|
||||
/* Note: this ignore check is also called in isInInstrumentList() */
|
||||
bool isIgnoreFunction(function *F) {
|
||||
|
||||
// Starting from "LLVMFuzzer" these are functions used in libfuzzer based
|
||||
// fuzzing campaign installations, e.g. oss-fuzz
|
||||
|
||||
static constexpr const char *ignoreList[] = {
|
||||
|
||||
"asan.",
|
||||
"llvm.",
|
||||
"sancov.",
|
||||
"__ubsan_",
|
||||
"ign.",
|
||||
"__afl_",
|
||||
"_fini",
|
||||
"__libc_csu",
|
||||
"__asan",
|
||||
"__msan",
|
||||
"__cmplog",
|
||||
"__sancov",
|
||||
"msan.",
|
||||
"LLVMFuzzerM",
|
||||
"LLVMFuzzerC",
|
||||
"LLVMFuzzerI",
|
||||
"__decide_deferred",
|
||||
"maybe_duplicate_stderr",
|
||||
"discard_output",
|
||||
"close_stdout",
|
||||
"dup_and_close_stderr",
|
||||
"maybe_close_fd_mask",
|
||||
"ExecuteFilesOnyByOne"
|
||||
|
||||
};
|
||||
|
||||
const char *name = IDENTIFIER_POINTER(DECL_NAME(F->decl));
|
||||
int len = IDENTIFIER_LENGTH(DECL_NAME(F->decl));
|
||||
|
||||
for (auto const &ignoreListFunc : ignoreList) {
|
||||
|
||||
if (strncmp(name, ignoreListFunc, len) == 0) { return true; }
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void initInstrumentList() {
|
||||
|
||||
char *allowlist = getenv("AFL_GCC_ALLOWLIST");
|
||||
if (!allowlist) allowlist = getenv("AFL_GCC_INSTRUMENT_FILE");
|
||||
if (!allowlist) allowlist = getenv("AFL_GCC_WHITELIST");
|
||||
if (!allowlist) allowlist = getenv("AFL_LLVM_ALLOWLIST");
|
||||
if (!allowlist) allowlist = getenv("AFL_LLVM_INSTRUMENT_FILE");
|
||||
if (!allowlist) allowlist = getenv("AFL_LLVM_WHITELIST");
|
||||
char *denylist = getenv("AFL_GCC_DENYLIST");
|
||||
if (!denylist) denylist = getenv("AFL_GCC_BLOCKLIST");
|
||||
if (!denylist) denylist = getenv("AFL_LLVM_DENYLIST");
|
||||
if (!denylist) denylist = getenv("AFL_LLVM_BLOCKLIST");
|
||||
|
||||
if (allowlist && denylist)
|
||||
FATAL(
|
||||
"You can only specify either AFL_GCC_ALLOWLIST or AFL_GCC_DENYLIST "
|
||||
"but not both!");
|
||||
|
||||
if (allowlist) {
|
||||
|
||||
std::string line;
|
||||
std::ifstream fileStream;
|
||||
fileStream.open(allowlist);
|
||||
if (!fileStream) report_fatal_error("Unable to open AFL_GCC_ALLOWLIST");
|
||||
getline(fileStream, line);
|
||||
|
||||
while (fileStream) {
|
||||
|
||||
int is_file = -1;
|
||||
std::size_t npos;
|
||||
std::string original_line = line;
|
||||
|
||||
line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
|
||||
line.end());
|
||||
|
||||
// remove # and following
|
||||
if ((npos = line.find("#")) != std::string::npos)
|
||||
line = line.substr(0, npos);
|
||||
|
||||
if (line.compare(0, 4, "fun:") == 0) {
|
||||
|
||||
is_file = 0;
|
||||
line = line.substr(4);
|
||||
|
||||
} else if (line.compare(0, 9, "function:") == 0) {
|
||||
|
||||
is_file = 0;
|
||||
line = line.substr(9);
|
||||
|
||||
} else if (line.compare(0, 4, "src:") == 0) {
|
||||
|
||||
is_file = 1;
|
||||
line = line.substr(4);
|
||||
|
||||
} else if (line.compare(0, 7, "source:") == 0) {
|
||||
|
||||
is_file = 1;
|
||||
line = line.substr(7);
|
||||
|
||||
}
|
||||
|
||||
if (line.find(":") != std::string::npos) {
|
||||
|
||||
FATAL("invalid line in AFL_GCC_ALLOWLIST: %s", original_line.c_str());
|
||||
|
||||
}
|
||||
|
||||
if (line.length() > 0) {
|
||||
|
||||
// if the entry contains / or . it must be a file
|
||||
if (is_file == -1)
|
||||
if (line.find("/") != std::string::npos ||
|
||||
line.find(".") != std::string::npos)
|
||||
is_file = 1;
|
||||
// otherwise it is a function
|
||||
|
||||
if (is_file == 1)
|
||||
allowListFiles.push_back(line);
|
||||
else
|
||||
allowListFunctions.push_back(line);
|
||||
|
||||
}
|
||||
|
||||
getline(fileStream, line);
|
||||
|
||||
}
|
||||
|
||||
if (debug)
|
||||
DEBUGF("loaded allowlist with %zu file and %zu function entries\n",
|
||||
allowListFiles.size(), allowListFunctions.size());
|
||||
|
||||
}
|
||||
|
||||
if (denylist) {
|
||||
|
||||
std::string line;
|
||||
std::ifstream fileStream;
|
||||
fileStream.open(denylist);
|
||||
if (!fileStream) report_fatal_error("Unable to open AFL_GCC_DENYLIST");
|
||||
getline(fileStream, line);
|
||||
|
||||
while (fileStream) {
|
||||
|
||||
int is_file = -1;
|
||||
std::size_t npos;
|
||||
std::string original_line = line;
|
||||
|
||||
line.erase(std::remove_if(line.begin(), line.end(), ::isspace),
|
||||
line.end());
|
||||
|
||||
// remove # and following
|
||||
if ((npos = line.find("#")) != std::string::npos)
|
||||
line = line.substr(0, npos);
|
||||
|
||||
if (line.compare(0, 4, "fun:") == 0) {
|
||||
|
||||
is_file = 0;
|
||||
line = line.substr(4);
|
||||
|
||||
} else if (line.compare(0, 9, "function:") == 0) {
|
||||
|
||||
is_file = 0;
|
||||
line = line.substr(9);
|
||||
|
||||
} else if (line.compare(0, 4, "src:") == 0) {
|
||||
|
||||
is_file = 1;
|
||||
line = line.substr(4);
|
||||
|
||||
} else if (line.compare(0, 7, "source:") == 0) {
|
||||
|
||||
is_file = 1;
|
||||
line = line.substr(7);
|
||||
|
||||
}
|
||||
|
||||
if (line.find(":") != std::string::npos) {
|
||||
|
||||
FATAL("invalid line in AFL_GCC_DENYLIST: %s", original_line.c_str());
|
||||
|
||||
}
|
||||
|
||||
if (line.length() > 0) {
|
||||
|
||||
// if the entry contains / or . it must be a file
|
||||
if (is_file == -1)
|
||||
if (line.find("/") != std::string::npos ||
|
||||
line.find(".") != std::string::npos)
|
||||
is_file = 1;
|
||||
// otherwise it is a function
|
||||
|
||||
if (is_file == 1)
|
||||
denyListFiles.push_back(line);
|
||||
else
|
||||
denyListFunctions.push_back(line);
|
||||
|
||||
}
|
||||
|
||||
getline(fileStream, line);
|
||||
|
||||
}
|
||||
|
||||
if (debug)
|
||||
DEBUGF("loaded denylist with %zu file and %zu function entries\n",
|
||||
denyListFiles.size(), denyListFunctions.size());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Returns the source file name attached to the function declaration F. If
|
||||
there is no source location information, returns an empty string. */
|
||||
std::string getSourceName(function *F) {
|
||||
|
||||
return DECL_SOURCE_FILE(F->decl) ? DECL_SOURCE_FILE(F->decl) : "";
|
||||
|
||||
}
|
||||
|
||||
bool isInInstrumentList(function *F) {
|
||||
|
||||
bool return_default = true;
|
||||
|
||||
// is this a function with code? If it is external we don't instrument it
|
||||
// anyway and it can't be in the instrument file list. Or if it is it is
|
||||
// ignored.
|
||||
if (isIgnoreFunction(F)) return false;
|
||||
|
||||
if (!denyListFiles.empty() || !denyListFunctions.empty()) {
|
||||
|
||||
if (!denyListFunctions.empty()) {
|
||||
|
||||
std::string instFunction = IDENTIFIER_POINTER(DECL_NAME(F->decl));
|
||||
|
||||
for (std::list<std::string>::iterator it = denyListFunctions.begin();
|
||||
it != denyListFunctions.end(); ++it) {
|
||||
|
||||
/* We don't check for filename equality here because
|
||||
* filenames might actually be full paths. Instead we
|
||||
* check that the actual filename ends in the filename
|
||||
* specified in the list. We also allow UNIX-style pattern
|
||||
* matching */
|
||||
|
||||
if (instFunction.length() >= it->length()) {
|
||||
|
||||
if (fnmatch(("*" + *it).c_str(), instFunction.c_str(), 0) == 0) {
|
||||
|
||||
if (debug)
|
||||
DEBUGF(
|
||||
"Function %s is in the deny function list, not "
|
||||
"instrumenting ... \n",
|
||||
instFunction.c_str());
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!denyListFiles.empty()) {
|
||||
|
||||
std::string source_file = getSourceName(F);
|
||||
|
||||
if (!source_file.empty()) {
|
||||
|
||||
for (std::list<std::string>::iterator it = denyListFiles.begin();
|
||||
it != denyListFiles.end(); ++it) {
|
||||
|
||||
/* We don't check for filename equality here because
|
||||
* filenames might actually be full paths. Instead we
|
||||
* check that the actual filename ends in the filename
|
||||
* specified in the list. We also allow UNIX-style pattern
|
||||
* matching */
|
||||
|
||||
if (source_file.length() >= it->length()) {
|
||||
|
||||
if (fnmatch(("*" + *it).c_str(), source_file.c_str(), 0) == 0) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// we could not find out the location. in this case we say it is not
|
||||
// in the instrument file list
|
||||
if (!be_quiet)
|
||||
WARNF(
|
||||
"No debug information found for function %s, will be "
|
||||
"instrumented (recompile with -g -O[1-3]).",
|
||||
IDENTIFIER_POINTER(DECL_NAME(F->decl)));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if we do not have a instrument file list return true
|
||||
if (!allowListFiles.empty() || !allowListFunctions.empty()) {
|
||||
|
||||
return_default = false;
|
||||
|
||||
if (!allowListFunctions.empty()) {
|
||||
|
||||
std::string instFunction = IDENTIFIER_POINTER(DECL_NAME(F->decl));
|
||||
|
||||
for (std::list<std::string>::iterator it = allowListFunctions.begin();
|
||||
it != allowListFunctions.end(); ++it) {
|
||||
|
||||
/* We don't check for filename equality here because
|
||||
* filenames might actually be full paths. Instead we
|
||||
* check that the actual filename ends in the filename
|
||||
* specified in the list. We also allow UNIX-style pattern
|
||||
* matching */
|
||||
|
||||
if (instFunction.length() >= it->length()) {
|
||||
|
||||
if (fnmatch(("*" + *it).c_str(), instFunction.c_str(), 0) == 0) {
|
||||
|
||||
if (debug)
|
||||
DEBUGF(
|
||||
"Function %s is in the allow function list, instrumenting "
|
||||
"... \n",
|
||||
instFunction.c_str());
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!allowListFiles.empty()) {
|
||||
|
||||
std::string source_file = getSourceName(F);
|
||||
|
||||
if (!source_file.empty()) {
|
||||
|
||||
for (std::list<std::string>::iterator it = allowListFiles.begin();
|
||||
it != allowListFiles.end(); ++it) {
|
||||
|
||||
/* We don't check for filename equality here because
|
||||
* filenames might actually be full paths. Instead we
|
||||
* check that the actual filename ends in the filename
|
||||
* specified in the list. We also allow UNIX-style pattern
|
||||
* matching */
|
||||
|
||||
if (source_file.length() >= it->length()) {
|
||||
|
||||
if (fnmatch(("*" + *it).c_str(), source_file.c_str(), 0) == 0) {
|
||||
|
||||
if (debug)
|
||||
DEBUGF(
|
||||
"Function %s is in the allowlist (%s), instrumenting ... "
|
||||
"\n",
|
||||
IDENTIFIER_POINTER(DECL_NAME(F->decl)),
|
||||
source_file.c_str());
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// we could not find out the location. In this case we say it is not
|
||||
// in the instrument file list
|
||||
if (!be_quiet)
|
||||
WARNF(
|
||||
"No debug information found for function %s, will not be "
|
||||
"instrumented (recompile with -g -O[1-3]).",
|
||||
IDENTIFIER_POINTER(DECL_NAME(F->decl)));
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return return_default;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static struct plugin_info afl_plugin = {
|
||||
|
||||
.version = "20220907",
|
||||
.version = "20220420",
|
||||
.help = G_("AFL gcc plugin\n\
|
||||
\n\
|
||||
Set AFL_QUIET in the environment to silence it.\n\
|
||||
@ -920,7 +472,7 @@ Specify -frandom-seed for reproducible instrumentation.\n\
|
||||
|
||||
/* This is the function GCC calls when loading a plugin. Initialize
|
||||
and register further callbacks. */
|
||||
int plugin_init(struct plugin_name_args * info,
|
||||
int plugin_init(struct plugin_name_args *info,
|
||||
struct plugin_gcc_version *version) {
|
||||
|
||||
if (!plugin_default_version_check(version, &gcc_version))
|
||||
@ -950,7 +502,7 @@ int plugin_init(struct plugin_name_args * info,
|
||||
const char *name = info->base_name;
|
||||
register_callback(name, PLUGIN_INFO, NULL, &afl_plugin);
|
||||
|
||||
afl_pass * aflp = new afl_pass(quiet, inst_ratio);
|
||||
afl_pass *aflp = new afl_pass(quiet, inst_ratio);
|
||||
struct register_pass_info pass_info = {
|
||||
|
||||
.pass = aflp,
|
||||
|
@ -181,7 +181,7 @@ bool AFLdict2filePass::runOnModule(Module &M) {
|
||||
#endif
|
||||
|
||||
DenseMap<Value *, std::string *> valueMap;
|
||||
char * ptr;
|
||||
char *ptr;
|
||||
int found = 0;
|
||||
|
||||
/* Show a banner */
|
||||
@ -246,11 +246,11 @@ bool AFLdict2filePass::runOnModule(Module &M) {
|
||||
for (auto &IN : BB) {
|
||||
|
||||
CallInst *callInst = nullptr;
|
||||
CmpInst * cmpInst = nullptr;
|
||||
CmpInst *cmpInst = nullptr;
|
||||
|
||||
if ((cmpInst = dyn_cast<CmpInst>(&IN))) {
|
||||
|
||||
Value * op = cmpInst->getOperand(1);
|
||||
Value *op = cmpInst->getOperand(1);
|
||||
ConstantInt *ilen = dyn_cast<ConstantInt>(op);
|
||||
|
||||
/* We skip > 64 bit integers. why? first because their value is
|
||||
@ -518,7 +518,7 @@ bool AFLdict2filePass::runOnModule(Module &M) {
|
||||
|
||||
if (HasStr2 == true) {
|
||||
|
||||
Value * op2 = callInst->getArgOperand(2);
|
||||
Value *op2 = callInst->getArgOperand(2);
|
||||
ConstantInt *ilen = dyn_cast<ConstantInt>(op2);
|
||||
if (ilen) {
|
||||
|
||||
@ -631,7 +631,7 @@ bool AFLdict2filePass::runOnModule(Module &M) {
|
||||
|
||||
if (isMemcmp || isStrncmp || isStrncasecmp) {
|
||||
|
||||
Value * op2 = callInst->getArgOperand(2);
|
||||
Value *op2 = callInst->getArgOperand(2);
|
||||
ConstantInt *ilen = dyn_cast<ConstantInt>(op2);
|
||||
|
||||
if (ilen) {
|
||||
|
@ -101,7 +101,7 @@ llvmGetPassPluginInfo() {
|
||||
|
||||
}
|
||||
|
||||
PreservedAnalyses AFLcheckIfInstrument::run(Module & M,
|
||||
PreservedAnalyses AFLcheckIfInstrument::run(Module &M,
|
||||
ModuleAnalysisManager &MAM) {
|
||||
|
||||
/* Show a banner */
|
||||
@ -135,7 +135,7 @@ PreservedAnalyses AFLcheckIfInstrument::run(Module & M,
|
||||
DEBUGF("function %s is NOT in the instrument file list\n",
|
||||
F.getName().str().c_str());
|
||||
|
||||
auto & Ctx = F.getContext();
|
||||
auto &Ctx = F.getContext();
|
||||
AttributeList Attrs = F.getAttributes();
|
||||
#if LLVM_VERSION_MAJOR >= 14
|
||||
AttributeList NewAttrs = Attrs.addFnAttribute(Ctx, "skipinstrument");
|
||||
|
@ -251,7 +251,7 @@ bool AFLCoverage::runOnModule(Module &M) {
|
||||
|
||||
/* Decide instrumentation ratio */
|
||||
|
||||
char * inst_ratio_str = getenv("AFL_INST_RATIO");
|
||||
char *inst_ratio_str = getenv("AFL_INST_RATIO");
|
||||
unsigned int inst_ratio = 100;
|
||||
|
||||
if (inst_ratio_str) {
|
||||
@ -486,7 +486,7 @@ bool AFLCoverage::runOnModule(Module &M) {
|
||||
|
||||
Constant *PrevLocShuffleMask = ConstantVector::get(PrevLocShuffle);
|
||||
|
||||
Constant * PrevCallerShuffleMask = NULL;
|
||||
Constant *PrevCallerShuffleMask = NULL;
|
||||
SmallVector<Constant *, 32> PrevCallerShuffle = {UndefValue::get(Int32Ty)};
|
||||
|
||||
if (ctx_k) {
|
||||
@ -506,7 +506,7 @@ bool AFLCoverage::runOnModule(Module &M) {
|
||||
// other constants we need
|
||||
ConstantInt *One = ConstantInt::get(Int8Ty, 1);
|
||||
|
||||
Value * PrevCtx = NULL; // CTX sensitive coverage
|
||||
Value *PrevCtx = NULL; // CTX sensitive coverage
|
||||
LoadInst *PrevCaller = NULL; // K-CTX coverage
|
||||
|
||||
/* Instrument all the things! */
|
||||
|
@ -156,9 +156,9 @@ Iterator Unique(Iterator first, Iterator last) {
|
||||
bool CmpLogInstructions::hookInstrs(Module &M) {
|
||||
|
||||
std::vector<Instruction *> icomps;
|
||||
LLVMContext & C = M.getContext();
|
||||
LLVMContext &C = M.getContext();
|
||||
|
||||
Type * VoidTy = Type::getVoidTy(C);
|
||||
Type *VoidTy = Type::getVoidTy(C);
|
||||
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
|
||||
IntegerType *Int16Ty = IntegerType::getInt16Ty(C);
|
||||
IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
|
||||
@ -338,7 +338,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
|
||||
IntegerType *intTyOp1 = NULL;
|
||||
unsigned max_size = 0, cast_size = 0;
|
||||
unsigned attr = 0, vector_cnt = 0, is_fp = 0;
|
||||
CmpInst * cmpInst = dyn_cast<CmpInst>(selectcmpInst);
|
||||
CmpInst *cmpInst = dyn_cast<CmpInst>(selectcmpInst);
|
||||
|
||||
if (!cmpInst) { continue; }
|
||||
|
||||
@ -666,7 +666,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
|
||||
}
|
||||
|
||||
#if LLVM_MAJOR >= 11 /* use new pass manager */
|
||||
PreservedAnalyses CmpLogInstructions::run(Module & M,
|
||||
PreservedAnalyses CmpLogInstructions::run(Module &M,
|
||||
ModuleAnalysisManager &MAM) {
|
||||
|
||||
#else
|
||||
|
@ -506,8 +506,8 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
||||
IRBuilder<> IRB(ThenTerm);
|
||||
|
||||
std::vector<Value *> args;
|
||||
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
Value *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
args.push_back(v1Pcasted);
|
||||
args.push_back(v2Pcasted);
|
||||
|
||||
@ -537,10 +537,10 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
||||
IRBuilder<> IRB(ThenTerm);
|
||||
|
||||
std::vector<Value *> args;
|
||||
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
Value * v3Pbitcast = IRB.CreateBitCast(
|
||||
v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
|
||||
Value *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
Value *v3Pbitcast = IRB.CreateBitCast(
|
||||
v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
|
||||
Value *v3Pcasted =
|
||||
IRB.CreateIntCast(v3Pbitcast, IntegerType::get(C, 64), false);
|
||||
args.push_back(v1Pcasted);
|
||||
@ -572,8 +572,8 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
||||
IRBuilder<> IRB(ThenTerm);
|
||||
|
||||
std::vector<Value *> args;
|
||||
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
Value *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
args.push_back(v1Pcasted);
|
||||
args.push_back(v2Pcasted);
|
||||
|
||||
@ -603,10 +603,10 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
||||
IRBuilder<> IRB(ThenTerm);
|
||||
|
||||
std::vector<Value *> args;
|
||||
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
Value * v3Pbitcast = IRB.CreateBitCast(
|
||||
v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
|
||||
Value *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
Value *v3Pbitcast = IRB.CreateBitCast(
|
||||
v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
|
||||
Value *v3Pcasted =
|
||||
IRB.CreateIntCast(v3Pbitcast, IntegerType::get(C, 64), false);
|
||||
args.push_back(v1Pcasted);
|
||||
@ -638,8 +638,8 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
||||
IRBuilder<> IRB(ThenTerm);
|
||||
|
||||
std::vector<Value *> args;
|
||||
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
Value *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
args.push_back(v1Pcasted);
|
||||
args.push_back(v2Pcasted);
|
||||
|
||||
@ -668,8 +668,8 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
||||
IRBuilder<> IRB(ThenTerm);
|
||||
|
||||
std::vector<Value *> args;
|
||||
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
Value *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
args.push_back(v1Pcasted);
|
||||
args.push_back(v2Pcasted);
|
||||
|
||||
@ -698,8 +698,8 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
||||
IRBuilder<> IRB(ThenTerm);
|
||||
|
||||
std::vector<Value *> args;
|
||||
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
Value *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
args.push_back(v1Pcasted);
|
||||
args.push_back(v2Pcasted);
|
||||
|
||||
@ -728,8 +728,8 @@ bool CmpLogRoutines::hookRtns(Module &M) {
|
||||
IRBuilder<> IRB(ThenTerm);
|
||||
|
||||
std::vector<Value *> args;
|
||||
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
Value *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
|
||||
Value *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
|
||||
args.push_back(v1Pcasted);
|
||||
args.push_back(v2Pcasted);
|
||||
|
||||
|
@ -149,9 +149,9 @@ Iterator Unique(Iterator first, Iterator last) {
|
||||
bool CmplogSwitches::hookInstrs(Module &M) {
|
||||
|
||||
std::vector<SwitchInst *> switches;
|
||||
LLVMContext & C = M.getContext();
|
||||
LLVMContext &C = M.getContext();
|
||||
|
||||
Type * VoidTy = Type::getVoidTy(C);
|
||||
Type *VoidTy = Type::getVoidTy(C);
|
||||
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
|
||||
IntegerType *Int16Ty = IntegerType::getInt16Ty(C);
|
||||
IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
|
||||
@ -270,7 +270,7 @@ bool CmplogSwitches::hookInstrs(Module &M) {
|
||||
|
||||
for (auto &SI : switches) {
|
||||
|
||||
Value * Val = SI->getCondition();
|
||||
Value *Val = SI->getCondition();
|
||||
unsigned int max_size = Val->getType()->getIntegerBitWidth(), cast_size;
|
||||
unsigned char do_cast = 0;
|
||||
|
||||
|
@ -168,10 +168,10 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
||||
|
||||
DenseMap<Value *, std::string *> valueMap;
|
||||
std::vector<CallInst *> calls;
|
||||
LLVMContext & C = M.getContext();
|
||||
IntegerType * Int8Ty = IntegerType::getInt8Ty(C);
|
||||
IntegerType * Int32Ty = IntegerType::getInt32Ty(C);
|
||||
IntegerType * Int64Ty = IntegerType::getInt64Ty(C);
|
||||
LLVMContext &C = M.getContext();
|
||||
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
|
||||
IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
|
||||
IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 9
|
||||
FunctionCallee tolowerFn;
|
||||
@ -409,7 +409,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
||||
|
||||
/* check if third operand is a constant integer
|
||||
* strlen("constStr") and sizeof() are treated as constant */
|
||||
Value * op2 = callInst->getArgOperand(2);
|
||||
Value *op2 = callInst->getArgOperand(2);
|
||||
ConstantInt *ilen = dyn_cast<ConstantInt>(op2);
|
||||
if (ilen) {
|
||||
|
||||
@ -449,7 +449,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
||||
*Str2P = callInst->getArgOperand(1);
|
||||
StringRef Str1, Str2, ConstStr;
|
||||
std::string TmpConstStr;
|
||||
Value * VarStr;
|
||||
Value *VarStr;
|
||||
bool HasStr1 = getConstantStringInfo(Str1P, Str1);
|
||||
bool HasStr2 = getConstantStringInfo(Str2P, Str2);
|
||||
uint64_t constStrLen, unrollLen, constSizedLen = 0;
|
||||
@ -457,7 +457,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
||||
bool isSizedcmp = false;
|
||||
bool isCaseInsensitive = false;
|
||||
bool needs_null = false;
|
||||
Function * Callee = callInst->getCalledFunction();
|
||||
Function *Callee = callInst->getCalledFunction();
|
||||
|
||||
if (Callee) {
|
||||
|
||||
@ -616,14 +616,14 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
||||
|
||||
for (uint64_t i = 0; i < unrollLen; i++) {
|
||||
|
||||
BasicBlock * cur_cmp_bb = next_cmp_bb, *cur_lenchk_bb = next_lenchk_bb;
|
||||
BasicBlock *cur_cmp_bb = next_cmp_bb, *cur_lenchk_bb = next_lenchk_bb;
|
||||
unsigned char c;
|
||||
|
||||
if (cur_lenchk_bb) {
|
||||
|
||||
IRBuilder<> cur_lenchk_IRB(&*(cur_lenchk_bb->getFirstInsertionPt()));
|
||||
Value * icmp = cur_lenchk_IRB.CreateICmpEQ(
|
||||
sizedValue, ConstantInt::get(sizedValue->getType(), i));
|
||||
Value *icmp = cur_lenchk_IRB.CreateICmpEQ(
|
||||
sizedValue, ConstantInt::get(sizedValue->getType(), i));
|
||||
cur_lenchk_IRB.CreateCondBr(icmp, end_bb, cur_cmp_bb);
|
||||
cur_lenchk_bb->getTerminator()->eraseFromParent();
|
||||
|
||||
|
@ -230,9 +230,9 @@ char SplitComparesTransform::ID = 0;
|
||||
/// FCMP instructions with predicate xGT or xLT and EQ
|
||||
bool SplitComparesTransform::simplifyFPCompares(Module &M) {
|
||||
|
||||
LLVMContext & C = M.getContext();
|
||||
LLVMContext &C = M.getContext();
|
||||
std::vector<Instruction *> fcomps;
|
||||
IntegerType * Int1Ty = IntegerType::getInt1Ty(C);
|
||||
IntegerType *Int1Ty = IntegerType::getInt1Ty(C);
|
||||
|
||||
/* iterate over all functions, bbs and instruction and add
|
||||
* all integer comparisons with >= and <= predicates to the icomps vector */
|
||||
@ -362,8 +362,8 @@ bool SplitComparesTransform::simplifyFPCompares(Module &M) {
|
||||
|
||||
/// This function splits ICMP instructions with xGE or xLE predicates into two
|
||||
/// ICMP instructions with predicate xGT or xLT and EQ
|
||||
bool SplitComparesTransform::simplifyOrEqualsCompare(CmpInst * IcmpInst,
|
||||
Module & M,
|
||||
bool SplitComparesTransform::simplifyOrEqualsCompare(CmpInst *IcmpInst,
|
||||
Module &M,
|
||||
CmpWorklist &worklist) {
|
||||
|
||||
LLVMContext &C = M.getContext();
|
||||
@ -498,7 +498,7 @@ bool SplitComparesTransform::simplifySignedCompare(CmpInst *IcmpInst, Module &M,
|
||||
|
||||
/* create a new basic block which is executed if the signedness bit is
|
||||
* different */
|
||||
CmpInst * icmp_inv_sig_cmp;
|
||||
CmpInst *icmp_inv_sig_cmp;
|
||||
BasicBlock *sign_bb =
|
||||
BasicBlock::Create(C, "sign", end_bb->getParent(), end_bb);
|
||||
if (pred == CmpInst::ICMP_SGT) {
|
||||
@ -522,7 +522,7 @@ bool SplitComparesTransform::simplifySignedCompare(CmpInst *IcmpInst, Module &M,
|
||||
BranchInst::Create(end_bb, sign_bb);
|
||||
|
||||
/* create a new bb which is executed if signedness is equal */
|
||||
CmpInst * icmp_usign_cmp;
|
||||
CmpInst *icmp_usign_cmp;
|
||||
BasicBlock *middle_bb =
|
||||
BasicBlock::Create(C, "injected", end_bb->getParent(), end_bb);
|
||||
/* we can do a normal unsigned compare now */
|
||||
@ -566,8 +566,17 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M,
|
||||
case CmpInst::ICMP_NE:
|
||||
case CmpInst::ICMP_UGT:
|
||||
case CmpInst::ICMP_ULT:
|
||||
case CmpInst::ICMP_UGE:
|
||||
case CmpInst::ICMP_ULE:
|
||||
case CmpInst::ICMP_SGT:
|
||||
case CmpInst::ICMP_SLT:
|
||||
case CmpInst::ICMP_SGE:
|
||||
case CmpInst::ICMP_SLE:
|
||||
break;
|
||||
default:
|
||||
if (!be_quiet)
|
||||
fprintf(stderr, "Error: split-compare: Unsupported predicate (%u)\n",
|
||||
pred);
|
||||
// unsupported predicate!
|
||||
return false;
|
||||
|
||||
@ -581,6 +590,8 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M,
|
||||
if (!intTyOp0) {
|
||||
|
||||
// not an integer type
|
||||
if (!be_quiet)
|
||||
fprintf(stderr, "Error: split-compare: not an integer type\n");
|
||||
return false;
|
||||
|
||||
}
|
||||
@ -595,11 +606,11 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M,
|
||||
|
||||
LLVMContext &C = M.getContext();
|
||||
IntegerType *Int1Ty = IntegerType::getInt1Ty(C);
|
||||
BasicBlock * bb = cmp_inst->getParent();
|
||||
BasicBlock *bb = cmp_inst->getParent();
|
||||
IntegerType *OldIntType = IntegerType::get(C, bitw);
|
||||
IntegerType *NewIntType = IntegerType::get(C, bitw / 2);
|
||||
BasicBlock * end_bb = bb->splitBasicBlock(BasicBlock::iterator(cmp_inst));
|
||||
CmpInst * icmp_high, *icmp_low;
|
||||
BasicBlock *end_bb = bb->splitBasicBlock(BasicBlock::iterator(cmp_inst));
|
||||
CmpInst *icmp_high, *icmp_low;
|
||||
|
||||
/* create the comparison of the top halves of the original operands */
|
||||
Value *s_op0, *op0_high, *s_op1, *op1_high;
|
||||
@ -629,7 +640,7 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M,
|
||||
BasicBlock *cmp_low_bb =
|
||||
BasicBlock::Create(C, "" /*"injected"*/, end_bb->getParent(), end_bb);
|
||||
|
||||
Value * op0_low, *op1_low;
|
||||
Value *op0_low, *op1_low;
|
||||
IRBuilder<> Builder(cmp_low_bb);
|
||||
|
||||
op0_low = Builder.CreateTrunc(op0, NewIntType);
|
||||
@ -675,6 +686,12 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M,
|
||||
|
||||
}
|
||||
|
||||
case CmpInst::ICMP_SGE:
|
||||
case CmpInst::ICMP_SLE:
|
||||
case CmpInst::ICMP_SGT:
|
||||
case CmpInst::ICMP_SLT:
|
||||
case CmpInst::ICMP_UGE:
|
||||
case CmpInst::ICMP_ULE:
|
||||
case CmpInst::ICMP_UGT:
|
||||
case CmpInst::ICMP_ULT: {
|
||||
|
||||
@ -684,10 +701,11 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M,
|
||||
* if this is true we can go to the end if not we have to go to the
|
||||
* bb which checks the lower half of the operands */
|
||||
Instruction *op0_low, *op1_low;
|
||||
CmpInst * icmp_inv_cmp = nullptr;
|
||||
BasicBlock * inv_cmp_bb =
|
||||
CmpInst *icmp_inv_cmp = nullptr;
|
||||
BasicBlock *inv_cmp_bb =
|
||||
BasicBlock::Create(C, "inv_cmp", end_bb->getParent(), end_bb);
|
||||
if (pred == CmpInst::ICMP_UGT) {
|
||||
if (pred == CmpInst::ICMP_UGT || pred == CmpInst::ICMP_SGT ||
|
||||
pred == CmpInst::ICMP_UGE || pred == CmpInst::ICMP_SGE) {
|
||||
|
||||
icmp_inv_cmp = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT,
|
||||
op0_high, op1_high);
|
||||
@ -729,6 +747,8 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M,
|
||||
}
|
||||
|
||||
default:
|
||||
if (!be_quiet)
|
||||
fprintf(stderr, "Error: split-compare: should not happen\n");
|
||||
return false;
|
||||
|
||||
}
|
||||
@ -944,7 +964,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
||||
// BUG FIXME TODO: u64 does not work for > 64 bit ... e.g. 80 and 128 bit
|
||||
if (sizeInBits > 64) { continue; }
|
||||
|
||||
IntegerType * intType = IntegerType::get(C, op_size);
|
||||
IntegerType *intType = IntegerType::get(C, op_size);
|
||||
const unsigned int precision = sizeInBits == 32 ? 24
|
||||
: sizeInBits == 64 ? 53
|
||||
: sizeInBits == 128 ? 113
|
||||
@ -1052,8 +1072,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
||||
/*** now working in nonan_bb ***/
|
||||
|
||||
/* Treat -0.0 as equal to +0.0, that is for -0.0 make it +0.0 */
|
||||
Instruction * b_op0, *b_op1;
|
||||
Instruction * isMzero_op0, *isMzero_op1;
|
||||
Instruction *b_op0, *b_op1;
|
||||
Instruction *isMzero_op0, *isMzero_op1;
|
||||
const unsigned long long MinusZero = 1UL << (sizeInBits - 1U);
|
||||
const unsigned long long PlusZero = 0;
|
||||
|
||||
@ -1172,7 +1192,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
||||
/* compare the exponents of the operands */
|
||||
Instruction *icmp_exponents_equal;
|
||||
Instruction *icmp_exponent_result;
|
||||
BasicBlock * signequal2_bb = signequal_bb;
|
||||
BasicBlock *signequal2_bb = signequal_bb;
|
||||
switch (FcmpInst->getPredicate()) {
|
||||
|
||||
case CmpInst::FCMP_UEQ:
|
||||
@ -1342,8 +1362,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
||||
|
||||
/* compare the fractions of the operands */
|
||||
Instruction *icmp_fraction_result;
|
||||
BasicBlock * middle2_bb = middle_bb;
|
||||
PHINode * PN2 = nullptr;
|
||||
BasicBlock *middle2_bb = middle_bb;
|
||||
PHINode *PN2 = nullptr;
|
||||
switch (FcmpInst->getPredicate()) {
|
||||
|
||||
case CmpInst::FCMP_UEQ:
|
||||
@ -1484,7 +1504,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
||||
}
|
||||
|
||||
#if LLVM_MAJOR >= 11
|
||||
PreservedAnalyses SplitComparesTransform::run(Module & M,
|
||||
PreservedAnalyses SplitComparesTransform::run(Module &M,
|
||||
ModuleAnalysisManager &MAM) {
|
||||
|
||||
#else
|
||||
|
@ -102,7 +102,7 @@ class SplitSwitchesTransform : public ModulePass {
|
||||
struct CaseExpr {
|
||||
|
||||
ConstantInt *Val;
|
||||
BasicBlock * BB;
|
||||
BasicBlock *BB;
|
||||
|
||||
CaseExpr(ConstantInt *val = nullptr, BasicBlock *bb = nullptr)
|
||||
: Val(val), BB(bb) {
|
||||
@ -182,7 +182,7 @@ BasicBlock *SplitSwitchesTransform::switchConvert(
|
||||
unsigned ValTypeBitWidth = Cases[0].Val->getBitWidth();
|
||||
IntegerType *ValType =
|
||||
IntegerType::get(OrigBlock->getContext(), ValTypeBitWidth);
|
||||
IntegerType * ByteType = IntegerType::get(OrigBlock->getContext(), 8);
|
||||
IntegerType *ByteType = IntegerType::get(OrigBlock->getContext(), 8);
|
||||
unsigned BytesInValue = bytesChecked.size();
|
||||
std::vector<uint8_t> setSizes;
|
||||
std::vector<std::set<uint8_t> > byteSets(BytesInValue, std::set<uint8_t>());
|
||||
@ -221,8 +221,8 @@ BasicBlock *SplitSwitchesTransform::switchConvert(
|
||||
/* there are only smallestSize different bytes at index smallestIndex */
|
||||
|
||||
Instruction *Shift, *Trunc;
|
||||
Function * F = OrigBlock->getParent();
|
||||
BasicBlock * NewNode = BasicBlock::Create(Val->getContext(), "NodeBlock", F);
|
||||
Function *F = OrigBlock->getParent();
|
||||
BasicBlock *NewNode = BasicBlock::Create(Val->getContext(), "NodeBlock", F);
|
||||
Shift = BinaryOperator::Create(Instruction::LShr, Val,
|
||||
ConstantInt::get(ValType, smallestIndex * 8));
|
||||
NewNode->getInstList().push_back(Shift);
|
||||
@ -403,9 +403,9 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
|
||||
|
||||
BasicBlock *CurBlock = SI->getParent();
|
||||
BasicBlock *OrigBlock = CurBlock;
|
||||
Function * F = CurBlock->getParent();
|
||||
Function *F = CurBlock->getParent();
|
||||
/* this is the value we are switching on */
|
||||
Value * Val = SI->getCondition();
|
||||
Value *Val = SI->getCondition();
|
||||
BasicBlock *Default = SI->getDefaultDest();
|
||||
unsigned bitw = Val->getType()->getIntegerBitWidth();
|
||||
|
||||
@ -445,7 +445,7 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
|
||||
* round up bytesChecked (in case getBitWidth() % 8 != 0) */
|
||||
std::vector<bool> bytesChecked((7 + Cases[0].Val->getBitWidth()) / 8,
|
||||
false);
|
||||
BasicBlock * SwitchBlock =
|
||||
BasicBlock *SwitchBlock =
|
||||
switchConvert(Cases, bytesChecked, OrigBlock, NewDefault, Val, 0);
|
||||
|
||||
/* Branch to our shiny new if-then stuff... */
|
||||
@ -483,7 +483,7 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
|
||||
}
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
|
||||
PreservedAnalyses SplitSwitchesTransform::run(Module & M,
|
||||
PreservedAnalyses SplitSwitchesTransform::run(Module &M,
|
||||
ModuleAnalysisManager &MAM) {
|
||||
|
||||
#else
|
||||
|
@ -1,4 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "================================================="
|
||||
echo " Nyx build script"
|
||||
echo "================================================="
|
||||
@ -6,14 +9,14 @@ echo
|
||||
|
||||
echo "[*] Performing basic sanity checks..."
|
||||
|
||||
if [ ! "`uname -s`" = "Linux" ]; then
|
||||
if [ ! "$(uname -s)" = "Linux" ]; then
|
||||
|
||||
echo "[-] Error: Nyx mode is only available on Linux."
|
||||
exit 0
|
||||
|
||||
fi
|
||||
|
||||
if [ ! "`uname -m`" = "x86_64" ]; then
|
||||
if [ ! "$(uname -m)" = "x86_64" ]; then
|
||||
|
||||
echo "[-] Error: Nyx mode is only available on x86_64 (yet)."
|
||||
exit 0
|
||||
@ -22,10 +25,10 @@ fi
|
||||
|
||||
echo "[*] Making sure all Nyx is checked out"
|
||||
|
||||
git status 1>/dev/null 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
|
||||
git submodule init || exit 1
|
||||
if git status 1>/dev/null 2>&1; then
|
||||
|
||||
git submodule init
|
||||
echo "[*] initializing QEMU-Nyx submodule"
|
||||
git submodule update ./QEMU-Nyx 2>/dev/null # ignore errors
|
||||
echo "[*] initializing packer submodule"
|
||||
@ -47,32 +50,27 @@ test -e QEMU-Nyx/.git || { echo "[-] QEMU-Nyx not checked out, please install gi
|
||||
|
||||
echo "[*] checking packer init.cpio.gz ..."
|
||||
if [ ! -f "packer/linux_initramfs/init.cpio.gz" ]; then
|
||||
cd packer/linux_initramfs/
|
||||
sh pack.sh || exit 1
|
||||
cd ../../
|
||||
(cd packer/linux_initramfs/ && sh pack.sh)
|
||||
fi
|
||||
|
||||
echo "[*] Checking libnyx ..."
|
||||
if [ ! -f "libnyx/libnyx/target/release/liblibnyx.a" ]; then
|
||||
cd libnyx/libnyx
|
||||
cargo build --release || exit 1
|
||||
cd ../../
|
||||
(cd libnyx/libnyx && cargo build --release)
|
||||
fi
|
||||
|
||||
echo "[*] Checking QEMU-Nyx ..."
|
||||
if [ ! -f "QEMU-Nyx/x86_64-softmmu/qemu-system-x86_64" ]; then
|
||||
cd QEMU-Nyx/
|
||||
./compile_qemu_nyx.sh static || exit 1
|
||||
cd ..
|
||||
|
||||
if ! dpkg -s gtk3-devel > /dev/null 2>&1; then
|
||||
echo "[-] Disabling GTK because gtk3-devel is not installed."
|
||||
sed -i 's/--enable-gtk//g' QEMU-Nyx/compile_qemu_nyx.sh
|
||||
fi
|
||||
(cd QEMU-Nyx && ./compile_qemu_nyx.sh static)
|
||||
fi
|
||||
|
||||
echo "[*] Checking libnyx.so ..."
|
||||
if [ -f "libnyx/libnyx/target/release/liblibnyx.so" ]; then
|
||||
cp -v libnyx/libnyx/target/release/liblibnyx.so ../libnyx.so || exit 1
|
||||
else
|
||||
echo "[ ] libnyx.so not found..."
|
||||
exit 1
|
||||
fi
|
||||
cp libnyx/libnyx/target/release/liblibnyx.so ../libnyx.so
|
||||
|
||||
echo "[+] All done for nyx_mode, enjoy!"
|
||||
|
||||
exit 0
|
||||
|
@ -273,7 +273,7 @@ echo "[+] Configuration complete."
|
||||
|
||||
echo "[*] Attempting to build QEMU (fingers crossed!)..."
|
||||
|
||||
make -j `nproc` || exit 1
|
||||
make -j$(nproc) || exit 1
|
||||
|
||||
echo "[+] Build process successful!"
|
||||
|
||||
|
@ -139,7 +139,7 @@ static void __compcov_load(void) {
|
||||
char *bin_name = getenv("AFL_COMPCOV_BINNAME");
|
||||
|
||||
procmaps_iterator *maps = pmparser_parse(-1);
|
||||
procmaps_struct * maps_tmp = NULL;
|
||||
procmaps_struct *maps_tmp = NULL;
|
||||
|
||||
while ((maps_tmp = pmparser_next(maps)) != NULL) {
|
||||
|
||||
|
@ -32,8 +32,8 @@ implied warranty.
|
||||
*/
|
||||
typedef struct procmaps_struct {
|
||||
|
||||
void * addr_start; //< start address of the area
|
||||
void * addr_end; //< end address
|
||||
void *addr_start; //< start address of the area
|
||||
void *addr_end; //< end address
|
||||
unsigned long length; //< size of the range
|
||||
|
||||
char perm[5]; //< permissions rwxp
|
||||
|
@ -1390,7 +1390,7 @@ DLMALLOC_EXPORT void *mspace_memalign(mspace msp, size_t alignment,
|
||||
*/
|
||||
DLMALLOC_EXPORT void **mspace_independent_calloc(mspace msp, size_t n_elements,
|
||||
size_t elem_size,
|
||||
void * chunks[]);
|
||||
void *chunks[]);
|
||||
|
||||
/*
|
||||
mspace_independent_comalloc behaves as independent_comalloc, but
|
||||
@ -1399,7 +1399,7 @@ DLMALLOC_EXPORT void **mspace_independent_calloc(mspace msp, size_t n_elements,
|
||||
DLMALLOC_EXPORT void **mspace_independent_comalloc(mspace msp,
|
||||
size_t n_elements,
|
||||
size_t sizes[],
|
||||
void * chunks[]);
|
||||
void *chunks[]);
|
||||
|
||||
/*
|
||||
mspace_footprint() returns the number of bytes obtained from the
|
||||
@ -2607,7 +2607,7 @@ typedef struct malloc_tree_chunk *tbinptr; /* The type of bins of trees */
|
||||
|
||||
struct malloc_segment {
|
||||
|
||||
char * base; /* base address */
|
||||
char *base; /* base address */
|
||||
size_t size; /* allocated size */
|
||||
struct malloc_segment *next; /* ptr to next segment */
|
||||
flag_t sflags; /* mmap and extern flag */
|
||||
@ -2723,7 +2723,7 @@ struct malloc_state {
|
||||
binmap_t treemap;
|
||||
size_t dvsize;
|
||||
size_t topsize;
|
||||
char * least_addr;
|
||||
char *least_addr;
|
||||
mchunkptr dv;
|
||||
mchunkptr top;
|
||||
size_t trim_check;
|
||||
@ -2739,7 +2739,7 @@ struct malloc_state {
|
||||
MLOCK_T mutex; /* locate lock among fields that rarely change */
|
||||
#endif /* USE_LOCKS */
|
||||
msegment seg;
|
||||
void * extp; /* Unused but available for extensions */
|
||||
void *extp; /* Unused but available for extensions */
|
||||
size_t exts;
|
||||
|
||||
};
|
||||
@ -3593,7 +3593,7 @@ static void do_check_tree(mstate m, tchunkptr t) {
|
||||
/* Check all the chunks in a treebin. */
|
||||
static void do_check_treebin(mstate m, bindex_t i) {
|
||||
|
||||
tbinptr * tb = treebin_at(m, i);
|
||||
tbinptr *tb = treebin_at(m, i);
|
||||
tchunkptr t = *tb;
|
||||
int empty = (m->treemap & (1U << i)) == 0;
|
||||
if (t == 0) assert(empty);
|
||||
@ -3886,11 +3886,7 @@ static void internal_malloc_stats(mstate m) {
|
||||
mark_smallmap(M, I); \
|
||||
else if (RTCHECK(ok_address(M, B->fd))) \
|
||||
F = B->fd; \
|
||||
else { \
|
||||
\
|
||||
CORRUPTION_ERROR_ACTION(M); \
|
||||
\
|
||||
} \
|
||||
else { CORRUPTION_ERROR_ACTION(M); } \
|
||||
B->fd = P; \
|
||||
F->bk = P; \
|
||||
P->fd = F; \
|
||||
@ -4104,11 +4100,7 @@ static void internal_malloc_stats(mstate m) {
|
||||
} \
|
||||
if (RTCHECK(ok_address(M, RP))) \
|
||||
*RP = 0; \
|
||||
else { \
|
||||
\
|
||||
CORRUPTION_ERROR_ACTION(M); \
|
||||
\
|
||||
} \
|
||||
else { CORRUPTION_ERROR_ACTION(M); } \
|
||||
\
|
||||
} \
|
||||
\
|
||||
@ -4278,7 +4270,7 @@ static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) {
|
||||
size_t offset = oldp->prev_foot;
|
||||
size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD;
|
||||
size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
|
||||
char * cp =
|
||||
char *cp =
|
||||
(char *)CALL_MREMAP((char *)oldp - offset, oldmmsize, newmmsize, flags);
|
||||
if (cp != CMFAIL) {
|
||||
|
||||
@ -4412,14 +4404,14 @@ static void *prepend_alloc(mstate m, char *newbase, char *oldbase, size_t nb) {
|
||||
static void add_segment(mstate m, char *tbase, size_t tsize, flag_t mmapped) {
|
||||
|
||||
/* Determine locations and sizes of segment, fenceposts, old top */
|
||||
char * old_top = (char *)m->top;
|
||||
char *old_top = (char *)m->top;
|
||||
msegmentptr oldsp = segment_holding(m, old_top);
|
||||
char * old_end = oldsp->base + oldsp->size;
|
||||
char *old_end = oldsp->base + oldsp->size;
|
||||
size_t ssize = pad_request(sizeof(struct malloc_segment));
|
||||
char * rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
|
||||
char *rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
|
||||
size_t offset = align_offset(chunk2mem(rawsp));
|
||||
char * asp = rawsp + offset;
|
||||
char * csp = (asp < (old_top + MIN_CHUNK_SIZE)) ? old_top : asp;
|
||||
char *asp = rawsp + offset;
|
||||
char *csp = (asp < (old_top + MIN_CHUNK_SIZE)) ? old_top : asp;
|
||||
mchunkptr sp = (mchunkptr)csp;
|
||||
msegmentptr ss = (msegmentptr)(chunk2mem(sp));
|
||||
mchunkptr tnext = chunk_plus_offset(sp, ssize);
|
||||
@ -4473,7 +4465,7 @@ static void add_segment(mstate m, char *tbase, size_t tsize, flag_t mmapped) {
|
||||
/* Get memory from system using MORECORE or MMAP */
|
||||
static void *sys_alloc(mstate m, size_t nb) {
|
||||
|
||||
char * tbase = CMFAIL;
|
||||
char *tbase = CMFAIL;
|
||||
size_t tsize = 0;
|
||||
flag_t mmap_flag = 0;
|
||||
size_t asize; /* allocation size */
|
||||
@ -4521,7 +4513,7 @@ static void *sys_alloc(mstate m, size_t nb) {
|
||||
|
||||
if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) {
|
||||
|
||||
char * br = CMFAIL;
|
||||
char *br = CMFAIL;
|
||||
size_t ssize = asize; /* sbrk call size */
|
||||
msegmentptr ss = (m->top == 0) ? 0 : segment_holding(m, (char *)m->top);
|
||||
ACQUIRE_MALLOC_GLOBAL_LOCK();
|
||||
@ -4728,7 +4720,7 @@ static size_t release_unused_segments(mstate m) {
|
||||
msegmentptr sp = pred->next;
|
||||
while (sp != 0) {
|
||||
|
||||
char * base = sp->base;
|
||||
char *base = sp->base;
|
||||
size_t size = sp->size;
|
||||
msegmentptr next = sp->next;
|
||||
++nsegs;
|
||||
@ -5151,7 +5143,7 @@ void *dlmalloc(size_t bytes) {
|
||||
|
||||
if (!PREACTION(gm)) {
|
||||
|
||||
void * mem;
|
||||
void *mem;
|
||||
size_t nb;
|
||||
if (bytes <= MAX_SMALL_REQUEST) {
|
||||
|
||||
@ -5430,7 +5422,7 @@ void dlfree(void *mem) {
|
||||
|
||||
void *dlcalloc(size_t n_elements, size_t elem_size) {
|
||||
|
||||
void * mem;
|
||||
void *mem;
|
||||
size_t req = 0;
|
||||
if (n_elements != 0) {
|
||||
|
||||
@ -5598,9 +5590,10 @@ static void *internal_memalign(mstate m, size_t alignment, size_t bytes) {
|
||||
We've allocated enough total room so that this is always
|
||||
possible.
|
||||
*/
|
||||
char * br = (char *)mem2chunk((size_t)(
|
||||
((size_t)((char *)mem + alignment - SIZE_T_ONE)) & -alignment));
|
||||
char * pos = ((size_t)(br - (char *)(p)) >= MIN_CHUNK_SIZE)
|
||||
char *br = (char *)mem2chunk(
|
||||
(size_t)(((size_t)((char *)mem + alignment - SIZE_T_ONE)) &
|
||||
-alignment));
|
||||
char *pos = ((size_t)(br - (char *)(p)) >= MIN_CHUNK_SIZE)
|
||||
? br
|
||||
: br + alignment;
|
||||
mchunkptr newp = (mchunkptr)pos;
|
||||
@ -5666,10 +5659,10 @@ static void **ialloc(mstate m, size_t n_elements, size_t *sizes, int opts,
|
||||
size_t element_size; /* chunksize of each element, if all same */
|
||||
size_t contents_size; /* total size of elements */
|
||||
size_t array_size; /* request size of pointer array */
|
||||
void * mem; /* malloced aggregate space */
|
||||
void *mem; /* malloced aggregate space */
|
||||
mchunkptr p; /* corresponding chunk */
|
||||
size_t remainder_size; /* remaining bytes while splitting */
|
||||
void ** marray; /* either "chunks" or malloced ptr array */
|
||||
void **marray; /* either "chunks" or malloced ptr array */
|
||||
mchunkptr array_chunk; /* chunk for malloced ptr array */
|
||||
flag_t was_enabled; /* to disable mmap */
|
||||
size_t size;
|
||||
@ -5828,7 +5821,7 @@ static size_t internal_bulk_free(mstate m, void *array[], size_t nelem) {
|
||||
*a = 0;
|
||||
if (RTCHECK(ok_address(m, p) && ok_inuse(p))) {
|
||||
|
||||
void ** b = a + 1; /* try to merge with next chunk */
|
||||
void **b = a + 1; /* try to merge with next chunk */
|
||||
mchunkptr next = next_chunk(p);
|
||||
if (b != fence && *b == chunk2mem(next)) {
|
||||
|
||||
@ -5865,7 +5858,7 @@ static size_t internal_bulk_free(mstate m, void *array[], size_t nelem) {
|
||||
static void internal_inspect_all(mstate m,
|
||||
void (*handler)(void *start, void *end,
|
||||
size_t used_bytes,
|
||||
void * callback_arg),
|
||||
void *callback_arg),
|
||||
void *arg) {
|
||||
|
||||
if (is_initialized(m)) {
|
||||
@ -5880,7 +5873,7 @@ static void internal_inspect_all(mstate m,
|
||||
mchunkptr next = next_chunk(q);
|
||||
size_t sz = chunksize(q);
|
||||
size_t used;
|
||||
void * start;
|
||||
void *start;
|
||||
if (is_inuse(q)) {
|
||||
|
||||
used = sz - CHUNK_OVERHEAD; /* must not be mmapped */
|
||||
@ -6113,7 +6106,7 @@ size_t dlbulk_free(void *array[], size_t nelem) {
|
||||
#if MALLOC_INSPECT_ALL
|
||||
void dlmalloc_inspect_all(void (*handler)(void *start, void *end,
|
||||
size_t used_bytes,
|
||||
void * callback_arg),
|
||||
void *callback_arg),
|
||||
void *arg) {
|
||||
|
||||
ensure_initialization();
|
||||
@ -6253,7 +6246,7 @@ mspace create_mspace(size_t capacity, int locked) {
|
||||
size_t rs = ((capacity == 0) ? mparams.granularity
|
||||
: (capacity + TOP_FOOT_SIZE + msize));
|
||||
size_t tsize = granularity_align(rs);
|
||||
char * tbase = (char *)(CALL_MMAP(tsize));
|
||||
char *tbase = (char *)(CALL_MMAP(tsize));
|
||||
if (tbase != CMFAIL) {
|
||||
|
||||
m = init_user_mstate(tbase, tsize);
|
||||
@ -6322,7 +6315,7 @@ size_t destroy_mspace(mspace msp) {
|
||||
(void)DESTROY_LOCK(&ms->mutex); /* destroy before unmapped */
|
||||
while (sp != 0) {
|
||||
|
||||
char * base = sp->base;
|
||||
char *base = sp->base;
|
||||
size_t size = sp->size;
|
||||
flag_t flag = sp->sflags;
|
||||
(void)base; /* placate people compiling -Wunused-variable */
|
||||
@ -6360,7 +6353,7 @@ void *mspace_malloc(mspace msp, size_t bytes) {
|
||||
|
||||
if (!PREACTION(ms)) {
|
||||
|
||||
void * mem;
|
||||
void *mem;
|
||||
size_t nb;
|
||||
if (bytes <= MAX_SMALL_REQUEST) {
|
||||
|
||||
@ -6628,7 +6621,7 @@ void mspace_free(mspace msp, void *mem) {
|
||||
|
||||
void *mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) {
|
||||
|
||||
void * mem;
|
||||
void *mem;
|
||||
size_t req = 0;
|
||||
mstate ms = (mstate)msp;
|
||||
if (!ok_magic(ms)) {
|
||||
|
@ -97,19 +97,19 @@ void __libqasan_init_malloc(void);
|
||||
void __libqasan_hotpatch(void);
|
||||
|
||||
size_t __libqasan_malloc_usable_size(void *ptr);
|
||||
void * __libqasan_malloc(size_t size);
|
||||
void *__libqasan_malloc(size_t size);
|
||||
void __libqasan_free(void *ptr);
|
||||
void * __libqasan_calloc(size_t nmemb, size_t size);
|
||||
void * __libqasan_realloc(void *ptr, size_t size);
|
||||
void *__libqasan_calloc(size_t nmemb, size_t size);
|
||||
void *__libqasan_realloc(void *ptr, size_t size);
|
||||
int __libqasan_posix_memalign(void **ptr, size_t align, size_t len);
|
||||
void * __libqasan_memalign(size_t align, size_t len);
|
||||
void * __libqasan_aligned_alloc(size_t align, size_t len);
|
||||
void *__libqasan_memalign(size_t align, size_t len);
|
||||
void *__libqasan_aligned_alloc(size_t align, size_t len);
|
||||
|
||||
void * __libqasan_memcpy(void *dest, const void *src, size_t n);
|
||||
void * __libqasan_memmove(void *dest, const void *src, size_t n);
|
||||
void * __libqasan_memset(void *s, int c, size_t n);
|
||||
void * __libqasan_memchr(const void *s, int c, size_t n);
|
||||
void * __libqasan_memrchr(const void *s, int c, size_t n);
|
||||
void *__libqasan_memcpy(void *dest, const void *src, size_t n);
|
||||
void *__libqasan_memmove(void *dest, const void *src, size_t n);
|
||||
void *__libqasan_memset(void *s, int c, size_t n);
|
||||
void *__libqasan_memchr(const void *s, int c, size_t n);
|
||||
void *__libqasan_memrchr(const void *s, int c, size_t n);
|
||||
size_t __libqasan_strlen(const char *s);
|
||||
size_t __libqasan_strnlen(const char *s, size_t len);
|
||||
int __libqasan_strcmp(const char *str1, const char *str2);
|
||||
@ -118,12 +118,12 @@ int __libqasan_strcasecmp(const char *str1, const char *str2);
|
||||
int __libqasan_strncasecmp(const char *str1, const char *str2, size_t len);
|
||||
int __libqasan_memcmp(const void *mem1, const void *mem2, size_t len);
|
||||
int __libqasan_bcmp(const void *mem1, const void *mem2, size_t len);
|
||||
char * __libqasan_strstr(const char *haystack, const char *needle);
|
||||
char * __libqasan_strcasestr(const char *haystack, const char *needle);
|
||||
void * __libqasan_memmem(const void *haystack, size_t haystack_len,
|
||||
char *__libqasan_strstr(const char *haystack, const char *needle);
|
||||
char *__libqasan_strcasestr(const char *haystack, const char *needle);
|
||||
void *__libqasan_memmem(const void *haystack, size_t haystack_len,
|
||||
const void *needle, size_t needle_len);
|
||||
char * __libqasan_strchr(const char *s, int c);
|
||||
char * __libqasan_strrchr(const char *s, int c);
|
||||
char *__libqasan_strchr(const char *s, int c);
|
||||
char *__libqasan_strrchr(const char *s, int c);
|
||||
size_t __libqasan_wcslen(const wchar_t *s);
|
||||
wchar_t *__libqasan_wcscpy(wchar_t *d, const wchar_t *s);
|
||||
int __libqasan_wcscmp(const wchar_t *s1, const wchar_t *s2);
|
||||
|
@ -51,7 +51,7 @@ typedef struct {
|
||||
struct chunk_begin {
|
||||
|
||||
size_t requested_size;
|
||||
void * aligned_orig; // NULL if not aligned
|
||||
void *aligned_orig; // NULL if not aligned
|
||||
struct chunk_begin *next;
|
||||
struct chunk_begin *prev;
|
||||
char redzone[REDZONE_SIZE];
|
||||
@ -80,7 +80,7 @@ static unsigned char __tmp_alloc_zone[TMP_ZONE_SIZE];
|
||||
#else
|
||||
|
||||
// From dlmalloc.c
|
||||
void * dlmalloc(size_t);
|
||||
void *dlmalloc(size_t);
|
||||
void dlfree(void *);
|
||||
#define backend_malloc dlmalloc
|
||||
#define backend_free dlfree
|
||||
|
@ -130,8 +130,8 @@ int libc_perms;
|
||||
|
||||
static void find_libc(void) {
|
||||
|
||||
FILE * fp;
|
||||
char * line = NULL;
|
||||
FILE *fp;
|
||||
char *line = NULL;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
|
||||
@ -147,7 +147,7 @@ static void find_libc(void) {
|
||||
fields = sscanf(line,
|
||||
"%" PRIx64 "-%" PRIx64 " %c%c%c%c %" PRIx64
|
||||
" %x:%x %d"
|
||||
" %512s",
|
||||
" %511s",
|
||||
&min, &max, &flag_r, &flag_w, &flag_x, &flag_p, &offset,
|
||||
&dev_maj, &dev_min, &inode, path);
|
||||
|
||||
|
@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
void *__libqasan_memcpy(void *dest, const void *src, size_t n) {
|
||||
|
||||
unsigned char * d = dest;
|
||||
unsigned char *d = dest;
|
||||
const unsigned char *s = src;
|
||||
|
||||
if (!n) return dest;
|
||||
@ -47,7 +47,7 @@ void *__libqasan_memcpy(void *dest, const void *src, size_t n) {
|
||||
|
||||
void *__libqasan_memmove(void *dest, const void *src, size_t n) {
|
||||
|
||||
unsigned char * d = dest;
|
||||
unsigned char *d = dest;
|
||||
const unsigned char *s = src;
|
||||
|
||||
if (!n) return dest;
|
||||
|
@ -626,7 +626,7 @@ static void handle_stop_sig(int sig) {
|
||||
|
||||
static void set_up_environment(char **argv) {
|
||||
|
||||
u8 * x;
|
||||
u8 *x;
|
||||
char *afl_preload;
|
||||
char *frida_afl_preload = NULL;
|
||||
|
||||
|
30
src/afl-cc.c
30
src/afl-cc.c
@ -45,7 +45,7 @@
|
||||
#define LLVM_MINOR 0
|
||||
#endif
|
||||
|
||||
static u8 * obj_path; /* Path to runtime libraries */
|
||||
static u8 *obj_path; /* Path to runtime libraries */
|
||||
static u8 **cc_params; /* Parameters passed to the real CC */
|
||||
static u32 cc_par_cnt = 1; /* Param count, including argv0 */
|
||||
static u8 clang_mode; /* Invoked as afl-clang*? */
|
||||
@ -53,7 +53,7 @@ static u8 llvm_fullpath[PATH_MAX];
|
||||
static u8 instrument_mode, instrument_opt_mode, ngram_size, ctx_k, lto_mode;
|
||||
static u8 compiler_mode, plusplus_mode, have_instr_env = 0;
|
||||
static u8 have_gcc, have_llvm, have_gcc_plugin, have_lto, have_instr_list = 0;
|
||||
static u8 * lto_flag = AFL_CLANG_FLTO, *argvnull;
|
||||
static u8 *lto_flag = AFL_CLANG_FLTO, *argvnull;
|
||||
static u8 debug;
|
||||
static u8 cwd[4096];
|
||||
static u8 cmplog_mode;
|
||||
@ -422,8 +422,24 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
|
||||
if (compiler_mode == GCC_PLUGIN) {
|
||||
|
||||
char *fplugin_arg = alloc_printf("-fplugin=%s/afl-gcc-pass.so", obj_path);
|
||||
cc_params[cc_par_cnt++] = fplugin_arg;
|
||||
char *fplugin_arg;
|
||||
|
||||
if (cmplog_mode) {
|
||||
|
||||
fplugin_arg =
|
||||
alloc_printf("-fplugin=%s/afl-gcc-cmplog-pass.so", obj_path);
|
||||
cc_params[cc_par_cnt++] = fplugin_arg;
|
||||
fplugin_arg =
|
||||
alloc_printf("-fplugin=%s/afl-gcc-cmptrs-pass.so", obj_path);
|
||||
cc_params[cc_par_cnt++] = fplugin_arg;
|
||||
|
||||
} else {
|
||||
|
||||
fplugin_arg = alloc_printf("-fplugin=%s/afl-gcc-pass.so", obj_path);
|
||||
cc_params[cc_par_cnt++] = fplugin_arg;
|
||||
|
||||
}
|
||||
|
||||
cc_params[cc_par_cnt++] = "-fno-if-conversion";
|
||||
cc_params[cc_par_cnt++] = "-fno-if-conversion2";
|
||||
|
||||
@ -1879,6 +1895,7 @@ int main(int argc, char **argv, char **envp) {
|
||||
if (have_gcc_plugin)
|
||||
SAYF(
|
||||
"\nGCC Plugin-specific environment variables:\n"
|
||||
" AFL_GCC_CMPLOG: log operands of comparisons (RedQueen mutator)\n"
|
||||
" AFL_GCC_OUT_OF_LINE: disable inlined instrumentation\n"
|
||||
" AFL_GCC_SKIP_NEVERZERO: do not skip zero on trace counters\n"
|
||||
" AFL_GCC_INSTRUMENT_FILE: enable selective instrumentation by "
|
||||
@ -2149,9 +2166,8 @@ int main(int argc, char **argv, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
cmplog_mode = getenv("AFL_CMPLOG") || getenv("AFL_LLVM_CMPLOG");
|
||||
if (!be_quiet && cmplog_mode)
|
||||
printf("CmpLog mode by <andreafioraldi@gmail.com>\n");
|
||||
cmplog_mode = getenv("AFL_CMPLOG") || getenv("AFL_LLVM_CMPLOG") ||
|
||||
getenv("AFL_GCC_CMPLOG");
|
||||
|
||||
#if !defined(__ANDROID__) && !defined(ANDROID)
|
||||
ptr = find_object("afl-compiler-rt.o", argv[0]);
|
||||
|
@ -558,9 +558,9 @@ void print_suggested_envs(char *mispelled_env) {
|
||||
|
||||
for (j = 0; afl_environment_variables[j] != NULL; ++j) {
|
||||
|
||||
char * afl_env = afl_environment_variables[j] + 4;
|
||||
char *afl_env = afl_environment_variables[j] + 4;
|
||||
size_t afl_env_len = strlen(afl_env);
|
||||
char * reduced = ck_alloc(afl_env_len + 1);
|
||||
char *reduced = ck_alloc(afl_env_len + 1);
|
||||
|
||||
size_t start = 0;
|
||||
while (start < afl_env_len) {
|
||||
@ -598,7 +598,7 @@ void print_suggested_envs(char *mispelled_env) {
|
||||
|
||||
if (found) goto cleanup;
|
||||
|
||||
char * reduced = ck_alloc(env_name_len + 1);
|
||||
char *reduced = ck_alloc(env_name_len + 1);
|
||||
size_t start = 0;
|
||||
while (start < env_name_len) {
|
||||
|
||||
@ -1197,7 +1197,7 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) {
|
||||
u32 get_map_size(void) {
|
||||
|
||||
uint32_t map_size = DEFAULT_SHMEM_SIZE;
|
||||
char * ptr;
|
||||
char *ptr;
|
||||
|
||||
if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) {
|
||||
|
||||
|
@ -57,7 +57,7 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
|
||||
|
||||
FILE *f;
|
||||
u8 buf[MAX_LINE];
|
||||
u8 * lptr;
|
||||
u8 *lptr;
|
||||
u32 cur_line = 0;
|
||||
|
||||
u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
|
||||
@ -291,10 +291,10 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len,
|
||||
|
||||
void load_extras(afl_state_t *afl, u8 *dir) {
|
||||
|
||||
DIR * d;
|
||||
DIR *d;
|
||||
struct dirent *de;
|
||||
u32 min_len = MAX_DICT_FILE, max_len = 0, dict_level = 0;
|
||||
u8 * x;
|
||||
u8 *x;
|
||||
|
||||
u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
|
||||
|
||||
@ -330,7 +330,7 @@ void load_extras(afl_state_t *afl, u8 *dir) {
|
||||
while ((de = readdir(d))) {
|
||||
|
||||
struct stat st;
|
||||
u8 * fn = alloc_printf("%s/%s", dir, de->d_name);
|
||||
u8 *fn = alloc_printf("%s/%s", dir, de->d_name);
|
||||
s32 fd;
|
||||
|
||||
if (lstat(fn, &st) || access(fn, R_OK)) {
|
||||
|
@ -146,6 +146,10 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
OKF("CPU binding request using -b %d successful.", afl->cpu_to_bind);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
@ -185,7 +189,7 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
DIR * d;
|
||||
DIR *d;
|
||||
struct dirent *de;
|
||||
d = opendir("/proc");
|
||||
|
||||
@ -336,8 +340,8 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
||||
#elif defined(__sun)
|
||||
|
||||
kstat_named_t *n;
|
||||
kstat_ctl_t * m;
|
||||
kstat_t * k;
|
||||
kstat_ctl_t *m;
|
||||
kstat_t *k;
|
||||
cpu_stat_t cs;
|
||||
u32 ncpus;
|
||||
|
||||
@ -653,7 +657,7 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
|
||||
struct dirent **nl;
|
||||
s32 nl_cnt, subdirs = 1;
|
||||
u32 i;
|
||||
u8 * fn1, *dir = directory;
|
||||
u8 *fn1, *dir = directory;
|
||||
u8 val_buf[2][STRINGIFY_VAL_SIZE_MAX];
|
||||
|
||||
/* Auto-detect non-in-place resumption attempts. */
|
||||
@ -853,7 +857,7 @@ void perform_dry_run(afl_state_t *afl) {
|
||||
|
||||
struct queue_entry *q;
|
||||
u32 cal_failures = 0, idx;
|
||||
u8 * use_mem;
|
||||
u8 *use_mem;
|
||||
|
||||
for (idx = 0; idx < afl->queued_items; idx++) {
|
||||
|
||||
@ -1457,7 +1461,7 @@ void find_timeout(afl_state_t *afl) {
|
||||
|
||||
static u8 delete_files(u8 *path, u8 *prefix) {
|
||||
|
||||
DIR * d;
|
||||
DIR *d;
|
||||
struct dirent *d_ent;
|
||||
|
||||
d = opendir(path);
|
||||
@ -1585,7 +1589,7 @@ dir_cleanup_failed:
|
||||
static void handle_existing_out_dir(afl_state_t *afl) {
|
||||
|
||||
FILE *f;
|
||||
u8 * fn = alloc_printf("%s/fuzzer_stats", afl->out_dir);
|
||||
u8 *fn = alloc_printf("%s/fuzzer_stats", afl->out_dir);
|
||||
|
||||
/* See if the output directory is locked. If yes, bail out. If not,
|
||||
create a lock that will persist for the lifetime of the process
|
||||
@ -1878,9 +1882,9 @@ dir_cleanup_failed:
|
||||
|
||||
int check_main_node_exists(afl_state_t *afl) {
|
||||
|
||||
DIR * sd;
|
||||
DIR *sd;
|
||||
struct dirent *sd_ent;
|
||||
u8 * fn;
|
||||
u8 *fn;
|
||||
|
||||
sd = opendir(afl->sync_dir);
|
||||
if (!sd) { return 0; }
|
||||
@ -2581,7 +2585,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
|
||||
|
||||
if (unlikely(!fname)) { FATAL("BUG: Binary name is NULL"); }
|
||||
|
||||
u8 * env_path = 0;
|
||||
u8 *env_path = 0;
|
||||
struct stat st;
|
||||
|
||||
s32 fd;
|
||||
|
@ -74,7 +74,7 @@ void setup_custom_mutators(afl_state_t *afl) {
|
||||
|
||||
/* Try mutator library first */
|
||||
struct custom_mutator *mutator;
|
||||
u8 * fn = afl->afl_env.afl_custom_mutator_library;
|
||||
u8 *fn = afl->afl_env.afl_custom_mutator_library;
|
||||
u32 prev_mutator_count = 0;
|
||||
|
||||
if (fn) {
|
||||
@ -176,7 +176,7 @@ void destroy_custom_mutators(afl_state_t *afl) {
|
||||
|
||||
struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
|
||||
|
||||
void * dh;
|
||||
void *dh;
|
||||
struct custom_mutator *mutator = ck_alloc(sizeof(struct custom_mutator));
|
||||
|
||||
mutator->name = fn;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user