// 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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
//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;	
}
Beispiel #5
0
//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);
}
Beispiel #7
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;
}
Beispiel #8
0
// 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;
}
Beispiel #10
0
int __stdcall NumFuncs  (void){ return get_func_qty(); }
Beispiel #11
0
// 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()
}
Beispiel #12
0
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 */
}