static void test_match_chain(const int argc, char *argv[]) { t_upslst_item *flavor_list = NULL, *quals_list = NULL; t_upslst_item *vinst_list = NULL, *tinst_list = NULL; t_upslst_item *cinst_list = NULL; int need_unique = 0, i, num_matches; char *new_string = NULL; char *ups_db = "/usrdevel/s1/berman/upsdb"; if (! strcmp(argv[1],"1")) { need_unique = 1; } for (i = 3; i < argc; i += 2) { new_string = get_ups_string(argv[i]); flavor_list = upslst_add(flavor_list, new_string); new_string = get_ups_string(argv[i+1]); quals_list = upslst_add(quals_list, new_string); } /* point back to the first elements of the list */ flavor_list = upslst_first(flavor_list); quals_list = upslst_first(quals_list); num_matches = match_from_chain("tigger", argv[2], "*", (char *)NULL, (char *)NULL, ups_db, need_unique, flavor_list, quals_list, &cinst_list, &vinst_list, &tinst_list); printf("\nNumber of matches found in chain file is %d -\n",num_matches); print_inst(cinst_list); printf("\nNumber of matches found in version file is %d -\n",num_matches); print_inst(vinst_list); printf("\nNumber of matches found in table file is %d -\n",num_matches); print_inst(tinst_list); }
static void test_get_instance(const int argc, char *argv[]) { char cfile[] = "/usrdevel/s1/berman/upsdb/tigger/current.chain"; char vfile[] = "/usrdevel/s1/berman/upsdb/tigger/v2_0.version"; char tfile[] = "/usrdevel/s1/berman/upsdb/tigger/v2_0.tbl"; t_upslst_item *flavor_list = NULL, *quals_list = NULL, *inst_list = NULL; int need_unique = 0, i, num_matches; t_upstyp_product *product = NULL; char *new_string = NULL; if (! strcmp(argv[1],"1")) { need_unique = 1; } for (i = 2; i < argc; i += 2) { new_string = get_ups_string(argv[i]); flavor_list = upslst_add(flavor_list, new_string); new_string = get_ups_string(argv[i+1]); quals_list = upslst_add(quals_list, new_string); } /* point back to the first elements of the list */ flavor_list = upslst_first(flavor_list); quals_list = upslst_first(quals_list); if ((product = upsfil_read_file(&cfile[0])) != NULL) { print_inst(product->instance_list); num_matches = get_instance(product->instance_list, flavor_list, quals_list, need_unique, &inst_list); printf("\nNumber of matches found is %d, and they are -\n",num_matches); print_inst(inst_list); } }
static void test_match_table(const int argc, char *argv[]) { t_upslst_item *flavor_list = NULL, *quals_list = NULL, *inst_list = NULL; int need_unique = 0, i, num_matches; char *new_string = NULL; if (! strcmp(argv[1],"1")) { need_unique = 1; } for (i = 7; i < argc; i += 2) { new_string = get_ups_string(argv[i]); flavor_list = upslst_add(flavor_list, new_string); new_string = get_ups_string(argv[i+1]); quals_list = upslst_add(quals_list, new_string); } /* point back to the first elements of the list */ flavor_list = upslst_first(flavor_list); quals_list = upslst_first(quals_list); num_matches = match_from_table("tigger", (char *)argv[2], (char *)argv[3], (char *)argv[4], (char *)argv[5], (char *)argv[6], need_unique, flavor_list, quals_list, &inst_list); printf("\nNumber of matches found is %d, and they are -\n",num_matches); print_inst(inst_list); }
static void print_func(FUNCTION *func) { unsigned int start_pc = func->begin()->first; #ifdef WINDOWS_FORMAT fprintf(output, "__asm{\n"); #else fprintf(output, "__asm__ __volatile__(\n"); fprintf(output, "\"leave\\n\\t\"\n"); #endif #ifndef WINDOWS_NAKED print_prologue(start_pc); #endif if(start_pc == g_main_pc){ #ifdef WINDOWS_FORMAT fprintf(output, "call init_dependence_data\n"); #else fprintf(output, "\"call init_dependence_data\\n\\t\"\n"); #endif } for(FUNCTION::iterator it = func->begin(); it != func->end();it++){ g_pc = it->first; fprintf(output, "//%x\n", g_pc); if(map_tmp.count(it->first) == 0 ){ print_inst(it->second); } map_tmp[it->first] = 0; } #ifndef WINDOWS_NAKED //print_epilogue(start_pc); #endif #ifdef WINDOWS_FORMAT fprintf(output, "L_ERROR_0x%x:\n", start_pc); fprintf(output, "}\n"); #else fprintf(output, "\"L_ERROR_0x%x:\\n\\t\"\n", start_pc); fprintf(output, "\"call safety_guard\\n\\t\"\n"); fprintf(output, ":);\n"); #endif }
int process_block(struct self_s *self, struct process_state_s *process_state, uint64_t inst_log_prev, uint64_t eip_offset_limit) { uint64_t offset = 0; int result; int n, m, l; int err; int found; struct inst_log_entry_s *inst_exe_prev; struct inst_log_entry_s *inst_exe; struct inst_log_entry_s *inst_log_entry = self->inst_log_entry; struct instruction_s *instruction = NULL; int instruction_offset = 0; int octets = 0; //struct memory_s *memory_text; //struct memory_s *memory_stack; struct memory_s *memory_reg; //struct memory_s *memory_data; struct dis_instructions_s dis_instructions; int *memory_used; struct entry_point_s *entry = self->entry_point; uint64_t list_length = self->entry_point_list_length; void *handle_void = self->handle_void; //memory_text = process_state->memory_text; //memory_stack = process_state->memory_stack; memory_reg = process_state->memory_reg; //memory_data = process_state->memory_data; memory_used = process_state->memory_used; debug_print(DEBUG_EXE, 1, "process_block entry\n"); debug_print(DEBUG_EXE, 1, "inst_log=%"PRId64"\n", inst_log); debug_print(DEBUG_EXE, 1, "dis:Data at %p, size=0x%"PRIx64"\n", inst, inst_size); for (offset = 0; ;) { //for (offset = 0; offset < inst_size; //offset += dis_instructions.bytes_used) { /* Update EIP */ offset = memory_reg[2].offset_value; if (offset >= eip_offset_limit) { debug_print(DEBUG_EXE, 1, "Over ran offset=0x%"PRIx64" >= eip_offset_limit=0x%"PRIx64" \n", offset, eip_offset_limit); return 1; } dis_instructions.instruction_number = 0; dis_instructions.bytes_used = 0; debug_print(DEBUG_EXE, 1, "eip=0x%"PRIx64", offset=0x%"PRIx64"\n", memory_reg[2].offset_value, offset); /* the calling program must define this function. This is a callback. */ result = disassemble(self, &dis_instructions, inst, inst_size, offset); debug_print(DEBUG_EXE, 1, "bytes used = %d\n", dis_instructions.bytes_used); debug_print(DEBUG_EXE, 1, "eip=0x%"PRIx64", offset=0x%"PRIx64"\n", memory_reg[2].offset_value, offset); /* Memory not used yet */ if (0 == memory_used[offset]) { debug_print(DEBUG_EXE, 1, "Memory not used yet\n"); for (n = 0; n < dis_instructions.bytes_used; n++) { memory_used[offset + n] = -n; debug_print(DEBUG_EXE, 1, " 0x%02x\n", inst[offset + n]); } debug_print(DEBUG_EXE, 1, "\n"); memory_used[offset] = inst_log; } else { int inst_this = memory_used[offset]; if (inst_this < 0) { /* FIXME: What to do in this case? */ /* problem caused by rep movs instruction */ debug_print(DEBUG_EXE, 1, "process_block:line110:FIXME:Not a valid instuction %d at eip offset 0x%"PRIx64"\n", inst_this, offset); } /* If value == maxint, then it is the destination of a jump */ /* But I need to separate the instruction flows */ /* A jump/branch inst should create a new instruction tree */ debug_print(DEBUG_EXE, 1, "Memory already used\n"); inst_exe_prev = &inst_log_entry[inst_log_prev]; inst_exe = &inst_log_entry[inst_this]; debug_print(DEBUG_EXE, 1, "inst_exe_prev=%p, inst_exe=%p\n", inst_exe_prev, inst_exe); inst_exe->prev_size++; if (inst_exe->prev_size == 1) { inst_exe->prev = malloc(sizeof(inst_exe->prev)); } else { inst_exe->prev = realloc(inst_exe->prev, sizeof(inst_exe->prev) * inst_exe->prev_size); } inst_exe->prev[inst_exe->prev_size - 1] = inst_log_prev; if (inst_exe_prev->next_size > 0) { debug_print(DEBUG_EXE, 1, "JCD8a: next_size = 0x%x\n", inst_exe_prev->next_size); } if (inst_exe_prev->next_size == 0) { inst_exe_prev->next_size++; inst_exe_prev->next = malloc(sizeof(inst_exe_prev->next)); inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_this; } else { found = 0; for (l = 0; l < inst_exe_prev->next_size; l++) { if (inst_exe_prev->next[inst_exe_prev->next_size - 1] == inst_this) { found = 1; break; } } if (!found) { inst_exe_prev->next_size++; if (inst_exe_prev->next_size > 2) { debug_print(DEBUG_EXE, 1, "process_block: next_size = %d, inst = 0x%x\n", inst_exe_prev->next_size, inst_this); } inst_exe_prev->next = realloc(inst_exe_prev->next, sizeof(inst_exe_prev->next) * inst_exe_prev->next_size); inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_this; } } break; } //debug_print(DEBUG_EXE, 1, "disassemble_fn\n"); //disassemble_fn = disassembler (handle->bfd); //debug_print(DEBUG_EXE, 1, "disassemble_fn done\n"); debug_print(DEBUG_EXE, 1, "disassemble att : "); bf_disassemble_set_options(handle_void, "att"); bf_disassemble_callback_start(handle_void); octets = bf_disassemble(handle_void, offset); bf_disassemble_callback_end(handle_void); debug_print(DEBUG_EXE, 1, " octets=%d\n", octets); debug_print(DEBUG_EXE, 1, "disassemble intel: "); bf_disassemble_set_options(handle_void, "intel"); bf_disassemble_callback_start(handle_void); octets = bf_disassemble(handle_void, offset); bf_disassemble_callback_end(handle_void); debug_print(DEBUG_EXE, 1, " octets=%d\n", octets); if (dis_instructions.bytes_used != octets) { debug_print(DEBUG_EXE, 1, "Unhandled instruction. Length mismatch. Got %d, expected %d, Exiting\n", dis_instructions.bytes_used, octets); return 1; } /* Update EIP */ memory_reg[2].offset_value += octets; debug_print(DEBUG_EXE, 1, "Number of RTL dis_instructions=%d\n", dis_instructions.instruction_number); if (result != 0) { debug_print(DEBUG_EXE, 1, "Unhandled instruction. Exiting\n"); return 1; } if (dis_instructions.instruction_number == 0) { debug_print(DEBUG_EXE, 1, "NOP instruction. Get next inst\n"); continue; } for (n = 0; n < dis_instructions.instruction_number; n++) { instruction = &dis_instructions.instruction[n]; debug_print(DEBUG_EXE, 1, "Printing inst1111:0x%x, 0x%x, 0x%"PRIx64"\n",instruction_offset, n, inst_log); err = print_inst(self, instruction, instruction_offset + n + 1, NULL); if (err) { debug_print(DEBUG_EXE, 1, "print_inst failed\n"); return err; } inst_exe_prev = &inst_log_entry[inst_log_prev]; inst_exe = &inst_log_entry[inst_log]; memcpy(&(inst_exe->instruction), instruction, sizeof(struct instruction_s)); err = execute_instruction(self, process_state, inst_exe); if (err) { debug_print(DEBUG_EXE, 1, "execute_intruction failed err=%d\n", err); return err; } inst_exe->prev_size++; if (inst_exe->prev_size == 1) { inst_exe->prev = malloc(sizeof(inst_exe->prev)); } else { inst_exe->prev = realloc(inst_exe->prev, sizeof(inst_exe->prev) * inst_exe->prev_size); } inst_exe->prev[inst_exe->prev_size - 1] = inst_log_prev; inst_exe_prev->next_size++; if (inst_exe_prev->next_size > 2) { debug_print(DEBUG_EXE, 1, "process_block:line203: next_size = %d, inst = 0x%"PRIx64"\n", inst_exe_prev->next_size, inst_log); } if (inst_exe_prev->next_size > 1) { debug_print(DEBUG_EXE, 1, "JCD8b: next_size = 0x%x\n", inst_exe_prev->next_size); } if (inst_exe_prev->next_size == 1) { inst_exe_prev->next = malloc(sizeof(inst_exe_prev->next)); inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_log; } else { inst_exe_prev->next = realloc(inst_exe_prev->next, sizeof(inst_exe_prev->next) * inst_exe_prev->next_size); inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_log; } inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_log; if (IF == instruction->opcode) { debug_print(DEBUG_EXE, 1, "IF FOUND\n"); //debug_print(DEBUG_EXE, 1, "Breaking at IF\n"); debug_print(DEBUG_EXE, 1, "IF: this EIP = 0x%"PRIx64"\n", memory_reg[2].offset_value); debug_print(DEBUG_EXE, 1, "IF: jump dst abs EIP = 0x%"PRIx64"\n", inst_exe->value3.offset_value); debug_print(DEBUG_EXE, 1, "IF: inst_log = %"PRId64"\n", inst_log); for (m = 0; m < list_length; m++ ) { if (0 == entry[m].used) { entry[m].esp_init_value = memory_reg[0].init_value; entry[m].esp_offset_value = memory_reg[0].offset_value; entry[m].ebp_init_value = memory_reg[1].init_value; entry[m].ebp_offset_value = memory_reg[1].offset_value; entry[m].eip_init_value = memory_reg[2].init_value; entry[m].eip_offset_value = memory_reg[2].offset_value; entry[m].previous_instuction = inst_log; entry[m].used = 1; debug_print(DEBUG_EXE, 1, "JCD:8 used 1\n"); break; } } /* FIXME: Would starting a "m" be better here? */ for (m = 0; m < list_length; m++ ) { if (0 == entry[m].used) { entry[m].esp_init_value = memory_reg[0].init_value; entry[m].esp_offset_value = memory_reg[0].offset_value; entry[m].ebp_init_value = memory_reg[1].init_value; entry[m].ebp_offset_value = memory_reg[1].offset_value; entry[m].eip_init_value = inst_exe->value3.init_value; entry[m].eip_offset_value = inst_exe->value3.offset_value; entry[m].previous_instuction = inst_log; entry[m].used = 1; debug_print(DEBUG_EXE, 1, "JCD:8 used 2\n"); break; } } } if (JMPT == instruction->opcode) { /* FIXME: add the jump table detection here */ uint64_t inst_base; int tmp; struct inst_log_entry_s *inst_exe_base; struct instruction_s *instruction = NULL; int relocation_area; uint64_t relocation_index; tmp = search_for_jump_table_base(self, inst_log, &inst_base); if (tmp) { debug_print(DEBUG_EXE, 1, "FIXME: JMPT reached..exiting %d 0x%"PRIx64"\n", tmp, inst_base); exit(1); } inst_exe_base = &inst_log_entry[inst_base]; instruction = &(inst_exe_base->instruction); debug_print(DEBUG_EXE, 1, "Relocated = 0x%x\n", instruction->srcB.relocated); debug_print(DEBUG_EXE, 1, "Relocated_area = 0x%x\n", instruction->srcB.relocated_area); debug_print(DEBUG_EXE, 1, "Relocated_index = 0x%x\n", instruction->srcB.relocated_index); if (2 == instruction->srcB.relocated_area) { uint64_t index = instruction->srcB.relocated_index; tmp = 0; do { tmp = bf_find_relocation_rodata(handle_void, index, &relocation_area, &relocation_index); if (!tmp) { if (1 != relocation_area) { debug_print(DEBUG_EXE, 1, "JMPT Relocation area not to code\n"); exit(1); } for (m = 0; m < list_length; m++ ) { if (0 == entry[m].used) { entry[m].esp_init_value = memory_reg[0].init_value; entry[m].esp_offset_value = memory_reg[0].offset_value; entry[m].ebp_init_value = memory_reg[1].init_value; entry[m].ebp_offset_value = memory_reg[1].offset_value; entry[m].eip_init_value = 0; entry[m].eip_offset_value = relocation_index; entry[m].previous_instuction = inst_log; entry[m].used = 1; debug_print(DEBUG_EXE, 1, "JMPT new entry \n"); break; } } } else { debug_print(DEBUG_EXE, 1, "JMPT index, 0x%"PRIx64", not found in rodata relocation table\n", index); } index += 8; } while (!tmp); } } inst_log_prev = inst_log; inst_log++; if (0 == memory_reg[2].offset_value) { debug_print(DEBUG_EXE, 1, "Function exited\n"); if (inst_exe_prev->instruction.opcode == NOP) { inst_exe_prev->instruction.opcode = RET; } break; } if (JMPT == instruction->opcode) { debug_print(DEBUG_EXE, 1, "Function exited. Temporary action for JMPT\n"); break; } } instruction_offset += dis_instructions.instruction_number; if (0 == memory_reg[2].offset_value) { debug_print(DEBUG_EXE, 1, "Breaking\n"); break; } if (instruction && (JMPT == instruction->opcode)) { debug_print(DEBUG_EXE, 1, "Function exited. Temporary action for JMPT\n"); break; } #if 0 if (IF == instruction->opcode) { debug_print(DEBUG_EXE, 1, "Breaking at IF\n"); debug_print(DEBUG_EXE, 1, "IF: this EIP = 0x%"PRIx64"\n", memory_reg[2].offset_value); debug_print(DEBUG_EXE, 1, "IF: jump dst abs EIP = 0x%"PRIx64"\n", inst_exe->value3.offset_value); debug_print(DEBUG_EXE, 1, "IF: inst_log = %"PRId64"\n", inst_log); for (n = 0; n < list_length; n++ ) { if (0 == entry[n].used) { entry[n].esp_init_value = memory_reg[0].init_value; entry[n].esp_offset_value = memory_reg[0].offset_value; entry[n].ebp_init_value = memory_reg[1].init_value; entry[n].ebp_offset_value = memory_reg[1].offset_value; entry[n].eip_init_value = memory_reg[2].init_value; entry[n].eip_offset_value = memory_reg[2].offset_value; entry[n].previous_instuction = inst_log - 1; entry[n].used = 1; break; } } /* FIXME: Would starting a "n" be better here? */ for (n = 0; n < list_length; n++ ) { if (0 == entry[n].used) { entry[n].esp_init_value = memory_reg[0].init_value; entry[n].esp_offset_value = memory_reg[0].offset_value; entry[n].ebp_init_value = memory_reg[1].init_value; entry[n].ebp_offset_value = memory_reg[1].offset_value; entry[n].eip_init_value = inst_exe->value3.init_value; entry[n].eip_offset_value = inst_exe->value3.offset_value; entry[n].previous_instuction = inst_log - 1; entry[n].used = 1; break; } } break; } #endif } return 0; }
void simulate(FILE **oFile, word *regs, word *prog, word *mem, size *PC, size *GP) { size pc = 0, // current instruction gp = 0, // current mem location iType; // current instruction type Ibits curr_instr; // current instr value // This is the actual simulation. It will loop until either // the program counter reaches the limit and thus exiting // with an error code, or the proper exit command is made. // This is done by translating op/func codes into calls to // simulation functions. Notice that each function is // passed the same parameters (save syscalls). While this // could be prevented by using gloabl variables, the extra // work is worth the encapsulation. // Each simulation function will return the address to the // next instruction. Thus each loop will start by grabbing // the instruction from the instruction array. It will then // store the encoding into a union to permit efficient // memory usage, and easy bit field referencing. while(pc < *PC) { curr_instr.bits = prog[pc]; // get next instruction iType = get_iType(curr_instr.R.op, &pc); // get instruction type print_inst(oFile, &curr_instr, &pc, 1); // print instruction if(iType == 0) { // handle R-type switch(curr_instr.R.fn) { case 12: pc = sim_syscall(regs, mem, PC, &pc, GP, &gp); if (pc == -1) return; break; case 16: pc = sim_mfhi(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; case 18: pc = sim_mflo(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; case 24: pc = sim_mult(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; case 26: pc = sim_div(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; case 33: pc = sim_addu(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; case 35: pc = sim_subu(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; case 36: pc = sim_and(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; case 37: pc = sim_or(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; case 42: pc = sim_slt(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; default: fprintf(stderr, "ERROR: Illegal function encoding - line %d\n", pc); exit(1); } } else if (iType == 1) { // handle I-type switch(curr_instr.I.op) { case 9: pc = sim_addiu(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; case 4: pc = sim_beq(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; case 5: pc = sim_bne(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; case 35: pc = sim_lw(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; case 43: pc = sim_sw(&curr_instr, regs, mem, PC, &pc, GP, &gp); break; } } else { // handle J-type pc = sim_j(&curr_instr, regs, mem, PC, &pc, GP, &gp); } print_regs(oFile, regs); // status of regs print_mem(oFile, mem, GP); // status of mem } }
void print_list(FILE *fptr, inst_t head) { while (head) { print_inst(fptr, head); head = head->next; } }