1
0
Fork 0
x64dbg/src/dbg/mnemonichelp.cpp

139 lines
4.1 KiB
C++

#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("int")) //INT n
return "int n";
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 mnemuni = getUniversalMnemonic(mnem);
auto found = MnemonicMap.find(mnemuni);
if(found == MnemonicMap.end())
{
if(mnemuni[0] == 'v') //v/vm
{
found = MnemonicMap.find(mnemuni.c_str() + 1);
if(found == MnemonicMap.end())
return "";
}
else
return "";
}
const auto & description = found->second;
if(StringUtils::StartsWith(description, "-R:")) //redirect
{
SHARED_RELEASE();
return getDescription(description.c_str() + 3, depth + 1);
}
return description;
}
String MnemonicHelp::getBriefDescription(const char* mnem)
{
if(mnem == nullptr)
return "Invalid mnemonic!";
SHARED_ACQUIRE(LockMnemonicHelp);
auto mnemLower = StringUtils::ToLower(mnem);
if(mnemLower == "???")
return "invalid instruction";
auto found = MnemonicBriefMap.find(mnemLower);
if(found == MnemonicBriefMap.end())
{
if(mnemLower[0] == 'v') //v/vm
{
found = MnemonicBriefMap.find(mnemLower.c_str() + 1);
if(found != MnemonicBriefMap.end())
{
if(mnemLower.length() > 1 && mnemLower[1] == 'm') //vm
return "vm " + found->second;
return "vector " + found->second;
}
}
return "";
}
return found->second;
}