mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-13 18:48:08 +00:00
Merge branch 'master' of github.com:vanhauser-thc/AFLplusplus
This commit is contained in:
2
Makefile
2
Makefile
@ -280,6 +280,8 @@ code-format:
|
|||||||
./.custom-format.py -i qemu_mode/libcompcov/*.c
|
./.custom-format.py -i qemu_mode/libcompcov/*.c
|
||||||
./.custom-format.py -i qemu_mode/libcompcov/*.cc
|
./.custom-format.py -i qemu_mode/libcompcov/*.cc
|
||||||
./.custom-format.py -i qemu_mode/libcompcov/*.h
|
./.custom-format.py -i qemu_mode/libcompcov/*.h
|
||||||
|
./.custom-format.py -i qbdi_mode/*.c
|
||||||
|
./.custom-format.py -i qbdi_mode/*.cpp
|
||||||
./.custom-format.py -i *.h
|
./.custom-format.py -i *.h
|
||||||
./.custom-format.py -i *.c
|
./.custom-format.py -i *.c
|
||||||
|
|
||||||
|
@ -69,6 +69,9 @@ int dup2(int old, int new) {
|
|||||||
|
|
||||||
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
||||||
|
|
||||||
|
(void)sockfd;
|
||||||
|
(void)addr;
|
||||||
|
(void)addrlen;
|
||||||
fprintf(stderr, "Info: Emulating accept on %d\n", sockfd);
|
fprintf(stderr, "Info: Emulating accept on %d\n", sockfd);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -76,6 +79,9 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
|||||||
|
|
||||||
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||||
|
|
||||||
|
(void)sockfd;
|
||||||
|
(void)addr;
|
||||||
|
(void)addrlen;
|
||||||
fprintf(stderr, "Info: Emulating bind on port %d\n",
|
fprintf(stderr, "Info: Emulating bind on port %d\n",
|
||||||
ntohs(((struct sockaddr_in *)addr)->sin_port));
|
ntohs(((struct sockaddr_in *)addr)->sin_port));
|
||||||
return 0;
|
return 0;
|
||||||
@ -84,6 +90,20 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
|||||||
|
|
||||||
int listen(int sockfd, int backlog) {
|
int listen(int sockfd, int backlog) {
|
||||||
|
|
||||||
|
(void)sockfd;
|
||||||
|
(void)backlog;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int setsockopt(int sockfd, int level, int optid, const void *optdata,
|
||||||
|
socklen_t optdatalen) {
|
||||||
|
|
||||||
|
(void)sockfd;
|
||||||
|
(void)level;
|
||||||
|
(void)optid;
|
||||||
|
(void)optdata;
|
||||||
|
(void)optdatalen;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -470,7 +470,9 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
if (selectcmpInst->getPredicate() == CmpInst::FCMP_OEQ ||
|
if (selectcmpInst->getPredicate() == CmpInst::FCMP_OEQ ||
|
||||||
selectcmpInst->getPredicate() == CmpInst::FCMP_ONE ||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_ONE ||
|
||||||
selectcmpInst->getPredicate() == CmpInst::FCMP_UNE ||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_UNE ||
|
||||||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_UGT ||
|
||||||
selectcmpInst->getPredicate() == CmpInst::FCMP_OGT ||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_OGT ||
|
||||||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_ULT ||
|
||||||
selectcmpInst->getPredicate() == CmpInst::FCMP_OLT) {
|
selectcmpInst->getPredicate() == CmpInst::FCMP_OLT) {
|
||||||
|
|
||||||
auto op0 = selectcmpInst->getOperand(0);
|
auto op0 = selectcmpInst->getOperand(0);
|
||||||
@ -655,6 +657,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, m_e0, m_e1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, m_e0, m_e1);
|
||||||
break;
|
break;
|
||||||
case CmpInst::FCMP_OGT:
|
case CmpInst::FCMP_OGT:
|
||||||
|
case CmpInst::FCMP_UGT:
|
||||||
Instruction *icmp_exponent;
|
Instruction *icmp_exponent;
|
||||||
icmp_exponent =
|
icmp_exponent =
|
||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, m_e0, m_e1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, m_e0, m_e1);
|
||||||
@ -664,6 +667,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0);
|
BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0);
|
||||||
break;
|
break;
|
||||||
case CmpInst::FCMP_OLT:
|
case CmpInst::FCMP_OLT:
|
||||||
|
case CmpInst::FCMP_ULT:
|
||||||
icmp_exponent =
|
icmp_exponent =
|
||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, m_e0, m_e1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, m_e0, m_e1);
|
||||||
signequal_bb->getInstList().insert(
|
signequal_bb->getInstList().insert(
|
||||||
@ -755,6 +759,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, t_f0, t_f1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_NE, t_f0, t_f1);
|
||||||
break;
|
break;
|
||||||
case CmpInst::FCMP_OGT:
|
case CmpInst::FCMP_OGT:
|
||||||
|
case CmpInst::FCMP_UGT:
|
||||||
Instruction *icmp_fraction;
|
Instruction *icmp_fraction;
|
||||||
icmp_fraction =
|
icmp_fraction =
|
||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT, t_f0, t_f1);
|
||||||
@ -764,6 +769,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0);
|
BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0);
|
||||||
break;
|
break;
|
||||||
case CmpInst::FCMP_OLT:
|
case CmpInst::FCMP_OLT:
|
||||||
|
case CmpInst::FCMP_ULT:
|
||||||
icmp_fraction =
|
icmp_fraction =
|
||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT, t_f0, t_f1);
|
||||||
middle_bb->getInstList().insert(
|
middle_bb->getInstList().insert(
|
||||||
@ -802,6 +808,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
PN->addIncoming(icmp_fraction_result, middle_bb);
|
PN->addIncoming(icmp_fraction_result, middle_bb);
|
||||||
break;
|
break;
|
||||||
case CmpInst::FCMP_OGT:
|
case CmpInst::FCMP_OGT:
|
||||||
|
case CmpInst::FCMP_UGT:
|
||||||
/* if op1 is negative goto true branch,
|
/* if op1 is negative goto true branch,
|
||||||
else go on comparing */
|
else go on comparing */
|
||||||
PN->addIncoming(t_s1, bb);
|
PN->addIncoming(t_s1, bb);
|
||||||
@ -809,6 +816,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
PN->addIncoming(icmp_fraction_result, middle_bb);
|
PN->addIncoming(icmp_fraction_result, middle_bb);
|
||||||
break;
|
break;
|
||||||
case CmpInst::FCMP_OLT:
|
case CmpInst::FCMP_OLT:
|
||||||
|
case CmpInst::FCMP_ULT:
|
||||||
/* if op0 is negative goto true branch,
|
/* if op0 is negative goto true branch,
|
||||||
else go on comparing */
|
else go on comparing */
|
||||||
PN->addIncoming(t_s0, bb);
|
PN->addIncoming(t_s0, bb);
|
||||||
|
@ -719,8 +719,12 @@ static void set_up_environment(void) {
|
|||||||
|
|
||||||
s32 i, afl_preload_size = strlen(afl_preload);
|
s32 i, afl_preload_size = strlen(afl_preload);
|
||||||
for (i = 0; i < afl_preload_size; ++i) {
|
for (i = 0; i < afl_preload_size; ++i) {
|
||||||
|
|
||||||
if (afl_preload[i] == ',')
|
if (afl_preload[i] == ',')
|
||||||
PFATAL("Comma (',') is not allowed in AFL_PRELOAD when -Q is specified!");
|
PFATAL(
|
||||||
|
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||||
|
"specified!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemu_preload)
|
if (qemu_preload)
|
||||||
@ -862,8 +866,7 @@ static void find_binary(u8* fname) {
|
|||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
s32 opt;
|
s32 opt;
|
||||||
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0,
|
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
|
||||||
use_wine = 0;
|
|
||||||
char** use_argv;
|
char** use_argv;
|
||||||
|
|
||||||
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
|
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
|
||||||
|
@ -345,7 +345,12 @@ u8 trim_case_python(char** argv, struct queue_entry* q, u8* in_buf) {
|
|||||||
fault = run_target(argv, exec_tmout);
|
fault = run_target(argv, exec_tmout);
|
||||||
++trim_execs;
|
++trim_execs;
|
||||||
|
|
||||||
if (stop_soon || fault == FAULT_ERROR) goto abort_trimming;
|
if (stop_soon || fault == FAULT_ERROR) {
|
||||||
|
|
||||||
|
free(retbuf);
|
||||||
|
goto abort_trimming;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST);
|
cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST);
|
||||||
|
|
||||||
@ -381,6 +386,8 @@ u8 trim_case_python(char** argv, struct queue_entry* q, u8* in_buf) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(retbuf);
|
||||||
|
|
||||||
/* Since this can be slow, update the screen every now and then. */
|
/* Since this can be slow, update the screen every now and then. */
|
||||||
|
|
||||||
if (!(trim_exec++ % stats_update_freq)) show_stats();
|
if (!(trim_exec++ % stats_update_freq)) show_stats();
|
||||||
|
@ -720,8 +720,12 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
s32 i, afl_preload_size = strlen(afl_preload);
|
s32 i, afl_preload_size = strlen(afl_preload);
|
||||||
for (i = 0; i < afl_preload_size; ++i) {
|
for (i = 0; i < afl_preload_size; ++i) {
|
||||||
|
|
||||||
if (afl_preload[i] == ',')
|
if (afl_preload[i] == ',')
|
||||||
PFATAL("Comma (',') is not allowed in AFL_PRELOAD when -Q is specified!");
|
PFATAL(
|
||||||
|
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||||
|
"specified!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemu_preload)
|
if (qemu_preload)
|
||||||
|
@ -368,8 +368,12 @@ static void set_up_environment(void) {
|
|||||||
|
|
||||||
s32 i, afl_preload_size = strlen(afl_preload);
|
s32 i, afl_preload_size = strlen(afl_preload);
|
||||||
for (i = 0; i < afl_preload_size; ++i) {
|
for (i = 0; i < afl_preload_size; ++i) {
|
||||||
|
|
||||||
if (afl_preload[i] == ',')
|
if (afl_preload[i] == ',')
|
||||||
PFATAL("Comma (',') is not allowed in AFL_PRELOAD when -Q is specified!");
|
PFATAL(
|
||||||
|
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||||
|
"specified!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemu_preload)
|
if (qemu_preload)
|
||||||
@ -525,8 +529,7 @@ static void find_binary(u8* fname) {
|
|||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
s32 opt;
|
s32 opt;
|
||||||
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0,
|
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
|
||||||
use_wine = 0;
|
|
||||||
u32 tcnt = 0;
|
u32 tcnt = 0;
|
||||||
char** use_argv;
|
char** use_argv;
|
||||||
|
|
||||||
|
@ -892,8 +892,12 @@ static void set_up_environment(void) {
|
|||||||
|
|
||||||
s32 i, afl_preload_size = strlen(afl_preload);
|
s32 i, afl_preload_size = strlen(afl_preload);
|
||||||
for (i = 0; i < afl_preload_size; ++i) {
|
for (i = 0; i < afl_preload_size; ++i) {
|
||||||
|
|
||||||
if (afl_preload[i] == ',')
|
if (afl_preload[i] == ',')
|
||||||
PFATAL("Comma (',') is not allowed in AFL_PRELOAD when -Q is specified!");
|
PFATAL(
|
||||||
|
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||||
|
"specified!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemu_preload)
|
if (qemu_preload)
|
||||||
@ -1053,8 +1057,7 @@ static void read_bitmap(u8* fname) {
|
|||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
s32 opt;
|
s32 opt;
|
||||||
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0,
|
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
|
||||||
use_wine = 0;
|
|
||||||
char** use_argv;
|
char** use_argv;
|
||||||
|
|
||||||
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
|
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
The idea and much of the original implementation comes from Nathan Voss <njvoss299@gmail.com>.
|
The idea and much of the original implementation comes from Nathan Voss <njvoss299@gmail.com>.
|
||||||
|
|
||||||
The port to afl++ if by Dominik Maier <mail@dmnk.co>.
|
The port to afl++ is by Dominik Maier <mail@dmnk.co>.
|
||||||
|
|
||||||
The CompareCoverage and NeverZero counters features by Andrea Fioraldi <andreafioraldi@gmail.com>.
|
The CompareCoverage and NeverZero counters features are by Andrea Fioraldi <andreafioraldi@gmail.com>.
|
||||||
|
|
||||||
## 1) Introduction
|
## 1) Introduction
|
||||||
|
|
||||||
@ -16,13 +16,13 @@ with afl-gcc or used in QEMU mode, or with other extensions such as
|
|||||||
TriforceAFL.
|
TriforceAFL.
|
||||||
|
|
||||||
There is a significant performance penalty compared to native AFL,
|
There is a significant performance penalty compared to native AFL,
|
||||||
but at least we're able to use AFL on these binaries, right?
|
but at least we're able to use AFL++ on these binaries, right?
|
||||||
|
|
||||||
## 2) How to use
|
## 2) How to use
|
||||||
|
|
||||||
Requirements: you need an installed python environment.
|
Requirements: you need an installed python environment.
|
||||||
|
|
||||||
### Building AFL's Unicorn Mode
|
### Building AFL++'s Unicorn Mode
|
||||||
|
|
||||||
First, make afl++ as usual.
|
First, make afl++ as usual.
|
||||||
Once that completes successfully you need to build and add in the Unicorn Mode
|
Once that completes successfully you need to build and add in the Unicorn Mode
|
||||||
@ -35,7 +35,7 @@ NOTE: This script checks out a Unicorn Engine fork as submodule that has been te
|
|||||||
and is stable-ish, based on the unicorn engine master.
|
and is stable-ish, based on the unicorn engine master.
|
||||||
|
|
||||||
Building Unicorn will take a little bit (~5-10 minutes). Once it completes
|
Building Unicorn will take a little bit (~5-10 minutes). Once it completes
|
||||||
it automatically compiles a sample application and verify that it works.
|
it automatically compiles a sample application and verifies that it works.
|
||||||
|
|
||||||
### Fuzzing with Unicorn Mode
|
### Fuzzing with Unicorn Mode
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ The 'helper_scripts' directory also contains several helper scripts that allow y
|
|||||||
to dump context from a running process, load it, and hook heap allocations. For details
|
to dump context from a running process, load it, and hook heap allocations. For details
|
||||||
on how to use this check out the follow-up blog post to the one linked above.
|
on how to use this check out the follow-up blog post to the one linked above.
|
||||||
|
|
||||||
A example use of AFL-Unicorn mode is discussed in the Paper Unicorefuzz:
|
A example use of AFL-Unicorn mode is discussed in the paper Unicorefuzz:
|
||||||
https://www.usenix.org/conference/woot19/presentation/maier
|
https://www.usenix.org/conference/woot19/presentation/maier
|
||||||
|
|
||||||
## 3) Options
|
## 3) Options
|
||||||
@ -91,7 +91,7 @@ https://www.usenix.org/conference/woot19/presentation/maier
|
|||||||
As for the QEMU-based instrumentation, the afl-unicorn twist of afl++
|
As for the QEMU-based instrumentation, the afl-unicorn twist of afl++
|
||||||
comes with a sub-instruction based instrumentation similar in purpose to laf-intel.
|
comes with a sub-instruction based instrumentation similar in purpose to laf-intel.
|
||||||
|
|
||||||
The options that enables Unicorn CompareCoverage are the same used for QEMU.
|
The options that enable Unicorn CompareCoverage are the same used for QEMU.
|
||||||
AFL_COMPCOV_LEVEL=1 is to instrument comparisons with only immediate
|
AFL_COMPCOV_LEVEL=1 is to instrument comparisons with only immediate
|
||||||
values. QEMU_COMPCOV_LEVEL=2 instruments all
|
values. QEMU_COMPCOV_LEVEL=2 instruments all
|
||||||
comparison instructions. Comparison instructions are currently instrumented only
|
comparison instructions. Comparison instructions are currently instrumented only
|
||||||
|
Reference in New Issue
Block a user