DBG: added mnemonichelp and mnemonicbrief commands + export
This commit is contained in:
parent
2560e19b88
commit
1541f84867
File diff suppressed because one or more lines are too long
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
};
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -54,6 +54,7 @@ enum SectionLock
|
|||
LockPluginCommandList,
|
||||
LockPluginMenuList,
|
||||
LockSehCache,
|
||||
LockMnemonicHelp,
|
||||
|
||||
// Number of elements in this enumeration. Must always be the last
|
||||
// index.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue