1
0
Fork 0

DBG: added mnemonichelp and mnemonicbrief commands + export

This commit is contained in:
mrexodia 2016-05-25 15:57:03 +02:00
parent 2560e19b88
commit 1541f84867
13 changed files with 5511 additions and 1 deletions

5310
bin/mnemdb.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -19,6 +19,7 @@
#include "breakpoint.h"
#include "threading.h"
#include "stringformat.h"
#include "mnemonichelp.h"
static DBGFUNCTIONS _dbgfunctions;
@ -243,6 +244,13 @@ static bool _stringformatinline(const char* format, size_t resultSize, char* res
return true;
}
static void _getmnemonicbrief(const char* mnem, size_t resultSize, char* result)
{
if(!result)
return;
strcpy_s(result, resultSize, MnemonicHelp::getBriefDescription(mnem).c_str());
}
void dbgfunctionsinit()
{
_dbgfunctions.AssembleAtEx = _assembleatex;
@ -284,4 +292,5 @@ void dbgfunctionsinit()
_dbgfunctions.PatchGetEx = (PATCHGETEX)PatchGet;
_dbgfunctions.GetBridgeBp = _getbridgebp;
_dbgfunctions.StringFormatInline = _stringformatinline;
_dbgfunctions.GetMnemonicBrief = _getmnemonicbrief;
}

View File

@ -84,6 +84,7 @@ typedef bool (*VALFROMSTRING)(const char* string, duint* value);
typedef bool (*PATCHGETEX)(duint addr, DBGPATCHINFO* info);
typedef bool(*GETBRIDGEBP)(BPXTYPE type, duint addr, BRIDGEBP* bp);
typedef bool(*STRINGFORMATINLINE)(const char* format, size_t resultSize, char* result);
typedef void(*GETMNEMONICBRIEF)(const char* mnem, size_t resultSize, char* result);
typedef struct DBGFUNCTIONS_
{
@ -126,6 +127,7 @@ typedef struct DBGFUNCTIONS_
PATCHGETEX PatchGetEx;
GETBRIDGEBP GetBridgeBp;
STRINGFORMATINLINE StringFormatInline;
GETMNEMONICBRIEF GetMnemonicBrief;
} DBGFUNCTIONS;
#ifdef BUILD_DBG

View File

@ -33,6 +33,7 @@
#include "exceptiondirectoryanalysis.h"
#include "_scriptapi_stack.h"
#include "threading.h"
#include "mnemonichelp.h"
static bool bRefinit = false;
static int maxFindResults = 5000;
@ -2357,5 +2358,29 @@ CMDRESULT cbInstrSavedata(int argc, char* argv[])
dprintf("%p[% " fext "X] written to \"%s\" !\n", addr, size, argv[1]);
return STATUS_CONTINUE;
}
CMDRESULT cbInstrMnemonichelp(int argc, char* argv[])
{
if(argc < 2)
return STATUS_ERROR;
auto description = MnemonicHelp::getDescription(argv[1]);
if(!description.length())
dputs("no description or empty description");
else
{
auto padding = "================================================================";
auto logText = StringUtils::sprintf("%s%s%s", padding, description.c_str(), padding);
GuiAddLogMessage(logText.c_str());
}
return STATUS_CONTINUE;
}
CMDRESULT cbInstrMnemonicbrief(int argc, char* argv[])
{
if(argc < 2)
return STATUS_ERROR;
dputs(MnemonicHelp::getBriefDescription(argv[1]).c_str());
return STATUS_CONTINUE;
}

View File

@ -79,5 +79,7 @@ CMDRESULT cbInstrExanalyse(int argc, char* argv[]);
CMDRESULT cbInstrVirtualmod(int argc, char* argv[]);
CMDRESULT cbInstrSetMaxFindResult(int argc, char* argv[]);
CMDRESULT cbInstrSavedata(int argc, char* argv[]);
CMDRESULT cbInstrMnemonichelp(int argc, char* argv[]);
CMDRESULT cbInstrMnemonicbrief(int argc, char* argv[]);
#endif // _INSTRUCTION_H

111
src/dbg/mnemonichelp.cpp Normal file
View File

@ -0,0 +1,111 @@
#include "mnemonichelp.h"
#include "threading.h"
#include <algorithm>
#include <string>
#include <locale>
static std::unordered_map<String, String> MnemonicMap;
static std::unordered_map<String, String> MnemonicBriefMap;
bool MnemonicHelp::loadFromText(const char* json)
{
EXCLUSIVE_ACQUIRE(LockMnemonicHelp);
MnemonicMap.clear();
auto root = json_loads(json, 0, 0);
if(root)
{
// Get a handle to the root object -> x86-64 subtree
auto jsonData = json_object_get(root, "x86-64");
// Check if there was something to load
if(jsonData)
{
size_t i;
JSON value;
json_array_foreach(jsonData, i, value)
{
auto mnem = json_string_value(json_object_get(value, "mnem"));
auto description = json_string_value(json_object_get(value, "description"));
if(mnem && description)
MnemonicMap[StringUtils::ToLower(mnem)] = description;
}
}
// Get a handle to the root object -> x86-64-brief subtree
auto jsonDataBrief = json_object_get(root, "x86-64-brief");
// Check if there was something to load
if(jsonDataBrief)
{
size_t i;
JSON value;
json_array_foreach(jsonDataBrief, i, value)
{
auto mnem = json_string_value(json_object_get(value, "mnem"));
auto description = json_string_value(json_object_get(value, "description"));
if(mnem && description)
MnemonicBriefMap[mnem] = description;
}
}
// Free root
json_decref(root);
}
else
return false;
return true;
}
String MnemonicHelp::getUniversalMnemonic(const String & mnem)
{
auto mnemLower = StringUtils::ToLower(mnem);
auto startsWith = [&](const char* n)
{
return StringUtils::StartsWith(mnemLower, n);
};
if(mnemLower == "jmp")
return mnemLower;
if(mnemLower == "loop") //LOOP
return mnemLower;
if(startsWith("cmov")) //CMOVcc
return "cmovcc";
if(startsWith("fcmov")) //FCMOVcc
return "fcmovcc";
if(startsWith("j")) //Jcc
return "jcc";
if(startsWith("loop")) //LOOPcc
return "loopcc";
if(startsWith("set")) //SETcc
return "setcc";
return mnemLower;
}
String MnemonicHelp::getDescription(const char* mnem, int depth)
{
if(mnem == nullptr)
return "Invalid mnemonic!";
if(depth == 10)
return "Too many redirections...";
SHARED_ACQUIRE(LockMnemonicHelp);
auto found = MnemonicMap.find(getUniversalMnemonic(mnem));
if(found == MnemonicMap.end())
return "";
const auto & description = found->second;
if(StringUtils::StartsWith(description, "-R")) //redirect
{
SHARED_RELEASE();
return getDescription(description.c_str() + 2, depth + 1);
}
return description;
}
String MnemonicHelp::getBriefDescription(const char* mnem)
{
if(mnem == nullptr)
return "Invalid mnemonic!";
SHARED_ACQUIRE(LockMnemonicHelp);
auto found = MnemonicBriefMap.find(StringUtils::ToLower(mnem));
if(found == MnemonicBriefMap.end())
return "";
return found->second;
}

12
src/dbg/mnemonichelp.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include "_global.h"
class MnemonicHelp
{
public:
static bool loadFromText(const char* json);
static String getUniversalMnemonic(const String & mnem);
static String getDescription(const char* mnem, int depth = 0);
static String getBriefDescription(const char* mnem);
};

View File

@ -182,4 +182,17 @@ WString StringUtils::sprintf(const wchar_t* format, ...)
}
va_end(args);
return WString(buffer());
}
}
String StringUtils::ToLower(const String & s)
{
auto result = s;
for(size_t i = 0; i < result.size(); i++)
result[i] = tolower(result[i]);
return result;
}
bool StringUtils::StartsWith(const String & h, const String & n)
{
return strstr(h.c_str(), n.c_str()) == h.c_str();
}

View File

@ -26,6 +26,8 @@ public:
static void ReplaceAll(WString & s, const WString & from, const WString & to);
static String sprintf(const char* format, ...);
static WString sprintf(const wchar_t* format, ...);
static String ToLower(const String & s);
static bool StartsWith(const String & h, const String & n);
private:
static const String WHITESPACE;

View File

@ -54,6 +54,7 @@ enum SectionLock
LockPluginCommandList,
LockPluginMenuList,
LockSehCache,
LockMnemonicHelp,
// Number of elements in this enumeration. Must always be the last
// index.

View File

@ -21,6 +21,7 @@
#include "_scriptapi_gui.h"
#include "filehelper.h"
#include "database.h"
#include "mnemonichelp.h"
static MESSAGE_STACK* gMsgStack = 0;
static HANDLE hCommandLoopThread = 0;
@ -265,6 +266,8 @@ static void registercommands()
dbgcmdnew("setmaxfindresult\1findsetmaxresult", cbInstrSetMaxFindResult, false); //set the maximum number of occurences found
dbgcmdnew("savedata", cbInstrSavedata, true); //save data to disk
dbgcmdnew("scriptdll\1dllscript", cbScriptDll, false); //execute a script DLL
dbgcmdnew("mnemonichelp", cbInstrMnemonichelp, false); //mnemonic help
dbgcmdnew("mnemonicbrief", cbInstrMnemonicbrief, false); //mnemonic brief
}
static bool cbCommandProvider(char* cmd, int maxlen)
@ -414,6 +417,18 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
DeleteFileW(StringUtils::Utf8ToUtf16(alloctrace).c_str());
setalloctrace(alloctrace);
// Load mnemonic help database
String mnemonicHelpData;
if(FileHelper::ReadAllText(StringUtils::sprintf("%s\\..\\mnemdb.json", dir), mnemonicHelpData))
{
if(MnemonicHelp::loadFromText(mnemonicHelpData.c_str()))
dputs("Mnemonic help database loaded!");
else
dputs("Failed to load mnemonic help database...");
}
else
dputs("Failed to read mnemonic help database...");
// Create database directory in the local debugger folder
DbSetPath(StringUtils::sprintf("%s\\db", dir).c_str(), nullptr);

View File

@ -55,6 +55,7 @@
<ClCompile Include="loop.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="memory.cpp" />
<ClCompile Include="mnemonichelp.cpp" />
<ClCompile Include="module.cpp" />
<ClCompile Include="msgqueue.cpp" />
<ClCompile Include="murmurhash.cpp" />
@ -139,6 +140,7 @@
<ClInclude Include="lz4\lz4file.h" />
<ClInclude Include="lz4\lz4hc.h" />
<ClInclude Include="memory.h" />
<ClInclude Include="mnemonichelp.h" />
<ClInclude Include="module.h" />
<ClInclude Include="msgqueue.h" />
<ClInclude Include="murmurhash.h" />

View File

@ -296,6 +296,9 @@
<ClCompile Include="exhandlerinfo.cpp">
<Filter>Source Files\Information</Filter>
</ClCompile>
<ClCompile Include="mnemonichelp.cpp">
<Filter>Source Files\Information</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="x64_dbg.h">
@ -652,5 +655,8 @@
<ClInclude Include="exhandlerinfo.h">
<Filter>Header Files\Information</Filter>
</ClInclude>
<ClInclude Include="mnemonichelp.h">
<Filter>Header Files\Information</Filter>
</ClInclude>
</ItemGroup>
</Project>