editcap: add change offset.

This option skips some bytes when fuzzing, that prevents some headers from being changed. This focuses fuzzer to a smaller part of the packet.

Change-Id: I1db83235e93f2774a9991e3af70f633487b816fa
Reviewed-on: https://code.wireshark.org/review/9982
Petri-Dish: Anders Broman <a.broman58@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Dario Lombardo 2015-08-11 23:58:54 +02:00 committed by Anders Broman
parent 99e3244324
commit 0b7d1611d0
3 changed files with 32 additions and 5 deletions

View File

@ -15,6 +15,7 @@ S<[ B<-E> E<lt>error probabilityE<gt> ]>
S<[ B<-F> E<lt>file formatE<gt> ]>
S<[ B<-h> ]>
S<[ B<-i> E<lt>seconds per fileE<gt> ]>
S<[ B<-o> E<lt>change offsetE<gt> ]>
S<[ B<-L> ]>
S<[ B<-r> ]>
S<[ B<-s> E<lt>snaplenE<gt> ]>
@ -188,6 +189,13 @@ Adjust the original frame length accordingly when chopping and/or snapping
(in addition to the captured length, which is always adjusted regardless of
whether B<-L> is specified or not). See also B<-C <choplen>> and B<-s <snaplen>>.
=item -o E<lt>change offsetE<gt>
When used in conjuction with -E, skip some bytes from the beginning of the packet
from being changed. In this way some headers don't get changed, and the fuzzer is
more focused on a smaller part of the packet. Keeping a part of the packet fixed
the same dissector is triggered, that make the fuzzing more precise.
=item -r
Reverse the packet selection.

View File

@ -747,6 +747,9 @@ print_usage(FILE *output)
fprintf(output, " all packets to the timestamp of the first packet.\n");
fprintf(output, " -E <error probability> set the probability (between 0.0 and 1.0 incl.) that\n");
fprintf(output, " a particular packet byte will be randomly changed.\n");
fprintf(output, " -o <change offset> When used in conjuction with -E, skip some bytes from the\n");
fprintf(output, " beginning of the packet. This allows to preserve some\n");
fprintf(output, " bytes, in order to have some headers untouched.\n");
fprintf(output, "\n");
fprintf(output, "Output File(s):\n");
fprintf(output, " -c <packets per file> split the packet output to different files based on\n");
@ -921,6 +924,7 @@ DIAG_ON(cast-qual)
nstime_t block_start;
gchar *fprefix = NULL;
gchar *fsuffix = NULL;
guint32 change_offset = 0;
const struct wtap_pkthdr *phdr;
struct wtap_pkthdr temp_phdr;
@ -978,7 +982,7 @@ DIAG_ON(cast-qual)
#endif
/* Process the options */
while ((opt = getopt_long(argc, argv, "a:A:B:c:C:dD:E:F:hi:I:Lrs:S:t:T:vVw:", long_options, NULL)) != -1) {
while ((opt = getopt_long(argc, argv, "a:A:B:c:C:dD:E:F:hi:I:Lo:rs:S:t:T:vVw:", long_options, NULL)) != -1) {
switch (opt) {
case 'a':
{
@ -1159,6 +1163,10 @@ DIAG_ON(cast-qual)
adjlen = TRUE;
break;
case 'o':
change_offset = (guint32)strtol(optarg, &p, 10);
break;
case 'r':
keep_em = !keep_em; /* Just invert */
break;
@ -1608,14 +1616,21 @@ DIAG_ON(cast-qual)
}
} /* suppress duplicates by time window */
if (change_offset > phdr->caplen) {
fprintf(stderr, "change offset %u is longer than caplen %u in packet %u\n",
change_offset, phdr->caplen, count);
}
/* Random error mutation */
if (err_prob > 0.0) {
if (err_prob > 0.0 && change_offset <= phdr->caplen) {
int real_data_start = 0;
/* Protect non-protocol data */
if (wtap_file_type_subtype(wth) == WTAP_FILE_TYPE_SUBTYPE_CATAPULT_DCT2000)
real_data_start = find_dct2000_real_data(buf);
real_data_start += change_offset;
for (i = real_data_start; i < (int) phdr->caplen; i++) {
if (rand() <= err_prob * RAND_MAX) {
err_type = rand() / (RAND_MAX / ERR_WT_TOTAL + 1);

View File

@ -48,13 +48,16 @@ VALGRIND=0
# Run under AddressSanitizer ?
ASAN=0
# Don't skip any byte from being changed
CHANGE_OFFSET=0
# The maximum permitted amount of memory leaked. Eventually this should be
# worked down to zero, but right now that would fail on every single capture.
# Only has effect when running under valgrind.
MAX_LEAK=`expr 1024 \* 100`
# To do: add options for file names and limits
while getopts "2b:C:d:e:agp:P:" OPTCHAR ; do
while getopts "2b:C:d:e:agp:P:o:" OPTCHAR ; do
case $OPTCHAR in
a) ASAN=1 ;;
2) TWO_PASS="-2 " ;;
@ -65,6 +68,7 @@ while getopts "2b:C:d:e:agp:P:" OPTCHAR ; do
g) VALGRIND=1 ;;
p) MAX_PASSES=$OPTARG ;;
P) MIN_PLUGINS=$OPTARG ;;
o) CHANGE_OFFSET=$OPTARG ;;
esac
done
shift $(($OPTIND - 1))
@ -176,9 +180,9 @@ while [ \( $PASS -lt $MAX_PASSES -o $MAX_PASSES -lt 1 \) -a $DONE -ne 1 ] ; do
DISSECTOR_BUG=0
VG_ERR_CNT=0
"$EDITCAP" -E $ERR_PROB "$CF" $TMP_DIR/$TMP_FILE > /dev/null 2>&1
"$EDITCAP" -E $ERR_PROB -o $CHANGE_OFFSET "$CF" $TMP_DIR/$TMP_FILE > /dev/null 2>&1
if [ $? -ne 0 ] ; then
"$EDITCAP" -E $ERR_PROB -T ether "$CF" $TMP_DIR/$TMP_FILE \
"$EDITCAP" -E $ERR_PROB -o $CHANGE_OFFSET -T ether "$CF" $TMP_DIR/$TMP_FILE \
> /dev/null 2>&1
if [ $? -ne 0 ] ; then
echo "Invalid format for editcap"