Skip to content

Commit

Permalink
Mov instruction manipulating esp and ebp added to plugin to detect mo…
Browse files Browse the repository at this point in the history
…re args (#22)

* Arguments passed using mov instruction (mov* [ebp*], ... or mov* [esp*], ...) are recognized, Functions ending with Stub are also recognized, small bugfix with string concatenation

* Ignoring instructions of prolog and epilog when trying to detect arguments of functions

* Avoid putting same comments duplicated whenever analysis is done again

* Reverted back to VS2013 since appveyor was failing the build (untested here, dont have VS2013)

* Update xAnalyzer.vcxproj

* Update xanalyzer.cpp
  • Loading branch information
Herz3h authored and ThunderCls committed Jun 16, 2017
1 parent 84f4f0b commit 2f09732
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 17 deletions.
2 changes: 1 addition & 1 deletion xAnalyzer/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ PLUG_EXPORT void CBMENUENTRY(CBTYPE cbType, PLUG_CB_MENUENTRY* info)
mbp.cbSize = sizeof(MSGBOXPARAMS);
mbp.hInstance = pluginHInstance;
mbp.lpszCaption = "About...";
mbp.lpszText = "["PLUGIN_NAME " " PLUGIN_VERSION_STR"]\n"
mbp.lpszText = "[" PLUGIN_NAME " " PLUGIN_VERSION_STR"]\n"
"Extended analysis for static code \n\n"
"http://github.com/ThunderCls/xAnalyzer\n"
"Coded By : ThunderCls - 2016\n"
Expand Down
2 changes: 1 addition & 1 deletion xAnalyzer/pluginmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "plugin.h"

// Variables
const char *szprojectnameInfo = "\n"PLUGIN_NAME " " PLUGIN_VERSION_STR" Plugin by ThunderCls 2017\n"
const char *szprojectnameInfo = "\n" PLUGIN_NAME " " PLUGIN_VERSION_STR" Plugin by ThunderCls 2017\n"
"Extended analysis for static code\n"
"-> For latest release, issues, etc....\n"
"-> For help type command \"xanal help\"\n"
Expand Down
4 changes: 2 additions & 2 deletions xAnalyzer/xAnalyzer.vcxproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
Expand Down Expand Up @@ -366,4 +366,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
52 changes: 41 additions & 11 deletions xAnalyzer/xanalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,14 +328,20 @@ void AnalyzeBytesRange(duint dwEntry, duint dwExit)
CallDestination = bii.addr;
DbgDisasmFastAt(CallDestination, &cbii);
GuiGetDisassembly(CurrentAddress, szDisasmText);
GuiGetDisassembly(bii.addr, szJmpDisasmText); // Detect function name on call scheme: CALL -> JMP -> JMP -> API
GuiGetDisassembly(CallDestination, szJmpDisasmText); // Detect function name on call scheme: CALL -> JMP -> JMP -> API

// save data for the argument
ai.manual = true;
ai.rvaEnd = CurrentAddress - Module::BaseFromAddr(CurrentAddress); // call address is the last
if (Strip_x64dbg_calls(szDisasmText) || (cbii.branch && Strip_x64dbg_calls(szJmpDisasmText)))
{
szOriginalCharsetAPIFunction = szAPIFunction;

// Remove Stub suffix from function names if found
auto stub = szAPIFunction.find("Stub");
if (stub != std::string::npos)
szAPIFunction = szAPIFunction.substr(0, stub);

// transform charsets search
if (szAPIFunction.back() == 'A' || szAPIFunction.back() == 'W')
szAPIFunction.pop_back();
Expand Down Expand Up @@ -445,7 +451,7 @@ void AnalyzeBytesRange(duint dwEntry, duint dwExit)
// --------------------------------------------------------------------------------------
else if (!bii.branch)
{
if (IsArgumentInstruction(&bii)) // only arguments instruction / excluding unusual instructions
if (IsArgumentInstruction(&bii, CurrentAddress)) // only arguments instruction / excluding unusual instructions
{
if (IS.size() < INSTRUCTIONSTACK_MAXSIZE) // save instruction into stack
{
Expand Down Expand Up @@ -899,7 +905,7 @@ bool Strip_x64dbg_calls(LPSTR lpszCallText)

// in case of undefined: CALL [0x007FF154]
strcpy_s(funct, MAX_COMMENT_SIZE, lpszAPIFunction);
if (ishex(funct) || HasRegister(funct))
if (IsHex(funct) || HasRegister(funct))
sprintf_s(lpszAPIFunction, MAX_COMMENT_SIZE, "sub_[%s]", funct);

szAPIFunction = lpszAPIFunction;
Expand Down Expand Up @@ -1026,7 +1032,7 @@ void SetAutoCommentIfCommentIsEmpty(INSTRUCTIONSTACK *inst, char *CommentString,

if (inst_source != NULL && ((strlen(inst_source) + 10) <= spaceleft - 1)) // avoid BoF for longer comments than MAX_COMMENT_SIZE (FIXED!)
{
bool instHex = ishex(inst_source);
bool instHex = IsHex(inst_source);
if (instHex) // get constants as value of argument / excluding push memory, registers, etc
ToUpperHex(inst_source);

Expand Down Expand Up @@ -1122,6 +1128,28 @@ bool IsNumericParam(string paramType)
return false;
}

// ------------------------------------------------------------------------------------
// Returns true if instruction is a mov manipulating esp or ebp, excluding epilog, prolog
// otherwise returns false
// ------------------------------------------------------------------------------------
bool IsMovStack(const BASIC_INSTRUCTION_INFO *bii, duint CurrentAddress)
{
auto isMovInstruction = strstr(bii->instruction, "mov") != nullptr;

if (isMovInstruction && !IsProlog(bii, CurrentAddress) && !IsEpilog(bii)) // Is a mov instruction excluding prolog and epilog
{
char *next_token = NULL;
auto movDestination = strtok_s((char*)bii->instruction, ",", &next_token); // Get the left part of ,
auto isMovDestinationEsp = strstr(movDestination, "esp") != nullptr;
auto isMovDestinationEbp = strstr(movDestination, "ebp") != nullptr;

if(movDestination != nullptr && (isMovDestinationEsp || isMovDestinationEbp)) // If instruction manipulate [esp*] or [ebp*], its valid
return true;
}

return false;
}

// ------------------------------------------------------------------------------------
// Check if the current executable is a VB
// ------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1318,7 +1346,7 @@ bool IsHeaderConstant(const char *CommentString, char *szComment, char *inst_sou

if (inst_source != NULL)
{
if(instHex = ishex(inst_source))
if(instHex = IsHex(inst_source))
instConst = hextoduint(inst_source);
}

Expand Down Expand Up @@ -1622,7 +1650,7 @@ int GetFunctionParamCount(LPSTR lpszApiModule, string lpszApiFunction)
Utf8Ini *defApiFile = search->second;
string params = defApiFile->GetValue(lpszApiFunction, "ParamCount");
// check if key is found
if (!params.empty() && ishex(params.c_str()))
if (!params.empty() && IsHex(params.c_str()))
return atoi(params.c_str());
}

Expand Down Expand Up @@ -1662,7 +1690,7 @@ bool GetFunctionParam(LPSTR lpszApiModule, string lpszApiFunction, duint dwParam
// ------------------------------------------------------------------------------------
// Returns true if the specified string is a valid hex value
// ------------------------------------------------------------------------------------
bool ishex(const char *str)
bool IsHex(const char *str)
{
duint index = 0;

Expand Down Expand Up @@ -1906,7 +1934,7 @@ bool IsArgumentRegister(const char *destination)
// ------------------------------------------------------------------------------------
// True if instruction is a valid argument instruction
// ------------------------------------------------------------------------------------
bool IsArgumentInstruction(const BASIC_INSTRUCTION_INFO *bii)
bool IsArgumentInstruction(const BASIC_INSTRUCTION_INFO *bii, duint CurrentAddress)
{
#ifdef _WIN64
bool IsArgument = false;
Expand Down Expand Up @@ -1935,11 +1963,13 @@ bool IsArgumentInstruction(const BASIC_INSTRUCTION_INFO *bii)
return IsArgument;

#else
return (strncmp(bii->instruction, "push ", 5) == 0 &&
auto validPushInstruction = strncmp(bii->instruction, "push ", 5) == 0 &&
strcmp((char*)(bii->instruction + 5), "ebp") != 0 &&
strcmp((char*)(bii->instruction + 5), "esp") != 0 &&
strcmp((char*)(bii->instruction + 5), "ds") != 0 &&
strcmp((char*)(bii->instruction + 5), "es") != 0);
strcmp((char*)(bii->instruction + 5), "es") != 0;

return (validPushInstruction || IsMovStack(bii, CurrentAddress));
#endif
}

Expand Down Expand Up @@ -2414,4 +2444,4 @@ void DisplayHelp()
"xanal help : Brings up this help text\r\n\n";

GuiAddLogMessage(pluginHelp);
}
}
5 changes: 3 additions & 2 deletions xAnalyzer/xanalyzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void SetAutoCommentIfCommentIsEmpty(INSTRUCTIONSTACK *inst, char *CommentString,
bool SearchApiFileForDefinition(LPSTR lpszApiModule, LPSTR lpszApiDefinition, bool recursive);
int GetFunctionParamCount(LPSTR lpszApiModule, string lpszApiFunction);
bool GetFunctionParam(LPSTR lpszApiModule, string lpszApiFunction, duint dwParamNo, LPSTR lpszApiFunctionParameter);
bool ishex(const char *str);
bool IsHex(const char *str);
duint hextoduint(LPCTSTR str);
void DoInitialAnalysis();
void ProcessDllFunctionCalls(duint startAddr = -1, duint size = -1);
Expand All @@ -95,10 +95,11 @@ string CallDirection(BASIC_INSTRUCTION_INFO *bii);
bool SetFunctionParams(Script::Argument::ArgumentInfo *ai, char *szAPIModuleName);
bool IsHeaderConstant(const char *CommentString, char *szComment, char *inst_source = NULL);
bool IsNumericParam(string paramType);
bool IsMovStack(BASIC_INSTRUCTION_INFO *bii, duint CurrentAddress);
void TraverseHFilesTree(string &base, string header, string &htype, char *lpszApiConstant, Utf8Ini *defApiHFile, bool getTypeDisplay = false);
void GetConstantValue(char *lpszApiConstant, const char *CommentString);
bool SetSubParams(Argument::ArgumentInfo *ai);
bool IsArgumentInstruction(const BASIC_INSTRUCTION_INFO *bii);
bool IsArgumentInstruction(const BASIC_INSTRUCTION_INFO *bii, duint CurrentAddress);
bool IsProlog(const BASIC_INSTRUCTION_INFO *bii, duint CurrentAddress);
bool IsEpilog(const BASIC_INSTRUCTION_INFO *bii);
char *GetInstructionSource(char *instruction);
Expand Down

0 comments on commit 2f09732

Please sign in to comment.