int ConnectBrokenFunctionChunk(ea_t address) { int connected_links_count=0; func_t *func=get_func(address); char function_name[1024]={0,}; get_func_name(address,function_name,sizeof(function_name)); bool is_function=false; bool AddFunctionAsMemberOfFunction=false; ea_t cref=get_first_cref_to(address); while(cref!=BADADDR) { func_t *cref_func=get_func(cref); if(cref_func!=func) { char op_buffer[40]={0,}; ua_mnem(cref,op_buffer,sizeof(op_buffer)); if(cmd.itype==NN_call || cmd.itype==NN_callfi || cmd.itype==NN_callni) { is_function=true; break; } } cref=get_next_cref_to(address,cref); } if(!is_function) { if(func) del_func(address); cref=get_first_cref_to(address); while(cref!=BADADDR) { func_t *cref_func=get_func(cref); if(cref_func) { char cref_function_name[1024]; get_func_name(cref,cref_function_name,sizeof(cref_function_name)); msg("Adding Location %s(%x) To Function Member Of %s(%x:%x)\n",function_name,address,cref_function_name,cref_func->startEA,cref); append_func_tail(cref_func,address,GetBlockEnd(address)); connected_links_count++; } cref=get_next_cref_to(address,cref); } }else if(AddFunctionAsMemberOfFunction) { cref=get_first_cref_to(address); while(cref!=BADADDR) { char op_buffer[40]={0,}; ua_mnem(cref,op_buffer,sizeof(op_buffer)); if(!(cmd.itype==NN_call || cmd.itype==NN_callfi || cmd.itype==NN_callni)) { func_t *cref_func=get_func(cref); if(cref_func) { char cref_function_name[1024]; get_func_name(cref,cref_function_name,sizeof(cref_function_name)); msg("Adding Function %s(%x) To Function Member Of %s(%x:%x)\n",function_name,address,cref_function_name,cref_func->startEA,cref); append_func_tail(cref_func,address,GetBlockEnd(address)); connected_links_count++; } } cref=get_next_cref_to(address,cref); } } return connected_links_count; }
bool idaapi dump_funcs_ctree(void *ud, qstring &crypto_prefix) { logmsg(DEBUG, "dump_funcs_ctree entered\n"); std::map<ea_t, ctree_dump_line> data_to_dump; // enumerate through all the functions in the idb file bool heuristic_flag; size_t count = 0, heur_count = 0, crypto_count = 0; size_t total_func_qty = get_func_qty(); for (size_t i = 0 ; i < total_func_qty ; i ++) { heuristic_flag = 0; func_t *function = getn_func(i); if (function != NULL) { bool crypto_flag = func_name_has_prefix(crypto_prefix, function->startEA); // skip libs that are not marked as crypto if ( ((function->flags & FUNC_LIB) != 0) && !crypto_flag ) continue; // From this point on, we have a function outside of lib or a crypto one // Ignore functions less than MIN_FUNC_SIZE_DUMP bytes if ( ((function->endEA - function->startEA) < MIN_FUNC_SIZE_DUMP) && !crypto_flag ) continue; // If function is bigger than MIN_HEURISTIC_FUNC_SIZE_DUMP, mark as being triggered by the heuristic if (function->endEA - function->startEA > MIN_HEURISTIC_FUNC_SIZE_DUMP) heuristic_flag = 1; // dump up to N_CRYPTO_FUNCS_TO_DUMP crypto functions // dump up to N_HEUR_FUNCS_TO_DUMP heuristic functions // at least N_FUNCS_TO_DUMP functions will be dumped if ((count < N_FUNCS_TO_DUMP) || (crypto_flag && (crypto_count < N_CRYPTO_FUNCS_TO_DUMP)) || (heuristic_flag && (heur_count < N_HEUR_FUNCS_TO_DUMP))) { hexrays_failure_t hf; cfuncptr_t cfunc = decompile(function, &hf); logmsg(DEBUG, "\nafter decompile()\n"); if (cfunc != NULL) { ctree_dumper_t ctree_dumper; ctree_dumper.apply_to(&cfunc->body, NULL); ctree_dump_line func_dump; func_dump.ctree_dump = ctree_dumper.ctree_dump; func_dump.ctree_for_hash = ctree_dumper.ctree_for_hash; func_dump.func_depth = -1; func_dump.func_start = function->startEA; func_dump.func_end = function->endEA; qstring func_name; if (get_func_name2(&func_name, function->startEA) != 0) { if (func_name.length() > 0) { func_dump.func_name = func_name; } } func_parent_iterator_t fpi(function); for (ea_t addr = get_first_cref_to(function->startEA); addr != BADADDR; addr = get_next_cref_to(function->startEA, addr)) { func_t *referer = get_func(addr); if (referer != NULL) { func_dump.referres.push_back(referer->startEA); } } func_dump.heuristic_flag = heuristic_flag; // 0 or 1 depending on code above if (heuristic_flag) heur_count++; if (crypto_flag) crypto_count++; count++; data_to_dump[function->startEA] = func_dump; } } } } dump_ctrees_in_file(data_to_dump, crypto_prefix); return true; }
//---------------------------------------------------------------------- static int idaapi notify(processor_t::idp_notify msgid, ...) // Various messages: { va_list va; va_start(va, msgid); // A well behaved processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; int retcode = 1; switch ( msgid ) { case processor_t::init: helper.create("$ spc700"); break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::oldfile: case processor_t::newfile: { char buf[MAXSTR]; const char *device_ptr = buf; ssize_t len = helper.hashstr("device", buf, sizeof(buf)); if ( len <= 0 ) device_ptr = "spc700"; if ( msgid == processor_t::newfile ) { set_device_name(device_ptr, IORESP_ALL); set_dsp_regs_enum(); set_default_segreg_value(NULL, rDs, 0); set_default_segreg_value(NULL, rFp, 0); } } break; case processor_t::may_be_func: retcode = 0; ea_t cref_addr; for( cref_addr = get_first_cref_to(cmd.ea); cref_addr != BADADDR; cref_addr = get_next_cref_to(cmd.ea, cref_addr) ) { uint8 opcode = get_byte(cref_addr); const struct opcode_info_t &opinfo = get_opcode_info(opcode); if ( opinfo.itype == SPC_call || opinfo.itype == SPC_jmp ) { retcode = 100; break; } } break; case processor_t::is_call_insn: { const struct opcode_info_t &opinfo = get_opcode_info(get_byte(va_arg(va, ea_t))); if ( opinfo.itype == SPC_call ) retcode = 2; else retcode = 0; } break; case processor_t::is_ret_insn: { const struct opcode_info_t &opinfo = get_opcode_info(get_byte(va_arg(va, ea_t))); if ( opinfo.itype == SPC_ret || opinfo.itype == SPC_reti ) retcode = 2; else retcode = 0; } break; case processor_t::is_indirect_jump: { const struct opcode_info_t &opinfo = get_opcode_info(get_byte(va_arg(va, ea_t))); if ( opinfo.itype == SPC_jmp ) { if ( opinfo.addr == ABS_IX_INDIR ) retcode = 3; else retcode = 2; } else retcode = 1; } break; default: break; } va_end(va); return retcode; }