示例#1
0
文件: Core.cpp 项目: nihilus/WhatAPIs
// Process function
void processFunction(func_t *f)
{
	// Skip tiny functions
	if(f->size() >= 5)
	{
		// Don't add comments to API wrappers
        char name[MAXNAMELEN]; name[0] = name[SIZESTR(name)] = 0;
		if(!apiMap.empty())
		{
			if(get_short_name(BADADDR, f->startEA, name, SIZESTR(name)))
			{
				if(apiMap.find(name) != apiMap.end())
					return;
			}
		}

		// Iterate function body
        STRLIST importLstTmp;
        LPSTR commentPtr = NULL;
		char comment[MAXSTR]; comment[0] = comment[SIZESTR(comment)] = 0;
        UINT commentLen = 0;

        #define ADDNM(_str) { UINT l = strlen(_str); memcpy(comment + commentLen, _str, l); commentLen += l; _ASSERT(commentLen < MAXSTR); }

        func_item_iterator_t it(f);
		do
		{
            ea_t currentEA = it.current();

			// Will be a "to" xref
			xrefblk_t xb;
			if(xb.first_from(currentEA, XREF_FAR))
			{
				BOOL isImpFunc = FALSE;
                name[0] = 0;

				// If in import segment
				// ============================================================================================
				ea_t refAdrEa = xb.to;
				if(isInImportSeg(refAdrEa))
				{
					flags_t flags = get_flags_novalue(refAdrEa);
					if(has_name(flags) && hasRef(flags) && isDwrd(flags))
					{
						if(get_short_name(BADADDR, refAdrEa, name, SIZESTR(name)))
						{
							// Nix the imp prefix if there is one
							if(strncmp(name, "__imp_", SIZESTR("__imp_")) == 0)
								memmove(name, name + SIZESTR("__imp_"), ((strlen(name) - SIZESTR("__imp_")) + 1));

							isImpFunc = TRUE;
						}
						else
							msg(EAFORMAT" *** Failed to get import name! ***\n", refAdrEa);
					}
				}
				// Else, check for import wrapper
				// ============================================================================================
				else
				if(!apiMap.empty())
				{
					// Reference is a function entry?
					flags_t flags = get_flags_novalue(refAdrEa);
					if(isCode(flags) && has_name(flags) && hasRef(flags))
					{
						if(func_t *refFuncPtr = get_func(refAdrEa))
						{
							if(refFuncPtr->startEA == refAdrEa)
							{
								if(get_short_name(BADADDR, refAdrEa, name, SIZESTR(name)))
								{
									// Skip common unwanted types "sub_.." or "unknown_libname_.."
									if(
										// not "sub_..
										/*"sub_"*/ (*((PUINT) name) != 0x5F627573) &&

										// not "unknown_libname_..
										/*"unknown_"*/ ((*((PUINT64) name) != 0x5F6E776F6E6B6E75) && (*((PUINT64) (name + 8)) != /*"libname_"*/ 0x5F656D616E62696C)) &&

										// not nullsub_..
										/*"nullsub_"*/ (*((PUINT64) name) != 0x5F6275736C6C756E)
										)
									{
										// Nix the import prefixes
										if(strncmp(name, "__imp_", SIZESTR("__imp_")) == 0)
											memmove(name, name + SIZESTR("__imp_"), ((strlen(name) - SIZESTR("__imp_")) + 1));

										// Assumed to be a wrapped import if it's in the list
										isImpFunc = (apiMap.find(name) != apiMap.end());
									}
								}
								else
									msg(EAFORMAT" *** Failed to get function name! ***\n", refAdrEa);
							}
						}
					}
				}

				// Found import function to add list
				if(isImpFunc)
				{
					// Skip those large common STL names
					if(strncmp(name, "std::", SIZESTR("std::")) != 0)
					{
						// Skip if already seen in this function
						BOOL known = FALSE;
						for(STRLIST::iterator ji = importLstTmp.begin(); ji != importLstTmp.end(); ji++)
						{
							if(strcmp(ji->c_str(), name) == 0)
							{
								known = TRUE;
								break;
							}
						}

						// Not seen
						if(!known)
						{
							importLstTmp.push_front(name);

                            // Append to existing comments w/line feed
                            if(!commentLen && !commentPtr)
                            {
                                commentPtr = get_func_cmt(f, true);
                                if(!commentPtr)
                                    get_func_cmt(f, false);

                                if(commentPtr)
                                {
                                    commentLen = strlen(commentPtr);
                                    // Bail out not enough comment space
                                    if(commentLen >= (MAXSTR - 20))
                                    {
                                        qfree(commentPtr);
                                        return;
                                    }

                                    memcpy(comment, commentPtr, commentLen);
                                    ADDNM("\n"MYTAG);
                                }
                            }

                            if(!commentLen)
                                ADDNM(MYTAG);

							// Append a "..." (continuation) and bail out if name hits max comment length
							if((commentLen + strlen(name) + SIZESTR("()") + sizeof(", ")) >= (MAXSTR - sizeof("...")))
							{
                                ADDNM(" ...");
								break;
							}
							// Append this function name
							else
							{
								if(importLstTmp.size() != 1)
                                    ADDNM(", ");
                                ADDNM(name); ADDNM("()");
							}
						}
					}
					else
					{
						//msg("%s\n", szName);
					}
				}
			}

		}while(it.next_addr());

		if(!importLstTmp.empty() && commentLen)
		{
            // Add comment
            comment[commentLen] = 0;
			set_func_cmt(f, comment, true);
			commentCount++;
		}

        if(commentPtr)
            qfree(commentPtr);
	}
}