void IN_DrawValue(int x,int y,int value) { char v[4]; int j; int index; valtostr(v,value); j = mystrlen(v) - 1; while(j >= 0) { index = (v[j--] - '0'); x -= snums[index]->width+2; DrawJagobj(snums[index], x, y); } }
/* 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; }
bool handler__watch(globals_t * vars, char **argv, unsigned argc) { value_t o, n; unsigned id; char *end = NULL, buf[128], timestamp[64]; time_t t; match_location loc; value_t old_val; void *address; scan_data_type_t data_type = vars->options.scan_data_type; if (argc != 2) { show_error("was expecting one argument, see `help watch`.\n"); return false; } if ((data_type == BYTEARRAY) || (data_type == STRING)) { show_error("`watch` is not supported for bytearray or string.\n"); return false; } /* parse argument */ id = strtoul(argv[1], &end, 0x00); /* check that strtoul() worked */ if (argv[1][0] == '\0' || *end != '\0') { show_error("sorry, couldn't parse `%s`, try `help watch`\n", argv[1]); return false; } loc = nth_match(vars->matches, id); /* check this is a valid match-id */ if (!loc.swath) { show_error("you specified a non-existent match `%u`.\n", id); show_info("use \"list\" to list matches, or \"help\" for other commands.\n"); return false; } address = remote_address_of_nth_element(loc.swath, loc.index /* ,MATCHES_AND_VALUES */); old_val = data_to_val(loc.swath, loc.index /* ,MATCHES_AND_VALUES */); old_val.flags = loc.swath->data[loc.index].match_info; valcpy(&o, &old_val); valcpy(&n, &o); valtostr(&o, buf, sizeof(buf)); if (INTERRUPTABLE()) { (void) detach(vars->target); ENDINTERRUPTABLE(); return true; } /* every entry is timestamped */ t = time(NULL); strftime(timestamp, sizeof(timestamp), "[%T]", localtime(&t)); show_info("%s monitoring %10p for changes until interrupted...\n", timestamp, address); while (true) { if (attach(vars->target) == false) return false; if (peekdata(vars->target, address, &n) == false) return false; truncval(&n, &old_val); /* check if the new value is different */ match_flags tmpflags; zero_match_flags(&tmpflags); scan_routine_t valuecmp_routine = (get_scanroutine(ANYNUMBER, MATCHCHANGED)); if (valuecmp_routine(&o, &n, NULL, &tmpflags, address)) { valcpy(&o, &n); truncval(&o, &old_val); valtostr(&o, buf, sizeof(buf)); /* fetch new timestamp */ t = time(NULL); strftime(timestamp, sizeof(timestamp), "[%T]", localtime(&t)); show_info("%s %10p -> %s\n", timestamp, address, buf); } /* detach after valuecmp_routine, since it may read more data (e.g. bytearray) */ detach(vars->target); (void) sleep(1); } }