diff options
-rw-r--r-- | include/forkserver.h | 34 | ||||
-rw-r--r-- | src/afl-forkserver.c | 101 | ||||
-rw-r--r-- | src/afl-fuzz-init.c | 37 | ||||
-rw-r--r-- | src/afl-fuzz-stats.c | 11 | ||||
-rw-r--r-- | src/afl-fuzz.c | 212 | ||||
-rw-r--r-- | src/afl-showmap.c | 11 |
6 files changed, 228 insertions, 178 deletions
diff --git a/include/forkserver.h b/include/forkserver.h index 227f75c1..2418381f 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -39,6 +39,7 @@ */ typedef enum NyxReturnValue { + Normal, Crash, Asan, @@ -47,22 +48,23 @@ typedef enum NyxReturnValue { Error, IoError, Abort, + } NyxReturnValue; -typedef struct{ - void* (*nyx_new)(const char *sharedir, - const char *workdir, - uint32_t worker_id, - uint32_t cpu_id, - bool create_snapshot); +typedef struct { + + void *(*nyx_new)(const char *sharedir, const char *workdir, + uint32_t worker_id, uint32_t cpu_id, bool create_snapshot); void (*nyx_shutdown)(void *qemu_process); void (*nyx_option_set_reload_mode)(void *qemu_process, bool enable); - void (*nyx_option_set_timeout)(void *qemu_process, uint8_t timeout_sec, uint32_t timeout_usec); + void (*nyx_option_set_timeout)(void *qemu_process, uint8_t timeout_sec, + uint32_t timeout_usec); void (*nyx_option_apply)(void *qemu_process); void (*nyx_set_afl_input)(void *qemu_process, uint8_t *buffer, uint32_t size); enum NyxReturnValue (*nyx_exec)(void *qemu_process); - uint8_t* (*nyx_get_bitmap_buffer)(void *qemu_process); + uint8_t *(*nyx_get_bitmap_buffer)(void *qemu_process); size_t (*nyx_get_bitmap_buffer_size)(void *qemu_process); + } nyx_plugin_handler_t; #endif @@ -156,14 +158,14 @@ typedef struct afl_forkserver { u8 kill_signal; #ifdef __linux__ - nyx_plugin_handler_t* nyx_handlers; - char *out_dir_path; /* path to the output directory */ - u8 nyx_mode; /* if running in nyx mode or not */ - bool nyx_parent; /* create initial snapshot */ - bool nyx_standalone; /* don't serialize the snapshot */ - void* nyx_runner; /* nyx runner object */ - u32 nyx_id; /* nyx runner id (0 -> master) */ - u32 nyx_bind_cpu_id; /* nyx runner cpu id */ + nyx_plugin_handler_t *nyx_handlers; + char * out_dir_path; /* path to the output directory */ + u8 nyx_mode; /* if running in nyx mode or not */ + bool nyx_parent; /* create initial snapshot */ + bool nyx_standalone; /* don't serialize the snapshot */ + void * nyx_runner; /* nyx runner object */ + u32 nyx_id; /* nyx runner id (0 -> master) */ + u32 nyx_bind_cpu_id; /* nyx runner cpu id */ #endif } afl_forkserver_t; diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 16f684be..d34f9ce2 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -389,43 +389,47 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, #ifdef __linux__ if (fsrv->nyx_mode) { - if(fsrv->nyx_runner != NULL){ - return; - } + if (fsrv->nyx_runner != NULL) { return; } if (!be_quiet) { ACTF("Spinning up the NYX backend..."); } - if(fsrv->out_dir_path == NULL){ - FATAL("Nyx workdir path not found..."); - } + if (fsrv->out_dir_path == NULL) { FATAL("Nyx workdir path not found..."); } char *x = alloc_printf("%s/workdir", fsrv->out_dir_path); - if(fsrv->nyx_id == 0xFFFFFFFF){ - FATAL("Nyx ID is not set..."); - } + if (fsrv->nyx_id == 0xFFFFFFFF) { FATAL("Nyx ID is not set..."); } - if(fsrv->nyx_bind_cpu_id == 0xFFFFFFFF){ - FATAL("Nyx CPU ID is not set..."); - } + if (fsrv->nyx_bind_cpu_id == 0xFFFFFFFF) { + + FATAL("Nyx CPU ID is not set..."); - if (fsrv->nyx_parent){ - fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id, !fsrv->nyx_standalone); - } - else{ - fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id, true); } - if(fsrv->nyx_runner == NULL){ - FATAL("Something went wrong ..."); + if (fsrv->nyx_parent) { + + fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new( + fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id, + !fsrv->nyx_standalone); + + } else { + + fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new( + fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id, true); + } - fsrv->map_size = fsrv->nyx_handlers->nyx_get_bitmap_buffer_size(fsrv->nyx_runner);; + if (fsrv->nyx_runner == NULL) { FATAL("Something went wrong ..."); } + + fsrv->map_size = + fsrv->nyx_handlers->nyx_get_bitmap_buffer_size(fsrv->nyx_runner); + ; fsrv->real_map_size = fsrv->map_size; - fsrv->trace_bits = fsrv->nyx_handlers->nyx_get_bitmap_buffer(fsrv->nyx_runner); + fsrv->trace_bits = + fsrv->nyx_handlers->nyx_get_bitmap_buffer(fsrv->nyx_runner); - fsrv->nyx_handlers->nyx_option_set_reload_mode(fsrv->nyx_runner, getenv("NYX_DISABLE_SNAPSHOT_MODE") == NULL); + fsrv->nyx_handlers->nyx_option_set_reload_mode( + fsrv->nyx_runner, getenv("NYX_DISABLE_SNAPSHOT_MODE") == NULL); fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner); fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, 2, 0); @@ -433,7 +437,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* dry run */ fsrv->nyx_handlers->nyx_set_afl_input(fsrv->nyx_runner, "INIT", 4); - switch(fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner)){ + switch (fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner)) { + case Abort: fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); FATAL("Error: Nyx abort occured..."); @@ -447,9 +452,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, break; default: break; + } + return; + } + #endif if (!be_quiet) { ACTF("Spinning up the fork server..."); } @@ -1163,10 +1172,9 @@ void afl_fsrv_kill(afl_forkserver_t *fsrv) { fsrv->child_pid = -1; #ifdef __linux__ - if(fsrv->nyx_mode){ - fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); - } + if (fsrv->nyx_mode) { fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); } #endif + } /* Get the map size from the target forkserver */ @@ -1184,10 +1192,13 @@ u32 afl_fsrv_get_mapsize(afl_forkserver_t *fsrv, char **argv, void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { #ifdef __linux__ - if(fsrv->nyx_mode){ + if (fsrv->nyx_mode) { + fsrv->nyx_handlers->nyx_set_afl_input(fsrv->nyx_runner, buf, len); return; + } + #endif #ifdef AFL_PERSISTENT_RECORD if (unlikely(fsrv->persistent_record)) { @@ -1303,21 +1314,26 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, u32 write_value = fsrv->last_run_timed_out; #ifdef __linux__ - if(fsrv->nyx_mode){ + if (fsrv->nyx_mode) { static uint32_t last_timeout_value = 0; - if (last_timeout_value != timeout){ - fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, timeout/1000, (timeout%1000) * 1000); + if (last_timeout_value != timeout) { + + fsrv->nyx_handlers->nyx_option_set_timeout( + fsrv->nyx_runner, timeout / 1000, (timeout % 1000) * 1000); fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner); last_timeout_value = timeout; + } - enum NyxReturnValue ret_val = fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner); + enum NyxReturnValue ret_val = + fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner); fsrv->total_execs++; - switch(ret_val){ + switch (ret_val) { + case Normal: return FSRV_RUN_OK; case Crash: @@ -1333,29 +1349,40 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); FATAL("Error: Nyx abort occured..."); case IoError: - if (*stop_soon_p){ + if (*stop_soon_p) { + return 0; - } - else{ + + } else { + FATAL("Error: QEMU-Nyx has died..."); + } + break; case Error: FATAL("Error: Nyx runtime error has occured..."); break; + } + return FSRV_RUN_OK; - } + + } + #endif /* After this memset, fsrv->trace_bits[] are effectively volatile, so we must prevent any earlier operations from venturing into that territory. */ #ifdef __linux__ - if(!fsrv->nyx_mode){ + if (!fsrv->nyx_mode) { + memset(fsrv->trace_bits, 0, fsrv->map_size); MEM_BARRIER(); + } + #else memset(fsrv->trace_bits, 0, fsrv->map_size); MEM_BARRIER(); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index b6de3712..dc18f1a9 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -411,11 +411,10 @@ void bind_to_free_cpu(afl_state_t *afl) { OKF("Found a free CPU core, try binding to #%u.", i); if (bind_cpu(afl, i)) { -#ifdef __linux__ - if(afl->fsrv.nyx_mode){ - afl->fsrv.nyx_bind_cpu_id = i; - } -#endif + + #ifdef __linux__ + if (afl->fsrv.nyx_mode) { afl->fsrv.nyx_bind_cpu_id = i; } + #endif /* Success :) */ break; @@ -1095,9 +1094,12 @@ void perform_dry_run(afl_state_t *afl) { case FSRV_RUN_NOINST: #ifdef __linux__ - if(afl->fsrv.nyx_mode && afl->fsrv.nyx_runner != NULL){ + if (afl->fsrv.nyx_mode && afl->fsrv.nyx_runner != NULL) { + afl->fsrv.nyx_handlers->nyx_shutdown(afl->fsrv.nyx_runner); + } + #endif FATAL("No instrumentation detected"); @@ -2453,9 +2455,7 @@ void fix_up_sync(afl_state_t *afl) { x = alloc_printf("%s/%s", afl->out_dir, afl->sync_id); #ifdef __linux__ - if(afl->fsrv.nyx_mode){ - afl->fsrv.out_dir_path = afl->out_dir; - } + if (afl->fsrv.nyx_mode) { afl->fsrv.out_dir_path = afl->out_dir; } #endif afl->sync_dir = afl->out_dir; afl->out_dir = x; @@ -2595,17 +2595,26 @@ void check_binary(afl_state_t *afl, u8 *fname) { afl->fsrv.target_path = ck_strdup(fname); #ifdef __linux__ - if(afl->fsrv.nyx_mode){ + if (afl->fsrv.nyx_mode) { + /* check if target_path is a nyx sharedir */ - if (stat(afl->fsrv.target_path, &st) || S_ISDIR(st.st_mode)){ - char* tmp = alloc_printf("%s/config.ron", afl->fsrv.target_path); - if (stat(tmp, &st) || S_ISREG(st.st_mode)){ + if (stat(afl->fsrv.target_path, &st) || S_ISDIR(st.st_mode)) { + + char *tmp = alloc_printf("%s/config.ron", afl->fsrv.target_path); + if (stat(tmp, &st) || S_ISREG(st.st_mode)) { + free(tmp); return; + } + } - FATAL("Directory '%s' not found or is not a nyx share directory", afl->fsrv.target_path); + + FATAL("Directory '%s' not found or is not a nyx share directory", + afl->fsrv.target_path); + } + #endif if (stat(afl->fsrv.target_path, &st) || !S_ISREG(st.st_mode) || !(st.st_mode & 0111) || (f_len = st.st_size) < 4) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 5f035762..ba8faaf0 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -680,14 +680,16 @@ void show_stats(afl_state_t *afl) { memset(banner, ' ', banner_pad); #ifdef __linux__ - if(afl->fsrv.nyx_mode){ + if (afl->fsrv.nyx_mode) { + sprintf(banner + banner_pad, "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx", afl->crash_mode ? cPIN "peruvian were-rabbit" : cYEL "american fuzzy lop", si, afl->use_banner, afl->power_name); - } - else{ + + } else { + #endif sprintf(banner + banner_pad, "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]", @@ -696,8 +698,11 @@ void show_stats(afl_state_t *afl) { si, afl->use_banner, afl->power_name); #ifdef __linux__ + } + #endif + } SAYF("\n%s\n", banner); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 5b568aa4..01d2096b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -389,74 +389,59 @@ static void fasan_check_afl_preload(char *afl_preload) { } -#ifdef __linux__ -#include <dlfcn.h> + #ifdef __linux__ + #include <dlfcn.h> -nyx_plugin_handler_t* afl_load_libnyx_plugin(u8* libnyx_binary){ - void *handle; - nyx_plugin_handler_t* plugin = calloc(1, sizeof(nyx_plugin_handler_t)); +nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { - ACTF("Trying to load libnyx.so plugin..."); - handle = dlopen((char*) libnyx_binary, RTLD_NOW); - if (!handle) { - goto fail; - } + void * handle; + nyx_plugin_handler_t *plugin = calloc(1, sizeof(nyx_plugin_handler_t)); - plugin->nyx_new = dlsym(handle, "nyx_new"); - if (plugin->nyx_new == NULL){ - goto fail; - } - - plugin->nyx_shutdown = dlsym(handle, "nyx_shutdown"); - if (plugin->nyx_shutdown == NULL){ - goto fail; - } - - plugin->nyx_option_set_reload_mode = dlsym(handle, "nyx_option_set_reload_mode"); - if (plugin->nyx_option_set_reload_mode == NULL){ - goto fail; - } - - plugin->nyx_option_set_timeout = dlsym(handle, "nyx_option_set_timeout"); - if (plugin->nyx_option_set_timeout == NULL){ - goto fail; - } - - plugin->nyx_option_apply = dlsym(handle, "nyx_option_apply"); - if (plugin->nyx_option_apply == NULL){ - goto fail; - } - - plugin->nyx_set_afl_input = dlsym(handle, "nyx_set_afl_input"); - if (plugin->nyx_set_afl_input == NULL){ - goto fail; - } + ACTF("Trying to load libnyx.so plugin..."); + handle = dlopen((char *)libnyx_binary, RTLD_NOW); + if (!handle) { goto fail; } - plugin->nyx_exec = dlsym(handle, "nyx_exec"); - if (plugin->nyx_exec == NULL){ - goto fail; - } + plugin->nyx_new = dlsym(handle, "nyx_new"); + if (plugin->nyx_new == NULL) { goto fail; } - plugin->nyx_get_bitmap_buffer = dlsym(handle, "nyx_get_bitmap_buffer"); - if (plugin->nyx_get_bitmap_buffer == NULL){ - goto fail; - } + plugin->nyx_shutdown = dlsym(handle, "nyx_shutdown"); + if (plugin->nyx_shutdown == NULL) { goto fail; } - plugin->nyx_get_bitmap_buffer_size = dlsym(handle, "nyx_get_bitmap_buffer_size"); - if (plugin->nyx_get_bitmap_buffer_size == NULL){ - goto fail; - } - - OKF("libnyx plugin is ready!"); - return plugin; + plugin->nyx_option_set_reload_mode = + dlsym(handle, "nyx_option_set_reload_mode"); + if (plugin->nyx_option_set_reload_mode == NULL) { goto fail; } - fail: + plugin->nyx_option_set_timeout = dlsym(handle, "nyx_option_set_timeout"); + if (plugin->nyx_option_set_timeout == NULL) { goto fail; } + + plugin->nyx_option_apply = dlsym(handle, "nyx_option_apply"); + if (plugin->nyx_option_apply == NULL) { goto fail; } + + plugin->nyx_set_afl_input = dlsym(handle, "nyx_set_afl_input"); + if (plugin->nyx_set_afl_input == NULL) { goto fail; } + + plugin->nyx_exec = dlsym(handle, "nyx_exec"); + if (plugin->nyx_exec == NULL) { goto fail; } + + plugin->nyx_get_bitmap_buffer = dlsym(handle, "nyx_get_bitmap_buffer"); + if (plugin->nyx_get_bitmap_buffer == NULL) { goto fail; } + + plugin->nyx_get_bitmap_buffer_size = + dlsym(handle, "nyx_get_bitmap_buffer_size"); + if (plugin->nyx_get_bitmap_buffer_size == NULL) { goto fail; } + + OKF("libnyx plugin is ready!"); + return plugin; + +fail: + + FATAL("failed to load libnyx: %s\n", dlerror()); + free(plugin); + return NULL; - FATAL("failed to load libnyx: %s\n", dlerror()); - free(plugin); - return NULL; } -#endif + + #endif /* Main entry point */ @@ -918,13 +903,10 @@ int main(int argc, char **argv_orig, char **envp) { afl->use_banner = optarg; break; -#ifdef __linux__ - case 'X': /* NYX mode */ + #ifdef __linux__ + case 'X': /* NYX mode */ - if (afl->fsrv.nyx_mode) { - FATAL("Multiple -X options not supported"); - - } + if (afl->fsrv.nyx_mode) { FATAL("Multiple -X options not supported"); } afl->fsrv.nyx_parent = true; afl->fsrv.nyx_standalone = true; @@ -933,21 +915,17 @@ int main(int argc, char **argv_orig, char **envp) { break; - case 'Y': /* NYX distributed mode */ - if (afl->fsrv.nyx_mode) { - - FATAL("Multiple -Y options not supported"); - - } + case 'Y': /* NYX distributed mode */ + if (afl->fsrv.nyx_mode) { FATAL("Multiple -Y options not supported"); } afl->fsrv.nyx_mode = 1; break; -#else + #else case 'X': case 'Y': FATAL("Nyx mode is only availabe on linux..."); break; -#endif + #endif case 'A': /* CoreSight mode */ #if !defined(__aarch64__) || !defined(__linux__) @@ -1288,13 +1266,16 @@ int main(int argc, char **argv_orig, char **envp) { OKF("NOTE: This is v3.x which changes defaults and behaviours - see " "README.md"); -#ifdef __linux__ - if (afl->fsrv.nyx_mode){ + #ifdef __linux__ + if (afl->fsrv.nyx_mode) { + OKF("afl++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)"); OKF("Nyx is open source, get it at " - "https://github.com/Nyx-Fuzz"); + "https://github.com/Nyx-Fuzz"); + } -#endif + + #endif if (afl->sync_id && afl->is_main_node && afl->afl_env.afl_custom_mutator_only) { @@ -1337,32 +1318,55 @@ int main(int argc, char **argv_orig, char **envp) { } -#ifdef __linux__ + #ifdef __linux__ if (afl->fsrv.nyx_mode) { - if (afl->fsrv.nyx_standalone && strncmp(afl->sync_id, "default", strlen("default")) != 0){ - FATAL("distributed fuzzing is not supported in this Nyx mode (use -Y instead)"); + if (afl->fsrv.nyx_standalone && + strncmp(afl->sync_id, "default", strlen("default")) != 0) { + + FATAL( + "distributed fuzzing is not supported in this Nyx mode (use -Y " + "instead)"); + } - if (!afl->fsrv.nyx_standalone){ - if (afl->is_main_node){ - if(strncmp("0", afl->sync_id, strlen("0") != 0)){ - FATAL("for Nyx -Y mode, the Main (-M) parameter has to be set to 0 (-M 0)"); + if (!afl->fsrv.nyx_standalone) { + + if (afl->is_main_node) { + + if (strncmp("0", afl->sync_id, strlen("0") != 0)) { + + FATAL( + "for Nyx -Y mode, the Main (-M) parameter has to be set to 0 (-M " + "0)"); + } + afl->fsrv.nyx_id = 0; + } - if (afl->is_secondary_node){ + if (afl->is_secondary_node) { + long nyx_id = strtol(afl->sync_id, NULL, 10); - if (nyx_id == 0 || nyx_id == LONG_MAX){ - FATAL("for Nyx -Y mode, the Secondary (-S) parameter has to be a numeric value and >= 1 (e.g. -S 1)"); + if (nyx_id == 0 || nyx_id == LONG_MAX) { + + FATAL( + "for Nyx -Y mode, the Secondary (-S) parameter has to be a " + "numeric value and >= 1 (e.g. -S 1)"); + } + afl->fsrv.nyx_id = nyx_id; + } + } + } -#endif + + #endif if (afl->sync_id) { @@ -1587,22 +1591,28 @@ int main(int argc, char **argv_orig, char **envp) { afl->fsrv.use_fauxsrv = afl->non_instrumented_mode == 1 || afl->no_forkserver; -#ifdef __linux__ - if (!afl->fsrv.nyx_mode){ + #ifdef __linux__ + if (!afl->fsrv.nyx_mode) { + check_crash_handling(); check_cpu_governor(afl); - } - else{ - u8* libnyx_binary = find_afl_binary(argv[0], "nyx_mode/libnyx.so"); + + } else { + + u8 *libnyx_binary = find_afl_binary(argv[0], "nyx_mode/libnyx.so"); afl->fsrv.nyx_handlers = afl_load_libnyx_plugin(libnyx_binary); - if(afl->fsrv.nyx_handlers == NULL){ + if (afl->fsrv.nyx_handlers == NULL) { + FATAL("failed to initialize libnyx.so..."); + } + } -#else + + #else check_crash_handling(); check_cpu_governor(afl); -#endif + #endif if (getenv("LD_PRELOAD")) { @@ -2085,11 +2095,15 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->queue_buf[entry]->disabled) { ++valid_seeds; } if (!afl->pending_not_fuzzed || !valid_seeds) { -#ifdef __linux__ - if(afl->fsrv.nyx_mode){ + + #ifdef __linux__ + if (afl->fsrv.nyx_mode) { + afl->fsrv.nyx_handlers->nyx_shutdown(afl->fsrv.nyx_runner); + } -#endif + + #endif FATAL("We need at least one valid input seed that does not crash!"); } diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 115f9f2a..e30819b3 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -105,15 +105,8 @@ static sharedmem_t * shm_fuzz; static const u8 count_class_human[256] = { - [0] = 0, - [1] = 1, - [2] = 2, - [3] = 3, - [4] = 4, - [8] = 5, - [16] = 6, - [32] = 7, - [128] = 8 + [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, + [8] = 5, [16] = 6, [32] = 7, [128] = 8 }; |