Home | History | Annotate | Download | only in honggfuzz
      1 /*
      2  *
      3  * honggfuzz - run->dynamicFilefer mangling routines
      4  * -----------------------------------------
      5  *
      6  * Author:
      7  * Robert Swiecki <swiecki (at) google.com>
      8  *
      9  * Copyright 2010-2015 by Google Inc. All Rights Reserved.
     10  *
     11  * Licensed under the Apache License, Version 2.0 (the "License"); you may
     12  * not use this file except in compliance with the License. You may obtain
     13  * a copy of the License at
     14  *
     15  * http://www.apache.org/licenses/LICENSE-2.0
     16  *
     17  * Unless required by applicable law or agreed to in writing, software
     18  * distributed under the License is distributed on an "AS IS" BASIS,
     19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
     20  * implied. See the License for the specific language governing
     21  * permissions and limitations under the License.
     22  *
     23  */
     24 
     25 #include "mangle.h"
     26 
     27 #include <inttypes.h>
     28 #include <math.h>
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <string.h>
     32 #include <sys/mman.h>
     33 #include <unistd.h>
     34 
     35 #include "libcommon/common.h"
     36 #include "libcommon/log.h"
     37 #include "libcommon/util.h"
     38 
     39 static inline void mangle_Overwrite(run_t* run, const uint8_t* src, size_t off, size_t sz) {
     40     size_t maxToCopy = run->dynamicFileSz - off;
     41     if (sz > maxToCopy) {
     42         sz = maxToCopy;
     43     }
     44 
     45     memmove(&run->dynamicFile[off], src, sz);
     46 }
     47 
     48 static inline void mangle_Move(run_t* run, size_t off_from, size_t off_to, size_t len) {
     49     if (off_from >= run->dynamicFileSz) {
     50         return;
     51     }
     52     if (off_to >= run->dynamicFileSz) {
     53         return;
     54     }
     55 
     56     ssize_t len_from = (ssize_t)run->dynamicFileSz - off_from - 1;
     57     ssize_t len_to = (ssize_t)run->dynamicFileSz - off_to - 1;
     58 
     59     if ((ssize_t)len > len_from) {
     60         len = len_from;
     61     }
     62     if ((ssize_t)len > len_to) {
     63         len = len_to;
     64     }
     65 
     66     memmove(&run->dynamicFile[off_to], &run->dynamicFile[off_from], len);
     67 }
     68 
     69 static void mangle_Inflate(run_t* run, size_t off, size_t len) {
     70     if (run->dynamicFileSz >= run->global->maxFileSz) {
     71         return;
     72     }
     73     if (len > (run->global->maxFileSz - run->dynamicFileSz)) {
     74         len = run->global->maxFileSz - run->dynamicFileSz;
     75     }
     76 
     77     run->dynamicFileSz += len;
     78     mangle_Move(run, off, off + len, run->dynamicFileSz);
     79 }
     80 
     81 static void mangle_MemMove(run_t* run) {
     82     size_t off_from = util_rndGet(0, run->dynamicFileSz - 1);
     83     size_t off_to = util_rndGet(0, run->dynamicFileSz - 1);
     84     size_t len = util_rndGet(0, run->dynamicFileSz);
     85 
     86     mangle_Move(run, off_from, off_to, len);
     87 }
     88 
     89 static void mangle_Byte(run_t* run) {
     90     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
     91     run->dynamicFile[off] = (uint8_t)util_rnd64();
     92 }
     93 
     94 static void mangle_Bytes(run_t* run) {
     95     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
     96     uint32_t val = (uint32_t)util_rnd64();
     97 
     98     /* Overwrite with random 2,3,4-byte values */
     99     size_t toCopy = util_rndGet(2, 4);
    100     mangle_Overwrite(run, (uint8_t*)&val, off, toCopy);
    101 }
    102 
    103 static void mangle_Bit(run_t* run) {
    104     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    105     run->dynamicFile[off] ^= (uint8_t)(1U << util_rndGet(0, 7));
    106 }
    107 
    108 static void mangle_DictionaryInsert(run_t* run) {
    109     if (run->global->dictionaryCnt == 0) {
    110         mangle_Bit(run);
    111         return;
    112     }
    113 
    114     uint64_t choice = util_rndGet(0, run->global->dictionaryCnt - 1);
    115     struct strings_t* str = TAILQ_FIRST(&run->global->dictq);
    116     for (uint64_t i = 0; i < choice; i++) {
    117         str = TAILQ_NEXT(str, pointers);
    118     }
    119 
    120     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    121     mangle_Inflate(run, off, str->len);
    122     mangle_Move(run, off, off + str->len, str->len);
    123     mangle_Overwrite(run, (uint8_t*)str->s, off, str->len);
    124 }
    125 
    126 static void mangle_Dictionary(run_t* run) {
    127     if (run->global->dictionaryCnt == 0) {
    128         mangle_Bit(run);
    129         return;
    130     }
    131 
    132     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    133 
    134     uint64_t choice = util_rndGet(0, run->global->dictionaryCnt - 1);
    135     struct strings_t* str = TAILQ_FIRST(&run->global->dictq);
    136     for (uint64_t i = 0; i < choice; i++) {
    137         str = TAILQ_NEXT(str, pointers);
    138     }
    139 
    140     mangle_Overwrite(run, (uint8_t*)str->s, off, str->len);
    141 }
    142 
    143 static void mangle_Magic(run_t* run) {
    144     static const struct {
    145         const uint8_t val[8];
    146         const size_t size;
    147     } mangleMagicVals[] = {
    148         /* 1B - No endianness */
    149         {"\x00\x00\x00\x00\x00\x00\x00\x00", 1},
    150         {"\x01\x00\x00\x00\x00\x00\x00\x00", 1},
    151         {"\x02\x00\x00\x00\x00\x00\x00\x00", 1},
    152         {"\x03\x00\x00\x00\x00\x00\x00\x00", 1},
    153         {"\x04\x00\x00\x00\x00\x00\x00\x00", 1},
    154         {"\x05\x00\x00\x00\x00\x00\x00\x00", 1},
    155         {"\x06\x00\x00\x00\x00\x00\x00\x00", 1},
    156         {"\x07\x00\x00\x00\x00\x00\x00\x00", 1},
    157         {"\x08\x00\x00\x00\x00\x00\x00\x00", 1},
    158         {"\x09\x00\x00\x00\x00\x00\x00\x00", 1},
    159         {"\x0A\x00\x00\x00\x00\x00\x00\x00", 1},
    160         {"\x0B\x00\x00\x00\x00\x00\x00\x00", 1},
    161         {"\x0C\x00\x00\x00\x00\x00\x00\x00", 1},
    162         {"\x0D\x00\x00\x00\x00\x00\x00\x00", 1},
    163         {"\x0E\x00\x00\x00\x00\x00\x00\x00", 1},
    164         {"\x0F\x00\x00\x00\x00\x00\x00\x00", 1},
    165         {"\x10\x00\x00\x00\x00\x00\x00\x00", 1},
    166         {"\x20\x00\x00\x00\x00\x00\x00\x00", 1},
    167         {"\x40\x00\x00\x00\x00\x00\x00\x00", 1},
    168         {"\x7E\x00\x00\x00\x00\x00\x00\x00", 1},
    169         {"\x7F\x00\x00\x00\x00\x00\x00\x00", 1},
    170         {"\x80\x00\x00\x00\x00\x00\x00\x00", 1},
    171         {"\x81\x00\x00\x00\x00\x00\x00\x00", 1},
    172         {"\xC0\x00\x00\x00\x00\x00\x00\x00", 1},
    173         {"\xFE\x00\x00\x00\x00\x00\x00\x00", 1},
    174         {"\xFF\x00\x00\x00\x00\x00\x00\x00", 1},
    175         /* 2B - NE */
    176         {"\x00\x00\x00\x00\x00\x00\x00\x00", 2},
    177         {"\x01\x01\x00\x00\x00\x00\x00\x00", 2},
    178         {"\x80\x80\x00\x00\x00\x00\x00\x00", 2},
    179         {"\xFF\xFF\x00\x00\x00\x00\x00\x00", 2},
    180         /* 2B - BE */
    181         {"\x00\x01\x00\x00\x00\x00\x00\x00", 2},
    182         {"\x00\x02\x00\x00\x00\x00\x00\x00", 2},
    183         {"\x00\x03\x00\x00\x00\x00\x00\x00", 2},
    184         {"\x00\x04\x00\x00\x00\x00\x00\x00", 2},
    185         {"\x00\x05\x00\x00\x00\x00\x00\x00", 2},
    186         {"\x00\x06\x00\x00\x00\x00\x00\x00", 2},
    187         {"\x00\x07\x00\x00\x00\x00\x00\x00", 2},
    188         {"\x00\x08\x00\x00\x00\x00\x00\x00", 2},
    189         {"\x00\x09\x00\x00\x00\x00\x00\x00", 2},
    190         {"\x00\x0A\x00\x00\x00\x00\x00\x00", 2},
    191         {"\x00\x0B\x00\x00\x00\x00\x00\x00", 2},
    192         {"\x00\x0C\x00\x00\x00\x00\x00\x00", 2},
    193         {"\x00\x0D\x00\x00\x00\x00\x00\x00", 2},
    194         {"\x00\x0E\x00\x00\x00\x00\x00\x00", 2},
    195         {"\x00\x0F\x00\x00\x00\x00\x00\x00", 2},
    196         {"\x00\x10\x00\x00\x00\x00\x00\x00", 2},
    197         {"\x00\x20\x00\x00\x00\x00\x00\x00", 2},
    198         {"\x00\x40\x00\x00\x00\x00\x00\x00", 2},
    199         {"\x00\x7E\x00\x00\x00\x00\x00\x00", 2},
    200         {"\x00\x7F\x00\x00\x00\x00\x00\x00", 2},
    201         {"\x00\x80\x00\x00\x00\x00\x00\x00", 2},
    202         {"\x00\x81\x00\x00\x00\x00\x00\x00", 2},
    203         {"\x00\xC0\x00\x00\x00\x00\x00\x00", 2},
    204         {"\x00\xFE\x00\x00\x00\x00\x00\x00", 2},
    205         {"\x00\xFF\x00\x00\x00\x00\x00\x00", 2},
    206         {"\x7E\xFF\x00\x00\x00\x00\x00\x00", 2},
    207         {"\x7F\xFF\x00\x00\x00\x00\x00\x00", 2},
    208         {"\x80\x00\x00\x00\x00\x00\x00\x00", 2},
    209         {"\x80\x01\x00\x00\x00\x00\x00\x00", 2},
    210         {"\xFF\xFE\x00\x00\x00\x00\x00\x00", 2},
    211         /* 2B - LE */
    212         {"\x00\x00\x00\x00\x00\x00\x00\x00", 2},
    213         {"\x01\x00\x00\x00\x00\x00\x00\x00", 2},
    214         {"\x02\x00\x00\x00\x00\x00\x00\x00", 2},
    215         {"\x03\x00\x00\x00\x00\x00\x00\x00", 2},
    216         {"\x04\x00\x00\x00\x00\x00\x00\x00", 2},
    217         {"\x05\x00\x00\x00\x00\x00\x00\x00", 2},
    218         {"\x06\x00\x00\x00\x00\x00\x00\x00", 2},
    219         {"\x07\x00\x00\x00\x00\x00\x00\x00", 2},
    220         {"\x08\x00\x00\x00\x00\x00\x00\x00", 2},
    221         {"\x09\x00\x00\x00\x00\x00\x00\x00", 2},
    222         {"\x0A\x00\x00\x00\x00\x00\x00\x00", 2},
    223         {"\x0B\x00\x00\x00\x00\x00\x00\x00", 2},
    224         {"\x0C\x00\x00\x00\x00\x00\x00\x00", 2},
    225         {"\x0D\x00\x00\x00\x00\x00\x00\x00", 2},
    226         {"\x0E\x00\x00\x00\x00\x00\x00\x00", 2},
    227         {"\x0F\x00\x00\x00\x00\x00\x00\x00", 2},
    228         {"\x10\x00\x00\x00\x00\x00\x00\x00", 2},
    229         {"\x20\x00\x00\x00\x00\x00\x00\x00", 2},
    230         {"\x40\x00\x00\x00\x00\x00\x00\x00", 2},
    231         {"\x7E\x00\x00\x00\x00\x00\x00\x00", 2},
    232         {"\x7F\x00\x00\x00\x00\x00\x00\x00", 2},
    233         {"\x80\x00\x00\x00\x00\x00\x00\x00", 2},
    234         {"\x81\x00\x00\x00\x00\x00\x00\x00", 2},
    235         {"\xC0\x00\x00\x00\x00\x00\x00\x00", 2},
    236         {"\xFE\x00\x00\x00\x00\x00\x00\x00", 2},
    237         {"\xFF\x00\x00\x00\x00\x00\x00\x00", 2},
    238         {"\xFF\x7E\x00\x00\x00\x00\x00\x00", 2},
    239         {"\xFF\x7F\x00\x00\x00\x00\x00\x00", 2},
    240         {"\x00\x80\x00\x00\x00\x00\x00\x00", 2},
    241         {"\x01\x80\x00\x00\x00\x00\x00\x00", 2},
    242         {"\xFE\xFF\x00\x00\x00\x00\x00\x00", 2},
    243         /* 4B - NE */
    244         {"\x00\x00\x00\x00\x00\x00\x00\x00", 4},
    245         {"\x01\x01\x01\x01\x00\x00\x00\x00", 4},
    246         {"\x80\x80\x80\x80\x00\x00\x00\x00", 4},
    247         {"\xFF\xFF\xFF\xFF\x00\x00\x00\x00", 4},
    248         /* 4B - BE */
    249         {"\x00\x00\x00\x01\x00\x00\x00\x00", 4},
    250         {"\x00\x00\x00\x02\x00\x00\x00\x00", 4},
    251         {"\x00\x00\x00\x03\x00\x00\x00\x00", 4},
    252         {"\x00\x00\x00\x04\x00\x00\x00\x00", 4},
    253         {"\x00\x00\x00\x05\x00\x00\x00\x00", 4},
    254         {"\x00\x00\x00\x06\x00\x00\x00\x00", 4},
    255         {"\x00\x00\x00\x07\x00\x00\x00\x00", 4},
    256         {"\x00\x00\x00\x08\x00\x00\x00\x00", 4},
    257         {"\x00\x00\x00\x09\x00\x00\x00\x00", 4},
    258         {"\x00\x00\x00\x0A\x00\x00\x00\x00", 4},
    259         {"\x00\x00\x00\x0B\x00\x00\x00\x00", 4},
    260         {"\x00\x00\x00\x0C\x00\x00\x00\x00", 4},
    261         {"\x00\x00\x00\x0D\x00\x00\x00\x00", 4},
    262         {"\x00\x00\x00\x0E\x00\x00\x00\x00", 4},
    263         {"\x00\x00\x00\x0F\x00\x00\x00\x00", 4},
    264         {"\x00\x00\x00\x10\x00\x00\x00\x00", 4},
    265         {"\x00\x00\x00\x20\x00\x00\x00\x00", 4},
    266         {"\x00\x00\x00\x40\x00\x00\x00\x00", 4},
    267         {"\x00\x00\x00\x7E\x00\x00\x00\x00", 4},
    268         {"\x00\x00\x00\x7F\x00\x00\x00\x00", 4},
    269         {"\x00\x00\x00\x80\x00\x00\x00\x00", 4},
    270         {"\x00\x00\x00\x81\x00\x00\x00\x00", 4},
    271         {"\x00\x00\x00\xC0\x00\x00\x00\x00", 4},
    272         {"\x00\x00\x00\xFE\x00\x00\x00\x00", 4},
    273         {"\x00\x00\x00\xFF\x00\x00\x00\x00", 4},
    274         {"\x7E\xFF\xFF\xFF\x00\x00\x00\x00", 4},
    275         {"\x7F\xFF\xFF\xFF\x00\x00\x00\x00", 4},
    276         {"\x80\x00\x00\x00\x00\x00\x00\x00", 4},
    277         {"\x80\x00\x00\x01\x00\x00\x00\x00", 4},
    278         {"\xFF\xFF\xFF\xFE\x00\x00\x00\x00", 4},
    279         /* 4B - LE */
    280         {"\x00\x00\x00\x00\x00\x00\x00\x00", 4},
    281         {"\x01\x00\x00\x00\x00\x00\x00\x00", 4},
    282         {"\x02\x00\x00\x00\x00\x00\x00\x00", 4},
    283         {"\x03\x00\x00\x00\x00\x00\x00\x00", 4},
    284         {"\x04\x00\x00\x00\x00\x00\x00\x00", 4},
    285         {"\x05\x00\x00\x00\x00\x00\x00\x00", 4},
    286         {"\x06\x00\x00\x00\x00\x00\x00\x00", 4},
    287         {"\x07\x00\x00\x00\x00\x00\x00\x00", 4},
    288         {"\x08\x00\x00\x00\x00\x00\x00\x00", 4},
    289         {"\x09\x00\x00\x00\x00\x00\x00\x00", 4},
    290         {"\x0A\x00\x00\x00\x00\x00\x00\x00", 4},
    291         {"\x0B\x00\x00\x00\x00\x00\x00\x00", 4},
    292         {"\x0C\x00\x00\x00\x00\x00\x00\x00", 4},
    293         {"\x0D\x00\x00\x00\x00\x00\x00\x00", 4},
    294         {"\x0E\x00\x00\x00\x00\x00\x00\x00", 4},
    295         {"\x0F\x00\x00\x00\x00\x00\x00\x00", 4},
    296         {"\x10\x00\x00\x00\x00\x00\x00\x00", 4},
    297         {"\x20\x00\x00\x00\x00\x00\x00\x00", 4},
    298         {"\x40\x00\x00\x00\x00\x00\x00\x00", 4},
    299         {"\x7E\x00\x00\x00\x00\x00\x00\x00", 4},
    300         {"\x7F\x00\x00\x00\x00\x00\x00\x00", 4},
    301         {"\x80\x00\x00\x00\x00\x00\x00\x00", 4},
    302         {"\x81\x00\x00\x00\x00\x00\x00\x00", 4},
    303         {"\xC0\x00\x00\x00\x00\x00\x00\x00", 4},
    304         {"\xFE\x00\x00\x00\x00\x00\x00\x00", 4},
    305         {"\xFF\x00\x00\x00\x00\x00\x00\x00", 4},
    306         {"\xFF\xFF\xFF\x7E\x00\x00\x00\x00", 4},
    307         {"\xFF\xFF\xFF\x7F\x00\x00\x00\x00", 4},
    308         {"\x00\x00\x00\x80\x00\x00\x00\x00", 4},
    309         {"\x01\x00\x00\x80\x00\x00\x00\x00", 4},
    310         {"\xFE\xFF\xFF\xFF\x00\x00\x00\x00", 4},
    311         /* 8B - NE */
    312         {"\x00\x00\x00\x00\x00\x00\x00\x00", 8},
    313         {"\x01\x01\x01\x01\x01\x01\x01\x01", 8},
    314         {"\x80\x80\x80\x80\x80\x80\x80\x80", 8},
    315         {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
    316         /* 8B - BE */
    317         {"\x00\x00\x00\x00\x00\x00\x00\x01", 8},
    318         {"\x00\x00\x00\x00\x00\x00\x00\x02", 8},
    319         {"\x00\x00\x00\x00\x00\x00\x00\x03", 8},
    320         {"\x00\x00\x00\x00\x00\x00\x00\x04", 8},
    321         {"\x00\x00\x00\x00\x00\x00\x00\x05", 8},
    322         {"\x00\x00\x00\x00\x00\x00\x00\x06", 8},
    323         {"\x00\x00\x00\x00\x00\x00\x00\x07", 8},
    324         {"\x00\x00\x00\x00\x00\x00\x00\x08", 8},
    325         {"\x00\x00\x00\x00\x00\x00\x00\x09", 8},
    326         {"\x00\x00\x00\x00\x00\x00\x00\x0A", 8},
    327         {"\x00\x00\x00\x00\x00\x00\x00\x0B", 8},
    328         {"\x00\x00\x00\x00\x00\x00\x00\x0C", 8},
    329         {"\x00\x00\x00\x00\x00\x00\x00\x0D", 8},
    330         {"\x00\x00\x00\x00\x00\x00\x00\x0E", 8},
    331         {"\x00\x00\x00\x00\x00\x00\x00\x0F", 8},
    332         {"\x00\x00\x00\x00\x00\x00\x00\x10", 8},
    333         {"\x00\x00\x00\x00\x00\x00\x00\x20", 8},
    334         {"\x00\x00\x00\x00\x00\x00\x00\x40", 8},
    335         {"\x00\x00\x00\x00\x00\x00\x00\x7E", 8},
    336         {"\x00\x00\x00\x00\x00\x00\x00\x7F", 8},
    337         {"\x00\x00\x00\x00\x00\x00\x00\x80", 8},
    338         {"\x00\x00\x00\x00\x00\x00\x00\x81", 8},
    339         {"\x00\x00\x00\x00\x00\x00\x00\xC0", 8},
    340         {"\x00\x00\x00\x00\x00\x00\x00\xFE", 8},
    341         {"\x00\x00\x00\x00\x00\x00\x00\xFF", 8},
    342         {"\x7E\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
    343         {"\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
    344         {"\x80\x00\x00\x00\x00\x00\x00\x00", 8},
    345         {"\x80\x00\x00\x00\x00\x00\x00\x01", 8},
    346         {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE", 8},
    347         /* 8B - LE */
    348         {"\x00\x00\x00\x00\x00\x00\x00\x00", 8},
    349         {"\x01\x00\x00\x00\x00\x00\x00\x00", 8},
    350         {"\x02\x00\x00\x00\x00\x00\x00\x00", 8},
    351         {"\x03\x00\x00\x00\x00\x00\x00\x00", 8},
    352         {"\x04\x00\x00\x00\x00\x00\x00\x00", 8},
    353         {"\x05\x00\x00\x00\x00\x00\x00\x00", 8},
    354         {"\x06\x00\x00\x00\x00\x00\x00\x00", 8},
    355         {"\x07\x00\x00\x00\x00\x00\x00\x00", 8},
    356         {"\x08\x00\x00\x00\x00\x00\x00\x00", 8},
    357         {"\x09\x00\x00\x00\x00\x00\x00\x00", 8},
    358         {"\x0A\x00\x00\x00\x00\x00\x00\x00", 8},
    359         {"\x0B\x00\x00\x00\x00\x00\x00\x00", 8},
    360         {"\x0C\x00\x00\x00\x00\x00\x00\x00", 8},
    361         {"\x0D\x00\x00\x00\x00\x00\x00\x00", 8},
    362         {"\x0E\x00\x00\x00\x00\x00\x00\x00", 8},
    363         {"\x0F\x00\x00\x00\x00\x00\x00\x00", 8},
    364         {"\x10\x00\x00\x00\x00\x00\x00\x00", 8},
    365         {"\x20\x00\x00\x00\x00\x00\x00\x00", 8},
    366         {"\x40\x00\x00\x00\x00\x00\x00\x00", 8},
    367         {"\x7E\x00\x00\x00\x00\x00\x00\x00", 8},
    368         {"\x7F\x00\x00\x00\x00\x00\x00\x00", 8},
    369         {"\x80\x00\x00\x00\x00\x00\x00\x00", 8},
    370         {"\x81\x00\x00\x00\x00\x00\x00\x00", 8},
    371         {"\xC0\x00\x00\x00\x00\x00\x00\x00", 8},
    372         {"\xFE\x00\x00\x00\x00\x00\x00\x00", 8},
    373         {"\xFF\x00\x00\x00\x00\x00\x00\x00", 8},
    374         {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7E", 8},
    375         {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F", 8},
    376         {"\x00\x00\x00\x00\x00\x00\x00\x80", 8},
    377         {"\x01\x00\x00\x00\x00\x00\x00\x80", 8},
    378         {"\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
    379     };
    380 
    381     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    382     uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleMagicVals) - 1);
    383     mangle_Overwrite(run, mangleMagicVals[choice].val, off, mangleMagicVals[choice].size);
    384 }
    385 
    386 static void mangle_MemSet(run_t* run) {
    387     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    388     size_t sz = util_rndGet(1, run->dynamicFileSz - off);
    389     int val = (int)util_rndGet(0, UINT8_MAX);
    390 
    391     memset(&run->dynamicFile[off], val, sz);
    392 }
    393 
    394 static void mangle_Random(run_t* run) {
    395     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    396     size_t len = util_rndGet(1, run->dynamicFileSz - off);
    397     util_rndBuf(&run->dynamicFile[off], len);
    398 }
    399 
    400 static void mangle_AddSub(run_t* run) {
    401     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    402 
    403     /* 1,2,4,8 */
    404     uint64_t varLen = 1U << util_rndGet(0, 3);
    405     if ((run->dynamicFileSz - off) < varLen) {
    406         varLen = 1;
    407     }
    408 
    409     int delta = (int)util_rndGet(0, 8192);
    410     delta -= 4096;
    411 
    412     switch (varLen) {
    413         case 1: {
    414             run->dynamicFile[off] += delta;
    415             return;
    416             break;
    417         }
    418         case 2: {
    419             int16_t val;
    420             memcpy(&val, &run->dynamicFile[off], sizeof(val));
    421             if (util_rnd64() & 0x1) {
    422                 val += delta;
    423             } else {
    424                 /* Foreign endianess */
    425                 val = __builtin_bswap16(val);
    426                 val += delta;
    427                 val = __builtin_bswap16(val);
    428             }
    429             mangle_Overwrite(run, (uint8_t*)&val, off, varLen);
    430             return;
    431             break;
    432         }
    433         case 4: {
    434             int32_t val;
    435             memcpy(&val, &run->dynamicFile[off], sizeof(val));
    436             if (util_rnd64() & 0x1) {
    437                 val += delta;
    438             } else {
    439                 /* Foreign endianess */
    440                 val = __builtin_bswap32(val);
    441                 val += delta;
    442                 val = __builtin_bswap32(val);
    443             }
    444             mangle_Overwrite(run, (uint8_t*)&val, off, varLen);
    445             return;
    446             break;
    447         }
    448         case 8: {
    449             int64_t val;
    450             memcpy(&val, &run->dynamicFile[off], sizeof(val));
    451             if (util_rnd64() & 0x1) {
    452                 val += delta;
    453             } else {
    454                 /* Foreign endianess */
    455                 val = __builtin_bswap64(val);
    456                 val += delta;
    457                 val = __builtin_bswap64(val);
    458             }
    459             mangle_Overwrite(run, (uint8_t*)&val, off, varLen);
    460             return;
    461             break;
    462         }
    463         default: {
    464             LOG_F("Unknown variable length size: %" PRIu64, varLen);
    465             break;
    466         }
    467     }
    468 }
    469 
    470 static void mangle_IncByte(run_t* run) {
    471     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    472     run->dynamicFile[off] += (uint8_t)1UL;
    473 }
    474 
    475 static void mangle_DecByte(run_t* run) {
    476     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    477     run->dynamicFile[off] -= (uint8_t)1UL;
    478 }
    479 
    480 static void mangle_NegByte(run_t* run) {
    481     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    482     run->dynamicFile[off] = ~(run->dynamicFile[off]);
    483 }
    484 
    485 static void mangle_CloneByte(run_t* run) {
    486     size_t off1 = util_rndGet(0, run->dynamicFileSz - 1);
    487     size_t off2 = util_rndGet(0, run->dynamicFileSz - 1);
    488 
    489     uint8_t tmp = run->dynamicFile[off1];
    490     run->dynamicFile[off1] = run->dynamicFile[off2];
    491     run->dynamicFile[off2] = tmp;
    492 }
    493 
    494 static void mangle_Resize(run_t* run) {
    495     run->dynamicFileSz = util_rndGet(0, run->global->maxFileSz);
    496 }
    497 
    498 static void mangle_Expand(run_t* run) {
    499     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    500     size_t len = util_rndGet(1, run->dynamicFileSz - off);
    501 
    502     mangle_Inflate(run, off, len);
    503     mangle_Move(run, off, off + len, run->dynamicFileSz);
    504 }
    505 
    506 static void mangle_Shrink(run_t* run) {
    507     if (run->dynamicFileSz <= 1U) {
    508         return;
    509     }
    510 
    511     size_t len = util_rndGet(1, run->dynamicFileSz - 1);
    512     size_t off = util_rndGet(0, len);
    513 
    514     mangle_Move(run, off + len, off, run->dynamicFileSz);
    515     run->dynamicFileSz -= len;
    516 }
    517 
    518 static void mangle_InsertRnd(run_t* run) {
    519     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    520     size_t len = util_rndGet(1, run->dynamicFileSz - off);
    521 
    522     mangle_Inflate(run, off, len);
    523     mangle_Move(run, off, off + len, run->dynamicFileSz);
    524     util_rndBuf(&run->dynamicFile[off], len);
    525 }
    526 
    527 static void mangle_ASCIIVal(run_t* run) {
    528     char buf[32];
    529     snprintf(buf, sizeof(buf), "%" PRId64, (int64_t)util_rnd64());
    530     size_t off = util_rndGet(0, run->dynamicFileSz - 1);
    531 
    532     mangle_Overwrite(run, (uint8_t*)buf, off, strlen(buf));
    533 }
    534 
    535 void mangle_mangleContent(run_t* run) {
    536     if (run->mutationsPerRun == 0U) {
    537         return;
    538     }
    539 
    540     /* 20% chance to change the file size */
    541     if ((util_rnd64() % 5) == 0) {
    542         mangle_Resize(run);
    543     }
    544 
    545     /* No point in modifying it if its size is 0 */
    546     if (run->dynamicFileSz == 0UL) {
    547         return;
    548     }
    549 
    550     static void (*const mangleFuncs[])(run_t * run) = {
    551         mangle_Byte,
    552         mangle_Bit,
    553         mangle_Bytes,
    554         mangle_Magic,
    555         mangle_IncByte,
    556         mangle_DecByte,
    557         mangle_NegByte,
    558         mangle_AddSub,
    559         mangle_Dictionary,
    560         mangle_DictionaryInsert,
    561         mangle_MemMove,
    562         mangle_MemSet,
    563         mangle_Random,
    564         mangle_CloneByte,
    565         mangle_Expand,
    566         mangle_Shrink,
    567         mangle_InsertRnd,
    568         mangle_ASCIIVal,
    569     };
    570 
    571     /* Max number of stacked changes is 6 */
    572     uint64_t changesCnt = util_rndGet(1, run->global->mutationsPerRun);
    573 
    574     for (uint64_t x = 0; x < changesCnt; x++) {
    575         uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleFuncs) - 1);
    576         mangleFuncs[choice](run);
    577     }
    578 }
    579