Esempio n. 1
0
char *DieHolder::get_type_comment(void)
{
  char *comment = NULL;
  uint32 ordinal = 0;

  if(get_type_ordinal(&ordinal))
  {
    type_t const *type = NULL;
    p_list const *fields = NULL;
    bool const found = get_numbered_type(idati, ordinal, &type, &fields);

    if(found)
    {
      // dynamic type string allocation does not work (returns T_SHORTSTR)
      // so allocate a huge buffer on the stack...
      char buf[MAXSTR];
      int const ret = print_type_to_one_line(buf, sizeof(buf), idati, type, get_name(),
                                             NULL, fields, NULL);
      if(ret >= 0);
      {
        size_t len = strlen(buf);
        comment = static_cast<char *>(qalloc(len + 1));

        if(comment != NULL)
        {
          memcpy(comment, buf, len + 1);
        }
      }
    }
  }

  return comment;
}
Esempio n. 2
0
int get_idx_type_size(cexpr_t *idx_expr)
{
	char buff[MAXSTR];
	print_type_to_one_line(buff, MAXSTR, idati, idx_expr->type.u_str());
	
	if(strstr(buff, "char"))
		return 1;
	else if(strstr(buff, "short"))
		return 2;
	else if(strstr(buff, "int"))
		return 4;

	return 0;
}
  // Determine the node color. Feel free to change it.
  bgcolor_t idaapi cfunc_graph_t::get_node_color(int n)
  {
    const citem_t *item = items[n];
    if ( item == highlight )
      return CL_GREEN;          // Highlighted item
    if ( item->is_expr() )
    {
      char buf[MAXSTR];
      const cexpr_t *e = (const cexpr_t *)item;
      if ( print_type_to_one_line(buf, sizeof(buf), idati, e->type.u_str()) != T_NORMAL )
        return CL_YELLOWGREEN; // Problematic type
    }

	if(item->op == cot_call)
		return CL_RED;

    return DEFCOLOR;
  }
Esempio n. 4
0
char * callgraph_t::get_node_label(int n, char *buf, int bufsize) const
{
	int_ea_map_t::const_iterator it = node2ea.find(n);
	
	if ( it != node2ea.end() )
	{
		const citem_t *item = it->second;

		char *ptr = buf;
		char *endp = buf + bufsize;
		
		// Each node will have the element type at the first line
		APPEND(ptr, endp, get_ctype_name(item->op));
		const cexpr_t *e = (const cexpr_t *)item;
		const cinsn_t *i = (const cinsn_t *)item;
		
		// For some item types, display additional information
		switch ( item->op )
		{
		  case cot_ptr     : // *x
		  case cot_memptr  : // x->m
			// Display access size for pointers
			ptr += qsnprintf(ptr, endp-ptr, ".%d", e->ptrsize);
			if ( item->op == cot_ptr )
			  break;
		  case cot_memref  : // x.m
			// Display member offset for structure fields
			ptr += qsnprintf(ptr, endp-ptr, " (m=%d)", e->m);
			break;
		  case cot_obj     : // v
		  case cot_var     : // l
			// Display object size for local variables and global data
			ptr += qsnprintf(ptr, endp-ptr, ".%d", e->refwidth);
		  case cot_num     : // n
		  case cot_helper  : // arbitrary name
		  case cot_str     : // string constant
			// Display helper names and number values
			APPCHAR(ptr, endp, ' ');
			e->print1(ptr, endp-ptr, NULL);
			tag_remove(ptr, ptr, 0);
			ptr = tail(ptr);
			break;
		 case cit_goto:
			// Display target label number for gotos
			ptr += qsnprintf(ptr, endp-ptr, " LABEL_%d", i->cgoto->label_num);
			break;
		 case cit_asm:
			// Display instruction block address and size for asm-statements
			ptr += qsnprintf(ptr, endp-ptr, " %a.%"FMT_Z, *i->casm->begin(), i->casm->size());
			break;
		  default:
			break;
		}
    
		// The second line of the node contains the item address
		ptr += qsnprintf(ptr, endp-ptr, "\nea: %a", item->ea);
		if ( item->is_expr() && !e->type.empty() )
		{
		  // For typed expressions, the third line will have
		  // the expression type in human readable form
		  APPCHAR(ptr, endp, '\n');
		  if ( print_type_to_one_line(ptr, endp-ptr, idati, e->type.u_str()) != T_NORMAL )
		  { // could not print the type?
			APPCHAR(ptr, endp, '?');
			APPZERO(ptr, endp);
		  }

		  if(e->type.is_ptr())
			{
				typestring ptr_rem = remove_pointer(e->type);
				if(ptr_rem.is_struct())
				{
					qstring typenm;

					print_type_to_qstring(&typenm, "prefix ", 0,0, PRTYPE_MULTI | PRTYPE_TYPE | PRTYPE_SEMI, idati, ptr_rem.u_str());
				}
			}
		}
	}
	
	return buf;
}
Esempio n. 5
0
//--------------------------------------------------------------------------
void run(int /*arg*/)
{
  if ( !autoIsOk()
    && askyn_c(-1, "HIDECANCEL\n"
                   "The autoanalysis has not finished yet.\n"
                   "The result might be incomplete. Do you want to continue?") < 0 )
    return;

  // gather information about the entry points
  entrylist_t *li = new entrylist_t;
  size_t n = get_entry_qty();
  for ( size_t i=0; i < n; i++ )
  {
    asize_t ord = get_entry_ordinal((int)i);
    ea_t ea = get_entry(ord);
    if ( ord == ea )
      continue;
    qtype type, fnames;
    char decl[MAXSTR];
    char true_name[MAXSTR];
    asize_t argsize = 0;
    get_entry_name(ord, true_name, sizeof(true_name));
    if ( get_tinfo(ea, &type, &fnames)
      && print_type_to_one_line(
                decl, sizeof(decl),
                idati,
                type.c_str(),
                true_name,
                NULL,
                fnames.c_str()) == T_NORMAL )
    {
//    found type info -- calc the args size
      func_type_info_t fi;
      int a = build_funcarg_info(idati, type.c_str(), fnames.c_str(), &fi, 0);
      if ( a != 0 )
      {
        for ( int k=0; k < a; k++ )
        {
          const type_t *ptr = fi[k].type.c_str();
          int s1 = (int)get_type_size(idati, ptr);
          s1 = qmax(s1, inf.cc.size_i);
          argsize += s1;
        }
      }
    }
    else if ( get_long_name(BADADDR, ea, decl, sizeof(decl)) != NULL
           && get_true_name(BADADDR, ea, true_name, sizeof(true_name)) != NULL
           && strcmp(decl, true_name) != 0 )
    {
//      found mangled name
    }
    else
    {
//      found nothing, just show the name
      const char *name = get_name(BADADDR, ea, true_name, sizeof(true_name));
      if ( name == NULL )
        continue;
      qstrncpy(decl, name, sizeof(decl));
    }
    if ( argsize == 0 )
    {
      func_t *pfn = get_func(ea);
      if ( pfn != NULL )
        argsize = pfn->argsize;
    }
    item_t x;
    x.ord = (int)ord;
    x.ea = ea;
    x.decl = decl;
    x.argsize = (uint32)argsize;
    li->push_back(x);
  }

  // now open the window
  choose2(false,                // non-modal window
          -1, -1, -1, -1,       // position is determined by Windows
          li,                   // pass the created array
          qnumber(header),      // number of columns
          widths,               // widths of columns
          sizer,                // function that returns number of lines
          desc,                 // function that generates a line
          "Exported functions", // window title
          -1,                   // use the default icon for the window
          0,                    // position the cursor on the first line
          NULL,                 // "kill" callback
          NULL,                 // "new" callback
          NULL,                 // "update" callback
          NULL,                 // "edit" callback
          enter_cb,             // function to call when the user pressed Enter
          destroy_cb,           // function to call when the window is closed
          NULL,                 // use default popup menu items
          NULL);                // use the same icon for all lines
}
Esempio n. 6
0
//--------------------------------------------------------------------------
// Generate text for the current location
int ida_export class_place_t__generate(
									   const cp_t *ths,
									   void *ud,
									   char *lines[],
									   int maxsize,
									   int *default_lnnum,
									   color_t *prefix_color,
									   bgcolor_t *bg_color)
{
	strvec_t &sv = *(strvec_t *)ud;
	uval_t idx = ths->idx;
	if ( idx > get_last_class_idx() || maxsize <= 0 )
		return 0;
	char name[MAXNAMESIZE];

	tid_t tid = get_class_by_idx(idx);
	if (tid==BADNODE)
		return 0;
	switch (ths->section)
	{
	case 0:	
		if (get_class_name(tid, name, MAXNAMESIZE))
		{
			char line[MAXSTR];
			class_t * clas = get_class(tid);
			if(!clas)
				return 0;
			if (clas->parents_tid.size())
				qsnprintf(line, MAXSTR, "class %s: derived from: 0x%p", name, clas->parents_tid.front());
			else
				qsnprintf(line, MAXSTR, "class %s", name );
				
			lines[0] = qstrdup(line);
			*bg_color = 0xC0C0FF;
		}
		break;

	case 1:
		{
			char line[MAXSTR];
			class_t * clas = get_class(tid);
			if(!clas)
				return 0;
			if (clas->virt_table_ea != BADADDR)
				qsnprintf(line, MAXSTR, "vftable: %p", clas->virt_table_ea);
			else
				qsnprintf(line, MAXSTR, "no virtual table");				
			lines[0] = qstrdup(line);
			*bg_color = 0xC0FFC0;
		}
		break;

	case 2:
		{
			char *line;
			class_t * clas = get_class(tid);
			if(!clas)
				return 0;

			ea_t ea = BADADDR;
			if (clas->functions_ea.size() && ths->subsection<=clas->functions_ea.size())
				ea = clas->functions_ea[ths->subsection];
			if (ea!=BADADDR)
			{
				qstring tmpline;
				get_colored_long_name(&tmpline, ea);

				qtype type;
				qtype fields;  
				if (!get_tinfo(ea, &type, &fields))
				{
					if (!guess_func_tinfo(get_func(ea), &type, &fields))
						goto pokracuj; 
				}
				line = qstrdup(tmpline.c_str()); 
				print_type_to_one_line(line, MAXSTR, idati, type.c_str(), line, 0, fields.c_str(), 0);
pokracuj:
				;				

			}
			else qsnprintf(line, MAXSTR, "bad func");
			lines[0] = qstrdup(line);
			*bg_color = 0xC0FFFF;
		}
		break;

	}
	

	//*prefix_color = sv[idx%sv.size()].color;
	//*bg_color = sv[idx%sv.size()].bgcolor;
	*default_lnnum = 0;
	return 1; // generated one line

	//setup_makeline(-1, ..., save_line_in_array, 0)
	//finish_makeline();
}
Esempio n. 7
0
        /*! 
            @brief This function determines if a ctree item is legitimate; it
                   marks variables legitimate via the afVariableIsLegit array
                   and saves legitimate items in the vectorLegitItems vector

            @param[in] pItem The visited ctree item
            @return Returns 0 to continue the traversal, returns 1 to stop
                    the traversal
        */
        int
        visit_item (
            citem_t* pItem
            )
        {
            cexpr_t* pExpression;
            char szType[16];

            //
            // Ensure that we're initialized
            //
            if (!fInitialized)
            {
                if (!Initialize())
                {
                    return 1;
                }
            }

            //
            // If we're traversing the graph solely to mark descendants as
            // legitimate...
            //
            if (fMarkingDescendantsLegit)
            {
                //
                // Don't descend through items through which we've already
                //   descended
                //
                if (vectorDescendantsMarkedLegit.has(pItem))
                {
                    return 0;
                }

                //
                // If this is a variable, mark the variable legitimate
                //
                if (pItem->op == cot_var)
                {
                    afVariableIsLegit[((cexpr_t*)pItem)->v.idx] = true;
                }

                //
                // Mark the item itself legitimate
                //
                if (!vectorLegitItems.has(pItem))
                {
                    vectorLegitItems.push_back(
                        pItem);
                    fNewLegitItemFound = true;
                }

                //
                // Remember that we've now descended through this item
                //
                vectorDescendantsMarkedLegit.push_back(
                    pItem);

                //
                // Continue marking other descendant items as legitimate
                //
                return 0;
            }

            //
            // If this item was already marked as legititmate...
            //
            if (vectorLegitItems.has(pItem))
            {
                //
                // If we have a legitimate item that's an if/for/while/do/
                // return statement then mark the expression part of that node
                // (for example, the "x" in "if(x)") as legitimate as well
                //
                pExpression = NULL;
                switch (pItem->op)
                {
                case cit_if:
                    pExpression = &((cinsn_t*)pItem)->cif->expr; break;
                case cit_for:
                    pExpression = &((cinsn_t*)pItem)->cfor->expr; break;
                case cit_while:
                    pExpression = &((cinsn_t*)pItem)->cwhile->expr; break;
                case cit_do:
                    pExpression = &((cinsn_t*)pItem)->cdo->expr; break;
                case cit_return:
                    pExpression = &((cinsn_t*)pItem)->creturn->expr; break;
                default:
                    break;
                }
                if (pExpression == NULL)
                {
                    return 0;
                }

                //
                // If the expression hasn't already been marked as legitimate
                // then mark it so and mark all of its descendants as
                // legitimate as well
                //
                if (!vectorDescendantsMarkedLegit.has(pExpression))
                {
                    //
                    // Mark all items under this expression/call as legitimate
                    //
                    fMarkingDescendantsLegit = true;
                    apply_to(
                        pExpression,
                        NULL);
                    fMarkingDescendantsLegit = false;

                    //
                    // cit_for statements require us to also process the
                    // for-loop initialization and step expressions
                    //
                    if (pItem->op == cit_for)
                    {
                        //
                        // Process the for-loop's initialization expression
                        //
                        pExpression = &((cinsn_t*)pItem)->cfor->init;
                        if (!vectorDescendantsMarkedLegit.has(pExpression))
                        {
                            //
                            // Mark all items under this expression as legit
                            //
                            fMarkingDescendantsLegit = true;
                            apply_to(
                                pExpression,
                                NULL);
                            fMarkingDescendantsLegit = false;
                        }

                        //
                        // Process the for-loop's step expression
                        //
                        pExpression = &((cinsn_t*)pItem)->cfor->step;
                        if (!vectorDescendantsMarkedLegit.has(pExpression))
                        {
                            //
                            // Mark all items under this expression as legit
                            //
                            fMarkingDescendantsLegit = true;
                            apply_to(
                                pExpression,
                                NULL);
                            fMarkingDescendantsLegit = false;
                        }
                    }
                }

                return 0;
            }

            //
            // If this item is a legitimate variable and/or a CPPEH_RECORD
            // variable, or a function, global variable, legit macro, goto,
            // break, continue, return, or asm-statement then mark the ancestor
            // expressions as legitimate
            //
            if (pItem->op == cot_var)
            {
                if (!afVariableIsLegit[((cexpr_t*)pItem)->v.idx])
                {
                    if (T_NORMAL != print_type_to_one_line(
                        szType,
                        _countof(szType),
                        idati,
                        ((cexpr_t*)pItem)->type.u_str()))
                    {
                        return 0;
                    }
                    if (0 != strcmp(szType, "CPPEH_RECORD"))
                    {
                        return 0;
                    }
                }
            }
            else if (!((pItem->op == cot_obj) ||
                ((pItem->op == cot_call) &&
                    IsLegitimateCall((cexpr_t*)pItem)) ||
                (pItem->op == cit_goto) ||
                (pItem->op == cit_break) ||
                (pItem->op == cit_continue) ||
                (pItem->op == cit_return)) ||
                (pItem->op == cit_asm))
            {
                return 0;
            }

            //
            // Iterate through all ancestors (assumes that the decompilation
            // graph is a tree and that no item has more than one parent)
            //
            for(citem_t* pCurrentItem = pItem;
                pCurrentItem != NULL;
                pCurrentItem = pFunction->body.find_parent_of(pCurrentItem))
            {
                if (!vectorLegitItems.has(pCurrentItem))
                {
                    vectorLegitItems.push_back(
                        pCurrentItem);
                    fNewLegitItemFound = true;
                }

                if ((pCurrentItem->op == cit_expr) ||
                    ((pCurrentItem->op == cot_call) &&
                        IsLegitimateCall((cexpr_t*)pCurrentItem)) ||
                    (pCurrentItem->op == cit_return))
                {
                    //
                    // This is a cit_expr statement node or cot_call
                    // expression
                    //

                    if (!vectorDescendantsMarkedLegit.has(pCurrentItem))
                    {
                        //
                        // Mark all items under this expression/call as legit
                        //
                        fMarkingDescendantsLegit = true;
                        apply_to(
                            pCurrentItem,
                            NULL);
                        fMarkingDescendantsLegit = false;
                    }
                }
            }

            return 0;
        }