/* op_t get_first_operand(FILE *f, ea_t addr) { char buf[MAXSTR]; char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(addr); generate_disasm_line(cmd.ea, buf, sizeof(buf)-1); // This will appear as colour-tagged text (which will // be mostly unreadable in IDA's tag_remove(buf, instr_clean, sizeof(instr_clean)-1); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); for(int i = 0; cmd.Operands[i].type != o_void; i++){ qfprintf(f,"operand number %d, type %d, reg %d, phrase %d, value %a, addr %a\n", i, cmd.Operands[i].type,cmd.Operands[i].reg, cmd.Operands[i].phrase,cmd.Operands[i].value, cmd.Operands[i].addr); //if(cmd.Operands[i].type == o_reg) return cmd.Operands[i]; } return cmd.Operands[0]; } */ op_t get_first_operand_new(ea_t addr) { ua_ana0(addr); return cmd.Operands[0]; }
//TODO: better algo of course!!! //By now - it's full os shitty false positives int assign_type(ea_t address, int *value) { flags_t flags = getFlags(address); if (isHead(flags) && isCode(flags)) { ua_ana0(address); if(cmd.itype == NN_mov) if(cmd.Operands[1].type == o_imm){ *value = cmd.Operands[1].value; return CONSTVALUE; } else return VARVALUE; return VARVALUEVULN; } else{ return UNDEFINED; } return UNDEFINED; }
Register parse_pointer (ea_t ea, int operand, ea_t &offset) { ua_ana0(ea); if (cmd.Operands[operand].type != o_displ) return REGISTER_UNSET; offset = cmd.Operands[operand].addr; return cmd.Operands[operand].reg; }
//TODO: this is not a f*****g smart function! this is total crap!!! //TODO: kill locating algo by function, Cause there a lot of places, where IDA f*****g sucks, and dont understand bounds of function!!!! //replace by discovery up by the tree ea_t find_instruction_that_changes_operand_backward_smart(ea_t start, op_t operand) { func_t *f = get_func(start); char buf[MAXSTR]; char instr_clean[MAXSTR]; if(f) { ea_t addr = prev_head(start, f->startEA); while (addr != BADADDR) { flags_t flags = getFlags(addr); if (isHead(flags) && isCode(flags)) { ua_ana0(addr); switch(cmd.itype){ case NN_lea: case NN_pop: case NN_shl: case NN_shr: case NN_sal: case NN_sar: case NN_imul: case NN_mul: case NN_idiv: case NN_div: case NN_xor: case NN_or: case NN_not: case NN_neg: case NN_inc: case NN_dec: case NN_add: case NN_sub: case NN_mov: case NN_movsx: case NN_movzx:{ for(int i = 0; cmd.Operands[i].type != o_void; i++){ if((cmd.Operands[i].type == operand.type) && (cmd.Operands[i].reg == operand.reg)){ return addr; } }break; default:break; } } } addr = prev_head(addr, f->startEA); } } return BADADDR; }
//-------------------------------------------------------------------------- void load_file(linput_t *li, ushort /*neflag*/, const char * /*fileformatname*/) { header h; qlseek(li, 0); lread(li, &h, sizeof(h)); h.swap(); if ( ph.id != PLFM_HPPA ) set_processor_type("hppa", SETPROC_ALL|SETPROC_FATAL); inf.baseaddr = 0; load_aux_headers(li, h.aux_header_location, h.aux_header_size); load_spaces(li, h, h.space_location, h.space_total); load_subspaces(li, h, h.subspace_location, h.subspace_total); load_symbols(li, h, h.symbol_location, h.symbol_total); load_dl_header(li); create_filename_cmt(); ulong dp = h.presumed_dp; if ( dp == 0 ) { // 23 61 28 00 ldil ...., %dp // 37 7B 01 60 ldo 0xB0(%dp), %dp if ( ua_ana0(inf.startIP) && cmd.Op1.type == o_imm && cmd.Op2.type == o_reg ) { ulong v = cmd.Op1.value; if ( ua_ana0(cmd.ea+4) && cmd.Op1.type == o_displ ) dp = v + cmd.Op1.addr; } } if ( dp != 0 ) { netnode n; n.create("$ got"); n.altset(0, dp+1); } add_til("hpux"); }
char get_byte_with_optimization(ea_t ea) { switch (patchdiff_cpu) { case CPU_X8632: case CPU_X8664: return x86_get_byte(ea); case CPU_PPC: return ppc_get_byte(ea); default: { ua_ana0(ea); return (char)cmd.itype; } } }
ea_t find_instruction_backward(ea_t start, uint16 itype) { func_t *f = get_func(start); if(f) { ea_t addr = prev_head(start, f->startEA); while (addr != BADADDR) { flags_t flags = getFlags(addr); if (isHead(flags) && isCode(flags)) { ua_ana0(addr); if(cmd.itype == itype)return addr; } addr = prev_head(addr, f->startEA); } } return BADADDR; }
void pretty_printing_ex(FILE* f, TFuncMalloc func) { func_t *callee_func; qstring name_of_malloc_callee_function; int func_name_set = 0; for(int i = 0; i < Malloc_calls.size(); i++){ qfprintf(f,"\r\n"); callee_func = get_func(Malloc_calls[i].address); func_name_set = 0; if(callee_func){ func_name_set = 1; get_short_name(&name_of_malloc_callee_function, callee_func->startEA); //generate_disasm_line(callee_func->startEA, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function)); //tag_remove(name_of_malloc_callee_function, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function)); } if(func_name_set) qfprintf(f,"%s xref: at %a %s\n", func.alloc_func_name, Malloc_calls[i].address, name_of_malloc_callee_function.c_str()); else qfprintf(f,"%s xref: at %a %s\n", func.alloc_func_name, Malloc_calls[i].address, "CISSRT_undefined_function"); if(Malloc_calls[i].type == CONSTVALUE){ qfprintf(f,"Type: CONST = %d Malloc bytes\n", Malloc_calls[i].value); } if(Malloc_calls[i].type == VARVALUE){ char buffer[MAXSTR]; //char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buffer, sizeof(buffer)); tag_remove(buffer, buffer, sizeof(buffer)); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: VAR, last modif at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, buffer); else qfprintf(f,"Type: VAR, last modif lost :( \n"); //qfprintf(f,"last modif: \n", instr_clean); } if(Malloc_calls[i].type == VARVALUEVULN){ char buffer[MAXSTR]; //char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buffer, sizeof(buffer)); tag_remove(buffer, buffer, sizeof(buffer)); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: VAR, Possible Integer Overflow %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, buffer); else qfprintf(f,"Type: VAR, last modif lost :( \n");//shouldnt be here } if(Malloc_calls[i].type == UNDEFINED){ char buffer[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buffer, sizeof(buffer)); tag_remove(buffer, buffer, sizeof(buffer)); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: UNDEFINED, at %a %s", Malloc_calls[i].address_of_last_size_object_modified, buffer);//shouldnt be here else qfprintf(f,"Type: UNDEFINED, last modif lost :("); } } }
void pretty_printing_ex(FILE* f, TFuncMallocWrapper func) { func_t *callee_func; qstring name_of_malloc_callee_function; int func_name_set = 0; for(int i = 0; i < Malloc_calls.size(); i++){ //qfprintf(f,"%s ----> %s xref: at %a \n", func.alloc_func_name, func.ancestor, Malloc_calls[i].address); qfprintf(f,"\r\n"); callee_func = get_func(Malloc_calls[i].address); func_name_set = 0; if(callee_func){ func_name_set = 1; get_short_name(&name_of_malloc_callee_function, callee_func->startEA); //generate_disasm_line(callee_func->startEA, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function)); //tag_remove(name_of_malloc_callee_function, name_of_malloc_callee_function, sizeof(name_of_malloc_callee_function)); } if(func_name_set) qfprintf(f,"%s argNumber = %d ----> %s xref: at %a %s\n", func.alloc_func_name, func.push_malloc_size_count, func.ancestor, Malloc_calls[i].address, name_of_malloc_callee_function.c_str()); else qfprintf(f,"%s argNumber = %d ----> %s xref: at %a %s\n", func.alloc_func_name, func.push_malloc_size_count, func.ancestor, Malloc_calls[i].address, "CISSRT_undefined_function"); //qfprintf(f,"%s xref: at %a %s\n", func.alloc_func_name, Malloc_calls[i].address, "CISSRT_undefined_function"); if(Malloc_calls[i].type == CONSTVALUE){ qfprintf(f,"Type: CONST = %d Malloc bytes\n", Malloc_calls[i].value); } else if(Malloc_calls[i].type == VARVALUE){ char buf[MAXSTR]; char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buf, sizeof(buf)-1); // This will appear as colour-tagged text (which will // be mostly unreadable in IDA's tag_remove(buf, instr_clean, sizeof(instr_clean)-1); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: VAR, last modif at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, instr_clean); else qfprintf(f,"Type: VAR, last modif lost :("); //qfprintf(f,"last modif: %s\n", instr_clean); } else if(Malloc_calls[i].type == VARVALUEVULN){ char buf[MAXSTR]; char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buf, sizeof(buf)-1); // This will appear as colour-tagged text (which will // be mostly unreadable in IDA's tag_remove(buf, instr_clean, sizeof(instr_clean)-1); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: VAR, Possible Integer Overflow at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, instr_clean); else qfprintf(f,"Type: VAR, last modif lost :("); } else if(Malloc_calls[i].type == UNDEFINED){ char buf[MAXSTR]; char instr_clean[MAXSTR]; // Store the disassembled text in buf ua_ana0(Malloc_calls[i].address_of_last_size_object_modified); generate_disasm_line(cmd.ea, buf, sizeof(buf)-1); // This will appear as colour-tagged text (which will // be mostly unreadable in IDA's tag_remove(buf, instr_clean, sizeof(instr_clean)-1); //qfprintf(f,"get_first_operand disasm instruction: %s\n", instr_clean); //qfprintf(f,"Type:var bytes, Possible Integer Overflow at %a %s\n", Malloc_calls[i].address_of_last_size_object_modified, instr_clean); if(Malloc_calls[i].address_of_last_size_object_modified != BADADDR) qfprintf(f,"Type: UNDEFINED, at %a %s", Malloc_calls[i].address_of_last_size_object_modified, instr_clean);//shouldnt be here else qfprintf(f,"Type: UNDEFINED, last modif lost :("); } } }
int is_trampoline(ea_t address) { ua_ana0(address); if(cmd.itype == NN_jmp)return 1; return 0; }
int PPCHelper_ConvertFunction(func_t* pFunc) { ea_t start = pFunc->startEA; ea_t end = pFunc->endEA; // struc_t* p_frame = get_frame(pFunc); const int MAX_REGS = 32; bool is_reg_saved[MAX_REGS]; // r0 - r31 for(int i=0; i<MAX_REGS; i++) is_reg_saved[i] = false; bool is_arg_saved[MAX_REGS]; // r0 - r31 for(int i=0; i<MAX_REGS; i++) is_arg_saved[i] = false; // process function from start to end for(ea_t ea=start; ea<end; ea+=4) { // get mnemonic char mnem[256]; if( !ua_mnem(ea, mnem, sizeof(mnem)) ) return false; tag_remove(mnem, mnem, sizeof(mnem)); char* ptr = (char*)qstrstr(mnem, "."); if(ptr) *ptr = 0; // prepare cmd struct for this address ua_ana0(ea); // fix mnemonic for "bl" if( cmd.itype == 13 && (cmd.auxpref & 8) ) { qstrncpy(mnem, "bl", sizeof(mnem)); } // fix mnemonic for "blr" else if( cmd.itype == 320 && cmd.auxpref == 0x500 ) { qstrncpy(mnem, "blr", sizeof(mnem)); } // handle register saving if( (!qstrcmp(mnem, "stdu") || !qstrcmp(mnem, "std")) && cmd.Op1.type == o_reg && cmd.Op2.type == o_displ && !is_reg_saved[cmd.Op1.reg] && cmd.Op2.reg == 1 ) // 1 == "sp" { int src_reg = cmd.Op1.reg; int offset = cmd.Op2.addr; int dst_reg = cmd.Op2.reg; char name[256]; if( src_reg == 0 ) qsnprintf(name, sizeof(name), "save_lr"); else if( src_reg == 1 ) qsnprintf(name, sizeof(name), "save_sp"); else qsnprintf(name, sizeof(name), "save_r%d", src_reg); add_stkvar2(pFunc, name, offset, 0, NULL, 0); is_reg_saved[cmd.Op1.reg] = true; //msg("%08X : stdu %%r%d, %d(%%r%d)\n", (unsigned int)ea, src_reg, offset, dst_reg); } // handle arg saving else if( !qstrcmp(mnem, "mr") && cmd.Op1.type == o_reg && cmd.Op2.type == o_reg && !is_arg_saved[cmd.Op2.reg] && cmd.Op2.reg >= 3 ) // args begin at r3 { int dst_reg = cmd.Op1.reg; int src_reg = cmd.Op2.reg; char canon[256]; qsnprintf(canon, sizeof(canon), "%%r%d", dst_reg); char name[256]; qsnprintf(name, sizeof(name), "arg%d", src_reg-3); add_regvar(pFunc, start, end, canon, name, NULL); is_arg_saved[cmd.Op2.reg] = true; //msg("%08X : mr %%r%d, %%r%d\n", (unsigned int)ea, dst_reg, src_reg); } // if a function is called, then no more args can be saved else if( !qstrcmp(mnem, "bl") ) { break; } } // process function from start to end msg("processing end to start (%08X to %08X) - %d\n", (unsigned int)end, (unsigned int)start, PPC_balways); bool is_in_return_point = false; for(ea_t ea=end-4; ea>start; ea-=4) { // get mnemonic char mnem[256]; if( !ua_mnem(ea, mnem, sizeof(mnem)) ) return false; tag_remove(mnem, mnem, sizeof(mnem)); char* ptr = (char*)qstrstr(mnem, "."); if(ptr) *ptr = 0; // prepare cmd struct for this address ua_ana0(ea); // fix mnemonic for "bl" if( cmd.itype == 13 && (cmd.auxpref & 8) ) { qstrncpy(mnem, "bl", sizeof(mnem)); } // fix mnemonic for "blr" else if( cmd.itype == 320 && cmd.auxpref == 0x500 ) { qstrncpy(mnem, "blr", sizeof(mnem)); } // msg("%08X: %3s inst_type = %d, insgpref = %d, segpref = %d, auxpref = %d\n", (unsigned int)ea, mnem, cmd.itype, cmd.segpref, cmd.insnpref, cmd.auxpref); //qstrncpy(mnem, "bl", sizeof(mnem)); /* msg("%08X: %s %d %d %d (%d %d %d %d) (%d %d %d %d) (%d %d %d %d) : %X %X %X : %X %X %X : %X %X %X : %X %X %X : %X %X %X : %X %X %X\n", (unsigned int)ea, mnem, cmd.Op1.type, cmd.Op2.type, cmd.Op3.type, cmd.Op1.specflag1, cmd.Op1.specflag2, cmd.Op1.specflag3, cmd.Op1.specflag4, cmd.Op2.specflag1, cmd.Op2.specflag2, cmd.Op2.specflag3, cmd.Op2.specflag4, cmd.Op3.specflag1, cmd.Op3.specflag2, cmd.Op3.specflag3, cmd.Op3.specflag4, (unsigned int)cmd.Op1.specval, (unsigned int)cmd.Op2.specval, (unsigned int)cmd.Op3.specval, (unsigned int)cmd.Op1.addr, (unsigned int)cmd.Op2.addr, (unsigned int)cmd.Op3.addr, (unsigned int)cmd.Op1.value, (unsigned int)cmd.Op2.value, (unsigned int)cmd.Op3.value, (unsigned int)cmd.Op1.reg, (unsigned int)cmd.Op2.reg, (unsigned int)cmd.Op3.reg, (unsigned int)cmd.Op1.dtyp, (unsigned int)cmd.Op2.dtyp, (unsigned int)cmd.Op3.dtyp, (unsigned int)cmd.Op1.flags, (unsigned int)cmd.Op2.flags, (unsigned int)cmd.Op3.flags); } */ // if found a function return point, then look above for return register if( !qstrcmp(mnem, "blr") ) { is_in_return_point = true; //msg("%08X return point end\n", (unsigned int)ea); } // if a function is called, thenit is no longer in the return point else if( !qstrcmp(mnem, "bl") ) { is_in_return_point = false; //msg("%08X return point start\n", (unsigned int)ea); } // look for possible return register else if( is_in_return_point && !qstrcmp(mnem, "mr") && cmd.Op1.type == o_reg && cmd.Op2.type == o_reg && cmd.Op1.reg == 3 ) // return value is in r3 { int dst_reg = cmd.Op1.reg; int src_reg = cmd.Op2.reg; char canon[256]; qsnprintf(canon, sizeof(canon), "%%r%d", src_reg); add_regvar(pFunc, start, end, canon, "ret", NULL); //msg("%08X return register\n", (unsigned int)ea); } } // analyse area to refresh any changes analyze_area(start, end); return 0; }
/* main workhorse */ void process_PIC(ea_t from, ea_t to) { int size; flags_t flag; dref_t dtype; bool has_PIC_init = false; /***********************************************************\ * Also we trace three special cases: * 1. Raw (not recognized ed by IDA) PIC prolog. * call $+5 * pop ebx <-- fake_addr * ... one or more non related with ebx instr * add ebx, offset_to_GOT * 2. Switch stmt * a) with known size N * cmp reg1, N * ja ... * mov reg2, ebx * sub reg2, [ebx+reg1*4+offset] * jmp reg2 * b) more general but size is unknown * mov reg1, ebx * sub reg1, [ebx+regX*4+offset] * jmp reg1 * 3. On UnixWare 7 UDK C compiler produced prolog * jmp end_of_function * main_function_body: * ... * end_of_function: * prolog like 1) * jmp main_function_body \***********************************************************/ int first_case = 0; ea_t fake_addr = 0; ea_t pic_to = 0; int second_case = 0; int reg1 = pic_reg, reg2, N = 0, offset; int second_caseB = 0; int there_jump = 0, from_jump, to_jump; #ifdef PIC_DEBUG RP_TRACE1("start %X\n", from); RP_TRACE1("end %X\n", to); #endif for ( ea_t a = from; a < to; ) { flag = getFlags(a); if ( !isCode(flag) ) { a++; continue; } size = ua_ana0(a); #define PIC_CONT a += size; continue; if ( !size ) { warning("Bad instruction at %X", a); a++; continue; } #ifdef PIC_SHOW report_instr(a); #endif if ( !has_PIC_init ) { if ( !there_jump ) { if ( cmd.itype == Ix86_jmp && ( cmd.Op1.type == o_near || cmd.Op1.type == o_far ) && cmd.Op1.addr < to && cmd.Op1.addr > a ) { from_jump = a + size; there_jump = 1; to_jump = a = cmd.Op1.addr; #ifdef PIC_DEBUG RP_TRACE2("from_jump %X, to_jump %X\n", from_jump, to_jump); #endif continue; } there_jump = -1; } if ( !first_case && is_gotbase() ) { first_case = 2; fake_addr = a + size; PIC_CONT; } if ( first_case ) switch(first_case) { case 1: if ( cmd.itype == Ix86_pop && cmd.Op1.type == o_reg && cmd.Op1.reg == pic_reg ) { first_case = 2; #ifdef PIC_DEBUG RP_TRACE("first case 2\n"); #endif } else { if ( is_change_stack(&cmd) ) { first_case = 0; } else { PIC_CONT; } } break; case 2: if ( cmd.itype == Ix86_add && cmd.Op1.type == 1 && cmd.Op1.reg == pic_reg && cmd.Op2.type == o_imm ) { pic_to = fake_addr + cmd.Op2.value; if ( (pic_to != got_addr) && (pic_to != got_plt_addr) ) warning("Strange PIC prolog at %X, points to %X", a, pic_to); #ifdef PIC_DEBUG RP_TRACE("PIC_init 1\n"); #endif pic_add_dref(a, pic_to, dr_O, cmd.Op2.dtyp); has_PIC_init = true; first_case = 0; } if ( is_change_PIC_reg(&cmd) ) { first_case = 0; } break; } if ( first_case || has_PIC_init ) { PIC_CONT; } if ( cmd.itype == Ix86_mov && cmd.Op1.type == o_reg && cmd.Op1.reg == pic_reg && cmd.Op2.type == o_imm && cmd.Op2.value == got_addr ) { has_PIC_init = true; #ifdef PIC_DEBUG RP_TRACE("PIC_init 2\n"); #endif PIC_CONT; } if ( cmd.itype == Ix86_call && cmd.Op1.type == o_near && cmd.Op1.addr == a + 5 ) { first_case = 1; fake_addr = a + size; #ifdef PIC_DEBUG RP_TRACE("first_case 1\n"); #endif PIC_CONT; } PIC_CONT; } /* not prolog yet */ if ( there_jump == 1 && cmd.itype == Ix86_jmp && ( cmd.Op1.type == o_near || cmd.Op1.type == o_far ) && cmd.Op1.addr < to && cmd.Op1.addr < a && cmd.Op1.addr >= from_jump ) { there_jump = 2; a = from_jump; to = to_jump; continue; } if ( second_case ) switch(second_case) { case 1: if ( cmd.itype == Ix86_ja && (cmd.Op1.type == o_far || cmd.Op1.type == o_near) ) { #ifdef PIC_DEBUG RP_TRACE("second_case 2\n"); #endif second_case = 2; } else { second_case = 0; } break; case 2: if ( cmd.itype == Ix86_mov && cmd.Op1.type == o_reg && cmd.Op2.type == o_reg && cmd.Op2.reg == pic_reg ) { reg2 = cmd.Op1.reg; #ifdef PIC_DEBUG RP_TRACE("second_case 3\n"); #endif second_case = 3; } else { second_case = 0; } break; case 3: if ( cmd.itype == Ix86_sub && cmd.Op1.type == o_reg && cmd.Op1.reg == reg2 && cmd.Op2.type == o_displ && cmd.Op2.specflag1 == 1 && get_SIB_base(cmd.Op2.specflag2) == pic_reg && get_SIB_reg(cmd.Op2.specflag2) == reg1 && get_SIB_SS(cmd.Op2.specflag2) == 2 ) /* wow! sub reg2, [pic_reg+reg1*4+offset] */ { offset = cmd.Op2.addr; pic_add_dref(a, pic_to + offset, dr_O, cmd.Op2.dtyp); #ifdef PIC_DEBUG RP_TRACE("second_case 4\n"); #endif second_case = 4; } else { #ifdef PIC_DEBUG RP_TRACE5("%d <-> %d, %d <-> %d, %d\n", get_SIB_base(cmd.Op2.specflag2), pic_reg, get_SIB_reg(cmd.Op2.specflag2), reg1, get_SIB_SS(cmd.Op2.specflag2) ); #endif second_case = 0; } break; case 4: if ( cmd.itype == Ix86_jmpni && cmd.Op1.type == o_reg && cmd.Op1.reg == reg2 ) { #ifdef PIC_DEBUG RP_TRACE2("second_case: %d from %X\n", N, (got_addr + offset) ); #endif process_switchA(a+size, pic_to + offset, N); second_case = 0; PIC_CONT; } else { second_case = 0; } break; } if ( second_case ) { PIC_CONT; } if ( cmd.itype == Ix86_cmp && cmd.Op1.type == o_reg && cmd.Op2.type == o_imm ) { second_case = 1; reg1 = cmd.Op1.reg; N = cmd.Op2.value; PIC_CONT; } /* check for 2b case */ if ( second_caseB ) switch(second_caseB) { case 1: if ( cmd.itype == Ix86_sub && cmd.Op1.type == o_reg && cmd.Op1.reg == reg1 && cmd.Op2.type == o_displ && cmd.Op2.specflag1 == 1 && get_SIB_base(cmd.Op2.specflag2) == pic_reg && get_SIB_reg(cmd.Op2.specflag2) != pic_reg && get_SIB_SS(cmd.Op2.specflag2) == 2 ) { offset = cmd.Op2.addr; second_caseB = 2; #ifdef PIC_DEBUG RP_TRACE("second_caseB is 2\n"); #endif } else { #ifdef PIC_DEBUG RP_TRACE5("%d <-> %d, %d <-> %d, %d\n", get_SIB_base(cmd.Op2.specflag2), pic_reg, get_SIB_reg(cmd.Op2.specflag2), reg1, get_SIB_SS(cmd.Op2.specflag2) ); #endif second_caseB = 0; } break; case 2: if ( cmd.itype == Ix86_jmpni && cmd.Op1.type == o_reg && cmd.Op1.reg == reg1 ) { #ifdef PIC_DEBUG RP_TRACE1("second_caseB: from %X\n", (got_addr + offset) ); #endif process_switchB(a+size, pic_to + offset, to); second_caseB = 0; PIC_CONT; } else { second_caseB = 0; } break; } /* second_caseB switch */ if ( cmd.itype == Ix86_mov && cmd.Op1.type == o_reg && cmd.Op2.type == o_reg && cmd.Op2.reg == pic_reg ) { second_caseB = 1; reg1 = cmd.Op1.reg; #ifdef PIC_DEBUG RP_TRACE("second_caseB is 1\n"); #endif PIC_CONT; /* ?? we anyway don`t deal with such instruction... */ } /* no more special cases... */ /* check for 1st operand for pic_reg */ if ( cmd.Op1.type == o_displ ) { if ( cmd.Op1.phrase == pic_reg && ! cmd.Op1.specflag1 ) { fake_addr = 0; if ( exists_addr(&cmd.Op1) ) fake_addr = cmd.Op1.addr; dtype = get_dreftype_op1(&cmd); pic_add_dref(a, pic_to + fake_addr, dtype, cmd.Op1.dtyp); #ifdef PIC_DEBUG RP_TRACE1("PIC: %X\n", got_addr + fake_addr); #endif PIC_CONT; } if ( cmd.Op1.specflag1 == 1 && ( ( get_SIB_base(cmd.Op1.specflag2) == pic_reg && get_SIB_reg(cmd.Op1.specflag2) != pic_reg ) || ( get_SIB_base(cmd.Op1.specflag2) != pic_reg && get_SIB_reg(cmd.Op1.specflag2) == pic_reg && get_SIB_SS(cmd.Op1.specflag2) == 0 ) ) ) { fake_addr = 0; if ( exists_addr(&cmd.Op1) ) fake_addr = cmd.Op1.addr; dtype = get_dreftype_op1(&cmd); pic_add_dref(a, pic_to + fake_addr, dtype, cmd.Op1.dtyp); #ifdef PIC_DEBUG RP_TRACE1("PIC: %X\n", got_addr + fake_addr); #endif PIC_CONT; } } /* check for 2nd operand for pic_reg */ if ( cmd.Op2.type == o_displ ) { if ( cmd.Op2.phrase == pic_reg && ! cmd.Op2.specflag1 ) { fake_addr = 0; if ( exists_addr(&cmd.Op2) ) fake_addr = cmd.Op2.addr; pic_add_dref(a, pic_to + fake_addr, get_dreftype_op2(&cmd), cmd.Op2.dtyp); #ifdef PIC_DEBUG RP_TRACE1("PIC: %X\n", got_addr + fake_addr); #endif PIC_CONT; } if ( cmd.Op2.specflag1 == 1 && ( ( get_SIB_base(cmd.Op2.specflag2) == pic_reg && get_SIB_reg(cmd.Op2.specflag2) != pic_reg ) || ( get_SIB_base(cmd.Op2.specflag2) != pic_reg && get_SIB_reg(cmd.Op2.specflag2) == pic_reg && get_SIB_SS(cmd.Op2.specflag2) == 0 ) ) ) { fake_addr = 0; if ( exists_addr(&cmd.Op2) ) fake_addr = cmd.Op2.addr; #ifdef PIC_DEBUG RP_TRACE1("PIC: %X\n", got_addr + fake_addr); #endif pic_add_dref(a, pic_to + fake_addr, get_dreftype_op2(&cmd), cmd.Op2.dtyp); PIC_CONT; } } a += size; } }
int dline_add(dline_t * dl, ea_t ea, char options) { char buf[256]; char tmp[256]; char dis[256]; char addr[30]; char * dll; int len; flags_t f; buf[0] = '\0'; f = getFlags(ea); generate_disasm_line(ea, dis, sizeof(dis)); ua_ana0(ea); init_output_buffer(buf, sizeof(buf)); // Adds block label if (has_dummy_name(f)) { get_nice_colored_name(ea,tmp,sizeof(tmp),GNCN_NOSEG|GNCN_NOFUNC); out_snprintf("%s", tmp); out_line(":\n", COLOR_DATNAME); } if (options) { qsnprintf(addr, sizeof(addr), "%lu", (unsigned long)ea); out_snprintf("%s ", addr); } out_insert(get_output_ptr(), dis); term_output_buffer(); len = strlen(buf); if (dl->available < (len+3)) { dll = (char *)qrealloc(dl->lines, sizeof(char*) * (dl->num+len+256)); if (!dll) return -1; dl->available = len+256; dl->lines = dll; } if (dl->num) { dl->lines[dl->num] = '\n'; dl->num++; } memcpy(&dl->lines[dl->num], buf, len); dl->available -= len+1; dl->num += len; dl->lines[dl->num] = '\0'; return 0; }