Skip to content

fix(AflppRedQueen): fix u64 I2S mutation and allow variable-length FnOperands#3741

Open
drewbarbs wants to merge 2 commits intoAFLplusplus:mainfrom
drewbarbs:fix-aflpprq
Open

fix(AflppRedQueen): fix u64 I2S mutation and allow variable-length FnOperands#3741
drewbarbs wants to merge 2 commits intoAFLplusplus:mainfrom
drewbarbs:fix-aflpprq

Conversation

@drewbarbs
Copy link

Description

These are a couple of small fixes to the Aflpp RedQueen implementation:

  • fix AflppRedQueen mutator's u64 I2S replacement

    When the RQ mutator sees that a 8 byte comparison operand is equal to 8 bytes from the input, then it treats that as an I2S correspondence and pushes a mutation that replaces those input bytes with a big-endian encoding of the second comparison operand, repl (this process is done on both the original/byte-swapped versions of the relevant values, to handle either byte order)

    This commit fixes a bit shifting bug (probably typo) that breaks the replacement by repeating one byte and dropping the most significant byte, which makes RQ unable to solve the comparison.

  • fix AflppCmpLogFnOperands::new to allow v0/v1 with different lengths

    AflppCmpLogFnOperands has fixed length ([u8; 32]) storage for v0 and v1, and separate v0_len/v1_len fields. However, the rust constructor/setters only allow for v0/v1 to be initialized from slices that are exactly 32 bytes long, since copy_from_slice panics otherwise. So v0_len/v1_len can only be 32. The instrumentation in libafl_targets' cmplog.{h,c} can create log entries where the v0_len/v1_len values are anywhere between 0 and 32, and this change allows us to do the same from rust.

    Note: in LibAFL's cmplog instrumentation, v0_len/v1_len are always the same value. In AFLplusplus' implementation, __cmplog_rtn_hook_str can create log entries with v0_len != v1_len, which this change also allows.

Checklist

  • I have run ./scripts/precommit.sh and addressed all comments

When the RQ mutator sees that a 8 byte comparison operand is equal to 8
bytes from the input, then it treats that as an I2S correspondence and
pushes a mutation that replaces those input bytes with a big-endian
encoding of the second comparison operand, `repl` (this process is done
on both the original/byte-swapped versions of the relevant values, to
handle either byte order)

This commit fixes a bit shifting bug (probably typo) that breaks the
replacement by repeating one byte and dropping the most significant
byte, which makes RQ unable to solve the comparison.
AflppCmpLogFnOperands has fixed length (`[u8; 32]`) storage for `v0` and
`v1`, and separate `v0_len`/`v1_len` fields. However, the rust
constructor/setters only allow for `v0`/`v1` to be initialized from
slices that are _exactly_ 32 bytes long, since `copy_from_slice` panics
otherwise. So `v0_len`/`v1_len` can only be 32. The instrumentation in
`libafl_targets`' `cmplog.{h,c}` can create log entries where the
`v0_len`/`v1_len` values are anywhere between 0 and 32, so this change
allows us to do the same from rust.

Note: in LibAFL's cmplog instrumentation, `v0_len`/`v1_len` are
always _the same_ value. In AFLplusplus' implementation,
`__cmplog_rtn_hook_str` can create log entries with `v0_len !=
v1_len`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant