You should handle the data received from AFL as a sequence of packets. This is AFL persistent mode example (comments are stripped):
int main(int argc, char** argv) {
char buf[100];
while (__AFL_LOOP(1000)) {
memset(buf, 0, 100);
read(0, buf, 100);
if (buf[0] == 'f') {
printf("one\n");
if (buf[1] == 'o') {
printf("two\n");
if (buf[2] == 'o') {
printf("three\n");
if (buf[3] == '!') {
printf("four\n");
abort();
}
}
}
}
}
return 0;
}
Modified example for your case would be:
//#define FIXED_PACKET_SIZE set to your packet size, assuming all packets have same size
//#define NUM_PACKETS_TO_RECEIVE set to number of packets you want to receive to get meaningfull output
int main(int argc, char** argv) {
char buf[FIXED_PACKET_SIZE*NUM_PACKETS_TO_RECEIVE];
while (__AFL_LOOP(1000)) {
memset(buf, 0, FIXED_PACKET_SIZE*NUM_PACKETS_TO_RECEIVE);
read(0, buf, FIXED_PACKET_SIZE*NUM_PACKETS_TO_RECEIVE);
unsigned curPacket = 0;
while (curPacket < NUM_PACKETS_TO_RECEIVE) {
if (buf[curPacket*FIXED_PACKET_SIZE] == 'f') {
printf("one\n");
if (buf[curPacket*FIXED_PACKET_SIZE+1] == 'o') {
printf("two\n");
if (buf[curPacket*FIXED_PACKET_SIZE+2] == 'o') {
printf("three\n");
if (buf[curPacket*FIXED_PACKET_SIZE+3] == '!') {
printf("four\n");
abort();
}
}
}
}
curPacket ++;
}
}
return 0;
}
AFL works bad for big input sizes - trying to modify all bits takes enormous time. When FIXED_PACKET_SIZE*NUM_PACKETS_TO_RECEIVE
is big, you should
try not to use fuzzed data for packet parts, that will unlikely result in errors.
Another problem can arise when AFL modifies your test data size - it can do so for some input mutations. Your read
call should handle these cases.