Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
pavledev committed Dec 7, 2020
0 parents commit 53e4a1a
Show file tree
Hide file tree
Showing 26 changed files with 27,223 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
41 changes: 41 additions & 0 deletions IDAExportFunctions.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29905.134
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IDAExportFunctions", "IDAExportFunctions\IDAExportFunctions.vcxproj", "{64170FA2-00BD-4404-8230-34085FF60A75}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IDASdkLib", "IDASdkLib\IDASdkLib.vcxproj", "{18649799-67FB-4C75-834D-0F2014AA5341}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{64170FA2-00BD-4404-8230-34085FF60A75}.Debug|x64.ActiveCfg = Debug|x64
{64170FA2-00BD-4404-8230-34085FF60A75}.Debug|x64.Build.0 = Debug|x64
{64170FA2-00BD-4404-8230-34085FF60A75}.Debug|x86.ActiveCfg = Debug|Win32
{64170FA2-00BD-4404-8230-34085FF60A75}.Debug|x86.Build.0 = Debug|Win32
{64170FA2-00BD-4404-8230-34085FF60A75}.Release|x64.ActiveCfg = Release|x64
{64170FA2-00BD-4404-8230-34085FF60A75}.Release|x64.Build.0 = Release|x64
{64170FA2-00BD-4404-8230-34085FF60A75}.Release|x86.ActiveCfg = Release|Win32
{64170FA2-00BD-4404-8230-34085FF60A75}.Release|x86.Build.0 = Release|Win32
{18649799-67FB-4C75-834D-0F2014AA5341}.Debug|x64.ActiveCfg = Debug|x64
{18649799-67FB-4C75-834D-0F2014AA5341}.Debug|x64.Build.0 = Debug|x64
{18649799-67FB-4C75-834D-0F2014AA5341}.Debug|x86.ActiveCfg = Debug|Win32
{18649799-67FB-4C75-834D-0F2014AA5341}.Debug|x86.Build.0 = Debug|Win32
{18649799-67FB-4C75-834D-0F2014AA5341}.Release|x64.ActiveCfg = Release|x64
{18649799-67FB-4C75-834D-0F2014AA5341}.Release|x64.Build.0 = Release|x64
{18649799-67FB-4C75-834D-0F2014AA5341}.Release|x86.ActiveCfg = Release|Win32
{18649799-67FB-4C75-834D-0F2014AA5341}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3A133ADE-DB07-4FFC-ADF3-58993EAFB140}
EndGlobalSection
EndGlobal
194 changes: 194 additions & 0 deletions IDAExportFunctions/Function.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
#include "Function.h"
#include "mystring.h"
#include "ida.h"
#include <sstream>

Function Function::getFunction(unsigned int functionAddress, std::map<unsigned int, unsigned int> virtualFunctions)
{
Function entry;
tinfo_t type;

entry.address = getHexAddress(functionAddress);
get_tinfo(&type, functionAddress);

entry.name = getFunctionName(functionAddress).c_str();

qstring functionType;
type.print(&functionType);
entry.type = functionType.c_str();

if (isFunctionPrefixReserved(entry.name.c_str()))
{
entry.name.clear();
}
else
{
entry.demangledName = getDemangledFunctionName(functionAddress, entry.name.c_str());
}

entry.callingConvention = getFunctionCallingConvention(type);

qstring returnType;

type.get_rettype().print(&returnType);
entry.returnType = returnType.c_str();

if (entry.returnType.length() > 0)
{
entry.prototype = entry.returnType + " " + getFunctionPrototype(functionAddress, entry.name.c_str());
}
else
{
entry.prototype = getFunctionPrototype(functionAddress, entry.name.c_str());
}

entry.parameters = getFunctionParameters(type);

auto it = virtualFunctions.find(functionAddress);

if (it != virtualFunctions.end())
{
entry.vtableIndex = it->second;
}

return entry;
}

std::string Function::getFunctionPrototype(unsigned int functionAddress, qstring functionName)
{
qstring prototype;

get_short_name(&prototype, functionAddress);
qstring tmpdem = prototype;
tmpdem.replace("__", "::");

if (functionName == tmpdem)
{
prototype = functionName;
}

return prototype.c_str();
}

std::string Function::getHexAddress(unsigned int functionAddress)
{
std::stringstream stream;
stream << std::uppercase << std::hex << functionAddress;

std::string hexAddress = stream.str().c_str();

return hexAddress;
}

std::string Function::getFunctionCallingConvention(tinfo_t type)
{
std::string callingConvention;

switch (type.get_cc())
{
case CM_CC_INVALID:
callingConvention = "";
break;
case CM_CC_VOIDARG:
callingConvention = "voidarg";
break;
case CM_CC_CDECL:
callingConvention = "cdecl";
break;
case CM_CC_ELLIPSIS:
callingConvention = "ellipsis";
break;
case CM_CC_STDCALL:
callingConvention = "stdcall";
break;
case CM_CC_PASCAL:
callingConvention = "pascal";
break;
case CM_CC_FASTCALL:
callingConvention = "fastcall";
break;
case CM_CC_THISCALL:
callingConvention = "thiscall";
break;
case CM_CC_MANUAL:
callingConvention = "manual";
break;
case CM_CC_SPOILED:
callingConvention = "spoiled";
break;
default:
callingConvention = "unknown";
break;
}

return callingConvention;
}

std::string Function::getDemangledFunctionName(unsigned int functionAddress, qstring functionName)
{
qstring demangledName;

get_short_name(&demangledName, functionAddress);
qstring tmpdem = demangledName;
tmpdem.replace("__", "::");

if (functionName == tmpdem)
{
demangledName = functionName;
}

std::string demangledName2 = demangledName.c_str();
int index = demangledName2.find_last_of("::");
int startIndex, count;

if (demangledName2.find("::`") != std::string::npos)
{
startIndex = index + 2;
}
else
{
startIndex = index + 1;
}

if (demangledName2.find("'(") != std::string::npos)
{
count = demangledName2.find('(', index) - startIndex - 1;
}
else if (demangledName2.find("' (") != std::string::npos)
{
count = demangledName2.find('(', index) - startIndex - 2;
}
else
{
count = demangledName2.find('(', index) - startIndex;
}

demangledName2 = demangledName2.substr(startIndex, count);
demangledName = demangledName2.c_str();

return demangledName.c_str();
}

std::vector<Function::Parameter> Function::getFunctionParameters(tinfo_t type)
{
func_type_data_t fi;
std::vector<Function::Parameter> parameters;

if (type.get_func_details(&fi))
{
for (auto const& p : fi)
{
Function::Parameter funcParam;
funcParam.name = p.name.c_str();

qstring type;

p.type.print(&type);
funcParam.type = type.c_str();

parameters.push_back(funcParam);
}
}

return parameters;
}
31 changes: 31 additions & 0 deletions IDAExportFunctions/Function.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once
#include "idp.hpp"
#include "mystring.h"

class Function
{
public:
class Parameter
{
public:
std::string name;
std::string type;
};

std::string prototype;
std::string address;
std::string name;
std::string demangledName;
std::string type;
std::string returnType;
std::string callingConvention;
std::vector<Parameter> parameters;
int vtableIndex = -1;

static Function getFunction(unsigned int functionAddress, std::map<unsigned int, unsigned int> virtualFunctions);
static std::string getFunctionPrototype(unsigned int functionAddress, qstring functionName);
static std::string getHexAddress(unsigned int functionAddress);
static std::string getFunctionCallingConvention(tinfo_t type);
static std::string getDemangledFunctionName(unsigned int functionAddress, qstring functionName);
static std::vector<Function::Parameter> getFunctionParameters(tinfo_t type);
};
Loading

0 comments on commit 53e4a1a

Please sign in to comment.