// Get pointer to func_t by routine name func_t * get_func_by_name(const char *func_name) { func_t * result_func = NULL; size_t func_total = get_func_qty(); if (func_total > 0) { char tmp[1024]; for (unsigned int i = 0; i < func_total - 1; i++) { func_t * func = getn_func(i); if (func != NULL) { memset(tmp, 0x00, sizeof(tmp)); char *func_n = get_func_name(func->startEA, tmp, sizeof(tmp)); if (func_n != NULL) { if (!strcmp(func_name, func_n)) { result_func = func; break; } } } } } return result_func; }
QStringList Ida2db::getAllNamedFunctions() { QStringList output; int numOfFuncs = get_func_qty(); if (numOfFuncs <= 0) { (void) msg("IDB2SIG: Not found any functions\n"); return output; } int i = 0; //size_t len = 0; func_t* pFunc = NULL; for (i = 0; i < numOfFuncs; i++) { pFunc = getn_func(i); if ((NULL != pFunc) && has_name(getFlags(pFunc->startEA)) && !(pFunc->flags & FUNC_LIB)) { char buf[512]; get_true_name(BADADDR, pFunc->startEA, buf, sizeof(buf)); //get_segm_name(pFunc->startEA, buf, sizeof buf); output.append(buf); //len += make_func_sig(pFunc->startEA, // (ulong) (pFunc->endEA - pFunc->startEA), // &pSigBuf[len]); } } return output; }
std::vector<ByteAddr> IdaFrontend::functionStarts() { std::vector<ByteAddr> result; for(std::size_t i = 0, n = get_func_qty(); i < n; i++) { func_t *func = getn_func(i); if(func != NULL) result.push_back(func->startEA); } return result; }
//ea_t find_function_EA_by_name(FILE *file, char *name) ea_t find_function_EA_by_name(char *name) { int count = strlen(name); for (uint i = 0; i < get_func_qty(); ++i) { func_t *f = getn_func(i); qstring buffer; get_short_name(&buffer, f->startEA); //qfprintf(file,"%s \n", buffer); if(strncmp(buffer.c_str(), name, count) == 0){ return f->startEA; } } return BADADDR; }
//ea_t find_function_EA_by_name(FILE *file, char *name) ea_t find_function_EA_by_name(char *name) { int count = strlen(name); for (uint i = 0; i < get_func_qty(); ++i) { func_t *f = getn_func(i); char buffer[MAXSTR]; get_short_name(BADADDR, f->startEA, buffer, MAXSTR); //qfprintf(file,"%s \n", buffer); if(strncmp(buffer, name, count) == 0){ return f->startEA; } } return BADADDR; }
void FindInvalidFunctionStartAndConnectBrokenFunctionChunk() { int connected_links_count=0; do { connected_links_count=0; for(int i=0;i<get_func_qty();i++) { func_t *f=getn_func(i); char function_name[100]={0,}; get_func_name(f->startEA,function_name,sizeof(function_name)); if(!IsValidFunctionStart(f->startEA)) { connected_links_count+=ConnectBrokenFunctionChunk(f->startEA); } } }while(connected_links_count>0); }
slist_t * parse_idb() { slist_t * sl; psig_t * sig; size_t fct_num, i; qvector<ea_t> class_l; fct_num = get_func_qty(); sl = siglist_init(fct_num, NULL); if (!sl) return NULL; for (i=0; i<fct_num; i++) { sig = sig_generate(i, class_l); if (sig) { // removes 1 line jump functions if (sig->sig == 0 || sig->lines <= 1) sig_free(sig); else siglist_add(sl, sig); } } if (!siglist_realloc(sl, class_l.size())) { siglist_free(sl); return NULL; } for (i=0; i<class_l.size(); i++) { sig = sig_class_generate(class_l[i]); if (sig) siglist_add(sl, sig); } siglist_sort(sl); return sl; }
// dump_cfgs dumps the control flow graph of each function contained within the // executable and stores them as DOT files within a /tmp/punkt.XXXXXX directory. void dump_cfgs() { char pattern[] = "/tmp/punkt.XXXXXX"; char *dir = mkdtemp(pattern); if (dir == NULL) { warning("unable to create output directory `%s`", dir); return; } int nfuncs = get_func_qty(); for (int i = 0; i < nfuncs; i++) { func_t *f = getn_func(i); ea_t faddr = f->start_ea; char title[32]; qsnprintf(title, sizeof(title), "%08X", faddr); char dst_path[1024]; qsnprintf(dst_path, sizeof(dst_path), "%s/%08X.dot", dir, faddr); if (!gen_flow_graph(dst_path, title, f, 0, 0, CHART_GEN_DOT)) { warning("unable to generate CFG for function at address %08X", faddr); continue; } } warning("punkt completed successfully :) DOT files stored in `%s`", dir); }
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; }
int __stdcall NumFuncs (void){ return get_func_qty(); }
// Plug-in process void CORE_Process(int iArg) { try { char version[16]; sprintf(version, "%u.%u", HIBYTE(MY_VERSION), LOBYTE(MY_VERSION)); msg("\n>> WhatAPIs: v: %s, built: %s, By Sirmabus\n", version, __DATE__); if (!autoIsOk()) { msg("** Must wait for IDA to finish processing before starting plug-in! **\n*** Aborted ***\n\n"); return; } // Show UI refreshUI(); int uiResult = AskUsingForm_c(mainDialog, version, doHyperlink); if (!uiResult) { msg(" - Canceled -\n"); return; } WaitBox::show(); TIMESTAMP startTime = getTimeStamp(); // Build import segment bounds table { msg("Import segments:\n"); refreshUI(); SEGLIST segList; for (int i = 0; i < get_segm_qty(); i++) { if (segment_t *s = getnseg(i)) { if (s->type == SEG_XTRN) { char buffer[64] = { "unknown" }; buffer[SIZESTR(buffer)] = 0; get_true_segm_name(s, buffer, SIZESTR(buffer)); msg(" [%d] \"%s\" "EAFORMAT" - "EAFORMAT"\n", segmentCount, buffer, s->startEA, s->endEA); BOUNDS b = { s->startEA, s->endEA }; segList.push_back(b); segmentCount++; } } } refreshUI(); // Flatten list into an array for speed if (segmentCount) { UINT size = (segmentCount * sizeof(BOUNDS)); if (segmentPtr = (BOUNDS *)_aligned_malloc(size, 16)) { BOUNDS *b = segmentPtr; for (SEGLIST::iterator i = segList.begin(); i != segList.end(); i++, b++) { b->startEA = i->startEA; b->endEA = i->endEA; } } else { msg("\n*** Allocation failure of %u bytes! ***\n", size); refreshUI(); } } } if (segmentCount) { // Make a list of all import names if (int moduleCount = get_import_module_qty()) { for (int i = 0; i < moduleCount; i++) enum_import_names(i, importNameCallback); char buffer[32]; msg("Parsed %s module imports.\n", prettyNumberString(moduleCount, buffer)); refreshUI(); } // Iterate through all functions.. BOOL aborted = FALSE; UINT functionCount = get_func_qty(); char buffer[32]; msg("Processing %s functions.\n", prettyNumberString(functionCount, buffer)); refreshUI(); for (UINT n = 0; n < functionCount; n++) { processFunction(getn_func(n)); if (WaitBox::isUpdateTime()) { if (WaitBox::updateAndCancelCheck((int)(((float)n / (float)functionCount) * 100.0f))) { msg("* Aborted *\n"); break; } } } refresh_idaview_anyway(); WaitBox::hide(); msg("\n"); msg("Done. %s comments add/appended in %s.\n", prettyNumberString(commentCount, buffer), timeString(getTimeStamp() - startTime)); msg("-------------------------------------------------------------\n"); } else msg("\n*** No import segments! ***\n"); if (segmentPtr) { _aligned_free(segmentPtr); segmentPtr = NULL; } apiMap.clear(); } CATCH() }
void idaapi PIC_run(int arg) { ea_t curr_addr; int n_funcz, i; func_t *curr_func; if ( is_first ) { got_addr = get_name_ea(BADADDR, got_name); if ( BADADDR == got_addr ) { got_addr = get_name_ea(BADADDR,got_name1); if ( BADADDR != got_addr ) { got_addr = get_long(got_addr); } else { got_addr = get_name_ea(BADADDR, got_name2); } } is_first = false; // 2 Nov 2005: dirty hack, bcs get_name_ea("_got") return BADADDR segment_t *s; if ( BADADDR == got_addr ) { s = get_segm_by_name(".got"); if ( s != NULL ) got_addr = s->startEA; } // 14 oct 2009 s = get_segm_by_name(".got.plt"); if ( s != NULL ) got_plt_addr = s->startEA; } if ( BADADDR == got_addr ) { msg("Cannot resolve _got address. Bad plugin initialization"); return; } #ifdef PIC_DEBUG RP_TRACE1( "got_addr %X\n", got_addr ); #endif switch (arg) { case 0: /* only function under current EA */ curr_addr = get_screen_ea(); #ifdef PIC_DEBUG RP_TRACE1( "curr_addr %X\n", curr_addr ); #endif /* next I had to resolve function */ curr_func = get_func(curr_addr); if ( NULL == curr_func ) { warning("Cannot operate not on function, address %X\n", curr_addr); return; } #if defined(PIC_DEBUG) || defined(PIC_SHOW) rp_log_fp = fopen(log_filename, "w+t"); #endif process_PIC(curr_func->startEA, curr_func->endEA); #if defined(PIC_DEBUG) || defined(PIC_SHOW) if ( NULL != rp_log_fp ) { fclose(rp_log_fp); rp_log_fp = NULL; } #endif break; case 1: /* process all defined functions */ #if defined(PIC_DEBUG) || defined(PIC_SHOW) rp_log_fp = fopen(log_filename, "w+t"); #endif n_funcz = get_func_qty(); if ( !n_funcz ) { warning("No functions defined!"); return; } for ( i = 0; i < n_funcz; i++ ) { curr_func = getn_func(i); if ( NULL == curr_func ) { RP_TRACE1("PIC: cannot get func N %d\n", i); continue; } process_PIC(curr_func->startEA, curr_func->endEA); } #if defined(PIC_DEBUG) || defined(PIC_SHOW) if ( NULL != rp_log_fp ) { fclose(rp_log_fp); rp_log_fp = NULL; } #endif break; default: warning("PIC: Unknown arg %d", arg); break; } /* switch */ }