Esempio n. 1
0
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;
}
Esempio n. 3
0
//----------------------------------------------------------------------
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;
}