Commit a4087e70 by 文周繁

Initial commit

parents
r
ni
fin
ni
q
r
ni
fin
ni
ni
q
r
ni
fin
ni
q
r
ni
c
ni
q
b main
b _start
r
q
b *0x5555555551c0
r
q
b *0x555763f3d1f9
r
ni
si
ni
si
ni
si
ni
q
b *0x555763f3d1f9
r
ni
q
r
ni
q
b *0x555763f3d1f9
r
vmmap
q
b *0x5555c556021f
r
q
catch syscall
r
c
vmmap
c
vmmap
c
vmmap
c
vmmap
c
b _start
c
b *0x5555c556021f
ni
c
c
c
info b
ni
info b
del 1
ni
info b
ni
fin
fin
ni
c
ni
si
ni
ni
si
ni
ni
ni
q
r
ni
q
r
b *0x5555b426da0b
c
b *0x5555b426da10
c
b *0x5555b426da15
c
b *0x5555b426da1c
c
b *0x5555b426da24
c
del 5
del 4
b *0x5555b426da32
c
b *0x5555b426da42
del 6
c
b *0x5555b426da60
c
ni
si
ni
si
ni
b *0x555555d57169
c
c
b *0x555555d57172
c
b *0x555555d57179
c
del 10
del 9
b *0x555555d57183
c
b *0x555555d5718c
c
b *0x555555d5719e
c
b *0x555555d571b6
c
ni
si
ni
ni
q
r
ni
fin
fin
ni
ni
ni
ni
q
r
b *0x5555c5553f43
c
info b
del 1
b *0x5555c5553f48
c
ni
ni
ni
ni
b *0x5555c5553fa2
c
b *0x5555c5553faa
c
b *0x5555c5553faf
c
ni
b *0x5555c5553fbb
c
b *0x5555c5553fc3
c
b *0x5555c5553fd7
c
ni
ni
fin
q
r
ni
ni
q
r
b *0x5555c5553f3e
c
b *0x5555c5553f47
c
b *0x5555c5553f4f
c
b *0x5555c5553f56
c
b *0x5555c5553f70
c
b *0x5555c5553f88
c
ni
b *0x5555c5553f9b
c
b *0x5555c5553f9c
c
b *0x5555c5553fa3
c
b *0x5555c5553fa5
c
b *0x5555c5553fad
c
b *0x5555c5553fae
c
b *0x5555c5553fb4
c
b *0x5555c5553fb6
c
b *0x5555c5553fbc
c
b *0x5555c5553fbd
c
b *0x5555c5553fd4
del 16
c
b *0x5555c5553ff2
c
q
q
b main
r
q
b main
r
q
b main
r
ni
ni
q
b main
r
q
b main
r
ni
ni
ni
ni
si
ni
si
ni
ni
fin
ni
si
q
b main
r
ni
ni
q
.idea/
.vscode/
7
\ No newline at end of file
File added
#include <iostream>
#include <list>
using namespace std;
int main(){
list
}
\ No newline at end of file
This diff is collapsed. Click to expand it.
#CC=clang
#CXX=clang++
CXXFLAGS = -std=c++11 -Wall -Wno-reorder -fPIC -pie -march=native \
-DVERSION=$(shell cat VERSION)
E9PATCH_OBJS=\
src/e9patch/e9CFR.o \
src/e9patch/e9alloc.o \
src/e9patch/e9elf.o \
src/e9patch/e9api.o \
src/e9patch/e9emit.o \
src/e9patch/e9json.o \
src/e9patch/e9mapping.o \
src/e9patch/e9misc.o \
src/e9patch/e9optimize.o \
src/e9patch/e9patch.o \
src/e9patch/e9pe.o \
src/e9patch/e9tactics.o \
src/e9patch/e9trampoline.o \
src/e9patch/e9x86_64.o
E9TOOL_OBJS=\
src/e9tool/e9action.o \
src/e9tool/e9cfg.o \
src/e9tool/e9codegen.o \
src/e9tool/e9csv.o \
src/e9tool/e9frontend.o \
src/e9tool/e9metadata.o \
src/e9tool/e9misc.o \
src/e9tool/e9parser.o \
src/e9tool/e9tool.o \
src/e9tool/e9types.o \
src/e9tool/e9x86_64.o
release: CXXFLAGS += -O2 -D NDEBUG
release: $(E9PATCH_OBJS)
$(CXX) $(CXXFLAGS) $(E9PATCH_OBJS) -o e9patch $(LDFLAGS)
debug: CXXFLAGS += -O0 -g
debug: $(E9PATCH_OBJS)
$(CXX) $(CXXFLAGS) $(E9PATCH_OBJS) -o e9patch
sanitize: CXXFLAGS += -O0 -g -fsanitize=address
sanitize: $(E9PATCH_OBJS)
$(CXX) $(CXXFLAGS) $(E9PATCH_OBJS) -o e9patch
tool: CXXFLAGS += -O0 -g -I src/e9tool/ -I zydis/include/ \
-I zydis/dependencies/zycore/include/ -Wno-unused-function
tool: $(E9TOOL_OBJS)
$(CXX) $(CXXFLAGS) $(E9TOOL_OBJS) -o e9tool libZydis.a \
-Wl,--dynamic-list=src/e9tool/e9tool.syms -ldl $(LDFLAGS)
tool.debug: CXXFLAGS += -O0 -g -I src/e9tool/ -I zydis/include/ \
-I zydis/dependencies/zycore/include/ -Wno-unused-function
tool.debug: $(E9TOOL_OBJS)
$(CXX) $(CXXFLAGS) $(E9TOOL_OBJS) -o e9tool libZydis.a \
-Wl,--dynamic-list=src/e9tool/e9tool.syms -ldl
tool.sanitize: CXXFLAGS += -O0 -g -I src/e9tool/ -I zydis/include/ \
-I zydis/dependencies/zycore/include/ -Wno-unused-function \
-fsanitize=address
tool.sanitize: $(E9TOOL_OBJS)
$(CXX) $(CXXFLAGS) $(E9TOOL_OBJS) -o e9tool libZydis.a \
-Wl,--dynamic-list=src/e9tool/e9tool.syms -ldl
tool.clean:
rm -rf $(E9TOOL_OBJS) e9tool
loader_elf:
$(CXX) -std=c++11 -Wall -fno-stack-protector -Wno-unused-function -fPIC \
-O0 -g -c src/e9patch/e9loader_elf.cpp
$(CXX) -pie -nostdlib -o e9loader_elf.bin e9loader_elf.o -T e9loader.ld
xxd -i e9loader_elf.bin > src/e9patch/e9loader_elf.c
loader_pe:
$(CXX) -std=c++11 -Wall -fno-stack-protector -fno-zero-initialized-in-bss \
-Wno-unused-function -fPIC -mabi=ms -fshort-wchar \
-Os -c src/e9patch/e9loader_pe.cpp
$(CXX) -pie -nostdlib -o e9loader_pe.bin e9loader_pe.o -T e9loader.ld
xxd -i e9loader_pe.bin > src/e9patch/e9loader_pe.c
src/e9patch/e9elf.o: loader_elf
src/e9patch/e9pe.o: loader_pe
clean:
rm -rf $(E9PATCH_OBJS) e9patch \
src/e9patch/e9loader.c e9loader.out e9loader.o e9loader.bin
CC=gcc
CFLAGS=-fPIC -O2 -I zydis/include/ -I zydis/dependencies/zycore/include/ \
-I zydis/src/
OBJS=zydis/src/Decoder.o \
zydis/src/DecoderData.o \
zydis/src/FormatterATT.o \
zydis/src/FormatterBase.o \
zydis/src/FormatterBuffer.o \
zydis/src/Formatter.o \
zydis/src/FormatterIntel.o \
zydis/src/MetaInfo.o \
zydis/src/Mnemonic.o \
zydis/src/Register.o \
zydis/src/SharedData.o \
zydis/src/String.o \
zydis/src/Utils.o \
zydis/src/Zydis.o \
zydis/dependencies/zycore/src/Allocator.o \
zydis/dependencies/zycore/src/ArgParse.o \
zydis/dependencies/zycore/src/Bitset.o \
zydis/dependencies/zycore/src/Format.o \
zydis/dependencies/zycore/src/List.o \
zydis/dependencies/zycore/src/String.o \
zydis/dependencies/zycore/src/Vector.o \
zydis/dependencies/zycore/src/Zycore.o
all: $(OBJS)
ar rcs libZydis.a $(OBJS)
# E9Patch - A Powerful Static Binary Rewriter
E9Patch is a powerful static binary rewriting tool for `x86_64` Linux ELF
binaries.
E9Patch is:
* *Scalable*: E9Patch can reliably rewrite large/complex binaries
including web browsers (>100MB in size).
* *Compatible*: The rewritten binary is a drop-in replacement of the
original, with no additional dependencies.
* *Fast*: E9Patch can rewrite most binaries in a few seconds.
* *Low Overheads*: Both performance and memory.
* *Programmable*: E9Patch is designed so that it can be easily integrated
into other projects.
See the [E9Tool User's Guide](https://github.com/GJDuck/e9patch/blob/master/doc/e9tool-user-guide.md) and the [E9Patch Programmer's Guide](https://github.com/GJDuck/e9patch/blob/master/doc/e9patch-programming-guide.md)
for more information.
## Download
Pre-built E9Patch binaries can be downloaded here:
* [https://github.com/GJDuck/e9patch/releases](https://github.com/GJDuck/e9patch/releases)
## Background
*Static binary rewriting* takes as input a binary file
(ELF executable or shared object, e.g. `a.out`) and outputs a new binary
file (e.g., `b.out`) with some patch/modification applied to it.
The patched `b.out` can then be used as a drop-in replacement of
the original `a.out`.
Typical binary rewriting applications include
instrumentation (the addition of new instructions)
or patching (replacing binary code with a new version).
Static binary rewriting is notoriously difficult.
One problem is that space for the new instructions must be allocated,
and this typically means that existing instructions will need to be moved
in order to make room.
However, some of these existing instructions may also be *jump targets*,
meaning that the all jump/call instructions in the original binary
will also need to be adjusted in the rewritten binary.
Unfortunately, things get complicated very quickly:
* The complete set of targets cannot be determined statically
(it is an undecidable problem in the general case of indirect
calls or jumps).
* Cross-binary calls/jumps are not uncommon, for example the `compare`
function pointer argument to libc's `qsort()`.
Since code pointers cannot be reliably distinguished from other data
in the general case,
this can mean that the entire shared library dependency tree also needs
to be rewritten.
Unless all jumps and calls are perfectly adjusted, the rewritten binary
will likely crash or otherwise misbehave.
This is why existing static binary rewriting tools tend to scale poorly.
### How E9Patch is Different
E9Patch is different to other tools in that it can statically
rewrite `x86_64` Linux ELF binaries
***without modifying the set of jump targets***.
To do so, E9Patch uses a set of novel low-level binary rewriting
techniques, such as *instruction punning, padding and eviction* that can
insert or replace binary code without the need to move existing
instructions.
Since existing instructions are not moved, the set of jump targets
remains unchanged, meaning that calls/jumps do not need to be corrected
(including cross binary calls/jumps).
E9Patch is therefore highly scalable by design, and can reliably rewrite very
large binaries such as Google Chrome and FireFox (>100MB in size).
To find out more on how E9Patch works, please see our PLDI'2020 paper:
* Gregory J. Duck, Xiang Gao, Abhik Roychoudhury, [Binary Rewriting without Control Flow Recovery](https://comp.nus.edu.sg/~gregory/papers/e9patch.pdf),
Programming Language Design and Implementation (PLDI), 2020.
[PLDI'2020 Presentation](https://www.youtube.com/watch?v=qK2ZCEStoG0)
### Additional Notes
The key to E9Patch's scalability is that it makes minimal assumptions
about the input binary.
However, E9Patch is not 100% assumption-free, and does assume:
* The binary can be *disassembled* and does not use *overlapping
instructions*.
The default E9Tool frontend uses the
[Zydis disassembler](https://github.com/zyantific/zydis).
* The binary does not read from, or write, to the patched executable
segments.
For example, *self-modifying code* is not supported.
Most off-the-self `x86_64` Linux binaries will satisfy these assumptions.
The instruction patching methodology that E9Patch uses is not
guaranteed to work for every instruction.
As such, the *coverage* of the patching may not be 100%.
E9Patch will print coverage information after the rewriting process,
e.g.:
num_patched = 2766 / 2766 (100.00%)
Most applications can expect at or near 100% coverage.
However, coverage can be diminished by several factors, including:
* Patching single-byte instructions such as `ret`s, `push`es and `pop`s.
These are difficult to patch, affecting coverage.
* Patching too many instructions.
* Binaries with large static code or data segments that limit the space
available for trampolines.
A patched binary with less than 100% coverage will still run
correctly, albeit with some instructions remaining unpatched.
Whether or not this is an issue depends largely on the application.
## Building
Building E9Patch is very easy: simply run the `build.sh` script.
This should automatically build two tools:
1. `e9patch`: the binary rewriter backend; and
2. `e9tool`: a basic linear disassembly frontend for E9Patch.
*Note*: E9Tool and E9Patch are considered to be different tools.
Limitations of E9Tool do not necessarily extend to E9Patch itself.
Other frontends for E9Patch (e.g., based on more advanced disassembly
techniques) can be built, although this is currently future work.
## Examples
E9Patch is usable via the E9Tool frontend.
For example, to add instruction printing instrumentation to all `xor`
instructions in `xterm`, we can use the following command:
$ ./e9tool -M 'asm=/xor.*/' -P print xterm
This will write out a modified `xterm` into the file `a.out`.
The modified `xterm` can be run as per normal, but will print the assembly
string of each executed `xor` instruction to `stderr`:
$ ./a.out
xorl %ebp, %ebp
xorl %ebx, %ebx
xorl %eax, %eax
xorl %edx, %edx
xorl %edi, %edi
...
For a full list of supported options and modes, see:
$ ./e9tool --help
### More Examples
Patch all jump instructions with "empty" instrumentation:
$ ./e9tool -M 'asm=/j.*/' -P empty xterm
$ ./a.out
Print all jump instructions with "print" instrumentation:
$ ./e9tool -M 'asm=/j.*/' -P print xterm
$ ./a.out
Same as above, but use "Intel" syntax:
$ ./e9tool -M 'asm=/j.*/' -P print xterm --syntax=intel
$ ./a.out
Patch all jump instructions with a call to an empty function:
$ ./e9compile.sh examples/nop.c
$ ./e9tool -M 'asm=/j.*/' -P 'entry()@nop' xterm
$ ./a.out
Patch all jump instructions with instruction count instrumentation:
$ ./e9compile.sh examples/counter.c
$ ./e9tool -M 'asm=/j.*/' -P 'entry()@counter' xterm
$ FREQ=10000 ./a.out
Patch all jump instructions with pretty print instrumentation:
$ ./e9compile.sh examples/print.c
$ ./e9tool -M 'asm=/j.*/' -P 'entry(addr,instr,size,asm)@print' xterm
$ ./a.out
Patch all jump instructions with "delay" instrumentation to slow the
program down:
$ ./e9compile.sh examples/delay.c
$ ./e9tool -M 'asm=/j.*/' -P 'entry()@delay' xterm
$ DELAY=100000 ./a.out
*Notes*:
* Tested for `XTerm(322)`
## Projects
Some other projects that use E9Patch include:
* [RedFat](https://github.com/GJDuck/RedFat): A binary hardening system based
on [low-fat pointers](https://github.com/GJDuck/LowFat).
* [E9AFL](https://github.com/GJDuck/e9afl): Automatically insert
[AFL](https://github.com/google/AFL) instrumentation into binaries.
* [E9Syscall](https://github.com/GJDuck/e9syscall): System call
interception using static binary rewriting of `libc.so`.
## Documentation
If you just want to test E9Patch out, then please try the above examples.
E9Patch is a low-level tool that is designed to be integrable into other
projects.
To find out more, please see the following documentation:
* [E9Patch Programmer's Guide](https://github.com/GJDuck/e9patch/blob/master/doc/e9patch-programming-guide.md)
* [E9Tool User's Guide](https://github.com/GJDuck/e9patch/blob/master/doc/e9tool-user-guide.md)
## Bugs
E9Patch should be considered beta-quality software.
Bugs can be reported here:
* [https://github.com/GJDuck/e9patch/issues](https://github.com/GJDuck/e9patch/issues)
## Versions
The current version of E9Patch is significantly improved compared to
the original prototype evaluated in the PLDI'2020 paper.
Specifically:
* The current version implements several new optimizations and can generate
significantly faster binaries, sometimes by a factor of 2x.
To enable the new optimizations, pass the `-O2` option to E9Tool.
* The implementation of the *Physical Page Grouping* space optimization
has also been improved.
* The patching coverage has also been slightly improved.
* Many new features have been implemented (see the documentation).
## License
This software has been released under the GNU Public License (GPL) Version 3.
Some specific files are released under the MIT license (check the file
preamble).
## Acknowledgements
This work was partially supported by the National Satellite of Excellence in
Trustworthy Software Systems, funded by National Research Foundation (NRF)
Singapore under the National Cybersecurity R&D (NCR) programme.
1.0.0-rc8
0x4260:ParseConfig@RET:0x43a8@-327:254
0x5a80:create_datasocket@RET:0x5b17@-56:24
0x5d00:writelogentry@RET:0x5e0f@-64:16
0x66d0:retr_thread@RET:0x6965@-168:104
0x7810:stor_thread@RET:0x7a31@-168:104
0x7810:stor_thread@RET:0x7a31@-208:16
0x7f30:append_thread@RET:0x80a8@-136:104
0x7f30:append_thread@RET:0x80a8@-160:16
0x8db0:pasv.part.0@RET:0x8f5a@-80:16
0x9540:ftp_client_thread@RET:0x9672@-64:16
0x9540:ftp_client_thread@RET:0x9672@-8408:16
0x9d60:list_sub@RET:0x9e8f@-64:16
0x9d60:list_sub@RET:0x9e8f@-144:68
0x9ff0:list_thread@RET:0xa15b@-152:104
0x9ff0:list_thread@RET:0xa15b@-176:16
0xa340:mlsd_sub@RET:0xa543@-64:16
0xa570:msld_thread@RET:0xa6db@-152:104
0xa570:msld_thread@RET:0xa6db@-176:16
0xa820:ftpmain@RET:0xa94f@-72:8328
File added
This source diff could not be displayed because it is too large. You can view the blob instead.
b main
r
ni
n
ni
si
ni
si
ni
q
Containers @ 5f222507
Subproject commit 5f222507b077b8e223cc56d0c57a6ef4ea29b5f5
#
# american fuzzy lop - LLVM instrumentation
# -----------------------------------------
#
# Written by Laszlo Szekeres <lszekeres@google.com> and
# Michal Zalewski <lcamtuf@google.com>
#
# LLVM integration design comes from Laszlo Szekeres.
#
# Copyright 2015, 2016 Google LLC All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
PREFIX ?= /usr/local
HELPER_PATH = $(PREFIX)/lib/afl
BIN_PATH = $(PREFIX)/bin
VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2)
LLVM_CONFIG ?= llvm-config
CFLAGS ?= -O0 -funroll-loops
CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-DVERSION=\"$(VERSION)\"
ifdef AFL_TRACE_PC
CFLAGS += -DUSE_TRACE_PC=1
endif
CXXFLAGS ?= -O0 -funroll-loops
CXXFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \
-DVERSION=\"$(VERSION)\" -Wno-variadic-macros
# Mark nodelete to work around unload bug in upstream LLVM 5.0+
CLANG_CFL = `$(LLVM_CONFIG) --cxxflags` -Wl,-znodelete -fno-rtti -fpic $(CXXFLAGS)
CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
# User teor2345 reports that this is required to make things work on MacOS X.
ifeq "$(shell uname)" "Darwin"
CLANG_LFL += -Wl,-flat_namespace -Wl,-undefined,suppress
endif
# We were using llvm-config --bindir to get the location of clang, but
# this seems to be busted on some distros, so using the one in $PATH is
# probably better.
ifeq "$(origin CC)" "default"
CC = clang
CXX = clang++
endif
ifndef AFL_TRACE_PC
PROGS = ../afl-clang-fast ../afl-llvm-pass.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../afl-llvm-rt-state-tracer.o ../afl-llvm-rt-state-tracer.o.cpp.o
else
PROGS = ../afl-clang-fast ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../afl-llvm-rt-state-tracer.o ../afl-llvm-rt-state-tracer.o.cpp.o
endif
CONTAINERS = ./containers.a
TLSH = ./libtlsh.a
MVPTREE = ./libmvptree.a
STDCXX = $(shell find /usr/lib -name "libstdc++.a" | grep x86_64 | grep -v 32 | head -n 1)
all: test_deps $(PROGS) test_build all_done obj_section_rename
test_deps:
ifndef AFL_TRACE_PC
@echo "[*] Checking for working 'llvm-config'..."
@which $(LLVM_CONFIG) >/dev/null 2>&1 || ( echo "[-] Oops, can't find 'llvm-config'. Install clang or set \$$LLVM_CONFIG or \$$PATH beforehand."; echo " (Sometimes, the binary will be named llvm-config-3.5 or something like that.)"; exit 1 )
else
@echo "[!] Note: using -fsanitize=trace-pc mode (this will fail with older LLVM)."
endif
@echo "[*] Checking for working '$(CC)'..."
@which $(CC) >/dev/null 2>&1 || ( echo "[-] Oops, can't find '$(CC)'. Make sure that it's in your \$$PATH (or set \$$CC and \$$CXX)."; exit 1 )
@echo "[*] Checking for '../afl-showmap'..."
@test -f ../afl-showmap || ( echo "[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first."; exit 1 )
@echo "[+] All set and ready to build."
../afl-clang-fast: afl-clang-fast.c | test_deps
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
ln -sf afl-clang-fast ../afl-clang-fast++
../afl-llvm-pass.so: afl-llvm-pass.so.cc | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
$(CONTAINERS):
cd Containers && \
make static_clang && \
cp containers.a ..
$(MVPTREE):
cd mvptree && \
make && \
cp libmvptree.a ..
$(TLSH):
cd tlsh && \
mkdir -p build && \
cd build && \
cmake .. && \
make && \
cp ../lib/libtlsh.a ../..
../afl-llvm-rt-state-tracer.o: afl-llvm-rt-state-tracer.o.c $(CONTAINERS) $(TLSH) $(MVPTREE)
$(CC) $(CFLAGS) -fPIC -c $< -o $@.tmp.o
ld -r -o $@ $@.tmp.o $(CONTAINERS)
mv $@ $@.tmp.o
ld -r -o $@ $@.tmp.o $(TLSH)
mv $@ $@.tmp.o
ld -r -o $@ $@.tmp.o $(MVPTREE)
cp $@ $@.cpp.o
mv $@ $@.tmp.o
ld -r -o $@ $@.tmp.o $(STDCXX)
rm $@.tmp.o
../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps
$(CC) $(CFLAGS) -fPIC -c $< -o $@
../afl-llvm-rt-32.o: afl-llvm-rt.o.c | test_deps
@printf "[*] Building 32-bit variant of the runtime (-m32)... "
@$(CC) $(CFLAGS) -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
../afl-llvm-rt-64.o: afl-llvm-rt.o.c | test_deps
@printf "[*] Building 64-bit variant of the runtime (-m64)... "
@$(CC) $(CFLAGS) -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi
obj_section_rename:
for OBJ_FILE in ../afl-llvm-rt*.o ; do \
objcopy --rename-section .data=.tracer_data $${OBJ_FILE}; \
objcopy --rename-section .bss=.tracer_bss $${OBJ_FILE}; \
done
test_build: $(PROGS)
@echo "[*] Testing the CC wrapper and instrumentation output..."
unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; AFL_QUIET=1 AFL_PATH=. AFL_CC=$(CC) ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS)
# Use /dev/null to avoid problems with optimization messing up expected
# branches. See https://github.com/google/AFL/issues/30.
../afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null
echo 1 | ../afl-showmap -m none -q -o .test-instr1 ./test-instr
@rm -f test-instr
@cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please ping <lcamtuf@google.com> to troubleshoot the issue."; echo; exit 1; fi
@echo "[+] All right, the instrumentation seems to be working!"
all_done: test_build
@echo "[+] All done! You can now use '../afl-clang-fast' to compile programs."
.NOTPARALLEL: clean
clean:
rm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1
rm -f $(PROGS) ../afl-clang-fast++
clang -O0 -funroll-loops -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -DAFL_PATH=\"/usr/local/lib/afl\" -DBIN_PATH=\"/usr/local/bin\" -DVERSION=\"2.56b\" -fPIC -c afl-llvm-rt-state-tracer.o.c -o ./afl-llvm-rt-state-tracer.o.tmp.o
ld -r -o ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o ./libcontainers.a
mv ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o
ld -r -o ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o ./libtlsh.a
mv ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o
ld -r -o ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o ./libmvptree.a
mv ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o
ld -r -o ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o /usr/lib/gcc/x86_64-linux-gnu/9/libstdc++.a
rm ./afl-llvm-rt-state-tracer.o.tmp.o
gcc -shared afl-llvm-rt-state-tracer.o -o state-tracer2.so
#include <stdio.h>
#include <string.h>
void print()
{
printf("I am print\n");
}
int add(int a, int b)
{
printf("Sum %d and %d is %d\n", a, b, a + b);
return 0;
}
//static void king() __attribute__((constructor(101))); the following is also right
static __attribute__((constructor(101))) void king()
{
printf("I am king\n");
}
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <stdlib.h>
#define LibPath "/home/echo/afl-llvm-state-tracer/state-tracer-log.so"
int main(int argc, char **argv)
{
// void (*print)();
// int (*add)(int, int);
void *handle;
// void (*init_state_tracer)();
void (*new_heap_alloc_record)(void*,size_t);
void (*free_heap_alloc_record)(void*);
// void (*end_state_tracer)();
// if (argc < 2)
// return -1;
printf("start\n");
handle = dlopen(LibPath, RTLD_LAZY);
if (!handle) {
printf("dlopen failed: %s\n", dlerror());
return -1;
}
// init_state_tracer = dlsym(handle, "init_state_tracer");
// if (!init_state_tracer) {
// printf("dlsym failed: %s\n", dlerror());
// return -1;
// }
new_heap_alloc_record= dlsym(handle, "new_heap_alloc_record");
if (!new_heap_alloc_record) {
printf("dlsym failed: %s\n", dlerror());
return -1;
}
free_heap_alloc_record= dlsym(handle, "free_heap_alloc_record");
if (!free_heap_alloc_record) {
printf("dlsym failed: %s\n", dlerror());
return -1;
}
// end_state_tracer = dlsym(handle, "end_state_tracer");
// if (!end_state_tracer) {
// printf("dlsym failed: %s\n", dlerror());
// return -1;
// }
// init_state_tracer();
// record 1
size_t addrsize=0x128;
void* addr1=malloc(addrsize);
new_heap_alloc_record(addr1,addrsize);
// record 2
addrsize=0x100;
void* addr2=malloc(addrsize);
new_heap_alloc_record(addr2,addrsize);
// free 1
free_heap_alloc_record(addr1);
free(addr1);
addr1=NULL;
// free2
// free_heap_alloc_record(addr2);
// free(addr2);
// addr2=NULL;
// end_state_tracer();
addrsize=0x200;
void* addr3=malloc(addrsize);
new_heap_alloc_record(addr3,addrsize);
dlclose(handle);
return 0;
}
\ No newline at end of file
clang -O0 -funroll-loops -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -DAFL_PATH=\"/usr/local/lib/afl\" -DBIN_PATH=\"/usr/local/bin\" -DVERSION=\"2.56b\" -fPIC -c afl-llvm-rt-state-tracer.o.c -o ./afl-llvm-rt-state-tracer.o.tmp.o
ld -r -o ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o ./libcontainers.a
mv ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o
ld -r -o ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o ./libtlsh.a
mv ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o
ld -r -o ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o ./libmvptree.a
cp ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.cpp.o
mv ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o
ld -r -o ./afl-llvm-rt-state-tracer.o ./afl-llvm-rt-state-tracer.o.tmp.o /usr/lib/gcc/x86_64-linux-gnu/9/libstdc++.a
rm ./afl-llvm-rt-state-tracer.o.tmp.o
\ No newline at end of file
mvptree @ bc229f6e
Subproject commit bc229f6ebd73413a892d0c0d96fa6b360505e7ec
[start]---------------------------------------------------------------------------------------------------
STATE TRACER STARTED
NO SHM (for testing)
[start]---------------------------------------------------------------------------------------------------
NEW HEAP ALLOC: 0x55555556e550 (296 bytes)
NEW ALLOC [0]: 0x55555556e550, 296
NEW HEAP ALLOC: 0x55555556e700 (256 bytes)
NEW ALLOC [1]: 0x55555556e700, 256
FREE HEAP ALLOC: 0x55555556e550 (93824992339984 bytes)
FREE ALLOC [0]: 0x55555556e550
NEW HEAP ALLOC: 0x55555556e890 (512 bytes)
NEW ALLOC [2]: 0x55555556e890, 512
[end]---------------------------------------------------------------------------------------------------
# DUMPS: 0
Latest iteration: 0
No dumps found, skipping analysis...
#ifndef _H_STATE_TRACER_
#define _H_STATE_TRACER_
#define SHM_STATE_ENV_VAR "STATE_SHM_ID"
#define MVP_RADIUS_ENV_VAR "MVP_RADIUS"
#define MVP_CALIBRATION_ENV_VAR "MVP_CALIBRATION_SHM_ID"
#define AFL_OUTDIR_ENV_VAR "AFL_OUTDIR"
#define MIN_STACK_ALLOC_SIZE 64
#define TLSH_SIZE 72
#define MAX_NUM_STATES 100
#define MAX_REPETITIONS 1000
#define RATE_LIMIT 5
struct state_shared {
unsigned int seq_len;
unsigned int seq[MAX_NUM_STATES];
unsigned int iterations;
};
enum { TRACER_IDLE, TRACER_ANALYZING, TRACER_DONE };
struct calibration {
/* Set to 1 to turn on calibration */
int enabled;
/* Sequence of hashes from the first calibration execution */
int initialized;
int ref_len;
char ref_state_seq[MAX_NUM_STATES][TLSH_SIZE+1];
/* TLSH distances between the first execution and the subsequent ones */
int dist_len;
int dist[MAX_NUM_STATES*MAX_REPETITIONS];
/* TLSH distance for MVP radius */
int mvp_radius;
/* Rate limiting to prevent state explosion */
int rate_limit;
};
#endif
#include "stdio.h"
#include "string.h"
#define LOG_FILE "/home/echo/e9patch/src/e9tool/symfunc.log"
#define asm_instr "call 0x1130"
char FuncSym[20][256];
char FuncOff[20][256];
unsigned size=0;
char *Global_FuncSym[]={
"malloc","calloc","realloc","free",
"recv","recvmsg","recvfrom",
"send","sendto","sendmsg","read","write",
"fprintf","fgets","fwrite",
"fread","_exit","close","fclose"
};
char* my_strtok(char* str, char* delimiters)
{
//str传NULL的时候如果上次有记录,则用上一次的下一个位置,不然就为NULL
static char* p_last = NULL;
if (str == NULL && p_last == NULL)
return NULL;
if (str == NULL)
{
//用来返回的当前位置
str = p_last;
char* tmp = p_last;
int len = strlen(delimiters);
while (*tmp)
{
for (int i = 0; i < len; ++i)
{
if (*tmp == delimiters[i])
{
p_last = tmp+1;
*tmp = '\0';
return str;
}
}
//走到这里表示当前的tmp没有在delimiters中能找到的
tmp++;
}
//走到这里就是自己走到斜杠\0的位置,就要将p_last 设置成为NULL
char* ret = p_last;
p_last = NULL;
return ret;
}
else
{
char* tmp = str;
int len = strlen(delimiters);
while (*tmp)
{
for (int i = 0; i < len; ++i)
{
if (*tmp == delimiters[i])
{
p_last = tmp+1;
*tmp = '\0';
return str;
}
}
//走到这里表示当前的tmp没有在delimiters中能找到的
tmp++;
}
//找到了,找不到
char* ret = p_last;
p_last = NULL;
return ret;
}
}
int main(int argc,char** argv)
{
char asm_malloc[100];
strcpy(asm_malloc,asm_instr);
FILE *fp;
char load_file[256];
char line[1000];
fp=fopen(LOG_FILE,"r");
if(fp==NULL)
{
printf("can not load file!");
return 1;
}
int line_id=0;
while(!feof(fp))
{
memset(&line,0,sizeof(line));
fgets(line,1000,fp);
int len=0;
if(line)
{
printf("[%d] %s",line_id,line);
char* temp=my_strtok(line,":");
if(temp)
{
strcpy(FuncOff[line_id],temp);
printf("func:%s\n",FuncOff[line_id]);
strcpy(FuncSym[line_id],my_strtok(NULL,":"));
printf("offs:%s",FuncSym[line_id]);
len=strlen(FuncSym[line_id]);
FuncSym[line_id][len-1]='\0'; // '\n' --> '\0'
line_id++;
}
}
}
fclose(fp);
// match target function
char *temp1 = my_strtok(asm_malloc," ");
printf("info1 of asm_malloc:%s\n",temp1);
char *temp2 = my_strtok(NULL," ");
printf("info2 of asm_malloc:%s\n",temp2);
int res=strcmp(FuncOff[0],temp2);
printf("debug..%d\n",res);
// size=sizeof(FuncOff)/sizeof(FuncOff[0]);
// printf("size=%d\n",size);
int size=sizeof(Global_FuncSym)/sizeof(Global_FuncSym[0]);
for(int i=0;i<line_id;i++)
{
if(strcmp(FuncOff[i],temp2)==0)
{
printf("offset: [%s] matching function: %s\n",temp2,FuncSym[i]);
for(int j=0;j<size;j++)
{
if(strcmp(FuncSym[i],Global_FuncSym[j])==0){
printf("match Global_Funsym[%d]\n",j);
}
}
break;
}
}
//printf("instr [%s] don't match any function\n",asm_instr);
return 0;
}
\ No newline at end of file
0
[*]------------------------------------------------------------------------------------
[*] STATE TRACER STARTED
[*] NO SHM (for testing)
[*] STATE TRACER END
[*]------------------------------------------------------------------------------------
[*] NEW HEAP ALLOC: 0x55555556e140 (296 bytes)
[*] NEW ALLOC [0]: 0x55555556e140, 296
Obtained 6 stack frames.
[*]------------------------------------------------------------------------------------
/home/echo/afl-llvm-state-tracer/state-tracer2.so(+0xa794) [0x7ffff7d86794]
/home/echo/afl-llvm-state-tracer/state-tracer2.so(new_alloc_record+0xd0) [0x7ffff7d86720]
/home/echo/afl-llvm-state-tracer/state-tracer2.so(new_heap_alloc_record+0x8c) [0x7ffff7d86a6c]
./loader(+0x1309) [0x555555555309]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0x7ffff7de0083]
./loader(+0x114e) [0x55555555514e]
[*]------------------------------------------------------------------------------------
[*] NEW HEAP ALLOC: 0x55555556e570 (256 bytes)
[*] NEW ALLOC [1]: 0x55555556e570, 256
Obtained 6 stack frames.
[*]------------------------------------------------------------------------------------
/home/echo/afl-llvm-state-tracer/state-tracer2.so(+0xa794) [0x7ffff7d86794]
/home/echo/afl-llvm-state-tracer/state-tracer2.so(new_alloc_record+0xd0) [0x7ffff7d86720]
/home/echo/afl-llvm-state-tracer/state-tracer2.so(new_heap_alloc_record+0x8c) [0x7ffff7d86a6c]
./loader(+0x1335) [0x555555555335]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0x7ffff7de0083]
./loader(+0x114e) [0x55555555514e]
[*]------------------------------------------------------------------------------------
[*] FREE HEAP ALLOC: 0x55555556e140
[*] FREE ALLOC [0]: 0x55555556e140
[*]------------------------------------------------------------------------------------
[*] NEW HEAP ALLOC: 0x55555556e700 (512 bytes)
[*] NEW ALLOC [2]: 0x55555556e700, 512
Obtained 6 stack frames.
[*]------------------------------------------------------------------------------------
/home/echo/afl-llvm-state-tracer/state-tracer2.so(+0xa794) [0x7ffff7d86794]
/home/echo/afl-llvm-state-tracer/state-tracer2.so(new_alloc_record+0xd0) [0x7ffff7d86720]
/home/echo/afl-llvm-state-tracer/state-tracer2.so(new_heap_alloc_record+0x8c) [0x7ffff7d86a6c]
./loader(+0x1382) [0x555555555382]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0x7ffff7de0083]
./loader(+0x114e) [0x55555555514e]
[*]------------------------------------------------------------------------------------
[*] End TRACER STARTED
# DUMPS: 0
Latest iteration: 0
No dumps found, skipping analysis...
[*] End TRACER ENDED
//
// Created by echo on 11/29/23.
//
tlsh @ fb38843a
Subproject commit fb38843a474ea2bd3a94400a3d61a37b403ca0b0
// Compile with:
// gcc tlsh-test.c -lmvptree -ltlsh -lstdc++ -L. -o tlsh-test
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include "tlsh-wrapper.h"
#include "mvptree.h"
#define MVP_BRANCHFACTOR 2
#define MVP_PATHLENGTH 5
#define MVP_LEAFCAP 25
// Fast tanimoto code with 8 bit LUT
// by Ernst-Georg Schmid
// https://github.com/ergo70/tanimoto
static const uint8_t popcount_counts_byte[] =
{
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
};
float tanimoto_distance(MVPDP *pointA, MVPDP *pointB){
if (!pointA || !pointB || pointA->datalen != pointB->datalen) return -1.0f;
uint8_t * data1 = pointA->data;
uint8_t * data2 = pointB->data;
unsigned int and_count=0, or_count=0;
int size = pointA->datalen;
uint8_t tmp;
float result;
while (size--)
{
tmp = (*data2 | *data1);
or_count += popcount_counts_byte[tmp];
tmp = (*data2 & *data1);
and_count += popcount_counts_byte[tmp];
data2++;
data1++;
}
result = (float) 1.0f - and_count / (or_count * 1.0f);
/*
printf("\nComparing: %s\n", (char*) pointA->data);
printf("To : %s\n", (char*) pointB->data);
printf("Distance : %f\n", result);
*/
return result;
}
int main () {
int showvers = 0;
const char * mvp_file = "tree.mvp";
MVPError err;
MVPTree* tree;
CmpFunc distance_func = tanimoto_distance;
printf("Reading MVP Tree from file (%s)...\n", mvp_file);
tree = mvptree_read(mvp_file, distance_func, MVP_BRANCHFACTOR, MVP_PATHLENGTH, MVP_LEAFCAP, &err);
if(err != MVP_SUCCESS || tree == NULL) {
printf("Unable to read MVP Tree from file, initializing new one...\n");
Tlsh* t[10];
for(int i=0; i<10; i++) {
t[i] = Tlsh_new();
}
const char *str[10];
str[0] = "This is a test for Lili Diao. This is a string. Hello Hello Hello ";
str[1] = "This is a test for Jon Oliver. This is a string. Hello Hello Hello ";
str[2] = "This is a test for Lili Ciao. This is a string. Hello Hello Hello ";
str[3] = "This is a test for Lili Diao.";
str[4] = "This is a string. Hello Hello Hello ";
str[5] = "Hello Hello Hello ";
str[6] = " ";
str[7] = "a test is a string.";
str[8] = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
str[9] = "a test for Lili Dao. Hello Hello";
for(int i=0; i<10; i++) {
char minSizeBuffer[512];
for (int i = 0; i < 511; i++) {
minSizeBuffer[i] = i % 26 + 'A';
}
minSizeBuffer[511] = 0;
strncpy(minSizeBuffer, str[i], strlen(str[i]));
Tlsh_final(t[i], (const unsigned char*) minSizeBuffer, 512, 0);
printf("String %d: %s\n", i, str[i]);
}
tree = mvptree_alloc(NULL, distance_func, MVP_BRANCHFACTOR, MVP_PATHLENGTH, MVP_LEAFCAP);
for(int i=0; i<10; i++) {
MVPDP *newpnt = dp_alloc(BYTEARRAY);
newpnt->data = strdup(Tlsh_get_hash(t[i], showvers));
newpnt->datalen = strlen(newpnt->data);
printf("Adding new point %d: %s (size = %d)\n", i, (char*)newpnt->data, newpnt->datalen);
char scratch[32];
snprintf(scratch, 32, "point%d", i);
newpnt->id = strdup(scratch);
err = mvptree_add(tree, &newpnt, 1);
if(err != MVP_SUCCESS) {
printf("MVPError: %d\n", err);
exit(1);
}
}
for(int i=0; i<10; i++) {
Tlsh_delete(t[i]);
}
printf("Writing MVP Tree to file (%s)...\n", mvp_file);
err = mvptree_write(tree, mvp_file, 00755);
}
printf("Querying MVP Tree\n");
const char * query = "";
//const char * query = "This is a test for Lili Diao. This is a string. Hello Hello Hello ";
//const char * query = "This is a test for Lili Biao. This is a string. Hello Hello Hello ";
//const char * query = "This is a string. Hello Hello Hello ";
Tlsh * t_query = Tlsh_new();
char minSizeBuffer[512];
for (int i = 0; i < 511; i++) {
minSizeBuffer[i] = i % 26 + 'A';
}
minSizeBuffer[511] = 0;
strncpy(minSizeBuffer, query, strlen(query));
Tlsh_final(t_query, (const unsigned char*) minSizeBuffer, 512, 0);
MVPDP *query_node = dp_alloc(BYTEARRAY);
query_node->data = strdup(Tlsh_get_hash(t_query, showvers));
query_node->datalen = strlen(query_node->data);
query_node->id = strdup("Query node");
printf("Query string: %s\n", query);
printf("Query point: %s (size = %d)\n", (char*)query_node->data, query_node->datalen);
unsigned int knearest = 1;
unsigned int nbresults = 0;
float radius = 0.1;
MVPDP **results = mvptree_retrieve(tree, query_node, knearest, radius, &nbresults, &err);
/*if(err != MVP_SUCCESS) {
printf("MVPError: %d\n", err);
exit(1);
}*/
printf("Retrieval results: %d\n", nbresults);
for(int i=0; i < nbresults; i++) {
printf("NODE FOUND: %s (id=%s, distance=%f)\n", (char *)results[i]->data, results[i]->id, tanimoto_distance(results[i], query_node) );
}
free(results);
dp_free(query_node, free);
mvptree_clear(tree, free);
free(tree);
Tlsh_delete(t_query);
}
#ifndef WRAPPER_H_
#define WRAPPER_H_
/* From:
* https://stackoverflow.com/questions/31903005/how-to-mix-c-and-c-correctly
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Tlsh Tlsh;
Tlsh* Tlsh_new();
const char* Tlsh_get_hash_buffer(Tlsh* tlsh, char *buffer, unsigned int bufSize, int showvers);
const char* Tlsh_get_hash(Tlsh* tlsh, int showvers);
void Tlsh_update(Tlsh* tlsh, const unsigned char* data, unsigned int len);
void Tlsh_final(Tlsh* tlsh, const unsigned char* data, unsigned int len, int fc_cons_option);
int Tlsh_from_str(Tlsh* tlsh, const char* str);
int Tlsh_total_diff(Tlsh* tlsh, const Tlsh *other, int len_diff);
void Tlsh_reset(Tlsh* tlsh);
void Tlsh_delete(Tlsh* tlsh);
#ifdef __cplusplus
}
#endif
#endif /* WRAPPER_H_ */
/*
Copyright 2013 Google LLC All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
american fuzzy lop - type definitions and minor macros
------------------------------------------------------
Written and maintained by Michal Zalewski <lcamtuf@google.com>
*/
#ifndef _HAVE_TYPES_H
#define _HAVE_TYPES_H
#include <stdint.h>
#include <stdlib.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
/*
Ugh. There is an unintended compiler / glibc #include glitch caused by
combining the u64 type an %llu in format strings, necessitating a workaround.
In essence, the compiler is always looking for 'unsigned long long' for %llu.
On 32-bit systems, the u64 type (aliased to uint64_t) is expanded to
'unsigned long long' in <bits/types.h>, so everything checks out.
But on 64-bit systems, it is #ifdef'ed in the same file as 'unsigned long'.
Now, it only happens in circumstances where the type happens to have the
expected bit width, *but* the compiler does not know that... and complains
about 'unsigned long' being unsafe to pass to %llu.
*/
#ifdef __x86_64__
typedef unsigned long long u64;
#else
typedef uint64_t u64;
#endif /* ^__x86_64__ */
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
#ifndef MIN
# define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a))
# define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b))
#endif /* !MIN */
#define SWAP16(_x) ({ \
u16 _ret = (_x); \
(u16)((_ret << 8) | (_ret >> 8)); \
})
#define SWAP32(_x) ({ \
u32 _ret = (_x); \
(u32)((_ret << 24) | (_ret >> 24) | \
((_ret << 8) & 0x00FF0000) | \
((_ret >> 8) & 0x0000FF00)); \
})
#ifdef AFL_LLVM_PASS
# define AFL_R(x) (random() % (x))
#else
# define R(x) (random() % (x))
#endif /* ^AFL_LLVM_PASS */
#define STRINGIFY_INTERNAL(x) #x
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
#define MEM_BARRIER() \
__asm__ volatile("" ::: "memory")
#define likely(_x) __builtin_expect(!!(_x), 1)
#define unlikely(_x) __builtin_expect(!!(_x), 0)
#endif /* ! _HAVE_TYPES_H */
File added
File added
File added
/*
* ___ _ _____ _
* ___ / _ \ / \ | ___| |
* / _ \ (_) |/ _ \ | |_ | |
* | __/\__, / ___ \| _| | |___
* \___| /_/_/ \_\_| |_____|
*
* american fuzzy lop - LLVM instrumentation bootstrap
* ---------------------------------------------------
*
* Written by Laszlo Szekeres <lszekeres@google.com> and
* Michal Zalewski <lcamtuf@google.com>
*
* LLVM integration design comes from Laszlo Szekeres.
*
* Copyright 2015, 2016 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* This code is the rewrite of afl-as.h's main_payload.
*
* E9Patch adaption:
* Xiang Gao
* Gregory J. Duck
*/
#include "stdlib.c"
#include "e9loader.h"
#define FORKSRV_FD 198
#define AREA_BASE ((uint8_t *)0x2A0000)
#define AREA_SIZE ((size_t)1 << 16)
static FILE *log = NULL;
static void print_message(bool fatal, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
if (log == NULL)
{
log = fopen("/tmp/e9afl.log", "a");
if (log != NULL)
setvbuf(log, NULL, _IONBF, 0);
}
if (log == NULL)
{
if (fatal)
abort();
return;
}
vfprintf(log, msg, ap);
if (fatal)
abort();
va_end(ap);
}
#define error(msg, ...) \
print_message(true, "e9afl runtime error: " msg "\n", ## __VA_ARGS__)
#define log(msg, ...) \
print_message(false, "e9afl log: " msg "\n", ## __VA_ARGS__)
/* SHM setup. */
static bool __afl_map_shm(void)
{
const char *id_str = getenv("__AFL_SHM_ID");
/*
* If we're running under AFL, attach to the appropriate region,
* replacing the early-stage __afl_area_initial region that is needed to
* allow some really hacky .init code to work correctly in projects such
* as OpenSSL.
*/
intptr_t afl_area_ptr = 0x0;
uint32_t shm_id = 0;
bool enabled = false;
if (id_str != NULL)
{
const char *map_size_str = getenv("AFL_MAP_SIZE");
if (map_size_str != 0 && atoi(map_size_str) < AREA_SIZE)
error("failed to set AFL area size to %s", map_size_str);
shm_id = (uint32_t)atoi(id_str);
(void)munmap(AREA_BASE, AREA_SIZE);
afl_area_ptr = (intptr_t)shmat(shm_id, AREA_BASE, 0);
enabled = true;
}
else
{
/*
* If there is no id_str then we are running the program normally
* and not with afl-fuzz. Create a dummy area so the program does
* not crash.
*/
afl_area_ptr = (intptr_t)mmap(AREA_BASE, AREA_SIZE,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
}
/* Whooooops. */
if (afl_area_ptr != (intptr_t)AREA_BASE)
error("failed to map AFL area (shm_id=%s): %s", id_str,
strerror(errno));
return enabled;
}
/* Init TLS if necessary. */
#include <asm/prctl.h>
static void __afl_init_tls(void)
{
uintptr_t val;
int r = (int)syscall(SYS_arch_prctl, ARCH_GET_FS, &val);
if (r < 0)
error("failed to get TLS base address: %s", strerror(errno));
if (val == 0x0)
{
/*
* If glibc is not dynamically linked then %fs may be uninitialized.
* Since the instrumentation uses TLS, this will cause the binary to
* crash. We fix this using a "dummy" TLS.
*/
static uint8_t dummy_tls[128] = {0};
r = (int)syscall(SYS_arch_prctl, ARCH_SET_FS,
dummy_tls + sizeof(dummy_tls));
if (r < 0)
error("failed to set TLS base address: %s", strerror(errno));
}
}
/* Fork server logic. */
static void __afl_start_forkserver(void)
{
const uint8_t tmp[4] = {0};
int child_pid;
/*
* Phone home and tell the parent that we're OK. If parent isn't there,
* assume we're not running in forkserver mode and just execute program.
*/
if (write(FORKSRV_FD + 1, tmp, 4) != 4)
return;
while (true)
{
/*
* Wait for parent by reading from the pipe. Abort if read fails.
*/
uint32_t was_killed;
if (read(FORKSRV_FD, &was_killed, sizeof(was_killed))
!= sizeof(was_killed))
error("failed to read from the fork server pipe: %s",
strerror(errno));
int status = 0;
if (was_killed)
{
if (waitpid(child_pid, &status, 0) < 0)
log("failed to wait for child process: %s", strerror(errno));
}
/*
* Once woken up, create a clone of our process.
*/
child_pid = fork();
if (child_pid < 0)
error("failed to fork process: %s", strerror(errno));
/*
* In child process: close fds, resume execution.
*/
if (!child_pid)
{
close(FORKSRV_FD);
close(FORKSRV_FD + 1);
return;
}
/*
* In parent process: write PID to pipe, then wait for child.
*/
if (write(FORKSRV_FD + 1, &child_pid, sizeof(child_pid))
!= sizeof(child_pid))
error("failed to write child pid to the fork server pipe: %s",
strerror(errno));
if (waitpid(child_pid, &status, 0) < 0)
log("failed to wait for the child process: %s", strerror(errno));
/*
* Relay wait status to pipe, then loop back.
*/
if (write(FORKSRV_FD + 1, &status, sizeof(status)) != sizeof(status))
error("failed to write child status to the fork server pipe: %s",
strerror(errno));
}
}
/*
* Init.
*/
void init(int argc, const char **argv, char **envp, void *_unused,
const struct e9_config_s *config)
{
__afl_init_tls();
if ((config->flags & E9_FLAG_EXE) == 0)
{
/*
* This is a shared library. For this, we set up a dummy area so the
* instrumentation does not crash during program initialization. The
* main executable is responsible for setting up AFL proper.
*/
(void)mmap(AREA_BASE, AREA_SIZE,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
return;
}
environ = envp;
if (__afl_map_shm())
{
log("fuzzing binary %s", argv[0]);
__afl_start_forkserver();
}
}
/*
* Entry. This is a (slower) alternative to the plugin instrumentation.
*
* USAGE:
* E9AFL_NO_INSTRUMENT=1 ./e9tool -M 'plugin(e9afl).match()' \
* -A 'call entry(random)@"afl-rt"' \
* path/to/binary
*/
void entry(uint32_t curr_loc)
{
uint32_t prev_loc = 0;
asm ("mov %%fs:0x4c,%0" : "=r"(prev_loc));
uint16_t idx = prev_loc ^ curr_loc;
AREA_BASE[idx]++;
asm ("mov %0,%%fs:0x4c" : : "r"(curr_loc >> 1));
}
// E9AFL_NO_INSTRUMENT=1 ./e9tool -M 'plugin(e9afl).match()' -A 'call entry(random)@"afl-rt"' path/to/binary
\ No newline at end of file
File added
0x48b0:bftpdutmp_log@RET:0x49f4@-344:312
0x48b0:bftpdutmp_log@RET:0x49f4@-648:304
0x4b80:bftpdutmp_pidexists@RET:0x4c17@-344:312
0x4c20:bftpdutmp_usercount@RET:0x4cd4@-360:312
0x4ce0:bftpdutmp_dup_ip_count@RET:0x4d84@-360:312
0x4e80:control_printf@RET:0x4fc4@-752:24
0x5470:command_epsv@RET:0x5628@-40:24
0x6110:command_pasv@RET:0x63a0@-56:24
0x63b0:dataconn@RET:0x6577@-40:24
0x6980:command_mget@RET:0x6ae6@-312:264
0x7220:run_script@RET:0x7385@-72:24
0x76e0:command_mput@RET:0x7846@-312:264
0x7ef0:command_chown@RET:0x8178@-568:256
0x7ef0:command_chown@RET:0x8178@-824:256
0x8220:command_adminwho@RET:0x8332@-344:312
0x8cd0:bftpd_stat@RET:0x902a@-440:392
0x8cd0:bftpd_stat@RET:0x902a@-712:272
0x8cd0:bftpd_stat@RET:0x902a@-808:32
0x8cd0:bftpd_stat@RET:0x902a@-968:148
0x8cd0:bftpd_stat@RET:0x902a@-1032:64
0x9540:bftpd_logwtmp@RET:0x9663@-424:392
0x9670:mygetpwuid@RET:0x97a0@-328:264
0x97b0:mygetpwnam@RET:0x98ea@-328:264
0x97b0:mygetpwnam@RET:0x98ea@-360:32
0x9d00:check_file_password@RET:0x9f19@-136:72
0x9d00:check_file_password@RET:0x9f19@-232:48
0x9f20:bftpd_login@RET:0xa3a1@-584:520
0xaa70:bftpd_statuslog@RET:0xabbd@-1264:24
0xabd0:bftpd_log@RET:0xad96@-1312:24
0xafe0:Get_Time_Zone_Difference@RET:0xb0e0@-72:56
0xafe0:Get_Time_Zone_Difference@RET:0xb0e0@-136:64
0xb340:print_file@RET:0xb422@-568:520
0xbb20:expand_groups@RET:0xbe8a@-104:40
0xbb20:expand_groups@RET:0xbe8a@-128:20
0xd770:md5_buffer@RET:0xd7fb@-200:168
#!/bin/bash
if [ -t 1 ]
then
RED="\033[31m"
GREEN="\033[32m"
YELLOW="\033[33m"
BOLD="\033[1m"
OFF="\033[0m"
else
RED=
GREEN=
YELLOW=
BOLD=
OFF=
fi
while [ $# -ge 1 ]
do
case "$1" in
--help|-h)
echo "usage: $0 [OPTIONS]"
echo
echo "OPTIONS:"
echo
echo " --help, -h"
echo " Print this message"
echo
exit 0
;;
*)
echo "unknown argument \"$1\"; try \`$0 --help' for more information"
exit 1
;;
esac
shift
done
TARGET=`readlink zydis`
if [ ! -d zydis ]
then
ZYDIS_VERSION=3f5a3ad8e16658c62d7033e9373232d19480d3cc
ZYCORE_VERSION=5c341bf141fe9274c9037c542274ead19fb645d8
echo -e "${GREEN}$0${OFF}: downloading zydis-$ZYDIS_VERSION.zip..."
wget -O zydis-$ZYDIS_VERSION.zip https://github.com/zyantific/zydis/archive/$ZYDIS_VERSION.zip
echo -e "${GREEN}$0${OFF}: downloading zycore-$ZYCORE_VERSION.zip..."
wget -O zycore-$ZYCORE_VERSION.zip https://github.com/zyantific/zycore-c/archive/$ZYCORE_VERSION.zip
echo -e "${GREEN}$0${OFF}: extracting zydis-$ZYDIS_VERSION.zip..."
unzip zydis-$ZYDIS_VERSION.zip
rm -f zydis-$ZYDIS_VERSION.zip
echo -e "${GREEN}$0${OFF}: extracting zycore-$ZYCORE_VERSION.zip..."
unzip zycore-$ZYCORE_VERSION.zip
rm -f zycore-$ZYCORE_VERSION.zip
echo -e "${GREEN}$0${OFF}: building Zydis..."
mv zydis-$ZYDIS_VERSION zydis/
rm -rf zydis/dependencies/zycore/
mv zycore-c-$ZYCORE_VERSION zydis/dependencies/zycore/
rm -rf zycore-c-$ZYCORE_VERSION
cat << EOF > zydis/include/ZydisExportConfig.h
#ifndef ZYDIS_EXPORT_H
#define ZYDIS_EXPORT_H
#define ZYDIS_EXPORT
#define ZYDIS_NO_EXPORT
#define ZYDIS_DEPRECATED __attribute__ ((__deprecated__))
#define ZYDIS_DEPRECATED_EXPORT ZYDIS_EXPORT ZYDIS_DEPRECATED
#define ZYDIS_DEPRECATED_NO_EXPORT ZYDIS_NO_EXPORT ZYDIS_DEPRECATED
#define ZYDIS_NO_DEPRECATED
#endif
EOF
cat << EOF > zydis/include/ZycoreExportConfig.h
#ifndef ZYCORE_EXPORT_H
#define ZYCORE_EXPORT_H
#define ZYCORE_EXPORT
#define ZYCORE_NO_EXPORT
#define ZYCORE_DEPRECATED __attribute__ ((__deprecated__))
#define ZYCORE_DEPRECATED_EXPORT ZYCORE_EXPORT ZYCORE_DEPRECATED
#define ZYCORE_DEPRECATED_NO_EXPORT ZYCORE_NO_EXPORT ZYCORE_DEPRECATED
#define ZYCORE_NO_DEPRECATED
#endif
EOF
make -f Makefile.zydis -j `nproc`
fi
echo -e "${GREEN}$0${OFF}: building e9patch and e9tool..."
make tool.clean clean
make -j `nproc` tool release
echo -e "${GREEN}$0${OFF}: done...!"
#!/usr/bin/python
#coding=utf-8
from pwn import *
local = True
hashlibc = True
context.log_level = 'debug'
#p = remote('pwnable.org', 12356)
elf_path="./test-instr-count4"
def change_ld(binary, ld):
"""
Force to use assigned new ld.so by changing the binary
"""
ld_tmp = b"/tmp/" + os.path.basename(ld)
if not os.access(ld, os.R_OK):
log.failure("Invalid path {} to ld".format(ld))
return None
else:
if os.access(ld_tmp, os.R_OK):
success(f"{ld_tmp.decode()} already exist.")
else:
os.system(f"cp {ld.decode()} {ld_tmp.decode()}")
success("cp")
if not isinstance(binary, ELF):
if not os.access(binary, os.R_OK):
log.failure("Invalid path {} to binary".format(binary))
return None
binary = ELF(binary, checksec=False)
debug_path = './{}_debug'.format(os.path.basename(binary.path))
if os.access(debug_path, os.F_OK):
success(f"{debug_path} already exits.")
else:
for segment in binary.segments:
if segment.header['p_type'] == 'PT_INTERP':
size = segment.header['p_memsz']
addr = segment.header['p_paddr']
data = segment.data()
if size <= len(ld_tmp):
log.failure("Failed to change PT_INTERP from {} to {}".format(data, ld))
return None
# print(len(ld_tmp))
binary.write(addr, ld_tmp.ljust(size, b'\x00'))
# if not os.access('/tmp/pwn', os.F_OK): os.mkdir('/tmp/pwn')
# path = '/tmp/pwn/{}_debug'.format(os.path.basename(binary.path))
# debug_path = './{}_debug'.format(os.path.basename(binary.path))
# if os.access(debug_path, os.F_OK):
# os.remove(debug_path)
# info("Removing exist file {}".format(debug_path))
binary.save(debug_path)
os.chmod(debug_path, 0b111000000) #rwx------
success("PT_INTERP has changed from {} to {}. Using temp debug file {}".format(data, ld_tmp, debug_path))
# return path
print(debug_path)
return ELF(debug_path, checksec=False)
if local:
if hashlibc:
libc_path = b'/usr/local/glibc-2.31/lib/libc-2.31.so'
ld_path = b'/usr/local/glibc-2.31/lib/ld-2.31.so'
libc = ELF(libc_path, checksec=False)
pwn_elf = change_ld(elf_path, ld_path)
#p = pwn_elf.process(env={'LD_PRELOAD':libc_path})
else:
p = process(elf_path)
libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so', checksec=False)
else:
# libc = ELF("./libc.so.6", checksec=False)
# libc = ELF('/lib/x86_64-linux-gnu/libc-2.31.so', checksec=False)
libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so', checksec=False)
#p = remote(host, port)
\ No newline at end of file
File added
File added
0xa7e0:read_hostsfile@RET:0xabac@-88:24
0xc100:cache_insert@RET:0xc50b@-88:24
0xdd30:extract_addresses@RET:0xe7ad@-88:24
0x11ae0:prettyprint_addr@RET:0x11c8f@-56:24
0x12d10:one_opt@RET:0x18425@-352:76
0x19d30:read_opts@RET:0x1a9de@-164:100
0x1b520:tcp_request@RET:0x1be8f@-96:32
0x1c1b0:forward_query.isra.0@RET:0x1c85f@-152:20
0x1c870:reply_query@RET:0x1cce3@-144:20
0x1ccf0:receive_query@RET:0x1d56d@-176:24
0x1ebf0:tcp_interface@RET:0x1edc0@-76:36
0x1edd0:create_wildcard_listeners@RET:0x1eec5@-72:24
0x1f7d0:pre_allocate_sfds@RET:0x1f9a0@-88:24
0x206b0:check_dns_listeners@RET:0x20d1c@-160:20
0x21de0:dhcp_packet@RET:0x22728@-304:24
0x24a50:lease_init@RET:0x25076@-88:24
0x24a50:lease_init@RET:0x25076@-112:20
0x279d0:dhcp_reply@RET:0x2bcc6@-240:20
0x2dd00:tftp_request@RET:0x2eb06@-280:48
0x30420:dhcp6_init@RET:0x30602@-72:24
0x32cc0:dhcp6_maybe_relay@RET:0x358b7@-88:24
0x392e0:periodic_ra@RET:0x3949b@-76:28
0x394a0:slaac_add_addrs@RET:0x3978b@-88:24
0x3c290:add_to_ipset@RET:0x3c645@-128:64
E9Tool/E9Patch Web Browser Guide
================================
This is a short demo for instrumenting modern web browsers using
E9Tool/E9Patch.
---
## Instrument Firefox
Modern versions of Firefox should be straightforward to instrument.
Below is a basic example:
0. Install E9Tool/E9Patch:
* [https://github.com/GJDuck/e9patch/releases](https://github.com/GJDuck/e9patch/releases)
1. Download
[Firefox](https://ftp.mozilla.org/pub/firefox/releases/108.0.2/linux-x86_64/en-US/firefox-108.0.2.tar.bz2):
$ wget https://ftp.mozilla.org/pub/firefox/releases/108.0.2/linux-x86_64/en-US/firefox-108.0.2.tar.bz2
For this demo we use Firefox version (108.0.2).
Other versions of Firefox may also work (untested).
2. Extract Firefox:
$ tar xvfj firefox-108.0.2.tar.bz2
$ cd firefox
3. Compile the instrumentation.
For this demo we use `counter.c`:
$ e9compile /usr/share/e9tool/examples/counter.c
4. Instrument the `libxul.so` binary.
Note that `libxul.so` is the main Firefox binary
(`firefox-bin` is mostly a wrapper that dynamically loads `libxul`).
In this example, we will insert `counter` instrumentation for each jump
instruction:
$ mv libxul.so libxul.orig.so
$ e9tool -M jmp -P 'entry()@counter' -c 5 -o libxul.so ./libxul.orig.so
Here:
* "`-M jmp`" matches all jump and conditional jump instructions.
* "`-P entry()@counter`" inserts a call to the `entry()` function defined
in `counter.c` for each matching instruction.
* "`-c 5`" tells E9Patch not to aggressively compress the output binary.
Since the input binary is quite large (~145MB), the output binary may use
more mappings beyond the system default.
This option reduces the number of mappings in exchange for a larger
output binary.
* "`-o libxul.so`" specifies that the output binary should be called
`libxul.so` (replacing the original).
* "`libxul.orig.so`" is the input binary (renamed from `libxul.so`).
5. Run Firefox with the instrumented `libxul.so`:
$ ./firefox
count = 1000000
count = 2000000
count = 3000000
count = 4000000
...
Notes:
* The `counter` instrumentation is not thread safe, so the counts will be
inaccurate for multi-threaded programs like Firefox.
However, this is just an example for demonstration purposes.
* The instrumented Firefox should be stable and behave the same as the
original, except for being slower and printing count information.
* Other kinds of instrumentation/rewriting is possible.
Please see the [E9Tool User
Guide](https://github.com/GJDuck/e9patch/blob/master/doc/e9tool-user-guide.md) for more information.
---
## Instrument Google Chrome?
It is also possible to instrument Google Chrome using E9Tool/E9Patch.
However, for modern versions of Chrome, this can be troublesome:
1. Chrome frequently uses data-in-code; and
2. Chrome seems to copy some code to different locations at runtime.
This breaks some of the basic assumptions for static binary rewriting.
It is possible to manually exclude affected regions from rewriting (see
E9Tool's `-E` option).
However, this process is manual, and depends on the specific Chrome version.
For older versions of Chrome (circa 2020), it is possible to successfully
rewrite Chrome by excluding all code before the "`ChromeMain`" symbol:
$ e9tool -E '.text..ChromeMain' ...
Here:
* "`-E '.text..ChromeMain'`" tells E9Tool to ignore all code in the
"`.text`" section before `ChromeMain`, which is usually <3% of all code.
This simple trick no longer works for modern versions of Chrome.
.TH E9COMPILE "1" "April 2023" "E9Compile" "E9Compile"
.SH NAME
E9Compile \- E9Tool instrumentation compiler
.SH SYNOPSIS
e9compile (\fIfile.c\fR | \fIfile.cpp\fR | \fIfile.s\fR) [\fIgcc-options\fR]
.SH DESCRIPTION
E9Compile is a simple gcc wrapper that can be used to compile E9Tool call
instrumentation implemented in C/C++.
E9Compile ensures that the generated binary code is compatible with E9Tool
call trampolines.
.PP
For more information, please refer to the following document:
.IP
\fI/usr/share/doc/e9tool/e9tool-user-guide.html\fR
.SH "SEE ALSO"
\fIe9patch\fR(1), \fIe9tool\fR(1)
.SH AUTHOR
\fBe9compile\fR is written by Gregory J. Duck <gregory@comp.nus.edu.sg>.
.TH E9PATCH "1" "April 2023" "E9Patch" "E9Patch"
.SH NAME
E9Patch \- a powerful static binary rewriting tool
.SH SYNOPSIS
e9patch [\fBOPTIONS\fR]
.PP
See below for the full list of options.
.SH DESCRIPTION
E9Patch is a powerful static rewriting for (stripped) x86_64 Linux ELF and
Windows PE binaries.
E9Patch is primarily designed for robustness, and can scale to very large
complex/binaries without introducing rewriting errors.
.PP
E9Patch is a low-level tool that is not designed to be used directly.
Instead, E9Patch should be invoked using a suitable \fIfrontend\fR, such as
E9Tool.
Please see the E9Tool manpage for more information.
.PP
For more information about advanced E9Patch usage, please refer to the
following document:
.IP
\fI/usr/share/doc/e9patch/e9patch-programming-guide.html\fR
.SH OUTPUT
.PP
E9Patch will output information about the patching progress in three main
phases.
The first phase tracks instruction patching success or failure:
.IP
\fB\[char46]\fR = Instruction was patched successfully
.br
\fBX\fR = Instruction could not be patched
.PP
The second phase tracks physical memory compression:
.IP
\fB+\fR = Service the virtual mapping with a new physical mapping
.br
\fBM\fR = Merge the virtual mapping into an existing physical mapping
.PP
The final phase prints the physical memory utilization:
.IP
\fB[hex]\fR = Each physical mapping utilization, higher = better
.PP
.SH OPTIONS
.IP "\fB\-OCFR\fR[=\fI\,false\/\fR]" 4
Enables [disables] heuristic-based "Control-Flow Recovery"
(CRF) analysis and related optimizations. This usually makes
the rewritten binary much faster, but may introduce rewriting
bugs if the built-in CRF analysis is inaccurate.
.br
Default: \fBfalse\fR (disabled)
.IP "\fB\-OCFR-hacks\fR[=\fI\,false\/\fR]" 4
Makes -OCFR even more conservative. This may help some
binaries that use non-standard relocations.
.br
Default: \fBfalse\fR (disabled)
.IP "\fB\-Oepilogue\fR=\fI\,N\/\fR" 4
Append a epilogue of up to N instructions to the end of each
trampoline. This may enhance \fB\-Opeephole\fR.
.br
Default: \fB0\fR (disabled)
.IP "\fB\-Oepilogue\-size\fR=\fI\,N\/\fR" 4
Additionally limits \fB\-Oepilogue\fR to N instruction bytes.
.br
Default: \fB64\fR
.IP "\fB\-Oorder\fR[=\fI\,false\/\fR]" 4
Enables [disables] the ordering of trampolines with respect
to the original instruction ordering (as much as is possible).
This may enhance \fB\-Opeephole\fR.
.br
Default: \fBfalse\fR (disabled)
.IP "\fB\-Opeephole\fR[=\fI\,false\/\fR]" 4
Enables [disables] jump peephole optimization.
.br
Default: \fBtrue\fR (enabled)
.IP "\fB\-Oprologue\fR=\fI\,N\/\fR" 4
Prepend a prologue of up to N instructions to the start of each
trampoline. This may enhance \fB\-Opeephole\fR. Requires \fB\-\-batch\fR.
.br
Default: \fB0\fR (disabled)
.IP "\fB\-Oprologue\-size\fR=\fI\,N\/\fR" 4
Additionally limits \fB\-Oprologue\fR to N instruction bytes.
.br
Default: \fB64\fR
.IP "\fB\-Oscratch\-stack\fR[=\fI\,false\/\fR]" 4
Allow the stack to be used as scratch space.
This allows faster code to be emitted, but may break transparency.
.br
Default: \fBfalse\fR (disabled)
.IP "\fB\-\-batch\fR[=\fI\,false\/\fR]" 4
Rewrite the binary in one batch rather than incrementally.
.br
Default: \fBfalse\fR (disabled)
.IP "\fB\-\-debug\fR[=\fI\,false\/\fR]" 4
Enable [disable] debug log messages.
.br
Default: \fBfalse\fR (disabled)
.IP "\fB\-\-help\fR, \fB\-h\fR" 4
Print the help message and exit.
.IP "\fB\-\-input\fR FILE, \fB\-i\fR FILE" 4
Read input from FILE instead of stdin.
.IP "\fB\-\-output\fR FILE, \fB\-o\fR FILE" 4
Write output to FILE instead of stdout.
.IP "\fB\-\-loader\-base\fR=\fI\,ADDR\/\fR" 4
Set ADDR to be the base address of the program loader.
Only relevant for ELF binaries.
.br
Default: 0x20e9e9000
.IP "\fB\-\-loader\-phdr\fR=\fI\,PHDR\/\fR" 4
Overwrite the corresponding PHDR to load the loader.
Valid values are "note", "relro", and "stack" for PT_NOTE, PT_RELRO
and PT_GNU_STACK respectively, or "any" to select any of the
above values. Note that selecting any value other than "note"
may relax the memory permissions in the patched binary.
Only relevant for ELF binaries.
.br
Default: note
.IP "\fB\-\-loader\-static\fR[=\fI\,false\/\fR]" 4
Enable [disable] the static loading of patched pages.
By default, patched pages are loaded dynamically during program
initialization (this is more reliable for complex binaries).
However, this can also bloat patched binary size.
Only relevant for ELF binaries.
.br
Default: \fBfalse\fR (disabled)
.IP "\fB\-\-log\fR=\fI\,[false]\/\fR" 4
Enable [disable] log output.
.br
Default: \fBtrue\fR (enabled)
.IP "\fB\-\-mem\-granularity\fR=\fI\,SIZE\/\fR" 4
Set SIZE to be the granularity used for the physical page
grouping memory optimization. Higher values result in
higher CPU+memory usage during rewriting, but also smaller
output binary files (i.e., better compression). Here, SIZE
must be one of {128,4096}.
.br
Default: \fB128\fR
.IP "\fB\-\-mem\-lb\fR=\fI\,LB\/\fR" 4
Set LB to be the minimum allowable trampoline address.
.IP "\fB\-\-mem\-ub\fR=\fI\,UB\/\fR" 4
Set UB to be the maximum allowable trampoline address.
.IP "\fB\-\-mem\-mapping\-size\fR=\fI\,SIZE\/\fR" 4
Set the mapping size to SIZE which must be a power\-of\-two
multiple of the page size (4096). Larger values result in
less virtual mappings being used, but larger output binary
files (i.e., worse compression).
.br
Default: \fB4096\fR
.IP "\fB\-\-mem\-multi\-page\fR[=\fI\,false\/\fR]" 4
Enable [disable] trampolines that cross page boundaries.
.br
Default: \fBtrue\fR (enabled)
.IP "\fB\-\-mem\-rebase\fR[=\fI\,ADDR\/\fR]" 4
Rebase the binary to the absolute address ADDR.
Only relevant for Windows PE binaries.
The special values "auto"
or "random" will cause a suitable base address to be chosen
automatically/randomly. The special value "none" leaves the
original base intact.
.br
Default: \fBnone\fR (disabled)
.IP "\fB\-\-tactic\-B1\fR[=\fI\,false\/\fR]" 4
.PD 0
.IP "\fB\-\-tactic\-B2\fR[=\fI\,false\/\fR]" 4
.PD 0
.IP "\fB\-\-tactic\-T1\fR[=\fI\,false\/\fR]" 4
.PD 0
.IP "\fB\-\-tactic\-T2\fR[=\fI\,false\/\fR]" 4
.PD 0
.IP "\fB\-\-tactic\-T3\fR[=\fI\,false\/\fR]" 4
.PD
Enables [disables] the corresponding tactic (B1/B2/T1/T2/T3).
.br
Default: \fBtrue\fR (enabled)
.IP
\fB\-\-tactic\-backward\-T3\fR[=\fI\,false\/\fR]
Enable [disables] backward jumps for tactic T3.
Default: \fBtrue\fR (enabled)
.TP
\fB\-\-trap\fR=\fI\,ADDR\/\fR
Insert a trap (int3) instruction at the trampoline entry for
the instruction at address ADDR. This can be used to debug
the trampoline using GDB.
.TP
\fB\-\-trap\-all\fR[=\fI\,false\/\fR]
Enable [disable] the insertion of a trap (int3) instruction at
all trampoline entries.
Default: \fBfalse\fR (disabled)
.TP
\fB\-\-trap\-entry\fR[=\fI\,false\/\fR]
Enable [disable] the insertion of a trap (int3) at the program
loader entry\-point.
Default: \fBfalse\fR (disabled)
.TP
\fB\-\-version\fR
Print the version and exit.
.SH "TROUBLESHOOTING"
The instrumented binary may sometimes fail to run properly.
See below for solutions to common problems.
.TP
\fBe9patch loader error: mmap(...) failed (errno=12)\fR
This occurs when the instrumented binary uses too many mappings.
This can usually be fixed by lowering the compression level,
see the \fB--compression\fR option for E9Tool (see \fBman e9tool\fR).
.TP
\fBTrace/breakpoint trap\fR
If using Control Flow Recovery (CFR) mode, the input binary may be
incompatible.
Disable CFR to resolve the issue.
.SH "SEE ALSO"
\fIe9tool\fR(1), \fIe9compile\fR(1), \fIe9afl\fR(1), \fIredfat\fR(1)
.SH AUTHOR
\fBe9patch\fR is written by Gregory J. Duck <gregory@comp.nus.edu.sg>.
.TH E9TOOL "1" "April 2023" "E9Tool" "E9Tool"
.SH NAME
E9Tool \- a powerful static binary rewriting tool
.SH SYNOPSIS
e9tool [\fBOPTIONS\fR] -M \fBMATCH\fR -P \fBPATCH\fR \fIbinary\fR
.PP
Where
.IP "" 4
- \fBOPTIONS\fR are E9Tool options (see below)
.br
- \fBMATCH\fR specifies \fIwhich\fR instructions should be patched
.br
- \fBPATCH\fR specifies \fIhow\fR matching instructions should be patched
.br
- \fIbinary\fR is the binary name/path.
.SH DESCRIPTION
.PP
E9Tool is the default frontend for the E9Patch static rewriting system for
(stripped) x86_64 Linux ELF or Windows PE binaries.
E9Tool is designed to be more high-level and user friendly.
.PP
E9Tool implements the following basic work flow:
.IP "" 4
1. Disassemble the input \fIbinary\fR
.br
2. Find all instructions matching \fBMATCH\fR
.br
3. Generate low-level E9Patch commands for \fBPATCH\fR
.br
4. Invoke E9Patch with the commands to rewrite the \fIbinary\fR
.PP
The output binary will be written to \fIa.out\fR by default, or a
filename specified by the \fB-o\fR option (see below).
.PP
For the \fBMATCH\fR and \fBPATCH\fR specification languages, as well as other
advanced E9Tool usage, please refer to the following document:
.IP "" 4
\fI/usr/share/doc/e9tool/e9tool-user-guide.html\fR
.SH EXAMPLE USAGE
For this example, we will rewrite the \fIxterm\fR binary with
instrumentation that prints information to the terminal.
The instrumentation is implemented in the \fIprint.c\fR file available here:
.IP "" 4
/usr/share/e9tool/examples/print.c
.PP
Here, the \fIprint.c\fR file exports the following function:
.nf
.sp
#include \fB"stdlib.c"\fR
void \fIentry\fR(const void *\fIaddr\fR,
const uint8_t *\fIinstr\fR,
size_t \fIsize\fR,
const char *\fIasm\fR)
{
...
}
.fi
.PP
Here:
.IP "" 4
- \fB"stdlib.c"\fR is the standard library (for printf, etc.)
.br
- \fIaddr\fR is the instruction address
.br
- \fIinstr\fR is the instruction bytes
.br
- \fIsize\fR is the size of the instruction
.br
- \fIasm\fR is the disassembly string of the instruction
.PP
Next, the instrumentation is compiled using the \fBe9compile\fR
script:
.IP "" 4
$ e9compile /usr/share/e9tool/examples/print.c
.PP
This generate a small binary named \fIprint\fR.
Next, we use \fBe9tool\fR to instrument the \fIxterm\fR program as follows:
.IP "" 4
$ e9tool -M 'asm=/xor.*/' -P 'entry(addr,instr,size,asm)@print' \fIxterm\fR
.PP
Here:
.IP "" 4
- the "\fB-M ...\fR" option matches all "xor" instructions
.br
- the "\fB-P ...\fR" option patches all matching xor instructions.
.PP
The patch will instrument all matching xor instructions will a call to
\fIentry()\fR from \fIprint\fR.
For each matching instruction, E9Tool will also pass the
corresponding values for each parameter of \fIentry()\fR.
.PP
The rewritten (instrumented) binary will be written to \fIa.out\fR,
and can be executed as follows:
.IP "" 4
$ ./\fIa.out\fR
.PP
The rewritten binary will run the same as the original,
but will also print information for each xor instruction that is executed.
.PP
This is a basic example, and E9Tool supports several options and use cases.
For more information, please refer to the following document:
.IP "" 4
\fI/usr/share/doc/e9tool/e9tool-user-guide.html\fR
.SH OPTIONS
.IP "\fB\-\-backend\fR PROG" 4
Use PROG as the backend.
The default is "e9patch".
.IP "\fB\-CFR\fr, \fB\-X\fR" 4
Enables binary rewriting "with" control-flow recovery. This
usually makes the rewritten binary much faster, but may
introduce rewriting bugs if the built-in recovery analysis is
inaccurate.
.IP "\fB\-\-compression\fR N, \fB\-c\fR N" 4
Set the compression level to be N, where N is a number within
the range 0..9. The default is 9 for maximum compression.
Higher compression makes the output binary smaller, but also
increases the number of mappings (mmap() calls) required.
.IP "\fB\-\-Dsync\fR N" 4
If the disassembler desyncs (e.g., data in the code section),
then automatically exclude N surrounding instructions.
The default is 64.
.IP "\fB\-\-Dthreshold\fR N" 4
Treat suspicious instructions as data.
Lower numbers means less tolerance.
The default is 2.
.IP "\fB\-\-debug\fR" 4
Enable debug output.
.IP "\fB\-\-exclude\fR RANGE, \fB\-E\fR RANGE" 4
Exclude the address RANGE from disassembly and rewriting.
Here, RANGE has the format `LB .. UB', where LB/UB are
integer addresses, section names or symbols. The address
range [LB..UB) will be excluded, and UB must point to the
first instruction where disassembly should resume.
.IP "\fB\-\-executable\fR" 4
Treat the input file as an executable, even if it appears to
be a shared library. See the `\-\-shared' option for more
information.
.IP "\fB\-\-format\fR FORMAT" 4
Set the output format to FORMAT which is one of {binary,
json, patch, patch.gz, patch,bz2, patch.xz}. Here:
.IP
\- "binary" is a modified ELF executable file;
.br
\- "json" is the raw JSON RPC stream for the e9patch
backend; or
.br
\- "patch" "patch.gz" "patch.bz2" and "patch.xz"
are (compressed) binary diffs in xxd format.
.IP
The default format is "binary".
.IP "\fB\-\-help\fR, \fB\-h\fR" 4
Print the help message and exit.
.IP "\fB\-\-no\-warnings\fR" 4
Do not print warning messages.
.IP "\fB\-\-plt\fR" 4
Enable the disassembly/rewriting of the .plt.* sections which
are excluded by default.
.IP "\fB\-\-plugin\fR=NAME:OPTION"
Pass OPTION to the plugin with NAME.
Here NAME must identify a
plugin used by a matching or patching operation.
.IP "\fB\-O0\fR, \fB\-O1\fR, \fB\-O2\fR, \fB\-O3\fR, \fB\-Os\fR"
Set the optimization level.
Here:
.IP
\fB\-O0\fR disables all optimization
.br
\fB\-O1\fR conservatively optimizes for performance
.br
\fB\-O2\fR optimizes for performance
.br
\fB\-O3\fR aggressively optimizes for performance
.br
\fB\-Os\fR optimizes for space
.IP
The default is \fB\-O2\fR.
.IP "\fB\-\-option\fR OPTION" 4
Pass OPTION to the e9patch backend.
.IP "\fB\-\-output\fR FILE, \fB\-o\fR FILE" 4
Specifies the path to the output file.
The default filename is
one of {"a.out", "a.so", "a.exe", "a.dll"}, depending on
the input binary type.
.IP "\fB\-\-seed\fR=\fI\,SEED\/\fR" 4
Set SEED as the random number seed.
.IP "\fB\-\-shared\fR" 4
Treat the input file as a shared library, even if it appears to
be an executable. By default, the input file will only be
treated as a shared library if (1) it is a dynamic executable
(ET_DYN) and (2) has a filename of the form:
.IP
[PATH/]lib*.so[.VERSION]
.IP "\fB\-\-static\-loader\fR, \fB\-s\fR" 4
Replace patched pages statically.
By default, patched pages
are loaded during program initialization as this is more
reliable for large/complex binaries. However, this may bloat
the size of the output patched binary.
.IP "\fB\-\-syntax\fR SYNTAX" 4
Selects the assembly syntax to be SYNTAX.
Possible values are:
.IP
"ATT": X86_64 ATT asm syntax
.br
"intel": X86_64 Intel asm syntax
.IP
The default syntax is "ATT".
.IP "\fB\-\-trap\fR=\fI\,ADDR\/\fR, \fB\-\-trap\-all\fR" 4
Insert a trap (int3) instruction at the corresponding
trampoline entry. This can be used for debugging with gdb.
.IP "\fB\-\-use\-disasm \fI\,FILE\/\fR" 4
Use the instruction information in FILE rather than the default
disassmebler. Here, FILE is a CSV file with a single column
representing instruction addresses.
.IP "\fB\-\-use\-targets \fI\,FILE\/\fR" 4
Use the jump/call target information in FILE rather than the
default control-flow recovery analysis. Here, FILE is a CSV
file where the first column is all jump/call targets, and an
optional second column is 1 for call targets (functions), or
0 otherwise (the default is 0).
.IP "\fB\-\-version\fR" 4
Print the version and exit.
.SH "SEE ALSO"
\fIe9patch\fR(1), \fIe9compile\fR(1), \fIe9afl\fR(1), \fIredfat\fR(1)
.SH AUTHOR
\fBe9patch\fR is written by Gregory J. Duck <gregory@comp.nus.edu.sg>.
0x2e30:get_psk_info@RET:0x2f61@-144:8
0x2e30:get_psk_info@RET:0x2f61@-152:8
0x3320:dtls_check_tls_extension@RET:0x37d6@-72:8
0x37e0:dtls_prepare_record@RET:0x3a97@-88:24
0x37e0:dtls_prepare_record@RET:0x3a97@-101:8
0x37e0:dtls_prepare_record@RET:0x3a97@-112:11
0x37e0:dtls_prepare_record@RET:0x3a97@-128:8
0x37e0:dtls_prepare_record@RET:0x3a97@-136:8
0x3aa0:dtls_send_multi@RET:0x3d22@-1472:8
0x3aa0:dtls_send_multi@RET:0x3d22@-1480:8
0x3aa0:dtls_send_multi@RET:0x3d22@-1488:8
0x3aa0:dtls_send_multi@RET:0x3d22@-1496:8
0x3aa0:dtls_send_multi@RET:0x3d22@-1504:8
0x3aa0:dtls_send_multi@RET:0x3d22@-1512:8
0x3aa0:dtls_send_multi@RET:0x3d22@-1520:8
0x3d30:dtls_retransmit@RET:0x3ec0@-1456:8
0x3d30:dtls_retransmit@RET:0x3ec0@-1464:8
0x3d30:dtls_retransmit@RET:0x3ec0@-1472:8
0x3d30:dtls_retransmit@RET:0x3ec0@-1480:8
0x3ed0:calculate_key_block.isra.0@RET:0x41b4@-120:16
0x3ed0:calculate_key_block.isra.0@RET:0x41b4@-128:8
0x4250:dtls_send_handshake_msg_hash@RET:0x4403@-104:8
0x4250:dtls_send_handshake_msg_hash@RET:0x4403@-120:8
0x4250:dtls_send_handshake_msg_hash@RET:0x4403@-128:8
0x4410:dtls_send_client_hello@RET:0x4771@-176:8
0x4410:dtls_send_client_hello@RET:0x4771@-192:16
0x4410:dtls_send_client_hello@RET:0x4771@-200:8
0x4840:dtls_send_certificate_verify_ecdh.isra.0@RET:0x49ae@-296:16
0x49c0:dtls_verify_peer@RET:0x4c3d@-136:72
0x49c0:dtls_verify_peer@RET:0x4c3d@-165:29
0x49c0:dtls_verify_peer@RET:0x4c3d@-360:12
0x49c0:dtls_verify_peer@RET:0x4c3d@-368:8
0x4d30:dtls_send_server_hello_msgs@RET:0x52b7@-178:8
0x4d30:dtls_send_server_hello_msgs@RET:0x52b7@-216:18
0x4d30:dtls_send_server_hello_msgs@RET:0x52b7@-352:8
0x4d30:dtls_send_server_hello_msgs@RET:0x52b7@-368:16
0x5400:handle_handshake_msg@RET:0x73b6@-134:32
0x5400:handle_handshake_msg@RET:0x73b6@-152:16
0x5400:handle_handshake_msg@RET:0x73b6@-168:16
0x5400:handle_handshake_msg@RET:0x73b6@-184:16
0x5400:handle_handshake_msg@RET:0x73b6@-200:16
0x5400:handle_handshake_msg@RET:0x73b6@-216:16
0x5400:handle_handshake_msg@RET:0x73b6@-232:16
0x5400:handle_handshake_msg@RET:0x73b6@-248:16
0x5400:handle_handshake_msg@RET:0x73b6@-256:8
0x5400:handle_handshake_msg@RET:0x73b6@-264:8
0x5400:handle_handshake_msg@RET:0x73b6@-272:8
0x5400:handle_handshake_msg@RET:0x73b6@-284:12
0x5400:handle_handshake_msg@RET:0x73b6@-296:12
0x5400:handle_handshake_msg@RET:0x73b6@-304:8
0x7450:dtls_alert_send_from_err@RET:0x755e@-32:14
0x7450:dtls_alert_send_from_err@RET:0x755e@-40:8
0x7450:dtls_alert_send_from_err@RET:0x755e@-56:12
0x7570:dtls_close@RET:0x760f@-48:14
0x7570:dtls_close@RET:0x760f@-56:8
0x7760:dtls_handle_message@RET:0x859d@-88:24
0x7760:dtls_handle_message@RET:0x859d@-101:8
0x7760:dtls_handle_message@RET:0x859d@-112:11
0x7760:dtls_handle_message@RET:0x859d@-120:8
0x7760:dtls_handle_message@RET:0x859d@-128:8
0x7760:dtls_handle_message@RET:0x859d@-136:8
0x7760:dtls_handle_message@RET:0x859d@-144:8
0x7760:dtls_handle_message@RET:0x859d@-160:8
0x8950:dtls_write@RET:0x89ff@-56:8
0x8950:dtls_write@RET:0x89ff@-64:8
0x8cb0:dtls_p_hash@RET:0x8fa4@-104:40
0x8cb0:dtls_p_hash@RET:0x8fa4@-144:8
0x8cb0:dtls_p_hash@RET:0x8fa4@-152:8
0x8cb0:dtls_p_hash@RET:0x8fa4@-160:8
0x8cb0:dtls_p_hash@RET:0x8fa4@-168:8
0x8cb0:dtls_p_hash@RET:0x8fa4@-176:8
0x8cb0:dtls_p_hash@RET:0x8fa4@-184:8
0x8cb0:dtls_p_hash@RET:0x8fa4@-192:8
0x9350:dtls_ecdsa_generate_key@RET:0x94a7@-176:8
0x9550:dtls_ecdsa_create_sig@RET:0x9649@-224:8
0x9550:dtls_ecdsa_create_sig@RET:0x9649@-232:8
0x9550:dtls_ecdsa_create_sig@RET:0x9649@-240:8
0x9550:dtls_ecdsa_create_sig@RET:0x9649@-248:8
0x9730:dtls_ecdsa_verify_sig@RET:0x983a@-224:8
0x9730:dtls_ecdsa_verify_sig@RET:0x983a@-232:8
0x9730:dtls_ecdsa_verify_sig@RET:0x983a@-240:8
0x9730:dtls_ecdsa_verify_sig@RET:0x983a@-248:8
0x9cd0:dtls_ccm_encrypt_message@RET:0xa194@-88:24
0x9cd0:dtls_ccm_encrypt_message@RET:0xa194@-104:16
0x9cd0:dtls_ccm_encrypt_message@RET:0xa194@-144:8
0x9cd0:dtls_ccm_encrypt_message@RET:0xa194@-152:8
0x9cd0:dtls_ccm_encrypt_message@RET:0xa194@-160:8
0x9cd0:dtls_ccm_encrypt_message@RET:0xa194@-168:8
0x9cd0:dtls_ccm_encrypt_message@RET:0xa194@-176:8
0x9cd0:dtls_ccm_encrypt_message@RET:0xa194@-184:8
0x9cd0:dtls_ccm_encrypt_message@RET:0xa194@-192:8
0x9cd0:dtls_ccm_encrypt_message@RET:0xa194@-200:8
0x9cd0:dtls_ccm_encrypt_message@RET:0xa194@-208:8
0x9cd0:dtls_ccm_encrypt_message@RET:0xa194@-216:8
0xa1a0:dtls_ccm_decrypt_message@RET:0xa6a4@-88:24
0xa1a0:dtls_ccm_decrypt_message@RET:0xa6a4@-104:16
0xa1a0:dtls_ccm_decrypt_message@RET:0xa6a4@-144:8
0xa1a0:dtls_ccm_decrypt_message@RET:0xa6a4@-152:8
0xa1a0:dtls_ccm_decrypt_message@RET:0xa6a4@-160:8
0xa1a0:dtls_ccm_decrypt_message@RET:0xa6a4@-168:8
0xa1a0:dtls_ccm_decrypt_message@RET:0xa6a4@-176:8
0xa1a0:dtls_ccm_decrypt_message@RET:0xa6a4@-184:8
0xa1a0:dtls_ccm_decrypt_message@RET:0xa6a4@-192:8
0xa1a0:dtls_ccm_decrypt_message@RET:0xa6a4@-200:8
0xa1a0:dtls_ccm_decrypt_message@RET:0xa6a4@-208:8
0xa1a0:dtls_ccm_decrypt_message@RET:0xa6a4@-216:8
0xb250:rijndaelEncrypt@RET:0xb60c@-64:8
0xb250:rijndaelEncrypt@RET:0xb60c@-72:8
0xb250:rijndaelEncrypt@RET:0xb60c@-80:8
0xb660:fieldMult@RET:0xb83f@-64:16
0xb660:fieldMult@RET:0xb83f@-80:16
0xb660:fieldMult@RET:0xb83f@-88:8
0xb660:fieldMult@RET:0xb83f@-96:8
0xb660:fieldMult@RET:0xb83f@-104:8
0xb660:fieldMult@RET:0xb83f@-112:8
0xb660:fieldMult@RET:0xb83f@-128:15
0xb850:fieldModO@RET:0xba2e@-120:36
0xb850:fieldModO@RET:0xba2e@-168:8
0xba40:fieldSub.part.0@RET:0xbab6@-40:24
0xba40:fieldSub.part.0@RET:0xbab6@-56:16
0xbb20:fieldAddAndDivide@RET:0xbc2b@-40:24
0xbb20:fieldAddAndDivide@RET:0xbc2b@-56:16
0xbc30:fieldInv@RET:0xc0e8@-120:16
0xbc30:fieldInv@RET:0xc0e8@-136:16
0xbc30:fieldInv@RET:0xc0e8@-152:16
0xbc30:fieldInv@RET:0xc0e8@-168:16
0xbc30:fieldInv@RET:0xc0e8@-184:16
0xbc30:fieldInv@RET:0xc0e8@-200:16
0xbc30:fieldInv@RET:0xc0e8@-216:16
0xbc30:fieldInv@RET:0xc0e8@-232:16
0xbc30:fieldInv@RET:0xc0e8@-248:16
0xbc30:fieldInv@RET:0xc0e8@-264:16
0xbc30:fieldInv@RET:0xc0e8@-272:8
0xbc30:fieldInv@RET:0xc0e8@-280:8
0xbc30:fieldInv@RET:0xc0e8@-288:8
0xbc30:fieldInv@RET:0xc0e8@-304:12
0xc150:fieldModP@RET:0xc40c@-88:16
0xc150:fieldModP@RET:0xc40c@-120:32
0xc420:ec_double@RET:0xc658@-200:16
0xc420:ec_double@RET:0xc658@-240:8
0xc420:ec_double@RET:0xc658@-248:8
0xc660:ec_add@RET:0xc98d@-240:8
0xc660:ec_add@RET:0xc98d@-248:8
0xc660:ec_add@RET:0xc98d@-256:8
0xc9a0:ecc_ec_mult@RET:0xcb2b@-104:16
0xc9a0:ecc_ec_mult@RET:0xcb2b@-136:16
0xc9a0:ecc_ec_mult@RET:0xcb2b@-152:16
0xc9a0:ecc_ec_mult@RET:0xcb2b@-168:16
0xc9a0:ecc_ec_mult@RET:0xcb2b@-184:16
0xc9a0:ecc_ec_mult@RET:0xcb2b@-200:16
0xc9a0:ecc_ec_mult@RET:0xcb2b@-208:8
0xc9a0:ecc_ec_mult@RET:0xcb2b@-216:8
0xc9a0:ecc_ec_mult@RET:0xcb2b@-224:8
0xc9a0:ecc_ec_mult@RET:0xcb2b@-232:8
0xcb30:ecc_ecdsa_sign_hash@RET:0xccdd@-136:32
0xccf0:ecc_ecdsa_validate@RET:0xce84@-296:8
0xccf0:ecc_ecdsa_validate@RET:0xce84@-464:8
0xccf0:ecc_ecdsa_validate@RET:0xce84@-472:8
0xcf30:dtls_sha256_transform@RET:0xd167@-64:8
File added
#!/bin/sh
#
# Copyright (C) 2022 National University of Singapore
#
# 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/>.
if [ -t 1 ]
then
RED="\033[31m"
GREEN="\033[32m"
YELLOW="\033[33m"
BOLD="\033[1m"
OFF="\033[0m"
else
RED=
GREEN=
YELLOW=
BOLD=
OFF=
fi
if [ $# -lt 1 ]
then
echo "${YELLOW}usage${OFF}: $0 file.c [CFLAGS ...]" >&2
exit 1
fi
case "$1" in
*.s)
CC=gcc
EXTENSION=s
;;
*.c)
CC=gcc
EXTENSION=c
;;
*.cpp)
CC=g++
EXTENSION=cpp
;;
*)
echo >&2
echo "${RED}error${OFF}: file $1 must have a .c/.cpp/.s extension" >&2
echo >&2
exit 1
;;
esac
BASENAME=`basename $1 .$EXTENSION`
DIRNAME=`dirname $1`
shift
CFLAGS="-fno-stack-protector -fno-builtin -fno-exceptions -fpermissive\
-fpie -O0 -g -Wno-unused-function -U_FORTIFY_SOURCE \
-mno-mmx -mno-sse -mno-avx -mno-avx2 -mno-avx512f -msoft-float \
-mstringop-strategy=loop -fno-tree-vectorize -fomit-frame-pointer \
-I examples/"
COMPILE="$CC $CFLAGS -c -Wall $@ \"$DIRNAME/$BASENAME.$EXTENSION\""
echo "$COMPILE" | xargs
if ! eval "$COMPILE"
then
echo >&2
echo "${RED}error${OFF}: compilation of (${YELLOW}$BASENAME${OFF}) failed" >&2
echo >&2
exit 1
fi
CFLAGS="-pie -nostdlib \
-Wl,-z -Wl,max-page-size=4096 \
-Wl,-z -Wl,norelro \
-Wl,-z -Wl,stack-size=0 \
-Wl,--export-dynamic \
-Wl,--entry=0x0"
COMPILE="$CC \"$BASENAME.o\" -o \"$BASENAME\" $CFLAGS"
echo "$COMPILE" | xargs
if ! eval "$COMPILE"
then
echo >&2
echo "${RED}error${OFF}: linking (${YELLOW}$BASENAME${OFF}) failed" >&2
echo >&2
exit 1
fi
RELOCS=`readelf -r "$BASENAME" | head -n 10 | grep 'R_X86_64_'`
if [ ! -z "$RELOCS" ]
then
echo >&2
echo "${RED}warning${OFF}: the generated file (${YELLOW}$BASENAME${OFF}) contains relocations" >&2
echo >&2
echo "EXPLANATION:" >&2
echo >&2
echo " E9Tool's call instrumentation does not support relocations. These are" >&2
echo " usually caused by global variables that contain pointers, e.g.:" >&2
echo >&2
echo " ${YELLOW}const char *days[] = {\"mon\", \"tue\", \"wed\", \"thu\", \"fri\", \"sat\", \"sun\"};${OFF}" >&2
echo >&2
echo " Here, the global variable days[] is an array-of-pointers which usually" >&2
echo " results in relocations in the instrumentation binary. Currently, E9Tool's" >&2
echo " call instrumentation does not apply relocations, meaning that the final" >&2
echo " patched binary using the instrumentation may crash." >&2
echo >&2
echo " It may be possible to rewrite code to avoid relocations in exchange for" >&2
echo " extra padding, e.g.:" >&2
echo >&2
echo " ${YELLOW}const char days[][4] = {\"mon\", \"tue\", \"wed\", \"thu\", \"fri\", \"sat\", \"sun\"};${OFF}" >&2
echo >&2
fi
if [ "$NO_SIMD_CHECK" = "" ]
then
SIMD=`objdump -d "$BASENAME" | grep -E '%(x|y|z)mm[0-9]' | head -n 10`
if [ ! -z "$SIMD" ]
then
echo >&2
echo "${RED}warning${OFF}: the generated file (${YELLOW}$BASENAME${OFF}) contains SIMD instructions" >&2
echo >&2
echo "EXPLANATION:" >&2
echo >&2
echo " E9Tool's call instrumentation does not save/restore the extended CPU state." >&2
echo " This can lead to subtle bugs if this state is clobbered by the trampoline" >&2
echo " code. This warning can be ignored if you know what you are doing." >&2
echo " (define NO_SIMD_CHECK=1 to disable)." >&2
echo >&2
fi
fi
exit 0
SECTIONS
{
.text : { *(.text.entry)
*(.text .rodata .rodata.* .data .data.*) }
/DISCARD/ : { *(*) }
}
OUTPUT_FORMAT(binary)
File added
File added
File added
0x412f:bftpdutmp_log@RET:0x4301@-328:312
0x412f:bftpdutmp_log@RET:0x4301@-632:304
0x4302:bftpdutmp_pidexists@RET:0x43ac@-328:312
0x43ad:bftpdutmp_usercount@RET:0x44a6@-328:312
0x44a7:bftpdutmp_dup_ip_count@RET:0x4570@-328:312
0x4571:bftpdutmp_remove_pid@RET:0x468f@-328:312
0x4690:control_printf@RET:0x47d5@-712:520
0x576f:test_abort@RET:0x5973@-296:264
0x576f:test_abort@RET:0x5973@-424:128
0x5993:command_mput@RET:0x5b40@-280:264
0x60fc:command_mget@RET:0x62a9@-280:264
0x62aa:command_retr@RET:0x6a34@-168:152
0x6c5f:command_mdtm@RET:0x6db1@-168:152
0x6e9e:command_dele@RET:0x70b8@-168:152
0x765b:command_size@RET:0x773e@-168:152
0x79f6:command_chown@RET:0x7cf8@-280:264
0x79f6:command_chown@RET:0x7cf8@-536:256
0x79f6:command_chown@RET:0x7cf8@-792:256
0x79f6:command_chown@RET:0x7cf8@-1048:256
0x7cf9:command_md5@RET:0x7ea7@-1048:1032
0x7cf9:command_md5@RET:0x7ea7@-1112:64
0x7cf9:command_md5@RET:0x7ea7@-1288:160
0x7ea8:command_site@RET:0x80fa@-152:136
0x837b:parsecmd@RET:0x8684@-88:72
0x88c2:command_adminlogin@RET:0x8a2a@-280:264
0x8a58:command_adminlog@RET:0x8be9@-280:264
0x8a58:command_adminlog@RET:0x8be9@-408:128
0x8c1e:command_adminwho@RET:0x8d58@-328:312
0x9697:bftpd_stat@RET:0x9a5d@-408:392
0x9697:bftpd_stat@RET:0x9a5d@-680:272
0x9697:bftpd_stat@RET:0x9a5d@-936:148
0x9697:bftpd_stat@RET:0x9a5d@-1000:64
0x9a5e:dirlist_one_file@RET:0x9b92@-168:152
0xa05c:mygetpwuid@RET:0xa24a@-280:264
0xa24b:mygetpwnam@RET:0xa415@-280:264
0xa47e:bftpd_logwtmp@RET:0xa5e7@-408:392
0xa6ce:bftpd_login@RET:0xb3a3@-536:520
0xb4e0:checkuser@RET:0xb5e9@-280:264
0xb682:check_file_password@RET:0xb898@-88:72
0xb9f3:bftpd_statuslog@RET:0xbb54@-1240:1032
0xbb55:bftpd_log@RET:0xbd35@-1224:1032
0xbfc1:Get_Time_Zone_Difference@RET:0xc0c1@-136:64
0xc0ee:print_file@RET:0xc1ca@-536:520
0xc4bd:main@RET:0xd0bd@-536:520
0xe17b:getoption_directories@RET:0xe3f7@-552:520
0xebc2:process_block@RET:0xfece@-88:72
0x10290:md5_buffer@RET:0x1031f@-184:168
0x7170:main@RET:0x90e3@-648:16
0xa7e0:read_hostsfile@RET:0xabac@-88:24
0xa7e0:read_hostsfile@RET:0xabac@-108:16
0xc100:cache_insert@RET:0xc50b@-88:24
0xdd30:extract_addresses@RET:0xe7ad@-88:24
0xdd30:extract_addresses@RET:0xe7ad@-128:16
0x11ae0:prettyprint_addr@RET:0x11c8f@-56:24
0x12d10:one_opt@RET:0x18425@-352:76
0x18fb0:read_file@RET:0x19476@-64:16
0x19d30:read_opts@RET:0x1a9de@-164:100
0x1b520:tcp_request@RET:0x1be8f@-96:32
0x1c1b0:forward_query.isra.0@RET:0x1c85f@-108:16
0x1c1b0:forward_query.isra.0@RET:0x1c85f@-152:20
0x1c870:reply_query@RET:0x1cce3@-144:20
0x1ccf0:receive_query@RET:0x1d56d@-176:24
0x1ccf0:receive_query@RET:0x1d56d@-216:16
0x1ccf0:receive_query@RET:0x1d56d@-232:16
0x1d6d0:enumerate_interfaces.part.0@RET:0x1d99a@-80:16
0x1dc70:iface_allowed.isra.0@RET:0x1e3bc@-172:16
0x1ebf0:tcp_interface@RET:0x1edc0@-32:16
0x1ebf0:tcp_interface@RET:0x1edc0@-76:36
0x1edd0:create_wildcard_listeners@RET:0x1eec5@-72:24
0x1f3d0:random_sock@RET:0x1f51e@-88:16
0x1f530:local_bind@RET:0x1f5e5@-72:16
0x1f7d0:pre_allocate_sfds@RET:0x1f9a0@-88:24
0x20000:reload_servers@RET:0x2028a@-104:16
0x20000:reload_servers@RET:0x2028a@-136:16
0x206b0:check_dns_listeners@RET:0x20d1c@-136:16
0x206b0:check_dns_listeners@RET:0x20d1c@-160:20
0x214c0:icmp_ping@RET:0x21865@-356:16
0x21de0:dhcp_packet@RET:0x22728@-136:16
0x21de0:dhcp_packet@RET:0x22728@-264:16
0x21de0:dhcp_packet@RET:0x22728@-280:16
0x21de0:dhcp_packet@RET:0x22728@-304:24
0x21de0:dhcp_packet@RET:0x22728@-432:16
0x22c50:dhcp_read_ethers@RET:0x231da@-92:16
0x24a50:lease_init@RET:0x25076@-64:16
0x24a50:lease_init@RET:0x25076@-88:24
0x24a50:lease_init@RET:0x25076@-112:20
0x279d0:dhcp_reply@RET:0x2bcc6@-88:16
0x279d0:dhcp_reply@RET:0x2bcc6@-240:20
0x2c770:create_helper@RET:0x2d48b@-232:16
0x2dd00:tftp_request@RET:0x2eb06@-280:48
0x2dd00:tftp_request@RET:0x2eb06@-360:16
0x2dd00:tftp_request@RET:0x2eb06@-392:16
0x2dd00:tftp_request@RET:0x2eb06@-408:16
0x2f260:my_syslog@RET:0x2f6e5@-232:16
0x2f260:my_syslog@RET:0x2f6e5@-304:16
0x30010:construct_worker@RET:0x3041b@-104:16
0x30010:construct_worker@RET:0x3041b@-120:16
0x30420:dhcp6_init@RET:0x30602@-72:24
0x30610:dhcp6_packet@RET:0x30a9b@-88:16
0x30610:dhcp6_packet@RET:0x30a9b@-104:16
0x30610:dhcp6_packet@RET:0x30a9b@-136:16
0x30610:dhcp6_packet@RET:0x30a9b@-272:16
0x30610:dhcp6_packet@RET:0x30a9b@-312:16
0x30aa0:get_client_mac@RET:0x30ba4@-136:16
0x31190:dhcp_construct_contexts@RET:0x3137a@-64:16
0x32cc0:dhcp6_maybe_relay@RET:0x358b7@-88:24
0x35a10:relay_upstream6@RET:0x35d24@-152:16
0x37e20:send_ra@RET:0x3890b@-136:16
0x37e20:send_ra@RET:0x3890b@-216:16
0x37e20:send_ra@RET:0x3890b@-280:16
0x38df0:ra_init@RET:0x3901d@-72:16
0x392e0:periodic_ra@RET:0x3949b@-76:28
0x394a0:slaac_add_addrs@RET:0x3978b@-88:24
0x39790:periodic_slaac@RET:0x39a25@-104:16
0x3c290:add_to_ipset@RET:0x3c645@-128:64
0x26f7:get_psk_info@RET:0x28c3@-120:104
0x28c4:read_from_peer@RET:0x29ba@-32:16
0x29bb:send_to_peer@RET:0x2a10@-32:20
0x2a11:dtls_handle_read@RET:0x2b6c@-168:152
0x2b6d:resolve_address@RET:0x2ce7@-72:56
0x2b6d:resolve_address@RET:0x2ce7@-112:20
0x2ce8:usage@RET:0x2d57@-32:16
0x2d58:main@RET:0x3282@-152:136
0x2d58:main@RET:0x3282@-280:128
0x2d58:main@RET:0x3282@-312:32
0x2d58:main@RET:0x3282@-328:16
0x3b00:dtls_prepare_record@RET:0x3db7@-88:24
0x41f0:calculate_key_block@RET:0x44d4@-120:16
0x4570:dtls_send_handshake_msg_hash@RET:0x4723@-104:28
0x4570:dtls_send_handshake_msg_hash@RET:0x4723@-120:16
0x4730:dtls_send_client_hello@RET:0x4a91@-168:104
0x4730:dtls_send_client_hello@RET:0x4a91@-192:16
0x4b60:dtls_send_certificate_verify_ecdh@RET:0x4cce@-296:16
0x4ce0:dtls_verify_peer@RET:0x4f5d@-136:72
0x4ce0:dtls_verify_peer@RET:0x4f5d@-168:32
0x5050:dtls_send_server_hello_msgs@RET:0x55d7@-216:152
0x5050:dtls_send_server_hello_msgs@RET:0x55d7@-368:16
0x5720:handle_handshake_msg@RET:0x76d6@-136:72
0x5720:handle_handshake_msg@RET:0x76d6@-248:112
0x7a80:dtls_handle_message@RET:0x88bd@-88:24
0x8fd0:dtls_p_hash@RET:0x92c4@-104:40
0x9ff0:dtls_ccm_encrypt_message@RET:0xa4b4@-88:24
0x9ff0:dtls_ccm_encrypt_message@RET:0xa4b4@-104:16
0x9ff0:dtls_ccm_encrypt_message@RET:0xa4b4@-120:16
0x9ff0:dtls_ccm_encrypt_message@RET:0xa4b4@-136:16
0xa4c0:dtls_ccm_decrypt_message@RET:0xa9c4@-88:24
0xa4c0:dtls_ccm_decrypt_message@RET:0xa9c4@-104:16
0xa4c0:dtls_ccm_decrypt_message@RET:0xa9c4@-120:16
0xa4c0:dtls_ccm_decrypt_message@RET:0xa9c4@-136:16
0xb980:fieldMult@RET:0xbb5f@-64:16
0xb980:fieldMult@RET:0xbb5f@-80:16
0xbb70:fieldModO@RET:0xbd4e@-120:72
0xbb70:fieldModO@RET:0xbd4e@-168:48
0xbd60:fieldAdd@RET:0xbdd6@-40:24
0xbd60:fieldAdd@RET:0xbdd6@-56:16
0xbe40:fieldAddAndDivide@RET:0xbf4b@-56:40
0xbf50:fieldInv@RET:0xc408@-136:32
0xbf50:fieldInv@RET:0xc408@-168:32
0xbf50:fieldInv@RET:0xc408@-200:32
0xbf50:fieldInv@RET:0xc408@-232:32
0xbf50:fieldInv@RET:0xc408@-264:32
0xc470:fieldModP@RET:0xc72c@-88:40
0xc470:fieldModP@RET:0xc72c@-120:32
0xc740:ec_double@RET:0xc978@-200:32
0xccc0:ecc_ec_mult@RET:0xce4b@-104:40
0xccc0:ecc_ec_mult@RET:0xce4b@-136:32
0xccc0:ecc_ec_mult@RET:0xce4b@-168:32
0xccc0:ecc_ec_mult@RET:0xce4b@-200:32
0xce50:ecc_ecdsa_sign_hash@RET:0xcffd@-136:72
0xd010:ecc_ecdsa_validate@RET:0xd1a4@-296:32
0xdbc0:dtls_ticks@RET:0xdc31@-40:24
0x11d9e:ratelimit_error@RET:0x11ed5@-4296:192
0x11fc1:acl_verify@RET:0x1324c@-328:264
0x11fc1:acl_verify@RET:0x1324c@-3464:1072
0x133d9:acl_read@RET:0x139f6@-136:72
0x13b91:acl_check_internal@RET:0x172f7@-224:40
0x18a21:daemon_go@RET:0x1b9e0@-193:129
0x18a21:daemon_go@RET:0x1b9e0@-488:128
0x1ba10:dbfn_open@RET:0x1c117@-328:264
0x1d66b:next_emf@RET:0x1d7b4@-312:264
0x1ecdb:common_error@RET:0x1ee51@-728:520
0x20c35:post_process_one@RET:0x217cb@-104:40
0x219cc:par_reduce@RET:0x21efd@-200:136
0x29a45:dns_basic_lookup@RET:0x2a1fa@-616:256
0x29a45:dns_basic_lookup@RET:0x2a1fa@-872:256
0x29a45:dns_basic_lookup@RET:0x2a1fa@-1128:256
0x2a1ff:dns_lookup@RET:0x2a4c3@-2184:1040
0x2a1ff:dns_lookup@RET:0x2a4c3@-3240:1040
0x2a4c8:dns_special_lookup@RET:0x2a976@-1128:1064
0x2ae13:milliwait@RET:0x2af03@-168:136
0x2b632:get_stdinput@RET:0x2b80f@-1080:1032
0x2c174:main@RET:0x333da@-4576:128
0x2c174:main@RET:0x333da@-4728:144
0x35930:expand_string_internal@RET:0x3c1c3@-2120:2056
0x35930:expand_string_internal@RET:0x3c1c3@-2376:256
0x35930:expand_string_internal@RET:0x3c1c3@-3184:808
0x3c3de:eval_condition@RET:0x3d98f@-327:263
0x3c3de:eval_condition@RET:0x3d98f@-544:72
0x3e8b1:read_condition@RET:0x3f1b7@-1096:1032
0x42d7e:native_sha1_mid@RET:0x42fa2@-232:80
0x42d7e:native_sha1_mid@RET:0x42fa2@-312:80
0x43db4:set_address_from_dns@RET:0x442f7@-2120:2056
0x43db4:set_address_from_dns@RET:0x442f7@-3192:1072
0x44ae8:host_aton@RET:0x44ddb@-124:60
0x44de0:host_fake_gethostbyname@RET:0x451cd@-3192:1072
0x463db:host_find_bydns@RET:0x472e8@-376:312
0x463db:host_find_bydns@RET:0x472e8@-3512:1072
0x472ed:host_name_lookup@RET:0x47da0@-328:264
0x472ed:host_name_lookup@RET:0x47da0@-3464:1072
0x48403:ip_tcpsocket@RET:0x484c2@-296:264
0x48846:ip_get_address_family@RET:0x488a6@-152:136
0x4e318:os_getloadavg@RET:0x4e3c6@-72:40
0x4fd90:parse_forward_list@RET:0x50891@-327:263
0x51079:queue_get_spool_list@RET:0x5149e@-328:253
0x51527:queue_run@RET:0x5212e@-323:259
0x51527:queue_run@RET:0x5212e@-391:63
0x528b3:queue_action@RET:0x534fe@-104:40
0x559ac:read_macro_assignment@RET:0x55bcc@-136:72
0x56aad:readconf_handle_option@RET:0x5816d@-136:72
0x56aad:readconf_handle_option@RET:0x5816d@-200:64
0x58663:print_ol@RET:0x58fec@-136:72
0x599e8:readconf_main@RET:0x5a5e8@-4503:335
0x5a5ed:readconf_driver_init@RET:0x5aa06@-136:72
0x5b3f5:readconf_rest@RET:0x5b842@-136:72
0x5c348:receive_statvfs@RET:0x5c5ae@-1080:1032
0x5cd7a:receive_msg@RET:0x5f21b@-216:48
0x67686:search_open@RET:0x679d4@-328:264
0x6b4e3:parse_commands@RET:0x6cdd3@-104:32
0x6f0d0:smtp_notquit_exit@RET:0x6f2d9@-344:136
0x6f87f:smtp_start_session@RET:0x705f6@-113:37
0x7700b:spool_write_header@RET:0x77aee@-216:48
0x7a3a2:string_sprintf@RET:0x7a4d9@-4296:192
0x7a58b:string_open_failed@RET:0x7a6ea@-1232:1024
0x7ba22:internal_transport_write_message@RET:0x7bed0@-600:536
0x7c663:transport_update_waiting@RET:0x7c9c6@-328:264
0x7c9cb:transport_check_waiting@RET:0x7cfda@-328:264
0x7ed6a:one_check_dnsbl@RET:0x7f511@-328:264
0x7ed6a:one_check_dnsbl@RET:0x7f511@-376:48
0x7ed6a:one_check_dnsbl@RET:0x7f511@-2440:2064
0x7ed6a:one_check_dnsbl@RET:0x7f511@-3512:1072
0x7f952:do_callout@RET:0x8134f@-12408:32
0x7f952:do_callout@RET:0x8134f@-12440:32
0x8345c:verify_get_ident@RET:0x83890@-2104:2056
0x83954:verify_check_dnsbl@RET:0x83f1f@-1608:128
0x84425:lf_sqlperform@RET:0x847a5@-1096:512
0x84a13:dnslookup_router_entry@RET:0x85165@-328:264
0x860f3:queryprogram_router_entry@RET:0x86c08@-1144:36
0x87d61:rf_get_errors_address@RET:0x87fc8@-216:152
0x89882:check_file_format@RET:0x89a59@-328:264
0x89d30:appendfile_transport_entry@RET:0x8c85b@-328:264
0x9235a:smtp_deliver@RET:0x93901@-136:72
0x9235a:smtp_deliver@RET:0x93901@-12472:32
0x9235a:smtp_deliver@RET:0x93901@-12504:32
0x95641:dnsdb_find@RET:0x9671d@-10580:2060
0x95641:dnsdb_find@RET:0x9671d@-11656:1072
0x4260:ParseConfig@RET:0x4687@-327:254
0x5a80:create_datasocket@RET:0x5b8b@-56:24
0x5d00:writelogentry@RET:0x5e4b@-64:16
0x66d0:retr_thread@RET:0x6b28@-168:104
0x7810:stor_thread@RET:0x7beb@-168:104
0x7810:stor_thread@RET:0x7beb@-208:16
0x7f30:append_thread@RET:0x8200@-136:104
0x7f30:append_thread@RET:0x8200@-160:16
0x8db0:pasv.part.0@RET:0x9000@-80:16
0x9540:ftp_client_thread@RET:0x9af9@-64:16
0x9540:ftp_client_thread@RET:0x9af9@-8408:16
0x9d60:list_sub@RET:0x9fdf@-64:16
0x9d60:list_sub@RET:0x9fdf@-144:68
0x9ff0:list_thread@RET:0xa27a@-152:104
0x9ff0:list_thread@RET:0xa27a@-176:16
0xa340:mlsd_sub@RET:0xa561@-64:16
0xa570:msld_thread@RET:0xa7fa@-152:104
0xa570:msld_thread@RET:0xa7fa@-176:16
0xa820:ftpmain@RET:0xaa4f@-72:24
0x1bbe6:register_services@RET:0x1c3d2@-280:264
0x1bbe6:register_services@RET:0x1c3d2@-664:384
0x1bbe6:register_services@RET:0x1c3d2@-1176:512
0x1c3d3:signal_signalfd_cb@RET:0x1c534@-152:136
0x1c535:main@RET:0x1d2ae@-440:424
0x1c535:main@RET:0x1d2ae@-568:128
0x1dbdf:sort_tag_create@RET:0x1e01d@-1048:1032
0x24147:db_pl_delete_bypath@RET:0x24290@-312:144
0x26c6e:db_queue_add_by_fileid@RET:0x26d64@-152:136
0x27579:queue_fetch_byitemid@RET:0x2766c@-112:96
0x2773f:db_queue_fetch_byfileid@RET:0x27912@-112:96
0x27913:queue_fetch_bypos@RET:0x27a36@-112:96
0x281e3:db_queue_delete_byitemid@RET:0x282a8@-232:216
0x28353:db_queue_delete_byposrelativetoitem@RET:0x28431@-232:216
0x28b4c:queue_reshuffle@RET:0x28ebc@-112:96
0x28b4c:queue_reshuffle@RET:0x28ebc@-376:208
0x2a5fc:db_statements_prepare_insert@RET:0x2a899@-2072:2056
0x2a5fc:db_statements_prepare_insert@RET:0x2a899@-3096:1024
0x2a89a:db_statements_prepare_update@RET:0x2ab75@-2072:2056
0x2bb0d:db_drop_from_master@RET:0x2be6f@-2080:2064
0x2dead:logger_confuse@RET:0x2df85@-104:88
0x2e0b7:conffile_expand_libname@RET:0x2e455@-408:392
0x30f22:cache_daap_get@RET:0x30fa5@-120:88
0x31aaa:file_path_ignore@RET:0x31be5@-88:72
0x3216d:playlist_add@RET:0x3220e@-120:104
0x35079:queue_item_stream_add@RET:0x351f9@-392:376
0x35079:queue_item_stream_add@RET:0x351f9@-600:208
0x3563f:playlist_add_files@RET:0x35999@-1064:384
0x35c15:queue_save@RET:0x3601c@-168:152
0x35c15:queue_save@RET:0x3601c@-552:384
0x37ead:process_url@RET:0x380f4@-328:312
0x3865e:scan_playlist@RET:0x38b8f@-4648:384
0x38e5a:apple_rss_feedurl_get@RET:0x39171@-120:104
0x39a47:rss_save@RET:0x39e26@-392:376
0x39f32:rss_scan_all@RET:0x3a12d@-112:96
0x3cab5:connection_test@RET:0x3cf75@-184:128
0x3dc8e:create_group_entry@RET:0x3e0cc@-88:72
0x3dc8e:create_group_entry@RET:0x3e0cc@-168:64
0x3eaa4:itunes_pairing_hash@RET:0x3ecc6@-88:72
0x3f910:do_pairing@RET:0x3fb42@-152:136
0x406ce:httpd_request_not_modified_since@RET:0x407f5@-1016:1000
0x42134:httpd_stream_file@RET:0x4307a@-88:72
0x43737:httpd_basic_auth@RET:0x43acd@-280:264
0x44f75:rsp_reply_playlist@RET:0x45832@-680:144
0x45f4b:rsp_init@RET:0x460b8@-88:72
0x4a8e6:daap_reply_browse@RET:0x4af8b@-168:68
0x4baa1:daap_init@RET:0x4bc0b@-88:72
0x4c29a:find_first_song_id@RET:0x4c4b6@-680:512
0x4c4b7:dacp_queueitem_add@RET:0x4cb6b@-1048:1032
0x4c4b7:dacp_queueitem_add@RET:0x4cb6b@-1136:88
0x4e0eb:dacp_propset_devicevolume@RET:0x4e16c@-360:344
0x4e16d:dacp_propset_devicepreventplayback@RET:0x4e242@-360:344
0x4e243:dacp_propset_devicebusy@RET:0x4e318@-360:344
0x4fb34:dacp_reply_playqueuecontents@RET:0x503fe@-376:208
0x51d4d:dacp_reply_volumeup@RET:0x51e60@-360:344
0x51e61:dacp_reply_volumedown@RET:0x51f74@-360:344
0x51f75:dacp_reply_mutetoggle@RET:0x52064@-360:328
0x5220d:dacp_init@RET:0x5262a@-88:72
0x52820:safe_json_add_string_from_int64@RET:0x528c9@-120:104
0x52949:safe_json_add_time_from_string@RET:0x52ab1@-120:64
0x52ab2:artist_to_json@RET:0x52c9a@-120:104
0x52ab2:artist_to_json@RET:0x52c9a@-232:112
0x52c9b:album_to_json@RET:0x52ea4@-120:104
0x52c9b:album_to_json@RET:0x52ea4@-232:112
0x52ea5:track_to_json@RET:0x534a0@-120:104
0x52ea5:track_to_json@RET:0x534a0@-232:112
0x534a1:playlist_to_json@RET:0x53659@-120:104
0x536e6:fetch_tracks@RET:0x53803@-520:504
0x538e4:fetch_artist@RET:0x53a03@-112:96
0x538e4:fetch_artist@RET:0x53a03@-248:80
0x53ae4:fetch_album@RET:0x53c03@-112:96
0x53ae4:fetch_album@RET:0x53c03@-248:80
0x53c04:fetch_playlists@RET:0x53d2b@-168:152
0x53d2c:fetch_playlist@RET:0x53e54@-112:96
0x53d2c:fetch_playlist@RET:0x53e54@-312:144
0x54e1d:jsonapi_reply_library@RET:0x550d9@-168:152
0x5573f:jsonapi_reply_outputs_get_byid@RET:0x558b1@-360:344
0x569fb:queue_item_to_json@RET:0x570ae@-120:104
0x569fb:queue_item_to_json@RET:0x570ae@-232:112
0x570af:queue_tracks_add_artist@RET:0x571c6@-112:96
0x571c7:queue_tracks_add_album@RET:0x572de@-112:96
0x572df:queue_tracks_add_track@RET:0x573f6@-112:96
0x57e7f:jsonapi_reply_queue@RET:0x582a3@-128:88
0x57e7f:jsonapi_reply_queue@RET:0x582a3@-392:208
0x58b2c:jsonapi_reply_library_artist_albums@RET:0x58d97@-112:96
0x59160:jsonapi_reply_library_album_tracks@RET:0x593cb@-112:96
0x594dd:jsonapi_reply_library_tracks_get_byid@RET:0x596f3@-112:96
0x594dd:jsonapi_reply_library_tracks_get_byid@RET:0x596f3@-680:512
0x59b9b:jsonapi_reply_library_playlists@RET:0x59df5@-112:96
0x5ad5f:jsonapi_reply_library_count@RET:0x5b04b@-112:96
0x5b04c:jsonapi_reply_library_files@RET:0x5b4c5@-112:96
0x5c5c4:jsonapi_init@RET:0x5c81b@-88:72
0x5d009:streaming_icy_meta_splice@RET:0x5d18c@-4104:4088
0x5d2d8:streaming_send_cb@RET:0x5d6c5@-1432:1416
0x5e2a5:oauth_init@RET:0x5e3f0@-88:72
0x5ea8a:artworkapi_init@RET:0x5ebd5@-88:72
0x5eecc:http_client_request@RET:0x5f324@-1048:1032
0x63cea:open_filter@RET:0x646cf@-568:520
0x6761b:online_source_request_url_make@RET:0x67b1c@-536:520
0x67d46:online_source_search@RET:0x68299@-2072:2056
0x67d46:online_source_search@RET:0x68299@-2328:256
0x68e7f:source_item_ownpl_get@RET:0x6911c@-4184:80
0x69a47:artwork_get_item@RET:0x69d97@-4360:256
0x69d98:artwork_get_group@RET:0x6a00f@-4328:224
0x6ba47:two_str_hash@RET:0x6bbbd@-2072:2056
0x71acf:speaker_enumerate@RET:0x71b9a@-360:344
0x7cd1f:raop_crypt_encrypt_aes_key_base64@RET:0x7d24e@-280:264
0x7cd1f:raop_crypt_encrypt_aes_key_base64@RET:0x7d24e@-344:64
0x7d24f:raop_add_auth@RET:0x7d934@-280:264
0x7dcc6:raop_add_headers@RET:0x7def4@-88:72
0x7e203:raop_send_req_flush@RET:0x7e424@-88:72
0x7e610:raop_send_req_record@RET:0x7e857@-88:72
0x7e858:raop_send_req_setup@RET:0x7eab4@-152:136
0x81323:packet_prepare@RET:0x814e0@-88:72
0x81b6a:raop_v2_timing_cb@RET:0x81eca@-216:128
0x84fa8:raop_init@RET:0x85395@-88:72
0x867b4:dump_card@RET:0x86bbb@-296:264
0x8c066:name_from_addr@RET:0x8c193@-1048:1032
0x8cd22:commands_exec_sync@RET:0x8cfc0@-152:88
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment