Example #1
0
matches_and_old_values_array *
null_terminate (matches_and_old_values_array *array,
                matches_and_old_values_swath *swath)
{
    unsigned long bytes_needed;

    if (swath->number_of_bytes == 0) {
        assert(swath->first_byte_in_child == NULL);

    } else {
        swath = local_address_beyond_last_element(swath );
        array = allocate_enough_to_reach(array, ((void *)swath) +
                                         sizeof(matches_and_old_values_swath),
                                         &swath);
        swath->first_byte_in_child = NULL;
        swath->number_of_bytes = 0;
    }

    bytes_needed = ((void *)swath + sizeof(matches_and_old_values_swath) -
                    (void *)array);

    if (bytes_needed < array->bytes_allocated) {
        /* reduce array to its final size */
        if (!(array = realloc(array, bytes_needed)))
            return NULL;

        array->bytes_allocated = bytes_needed;
    }

    return array;
}
match_location nth_match(matches_and_old_values_array *matches, unsigned n)
{
    unsigned i = 0;

    matches_and_old_values_swath *reading_swath_index = (matches_and_old_values_swath *)matches->swaths;
    int reading_iterator = 0;

    if (!matches) return (match_location){ NULL, 0 };

    while (reading_swath_index->first_byte_in_child) {
        /* Only actual matches are considered */
        if (flags_to_max_width_in_bytes(reading_swath_index->data[reading_iterator].match_info) > 0)
        {
            if (i == n)
            {
                return (match_location){ reading_swath_index, reading_iterator };
            }
        
            ++i;
        }

        /* Go on to the next one... */
        ++reading_iterator;
        if (reading_iterator >= reading_swath_index->number_of_bytes)
        {
            reading_swath_index = local_address_beyond_last_element((matches_and_old_values_swath *)reading_swath_index );
            reading_iterator = 0;
        }
    }

    /* I guess this is not a valid match-id */
    return (match_location){ NULL, 0 };
}
Example #3
0
bool handler__set(globals_t * vars, char **argv, unsigned argc)
{
    unsigned block, seconds = 1;
    char *delay = NULL;
    char *end;
    bool cont = false;
    struct setting {
        char *matchids;
        char *value;
        unsigned seconds;
    } *settings = NULL;

    assert(argc != 0);
    assert(argv != NULL);
    assert(vars != NULL);


    if (argc < 2) {
        show_error("expected an argument, type `help set` for details.\n");
        return false;
    }

    /* supporting `set` for bytearray will cause annoying syntax problems... */
    if ((vars->options.scan_data_type == BYTEARRAY)
       ||(vars->options.scan_data_type == STRING))
    {
        show_error("`set` is not supported for bytearray or string, use `write` instead.\n");
        return false;
    }

    /* check if there are any matches */
    if (vars->num_matches == 0) {
        show_error("no matches are known.\n");
        return false;
    }

    /* --- parse arguments into settings structs --- */

    settings = calloca(argc - 1, sizeof(struct setting));

    /* parse every block into a settings struct */
    for (block = 0; block < argc - 1; block++) {

        /* first seperate the block into matches and value, which are separated by '=' */
        if ((settings[block].value = strchr(argv[block + 1], '=')) == NULL) {

            /* no '=' found, whole string must be the value */
            settings[block].value = argv[block + 1];
        } else {
            /* there is a '=', value+1 points to value string. */

            /* use strndupa() to copy the matchids into a new buffer */
            settings[block].matchids =
                strndupa(argv[block + 1],
                         (size_t) (settings[block].value++ - argv[block + 1]));
        }

        /* value points to the value string, possibly with a delay suffix */

        /* matchids points to the match-ids (possibly multiple) or NULL */

        /* now check for a delay suffix (meaning continuous mode), eg 0xff/10 */
        if ((delay = strchr(settings[block].value, '/')) != NULL) {
            char *end = NULL;

            /* parse delay count */
            settings[block].seconds = strtoul(delay + 1, &end, 10);

            if (*(delay + 1) == '\0') {
                /* empty delay count, eg: 12=32/ */
                show_error("you specified an empty delay count, `%s`, see `help set`.\n", settings[block].value);
                return false;
            } else if (*end != '\0') {
                /* parse failed before end, probably trailing garbage, eg 34=9/16foo */
                show_error("trailing garbage after delay count, `%s`.\n", settings[block].value);
                return false;
            } else if (settings[block].seconds == 0) {
                /* 10=24/0 disables continous mode */
                show_info("you specified a zero delay, disabling continuous mode.\n");
            } else {
                /* valid delay count seen and understood */
                show_info("setting %s every %u seconds until interrupted...\n", settings[block].matchids ? settings[block].  matchids : "all", settings[block].seconds);

                /* continuous mode on */
                cont = true;
            }

            /* remove any delay suffix from the value */
            settings[block].value =
                strndupa(settings[block].value,
                         (size_t) (delay - settings[block].value));
        }                       /* if (strchr('/')) */
    }                           /* for(block...) */

    /* --- setup a longjmp to handle interrupt --- */
    if (INTERRUPTABLE()) {
        
        /* control returns here when interrupted */
// settings is allocated with alloca, do not free it
//        free(settings);
        detach(vars->target);
        ENDINTERRUPTABLE();
        return true;
    }

    /* --- execute the parsed setting structs --- */

    while (true) {
        uservalue_t userval;

        /* for every settings struct */
        for (block = 0; block < argc - 1; block++) {

            /* check if this block has anything to do this iteration */
            if (seconds != 1) {
                /* not the first iteration (all blocks get executed first iteration) */

                /* if settings.seconds is zero, then this block is only executed once */
                /* if seconds % settings.seconds is zero, then this block must be executed */
                if (settings[block].seconds == 0
                    || (seconds % settings[block].seconds) != 0)
                    continue;
            }

            /* convert value */
            if (!parse_uservalue_number(settings[block].value, &userval)) {
                show_error("bad number `%s` provided\n", settings[block].value);
                goto fail;
            }

            /* check if specific match(s) were specified */
            if (settings[block].matchids != NULL) {
                char *id, *lmatches = NULL;
                unsigned num = 0;

                /* create local copy of the matchids for strtok() to modify */
                lmatches = strdupa(settings[block].matchids);

                /* now seperate each match, spearated by commas */
                while ((id = strtok(lmatches, ",")) != NULL) {
                    match_location loc;

                    /* set to NULL for strtok() */
                    lmatches = NULL;

                    /* parse this id */
                    num = strtoul(id, &end, 0x00);

                    /* check that succeeded */
                    if (*id == '\0' || *end != '\0') {
                        show_error("could not parse match id `%s`\n", id);
                        goto fail;
                    }

                    /* check this is a valid match-id */
                    loc = nth_match(vars->matches, num);
                    if (loc.swath) {
                        value_t v;
                        value_t old;
                        void *address = remote_address_of_nth_element(loc.swath, loc.index /* ,MATCHES_AND_VALUES */);

                        /* copy val onto v */
                        /* XXX: valcmp? make sure the sizes match */
                        old = data_to_val(loc.swath, loc.index /* ,MATCHES_AND_VALUES */);
                        zero_value(&v);
                        v.flags = old.flags = loc.swath->data[loc.index].match_info;
                        uservalue2value(&v, &userval);
                        
                        show_info("setting *%p to %#"PRIx64"...\n", address, v.int64_value);

                        /* set the value specified */
                        fix_endianness(vars, &v);
                        if (setaddr(vars->target, address, &v) == false) {
                            show_error("failed to set a value.\n");
                            goto fail;
                        }

                    } else {
                        /* match-id > than number of matches */
                        show_error("found an invalid match-id `%s`\n", id);
                        goto fail;
                    }
                }
            } else {
                
                matches_and_old_values_swath *reading_swath_index = (matches_and_old_values_swath *)vars->matches->swaths;
                int reading_iterator = 0;

                /* user wants to set all matches */
                while (reading_swath_index->first_byte_in_child) {

                    /* Only actual matches are considered */
                    if (flags_to_max_width_in_bytes(reading_swath_index->data[reading_iterator].match_info) > 0)
                    {
                        void *address = remote_address_of_nth_element(reading_swath_index, reading_iterator /* ,MATCHES_AND_VALUES */);

                        /* XXX: as above : make sure the sizes match */
                                    
                        value_t old = data_to_val(reading_swath_index, reading_iterator /* ,MATCHES_AND_VALUES */);
                        value_t v;
                        zero_value(&v);
                        v.flags = old.flags = reading_swath_index->data[reading_iterator].match_info;
                        uservalue2value(&v, &userval);

                        show_info("setting *%p to %#"PRIx64"...\n", address, v.int64_value);

                        fix_endianness(vars, &v);
                        if (setaddr(vars->target, address, &v) == false) {
                            show_error("failed to set a value.\n");
                            goto fail;
                        }
                    }
                     
                     /* Go on to the next one... */
                    ++reading_iterator;
                    if (reading_iterator >= reading_swath_index->number_of_bytes)
                    {
                        reading_swath_index = local_address_beyond_last_element(reading_swath_index /* ,MATCHES_AND_VALUES */);
                        reading_iterator = 0;
                    }
                }
            }                   /* if (matchid != NULL) else ... */
        }                       /* for(block) */

        if (cont) {
            sleep(1);
        } else {
            break;
        }

        seconds++;
    }                           /* while(true) */

    ENDINTERRUPTABLE();
    return true;

fail:
    ENDINTERRUPTABLE();
    return false;
    
}
Example #4
0
/* FORMAT (don't change, front-end depends on this): 
 * [#no] addr, value, [possible types (separated by space)]
 */
bool handler__list(globals_t * vars, char **argv, unsigned argc)
{
    unsigned i = 0;
    int buf_len = 128; /* will be realloc later if necessary */
    element_t *np = NULL;
    char *v = malloc(buf_len);
    if (v == NULL)
    {
        show_error("memory allocation failed.\n");
        return false;
    }
    char *bytearray_suffix = ", [bytearray]";
    char *string_suffix = ", [string]";

    USEPARAMS();

    if(!(vars->matches))
        return true;

    if (vars->regions)
        np = vars->regions->head;

    matches_and_old_values_swath *reading_swath_index = (matches_and_old_values_swath *)vars->matches->swaths;
    int reading_iterator = 0;

    /* list all known matches */
    while (reading_swath_index->first_byte_in_child) {

        match_flags flags = reading_swath_index->data[reading_iterator].match_info;

        /* Only actual matches are considered */
        if (flags_to_max_width_in_bytes(flags) > 0)
        {
            switch(globals.options.scan_data_type)
            {
            case BYTEARRAY:
                ; /* cheat gcc */ 
                buf_len = flags.bytearray_length * 3 + 32;
                v = realloc(v, buf_len); /* for each byte and the suffix', this should be enough */

                if (v == NULL)
                {
                    show_error("memory allocation failed.\n");
                    return false;
                }
                data_to_bytearray_text(v, buf_len, reading_swath_index, reading_iterator, flags.bytearray_length);
                assert(strlen(v) + strlen(bytearray_suffix) + 1 <= buf_len); /* or maybe realloc is better? */
                strcat(v, bytearray_suffix);
                break;
            case STRING:
                ; /* cheat gcc */
                buf_len = flags.string_length + strlen(string_suffix) + 32; /* for the string and suffix, this should be enough */
                v = realloc(v, buf_len);
                if (v == NULL)
                {
                    show_error("memory allocation failed.\n");
                    return false;
                }
                data_to_printable_string(v, buf_len, reading_swath_index, reading_iterator, flags.string_length);
                assert(strlen(v) + strlen(string_suffix) + 1 <= buf_len); /* or maybe realloc is better? */
                strcat(v, string_suffix);
                break;
            default: /* numbers */
                ; /* cheat gcc */
                value_t val = data_to_val(reading_swath_index, reading_iterator /* ,MATCHES_AND_VALUES */);
                truncval_to_flags(&val, flags);

                valtostr(&val, v, buf_len);
                break;
            }

            void *address = remote_address_of_nth_element(reading_swath_index,
                reading_iterator /* ,MATCHES_AND_VALUES */);
            unsigned long address_ul = (unsigned long)address;
            int region_id = 99;
            unsigned long match_off = 0;
            const char *region_type = "??";
            /* get region info belonging to the match -
             * note: we assume the regions list and matches to be sorted
             */
            while (np) {
                region_t *region = np->data;
                unsigned long region_start = (unsigned long)region->start;
                if (address_ul < region_start + region->size &&
                  address_ul >= region_start) {
                    region_id = region->id;
                    match_off = address_ul - region->load_addr;
                    region_type = region_type_names[region->type];
                    break;
                }
                np = np->next;
            }
            fprintf(stdout, "[%2u] "POINTER_FMT", %2u + "POINTER_FMT", %5s, %s\n", 
                    i++, address_ul, region_id, match_off, region_type, v);
        }

        /* Go on to the next one... */
        ++reading_iterator;
        if (reading_iterator >= reading_swath_index->number_of_bytes)
        {
            assert(((matches_and_old_values_swath *)(local_address_beyond_last_element(reading_swath_index /* ,MATCHES_AND_VALUES */)))->number_of_bytes >= 0);
            reading_swath_index = local_address_beyond_last_element(reading_swath_index /* ,MATCHES_AND_VALUES */);
            reading_iterator = 0;
        }
    }

    free(v);
    return true;
}