Có 2 bước chính trong việc xây dựng, biến đổi các dữ liệu đầu vào của AFL:
- Mutation: AFL sẽ thực hiện các biến đổi trên cùng 1 test case với các vị trí khác nhau. các biến đổi này bao gồm:
- Đảo bit: thực hiện từ 1 cho tới 32 bits
- Tăng/giảm các số nguyên dạng 8, 16, 32 bits dưới dạng little/big endian
- Sử dụng các số đặc biệt: số 0, số nguyên có dấu/ không dấu lớn nhất/ nhỏ nhất với độ dài khác nhau (cả little/big endian)
- Sử dụng các byte đặc biệt được cung cấp bởi người dùng hoặc tự phát hiện
- Havoc:
- Sử dụng các biến đổi như mutation
- Ghi đè các byte bằng byte bất kì
- Xoá, lặp, gán giá trị cho mỗi byte trong các block nhiều byte
Nếu qua mutation và havoc AFL không phát hiện thêm test case nào thu được nhánh chương trình mới thì AFL sẽ lấy 2 test case, kết hợp với nhau ở vị trí bất kì rồi thực hiện lại từ đầu.
AFL cũng là fuzzer đầu tiên sử dụng “binned hitcounts” trong việc thống kê độ bao phủ của mã nguồn.
Các nhánh của chương trình được AFL lưu lại và thống kê theo số lần đã thực thi. AFL sẽ lưu trữ thông tin về nhánh – số lần thực thi và chia các nhánh đó vào trong các buckets theo số lần thực thi. Các buckets được chia theo: 1, 2, 4-7, 8-15, 16-31, 32-127, và 128 lần thực thi trở lên. Một test case được xem là thú vị nếu test case đó được đưa vào 1 bucket mới.
Tác giả của AFL khuyên rằng nên sử dụng test case ban đầu có độ lớn nhỏ bởi test case càng nhỏ thì thời gian thực thi cũng sẽ ngắn hơn. AFL cũng ưu tiên việc sử dụng các test case nhỏ. Khi một test case mới có độ dài ngắn hơn test case khác nhưng cũng cho ra cùng một kết quả thì test case cũ sẽ được loại bỏ, thay thế bằng test case mới.