mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-12 10:08:07 +00:00
Merge branch 'dev' of https://github.com/vanhauser-thc/AFLplusplus into dev
This commit is contained in:
@ -29,16 +29,15 @@ typedef struct my_mutator {
|
|||||||
afl_t *afl;
|
afl_t *afl;
|
||||||
|
|
||||||
// any additional data here!
|
// any additional data here!
|
||||||
uint8_t *trim_buf;
|
size_t trim_size_current;
|
||||||
size_t trim_buf_size;
|
int trimmming_steps;
|
||||||
int trimmming_steps;
|
int cur_step;
|
||||||
int cur_step;
|
|
||||||
|
|
||||||
// Reused buffers:
|
// Reused buffers:
|
||||||
BUF_VAR(u8, fuzz);
|
BUF_VAR(u8, fuzz);
|
||||||
BUF_VAR(u8, data);
|
BUF_VAR(u8, data);
|
||||||
BUF_VAR(u8, havoc);
|
BUF_VAR(u8, havoc);
|
||||||
BUF_VAR(u8, trim_out);
|
BUF_VAR(u8, trim);
|
||||||
BUF_VAR(u8, pre_save);
|
BUF_VAR(u8, pre_save);
|
||||||
|
|
||||||
} my_mutator_t;
|
} my_mutator_t;
|
||||||
@ -52,7 +51,7 @@ typedef struct my_mutator {
|
|||||||
* in the same way.
|
* in the same way.
|
||||||
* @return Pointer to the data object this custom mutator instance should use.
|
* @return Pointer to the data object this custom mutator instance should use.
|
||||||
* There may be multiple instances of this mutator in one afl-fuzz run!
|
* There may be multiple instances of this mutator in one afl-fuzz run!
|
||||||
* Returns NULL on error.
|
* Return NULL on error.
|
||||||
*/
|
*/
|
||||||
my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) {
|
my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) {
|
||||||
|
|
||||||
@ -80,11 +79,13 @@ my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) {
|
|||||||
* @param[in] data pointer returned in afl_custom_init for this fuzz case
|
* @param[in] data pointer returned in afl_custom_init for this fuzz case
|
||||||
* @param[in] buf Pointer to input data to be mutated
|
* @param[in] buf Pointer to input data to be mutated
|
||||||
* @param[in] buf_size Size of input data
|
* @param[in] buf_size Size of input data
|
||||||
|
* @param[out] out_buf the buffer we will work on. we can reuse *buf. NULL on
|
||||||
|
* error.
|
||||||
* @param[in] add_buf Buffer containing the additional test case
|
* @param[in] add_buf Buffer containing the additional test case
|
||||||
* @param[in] add_buf_size Size of the additional test case
|
* @param[in] add_buf_size Size of the additional test case
|
||||||
* @param[in] max_size Maximum size of the mutated output. The mutation must not
|
* @param[in] max_size Maximum size of the mutated output. The mutation must not
|
||||||
* produce data larger than max_size.
|
* produce data larger than max_size.
|
||||||
* @return Size of the mutated output. Negative return will abort fuzzing.
|
* @return Size of the mutated output.
|
||||||
*/
|
*/
|
||||||
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||||
u8 **out_buf, uint8_t *add_buf,
|
u8 **out_buf, uint8_t *add_buf,
|
||||||
@ -100,7 +101,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
|||||||
if (!mutated_out) {
|
if (!mutated_out) {
|
||||||
|
|
||||||
perror("custom mutator allocation (maybe_grow)");
|
perror("custom mutator allocation (maybe_grow)");
|
||||||
return -1; /* afl-fuzz will very likely error out after this. */
|
return 0; /* afl-fuzz will very likely error out after this. */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +136,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
|||||||
* processing. External library should allocate memory for out_buf.
|
* processing. External library should allocate memory for out_buf.
|
||||||
* The buf pointer may be reused (up to the given buf_size);
|
* The buf pointer may be reused (up to the given buf_size);
|
||||||
* @return Size of the output buffer after processing or the needed amount.
|
* @return Size of the output buffer after processing or the needed amount.
|
||||||
* A return smaller 1 indicates an error.
|
* A return of 0 indicates an error.
|
||||||
*/
|
*/
|
||||||
size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||||
uint8_t **out_buf) {
|
uint8_t **out_buf) {
|
||||||
@ -146,7 +147,8 @@ size_t afl_custom_pre_save(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
|||||||
if (!data->pre_save_buf) {
|
if (!data->pre_save_buf) {
|
||||||
|
|
||||||
perror("custom mutator realloc failed.");
|
perror("custom mutator realloc failed.");
|
||||||
return -1;
|
*out_buf = NULL;
|
||||||
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,8 +197,11 @@ int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) {
|
|||||||
data->trimmming_steps = 1;
|
data->trimmming_steps = 1;
|
||||||
|
|
||||||
data->cur_step = 0;
|
data->cur_step = 0;
|
||||||
data->trim_buf = buf;
|
|
||||||
data->trim_buf_size = buf_size;
|
maybe_grow(BUF_PARAMS(data, trim), buf_size);
|
||||||
|
memcpy(data->trim_buf, buf, buf_size);
|
||||||
|
|
||||||
|
data->trim_size_current = buf_size;
|
||||||
|
|
||||||
return data->trimmming_steps;
|
return data->trimmming_steps;
|
||||||
|
|
||||||
@ -218,15 +223,15 @@ int afl_custom_init_trim(my_mutator_t *data, uint8_t *buf, size_t buf_size) {
|
|||||||
* External library should allocate memory for out_buf.
|
* External library should allocate memory for out_buf.
|
||||||
* AFL++ will not release the memory after saving the test case.
|
* AFL++ will not release the memory after saving the test case.
|
||||||
* Keep a ref in *data.
|
* Keep a ref in *data.
|
||||||
|
* *out_buf = NULL is treated as error.
|
||||||
* @return Pointer to the size of the trimmed test case
|
* @return Pointer to the size of the trimmed test case
|
||||||
*/
|
*/
|
||||||
size_t afl_custom_trim(my_mutator_t *data, uint8_t **out_buf) {
|
size_t afl_custom_trim(my_mutator_t *data, uint8_t **out_buf) {
|
||||||
|
|
||||||
size_t ret = data->trim_buf_size - 1;
|
*out_buf = data->trim_buf;
|
||||||
|
|
||||||
*out_buf = maybe_grow(BUF_PARAMS(data, trim_out), ret);
|
|
||||||
// Remove the last byte of the trimming input
|
// Remove the last byte of the trimming input
|
||||||
memcpy(*out_buf, data->trim_buf, ret);
|
return data->trim_size_current - 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +271,7 @@ int afl_custom_post_trim(my_mutator_t *data, int success) {
|
|||||||
* output
|
* output
|
||||||
* @param[in] buf_size Size of input data
|
* @param[in] buf_size Size of input data
|
||||||
* @param[out] out_buf The output buffer. buf can be reused, if the content
|
* @param[out] out_buf The output buffer. buf can be reused, if the content
|
||||||
* fits.
|
* fits. *out_buf = NULL is treated as error.
|
||||||
* @param[in] max_size Maximum size of the mutated output. The mutation must
|
* @param[in] max_size Maximum size of the mutated output. The mutation must
|
||||||
* not produce data larger than max_size.
|
* not produce data larger than max_size.
|
||||||
* @return Size of the mutated output.
|
* @return Size of the mutated output.
|
||||||
@ -277,6 +282,13 @@ size_t afl_custom_havoc_mutation(my_mutator_t *data, u8 *buf, size_t buf_size,
|
|||||||
if (buf_size == 0) {
|
if (buf_size == 0) {
|
||||||
|
|
||||||
*out_buf = maybe_grow(BUF_PARAMS(data, havoc), 1);
|
*out_buf = maybe_grow(BUF_PARAMS(data, havoc), 1);
|
||||||
|
if (!*out_buf) {
|
||||||
|
|
||||||
|
perror("custom havoc: maybe_grow");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
**out_buf = rand() % 256;
|
**out_buf = rand() % 256;
|
||||||
buf_size = 1;
|
buf_size = 1;
|
||||||
|
|
||||||
@ -354,7 +366,7 @@ void afl_custom_deinit(my_mutator_t *data) {
|
|||||||
free(data->havoc_buf);
|
free(data->havoc_buf);
|
||||||
free(data->data_buf);
|
free(data->data_buf);
|
||||||
free(data->fuzz_buf);
|
free(data->fuzz_buf);
|
||||||
free(data->trim_out_buf);
|
free(data->trim_buf);
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -649,14 +649,16 @@ struct custom_mutator {
|
|||||||
* (Optional for now. Required in the future)
|
* (Optional for now. Required in the future)
|
||||||
*
|
*
|
||||||
* @param data pointer returned in afl_custom_init for this fuzz case
|
* @param data pointer returned in afl_custom_init for this fuzz case
|
||||||
* @param[inout] buf Pointer to the input data to be mutated and the mutated
|
* @param[in] buf Pointer to the input data to be mutated and the mutated
|
||||||
* output
|
* output
|
||||||
* @param[in] buf_size Size of the input/output data
|
* @param[in] buf_size Size of the input/output data
|
||||||
|
* @param[out] out_buf the new buffer. We may reuse *buf if large enough.
|
||||||
|
* *out_buf = NULL is treated as FATAL.
|
||||||
* @param[in] add_buf Buffer containing the additional test case
|
* @param[in] add_buf Buffer containing the additional test case
|
||||||
* @param[in] add_buf_size Size of the additional test case
|
* @param[in] add_buf_size Size of the additional test case
|
||||||
* @param[in] max_size Maximum size of the mutated output. The mutation must
|
* @param[in] max_size Maximum size of the mutated output. The mutation must
|
||||||
* not produce data larger than max_size.
|
* not produce data larger than max_size.
|
||||||
* @return Size of the mutated output. Negative on error will abort exeuction.
|
* @return Size of the mutated output.
|
||||||
*/
|
*/
|
||||||
size_t (*afl_custom_fuzz)(void *data, u8 *buf, size_t buf_size, u8 **out_buf,
|
size_t (*afl_custom_fuzz)(void *data, u8 *buf, size_t buf_size, u8 **out_buf,
|
||||||
u8 *add_buf, size_t add_buf_size, size_t max_size);
|
u8 *add_buf, size_t add_buf_size, size_t max_size);
|
||||||
|
@ -229,7 +229,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
|
|
||||||
size_t retlen = afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf);
|
size_t retlen = afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf);
|
||||||
|
|
||||||
if (unlikely(retlen < 0 || !retbuf))
|
if (unlikely(!retbuf))
|
||||||
FATAL("custom_trim failed (ret %zd)", retlen);
|
FATAL("custom_trim failed (ret %zd)", retlen);
|
||||||
else if (unlikely(retlen > orig_len))
|
else if (unlikely(retlen > orig_len))
|
||||||
FATAL(
|
FATAL(
|
||||||
|
@ -1618,8 +1618,8 @@ custom_mutator_stage:
|
|||||||
afl->mutator->data, out_buf, len, &mutated_buf, new_buf, target->len,
|
afl->mutator->data, out_buf, len, &mutated_buf, new_buf, target->len,
|
||||||
max_seed_size);
|
max_seed_size);
|
||||||
|
|
||||||
if (unlikely(mutated_size < 0))
|
if (unlikely(!mutated_buf))
|
||||||
FATAL("custom_fuzz returned %zd", mutated_size);
|
FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size);
|
||||||
|
|
||||||
if (mutated_size > len) afl->out_size = mutated_size;
|
if (mutated_size > len) afl->out_size = mutated_size;
|
||||||
|
|
||||||
@ -1734,7 +1734,7 @@ havoc_stage:
|
|||||||
u8 * custom_havoc_buf = NULL;
|
u8 * custom_havoc_buf = NULL;
|
||||||
size_t new_len = afl->mutator->afl_custom_havoc_mutation(
|
size_t new_len = afl->mutator->afl_custom_havoc_mutation(
|
||||||
afl->mutator->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE);
|
afl->mutator->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE);
|
||||||
if (unlikely(new_len < 0))
|
if (unlikely(!custom_havoc_buf))
|
||||||
FATAL("Error in custom_havoc (return %zd)", new_len);
|
FATAL("Error in custom_havoc (return %zd)", new_len);
|
||||||
if (likely(new_len > 0 && custom_havoc_buf)) {
|
if (likely(new_len > 0 && custom_havoc_buf)) {
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
FATAL("Call failed");
|
FATAL("python custom fuzz: call failed");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
|
|||||||
size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem,
|
size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem,
|
||||||
len, &new_buf);
|
len, &new_buf);
|
||||||
|
|
||||||
if (unlikely(new_size <= 0 || !new_buf))
|
if (unlikely(!new_buf))
|
||||||
FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size);
|
FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size);
|
||||||
|
|
||||||
/* everything as planned. use the new data. */
|
/* everything as planned. use the new data. */
|
||||||
|
Reference in New Issue
Block a user