int dump_heap(struct heap **heap_dump, int pid_id) { char dump_file[30]; char *dump_data = (char*)malloc(100); FILE *df = NULL; int hs = 0; int bytes = 0; bzero(dump_data,100); ptrace(PTRACE_ATTACH, pid_id, NULL, NULL); sprintf(dump_file,"%d.dump",pid_id); df = fopen(dump_file,"a+"); if(df == NULL) { printf("* Error creating file %s, quitting.\n", dump_file); ptrace(PTRACE_DETACH, pid_id, NULL, NULL); return -1; } printf("--------------------------------------------------------------\n"); printf("* Dumping memory to %s this can take awhile.\n", dump_file); while(hs < heap_structure_size) { while(heap_dump[hs]->saddress <= heap_dump[hs]->address) { ltostr(dump_data,peekdata(heap_dump[hs]->saddress,pid_id)); bytes += fwrite(dump_data,1,sizeof(dump_data),df); heap_dump[hs]->saddress++; } printf("* Wrote %d bytes.\n", bytes); bytes = 0; hs++; } fclose(df); ptrace(PTRACE_DETACH, pid_id, NULL, NULL); printf("* Finished.\n"); return 0; }
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); } }