diff --git a/hooks/AStyleWhore.exe b/hooks/AStyleWhore.exe index e3a10e1f..0dc6d0d2 100644 Binary files a/hooks/AStyleWhore.exe and b/hooks/AStyleWhore.exe differ diff --git a/src/bridge/Utf8Ini.h b/src/bridge/Utf8Ini.h index 3cbf2cf4..634682b6 100644 --- a/src/bridge/Utf8Ini.h +++ b/src/bridge/Utf8Ini.h @@ -1,326 +1,326 @@ -#ifndef _UTF8INI_H -#define _UTF8INI_H - -#include -#include -#include - -class Utf8Ini -{ -public: - /** - \brief Serialize to the INI file format. - */ - inline std::string Serialize() const - { - std::string output; - for(const auto & section : _sections) - { - if(output.length()) - appendLine(output, ""); - appendLine(output, makeSectionText(section.first)); - for(const auto & keyvalue : section.second) - if(keyvalue.first.length()) - appendLine(output, makeKeyValueText(keyvalue.first, keyvalue.second)); - } - return output; - } - - /** - \brief Deserialize from the INI file format. - \param data The INI data. - \param [out] errorLine The error line (only has a meaning when this function failed). - \return true if it succeeds, false if it fails. - */ - inline bool Deserialize(const std::string & data, int & errorLine) - { - //initialize - errorLine = 0; - Clear(); - - //read lines - std::vector lines; - std::string curLine; - for(auto ch : data) - { - switch(ch) - { - case '\r': - break; - case '\n': - lines.push_back(trim(curLine)); - curLine.clear(); - break; - default: - curLine += ch; - } - } - if(curLine.length()) - lines.push_back(trim(curLine)); - - //parse lines - std::string section = ""; - for(const auto & line : lines) - { - errorLine++; - switch(getLineType(line)) - { - case LineType::Invalid: - MessageBoxA(0, line.c_str(), "line", 0); - return false; - - case LineType::Comment: - case LineType::Empty: - continue; - - case LineType::KeyValue: - { - std::string key; - std::string value; - if(!section.length() || - !parseKeyValueLine(line, key, value) || - !SetValue(section, key, value)) - return false; - } - break; - - case LineType::Section: - if(!parseSectionLine(line, section)) - return false; - } - } - return true; - } - - /** - \brief Sets a value. This will overwrite older values. - \param section The section. Must have a length greater than one. - \param key The key. Must have a length greater than one. - \param value The value. Can be empty (effectively removing the value). - \return true if the value was set successfully, false otherwise. - */ - inline bool SetValue(const std::string & section, const std::string & key, const std::string & value) - { - auto trimmedSection = trim(section); - auto trimmedKey = trim(key); - if(!trimmedSection.length() || !trimmedKey.length()) - return false; - auto found = _sections.find(trimmedSection); - if(found != _sections.end()) - found->second[trimmedKey] = value; - else - { - KeyValueMap keyValueMap; - keyValueMap[trimmedKey] = value; - _sections[trimmedSection] = keyValueMap; - } - return true; - } - - /** - \brief Removes all key/value pairs from a section. - \param section The section to clear. - \return true if it succeeds, false otherwise. - */ - inline bool ClearSection(const std::string & section) - { - auto trimmedSection = trim(section); - if(!trimmedSection.length()) - return false; - auto found = _sections.find(trimmedSection); - if(found == _sections.end()) - return false; - _sections.erase(found); - return true; - } - - /** - \brief Removes all sections. - */ - inline void Clear() - { - _sections.clear(); - } - - /** - \brief Gets a value. - \param section The section. - \param key The key. - \param [in,out] value The value. - \return The value. Empty string when the value was not found or empty. - */ - inline std::string GetValue(const std::string & section, const std::string & key) const - { - auto trimmedSection = trim(section); - auto trimmedKey = trim(key); - if(!trimmedSection.length() || !trimmedKey.length()) - return ""; - auto sectionFound = _sections.find(trimmedSection); - if(sectionFound == _sections.end()) - return ""; - const auto & keyValueMap = sectionFound->second; - auto keyFound = keyValueMap.find(trimmedKey); - if(keyFound == keyValueMap.end()) - return ""; - return keyFound->second; - } - -private: - typedef std::map KeyValueMap; - std::map _sections; - - enum class LineType - { - Invalid, - Empty, - Section, - KeyValue, - Comment - }; - - static inline LineType getLineType(const std::string & line) - { - auto len = line.length(); - if(!len) - return LineType::Empty; - if(line[0] == '[' && line[len - 1] == ']') - return LineType::Section; - if(line[0] == ';') - return LineType::Comment; - if(line.find('=') != std::string::npos) - return LineType::KeyValue; - return LineType::Invalid; - } - - static inline std::string trim(const std::string & str) - { - auto len = str.length(); - if(!len) - return ""; - size_t pre = 0; - while(str[pre] == ' ') - pre++; - size_t post = 0; - while(str[len - post - 1] == ' ' && post < len) - post++; - auto sublen = len - post - pre; - return sublen > 0 ? str.substr(pre, len - post - pre) : ""; - } - - static inline bool parseKeyValueLine(const std::string & line, std::string & key, std::string & value) - { - auto pos = line.find('='); - key = trim(line.substr(0, pos)); - value = trim(line.substr(pos + 1)); - auto len = value.length(); - if(len && value[0] == '\"' && value[len - 1] == '\"') - value = unescapeValue(value); - return true; - } - - static inline bool parseSectionLine(const std::string & line, std::string & section) - { - section = trim(line.substr(1, line.length() - 2)); - return section.length() > 0; - } - - static inline void appendLine(std::string & output, const std::string & line) - { - if(output.length()) - output += "\r\n"; - output += line; - } - - static inline std::string makeSectionText(const std::string & section) - { - return "[" + section + "]"; - } - - static inline std::string makeKeyValueText(const std::string & key, const std::string & value) - { - return key + "=" + escapeValue(value); - } - - static inline bool needsEscaping(const std::string & value) - { - auto len = value.length(); - return len && (value[0] == ' ' || value[len - 1] == ' ' || - value.find('\n') != std::string::npos || - value.find('\"') != std::string::npos); - } - - static inline std::string escapeValue(const std::string & value) - { - if(!needsEscaping(value)) - return value; - std::string escaped = "\""; - for(auto ch : value) - { - switch(ch) - { - case '\"': - escaped += "\\\""; - break; - case '\\': - escaped += "\\\\"; - break; - case '\r': - escaped += "\\r"; - break; - case '\n': - escaped += "\\n"; - break; - case '\t': - escaped += "\\t"; - default: - escaped += ch; - } - } - return escaped + "\""; - } - - static inline std::string unescapeValue(const std::string & str) - { - std::string result; - bool bEscaped = false; - for(auto ch : str) - { - if(!bEscaped) - { - switch(ch) - { - case '\"': - break; - case '\\': - bEscaped = true; - break; - default: - result += ch; - } - } - else - { - switch(ch) - { - case 'r': - result += '\r'; - break; - case 'n': - result += '\n'; - break; - case 't': - result += '\t'; - break; - default: - result += ch; - } - bEscaped = false; - } - } - if(bEscaped) - result += '\\'; - return result; - } -}; - +#ifndef _UTF8INI_H +#define _UTF8INI_H + +#include +#include +#include + +class Utf8Ini +{ +public: + /** + \brief Serialize to the INI file format. + */ + inline std::string Serialize() const + { + std::string output; + for(const auto & section : _sections) + { + if(output.length()) + appendLine(output, ""); + appendLine(output, makeSectionText(section.first)); + for(const auto & keyvalue : section.second) + if(keyvalue.first.length()) + appendLine(output, makeKeyValueText(keyvalue.first, keyvalue.second)); + } + return output; + } + + /** + \brief Deserialize from the INI file format. + \param data The INI data. + \param [out] errorLine The error line (only has a meaning when this function failed). + \return true if it succeeds, false if it fails. + */ + inline bool Deserialize(const std::string & data, int & errorLine) + { + //initialize + errorLine = 0; + Clear(); + + //read lines + std::vector lines; + std::string curLine; + for(auto ch : data) + { + switch(ch) + { + case '\r': + break; + case '\n': + lines.push_back(trim(curLine)); + curLine.clear(); + break; + default: + curLine += ch; + } + } + if(curLine.length()) + lines.push_back(trim(curLine)); + + //parse lines + std::string section = ""; + for(const auto & line : lines) + { + errorLine++; + switch(getLineType(line)) + { + case LineType::Invalid: + MessageBoxA(0, line.c_str(), "line", 0); + return false; + + case LineType::Comment: + case LineType::Empty: + continue; + + case LineType::KeyValue: + { + std::string key; + std::string value; + if(!section.length() || + !parseKeyValueLine(line, key, value) || + !SetValue(section, key, value)) + return false; + } + break; + + case LineType::Section: + if(!parseSectionLine(line, section)) + return false; + } + } + return true; + } + + /** + \brief Sets a value. This will overwrite older values. + \param section The section. Must have a length greater than one. + \param key The key. Must have a length greater than one. + \param value The value. Can be empty (effectively removing the value). + \return true if the value was set successfully, false otherwise. + */ + inline bool SetValue(const std::string & section, const std::string & key, const std::string & value) + { + auto trimmedSection = trim(section); + auto trimmedKey = trim(key); + if(!trimmedSection.length() || !trimmedKey.length()) + return false; + auto found = _sections.find(trimmedSection); + if(found != _sections.end()) + found->second[trimmedKey] = value; + else + { + KeyValueMap keyValueMap; + keyValueMap[trimmedKey] = value; + _sections[trimmedSection] = keyValueMap; + } + return true; + } + + /** + \brief Removes all key/value pairs from a section. + \param section The section to clear. + \return true if it succeeds, false otherwise. + */ + inline bool ClearSection(const std::string & section) + { + auto trimmedSection = trim(section); + if(!trimmedSection.length()) + return false; + auto found = _sections.find(trimmedSection); + if(found == _sections.end()) + return false; + _sections.erase(found); + return true; + } + + /** + \brief Removes all sections. + */ + inline void Clear() + { + _sections.clear(); + } + + /** + \brief Gets a value. + \param section The section. + \param key The key. + \param [in,out] value The value. + \return The value. Empty string when the value was not found or empty. + */ + inline std::string GetValue(const std::string & section, const std::string & key) const + { + auto trimmedSection = trim(section); + auto trimmedKey = trim(key); + if(!trimmedSection.length() || !trimmedKey.length()) + return ""; + auto sectionFound = _sections.find(trimmedSection); + if(sectionFound == _sections.end()) + return ""; + const auto & keyValueMap = sectionFound->second; + auto keyFound = keyValueMap.find(trimmedKey); + if(keyFound == keyValueMap.end()) + return ""; + return keyFound->second; + } + +private: + typedef std::map KeyValueMap; + std::map _sections; + + enum class LineType + { + Invalid, + Empty, + Section, + KeyValue, + Comment + }; + + static inline LineType getLineType(const std::string & line) + { + auto len = line.length(); + if(!len) + return LineType::Empty; + if(line[0] == '[' && line[len - 1] == ']') + return LineType::Section; + if(line[0] == ';') + return LineType::Comment; + if(line.find('=') != std::string::npos) + return LineType::KeyValue; + return LineType::Invalid; + } + + static inline std::string trim(const std::string & str) + { + auto len = str.length(); + if(!len) + return ""; + size_t pre = 0; + while(str[pre] == ' ') + pre++; + size_t post = 0; + while(str[len - post - 1] == ' ' && post < len) + post++; + auto sublen = len - post - pre; + return sublen > 0 ? str.substr(pre, len - post - pre) : ""; + } + + static inline bool parseKeyValueLine(const std::string & line, std::string & key, std::string & value) + { + auto pos = line.find('='); + key = trim(line.substr(0, pos)); + value = trim(line.substr(pos + 1)); + auto len = value.length(); + if(len && value[0] == '\"' && value[len - 1] == '\"') + value = unescapeValue(value); + return true; + } + + static inline bool parseSectionLine(const std::string & line, std::string & section) + { + section = trim(line.substr(1, line.length() - 2)); + return section.length() > 0; + } + + static inline void appendLine(std::string & output, const std::string & line) + { + if(output.length()) + output += "\r\n"; + output += line; + } + + static inline std::string makeSectionText(const std::string & section) + { + return "[" + section + "]"; + } + + static inline std::string makeKeyValueText(const std::string & key, const std::string & value) + { + return key + "=" + escapeValue(value); + } + + static inline bool needsEscaping(const std::string & value) + { + auto len = value.length(); + return len && (value[0] == ' ' || value[len - 1] == ' ' || + value.find('\n') != std::string::npos || + value.find('\"') != std::string::npos); + } + + static inline std::string escapeValue(const std::string & value) + { + if(!needsEscaping(value)) + return value; + std::string escaped = "\""; + for(auto ch : value) + { + switch(ch) + { + case '\"': + escaped += "\\\""; + break; + case '\\': + escaped += "\\\\"; + break; + case '\r': + escaped += "\\r"; + break; + case '\n': + escaped += "\\n"; + break; + case '\t': + escaped += "\\t"; + default: + escaped += ch; + } + } + return escaped + "\""; + } + + static inline std::string unescapeValue(const std::string & str) + { + std::string result; + bool bEscaped = false; + for(auto ch : str) + { + if(!bEscaped) + { + switch(ch) + { + case '\"': + break; + case '\\': + bEscaped = true; + break; + default: + result += ch; + } + } + else + { + switch(ch) + { + case 'r': + result += '\r'; + break; + case 'n': + result += '\n'; + break; + case 't': + result += '\t'; + break; + default: + result += ch; + } + bEscaped = false; + } + } + if(bEscaped) + result += '\\'; + return result; + } +}; + #endif //_UTF8INI_H \ No newline at end of file diff --git a/src/bridge/_global.cpp b/src/bridge/_global.cpp index 5ef4d07b..a9ce42d1 100644 --- a/src/bridge/_global.cpp +++ b/src/bridge/_global.cpp @@ -1,26 +1,26 @@ -#include "_global.h" - -GUIGUIINIT _gui_guiinit; -GUISENDMESSAGE _gui_sendmessage; -GUISENDMESSAGEASYNC _gui_sendmessageasync; - -DBGDBGINIT _dbg_dbginit; -DBGMEMFINDBASEADDR _dbg_memfindbaseaddr; -DBGMEMREAD _dbg_memread; -DBGMEMWRITE _dbg_memwrite; -DBGDBGCMDEXEC _dbg_dbgcmdexec; -DBGMEMMAP _dbg_memmap; -DBGDBGEXITSIGNAL _dbg_dbgexitsignal; -DBGVALFROMSTRING _dbg_valfromstring; -DBGISDEBUGGING _dbg_isdebugging; -DBGISJUMPGOINGTOEXECUTE _dbg_isjumpgoingtoexecute; -DBGADDRINFOGET _dbg_addrinfoget; -DBGADDRINFOSET _dbg_addrinfoset; -DBGBPGETTYPEAT _dbg_bpgettypeat; -DBGGETREGDUMP _dbg_getregdump; -DBGVALTOSTRING _dbg_valtostring; -DBGMEMISVALIDREADPTR _dbg_memisvalidreadptr; -DBGGETBPLIST _dbg_getbplist; -DBGDBGCMDEXECDIRECT _dbg_dbgcmddirectexec; -DBGGETBRANCHDESTINATION _dbg_getbranchdestination; -DBGSENDMESSAGE _dbg_sendmessage; +#include "_global.h" + +GUIGUIINIT _gui_guiinit; +GUISENDMESSAGE _gui_sendmessage; +GUISENDMESSAGEASYNC _gui_sendmessageasync; + +DBGDBGINIT _dbg_dbginit; +DBGMEMFINDBASEADDR _dbg_memfindbaseaddr; +DBGMEMREAD _dbg_memread; +DBGMEMWRITE _dbg_memwrite; +DBGDBGCMDEXEC _dbg_dbgcmdexec; +DBGMEMMAP _dbg_memmap; +DBGDBGEXITSIGNAL _dbg_dbgexitsignal; +DBGVALFROMSTRING _dbg_valfromstring; +DBGISDEBUGGING _dbg_isdebugging; +DBGISJUMPGOINGTOEXECUTE _dbg_isjumpgoingtoexecute; +DBGADDRINFOGET _dbg_addrinfoget; +DBGADDRINFOSET _dbg_addrinfoset; +DBGBPGETTYPEAT _dbg_bpgettypeat; +DBGGETREGDUMP _dbg_getregdump; +DBGVALTOSTRING _dbg_valtostring; +DBGMEMISVALIDREADPTR _dbg_memisvalidreadptr; +DBGGETBPLIST _dbg_getbplist; +DBGDBGCMDEXECDIRECT _dbg_dbgcmddirectexec; +DBGGETBRANCHDESTINATION _dbg_getbranchdestination; +DBGSENDMESSAGE _dbg_sendmessage; diff --git a/src/bridge/_global.h b/src/bridge/_global.h index e880e35b..18cdf768 100644 --- a/src/bridge/_global.h +++ b/src/bridge/_global.h @@ -1,61 +1,61 @@ -#ifndef _GLOBAL_H -#define _GLOBAL_H - -#include -#include "bridgemain.h" - -//GUI typedefs -typedef int (*GUIGUIINIT)(int, char**); -typedef void* (*GUISENDMESSAGE)(GUIMSG type, void* param1, void* param2); -typedef void (*GUISENDMESSAGEASYNC)(GUIMSG type, void* param1, void* param2); - -//GUI functions -extern GUIGUIINIT _gui_guiinit; -extern GUISENDMESSAGE _gui_sendmessage; -extern GUISENDMESSAGEASYNC _gui_sendmessageasync; - -//DBG typedefs -typedef const char* (*DBGDBGINIT)(); -typedef duint (*DBGMEMFINDBASEADDR)(duint addr, duint* size); -typedef bool (*DBGMEMREAD)(duint addr, unsigned char* dest, duint size, duint* read); -typedef bool (*DBGMEMWRITE)(duint addr, const unsigned char* src, duint size, duint* written); -typedef bool (*DBGDBGCMDEXEC)(const char* cmd); -typedef bool (*DBGMEMMAP)(MEMMAP* memmap); -typedef void (*DBGDBGEXITSIGNAL)(); -typedef bool (*DBGVALFROMSTRING)(const char* string, duint* value); -typedef bool (*DBGISDEBUGGING)(); -typedef bool (*DBGISJUMPGOINGTOEXECUTE)(duint addr); -typedef bool (*DBGADDRINFOGET)(duint addr, SEGMENTREG segment, ADDRINFO* addrinfo); -typedef bool (*DBGADDRINFOSET)(duint addr, ADDRINFO* addrinfo); -typedef BPXTYPE (*DBGBPGETTYPEAT)(duint addr); -typedef bool (*DBGGETREGDUMP)(REGDUMP* regdump); -typedef bool (*DBGVALTOSTRING)(const char* string, duint value); -typedef bool (*DBGMEMISVALIDREADPTR)(duint addr); -typedef int (*DBGGETBPLIST)(BPXTYPE type, BPMAP* bplist); -typedef bool (*DBGDBGCMDEXECDIRECT)(const char* cmd); -typedef duint (*DBGGETBRANCHDESTINATION)(duint addr); -typedef duint (*DBGSENDMESSAGE)(DBGMSG type, void* param1, void* param2); - -//DBG functions -extern DBGDBGINIT _dbg_dbginit; -extern DBGMEMFINDBASEADDR _dbg_memfindbaseaddr; -extern DBGMEMREAD _dbg_memread; -extern DBGMEMWRITE _dbg_memwrite; -extern DBGDBGCMDEXEC _dbg_dbgcmdexec; -extern DBGMEMMAP _dbg_memmap; -extern DBGDBGEXITSIGNAL _dbg_dbgexitsignal; -extern DBGVALFROMSTRING _dbg_valfromstring; -extern DBGISDEBUGGING _dbg_isdebugging; -extern DBGISJUMPGOINGTOEXECUTE _dbg_isjumpgoingtoexecute; -extern DBGADDRINFOGET _dbg_addrinfoget; -extern DBGADDRINFOSET _dbg_addrinfoset; -extern DBGBPGETTYPEAT _dbg_bpgettypeat; -extern DBGGETREGDUMP _dbg_getregdump; -extern DBGVALTOSTRING _dbg_valtostring; -extern DBGMEMISVALIDREADPTR _dbg_memisvalidreadptr; -extern DBGGETBPLIST _dbg_getbplist; -extern DBGDBGCMDEXECDIRECT _dbg_dbgcmddirectexec; -extern DBGGETBRANCHDESTINATION _dbg_getbranchdestination; -extern DBGSENDMESSAGE _dbg_sendmessage; - -#endif // _GLOBAL_H +#ifndef _GLOBAL_H +#define _GLOBAL_H + +#include +#include "bridgemain.h" + +//GUI typedefs +typedef int (*GUIGUIINIT)(int, char**); +typedef void* (*GUISENDMESSAGE)(GUIMSG type, void* param1, void* param2); +typedef void (*GUISENDMESSAGEASYNC)(GUIMSG type, void* param1, void* param2); + +//GUI functions +extern GUIGUIINIT _gui_guiinit; +extern GUISENDMESSAGE _gui_sendmessage; +extern GUISENDMESSAGEASYNC _gui_sendmessageasync; + +//DBG typedefs +typedef const char* (*DBGDBGINIT)(); +typedef duint (*DBGMEMFINDBASEADDR)(duint addr, duint* size); +typedef bool (*DBGMEMREAD)(duint addr, unsigned char* dest, duint size, duint* read); +typedef bool (*DBGMEMWRITE)(duint addr, const unsigned char* src, duint size, duint* written); +typedef bool (*DBGDBGCMDEXEC)(const char* cmd); +typedef bool (*DBGMEMMAP)(MEMMAP* memmap); +typedef void (*DBGDBGEXITSIGNAL)(); +typedef bool (*DBGVALFROMSTRING)(const char* string, duint* value); +typedef bool (*DBGISDEBUGGING)(); +typedef bool (*DBGISJUMPGOINGTOEXECUTE)(duint addr); +typedef bool (*DBGADDRINFOGET)(duint addr, SEGMENTREG segment, ADDRINFO* addrinfo); +typedef bool (*DBGADDRINFOSET)(duint addr, ADDRINFO* addrinfo); +typedef BPXTYPE (*DBGBPGETTYPEAT)(duint addr); +typedef bool (*DBGGETREGDUMP)(REGDUMP* regdump); +typedef bool (*DBGVALTOSTRING)(const char* string, duint value); +typedef bool (*DBGMEMISVALIDREADPTR)(duint addr); +typedef int (*DBGGETBPLIST)(BPXTYPE type, BPMAP* bplist); +typedef bool (*DBGDBGCMDEXECDIRECT)(const char* cmd); +typedef duint (*DBGGETBRANCHDESTINATION)(duint addr); +typedef duint (*DBGSENDMESSAGE)(DBGMSG type, void* param1, void* param2); + +//DBG functions +extern DBGDBGINIT _dbg_dbginit; +extern DBGMEMFINDBASEADDR _dbg_memfindbaseaddr; +extern DBGMEMREAD _dbg_memread; +extern DBGMEMWRITE _dbg_memwrite; +extern DBGDBGCMDEXEC _dbg_dbgcmdexec; +extern DBGMEMMAP _dbg_memmap; +extern DBGDBGEXITSIGNAL _dbg_dbgexitsignal; +extern DBGVALFROMSTRING _dbg_valfromstring; +extern DBGISDEBUGGING _dbg_isdebugging; +extern DBGISJUMPGOINGTOEXECUTE _dbg_isjumpgoingtoexecute; +extern DBGADDRINFOGET _dbg_addrinfoget; +extern DBGADDRINFOSET _dbg_addrinfoset; +extern DBGBPGETTYPEAT _dbg_bpgettypeat; +extern DBGGETREGDUMP _dbg_getregdump; +extern DBGVALTOSTRING _dbg_valtostring; +extern DBGMEMISVALIDREADPTR _dbg_memisvalidreadptr; +extern DBGGETBPLIST _dbg_getbplist; +extern DBGDBGCMDEXECDIRECT _dbg_dbgcmddirectexec; +extern DBGGETBRANCHDESTINATION _dbg_getbranchdestination; +extern DBGSENDMESSAGE _dbg_sendmessage; + +#endif // _GLOBAL_H diff --git a/src/bridge/bridgelist.h b/src/bridge/bridgelist.h index 76101133..78b6c887 100644 --- a/src/bridge/bridgelist.h +++ b/src/bridge/bridgelist.h @@ -1,129 +1,129 @@ -#ifndef _LIST_H -#define _LIST_H - -typedef struct -{ - int count; //Number of element in the list. - size_t size; //Size of list in bytes (used for type checking). - void* data; //Pointer to the list contents. Must be deleted by the caller using BridgeFree (or List::Free). -} ListInfo; - -#define ListOf(Type) ListInfo* - -#ifdef __cplusplus - -#include - -/** -\brief A list object. This object is NOT thread safe. -\tparam Type List contents type. -*/ -template -class List -{ -public: - /** - \brief List constructor. - \param _freeData (Optional) the free function. - */ - explicit inline List() - { - memset(&_listInfo, 0, sizeof(_listInfo)); - } - - /** - \brief List destructor. - */ - inline ~List() - { - cleanup(); - } - - /** - \brief Gets the list data. - \return Returns ListInfo->data. Can be null if the list was never initialized. Will be destroyed once this object goes out of scope! - */ - inline Type* data() const - { - return reinterpret_cast(_listInfo.data); - } - - /** - \brief Gets the number of elements in the list. This will crash the program if the data is not consistent with the specified template argument. - \return The number of elements in the list. - */ - inline int count() const - { - if(_listInfo.size != _listInfo.count * sizeof(Type)) //make sure the user is using the correct type. - __debugbreak(); - return _listInfo.count; - } - - /** - \brief Cleans up the list, freeing the list data when it is not null. - */ - inline void cleanup() - { - if(_listInfo.data) - { - BridgeFree(_listInfo.data); - _listInfo.data = nullptr; - } - } - - /** - \brief Reference operator (cleans up the previous list) - \return Pointer to the ListInfo. - */ - inline ListInfo* operator&() - { - cleanup(); - return &_listInfo; - } - - /** - \brief Array indexer operator. This will crash if you try to access out-of-bounds. - \param index Zero-based index of the item you want to get. - \return Reference to a value at that index. - */ - inline Type & operator[](size_t index) const - { - if(index >= size_t(count())) //make sure the out-of-bounds access is caught as soon as possible. - __debugbreak(); - return data()[index]; - } - - /** - \brief Copies data to a ListInfo structure.. - \param [out] listInfo If non-null, information describing the list. - \param listData Data to copy in the ListInfo structure. - \return true if it succeeds, false if it fails. - */ - static inline bool CopyData(ListInfo* listInfo, const std::vector & listData) - { - if(!listInfo) - return false; - listInfo->count = int(listData.size()); - listInfo->size = listInfo->count * sizeof(Type); - if(listInfo->count) - { - listInfo->data = BridgeAlloc(listInfo->size); - Type* curItem = reinterpret_cast(listInfo->data); - for(const auto & item : listData) - { - *curItem = item; - ++curItem; - } - } - else - listInfo->data = nullptr; - return true; - } - -private: - ListInfo _listInfo; -}; - -#endif //__cplusplus - +#ifndef _LIST_H +#define _LIST_H + +typedef struct +{ + int count; //Number of element in the list. + size_t size; //Size of list in bytes (used for type checking). + void* data; //Pointer to the list contents. Must be deleted by the caller using BridgeFree (or List::Free). +} ListInfo; + +#define ListOf(Type) ListInfo* + +#ifdef __cplusplus + +#include + +/** +\brief A list object. This object is NOT thread safe. +\tparam Type List contents type. +*/ +template +class List +{ +public: + /** + \brief List constructor. + \param _freeData (Optional) the free function. + */ + explicit inline List() + { + memset(&_listInfo, 0, sizeof(_listInfo)); + } + + /** + \brief List destructor. + */ + inline ~List() + { + cleanup(); + } + + /** + \brief Gets the list data. + \return Returns ListInfo->data. Can be null if the list was never initialized. Will be destroyed once this object goes out of scope! + */ + inline Type* data() const + { + return reinterpret_cast(_listInfo.data); + } + + /** + \brief Gets the number of elements in the list. This will crash the program if the data is not consistent with the specified template argument. + \return The number of elements in the list. + */ + inline int count() const + { + if(_listInfo.size != _listInfo.count * sizeof(Type)) //make sure the user is using the correct type. + __debugbreak(); + return _listInfo.count; + } + + /** + \brief Cleans up the list, freeing the list data when it is not null. + */ + inline void cleanup() + { + if(_listInfo.data) + { + BridgeFree(_listInfo.data); + _listInfo.data = nullptr; + } + } + + /** + \brief Reference operator (cleans up the previous list) + \return Pointer to the ListInfo. + */ + inline ListInfo* operator&() + { + cleanup(); + return &_listInfo; + } + + /** + \brief Array indexer operator. This will crash if you try to access out-of-bounds. + \param index Zero-based index of the item you want to get. + \return Reference to a value at that index. + */ + inline Type & operator[](size_t index) const + { + if(index >= size_t(count())) //make sure the out-of-bounds access is caught as soon as possible. + __debugbreak(); + return data()[index]; + } + + /** + \brief Copies data to a ListInfo structure.. + \param [out] listInfo If non-null, information describing the list. + \param listData Data to copy in the ListInfo structure. + \return true if it succeeds, false if it fails. + */ + static inline bool CopyData(ListInfo* listInfo, const std::vector & listData) + { + if(!listInfo) + return false; + listInfo->count = int(listData.size()); + listInfo->size = listInfo->count * sizeof(Type); + if(listInfo->count) + { + listInfo->data = BridgeAlloc(listInfo->size); + Type* curItem = reinterpret_cast(listInfo->data); + for(const auto & item : listData) + { + *curItem = item; + ++curItem; + } + } + else + listInfo->data = nullptr; + return true; + } + +private: + ListInfo _listInfo; +}; + +#endif //__cplusplus + #endif //_LIST_H \ No newline at end of file diff --git a/src/bridge/bridgemain.cpp b/src/bridge/bridgemain.cpp index c29cd0f4..da361cae 100644 --- a/src/bridge/bridgemain.cpp +++ b/src/bridge/bridgemain.cpp @@ -1,1238 +1,1238 @@ -/** - * \file bridgemain.cpp - * - * \brief Defines functions to initialize and start the Bridge and - * to interface with the GUI and the DBG. - */ -#include "_global.h" -#include "bridgemain.h" -#include -#include "Utf8Ini.h" - -static HINSTANCE hInst; -static Utf8Ini settings; -static wchar_t szIniFile[MAX_PATH] = L""; -static CRITICAL_SECTION csIni; - -#ifdef _WIN64 -#define dbg_lib "x64dbg.dll" -#define gui_lib "x64gui.dll" -#else -#define dbg_lib "x32dbg.dll" -#define gui_lib "x32gui.dll" -#endif // _WIN64 - -#define LOADLIBRARY(name) \ - szLib=name; \ - hInst=LoadLibraryA(name); \ - if(!hInst) \ - return "Error loading library \""name"\"!" - -#define LOADEXPORT(name) \ - *((FARPROC*)&name)=GetProcAddress(hInst, #name); \ - if(!name) \ - { \ - sprintf(szError, "Export %s:%s could not be found!", szLib, #name); \ - return szError; \ - } - -BRIDGE_IMPEXP const char* BridgeInit() -{ - //Initialize critial section - InitializeCriticalSection(&csIni); - - //Settings load - if(!GetModuleFileNameW(0, szIniFile, MAX_PATH)) - return "Error getting module path!"; - int len = (int)wcslen(szIniFile); - while(szIniFile[len] != L'.' && szIniFile[len] != L'\\' && len) - len--; - if(szIniFile[len] == L'\\') - wcscat_s(szIniFile, L".ini"); - else - wcscpy_s(&szIniFile[len], _countof(szIniFile) - len, L".ini"); - - HINSTANCE hInst; - const char* szLib; - static char szError[256] = ""; - - //GUI Load - LOADLIBRARY(gui_lib); - LOADEXPORT(_gui_guiinit); - LOADEXPORT(_gui_sendmessage); - - //DBG Load - LOADLIBRARY(dbg_lib); - LOADEXPORT(_dbg_dbginit); - LOADEXPORT(_dbg_memfindbaseaddr); - LOADEXPORT(_dbg_memread); - LOADEXPORT(_dbg_memwrite); - LOADEXPORT(_dbg_dbgcmdexec); - LOADEXPORT(_dbg_memmap); - LOADEXPORT(_dbg_dbgexitsignal); - LOADEXPORT(_dbg_valfromstring); - LOADEXPORT(_dbg_isdebugging); - LOADEXPORT(_dbg_isjumpgoingtoexecute); - LOADEXPORT(_dbg_addrinfoget); - LOADEXPORT(_dbg_addrinfoset); - LOADEXPORT(_dbg_bpgettypeat); - LOADEXPORT(_dbg_getregdump); - LOADEXPORT(_dbg_valtostring); - LOADEXPORT(_dbg_memisvalidreadptr); - LOADEXPORT(_dbg_getbplist); - LOADEXPORT(_dbg_dbgcmddirectexec); - LOADEXPORT(_dbg_getbranchdestination); - LOADEXPORT(_dbg_sendmessage); - return 0; -} - -BRIDGE_IMPEXP const char* BridgeStart() -{ - if(!_dbg_dbginit || !_gui_guiinit) - return "\"_dbg_dbginit\" || \"_gui_guiinit\" was not loaded yet, call BridgeInit!"; - int errorLine = 0; - BridgeSettingRead(&errorLine); - _dbg_sendmessage(DBG_INITIALIZE_LOCKS, nullptr, nullptr); //initialize locks before any other thread than the main thread are started - _gui_guiinit(0, 0); //remove arguments - if(!BridgeSettingFlush()) - return "Failed to save settings!"; - _dbg_sendmessage(DBG_DEINITIALIZE_LOCKS, nullptr, nullptr); //deinitialize locks when only one thread is left (hopefully) - DeleteCriticalSection(&csIni); - return 0; -} - -BRIDGE_IMPEXP void* BridgeAlloc(size_t size) -{ - unsigned char* ptr = (unsigned char*)GlobalAlloc(GMEM_FIXED, size); - if(!ptr) - { - MessageBoxA(0, "Could not allocate memory", "Error", MB_ICONERROR); - ExitProcess(1); - } - memset(ptr, 0, size); - return ptr; -} - -BRIDGE_IMPEXP void BridgeFree(void* ptr) -{ - if(ptr) - GlobalFree(ptr); -} - -BRIDGE_IMPEXP bool BridgeSettingGet(const char* section, const char* key, char* value) -{ - if(!section || !key || !value) - return false; - EnterCriticalSection(&csIni); - auto foundValue = settings.GetValue(section, key); - bool result = foundValue.length() > 0; - if(result) - strcpy_s(value, MAX_SETTING_SIZE, foundValue.c_str()); - LeaveCriticalSection(&csIni); - return result; -} - -BRIDGE_IMPEXP bool BridgeSettingGetUint(const char* section, const char* key, duint* value) -{ - if(!section || !key || !value) - return false; - char newvalue[MAX_SETTING_SIZE] = ""; - if(!BridgeSettingGet(section, key, newvalue)) - return false; -#ifdef _WIN64 - int ret = sscanf(newvalue, "%llX", value); -#else - int ret = sscanf(newvalue, "%X", value); -#endif //_WIN64 - if(ret) - return true; - return false; -} - -BRIDGE_IMPEXP bool BridgeSettingSet(const char* section, const char* key, const char* value) -{ - bool success = false; - if(section) - { - EnterCriticalSection(&csIni); - if(!key) - success = settings.ClearSection(section); - else if(!value) - success = settings.SetValue(section, key, ""); - else - success = settings.SetValue(section, key, value); - LeaveCriticalSection(&csIni); - } - return success; -} - -BRIDGE_IMPEXP bool BridgeSettingSetUint(const char* section, const char* key, duint value) -{ - if(!section || !key) - return false; - char newvalue[MAX_SETTING_SIZE] = ""; -#ifdef _WIN64 - sprintf(newvalue, "%llX", value); -#else - sprintf(newvalue, "%X", value); -#endif //_WIN64 - return BridgeSettingSet(section, key, newvalue); -} - -BRIDGE_IMPEXP bool BridgeSettingFlush() -{ - EnterCriticalSection(&csIni); - std::string iniData = settings.Serialize(); - LeaveCriticalSection(&csIni); - bool success = false; - HANDLE hFile = CreateFileW(szIniFile, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); - if(hFile != INVALID_HANDLE_VALUE) - { - SetEndOfFile(hFile); - DWORD written = 0; - if(WriteFile(hFile, iniData.c_str(), (DWORD)iniData.length(), &written, nullptr)) - success = true; - CloseHandle(hFile); - } - return success; -} - -BRIDGE_IMPEXP bool BridgeSettingRead(int* errorLine) -{ - if(errorLine) - *errorLine = 0; - bool success = false; - std::string iniData; - HANDLE hFile = CreateFileW(szIniFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); - if(hFile != INVALID_HANDLE_VALUE) - { - DWORD fileSize = GetFileSize(hFile, nullptr); - if(fileSize) - { - unsigned char utf8bom[] = { 0xEF, 0xBB, 0xBF }; - char* fileData = (char*)BridgeAlloc(sizeof(utf8bom) + fileSize + 1); - DWORD read = 0; - if(ReadFile(hFile, fileData, fileSize, &read, nullptr)) - { - success = true; - if(!memcmp(fileData, utf8bom, sizeof(utf8bom))) - iniData.assign(fileData + sizeof(utf8bom)); - else - iniData.assign(fileData); - } - BridgeFree(fileData); - } - CloseHandle(hFile); - } - if(success) //if we failed to read the file, the current settings are better than none at all - { - EnterCriticalSection(&csIni); - int errline = 0; - success = settings.Deserialize(iniData, errline); - if(errorLine) - *errorLine = errline; - LeaveCriticalSection(&csIni); - } - return success; -} - -BRIDGE_IMPEXP int BridgeGetDbgVersion() -{ - return DBG_VERSION; -} - -BRIDGE_IMPEXP bool DbgMemRead(duint va, unsigned char* dest, duint size) -{ - if(IsBadWritePtr(dest, size)) - { - GuiAddLogMessage("DbgMemRead with invalid boundaries!\n"); - return false; - } - - if (!_dbg_memread(va, dest, size, 0)) - { - // Zero the buffer on failure - memset(dest, 0, size); - return false; - } - - return true; -} - -BRIDGE_IMPEXP bool DbgMemWrite(duint va, const unsigned char* src, duint size) -{ - if(IsBadReadPtr(src, size)) - { - GuiAddLogMessage("DbgMemWrite with invalid boundaries!\n"); - return false; - } - return _dbg_memwrite(va, src, size, 0); -} - -// FIXME, not exactly base if it still does a find? -BRIDGE_IMPEXP duint DbgMemGetPageSize(duint base) -{ - duint size = 0; - _dbg_memfindbaseaddr(base, &size); - return size; -} - -BRIDGE_IMPEXP duint DbgMemFindBaseAddr(duint addr, duint* size) -{ - return _dbg_memfindbaseaddr(addr, size); -} - -BRIDGE_IMPEXP bool DbgCmdExec(const char* cmd) -{ - return _dbg_dbgcmdexec(cmd); -} - -// FIXME -BRIDGE_IMPEXP bool DbgMemMap(MEMMAP* memmap) -{ - return _dbg_memmap(memmap); -} - -BRIDGE_IMPEXP bool DbgIsValidExpression(const char* expression) -{ - duint value = 0; - return _dbg_valfromstring(expression, &value); -} - -BRIDGE_IMPEXP bool DbgIsDebugging() -{ - return _dbg_isdebugging(); -} - -BRIDGE_IMPEXP bool DbgIsJumpGoingToExecute(duint addr) -{ - return _dbg_isjumpgoingtoexecute(addr); -} - -// FIXME required size of arg _text_? -BRIDGE_IMPEXP bool DbgGetLabelAt(duint addr, SEGMENTREG segment, char* text) //(module.)+label -{ - if(!text || !addr) - return false; - ADDRINFO info; - memset(&info, 0, sizeof(info)); - info.flags = flaglabel; - if(!_dbg_addrinfoget(addr, segment, &info)) - { - duint addr_ = 0; - if(!DbgMemIsValidReadPtr(addr)) - return false; - DbgMemRead(addr, (unsigned char*)&addr_, sizeof(duint)); - ADDRINFO ptrinfo = info; - if(!_dbg_addrinfoget(addr_, SEG_DEFAULT, &ptrinfo)) - return false; - sprintf_s(info.label, "&%s", ptrinfo.label); - } - strcpy_s(text, MAX_LABEL_SIZE, info.label); - return true; -} - -BRIDGE_IMPEXP bool DbgSetLabelAt(duint addr, const char* text) -{ - if(!text || strlen(text) >= MAX_LABEL_SIZE || !addr) - return false; - ADDRINFO info; - memset(&info, 0, sizeof(info)); - info.flags = flaglabel; - strcpy_s(info.label, text); - if(!_dbg_addrinfoset(addr, &info)) - return false; - return true; -} - -// FIXME required size of arg _text_? -BRIDGE_IMPEXP bool DbgGetCommentAt(duint addr, char* text) //comment (not live) -{ - if(!text || !addr) - return false; - ADDRINFO info; - memset(&info, 0, sizeof(info)); - info.flags = flagcomment; - if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) - return false; - strcpy_s(text, MAX_COMMENT_SIZE, info.comment); - return true; -} - -BRIDGE_IMPEXP bool DbgSetCommentAt(duint addr, const char* text) -{ - if(!text || strlen(text) >= MAX_COMMENT_SIZE || !addr) - return false; - ADDRINFO info; - memset(&info, 0, sizeof(info)); - info.flags = flagcomment; - strcpy_s(info.comment, MAX_COMMENT_SIZE, text); - if(!_dbg_addrinfoset(addr, &info)) - return false; - return true; -} - -// FIXME required size of arg _text_? -BRIDGE_IMPEXP bool DbgGetModuleAt(duint addr, char* text) -{ - if(!text || !addr) - return false; - ADDRINFO info; - memset(&info, 0, sizeof(info)); - info.flags = flagmodule; - if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) - return false; - strcpy_s(text, MAX_MODULE_SIZE, info.module); - return true; -} - -BRIDGE_IMPEXP bool DbgGetBookmarkAt(duint addr) -{ - if(!addr) - return false; - ADDRINFO info; - memset(&info, 0, sizeof(info)); - info.flags = flagbookmark; - if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) - return false; - return info.isbookmark; -} - -BRIDGE_IMPEXP bool DbgSetBookmarkAt(duint addr, bool isbookmark) -{ - if(!addr) - return false; - ADDRINFO info; - memset(&info, 0, sizeof(info)); - info.flags = flagbookmark; - info.isbookmark = isbookmark; - return _dbg_addrinfoset(addr, &info); -} - -// FIXME return on success? -BRIDGE_IMPEXP const char* DbgInit() -{ - return _dbg_dbginit(); -} - -BRIDGE_IMPEXP void DbgExit() -{ - _dbg_dbgexitsignal(); //send exit signal to debugger -} - -BRIDGE_IMPEXP BPXTYPE DbgGetBpxTypeAt(duint addr) -{ - return _dbg_bpgettypeat(addr); -} - -BRIDGE_IMPEXP duint DbgValFromString(const char* string) -{ - duint value = 0; - _dbg_valfromstring(string, &value); - return value; -} - -BRIDGE_IMPEXP bool DbgGetRegDump(REGDUMP* regdump) -{ - return _dbg_getregdump(regdump); -} - -// FIXME all -BRIDGE_IMPEXP bool DbgValToString(const char* string, duint value) -{ - return _dbg_valtostring(string, value); -} - -BRIDGE_IMPEXP bool DbgMemIsValidReadPtr(duint addr) -{ - return _dbg_memisvalidreadptr(addr); -} - -// FIXME return -BRIDGE_IMPEXP int DbgGetBpList(BPXTYPE type, BPMAP* list) -{ - return _dbg_getbplist(type, list); -} - -// FIXME all -BRIDGE_IMPEXP bool DbgCmdExecDirect(const char* cmd) -{ - return _dbg_dbgcmddirectexec(cmd); -} - -BRIDGE_IMPEXP FUNCTYPE DbgGetFunctionTypeAt(duint addr) -{ - ADDRINFO info; - memset(&info, 0, sizeof(info)); - info.flags = flagfunction; - if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) - return FUNC_NONE; - duint start = info.function.start; - duint end = info.function.end; - if(start == end) - return FUNC_SINGLE; - else if(addr == start) - return FUNC_BEGIN; - else if(addr == end) - return FUNC_END; - return FUNC_MIDDLE; -} - -// FIXME depth -BRIDGE_IMPEXP LOOPTYPE DbgGetLoopTypeAt(duint addr, int depth) -{ - ADDRINFO info; - memset(&info, 0, sizeof(info)); - info.flags = flagloop; - info.loop.depth = depth; - if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) - return LOOP_NONE; - duint start = info.loop.start; - duint end = info.loop.end; - if(addr == start) - return LOOP_BEGIN; - else if(addr == end) - return LOOP_END; - return LOOP_MIDDLE; -} - -BRIDGE_IMPEXP duint DbgGetBranchDestination(duint addr) -{ - return _dbg_getbranchdestination(addr); -} - -BRIDGE_IMPEXP void DbgScriptLoad(const char* filename) -{ - _dbg_sendmessage(DBG_SCRIPT_LOAD, (void*)filename, 0); -} - -// FIXME every? -BRIDGE_IMPEXP void DbgScriptUnload() -{ - _dbg_sendmessage(DBG_SCRIPT_UNLOAD, 0, 0); -} - -// FIXME "the script?"; destline -BRIDGE_IMPEXP void DbgScriptRun(int destline) -{ - _dbg_sendmessage(DBG_SCRIPT_RUN, (void*)(duint)destline, 0); -} - -BRIDGE_IMPEXP void DbgScriptStep() -{ - _dbg_sendmessage(DBG_SCRIPT_STEP, 0, 0); -} - -BRIDGE_IMPEXP bool DbgScriptBpToggle(int line) -{ - if(_dbg_sendmessage(DBG_SCRIPT_BPTOGGLE, (void*)(duint)line, 0)) - return true; - return false; -} - -BRIDGE_IMPEXP bool DbgScriptBpGet(int line) -{ - if(_dbg_sendmessage(DBG_SCRIPT_BPGET, (void*)(duint)line, 0)) - return true; - return false; -} - -BRIDGE_IMPEXP bool DbgScriptCmdExec(const char* command) -{ - if(_dbg_sendmessage(DBG_SCRIPT_CMDEXEC, (void*)command, 0)) - return true; - return false; -} - -BRIDGE_IMPEXP void DbgScriptAbort() -{ - _dbg_sendmessage(DBG_SCRIPT_ABORT, 0, 0); -} - -BRIDGE_IMPEXP SCRIPTLINETYPE DbgScriptGetLineType(int line) -{ - return (SCRIPTLINETYPE)_dbg_sendmessage(DBG_SCRIPT_GETLINETYPE, (void*)(duint)line, 0); -} - -BRIDGE_IMPEXP void DbgScriptSetIp(int line) -{ - _dbg_sendmessage(DBG_SCRIPT_SETIP, (void*)(duint)line, 0); -} - -// FIXME non-null? -BRIDGE_IMPEXP bool DbgScriptGetBranchInfo(int line, SCRIPTBRANCH* info) -{ - return !!_dbg_sendmessage(DBG_SCRIPT_GETBRANCHINFO, (void*)(duint)line, info); -} - -// FIXME all -BRIDGE_IMPEXP void DbgSymbolEnum(duint base, CBSYMBOLENUM cbSymbolEnum, void* user) -{ - SYMBOLCBINFO cbInfo; - cbInfo.base = base; - cbInfo.cbSymbolEnum = cbSymbolEnum; - cbInfo.user = user; - _dbg_sendmessage(DBG_SYMBOL_ENUM, &cbInfo, 0); -} - -BRIDGE_IMPEXP bool DbgAssembleAt(duint addr, const char* instruction) -{ - if(_dbg_sendmessage(DBG_ASSEMBLE_AT, (void*)addr, (void*)instruction)) - return true; - return false; -} - -BRIDGE_IMPEXP duint DbgModBaseFromName(const char* name) -{ - return _dbg_sendmessage(DBG_MODBASE_FROM_NAME, (void*)name, 0); -} - -BRIDGE_IMPEXP void DbgDisasmAt(duint addr, DISASM_INSTR* instr) -{ - _dbg_sendmessage(DBG_DISASM_AT, (void*)addr, instr); -} - -BRIDGE_IMPEXP bool DbgStackCommentGet(duint addr, STACK_COMMENT* comment) -{ - return !!_dbg_sendmessage(DBG_STACK_COMMENT_GET, (void*)addr, comment); -} - -BRIDGE_IMPEXP void DbgGetThreadList(THREADLIST* list) -{ - _dbg_sendmessage(DBG_GET_THREAD_LIST, list, 0); -} - -BRIDGE_IMPEXP void DbgSettingsUpdated() -{ - _dbg_sendmessage(DBG_SETTINGS_UPDATED, 0, 0); -} - -BRIDGE_IMPEXP void DbgDisasmFastAt(duint addr, BASIC_INSTRUCTION_INFO* basicinfo) -{ - _dbg_sendmessage(DBG_DISASM_FAST_AT, (void*)addr, basicinfo); -} - -BRIDGE_IMPEXP void DbgMenuEntryClicked(int hEntry) -{ - _dbg_sendmessage(DBG_MENU_ENTRY_CLICKED, (void*)(duint)hEntry, 0); -} - -// FIXME not sure -BRIDGE_IMPEXP bool DbgFunctionGet(duint addr, duint* start, duint* end) -{ - FUNCTION_LOOP_INFO info; - info.addr = addr; - if(!_dbg_sendmessage(DBG_FUNCTION_GET, &info, 0)) - return false; - if(start) - *start = info.start; - if(end) - *end = info.end; - return true; -} - -// FIXME brief, return -BRIDGE_IMPEXP bool DbgFunctionOverlaps(duint start, duint end) -{ - FUNCTION_LOOP_INFO info; - info.start = start; - info.end = end; - if(!_dbg_sendmessage(DBG_FUNCTION_OVERLAPS, &info, 0)) - return false; - return true; -} - -// FIXME brief, return -BRIDGE_IMPEXP bool DbgFunctionAdd(duint start, duint end) -{ - FUNCTION_LOOP_INFO info; - info.start = start; - info.end = end; - info.manual = false; - if(!_dbg_sendmessage(DBG_FUNCTION_ADD, &info, 0)) - return false; - return true; -} - -// FIXME brief, return -BRIDGE_IMPEXP bool DbgFunctionDel(duint addr) -{ - FUNCTION_LOOP_INFO info; - info.addr = addr; - if(!_dbg_sendmessage(DBG_FUNCTION_DEL, &info, 0)) - return false; - return true; -} - -// FIXME depth -BRIDGE_IMPEXP bool DbgLoopGet(int depth, duint addr, duint* start, duint* end) -{ - FUNCTION_LOOP_INFO info; - info.addr = addr; - info.depth = depth; - if(!_dbg_sendmessage(DBG_LOOP_GET, &info, 0)) - return false; - *start = info.start; - *end = info.end; - return true; -} - -// FIXME brief, depth, return -BRIDGE_IMPEXP bool DbgLoopOverlaps(int depth, duint start, duint end) -{ - FUNCTION_LOOP_INFO info; - info.start = start; - info.end = end; - info.depth = depth; - if(!_dbg_sendmessage(DBG_LOOP_OVERLAPS, &info, 0)) - return false; - return true; -} - -// FIXME brief, return -BRIDGE_IMPEXP bool DbgLoopAdd(duint start, duint end) -{ - FUNCTION_LOOP_INFO info; - info.start = start; - info.end = end; - info.manual = false; - if(!_dbg_sendmessage(DBG_LOOP_ADD, &info, 0)) - return false; - return true; -} - -// FIXME brief, brief -BRIDGE_IMPEXP bool DbgLoopDel(int depth, duint addr) -{ - FUNCTION_LOOP_INFO info; - info.addr = addr; - info.depth = depth; - if(!_dbg_sendmessage(DBG_LOOP_DEL, &info, 0)) - return false; - return true; -} - -// FIXME all -BRIDGE_IMPEXP bool DbgIsRunLocked() -{ - if(_dbg_sendmessage(DBG_IS_RUN_LOCKED, 0, 0)) - return true; - return false; -} - -BRIDGE_IMPEXP bool DbgIsBpDisabled(duint addr) -{ - if(_dbg_sendmessage(DBG_IS_BP_DISABLED, (void*)addr, 0)) - return true; - return false; -} - -BRIDGE_IMPEXP bool DbgSetAutoCommentAt(duint addr, const char* text) -{ - if(_dbg_sendmessage(DBG_SET_AUTO_COMMENT_AT, (void*)addr, (void*)text)) - return true; - return false; -} - -// FIXME brief -BRIDGE_IMPEXP void DbgClearAutoCommentRange(duint start, duint end) -{ - _dbg_sendmessage(DBG_DELETE_AUTO_COMMENT_RANGE, (void*)start, (void*)end); -} - -BRIDGE_IMPEXP bool DbgSetAutoLabelAt(duint addr, const char* text) -{ - if(_dbg_sendmessage(DBG_SET_AUTO_LABEL_AT, (void*)addr, (void*)text)) - return true; - return false; -} - -// FIXME brief -BRIDGE_IMPEXP void DbgClearAutoLabelRange(duint start, duint end) -{ - _dbg_sendmessage(DBG_DELETE_AUTO_LABEL_RANGE, (void*)start, (void*)end); -} - -BRIDGE_IMPEXP bool DbgSetAutoBookmarkAt(duint addr) -{ - if(_dbg_sendmessage(DBG_SET_AUTO_BOOKMARK_AT, (void*)addr, 0)) - return true; - return false; -} - -// FIXME brief -BRIDGE_IMPEXP void DbgClearAutoBookmarkRange(duint start, duint end) -{ - _dbg_sendmessage(DBG_DELETE_AUTO_BOOKMARK_RANGE, (void*)start, (void*)end); -} - -BRIDGE_IMPEXP bool DbgSetAutoFunctionAt(duint start, duint end) -{ - if(_dbg_sendmessage(DBG_SET_AUTO_FUNCTION_AT, (void*)start, (void*)end)) - return true; - return false; -} - -// FIXME brief -BRIDGE_IMPEXP void DbgClearAutoFunctionRange(duint start, duint end) -{ - _dbg_sendmessage(DBG_DELETE_AUTO_FUNCTION_RANGE, (void*)start, (void*)end); -} - -// FIXME size of the buffer? -BRIDGE_IMPEXP bool DbgGetStringAt(duint addr, char* text) -{ - if(_dbg_sendmessage(DBG_GET_STRING_AT, (void*)addr, text)) - return true; - return false; -} - -BRIDGE_IMPEXP const DBGFUNCTIONS* DbgFunctions() -{ - return (const DBGFUNCTIONS*)_dbg_sendmessage(DBG_GET_FUNCTIONS, 0, 0); -} - -BRIDGE_IMPEXP bool DbgWinEvent(MSG* message, long* result) -{ - if(_dbg_sendmessage(DBG_WIN_EVENT, message, result)) - return true; - return false; -} - -BRIDGE_IMPEXP bool DbgWinEventGlobal(MSG* message) -{ - if(_dbg_sendmessage(DBG_WIN_EVENT_GLOBAL, message, 0)) - return true; - return false; -} - -BRIDGE_IMPEXP bool DbgIsRunning() -{ - return !DbgIsRunLocked(); -} - -BRIDGE_IMPEXP duint DbgGetTimeWastedCounter() -{ - return _dbg_sendmessage(DBG_GET_TIME_WASTED_COUNTER, nullptr, nullptr); -} - -BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip) -{ - _gui_sendmessage(GUI_DISASSEMBLE_AT, (void*)addr, (void*)cip); -} - -BRIDGE_IMPEXP void GuiSetDebugState(DBGSTATE state) -{ - _gui_sendmessage(GUI_SET_DEBUG_STATE, (void*)state, 0); -} - - -BRIDGE_IMPEXP void GuiAddLogMessage(const char* msg) -{ - _gui_sendmessage(GUI_ADD_MSG_TO_LOG, (void*)msg, 0); -} - -BRIDGE_IMPEXP void GuiLogClear() -{ - _gui_sendmessage(GUI_CLEAR_LOG, 0, 0); -} - -BRIDGE_IMPEXP void GuiUpdateAllViews() -{ - GuiUpdateRegisterView(); - GuiUpdateDisassemblyView(); - GuiUpdateBreakpointsView(); - GuiUpdateDumpView(); - GuiUpdateThreadView(); - GuiUpdateSideBar(); - GuiRepaintTableView(); -} - -BRIDGE_IMPEXP void GuiUpdateRegisterView() -{ - _gui_sendmessage(GUI_UPDATE_REGISTER_VIEW, 0, 0); -} - -BRIDGE_IMPEXP void GuiUpdateDisassemblyView() -{ - _gui_sendmessage(GUI_UPDATE_DISASSEMBLY_VIEW, 0, 0); -} - - -BRIDGE_IMPEXP void GuiUpdateBreakpointsView() -{ - _gui_sendmessage(GUI_UPDATE_BREAKPOINTS_VIEW, 0, 0); -} - - -BRIDGE_IMPEXP void GuiUpdateWindowTitle(const char* filename) -{ - _gui_sendmessage(GUI_UPDATE_WINDOW_TITLE, (void*)filename, 0); -} - - -BRIDGE_IMPEXP HWND GuiGetWindowHandle() -{ - return (HWND)_gui_sendmessage(GUI_GET_WINDOW_HANDLE, 0, 0); -} - - -BRIDGE_IMPEXP void GuiDumpAt(duint va) -{ - _gui_sendmessage(GUI_DUMP_AT, (void*)va, 0); -} - - -BRIDGE_IMPEXP void GuiScriptAdd(int count, const char** lines) -{ - _gui_sendmessage(GUI_SCRIPT_ADD, (void*)(duint)count, (void*)lines); -} - - -BRIDGE_IMPEXP void GuiScriptClear() -{ - _gui_sendmessage(GUI_SCRIPT_CLEAR, 0, 0); -} - - -BRIDGE_IMPEXP void GuiScriptSetIp(int line) -{ - _gui_sendmessage(GUI_SCRIPT_SETIP, (void*)(duint)line, 0); -} - - -BRIDGE_IMPEXP void GuiScriptError(int line, const char* message) -{ - _gui_sendmessage(GUI_SCRIPT_ERROR, (void*)(duint)line, (void*)message); -} - - -BRIDGE_IMPEXP void GuiScriptSetTitle(const char* title) -{ - _gui_sendmessage(GUI_SCRIPT_SETTITLE, (void*)title, 0); -} - - -BRIDGE_IMPEXP void GuiScriptSetInfoLine(int line, const char* info) -{ - _gui_sendmessage(GUI_SCRIPT_SETINFOLINE, (void*)(duint)line, (void*)info); -} - - -BRIDGE_IMPEXP void GuiScriptMessage(const char* message) -{ - _gui_sendmessage(GUI_SCRIPT_MESSAGE, (void*)message, 0); -} - - -BRIDGE_IMPEXP int GuiScriptMsgyn(const char* message) -{ - return (int)(duint)_gui_sendmessage(GUI_SCRIPT_MSGYN, (void*)message, 0); -} - - -BRIDGE_IMPEXP void GuiScriptEnableHighlighting(bool enable) -{ - _gui_sendmessage(GUI_SCRIPT_ENABLEHIGHLIGHTING, (void*)(duint)enable, 0); -} - - -BRIDGE_IMPEXP void GuiSymbolLogAdd(const char* message) -{ - _gui_sendmessage(GUI_SYMBOL_LOG_ADD, (void*)message, 0); -} - - -BRIDGE_IMPEXP void GuiSymbolLogClear() -{ - _gui_sendmessage(GUI_SYMBOL_LOG_CLEAR, 0, 0); -} - - -BRIDGE_IMPEXP void GuiSymbolSetProgress(int percent) -{ - _gui_sendmessage(GUI_SYMBOL_SET_PROGRESS, (void*)(duint)percent, 0); -} - - -BRIDGE_IMPEXP void GuiSymbolUpdateModuleList(int count, SYMBOLMODULEINFO* modules) -{ - _gui_sendmessage(GUI_SYMBOL_UPDATE_MODULE_LIST, (void*)(duint)count, (void*)modules); -} - - -BRIDGE_IMPEXP void GuiReferenceAddColumn(int width, const char* title) -{ - _gui_sendmessage(GUI_REF_ADDCOLUMN, (void*)(duint)width, (void*)title); -} - - -BRIDGE_IMPEXP void GuiSymbolRefreshCurrent() -{ - _gui_sendmessage(GUI_SYMBOL_REFRESH_CURRENT, 0, 0); -} - - -BRIDGE_IMPEXP void GuiReferenceSetRowCount(int count) -{ - _gui_sendmessage(GUI_REF_SETROWCOUNT, (void*)(duint)count, 0); -} - - -BRIDGE_IMPEXP int GuiReferenceGetRowCount() -{ - return (int)(duint)_gui_sendmessage(GUI_REF_GETROWCOUNT, 0, 0); -} - - -BRIDGE_IMPEXP void GuiReferenceDeleteAllColumns() -{ - _gui_sendmessage(GUI_REF_DELETEALLCOLUMNS, 0, 0); -} - -BRIDGE_IMPEXP void GuiReferenceInitialize(const char* name) -{ - _gui_sendmessage(GUI_REF_INITIALIZE, (void*)name, 0); -} - -BRIDGE_IMPEXP void GuiReferenceSetCellContent(int row, int col, const char* str) -{ - CELLINFO info; - info.row = row; - info.col = col; - info.str = str; - _gui_sendmessage(GUI_REF_SETCELLCONTENT, &info, 0); -} - - -BRIDGE_IMPEXP const char* GuiReferenceGetCellContent(int row, int col) -{ - return (const char*)_gui_sendmessage(GUI_REF_GETCELLCONTENT, (void*)(duint)row, (void*)(duint)col); -} - - -BRIDGE_IMPEXP void GuiReferenceReloadData() -{ - _gui_sendmessage(GUI_REF_RELOADDATA, 0, 0); -} - - -BRIDGE_IMPEXP void GuiReferenceSetSingleSelection(int index, bool scroll) -{ - _gui_sendmessage(GUI_REF_SETSINGLESELECTION, (void*)(duint)index, (void*)(duint)scroll); -} - - -BRIDGE_IMPEXP void GuiReferenceSetProgress(int progress) -{ - _gui_sendmessage(GUI_REF_SETPROGRESS, (void*)(duint)progress, 0); -} - - -BRIDGE_IMPEXP void GuiReferenceSetSearchStartCol(int col) -{ - _gui_sendmessage(GUI_REF_SETSEARCHSTARTCOL, (void*)(duint)col, 0); -} - - -BRIDGE_IMPEXP void GuiStackDumpAt(duint addr, duint csp) -{ - _gui_sendmessage(GUI_STACK_DUMP_AT, (void*)addr, (void*)csp); -} - - -BRIDGE_IMPEXP void GuiUpdateDumpView() -{ - _gui_sendmessage(GUI_UPDATE_DUMP_VIEW, 0, 0); -} - - -BRIDGE_IMPEXP void GuiUpdateMemoryView() -{ - _gui_sendmessage(GUI_UPDATE_MEMORY_VIEW, 0, 0); -} - - -BRIDGE_IMPEXP void GuiUpdateThreadView() -{ - _gui_sendmessage(GUI_UPDATE_THREAD_VIEW, 0, 0); -} - - -BRIDGE_IMPEXP void GuiAddRecentFile(const char* file) -{ - _gui_sendmessage(GUI_ADD_RECENT_FILE, (void*)file, 0); -} - - -BRIDGE_IMPEXP void GuiSetLastException(unsigned int exception) -{ - _gui_sendmessage(GUI_SET_LAST_EXCEPTION, (void*)(duint)exception, 0); -} - - -BRIDGE_IMPEXP bool GuiGetDisassembly(duint addr, char* text) -{ - return !!_gui_sendmessage(GUI_GET_DISASSEMBLY, (void*)addr, text); -} - - -BRIDGE_IMPEXP int GuiMenuAdd(int hMenu, const char* title) -{ - return (int)(duint)_gui_sendmessage(GUI_MENU_ADD, (void*)(duint)hMenu, (void*)title); -} - - -BRIDGE_IMPEXP int GuiMenuAddEntry(int hMenu, const char* title) -{ - return (int)(duint)_gui_sendmessage(GUI_MENU_ADD_ENTRY, (void*)(duint)hMenu, (void*)title); -} - - -BRIDGE_IMPEXP void GuiMenuAddSeparator(int hMenu) -{ - _gui_sendmessage(GUI_MENU_ADD_SEPARATOR, (void*)(duint)hMenu, 0); -} - - -BRIDGE_IMPEXP void GuiMenuClear(int hMenu) -{ - _gui_sendmessage(GUI_MENU_CLEAR, (void*)(duint)hMenu, 0); -} - - -BRIDGE_IMPEXP bool GuiSelectionGet(int hWindow, SELECTIONDATA* selection) -{ - return !!_gui_sendmessage(GUI_SELECTION_GET, (void*)(duint)hWindow, selection); -} - - -BRIDGE_IMPEXP bool GuiSelectionSet(int hWindow, const SELECTIONDATA* selection) -{ - return !!_gui_sendmessage(GUI_SELECTION_SET, (void*)(duint)hWindow, (void*)selection); -} - - -BRIDGE_IMPEXP bool GuiGetLineWindow(const char* title, char* text) -{ - return !!_gui_sendmessage(GUI_GETLINE_WINDOW, (void*)title, text); -} - - -BRIDGE_IMPEXP void GuiAutoCompleteAddCmd(const char* cmd) -{ - _gui_sendmessage(GUI_AUTOCOMPLETE_ADDCMD, (void*)cmd, 0); -} - - -BRIDGE_IMPEXP void GuiAutoCompleteDelCmd(const char* cmd) -{ - _gui_sendmessage(GUI_AUTOCOMPLETE_DELCMD, (void*)cmd, 0); -} - - -BRIDGE_IMPEXP void GuiAutoCompleteClearAll() -{ - _gui_sendmessage(GUI_AUTOCOMPLETE_CLEARALL, 0, 0); -} - - -BRIDGE_IMPEXP void GuiAddStatusBarMessage(const char* msg) -{ - _gui_sendmessage(GUI_ADD_MSG_TO_STATUSBAR, (void*)msg, 0); -} - - -BRIDGE_IMPEXP void GuiUpdateSideBar() -{ - _gui_sendmessage(GUI_UPDATE_SIDEBAR, 0, 0); -} - - -BRIDGE_IMPEXP void GuiRepaintTableView() -{ - _gui_sendmessage(GUI_REPAINT_TABLE_VIEW, 0, 0); -} - - -BRIDGE_IMPEXP void GuiUpdatePatches() -{ - _gui_sendmessage(GUI_UPDATE_PATCHES, 0, 0); -} - - -BRIDGE_IMPEXP void GuiUpdateCallStack() -{ - _gui_sendmessage(GUI_UPDATE_CALLSTACK, 0, 0); -} - -BRIDGE_IMPEXP void GuiLoadSourceFile(const char* path, int line) -{ - _gui_sendmessage(GUI_LOAD_SOURCE_FILE, (void*)path, (void*)line); -} - -BRIDGE_IMPEXP void GuiMenuSetIcon(int hMenu, const ICONDATA* icon) -{ - _gui_sendmessage(GUI_MENU_SET_ICON, (void*)hMenu, (void*)icon); -} - -BRIDGE_IMPEXP void GuiMenuSetEntryIcon(int hEntry, const ICONDATA* icon) -{ - _gui_sendmessage(GUI_MENU_SET_ENTRY_ICON, (void*)hEntry, (void*)icon); -} - -BRIDGE_IMPEXP void GuiShowCpu() -{ - _gui_sendmessage(GUI_SHOW_CPU, 0, 0); -} - -BRIDGE_IMPEXP void GuiAddQWidgetTab(void* qWidget) -{ - _gui_sendmessage(GUI_ADD_QWIDGET_TAB, qWidget, nullptr); -} - -BRIDGE_IMPEXP void GuiShowQWidgetTab(void* qWidget) -{ - _gui_sendmessage(GUI_SHOW_QWIDGET_TAB, qWidget, nullptr); -} - -BRIDGE_IMPEXP void GuiCloseQWidgetTab(void* qWidget) -{ - _gui_sendmessage(GUI_CLOSE_QWIDGET_TAB, qWidget, nullptr); -} - -BRIDGE_IMPEXP void GuiExecuteOnGuiThread(GUICALLBACK cbGuiThread) -{ - _gui_sendmessage(GUI_EXECUTE_ON_GUI_THREAD, cbGuiThread, nullptr); -} - -BRIDGE_IMPEXP void GuiUpdateTimeWastedCounter() -{ - _gui_sendmessage(GUI_UPDATE_TIME_WASTED_COUNTER, nullptr, nullptr); -} - -BRIDGE_IMPEXP void GuiSetGlobalNotes(const char* text) -{ - _gui_sendmessage(GUI_SET_GLOBAL_NOTES, (void*)text, nullptr); -} - -BRIDGE_IMPEXP void GuiGetGlobalNotes(char** text) -{ - _gui_sendmessage(GUI_GET_GLOBAL_NOTES, text, nullptr); -} - -BRIDGE_IMPEXP void GuiSetDebuggeeNotes(const char* text) -{ - _gui_sendmessage(GUI_SET_DEBUGGEE_NOTES, (void*)text, nullptr); -} - -BRIDGE_IMPEXP void GuiGetDebuggeeNotes(char** text) -{ - _gui_sendmessage(GUI_GET_DEBUGGEE_NOTES, text, nullptr); -} - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - hInst = hinstDLL; - return TRUE; +/** + * \file bridgemain.cpp + * + * \brief Defines functions to initialize and start the Bridge and + * to interface with the GUI and the DBG. + */ +#include "_global.h" +#include "bridgemain.h" +#include +#include "Utf8Ini.h" + +static HINSTANCE hInst; +static Utf8Ini settings; +static wchar_t szIniFile[MAX_PATH] = L""; +static CRITICAL_SECTION csIni; + +#ifdef _WIN64 +#define dbg_lib "x64dbg.dll" +#define gui_lib "x64gui.dll" +#else +#define dbg_lib "x32dbg.dll" +#define gui_lib "x32gui.dll" +#endif // _WIN64 + +#define LOADLIBRARY(name) \ + szLib=name; \ + hInst=LoadLibraryA(name); \ + if(!hInst) \ + return "Error loading library \""name"\"!" + +#define LOADEXPORT(name) \ + *((FARPROC*)&name)=GetProcAddress(hInst, #name); \ + if(!name) \ + { \ + sprintf(szError, "Export %s:%s could not be found!", szLib, #name); \ + return szError; \ + } + +BRIDGE_IMPEXP const char* BridgeInit() +{ + //Initialize critial section + InitializeCriticalSection(&csIni); + + //Settings load + if(!GetModuleFileNameW(0, szIniFile, MAX_PATH)) + return "Error getting module path!"; + int len = (int)wcslen(szIniFile); + while(szIniFile[len] != L'.' && szIniFile[len] != L'\\' && len) + len--; + if(szIniFile[len] == L'\\') + wcscat_s(szIniFile, L".ini"); + else + wcscpy_s(&szIniFile[len], _countof(szIniFile) - len, L".ini"); + + HINSTANCE hInst; + const char* szLib; + static char szError[256] = ""; + + //GUI Load + LOADLIBRARY(gui_lib); + LOADEXPORT(_gui_guiinit); + LOADEXPORT(_gui_sendmessage); + + //DBG Load + LOADLIBRARY(dbg_lib); + LOADEXPORT(_dbg_dbginit); + LOADEXPORT(_dbg_memfindbaseaddr); + LOADEXPORT(_dbg_memread); + LOADEXPORT(_dbg_memwrite); + LOADEXPORT(_dbg_dbgcmdexec); + LOADEXPORT(_dbg_memmap); + LOADEXPORT(_dbg_dbgexitsignal); + LOADEXPORT(_dbg_valfromstring); + LOADEXPORT(_dbg_isdebugging); + LOADEXPORT(_dbg_isjumpgoingtoexecute); + LOADEXPORT(_dbg_addrinfoget); + LOADEXPORT(_dbg_addrinfoset); + LOADEXPORT(_dbg_bpgettypeat); + LOADEXPORT(_dbg_getregdump); + LOADEXPORT(_dbg_valtostring); + LOADEXPORT(_dbg_memisvalidreadptr); + LOADEXPORT(_dbg_getbplist); + LOADEXPORT(_dbg_dbgcmddirectexec); + LOADEXPORT(_dbg_getbranchdestination); + LOADEXPORT(_dbg_sendmessage); + return 0; +} + +BRIDGE_IMPEXP const char* BridgeStart() +{ + if(!_dbg_dbginit || !_gui_guiinit) + return "\"_dbg_dbginit\" || \"_gui_guiinit\" was not loaded yet, call BridgeInit!"; + int errorLine = 0; + BridgeSettingRead(&errorLine); + _dbg_sendmessage(DBG_INITIALIZE_LOCKS, nullptr, nullptr); //initialize locks before any other thread than the main thread are started + _gui_guiinit(0, 0); //remove arguments + if(!BridgeSettingFlush()) + return "Failed to save settings!"; + _dbg_sendmessage(DBG_DEINITIALIZE_LOCKS, nullptr, nullptr); //deinitialize locks when only one thread is left (hopefully) + DeleteCriticalSection(&csIni); + return 0; +} + +BRIDGE_IMPEXP void* BridgeAlloc(size_t size) +{ + unsigned char* ptr = (unsigned char*)GlobalAlloc(GMEM_FIXED, size); + if(!ptr) + { + MessageBoxA(0, "Could not allocate memory", "Error", MB_ICONERROR); + ExitProcess(1); + } + memset(ptr, 0, size); + return ptr; +} + +BRIDGE_IMPEXP void BridgeFree(void* ptr) +{ + if(ptr) + GlobalFree(ptr); +} + +BRIDGE_IMPEXP bool BridgeSettingGet(const char* section, const char* key, char* value) +{ + if(!section || !key || !value) + return false; + EnterCriticalSection(&csIni); + auto foundValue = settings.GetValue(section, key); + bool result = foundValue.length() > 0; + if(result) + strcpy_s(value, MAX_SETTING_SIZE, foundValue.c_str()); + LeaveCriticalSection(&csIni); + return result; +} + +BRIDGE_IMPEXP bool BridgeSettingGetUint(const char* section, const char* key, duint* value) +{ + if(!section || !key || !value) + return false; + char newvalue[MAX_SETTING_SIZE] = ""; + if(!BridgeSettingGet(section, key, newvalue)) + return false; +#ifdef _WIN64 + int ret = sscanf(newvalue, "%llX", value); +#else + int ret = sscanf(newvalue, "%X", value); +#endif //_WIN64 + if(ret) + return true; + return false; +} + +BRIDGE_IMPEXP bool BridgeSettingSet(const char* section, const char* key, const char* value) +{ + bool success = false; + if(section) + { + EnterCriticalSection(&csIni); + if(!key) + success = settings.ClearSection(section); + else if(!value) + success = settings.SetValue(section, key, ""); + else + success = settings.SetValue(section, key, value); + LeaveCriticalSection(&csIni); + } + return success; +} + +BRIDGE_IMPEXP bool BridgeSettingSetUint(const char* section, const char* key, duint value) +{ + if(!section || !key) + return false; + char newvalue[MAX_SETTING_SIZE] = ""; +#ifdef _WIN64 + sprintf(newvalue, "%llX", value); +#else + sprintf(newvalue, "%X", value); +#endif //_WIN64 + return BridgeSettingSet(section, key, newvalue); +} + +BRIDGE_IMPEXP bool BridgeSettingFlush() +{ + EnterCriticalSection(&csIni); + std::string iniData = settings.Serialize(); + LeaveCriticalSection(&csIni); + bool success = false; + HANDLE hFile = CreateFileW(szIniFile, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if(hFile != INVALID_HANDLE_VALUE) + { + SetEndOfFile(hFile); + DWORD written = 0; + if(WriteFile(hFile, iniData.c_str(), (DWORD)iniData.length(), &written, nullptr)) + success = true; + CloseHandle(hFile); + } + return success; +} + +BRIDGE_IMPEXP bool BridgeSettingRead(int* errorLine) +{ + if(errorLine) + *errorLine = 0; + bool success = false; + std::string iniData; + HANDLE hFile = CreateFileW(szIniFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); + if(hFile != INVALID_HANDLE_VALUE) + { + DWORD fileSize = GetFileSize(hFile, nullptr); + if(fileSize) + { + unsigned char utf8bom[] = { 0xEF, 0xBB, 0xBF }; + char* fileData = (char*)BridgeAlloc(sizeof(utf8bom) + fileSize + 1); + DWORD read = 0; + if(ReadFile(hFile, fileData, fileSize, &read, nullptr)) + { + success = true; + if(!memcmp(fileData, utf8bom, sizeof(utf8bom))) + iniData.assign(fileData + sizeof(utf8bom)); + else + iniData.assign(fileData); + } + BridgeFree(fileData); + } + CloseHandle(hFile); + } + if(success) //if we failed to read the file, the current settings are better than none at all + { + EnterCriticalSection(&csIni); + int errline = 0; + success = settings.Deserialize(iniData, errline); + if(errorLine) + *errorLine = errline; + LeaveCriticalSection(&csIni); + } + return success; +} + +BRIDGE_IMPEXP int BridgeGetDbgVersion() +{ + return DBG_VERSION; +} + +BRIDGE_IMPEXP bool DbgMemRead(duint va, unsigned char* dest, duint size) +{ + if(IsBadWritePtr(dest, size)) + { + GuiAddLogMessage("DbgMemRead with invalid boundaries!\n"); + return false; + } + + if (!_dbg_memread(va, dest, size, 0)) + { + // Zero the buffer on failure + memset(dest, 0, size); + return false; + } + + return true; +} + +BRIDGE_IMPEXP bool DbgMemWrite(duint va, const unsigned char* src, duint size) +{ + if(IsBadReadPtr(src, size)) + { + GuiAddLogMessage("DbgMemWrite with invalid boundaries!\n"); + return false; + } + return _dbg_memwrite(va, src, size, 0); +} + +// FIXME, not exactly base if it still does a find? +BRIDGE_IMPEXP duint DbgMemGetPageSize(duint base) +{ + duint size = 0; + _dbg_memfindbaseaddr(base, &size); + return size; +} + +BRIDGE_IMPEXP duint DbgMemFindBaseAddr(duint addr, duint* size) +{ + return _dbg_memfindbaseaddr(addr, size); +} + +BRIDGE_IMPEXP bool DbgCmdExec(const char* cmd) +{ + return _dbg_dbgcmdexec(cmd); +} + +// FIXME +BRIDGE_IMPEXP bool DbgMemMap(MEMMAP* memmap) +{ + return _dbg_memmap(memmap); +} + +BRIDGE_IMPEXP bool DbgIsValidExpression(const char* expression) +{ + duint value = 0; + return _dbg_valfromstring(expression, &value); +} + +BRIDGE_IMPEXP bool DbgIsDebugging() +{ + return _dbg_isdebugging(); +} + +BRIDGE_IMPEXP bool DbgIsJumpGoingToExecute(duint addr) +{ + return _dbg_isjumpgoingtoexecute(addr); +} + +// FIXME required size of arg _text_? +BRIDGE_IMPEXP bool DbgGetLabelAt(duint addr, SEGMENTREG segment, char* text) //(module.)+label +{ + if(!text || !addr) + return false; + ADDRINFO info; + memset(&info, 0, sizeof(info)); + info.flags = flaglabel; + if(!_dbg_addrinfoget(addr, segment, &info)) + { + duint addr_ = 0; + if(!DbgMemIsValidReadPtr(addr)) + return false; + DbgMemRead(addr, (unsigned char*)&addr_, sizeof(duint)); + ADDRINFO ptrinfo = info; + if(!_dbg_addrinfoget(addr_, SEG_DEFAULT, &ptrinfo)) + return false; + sprintf_s(info.label, "&%s", ptrinfo.label); + } + strcpy_s(text, MAX_LABEL_SIZE, info.label); + return true; +} + +BRIDGE_IMPEXP bool DbgSetLabelAt(duint addr, const char* text) +{ + if(!text || strlen(text) >= MAX_LABEL_SIZE || !addr) + return false; + ADDRINFO info; + memset(&info, 0, sizeof(info)); + info.flags = flaglabel; + strcpy_s(info.label, text); + if(!_dbg_addrinfoset(addr, &info)) + return false; + return true; +} + +// FIXME required size of arg _text_? +BRIDGE_IMPEXP bool DbgGetCommentAt(duint addr, char* text) //comment (not live) +{ + if(!text || !addr) + return false; + ADDRINFO info; + memset(&info, 0, sizeof(info)); + info.flags = flagcomment; + if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) + return false; + strcpy_s(text, MAX_COMMENT_SIZE, info.comment); + return true; +} + +BRIDGE_IMPEXP bool DbgSetCommentAt(duint addr, const char* text) +{ + if(!text || strlen(text) >= MAX_COMMENT_SIZE || !addr) + return false; + ADDRINFO info; + memset(&info, 0, sizeof(info)); + info.flags = flagcomment; + strcpy_s(info.comment, MAX_COMMENT_SIZE, text); + if(!_dbg_addrinfoset(addr, &info)) + return false; + return true; +} + +// FIXME required size of arg _text_? +BRIDGE_IMPEXP bool DbgGetModuleAt(duint addr, char* text) +{ + if(!text || !addr) + return false; + ADDRINFO info; + memset(&info, 0, sizeof(info)); + info.flags = flagmodule; + if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) + return false; + strcpy_s(text, MAX_MODULE_SIZE, info.module); + return true; +} + +BRIDGE_IMPEXP bool DbgGetBookmarkAt(duint addr) +{ + if(!addr) + return false; + ADDRINFO info; + memset(&info, 0, sizeof(info)); + info.flags = flagbookmark; + if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) + return false; + return info.isbookmark; +} + +BRIDGE_IMPEXP bool DbgSetBookmarkAt(duint addr, bool isbookmark) +{ + if(!addr) + return false; + ADDRINFO info; + memset(&info, 0, sizeof(info)); + info.flags = flagbookmark; + info.isbookmark = isbookmark; + return _dbg_addrinfoset(addr, &info); +} + +// FIXME return on success? +BRIDGE_IMPEXP const char* DbgInit() +{ + return _dbg_dbginit(); +} + +BRIDGE_IMPEXP void DbgExit() +{ + _dbg_dbgexitsignal(); //send exit signal to debugger +} + +BRIDGE_IMPEXP BPXTYPE DbgGetBpxTypeAt(duint addr) +{ + return _dbg_bpgettypeat(addr); +} + +BRIDGE_IMPEXP duint DbgValFromString(const char* string) +{ + duint value = 0; + _dbg_valfromstring(string, &value); + return value; +} + +BRIDGE_IMPEXP bool DbgGetRegDump(REGDUMP* regdump) +{ + return _dbg_getregdump(regdump); +} + +// FIXME all +BRIDGE_IMPEXP bool DbgValToString(const char* string, duint value) +{ + return _dbg_valtostring(string, value); +} + +BRIDGE_IMPEXP bool DbgMemIsValidReadPtr(duint addr) +{ + return _dbg_memisvalidreadptr(addr); +} + +// FIXME return +BRIDGE_IMPEXP int DbgGetBpList(BPXTYPE type, BPMAP* list) +{ + return _dbg_getbplist(type, list); +} + +// FIXME all +BRIDGE_IMPEXP bool DbgCmdExecDirect(const char* cmd) +{ + return _dbg_dbgcmddirectexec(cmd); +} + +BRIDGE_IMPEXP FUNCTYPE DbgGetFunctionTypeAt(duint addr) +{ + ADDRINFO info; + memset(&info, 0, sizeof(info)); + info.flags = flagfunction; + if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) + return FUNC_NONE; + duint start = info.function.start; + duint end = info.function.end; + if(start == end) + return FUNC_SINGLE; + else if(addr == start) + return FUNC_BEGIN; + else if(addr == end) + return FUNC_END; + return FUNC_MIDDLE; +} + +// FIXME depth +BRIDGE_IMPEXP LOOPTYPE DbgGetLoopTypeAt(duint addr, int depth) +{ + ADDRINFO info; + memset(&info, 0, sizeof(info)); + info.flags = flagloop; + info.loop.depth = depth; + if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) + return LOOP_NONE; + duint start = info.loop.start; + duint end = info.loop.end; + if(addr == start) + return LOOP_BEGIN; + else if(addr == end) + return LOOP_END; + return LOOP_MIDDLE; +} + +BRIDGE_IMPEXP duint DbgGetBranchDestination(duint addr) +{ + return _dbg_getbranchdestination(addr); +} + +BRIDGE_IMPEXP void DbgScriptLoad(const char* filename) +{ + _dbg_sendmessage(DBG_SCRIPT_LOAD, (void*)filename, 0); +} + +// FIXME every? +BRIDGE_IMPEXP void DbgScriptUnload() +{ + _dbg_sendmessage(DBG_SCRIPT_UNLOAD, 0, 0); +} + +// FIXME "the script?"; destline +BRIDGE_IMPEXP void DbgScriptRun(int destline) +{ + _dbg_sendmessage(DBG_SCRIPT_RUN, (void*)(duint)destline, 0); +} + +BRIDGE_IMPEXP void DbgScriptStep() +{ + _dbg_sendmessage(DBG_SCRIPT_STEP, 0, 0); +} + +BRIDGE_IMPEXP bool DbgScriptBpToggle(int line) +{ + if(_dbg_sendmessage(DBG_SCRIPT_BPTOGGLE, (void*)(duint)line, 0)) + return true; + return false; +} + +BRIDGE_IMPEXP bool DbgScriptBpGet(int line) +{ + if(_dbg_sendmessage(DBG_SCRIPT_BPGET, (void*)(duint)line, 0)) + return true; + return false; +} + +BRIDGE_IMPEXP bool DbgScriptCmdExec(const char* command) +{ + if(_dbg_sendmessage(DBG_SCRIPT_CMDEXEC, (void*)command, 0)) + return true; + return false; +} + +BRIDGE_IMPEXP void DbgScriptAbort() +{ + _dbg_sendmessage(DBG_SCRIPT_ABORT, 0, 0); +} + +BRIDGE_IMPEXP SCRIPTLINETYPE DbgScriptGetLineType(int line) +{ + return (SCRIPTLINETYPE)_dbg_sendmessage(DBG_SCRIPT_GETLINETYPE, (void*)(duint)line, 0); +} + +BRIDGE_IMPEXP void DbgScriptSetIp(int line) +{ + _dbg_sendmessage(DBG_SCRIPT_SETIP, (void*)(duint)line, 0); +} + +// FIXME non-null? +BRIDGE_IMPEXP bool DbgScriptGetBranchInfo(int line, SCRIPTBRANCH* info) +{ + return !!_dbg_sendmessage(DBG_SCRIPT_GETBRANCHINFO, (void*)(duint)line, info); +} + +// FIXME all +BRIDGE_IMPEXP void DbgSymbolEnum(duint base, CBSYMBOLENUM cbSymbolEnum, void* user) +{ + SYMBOLCBINFO cbInfo; + cbInfo.base = base; + cbInfo.cbSymbolEnum = cbSymbolEnum; + cbInfo.user = user; + _dbg_sendmessage(DBG_SYMBOL_ENUM, &cbInfo, 0); +} + +BRIDGE_IMPEXP bool DbgAssembleAt(duint addr, const char* instruction) +{ + if(_dbg_sendmessage(DBG_ASSEMBLE_AT, (void*)addr, (void*)instruction)) + return true; + return false; +} + +BRIDGE_IMPEXP duint DbgModBaseFromName(const char* name) +{ + return _dbg_sendmessage(DBG_MODBASE_FROM_NAME, (void*)name, 0); +} + +BRIDGE_IMPEXP void DbgDisasmAt(duint addr, DISASM_INSTR* instr) +{ + _dbg_sendmessage(DBG_DISASM_AT, (void*)addr, instr); +} + +BRIDGE_IMPEXP bool DbgStackCommentGet(duint addr, STACK_COMMENT* comment) +{ + return !!_dbg_sendmessage(DBG_STACK_COMMENT_GET, (void*)addr, comment); +} + +BRIDGE_IMPEXP void DbgGetThreadList(THREADLIST* list) +{ + _dbg_sendmessage(DBG_GET_THREAD_LIST, list, 0); +} + +BRIDGE_IMPEXP void DbgSettingsUpdated() +{ + _dbg_sendmessage(DBG_SETTINGS_UPDATED, 0, 0); +} + +BRIDGE_IMPEXP void DbgDisasmFastAt(duint addr, BASIC_INSTRUCTION_INFO* basicinfo) +{ + _dbg_sendmessage(DBG_DISASM_FAST_AT, (void*)addr, basicinfo); +} + +BRIDGE_IMPEXP void DbgMenuEntryClicked(int hEntry) +{ + _dbg_sendmessage(DBG_MENU_ENTRY_CLICKED, (void*)(duint)hEntry, 0); +} + +// FIXME not sure +BRIDGE_IMPEXP bool DbgFunctionGet(duint addr, duint* start, duint* end) +{ + FUNCTION_LOOP_INFO info; + info.addr = addr; + if(!_dbg_sendmessage(DBG_FUNCTION_GET, &info, 0)) + return false; + if(start) + *start = info.start; + if(end) + *end = info.end; + return true; +} + +// FIXME brief, return +BRIDGE_IMPEXP bool DbgFunctionOverlaps(duint start, duint end) +{ + FUNCTION_LOOP_INFO info; + info.start = start; + info.end = end; + if(!_dbg_sendmessage(DBG_FUNCTION_OVERLAPS, &info, 0)) + return false; + return true; +} + +// FIXME brief, return +BRIDGE_IMPEXP bool DbgFunctionAdd(duint start, duint end) +{ + FUNCTION_LOOP_INFO info; + info.start = start; + info.end = end; + info.manual = false; + if(!_dbg_sendmessage(DBG_FUNCTION_ADD, &info, 0)) + return false; + return true; +} + +// FIXME brief, return +BRIDGE_IMPEXP bool DbgFunctionDel(duint addr) +{ + FUNCTION_LOOP_INFO info; + info.addr = addr; + if(!_dbg_sendmessage(DBG_FUNCTION_DEL, &info, 0)) + return false; + return true; +} + +// FIXME depth +BRIDGE_IMPEXP bool DbgLoopGet(int depth, duint addr, duint* start, duint* end) +{ + FUNCTION_LOOP_INFO info; + info.addr = addr; + info.depth = depth; + if(!_dbg_sendmessage(DBG_LOOP_GET, &info, 0)) + return false; + *start = info.start; + *end = info.end; + return true; +} + +// FIXME brief, depth, return +BRIDGE_IMPEXP bool DbgLoopOverlaps(int depth, duint start, duint end) +{ + FUNCTION_LOOP_INFO info; + info.start = start; + info.end = end; + info.depth = depth; + if(!_dbg_sendmessage(DBG_LOOP_OVERLAPS, &info, 0)) + return false; + return true; +} + +// FIXME brief, return +BRIDGE_IMPEXP bool DbgLoopAdd(duint start, duint end) +{ + FUNCTION_LOOP_INFO info; + info.start = start; + info.end = end; + info.manual = false; + if(!_dbg_sendmessage(DBG_LOOP_ADD, &info, 0)) + return false; + return true; +} + +// FIXME brief, brief +BRIDGE_IMPEXP bool DbgLoopDel(int depth, duint addr) +{ + FUNCTION_LOOP_INFO info; + info.addr = addr; + info.depth = depth; + if(!_dbg_sendmessage(DBG_LOOP_DEL, &info, 0)) + return false; + return true; +} + +// FIXME all +BRIDGE_IMPEXP bool DbgIsRunLocked() +{ + if(_dbg_sendmessage(DBG_IS_RUN_LOCKED, 0, 0)) + return true; + return false; +} + +BRIDGE_IMPEXP bool DbgIsBpDisabled(duint addr) +{ + if(_dbg_sendmessage(DBG_IS_BP_DISABLED, (void*)addr, 0)) + return true; + return false; +} + +BRIDGE_IMPEXP bool DbgSetAutoCommentAt(duint addr, const char* text) +{ + if(_dbg_sendmessage(DBG_SET_AUTO_COMMENT_AT, (void*)addr, (void*)text)) + return true; + return false; +} + +// FIXME brief +BRIDGE_IMPEXP void DbgClearAutoCommentRange(duint start, duint end) +{ + _dbg_sendmessage(DBG_DELETE_AUTO_COMMENT_RANGE, (void*)start, (void*)end); +} + +BRIDGE_IMPEXP bool DbgSetAutoLabelAt(duint addr, const char* text) +{ + if(_dbg_sendmessage(DBG_SET_AUTO_LABEL_AT, (void*)addr, (void*)text)) + return true; + return false; +} + +// FIXME brief +BRIDGE_IMPEXP void DbgClearAutoLabelRange(duint start, duint end) +{ + _dbg_sendmessage(DBG_DELETE_AUTO_LABEL_RANGE, (void*)start, (void*)end); +} + +BRIDGE_IMPEXP bool DbgSetAutoBookmarkAt(duint addr) +{ + if(_dbg_sendmessage(DBG_SET_AUTO_BOOKMARK_AT, (void*)addr, 0)) + return true; + return false; +} + +// FIXME brief +BRIDGE_IMPEXP void DbgClearAutoBookmarkRange(duint start, duint end) +{ + _dbg_sendmessage(DBG_DELETE_AUTO_BOOKMARK_RANGE, (void*)start, (void*)end); +} + +BRIDGE_IMPEXP bool DbgSetAutoFunctionAt(duint start, duint end) +{ + if(_dbg_sendmessage(DBG_SET_AUTO_FUNCTION_AT, (void*)start, (void*)end)) + return true; + return false; +} + +// FIXME brief +BRIDGE_IMPEXP void DbgClearAutoFunctionRange(duint start, duint end) +{ + _dbg_sendmessage(DBG_DELETE_AUTO_FUNCTION_RANGE, (void*)start, (void*)end); +} + +// FIXME size of the buffer? +BRIDGE_IMPEXP bool DbgGetStringAt(duint addr, char* text) +{ + if(_dbg_sendmessage(DBG_GET_STRING_AT, (void*)addr, text)) + return true; + return false; +} + +BRIDGE_IMPEXP const DBGFUNCTIONS* DbgFunctions() +{ + return (const DBGFUNCTIONS*)_dbg_sendmessage(DBG_GET_FUNCTIONS, 0, 0); +} + +BRIDGE_IMPEXP bool DbgWinEvent(MSG* message, long* result) +{ + if(_dbg_sendmessage(DBG_WIN_EVENT, message, result)) + return true; + return false; +} + +BRIDGE_IMPEXP bool DbgWinEventGlobal(MSG* message) +{ + if(_dbg_sendmessage(DBG_WIN_EVENT_GLOBAL, message, 0)) + return true; + return false; +} + +BRIDGE_IMPEXP bool DbgIsRunning() +{ + return !DbgIsRunLocked(); +} + +BRIDGE_IMPEXP duint DbgGetTimeWastedCounter() +{ + return _dbg_sendmessage(DBG_GET_TIME_WASTED_COUNTER, nullptr, nullptr); +} + +BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip) +{ + _gui_sendmessage(GUI_DISASSEMBLE_AT, (void*)addr, (void*)cip); +} + +BRIDGE_IMPEXP void GuiSetDebugState(DBGSTATE state) +{ + _gui_sendmessage(GUI_SET_DEBUG_STATE, (void*)state, 0); +} + + +BRIDGE_IMPEXP void GuiAddLogMessage(const char* msg) +{ + _gui_sendmessage(GUI_ADD_MSG_TO_LOG, (void*)msg, 0); +} + +BRIDGE_IMPEXP void GuiLogClear() +{ + _gui_sendmessage(GUI_CLEAR_LOG, 0, 0); +} + +BRIDGE_IMPEXP void GuiUpdateAllViews() +{ + GuiUpdateRegisterView(); + GuiUpdateDisassemblyView(); + GuiUpdateBreakpointsView(); + GuiUpdateDumpView(); + GuiUpdateThreadView(); + GuiUpdateSideBar(); + GuiRepaintTableView(); +} + +BRIDGE_IMPEXP void GuiUpdateRegisterView() +{ + _gui_sendmessage(GUI_UPDATE_REGISTER_VIEW, 0, 0); +} + +BRIDGE_IMPEXP void GuiUpdateDisassemblyView() +{ + _gui_sendmessage(GUI_UPDATE_DISASSEMBLY_VIEW, 0, 0); +} + + +BRIDGE_IMPEXP void GuiUpdateBreakpointsView() +{ + _gui_sendmessage(GUI_UPDATE_BREAKPOINTS_VIEW, 0, 0); +} + + +BRIDGE_IMPEXP void GuiUpdateWindowTitle(const char* filename) +{ + _gui_sendmessage(GUI_UPDATE_WINDOW_TITLE, (void*)filename, 0); +} + + +BRIDGE_IMPEXP HWND GuiGetWindowHandle() +{ + return (HWND)_gui_sendmessage(GUI_GET_WINDOW_HANDLE, 0, 0); +} + + +BRIDGE_IMPEXP void GuiDumpAt(duint va) +{ + _gui_sendmessage(GUI_DUMP_AT, (void*)va, 0); +} + + +BRIDGE_IMPEXP void GuiScriptAdd(int count, const char** lines) +{ + _gui_sendmessage(GUI_SCRIPT_ADD, (void*)(duint)count, (void*)lines); +} + + +BRIDGE_IMPEXP void GuiScriptClear() +{ + _gui_sendmessage(GUI_SCRIPT_CLEAR, 0, 0); +} + + +BRIDGE_IMPEXP void GuiScriptSetIp(int line) +{ + _gui_sendmessage(GUI_SCRIPT_SETIP, (void*)(duint)line, 0); +} + + +BRIDGE_IMPEXP void GuiScriptError(int line, const char* message) +{ + _gui_sendmessage(GUI_SCRIPT_ERROR, (void*)(duint)line, (void*)message); +} + + +BRIDGE_IMPEXP void GuiScriptSetTitle(const char* title) +{ + _gui_sendmessage(GUI_SCRIPT_SETTITLE, (void*)title, 0); +} + + +BRIDGE_IMPEXP void GuiScriptSetInfoLine(int line, const char* info) +{ + _gui_sendmessage(GUI_SCRIPT_SETINFOLINE, (void*)(duint)line, (void*)info); +} + + +BRIDGE_IMPEXP void GuiScriptMessage(const char* message) +{ + _gui_sendmessage(GUI_SCRIPT_MESSAGE, (void*)message, 0); +} + + +BRIDGE_IMPEXP int GuiScriptMsgyn(const char* message) +{ + return (int)(duint)_gui_sendmessage(GUI_SCRIPT_MSGYN, (void*)message, 0); +} + + +BRIDGE_IMPEXP void GuiScriptEnableHighlighting(bool enable) +{ + _gui_sendmessage(GUI_SCRIPT_ENABLEHIGHLIGHTING, (void*)(duint)enable, 0); +} + + +BRIDGE_IMPEXP void GuiSymbolLogAdd(const char* message) +{ + _gui_sendmessage(GUI_SYMBOL_LOG_ADD, (void*)message, 0); +} + + +BRIDGE_IMPEXP void GuiSymbolLogClear() +{ + _gui_sendmessage(GUI_SYMBOL_LOG_CLEAR, 0, 0); +} + + +BRIDGE_IMPEXP void GuiSymbolSetProgress(int percent) +{ + _gui_sendmessage(GUI_SYMBOL_SET_PROGRESS, (void*)(duint)percent, 0); +} + + +BRIDGE_IMPEXP void GuiSymbolUpdateModuleList(int count, SYMBOLMODULEINFO* modules) +{ + _gui_sendmessage(GUI_SYMBOL_UPDATE_MODULE_LIST, (void*)(duint)count, (void*)modules); +} + + +BRIDGE_IMPEXP void GuiReferenceAddColumn(int width, const char* title) +{ + _gui_sendmessage(GUI_REF_ADDCOLUMN, (void*)(duint)width, (void*)title); +} + + +BRIDGE_IMPEXP void GuiSymbolRefreshCurrent() +{ + _gui_sendmessage(GUI_SYMBOL_REFRESH_CURRENT, 0, 0); +} + + +BRIDGE_IMPEXP void GuiReferenceSetRowCount(int count) +{ + _gui_sendmessage(GUI_REF_SETROWCOUNT, (void*)(duint)count, 0); +} + + +BRIDGE_IMPEXP int GuiReferenceGetRowCount() +{ + return (int)(duint)_gui_sendmessage(GUI_REF_GETROWCOUNT, 0, 0); +} + + +BRIDGE_IMPEXP void GuiReferenceDeleteAllColumns() +{ + _gui_sendmessage(GUI_REF_DELETEALLCOLUMNS, 0, 0); +} + +BRIDGE_IMPEXP void GuiReferenceInitialize(const char* name) +{ + _gui_sendmessage(GUI_REF_INITIALIZE, (void*)name, 0); +} + +BRIDGE_IMPEXP void GuiReferenceSetCellContent(int row, int col, const char* str) +{ + CELLINFO info; + info.row = row; + info.col = col; + info.str = str; + _gui_sendmessage(GUI_REF_SETCELLCONTENT, &info, 0); +} + + +BRIDGE_IMPEXP const char* GuiReferenceGetCellContent(int row, int col) +{ + return (const char*)_gui_sendmessage(GUI_REF_GETCELLCONTENT, (void*)(duint)row, (void*)(duint)col); +} + + +BRIDGE_IMPEXP void GuiReferenceReloadData() +{ + _gui_sendmessage(GUI_REF_RELOADDATA, 0, 0); +} + + +BRIDGE_IMPEXP void GuiReferenceSetSingleSelection(int index, bool scroll) +{ + _gui_sendmessage(GUI_REF_SETSINGLESELECTION, (void*)(duint)index, (void*)(duint)scroll); +} + + +BRIDGE_IMPEXP void GuiReferenceSetProgress(int progress) +{ + _gui_sendmessage(GUI_REF_SETPROGRESS, (void*)(duint)progress, 0); +} + + +BRIDGE_IMPEXP void GuiReferenceSetSearchStartCol(int col) +{ + _gui_sendmessage(GUI_REF_SETSEARCHSTARTCOL, (void*)(duint)col, 0); +} + + +BRIDGE_IMPEXP void GuiStackDumpAt(duint addr, duint csp) +{ + _gui_sendmessage(GUI_STACK_DUMP_AT, (void*)addr, (void*)csp); +} + + +BRIDGE_IMPEXP void GuiUpdateDumpView() +{ + _gui_sendmessage(GUI_UPDATE_DUMP_VIEW, 0, 0); +} + + +BRIDGE_IMPEXP void GuiUpdateMemoryView() +{ + _gui_sendmessage(GUI_UPDATE_MEMORY_VIEW, 0, 0); +} + + +BRIDGE_IMPEXP void GuiUpdateThreadView() +{ + _gui_sendmessage(GUI_UPDATE_THREAD_VIEW, 0, 0); +} + + +BRIDGE_IMPEXP void GuiAddRecentFile(const char* file) +{ + _gui_sendmessage(GUI_ADD_RECENT_FILE, (void*)file, 0); +} + + +BRIDGE_IMPEXP void GuiSetLastException(unsigned int exception) +{ + _gui_sendmessage(GUI_SET_LAST_EXCEPTION, (void*)(duint)exception, 0); +} + + +BRIDGE_IMPEXP bool GuiGetDisassembly(duint addr, char* text) +{ + return !!_gui_sendmessage(GUI_GET_DISASSEMBLY, (void*)addr, text); +} + + +BRIDGE_IMPEXP int GuiMenuAdd(int hMenu, const char* title) +{ + return (int)(duint)_gui_sendmessage(GUI_MENU_ADD, (void*)(duint)hMenu, (void*)title); +} + + +BRIDGE_IMPEXP int GuiMenuAddEntry(int hMenu, const char* title) +{ + return (int)(duint)_gui_sendmessage(GUI_MENU_ADD_ENTRY, (void*)(duint)hMenu, (void*)title); +} + + +BRIDGE_IMPEXP void GuiMenuAddSeparator(int hMenu) +{ + _gui_sendmessage(GUI_MENU_ADD_SEPARATOR, (void*)(duint)hMenu, 0); +} + + +BRIDGE_IMPEXP void GuiMenuClear(int hMenu) +{ + _gui_sendmessage(GUI_MENU_CLEAR, (void*)(duint)hMenu, 0); +} + + +BRIDGE_IMPEXP bool GuiSelectionGet(int hWindow, SELECTIONDATA* selection) +{ + return !!_gui_sendmessage(GUI_SELECTION_GET, (void*)(duint)hWindow, selection); +} + + +BRIDGE_IMPEXP bool GuiSelectionSet(int hWindow, const SELECTIONDATA* selection) +{ + return !!_gui_sendmessage(GUI_SELECTION_SET, (void*)(duint)hWindow, (void*)selection); +} + + +BRIDGE_IMPEXP bool GuiGetLineWindow(const char* title, char* text) +{ + return !!_gui_sendmessage(GUI_GETLINE_WINDOW, (void*)title, text); +} + + +BRIDGE_IMPEXP void GuiAutoCompleteAddCmd(const char* cmd) +{ + _gui_sendmessage(GUI_AUTOCOMPLETE_ADDCMD, (void*)cmd, 0); +} + + +BRIDGE_IMPEXP void GuiAutoCompleteDelCmd(const char* cmd) +{ + _gui_sendmessage(GUI_AUTOCOMPLETE_DELCMD, (void*)cmd, 0); +} + + +BRIDGE_IMPEXP void GuiAutoCompleteClearAll() +{ + _gui_sendmessage(GUI_AUTOCOMPLETE_CLEARALL, 0, 0); +} + + +BRIDGE_IMPEXP void GuiAddStatusBarMessage(const char* msg) +{ + _gui_sendmessage(GUI_ADD_MSG_TO_STATUSBAR, (void*)msg, 0); +} + + +BRIDGE_IMPEXP void GuiUpdateSideBar() +{ + _gui_sendmessage(GUI_UPDATE_SIDEBAR, 0, 0); +} + + +BRIDGE_IMPEXP void GuiRepaintTableView() +{ + _gui_sendmessage(GUI_REPAINT_TABLE_VIEW, 0, 0); +} + + +BRIDGE_IMPEXP void GuiUpdatePatches() +{ + _gui_sendmessage(GUI_UPDATE_PATCHES, 0, 0); +} + + +BRIDGE_IMPEXP void GuiUpdateCallStack() +{ + _gui_sendmessage(GUI_UPDATE_CALLSTACK, 0, 0); +} + +BRIDGE_IMPEXP void GuiLoadSourceFile(const char* path, int line) +{ + _gui_sendmessage(GUI_LOAD_SOURCE_FILE, (void*)path, (void*)line); +} + +BRIDGE_IMPEXP void GuiMenuSetIcon(int hMenu, const ICONDATA* icon) +{ + _gui_sendmessage(GUI_MENU_SET_ICON, (void*)hMenu, (void*)icon); +} + +BRIDGE_IMPEXP void GuiMenuSetEntryIcon(int hEntry, const ICONDATA* icon) +{ + _gui_sendmessage(GUI_MENU_SET_ENTRY_ICON, (void*)hEntry, (void*)icon); +} + +BRIDGE_IMPEXP void GuiShowCpu() +{ + _gui_sendmessage(GUI_SHOW_CPU, 0, 0); +} + +BRIDGE_IMPEXP void GuiAddQWidgetTab(void* qWidget) +{ + _gui_sendmessage(GUI_ADD_QWIDGET_TAB, qWidget, nullptr); +} + +BRIDGE_IMPEXP void GuiShowQWidgetTab(void* qWidget) +{ + _gui_sendmessage(GUI_SHOW_QWIDGET_TAB, qWidget, nullptr); +} + +BRIDGE_IMPEXP void GuiCloseQWidgetTab(void* qWidget) +{ + _gui_sendmessage(GUI_CLOSE_QWIDGET_TAB, qWidget, nullptr); +} + +BRIDGE_IMPEXP void GuiExecuteOnGuiThread(GUICALLBACK cbGuiThread) +{ + _gui_sendmessage(GUI_EXECUTE_ON_GUI_THREAD, cbGuiThread, nullptr); +} + +BRIDGE_IMPEXP void GuiUpdateTimeWastedCounter() +{ + _gui_sendmessage(GUI_UPDATE_TIME_WASTED_COUNTER, nullptr, nullptr); +} + +BRIDGE_IMPEXP void GuiSetGlobalNotes(const char* text) +{ + _gui_sendmessage(GUI_SET_GLOBAL_NOTES, (void*)text, nullptr); +} + +BRIDGE_IMPEXP void GuiGetGlobalNotes(char** text) +{ + _gui_sendmessage(GUI_GET_GLOBAL_NOTES, text, nullptr); +} + +BRIDGE_IMPEXP void GuiSetDebuggeeNotes(const char* text) +{ + _gui_sendmessage(GUI_SET_DEBUGGEE_NOTES, (void*)text, nullptr); +} + +BRIDGE_IMPEXP void GuiGetDebuggeeNotes(char** text) +{ + _gui_sendmessage(GUI_GET_DEBUGGEE_NOTES, text, nullptr); +} + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + hInst = hinstDLL; + return TRUE; } \ No newline at end of file diff --git a/src/bridge/bridgemain.h b/src/bridge/bridgemain.h index 843bb9a8..2d896fe1 100644 --- a/src/bridge/bridgemain.h +++ b/src/bridge/bridgemain.h @@ -1,888 +1,888 @@ -#ifndef _BRIDGEMAIN_H_ -#define _BRIDGEMAIN_H_ - -#include - -#ifndef __cplusplus -#include -#endif - -//list structure (and C++ wrapper) -#include "bridgelist.h" - -//default structure alignments forced -#ifdef _WIN64 -#pragma pack(push, 16) -#else //x86 -#pragma pack(push, 8) -#endif //_WIN64 - -#ifdef _WIN64 -typedef unsigned long long duint; -typedef signed long long dsint; -#else -typedef unsigned long duint; -typedef signed long dsint; -#endif //_WIN64 - -#ifndef BRIDGE_IMPEXP -#ifdef BUILD_BRIDGE -#define BRIDGE_IMPEXP __declspec(dllexport) -#else -#define BRIDGE_IMPEXP __declspec(dllimport) -#endif //BUILD_BRIDGE -#endif //BRIDGE_IMPEXP - -#ifdef __cplusplus -extern "C" -{ -#endif - -//Bridge defines -#define MAX_SETTING_SIZE 65536 -#define DBG_VERSION 25 - -//Bridge functions -BRIDGE_IMPEXP const char* BridgeInit(); -BRIDGE_IMPEXP const char* BridgeStart(); -BRIDGE_IMPEXP void* BridgeAlloc(size_t size); -BRIDGE_IMPEXP void BridgeFree(void* ptr); -BRIDGE_IMPEXP bool BridgeSettingGet(const char* section, const char* key, char* value); -BRIDGE_IMPEXP bool BridgeSettingGetUint(const char* section, const char* key, duint* value); -BRIDGE_IMPEXP bool BridgeSettingSet(const char* section, const char* key, const char* value); -BRIDGE_IMPEXP bool BridgeSettingSetUint(const char* section, const char* key, duint value); -BRIDGE_IMPEXP bool BridgeSettingFlush(); -BRIDGE_IMPEXP bool BridgeSettingRead(int* errorLine); -BRIDGE_IMPEXP int BridgeGetDbgVersion(); - -//Debugger defines -#define MAX_LABEL_SIZE 256 -#define MAX_COMMENT_SIZE 512 -#define MAX_MODULE_SIZE 256 -#define MAX_BREAKPOINT_SIZE 256 -#define MAX_SCRIPT_LINE_SIZE 2048 -#define MAX_THREAD_NAME_SIZE 256 -#define MAX_STRING_SIZE 512 -#define MAX_ERROR_SIZE 512 -#define RIGHTS_STRING_SIZE (sizeof("ERWCG") + 1) -#define MAX_SECTION_SIZE 10 - -#define TYPE_VALUE 1 -#define TYPE_MEMORY 2 -#define TYPE_ADDR 4 -#define MAX_MNEMONIC_SIZE 64 -#define PAGE_SIZE 0x1000 - -//Debugger enums -typedef enum -{ - initialized, - paused, - running, - stopped -} DBGSTATE; - -typedef enum -{ - SEG_DEFAULT, - SEG_ES, - SEG_DS, - SEG_FS, - SEG_GS, - SEG_CS, - SEG_SS -} SEGMENTREG; - -typedef enum -{ - flagmodule = 1, - flaglabel = 2, - flagcomment = 4, - flagbookmark = 8, - flagfunction = 16, - flagloop = 32 -} ADDRINFOFLAGS; - -typedef enum -{ - bp_none = 0, - bp_normal = 1, - bp_hardware = 2, - bp_memory = 4 -} BPXTYPE; - -typedef enum -{ - FUNC_NONE, - FUNC_BEGIN, - FUNC_MIDDLE, - FUNC_END, - FUNC_SINGLE -} FUNCTYPE; - -typedef enum -{ - LOOP_NONE, - LOOP_BEGIN, - LOOP_MIDDLE, - LOOP_ENTRY, - LOOP_END -} LOOPTYPE; - -typedef enum -{ - DBG_SCRIPT_LOAD, // param1=const char* filename, param2=unused - DBG_SCRIPT_UNLOAD, // param1=unused, param2=unused - DBG_SCRIPT_RUN, // param1=int destline, param2=unused - DBG_SCRIPT_STEP, // param1=unused, param2=unused - DBG_SCRIPT_BPTOGGLE, // param1=int line, param2=unused - DBG_SCRIPT_BPGET, // param1=int line, param2=unused - DBG_SCRIPT_CMDEXEC, // param1=const char* command, param2=unused - DBG_SCRIPT_ABORT, // param1=unused, param2=unused - DBG_SCRIPT_GETLINETYPE, // param1=int line, param2=unused - DBG_SCRIPT_SETIP, // param1=int line, param2=unused - DBG_SCRIPT_GETBRANCHINFO, // param1=int line, param2=SCRIPTBRANCH* info - DBG_SYMBOL_ENUM, // param1=SYMBOLCBINFO* cbInfo, param2=unused - DBG_ASSEMBLE_AT, // param1=duint addr, param2=const char* instruction - DBG_MODBASE_FROM_NAME, // param1=const char* modname, param2=unused - DBG_DISASM_AT, // param1=duint addr, param2=DISASM_INSTR* instr - DBG_STACK_COMMENT_GET, // param1=duint addr, param2=STACK_COMMENT* comment - DBG_GET_THREAD_LIST, // param1=THREADALLINFO* list, param2=unused - DBG_SETTINGS_UPDATED, // param1=unused, param2=unused - DBG_DISASM_FAST_AT, // param1=duint addr, param2=BASIC_INSTRUCTION_INFO* basicinfo - DBG_MENU_ENTRY_CLICKED, // param1=int hEntry, param2=unused - DBG_FUNCTION_GET, // param1=FUNCTION_LOOP_INFO* info, param2=unused - DBG_FUNCTION_OVERLAPS, // param1=FUNCTION_LOOP_INFO* info, param2=unused - DBG_FUNCTION_ADD, // param1=FUNCTION_LOOP_INFO* info, param2=unused - DBG_FUNCTION_DEL, // param1=FUNCTION_LOOP_INFO* info, param2=unused - DBG_LOOP_GET, // param1=FUNCTION_LOOP_INFO* info, param2=unused - DBG_LOOP_OVERLAPS, // param1=FUNCTION_LOOP_INFO* info, param2=unused - DBG_LOOP_ADD, // param1=FUNCTION_LOOP_INFO* info, param2=unused - DBG_LOOP_DEL, // param1=FUNCTION_LOOP_INFO* info, param2=unused - DBG_IS_RUN_LOCKED, // param1=unused, param2=unused - DBG_IS_BP_DISABLED, // param1=duint addr, param2=unused - DBG_SET_AUTO_COMMENT_AT, // param1=duint addr, param2=const char* text - DBG_DELETE_AUTO_COMMENT_RANGE, // param1=duint start, param2=duint end - DBG_SET_AUTO_LABEL_AT, // param1=duint addr, param2=const char* text - DBG_DELETE_AUTO_LABEL_RANGE, // param1=duint start, param2=duint end - DBG_SET_AUTO_BOOKMARK_AT, // param1=duint addr, param2=const char* text - DBG_DELETE_AUTO_BOOKMARK_RANGE, // param1=duint start, param2=duint end - DBG_SET_AUTO_FUNCTION_AT, // param1=duint addr, param2=const char* text - DBG_DELETE_AUTO_FUNCTION_RANGE, // param1=duint start, param2=duint end - DBG_GET_STRING_AT, // param1=duint addr, param2=unused - DBG_GET_FUNCTIONS, // param1=unused, param2=unused - DBG_WIN_EVENT, // param1=MSG* message, param2=long* result - DBG_WIN_EVENT_GLOBAL, // param1=MSG* message, param2=unused - DBG_INITIALIZE_LOCKS, // param1=unused, param2=unused - DBG_DEINITIALIZE_LOCKS, // param1=unused, param2=unused - DBG_GET_TIME_WASTED_COUNTER // param1=unused, param2=unused -} DBGMSG; - -typedef enum -{ - linecommand, - linebranch, - linelabel, - linecomment, - lineempty, -} SCRIPTLINETYPE; - -typedef enum -{ - scriptnobranch, - scriptjmp, - scriptjnejnz, - scriptjejz, - scriptjbjl, - scriptjajg, - scriptjbejle, - scriptjaejge, - scriptcall -} SCRIPTBRANCHTYPE; - -typedef enum -{ - instr_normal, - instr_branch, - instr_stack -} DISASM_INSTRTYPE; - -typedef enum -{ - arg_normal, - arg_memory -} DISASM_ARGTYPE; - -typedef enum -{ - str_none, - str_ascii, - str_unicode -} STRING_TYPE; - -typedef enum -{ - _PriorityIdle = -15, - _PriorityAboveNormal = 1, - _PriorityBelowNormal = -1, - _PriorityHighest = 2, - _PriorityLowest = -2, - _PriorityNormal = 0, - _PriorityTimeCritical = 15, - _PriorityUnknown = 0x7FFFFFFF -} THREADPRIORITY; - -typedef enum -{ - _Executive = 0, - _FreePage = 1, - _PageIn = 2, - _PoolAllocation = 3, - _DelayExecution = 4, - _Suspended = 5, - _UserRequest = 6, - _WrExecutive = 7, - _WrFreePage = 8, - _WrPageIn = 9, - _WrPoolAllocation = 10, - _WrDelayExecution = 11, - _WrSuspended = 12, - _WrUserRequest = 13, - _WrEventPair = 14, - _WrQueue = 15, - _WrLpcReceive = 16, - _WrLpcReply = 17, - _WrVirtualMemory = 18, - _WrPageOut = 19, - _WrRendezvous = 20, - _Spare2 = 21, - _Spare3 = 22, - _Spare4 = 23, - _Spare5 = 24, - _WrCalloutStack = 25, - _WrKernel = 26, - _WrResource = 27, - _WrPushLock = 28, - _WrMutex = 29, - _WrQuantumEnd = 30, - _WrDispatchInt = 31, - _WrPreempted = 32, - _WrYieldExecution = 33, - _WrFastMutex = 34, - _WrGuardedMutex = 35, - _WrRundown = 36, -} THREADWAITREASON; - -typedef enum -{ - size_byte = 1, - size_word = 2, - size_dword = 4, - size_qword = 8 -} MEMORY_SIZE; - -//Debugger typedefs -typedef MEMORY_SIZE VALUE_SIZE; -typedef struct SYMBOLINFO_ SYMBOLINFO; -typedef struct DBGFUNCTIONS_ DBGFUNCTIONS; - -typedef void (*CBSYMBOLENUM)(SYMBOLINFO* symbol, void* user); - -//Debugger structs -typedef struct -{ - MEMORY_BASIC_INFORMATION mbi; - char info[MAX_MODULE_SIZE]; -} MEMPAGE; - -typedef struct -{ - int count; - MEMPAGE* page; -} MEMMAP; - -typedef struct -{ - BPXTYPE type; - duint addr; - bool enabled; - bool singleshoot; - bool active; - char name[MAX_BREAKPOINT_SIZE]; - char mod[MAX_MODULE_SIZE]; - unsigned short slot; -} BRIDGEBP; - -typedef struct -{ - int count; - BRIDGEBP* bp; -} BPMAP; - -typedef struct -{ - duint start; //OUT - duint end; //OUT -} FUNCTION; - -typedef struct -{ - int depth; //IN - duint start; //OUT - duint end; //OUT -} LOOP; - -typedef struct -{ - int flags; //ADDRINFOFLAGS (IN) - char module[MAX_MODULE_SIZE]; //module the address is in - char label[MAX_LABEL_SIZE]; - char comment[MAX_COMMENT_SIZE]; - bool isbookmark; - FUNCTION function; - LOOP loop; -} ADDRINFO; - -struct SYMBOLINFO_ -{ - duint addr; - char* decoratedSymbol; - char* undecoratedSymbol; -}; - -typedef struct -{ - duint base; - char name[MAX_MODULE_SIZE]; -} SYMBOLMODULEINFO; - -typedef struct -{ - duint base; - CBSYMBOLENUM cbSymbolEnum; - void* user; -} SYMBOLCBINFO; - -typedef struct -{ - bool c; - bool p; - bool a; - bool z; - bool s; - bool t; - bool i; - bool d; - bool o; -} FLAGS; - -typedef struct -{ - bool FZ; - bool PM; - bool UM; - bool OM; - bool ZM; - bool IM; - bool DM; - bool DAZ; - bool PE; - bool UE; - bool OE; - bool ZE; - bool DE; - bool IE; - - unsigned short RC; -} MXCSRFIELDS; - -typedef struct -{ - bool B; - bool C3; - bool C2; - bool C1; - bool C0; - bool IR; - bool SF; - bool P; - bool U; - bool O; - bool Z; - bool D; - bool I; - - unsigned short TOP; - -} X87STATUSWORDFIELDS; - -typedef struct -{ - bool IC; - bool IEM; - bool PM; - bool UM; - bool OM; - bool ZM; - bool DM; - bool IM; - - unsigned short RC; - unsigned short PC; - -} X87CONTROLWORDFIELDS; - -typedef struct DECLSPEC_ALIGN(16) _XMMREGISTER -{ - ULONGLONG Low; - LONGLONG High; -} XMMREGISTER; - -typedef struct -{ - XMMREGISTER Low; //XMM/SSE part - XMMREGISTER High; //AVX part -} YMMREGISTER; - -typedef struct -{ - BYTE data[10]; - int st_value; - int tag; -} X87FPUREGISTER; - -typedef struct -{ - WORD ControlWord; - WORD StatusWord; - WORD TagWord; - DWORD ErrorOffset; - DWORD ErrorSelector; - DWORD DataOffset; - DWORD DataSelector; - DWORD Cr0NpxState; -} X87FPU; - -typedef struct -{ - ULONG_PTR cax; - ULONG_PTR ccx; - ULONG_PTR cdx; - ULONG_PTR cbx; - ULONG_PTR csp; - ULONG_PTR cbp; - ULONG_PTR csi; - ULONG_PTR cdi; -#ifdef _WIN64 - ULONG_PTR r8; - ULONG_PTR r9; - ULONG_PTR r10; - ULONG_PTR r11; - ULONG_PTR r12; - ULONG_PTR r13; - ULONG_PTR r14; - ULONG_PTR r15; -#endif //_WIN64 - ULONG_PTR cip; - ULONG_PTR eflags; - unsigned short gs; - unsigned short fs; - unsigned short es; - unsigned short ds; - unsigned short cs; - unsigned short ss; - ULONG_PTR dr0; - ULONG_PTR dr1; - ULONG_PTR dr2; - ULONG_PTR dr3; - ULONG_PTR dr6; - ULONG_PTR dr7; - BYTE RegisterArea[80]; - X87FPU x87fpu; - DWORD MxCsr; -#ifdef _WIN64 - XMMREGISTER XmmRegisters[16]; - YMMREGISTER YmmRegisters[16]; -#else // x86 - XMMREGISTER XmmRegisters[8]; - YMMREGISTER YmmRegisters[8]; -#endif -} REGISTERCONTEXT; - -typedef struct -{ - DWORD code; - const char* name; -} LASTERROR; - -typedef struct -{ - REGISTERCONTEXT regcontext; - FLAGS flags; - X87FPUREGISTER x87FPURegisters[8]; - unsigned long long mmx[8]; - MXCSRFIELDS MxCsrFields; - X87STATUSWORDFIELDS x87StatusWordFields; - X87CONTROLWORDFIELDS x87ControlWordFields; - LASTERROR lastError; -} REGDUMP; - -typedef struct -{ - DISASM_ARGTYPE type; - SEGMENTREG segment; - char mnemonic[64]; - duint constant; - duint value; - duint memvalue; -} DISASM_ARG; - -typedef struct -{ - char instruction[64]; - DISASM_INSTRTYPE type; - int argcount; - int instr_size; - DISASM_ARG arg[3]; -} DISASM_INSTR; - -typedef struct -{ - char color[8]; //hex color-code - char comment[MAX_COMMENT_SIZE]; -} STACK_COMMENT; - -typedef struct -{ - int ThreadNumber; - HANDLE Handle; - DWORD ThreadId; - duint ThreadStartAddress; - duint ThreadLocalBase; - char threadName[MAX_THREAD_NAME_SIZE]; -} THREADINFO; - -typedef struct -{ - THREADINFO BasicInfo; - duint ThreadCip; - DWORD SuspendCount; - THREADPRIORITY Priority; - THREADWAITREASON WaitReason; - DWORD LastError; -} THREADALLINFO; - -typedef struct -{ - int count; - THREADALLINFO* list; - int CurrentThread; -} THREADLIST; - -typedef struct -{ - ULONG_PTR value; //displacement / addrvalue (rip-relative) - MEMORY_SIZE size; //byte/word/dword/qword - char mnemonic[MAX_MNEMONIC_SIZE]; -} MEMORY_INFO; - -typedef struct -{ - ULONG_PTR value; - VALUE_SIZE size; -} VALUE_INFO; - -typedef struct -{ - DWORD type; //value|memory|addr - VALUE_INFO value; //immediat - MEMORY_INFO memory; - ULONG_PTR addr; //addrvalue (jumps + calls) - bool branch; //jumps/calls - bool call; //instruction is a call - int size; - char instruction[MAX_MNEMONIC_SIZE * 4]; -} BASIC_INSTRUCTION_INFO; - -typedef struct -{ - SCRIPTBRANCHTYPE type; - int dest; - char branchlabel[256]; -} SCRIPTBRANCH; - -typedef struct -{ - duint addr; - duint start; - duint end; - bool manual; - int depth; -} FUNCTION_LOOP_INFO; - -//Debugger functions -BRIDGE_IMPEXP const char* DbgInit(); -BRIDGE_IMPEXP void DbgExit(); -BRIDGE_IMPEXP bool DbgMemRead(duint va, unsigned char* dest, duint size); -BRIDGE_IMPEXP bool DbgMemWrite(duint va, const unsigned char* src, duint size); -BRIDGE_IMPEXP duint DbgMemGetPageSize(duint base); -BRIDGE_IMPEXP duint DbgMemFindBaseAddr(duint addr, duint* size); -BRIDGE_IMPEXP bool DbgCmdExec(const char* cmd); -BRIDGE_IMPEXP bool DbgCmdExecDirect(const char* cmd); -BRIDGE_IMPEXP bool DbgMemMap(MEMMAP* memmap); -BRIDGE_IMPEXP bool DbgIsValidExpression(const char* expression); -BRIDGE_IMPEXP bool DbgIsDebugging(); -BRIDGE_IMPEXP bool DbgIsJumpGoingToExecute(duint addr); -BRIDGE_IMPEXP bool DbgGetLabelAt(duint addr, SEGMENTREG segment, char* text); -BRIDGE_IMPEXP bool DbgSetLabelAt(duint addr, const char* text); -BRIDGE_IMPEXP bool DbgGetCommentAt(duint addr, char* text); -BRIDGE_IMPEXP bool DbgSetCommentAt(duint addr, const char* text); -BRIDGE_IMPEXP bool DbgGetBookmarkAt(duint addr); -BRIDGE_IMPEXP bool DbgSetBookmarkAt(duint addr, bool isbookmark); -BRIDGE_IMPEXP bool DbgGetModuleAt(duint addr, char* text); -BRIDGE_IMPEXP BPXTYPE DbgGetBpxTypeAt(duint addr); -BRIDGE_IMPEXP duint DbgValFromString(const char* string); -BRIDGE_IMPEXP bool DbgGetRegDump(REGDUMP* regdump); -BRIDGE_IMPEXP bool DbgValToString(const char* string, duint value); -BRIDGE_IMPEXP bool DbgMemIsValidReadPtr(duint addr); -BRIDGE_IMPEXP int DbgGetBpList(BPXTYPE type, BPMAP* list); -BRIDGE_IMPEXP FUNCTYPE DbgGetFunctionTypeAt(duint addr); -BRIDGE_IMPEXP LOOPTYPE DbgGetLoopTypeAt(duint addr, int depth); -BRIDGE_IMPEXP duint DbgGetBranchDestination(duint addr); -BRIDGE_IMPEXP void DbgScriptLoad(const char* filename); -BRIDGE_IMPEXP void DbgScriptUnload(); -BRIDGE_IMPEXP void DbgScriptRun(int destline); -BRIDGE_IMPEXP void DbgScriptStep(); -BRIDGE_IMPEXP bool DbgScriptBpToggle(int line); -BRIDGE_IMPEXP bool DbgScriptBpGet(int line); -BRIDGE_IMPEXP bool DbgScriptCmdExec(const char* command); -BRIDGE_IMPEXP void DbgScriptAbort(); -BRIDGE_IMPEXP SCRIPTLINETYPE DbgScriptGetLineType(int line); -BRIDGE_IMPEXP void DbgScriptSetIp(int line); -BRIDGE_IMPEXP bool DbgScriptGetBranchInfo(int line, SCRIPTBRANCH* info); -BRIDGE_IMPEXP void DbgSymbolEnum(duint base, CBSYMBOLENUM cbSymbolEnum, void* user); -BRIDGE_IMPEXP bool DbgAssembleAt(duint addr, const char* instruction); -BRIDGE_IMPEXP duint DbgModBaseFromName(const char* name); -BRIDGE_IMPEXP void DbgDisasmAt(duint addr, DISASM_INSTR* instr); -BRIDGE_IMPEXP bool DbgStackCommentGet(duint addr, STACK_COMMENT* comment); -BRIDGE_IMPEXP void DbgGetThreadList(THREADLIST* list); -BRIDGE_IMPEXP void DbgSettingsUpdated(); -BRIDGE_IMPEXP void DbgDisasmFastAt(duint addr, BASIC_INSTRUCTION_INFO* basicinfo); -BRIDGE_IMPEXP void DbgMenuEntryClicked(int hEntry); -BRIDGE_IMPEXP bool DbgFunctionGet(duint addr, duint* start, duint* end); -BRIDGE_IMPEXP bool DbgFunctionOverlaps(duint start, duint end); -BRIDGE_IMPEXP bool DbgFunctionAdd(duint start, duint end); -BRIDGE_IMPEXP bool DbgFunctionDel(duint addr); -BRIDGE_IMPEXP bool DbgLoopGet(int depth, duint addr, duint* start, duint* end); -BRIDGE_IMPEXP bool DbgLoopOverlaps(int depth, duint start, duint end); -BRIDGE_IMPEXP bool DbgLoopAdd(duint start, duint end); -BRIDGE_IMPEXP bool DbgLoopDel(int depth, duint addr); -BRIDGE_IMPEXP bool DbgIsRunLocked(); -BRIDGE_IMPEXP bool DbgIsBpDisabled(duint addr); -BRIDGE_IMPEXP bool DbgSetAutoCommentAt(duint addr, const char* text); -BRIDGE_IMPEXP void DbgClearAutoCommentRange(duint start, duint end); -BRIDGE_IMPEXP bool DbgSetAutoLabelAt(duint addr, const char* text); -BRIDGE_IMPEXP void DbgClearAutoLabelRange(duint start, duint end); -BRIDGE_IMPEXP bool DbgSetAutoBookmarkAt(duint addr); -BRIDGE_IMPEXP void DbgClearAutoBookmarkRange(duint start, duint end); -BRIDGE_IMPEXP bool DbgSetAutoFunctionAt(duint start, duint end); -BRIDGE_IMPEXP void DbgClearAutoFunctionRange(duint start, duint end); -BRIDGE_IMPEXP bool DbgGetStringAt(duint addr, char* text); -BRIDGE_IMPEXP const DBGFUNCTIONS* DbgFunctions(); -BRIDGE_IMPEXP bool DbgWinEvent(MSG* message, long* result); -BRIDGE_IMPEXP bool DbgWinEventGlobal(MSG* message); -BRIDGE_IMPEXP bool DbgIsRunning(); -BRIDGE_IMPEXP duint DbgGetTimeWastedCounter(); - -//Gui defines -#define GUI_PLUGIN_MENU 0 -#define GUI_DISASM_MENU 1 -#define GUI_DUMP_MENU 2 -#define GUI_STACK_MENU 3 - -#define GUI_DISASSEMBLY 0 -#define GUI_DUMP 1 -#define GUI_STACK 2 - -#define GUI_MAX_LINE_SIZE 65536 -#define GUI_MAX_DISASSEMBLY_SIZE 2048 - -//Gui enums -typedef enum -{ - GUI_DISASSEMBLE_AT, // param1=(duint)va, param2=(duint)cip - GUI_SET_DEBUG_STATE, // param1=(DBGSTATE)state, param2=unused - GUI_ADD_MSG_TO_LOG, // param1=(const char*)msg, param2=unused - GUI_CLEAR_LOG, // param1=unused, param2=unused - GUI_UPDATE_REGISTER_VIEW, // param1=unused, param2=unused - GUI_UPDATE_DISASSEMBLY_VIEW, // param1=unused, param2=unused - GUI_UPDATE_BREAKPOINTS_VIEW, // param1=unused, param2=unused - GUI_UPDATE_WINDOW_TITLE, // param1=(const char*)file, param2=unused - GUI_GET_WINDOW_HANDLE, // param1=unused, param2=unused - GUI_DUMP_AT, // param1=(duint)va param2=unused - GUI_SCRIPT_ADD, // param1=int count, param2=const char** lines - GUI_SCRIPT_CLEAR, // param1=unused, param2=unused - GUI_SCRIPT_SETIP, // param1=int line, param2=unused - GUI_SCRIPT_ERROR, // param1=int line, param2=const char* message - GUI_SCRIPT_SETTITLE, // param1=const char* title, param2=unused - GUI_SCRIPT_SETINFOLINE, // param1=int line, param2=const char* info - GUI_SCRIPT_MESSAGE, // param1=const char* message, param2=unused - GUI_SCRIPT_MSGYN, // param1=const char* message, param2=unused - GUI_SYMBOL_LOG_ADD, // param1(const char*)msg, param2=unused - GUI_SYMBOL_LOG_CLEAR, // param1=unused, param2=unused - GUI_SYMBOL_SET_PROGRESS, // param1=int percent param2=unused - GUI_SYMBOL_UPDATE_MODULE_LIST, // param1=int count, param2=SYMBOLMODULEINFO* modules - GUI_REF_ADDCOLUMN, // param1=int width, param2=(const char*)title - GUI_REF_SETROWCOUNT, // param1=int rows, param2=unused - GUI_REF_GETROWCOUNT, // param1=unused, param2=unused - GUI_REF_DELETEALLCOLUMNS, // param1=unused, param2=unused - GUI_REF_SETCELLCONTENT, // param1=(CELLINFO*)info, param2=unused - GUI_REF_GETCELLCONTENT, // param1=int row, param2=int col - GUI_REF_RELOADDATA, // param1=unused, param2=unused - GUI_REF_SETSINGLESELECTION, // param1=int index, param2=bool scroll - GUI_REF_SETPROGRESS, // param1=int progress, param2=unused - GUI_REF_SETSEARCHSTARTCOL, // param1=int col param2=unused - GUI_STACK_DUMP_AT, // param1=duint addr, param2=duint csp - GUI_UPDATE_DUMP_VIEW, // param1=unused, param2=unused - GUI_UPDATE_THREAD_VIEW, // param1=unused, param2=unused - GUI_ADD_RECENT_FILE, // param1=(const char*)file, param2=unused - GUI_SET_LAST_EXCEPTION, // param1=unsigned int code, param2=unused - GUI_GET_DISASSEMBLY, // param1=duint addr, param2=char* text - GUI_MENU_ADD, // param1=int hMenu, param2=const char* title - GUI_MENU_ADD_ENTRY, // param1=int hMenu, param2=const char* title - GUI_MENU_ADD_SEPARATOR, // param1=int hMenu, param2=unused - GUI_MENU_CLEAR, // param1=int hMenu, param2=unused - GUI_SELECTION_GET, // param1=int hWindow, param2=SELECTIONDATA* selection - GUI_SELECTION_SET, // param1=int hWindow, param2=const SELECTIONDATA* selection - GUI_GETLINE_WINDOW, // param1=const char* title, param2=char* text - GUI_AUTOCOMPLETE_ADDCMD, // param1=const char* cmd, param2=ununsed - GUI_AUTOCOMPLETE_DELCMD, // param1=const char* cmd, param2=ununsed - GUI_AUTOCOMPLETE_CLEARALL, // param1=unused, param2=unused - GUI_SCRIPT_ENABLEHIGHLIGHTING, // param1=bool enable, param2=unused - GUI_ADD_MSG_TO_STATUSBAR, // param1=const char* msg, param2=unused - GUI_UPDATE_SIDEBAR, // param1=unused, param2=unused - GUI_REPAINT_TABLE_VIEW, // param1=unused, param2=unused - GUI_UPDATE_PATCHES, // param1=unused, param2=unused - GUI_UPDATE_CALLSTACK, // param1=unused, param2=unused - GUI_SYMBOL_REFRESH_CURRENT, // param1=unused, param2=unused - GUI_UPDATE_MEMORY_VIEW, // param1=unused, param2=unused - GUI_REF_INITIALIZE, // param1=const char* name, param2=unused - GUI_LOAD_SOURCE_FILE, // param1=const char* path, param2=line - GUI_MENU_SET_ICON, // param1=int hMenu, param2=ICONINFO* - GUI_MENU_SET_ENTRY_ICON, // param1=int hEntry, param2=ICONINFO* - GUI_SHOW_CPU, // param1=unused, param2=unused - GUI_ADD_QWIDGET_TAB, // param1=QWidget*, param2=unused - GUI_SHOW_QWIDGET_TAB, // param1=QWidget*, param2=unused - GUI_CLOSE_QWIDGET_TAB, // param1=QWidget*, param2=unused - GUI_EXECUTE_ON_GUI_THREAD, // param1=GUICALLBACK, param2=unused - GUI_UPDATE_TIME_WASTED_COUNTER, // param1=unused, param2=unused - GUI_SET_GLOBAL_NOTES, // param1=const char* text, param2=unused - GUI_GET_GLOBAL_NOTES, // param1=char** text, param2=unused - GUI_SET_DEBUGGEE_NOTES, // param1=const char* text, param2=unused - GUI_GET_DEBUGGEE_NOTES // param1=char** text, param2=unused -} GUIMSG; - -//GUI Typedefs -typedef void (*GUICALLBACK)(); - -//GUI structures -typedef struct -{ - int row; - int col; - const char* str; -} CELLINFO; - -typedef struct -{ - duint start; - duint end; - duint view; -} SELECTIONDATA; - -typedef struct -{ - const void* data; - duint size; -} ICONDATA; - -//GUI functions -BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip); -BRIDGE_IMPEXP void GuiSetDebugState(DBGSTATE state); -BRIDGE_IMPEXP void GuiAddLogMessage(const char* msg); -BRIDGE_IMPEXP void GuiLogClear(); -BRIDGE_IMPEXP void GuiUpdateAllViews(); -BRIDGE_IMPEXP void GuiUpdateRegisterView(); -BRIDGE_IMPEXP void GuiUpdateDisassemblyView(); -BRIDGE_IMPEXP void GuiUpdateBreakpointsView(); -BRIDGE_IMPEXP void GuiUpdateWindowTitle(const char* filename); -BRIDGE_IMPEXP HWND GuiGetWindowHandle(); -BRIDGE_IMPEXP void GuiDumpAt(duint va); -BRIDGE_IMPEXP void GuiScriptAdd(int count, const char** lines); -BRIDGE_IMPEXP void GuiScriptClear(); -BRIDGE_IMPEXP void GuiScriptSetIp(int line); -BRIDGE_IMPEXP void GuiScriptError(int line, const char* message); -BRIDGE_IMPEXP void GuiScriptSetTitle(const char* title); -BRIDGE_IMPEXP void GuiScriptSetInfoLine(int line, const char* info); -BRIDGE_IMPEXP void GuiScriptMessage(const char* message); -BRIDGE_IMPEXP int GuiScriptMsgyn(const char* message); -BRIDGE_IMPEXP void GuiScriptEnableHighlighting(bool enable); -BRIDGE_IMPEXP void GuiSymbolLogAdd(const char* message); -BRIDGE_IMPEXP void GuiSymbolLogClear(); -BRIDGE_IMPEXP void GuiSymbolSetProgress(int percent); -BRIDGE_IMPEXP void GuiSymbolUpdateModuleList(int count, SYMBOLMODULEINFO* modules); -BRIDGE_IMPEXP void GuiSymbolRefreshCurrent(); -BRIDGE_IMPEXP void GuiReferenceAddColumn(int width, const char* title); -BRIDGE_IMPEXP void GuiReferenceSetRowCount(int count); -BRIDGE_IMPEXP int GuiReferenceGetRowCount(); -BRIDGE_IMPEXP void GuiReferenceDeleteAllColumns(); -BRIDGE_IMPEXP void GuiReferenceInitialize(const char* name); -BRIDGE_IMPEXP void GuiReferenceSetCellContent(int row, int col, const char* str); -BRIDGE_IMPEXP const char* GuiReferenceGetCellContent(int row, int col); -BRIDGE_IMPEXP void GuiReferenceReloadData(); -BRIDGE_IMPEXP void GuiReferenceSetSingleSelection(int index, bool scroll); -BRIDGE_IMPEXP void GuiReferenceSetProgress(int progress); -BRIDGE_IMPEXP void GuiReferenceSetSearchStartCol(int col); -BRIDGE_IMPEXP void GuiStackDumpAt(duint addr, duint csp); -BRIDGE_IMPEXP void GuiUpdateDumpView(); -BRIDGE_IMPEXP void GuiUpdateThreadView(); -BRIDGE_IMPEXP void GuiUpdateMemoryView(); -BRIDGE_IMPEXP void GuiAddRecentFile(const char* file); -BRIDGE_IMPEXP void GuiSetLastException(unsigned int exception); -BRIDGE_IMPEXP bool GuiGetDisassembly(duint addr, char* text); -BRIDGE_IMPEXP int GuiMenuAdd(int hMenu, const char* title); -BRIDGE_IMPEXP int GuiMenuAddEntry(int hMenu, const char* title); -BRIDGE_IMPEXP void GuiMenuAddSeparator(int hMenu); -BRIDGE_IMPEXP void GuiMenuClear(int hMenu); -BRIDGE_IMPEXP bool GuiSelectionGet(int hWindow, SELECTIONDATA* selection); -BRIDGE_IMPEXP bool GuiSelectionSet(int hWindow, const SELECTIONDATA* selection); -BRIDGE_IMPEXP bool GuiGetLineWindow(const char* title, char* text); -BRIDGE_IMPEXP void GuiAutoCompleteAddCmd(const char* cmd); -BRIDGE_IMPEXP void GuiAutoCompleteDelCmd(const char* cmd); -BRIDGE_IMPEXP void GuiAutoCompleteClearAll(); -BRIDGE_IMPEXP void GuiAddStatusBarMessage(const char* msg); -BRIDGE_IMPEXP void GuiUpdateSideBar(); -BRIDGE_IMPEXP void GuiRepaintTableView(); -BRIDGE_IMPEXP void GuiUpdatePatches(); -BRIDGE_IMPEXP void GuiUpdateCallStack(); -BRIDGE_IMPEXP void GuiLoadSourceFile(const char* path, int line); -BRIDGE_IMPEXP void GuiMenuSetIcon(int hMenu, const ICONDATA* icon); -BRIDGE_IMPEXP void GuiMenuSetEntryIcon(int hEntry, const ICONDATA* icon); -BRIDGE_IMPEXP void GuiShowCpu(); -BRIDGE_IMPEXP void GuiAddQWidgetTab(void* qWidget); -BRIDGE_IMPEXP void GuiShowQWidgetTab(void* qWidget); -BRIDGE_IMPEXP void GuiCloseQWidgetTab(void* qWidget); -BRIDGE_IMPEXP void GuiExecuteOnGuiThread(GUICALLBACK cbGuiThread); -BRIDGE_IMPEXP void GuiUpdateTimeWastedCounter(); -BRIDGE_IMPEXP void GuiSetGlobalNotes(const char* text); -BRIDGE_IMPEXP void GuiGetGlobalNotes(char** text); -BRIDGE_IMPEXP void GuiSetDebuggeeNotes(const char* text); -BRIDGE_IMPEXP void GuiGetDebuggeeNotes(char** text); - -#ifdef __cplusplus -} -#endif - -#pragma pack(pop) - -#endif // _BRIDGEMAIN_H_ +#ifndef _BRIDGEMAIN_H_ +#define _BRIDGEMAIN_H_ + +#include + +#ifndef __cplusplus +#include +#endif + +//list structure (and C++ wrapper) +#include "bridgelist.h" + +//default structure alignments forced +#ifdef _WIN64 +#pragma pack(push, 16) +#else //x86 +#pragma pack(push, 8) +#endif //_WIN64 + +#ifdef _WIN64 +typedef unsigned long long duint; +typedef signed long long dsint; +#else +typedef unsigned long duint; +typedef signed long dsint; +#endif //_WIN64 + +#ifndef BRIDGE_IMPEXP +#ifdef BUILD_BRIDGE +#define BRIDGE_IMPEXP __declspec(dllexport) +#else +#define BRIDGE_IMPEXP __declspec(dllimport) +#endif //BUILD_BRIDGE +#endif //BRIDGE_IMPEXP + +#ifdef __cplusplus +extern "C" +{ +#endif + +//Bridge defines +#define MAX_SETTING_SIZE 65536 +#define DBG_VERSION 25 + +//Bridge functions +BRIDGE_IMPEXP const char* BridgeInit(); +BRIDGE_IMPEXP const char* BridgeStart(); +BRIDGE_IMPEXP void* BridgeAlloc(size_t size); +BRIDGE_IMPEXP void BridgeFree(void* ptr); +BRIDGE_IMPEXP bool BridgeSettingGet(const char* section, const char* key, char* value); +BRIDGE_IMPEXP bool BridgeSettingGetUint(const char* section, const char* key, duint* value); +BRIDGE_IMPEXP bool BridgeSettingSet(const char* section, const char* key, const char* value); +BRIDGE_IMPEXP bool BridgeSettingSetUint(const char* section, const char* key, duint value); +BRIDGE_IMPEXP bool BridgeSettingFlush(); +BRIDGE_IMPEXP bool BridgeSettingRead(int* errorLine); +BRIDGE_IMPEXP int BridgeGetDbgVersion(); + +//Debugger defines +#define MAX_LABEL_SIZE 256 +#define MAX_COMMENT_SIZE 512 +#define MAX_MODULE_SIZE 256 +#define MAX_BREAKPOINT_SIZE 256 +#define MAX_SCRIPT_LINE_SIZE 2048 +#define MAX_THREAD_NAME_SIZE 256 +#define MAX_STRING_SIZE 512 +#define MAX_ERROR_SIZE 512 +#define RIGHTS_STRING_SIZE (sizeof("ERWCG") + 1) +#define MAX_SECTION_SIZE 10 + +#define TYPE_VALUE 1 +#define TYPE_MEMORY 2 +#define TYPE_ADDR 4 +#define MAX_MNEMONIC_SIZE 64 +#define PAGE_SIZE 0x1000 + +//Debugger enums +typedef enum +{ + initialized, + paused, + running, + stopped +} DBGSTATE; + +typedef enum +{ + SEG_DEFAULT, + SEG_ES, + SEG_DS, + SEG_FS, + SEG_GS, + SEG_CS, + SEG_SS +} SEGMENTREG; + +typedef enum +{ + flagmodule = 1, + flaglabel = 2, + flagcomment = 4, + flagbookmark = 8, + flagfunction = 16, + flagloop = 32 +} ADDRINFOFLAGS; + +typedef enum +{ + bp_none = 0, + bp_normal = 1, + bp_hardware = 2, + bp_memory = 4 +} BPXTYPE; + +typedef enum +{ + FUNC_NONE, + FUNC_BEGIN, + FUNC_MIDDLE, + FUNC_END, + FUNC_SINGLE +} FUNCTYPE; + +typedef enum +{ + LOOP_NONE, + LOOP_BEGIN, + LOOP_MIDDLE, + LOOP_ENTRY, + LOOP_END +} LOOPTYPE; + +typedef enum +{ + DBG_SCRIPT_LOAD, // param1=const char* filename, param2=unused + DBG_SCRIPT_UNLOAD, // param1=unused, param2=unused + DBG_SCRIPT_RUN, // param1=int destline, param2=unused + DBG_SCRIPT_STEP, // param1=unused, param2=unused + DBG_SCRIPT_BPTOGGLE, // param1=int line, param2=unused + DBG_SCRIPT_BPGET, // param1=int line, param2=unused + DBG_SCRIPT_CMDEXEC, // param1=const char* command, param2=unused + DBG_SCRIPT_ABORT, // param1=unused, param2=unused + DBG_SCRIPT_GETLINETYPE, // param1=int line, param2=unused + DBG_SCRIPT_SETIP, // param1=int line, param2=unused + DBG_SCRIPT_GETBRANCHINFO, // param1=int line, param2=SCRIPTBRANCH* info + DBG_SYMBOL_ENUM, // param1=SYMBOLCBINFO* cbInfo, param2=unused + DBG_ASSEMBLE_AT, // param1=duint addr, param2=const char* instruction + DBG_MODBASE_FROM_NAME, // param1=const char* modname, param2=unused + DBG_DISASM_AT, // param1=duint addr, param2=DISASM_INSTR* instr + DBG_STACK_COMMENT_GET, // param1=duint addr, param2=STACK_COMMENT* comment + DBG_GET_THREAD_LIST, // param1=THREADALLINFO* list, param2=unused + DBG_SETTINGS_UPDATED, // param1=unused, param2=unused + DBG_DISASM_FAST_AT, // param1=duint addr, param2=BASIC_INSTRUCTION_INFO* basicinfo + DBG_MENU_ENTRY_CLICKED, // param1=int hEntry, param2=unused + DBG_FUNCTION_GET, // param1=FUNCTION_LOOP_INFO* info, param2=unused + DBG_FUNCTION_OVERLAPS, // param1=FUNCTION_LOOP_INFO* info, param2=unused + DBG_FUNCTION_ADD, // param1=FUNCTION_LOOP_INFO* info, param2=unused + DBG_FUNCTION_DEL, // param1=FUNCTION_LOOP_INFO* info, param2=unused + DBG_LOOP_GET, // param1=FUNCTION_LOOP_INFO* info, param2=unused + DBG_LOOP_OVERLAPS, // param1=FUNCTION_LOOP_INFO* info, param2=unused + DBG_LOOP_ADD, // param1=FUNCTION_LOOP_INFO* info, param2=unused + DBG_LOOP_DEL, // param1=FUNCTION_LOOP_INFO* info, param2=unused + DBG_IS_RUN_LOCKED, // param1=unused, param2=unused + DBG_IS_BP_DISABLED, // param1=duint addr, param2=unused + DBG_SET_AUTO_COMMENT_AT, // param1=duint addr, param2=const char* text + DBG_DELETE_AUTO_COMMENT_RANGE, // param1=duint start, param2=duint end + DBG_SET_AUTO_LABEL_AT, // param1=duint addr, param2=const char* text + DBG_DELETE_AUTO_LABEL_RANGE, // param1=duint start, param2=duint end + DBG_SET_AUTO_BOOKMARK_AT, // param1=duint addr, param2=const char* text + DBG_DELETE_AUTO_BOOKMARK_RANGE, // param1=duint start, param2=duint end + DBG_SET_AUTO_FUNCTION_AT, // param1=duint addr, param2=const char* text + DBG_DELETE_AUTO_FUNCTION_RANGE, // param1=duint start, param2=duint end + DBG_GET_STRING_AT, // param1=duint addr, param2=unused + DBG_GET_FUNCTIONS, // param1=unused, param2=unused + DBG_WIN_EVENT, // param1=MSG* message, param2=long* result + DBG_WIN_EVENT_GLOBAL, // param1=MSG* message, param2=unused + DBG_INITIALIZE_LOCKS, // param1=unused, param2=unused + DBG_DEINITIALIZE_LOCKS, // param1=unused, param2=unused + DBG_GET_TIME_WASTED_COUNTER // param1=unused, param2=unused +} DBGMSG; + +typedef enum +{ + linecommand, + linebranch, + linelabel, + linecomment, + lineempty, +} SCRIPTLINETYPE; + +typedef enum +{ + scriptnobranch, + scriptjmp, + scriptjnejnz, + scriptjejz, + scriptjbjl, + scriptjajg, + scriptjbejle, + scriptjaejge, + scriptcall +} SCRIPTBRANCHTYPE; + +typedef enum +{ + instr_normal, + instr_branch, + instr_stack +} DISASM_INSTRTYPE; + +typedef enum +{ + arg_normal, + arg_memory +} DISASM_ARGTYPE; + +typedef enum +{ + str_none, + str_ascii, + str_unicode +} STRING_TYPE; + +typedef enum +{ + _PriorityIdle = -15, + _PriorityAboveNormal = 1, + _PriorityBelowNormal = -1, + _PriorityHighest = 2, + _PriorityLowest = -2, + _PriorityNormal = 0, + _PriorityTimeCritical = 15, + _PriorityUnknown = 0x7FFFFFFF +} THREADPRIORITY; + +typedef enum +{ + _Executive = 0, + _FreePage = 1, + _PageIn = 2, + _PoolAllocation = 3, + _DelayExecution = 4, + _Suspended = 5, + _UserRequest = 6, + _WrExecutive = 7, + _WrFreePage = 8, + _WrPageIn = 9, + _WrPoolAllocation = 10, + _WrDelayExecution = 11, + _WrSuspended = 12, + _WrUserRequest = 13, + _WrEventPair = 14, + _WrQueue = 15, + _WrLpcReceive = 16, + _WrLpcReply = 17, + _WrVirtualMemory = 18, + _WrPageOut = 19, + _WrRendezvous = 20, + _Spare2 = 21, + _Spare3 = 22, + _Spare4 = 23, + _Spare5 = 24, + _WrCalloutStack = 25, + _WrKernel = 26, + _WrResource = 27, + _WrPushLock = 28, + _WrMutex = 29, + _WrQuantumEnd = 30, + _WrDispatchInt = 31, + _WrPreempted = 32, + _WrYieldExecution = 33, + _WrFastMutex = 34, + _WrGuardedMutex = 35, + _WrRundown = 36, +} THREADWAITREASON; + +typedef enum +{ + size_byte = 1, + size_word = 2, + size_dword = 4, + size_qword = 8 +} MEMORY_SIZE; + +//Debugger typedefs +typedef MEMORY_SIZE VALUE_SIZE; +typedef struct SYMBOLINFO_ SYMBOLINFO; +typedef struct DBGFUNCTIONS_ DBGFUNCTIONS; + +typedef void (*CBSYMBOLENUM)(SYMBOLINFO* symbol, void* user); + +//Debugger structs +typedef struct +{ + MEMORY_BASIC_INFORMATION mbi; + char info[MAX_MODULE_SIZE]; +} MEMPAGE; + +typedef struct +{ + int count; + MEMPAGE* page; +} MEMMAP; + +typedef struct +{ + BPXTYPE type; + duint addr; + bool enabled; + bool singleshoot; + bool active; + char name[MAX_BREAKPOINT_SIZE]; + char mod[MAX_MODULE_SIZE]; + unsigned short slot; +} BRIDGEBP; + +typedef struct +{ + int count; + BRIDGEBP* bp; +} BPMAP; + +typedef struct +{ + duint start; //OUT + duint end; //OUT +} FUNCTION; + +typedef struct +{ + int depth; //IN + duint start; //OUT + duint end; //OUT +} LOOP; + +typedef struct +{ + int flags; //ADDRINFOFLAGS (IN) + char module[MAX_MODULE_SIZE]; //module the address is in + char label[MAX_LABEL_SIZE]; + char comment[MAX_COMMENT_SIZE]; + bool isbookmark; + FUNCTION function; + LOOP loop; +} ADDRINFO; + +struct SYMBOLINFO_ +{ + duint addr; + char* decoratedSymbol; + char* undecoratedSymbol; +}; + +typedef struct +{ + duint base; + char name[MAX_MODULE_SIZE]; +} SYMBOLMODULEINFO; + +typedef struct +{ + duint base; + CBSYMBOLENUM cbSymbolEnum; + void* user; +} SYMBOLCBINFO; + +typedef struct +{ + bool c; + bool p; + bool a; + bool z; + bool s; + bool t; + bool i; + bool d; + bool o; +} FLAGS; + +typedef struct +{ + bool FZ; + bool PM; + bool UM; + bool OM; + bool ZM; + bool IM; + bool DM; + bool DAZ; + bool PE; + bool UE; + bool OE; + bool ZE; + bool DE; + bool IE; + + unsigned short RC; +} MXCSRFIELDS; + +typedef struct +{ + bool B; + bool C3; + bool C2; + bool C1; + bool C0; + bool IR; + bool SF; + bool P; + bool U; + bool O; + bool Z; + bool D; + bool I; + + unsigned short TOP; + +} X87STATUSWORDFIELDS; + +typedef struct +{ + bool IC; + bool IEM; + bool PM; + bool UM; + bool OM; + bool ZM; + bool DM; + bool IM; + + unsigned short RC; + unsigned short PC; + +} X87CONTROLWORDFIELDS; + +typedef struct DECLSPEC_ALIGN(16) _XMMREGISTER +{ + ULONGLONG Low; + LONGLONG High; +} XMMREGISTER; + +typedef struct +{ + XMMREGISTER Low; //XMM/SSE part + XMMREGISTER High; //AVX part +} YMMREGISTER; + +typedef struct +{ + BYTE data[10]; + int st_value; + int tag; +} X87FPUREGISTER; + +typedef struct +{ + WORD ControlWord; + WORD StatusWord; + WORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + DWORD Cr0NpxState; +} X87FPU; + +typedef struct +{ + ULONG_PTR cax; + ULONG_PTR ccx; + ULONG_PTR cdx; + ULONG_PTR cbx; + ULONG_PTR csp; + ULONG_PTR cbp; + ULONG_PTR csi; + ULONG_PTR cdi; +#ifdef _WIN64 + ULONG_PTR r8; + ULONG_PTR r9; + ULONG_PTR r10; + ULONG_PTR r11; + ULONG_PTR r12; + ULONG_PTR r13; + ULONG_PTR r14; + ULONG_PTR r15; +#endif //_WIN64 + ULONG_PTR cip; + ULONG_PTR eflags; + unsigned short gs; + unsigned short fs; + unsigned short es; + unsigned short ds; + unsigned short cs; + unsigned short ss; + ULONG_PTR dr0; + ULONG_PTR dr1; + ULONG_PTR dr2; + ULONG_PTR dr3; + ULONG_PTR dr6; + ULONG_PTR dr7; + BYTE RegisterArea[80]; + X87FPU x87fpu; + DWORD MxCsr; +#ifdef _WIN64 + XMMREGISTER XmmRegisters[16]; + YMMREGISTER YmmRegisters[16]; +#else // x86 + XMMREGISTER XmmRegisters[8]; + YMMREGISTER YmmRegisters[8]; +#endif +} REGISTERCONTEXT; + +typedef struct +{ + DWORD code; + const char* name; +} LASTERROR; + +typedef struct +{ + REGISTERCONTEXT regcontext; + FLAGS flags; + X87FPUREGISTER x87FPURegisters[8]; + unsigned long long mmx[8]; + MXCSRFIELDS MxCsrFields; + X87STATUSWORDFIELDS x87StatusWordFields; + X87CONTROLWORDFIELDS x87ControlWordFields; + LASTERROR lastError; +} REGDUMP; + +typedef struct +{ + DISASM_ARGTYPE type; + SEGMENTREG segment; + char mnemonic[64]; + duint constant; + duint value; + duint memvalue; +} DISASM_ARG; + +typedef struct +{ + char instruction[64]; + DISASM_INSTRTYPE type; + int argcount; + int instr_size; + DISASM_ARG arg[3]; +} DISASM_INSTR; + +typedef struct +{ + char color[8]; //hex color-code + char comment[MAX_COMMENT_SIZE]; +} STACK_COMMENT; + +typedef struct +{ + int ThreadNumber; + HANDLE Handle; + DWORD ThreadId; + duint ThreadStartAddress; + duint ThreadLocalBase; + char threadName[MAX_THREAD_NAME_SIZE]; +} THREADINFO; + +typedef struct +{ + THREADINFO BasicInfo; + duint ThreadCip; + DWORD SuspendCount; + THREADPRIORITY Priority; + THREADWAITREASON WaitReason; + DWORD LastError; +} THREADALLINFO; + +typedef struct +{ + int count; + THREADALLINFO* list; + int CurrentThread; +} THREADLIST; + +typedef struct +{ + ULONG_PTR value; //displacement / addrvalue (rip-relative) + MEMORY_SIZE size; //byte/word/dword/qword + char mnemonic[MAX_MNEMONIC_SIZE]; +} MEMORY_INFO; + +typedef struct +{ + ULONG_PTR value; + VALUE_SIZE size; +} VALUE_INFO; + +typedef struct +{ + DWORD type; //value|memory|addr + VALUE_INFO value; //immediat + MEMORY_INFO memory; + ULONG_PTR addr; //addrvalue (jumps + calls) + bool branch; //jumps/calls + bool call; //instruction is a call + int size; + char instruction[MAX_MNEMONIC_SIZE * 4]; +} BASIC_INSTRUCTION_INFO; + +typedef struct +{ + SCRIPTBRANCHTYPE type; + int dest; + char branchlabel[256]; +} SCRIPTBRANCH; + +typedef struct +{ + duint addr; + duint start; + duint end; + bool manual; + int depth; +} FUNCTION_LOOP_INFO; + +//Debugger functions +BRIDGE_IMPEXP const char* DbgInit(); +BRIDGE_IMPEXP void DbgExit(); +BRIDGE_IMPEXP bool DbgMemRead(duint va, unsigned char* dest, duint size); +BRIDGE_IMPEXP bool DbgMemWrite(duint va, const unsigned char* src, duint size); +BRIDGE_IMPEXP duint DbgMemGetPageSize(duint base); +BRIDGE_IMPEXP duint DbgMemFindBaseAddr(duint addr, duint* size); +BRIDGE_IMPEXP bool DbgCmdExec(const char* cmd); +BRIDGE_IMPEXP bool DbgCmdExecDirect(const char* cmd); +BRIDGE_IMPEXP bool DbgMemMap(MEMMAP* memmap); +BRIDGE_IMPEXP bool DbgIsValidExpression(const char* expression); +BRIDGE_IMPEXP bool DbgIsDebugging(); +BRIDGE_IMPEXP bool DbgIsJumpGoingToExecute(duint addr); +BRIDGE_IMPEXP bool DbgGetLabelAt(duint addr, SEGMENTREG segment, char* text); +BRIDGE_IMPEXP bool DbgSetLabelAt(duint addr, const char* text); +BRIDGE_IMPEXP bool DbgGetCommentAt(duint addr, char* text); +BRIDGE_IMPEXP bool DbgSetCommentAt(duint addr, const char* text); +BRIDGE_IMPEXP bool DbgGetBookmarkAt(duint addr); +BRIDGE_IMPEXP bool DbgSetBookmarkAt(duint addr, bool isbookmark); +BRIDGE_IMPEXP bool DbgGetModuleAt(duint addr, char* text); +BRIDGE_IMPEXP BPXTYPE DbgGetBpxTypeAt(duint addr); +BRIDGE_IMPEXP duint DbgValFromString(const char* string); +BRIDGE_IMPEXP bool DbgGetRegDump(REGDUMP* regdump); +BRIDGE_IMPEXP bool DbgValToString(const char* string, duint value); +BRIDGE_IMPEXP bool DbgMemIsValidReadPtr(duint addr); +BRIDGE_IMPEXP int DbgGetBpList(BPXTYPE type, BPMAP* list); +BRIDGE_IMPEXP FUNCTYPE DbgGetFunctionTypeAt(duint addr); +BRIDGE_IMPEXP LOOPTYPE DbgGetLoopTypeAt(duint addr, int depth); +BRIDGE_IMPEXP duint DbgGetBranchDestination(duint addr); +BRIDGE_IMPEXP void DbgScriptLoad(const char* filename); +BRIDGE_IMPEXP void DbgScriptUnload(); +BRIDGE_IMPEXP void DbgScriptRun(int destline); +BRIDGE_IMPEXP void DbgScriptStep(); +BRIDGE_IMPEXP bool DbgScriptBpToggle(int line); +BRIDGE_IMPEXP bool DbgScriptBpGet(int line); +BRIDGE_IMPEXP bool DbgScriptCmdExec(const char* command); +BRIDGE_IMPEXP void DbgScriptAbort(); +BRIDGE_IMPEXP SCRIPTLINETYPE DbgScriptGetLineType(int line); +BRIDGE_IMPEXP void DbgScriptSetIp(int line); +BRIDGE_IMPEXP bool DbgScriptGetBranchInfo(int line, SCRIPTBRANCH* info); +BRIDGE_IMPEXP void DbgSymbolEnum(duint base, CBSYMBOLENUM cbSymbolEnum, void* user); +BRIDGE_IMPEXP bool DbgAssembleAt(duint addr, const char* instruction); +BRIDGE_IMPEXP duint DbgModBaseFromName(const char* name); +BRIDGE_IMPEXP void DbgDisasmAt(duint addr, DISASM_INSTR* instr); +BRIDGE_IMPEXP bool DbgStackCommentGet(duint addr, STACK_COMMENT* comment); +BRIDGE_IMPEXP void DbgGetThreadList(THREADLIST* list); +BRIDGE_IMPEXP void DbgSettingsUpdated(); +BRIDGE_IMPEXP void DbgDisasmFastAt(duint addr, BASIC_INSTRUCTION_INFO* basicinfo); +BRIDGE_IMPEXP void DbgMenuEntryClicked(int hEntry); +BRIDGE_IMPEXP bool DbgFunctionGet(duint addr, duint* start, duint* end); +BRIDGE_IMPEXP bool DbgFunctionOverlaps(duint start, duint end); +BRIDGE_IMPEXP bool DbgFunctionAdd(duint start, duint end); +BRIDGE_IMPEXP bool DbgFunctionDel(duint addr); +BRIDGE_IMPEXP bool DbgLoopGet(int depth, duint addr, duint* start, duint* end); +BRIDGE_IMPEXP bool DbgLoopOverlaps(int depth, duint start, duint end); +BRIDGE_IMPEXP bool DbgLoopAdd(duint start, duint end); +BRIDGE_IMPEXP bool DbgLoopDel(int depth, duint addr); +BRIDGE_IMPEXP bool DbgIsRunLocked(); +BRIDGE_IMPEXP bool DbgIsBpDisabled(duint addr); +BRIDGE_IMPEXP bool DbgSetAutoCommentAt(duint addr, const char* text); +BRIDGE_IMPEXP void DbgClearAutoCommentRange(duint start, duint end); +BRIDGE_IMPEXP bool DbgSetAutoLabelAt(duint addr, const char* text); +BRIDGE_IMPEXP void DbgClearAutoLabelRange(duint start, duint end); +BRIDGE_IMPEXP bool DbgSetAutoBookmarkAt(duint addr); +BRIDGE_IMPEXP void DbgClearAutoBookmarkRange(duint start, duint end); +BRIDGE_IMPEXP bool DbgSetAutoFunctionAt(duint start, duint end); +BRIDGE_IMPEXP void DbgClearAutoFunctionRange(duint start, duint end); +BRIDGE_IMPEXP bool DbgGetStringAt(duint addr, char* text); +BRIDGE_IMPEXP const DBGFUNCTIONS* DbgFunctions(); +BRIDGE_IMPEXP bool DbgWinEvent(MSG* message, long* result); +BRIDGE_IMPEXP bool DbgWinEventGlobal(MSG* message); +BRIDGE_IMPEXP bool DbgIsRunning(); +BRIDGE_IMPEXP duint DbgGetTimeWastedCounter(); + +//Gui defines +#define GUI_PLUGIN_MENU 0 +#define GUI_DISASM_MENU 1 +#define GUI_DUMP_MENU 2 +#define GUI_STACK_MENU 3 + +#define GUI_DISASSEMBLY 0 +#define GUI_DUMP 1 +#define GUI_STACK 2 + +#define GUI_MAX_LINE_SIZE 65536 +#define GUI_MAX_DISASSEMBLY_SIZE 2048 + +//Gui enums +typedef enum +{ + GUI_DISASSEMBLE_AT, // param1=(duint)va, param2=(duint)cip + GUI_SET_DEBUG_STATE, // param1=(DBGSTATE)state, param2=unused + GUI_ADD_MSG_TO_LOG, // param1=(const char*)msg, param2=unused + GUI_CLEAR_LOG, // param1=unused, param2=unused + GUI_UPDATE_REGISTER_VIEW, // param1=unused, param2=unused + GUI_UPDATE_DISASSEMBLY_VIEW, // param1=unused, param2=unused + GUI_UPDATE_BREAKPOINTS_VIEW, // param1=unused, param2=unused + GUI_UPDATE_WINDOW_TITLE, // param1=(const char*)file, param2=unused + GUI_GET_WINDOW_HANDLE, // param1=unused, param2=unused + GUI_DUMP_AT, // param1=(duint)va param2=unused + GUI_SCRIPT_ADD, // param1=int count, param2=const char** lines + GUI_SCRIPT_CLEAR, // param1=unused, param2=unused + GUI_SCRIPT_SETIP, // param1=int line, param2=unused + GUI_SCRIPT_ERROR, // param1=int line, param2=const char* message + GUI_SCRIPT_SETTITLE, // param1=const char* title, param2=unused + GUI_SCRIPT_SETINFOLINE, // param1=int line, param2=const char* info + GUI_SCRIPT_MESSAGE, // param1=const char* message, param2=unused + GUI_SCRIPT_MSGYN, // param1=const char* message, param2=unused + GUI_SYMBOL_LOG_ADD, // param1(const char*)msg, param2=unused + GUI_SYMBOL_LOG_CLEAR, // param1=unused, param2=unused + GUI_SYMBOL_SET_PROGRESS, // param1=int percent param2=unused + GUI_SYMBOL_UPDATE_MODULE_LIST, // param1=int count, param2=SYMBOLMODULEINFO* modules + GUI_REF_ADDCOLUMN, // param1=int width, param2=(const char*)title + GUI_REF_SETROWCOUNT, // param1=int rows, param2=unused + GUI_REF_GETROWCOUNT, // param1=unused, param2=unused + GUI_REF_DELETEALLCOLUMNS, // param1=unused, param2=unused + GUI_REF_SETCELLCONTENT, // param1=(CELLINFO*)info, param2=unused + GUI_REF_GETCELLCONTENT, // param1=int row, param2=int col + GUI_REF_RELOADDATA, // param1=unused, param2=unused + GUI_REF_SETSINGLESELECTION, // param1=int index, param2=bool scroll + GUI_REF_SETPROGRESS, // param1=int progress, param2=unused + GUI_REF_SETSEARCHSTARTCOL, // param1=int col param2=unused + GUI_STACK_DUMP_AT, // param1=duint addr, param2=duint csp + GUI_UPDATE_DUMP_VIEW, // param1=unused, param2=unused + GUI_UPDATE_THREAD_VIEW, // param1=unused, param2=unused + GUI_ADD_RECENT_FILE, // param1=(const char*)file, param2=unused + GUI_SET_LAST_EXCEPTION, // param1=unsigned int code, param2=unused + GUI_GET_DISASSEMBLY, // param1=duint addr, param2=char* text + GUI_MENU_ADD, // param1=int hMenu, param2=const char* title + GUI_MENU_ADD_ENTRY, // param1=int hMenu, param2=const char* title + GUI_MENU_ADD_SEPARATOR, // param1=int hMenu, param2=unused + GUI_MENU_CLEAR, // param1=int hMenu, param2=unused + GUI_SELECTION_GET, // param1=int hWindow, param2=SELECTIONDATA* selection + GUI_SELECTION_SET, // param1=int hWindow, param2=const SELECTIONDATA* selection + GUI_GETLINE_WINDOW, // param1=const char* title, param2=char* text + GUI_AUTOCOMPLETE_ADDCMD, // param1=const char* cmd, param2=ununsed + GUI_AUTOCOMPLETE_DELCMD, // param1=const char* cmd, param2=ununsed + GUI_AUTOCOMPLETE_CLEARALL, // param1=unused, param2=unused + GUI_SCRIPT_ENABLEHIGHLIGHTING, // param1=bool enable, param2=unused + GUI_ADD_MSG_TO_STATUSBAR, // param1=const char* msg, param2=unused + GUI_UPDATE_SIDEBAR, // param1=unused, param2=unused + GUI_REPAINT_TABLE_VIEW, // param1=unused, param2=unused + GUI_UPDATE_PATCHES, // param1=unused, param2=unused + GUI_UPDATE_CALLSTACK, // param1=unused, param2=unused + GUI_SYMBOL_REFRESH_CURRENT, // param1=unused, param2=unused + GUI_UPDATE_MEMORY_VIEW, // param1=unused, param2=unused + GUI_REF_INITIALIZE, // param1=const char* name, param2=unused + GUI_LOAD_SOURCE_FILE, // param1=const char* path, param2=line + GUI_MENU_SET_ICON, // param1=int hMenu, param2=ICONINFO* + GUI_MENU_SET_ENTRY_ICON, // param1=int hEntry, param2=ICONINFO* + GUI_SHOW_CPU, // param1=unused, param2=unused + GUI_ADD_QWIDGET_TAB, // param1=QWidget*, param2=unused + GUI_SHOW_QWIDGET_TAB, // param1=QWidget*, param2=unused + GUI_CLOSE_QWIDGET_TAB, // param1=QWidget*, param2=unused + GUI_EXECUTE_ON_GUI_THREAD, // param1=GUICALLBACK, param2=unused + GUI_UPDATE_TIME_WASTED_COUNTER, // param1=unused, param2=unused + GUI_SET_GLOBAL_NOTES, // param1=const char* text, param2=unused + GUI_GET_GLOBAL_NOTES, // param1=char** text, param2=unused + GUI_SET_DEBUGGEE_NOTES, // param1=const char* text, param2=unused + GUI_GET_DEBUGGEE_NOTES // param1=char** text, param2=unused +} GUIMSG; + +//GUI Typedefs +typedef void (*GUICALLBACK)(); + +//GUI structures +typedef struct +{ + int row; + int col; + const char* str; +} CELLINFO; + +typedef struct +{ + duint start; + duint end; + duint view; +} SELECTIONDATA; + +typedef struct +{ + const void* data; + duint size; +} ICONDATA; + +//GUI functions +BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip); +BRIDGE_IMPEXP void GuiSetDebugState(DBGSTATE state); +BRIDGE_IMPEXP void GuiAddLogMessage(const char* msg); +BRIDGE_IMPEXP void GuiLogClear(); +BRIDGE_IMPEXP void GuiUpdateAllViews(); +BRIDGE_IMPEXP void GuiUpdateRegisterView(); +BRIDGE_IMPEXP void GuiUpdateDisassemblyView(); +BRIDGE_IMPEXP void GuiUpdateBreakpointsView(); +BRIDGE_IMPEXP void GuiUpdateWindowTitle(const char* filename); +BRIDGE_IMPEXP HWND GuiGetWindowHandle(); +BRIDGE_IMPEXP void GuiDumpAt(duint va); +BRIDGE_IMPEXP void GuiScriptAdd(int count, const char** lines); +BRIDGE_IMPEXP void GuiScriptClear(); +BRIDGE_IMPEXP void GuiScriptSetIp(int line); +BRIDGE_IMPEXP void GuiScriptError(int line, const char* message); +BRIDGE_IMPEXP void GuiScriptSetTitle(const char* title); +BRIDGE_IMPEXP void GuiScriptSetInfoLine(int line, const char* info); +BRIDGE_IMPEXP void GuiScriptMessage(const char* message); +BRIDGE_IMPEXP int GuiScriptMsgyn(const char* message); +BRIDGE_IMPEXP void GuiScriptEnableHighlighting(bool enable); +BRIDGE_IMPEXP void GuiSymbolLogAdd(const char* message); +BRIDGE_IMPEXP void GuiSymbolLogClear(); +BRIDGE_IMPEXP void GuiSymbolSetProgress(int percent); +BRIDGE_IMPEXP void GuiSymbolUpdateModuleList(int count, SYMBOLMODULEINFO* modules); +BRIDGE_IMPEXP void GuiSymbolRefreshCurrent(); +BRIDGE_IMPEXP void GuiReferenceAddColumn(int width, const char* title); +BRIDGE_IMPEXP void GuiReferenceSetRowCount(int count); +BRIDGE_IMPEXP int GuiReferenceGetRowCount(); +BRIDGE_IMPEXP void GuiReferenceDeleteAllColumns(); +BRIDGE_IMPEXP void GuiReferenceInitialize(const char* name); +BRIDGE_IMPEXP void GuiReferenceSetCellContent(int row, int col, const char* str); +BRIDGE_IMPEXP const char* GuiReferenceGetCellContent(int row, int col); +BRIDGE_IMPEXP void GuiReferenceReloadData(); +BRIDGE_IMPEXP void GuiReferenceSetSingleSelection(int index, bool scroll); +BRIDGE_IMPEXP void GuiReferenceSetProgress(int progress); +BRIDGE_IMPEXP void GuiReferenceSetSearchStartCol(int col); +BRIDGE_IMPEXP void GuiStackDumpAt(duint addr, duint csp); +BRIDGE_IMPEXP void GuiUpdateDumpView(); +BRIDGE_IMPEXP void GuiUpdateThreadView(); +BRIDGE_IMPEXP void GuiUpdateMemoryView(); +BRIDGE_IMPEXP void GuiAddRecentFile(const char* file); +BRIDGE_IMPEXP void GuiSetLastException(unsigned int exception); +BRIDGE_IMPEXP bool GuiGetDisassembly(duint addr, char* text); +BRIDGE_IMPEXP int GuiMenuAdd(int hMenu, const char* title); +BRIDGE_IMPEXP int GuiMenuAddEntry(int hMenu, const char* title); +BRIDGE_IMPEXP void GuiMenuAddSeparator(int hMenu); +BRIDGE_IMPEXP void GuiMenuClear(int hMenu); +BRIDGE_IMPEXP bool GuiSelectionGet(int hWindow, SELECTIONDATA* selection); +BRIDGE_IMPEXP bool GuiSelectionSet(int hWindow, const SELECTIONDATA* selection); +BRIDGE_IMPEXP bool GuiGetLineWindow(const char* title, char* text); +BRIDGE_IMPEXP void GuiAutoCompleteAddCmd(const char* cmd); +BRIDGE_IMPEXP void GuiAutoCompleteDelCmd(const char* cmd); +BRIDGE_IMPEXP void GuiAutoCompleteClearAll(); +BRIDGE_IMPEXP void GuiAddStatusBarMessage(const char* msg); +BRIDGE_IMPEXP void GuiUpdateSideBar(); +BRIDGE_IMPEXP void GuiRepaintTableView(); +BRIDGE_IMPEXP void GuiUpdatePatches(); +BRIDGE_IMPEXP void GuiUpdateCallStack(); +BRIDGE_IMPEXP void GuiLoadSourceFile(const char* path, int line); +BRIDGE_IMPEXP void GuiMenuSetIcon(int hMenu, const ICONDATA* icon); +BRIDGE_IMPEXP void GuiMenuSetEntryIcon(int hEntry, const ICONDATA* icon); +BRIDGE_IMPEXP void GuiShowCpu(); +BRIDGE_IMPEXP void GuiAddQWidgetTab(void* qWidget); +BRIDGE_IMPEXP void GuiShowQWidgetTab(void* qWidget); +BRIDGE_IMPEXP void GuiCloseQWidgetTab(void* qWidget); +BRIDGE_IMPEXP void GuiExecuteOnGuiThread(GUICALLBACK cbGuiThread); +BRIDGE_IMPEXP void GuiUpdateTimeWastedCounter(); +BRIDGE_IMPEXP void GuiSetGlobalNotes(const char* text); +BRIDGE_IMPEXP void GuiGetGlobalNotes(char** text); +BRIDGE_IMPEXP void GuiSetDebuggeeNotes(const char* text); +BRIDGE_IMPEXP void GuiGetDebuggeeNotes(char** text); + +#ifdef __cplusplus +} +#endif + +#pragma pack(pop) + +#endif // _BRIDGEMAIN_H_ diff --git a/src/bridge/x64_dbg_bridge.vcxproj b/src/bridge/x64_dbg_bridge.vcxproj index a3bcdd6f..de464c90 100644 --- a/src/bridge/x64_dbg_bridge.vcxproj +++ b/src/bridge/x64_dbg_bridge.vcxproj @@ -1,157 +1,157 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - {944D9923-CB1A-6F6C-BCBC-9E00A71954C1} - Win32Proj - - - - DynamicLibrary - false - v120_xp - - - DynamicLibrary - false - v120_xp - - - DynamicLibrary - false - v120_xp - - - DynamicLibrary - false - v120_xp - - - - - - - - - - - - - - - - - - - false - $(ProjectDir)..\..\bin\x32\ - $(Platform)\$(Configuration)\ - x32bridge - - - false - $(ProjectDir)..\..\bin\x32\ - $(Platform)\$(Configuration)\ - x32bridge - - - false - $(ProjectDir)..\..\bin\x64\ - x64bridge - - - false - $(ProjectDir)..\..\bin\x64\ - x64bridge - - - - BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDLL - Level3 - ProgramDatabase - MaxSpeed - - - MachineX86 - true - Windows - true - true - - - - - BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level3 - ProgramDatabase - MaxSpeed - - - MachineX86 - true - Windows - true - true - - - - - BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDLL - Level3 - ProgramDatabase - - - true - Windows - true - true - - - - - BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level3 - ProgramDatabase - - - true - Windows - true - true - - - - - + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + {944D9923-CB1A-6F6C-BCBC-9E00A71954C1} + Win32Proj + + + + DynamicLibrary + false + v120_xp + + + DynamicLibrary + false + v120_xp + + + DynamicLibrary + false + v120_xp + + + DynamicLibrary + false + v120_xp + + + + + + + + + + + + + + + + + + + false + $(ProjectDir)..\..\bin\x32\ + $(Platform)\$(Configuration)\ + x32bridge + + + false + $(ProjectDir)..\..\bin\x32\ + $(Platform)\$(Configuration)\ + x32bridge + + + false + $(ProjectDir)..\..\bin\x64\ + x64bridge + + + false + $(ProjectDir)..\..\bin\x64\ + x64bridge + + + + BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + MaxSpeed + + + MachineX86 + true + Windows + true + true + + + + + BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + MaxSpeed + + + MachineX86 + true + Windows + true + true + + + + + BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + true + Windows + true + true + + + + + BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + + + true + Windows + true + true + + + + + \ No newline at end of file diff --git a/src/capstone_wrapper/capstone_wrapper.cpp b/src/capstone_wrapper/capstone_wrapper.cpp index edca8ebc..2777d913 100644 --- a/src/capstone_wrapper/capstone_wrapper.cpp +++ b/src/capstone_wrapper/capstone_wrapper.cpp @@ -1,301 +1,301 @@ -#include "capstone_wrapper.h" -#include - -csh Capstone::mHandle = 0; - -void Capstone::GlobalInitialize() -{ -#ifdef _WIN64 - cs_open(CS_ARCH_X86, CS_MODE_64, &mHandle); -#else //x86 - cs_open(CS_ARCH_X86, CS_MODE_32, &mHandle); -#endif //_WIN64 - cs_option(mHandle, CS_OPT_DETAIL, CS_OPT_ON); -} - -void Capstone::GlobalFinalize() -{ - if(mHandle) //close handle - cs_close(&mHandle); -} - -Capstone::Capstone() -{ - mInstr = nullptr; - mSuccess = false; -} - -Capstone::~Capstone() -{ - if(mInstr) //free last disassembled instruction - cs_free(mInstr, 1); -} - -bool Capstone::Disassemble(size_t addr, const unsigned char data[MAX_DISASM_BUFFER]) -{ - return Disassemble(addr, data, MAX_DISASM_BUFFER); -} - -bool Capstone::Disassemble(size_t addr, const unsigned char* data, int size) -{ - if(!data) - return false; - if(mInstr) //free last disassembled instruction - { - cs_free(mInstr, 1); - mInstr = nullptr; - } - return mSuccess = !!cs_disasm(mHandle, data, size, addr, 1, &mInstr); -} - -const cs_insn* Capstone::GetInstr() const -{ - if(!Success()) - return nullptr; - return mInstr; -} - -bool Capstone::Success() const -{ - return mSuccess; -} - -const char* Capstone::RegName(x86_reg reg) const -{ - return cs_reg_name(mHandle, reg); -} - -bool Capstone::InGroup(cs_group_type group) const -{ - if(!Success()) - return false; - return cs_insn_group(mHandle, mInstr, group); -} - -std::string Capstone::OperandText(int opindex) const -{ - if(!Success() || opindex >= mInstr->detail->x86.op_count) - return ""; - const auto & op = mInstr->detail->x86.operands[opindex]; - std::string result; - char temp[32] = ""; - switch(op.type) - { - case X86_OP_REG: - { - result = RegName(x86_reg(op.reg)); - } - break; - - case X86_OP_IMM: - { - sprintf_s(temp, "%llX", op.imm); - result = temp; - } - break; - - case X86_OP_MEM: - { - const auto & mem = op.mem; - if(op.mem.base == X86_REG_RIP) //rip-relative - { - sprintf_s(temp, "%llX", Address() + op.mem.disp + Size()); - result += temp; - } - else //normal - { - bool prependPlus = false; - if(mem.base) - { - result += RegName(x86_reg(mem.base)); - prependPlus = true; - } - if(mem.index) - { - if(prependPlus) - result += "+"; - result += RegName(x86_reg(mem.index)); - sprintf_s(temp, "*%X", mem.scale); - result += temp; - prependPlus = true; - } - if(mem.disp) - { - char operatorText = '+'; - if(mem.disp < 0) - { - operatorText = '-'; - sprintf_s(temp, "%llX", mem.disp * -1); - } - else - sprintf_s(temp, "%llX", mem.disp); - if(prependPlus) - result += operatorText; - result += temp; - } - } - } - break; - - case X86_OP_FP: - case X86_OP_INVALID: - { - } - break; - } - return result; -} - -int Capstone::Size() const -{ - if(!Success()) - return 1; - return GetInstr()->size; -} - -size_t Capstone::Address() const -{ - if(!Success()) - return 0; - return size_t(GetInstr()->address); -} - -const cs_x86 & Capstone::x86() const -{ - if(!Success()) - DebugBreak(); - return GetInstr()->detail->x86; -} - -bool Capstone::IsFilling() const -{ - if(!Success()) - return false; - switch(GetId()) - { - case X86_INS_NOP: - case X86_INS_INT3: - return true; - default: - return false; - } -} - -bool Capstone::IsLoop() const -{ - if(!Success()) - return false; - switch(GetId()) - { - case X86_INS_LOOP: - case X86_INS_LOOPE: - case X86_INS_LOOPNE: - return true; - default: - return false; - } -} - -x86_insn Capstone::GetId() const -{ - if(!Success()) - DebugBreak(); - return x86_insn(mInstr->id); -} - -std::string Capstone::InstructionText() const -{ - if(!Success()) - return "???"; - std::string result = Mnemonic(); - if(OpCount()) - { - result += " "; - result += mInstr->op_str; - } - return result; -} - -int Capstone::OpCount() const -{ - if(!Success()) - return 0; - return x86().op_count; -} - -cs_x86_op Capstone::operator[](int index) const -{ - if(!Success() || index >= OpCount()) - DebugBreak(); - return x86().operands[index]; -} - -bool Capstone::IsNop() const -{ - return GetId() == X86_INS_NOP; -} - -bool Capstone::IsInt3() const -{ - if(!Success()) - return false; - switch(GetId()) - { - case X86_INS_INT3: - return true; - case X86_INS_INT: - { - cs_x86_op op = x86().operands[0]; - return op.type == X86_OP_IMM && op.imm == 3; - } - default: - return false; - } -} - -std::string Capstone::Mnemonic() const -{ - if(!Success()) - return "???"; - return mInstr->mnemonic; -} - -const char* Capstone::MemSizeName(int size) const -{ - switch(size) - { - case 1: - return "byte"; - case 2: - return "word"; - case 4: - return "dword"; - case 6: - return "fword"; - case 8: - return "qword"; - case 10: - return "tword"; - case 16: - return "dqword"; - case 32: - return "yword"; - case 64: - return "zword"; - default: - return nullptr; - } -} - -size_t Capstone::BranchDestination() const -{ - if(!Success()) - return 0; - if(InGroup(CS_GRP_JUMP) || InGroup(CS_GRP_CALL) || IsLoop()) - { - const auto & op = x86().operands[0]; - if(op.type == CS_OP_IMM) - return size_t(op.imm); - } - return 0; +#include "capstone_wrapper.h" +#include + +csh Capstone::mHandle = 0; + +void Capstone::GlobalInitialize() +{ +#ifdef _WIN64 + cs_open(CS_ARCH_X86, CS_MODE_64, &mHandle); +#else //x86 + cs_open(CS_ARCH_X86, CS_MODE_32, &mHandle); +#endif //_WIN64 + cs_option(mHandle, CS_OPT_DETAIL, CS_OPT_ON); +} + +void Capstone::GlobalFinalize() +{ + if(mHandle) //close handle + cs_close(&mHandle); +} + +Capstone::Capstone() +{ + mInstr = nullptr; + mSuccess = false; +} + +Capstone::~Capstone() +{ + if(mInstr) //free last disassembled instruction + cs_free(mInstr, 1); +} + +bool Capstone::Disassemble(size_t addr, const unsigned char data[MAX_DISASM_BUFFER]) +{ + return Disassemble(addr, data, MAX_DISASM_BUFFER); +} + +bool Capstone::Disassemble(size_t addr, const unsigned char* data, int size) +{ + if(!data) + return false; + if(mInstr) //free last disassembled instruction + { + cs_free(mInstr, 1); + mInstr = nullptr; + } + return mSuccess = !!cs_disasm(mHandle, data, size, addr, 1, &mInstr); +} + +const cs_insn* Capstone::GetInstr() const +{ + if(!Success()) + return nullptr; + return mInstr; +} + +bool Capstone::Success() const +{ + return mSuccess; +} + +const char* Capstone::RegName(x86_reg reg) const +{ + return cs_reg_name(mHandle, reg); +} + +bool Capstone::InGroup(cs_group_type group) const +{ + if(!Success()) + return false; + return cs_insn_group(mHandle, mInstr, group); +} + +std::string Capstone::OperandText(int opindex) const +{ + if(!Success() || opindex >= mInstr->detail->x86.op_count) + return ""; + const auto & op = mInstr->detail->x86.operands[opindex]; + std::string result; + char temp[32] = ""; + switch(op.type) + { + case X86_OP_REG: + { + result = RegName(x86_reg(op.reg)); + } + break; + + case X86_OP_IMM: + { + sprintf_s(temp, "%llX", op.imm); + result = temp; + } + break; + + case X86_OP_MEM: + { + const auto & mem = op.mem; + if(op.mem.base == X86_REG_RIP) //rip-relative + { + sprintf_s(temp, "%llX", Address() + op.mem.disp + Size()); + result += temp; + } + else //normal + { + bool prependPlus = false; + if(mem.base) + { + result += RegName(x86_reg(mem.base)); + prependPlus = true; + } + if(mem.index) + { + if(prependPlus) + result += "+"; + result += RegName(x86_reg(mem.index)); + sprintf_s(temp, "*%X", mem.scale); + result += temp; + prependPlus = true; + } + if(mem.disp) + { + char operatorText = '+'; + if(mem.disp < 0) + { + operatorText = '-'; + sprintf_s(temp, "%llX", mem.disp * -1); + } + else + sprintf_s(temp, "%llX", mem.disp); + if(prependPlus) + result += operatorText; + result += temp; + } + } + } + break; + + case X86_OP_FP: + case X86_OP_INVALID: + { + } + break; + } + return result; +} + +int Capstone::Size() const +{ + if(!Success()) + return 1; + return GetInstr()->size; +} + +size_t Capstone::Address() const +{ + if(!Success()) + return 0; + return size_t(GetInstr()->address); +} + +const cs_x86 & Capstone::x86() const +{ + if(!Success()) + DebugBreak(); + return GetInstr()->detail->x86; +} + +bool Capstone::IsFilling() const +{ + if(!Success()) + return false; + switch(GetId()) + { + case X86_INS_NOP: + case X86_INS_INT3: + return true; + default: + return false; + } +} + +bool Capstone::IsLoop() const +{ + if(!Success()) + return false; + switch(GetId()) + { + case X86_INS_LOOP: + case X86_INS_LOOPE: + case X86_INS_LOOPNE: + return true; + default: + return false; + } +} + +x86_insn Capstone::GetId() const +{ + if(!Success()) + DebugBreak(); + return x86_insn(mInstr->id); +} + +std::string Capstone::InstructionText() const +{ + if(!Success()) + return "???"; + std::string result = Mnemonic(); + if(OpCount()) + { + result += " "; + result += mInstr->op_str; + } + return result; +} + +int Capstone::OpCount() const +{ + if(!Success()) + return 0; + return x86().op_count; +} + +cs_x86_op Capstone::operator[](int index) const +{ + if(!Success() || index >= OpCount()) + DebugBreak(); + return x86().operands[index]; +} + +bool Capstone::IsNop() const +{ + return GetId() == X86_INS_NOP; +} + +bool Capstone::IsInt3() const +{ + if(!Success()) + return false; + switch(GetId()) + { + case X86_INS_INT3: + return true; + case X86_INS_INT: + { + cs_x86_op op = x86().operands[0]; + return op.type == X86_OP_IMM && op.imm == 3; + } + default: + return false; + } +} + +std::string Capstone::Mnemonic() const +{ + if(!Success()) + return "???"; + return mInstr->mnemonic; +} + +const char* Capstone::MemSizeName(int size) const +{ + switch(size) + { + case 1: + return "byte"; + case 2: + return "word"; + case 4: + return "dword"; + case 6: + return "fword"; + case 8: + return "qword"; + case 10: + return "tword"; + case 16: + return "dqword"; + case 32: + return "yword"; + case 64: + return "zword"; + default: + return nullptr; + } +} + +size_t Capstone::BranchDestination() const +{ + if(!Success()) + return 0; + if(InGroup(CS_GRP_JUMP) || InGroup(CS_GRP_CALL) || IsLoop()) + { + const auto & op = x86().operands[0]; + if(op.type == CS_OP_IMM) + return size_t(op.imm); + } + return 0; } \ No newline at end of file diff --git a/src/capstone_wrapper/capstone_wrapper.h b/src/capstone_wrapper/capstone_wrapper.h index 81c0731a..64c78b0b 100644 --- a/src/capstone_wrapper/capstone_wrapper.h +++ b/src/capstone_wrapper/capstone_wrapper.h @@ -1,44 +1,44 @@ -#ifndef _CAPSTONE_WRAPPER_H -#define _CAPSTONE_WRAPPER_H - -#include "../dbg/capstone/capstone.h" -#include - -#define MAX_DISASM_BUFFER 16 - -class Capstone -{ -public: - static void GlobalInitialize(); - static void GlobalFinalize(); - Capstone(); - ~Capstone(); - bool Disassemble(size_t addr, const unsigned char data[MAX_DISASM_BUFFER]); - bool Disassemble(size_t addr, const unsigned char* data, int size); - const cs_insn* GetInstr() const; - bool Success() const; - const char* RegName(x86_reg reg) const; - bool InGroup(cs_group_type group) const; - std::string OperandText(int opindex) const; - int Size() const; - size_t Address() const; - const cs_x86 & x86() const; - bool IsFilling() const; - bool IsLoop() const; - x86_insn GetId() const; - std::string InstructionText() const; - int OpCount() const; - cs_x86_op operator[](int index) const; - bool IsNop() const; - bool IsInt3() const; - std::string Mnemonic() const; - const char* MemSizeName(int size) const; - size_t BranchDestination() const; - -private: - static csh mHandle; - cs_insn* mInstr; - bool mSuccess; -}; - +#ifndef _CAPSTONE_WRAPPER_H +#define _CAPSTONE_WRAPPER_H + +#include "../dbg/capstone/capstone.h" +#include + +#define MAX_DISASM_BUFFER 16 + +class Capstone +{ +public: + static void GlobalInitialize(); + static void GlobalFinalize(); + Capstone(); + ~Capstone(); + bool Disassemble(size_t addr, const unsigned char data[MAX_DISASM_BUFFER]); + bool Disassemble(size_t addr, const unsigned char* data, int size); + const cs_insn* GetInstr() const; + bool Success() const; + const char* RegName(x86_reg reg) const; + bool InGroup(cs_group_type group) const; + std::string OperandText(int opindex) const; + int Size() const; + size_t Address() const; + const cs_x86 & x86() const; + bool IsFilling() const; + bool IsLoop() const; + x86_insn GetId() const; + std::string InstructionText() const; + int OpCount() const; + cs_x86_op operator[](int index) const; + bool IsNop() const; + bool IsInt3() const; + std::string Mnemonic() const; + const char* MemSizeName(int size) const; + size_t BranchDestination() const; + +private: + static csh mHandle; + cs_insn* mInstr; + bool mSuccess; +}; + #endif //_CAPSTONE_WRAPPER_H \ No newline at end of file diff --git a/src/dbg/AnalysisPass.cpp b/src/dbg/AnalysisPass.cpp index 53126874..13fc0fb1 100644 --- a/src/dbg/AnalysisPass.cpp +++ b/src/dbg/AnalysisPass.cpp @@ -1,95 +1,95 @@ -#include -#include -#include "AnalysisPass.h" -#include "memory.h" - -AnalysisPass::AnalysisPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks) : m_MainBlocks(MainBlocks) -{ - assert(VirtualEnd > VirtualStart); - - // Internal class data - m_VirtualStart = VirtualStart; - m_VirtualEnd = VirtualEnd; - m_InternalMaxThreads = 0; - - // Read remote instruction data to local memory - m_DataSize = VirtualEnd - VirtualStart; - m_Data = (unsigned char*)emalloc(m_DataSize, "AnalysisPass:m_Data"); - - if(!MemRead(VirtualStart, m_Data, m_DataSize)) - { - BridgeFree(m_Data); - assert(false); - } -} - -AnalysisPass::~AnalysisPass() -{ - if(m_Data) - efree(m_Data); -} - -BasicBlock* AnalysisPass::FindBBlockInRange(duint Address) -{ - // NOTE: __MUST__ BE A SORTED VECTOR - // - // Use a binary search - duint indexLo = 0; - duint indexHi = m_MainBlocks.size(); - - // Get a pointer to pure data - const auto blocks = m_MainBlocks.data(); - - while(indexHi > indexLo) - { - duint indexMid = (indexLo + indexHi) / 2; - auto entry = &blocks[indexMid]; - - if(Address < entry->VirtualStart) - { - // Continue search in lower half - indexHi = indexMid; - } - else if(Address >= entry->VirtualEnd) - { - // Continue search in upper half - indexLo = indexMid + 1; - } - else - { - // Address is within limits, return entry - return entry; - } - } - - // Not found - return nullptr; -} - -duint AnalysisPass::FindBBlockIndex(BasicBlock* Block) -{ - // Fast pointer arithmetic to find index - return ((duint)Block - (duint)m_MainBlocks.data()) / sizeof(BasicBlock); -} - -duint AnalysisPass::IdealThreadCount() -{ - if(m_InternalMaxThreads == 0) - { - // Determine the maximum hardware thread count at once - duint maximumThreads = max(std::thread::hardware_concurrency(), 1); - - // Don't consume 100% of the CPU, adjust accordingly - if(maximumThreads > 1) - maximumThreads -= 1; - - SetIdealThreadCount(maximumThreads); - } - - return m_InternalMaxThreads; -} - -void AnalysisPass::SetIdealThreadCount(duint Count) -{ - m_InternalMaxThreads = (BYTE)min(Count, 255); +#include +#include +#include "AnalysisPass.h" +#include "memory.h" + +AnalysisPass::AnalysisPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks) : m_MainBlocks(MainBlocks) +{ + assert(VirtualEnd > VirtualStart); + + // Internal class data + m_VirtualStart = VirtualStart; + m_VirtualEnd = VirtualEnd; + m_InternalMaxThreads = 0; + + // Read remote instruction data to local memory + m_DataSize = VirtualEnd - VirtualStart; + m_Data = (unsigned char*)emalloc(m_DataSize, "AnalysisPass:m_Data"); + + if(!MemRead(VirtualStart, m_Data, m_DataSize)) + { + BridgeFree(m_Data); + assert(false); + } +} + +AnalysisPass::~AnalysisPass() +{ + if(m_Data) + efree(m_Data); +} + +BasicBlock* AnalysisPass::FindBBlockInRange(duint Address) +{ + // NOTE: __MUST__ BE A SORTED VECTOR + // + // Use a binary search + duint indexLo = 0; + duint indexHi = m_MainBlocks.size(); + + // Get a pointer to pure data + const auto blocks = m_MainBlocks.data(); + + while(indexHi > indexLo) + { + duint indexMid = (indexLo + indexHi) / 2; + auto entry = &blocks[indexMid]; + + if(Address < entry->VirtualStart) + { + // Continue search in lower half + indexHi = indexMid; + } + else if(Address >= entry->VirtualEnd) + { + // Continue search in upper half + indexLo = indexMid + 1; + } + else + { + // Address is within limits, return entry + return entry; + } + } + + // Not found + return nullptr; +} + +duint AnalysisPass::FindBBlockIndex(BasicBlock* Block) +{ + // Fast pointer arithmetic to find index + return ((duint)Block - (duint)m_MainBlocks.data()) / sizeof(BasicBlock); +} + +duint AnalysisPass::IdealThreadCount() +{ + if(m_InternalMaxThreads == 0) + { + // Determine the maximum hardware thread count at once + duint maximumThreads = max(std::thread::hardware_concurrency(), 1); + + // Don't consume 100% of the CPU, adjust accordingly + if(maximumThreads > 1) + maximumThreads -= 1; + + SetIdealThreadCount(maximumThreads); + } + + return m_InternalMaxThreads; +} + +void AnalysisPass::SetIdealThreadCount(duint Count) +{ + m_InternalMaxThreads = (BYTE)min(Count, 255); } \ No newline at end of file diff --git a/src/dbg/AnalysisPass.h b/src/dbg/AnalysisPass.h index 8a0f8f30..141a9b66 100644 --- a/src/dbg/AnalysisPass.h +++ b/src/dbg/AnalysisPass.h @@ -1,41 +1,41 @@ -#pragma once - -#include "_global.h" -#include "BasicBlock.h" - -class AnalysisPass -{ -public: - AnalysisPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks); - virtual ~AnalysisPass(); - - virtual const char* GetName() = 0; - virtual bool Analyse() = 0; - -protected: - duint m_VirtualStart; - duint m_VirtualEnd; - duint m_DataSize; - unsigned char* m_Data; - BBlockArray & m_MainBlocks; - - inline unsigned char* AnalysisPass::TranslateAddress(duint Address) - { - assert(ValidateAddress(Address)); - - return &m_Data[Address - m_VirtualStart]; - } - - inline bool AnalysisPass::ValidateAddress(duint Address) - { - return (Address >= m_VirtualStart && Address < m_VirtualEnd); - } - - BasicBlock* FindBBlockInRange(duint Address); - duint FindBBlockIndex(BasicBlock* Block); - duint IdealThreadCount(); - void SetIdealThreadCount(duint Count); - -private: - BYTE m_InternalMaxThreads; +#pragma once + +#include "_global.h" +#include "BasicBlock.h" + +class AnalysisPass +{ +public: + AnalysisPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks); + virtual ~AnalysisPass(); + + virtual const char* GetName() = 0; + virtual bool Analyse() = 0; + +protected: + duint m_VirtualStart; + duint m_VirtualEnd; + duint m_DataSize; + unsigned char* m_Data; + BBlockArray & m_MainBlocks; + + inline unsigned char* AnalysisPass::TranslateAddress(duint Address) + { + assert(ValidateAddress(Address)); + + return &m_Data[Address - m_VirtualStart]; + } + + inline bool AnalysisPass::ValidateAddress(duint Address) + { + return (Address >= m_VirtualStart && Address < m_VirtualEnd); + } + + BasicBlock* FindBBlockInRange(duint Address); + duint FindBBlockIndex(BasicBlock* Block); + duint IdealThreadCount(); + void SetIdealThreadCount(duint Count); + +private: + BYTE m_InternalMaxThreads; }; \ No newline at end of file diff --git a/src/dbg/BasicBlock.h b/src/dbg/BasicBlock.h index 8257da45..7473b3ec 100644 --- a/src/dbg/BasicBlock.h +++ b/src/dbg/BasicBlock.h @@ -1,80 +1,80 @@ -#pragma once - -#include "_global.h" - -enum BasicBlockFlags : duint -{ - BASIC_BLOCK_FLAG_NONE = 0, // No flag - - BASIC_BLOCK_FLAG_FUNCTION = (1 << 1), // Scanned; also part of a known function - BASIC_BLOCK_FLAG_ORPHANED = (1 << 2), // No targets ever reach this block - BASIC_BLOCK_FLAG_CUTOFF = (1 << 3), // Ends prematurely because of another JMP to location - BASIC_BLOCK_FLAG_DELETE = (1 << 4), // Delete element at the next possible time - - BASIC_BLOCK_FLAG_CALL = (1 << 5), // The block ends with a call - BASIC_BLOCK_FLAG_RET = (1 << 6), // The block ends with a retn - BASIC_BLOCK_FLAG_ABSJMP = (1 << 7), // Branch is absolute - BASIC_BLOCK_FLAG_INDIRECT = (1 << 8), // This block ends with an indirect branch - BASIC_BLOCK_FLAG_INDIRPTR = (1 << 9), // This block ends with an indirect branch; pointer known - - BASIC_BLOCK_FLAG_PREPAD = (1 << 10), // Block ends because there was padding afterwards - BASIC_BLOCK_FLAG_PAD = (1 << 11), // Block is only a series of padding instructions -}; - -struct BasicBlock -{ - duint VirtualStart; // Inclusive - duint VirtualEnd; // Exclusive - duint Flags; - duint Target; - - __forceinline bool GetFlag(duint Flag) - { - return (Flags & Flag) == Flag; - } - - __forceinline void SetFlag(duint Flag) - { - Flags |= Flag; - } - - __forceinline duint Size() - { - return VirtualEnd - VirtualStart; - } - - bool operator< (const BasicBlock & b) const - { - return VirtualStart < b.VirtualStart; - } - - bool operator== (const BasicBlock & b) const - { - return VirtualStart == b.VirtualStart; - } -}; - -struct FunctionDef -{ - duint VirtualStart; // Inclusive - duint VirtualEnd; // Exclusive - - duint BBlockStart; // Index of first basic block - duint BBlockEnd; // Index of last basic block - - bool operator< (const FunctionDef & b) const - { - if(VirtualStart == b.VirtualStart) - return VirtualEnd > b.VirtualEnd; - - return VirtualStart < b.VirtualStart; - } - - bool operator== (const FunctionDef & b) const - { - return VirtualStart == b.VirtualStart; - } -}; - -typedef std::vector BBlockArray; +#pragma once + +#include "_global.h" + +enum BasicBlockFlags : duint +{ + BASIC_BLOCK_FLAG_NONE = 0, // No flag + + BASIC_BLOCK_FLAG_FUNCTION = (1 << 1), // Scanned; also part of a known function + BASIC_BLOCK_FLAG_ORPHANED = (1 << 2), // No targets ever reach this block + BASIC_BLOCK_FLAG_CUTOFF = (1 << 3), // Ends prematurely because of another JMP to location + BASIC_BLOCK_FLAG_DELETE = (1 << 4), // Delete element at the next possible time + + BASIC_BLOCK_FLAG_CALL = (1 << 5), // The block ends with a call + BASIC_BLOCK_FLAG_RET = (1 << 6), // The block ends with a retn + BASIC_BLOCK_FLAG_ABSJMP = (1 << 7), // Branch is absolute + BASIC_BLOCK_FLAG_INDIRECT = (1 << 8), // This block ends with an indirect branch + BASIC_BLOCK_FLAG_INDIRPTR = (1 << 9), // This block ends with an indirect branch; pointer known + + BASIC_BLOCK_FLAG_PREPAD = (1 << 10), // Block ends because there was padding afterwards + BASIC_BLOCK_FLAG_PAD = (1 << 11), // Block is only a series of padding instructions +}; + +struct BasicBlock +{ + duint VirtualStart; // Inclusive + duint VirtualEnd; // Exclusive + duint Flags; + duint Target; + + __forceinline bool GetFlag(duint Flag) + { + return (Flags & Flag) == Flag; + } + + __forceinline void SetFlag(duint Flag) + { + Flags |= Flag; + } + + __forceinline duint Size() + { + return VirtualEnd - VirtualStart; + } + + bool operator< (const BasicBlock & b) const + { + return VirtualStart < b.VirtualStart; + } + + bool operator== (const BasicBlock & b) const + { + return VirtualStart == b.VirtualStart; + } +}; + +struct FunctionDef +{ + duint VirtualStart; // Inclusive + duint VirtualEnd; // Exclusive + + duint BBlockStart; // Index of first basic block + duint BBlockEnd; // Index of last basic block + + bool operator< (const FunctionDef & b) const + { + if(VirtualStart == b.VirtualStart) + return VirtualEnd > b.VirtualEnd; + + return VirtualStart < b.VirtualStart; + } + + bool operator== (const FunctionDef & b) const + { + return VirtualStart == b.VirtualStart; + } +}; + +typedef std::vector BBlockArray; typedef std::vector FuncDefArray; \ No newline at end of file diff --git a/src/dbg/CodeFollowPass.cpp b/src/dbg/CodeFollowPass.cpp index 8478a54e..1224e930 100644 --- a/src/dbg/CodeFollowPass.cpp +++ b/src/dbg/CodeFollowPass.cpp @@ -1,92 +1,92 @@ -#include "AnalysisPass.h" -#include "CodeFollowPass.h" - -CodeFollowPass::CodeFollowPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks) - : AnalysisPass(VirtualStart, VirtualEnd, MainBlocks) -{ - -} - -CodeFollowPass::~CodeFollowPass() -{ -} - -const char* CodeFollowPass::GetName() -{ - return "Code Follower"; -} - -bool CodeFollowPass::Analyse() -{ - // First gather all possible function references with certain tables - // - // This includes: - // Main entry - // Module exports - // Module import references (?) - // Control flow guard - // RUNTIME_FUNCTION - // TLS callbacks - // FLS callbacks - return false; -} - -duint CodeFollowPass::GetReferenceOperand(const cs_x86 & Context) -{ - for(int i = 0; i < Context.op_count; i++) - { - auto operand = Context.operands[i]; - - // Looking for immediate references - if(operand.type == X86_OP_IMM) - { - duint dest = (duint)operand.imm; - - if(ValidateAddress(dest)) - return dest; - } - } - - return 0; -} - -duint CodeFollowPass::GetMemoryOperand(Capstone & Disasm, const cs_x86 & Context, bool* Indirect) -{ - if(Context.op_count <= 0) - return 0; - - // Only the first operand matters - auto operand = Context.operands[0]; - - // Jumps and calls only - if(Disasm.InGroup(CS_GRP_CALL) || Disasm.InGroup(CS_GRP_JUMP)) - { - // Looking for memory references - if(operand.type == X86_OP_MEM) - { - // Notify if the operand was indirect - if(Indirect) - { - if(operand.mem.base != X86_REG_INVALID || - operand.mem.index != X86_REG_INVALID || - operand.mem.scale != 0) - { - *Indirect = true; - return 0; - } - } - - // TODO: Read pointer - // TODO: Find virtual tables (new pass?) - // TODO: Translate RIP-Relative - return 0; - - duint dest = (duint)operand.mem.disp; - - if(ValidateAddress(dest)) - return dest; - } - } - - return 0; +#include "AnalysisPass.h" +#include "CodeFollowPass.h" + +CodeFollowPass::CodeFollowPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks) + : AnalysisPass(VirtualStart, VirtualEnd, MainBlocks) +{ + +} + +CodeFollowPass::~CodeFollowPass() +{ +} + +const char* CodeFollowPass::GetName() +{ + return "Code Follower"; +} + +bool CodeFollowPass::Analyse() +{ + // First gather all possible function references with certain tables + // + // This includes: + // Main entry + // Module exports + // Module import references (?) + // Control flow guard + // RUNTIME_FUNCTION + // TLS callbacks + // FLS callbacks + return false; +} + +duint CodeFollowPass::GetReferenceOperand(const cs_x86 & Context) +{ + for(int i = 0; i < Context.op_count; i++) + { + auto operand = Context.operands[i]; + + // Looking for immediate references + if(operand.type == X86_OP_IMM) + { + duint dest = (duint)operand.imm; + + if(ValidateAddress(dest)) + return dest; + } + } + + return 0; +} + +duint CodeFollowPass::GetMemoryOperand(Capstone & Disasm, const cs_x86 & Context, bool* Indirect) +{ + if(Context.op_count <= 0) + return 0; + + // Only the first operand matters + auto operand = Context.operands[0]; + + // Jumps and calls only + if(Disasm.InGroup(CS_GRP_CALL) || Disasm.InGroup(CS_GRP_JUMP)) + { + // Looking for memory references + if(operand.type == X86_OP_MEM) + { + // Notify if the operand was indirect + if(Indirect) + { + if(operand.mem.base != X86_REG_INVALID || + operand.mem.index != X86_REG_INVALID || + operand.mem.scale != 0) + { + *Indirect = true; + return 0; + } + } + + // TODO: Read pointer + // TODO: Find virtual tables (new pass?) + // TODO: Translate RIP-Relative + return 0; + + duint dest = (duint)operand.mem.disp; + + if(ValidateAddress(dest)) + return dest; + } + } + + return 0; } \ No newline at end of file diff --git a/src/dbg/CodeFollowPass.h b/src/dbg/CodeFollowPass.h index d84fba7d..bcb3af72 100644 --- a/src/dbg/CodeFollowPass.h +++ b/src/dbg/CodeFollowPass.h @@ -1,19 +1,19 @@ -#pragma once - -#include "AnalysisPass.h" -#include "BasicBlock.h" -#include - -class CodeFollowPass : public AnalysisPass -{ -public: - CodeFollowPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks); - virtual ~CodeFollowPass(); - - virtual const char* GetName() override; - virtual bool Analyse() override; - -private: - duint GetReferenceOperand(const cs_x86 & Context); - duint GetMemoryOperand(Capstone & Disasm, const cs_x86 & Context, bool* Indirect); +#pragma once + +#include "AnalysisPass.h" +#include "BasicBlock.h" +#include + +class CodeFollowPass : public AnalysisPass +{ +public: + CodeFollowPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks); + virtual ~CodeFollowPass(); + + virtual const char* GetName() override; + virtual bool Analyse() override; + +private: + duint GetReferenceOperand(const cs_x86 & Context); + duint GetMemoryOperand(Capstone & Disasm, const cs_x86 & Context, bool* Indirect); }; \ No newline at end of file diff --git a/src/dbg/DeviceNameResolver/DeviceNameResolver.h b/src/dbg/DeviceNameResolver/DeviceNameResolver.h index 70e584ae..dc14d04d 100644 --- a/src/dbg/DeviceNameResolver/DeviceNameResolver.h +++ b/src/dbg/DeviceNameResolver/DeviceNameResolver.h @@ -1,22 +1,22 @@ -#ifndef _DEVICENAMERESOLVER_H -#define _DEVICENAMERESOLVER_H - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -__declspec(dllexport) bool DevicePathToPathW(const wchar_t* szDevicePath, wchar_t* szPath, size_t nSize); -__declspec(dllexport) bool DevicePathToPathA(const char* szDevicePath, char* szPath, size_t nSize); -__declspec(dllexport) bool DevicePathFromFileHandleW(HANDLE hFile, wchar_t* szDevicePath, size_t nSize); -__declspec(dllexport) bool DevicePathFromFileHandleA(HANDLE hFile, char* szDevicePath, size_t nSize); -__declspec(dllexport) bool PathFromFileHandleW(HANDLE hFile, wchar_t* szPath, size_t nSize); -__declspec(dllexport) bool PathFromFileHandleA(HANDLE hFile, char* szPath, size_t nSize); - -#ifdef __cplusplus -} -#endif - -#endif // _DEVICENAMERESOLVER_H +#ifndef _DEVICENAMERESOLVER_H +#define _DEVICENAMERESOLVER_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +__declspec(dllexport) bool DevicePathToPathW(const wchar_t* szDevicePath, wchar_t* szPath, size_t nSize); +__declspec(dllexport) bool DevicePathToPathA(const char* szDevicePath, char* szPath, size_t nSize); +__declspec(dllexport) bool DevicePathFromFileHandleW(HANDLE hFile, wchar_t* szDevicePath, size_t nSize); +__declspec(dllexport) bool DevicePathFromFileHandleA(HANDLE hFile, char* szDevicePath, size_t nSize); +__declspec(dllexport) bool PathFromFileHandleW(HANDLE hFile, wchar_t* szPath, size_t nSize); +__declspec(dllexport) bool PathFromFileHandleA(HANDLE hFile, char* szPath, size_t nSize); + +#ifdef __cplusplus +} +#endif + +#endif // _DEVICENAMERESOLVER_H diff --git a/src/dbg/FunctionPass.cpp b/src/dbg/FunctionPass.cpp index bbaa04ad..aa8e008b 100644 --- a/src/dbg/FunctionPass.cpp +++ b/src/dbg/FunctionPass.cpp @@ -1,359 +1,359 @@ -#include "FunctionPass.h" -#include -#include "memory.h" -#include "console.h" -#include "debugger.h" -#include "module.h" -#include "function.h" - -FunctionPass::FunctionPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks) - : AnalysisPass(VirtualStart, VirtualEnd, MainBlocks) -{ - // Zero values - m_FunctionInfo = nullptr; - m_FunctionInfoSize = 0; - - // This will only be valid if the address range is within a loaded module - m_ModuleStart = ModBaseFromAddr(VirtualStart); - - if(m_ModuleStart != 0) - { - char modulePath[MAX_PATH]; - memset(modulePath, 0, sizeof(modulePath)); - - ModPathFromAddr(m_ModuleStart, modulePath, ARRAYSIZE(modulePath)); - - HANDLE fileHandle; - DWORD fileSize; - HANDLE fileMapHandle; - ULONG_PTR fileMapVa; - if(StaticFileLoadW( - StringUtils::Utf8ToUtf16(modulePath).c_str(), - UE_ACCESS_READ, - false, - &fileHandle, - &fileSize, - &fileMapHandle, - &fileMapVa)) - { - // Find a pointer to IMAGE_DIRECTORY_ENTRY_EXCEPTION for later use - ULONG_PTR virtualOffset = GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALOFFSET); - m_FunctionInfoSize = (ULONG)GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALSIZE); - - // Unload the file - StaticFileUnloadW(nullptr, false, fileHandle, fileSize, fileMapHandle, fileMapVa); - - // Get a copy of the function table - if(virtualOffset) - { - // Read the table into a buffer - m_FunctionInfo = BridgeAlloc(m_FunctionInfoSize); - - if(m_FunctionInfo) - MemRead(virtualOffset + m_ModuleStart, m_FunctionInfo, m_FunctionInfoSize); - } - } - } -} - -FunctionPass::~FunctionPass() -{ - if(m_FunctionInfo) - BridgeFree(m_FunctionInfo); -} - -const char* FunctionPass::GetName() -{ - return "Function Analysis"; -} - -bool FunctionPass::Analyse() -{ - // THREAD_WORK = ceil(TOTAL / # THREADS) - duint workAmount = (m_MainBlocks.size() + (IdealThreadCount() - 1)) / IdealThreadCount(); - - // Initialize thread vector - auto threadFunctions = new std::vector[IdealThreadCount()]; - - concurrency::parallel_for(duint (0), IdealThreadCount(), [&](duint i) - { - duint threadWorkStart = (workAmount * i); - duint threadWorkStop = min((threadWorkStart + workAmount), m_MainBlocks.size()); - - // Memory allocation optimization - // TODO: Option to conserve memory - threadFunctions[i].reserve(30000); - - // Execute - AnalysisWorker(threadWorkStart, threadWorkStop, &threadFunctions[i]); - }); - - std::vector funcs; - - // Merge thread vectors into single local - for(duint i = 0; i < IdealThreadCount(); i++) - std::move(threadFunctions[i].begin(), threadFunctions[i].end(), std::back_inserter(funcs)); - - // Sort and remove duplicates - std::sort(funcs.begin(), funcs.end()); - funcs.erase(std::unique(funcs.begin(), funcs.end()), funcs.end()); - - dprintf("%u functions\n", funcs.size()); - - FunctionClear(); - for(auto & func : funcs) - { - FunctionAdd(func.VirtualStart, func.VirtualEnd - 1, true); - } - GuiUpdateAllViews(); - - delete[] threadFunctions; - return true; -} - -void FunctionPass::AnalysisWorker(duint Start, duint End, std::vector* Blocks) -{ - // Step 1: Use any defined functions in the PE function table - FindFunctionWorkerPrepass(Start, End, Blocks); - - // Step 2: for each block that contains a CALL flag, - // add it to a local function start array - // - // NOTE: *Some* indirect calls are included - auto blockItr = std::next(m_MainBlocks.begin(), Start); - - for(duint i = Start; i < End; i++, ++blockItr) - { - if(blockItr->GetFlag(BASIC_BLOCK_FLAG_CALL)) - { - duint destination = blockItr->Target; - - // Was it a pointer? - if(blockItr->GetFlag(BASIC_BLOCK_FLAG_INDIRPTR)) - { - // Read it from memory - if(!MemRead(destination, &destination, sizeof(duint))) - continue; - - // Validity check - if(!MemIsValidReadPtr(destination)) - continue; - - dprintf("Indirect pointer: 0x%p 0x%p\n", blockItr->Target, destination); - } - - // Destination must be within analysis limits - if(!ValidateAddress(destination)) - continue; - - FunctionDef def; - def.VirtualStart = destination; - def.VirtualEnd = 0; - def.BBlockStart = 0; - def.BBlockEnd = 0; - Blocks->push_back(def); - } - } - - // Step 3: Sort and remove duplicates - std::sort(Blocks->begin(), Blocks->end()); - Blocks->erase(std::unique(Blocks->begin(), Blocks->end()), Blocks->end()); - - // Step 4: Find the end of functions - FindFunctionWorker(Blocks); - - dprintf("Total detected functions: %d\n", Blocks->size()); - - // Step 5: Find all orphaned blocks and repeat analysis process - // TODO -} - -void FunctionPass::FindFunctionWorkerPrepass(duint Start, duint End, std::vector* Blocks) -{ - const duint minFunc = std::next(m_MainBlocks.begin(), Start)->VirtualStart; - const duint maxFunc = std::next(m_MainBlocks.begin(), End - 1)->VirtualEnd; - -#ifdef _WIN64 - // RUNTIME_FUNCTION exception information - EnumerateFunctionRuntimeEntries64([&](PRUNTIME_FUNCTION Function) - { - const duint funcAddr = m_ModuleStart + Function->BeginAddress; - const duint funcEnd = m_ModuleStart + Function->EndAddress; - - // If within limits... - if(funcAddr >= minFunc && funcAddr < maxFunc) - { - // Add the descriptor - FunctionDef def; - def.VirtualStart = funcAddr; - def.VirtualEnd = funcEnd; - def.BBlockStart = 0; - def.BBlockEnd = 0; - Blocks->push_back(def); - } - - return true; - }); -#endif // _WIN64 - - // Module exports (return value ignored) - apienumexports(m_ModuleStart, [&](duint Base, const char* Module, const char* Name, duint Address) - { - // If within limits... - if(Address >= minFunc && Address < maxFunc) - { - // Add the descriptor - FunctionDef def; - def.VirtualStart = Address; - def.VirtualEnd = 0; - def.BBlockStart = 0; - def.BBlockEnd = 0; - Blocks->push_back(def); - } - }); -} - -void FunctionPass::FindFunctionWorker(std::vector* Blocks) -{ - // Cached final block - BasicBlock* finalBlock = &m_MainBlocks.back(); - - // Enumerate all function entries for this thread - for(auto & block : *Blocks) - { - // Sometimes the ending address is already supplied, so - // check first - if(block.VirtualEnd != 0) - { - if(ResolveKnownFunctionEnd(&block)) - continue; - } - - // Now the function end must be determined by heuristics (find manually) - ResolveFunctionEnd(&block, finalBlock); - } -} - -bool FunctionPass::ResolveKnownFunctionEnd(FunctionDef* Function) -{ - // Helper to link final blocks to function - auto startBlock = FindBBlockInRange(Function->VirtualStart); - auto endBlock = FindBBlockInRange(Function->VirtualEnd); - - if(!startBlock || !endBlock) - return false; - - // Find block start/end indices - Function->BBlockStart = FindBBlockIndex(startBlock); - Function->BBlockEnd = FindBBlockIndex(endBlock); - - // Set the flag for blocks that have been scanned - for(BasicBlock* block = startBlock; (duint)block <= (duint)endBlock; block++) - block->SetFlag(BASIC_BLOCK_FLAG_FUNCTION); - - return true; -} - -bool FunctionPass::ResolveFunctionEnd(FunctionDef* Function, BasicBlock* LastBlock) -{ - ASSERT_TRUE(Function->VirtualStart != 0); - - // Find the first basic block of the function - BasicBlock* block = FindBBlockInRange(Function->VirtualStart); - - if(!block) - { - ASSERT_ALWAYS("Block should exist at this point"); - return false; - } - - // The maximum address is determined by any jump that extends past - // a RET or other terminating basic block. A function may have multiple - // return statements. - duint maximumAddr = 0; - - // Loop forever until the end is found - for(; (duint)block <= (duint)LastBlock; block++) - { - // Block is now in use - block->SetFlag(BASIC_BLOCK_FLAG_FUNCTION); - - // Calculate max from just linear instructions - maximumAddr = max(maximumAddr, block->VirtualEnd - 1); - - // Find maximum jump target - if(!block->GetFlag(BASIC_BLOCK_FLAG_CALL) && !block->GetFlag(BASIC_BLOCK_FLAG_INDIRECT)) - { - if(block->Target != 0) - { - // Here's a problem: Compilers add tail-call elimination with a jump. - // Solve this by creating a maximum jump limit: +/- 512 bytes from the end. - // - // abs(block->VirtualEnd - block->Target) -- unsigned - if(min(block->VirtualEnd - block->Target, block->Target - block->VirtualEnd) <= 512) - maximumAddr = max(maximumAddr, block->Target); - } - } - - // Sanity check - ASSERT_TRUE(maximumAddr >= block->VirtualStart); - - // Does this node contain the maximum address? - if(maximumAddr >= block->VirtualStart && maximumAddr < block->VirtualEnd) - { - // It does! There's 4 possibilities next: - // - // 1. Return - // 2. Tail-call elimination - // 3. Optimized loop - // 4. Function continues to next block - // - // 1. - if(block->GetFlag(BASIC_BLOCK_FLAG_RET)) - break; - - if(block->Target != 0) - { - // NOTE: Both must be an absolute jump - if(block->GetFlag(BASIC_BLOCK_FLAG_ABSJMP)) - { - // 2. - // - // abs(block->VirtualEnd - block->Target) -- unsigned - if(min(block->VirtualEnd - block->Target, block->Target - block->VirtualEnd) > 128) - break; - - // 3. - if(block->Target >= Function->VirtualStart && block->Target < block->VirtualEnd) - break; - } - } - - // 4. Continue - } - } - - // Loop is done. Set the information in the function structure. - Function->VirtualEnd = block->VirtualEnd; - Function->BBlockEnd = FindBBlockIndex(block); - return true; -} - -#ifdef _WIN64 -void FunctionPass::EnumerateFunctionRuntimeEntries64(std::function Callback) -{ - if(!m_FunctionInfo) - return; - - // Get the table pointer and size - auto functionTable = (PRUNTIME_FUNCTION)m_FunctionInfo; - ULONG totalCount = (m_FunctionInfoSize / sizeof(RUNTIME_FUNCTION)); - - // Enumerate each entry - for(ULONG i = 0; i < totalCount; i++) - { - if(!Callback(&functionTable[i])) - break; - } -} +#include "FunctionPass.h" +#include +#include "memory.h" +#include "console.h" +#include "debugger.h" +#include "module.h" +#include "function.h" + +FunctionPass::FunctionPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks) + : AnalysisPass(VirtualStart, VirtualEnd, MainBlocks) +{ + // Zero values + m_FunctionInfo = nullptr; + m_FunctionInfoSize = 0; + + // This will only be valid if the address range is within a loaded module + m_ModuleStart = ModBaseFromAddr(VirtualStart); + + if(m_ModuleStart != 0) + { + char modulePath[MAX_PATH]; + memset(modulePath, 0, sizeof(modulePath)); + + ModPathFromAddr(m_ModuleStart, modulePath, ARRAYSIZE(modulePath)); + + HANDLE fileHandle; + DWORD fileSize; + HANDLE fileMapHandle; + ULONG_PTR fileMapVa; + if(StaticFileLoadW( + StringUtils::Utf8ToUtf16(modulePath).c_str(), + UE_ACCESS_READ, + false, + &fileHandle, + &fileSize, + &fileMapHandle, + &fileMapVa)) + { + // Find a pointer to IMAGE_DIRECTORY_ENTRY_EXCEPTION for later use + ULONG_PTR virtualOffset = GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALOFFSET); + m_FunctionInfoSize = (ULONG)GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALSIZE); + + // Unload the file + StaticFileUnloadW(nullptr, false, fileHandle, fileSize, fileMapHandle, fileMapVa); + + // Get a copy of the function table + if(virtualOffset) + { + // Read the table into a buffer + m_FunctionInfo = BridgeAlloc(m_FunctionInfoSize); + + if(m_FunctionInfo) + MemRead(virtualOffset + m_ModuleStart, m_FunctionInfo, m_FunctionInfoSize); + } + } + } +} + +FunctionPass::~FunctionPass() +{ + if(m_FunctionInfo) + BridgeFree(m_FunctionInfo); +} + +const char* FunctionPass::GetName() +{ + return "Function Analysis"; +} + +bool FunctionPass::Analyse() +{ + // THREAD_WORK = ceil(TOTAL / # THREADS) + duint workAmount = (m_MainBlocks.size() + (IdealThreadCount() - 1)) / IdealThreadCount(); + + // Initialize thread vector + auto threadFunctions = new std::vector[IdealThreadCount()]; + + concurrency::parallel_for(duint (0), IdealThreadCount(), [&](duint i) + { + duint threadWorkStart = (workAmount * i); + duint threadWorkStop = min((threadWorkStart + workAmount), m_MainBlocks.size()); + + // Memory allocation optimization + // TODO: Option to conserve memory + threadFunctions[i].reserve(30000); + + // Execute + AnalysisWorker(threadWorkStart, threadWorkStop, &threadFunctions[i]); + }); + + std::vector funcs; + + // Merge thread vectors into single local + for(duint i = 0; i < IdealThreadCount(); i++) + std::move(threadFunctions[i].begin(), threadFunctions[i].end(), std::back_inserter(funcs)); + + // Sort and remove duplicates + std::sort(funcs.begin(), funcs.end()); + funcs.erase(std::unique(funcs.begin(), funcs.end()), funcs.end()); + + dprintf("%u functions\n", funcs.size()); + + FunctionClear(); + for(auto & func : funcs) + { + FunctionAdd(func.VirtualStart, func.VirtualEnd - 1, true); + } + GuiUpdateAllViews(); + + delete[] threadFunctions; + return true; +} + +void FunctionPass::AnalysisWorker(duint Start, duint End, std::vector* Blocks) +{ + // Step 1: Use any defined functions in the PE function table + FindFunctionWorkerPrepass(Start, End, Blocks); + + // Step 2: for each block that contains a CALL flag, + // add it to a local function start array + // + // NOTE: *Some* indirect calls are included + auto blockItr = std::next(m_MainBlocks.begin(), Start); + + for(duint i = Start; i < End; i++, ++blockItr) + { + if(blockItr->GetFlag(BASIC_BLOCK_FLAG_CALL)) + { + duint destination = blockItr->Target; + + // Was it a pointer? + if(blockItr->GetFlag(BASIC_BLOCK_FLAG_INDIRPTR)) + { + // Read it from memory + if(!MemRead(destination, &destination, sizeof(duint))) + continue; + + // Validity check + if(!MemIsValidReadPtr(destination)) + continue; + + dprintf("Indirect pointer: 0x%p 0x%p\n", blockItr->Target, destination); + } + + // Destination must be within analysis limits + if(!ValidateAddress(destination)) + continue; + + FunctionDef def; + def.VirtualStart = destination; + def.VirtualEnd = 0; + def.BBlockStart = 0; + def.BBlockEnd = 0; + Blocks->push_back(def); + } + } + + // Step 3: Sort and remove duplicates + std::sort(Blocks->begin(), Blocks->end()); + Blocks->erase(std::unique(Blocks->begin(), Blocks->end()), Blocks->end()); + + // Step 4: Find the end of functions + FindFunctionWorker(Blocks); + + dprintf("Total detected functions: %d\n", Blocks->size()); + + // Step 5: Find all orphaned blocks and repeat analysis process + // TODO +} + +void FunctionPass::FindFunctionWorkerPrepass(duint Start, duint End, std::vector* Blocks) +{ + const duint minFunc = std::next(m_MainBlocks.begin(), Start)->VirtualStart; + const duint maxFunc = std::next(m_MainBlocks.begin(), End - 1)->VirtualEnd; + +#ifdef _WIN64 + // RUNTIME_FUNCTION exception information + EnumerateFunctionRuntimeEntries64([&](PRUNTIME_FUNCTION Function) + { + const duint funcAddr = m_ModuleStart + Function->BeginAddress; + const duint funcEnd = m_ModuleStart + Function->EndAddress; + + // If within limits... + if(funcAddr >= minFunc && funcAddr < maxFunc) + { + // Add the descriptor + FunctionDef def; + def.VirtualStart = funcAddr; + def.VirtualEnd = funcEnd; + def.BBlockStart = 0; + def.BBlockEnd = 0; + Blocks->push_back(def); + } + + return true; + }); +#endif // _WIN64 + + // Module exports (return value ignored) + apienumexports(m_ModuleStart, [&](duint Base, const char* Module, const char* Name, duint Address) + { + // If within limits... + if(Address >= minFunc && Address < maxFunc) + { + // Add the descriptor + FunctionDef def; + def.VirtualStart = Address; + def.VirtualEnd = 0; + def.BBlockStart = 0; + def.BBlockEnd = 0; + Blocks->push_back(def); + } + }); +} + +void FunctionPass::FindFunctionWorker(std::vector* Blocks) +{ + // Cached final block + BasicBlock* finalBlock = &m_MainBlocks.back(); + + // Enumerate all function entries for this thread + for(auto & block : *Blocks) + { + // Sometimes the ending address is already supplied, so + // check first + if(block.VirtualEnd != 0) + { + if(ResolveKnownFunctionEnd(&block)) + continue; + } + + // Now the function end must be determined by heuristics (find manually) + ResolveFunctionEnd(&block, finalBlock); + } +} + +bool FunctionPass::ResolveKnownFunctionEnd(FunctionDef* Function) +{ + // Helper to link final blocks to function + auto startBlock = FindBBlockInRange(Function->VirtualStart); + auto endBlock = FindBBlockInRange(Function->VirtualEnd); + + if(!startBlock || !endBlock) + return false; + + // Find block start/end indices + Function->BBlockStart = FindBBlockIndex(startBlock); + Function->BBlockEnd = FindBBlockIndex(endBlock); + + // Set the flag for blocks that have been scanned + for(BasicBlock* block = startBlock; (duint)block <= (duint)endBlock; block++) + block->SetFlag(BASIC_BLOCK_FLAG_FUNCTION); + + return true; +} + +bool FunctionPass::ResolveFunctionEnd(FunctionDef* Function, BasicBlock* LastBlock) +{ + ASSERT_TRUE(Function->VirtualStart != 0); + + // Find the first basic block of the function + BasicBlock* block = FindBBlockInRange(Function->VirtualStart); + + if(!block) + { + ASSERT_ALWAYS("Block should exist at this point"); + return false; + } + + // The maximum address is determined by any jump that extends past + // a RET or other terminating basic block. A function may have multiple + // return statements. + duint maximumAddr = 0; + + // Loop forever until the end is found + for(; (duint)block <= (duint)LastBlock; block++) + { + // Block is now in use + block->SetFlag(BASIC_BLOCK_FLAG_FUNCTION); + + // Calculate max from just linear instructions + maximumAddr = max(maximumAddr, block->VirtualEnd - 1); + + // Find maximum jump target + if(!block->GetFlag(BASIC_BLOCK_FLAG_CALL) && !block->GetFlag(BASIC_BLOCK_FLAG_INDIRECT)) + { + if(block->Target != 0) + { + // Here's a problem: Compilers add tail-call elimination with a jump. + // Solve this by creating a maximum jump limit: +/- 512 bytes from the end. + // + // abs(block->VirtualEnd - block->Target) -- unsigned + if(min(block->VirtualEnd - block->Target, block->Target - block->VirtualEnd) <= 512) + maximumAddr = max(maximumAddr, block->Target); + } + } + + // Sanity check + ASSERT_TRUE(maximumAddr >= block->VirtualStart); + + // Does this node contain the maximum address? + if(maximumAddr >= block->VirtualStart && maximumAddr < block->VirtualEnd) + { + // It does! There's 4 possibilities next: + // + // 1. Return + // 2. Tail-call elimination + // 3. Optimized loop + // 4. Function continues to next block + // + // 1. + if(block->GetFlag(BASIC_BLOCK_FLAG_RET)) + break; + + if(block->Target != 0) + { + // NOTE: Both must be an absolute jump + if(block->GetFlag(BASIC_BLOCK_FLAG_ABSJMP)) + { + // 2. + // + // abs(block->VirtualEnd - block->Target) -- unsigned + if(min(block->VirtualEnd - block->Target, block->Target - block->VirtualEnd) > 128) + break; + + // 3. + if(block->Target >= Function->VirtualStart && block->Target < block->VirtualEnd) + break; + } + } + + // 4. Continue + } + } + + // Loop is done. Set the information in the function structure. + Function->VirtualEnd = block->VirtualEnd; + Function->BBlockEnd = FindBBlockIndex(block); + return true; +} + +#ifdef _WIN64 +void FunctionPass::EnumerateFunctionRuntimeEntries64(std::function Callback) +{ + if(!m_FunctionInfo) + return; + + // Get the table pointer and size + auto functionTable = (PRUNTIME_FUNCTION)m_FunctionInfo; + ULONG totalCount = (m_FunctionInfoSize / sizeof(RUNTIME_FUNCTION)); + + // Enumerate each entry + for(ULONG i = 0; i < totalCount; i++) + { + if(!Callback(&functionTable[i])) + break; + } +} #endif // _WIN64 \ No newline at end of file diff --git a/src/dbg/FunctionPass.h b/src/dbg/FunctionPass.h index fcb5bd6d..523ac694 100644 --- a/src/dbg/FunctionPass.h +++ b/src/dbg/FunctionPass.h @@ -1,32 +1,32 @@ -#pragma once - -#include -#include "AnalysisPass.h" -#include "BasicBlock.h" - -class FunctionPass : public AnalysisPass -{ -public: - FunctionPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks); - virtual ~FunctionPass(); - - virtual const char* GetName() override; - virtual bool Analyse() override; - -private: - duint m_ModuleStart; - - PVOID m_FunctionInfo; - ULONG m_FunctionInfoSize; - - void AnalysisWorker(duint Start, duint End, std::vector* Blocks); - void FindFunctionWorkerPrepass(duint Start, duint End, std::vector* Blocks); - void FindFunctionWorker(std::vector* Blocks); - - bool ResolveKnownFunctionEnd(FunctionDef* Function); - bool ResolveFunctionEnd(FunctionDef* Function, BasicBlock* LastBlock); - -#ifdef _WIN64 - void EnumerateFunctionRuntimeEntries64(std::function Callback); -#endif // _WIN64 +#pragma once + +#include +#include "AnalysisPass.h" +#include "BasicBlock.h" + +class FunctionPass : public AnalysisPass +{ +public: + FunctionPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks); + virtual ~FunctionPass(); + + virtual const char* GetName() override; + virtual bool Analyse() override; + +private: + duint m_ModuleStart; + + PVOID m_FunctionInfo; + ULONG m_FunctionInfoSize; + + void AnalysisWorker(duint Start, duint End, std::vector* Blocks); + void FindFunctionWorkerPrepass(duint Start, duint End, std::vector* Blocks); + void FindFunctionWorker(std::vector* Blocks); + + bool ResolveKnownFunctionEnd(FunctionDef* Function); + bool ResolveFunctionEnd(FunctionDef* Function, BasicBlock* LastBlock); + +#ifdef _WIN64 + void EnumerateFunctionRuntimeEntries64(std::function Callback); +#endif // _WIN64 }; \ No newline at end of file diff --git a/src/dbg/LinearPass.cpp b/src/dbg/LinearPass.cpp index 52d3e932..8bf54fe5 100644 --- a/src/dbg/LinearPass.cpp +++ b/src/dbg/LinearPass.cpp @@ -1,327 +1,327 @@ -#include -#include -#include "AnalysisPass.h" -#include "LinearPass.h" -#include - -LinearPass::LinearPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks) - : AnalysisPass(VirtualStart, VirtualEnd, MainBlocks) -{ - // This is a fix for when the total data analysis size is less - // than what parallelization can support. The minimum size requirement - // is ((# THREADS) * (512)) bytes. If the requirement isn't met, - // scale to use a single thread. - if((512 * IdealThreadCount()) >= m_DataSize) - SetIdealThreadCount(1); -} - -LinearPass::~LinearPass() -{ -} - -const char* LinearPass::GetName() -{ - return "Linear Scandown"; -} - -bool LinearPass::Analyse() -{ - // Divide the work up between each thread - // THREAD_WORK = (TOTAL / # THREADS) - duint workAmount = m_DataSize / IdealThreadCount(); - - // Initialize thread vector - auto threadBlocks = new std::vector[IdealThreadCount()]; - - concurrency::parallel_for(duint (0), IdealThreadCount(), [&](duint i) - { - duint threadWorkStart = m_VirtualStart + (workAmount * i); - duint threadWorkStop = min((threadWorkStart + workAmount), m_VirtualEnd); - - // Allow a 256-byte variance of scanning because of - // integer rounding errors and instruction overlap - if(threadWorkStart > m_VirtualStart) - { - threadWorkStart = max((threadWorkStart - 256), m_VirtualStart); - threadWorkStop = min((threadWorkStop + 256), m_VirtualEnd); - } - - // Memory allocation optimization - // TODO: Option to conserve memory - threadBlocks[i].reserve(100000); - - // Execute - AnalysisWorker(threadWorkStart, threadWorkStop, &threadBlocks[i]); - }); - - // Clear old data and combine vectors - m_MainBlocks.clear(); - - for(duint i = 0; i < IdealThreadCount(); i++) - { - std::move(threadBlocks[i].begin(), threadBlocks[i].end(), std::back_inserter(m_MainBlocks)); - - // Free old elements to conserve memory further - BBlockArray().swap(threadBlocks[i]); - } - - // Free memory ASAP - delete[] threadBlocks; - - // Sort and remove duplicates - std::sort(m_MainBlocks.begin(), m_MainBlocks.end()); - m_MainBlocks.erase(std::unique(m_MainBlocks.begin(), m_MainBlocks.end()), m_MainBlocks.end()); - - // Run overlap analysis sub-pass - AnalyseOverlaps(); - return true; -} - -void LinearPass::AnalyseOverlaps() -{ - // Goal of this function: - // - // Remove all overlapping - // basic blocks because of threads not ending or - // starting at absolutely defined points. - // (Example: one thread starts in the middle of - // an instruction) - // - // This also checks for basic block targets jumping into - // the middle of other basic blocks. - // - // THREAD_WORK = ceil(TOTAL / # THREADS) - duint workTotal = m_MainBlocks.size(); - duint workAmount = (workTotal + (IdealThreadCount() - 1)) / IdealThreadCount(); - - // Initialize thread vectors - auto threadInserts = new std::vector[IdealThreadCount()]; - - concurrency::parallel_for(duint (0), IdealThreadCount(), [&](duint i) - { - duint threadWorkStart = (workAmount * i); - duint threadWorkStop = min((threadWorkStart + workAmount), workTotal); - - // Again, allow an overlap of +/- 1 entry - if(threadWorkStart > 0) - { - threadWorkStart = max((threadWorkStart - 1), 0); - threadWorkStop = min((threadWorkStop + 1), workTotal); - } - - // Execute - AnalysisOverlapWorker(threadWorkStart, threadWorkStop, &threadInserts[i]); - }); - - // THREAD VECTOR - std::vector overlapInserts; - { - for(duint i = 0; i < IdealThreadCount(); i++) - std::move(threadInserts[i].begin(), threadInserts[i].end(), std::back_inserter(overlapInserts)); - - // Sort and remove duplicates - std::sort(overlapInserts.begin(), overlapInserts.end()); - overlapInserts.erase(std::unique(overlapInserts.begin(), overlapInserts.end()), overlapInserts.end()); - - delete[] threadInserts; - } - - // GLOBAL VECTOR - { - // Erase blocks marked for deletion - m_MainBlocks.erase(std::remove_if(m_MainBlocks.begin(), m_MainBlocks.end(), [](BasicBlock & Elem) - { - return Elem.GetFlag(BASIC_BLOCK_FLAG_DELETE); - })); - - // Insert - std::move(overlapInserts.begin(), overlapInserts.end(), std::back_inserter(m_MainBlocks)); - - // Final sort - std::sort(m_MainBlocks.begin(), m_MainBlocks.end()); - } -} - -void LinearPass::AnalysisWorker(duint Start, duint End, BBlockArray* Blocks) -{ - Capstone disasm; - - duint blockBegin = Start; // BBlock starting virtual address - duint blockEnd; // BBlock ending virtual address - bool blockPrevPad = false; // Indicator if the last instruction was padding - BasicBlock* lastBlock = nullptr;// Avoid an expensive call to std::vector::back() - - for(duint i = Start; i < End;) - { - if(!disasm.Disassemble(i, TranslateAddress(i))) - { - // Skip instructions that can't be determined - i++; - continue; - } - - // Increment counter - i += disasm.Size(); - blockEnd = i; - - // The basic block ends here if it is a branch - bool call = disasm.InGroup(CS_GRP_CALL); // CALL - bool jmp = disasm.InGroup(CS_GRP_JUMP); // JUMP - bool ret = disasm.InGroup(CS_GRP_RET); // RETURN - bool padding = disasm.IsFilling(); // INSTRUCTION PADDING - - if(padding) - { - // PADDING is treated differently. They are all created as their - // own separate block for more analysis later. - duint realBlockEnd = blockEnd - disasm.Size(); - - if((realBlockEnd - blockBegin) > 0) - { - // The next line terminates the BBlock before the INT instruction. - // Early termination, faked as an indirect JMP. Rare case. - lastBlock = CreateBlockWorker(Blocks, blockBegin, realBlockEnd, false, false, false, false); - lastBlock->SetFlag(BASIC_BLOCK_FLAG_PREPAD); - - blockBegin = realBlockEnd; - } - } - - if(call || jmp || ret || padding) - { - // Was this a padding instruction? - if(padding && blockPrevPad) - { - // Append it to the previous block - lastBlock->VirtualEnd = blockEnd; - } - else - { - // Otherwise use the default route: create a new entry - auto block = lastBlock = CreateBlockWorker(Blocks, blockBegin, blockEnd, call, jmp, ret, padding); - - // Figure out the operand type - auto operand = disasm.x86().operands[0]; - - if(operand.type == X86_OP_IMM) - { - // Branch target immediate - block->Target = (duint)operand.imm; - - // Check if absolute jump - if(disasm.GetId() == X86_INS_JMP) - block->SetFlag(BASIC_BLOCK_FLAG_ABSJMP); - } - else - { - // Indirects - block->SetFlag(BASIC_BLOCK_FLAG_INDIRECT); - - if(operand.type == X86_OP_MEM && - operand.mem.base == X86_REG_INVALID && - operand.mem.index == X86_REG_INVALID && - operand.mem.scale == 1) - { - block->SetFlag(BASIC_BLOCK_FLAG_INDIRPTR); - block->Target = (duint)operand.mem.disp; - } - } - } - - // Reset the loop variables - blockBegin = i; - blockPrevPad = padding; - } - } -} - -void LinearPass::AnalysisOverlapWorker(duint Start, duint End, BBlockArray* Insertions) -{ - // Comparison function to see if two blocks overlap - auto BlockOverlapsRemove = [](BasicBlock * A, BasicBlock * B) -> BasicBlock* - { - // Do the blocks overlap? - if(max(A->VirtualStart, B->VirtualStart) <= min((A->VirtualEnd - 1), (B->VirtualEnd - 1))) - { - // Return the block that should be removed - if(A->Size() > B->Size()) - return B; - - return A; - } - - return nullptr; - }; - - // Get a pointer to pure data - const auto blocks = m_MainBlocks.data(); - - for(duint i = Start; i < End; i++) - { - const auto curr = &blocks[i]; - const auto next = &blocks[i + 1]; - - // Current versus next (overlap -> delete) - BasicBlock* removal = BlockOverlapsRemove(curr, next); - - if(removal) - removal->SetFlag(BASIC_BLOCK_FLAG_DELETE); - - // Find blocks that need to be split in two because - // of CALL/JMP targets - // - // Find targets in the virtual range - if(ValidateAddress(curr->Target)) - { - removal = FindBBlockInRange(curr->Target); - - // If the target does not equal the block start... - if(removal && curr->Target != removal->VirtualStart) - { - // Mark for deletion - removal->SetFlag(BASIC_BLOCK_FLAG_DELETE); - - // Block part 1 - BasicBlock block1; - block1.VirtualStart = removal->VirtualStart; - block1.VirtualEnd = curr->Target; - block1.Target = 0; - block1.Flags = BASIC_BLOCK_FLAG_CUTOFF; - - // Block part 2 - BasicBlock block2; - block2.VirtualStart = curr->Target; - block2.VirtualEnd = removal->VirtualEnd; - block2.Target = removal->Target; - block2.Flags = removal->Flags; - - Insertions->push_back(block1); - Insertions->push_back(block2); - } - } - } -} - -BasicBlock* LinearPass::CreateBlockWorker(std::vector* Blocks, duint Start, duint End, bool Call, bool Jmp, bool Ret, bool Pad) -{ - BasicBlock block; - block.VirtualStart = Start; - block.VirtualEnd = End; - block.Flags = 0; - block.Target = 0; - - // Check for calls - if(Call) - block.SetFlag(BASIC_BLOCK_FLAG_CALL); - - // Check for returns - if(Ret) - block.SetFlag(BASIC_BLOCK_FLAG_RET); - - // Check for interrupts - if(Pad) - block.SetFlag(BASIC_BLOCK_FLAG_PAD); - - Blocks->push_back(block); - return &Blocks->back(); +#include +#include +#include "AnalysisPass.h" +#include "LinearPass.h" +#include + +LinearPass::LinearPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks) + : AnalysisPass(VirtualStart, VirtualEnd, MainBlocks) +{ + // This is a fix for when the total data analysis size is less + // than what parallelization can support. The minimum size requirement + // is ((# THREADS) * (512)) bytes. If the requirement isn't met, + // scale to use a single thread. + if((512 * IdealThreadCount()) >= m_DataSize) + SetIdealThreadCount(1); +} + +LinearPass::~LinearPass() +{ +} + +const char* LinearPass::GetName() +{ + return "Linear Scandown"; +} + +bool LinearPass::Analyse() +{ + // Divide the work up between each thread + // THREAD_WORK = (TOTAL / # THREADS) + duint workAmount = m_DataSize / IdealThreadCount(); + + // Initialize thread vector + auto threadBlocks = new std::vector[IdealThreadCount()]; + + concurrency::parallel_for(duint (0), IdealThreadCount(), [&](duint i) + { + duint threadWorkStart = m_VirtualStart + (workAmount * i); + duint threadWorkStop = min((threadWorkStart + workAmount), m_VirtualEnd); + + // Allow a 256-byte variance of scanning because of + // integer rounding errors and instruction overlap + if(threadWorkStart > m_VirtualStart) + { + threadWorkStart = max((threadWorkStart - 256), m_VirtualStart); + threadWorkStop = min((threadWorkStop + 256), m_VirtualEnd); + } + + // Memory allocation optimization + // TODO: Option to conserve memory + threadBlocks[i].reserve(100000); + + // Execute + AnalysisWorker(threadWorkStart, threadWorkStop, &threadBlocks[i]); + }); + + // Clear old data and combine vectors + m_MainBlocks.clear(); + + for(duint i = 0; i < IdealThreadCount(); i++) + { + std::move(threadBlocks[i].begin(), threadBlocks[i].end(), std::back_inserter(m_MainBlocks)); + + // Free old elements to conserve memory further + BBlockArray().swap(threadBlocks[i]); + } + + // Free memory ASAP + delete[] threadBlocks; + + // Sort and remove duplicates + std::sort(m_MainBlocks.begin(), m_MainBlocks.end()); + m_MainBlocks.erase(std::unique(m_MainBlocks.begin(), m_MainBlocks.end()), m_MainBlocks.end()); + + // Run overlap analysis sub-pass + AnalyseOverlaps(); + return true; +} + +void LinearPass::AnalyseOverlaps() +{ + // Goal of this function: + // + // Remove all overlapping + // basic blocks because of threads not ending or + // starting at absolutely defined points. + // (Example: one thread starts in the middle of + // an instruction) + // + // This also checks for basic block targets jumping into + // the middle of other basic blocks. + // + // THREAD_WORK = ceil(TOTAL / # THREADS) + duint workTotal = m_MainBlocks.size(); + duint workAmount = (workTotal + (IdealThreadCount() - 1)) / IdealThreadCount(); + + // Initialize thread vectors + auto threadInserts = new std::vector[IdealThreadCount()]; + + concurrency::parallel_for(duint (0), IdealThreadCount(), [&](duint i) + { + duint threadWorkStart = (workAmount * i); + duint threadWorkStop = min((threadWorkStart + workAmount), workTotal); + + // Again, allow an overlap of +/- 1 entry + if(threadWorkStart > 0) + { + threadWorkStart = max((threadWorkStart - 1), 0); + threadWorkStop = min((threadWorkStop + 1), workTotal); + } + + // Execute + AnalysisOverlapWorker(threadWorkStart, threadWorkStop, &threadInserts[i]); + }); + + // THREAD VECTOR + std::vector overlapInserts; + { + for(duint i = 0; i < IdealThreadCount(); i++) + std::move(threadInserts[i].begin(), threadInserts[i].end(), std::back_inserter(overlapInserts)); + + // Sort and remove duplicates + std::sort(overlapInserts.begin(), overlapInserts.end()); + overlapInserts.erase(std::unique(overlapInserts.begin(), overlapInserts.end()), overlapInserts.end()); + + delete[] threadInserts; + } + + // GLOBAL VECTOR + { + // Erase blocks marked for deletion + m_MainBlocks.erase(std::remove_if(m_MainBlocks.begin(), m_MainBlocks.end(), [](BasicBlock & Elem) + { + return Elem.GetFlag(BASIC_BLOCK_FLAG_DELETE); + })); + + // Insert + std::move(overlapInserts.begin(), overlapInserts.end(), std::back_inserter(m_MainBlocks)); + + // Final sort + std::sort(m_MainBlocks.begin(), m_MainBlocks.end()); + } +} + +void LinearPass::AnalysisWorker(duint Start, duint End, BBlockArray* Blocks) +{ + Capstone disasm; + + duint blockBegin = Start; // BBlock starting virtual address + duint blockEnd; // BBlock ending virtual address + bool blockPrevPad = false; // Indicator if the last instruction was padding + BasicBlock* lastBlock = nullptr;// Avoid an expensive call to std::vector::back() + + for(duint i = Start; i < End;) + { + if(!disasm.Disassemble(i, TranslateAddress(i))) + { + // Skip instructions that can't be determined + i++; + continue; + } + + // Increment counter + i += disasm.Size(); + blockEnd = i; + + // The basic block ends here if it is a branch + bool call = disasm.InGroup(CS_GRP_CALL); // CALL + bool jmp = disasm.InGroup(CS_GRP_JUMP); // JUMP + bool ret = disasm.InGroup(CS_GRP_RET); // RETURN + bool padding = disasm.IsFilling(); // INSTRUCTION PADDING + + if(padding) + { + // PADDING is treated differently. They are all created as their + // own separate block for more analysis later. + duint realBlockEnd = blockEnd - disasm.Size(); + + if((realBlockEnd - blockBegin) > 0) + { + // The next line terminates the BBlock before the INT instruction. + // Early termination, faked as an indirect JMP. Rare case. + lastBlock = CreateBlockWorker(Blocks, blockBegin, realBlockEnd, false, false, false, false); + lastBlock->SetFlag(BASIC_BLOCK_FLAG_PREPAD); + + blockBegin = realBlockEnd; + } + } + + if(call || jmp || ret || padding) + { + // Was this a padding instruction? + if(padding && blockPrevPad) + { + // Append it to the previous block + lastBlock->VirtualEnd = blockEnd; + } + else + { + // Otherwise use the default route: create a new entry + auto block = lastBlock = CreateBlockWorker(Blocks, blockBegin, blockEnd, call, jmp, ret, padding); + + // Figure out the operand type + auto operand = disasm.x86().operands[0]; + + if(operand.type == X86_OP_IMM) + { + // Branch target immediate + block->Target = (duint)operand.imm; + + // Check if absolute jump + if(disasm.GetId() == X86_INS_JMP) + block->SetFlag(BASIC_BLOCK_FLAG_ABSJMP); + } + else + { + // Indirects + block->SetFlag(BASIC_BLOCK_FLAG_INDIRECT); + + if(operand.type == X86_OP_MEM && + operand.mem.base == X86_REG_INVALID && + operand.mem.index == X86_REG_INVALID && + operand.mem.scale == 1) + { + block->SetFlag(BASIC_BLOCK_FLAG_INDIRPTR); + block->Target = (duint)operand.mem.disp; + } + } + } + + // Reset the loop variables + blockBegin = i; + blockPrevPad = padding; + } + } +} + +void LinearPass::AnalysisOverlapWorker(duint Start, duint End, BBlockArray* Insertions) +{ + // Comparison function to see if two blocks overlap + auto BlockOverlapsRemove = [](BasicBlock * A, BasicBlock * B) -> BasicBlock* + { + // Do the blocks overlap? + if(max(A->VirtualStart, B->VirtualStart) <= min((A->VirtualEnd - 1), (B->VirtualEnd - 1))) + { + // Return the block that should be removed + if(A->Size() > B->Size()) + return B; + + return A; + } + + return nullptr; + }; + + // Get a pointer to pure data + const auto blocks = m_MainBlocks.data(); + + for(duint i = Start; i < End; i++) + { + const auto curr = &blocks[i]; + const auto next = &blocks[i + 1]; + + // Current versus next (overlap -> delete) + BasicBlock* removal = BlockOverlapsRemove(curr, next); + + if(removal) + removal->SetFlag(BASIC_BLOCK_FLAG_DELETE); + + // Find blocks that need to be split in two because + // of CALL/JMP targets + // + // Find targets in the virtual range + if(ValidateAddress(curr->Target)) + { + removal = FindBBlockInRange(curr->Target); + + // If the target does not equal the block start... + if(removal && curr->Target != removal->VirtualStart) + { + // Mark for deletion + removal->SetFlag(BASIC_BLOCK_FLAG_DELETE); + + // Block part 1 + BasicBlock block1; + block1.VirtualStart = removal->VirtualStart; + block1.VirtualEnd = curr->Target; + block1.Target = 0; + block1.Flags = BASIC_BLOCK_FLAG_CUTOFF; + + // Block part 2 + BasicBlock block2; + block2.VirtualStart = curr->Target; + block2.VirtualEnd = removal->VirtualEnd; + block2.Target = removal->Target; + block2.Flags = removal->Flags; + + Insertions->push_back(block1); + Insertions->push_back(block2); + } + } + } +} + +BasicBlock* LinearPass::CreateBlockWorker(std::vector* Blocks, duint Start, duint End, bool Call, bool Jmp, bool Ret, bool Pad) +{ + BasicBlock block; + block.VirtualStart = Start; + block.VirtualEnd = End; + block.Flags = 0; + block.Target = 0; + + // Check for calls + if(Call) + block.SetFlag(BASIC_BLOCK_FLAG_CALL); + + // Check for returns + if(Ret) + block.SetFlag(BASIC_BLOCK_FLAG_RET); + + // Check for interrupts + if(Pad) + block.SetFlag(BASIC_BLOCK_FLAG_PAD); + + Blocks->push_back(block); + return &Blocks->back(); } \ No newline at end of file diff --git a/src/dbg/LinearPass.h b/src/dbg/LinearPass.h index 0f0e7c42..395c5633 100644 --- a/src/dbg/LinearPass.h +++ b/src/dbg/LinearPass.h @@ -1,20 +1,20 @@ -#pragma once - -#include "AnalysisPass.h" -#include "BasicBlock.h" - -class LinearPass : public AnalysisPass -{ -public: - LinearPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks); - virtual ~LinearPass(); - - virtual const char* GetName() override; - virtual bool Analyse() override; - void AnalyseOverlaps(); - -private: - void AnalysisWorker(duint Start, duint End, BBlockArray* Blocks); - void AnalysisOverlapWorker(duint Start, duint End, BBlockArray* Insertions); - BasicBlock* CreateBlockWorker(BBlockArray* Blocks, duint Start, duint End, bool Call, bool Jmp, bool Ret, bool Pad); +#pragma once + +#include "AnalysisPass.h" +#include "BasicBlock.h" + +class LinearPass : public AnalysisPass +{ +public: + LinearPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks); + virtual ~LinearPass(); + + virtual const char* GetName() override; + virtual bool Analyse() override; + void AnalyseOverlaps(); + +private: + void AnalysisWorker(duint Start, duint End, BBlockArray* Blocks); + void AnalysisOverlapWorker(duint Start, duint End, BBlockArray* Insertions); + BasicBlock* CreateBlockWorker(BBlockArray* Blocks, duint Start, duint End, bool Call, bool Jmp, bool Ret, bool Pad); }; \ No newline at end of file diff --git a/src/dbg/TitanEngine/TitanEngine.h b/src/dbg/TitanEngine/TitanEngine.h index da4f3656..55d01c2b 100644 --- a/src/dbg/TitanEngine/TitanEngine.h +++ b/src/dbg/TitanEngine/TitanEngine.h @@ -1,1115 +1,1115 @@ -#ifndef TITANENGINE -#define TITANENGINE - -#define TITCALL - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include -#include - -#pragma pack(push, 1) - -// Global.Constant.Structure.Declaration: -// Engine.External: -#define UE_STRUCT_PE32STRUCT 1 -#define UE_STRUCT_PE64STRUCT 2 -#define UE_STRUCT_PESTRUCT 3 -#define UE_STRUCT_IMPORTENUMDATA 4 -#define UE_STRUCT_THREAD_ITEM_DATA 5 -#define UE_STRUCT_LIBRARY_ITEM_DATA 6 -#define UE_STRUCT_LIBRARY_ITEM_DATAW 7 -#define UE_STRUCT_PROCESS_ITEM_DATA 8 -#define UE_STRUCT_HANDLERARRAY 9 -#define UE_STRUCT_PLUGININFORMATION 10 -#define UE_STRUCT_HOOK_ENTRY 11 -#define UE_STRUCT_FILE_STATUS_INFO 12 -#define UE_STRUCT_FILE_FIX_INFO 13 -#define UE_STRUCT_X87FPUREGISTER 14 -#define UE_STRUCT_X87FPU 15 -#define UE_STRUCT_TITAN_ENGINE_CONTEXT 16 - -#define UE_ACCESS_READ 0 -#define UE_ACCESS_WRITE 1 -#define UE_ACCESS_ALL 2 - -#define UE_HIDE_PEBONLY 0 -#define UE_HIDE_BASIC 1 - -#define UE_PLUGIN_CALL_REASON_PREDEBUG 1 -#define UE_PLUGIN_CALL_REASON_EXCEPTION 2 -#define UE_PLUGIN_CALL_REASON_POSTDEBUG 3 -#define UE_PLUGIN_CALL_REASON_UNHANDLEDEXCEPTION 4 - -#define TEE_HOOK_NRM_JUMP 1 -#define TEE_HOOK_NRM_CALL 3 -#define TEE_HOOK_IAT 5 - -#define UE_ENGINE_ALOW_MODULE_LOADING 1 -#define UE_ENGINE_AUTOFIX_FORWARDERS 2 -#define UE_ENGINE_PASS_ALL_EXCEPTIONS 3 -#define UE_ENGINE_NO_CONSOLE_WINDOW 4 -#define UE_ENGINE_BACKUP_FOR_CRITICAL_FUNCTIONS 5 -#define UE_ENGINE_CALL_PLUGIN_CALLBACK 6 -#define UE_ENGINE_RESET_CUSTOM_HANDLER 7 -#define UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK 8 -#define UE_ENGINE_SET_DEBUG_PRIVILEGE 9 - -#define UE_OPTION_REMOVEALL 1 -#define UE_OPTION_DISABLEALL 2 -#define UE_OPTION_REMOVEALLDISABLED 3 -#define UE_OPTION_REMOVEALLENABLED 4 - -#define UE_STATIC_DECRYPTOR_XOR 1 -#define UE_STATIC_DECRYPTOR_SUB 2 -#define UE_STATIC_DECRYPTOR_ADD 3 - -#define UE_STATIC_DECRYPTOR_FOREWARD 1 -#define UE_STATIC_DECRYPTOR_BACKWARD 2 - -#define UE_STATIC_KEY_SIZE_1 1 -#define UE_STATIC_KEY_SIZE_2 2 -#define UE_STATIC_KEY_SIZE_4 4 -#define UE_STATIC_KEY_SIZE_8 8 - -#define UE_STATIC_APLIB 1 -#define UE_STATIC_APLIB_DEPACK 2 -#define UE_STATIC_LZMA 3 - -#define UE_STATIC_HASH_MD5 1 -#define UE_STATIC_HASH_SHA1 2 -#define UE_STATIC_HASH_CRC32 3 - -#define UE_RESOURCE_LANGUAGE_ANY -1 - -#define UE_PE_OFFSET 0 -#define UE_IMAGEBASE 1 -#define UE_OEP 2 -#define UE_SIZEOFIMAGE 3 -#define UE_SIZEOFHEADERS 4 -#define UE_SIZEOFOPTIONALHEADER 5 -#define UE_SECTIONALIGNMENT 6 -#define UE_IMPORTTABLEADDRESS 7 -#define UE_IMPORTTABLESIZE 8 -#define UE_RESOURCETABLEADDRESS 9 -#define UE_RESOURCETABLESIZE 10 -#define UE_EXPORTTABLEADDRESS 11 -#define UE_EXPORTTABLESIZE 12 -#define UE_TLSTABLEADDRESS 13 -#define UE_TLSTABLESIZE 14 -#define UE_RELOCATIONTABLEADDRESS 15 -#define UE_RELOCATIONTABLESIZE 16 -#define UE_TIMEDATESTAMP 17 -#define UE_SECTIONNUMBER 18 -#define UE_CHECKSUM 19 -#define UE_SUBSYSTEM 20 -#define UE_CHARACTERISTICS 21 -#define UE_NUMBEROFRVAANDSIZES 22 -#define UE_BASEOFCODE 23 -#define UE_BASEOFDATA 24 -//leaving some enum space here for future additions -#define UE_SECTIONNAME 40 -#define UE_SECTIONVIRTUALOFFSET 41 -#define UE_SECTIONVIRTUALSIZE 42 -#define UE_SECTIONRAWOFFSET 43 -#define UE_SECTIONRAWSIZE 44 -#define UE_SECTIONFLAGS 45 - -#define UE_VANOTFOUND = -2; - -#define UE_CH_BREAKPOINT 1 -#define UE_CH_SINGLESTEP 2 -#define UE_CH_ACCESSVIOLATION 3 -#define UE_CH_ILLEGALINSTRUCTION 4 -#define UE_CH_NONCONTINUABLEEXCEPTION 5 -#define UE_CH_ARRAYBOUNDSEXCEPTION 6 -#define UE_CH_FLOATDENORMALOPERAND 7 -#define UE_CH_FLOATDEVIDEBYZERO 8 -#define UE_CH_INTEGERDEVIDEBYZERO 9 -#define UE_CH_INTEGEROVERFLOW 10 -#define UE_CH_PRIVILEGEDINSTRUCTION 11 -#define UE_CH_PAGEGUARD 12 -#define UE_CH_EVERYTHINGELSE 13 -#define UE_CH_CREATETHREAD 14 -#define UE_CH_EXITTHREAD 15 -#define UE_CH_CREATEPROCESS 16 -#define UE_CH_EXITPROCESS 17 -#define UE_CH_LOADDLL 18 -#define UE_CH_UNLOADDLL 19 -#define UE_CH_OUTPUTDEBUGSTRING 20 -#define UE_CH_AFTEREXCEPTIONPROCESSING 21 -#define UE_CH_SYSTEMBREAKPOINT 23 -#define UE_CH_UNHANDLEDEXCEPTION 24 -#define UE_CH_RIPEVENT 25 -#define UE_CH_DEBUGEVENT 26 - -#define UE_OPTION_HANDLER_RETURN_HANDLECOUNT 1 -#define UE_OPTION_HANDLER_RETURN_ACCESS 2 -#define UE_OPTION_HANDLER_RETURN_FLAGS 3 -#define UE_OPTION_HANDLER_RETURN_TYPENAME 4 - -#define UE_BREAKPOINT_INT3 1 -#define UE_BREAKPOINT_LONG_INT3 2 -#define UE_BREAKPOINT_UD2 3 - -#define UE_BPXREMOVED 0 -#define UE_BPXACTIVE 1 -#define UE_BPXINACTIVE 2 - -#define UE_BREAKPOINT 0 -#define UE_SINGLESHOOT 1 -#define UE_HARDWARE 2 -#define UE_MEMORY 3 -#define UE_MEMORY_READ 4 -#define UE_MEMORY_WRITE 5 -#define UE_MEMORY_EXECUTE 6 -#define UE_BREAKPOINT_TYPE_INT3 0x10000000 -#define UE_BREAKPOINT_TYPE_LONG_INT3 0x20000000 -#define UE_BREAKPOINT_TYPE_UD2 0x30000000 - -#define UE_HARDWARE_EXECUTE 4 -#define UE_HARDWARE_WRITE 5 -#define UE_HARDWARE_READWRITE 6 - -#define UE_HARDWARE_SIZE_1 7 -#define UE_HARDWARE_SIZE_2 8 -#define UE_HARDWARE_SIZE_4 9 -#define UE_HARDWARE_SIZE_8 10 - -#define UE_ON_LIB_LOAD 1 -#define UE_ON_LIB_UNLOAD 2 -#define UE_ON_LIB_ALL 3 - -#define UE_APISTART 0 -#define UE_APIEND 1 - -#define UE_PLATFORM_x86 1 -#define UE_PLATFORM_x64 2 -#define UE_PLATFORM_ALL 3 - -#define UE_FUNCTION_STDCALL 1 -#define UE_FUNCTION_CCALL 2 -#define UE_FUNCTION_FASTCALL 3 -#define UE_FUNCTION_STDCALL_RET 4 -#define UE_FUNCTION_CCALL_RET 5 -#define UE_FUNCTION_FASTCALL_RET 6 -#define UE_FUNCTION_STDCALL_CALL 7 -#define UE_FUNCTION_CCALL_CALL 8 -#define UE_FUNCTION_FASTCALL_CALL 9 -#define UE_PARAMETER_BYTE 0 -#define UE_PARAMETER_WORD 1 -#define UE_PARAMETER_DWORD 2 -#define UE_PARAMETER_QWORD 3 -#define UE_PARAMETER_PTR_BYTE 4 -#define UE_PARAMETER_PTR_WORD 5 -#define UE_PARAMETER_PTR_DWORD 6 -#define UE_PARAMETER_PTR_QWORD 7 -#define UE_PARAMETER_STRING 8 -#define UE_PARAMETER_UNICODE 9 - -#define UE_EAX 1 -#define UE_EBX 2 -#define UE_ECX 3 -#define UE_EDX 4 -#define UE_EDI 5 -#define UE_ESI 6 -#define UE_EBP 7 -#define UE_ESP 8 -#define UE_EIP 9 -#define UE_EFLAGS 10 -#define UE_DR0 11 -#define UE_DR1 12 -#define UE_DR2 13 -#define UE_DR3 14 -#define UE_DR6 15 -#define UE_DR7 16 -#define UE_RAX 17 -#define UE_RBX 18 -#define UE_RCX 19 -#define UE_RDX 20 -#define UE_RDI 21 -#define UE_RSI 22 -#define UE_RBP 23 -#define UE_RSP 24 -#define UE_RIP 25 -#define UE_RFLAGS 26 -#define UE_R8 27 -#define UE_R9 28 -#define UE_R10 29 -#define UE_R11 30 -#define UE_R12 31 -#define UE_R13 32 -#define UE_R14 33 -#define UE_R15 34 -#define UE_CIP 35 -#define UE_CSP 36 -#ifdef _WIN64 -#define UE_CFLAGS UE_RFLAGS -#else -#define UE_CFLAGS UE_EFLAGS -#endif -#define UE_SEG_GS 37 -#define UE_SEG_FS 38 -#define UE_SEG_ES 39 -#define UE_SEG_DS 40 -#define UE_SEG_CS 41 -#define UE_SEG_SS 42 -#define UE_x87_r0 43 -#define UE_x87_r1 44 -#define UE_x87_r2 45 -#define UE_x87_r3 46 -#define UE_x87_r4 47 -#define UE_x87_r5 48 -#define UE_x87_r6 49 -#define UE_x87_r7 50 -#define UE_X87_STATUSWORD 51 -#define UE_X87_CONTROLWORD 52 -#define UE_X87_TAGWORD 53 -#define UE_MXCSR 54 -#define UE_MMX0 55 -#define UE_MMX1 56 -#define UE_MMX2 57 -#define UE_MMX3 58 -#define UE_MMX4 59 -#define UE_MMX5 60 -#define UE_MMX6 61 -#define UE_MMX7 62 -#define UE_XMM0 63 -#define UE_XMM1 64 -#define UE_XMM2 65 -#define UE_XMM3 66 -#define UE_XMM4 67 -#define UE_XMM5 68 -#define UE_XMM6 69 -#define UE_XMM7 70 -#define UE_XMM8 71 -#define UE_XMM9 72 -#define UE_XMM10 73 -#define UE_XMM11 74 -#define UE_XMM12 75 -#define UE_XMM13 76 -#define UE_XMM14 77 -#define UE_XMM15 78 -#define UE_x87_ST0 79 -#define UE_x87_ST1 80 -#define UE_x87_ST2 81 -#define UE_x87_ST3 82 -#define UE_x87_ST4 83 -#define UE_x87_ST5 84 -#define UE_x87_ST6 85 -#define UE_x87_ST7 86 -#define UE_YMM0 87 -#define UE_YMM1 88 -#define UE_YMM2 89 -#define UE_YMM3 90 -#define UE_YMM4 91 -#define UE_YMM5 92 -#define UE_YMM6 93 -#define UE_YMM7 94 -#define UE_YMM8 95 -#define UE_YMM9 96 -#define UE_YMM10 97 -#define UE_YMM11 98 -#define UE_YMM12 99 -#define UE_YMM13 100 -#define UE_YMM14 101 -#define UE_YMM15 102 - -#ifndef CONTEXT_EXTENDED_REGISTERS -#define CONTEXT_EXTENDED_REGISTERS 0 -#endif - -typedef struct -{ - DWORD PE32Offset; - DWORD ImageBase; - DWORD OriginalEntryPoint; - DWORD BaseOfCode; - DWORD BaseOfData; - DWORD NtSizeOfImage; - DWORD NtSizeOfHeaders; - WORD SizeOfOptionalHeaders; - DWORD FileAlignment; - DWORD SectionAligment; - DWORD ImportTableAddress; - DWORD ImportTableSize; - DWORD ResourceTableAddress; - DWORD ResourceTableSize; - DWORD ExportTableAddress; - DWORD ExportTableSize; - DWORD TLSTableAddress; - DWORD TLSTableSize; - DWORD RelocationTableAddress; - DWORD RelocationTableSize; - DWORD TimeDateStamp; - WORD SectionNumber; - DWORD CheckSum; - WORD SubSystem; - WORD Characteristics; - DWORD NumberOfRvaAndSizes; -} PE32Struct, *PPE32Struct; - -typedef struct -{ - DWORD PE64Offset; - DWORD64 ImageBase; - DWORD OriginalEntryPoint; - DWORD BaseOfCode; - DWORD BaseOfData; - DWORD NtSizeOfImage; - DWORD NtSizeOfHeaders; - WORD SizeOfOptionalHeaders; - DWORD FileAlignment; - DWORD SectionAligment; - DWORD ImportTableAddress; - DWORD ImportTableSize; - DWORD ResourceTableAddress; - DWORD ResourceTableSize; - DWORD ExportTableAddress; - DWORD ExportTableSize; - DWORD TLSTableAddress; - DWORD TLSTableSize; - DWORD RelocationTableAddress; - DWORD RelocationTableSize; - DWORD TimeDateStamp; - WORD SectionNumber; - DWORD CheckSum; - WORD SubSystem; - WORD Characteristics; - DWORD NumberOfRvaAndSizes; -} PE64Struct, *PPE64Struct; - -#if defined(_WIN64) -typedef PE64Struct PEStruct; -#else -typedef PE32Struct PEStruct; -#endif - -typedef struct -{ - bool NewDll; - int NumberOfImports; - ULONG_PTR ImageBase; - ULONG_PTR BaseImportThunk; - ULONG_PTR ImportThunk; - char* APIName; - char* DLLName; -} ImportEnumData, *PImportEnumData; - -typedef struct -{ - HANDLE hThread; - DWORD dwThreadId; - void* ThreadStartAddress; - void* ThreadLocalBase; - void* TebAddress; - ULONG WaitTime; - LONG Priority; - LONG BasePriority; - ULONG ContextSwitches; - ULONG ThreadState; - ULONG WaitReason; -} THREAD_ITEM_DATA, *PTHREAD_ITEM_DATA; - -typedef struct -{ - HANDLE hFile; - void* BaseOfDll; - HANDLE hFileMapping; - void* hFileMappingView; - char szLibraryPath[MAX_PATH]; - char szLibraryName[MAX_PATH]; -} LIBRARY_ITEM_DATA, *PLIBRARY_ITEM_DATA; - -typedef struct -{ - HANDLE hFile; - void* BaseOfDll; - HANDLE hFileMapping; - void* hFileMappingView; - wchar_t szLibraryPath[MAX_PATH]; - wchar_t szLibraryName[MAX_PATH]; -} LIBRARY_ITEM_DATAW, *PLIBRARY_ITEM_DATAW; - -typedef struct -{ - HANDLE hProcess; - DWORD dwProcessId; - HANDLE hThread; - DWORD dwThreadId; - HANDLE hFile; - void* BaseOfImage; - void* ThreadStartAddress; - void* ThreadLocalBase; -} PROCESS_ITEM_DATA, *PPROCESS_ITEM_DATA; - -typedef struct -{ - ULONG ProcessId; - HANDLE hHandle; -} HandlerArray, *PHandlerArray; - -typedef struct -{ - char PluginName[64]; - DWORD PluginMajorVersion; - DWORD PluginMinorVersion; - HMODULE PluginBaseAddress; - void* TitanDebuggingCallBack; - void* TitanRegisterPlugin; - void* TitanReleasePlugin; - void* TitanResetPlugin; - bool PluginDisabled; -} PluginInformation, *PPluginInformation; - -#define TEE_MAXIMUM_HOOK_SIZE 14 -#define TEE_MAXIMUM_HOOK_RELOCS 7 -#if defined(_WIN64) -#define TEE_MAXIMUM_HOOK_INSERT_SIZE 14 -#else -#define TEE_MAXIMUM_HOOK_INSERT_SIZE 5 -#endif - -typedef struct HOOK_ENTRY -{ - bool IATHook; - BYTE HookType; - DWORD HookSize; - void* HookAddress; - void* RedirectionAddress; - BYTE HookBytes[TEE_MAXIMUM_HOOK_SIZE]; - BYTE OriginalBytes[TEE_MAXIMUM_HOOK_SIZE]; - void* IATHookModuleBase; - DWORD IATHookNameHash; - bool HookIsEnabled; - bool HookIsRemote; - void* PatchedEntry; - DWORD RelocationInfo[TEE_MAXIMUM_HOOK_RELOCS]; - int RelocationCount; -} HOOK_ENTRY, *PHOOK_ENTRY; - -#define UE_DEPTH_SURFACE 0 -#define UE_DEPTH_DEEP 1 - -#define UE_UNPACKER_CONDITION_SEARCH_FROM_EP 1 - -#define UE_UNPACKER_CONDITION_LOADLIBRARY 1 -#define UE_UNPACKER_CONDITION_GETPROCADDRESS 2 -#define UE_UNPACKER_CONDITION_ENTRYPOINTBREAK 3 -#define UE_UNPACKER_CONDITION_RELOCSNAPSHOT1 4 -#define UE_UNPACKER_CONDITION_RELOCSNAPSHOT2 5 - -#define UE_FIELD_OK 0 -#define UE_FIELD_BROKEN_NON_FIXABLE 1 -#define UE_FIELD_BROKEN_NON_CRITICAL 2 -#define UE_FIELD_BROKEN_FIXABLE_FOR_STATIC_USE 3 -#define UE_FIELD_BROKEN_BUT_CAN_BE_EMULATED 4 -#define UE_FIELD_FIXABLE_NON_CRITICAL 5 -#define UE_FIELD_FIXABLE_CRITICAL 6 -#define UE_FIELD_NOT_PRESET 7 -#define UE_FIELD_NOT_PRESET_WARNING 8 - -#define UE_RESULT_FILE_OK 10 -#define UE_RESULT_FILE_INVALID_BUT_FIXABLE 11 -#define UE_RESULT_FILE_INVALID_AND_NON_FIXABLE 12 -#define UE_RESULT_FILE_INVALID_FORMAT 13 - -typedef struct -{ - BYTE OveralEvaluation; - bool EvaluationTerminatedByException; - bool FileIs64Bit; - bool FileIsDLL; - bool FileIsConsole; - bool MissingDependencies; - bool MissingDeclaredAPIs; - BYTE SignatureMZ; - BYTE SignaturePE; - BYTE EntryPoint; - BYTE ImageBase; - BYTE SizeOfImage; - BYTE FileAlignment; - BYTE SectionAlignment; - BYTE ExportTable; - BYTE RelocationTable; - BYTE ImportTable; - BYTE ImportTableSection; - BYTE ImportTableData; - BYTE IATTable; - BYTE TLSTable; - BYTE LoadConfigTable; - BYTE BoundImportTable; - BYTE COMHeaderTable; - BYTE ResourceTable; - BYTE ResourceData; - BYTE SectionTable; -} FILE_STATUS_INFO, *PFILE_STATUS_INFO; - -typedef struct -{ - BYTE OveralEvaluation; - bool FixingTerminatedByException; - bool FileFixPerformed; - bool StrippedRelocation; - bool DontFixRelocations; - DWORD OriginalRelocationTableAddress; - DWORD OriginalRelocationTableSize; - bool StrippedExports; - bool DontFixExports; - DWORD OriginalExportTableAddress; - DWORD OriginalExportTableSize; - bool StrippedResources; - bool DontFixResources; - DWORD OriginalResourceTableAddress; - DWORD OriginalResourceTableSize; - bool StrippedTLS; - bool DontFixTLS; - DWORD OriginalTLSTableAddress; - DWORD OriginalTLSTableSize; - bool StrippedLoadConfig; - bool DontFixLoadConfig; - DWORD OriginalLoadConfigTableAddress; - DWORD OriginalLoadConfigTableSize; - bool StrippedBoundImports; - bool DontFixBoundImports; - DWORD OriginalBoundImportTableAddress; - DWORD OriginalBoundImportTableSize; - bool StrippedIAT; - bool DontFixIAT; - DWORD OriginalImportAddressTableAddress; - DWORD OriginalImportAddressTableSize; - bool StrippedCOM; - bool DontFixCOM; - DWORD OriginalCOMTableAddress; - DWORD OriginalCOMTableSize; -} FILE_FIX_INFO, *PFILE_FIX_INFO; - -typedef struct DECLSPEC_ALIGN(16) _XmmRegister_t -{ - ULONGLONG Low; - LONGLONG High; -} XmmRegister_t; - -typedef struct -{ - XmmRegister_t Low; //XMM/SSE part - XmmRegister_t High; //AVX part -} YmmRegister_t; - -typedef struct -{ - BYTE data[10]; - int st_value; - int tag; -} x87FPURegister_t; - -typedef struct -{ - WORD ControlWord; - WORD StatusWord; - WORD TagWord; - DWORD ErrorOffset; - DWORD ErrorSelector; - DWORD DataOffset; - DWORD DataSelector; - DWORD Cr0NpxState; -} x87FPU_t; - -typedef struct -{ - ULONG_PTR cax; - ULONG_PTR ccx; - ULONG_PTR cdx; - ULONG_PTR cbx; - ULONG_PTR csp; - ULONG_PTR cbp; - ULONG_PTR csi; - ULONG_PTR cdi; -#ifdef _WIN64 - ULONG_PTR r8; - ULONG_PTR r9; - ULONG_PTR r10; - ULONG_PTR r11; - ULONG_PTR r12; - ULONG_PTR r13; - ULONG_PTR r14; - ULONG_PTR r15; -#endif //_WIN64 - ULONG_PTR cip; - ULONG_PTR eflags; - unsigned short gs; - unsigned short fs; - unsigned short es; - unsigned short ds; - unsigned short cs; - unsigned short ss; - ULONG_PTR dr0; - ULONG_PTR dr1; - ULONG_PTR dr2; - ULONG_PTR dr3; - ULONG_PTR dr6; - ULONG_PTR dr7; - BYTE RegisterArea[80]; - x87FPU_t x87fpu; - DWORD MxCsr; -#ifdef _WIN64 - XmmRegister_t XmmRegisters[16]; - YmmRegister_t YmmRegisters[16]; -#else // x86 - XmmRegister_t XmmRegisters[8]; - YmmRegister_t YmmRegisters[8]; -#endif -} TITAN_ENGINE_CONTEXT_t; - -#ifdef __cplusplus -extern "C" -{ -#endif - -// Global.Function.Declaration: -// TitanEngine.Dumper.functions: -__declspec(dllexport) bool TITCALL DumpProcess(HANDLE hProcess, LPVOID ImageBase, const char* szDumpFileName, ULONG_PTR EntryPoint); -__declspec(dllexport) bool TITCALL DumpProcessW(HANDLE hProcess, LPVOID ImageBase, const wchar_t* szDumpFileName, ULONG_PTR EntryPoint); -__declspec(dllexport) bool TITCALL DumpProcessEx(DWORD ProcessId, LPVOID ImageBase, const char* szDumpFileName, ULONG_PTR EntryPoint); -__declspec(dllexport) bool TITCALL DumpProcessExW(DWORD ProcessId, LPVOID ImageBase, const wchar_t* szDumpFileName, ULONG_PTR EntryPoint); -__declspec(dllexport) bool TITCALL DumpMemory(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpMemoryW(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpMemoryEx(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpMemoryExW(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpRegions(HANDLE hProcess, const char* szDumpFolder, bool DumpAboveImageBaseOnly); -__declspec(dllexport) bool TITCALL DumpRegionsW(HANDLE hProcess, const wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly); -__declspec(dllexport) bool TITCALL DumpRegionsEx(DWORD ProcessId, const char* szDumpFolder, bool DumpAboveImageBaseOnly); -__declspec(dllexport) bool TITCALL DumpRegionsExW(DWORD ProcessId, const wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly); -__declspec(dllexport) bool TITCALL DumpModule(HANDLE hProcess, LPVOID ModuleBase, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpModuleW(HANDLE hProcess, LPVOID ModuleBase, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpModuleEx(DWORD ProcessId, LPVOID ModuleBase, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpModuleExW(DWORD ProcessId, LPVOID ModuleBase, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL PastePEHeader(HANDLE hProcess, LPVOID ImageBase, const char* szDebuggedFileName); -__declspec(dllexport) bool TITCALL PastePEHeaderW(HANDLE hProcess, LPVOID ImageBase, const wchar_t* szDebuggedFileName); -__declspec(dllexport) bool TITCALL ExtractSection(const char* szFileName, const char* szDumpFileName, DWORD SectionNumber); -__declspec(dllexport) bool TITCALL ExtractSectionW(const wchar_t* szFileName, const wchar_t* szDumpFileName, DWORD SectionNumber); -__declspec(dllexport) bool TITCALL ResortFileSections(const char* szFileName); -__declspec(dllexport) bool TITCALL ResortFileSectionsW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL FindOverlay(const char* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize); -__declspec(dllexport) bool TITCALL FindOverlayW(const wchar_t* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize); -__declspec(dllexport) bool TITCALL ExtractOverlay(const char* szFileName, const char* szExtactedFileName); -__declspec(dllexport) bool TITCALL ExtractOverlayW(const wchar_t* szFileName, const wchar_t* szExtactedFileName); -__declspec(dllexport) bool TITCALL AddOverlay(const char* szFileName, const char* szOverlayFileName); -__declspec(dllexport) bool TITCALL AddOverlayW(const wchar_t* szFileName, const wchar_t* szOverlayFileName); -__declspec(dllexport) bool TITCALL CopyOverlay(const char* szInFileName, const char* szOutFileName); -__declspec(dllexport) bool TITCALL CopyOverlayW(const wchar_t* szInFileName, const wchar_t* szOutFileName); -__declspec(dllexport) bool TITCALL RemoveOverlay(const char* szFileName); -__declspec(dllexport) bool TITCALL RemoveOverlayW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL MakeAllSectionsRWE(const char* szFileName); -__declspec(dllexport) bool TITCALL MakeAllSectionsRWEW(const wchar_t* szFileName); -__declspec(dllexport) long TITCALL AddNewSectionEx(const char* szFileName, const char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize); -__declspec(dllexport) long TITCALL AddNewSectionExW(const wchar_t* szFileName, const char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize); -__declspec(dllexport) long TITCALL AddNewSection(const char* szFileName, const char* szSectionName, DWORD SectionSize); -__declspec(dllexport) long TITCALL AddNewSectionW(const wchar_t* szFileName, const char* szSectionName, DWORD SectionSize); -__declspec(dllexport) bool TITCALL ResizeLastSection(const char* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData); -__declspec(dllexport) bool TITCALL ResizeLastSectionW(const wchar_t* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData); -__declspec(dllexport) void TITCALL SetSharedOverlay(const char* szFileName); -__declspec(dllexport) void TITCALL SetSharedOverlayW(const wchar_t* szFileName); -__declspec(dllexport) char* TITCALL GetSharedOverlay(); -__declspec(dllexport) wchar_t* TITCALL GetSharedOverlayW(); -__declspec(dllexport) bool TITCALL DeleteLastSection(const char* szFileName); -__declspec(dllexport) bool TITCALL DeleteLastSectionW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL DeleteLastSectionEx(const char* szFileName, DWORD NumberOfSections); -__declspec(dllexport) bool TITCALL DeleteLastSectionExW(const wchar_t* szFileName, DWORD NumberOfSections); -__declspec(dllexport) ULONG_PTR TITCALL GetPE32DataFromMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData); -__declspec(dllexport) ULONG_PTR TITCALL GetPE32Data(const char* szFileName, DWORD WhichSection, DWORD WhichData); -__declspec(dllexport) ULONG_PTR TITCALL GetPE32DataW(const wchar_t* szFileName, DWORD WhichSection, DWORD WhichData); -__declspec(dllexport) bool TITCALL GetPE32DataFromMappedFileEx(ULONG_PTR FileMapVA, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL GetPE32DataEx(const char* szFileName, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL GetPE32DataExW(const wchar_t* szFileName, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL SetPE32DataForMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); -__declspec(dllexport) bool TITCALL SetPE32Data(const char* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); -__declspec(dllexport) bool TITCALL SetPE32DataW(const wchar_t* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); -__declspec(dllexport) bool TITCALL SetPE32DataForMappedFileEx(ULONG_PTR FileMapVA, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL SetPE32DataEx(const char* szFileName, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL SetPE32DataExW(const wchar_t* szFileName, LPVOID DataStorage); -__declspec(dllexport) long TITCALL GetPE32SectionNumberFromVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert); -__declspec(dllexport) ULONG_PTR TITCALL ConvertVAtoFileOffset(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType); -__declspec(dllexport) ULONG_PTR TITCALL ConvertVAtoFileOffsetEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool AddressIsRVA, bool ReturnType); -__declspec(dllexport) ULONG_PTR TITCALL ConvertFileOffsetToVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType); -__declspec(dllexport) ULONG_PTR TITCALL ConvertFileOffsetToVAEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool ReturnType); -__declspec(dllexport) bool TITCALL MemoryReadSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead); -__declspec(dllexport) bool TITCALL MemoryWriteSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten); -// TitanEngine.Realigner.functions: -__declspec(dllexport) bool TITCALL FixHeaderCheckSum(const char* szFileName); -__declspec(dllexport) bool TITCALL FixHeaderCheckSumW(const wchar_t* szFileName); -__declspec(dllexport) long TITCALL RealignPE(ULONG_PTR FileMapVA, DWORD FileSize, DWORD RealingMode); -__declspec(dllexport) long TITCALL RealignPEEx(const char* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment); -__declspec(dllexport) long TITCALL RealignPEExW(const wchar_t* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment); -__declspec(dllexport) bool TITCALL WipeSection(const char* szFileName, int WipeSectionNumber, bool RemovePhysically); -__declspec(dllexport) bool TITCALL WipeSectionW(const wchar_t* szFileName, int WipeSectionNumber, bool RemovePhysically); -__declspec(dllexport) bool TITCALL IsPE32FileValidEx(const char* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo); -__declspec(dllexport) bool TITCALL IsPE32FileValidExW(const wchar_t* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo); -__declspec(dllexport) bool TITCALL FixBrokenPE32FileEx(const char* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo); -__declspec(dllexport) bool TITCALL FixBrokenPE32FileExW(const wchar_t* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo); -__declspec(dllexport) bool TITCALL IsFileDLL(const char* szFileName, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL IsFileDLLW(const wchar_t* szFileName, ULONG_PTR FileMapVA); -// TitanEngine.Hider.functions: -__declspec(dllexport) void* TITCALL GetPEBLocation(HANDLE hProcess); -__declspec(dllexport) void* TITCALL GetPEBLocation64(HANDLE hProcess); -__declspec(dllexport) void* TITCALL GetTEBLocation(HANDLE hThread); -__declspec(dllexport) void* TITCALL GetTEBLocation64(HANDLE hThread); -__declspec(dllexport) bool TITCALL HideDebugger(HANDLE hProcess, DWORD PatchAPILevel); -__declspec(dllexport) bool TITCALL UnHideDebugger(HANDLE hProcess, DWORD PatchAPILevel); -// TitanEngine.Relocater.functions: -__declspec(dllexport) void TITCALL RelocaterCleanup(); -__declspec(dllexport) void TITCALL RelocaterInit(DWORD MemorySize, ULONG_PTR OldImageBase, ULONG_PTR NewImageBase); -__declspec(dllexport) void TITCALL RelocaterAddNewRelocation(HANDLE hProcess, ULONG_PTR RelocateAddress, DWORD RelocateState); -__declspec(dllexport) long TITCALL RelocaterEstimatedSize(); -__declspec(dllexport) bool TITCALL RelocaterExportRelocation(ULONG_PTR StorePlace, DWORD StorePlaceRVA, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL RelocaterExportRelocationEx(const char* szFileName, const char* szSectionName); -__declspec(dllexport) bool TITCALL RelocaterExportRelocationExW(const wchar_t* szFileName, const char* szSectionName); -__declspec(dllexport) bool TITCALL RelocaterGrabRelocationTable(HANDLE hProcess, ULONG_PTR MemoryStart, DWORD MemorySize); -__declspec(dllexport) bool TITCALL RelocaterGrabRelocationTableEx(HANDLE hProcess, ULONG_PTR MemoryStart, ULONG_PTR MemorySize, DWORD NtSizeOfImage); -__declspec(dllexport) bool TITCALL RelocaterMakeSnapshot(HANDLE hProcess, const char* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize); -__declspec(dllexport) bool TITCALL RelocaterMakeSnapshotW(HANDLE hProcess, const wchar_t* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize); -__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshots(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, const char* szDumpFile1, const char* szDumpFile2, ULONG_PTR MemStart); -__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshotsW(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, const wchar_t* szDumpFile1, const wchar_t* szDumpFile2, ULONG_PTR MemStart); -__declspec(dllexport) bool TITCALL RelocaterChangeFileBase(const char* szFileName, ULONG_PTR NewImageBase); -__declspec(dllexport) bool TITCALL RelocaterChangeFileBaseW(const wchar_t* szFileName, ULONG_PTR NewImageBase); -__declspec(dllexport) bool TITCALL RelocaterRelocateMemoryBlock(ULONG_PTR FileMapVA, ULONG_PTR MemoryLocation, void* RelocateMemory, DWORD RelocateMemorySize, ULONG_PTR CurrentLoadedBase, ULONG_PTR RelocateBase); -__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTable(const char* szFileName); -__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTableW(const wchar_t* szFileName); -// TitanEngine.Resourcer.functions: -__declspec(dllexport) ULONG_PTR TITCALL ResourcerLoadFileForResourceUse(const char* szFileName); -__declspec(dllexport) ULONG_PTR TITCALL ResourcerLoadFileForResourceUseW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL ResourcerFreeLoadedFile(LPVOID LoadedFileBase); -__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileEx(ULONG_PTR FileMapVA, const char* szResourceType, const char* szResourceName, const char* szExtractedFileName); -__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFile(const char* szFileName, const char* szResourceType, const char* szResourceName, const char* szExtractedFileName); -__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileW(const wchar_t* szFileName, char* szResourceType, const char* szResourceName, const char* szExtractedFileName); -__declspec(dllexport) bool TITCALL ResourcerFindResource(const char* szFileName, const char* szResourceType, DWORD ResourceType, const char* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); -__declspec(dllexport) bool TITCALL ResourcerFindResourceW(const wchar_t* szFileName, const wchar_t* szResourceType, DWORD ResourceType, const wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); -__declspec(dllexport) bool TITCALL ResourcerFindResourceEx(ULONG_PTR FileMapVA, DWORD FileSize, const wchar_t* szResourceType, DWORD ResourceType, const wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); -__declspec(dllexport) void TITCALL ResourcerEnumerateResource(const char* szFileName, void* CallBack); -__declspec(dllexport) void TITCALL ResourcerEnumerateResourceW(const wchar_t* szFileName, void* CallBack); -__declspec(dllexport) void TITCALL ResourcerEnumerateResourceEx(ULONG_PTR FileMapVA, DWORD FileSize, void* CallBack); -// TitanEngine.Threader.functions: -__declspec(dllexport) bool TITCALL ThreaderImportRunningThreadData(DWORD ProcessId); -__declspec(dllexport) void* TITCALL ThreaderGetThreadInfo(HANDLE hThread, DWORD ThreadId); -__declspec(dllexport) void TITCALL ThreaderEnumThreadInfo(void* EnumCallBack); -__declspec(dllexport) bool TITCALL ThreaderPauseThread(HANDLE hThread); -__declspec(dllexport) bool TITCALL ThreaderResumeThread(HANDLE hThread); -__declspec(dllexport) bool TITCALL ThreaderTerminateThread(HANDLE hThread, DWORD ThreadExitCode); -__declspec(dllexport) bool TITCALL ThreaderPauseAllThreads(bool LeaveMainRunning); -__declspec(dllexport) bool TITCALL ThreaderResumeAllThreads(bool LeaveMainPaused); -__declspec(dllexport) bool TITCALL ThreaderPauseProcess(); -__declspec(dllexport) bool TITCALL ThreaderResumeProcess(); -__declspec(dllexport) ULONG_PTR TITCALL ThreaderCreateRemoteThread(ULONG_PTR ThreadStartAddress, bool AutoCloseTheHandle, LPVOID ThreadPassParameter, LPDWORD ThreadId); -__declspec(dllexport) bool TITCALL ThreaderInjectAndExecuteCode(LPVOID InjectCode, DWORD StartDelta, DWORD InjectSize); -__declspec(dllexport) ULONG_PTR TITCALL ThreaderCreateRemoteThreadEx(HANDLE hProcess, ULONG_PTR ThreadStartAddress, bool AutoCloseTheHandle, LPVOID ThreadPassParameter, LPDWORD ThreadId); -__declspec(dllexport) bool TITCALL ThreaderInjectAndExecuteCodeEx(HANDLE hProcess, LPVOID InjectCode, DWORD StartDelta, DWORD InjectSize); -__declspec(dllexport) void TITCALL ThreaderSetCallBackForNextExitThreadEvent(LPVOID exitThreadCallBack); -__declspec(dllexport) bool TITCALL ThreaderIsThreadStillRunning(HANDLE hThread); -__declspec(dllexport) bool TITCALL ThreaderIsThreadActive(HANDLE hThread); -__declspec(dllexport) bool TITCALL ThreaderIsAnyThreadActive(); -__declspec(dllexport) bool TITCALL ThreaderExecuteOnlyInjectedThreads(); -__declspec(dllexport) ULONG_PTR TITCALL ThreaderGetOpenHandleForThread(DWORD ThreadId); -__declspec(dllexport) bool TITCALL ThreaderIsExceptionInMainThread(); -// TitanEngine.Debugger.functions: -__declspec(dllexport) void* TITCALL StaticDisassembleEx(ULONG_PTR DisassmStart, LPVOID DisassmAddress); -__declspec(dllexport) void* TITCALL StaticDisassemble(LPVOID DisassmAddress); -__declspec(dllexport) void* TITCALL DisassembleEx(HANDLE hProcess, LPVOID DisassmAddress, bool ReturnInstructionType); -__declspec(dllexport) void* TITCALL Disassemble(LPVOID DisassmAddress); -__declspec(dllexport) long TITCALL StaticLengthDisassemble(LPVOID DisassmAddress); -__declspec(dllexport) long TITCALL LengthDisassembleEx(HANDLE hProcess, LPVOID DisassmAddress); -__declspec(dllexport) long TITCALL LengthDisassemble(LPVOID DisassmAddress); -__declspec(dllexport) void* TITCALL InitDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder); -__declspec(dllexport) void* TITCALL InitDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder); -__declspec(dllexport) void* TITCALL InitDebugEx(const char* szFileName, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack); -__declspec(dllexport) void* TITCALL InitDebugExW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, LPVOID EntryCallBack); -__declspec(dllexport) void* TITCALL InitDLLDebug(const char* szFileName, bool ReserveModuleBase, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack); -__declspec(dllexport) void* TITCALL InitDLLDebugW(const wchar_t* szFileName, bool ReserveModuleBase, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, LPVOID EntryCallBack); -__declspec(dllexport) bool TITCALL StopDebug(); -__declspec(dllexport) void TITCALL SetBPXOptions(long DefaultBreakPointType); -__declspec(dllexport) bool TITCALL IsBPXEnabled(ULONG_PTR bpxAddress); -__declspec(dllexport) bool TITCALL EnableBPX(ULONG_PTR bpxAddress); -__declspec(dllexport) bool TITCALL DisableBPX(ULONG_PTR bpxAddress); -__declspec(dllexport) bool TITCALL SetBPX(ULONG_PTR bpxAddress, DWORD bpxType, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL DeleteBPX(ULONG_PTR bpxAddress); -__declspec(dllexport) bool TITCALL SafeDeleteBPX(ULONG_PTR bpxAddress); -__declspec(dllexport) bool TITCALL SetAPIBreakPoint(const char* szDLLName, const char* szAPIName, DWORD bpxType, DWORD bpxPlace, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL DeleteAPIBreakPoint(const char* szDLLName, const char* szAPIName, DWORD bpxPlace); -__declspec(dllexport) bool TITCALL SafeDeleteAPIBreakPoint(const char* szDLLName, const char* szAPIName, DWORD bpxPlace); -__declspec(dllexport) bool TITCALL SetMemoryBPX(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL SetMemoryBPXEx(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory, DWORD BreakPointType, bool RestoreOnHit, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL RemoveMemoryBPX(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory); -__declspec(dllexport) bool TITCALL GetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea); -__declspec(dllexport) void TITCALL Getx87FPURegisters(x87FPURegister_t x87FPURegisters[8], TITAN_ENGINE_CONTEXT_t* titcontext); -__declspec(dllexport) void TITCALL GetMMXRegisters(uint64_t mmx[8], TITAN_ENGINE_CONTEXT_t* titcontext); -__declspec(dllexport) bool TITCALL GetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); -__declspec(dllexport) bool TITCALL SetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); -__declspec(dllexport) ULONG_PTR TITCALL GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister); -__declspec(dllexport) ULONG_PTR TITCALL GetContextData(DWORD IndexOfRegister); -__declspec(dllexport) bool TITCALL SetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea); -__declspec(dllexport) bool TITCALL SetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister, ULONG_PTR NewRegisterValue); -__declspec(dllexport) bool TITCALL SetContextData(DWORD IndexOfRegister, ULONG_PTR NewRegisterValue); -__declspec(dllexport) bool TITCALL GetAVXContext(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); -__declspec(dllexport) bool TITCALL SetAVXContext(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); -__declspec(dllexport) void TITCALL ClearExceptionNumber(); -__declspec(dllexport) long TITCALL CurrentExceptionNumber(); -__declspec(dllexport) bool TITCALL MatchPatternEx(HANDLE hProcess, void* MemoryToCheck, int SizeOfMemoryToCheck, void* PatternToMatch, int SizeOfPatternToMatch, PBYTE WildCard); -__declspec(dllexport) bool TITCALL MatchPattern(void* MemoryToCheck, int SizeOfMemoryToCheck, void* PatternToMatch, int SizeOfPatternToMatch, PBYTE WildCard); -__declspec(dllexport) ULONG_PTR TITCALL FindEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, LPBYTE WildCard); -extern "C" __declspec(dllexport) ULONG_PTR TITCALL Find(LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, LPBYTE WildCard); -__declspec(dllexport) bool TITCALL FillEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, PBYTE FillByte); -__declspec(dllexport) bool TITCALL Fill(LPVOID MemoryStart, DWORD MemorySize, PBYTE FillByte); -__declspec(dllexport) bool TITCALL PatchEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, LPVOID ReplacePattern, DWORD ReplaceSize, bool AppendNOP, bool PrependNOP); -__declspec(dllexport) bool TITCALL Patch(LPVOID MemoryStart, DWORD MemorySize, LPVOID ReplacePattern, DWORD ReplaceSize, bool AppendNOP, bool PrependNOP); -__declspec(dllexport) bool TITCALL ReplaceEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, DWORD NumberOfRepetitions, LPVOID ReplacePattern, DWORD ReplaceSize, PBYTE WildCard); -__declspec(dllexport) bool TITCALL Replace(LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, DWORD NumberOfRepetitions, LPVOID ReplacePattern, DWORD ReplaceSize, PBYTE WildCard); -__declspec(dllexport) void* TITCALL GetDebugData(); -__declspec(dllexport) void* TITCALL GetTerminationData(); -__declspec(dllexport) long TITCALL GetExitCode(); -__declspec(dllexport) ULONG_PTR TITCALL GetDebuggedDLLBaseAddress(); -__declspec(dllexport) ULONG_PTR TITCALL GetDebuggedFileBaseAddress(); -__declspec(dllexport) bool TITCALL GetRemoteString(HANDLE hProcess, LPVOID StringAddress, LPVOID StringStorage, int MaximumStringSize); -__declspec(dllexport) ULONG_PTR TITCALL GetFunctionParameter(HANDLE hProcess, DWORD FunctionType, DWORD ParameterNumber, DWORD ParameterType); -__declspec(dllexport) ULONG_PTR TITCALL GetJumpDestinationEx(HANDLE hProcess, ULONG_PTR InstructionAddress, bool JustJumps); -__declspec(dllexport) ULONG_PTR TITCALL GetJumpDestination(HANDLE hProcess, ULONG_PTR InstructionAddress); -__declspec(dllexport) bool TITCALL IsJumpGoingToExecuteEx(HANDLE hProcess, HANDLE hThread, ULONG_PTR InstructionAddress, ULONG_PTR RegFlags); -__declspec(dllexport) bool TITCALL IsJumpGoingToExecute(); -__declspec(dllexport) void TITCALL SetCustomHandler(DWORD ExceptionId, LPVOID CallBack); -__declspec(dllexport) void TITCALL ForceClose(); -__declspec(dllexport) void TITCALL StepInto(LPVOID traceCallBack); -__declspec(dllexport) void TITCALL StepOver(LPVOID traceCallBack); -__declspec(dllexport) void TITCALL StepOut(LPVOID StepOut, bool StepFinal); -__declspec(dllexport) void TITCALL SingleStep(DWORD StepCount, LPVOID StepCallBack); -__declspec(dllexport) bool TITCALL GetUnusedHardwareBreakPointRegister(LPDWORD RegisterIndex); -__declspec(dllexport) bool TITCALL SetHardwareBreakPointEx(HANDLE hActiveThread, ULONG_PTR bpxAddress, DWORD IndexOfRegister, DWORD bpxType, DWORD bpxSize, LPVOID bpxCallBack, LPDWORD IndexOfSelectedRegister); -__declspec(dllexport) bool TITCALL SetHardwareBreakPoint(ULONG_PTR bpxAddress, DWORD IndexOfRegister, DWORD bpxType, DWORD bpxSize, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL DeleteHardwareBreakPoint(DWORD IndexOfRegister); -__declspec(dllexport) bool TITCALL RemoveAllBreakPoints(DWORD RemoveOption); -__declspec(dllexport) PROCESS_INFORMATION* TITCALL TitanGetProcessInformation(); -__declspec(dllexport) STARTUPINFOW* TITCALL TitanGetStartupInformation(); -__declspec(dllexport) void TITCALL DebugLoop(); -__declspec(dllexport) void TITCALL SetDebugLoopTimeOut(DWORD TimeOut); -__declspec(dllexport) void TITCALL SetNextDbgContinueStatus(DWORD SetDbgCode); -__declspec(dllexport) bool TITCALL AttachDebugger(DWORD ProcessId, bool KillOnExit, LPVOID DebugInfo, LPVOID CallBack); -__declspec(dllexport) bool TITCALL DetachDebugger(DWORD ProcessId); -__declspec(dllexport) bool TITCALL DetachDebuggerEx(DWORD ProcessId); -__declspec(dllexport) void TITCALL DebugLoopEx(DWORD TimeOut); -__declspec(dllexport) void TITCALL AutoDebugEx(const char* szFileName, bool ReserveModuleBase, const char* szCommandLine, const char* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack); -__declspec(dllexport) void TITCALL AutoDebugExW(const wchar_t* szFileName, bool ReserveModuleBase, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack); -__declspec(dllexport) bool TITCALL IsFileBeingDebugged(); -__declspec(dllexport) void TITCALL SetErrorModel(bool DisplayErrorMessages); -// TitanEngine.FindOEP.functions: -__declspec(dllexport) void TITCALL FindOEPInit(); -__declspec(dllexport) bool TITCALL FindOEPGenerically(const char* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack); -__declspec(dllexport) bool TITCALL FindOEPGenericallyW(const wchar_t* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack); -// TitanEngine.Importer.functions: -__declspec(dllexport) void TITCALL ImporterAddNewDll(const char* szDLLName, ULONG_PTR FirstThunk); -__declspec(dllexport) void TITCALL ImporterAddNewAPI(const char* szAPIName, ULONG_PTR ThunkValue); -__declspec(dllexport) void TITCALL ImporterAddNewOrdinalAPI(ULONG_PTR OrdinalNumber, ULONG_PTR ThunkValue); -__declspec(dllexport) long TITCALL ImporterGetAddedDllCount(); -__declspec(dllexport) long TITCALL ImporterGetAddedAPICount(); -__declspec(dllexport) bool TITCALL ImporterExportIAT(ULONG_PTR StorePlace, ULONG_PTR FileMapVA, HANDLE hFileMap); -__declspec(dllexport) long TITCALL ImporterEstimatedSize(); -__declspec(dllexport) bool TITCALL ImporterExportIATEx(const char* szDumpFileName, const char* szExportFileName, const char* szSectionName); -__declspec(dllexport) bool TITCALL ImporterExportIATExW(const wchar_t* szDumpFileName, const wchar_t* szExportFileName, const wchar_t* szSectionName = L".RL!TEv2"); -__declspec(dllexport) ULONG_PTR TITCALL ImporterFindAPIWriteLocation(const char* szAPIName); -__declspec(dllexport) ULONG_PTR TITCALL ImporterFindOrdinalAPIWriteLocation(ULONG_PTR OrdinalNumber); -__declspec(dllexport) ULONG_PTR TITCALL ImporterFindAPIByWriteLocation(ULONG_PTR APIWriteLocation); -__declspec(dllexport) ULONG_PTR TITCALL ImporterFindDLLByWriteLocation(ULONG_PTR APIWriteLocation); -__declspec(dllexport) void* TITCALL ImporterGetDLLName(ULONG_PTR APIAddress); -__declspec(dllexport) void* TITCALL ImporterGetDLLNameW(ULONG_PTR APIAddress); -__declspec(dllexport) void* TITCALL ImporterGetAPIName(ULONG_PTR APIAddress); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetAPIOrdinalNumber(ULONG_PTR APIAddress); -__declspec(dllexport) void* TITCALL ImporterGetAPINameEx(ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteAPIAddressEx(const char* szDLLName, const char* szAPIName); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetLocalAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) void* TITCALL ImporterGetDLLNameFromDebugee(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) void* TITCALL ImporterGetDLLNameFromDebugeeW(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) void* TITCALL ImporterGetAPINameFromDebugee(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetAPIOrdinalNumberFromDebugee(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) long TITCALL ImporterGetDLLIndexEx(ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); -__declspec(dllexport) long TITCALL ImporterGetDLLIndex(HANDLE hProcess, ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteDLLBase(HANDLE hProcess, HMODULE LocalModuleBase); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteDLLBaseEx(HANDLE hProcess, const char* szModuleName); -__declspec(dllexport) void* TITCALL ImporterGetRemoteDLLBaseExW(HANDLE hProcess, const wchar_t* szModuleName); -__declspec(dllexport) bool TITCALL ImporterIsForwardedAPI(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) void* TITCALL ImporterGetForwardedAPIName(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) void* TITCALL ImporterGetForwardedDLLName(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) long TITCALL ImporterGetForwardedDLLIndex(HANDLE hProcess, ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetForwardedAPIOrdinalNumber(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetNearestAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) void* TITCALL ImporterGetNearestAPIName(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) bool TITCALL ImporterCopyOriginalIAT(const char* szOriginalFile, const char* szDumpFile); -__declspec(dllexport) bool TITCALL ImporterCopyOriginalIATW(const wchar_t* szOriginalFile, const wchar_t* szDumpFile); -__declspec(dllexport) bool TITCALL ImporterLoadImportTable(const char* szFileName); -__declspec(dllexport) bool TITCALL ImporterLoadImportTableW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL ImporterMoveOriginalIAT(const char* szOriginalFile, const char* szDumpFile, const char* szSectionName); -__declspec(dllexport) bool TITCALL ImporterMoveOriginalIATW(const wchar_t* szOriginalFile, const wchar_t* szDumpFile, const char* szSectionName); -__declspec(dllexport) void TITCALL ImporterAutoSearchIAT(DWORD ProcessId, const char* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); -__declspec(dllexport) void TITCALL ImporterAutoSearchIATW(DWORD ProcessIds, const wchar_t* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); -__declspec(dllexport) void TITCALL ImporterAutoSearchIATEx(DWORD ProcessId, ULONG_PTR ImageBase, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); -__declspec(dllexport) void TITCALL ImporterEnumAddedData(LPVOID EnumCallBack); -__declspec(dllexport) long TITCALL ImporterAutoFixIATEx(DWORD ProcessId, const char* szDumpedFile, const char* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback); -__declspec(dllexport) long TITCALL ImporterAutoFixIATExW(DWORD ProcessId, const wchar_t* szDumpedFile, const wchar_t* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback); -__declspec(dllexport) long TITCALL ImporterAutoFixIAT(DWORD ProcessId, const char* szDumpedFile, ULONG_PTR SearchStart); -__declspec(dllexport) long TITCALL ImporterAutoFixIATW(DWORD ProcessId, const wchar_t* szDumpedFile, ULONG_PTR SearchStart); -__declspec(dllexport) bool TITCALL ImporterDeleteAPI(DWORD_PTR apiAddr); -// Global.Engine.Hook.functions: -__declspec(dllexport) bool TITCALL HooksSafeTransitionEx(LPVOID HookAddressArray, int NumberOfHooks, bool TransitionStart); -__declspec(dllexport) bool TITCALL HooksSafeTransition(LPVOID HookAddress, bool TransitionStart); -__declspec(dllexport) bool TITCALL HooksIsAddressRedirected(LPVOID HookAddress); -__declspec(dllexport) void* TITCALL HooksGetTrampolineAddress(LPVOID HookAddress); -__declspec(dllexport) void* TITCALL HooksGetHookEntryDetails(LPVOID HookAddress); -__declspec(dllexport) bool TITCALL HooksInsertNewRedirection(LPVOID HookAddress, LPVOID RedirectTo, int HookType); -__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirectionEx(ULONG_PTR FileMapVA, ULONG_PTR LoadedModuleBase, const char* szHookFunction, LPVOID RedirectTo); -__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirection(const char* szModuleName, const char* szHookFunction, LPVOID RedirectTo); -__declspec(dllexport) bool TITCALL HooksRemoveRedirection(LPVOID HookAddress, bool RemoveAll); -__declspec(dllexport) bool TITCALL HooksRemoveRedirectionsForModule(HMODULE ModuleBase); -__declspec(dllexport) bool TITCALL HooksRemoveIATRedirection(const char* szModuleName, const char* szHookFunction, bool RemoveAll); -__declspec(dllexport) bool TITCALL HooksDisableRedirection(LPVOID HookAddress, bool DisableAll); -__declspec(dllexport) bool TITCALL HooksDisableRedirectionsForModule(HMODULE ModuleBase); -__declspec(dllexport) bool TITCALL HooksDisableIATRedirection(const char* szModuleName, const char* szHookFunction, bool DisableAll); -__declspec(dllexport) bool TITCALL HooksEnableRedirection(LPVOID HookAddress, bool EnableAll); -__declspec(dllexport) bool TITCALL HooksEnableRedirectionsForModule(HMODULE ModuleBase); -__declspec(dllexport) bool TITCALL HooksEnableIATRedirection(const char* szModuleName, const char* szHookFunction, bool EnableAll); -__declspec(dllexport) void TITCALL HooksScanModuleMemory(HMODULE ModuleBase, LPVOID CallBack); -__declspec(dllexport) void TITCALL HooksScanEntireProcessMemory(LPVOID CallBack); -__declspec(dllexport) void TITCALL HooksScanEntireProcessMemoryEx(); -// TitanEngine.Tracer.functions: -__declspec(dllexport) void TITCALL TracerInit(); -__declspec(dllexport) ULONG_PTR TITCALL TracerLevel1(HANDLE hProcess, ULONG_PTR AddressToTrace); -__declspec(dllexport) ULONG_PTR TITCALL HashTracerLevel1(HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD InputNumberOfInstructions); -__declspec(dllexport) long TITCALL TracerDetectRedirection(HANDLE hProcess, ULONG_PTR AddressToTrace); -__declspec(dllexport) ULONG_PTR TITCALL TracerFixKnownRedirection(HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD RedirectionId); -__declspec(dllexport) ULONG_PTR TITCALL TracerFixRedirectionViaModule(HMODULE hModuleHandle, HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD IdParameter); -__declspec(dllexport) long TITCALL TracerFixRedirectionViaImpRecPlugin(HANDLE hProcess, const char* szPluginName, ULONG_PTR AddressToTrace); -// TitanEngine.Exporter.functions: -__declspec(dllexport) void TITCALL ExporterCleanup(); -__declspec(dllexport) void TITCALL ExporterSetImageBase(ULONG_PTR ImageBase); -__declspec(dllexport) void TITCALL ExporterInit(DWORD MemorySize, ULONG_PTR ImageBase, DWORD ExportOrdinalBase, const char* szExportModuleName); -__declspec(dllexport) bool TITCALL ExporterAddNewExport(const char* szExportName, DWORD ExportRelativeAddress); -__declspec(dllexport) bool TITCALL ExporterAddNewOrdinalExport(DWORD OrdinalNumber, DWORD ExportRelativeAddress); -__declspec(dllexport) long TITCALL ExporterGetAddedExportCount(); -__declspec(dllexport) long TITCALL ExporterEstimatedSize(); -__declspec(dllexport) bool TITCALL ExporterBuildExportTable(ULONG_PTR StorePlace, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL ExporterBuildExportTableEx(const char* szExportFileName, const char* szSectionName); -__declspec(dllexport) bool TITCALL ExporterBuildExportTableExW(const wchar_t* szExportFileName, const char* szSectionName); -__declspec(dllexport) bool TITCALL ExporterLoadExportTable(const char* szFileName); -__declspec(dllexport) bool TITCALL ExporterLoadExportTableW(const wchar_t* szFileName); -// TitanEngine.Librarian.functions: -__declspec(dllexport) bool TITCALL LibrarianSetBreakPoint(const char* szLibraryName, DWORD bpxType, bool SingleShoot, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL LibrarianRemoveBreakPoint(const char* szLibraryName, DWORD bpxType); -__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfo(const char* szLibraryName); -__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoW(const wchar_t* szLibraryName); -__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoEx(void* BaseOfDll); -__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoExW(void* BaseOfDll); -__declspec(dllexport) void TITCALL LibrarianEnumLibraryInfo(void* EnumCallBack); -__declspec(dllexport) void TITCALL LibrarianEnumLibraryInfoW(void* EnumCallBack); -// TitanEngine.Process.functions: -__declspec(dllexport) long TITCALL GetActiveProcessId(const char* szImageName); -__declspec(dllexport) long TITCALL GetActiveProcessIdW(const wchar_t* szImageName); -__declspec(dllexport) void TITCALL EnumProcessesWithLibrary(const char* szLibraryName, void* EnumFunction); -__declspec(dllexport) HANDLE TITCALL TitanOpenProcess(DWORD dwDesiredAccess, bool bInheritHandle, DWORD dwProcessId); -// TitanEngine.TLSFixer.functions: -__declspec(dllexport) bool TITCALL TLSBreakOnCallBack(LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL TLSGrabCallBackData(const char* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks); -__declspec(dllexport) bool TITCALL TLSGrabCallBackDataW(const wchar_t* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks); -__declspec(dllexport) bool TITCALL TLSBreakOnCallBackEx(const char* szFileName, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL TLSBreakOnCallBackExW(const wchar_t* szFileName, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL TLSRemoveCallback(const char* szFileName); -__declspec(dllexport) bool TITCALL TLSRemoveCallbackW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL TLSRemoveTable(const char* szFileName); -__declspec(dllexport) bool TITCALL TLSRemoveTableW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL TLSBackupData(const char* szFileName); -__declspec(dllexport) bool TITCALL TLSBackupDataW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL TLSRestoreData(); -__declspec(dllexport) bool TITCALL TLSBuildNewTable(ULONG_PTR FileMapVA, ULONG_PTR StorePlace, ULONG_PTR StorePlaceRVA, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); -__declspec(dllexport) bool TITCALL TLSBuildNewTableEx(const char* szFileName, const char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); -__declspec(dllexport) bool TITCALL TLSBuildNewTableExW(const wchar_t* szFileName, const char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); -// TitanEngine.TranslateName.functions: -__declspec(dllexport) void* TITCALL TranslateNativeName(const char* szNativeName); -__declspec(dllexport) void* TITCALL TranslateNativeNameW(const wchar_t* szNativeName); -// TitanEngine.Handler.functions: -__declspec(dllexport) long TITCALL HandlerGetActiveHandleCount(DWORD ProcessId); -__declspec(dllexport) bool TITCALL HandlerIsHandleOpen(DWORD ProcessId, HANDLE hHandle); -__declspec(dllexport) void* TITCALL HandlerGetHandleName(HANDLE hProcess, DWORD ProcessId, HANDLE hHandle, bool TranslateName); -__declspec(dllexport) void* TITCALL HandlerGetHandleNameW(HANDLE hProcess, DWORD ProcessId, HANDLE hHandle, bool TranslateName); -__declspec(dllexport) long TITCALL HandlerEnumerateOpenHandles(DWORD ProcessId, LPVOID HandleBuffer, DWORD MaxHandleCount); -__declspec(dllexport) ULONG_PTR TITCALL HandlerGetHandleDetails(HANDLE hProcess, DWORD ProcessId, HANDLE hHandle, DWORD InformationReturn); -__declspec(dllexport) bool TITCALL HandlerCloseRemoteHandle(HANDLE hProcess, HANDLE hHandle); -__declspec(dllexport) long TITCALL HandlerEnumerateLockHandles(char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated, LPVOID HandleDataBuffer, DWORD MaxHandleCount); -__declspec(dllexport) long TITCALL HandlerEnumerateLockHandlesW(const wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated, LPVOID HandleDataBuffer, DWORD MaxHandleCount); -__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandles(const char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); -__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandlesW(const wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); -__declspec(dllexport) bool TITCALL HandlerIsFileLocked(const char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); -__declspec(dllexport) bool TITCALL HandlerIsFileLockedW(const wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); -// TitanEngine.Handler[Mutex].functions: -__declspec(dllexport) long TITCALL HandlerEnumerateOpenMutexes(HANDLE hProcess, DWORD ProcessId, LPVOID HandleBuffer, DWORD MaxHandleCount); -__declspec(dllexport) ULONG_PTR TITCALL HandlerGetOpenMutexHandle(HANDLE hProcess, DWORD ProcessId, const char* szMutexString); -__declspec(dllexport) ULONG_PTR TITCALL HandlerGetOpenMutexHandleW(HANDLE hProcess, DWORD ProcessId, const wchar_t* szMutexString); -__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutex(const char* szMutexString); -__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutexW(const wchar_t* szMutexString); -// TitanEngine.Injector.functions: -__declspec(dllexport) bool TITCALL RemoteLoadLibrary(HANDLE hProcess, const char* szLibraryFile, bool WaitForThreadExit); -__declspec(dllexport) bool TITCALL RemoteLoadLibraryW(HANDLE hProcess, const wchar_t* szLibraryFile, bool WaitForThreadExit); -__declspec(dllexport) bool TITCALL RemoteFreeLibrary(HANDLE hProcess, HMODULE hModule, const char* szLibraryFile, bool WaitForThreadExit); -__declspec(dllexport) bool TITCALL RemoteFreeLibraryW(HANDLE hProcess, HMODULE hModule, const wchar_t* szLibraryFile, bool WaitForThreadExit); -__declspec(dllexport) bool TITCALL RemoteExitProcess(HANDLE hProcess, DWORD ExitCode); -// TitanEngine.StaticUnpacker.functions: -__declspec(dllexport) bool TITCALL StaticFileLoad(const char* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL StaticFileLoadW(const wchar_t* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL StaticFileUnload(const char* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL StaticFileUnloadW(const wchar_t* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL StaticFileOpen(const char* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh); -__declspec(dllexport) bool TITCALL StaticFileOpenW(const wchar_t* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh); -__declspec(dllexport) bool TITCALL StaticFileGetContent(HANDLE FileHandle, DWORD FilePositionLow, LPDWORD FilePositionHigh, void* Buffer, DWORD Size); -__declspec(dllexport) void TITCALL StaticFileClose(HANDLE FileHandle); -__declspec(dllexport) void TITCALL StaticMemoryDecrypt(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionType, DWORD DecryptionKeySize, ULONG_PTR DecryptionKey); -__declspec(dllexport) void TITCALL StaticMemoryDecryptEx(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionKeySize, void* DecryptionCallBack); -__declspec(dllexport) void TITCALL StaticMemoryDecryptSpecial(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionKeySize, DWORD SpecDecryptionType, void* DecryptionCallBack); -__declspec(dllexport) void TITCALL StaticSectionDecrypt(ULONG_PTR FileMapVA, DWORD SectionNumber, bool SimulateLoad, DWORD DecryptionType, DWORD DecryptionKeySize, ULONG_PTR DecryptionKey); -__declspec(dllexport) bool TITCALL StaticMemoryDecompress(void* Source, DWORD SourceSize, void* Destination, DWORD DestinationSize, int Algorithm); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopy(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyW(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyExW(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64W(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticHashMemory(void* MemoryToHash, DWORD SizeOfMemory, void* HashDigest, bool OutputString, int Algorithm); -__declspec(dllexport) bool TITCALL StaticHashFileW(const wchar_t* szFileName, char* HashDigest, bool OutputString, int Algorithm); -__declspec(dllexport) bool TITCALL StaticHashFile(const char* szFileName, char* HashDigest, bool OutputString, int Algorithm); -// TitanEngine.Engine.functions: -__declspec(dllexport) void TITCALL EngineUnpackerInitialize(const char* szFileName, const char* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack); -__declspec(dllexport) void TITCALL EngineUnpackerInitializeW(const wchar_t* szFileName, const wchar_t* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack); -__declspec(dllexport) bool TITCALL EngineUnpackerSetBreakCondition(void* SearchStart, DWORD SearchSize, void* SearchPattern, DWORD PatternSize, DWORD PatternDelta, ULONG_PTR BreakType, bool SingleBreak, DWORD Parameter1, DWORD Parameter2); -__declspec(dllexport) void TITCALL EngineUnpackerSetEntryPointAddress(ULONG_PTR UnpackedEntryPointAddress); -__declspec(dllexport) void TITCALL EngineUnpackerFinalizeUnpacking(); -// TitanEngine.Engine.functions: -__declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool VariableSet); -__declspec(dllexport) bool TITCALL EngineCreateMissingDependencies(const char* szFileName, const char* szOutputFolder, bool LogCreatedFiles); -__declspec(dllexport) bool TITCALL EngineCreateMissingDependenciesW(const wchar_t* szFileName, const wchar_t* szOutputFolder, bool LogCreatedFiles); -__declspec(dllexport) bool TITCALL EngineFakeMissingDependencies(HANDLE hProcess); -__declspec(dllexport) bool TITCALL EngineDeleteCreatedDependencies(); -__declspec(dllexport) bool TITCALL EngineCreateUnpackerWindow(const char* WindowUnpackerTitle, const char* WindowUnpackerLongTitle, const char* WindowUnpackerName, const char* WindowUnpackerAuthor, void* StartUnpackingCallBack); -__declspec(dllexport) void TITCALL EngineAddUnpackerWindowLogMessage(const char* szLogMessage); -__declspec(dllexport) bool TITCALL EngineCheckStructAlignment(DWORD StructureType, ULONG_PTR StructureSize); -// Global.Engine.Extension.Functions: -__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginLoaded(const char* szPluginName); -__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginEnabled(const char* szPluginName); -__declspec(dllexport) bool TITCALL ExtensionManagerDisableAllPlugins(); -__declspec(dllexport) bool TITCALL ExtensionManagerDisablePlugin(const char* szPluginName); -__declspec(dllexport) bool TITCALL ExtensionManagerEnableAllPlugins(); -__declspec(dllexport) bool TITCALL ExtensionManagerEnablePlugin(const char* szPluginName); -__declspec(dllexport) bool TITCALL ExtensionManagerUnloadAllPlugins(); -__declspec(dllexport) bool TITCALL ExtensionManagerUnloadPlugin(const char* szPluginName); -__declspec(dllexport) void* TITCALL ExtensionManagerGetPluginInfo(const char* szPluginName); - -#ifdef __cplusplus -} -#endif - -#pragma pack(pop) - -#endif /*TITANENGINE*/ +#ifndef TITANENGINE +#define TITANENGINE + +#define TITCALL + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include +#include + +#pragma pack(push, 1) + +// Global.Constant.Structure.Declaration: +// Engine.External: +#define UE_STRUCT_PE32STRUCT 1 +#define UE_STRUCT_PE64STRUCT 2 +#define UE_STRUCT_PESTRUCT 3 +#define UE_STRUCT_IMPORTENUMDATA 4 +#define UE_STRUCT_THREAD_ITEM_DATA 5 +#define UE_STRUCT_LIBRARY_ITEM_DATA 6 +#define UE_STRUCT_LIBRARY_ITEM_DATAW 7 +#define UE_STRUCT_PROCESS_ITEM_DATA 8 +#define UE_STRUCT_HANDLERARRAY 9 +#define UE_STRUCT_PLUGININFORMATION 10 +#define UE_STRUCT_HOOK_ENTRY 11 +#define UE_STRUCT_FILE_STATUS_INFO 12 +#define UE_STRUCT_FILE_FIX_INFO 13 +#define UE_STRUCT_X87FPUREGISTER 14 +#define UE_STRUCT_X87FPU 15 +#define UE_STRUCT_TITAN_ENGINE_CONTEXT 16 + +#define UE_ACCESS_READ 0 +#define UE_ACCESS_WRITE 1 +#define UE_ACCESS_ALL 2 + +#define UE_HIDE_PEBONLY 0 +#define UE_HIDE_BASIC 1 + +#define UE_PLUGIN_CALL_REASON_PREDEBUG 1 +#define UE_PLUGIN_CALL_REASON_EXCEPTION 2 +#define UE_PLUGIN_CALL_REASON_POSTDEBUG 3 +#define UE_PLUGIN_CALL_REASON_UNHANDLEDEXCEPTION 4 + +#define TEE_HOOK_NRM_JUMP 1 +#define TEE_HOOK_NRM_CALL 3 +#define TEE_HOOK_IAT 5 + +#define UE_ENGINE_ALOW_MODULE_LOADING 1 +#define UE_ENGINE_AUTOFIX_FORWARDERS 2 +#define UE_ENGINE_PASS_ALL_EXCEPTIONS 3 +#define UE_ENGINE_NO_CONSOLE_WINDOW 4 +#define UE_ENGINE_BACKUP_FOR_CRITICAL_FUNCTIONS 5 +#define UE_ENGINE_CALL_PLUGIN_CALLBACK 6 +#define UE_ENGINE_RESET_CUSTOM_HANDLER 7 +#define UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK 8 +#define UE_ENGINE_SET_DEBUG_PRIVILEGE 9 + +#define UE_OPTION_REMOVEALL 1 +#define UE_OPTION_DISABLEALL 2 +#define UE_OPTION_REMOVEALLDISABLED 3 +#define UE_OPTION_REMOVEALLENABLED 4 + +#define UE_STATIC_DECRYPTOR_XOR 1 +#define UE_STATIC_DECRYPTOR_SUB 2 +#define UE_STATIC_DECRYPTOR_ADD 3 + +#define UE_STATIC_DECRYPTOR_FOREWARD 1 +#define UE_STATIC_DECRYPTOR_BACKWARD 2 + +#define UE_STATIC_KEY_SIZE_1 1 +#define UE_STATIC_KEY_SIZE_2 2 +#define UE_STATIC_KEY_SIZE_4 4 +#define UE_STATIC_KEY_SIZE_8 8 + +#define UE_STATIC_APLIB 1 +#define UE_STATIC_APLIB_DEPACK 2 +#define UE_STATIC_LZMA 3 + +#define UE_STATIC_HASH_MD5 1 +#define UE_STATIC_HASH_SHA1 2 +#define UE_STATIC_HASH_CRC32 3 + +#define UE_RESOURCE_LANGUAGE_ANY -1 + +#define UE_PE_OFFSET 0 +#define UE_IMAGEBASE 1 +#define UE_OEP 2 +#define UE_SIZEOFIMAGE 3 +#define UE_SIZEOFHEADERS 4 +#define UE_SIZEOFOPTIONALHEADER 5 +#define UE_SECTIONALIGNMENT 6 +#define UE_IMPORTTABLEADDRESS 7 +#define UE_IMPORTTABLESIZE 8 +#define UE_RESOURCETABLEADDRESS 9 +#define UE_RESOURCETABLESIZE 10 +#define UE_EXPORTTABLEADDRESS 11 +#define UE_EXPORTTABLESIZE 12 +#define UE_TLSTABLEADDRESS 13 +#define UE_TLSTABLESIZE 14 +#define UE_RELOCATIONTABLEADDRESS 15 +#define UE_RELOCATIONTABLESIZE 16 +#define UE_TIMEDATESTAMP 17 +#define UE_SECTIONNUMBER 18 +#define UE_CHECKSUM 19 +#define UE_SUBSYSTEM 20 +#define UE_CHARACTERISTICS 21 +#define UE_NUMBEROFRVAANDSIZES 22 +#define UE_BASEOFCODE 23 +#define UE_BASEOFDATA 24 +//leaving some enum space here for future additions +#define UE_SECTIONNAME 40 +#define UE_SECTIONVIRTUALOFFSET 41 +#define UE_SECTIONVIRTUALSIZE 42 +#define UE_SECTIONRAWOFFSET 43 +#define UE_SECTIONRAWSIZE 44 +#define UE_SECTIONFLAGS 45 + +#define UE_VANOTFOUND = -2; + +#define UE_CH_BREAKPOINT 1 +#define UE_CH_SINGLESTEP 2 +#define UE_CH_ACCESSVIOLATION 3 +#define UE_CH_ILLEGALINSTRUCTION 4 +#define UE_CH_NONCONTINUABLEEXCEPTION 5 +#define UE_CH_ARRAYBOUNDSEXCEPTION 6 +#define UE_CH_FLOATDENORMALOPERAND 7 +#define UE_CH_FLOATDEVIDEBYZERO 8 +#define UE_CH_INTEGERDEVIDEBYZERO 9 +#define UE_CH_INTEGEROVERFLOW 10 +#define UE_CH_PRIVILEGEDINSTRUCTION 11 +#define UE_CH_PAGEGUARD 12 +#define UE_CH_EVERYTHINGELSE 13 +#define UE_CH_CREATETHREAD 14 +#define UE_CH_EXITTHREAD 15 +#define UE_CH_CREATEPROCESS 16 +#define UE_CH_EXITPROCESS 17 +#define UE_CH_LOADDLL 18 +#define UE_CH_UNLOADDLL 19 +#define UE_CH_OUTPUTDEBUGSTRING 20 +#define UE_CH_AFTEREXCEPTIONPROCESSING 21 +#define UE_CH_SYSTEMBREAKPOINT 23 +#define UE_CH_UNHANDLEDEXCEPTION 24 +#define UE_CH_RIPEVENT 25 +#define UE_CH_DEBUGEVENT 26 + +#define UE_OPTION_HANDLER_RETURN_HANDLECOUNT 1 +#define UE_OPTION_HANDLER_RETURN_ACCESS 2 +#define UE_OPTION_HANDLER_RETURN_FLAGS 3 +#define UE_OPTION_HANDLER_RETURN_TYPENAME 4 + +#define UE_BREAKPOINT_INT3 1 +#define UE_BREAKPOINT_LONG_INT3 2 +#define UE_BREAKPOINT_UD2 3 + +#define UE_BPXREMOVED 0 +#define UE_BPXACTIVE 1 +#define UE_BPXINACTIVE 2 + +#define UE_BREAKPOINT 0 +#define UE_SINGLESHOOT 1 +#define UE_HARDWARE 2 +#define UE_MEMORY 3 +#define UE_MEMORY_READ 4 +#define UE_MEMORY_WRITE 5 +#define UE_MEMORY_EXECUTE 6 +#define UE_BREAKPOINT_TYPE_INT3 0x10000000 +#define UE_BREAKPOINT_TYPE_LONG_INT3 0x20000000 +#define UE_BREAKPOINT_TYPE_UD2 0x30000000 + +#define UE_HARDWARE_EXECUTE 4 +#define UE_HARDWARE_WRITE 5 +#define UE_HARDWARE_READWRITE 6 + +#define UE_HARDWARE_SIZE_1 7 +#define UE_HARDWARE_SIZE_2 8 +#define UE_HARDWARE_SIZE_4 9 +#define UE_HARDWARE_SIZE_8 10 + +#define UE_ON_LIB_LOAD 1 +#define UE_ON_LIB_UNLOAD 2 +#define UE_ON_LIB_ALL 3 + +#define UE_APISTART 0 +#define UE_APIEND 1 + +#define UE_PLATFORM_x86 1 +#define UE_PLATFORM_x64 2 +#define UE_PLATFORM_ALL 3 + +#define UE_FUNCTION_STDCALL 1 +#define UE_FUNCTION_CCALL 2 +#define UE_FUNCTION_FASTCALL 3 +#define UE_FUNCTION_STDCALL_RET 4 +#define UE_FUNCTION_CCALL_RET 5 +#define UE_FUNCTION_FASTCALL_RET 6 +#define UE_FUNCTION_STDCALL_CALL 7 +#define UE_FUNCTION_CCALL_CALL 8 +#define UE_FUNCTION_FASTCALL_CALL 9 +#define UE_PARAMETER_BYTE 0 +#define UE_PARAMETER_WORD 1 +#define UE_PARAMETER_DWORD 2 +#define UE_PARAMETER_QWORD 3 +#define UE_PARAMETER_PTR_BYTE 4 +#define UE_PARAMETER_PTR_WORD 5 +#define UE_PARAMETER_PTR_DWORD 6 +#define UE_PARAMETER_PTR_QWORD 7 +#define UE_PARAMETER_STRING 8 +#define UE_PARAMETER_UNICODE 9 + +#define UE_EAX 1 +#define UE_EBX 2 +#define UE_ECX 3 +#define UE_EDX 4 +#define UE_EDI 5 +#define UE_ESI 6 +#define UE_EBP 7 +#define UE_ESP 8 +#define UE_EIP 9 +#define UE_EFLAGS 10 +#define UE_DR0 11 +#define UE_DR1 12 +#define UE_DR2 13 +#define UE_DR3 14 +#define UE_DR6 15 +#define UE_DR7 16 +#define UE_RAX 17 +#define UE_RBX 18 +#define UE_RCX 19 +#define UE_RDX 20 +#define UE_RDI 21 +#define UE_RSI 22 +#define UE_RBP 23 +#define UE_RSP 24 +#define UE_RIP 25 +#define UE_RFLAGS 26 +#define UE_R8 27 +#define UE_R9 28 +#define UE_R10 29 +#define UE_R11 30 +#define UE_R12 31 +#define UE_R13 32 +#define UE_R14 33 +#define UE_R15 34 +#define UE_CIP 35 +#define UE_CSP 36 +#ifdef _WIN64 +#define UE_CFLAGS UE_RFLAGS +#else +#define UE_CFLAGS UE_EFLAGS +#endif +#define UE_SEG_GS 37 +#define UE_SEG_FS 38 +#define UE_SEG_ES 39 +#define UE_SEG_DS 40 +#define UE_SEG_CS 41 +#define UE_SEG_SS 42 +#define UE_x87_r0 43 +#define UE_x87_r1 44 +#define UE_x87_r2 45 +#define UE_x87_r3 46 +#define UE_x87_r4 47 +#define UE_x87_r5 48 +#define UE_x87_r6 49 +#define UE_x87_r7 50 +#define UE_X87_STATUSWORD 51 +#define UE_X87_CONTROLWORD 52 +#define UE_X87_TAGWORD 53 +#define UE_MXCSR 54 +#define UE_MMX0 55 +#define UE_MMX1 56 +#define UE_MMX2 57 +#define UE_MMX3 58 +#define UE_MMX4 59 +#define UE_MMX5 60 +#define UE_MMX6 61 +#define UE_MMX7 62 +#define UE_XMM0 63 +#define UE_XMM1 64 +#define UE_XMM2 65 +#define UE_XMM3 66 +#define UE_XMM4 67 +#define UE_XMM5 68 +#define UE_XMM6 69 +#define UE_XMM7 70 +#define UE_XMM8 71 +#define UE_XMM9 72 +#define UE_XMM10 73 +#define UE_XMM11 74 +#define UE_XMM12 75 +#define UE_XMM13 76 +#define UE_XMM14 77 +#define UE_XMM15 78 +#define UE_x87_ST0 79 +#define UE_x87_ST1 80 +#define UE_x87_ST2 81 +#define UE_x87_ST3 82 +#define UE_x87_ST4 83 +#define UE_x87_ST5 84 +#define UE_x87_ST6 85 +#define UE_x87_ST7 86 +#define UE_YMM0 87 +#define UE_YMM1 88 +#define UE_YMM2 89 +#define UE_YMM3 90 +#define UE_YMM4 91 +#define UE_YMM5 92 +#define UE_YMM6 93 +#define UE_YMM7 94 +#define UE_YMM8 95 +#define UE_YMM9 96 +#define UE_YMM10 97 +#define UE_YMM11 98 +#define UE_YMM12 99 +#define UE_YMM13 100 +#define UE_YMM14 101 +#define UE_YMM15 102 + +#ifndef CONTEXT_EXTENDED_REGISTERS +#define CONTEXT_EXTENDED_REGISTERS 0 +#endif + +typedef struct +{ + DWORD PE32Offset; + DWORD ImageBase; + DWORD OriginalEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + DWORD NtSizeOfImage; + DWORD NtSizeOfHeaders; + WORD SizeOfOptionalHeaders; + DWORD FileAlignment; + DWORD SectionAligment; + DWORD ImportTableAddress; + DWORD ImportTableSize; + DWORD ResourceTableAddress; + DWORD ResourceTableSize; + DWORD ExportTableAddress; + DWORD ExportTableSize; + DWORD TLSTableAddress; + DWORD TLSTableSize; + DWORD RelocationTableAddress; + DWORD RelocationTableSize; + DWORD TimeDateStamp; + WORD SectionNumber; + DWORD CheckSum; + WORD SubSystem; + WORD Characteristics; + DWORD NumberOfRvaAndSizes; +} PE32Struct, *PPE32Struct; + +typedef struct +{ + DWORD PE64Offset; + DWORD64 ImageBase; + DWORD OriginalEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + DWORD NtSizeOfImage; + DWORD NtSizeOfHeaders; + WORD SizeOfOptionalHeaders; + DWORD FileAlignment; + DWORD SectionAligment; + DWORD ImportTableAddress; + DWORD ImportTableSize; + DWORD ResourceTableAddress; + DWORD ResourceTableSize; + DWORD ExportTableAddress; + DWORD ExportTableSize; + DWORD TLSTableAddress; + DWORD TLSTableSize; + DWORD RelocationTableAddress; + DWORD RelocationTableSize; + DWORD TimeDateStamp; + WORD SectionNumber; + DWORD CheckSum; + WORD SubSystem; + WORD Characteristics; + DWORD NumberOfRvaAndSizes; +} PE64Struct, *PPE64Struct; + +#if defined(_WIN64) +typedef PE64Struct PEStruct; +#else +typedef PE32Struct PEStruct; +#endif + +typedef struct +{ + bool NewDll; + int NumberOfImports; + ULONG_PTR ImageBase; + ULONG_PTR BaseImportThunk; + ULONG_PTR ImportThunk; + char* APIName; + char* DLLName; +} ImportEnumData, *PImportEnumData; + +typedef struct +{ + HANDLE hThread; + DWORD dwThreadId; + void* ThreadStartAddress; + void* ThreadLocalBase; + void* TebAddress; + ULONG WaitTime; + LONG Priority; + LONG BasePriority; + ULONG ContextSwitches; + ULONG ThreadState; + ULONG WaitReason; +} THREAD_ITEM_DATA, *PTHREAD_ITEM_DATA; + +typedef struct +{ + HANDLE hFile; + void* BaseOfDll; + HANDLE hFileMapping; + void* hFileMappingView; + char szLibraryPath[MAX_PATH]; + char szLibraryName[MAX_PATH]; +} LIBRARY_ITEM_DATA, *PLIBRARY_ITEM_DATA; + +typedef struct +{ + HANDLE hFile; + void* BaseOfDll; + HANDLE hFileMapping; + void* hFileMappingView; + wchar_t szLibraryPath[MAX_PATH]; + wchar_t szLibraryName[MAX_PATH]; +} LIBRARY_ITEM_DATAW, *PLIBRARY_ITEM_DATAW; + +typedef struct +{ + HANDLE hProcess; + DWORD dwProcessId; + HANDLE hThread; + DWORD dwThreadId; + HANDLE hFile; + void* BaseOfImage; + void* ThreadStartAddress; + void* ThreadLocalBase; +} PROCESS_ITEM_DATA, *PPROCESS_ITEM_DATA; + +typedef struct +{ + ULONG ProcessId; + HANDLE hHandle; +} HandlerArray, *PHandlerArray; + +typedef struct +{ + char PluginName[64]; + DWORD PluginMajorVersion; + DWORD PluginMinorVersion; + HMODULE PluginBaseAddress; + void* TitanDebuggingCallBack; + void* TitanRegisterPlugin; + void* TitanReleasePlugin; + void* TitanResetPlugin; + bool PluginDisabled; +} PluginInformation, *PPluginInformation; + +#define TEE_MAXIMUM_HOOK_SIZE 14 +#define TEE_MAXIMUM_HOOK_RELOCS 7 +#if defined(_WIN64) +#define TEE_MAXIMUM_HOOK_INSERT_SIZE 14 +#else +#define TEE_MAXIMUM_HOOK_INSERT_SIZE 5 +#endif + +typedef struct HOOK_ENTRY +{ + bool IATHook; + BYTE HookType; + DWORD HookSize; + void* HookAddress; + void* RedirectionAddress; + BYTE HookBytes[TEE_MAXIMUM_HOOK_SIZE]; + BYTE OriginalBytes[TEE_MAXIMUM_HOOK_SIZE]; + void* IATHookModuleBase; + DWORD IATHookNameHash; + bool HookIsEnabled; + bool HookIsRemote; + void* PatchedEntry; + DWORD RelocationInfo[TEE_MAXIMUM_HOOK_RELOCS]; + int RelocationCount; +} HOOK_ENTRY, *PHOOK_ENTRY; + +#define UE_DEPTH_SURFACE 0 +#define UE_DEPTH_DEEP 1 + +#define UE_UNPACKER_CONDITION_SEARCH_FROM_EP 1 + +#define UE_UNPACKER_CONDITION_LOADLIBRARY 1 +#define UE_UNPACKER_CONDITION_GETPROCADDRESS 2 +#define UE_UNPACKER_CONDITION_ENTRYPOINTBREAK 3 +#define UE_UNPACKER_CONDITION_RELOCSNAPSHOT1 4 +#define UE_UNPACKER_CONDITION_RELOCSNAPSHOT2 5 + +#define UE_FIELD_OK 0 +#define UE_FIELD_BROKEN_NON_FIXABLE 1 +#define UE_FIELD_BROKEN_NON_CRITICAL 2 +#define UE_FIELD_BROKEN_FIXABLE_FOR_STATIC_USE 3 +#define UE_FIELD_BROKEN_BUT_CAN_BE_EMULATED 4 +#define UE_FIELD_FIXABLE_NON_CRITICAL 5 +#define UE_FIELD_FIXABLE_CRITICAL 6 +#define UE_FIELD_NOT_PRESET 7 +#define UE_FIELD_NOT_PRESET_WARNING 8 + +#define UE_RESULT_FILE_OK 10 +#define UE_RESULT_FILE_INVALID_BUT_FIXABLE 11 +#define UE_RESULT_FILE_INVALID_AND_NON_FIXABLE 12 +#define UE_RESULT_FILE_INVALID_FORMAT 13 + +typedef struct +{ + BYTE OveralEvaluation; + bool EvaluationTerminatedByException; + bool FileIs64Bit; + bool FileIsDLL; + bool FileIsConsole; + bool MissingDependencies; + bool MissingDeclaredAPIs; + BYTE SignatureMZ; + BYTE SignaturePE; + BYTE EntryPoint; + BYTE ImageBase; + BYTE SizeOfImage; + BYTE FileAlignment; + BYTE SectionAlignment; + BYTE ExportTable; + BYTE RelocationTable; + BYTE ImportTable; + BYTE ImportTableSection; + BYTE ImportTableData; + BYTE IATTable; + BYTE TLSTable; + BYTE LoadConfigTable; + BYTE BoundImportTable; + BYTE COMHeaderTable; + BYTE ResourceTable; + BYTE ResourceData; + BYTE SectionTable; +} FILE_STATUS_INFO, *PFILE_STATUS_INFO; + +typedef struct +{ + BYTE OveralEvaluation; + bool FixingTerminatedByException; + bool FileFixPerformed; + bool StrippedRelocation; + bool DontFixRelocations; + DWORD OriginalRelocationTableAddress; + DWORD OriginalRelocationTableSize; + bool StrippedExports; + bool DontFixExports; + DWORD OriginalExportTableAddress; + DWORD OriginalExportTableSize; + bool StrippedResources; + bool DontFixResources; + DWORD OriginalResourceTableAddress; + DWORD OriginalResourceTableSize; + bool StrippedTLS; + bool DontFixTLS; + DWORD OriginalTLSTableAddress; + DWORD OriginalTLSTableSize; + bool StrippedLoadConfig; + bool DontFixLoadConfig; + DWORD OriginalLoadConfigTableAddress; + DWORD OriginalLoadConfigTableSize; + bool StrippedBoundImports; + bool DontFixBoundImports; + DWORD OriginalBoundImportTableAddress; + DWORD OriginalBoundImportTableSize; + bool StrippedIAT; + bool DontFixIAT; + DWORD OriginalImportAddressTableAddress; + DWORD OriginalImportAddressTableSize; + bool StrippedCOM; + bool DontFixCOM; + DWORD OriginalCOMTableAddress; + DWORD OriginalCOMTableSize; +} FILE_FIX_INFO, *PFILE_FIX_INFO; + +typedef struct DECLSPEC_ALIGN(16) _XmmRegister_t +{ + ULONGLONG Low; + LONGLONG High; +} XmmRegister_t; + +typedef struct +{ + XmmRegister_t Low; //XMM/SSE part + XmmRegister_t High; //AVX part +} YmmRegister_t; + +typedef struct +{ + BYTE data[10]; + int st_value; + int tag; +} x87FPURegister_t; + +typedef struct +{ + WORD ControlWord; + WORD StatusWord; + WORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + DWORD Cr0NpxState; +} x87FPU_t; + +typedef struct +{ + ULONG_PTR cax; + ULONG_PTR ccx; + ULONG_PTR cdx; + ULONG_PTR cbx; + ULONG_PTR csp; + ULONG_PTR cbp; + ULONG_PTR csi; + ULONG_PTR cdi; +#ifdef _WIN64 + ULONG_PTR r8; + ULONG_PTR r9; + ULONG_PTR r10; + ULONG_PTR r11; + ULONG_PTR r12; + ULONG_PTR r13; + ULONG_PTR r14; + ULONG_PTR r15; +#endif //_WIN64 + ULONG_PTR cip; + ULONG_PTR eflags; + unsigned short gs; + unsigned short fs; + unsigned short es; + unsigned short ds; + unsigned short cs; + unsigned short ss; + ULONG_PTR dr0; + ULONG_PTR dr1; + ULONG_PTR dr2; + ULONG_PTR dr3; + ULONG_PTR dr6; + ULONG_PTR dr7; + BYTE RegisterArea[80]; + x87FPU_t x87fpu; + DWORD MxCsr; +#ifdef _WIN64 + XmmRegister_t XmmRegisters[16]; + YmmRegister_t YmmRegisters[16]; +#else // x86 + XmmRegister_t XmmRegisters[8]; + YmmRegister_t YmmRegisters[8]; +#endif +} TITAN_ENGINE_CONTEXT_t; + +#ifdef __cplusplus +extern "C" +{ +#endif + +// Global.Function.Declaration: +// TitanEngine.Dumper.functions: +__declspec(dllexport) bool TITCALL DumpProcess(HANDLE hProcess, LPVOID ImageBase, const char* szDumpFileName, ULONG_PTR EntryPoint); +__declspec(dllexport) bool TITCALL DumpProcessW(HANDLE hProcess, LPVOID ImageBase, const wchar_t* szDumpFileName, ULONG_PTR EntryPoint); +__declspec(dllexport) bool TITCALL DumpProcessEx(DWORD ProcessId, LPVOID ImageBase, const char* szDumpFileName, ULONG_PTR EntryPoint); +__declspec(dllexport) bool TITCALL DumpProcessExW(DWORD ProcessId, LPVOID ImageBase, const wchar_t* szDumpFileName, ULONG_PTR EntryPoint); +__declspec(dllexport) bool TITCALL DumpMemory(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpMemoryW(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpMemoryEx(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpMemoryExW(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpRegions(HANDLE hProcess, const char* szDumpFolder, bool DumpAboveImageBaseOnly); +__declspec(dllexport) bool TITCALL DumpRegionsW(HANDLE hProcess, const wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly); +__declspec(dllexport) bool TITCALL DumpRegionsEx(DWORD ProcessId, const char* szDumpFolder, bool DumpAboveImageBaseOnly); +__declspec(dllexport) bool TITCALL DumpRegionsExW(DWORD ProcessId, const wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly); +__declspec(dllexport) bool TITCALL DumpModule(HANDLE hProcess, LPVOID ModuleBase, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpModuleW(HANDLE hProcess, LPVOID ModuleBase, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpModuleEx(DWORD ProcessId, LPVOID ModuleBase, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpModuleExW(DWORD ProcessId, LPVOID ModuleBase, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL PastePEHeader(HANDLE hProcess, LPVOID ImageBase, const char* szDebuggedFileName); +__declspec(dllexport) bool TITCALL PastePEHeaderW(HANDLE hProcess, LPVOID ImageBase, const wchar_t* szDebuggedFileName); +__declspec(dllexport) bool TITCALL ExtractSection(const char* szFileName, const char* szDumpFileName, DWORD SectionNumber); +__declspec(dllexport) bool TITCALL ExtractSectionW(const wchar_t* szFileName, const wchar_t* szDumpFileName, DWORD SectionNumber); +__declspec(dllexport) bool TITCALL ResortFileSections(const char* szFileName); +__declspec(dllexport) bool TITCALL ResortFileSectionsW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL FindOverlay(const char* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize); +__declspec(dllexport) bool TITCALL FindOverlayW(const wchar_t* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize); +__declspec(dllexport) bool TITCALL ExtractOverlay(const char* szFileName, const char* szExtactedFileName); +__declspec(dllexport) bool TITCALL ExtractOverlayW(const wchar_t* szFileName, const wchar_t* szExtactedFileName); +__declspec(dllexport) bool TITCALL AddOverlay(const char* szFileName, const char* szOverlayFileName); +__declspec(dllexport) bool TITCALL AddOverlayW(const wchar_t* szFileName, const wchar_t* szOverlayFileName); +__declspec(dllexport) bool TITCALL CopyOverlay(const char* szInFileName, const char* szOutFileName); +__declspec(dllexport) bool TITCALL CopyOverlayW(const wchar_t* szInFileName, const wchar_t* szOutFileName); +__declspec(dllexport) bool TITCALL RemoveOverlay(const char* szFileName); +__declspec(dllexport) bool TITCALL RemoveOverlayW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL MakeAllSectionsRWE(const char* szFileName); +__declspec(dllexport) bool TITCALL MakeAllSectionsRWEW(const wchar_t* szFileName); +__declspec(dllexport) long TITCALL AddNewSectionEx(const char* szFileName, const char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize); +__declspec(dllexport) long TITCALL AddNewSectionExW(const wchar_t* szFileName, const char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize); +__declspec(dllexport) long TITCALL AddNewSection(const char* szFileName, const char* szSectionName, DWORD SectionSize); +__declspec(dllexport) long TITCALL AddNewSectionW(const wchar_t* szFileName, const char* szSectionName, DWORD SectionSize); +__declspec(dllexport) bool TITCALL ResizeLastSection(const char* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData); +__declspec(dllexport) bool TITCALL ResizeLastSectionW(const wchar_t* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData); +__declspec(dllexport) void TITCALL SetSharedOverlay(const char* szFileName); +__declspec(dllexport) void TITCALL SetSharedOverlayW(const wchar_t* szFileName); +__declspec(dllexport) char* TITCALL GetSharedOverlay(); +__declspec(dllexport) wchar_t* TITCALL GetSharedOverlayW(); +__declspec(dllexport) bool TITCALL DeleteLastSection(const char* szFileName); +__declspec(dllexport) bool TITCALL DeleteLastSectionW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL DeleteLastSectionEx(const char* szFileName, DWORD NumberOfSections); +__declspec(dllexport) bool TITCALL DeleteLastSectionExW(const wchar_t* szFileName, DWORD NumberOfSections); +__declspec(dllexport) ULONG_PTR TITCALL GetPE32DataFromMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData); +__declspec(dllexport) ULONG_PTR TITCALL GetPE32Data(const char* szFileName, DWORD WhichSection, DWORD WhichData); +__declspec(dllexport) ULONG_PTR TITCALL GetPE32DataW(const wchar_t* szFileName, DWORD WhichSection, DWORD WhichData); +__declspec(dllexport) bool TITCALL GetPE32DataFromMappedFileEx(ULONG_PTR FileMapVA, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL GetPE32DataEx(const char* szFileName, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL GetPE32DataExW(const wchar_t* szFileName, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL SetPE32DataForMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); +__declspec(dllexport) bool TITCALL SetPE32Data(const char* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); +__declspec(dllexport) bool TITCALL SetPE32DataW(const wchar_t* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); +__declspec(dllexport) bool TITCALL SetPE32DataForMappedFileEx(ULONG_PTR FileMapVA, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL SetPE32DataEx(const char* szFileName, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL SetPE32DataExW(const wchar_t* szFileName, LPVOID DataStorage); +__declspec(dllexport) long TITCALL GetPE32SectionNumberFromVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert); +__declspec(dllexport) ULONG_PTR TITCALL ConvertVAtoFileOffset(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType); +__declspec(dllexport) ULONG_PTR TITCALL ConvertVAtoFileOffsetEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool AddressIsRVA, bool ReturnType); +__declspec(dllexport) ULONG_PTR TITCALL ConvertFileOffsetToVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType); +__declspec(dllexport) ULONG_PTR TITCALL ConvertFileOffsetToVAEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool ReturnType); +__declspec(dllexport) bool TITCALL MemoryReadSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead); +__declspec(dllexport) bool TITCALL MemoryWriteSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten); +// TitanEngine.Realigner.functions: +__declspec(dllexport) bool TITCALL FixHeaderCheckSum(const char* szFileName); +__declspec(dllexport) bool TITCALL FixHeaderCheckSumW(const wchar_t* szFileName); +__declspec(dllexport) long TITCALL RealignPE(ULONG_PTR FileMapVA, DWORD FileSize, DWORD RealingMode); +__declspec(dllexport) long TITCALL RealignPEEx(const char* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment); +__declspec(dllexport) long TITCALL RealignPEExW(const wchar_t* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment); +__declspec(dllexport) bool TITCALL WipeSection(const char* szFileName, int WipeSectionNumber, bool RemovePhysically); +__declspec(dllexport) bool TITCALL WipeSectionW(const wchar_t* szFileName, int WipeSectionNumber, bool RemovePhysically); +__declspec(dllexport) bool TITCALL IsPE32FileValidEx(const char* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo); +__declspec(dllexport) bool TITCALL IsPE32FileValidExW(const wchar_t* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo); +__declspec(dllexport) bool TITCALL FixBrokenPE32FileEx(const char* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo); +__declspec(dllexport) bool TITCALL FixBrokenPE32FileExW(const wchar_t* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo); +__declspec(dllexport) bool TITCALL IsFileDLL(const char* szFileName, ULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL IsFileDLLW(const wchar_t* szFileName, ULONG_PTR FileMapVA); +// TitanEngine.Hider.functions: +__declspec(dllexport) void* TITCALL GetPEBLocation(HANDLE hProcess); +__declspec(dllexport) void* TITCALL GetPEBLocation64(HANDLE hProcess); +__declspec(dllexport) void* TITCALL GetTEBLocation(HANDLE hThread); +__declspec(dllexport) void* TITCALL GetTEBLocation64(HANDLE hThread); +__declspec(dllexport) bool TITCALL HideDebugger(HANDLE hProcess, DWORD PatchAPILevel); +__declspec(dllexport) bool TITCALL UnHideDebugger(HANDLE hProcess, DWORD PatchAPILevel); +// TitanEngine.Relocater.functions: +__declspec(dllexport) void TITCALL RelocaterCleanup(); +__declspec(dllexport) void TITCALL RelocaterInit(DWORD MemorySize, ULONG_PTR OldImageBase, ULONG_PTR NewImageBase); +__declspec(dllexport) void TITCALL RelocaterAddNewRelocation(HANDLE hProcess, ULONG_PTR RelocateAddress, DWORD RelocateState); +__declspec(dllexport) long TITCALL RelocaterEstimatedSize(); +__declspec(dllexport) bool TITCALL RelocaterExportRelocation(ULONG_PTR StorePlace, DWORD StorePlaceRVA, ULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL RelocaterExportRelocationEx(const char* szFileName, const char* szSectionName); +__declspec(dllexport) bool TITCALL RelocaterExportRelocationExW(const wchar_t* szFileName, const char* szSectionName); +__declspec(dllexport) bool TITCALL RelocaterGrabRelocationTable(HANDLE hProcess, ULONG_PTR MemoryStart, DWORD MemorySize); +__declspec(dllexport) bool TITCALL RelocaterGrabRelocationTableEx(HANDLE hProcess, ULONG_PTR MemoryStart, ULONG_PTR MemorySize, DWORD NtSizeOfImage); +__declspec(dllexport) bool TITCALL RelocaterMakeSnapshot(HANDLE hProcess, const char* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize); +__declspec(dllexport) bool TITCALL RelocaterMakeSnapshotW(HANDLE hProcess, const wchar_t* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize); +__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshots(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, const char* szDumpFile1, const char* szDumpFile2, ULONG_PTR MemStart); +__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshotsW(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, const wchar_t* szDumpFile1, const wchar_t* szDumpFile2, ULONG_PTR MemStart); +__declspec(dllexport) bool TITCALL RelocaterChangeFileBase(const char* szFileName, ULONG_PTR NewImageBase); +__declspec(dllexport) bool TITCALL RelocaterChangeFileBaseW(const wchar_t* szFileName, ULONG_PTR NewImageBase); +__declspec(dllexport) bool TITCALL RelocaterRelocateMemoryBlock(ULONG_PTR FileMapVA, ULONG_PTR MemoryLocation, void* RelocateMemory, DWORD RelocateMemorySize, ULONG_PTR CurrentLoadedBase, ULONG_PTR RelocateBase); +__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTable(const char* szFileName); +__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTableW(const wchar_t* szFileName); +// TitanEngine.Resourcer.functions: +__declspec(dllexport) ULONG_PTR TITCALL ResourcerLoadFileForResourceUse(const char* szFileName); +__declspec(dllexport) ULONG_PTR TITCALL ResourcerLoadFileForResourceUseW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL ResourcerFreeLoadedFile(LPVOID LoadedFileBase); +__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileEx(ULONG_PTR FileMapVA, const char* szResourceType, const char* szResourceName, const char* szExtractedFileName); +__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFile(const char* szFileName, const char* szResourceType, const char* szResourceName, const char* szExtractedFileName); +__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileW(const wchar_t* szFileName, char* szResourceType, const char* szResourceName, const char* szExtractedFileName); +__declspec(dllexport) bool TITCALL ResourcerFindResource(const char* szFileName, const char* szResourceType, DWORD ResourceType, const char* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); +__declspec(dllexport) bool TITCALL ResourcerFindResourceW(const wchar_t* szFileName, const wchar_t* szResourceType, DWORD ResourceType, const wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); +__declspec(dllexport) bool TITCALL ResourcerFindResourceEx(ULONG_PTR FileMapVA, DWORD FileSize, const wchar_t* szResourceType, DWORD ResourceType, const wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); +__declspec(dllexport) void TITCALL ResourcerEnumerateResource(const char* szFileName, void* CallBack); +__declspec(dllexport) void TITCALL ResourcerEnumerateResourceW(const wchar_t* szFileName, void* CallBack); +__declspec(dllexport) void TITCALL ResourcerEnumerateResourceEx(ULONG_PTR FileMapVA, DWORD FileSize, void* CallBack); +// TitanEngine.Threader.functions: +__declspec(dllexport) bool TITCALL ThreaderImportRunningThreadData(DWORD ProcessId); +__declspec(dllexport) void* TITCALL ThreaderGetThreadInfo(HANDLE hThread, DWORD ThreadId); +__declspec(dllexport) void TITCALL ThreaderEnumThreadInfo(void* EnumCallBack); +__declspec(dllexport) bool TITCALL ThreaderPauseThread(HANDLE hThread); +__declspec(dllexport) bool TITCALL ThreaderResumeThread(HANDLE hThread); +__declspec(dllexport) bool TITCALL ThreaderTerminateThread(HANDLE hThread, DWORD ThreadExitCode); +__declspec(dllexport) bool TITCALL ThreaderPauseAllThreads(bool LeaveMainRunning); +__declspec(dllexport) bool TITCALL ThreaderResumeAllThreads(bool LeaveMainPaused); +__declspec(dllexport) bool TITCALL ThreaderPauseProcess(); +__declspec(dllexport) bool TITCALL ThreaderResumeProcess(); +__declspec(dllexport) ULONG_PTR TITCALL ThreaderCreateRemoteThread(ULONG_PTR ThreadStartAddress, bool AutoCloseTheHandle, LPVOID ThreadPassParameter, LPDWORD ThreadId); +__declspec(dllexport) bool TITCALL ThreaderInjectAndExecuteCode(LPVOID InjectCode, DWORD StartDelta, DWORD InjectSize); +__declspec(dllexport) ULONG_PTR TITCALL ThreaderCreateRemoteThreadEx(HANDLE hProcess, ULONG_PTR ThreadStartAddress, bool AutoCloseTheHandle, LPVOID ThreadPassParameter, LPDWORD ThreadId); +__declspec(dllexport) bool TITCALL ThreaderInjectAndExecuteCodeEx(HANDLE hProcess, LPVOID InjectCode, DWORD StartDelta, DWORD InjectSize); +__declspec(dllexport) void TITCALL ThreaderSetCallBackForNextExitThreadEvent(LPVOID exitThreadCallBack); +__declspec(dllexport) bool TITCALL ThreaderIsThreadStillRunning(HANDLE hThread); +__declspec(dllexport) bool TITCALL ThreaderIsThreadActive(HANDLE hThread); +__declspec(dllexport) bool TITCALL ThreaderIsAnyThreadActive(); +__declspec(dllexport) bool TITCALL ThreaderExecuteOnlyInjectedThreads(); +__declspec(dllexport) ULONG_PTR TITCALL ThreaderGetOpenHandleForThread(DWORD ThreadId); +__declspec(dllexport) bool TITCALL ThreaderIsExceptionInMainThread(); +// TitanEngine.Debugger.functions: +__declspec(dllexport) void* TITCALL StaticDisassembleEx(ULONG_PTR DisassmStart, LPVOID DisassmAddress); +__declspec(dllexport) void* TITCALL StaticDisassemble(LPVOID DisassmAddress); +__declspec(dllexport) void* TITCALL DisassembleEx(HANDLE hProcess, LPVOID DisassmAddress, bool ReturnInstructionType); +__declspec(dllexport) void* TITCALL Disassemble(LPVOID DisassmAddress); +__declspec(dllexport) long TITCALL StaticLengthDisassemble(LPVOID DisassmAddress); +__declspec(dllexport) long TITCALL LengthDisassembleEx(HANDLE hProcess, LPVOID DisassmAddress); +__declspec(dllexport) long TITCALL LengthDisassemble(LPVOID DisassmAddress); +__declspec(dllexport) void* TITCALL InitDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder); +__declspec(dllexport) void* TITCALL InitDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder); +__declspec(dllexport) void* TITCALL InitDebugEx(const char* szFileName, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack); +__declspec(dllexport) void* TITCALL InitDebugExW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, LPVOID EntryCallBack); +__declspec(dllexport) void* TITCALL InitDLLDebug(const char* szFileName, bool ReserveModuleBase, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack); +__declspec(dllexport) void* TITCALL InitDLLDebugW(const wchar_t* szFileName, bool ReserveModuleBase, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, LPVOID EntryCallBack); +__declspec(dllexport) bool TITCALL StopDebug(); +__declspec(dllexport) void TITCALL SetBPXOptions(long DefaultBreakPointType); +__declspec(dllexport) bool TITCALL IsBPXEnabled(ULONG_PTR bpxAddress); +__declspec(dllexport) bool TITCALL EnableBPX(ULONG_PTR bpxAddress); +__declspec(dllexport) bool TITCALL DisableBPX(ULONG_PTR bpxAddress); +__declspec(dllexport) bool TITCALL SetBPX(ULONG_PTR bpxAddress, DWORD bpxType, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL DeleteBPX(ULONG_PTR bpxAddress); +__declspec(dllexport) bool TITCALL SafeDeleteBPX(ULONG_PTR bpxAddress); +__declspec(dllexport) bool TITCALL SetAPIBreakPoint(const char* szDLLName, const char* szAPIName, DWORD bpxType, DWORD bpxPlace, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL DeleteAPIBreakPoint(const char* szDLLName, const char* szAPIName, DWORD bpxPlace); +__declspec(dllexport) bool TITCALL SafeDeleteAPIBreakPoint(const char* szDLLName, const char* szAPIName, DWORD bpxPlace); +__declspec(dllexport) bool TITCALL SetMemoryBPX(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL SetMemoryBPXEx(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory, DWORD BreakPointType, bool RestoreOnHit, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL RemoveMemoryBPX(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory); +__declspec(dllexport) bool TITCALL GetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea); +__declspec(dllexport) void TITCALL Getx87FPURegisters(x87FPURegister_t x87FPURegisters[8], TITAN_ENGINE_CONTEXT_t* titcontext); +__declspec(dllexport) void TITCALL GetMMXRegisters(uint64_t mmx[8], TITAN_ENGINE_CONTEXT_t* titcontext); +__declspec(dllexport) bool TITCALL GetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); +__declspec(dllexport) bool TITCALL SetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); +__declspec(dllexport) ULONG_PTR TITCALL GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister); +__declspec(dllexport) ULONG_PTR TITCALL GetContextData(DWORD IndexOfRegister); +__declspec(dllexport) bool TITCALL SetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea); +__declspec(dllexport) bool TITCALL SetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister, ULONG_PTR NewRegisterValue); +__declspec(dllexport) bool TITCALL SetContextData(DWORD IndexOfRegister, ULONG_PTR NewRegisterValue); +__declspec(dllexport) bool TITCALL GetAVXContext(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); +__declspec(dllexport) bool TITCALL SetAVXContext(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); +__declspec(dllexport) void TITCALL ClearExceptionNumber(); +__declspec(dllexport) long TITCALL CurrentExceptionNumber(); +__declspec(dllexport) bool TITCALL MatchPatternEx(HANDLE hProcess, void* MemoryToCheck, int SizeOfMemoryToCheck, void* PatternToMatch, int SizeOfPatternToMatch, PBYTE WildCard); +__declspec(dllexport) bool TITCALL MatchPattern(void* MemoryToCheck, int SizeOfMemoryToCheck, void* PatternToMatch, int SizeOfPatternToMatch, PBYTE WildCard); +__declspec(dllexport) ULONG_PTR TITCALL FindEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, LPBYTE WildCard); +extern "C" __declspec(dllexport) ULONG_PTR TITCALL Find(LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, LPBYTE WildCard); +__declspec(dllexport) bool TITCALL FillEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, PBYTE FillByte); +__declspec(dllexport) bool TITCALL Fill(LPVOID MemoryStart, DWORD MemorySize, PBYTE FillByte); +__declspec(dllexport) bool TITCALL PatchEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, LPVOID ReplacePattern, DWORD ReplaceSize, bool AppendNOP, bool PrependNOP); +__declspec(dllexport) bool TITCALL Patch(LPVOID MemoryStart, DWORD MemorySize, LPVOID ReplacePattern, DWORD ReplaceSize, bool AppendNOP, bool PrependNOP); +__declspec(dllexport) bool TITCALL ReplaceEx(HANDLE hProcess, LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, DWORD NumberOfRepetitions, LPVOID ReplacePattern, DWORD ReplaceSize, PBYTE WildCard); +__declspec(dllexport) bool TITCALL Replace(LPVOID MemoryStart, DWORD MemorySize, LPVOID SearchPattern, DWORD PatternSize, DWORD NumberOfRepetitions, LPVOID ReplacePattern, DWORD ReplaceSize, PBYTE WildCard); +__declspec(dllexport) void* TITCALL GetDebugData(); +__declspec(dllexport) void* TITCALL GetTerminationData(); +__declspec(dllexport) long TITCALL GetExitCode(); +__declspec(dllexport) ULONG_PTR TITCALL GetDebuggedDLLBaseAddress(); +__declspec(dllexport) ULONG_PTR TITCALL GetDebuggedFileBaseAddress(); +__declspec(dllexport) bool TITCALL GetRemoteString(HANDLE hProcess, LPVOID StringAddress, LPVOID StringStorage, int MaximumStringSize); +__declspec(dllexport) ULONG_PTR TITCALL GetFunctionParameter(HANDLE hProcess, DWORD FunctionType, DWORD ParameterNumber, DWORD ParameterType); +__declspec(dllexport) ULONG_PTR TITCALL GetJumpDestinationEx(HANDLE hProcess, ULONG_PTR InstructionAddress, bool JustJumps); +__declspec(dllexport) ULONG_PTR TITCALL GetJumpDestination(HANDLE hProcess, ULONG_PTR InstructionAddress); +__declspec(dllexport) bool TITCALL IsJumpGoingToExecuteEx(HANDLE hProcess, HANDLE hThread, ULONG_PTR InstructionAddress, ULONG_PTR RegFlags); +__declspec(dllexport) bool TITCALL IsJumpGoingToExecute(); +__declspec(dllexport) void TITCALL SetCustomHandler(DWORD ExceptionId, LPVOID CallBack); +__declspec(dllexport) void TITCALL ForceClose(); +__declspec(dllexport) void TITCALL StepInto(LPVOID traceCallBack); +__declspec(dllexport) void TITCALL StepOver(LPVOID traceCallBack); +__declspec(dllexport) void TITCALL StepOut(LPVOID StepOut, bool StepFinal); +__declspec(dllexport) void TITCALL SingleStep(DWORD StepCount, LPVOID StepCallBack); +__declspec(dllexport) bool TITCALL GetUnusedHardwareBreakPointRegister(LPDWORD RegisterIndex); +__declspec(dllexport) bool TITCALL SetHardwareBreakPointEx(HANDLE hActiveThread, ULONG_PTR bpxAddress, DWORD IndexOfRegister, DWORD bpxType, DWORD bpxSize, LPVOID bpxCallBack, LPDWORD IndexOfSelectedRegister); +__declspec(dllexport) bool TITCALL SetHardwareBreakPoint(ULONG_PTR bpxAddress, DWORD IndexOfRegister, DWORD bpxType, DWORD bpxSize, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL DeleteHardwareBreakPoint(DWORD IndexOfRegister); +__declspec(dllexport) bool TITCALL RemoveAllBreakPoints(DWORD RemoveOption); +__declspec(dllexport) PROCESS_INFORMATION* TITCALL TitanGetProcessInformation(); +__declspec(dllexport) STARTUPINFOW* TITCALL TitanGetStartupInformation(); +__declspec(dllexport) void TITCALL DebugLoop(); +__declspec(dllexport) void TITCALL SetDebugLoopTimeOut(DWORD TimeOut); +__declspec(dllexport) void TITCALL SetNextDbgContinueStatus(DWORD SetDbgCode); +__declspec(dllexport) bool TITCALL AttachDebugger(DWORD ProcessId, bool KillOnExit, LPVOID DebugInfo, LPVOID CallBack); +__declspec(dllexport) bool TITCALL DetachDebugger(DWORD ProcessId); +__declspec(dllexport) bool TITCALL DetachDebuggerEx(DWORD ProcessId); +__declspec(dllexport) void TITCALL DebugLoopEx(DWORD TimeOut); +__declspec(dllexport) void TITCALL AutoDebugEx(const char* szFileName, bool ReserveModuleBase, const char* szCommandLine, const char* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack); +__declspec(dllexport) void TITCALL AutoDebugExW(const wchar_t* szFileName, bool ReserveModuleBase, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack); +__declspec(dllexport) bool TITCALL IsFileBeingDebugged(); +__declspec(dllexport) void TITCALL SetErrorModel(bool DisplayErrorMessages); +// TitanEngine.FindOEP.functions: +__declspec(dllexport) void TITCALL FindOEPInit(); +__declspec(dllexport) bool TITCALL FindOEPGenerically(const char* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack); +__declspec(dllexport) bool TITCALL FindOEPGenericallyW(const wchar_t* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack); +// TitanEngine.Importer.functions: +__declspec(dllexport) void TITCALL ImporterAddNewDll(const char* szDLLName, ULONG_PTR FirstThunk); +__declspec(dllexport) void TITCALL ImporterAddNewAPI(const char* szAPIName, ULONG_PTR ThunkValue); +__declspec(dllexport) void TITCALL ImporterAddNewOrdinalAPI(ULONG_PTR OrdinalNumber, ULONG_PTR ThunkValue); +__declspec(dllexport) long TITCALL ImporterGetAddedDllCount(); +__declspec(dllexport) long TITCALL ImporterGetAddedAPICount(); +__declspec(dllexport) bool TITCALL ImporterExportIAT(ULONG_PTR StorePlace, ULONG_PTR FileMapVA, HANDLE hFileMap); +__declspec(dllexport) long TITCALL ImporterEstimatedSize(); +__declspec(dllexport) bool TITCALL ImporterExportIATEx(const char* szDumpFileName, const char* szExportFileName, const char* szSectionName); +__declspec(dllexport) bool TITCALL ImporterExportIATExW(const wchar_t* szDumpFileName, const wchar_t* szExportFileName, const wchar_t* szSectionName = L".RL!TEv2"); +__declspec(dllexport) ULONG_PTR TITCALL ImporterFindAPIWriteLocation(const char* szAPIName); +__declspec(dllexport) ULONG_PTR TITCALL ImporterFindOrdinalAPIWriteLocation(ULONG_PTR OrdinalNumber); +__declspec(dllexport) ULONG_PTR TITCALL ImporterFindAPIByWriteLocation(ULONG_PTR APIWriteLocation); +__declspec(dllexport) ULONG_PTR TITCALL ImporterFindDLLByWriteLocation(ULONG_PTR APIWriteLocation); +__declspec(dllexport) void* TITCALL ImporterGetDLLName(ULONG_PTR APIAddress); +__declspec(dllexport) void* TITCALL ImporterGetDLLNameW(ULONG_PTR APIAddress); +__declspec(dllexport) void* TITCALL ImporterGetAPIName(ULONG_PTR APIAddress); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetAPIOrdinalNumber(ULONG_PTR APIAddress); +__declspec(dllexport) void* TITCALL ImporterGetAPINameEx(ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteAPIAddressEx(const char* szDLLName, const char* szAPIName); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetLocalAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress); +__declspec(dllexport) void* TITCALL ImporterGetDLLNameFromDebugee(HANDLE hProcess, ULONG_PTR APIAddress); +__declspec(dllexport) void* TITCALL ImporterGetDLLNameFromDebugeeW(HANDLE hProcess, ULONG_PTR APIAddress); +__declspec(dllexport) void* TITCALL ImporterGetAPINameFromDebugee(HANDLE hProcess, ULONG_PTR APIAddress); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetAPIOrdinalNumberFromDebugee(HANDLE hProcess, ULONG_PTR APIAddress); +__declspec(dllexport) long TITCALL ImporterGetDLLIndexEx(ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); +__declspec(dllexport) long TITCALL ImporterGetDLLIndex(HANDLE hProcess, ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteDLLBase(HANDLE hProcess, HMODULE LocalModuleBase); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteDLLBaseEx(HANDLE hProcess, const char* szModuleName); +__declspec(dllexport) void* TITCALL ImporterGetRemoteDLLBaseExW(HANDLE hProcess, const wchar_t* szModuleName); +__declspec(dllexport) bool TITCALL ImporterIsForwardedAPI(HANDLE hProcess, ULONG_PTR APIAddress); +__declspec(dllexport) void* TITCALL ImporterGetForwardedAPIName(HANDLE hProcess, ULONG_PTR APIAddress); +__declspec(dllexport) void* TITCALL ImporterGetForwardedDLLName(HANDLE hProcess, ULONG_PTR APIAddress); +__declspec(dllexport) long TITCALL ImporterGetForwardedDLLIndex(HANDLE hProcess, ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetForwardedAPIOrdinalNumber(HANDLE hProcess, ULONG_PTR APIAddress); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetNearestAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress); +__declspec(dllexport) void* TITCALL ImporterGetNearestAPIName(HANDLE hProcess, ULONG_PTR APIAddress); +__declspec(dllexport) bool TITCALL ImporterCopyOriginalIAT(const char* szOriginalFile, const char* szDumpFile); +__declspec(dllexport) bool TITCALL ImporterCopyOriginalIATW(const wchar_t* szOriginalFile, const wchar_t* szDumpFile); +__declspec(dllexport) bool TITCALL ImporterLoadImportTable(const char* szFileName); +__declspec(dllexport) bool TITCALL ImporterLoadImportTableW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL ImporterMoveOriginalIAT(const char* szOriginalFile, const char* szDumpFile, const char* szSectionName); +__declspec(dllexport) bool TITCALL ImporterMoveOriginalIATW(const wchar_t* szOriginalFile, const wchar_t* szDumpFile, const char* szSectionName); +__declspec(dllexport) void TITCALL ImporterAutoSearchIAT(DWORD ProcessId, const char* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); +__declspec(dllexport) void TITCALL ImporterAutoSearchIATW(DWORD ProcessIds, const wchar_t* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); +__declspec(dllexport) void TITCALL ImporterAutoSearchIATEx(DWORD ProcessId, ULONG_PTR ImageBase, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); +__declspec(dllexport) void TITCALL ImporterEnumAddedData(LPVOID EnumCallBack); +__declspec(dllexport) long TITCALL ImporterAutoFixIATEx(DWORD ProcessId, const char* szDumpedFile, const char* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback); +__declspec(dllexport) long TITCALL ImporterAutoFixIATExW(DWORD ProcessId, const wchar_t* szDumpedFile, const wchar_t* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback); +__declspec(dllexport) long TITCALL ImporterAutoFixIAT(DWORD ProcessId, const char* szDumpedFile, ULONG_PTR SearchStart); +__declspec(dllexport) long TITCALL ImporterAutoFixIATW(DWORD ProcessId, const wchar_t* szDumpedFile, ULONG_PTR SearchStart); +__declspec(dllexport) bool TITCALL ImporterDeleteAPI(DWORD_PTR apiAddr); +// Global.Engine.Hook.functions: +__declspec(dllexport) bool TITCALL HooksSafeTransitionEx(LPVOID HookAddressArray, int NumberOfHooks, bool TransitionStart); +__declspec(dllexport) bool TITCALL HooksSafeTransition(LPVOID HookAddress, bool TransitionStart); +__declspec(dllexport) bool TITCALL HooksIsAddressRedirected(LPVOID HookAddress); +__declspec(dllexport) void* TITCALL HooksGetTrampolineAddress(LPVOID HookAddress); +__declspec(dllexport) void* TITCALL HooksGetHookEntryDetails(LPVOID HookAddress); +__declspec(dllexport) bool TITCALL HooksInsertNewRedirection(LPVOID HookAddress, LPVOID RedirectTo, int HookType); +__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirectionEx(ULONG_PTR FileMapVA, ULONG_PTR LoadedModuleBase, const char* szHookFunction, LPVOID RedirectTo); +__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirection(const char* szModuleName, const char* szHookFunction, LPVOID RedirectTo); +__declspec(dllexport) bool TITCALL HooksRemoveRedirection(LPVOID HookAddress, bool RemoveAll); +__declspec(dllexport) bool TITCALL HooksRemoveRedirectionsForModule(HMODULE ModuleBase); +__declspec(dllexport) bool TITCALL HooksRemoveIATRedirection(const char* szModuleName, const char* szHookFunction, bool RemoveAll); +__declspec(dllexport) bool TITCALL HooksDisableRedirection(LPVOID HookAddress, bool DisableAll); +__declspec(dllexport) bool TITCALL HooksDisableRedirectionsForModule(HMODULE ModuleBase); +__declspec(dllexport) bool TITCALL HooksDisableIATRedirection(const char* szModuleName, const char* szHookFunction, bool DisableAll); +__declspec(dllexport) bool TITCALL HooksEnableRedirection(LPVOID HookAddress, bool EnableAll); +__declspec(dllexport) bool TITCALL HooksEnableRedirectionsForModule(HMODULE ModuleBase); +__declspec(dllexport) bool TITCALL HooksEnableIATRedirection(const char* szModuleName, const char* szHookFunction, bool EnableAll); +__declspec(dllexport) void TITCALL HooksScanModuleMemory(HMODULE ModuleBase, LPVOID CallBack); +__declspec(dllexport) void TITCALL HooksScanEntireProcessMemory(LPVOID CallBack); +__declspec(dllexport) void TITCALL HooksScanEntireProcessMemoryEx(); +// TitanEngine.Tracer.functions: +__declspec(dllexport) void TITCALL TracerInit(); +__declspec(dllexport) ULONG_PTR TITCALL TracerLevel1(HANDLE hProcess, ULONG_PTR AddressToTrace); +__declspec(dllexport) ULONG_PTR TITCALL HashTracerLevel1(HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD InputNumberOfInstructions); +__declspec(dllexport) long TITCALL TracerDetectRedirection(HANDLE hProcess, ULONG_PTR AddressToTrace); +__declspec(dllexport) ULONG_PTR TITCALL TracerFixKnownRedirection(HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD RedirectionId); +__declspec(dllexport) ULONG_PTR TITCALL TracerFixRedirectionViaModule(HMODULE hModuleHandle, HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD IdParameter); +__declspec(dllexport) long TITCALL TracerFixRedirectionViaImpRecPlugin(HANDLE hProcess, const char* szPluginName, ULONG_PTR AddressToTrace); +// TitanEngine.Exporter.functions: +__declspec(dllexport) void TITCALL ExporterCleanup(); +__declspec(dllexport) void TITCALL ExporterSetImageBase(ULONG_PTR ImageBase); +__declspec(dllexport) void TITCALL ExporterInit(DWORD MemorySize, ULONG_PTR ImageBase, DWORD ExportOrdinalBase, const char* szExportModuleName); +__declspec(dllexport) bool TITCALL ExporterAddNewExport(const char* szExportName, DWORD ExportRelativeAddress); +__declspec(dllexport) bool TITCALL ExporterAddNewOrdinalExport(DWORD OrdinalNumber, DWORD ExportRelativeAddress); +__declspec(dllexport) long TITCALL ExporterGetAddedExportCount(); +__declspec(dllexport) long TITCALL ExporterEstimatedSize(); +__declspec(dllexport) bool TITCALL ExporterBuildExportTable(ULONG_PTR StorePlace, ULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL ExporterBuildExportTableEx(const char* szExportFileName, const char* szSectionName); +__declspec(dllexport) bool TITCALL ExporterBuildExportTableExW(const wchar_t* szExportFileName, const char* szSectionName); +__declspec(dllexport) bool TITCALL ExporterLoadExportTable(const char* szFileName); +__declspec(dllexport) bool TITCALL ExporterLoadExportTableW(const wchar_t* szFileName); +// TitanEngine.Librarian.functions: +__declspec(dllexport) bool TITCALL LibrarianSetBreakPoint(const char* szLibraryName, DWORD bpxType, bool SingleShoot, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL LibrarianRemoveBreakPoint(const char* szLibraryName, DWORD bpxType); +__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfo(const char* szLibraryName); +__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoW(const wchar_t* szLibraryName); +__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoEx(void* BaseOfDll); +__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoExW(void* BaseOfDll); +__declspec(dllexport) void TITCALL LibrarianEnumLibraryInfo(void* EnumCallBack); +__declspec(dllexport) void TITCALL LibrarianEnumLibraryInfoW(void* EnumCallBack); +// TitanEngine.Process.functions: +__declspec(dllexport) long TITCALL GetActiveProcessId(const char* szImageName); +__declspec(dllexport) long TITCALL GetActiveProcessIdW(const wchar_t* szImageName); +__declspec(dllexport) void TITCALL EnumProcessesWithLibrary(const char* szLibraryName, void* EnumFunction); +__declspec(dllexport) HANDLE TITCALL TitanOpenProcess(DWORD dwDesiredAccess, bool bInheritHandle, DWORD dwProcessId); +// TitanEngine.TLSFixer.functions: +__declspec(dllexport) bool TITCALL TLSBreakOnCallBack(LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL TLSGrabCallBackData(const char* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks); +__declspec(dllexport) bool TITCALL TLSGrabCallBackDataW(const wchar_t* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks); +__declspec(dllexport) bool TITCALL TLSBreakOnCallBackEx(const char* szFileName, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL TLSBreakOnCallBackExW(const wchar_t* szFileName, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL TLSRemoveCallback(const char* szFileName); +__declspec(dllexport) bool TITCALL TLSRemoveCallbackW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL TLSRemoveTable(const char* szFileName); +__declspec(dllexport) bool TITCALL TLSRemoveTableW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL TLSBackupData(const char* szFileName); +__declspec(dllexport) bool TITCALL TLSBackupDataW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL TLSRestoreData(); +__declspec(dllexport) bool TITCALL TLSBuildNewTable(ULONG_PTR FileMapVA, ULONG_PTR StorePlace, ULONG_PTR StorePlaceRVA, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); +__declspec(dllexport) bool TITCALL TLSBuildNewTableEx(const char* szFileName, const char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); +__declspec(dllexport) bool TITCALL TLSBuildNewTableExW(const wchar_t* szFileName, const char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); +// TitanEngine.TranslateName.functions: +__declspec(dllexport) void* TITCALL TranslateNativeName(const char* szNativeName); +__declspec(dllexport) void* TITCALL TranslateNativeNameW(const wchar_t* szNativeName); +// TitanEngine.Handler.functions: +__declspec(dllexport) long TITCALL HandlerGetActiveHandleCount(DWORD ProcessId); +__declspec(dllexport) bool TITCALL HandlerIsHandleOpen(DWORD ProcessId, HANDLE hHandle); +__declspec(dllexport) void* TITCALL HandlerGetHandleName(HANDLE hProcess, DWORD ProcessId, HANDLE hHandle, bool TranslateName); +__declspec(dllexport) void* TITCALL HandlerGetHandleNameW(HANDLE hProcess, DWORD ProcessId, HANDLE hHandle, bool TranslateName); +__declspec(dllexport) long TITCALL HandlerEnumerateOpenHandles(DWORD ProcessId, LPVOID HandleBuffer, DWORD MaxHandleCount); +__declspec(dllexport) ULONG_PTR TITCALL HandlerGetHandleDetails(HANDLE hProcess, DWORD ProcessId, HANDLE hHandle, DWORD InformationReturn); +__declspec(dllexport) bool TITCALL HandlerCloseRemoteHandle(HANDLE hProcess, HANDLE hHandle); +__declspec(dllexport) long TITCALL HandlerEnumerateLockHandles(char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated, LPVOID HandleDataBuffer, DWORD MaxHandleCount); +__declspec(dllexport) long TITCALL HandlerEnumerateLockHandlesW(const wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated, LPVOID HandleDataBuffer, DWORD MaxHandleCount); +__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandles(const char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); +__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandlesW(const wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); +__declspec(dllexport) bool TITCALL HandlerIsFileLocked(const char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); +__declspec(dllexport) bool TITCALL HandlerIsFileLockedW(const wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); +// TitanEngine.Handler[Mutex].functions: +__declspec(dllexport) long TITCALL HandlerEnumerateOpenMutexes(HANDLE hProcess, DWORD ProcessId, LPVOID HandleBuffer, DWORD MaxHandleCount); +__declspec(dllexport) ULONG_PTR TITCALL HandlerGetOpenMutexHandle(HANDLE hProcess, DWORD ProcessId, const char* szMutexString); +__declspec(dllexport) ULONG_PTR TITCALL HandlerGetOpenMutexHandleW(HANDLE hProcess, DWORD ProcessId, const wchar_t* szMutexString); +__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutex(const char* szMutexString); +__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutexW(const wchar_t* szMutexString); +// TitanEngine.Injector.functions: +__declspec(dllexport) bool TITCALL RemoteLoadLibrary(HANDLE hProcess, const char* szLibraryFile, bool WaitForThreadExit); +__declspec(dllexport) bool TITCALL RemoteLoadLibraryW(HANDLE hProcess, const wchar_t* szLibraryFile, bool WaitForThreadExit); +__declspec(dllexport) bool TITCALL RemoteFreeLibrary(HANDLE hProcess, HMODULE hModule, const char* szLibraryFile, bool WaitForThreadExit); +__declspec(dllexport) bool TITCALL RemoteFreeLibraryW(HANDLE hProcess, HMODULE hModule, const wchar_t* szLibraryFile, bool WaitForThreadExit); +__declspec(dllexport) bool TITCALL RemoteExitProcess(HANDLE hProcess, DWORD ExitCode); +// TitanEngine.StaticUnpacker.functions: +__declspec(dllexport) bool TITCALL StaticFileLoad(const char* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL StaticFileLoadW(const wchar_t* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL StaticFileUnload(const char* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL StaticFileUnloadW(const wchar_t* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL StaticFileOpen(const char* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh); +__declspec(dllexport) bool TITCALL StaticFileOpenW(const wchar_t* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh); +__declspec(dllexport) bool TITCALL StaticFileGetContent(HANDLE FileHandle, DWORD FilePositionLow, LPDWORD FilePositionHigh, void* Buffer, DWORD Size); +__declspec(dllexport) void TITCALL StaticFileClose(HANDLE FileHandle); +__declspec(dllexport) void TITCALL StaticMemoryDecrypt(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionType, DWORD DecryptionKeySize, ULONG_PTR DecryptionKey); +__declspec(dllexport) void TITCALL StaticMemoryDecryptEx(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionKeySize, void* DecryptionCallBack); +__declspec(dllexport) void TITCALL StaticMemoryDecryptSpecial(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionKeySize, DWORD SpecDecryptionType, void* DecryptionCallBack); +__declspec(dllexport) void TITCALL StaticSectionDecrypt(ULONG_PTR FileMapVA, DWORD SectionNumber, bool SimulateLoad, DWORD DecryptionType, DWORD DecryptionKeySize, ULONG_PTR DecryptionKey); +__declspec(dllexport) bool TITCALL StaticMemoryDecompress(void* Source, DWORD SourceSize, void* Destination, DWORD DestinationSize, int Algorithm); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopy(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyW(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyExW(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64W(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticHashMemory(void* MemoryToHash, DWORD SizeOfMemory, void* HashDigest, bool OutputString, int Algorithm); +__declspec(dllexport) bool TITCALL StaticHashFileW(const wchar_t* szFileName, char* HashDigest, bool OutputString, int Algorithm); +__declspec(dllexport) bool TITCALL StaticHashFile(const char* szFileName, char* HashDigest, bool OutputString, int Algorithm); +// TitanEngine.Engine.functions: +__declspec(dllexport) void TITCALL EngineUnpackerInitialize(const char* szFileName, const char* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack); +__declspec(dllexport) void TITCALL EngineUnpackerInitializeW(const wchar_t* szFileName, const wchar_t* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack); +__declspec(dllexport) bool TITCALL EngineUnpackerSetBreakCondition(void* SearchStart, DWORD SearchSize, void* SearchPattern, DWORD PatternSize, DWORD PatternDelta, ULONG_PTR BreakType, bool SingleBreak, DWORD Parameter1, DWORD Parameter2); +__declspec(dllexport) void TITCALL EngineUnpackerSetEntryPointAddress(ULONG_PTR UnpackedEntryPointAddress); +__declspec(dllexport) void TITCALL EngineUnpackerFinalizeUnpacking(); +// TitanEngine.Engine.functions: +__declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool VariableSet); +__declspec(dllexport) bool TITCALL EngineCreateMissingDependencies(const char* szFileName, const char* szOutputFolder, bool LogCreatedFiles); +__declspec(dllexport) bool TITCALL EngineCreateMissingDependenciesW(const wchar_t* szFileName, const wchar_t* szOutputFolder, bool LogCreatedFiles); +__declspec(dllexport) bool TITCALL EngineFakeMissingDependencies(HANDLE hProcess); +__declspec(dllexport) bool TITCALL EngineDeleteCreatedDependencies(); +__declspec(dllexport) bool TITCALL EngineCreateUnpackerWindow(const char* WindowUnpackerTitle, const char* WindowUnpackerLongTitle, const char* WindowUnpackerName, const char* WindowUnpackerAuthor, void* StartUnpackingCallBack); +__declspec(dllexport) void TITCALL EngineAddUnpackerWindowLogMessage(const char* szLogMessage); +__declspec(dllexport) bool TITCALL EngineCheckStructAlignment(DWORD StructureType, ULONG_PTR StructureSize); +// Global.Engine.Extension.Functions: +__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginLoaded(const char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginEnabled(const char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerDisableAllPlugins(); +__declspec(dllexport) bool TITCALL ExtensionManagerDisablePlugin(const char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerEnableAllPlugins(); +__declspec(dllexport) bool TITCALL ExtensionManagerEnablePlugin(const char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerUnloadAllPlugins(); +__declspec(dllexport) bool TITCALL ExtensionManagerUnloadPlugin(const char* szPluginName); +__declspec(dllexport) void* TITCALL ExtensionManagerGetPluginInfo(const char* szPluginName); + +#ifdef __cplusplus +} +#endif + +#pragma pack(pop) + +#endif /*TITANENGINE*/ diff --git a/src/dbg/XEDParse/XEDParse.h b/src/dbg/XEDParse/XEDParse.h index 7bdc1a5c..8a5912e5 100644 --- a/src/dbg/XEDParse/XEDParse.h +++ b/src/dbg/XEDParse/XEDParse.h @@ -1,53 +1,53 @@ -#ifndef _XEDPARSE_H -#define _XEDPARSE_H - -#include - -//XEDParse defines -#ifdef XEDPARSE_BUILD -#define XEDPARSE_EXPORT __declspec(dllexport) -#else -#define XEDPARSE_EXPORT __declspec(dllimport) -#endif //XEDPARSE_BUILD - -#define XEDPARSE_CALL //calling convention - -#define XEDPARSE_MAXBUFSIZE 256 -#define XEDPARSE_MAXASMSIZE 16 - -//typedefs -typedef bool (XEDPARSE_CALL* CBXEDPARSE_UNKNOWN)(const char* text, ULONGLONG* value); - -//XEDParse enums -enum XEDPARSE_STATUS -{ - XEDPARSE_ERROR = 0, - XEDPARSE_OK = 1 -}; - -//XEDParse structs -#pragma pack(push,8) -struct XEDPARSE -{ - bool x64; // use 64-bit instructions - ULONGLONG cip; //instruction pointer (for relative addressing) - unsigned int dest_size; //destination size (returned by XEDParse) - CBXEDPARSE_UNKNOWN cbUnknown; //unknown operand callback - unsigned char dest[XEDPARSE_MAXASMSIZE]; //destination buffer - char instr[XEDPARSE_MAXBUFSIZE]; //instruction text - char error[XEDPARSE_MAXBUFSIZE]; //error text (in case of an error) -}; -#pragma pack(pop) - -#ifdef __cplusplus -extern "C" -{ -#endif - -XEDPARSE_EXPORT XEDPARSE_STATUS XEDPARSE_CALL XEDParseAssemble(XEDPARSE* XEDParse); - -#ifdef __cplusplus -} -#endif - -#endif // _XEDPARSE_H +#ifndef _XEDPARSE_H +#define _XEDPARSE_H + +#include + +//XEDParse defines +#ifdef XEDPARSE_BUILD +#define XEDPARSE_EXPORT __declspec(dllexport) +#else +#define XEDPARSE_EXPORT __declspec(dllimport) +#endif //XEDPARSE_BUILD + +#define XEDPARSE_CALL //calling convention + +#define XEDPARSE_MAXBUFSIZE 256 +#define XEDPARSE_MAXASMSIZE 16 + +//typedefs +typedef bool (XEDPARSE_CALL* CBXEDPARSE_UNKNOWN)(const char* text, ULONGLONG* value); + +//XEDParse enums +enum XEDPARSE_STATUS +{ + XEDPARSE_ERROR = 0, + XEDPARSE_OK = 1 +}; + +//XEDParse structs +#pragma pack(push,8) +struct XEDPARSE +{ + bool x64; // use 64-bit instructions + ULONGLONG cip; //instruction pointer (for relative addressing) + unsigned int dest_size; //destination size (returned by XEDParse) + CBXEDPARSE_UNKNOWN cbUnknown; //unknown operand callback + unsigned char dest[XEDPARSE_MAXASMSIZE]; //destination buffer + char instr[XEDPARSE_MAXBUFSIZE]; //instruction text + char error[XEDPARSE_MAXBUFSIZE]; //error text (in case of an error) +}; +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" +{ +#endif + +XEDPARSE_EXPORT XEDPARSE_STATUS XEDPARSE_CALL XEDParseAssemble(XEDPARSE* XEDParse); + +#ifdef __cplusplus +} +#endif + +#endif // _XEDPARSE_H diff --git a/src/dbg/_dbgfunctions.cpp b/src/dbg/_dbgfunctions.cpp index 34805494..14ae7f8a 100644 --- a/src/dbg/_dbgfunctions.cpp +++ b/src/dbg/_dbgfunctions.cpp @@ -1,238 +1,238 @@ -/** - @file _dbgfunctions.cpp - - @brief Implements the dbgfunctions class. - */ - -#include "_global.h" -#include "_dbgfunctions.h" -#include "assemble.h" -#include "debugger.h" -#include "jit.h" -#include "patches.h" -#include "memory.h" -#include "disasm_fast.h" -#include "stackinfo.h" -#include "symbolinfo.h" -#include "module.h" - -static DBGFUNCTIONS _dbgfunctions; - -const DBGFUNCTIONS* dbgfunctionsget() -{ - return &_dbgfunctions; -} - -static bool _assembleatex(duint addr, const char* instruction, char* error, bool fillnop) -{ - return assembleat(addr, instruction, nullptr, error, fillnop); -} - -static bool _sectionfromaddr(duint addr, char* section) -{ - HMODULE hMod = (HMODULE)ModBaseFromAddr(addr); - if(!hMod) - return false; - wchar_t curModPath[MAX_PATH] = L""; - if(!GetModuleFileNameExW(fdProcessInfo->hProcess, hMod, curModPath, MAX_PATH)) - return false; - HANDLE FileHandle; - DWORD LoadedSize; - HANDLE FileMap; - ULONG_PTR FileMapVA; - if(StaticFileLoadW(curModPath, UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA)) - { - duint rva = addr - (duint)hMod; - int sectionNumber = GetPE32SectionNumberFromVA(FileMapVA, GetPE32DataFromMappedFile(FileMapVA, 0, UE_IMAGEBASE) + rva); - if(sectionNumber >= 0) - { - const char* name = (const char*)GetPE32DataFromMappedFile(FileMapVA, sectionNumber, UE_SECTIONNAME); - if(section) - strcpy_s(section, MAX_SECTION_SIZE, name); //maxi - StaticFileUnloadW(curModPath, false, FileHandle, LoadedSize, FileMap, FileMapVA); - return true; - } - StaticFileUnloadW(curModPath, false, FileHandle, LoadedSize, FileMap, FileMapVA); - } - return false; -} - -static bool _patchget(duint addr) -{ - return PatchGet(addr, nullptr); -} - -static bool _patchinrange(duint start, duint end) -{ - if(start > end) - std::swap(start, end); - - for(duint i = start; i <= end; i++) - { - if(_patchget(i)) - return true; - } - - return false; -} - -static bool _mempatch(duint va, const unsigned char* src, duint size) -{ - return MemPatch(va, src, size, nullptr); -} - -static void _patchrestorerange(duint start, duint end) -{ - if(start > end) - std::swap(start, end); - - for(duint i = start; i <= end; i++) - PatchDelete(i, true); - - GuiUpdatePatches(); -} - -static bool _patchrestore(duint addr) -{ - return PatchDelete(addr, true); -} - -static void _getcallstack(DBGCALLSTACK* callstack) -{ - stackgetcallstack(GetContextDataEx(hActiveThread, UE_CSP), (CALLSTACK*)callstack); -} - -static bool _getjitauto(bool* jit_auto) -{ - return dbggetjitauto(jit_auto, notfound, NULL, NULL); -} - -static bool _getcmdline(char* cmd_line, size_t* cbsize) -{ - if(!cmd_line && !cbsize) - return false; - char* cmdline; - if(!dbggetcmdline(&cmdline, NULL)) - return false; - if(!cmd_line && cbsize) - *cbsize = strlen(cmdline) + sizeof(char); - else if(cmd_line) - strcpy(cmd_line, cmdline); - efree(cmdline, "_getcmdline:cmdline"); - return true; -} - -static bool _setcmdline(const char* cmd_line) -{ - return dbgsetcmdline(cmd_line, nullptr); -} - -static bool _getjit(char* jit, bool jit64) -{ - arch dummy; - char jit_tmp[JIT_ENTRY_MAX_SIZE] = ""; - if(jit != NULL) - { - if(!dbggetjit(jit_tmp, jit64 ? x64 : x32, &dummy, NULL)) - return false; - strcpy_s(jit, MAX_SETTING_SIZE, jit_tmp); - } - else // if jit input == NULL: it returns false if there are not an OLD JIT STORED. - { - char oldjit[MAX_SETTING_SIZE] = ""; - if(!BridgeSettingGet("JIT", "Old", (char*) & oldjit)) - return false; - } - - return true; -} - -bool _getprocesslist(DBGPROCESSINFO** entries, int* count) -{ - std::vector list; - if(!dbglistprocesses(&list)) - return false; - *count = (int)list.size(); - if(!*count) - return false; - *entries = (DBGPROCESSINFO*)BridgeAlloc(*count * sizeof(DBGPROCESSINFO)); - for(int i = 0; i < *count; i++) - { - (*entries)[*count - i - 1].dwProcessId = list.at(i).th32ProcessID; - strcpy_s((*entries)[*count - i - 1].szExeFile, list.at(i).szExeFile); - } - return true; -} - -static void _memupdatemap() -{ - MemUpdateMap(); - GuiUpdateMemoryView(); -} - -static duint _getaddrfromline(const char* szSourceFile, int line) -{ - LONG displacement = 0; - IMAGEHLP_LINE64 lineData; - memset(&lineData, 0, sizeof(lineData)); - lineData.SizeOfStruct = sizeof(lineData); - if(!SymGetLineFromName64(fdProcessInfo->hProcess, NULL, szSourceFile, line, &displacement, &lineData)) - return 0; - return (duint)lineData.Address; -} - -static bool _getsourcefromaddr(duint addr, char* szSourceFile, int* line) -{ - char sourceFile[MAX_STRING_SIZE] = ""; - if(!SymGetSourceLine(addr, sourceFile, line)) - return false; - if(!FileExists(sourceFile)) - return false; - if(szSourceFile) - strcpy_s(szSourceFile, MAX_STRING_SIZE, sourceFile); - return true; -} - -static bool _valfromstring(const char* string, duint* value) -{ - return valfromstring(string, value); -} - -void dbgfunctionsinit() -{ - _dbgfunctions.AssembleAtEx = _assembleatex; - _dbgfunctions.SectionFromAddr = _sectionfromaddr; - _dbgfunctions.ModNameFromAddr = ModNameFromAddr; - _dbgfunctions.ModBaseFromAddr = ModBaseFromAddr; - _dbgfunctions.ModBaseFromName = ModBaseFromName; - _dbgfunctions.ModSizeFromAddr = ModSizeFromAddr; - _dbgfunctions.Assemble = assemble; - _dbgfunctions.PatchGet = _patchget; - _dbgfunctions.PatchInRange = _patchinrange; - _dbgfunctions.MemPatch = _mempatch; - _dbgfunctions.PatchRestoreRange = _patchrestorerange; - _dbgfunctions.PatchEnum = (PATCHENUM)PatchEnum; - _dbgfunctions.PatchRestore = _patchrestore; - _dbgfunctions.PatchFile = (PATCHFILE)PatchFile; - _dbgfunctions.ModPathFromAddr = ModPathFromAddr; - _dbgfunctions.ModPathFromName = ModPathFromName; - _dbgfunctions.DisasmFast = disasmfast; - _dbgfunctions.MemUpdateMap = _memupdatemap; - _dbgfunctions.GetCallStack = _getcallstack; - _dbgfunctions.SymbolDownloadAllSymbols = SymDownloadAllSymbols; - _dbgfunctions.GetJit = _getjit; - _dbgfunctions.GetJitAuto = _getjitauto; - _dbgfunctions.GetDefJit = dbggetdefjit; - _dbgfunctions.GetProcessList = _getprocesslist; - _dbgfunctions.GetPageRights = MemGetPageRights; - _dbgfunctions.SetPageRights = MemSetPageRights; - _dbgfunctions.PageRightsToString = MemPageRightsToString; - _dbgfunctions.IsProcessElevated = IsProcessElevated; - _dbgfunctions.GetCmdline = _getcmdline; - _dbgfunctions.SetCmdline = _setcmdline; - _dbgfunctions.FileOffsetToVa = valfileoffsettova; - _dbgfunctions.VaToFileOffset = valvatofileoffset; - _dbgfunctions.GetAddrFromLine = _getaddrfromline; - _dbgfunctions.GetSourceFromAddr = _getsourcefromaddr; - _dbgfunctions.ValFromString = _valfromstring; -} +/** + @file _dbgfunctions.cpp + + @brief Implements the dbgfunctions class. + */ + +#include "_global.h" +#include "_dbgfunctions.h" +#include "assemble.h" +#include "debugger.h" +#include "jit.h" +#include "patches.h" +#include "memory.h" +#include "disasm_fast.h" +#include "stackinfo.h" +#include "symbolinfo.h" +#include "module.h" + +static DBGFUNCTIONS _dbgfunctions; + +const DBGFUNCTIONS* dbgfunctionsget() +{ + return &_dbgfunctions; +} + +static bool _assembleatex(duint addr, const char* instruction, char* error, bool fillnop) +{ + return assembleat(addr, instruction, nullptr, error, fillnop); +} + +static bool _sectionfromaddr(duint addr, char* section) +{ + HMODULE hMod = (HMODULE)ModBaseFromAddr(addr); + if(!hMod) + return false; + wchar_t curModPath[MAX_PATH] = L""; + if(!GetModuleFileNameExW(fdProcessInfo->hProcess, hMod, curModPath, MAX_PATH)) + return false; + HANDLE FileHandle; + DWORD LoadedSize; + HANDLE FileMap; + ULONG_PTR FileMapVA; + if(StaticFileLoadW(curModPath, UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA)) + { + duint rva = addr - (duint)hMod; + int sectionNumber = GetPE32SectionNumberFromVA(FileMapVA, GetPE32DataFromMappedFile(FileMapVA, 0, UE_IMAGEBASE) + rva); + if(sectionNumber >= 0) + { + const char* name = (const char*)GetPE32DataFromMappedFile(FileMapVA, sectionNumber, UE_SECTIONNAME); + if(section) + strcpy_s(section, MAX_SECTION_SIZE, name); //maxi + StaticFileUnloadW(curModPath, false, FileHandle, LoadedSize, FileMap, FileMapVA); + return true; + } + StaticFileUnloadW(curModPath, false, FileHandle, LoadedSize, FileMap, FileMapVA); + } + return false; +} + +static bool _patchget(duint addr) +{ + return PatchGet(addr, nullptr); +} + +static bool _patchinrange(duint start, duint end) +{ + if(start > end) + std::swap(start, end); + + for(duint i = start; i <= end; i++) + { + if(_patchget(i)) + return true; + } + + return false; +} + +static bool _mempatch(duint va, const unsigned char* src, duint size) +{ + return MemPatch(va, src, size, nullptr); +} + +static void _patchrestorerange(duint start, duint end) +{ + if(start > end) + std::swap(start, end); + + for(duint i = start; i <= end; i++) + PatchDelete(i, true); + + GuiUpdatePatches(); +} + +static bool _patchrestore(duint addr) +{ + return PatchDelete(addr, true); +} + +static void _getcallstack(DBGCALLSTACK* callstack) +{ + stackgetcallstack(GetContextDataEx(hActiveThread, UE_CSP), (CALLSTACK*)callstack); +} + +static bool _getjitauto(bool* jit_auto) +{ + return dbggetjitauto(jit_auto, notfound, NULL, NULL); +} + +static bool _getcmdline(char* cmd_line, size_t* cbsize) +{ + if(!cmd_line && !cbsize) + return false; + char* cmdline; + if(!dbggetcmdline(&cmdline, NULL)) + return false; + if(!cmd_line && cbsize) + *cbsize = strlen(cmdline) + sizeof(char); + else if(cmd_line) + strcpy(cmd_line, cmdline); + efree(cmdline, "_getcmdline:cmdline"); + return true; +} + +static bool _setcmdline(const char* cmd_line) +{ + return dbgsetcmdline(cmd_line, nullptr); +} + +static bool _getjit(char* jit, bool jit64) +{ + arch dummy; + char jit_tmp[JIT_ENTRY_MAX_SIZE] = ""; + if(jit != NULL) + { + if(!dbggetjit(jit_tmp, jit64 ? x64 : x32, &dummy, NULL)) + return false; + strcpy_s(jit, MAX_SETTING_SIZE, jit_tmp); + } + else // if jit input == NULL: it returns false if there are not an OLD JIT STORED. + { + char oldjit[MAX_SETTING_SIZE] = ""; + if(!BridgeSettingGet("JIT", "Old", (char*) & oldjit)) + return false; + } + + return true; +} + +bool _getprocesslist(DBGPROCESSINFO** entries, int* count) +{ + std::vector list; + if(!dbglistprocesses(&list)) + return false; + *count = (int)list.size(); + if(!*count) + return false; + *entries = (DBGPROCESSINFO*)BridgeAlloc(*count * sizeof(DBGPROCESSINFO)); + for(int i = 0; i < *count; i++) + { + (*entries)[*count - i - 1].dwProcessId = list.at(i).th32ProcessID; + strcpy_s((*entries)[*count - i - 1].szExeFile, list.at(i).szExeFile); + } + return true; +} + +static void _memupdatemap() +{ + MemUpdateMap(); + GuiUpdateMemoryView(); +} + +static duint _getaddrfromline(const char* szSourceFile, int line) +{ + LONG displacement = 0; + IMAGEHLP_LINE64 lineData; + memset(&lineData, 0, sizeof(lineData)); + lineData.SizeOfStruct = sizeof(lineData); + if(!SymGetLineFromName64(fdProcessInfo->hProcess, NULL, szSourceFile, line, &displacement, &lineData)) + return 0; + return (duint)lineData.Address; +} + +static bool _getsourcefromaddr(duint addr, char* szSourceFile, int* line) +{ + char sourceFile[MAX_STRING_SIZE] = ""; + if(!SymGetSourceLine(addr, sourceFile, line)) + return false; + if(!FileExists(sourceFile)) + return false; + if(szSourceFile) + strcpy_s(szSourceFile, MAX_STRING_SIZE, sourceFile); + return true; +} + +static bool _valfromstring(const char* string, duint* value) +{ + return valfromstring(string, value); +} + +void dbgfunctionsinit() +{ + _dbgfunctions.AssembleAtEx = _assembleatex; + _dbgfunctions.SectionFromAddr = _sectionfromaddr; + _dbgfunctions.ModNameFromAddr = ModNameFromAddr; + _dbgfunctions.ModBaseFromAddr = ModBaseFromAddr; + _dbgfunctions.ModBaseFromName = ModBaseFromName; + _dbgfunctions.ModSizeFromAddr = ModSizeFromAddr; + _dbgfunctions.Assemble = assemble; + _dbgfunctions.PatchGet = _patchget; + _dbgfunctions.PatchInRange = _patchinrange; + _dbgfunctions.MemPatch = _mempatch; + _dbgfunctions.PatchRestoreRange = _patchrestorerange; + _dbgfunctions.PatchEnum = (PATCHENUM)PatchEnum; + _dbgfunctions.PatchRestore = _patchrestore; + _dbgfunctions.PatchFile = (PATCHFILE)PatchFile; + _dbgfunctions.ModPathFromAddr = ModPathFromAddr; + _dbgfunctions.ModPathFromName = ModPathFromName; + _dbgfunctions.DisasmFast = disasmfast; + _dbgfunctions.MemUpdateMap = _memupdatemap; + _dbgfunctions.GetCallStack = _getcallstack; + _dbgfunctions.SymbolDownloadAllSymbols = SymDownloadAllSymbols; + _dbgfunctions.GetJit = _getjit; + _dbgfunctions.GetJitAuto = _getjitauto; + _dbgfunctions.GetDefJit = dbggetdefjit; + _dbgfunctions.GetProcessList = _getprocesslist; + _dbgfunctions.GetPageRights = MemGetPageRights; + _dbgfunctions.SetPageRights = MemSetPageRights; + _dbgfunctions.PageRightsToString = MemPageRightsToString; + _dbgfunctions.IsProcessElevated = IsProcessElevated; + _dbgfunctions.GetCmdline = _getcmdline; + _dbgfunctions.SetCmdline = _setcmdline; + _dbgfunctions.FileOffsetToVa = valfileoffsettova; + _dbgfunctions.VaToFileOffset = valvatofileoffset; + _dbgfunctions.GetAddrFromLine = _getaddrfromline; + _dbgfunctions.GetSourceFromAddr = _getsourcefromaddr; + _dbgfunctions.ValFromString = _valfromstring; +} diff --git a/src/dbg/_dbgfunctions.h b/src/dbg/_dbgfunctions.h index dc8bb644..c2730ea2 100644 --- a/src/dbg/_dbgfunctions.h +++ b/src/dbg/_dbgfunctions.h @@ -1,118 +1,118 @@ -#ifndef _DBGFUNCTIONS_H -#define _DBGFUNCTIONS_H - -#ifndef __cplusplus -#include -#endif - -typedef struct -{ - char mod[MAX_MODULE_SIZE]; - duint addr; - unsigned char oldbyte; - unsigned char newbyte; -} DBGPATCHINFO; - -typedef struct -{ - duint addr; - duint from; - duint to; - char comment[MAX_COMMENT_SIZE]; -} DBGCALLSTACKENTRY; - -typedef struct -{ - int total; - DBGCALLSTACKENTRY* entries; -} DBGCALLSTACK; - -typedef struct -{ - DWORD dwProcessId; - char szExeFile[MAX_PATH]; -} DBGPROCESSINFO; - -typedef bool (*ASSEMBLEATEX)(duint addr, const char* instruction, char* error, bool fillnop); -typedef bool (*SECTIONFROMADDR)(duint addr, char* section); -typedef bool (*MODNAMEFROMADDR)(duint addr, char* modname, bool extension); -typedef duint (*MODBASEFROMADDR)(duint addr); -typedef duint (*MODBASEFROMNAME)(const char* modname); -typedef duint (*MODSIZEFROMADDR)(duint addr); -typedef bool (*ASSEMBLE)(duint addr, unsigned char* dest, int* size, const char* instruction, char* error); -typedef bool (*PATCHGET)(duint addr); -typedef bool (*PATCHINRANGE)(duint start, duint end); -typedef bool (*MEMPATCH)(duint va, const unsigned char* src, duint size); -typedef void (*PATCHRESTORERANGE)(duint start, duint end); -typedef bool (*PATCHENUM)(DBGPATCHINFO* patchlist, size_t* cbsize); -typedef bool (*PATCHRESTORE)(duint addr); -typedef int (*PATCHFILE)(DBGPATCHINFO* patchlist, int count, const char* szFileName, char* error); -typedef int (*MODPATHFROMADDR)(duint addr, char* path, int size); -typedef int (*MODPATHFROMNAME)(const char* modname, char* path, int size); -typedef bool (*DISASMFAST)(unsigned char* data, duint addr, BASIC_INSTRUCTION_INFO* basicinfo); -typedef void (*MEMUPDATEMAP)(); -typedef void (*GETCALLSTACK)(DBGCALLSTACK* callstack); -typedef void (*SYMBOLDOWNLOADALLSYMBOLS)(const char* szSymbolStore); -typedef bool (*GETJIT)(char* jit, bool x64); -typedef bool (*GETJITAUTO)(bool* jitauto); -typedef bool (*GETDEFJIT)(char* defjit); -typedef bool (*GETPROCESSLIST)(DBGPROCESSINFO** entries, int* count); -typedef bool (*GETPAGERIGHTS)(duint addr, char* rights); -typedef bool (*SETPAGERIGHTS)(duint addr, const char* rights); -typedef bool (*PAGERIGHTSTOSTRING)(DWORD protect, char* rights); -typedef bool (*ISPROCESSELEVATED)(); -typedef bool (*GETCMDLINE)(char* cmdline, size_t* cbsize); -typedef bool (*SETCMDLINE)(const char* cmdline); -typedef duint (*FILEOFFSETTOVA)(const char* modname, duint offset); -typedef duint (*VATOFILEOFFSET)(duint va); -typedef duint (*GETADDRFROMLINE)(const char* szSourceFile, int line); -typedef bool (*GETSOURCEFROMADDR)(duint addr, char* szSourceFile, int* line); -typedef bool (*VALFROMSTRING)(const char* string, duint* value); - -typedef struct DBGFUNCTIONS_ -{ - ASSEMBLEATEX AssembleAtEx; - SECTIONFROMADDR SectionFromAddr; - MODNAMEFROMADDR ModNameFromAddr; - MODBASEFROMADDR ModBaseFromAddr; - MODBASEFROMNAME ModBaseFromName; - MODSIZEFROMADDR ModSizeFromAddr; - ASSEMBLE Assemble; - PATCHGET PatchGet; - PATCHINRANGE PatchInRange; - MEMPATCH MemPatch; - PATCHRESTORERANGE PatchRestoreRange; - PATCHENUM PatchEnum; - PATCHRESTORE PatchRestore; - PATCHFILE PatchFile; - MODPATHFROMADDR ModPathFromAddr; - MODPATHFROMNAME ModPathFromName; - DISASMFAST DisasmFast; - MEMUPDATEMAP MemUpdateMap; - GETCALLSTACK GetCallStack; - SYMBOLDOWNLOADALLSYMBOLS SymbolDownloadAllSymbols; - GETJITAUTO GetJitAuto; - GETJIT GetJit; - GETDEFJIT GetDefJit; - GETPROCESSLIST GetProcessList; - GETPAGERIGHTS GetPageRights; - SETPAGERIGHTS SetPageRights; - PAGERIGHTSTOSTRING PageRightsToString; - ISPROCESSELEVATED IsProcessElevated; - GETCMDLINE GetCmdline; - SETCMDLINE SetCmdline; - FILEOFFSETTOVA FileOffsetToVa; - VATOFILEOFFSET VaToFileOffset; - GETADDRFROMLINE GetAddrFromLine; - GETSOURCEFROMADDR GetSourceFromAddr; - VALFROMSTRING ValFromString; -} DBGFUNCTIONS; - -#ifdef BUILD_DBG - -const DBGFUNCTIONS* dbgfunctionsget(); -void dbgfunctionsinit(); - -#endif //BUILD_DBG - -#endif //_DBGFUNCTIONS_H +#ifndef _DBGFUNCTIONS_H +#define _DBGFUNCTIONS_H + +#ifndef __cplusplus +#include +#endif + +typedef struct +{ + char mod[MAX_MODULE_SIZE]; + duint addr; + unsigned char oldbyte; + unsigned char newbyte; +} DBGPATCHINFO; + +typedef struct +{ + duint addr; + duint from; + duint to; + char comment[MAX_COMMENT_SIZE]; +} DBGCALLSTACKENTRY; + +typedef struct +{ + int total; + DBGCALLSTACKENTRY* entries; +} DBGCALLSTACK; + +typedef struct +{ + DWORD dwProcessId; + char szExeFile[MAX_PATH]; +} DBGPROCESSINFO; + +typedef bool (*ASSEMBLEATEX)(duint addr, const char* instruction, char* error, bool fillnop); +typedef bool (*SECTIONFROMADDR)(duint addr, char* section); +typedef bool (*MODNAMEFROMADDR)(duint addr, char* modname, bool extension); +typedef duint (*MODBASEFROMADDR)(duint addr); +typedef duint (*MODBASEFROMNAME)(const char* modname); +typedef duint (*MODSIZEFROMADDR)(duint addr); +typedef bool (*ASSEMBLE)(duint addr, unsigned char* dest, int* size, const char* instruction, char* error); +typedef bool (*PATCHGET)(duint addr); +typedef bool (*PATCHINRANGE)(duint start, duint end); +typedef bool (*MEMPATCH)(duint va, const unsigned char* src, duint size); +typedef void (*PATCHRESTORERANGE)(duint start, duint end); +typedef bool (*PATCHENUM)(DBGPATCHINFO* patchlist, size_t* cbsize); +typedef bool (*PATCHRESTORE)(duint addr); +typedef int (*PATCHFILE)(DBGPATCHINFO* patchlist, int count, const char* szFileName, char* error); +typedef int (*MODPATHFROMADDR)(duint addr, char* path, int size); +typedef int (*MODPATHFROMNAME)(const char* modname, char* path, int size); +typedef bool (*DISASMFAST)(unsigned char* data, duint addr, BASIC_INSTRUCTION_INFO* basicinfo); +typedef void (*MEMUPDATEMAP)(); +typedef void (*GETCALLSTACK)(DBGCALLSTACK* callstack); +typedef void (*SYMBOLDOWNLOADALLSYMBOLS)(const char* szSymbolStore); +typedef bool (*GETJIT)(char* jit, bool x64); +typedef bool (*GETJITAUTO)(bool* jitauto); +typedef bool (*GETDEFJIT)(char* defjit); +typedef bool (*GETPROCESSLIST)(DBGPROCESSINFO** entries, int* count); +typedef bool (*GETPAGERIGHTS)(duint addr, char* rights); +typedef bool (*SETPAGERIGHTS)(duint addr, const char* rights); +typedef bool (*PAGERIGHTSTOSTRING)(DWORD protect, char* rights); +typedef bool (*ISPROCESSELEVATED)(); +typedef bool (*GETCMDLINE)(char* cmdline, size_t* cbsize); +typedef bool (*SETCMDLINE)(const char* cmdline); +typedef duint (*FILEOFFSETTOVA)(const char* modname, duint offset); +typedef duint (*VATOFILEOFFSET)(duint va); +typedef duint (*GETADDRFROMLINE)(const char* szSourceFile, int line); +typedef bool (*GETSOURCEFROMADDR)(duint addr, char* szSourceFile, int* line); +typedef bool (*VALFROMSTRING)(const char* string, duint* value); + +typedef struct DBGFUNCTIONS_ +{ + ASSEMBLEATEX AssembleAtEx; + SECTIONFROMADDR SectionFromAddr; + MODNAMEFROMADDR ModNameFromAddr; + MODBASEFROMADDR ModBaseFromAddr; + MODBASEFROMNAME ModBaseFromName; + MODSIZEFROMADDR ModSizeFromAddr; + ASSEMBLE Assemble; + PATCHGET PatchGet; + PATCHINRANGE PatchInRange; + MEMPATCH MemPatch; + PATCHRESTORERANGE PatchRestoreRange; + PATCHENUM PatchEnum; + PATCHRESTORE PatchRestore; + PATCHFILE PatchFile; + MODPATHFROMADDR ModPathFromAddr; + MODPATHFROMNAME ModPathFromName; + DISASMFAST DisasmFast; + MEMUPDATEMAP MemUpdateMap; + GETCALLSTACK GetCallStack; + SYMBOLDOWNLOADALLSYMBOLS SymbolDownloadAllSymbols; + GETJITAUTO GetJitAuto; + GETJIT GetJit; + GETDEFJIT GetDefJit; + GETPROCESSLIST GetProcessList; + GETPAGERIGHTS GetPageRights; + SETPAGERIGHTS SetPageRights; + PAGERIGHTSTOSTRING PageRightsToString; + ISPROCESSELEVATED IsProcessElevated; + GETCMDLINE GetCmdline; + SETCMDLINE SetCmdline; + FILEOFFSETTOVA FileOffsetToVa; + VATOFILEOFFSET VaToFileOffset; + GETADDRFROMLINE GetAddrFromLine; + GETSOURCEFROMADDR GetSourceFromAddr; + VALFROMSTRING ValFromString; +} DBGFUNCTIONS; + +#ifdef BUILD_DBG + +const DBGFUNCTIONS* dbgfunctionsget(); +void dbgfunctionsinit(); + +#endif //BUILD_DBG + +#endif //_DBGFUNCTIONS_H diff --git a/src/dbg/_exports.cpp b/src/dbg/_exports.cpp index 982b7e87..4c2822e8 100644 --- a/src/dbg/_exports.cpp +++ b/src/dbg/_exports.cpp @@ -1,1014 +1,1014 @@ -/** - @file _exports.cpp - - @brief Implements the exports class. - */ - -#include "_exports.h" -#include "memory.h" -#include "debugger.h" -#include "value.h" -#include "threading.h" -#include "breakpoint.h" -#include "disasm_helper.h" -#include "simplescript.h" -#include "symbolinfo.h" -#include "assemble.h" -#include "stackinfo.h" -#include "thread.h" -#include "disasm_fast.h" -#include "plugin_loader.h" -#include "_dbgfunctions.h" -#include "module.h" -#include "comment.h" -#include "label.h" -#include "bookmark.h" -#include "function.h" -#include "loop.h" -#include "error.h" -#include "x64_dbg.h" -#include "threading.h" - -static bool bOnlyCipAutoComments = false; - -extern "C" DLL_EXPORT duint _dbg_memfindbaseaddr(duint addr, duint* size) -{ - return MemFindBaseAddr(addr, size); -} - -extern "C" DLL_EXPORT bool _dbg_memread(duint addr, unsigned char* dest, duint size, duint* read) -{ - return MemRead(addr, dest, size, read); -} - -extern "C" DLL_EXPORT bool _dbg_memwrite(duint addr, const unsigned char* src, duint size, duint* written) -{ - return MemWrite(addr, src, size, written); -} - -extern "C" DLL_EXPORT bool _dbg_memmap(MEMMAP* memmap) -{ - SHARED_ACQUIRE(LockMemoryPages); - - int pagecount = (int)memoryPages.size(); - memset(memmap, 0, sizeof(MEMMAP)); - memmap->count = pagecount; - if(!pagecount) - return true; - - // Allocate memory that is already zeroed - memmap->page = (MEMPAGE*)BridgeAlloc(sizeof(MEMPAGE) * pagecount); - - // Copy all elements over - int i = 0; - - for(auto & itr : memoryPages) - memcpy(&memmap->page[i++], &itr.second, sizeof(MEMPAGE)); - - // Done - return true; -} - -extern "C" DLL_EXPORT bool _dbg_memisvalidreadptr(duint addr) -{ - return MemIsValidReadPtr(addr); -} - -extern "C" DLL_EXPORT bool _dbg_valfromstring(const char* string, duint* value) -{ - return valfromstring(string, value); -} - -extern "C" DLL_EXPORT bool _dbg_isdebugging() -{ - if(IsFileBeingDebugged()) - return true; - - return false; -} - -extern "C" DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr) -{ - static duint cacheFlags; - static duint cacheAddr; - static bool cacheResult; - if(cacheAddr != addr || cacheFlags != GetContextDataEx(hActiveThread, UE_EFLAGS)) - { - cacheFlags = GetContextDataEx(hActiveThread, UE_EFLAGS); - cacheAddr = addr; - cacheResult = IsJumpGoingToExecuteEx(fdProcessInfo->hProcess, fdProcessInfo->hThread, (ULONG_PTR)cacheAddr, cacheFlags); - } - return cacheResult; -} - -extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDRINFO* addrinfo) -{ - if(!DbgIsDebugging()) - return false; - bool retval = false; - if(addrinfo->flags & flagmodule) //get module - { - if(ModNameFromAddr(addr, addrinfo->module, false)) //get module name - retval = true; - } - if(addrinfo->flags & flaglabel) - { - if(LabelGet(addr, addrinfo->label)) - retval = true; - else //no user labels - { - DWORD64 displacement = 0; - char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)]; - PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; - pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); - pSymbol->MaxNameLen = MAX_LABEL_SIZE; - if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) && !displacement) - { - pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; - if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) - strcpy_s(addrinfo->label, pSymbol->Name); - retval = true; - } - if(!retval) //search for CALL - { - BASIC_INSTRUCTION_INFO basicinfo; - memset(&basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO)); - if(disasmfast(addr, &basicinfo) && basicinfo.branch && !basicinfo.call && basicinfo.memory.value) //thing is a JMP - { - duint val = 0; - if(MemRead(basicinfo.memory.value, &val, sizeof(val))) - { - if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) && !displacement) - { - pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; - if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) - sprintf_s(addrinfo->label, "JMP.&%s", pSymbol->Name); - retval = true; - } - } - } - } - if(!retval) //search for module entry - { - duint entry = ModEntryFromAddr(addr); - if(entry && entry == addr) - { - strcpy_s(addrinfo->label, "EntryPoint"); - retval = true; - } - } - } - } - if(addrinfo->flags & flagbookmark) - { - addrinfo->isbookmark = BookmarkGet(addr); - retval = true; - } - if(addrinfo->flags & flagfunction) - { - if(FunctionGet(addr, &addrinfo->function.start, &addrinfo->function.end)) - retval = true; - } - if(addrinfo->flags & flagloop) - { - if(LoopGet(addrinfo->loop.depth, addr, &addrinfo->loop.start, &addrinfo->loop.end)) - retval = true; - } - if(addrinfo->flags & flagcomment) - { - *addrinfo->comment = 0; - if(CommentGet(addr, addrinfo->comment)) - retval = true; - else - { - DWORD dwDisplacement; - IMAGEHLP_LINE64 line; - line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); - if(SafeSymGetLineFromAddr64(fdProcessInfo->hProcess, (DWORD64)addr, &dwDisplacement, &line) && !dwDisplacement) - { - char filename[deflen] = ""; - strcpy_s(filename, line.FileName); - int len = (int)strlen(filename); - while(filename[len] != '\\' && len != 0) - len--; - if(len) - len++; - sprintf_s(addrinfo->comment, "\1%s:%u", filename + len, line.LineNumber); - retval = true; - } - else if(!bOnlyCipAutoComments || addr == GetContextDataEx(hActiveThread, UE_CIP)) //no line number - { - DISASM_INSTR instr; - String temp_string; - String comment; - ADDRINFO newinfo; - char ascii[256 * 2] = ""; - char unicode[256 * 2] = ""; - - memset(&instr, 0, sizeof(DISASM_INSTR)); - disasmget(addr, &instr); - int len_left = MAX_COMMENT_SIZE; - for(int i = 0; i < instr.argcount; i++) - { - memset(&newinfo, 0, sizeof(ADDRINFO)); - newinfo.flags = flaglabel; - - STRING_TYPE strtype = str_none; - - if(instr.arg[i].constant == instr.arg[i].value) //avoid: call ; addr:label - { - if(instr.type == instr_branch || !disasmgetstringat(instr.arg[i].constant, &strtype, ascii, unicode, len_left) || strtype == str_none) - continue; - switch(strtype) - { - case str_none: - break; - case str_ascii: - temp_string = instr.arg[i].mnemonic; - temp_string.append(":\""); - temp_string.append(ascii); - temp_string.append("\""); - break; - case str_unicode: - temp_string = instr.arg[i].mnemonic; - temp_string.append(":L\""); - temp_string.append(unicode); - temp_string.append("\""); - break; - } - } - else if(instr.arg[i].memvalue && (disasmgetstringat(instr.arg[i].memvalue, &strtype, ascii, unicode, len_left) || _dbg_addrinfoget(instr.arg[i].memvalue, instr.arg[i].segment, &newinfo))) - { - switch(strtype) - { - case str_none: - if(*newinfo.label) - { - temp_string = "["; - temp_string.append(instr.arg[i].mnemonic); - temp_string.append("]:"); - temp_string.append(newinfo.label); - } - break; - case str_ascii: - temp_string = "["; - temp_string.append(instr.arg[i].mnemonic); - temp_string.append("]:"); - temp_string.append(ascii); - break; - case str_unicode: - temp_string = "["; - temp_string.append(instr.arg[i].mnemonic); - temp_string.append("]:"); - temp_string.append(unicode); - break; - } - } - else if(instr.arg[i].value && (disasmgetstringat(instr.arg[i].value, &strtype, ascii, unicode, len_left) || _dbg_addrinfoget(instr.arg[i].value, instr.arg[i].segment, &newinfo))) - { - if(instr.type != instr_normal) //stack/jumps (eg add esp,4 or jmp 401110) cannot directly point to strings - strtype = str_none; - switch(strtype) - { - case str_none: - if(*newinfo.label) - { - temp_string = instr.arg[i].mnemonic; - temp_string.append(":"); - temp_string.append(newinfo.label); - } - break; - case str_ascii: - temp_string = instr.arg[i].mnemonic; - temp_string.append(":\""); - temp_string.append(ascii); - temp_string.append("\""); - break; - case str_unicode: - temp_string = instr.arg[i].mnemonic; - temp_string.append(":L\""); - temp_string.append(unicode); - temp_string.append("\""); - break; - } - } - else - continue; - - if(!strstr(comment.c_str(), temp_string.c_str())) - { - if(comment.length()) - comment.append(", "); - comment.append(temp_string); - retval = true; - } - } - comment.resize(MAX_COMMENT_SIZE - 2); - String fullComment = "\1"; - fullComment += comment; - strcpy_s(addrinfo->comment, fullComment.c_str()); - } - } - } - return retval; -} - -extern "C" DLL_EXPORT bool _dbg_addrinfoset(duint addr, ADDRINFO* addrinfo) -{ - bool retval = false; - if(addrinfo->flags & flaglabel) //set label - { - if(LabelSet(addr, addrinfo->label, true)) - retval = true; - } - if(addrinfo->flags & flagcomment) //set comment - { - if(CommentSet(addr, addrinfo->comment, true)) - retval = true; - } - if(addrinfo->flags & flagbookmark) //set bookmark - { - if(addrinfo->isbookmark) - retval = BookmarkSet(addr, true); - else - retval = BookmarkDelete(addr); - } - return retval; -} - -extern "C" DLL_EXPORT int _dbg_bpgettypeat(duint addr) -{ - static duint cacheAddr; - static int cacheBpCount; - static int cacheResult; - int bpcount = BpGetList(nullptr); - if(cacheAddr != addr || cacheBpCount != bpcount) - { - BREAKPOINT bp; - cacheAddr = addr; - cacheResult = 0; - cacheBpCount = bpcount; - if(BpGet(addr, BPNORMAL, 0, &bp)) - if(bp.enabled) - cacheResult |= bp_normal; - if(BpGet(addr, BPHARDWARE, 0, &bp)) - if(bp.enabled) - cacheResult |= bp_hardware; - if(BpGet(addr, BPMEMORY, 0, &bp)) - if(bp.enabled) - cacheResult |= bp_memory; - } - return cacheResult; -} - -static void GetMxCsrFields(MXCSRFIELDS* MxCsrFields, DWORD MxCsr) -{ - MxCsrFields->DAZ = valmxcsrflagfromstring(MxCsr, "DAZ"); - MxCsrFields->DE = valmxcsrflagfromstring(MxCsr, "DE"); - MxCsrFields->FZ = valmxcsrflagfromstring(MxCsr, "FZ"); - MxCsrFields->IE = valmxcsrflagfromstring(MxCsr, "IE"); - MxCsrFields->IM = valmxcsrflagfromstring(MxCsr, "IM"); - MxCsrFields->DM = valmxcsrflagfromstring(MxCsr, "DM"); - MxCsrFields->OE = valmxcsrflagfromstring(MxCsr, "OE"); - MxCsrFields->OM = valmxcsrflagfromstring(MxCsr, "OM"); - MxCsrFields->PE = valmxcsrflagfromstring(MxCsr, "PE"); - MxCsrFields->PM = valmxcsrflagfromstring(MxCsr, "PM"); - MxCsrFields->UE = valmxcsrflagfromstring(MxCsr, "UE"); - MxCsrFields->UM = valmxcsrflagfromstring(MxCsr, "UM"); - MxCsrFields->ZE = valmxcsrflagfromstring(MxCsr, "ZE"); - MxCsrFields->ZM = valmxcsrflagfromstring(MxCsr, "ZM"); - - MxCsrFields->RC = valmxcsrfieldfromstring(MxCsr, "RC"); -} - -static void Getx87ControlWordFields(X87CONTROLWORDFIELDS* x87ControlWordFields, WORD ControlWord) -{ - x87ControlWordFields->DM = valx87controlwordflagfromstring(ControlWord, "DM"); - x87ControlWordFields->IC = valx87controlwordflagfromstring(ControlWord, "IC"); - x87ControlWordFields->IEM = valx87controlwordflagfromstring(ControlWord, "IEM"); - x87ControlWordFields->IM = valx87controlwordflagfromstring(ControlWord, "IM"); - x87ControlWordFields->OM = valx87controlwordflagfromstring(ControlWord, "OM"); - x87ControlWordFields->PM = valx87controlwordflagfromstring(ControlWord, "PM"); - x87ControlWordFields->UM = valx87controlwordflagfromstring(ControlWord, "UM"); - x87ControlWordFields->ZM = valx87controlwordflagfromstring(ControlWord, "ZM"); - - x87ControlWordFields->RC = valx87controlwordfieldfromstring(ControlWord, "RC"); - x87ControlWordFields->PC = valx87controlwordfieldfromstring(ControlWord, "PC"); -} - -static void Getx87StatusWordFields(X87STATUSWORDFIELDS* x87StatusWordFields, WORD StatusWord) -{ - x87StatusWordFields->B = valx87statuswordflagfromstring(StatusWord, "B"); - x87StatusWordFields->C0 = valx87statuswordflagfromstring(StatusWord, "C0"); - x87StatusWordFields->C1 = valx87statuswordflagfromstring(StatusWord, "C1"); - x87StatusWordFields->C2 = valx87statuswordflagfromstring(StatusWord, "C2"); - x87StatusWordFields->C3 = valx87statuswordflagfromstring(StatusWord, "C3"); - x87StatusWordFields->D = valx87statuswordflagfromstring(StatusWord, "D"); - x87StatusWordFields->I = valx87statuswordflagfromstring(StatusWord, "I"); - x87StatusWordFields->IR = valx87statuswordflagfromstring(StatusWord, "IR"); - x87StatusWordFields->O = valx87statuswordflagfromstring(StatusWord, "O"); - x87StatusWordFields->P = valx87statuswordflagfromstring(StatusWord, "P"); - x87StatusWordFields->SF = valx87statuswordflagfromstring(StatusWord, "SF"); - x87StatusWordFields->U = valx87statuswordflagfromstring(StatusWord, "U"); - x87StatusWordFields->Z = valx87statuswordflagfromstring(StatusWord, "Z"); - - x87StatusWordFields->TOP = valx87statuswordfieldfromstring(StatusWord, "TOP"); -} - -static void TranslateTitanFpu(const x87FPU_t* titanfpu, X87FPU* fpu) -{ - fpu->ControlWord = titanfpu->ControlWord; - fpu->StatusWord = titanfpu->StatusWord; - fpu->TagWord = titanfpu->TagWord; - fpu->ErrorOffset = titanfpu->ErrorOffset; - fpu->ErrorSelector = titanfpu->ErrorSelector; - fpu->DataOffset = titanfpu->DataOffset; - fpu->DataSelector = titanfpu->DataSelector; - fpu->Cr0NpxState = titanfpu->Cr0NpxState; -} - -static void TranslateTitanContextToRegContext(const TITAN_ENGINE_CONTEXT_t* titcontext, REGISTERCONTEXT* regcontext) -{ - regcontext->cax = titcontext->cax; - regcontext->ccx = titcontext->ccx; - regcontext->cdx = titcontext->cdx; - regcontext->cbx = titcontext->cbx; - regcontext->csp = titcontext->csp; - regcontext->cbp = titcontext->cbp; - regcontext->csi = titcontext->csi; - regcontext->cdi = titcontext->cdi; -#ifdef _WIN64 - regcontext->r8 = titcontext->r8; - regcontext->r9 = titcontext->r9; - regcontext->r10 = titcontext->r10; - regcontext->r11 = titcontext->r11; - regcontext->r12 = titcontext->r12; - regcontext->r13 = titcontext->r13; - regcontext->r14 = titcontext->r14; - regcontext->r15 = titcontext->r15; -#endif //_WIN64 - regcontext->cip = titcontext->cip; - regcontext->eflags = titcontext->eflags; - regcontext->gs = titcontext->gs; - regcontext->fs = titcontext->fs; - regcontext->es = titcontext->es; - regcontext->ds = titcontext->ds; - regcontext->cs = titcontext->cs; - regcontext->ss = titcontext->ss; - regcontext->dr0 = titcontext->dr0; - regcontext->dr1 = titcontext->dr1; - regcontext->dr2 = titcontext->dr2; - regcontext->dr3 = titcontext->dr3; - regcontext->dr6 = titcontext->dr6; - regcontext->dr7 = titcontext->dr7; - memcpy(regcontext->RegisterArea, titcontext->RegisterArea, sizeof(regcontext->RegisterArea)); - TranslateTitanFpu(&titcontext->x87fpu, ®context->x87fpu); - regcontext->MxCsr = titcontext->MxCsr; - memcpy(regcontext->XmmRegisters, titcontext->XmmRegisters, sizeof(regcontext->XmmRegisters)); - memcpy(regcontext->YmmRegisters, titcontext->YmmRegisters, sizeof(regcontext->YmmRegisters)); -} - -static void TranslateTitanFpuRegister(const x87FPURegister_t* titanReg, X87FPUREGISTER* reg) -{ - memcpy(reg->data, titanReg->data, sizeof(reg->data)); - reg->st_value = titanReg->st_value; - reg->tag = titanReg->tag; -} - -static void TranslateTitanFpuRegisters(const x87FPURegister_t titanFpu[8], X87FPUREGISTER fpu[8]) -{ - for(int i = 0; i < 8; i++) - TranslateTitanFpuRegister(&titanFpu[i], &fpu[i]); -} - -extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump) -{ - if(!DbgIsDebugging()) - { - memset(regdump, 0, sizeof(REGDUMP)); - return true; - } - - TITAN_ENGINE_CONTEXT_t titcontext; - if(!GetFullContextDataEx(hActiveThread, &titcontext)) - return false; - TranslateTitanContextToRegContext(&titcontext, ®dump->regcontext); - - duint cflags = regdump->regcontext.eflags; - regdump->flags.c = valflagfromstring(cflags, "cf"); - regdump->flags.p = valflagfromstring(cflags, "pf"); - regdump->flags.a = valflagfromstring(cflags, "af"); - regdump->flags.z = valflagfromstring(cflags, "zf"); - regdump->flags.s = valflagfromstring(cflags, "sf"); - regdump->flags.t = valflagfromstring(cflags, "tf"); - regdump->flags.i = valflagfromstring(cflags, "if"); - regdump->flags.d = valflagfromstring(cflags, "df"); - regdump->flags.o = valflagfromstring(cflags, "of"); - - x87FPURegister_t x87FPURegisters[8]; - Getx87FPURegisters(x87FPURegisters, &titcontext); - TranslateTitanFpuRegisters(x87FPURegisters, regdump->x87FPURegisters); - - GetMMXRegisters(regdump->mmx, &titcontext); - GetMxCsrFields(& (regdump->MxCsrFields), regdump->regcontext.MxCsr); - Getx87ControlWordFields(& (regdump->x87ControlWordFields), regdump->regcontext.x87fpu.ControlWord); - Getx87StatusWordFields(& (regdump->x87StatusWordFields), regdump->regcontext.x87fpu.StatusWord); - LASTERROR lastError; - lastError.code = ThreadGetLastError(ThreadGetId(hActiveThread)); - lastError.name = ErrorCodeToName(lastError.code); - regdump->lastError = lastError; - - return true; -} - -extern "C" DLL_EXPORT bool _dbg_valtostring(const char* string, duint value) -{ - return valtostring(string, value, true); -} - -extern "C" DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* bpmap) -{ - if(!bpmap) - return 0; - std::vector list; - int bpcount = BpGetList(&list); - if(bpcount == 0) - { - bpmap->count = 0; - return 0; - } - - int retcount = 0; - std::vector bridgeList; - BRIDGEBP curBp; - unsigned short slot = 0; - for(int i = 0; i < bpcount; i++) - { - memset(&curBp, 0, sizeof(BRIDGEBP)); - switch(type) - { - case bp_none: //all types - break; - case bp_normal: //normal - if(list[i].type != BPNORMAL) - continue; - break; - case bp_hardware: //hardware - if(list[i].type != BPHARDWARE) - continue; - break; - case bp_memory: //memory - if(list[i].type != BPMEMORY) - continue; - break; - default: - return 0; - } - switch(list[i].type) - { - case BPNORMAL: - curBp.type = bp_normal; - break; - case BPHARDWARE: - curBp.type = bp_hardware; - break; - case BPMEMORY: - curBp.type = bp_memory; - break; - } - switch(((DWORD)list[i].titantype) >> 8) - { - case UE_DR0: - slot = 0; - break; - case UE_DR1: - slot = 1; - break; - case UE_DR2: - slot = 2; - break; - case UE_DR3: - slot = 3; - break; - } - curBp.addr = list[i].addr; - curBp.enabled = list[i].enabled; - //TODO: fix this - if(MemIsValidReadPtr(curBp.addr)) - curBp.active = true; - strcpy_s(curBp.mod, list[i].mod); - strcpy_s(curBp.name, list[i].name); - curBp.singleshoot = list[i].singleshoot; - curBp.slot = slot; - if(curBp.active) - { - bridgeList.push_back(curBp); - retcount++; - } - } - if(!retcount) - { - bpmap->count = retcount; - return retcount; - } - bpmap->count = retcount; - bpmap->bp = (BRIDGEBP*)BridgeAlloc(sizeof(BRIDGEBP) * retcount); - for(int i = 0; i < retcount; i++) - memcpy(&bpmap->bp[i], &bridgeList.at(i), sizeof(BRIDGEBP)); - return retcount; -} - -extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr) -{ - DISASM_INSTR instr; - memset(&instr, 0, sizeof(instr)); - disasmget(addr, &instr); - if(instr.type != instr_branch) - return 0; - if(strstr(instr.instruction, "ret")) - { - duint atcsp = DbgValFromString("@csp"); - if(DbgMemIsValidReadPtr(atcsp)) - return atcsp; - else - return 0; - } - else if(instr.arg[0].type == arg_memory) - return instr.arg[0].memvalue; - else - return instr.arg[0].value; -} - -extern "C" DLL_EXPORT bool _dbg_functionoverlaps(duint start, duint end) -{ - return FunctionOverlaps(start, end); -} - -extern "C" DLL_EXPORT duint _dbg_sendmessage(DBGMSG type, void* param1, void* param2) -{ - if(dbgisstopped()) - { - switch(type) //ignore win events - { - //these functions are safe to call when we did not initialize yet - case DBG_DEINITIALIZE_LOCKS: - case DBG_INITIALIZE_LOCKS: - case DBG_GET_FUNCTIONS: - case DBG_SETTINGS_UPDATED: - case DBG_GET_THREAD_LIST: - case DBG_WIN_EVENT: - case DBG_WIN_EVENT_GLOBAL: - break; - //the rest is unsafe -> throw an exception when people try to call them - default: - __debugbreak(); //we cannot process messages when the debugger is stopped, this must be a bug - } - } - switch(type) - { - case DBG_SCRIPT_LOAD: - { - scriptload((const char*)param1); - } - break; - - case DBG_SCRIPT_UNLOAD: - { - scriptunload(); - } - break; - - case DBG_SCRIPT_RUN: - { - scriptrun((int)(duint)param1); - } - break; - - case DBG_SCRIPT_STEP: - { - scriptstep(); - } - break; - - case DBG_SCRIPT_BPTOGGLE: - { - return scriptbptoggle((int)(duint)param1); - } - break; - - case DBG_SCRIPT_BPGET: - { - return scriptbpget((int)(duint)param1); - } - break; - - case DBG_SCRIPT_CMDEXEC: - { - return scriptcmdexec((const char*)param1); - } - break; - - case DBG_SCRIPT_ABORT: - { - scriptabort(); - } - break; - - case DBG_SCRIPT_GETLINETYPE: - { - return (duint)scriptgetlinetype((int)(duint)param1); - } - break; - - case DBG_SCRIPT_SETIP: - { - scriptsetip((int)(duint)param1); - } - break; - - case DBG_SCRIPT_GETBRANCHINFO: - { - return (duint)scriptgetbranchinfo((int)(duint)param1, (SCRIPTBRANCH*)param2); - } - break; - - case DBG_SYMBOL_ENUM: - { - SYMBOLCBINFO* cbInfo = (SYMBOLCBINFO*)param1; - SymEnum(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user); - } - break; - - case DBG_ASSEMBLE_AT: - { - return assembleat((duint)param1, (const char*)param2, 0, 0, false); - } - break; - - case DBG_MODBASE_FROM_NAME: - { - return ModBaseFromName((const char*)param1); - } - break; - - case DBG_DISASM_AT: - { - disasmget((duint)param1, (DISASM_INSTR*)param2); - } - break; - - case DBG_STACK_COMMENT_GET: - { - return stackcommentget((duint)param1, (STACK_COMMENT*)param2); - } - break; - - case DBG_GET_THREAD_LIST: - { - ThreadGetList((THREADLIST*)param1); - } - break; - - case DBG_SETTINGS_UPDATED: - { - valuesetsignedcalc(!settingboolget("Engine", "CalculationType")); //0:signed, 1:unsigned - SetEngineVariable(UE_ENGINE_SET_DEBUG_PRIVILEGE, settingboolget("Engine", "EnableDebugPrivilege")); - bOnlyCipAutoComments = settingboolget("Disassembler", "OnlyCipAutoComments"); - bListAllPages = settingboolget("Engine", "ListAllPages"); - bUndecorateSymbolNames = settingboolget("Engine", "UndecorateSymbolNames"); - bEnableSourceDebugging = settingboolget("Engine", "EnableSourceDebugging"); - - duint setting; - if(BridgeSettingGetUint("Engine", "BreakpointType", &setting)) - { - switch(setting) - { - case 0: //break_int3short - SetBPXOptions(UE_BREAKPOINT_INT3); - break; - case 1: //break_int3long - SetBPXOptions(UE_BREAKPOINT_LONG_INT3); - break; - case 2: //break_ud2 - SetBPXOptions(UE_BREAKPOINT_UD2); - break; - } - } - - char exceptionRange[MAX_SETTING_SIZE] = ""; - dbgclearignoredexceptions(); - if(BridgeSettingGet("Exceptions", "IgnoreRange", exceptionRange)) - { - char* entry = strtok(exceptionRange, ","); - while(entry) - { - unsigned long start; - unsigned long end; - if(sscanf(entry, "%08X-%08X", &start, &end) == 2 && start <= end) - { - ExceptionRange range; - range.start = start; - range.end = end; - dbgaddignoredexception(range); - } - entry = strtok(0, ","); - } - } - - char cachePath[MAX_SETTING_SIZE]; - if(BridgeSettingGet("Symbols", "CachePath", cachePath)) - { - // Trim the buffer to fit inside MAX_PATH - strncpy_s(szSymbolCachePath, cachePath, _TRUNCATE); - } - } - break; - - case DBG_DISASM_FAST_AT: - { - if(!param1 || !param2) - return 0; - BASIC_INSTRUCTION_INFO* basicinfo = (BASIC_INSTRUCTION_INFO*)param2; - if(!disasmfast((duint)param1, basicinfo)) - basicinfo->size = 1; - return 0; - } - break; - - case DBG_MENU_ENTRY_CLICKED: - { - int hEntry = (int)(duint)param1; - pluginmenucall(hEntry); - } - break; - - case DBG_FUNCTION_GET: - { - FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; - return (duint)FunctionGet(info->addr, &info->start, &info->end); - } - break; - - case DBG_FUNCTION_OVERLAPS: - { - FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; - return (duint)FunctionOverlaps(info->start, info->end); - } - break; - - case DBG_FUNCTION_ADD: - { - FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; - return (duint)FunctionAdd(info->start, info->end, info->manual); - } - break; - - case DBG_FUNCTION_DEL: - { - FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; - return (duint)FunctionDelete(info->addr); - } - break; - - case DBG_LOOP_GET: - { - FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; - return (duint)LoopGet(info->depth, info->addr, &info->start, &info->end); - } - break; - - case DBG_LOOP_OVERLAPS: - { - FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; - return (duint)LoopOverlaps(info->depth, info->start, info->end, 0); - } - break; - - case DBG_LOOP_ADD: - { - FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; - return (duint)LoopAdd(info->start, info->end, info->manual); - } - break; - - case DBG_LOOP_DEL: - { - FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; - return (duint)LoopDelete(info->depth, info->addr); - } - break; - - case DBG_IS_RUN_LOCKED: - { - return (duint)waitislocked(WAITID_RUN); - } - break; - - case DBG_IS_BP_DISABLED: - { - BREAKPOINT bp; - if(BpGet((duint)param1, BPNORMAL, 0, &bp)) - return !(duint)bp.enabled; - return (duint)false; - } - break; - - case DBG_SET_AUTO_COMMENT_AT: - { - return (duint)CommentSet((duint)param1, (const char*)param2, false); - } - break; - - case DBG_DELETE_AUTO_COMMENT_RANGE: - { - CommentDelRange((duint)param1, (duint)param2); - } - break; - - case DBG_SET_AUTO_LABEL_AT: - { - return (duint)LabelSet((duint)param1, (const char*)param2, false); - } - break; - - case DBG_DELETE_AUTO_LABEL_RANGE: - { - LabelDelRange((duint)param1, (duint)param2); - } - break; - - case DBG_SET_AUTO_BOOKMARK_AT: - { - return (duint)BookmarkSet((duint)param1, false); - } - break; - - case DBG_DELETE_AUTO_BOOKMARK_RANGE: - { - BookmarkDelRange((duint)param1, (duint)param2); - } - break; - - case DBG_SET_AUTO_FUNCTION_AT: - { - return (duint)FunctionAdd((duint)param1, (duint)param2, false); - } - break; - - case DBG_DELETE_AUTO_FUNCTION_RANGE: - { - FunctionDelRange((duint)param1, (duint)param2); - } - break; - - case DBG_GET_STRING_AT: - { - STRING_TYPE strtype; - char string[MAX_STRING_SIZE]; - if(disasmgetstringat((duint)param1, &strtype, string, string, MAX_STRING_SIZE - 3)) - { - if(strtype == str_ascii) - sprintf((char*)param2, "\"%s\"", string); - else //unicode - sprintf((char*)param2, "L\"%s\"", string); - return true; - } - return false; - } - break; - - case DBG_GET_FUNCTIONS: - { - return (duint)dbgfunctionsget(); - } - break; - - case DBG_WIN_EVENT: - { - return (duint)pluginwinevent((MSG*)param1, (long*)param2); - } - break; - - case DBG_WIN_EVENT_GLOBAL: - { - return (duint)pluginwineventglobal((MSG*)param1); - } - break; - - case DBG_INITIALIZE_LOCKS: - { - SectionLockerGlobal::Initialize(); - } - break; - - case DBG_DEINITIALIZE_LOCKS: - { - SectionLockerGlobal::Deinitialize(); - } - break; - - case DBG_GET_TIME_WASTED_COUNTER: - return dbggettimewastedcounter(); - } - return 0; -} +/** + @file _exports.cpp + + @brief Implements the exports class. + */ + +#include "_exports.h" +#include "memory.h" +#include "debugger.h" +#include "value.h" +#include "threading.h" +#include "breakpoint.h" +#include "disasm_helper.h" +#include "simplescript.h" +#include "symbolinfo.h" +#include "assemble.h" +#include "stackinfo.h" +#include "thread.h" +#include "disasm_fast.h" +#include "plugin_loader.h" +#include "_dbgfunctions.h" +#include "module.h" +#include "comment.h" +#include "label.h" +#include "bookmark.h" +#include "function.h" +#include "loop.h" +#include "error.h" +#include "x64_dbg.h" +#include "threading.h" + +static bool bOnlyCipAutoComments = false; + +extern "C" DLL_EXPORT duint _dbg_memfindbaseaddr(duint addr, duint* size) +{ + return MemFindBaseAddr(addr, size); +} + +extern "C" DLL_EXPORT bool _dbg_memread(duint addr, unsigned char* dest, duint size, duint* read) +{ + return MemRead(addr, dest, size, read); +} + +extern "C" DLL_EXPORT bool _dbg_memwrite(duint addr, const unsigned char* src, duint size, duint* written) +{ + return MemWrite(addr, src, size, written); +} + +extern "C" DLL_EXPORT bool _dbg_memmap(MEMMAP* memmap) +{ + SHARED_ACQUIRE(LockMemoryPages); + + int pagecount = (int)memoryPages.size(); + memset(memmap, 0, sizeof(MEMMAP)); + memmap->count = pagecount; + if(!pagecount) + return true; + + // Allocate memory that is already zeroed + memmap->page = (MEMPAGE*)BridgeAlloc(sizeof(MEMPAGE) * pagecount); + + // Copy all elements over + int i = 0; + + for(auto & itr : memoryPages) + memcpy(&memmap->page[i++], &itr.second, sizeof(MEMPAGE)); + + // Done + return true; +} + +extern "C" DLL_EXPORT bool _dbg_memisvalidreadptr(duint addr) +{ + return MemIsValidReadPtr(addr); +} + +extern "C" DLL_EXPORT bool _dbg_valfromstring(const char* string, duint* value) +{ + return valfromstring(string, value); +} + +extern "C" DLL_EXPORT bool _dbg_isdebugging() +{ + if(IsFileBeingDebugged()) + return true; + + return false; +} + +extern "C" DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr) +{ + static duint cacheFlags; + static duint cacheAddr; + static bool cacheResult; + if(cacheAddr != addr || cacheFlags != GetContextDataEx(hActiveThread, UE_EFLAGS)) + { + cacheFlags = GetContextDataEx(hActiveThread, UE_EFLAGS); + cacheAddr = addr; + cacheResult = IsJumpGoingToExecuteEx(fdProcessInfo->hProcess, fdProcessInfo->hThread, (ULONG_PTR)cacheAddr, cacheFlags); + } + return cacheResult; +} + +extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDRINFO* addrinfo) +{ + if(!DbgIsDebugging()) + return false; + bool retval = false; + if(addrinfo->flags & flagmodule) //get module + { + if(ModNameFromAddr(addr, addrinfo->module, false)) //get module name + retval = true; + } + if(addrinfo->flags & flaglabel) + { + if(LabelGet(addr, addrinfo->label)) + retval = true; + else //no user labels + { + DWORD64 displacement = 0; + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)]; + PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); + pSymbol->MaxNameLen = MAX_LABEL_SIZE; + if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) && !displacement) + { + pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; + if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) + strcpy_s(addrinfo->label, pSymbol->Name); + retval = true; + } + if(!retval) //search for CALL + { + BASIC_INSTRUCTION_INFO basicinfo; + memset(&basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO)); + if(disasmfast(addr, &basicinfo) && basicinfo.branch && !basicinfo.call && basicinfo.memory.value) //thing is a JMP + { + duint val = 0; + if(MemRead(basicinfo.memory.value, &val, sizeof(val))) + { + if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) && !displacement) + { + pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; + if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) + sprintf_s(addrinfo->label, "JMP.&%s", pSymbol->Name); + retval = true; + } + } + } + } + if(!retval) //search for module entry + { + duint entry = ModEntryFromAddr(addr); + if(entry && entry == addr) + { + strcpy_s(addrinfo->label, "EntryPoint"); + retval = true; + } + } + } + } + if(addrinfo->flags & flagbookmark) + { + addrinfo->isbookmark = BookmarkGet(addr); + retval = true; + } + if(addrinfo->flags & flagfunction) + { + if(FunctionGet(addr, &addrinfo->function.start, &addrinfo->function.end)) + retval = true; + } + if(addrinfo->flags & flagloop) + { + if(LoopGet(addrinfo->loop.depth, addr, &addrinfo->loop.start, &addrinfo->loop.end)) + retval = true; + } + if(addrinfo->flags & flagcomment) + { + *addrinfo->comment = 0; + if(CommentGet(addr, addrinfo->comment)) + retval = true; + else + { + DWORD dwDisplacement; + IMAGEHLP_LINE64 line; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + if(SafeSymGetLineFromAddr64(fdProcessInfo->hProcess, (DWORD64)addr, &dwDisplacement, &line) && !dwDisplacement) + { + char filename[deflen] = ""; + strcpy_s(filename, line.FileName); + int len = (int)strlen(filename); + while(filename[len] != '\\' && len != 0) + len--; + if(len) + len++; + sprintf_s(addrinfo->comment, "\1%s:%u", filename + len, line.LineNumber); + retval = true; + } + else if(!bOnlyCipAutoComments || addr == GetContextDataEx(hActiveThread, UE_CIP)) //no line number + { + DISASM_INSTR instr; + String temp_string; + String comment; + ADDRINFO newinfo; + char ascii[256 * 2] = ""; + char unicode[256 * 2] = ""; + + memset(&instr, 0, sizeof(DISASM_INSTR)); + disasmget(addr, &instr); + int len_left = MAX_COMMENT_SIZE; + for(int i = 0; i < instr.argcount; i++) + { + memset(&newinfo, 0, sizeof(ADDRINFO)); + newinfo.flags = flaglabel; + + STRING_TYPE strtype = str_none; + + if(instr.arg[i].constant == instr.arg[i].value) //avoid: call ; addr:label + { + if(instr.type == instr_branch || !disasmgetstringat(instr.arg[i].constant, &strtype, ascii, unicode, len_left) || strtype == str_none) + continue; + switch(strtype) + { + case str_none: + break; + case str_ascii: + temp_string = instr.arg[i].mnemonic; + temp_string.append(":\""); + temp_string.append(ascii); + temp_string.append("\""); + break; + case str_unicode: + temp_string = instr.arg[i].mnemonic; + temp_string.append(":L\""); + temp_string.append(unicode); + temp_string.append("\""); + break; + } + } + else if(instr.arg[i].memvalue && (disasmgetstringat(instr.arg[i].memvalue, &strtype, ascii, unicode, len_left) || _dbg_addrinfoget(instr.arg[i].memvalue, instr.arg[i].segment, &newinfo))) + { + switch(strtype) + { + case str_none: + if(*newinfo.label) + { + temp_string = "["; + temp_string.append(instr.arg[i].mnemonic); + temp_string.append("]:"); + temp_string.append(newinfo.label); + } + break; + case str_ascii: + temp_string = "["; + temp_string.append(instr.arg[i].mnemonic); + temp_string.append("]:"); + temp_string.append(ascii); + break; + case str_unicode: + temp_string = "["; + temp_string.append(instr.arg[i].mnemonic); + temp_string.append("]:"); + temp_string.append(unicode); + break; + } + } + else if(instr.arg[i].value && (disasmgetstringat(instr.arg[i].value, &strtype, ascii, unicode, len_left) || _dbg_addrinfoget(instr.arg[i].value, instr.arg[i].segment, &newinfo))) + { + if(instr.type != instr_normal) //stack/jumps (eg add esp,4 or jmp 401110) cannot directly point to strings + strtype = str_none; + switch(strtype) + { + case str_none: + if(*newinfo.label) + { + temp_string = instr.arg[i].mnemonic; + temp_string.append(":"); + temp_string.append(newinfo.label); + } + break; + case str_ascii: + temp_string = instr.arg[i].mnemonic; + temp_string.append(":\""); + temp_string.append(ascii); + temp_string.append("\""); + break; + case str_unicode: + temp_string = instr.arg[i].mnemonic; + temp_string.append(":L\""); + temp_string.append(unicode); + temp_string.append("\""); + break; + } + } + else + continue; + + if(!strstr(comment.c_str(), temp_string.c_str())) + { + if(comment.length()) + comment.append(", "); + comment.append(temp_string); + retval = true; + } + } + comment.resize(MAX_COMMENT_SIZE - 2); + String fullComment = "\1"; + fullComment += comment; + strcpy_s(addrinfo->comment, fullComment.c_str()); + } + } + } + return retval; +} + +extern "C" DLL_EXPORT bool _dbg_addrinfoset(duint addr, ADDRINFO* addrinfo) +{ + bool retval = false; + if(addrinfo->flags & flaglabel) //set label + { + if(LabelSet(addr, addrinfo->label, true)) + retval = true; + } + if(addrinfo->flags & flagcomment) //set comment + { + if(CommentSet(addr, addrinfo->comment, true)) + retval = true; + } + if(addrinfo->flags & flagbookmark) //set bookmark + { + if(addrinfo->isbookmark) + retval = BookmarkSet(addr, true); + else + retval = BookmarkDelete(addr); + } + return retval; +} + +extern "C" DLL_EXPORT int _dbg_bpgettypeat(duint addr) +{ + static duint cacheAddr; + static int cacheBpCount; + static int cacheResult; + int bpcount = BpGetList(nullptr); + if(cacheAddr != addr || cacheBpCount != bpcount) + { + BREAKPOINT bp; + cacheAddr = addr; + cacheResult = 0; + cacheBpCount = bpcount; + if(BpGet(addr, BPNORMAL, 0, &bp)) + if(bp.enabled) + cacheResult |= bp_normal; + if(BpGet(addr, BPHARDWARE, 0, &bp)) + if(bp.enabled) + cacheResult |= bp_hardware; + if(BpGet(addr, BPMEMORY, 0, &bp)) + if(bp.enabled) + cacheResult |= bp_memory; + } + return cacheResult; +} + +static void GetMxCsrFields(MXCSRFIELDS* MxCsrFields, DWORD MxCsr) +{ + MxCsrFields->DAZ = valmxcsrflagfromstring(MxCsr, "DAZ"); + MxCsrFields->DE = valmxcsrflagfromstring(MxCsr, "DE"); + MxCsrFields->FZ = valmxcsrflagfromstring(MxCsr, "FZ"); + MxCsrFields->IE = valmxcsrflagfromstring(MxCsr, "IE"); + MxCsrFields->IM = valmxcsrflagfromstring(MxCsr, "IM"); + MxCsrFields->DM = valmxcsrflagfromstring(MxCsr, "DM"); + MxCsrFields->OE = valmxcsrflagfromstring(MxCsr, "OE"); + MxCsrFields->OM = valmxcsrflagfromstring(MxCsr, "OM"); + MxCsrFields->PE = valmxcsrflagfromstring(MxCsr, "PE"); + MxCsrFields->PM = valmxcsrflagfromstring(MxCsr, "PM"); + MxCsrFields->UE = valmxcsrflagfromstring(MxCsr, "UE"); + MxCsrFields->UM = valmxcsrflagfromstring(MxCsr, "UM"); + MxCsrFields->ZE = valmxcsrflagfromstring(MxCsr, "ZE"); + MxCsrFields->ZM = valmxcsrflagfromstring(MxCsr, "ZM"); + + MxCsrFields->RC = valmxcsrfieldfromstring(MxCsr, "RC"); +} + +static void Getx87ControlWordFields(X87CONTROLWORDFIELDS* x87ControlWordFields, WORD ControlWord) +{ + x87ControlWordFields->DM = valx87controlwordflagfromstring(ControlWord, "DM"); + x87ControlWordFields->IC = valx87controlwordflagfromstring(ControlWord, "IC"); + x87ControlWordFields->IEM = valx87controlwordflagfromstring(ControlWord, "IEM"); + x87ControlWordFields->IM = valx87controlwordflagfromstring(ControlWord, "IM"); + x87ControlWordFields->OM = valx87controlwordflagfromstring(ControlWord, "OM"); + x87ControlWordFields->PM = valx87controlwordflagfromstring(ControlWord, "PM"); + x87ControlWordFields->UM = valx87controlwordflagfromstring(ControlWord, "UM"); + x87ControlWordFields->ZM = valx87controlwordflagfromstring(ControlWord, "ZM"); + + x87ControlWordFields->RC = valx87controlwordfieldfromstring(ControlWord, "RC"); + x87ControlWordFields->PC = valx87controlwordfieldfromstring(ControlWord, "PC"); +} + +static void Getx87StatusWordFields(X87STATUSWORDFIELDS* x87StatusWordFields, WORD StatusWord) +{ + x87StatusWordFields->B = valx87statuswordflagfromstring(StatusWord, "B"); + x87StatusWordFields->C0 = valx87statuswordflagfromstring(StatusWord, "C0"); + x87StatusWordFields->C1 = valx87statuswordflagfromstring(StatusWord, "C1"); + x87StatusWordFields->C2 = valx87statuswordflagfromstring(StatusWord, "C2"); + x87StatusWordFields->C3 = valx87statuswordflagfromstring(StatusWord, "C3"); + x87StatusWordFields->D = valx87statuswordflagfromstring(StatusWord, "D"); + x87StatusWordFields->I = valx87statuswordflagfromstring(StatusWord, "I"); + x87StatusWordFields->IR = valx87statuswordflagfromstring(StatusWord, "IR"); + x87StatusWordFields->O = valx87statuswordflagfromstring(StatusWord, "O"); + x87StatusWordFields->P = valx87statuswordflagfromstring(StatusWord, "P"); + x87StatusWordFields->SF = valx87statuswordflagfromstring(StatusWord, "SF"); + x87StatusWordFields->U = valx87statuswordflagfromstring(StatusWord, "U"); + x87StatusWordFields->Z = valx87statuswordflagfromstring(StatusWord, "Z"); + + x87StatusWordFields->TOP = valx87statuswordfieldfromstring(StatusWord, "TOP"); +} + +static void TranslateTitanFpu(const x87FPU_t* titanfpu, X87FPU* fpu) +{ + fpu->ControlWord = titanfpu->ControlWord; + fpu->StatusWord = titanfpu->StatusWord; + fpu->TagWord = titanfpu->TagWord; + fpu->ErrorOffset = titanfpu->ErrorOffset; + fpu->ErrorSelector = titanfpu->ErrorSelector; + fpu->DataOffset = titanfpu->DataOffset; + fpu->DataSelector = titanfpu->DataSelector; + fpu->Cr0NpxState = titanfpu->Cr0NpxState; +} + +static void TranslateTitanContextToRegContext(const TITAN_ENGINE_CONTEXT_t* titcontext, REGISTERCONTEXT* regcontext) +{ + regcontext->cax = titcontext->cax; + regcontext->ccx = titcontext->ccx; + regcontext->cdx = titcontext->cdx; + regcontext->cbx = titcontext->cbx; + regcontext->csp = titcontext->csp; + regcontext->cbp = titcontext->cbp; + regcontext->csi = titcontext->csi; + regcontext->cdi = titcontext->cdi; +#ifdef _WIN64 + regcontext->r8 = titcontext->r8; + regcontext->r9 = titcontext->r9; + regcontext->r10 = titcontext->r10; + regcontext->r11 = titcontext->r11; + regcontext->r12 = titcontext->r12; + regcontext->r13 = titcontext->r13; + regcontext->r14 = titcontext->r14; + regcontext->r15 = titcontext->r15; +#endif //_WIN64 + regcontext->cip = titcontext->cip; + regcontext->eflags = titcontext->eflags; + regcontext->gs = titcontext->gs; + regcontext->fs = titcontext->fs; + regcontext->es = titcontext->es; + regcontext->ds = titcontext->ds; + regcontext->cs = titcontext->cs; + regcontext->ss = titcontext->ss; + regcontext->dr0 = titcontext->dr0; + regcontext->dr1 = titcontext->dr1; + regcontext->dr2 = titcontext->dr2; + regcontext->dr3 = titcontext->dr3; + regcontext->dr6 = titcontext->dr6; + regcontext->dr7 = titcontext->dr7; + memcpy(regcontext->RegisterArea, titcontext->RegisterArea, sizeof(regcontext->RegisterArea)); + TranslateTitanFpu(&titcontext->x87fpu, ®context->x87fpu); + regcontext->MxCsr = titcontext->MxCsr; + memcpy(regcontext->XmmRegisters, titcontext->XmmRegisters, sizeof(regcontext->XmmRegisters)); + memcpy(regcontext->YmmRegisters, titcontext->YmmRegisters, sizeof(regcontext->YmmRegisters)); +} + +static void TranslateTitanFpuRegister(const x87FPURegister_t* titanReg, X87FPUREGISTER* reg) +{ + memcpy(reg->data, titanReg->data, sizeof(reg->data)); + reg->st_value = titanReg->st_value; + reg->tag = titanReg->tag; +} + +static void TranslateTitanFpuRegisters(const x87FPURegister_t titanFpu[8], X87FPUREGISTER fpu[8]) +{ + for(int i = 0; i < 8; i++) + TranslateTitanFpuRegister(&titanFpu[i], &fpu[i]); +} + +extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump) +{ + if(!DbgIsDebugging()) + { + memset(regdump, 0, sizeof(REGDUMP)); + return true; + } + + TITAN_ENGINE_CONTEXT_t titcontext; + if(!GetFullContextDataEx(hActiveThread, &titcontext)) + return false; + TranslateTitanContextToRegContext(&titcontext, ®dump->regcontext); + + duint cflags = regdump->regcontext.eflags; + regdump->flags.c = valflagfromstring(cflags, "cf"); + regdump->flags.p = valflagfromstring(cflags, "pf"); + regdump->flags.a = valflagfromstring(cflags, "af"); + regdump->flags.z = valflagfromstring(cflags, "zf"); + regdump->flags.s = valflagfromstring(cflags, "sf"); + regdump->flags.t = valflagfromstring(cflags, "tf"); + regdump->flags.i = valflagfromstring(cflags, "if"); + regdump->flags.d = valflagfromstring(cflags, "df"); + regdump->flags.o = valflagfromstring(cflags, "of"); + + x87FPURegister_t x87FPURegisters[8]; + Getx87FPURegisters(x87FPURegisters, &titcontext); + TranslateTitanFpuRegisters(x87FPURegisters, regdump->x87FPURegisters); + + GetMMXRegisters(regdump->mmx, &titcontext); + GetMxCsrFields(& (regdump->MxCsrFields), regdump->regcontext.MxCsr); + Getx87ControlWordFields(& (regdump->x87ControlWordFields), regdump->regcontext.x87fpu.ControlWord); + Getx87StatusWordFields(& (regdump->x87StatusWordFields), regdump->regcontext.x87fpu.StatusWord); + LASTERROR lastError; + lastError.code = ThreadGetLastError(ThreadGetId(hActiveThread)); + lastError.name = ErrorCodeToName(lastError.code); + regdump->lastError = lastError; + + return true; +} + +extern "C" DLL_EXPORT bool _dbg_valtostring(const char* string, duint value) +{ + return valtostring(string, value, true); +} + +extern "C" DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* bpmap) +{ + if(!bpmap) + return 0; + std::vector list; + int bpcount = BpGetList(&list); + if(bpcount == 0) + { + bpmap->count = 0; + return 0; + } + + int retcount = 0; + std::vector bridgeList; + BRIDGEBP curBp; + unsigned short slot = 0; + for(int i = 0; i < bpcount; i++) + { + memset(&curBp, 0, sizeof(BRIDGEBP)); + switch(type) + { + case bp_none: //all types + break; + case bp_normal: //normal + if(list[i].type != BPNORMAL) + continue; + break; + case bp_hardware: //hardware + if(list[i].type != BPHARDWARE) + continue; + break; + case bp_memory: //memory + if(list[i].type != BPMEMORY) + continue; + break; + default: + return 0; + } + switch(list[i].type) + { + case BPNORMAL: + curBp.type = bp_normal; + break; + case BPHARDWARE: + curBp.type = bp_hardware; + break; + case BPMEMORY: + curBp.type = bp_memory; + break; + } + switch(((DWORD)list[i].titantype) >> 8) + { + case UE_DR0: + slot = 0; + break; + case UE_DR1: + slot = 1; + break; + case UE_DR2: + slot = 2; + break; + case UE_DR3: + slot = 3; + break; + } + curBp.addr = list[i].addr; + curBp.enabled = list[i].enabled; + //TODO: fix this + if(MemIsValidReadPtr(curBp.addr)) + curBp.active = true; + strcpy_s(curBp.mod, list[i].mod); + strcpy_s(curBp.name, list[i].name); + curBp.singleshoot = list[i].singleshoot; + curBp.slot = slot; + if(curBp.active) + { + bridgeList.push_back(curBp); + retcount++; + } + } + if(!retcount) + { + bpmap->count = retcount; + return retcount; + } + bpmap->count = retcount; + bpmap->bp = (BRIDGEBP*)BridgeAlloc(sizeof(BRIDGEBP) * retcount); + for(int i = 0; i < retcount; i++) + memcpy(&bpmap->bp[i], &bridgeList.at(i), sizeof(BRIDGEBP)); + return retcount; +} + +extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr) +{ + DISASM_INSTR instr; + memset(&instr, 0, sizeof(instr)); + disasmget(addr, &instr); + if(instr.type != instr_branch) + return 0; + if(strstr(instr.instruction, "ret")) + { + duint atcsp = DbgValFromString("@csp"); + if(DbgMemIsValidReadPtr(atcsp)) + return atcsp; + else + return 0; + } + else if(instr.arg[0].type == arg_memory) + return instr.arg[0].memvalue; + else + return instr.arg[0].value; +} + +extern "C" DLL_EXPORT bool _dbg_functionoverlaps(duint start, duint end) +{ + return FunctionOverlaps(start, end); +} + +extern "C" DLL_EXPORT duint _dbg_sendmessage(DBGMSG type, void* param1, void* param2) +{ + if(dbgisstopped()) + { + switch(type) //ignore win events + { + //these functions are safe to call when we did not initialize yet + case DBG_DEINITIALIZE_LOCKS: + case DBG_INITIALIZE_LOCKS: + case DBG_GET_FUNCTIONS: + case DBG_SETTINGS_UPDATED: + case DBG_GET_THREAD_LIST: + case DBG_WIN_EVENT: + case DBG_WIN_EVENT_GLOBAL: + break; + //the rest is unsafe -> throw an exception when people try to call them + default: + __debugbreak(); //we cannot process messages when the debugger is stopped, this must be a bug + } + } + switch(type) + { + case DBG_SCRIPT_LOAD: + { + scriptload((const char*)param1); + } + break; + + case DBG_SCRIPT_UNLOAD: + { + scriptunload(); + } + break; + + case DBG_SCRIPT_RUN: + { + scriptrun((int)(duint)param1); + } + break; + + case DBG_SCRIPT_STEP: + { + scriptstep(); + } + break; + + case DBG_SCRIPT_BPTOGGLE: + { + return scriptbptoggle((int)(duint)param1); + } + break; + + case DBG_SCRIPT_BPGET: + { + return scriptbpget((int)(duint)param1); + } + break; + + case DBG_SCRIPT_CMDEXEC: + { + return scriptcmdexec((const char*)param1); + } + break; + + case DBG_SCRIPT_ABORT: + { + scriptabort(); + } + break; + + case DBG_SCRIPT_GETLINETYPE: + { + return (duint)scriptgetlinetype((int)(duint)param1); + } + break; + + case DBG_SCRIPT_SETIP: + { + scriptsetip((int)(duint)param1); + } + break; + + case DBG_SCRIPT_GETBRANCHINFO: + { + return (duint)scriptgetbranchinfo((int)(duint)param1, (SCRIPTBRANCH*)param2); + } + break; + + case DBG_SYMBOL_ENUM: + { + SYMBOLCBINFO* cbInfo = (SYMBOLCBINFO*)param1; + SymEnum(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user); + } + break; + + case DBG_ASSEMBLE_AT: + { + return assembleat((duint)param1, (const char*)param2, 0, 0, false); + } + break; + + case DBG_MODBASE_FROM_NAME: + { + return ModBaseFromName((const char*)param1); + } + break; + + case DBG_DISASM_AT: + { + disasmget((duint)param1, (DISASM_INSTR*)param2); + } + break; + + case DBG_STACK_COMMENT_GET: + { + return stackcommentget((duint)param1, (STACK_COMMENT*)param2); + } + break; + + case DBG_GET_THREAD_LIST: + { + ThreadGetList((THREADLIST*)param1); + } + break; + + case DBG_SETTINGS_UPDATED: + { + valuesetsignedcalc(!settingboolget("Engine", "CalculationType")); //0:signed, 1:unsigned + SetEngineVariable(UE_ENGINE_SET_DEBUG_PRIVILEGE, settingboolget("Engine", "EnableDebugPrivilege")); + bOnlyCipAutoComments = settingboolget("Disassembler", "OnlyCipAutoComments"); + bListAllPages = settingboolget("Engine", "ListAllPages"); + bUndecorateSymbolNames = settingboolget("Engine", "UndecorateSymbolNames"); + bEnableSourceDebugging = settingboolget("Engine", "EnableSourceDebugging"); + + duint setting; + if(BridgeSettingGetUint("Engine", "BreakpointType", &setting)) + { + switch(setting) + { + case 0: //break_int3short + SetBPXOptions(UE_BREAKPOINT_INT3); + break; + case 1: //break_int3long + SetBPXOptions(UE_BREAKPOINT_LONG_INT3); + break; + case 2: //break_ud2 + SetBPXOptions(UE_BREAKPOINT_UD2); + break; + } + } + + char exceptionRange[MAX_SETTING_SIZE] = ""; + dbgclearignoredexceptions(); + if(BridgeSettingGet("Exceptions", "IgnoreRange", exceptionRange)) + { + char* entry = strtok(exceptionRange, ","); + while(entry) + { + unsigned long start; + unsigned long end; + if(sscanf(entry, "%08X-%08X", &start, &end) == 2 && start <= end) + { + ExceptionRange range; + range.start = start; + range.end = end; + dbgaddignoredexception(range); + } + entry = strtok(0, ","); + } + } + + char cachePath[MAX_SETTING_SIZE]; + if(BridgeSettingGet("Symbols", "CachePath", cachePath)) + { + // Trim the buffer to fit inside MAX_PATH + strncpy_s(szSymbolCachePath, cachePath, _TRUNCATE); + } + } + break; + + case DBG_DISASM_FAST_AT: + { + if(!param1 || !param2) + return 0; + BASIC_INSTRUCTION_INFO* basicinfo = (BASIC_INSTRUCTION_INFO*)param2; + if(!disasmfast((duint)param1, basicinfo)) + basicinfo->size = 1; + return 0; + } + break; + + case DBG_MENU_ENTRY_CLICKED: + { + int hEntry = (int)(duint)param1; + pluginmenucall(hEntry); + } + break; + + case DBG_FUNCTION_GET: + { + FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; + return (duint)FunctionGet(info->addr, &info->start, &info->end); + } + break; + + case DBG_FUNCTION_OVERLAPS: + { + FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; + return (duint)FunctionOverlaps(info->start, info->end); + } + break; + + case DBG_FUNCTION_ADD: + { + FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; + return (duint)FunctionAdd(info->start, info->end, info->manual); + } + break; + + case DBG_FUNCTION_DEL: + { + FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; + return (duint)FunctionDelete(info->addr); + } + break; + + case DBG_LOOP_GET: + { + FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; + return (duint)LoopGet(info->depth, info->addr, &info->start, &info->end); + } + break; + + case DBG_LOOP_OVERLAPS: + { + FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; + return (duint)LoopOverlaps(info->depth, info->start, info->end, 0); + } + break; + + case DBG_LOOP_ADD: + { + FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; + return (duint)LoopAdd(info->start, info->end, info->manual); + } + break; + + case DBG_LOOP_DEL: + { + FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1; + return (duint)LoopDelete(info->depth, info->addr); + } + break; + + case DBG_IS_RUN_LOCKED: + { + return (duint)waitislocked(WAITID_RUN); + } + break; + + case DBG_IS_BP_DISABLED: + { + BREAKPOINT bp; + if(BpGet((duint)param1, BPNORMAL, 0, &bp)) + return !(duint)bp.enabled; + return (duint)false; + } + break; + + case DBG_SET_AUTO_COMMENT_AT: + { + return (duint)CommentSet((duint)param1, (const char*)param2, false); + } + break; + + case DBG_DELETE_AUTO_COMMENT_RANGE: + { + CommentDelRange((duint)param1, (duint)param2); + } + break; + + case DBG_SET_AUTO_LABEL_AT: + { + return (duint)LabelSet((duint)param1, (const char*)param2, false); + } + break; + + case DBG_DELETE_AUTO_LABEL_RANGE: + { + LabelDelRange((duint)param1, (duint)param2); + } + break; + + case DBG_SET_AUTO_BOOKMARK_AT: + { + return (duint)BookmarkSet((duint)param1, false); + } + break; + + case DBG_DELETE_AUTO_BOOKMARK_RANGE: + { + BookmarkDelRange((duint)param1, (duint)param2); + } + break; + + case DBG_SET_AUTO_FUNCTION_AT: + { + return (duint)FunctionAdd((duint)param1, (duint)param2, false); + } + break; + + case DBG_DELETE_AUTO_FUNCTION_RANGE: + { + FunctionDelRange((duint)param1, (duint)param2); + } + break; + + case DBG_GET_STRING_AT: + { + STRING_TYPE strtype; + char string[MAX_STRING_SIZE]; + if(disasmgetstringat((duint)param1, &strtype, string, string, MAX_STRING_SIZE - 3)) + { + if(strtype == str_ascii) + sprintf((char*)param2, "\"%s\"", string); + else //unicode + sprintf((char*)param2, "L\"%s\"", string); + return true; + } + return false; + } + break; + + case DBG_GET_FUNCTIONS: + { + return (duint)dbgfunctionsget(); + } + break; + + case DBG_WIN_EVENT: + { + return (duint)pluginwinevent((MSG*)param1, (long*)param2); + } + break; + + case DBG_WIN_EVENT_GLOBAL: + { + return (duint)pluginwineventglobal((MSG*)param1); + } + break; + + case DBG_INITIALIZE_LOCKS: + { + SectionLockerGlobal::Initialize(); + } + break; + + case DBG_DEINITIALIZE_LOCKS: + { + SectionLockerGlobal::Deinitialize(); + } + break; + + case DBG_GET_TIME_WASTED_COUNTER: + return dbggettimewastedcounter(); + } + return 0; +} diff --git a/src/dbg/_exports.h b/src/dbg/_exports.h index c96938d6..9ef7153c 100644 --- a/src/dbg/_exports.h +++ b/src/dbg/_exports.h @@ -1,33 +1,33 @@ -#ifndef _EXPORTS_H -#define _EXPORTS_H - -#include "_global.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -DLL_EXPORT duint _dbg_memfindbaseaddr(duint addr, duint* size); -DLL_EXPORT bool _dbg_memread(duint addr, unsigned char* dest, duint size, duint* read); -DLL_EXPORT bool _dbg_memwrite(duint addr, const unsigned char* src, duint size, duint* written); -DLL_EXPORT bool _dbg_memmap(MEMMAP* memmap); -DLL_EXPORT bool _dbg_memisvalidreadptr(duint addr); -DLL_EXPORT bool _dbg_valfromstring(const char* string, duint* value); -DLL_EXPORT bool _dbg_isdebugging(); -DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr); -DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDRINFO* addrinfo); -DLL_EXPORT bool _dbg_addrinfoset(duint addr, ADDRINFO* addrinfo); -DLL_EXPORT int _dbg_bpgettypeat(duint addr); -DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump); -DLL_EXPORT bool _dbg_valtostring(const char* string, duint value); -DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* list); -DLL_EXPORT duint _dbg_getbranchdestination(duint addr); -DLL_EXPORT bool _dbg_functionoverlaps(duint start, duint end); -DLL_EXPORT duint _dbg_sendmessage(DBGMSG type, void* param1, void* param2); - -#ifdef __cplusplus -} -#endif - -#endif // _EXPORTS_H +#ifndef _EXPORTS_H +#define _EXPORTS_H + +#include "_global.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +DLL_EXPORT duint _dbg_memfindbaseaddr(duint addr, duint* size); +DLL_EXPORT bool _dbg_memread(duint addr, unsigned char* dest, duint size, duint* read); +DLL_EXPORT bool _dbg_memwrite(duint addr, const unsigned char* src, duint size, duint* written); +DLL_EXPORT bool _dbg_memmap(MEMMAP* memmap); +DLL_EXPORT bool _dbg_memisvalidreadptr(duint addr); +DLL_EXPORT bool _dbg_valfromstring(const char* string, duint* value); +DLL_EXPORT bool _dbg_isdebugging(); +DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr); +DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDRINFO* addrinfo); +DLL_EXPORT bool _dbg_addrinfoset(duint addr, ADDRINFO* addrinfo); +DLL_EXPORT int _dbg_bpgettypeat(duint addr); +DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump); +DLL_EXPORT bool _dbg_valtostring(const char* string, duint value); +DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* list); +DLL_EXPORT duint _dbg_getbranchdestination(duint addr); +DLL_EXPORT bool _dbg_functionoverlaps(duint start, duint end); +DLL_EXPORT duint _dbg_sendmessage(DBGMSG type, void* param1, void* param2); + +#ifdef __cplusplus +} +#endif + +#endif // _EXPORTS_H diff --git a/src/dbg/_global.cpp b/src/dbg/_global.cpp index a28dcc69..afeea40f 100644 --- a/src/dbg/_global.cpp +++ b/src/dbg/_global.cpp @@ -1,348 +1,348 @@ -/** -\file _global.cpp -\brief Implements the global class. -*/ - -#include "_global.h" -#include -#include - -/** -\brief x64dbg library instance. -*/ -HINSTANCE hInst; - -/** -\brief Number of allocated buffers by emalloc(). This should be 0 when x64dbg ends. -*/ -static int emalloc_count = 0; - -/** -\brief Path for debugging, used to create an allocation trace file on emalloc() or efree(). Not used. -*/ -static char alloctrace[MAX_PATH] = ""; - -/** -\brief Allocates a new buffer. -\param size The size of the buffer to allocate (in bytes). -\param reason The reason for allocation (can be used for memory allocation tracking). -\return Always returns a valid pointer to the buffer you requested. Will quit the application on errors. -*/ -void* emalloc(size_t size, const char* reason) -{ - ASSERT_NONZERO(size); - - unsigned char* a = (unsigned char*)GlobalAlloc(GMEM_FIXED, size); - if(!a) - { - MessageBoxA(0, "Could not allocate memory", "Error", MB_ICONERROR); - ExitProcess(1); - } - memset(a, 0, size); - emalloc_count++; - /* - FILE* file = fopen(alloctrace, "a+"); - fprintf(file, "DBG%.5d: alloc:" fhex ":%s:" fhex "\n", emalloc_count, a, reason, size); - fclose(file); - */ - return a; -} - -/** -\brief Reallocates a buffer allocated with emalloc(). -\param [in] Pointer to memory previously allocated with emalloc(). When NULL a new buffer will be allocated by emalloc(). -\param size The new memory size. -\param reason The reason for allocation (can be used for memory allocation tracking). -\return Always returns a valid pointer to the buffer you requested. Will quit the application on errors. -*/ -void* erealloc(void* ptr, size_t size, const char* reason) -{ - ASSERT_NONZERO(size); - - // Free the memory if the pointer was set (as per documentation). - if (ptr) - efree(ptr); - - return emalloc(size, reason); -} - -/** -\brief Free memory previously allocated with emalloc(). -\param [in] Pointer to the memory to free. -\param reason The reason for freeing, should be the same as the reason for allocating. -*/ -void efree(void* ptr, const char* reason) -{ - emalloc_count--; - /* - FILE* file = fopen(alloctrace, "a+"); - fprintf(file, "DBG%.5d: free:" fhex ":%s\n", emalloc_count, ptr, reason); - fclose(file); - */ - GlobalFree(ptr); -} - -void* json_malloc(size_t size) -{ - return emalloc(size, "json:ptr"); -} - -void json_free(void* ptr) -{ - efree(ptr, "json:ptr"); -} - -/** -\brief Gets the number of memory leaks. This number is only valid in _dbg_dbgexitsignal(). -\return The number of memory leaks. -*/ -int memleaks() -{ - return emalloc_count; -} - -/** -\brief Sets the path for the allocation trace file. -\param file UTF-8 filepath. -*/ -void setalloctrace(const char* file) -{ - strcpy_s(alloctrace, file); -} - -/** -\brief A function to determine if a string is contained in a specifically formatted 'array string'. -\param cmd_list Array of strings separated by '\1'. -\param cmd The string to look for. -\return true if \p cmd is contained in \p cmd_list. -*/ -bool arraycontains(const char* cmd_list, const char* cmd) -{ - //TODO: fix this function a little - if(!cmd_list || !cmd) - return false; - char temp[deflen] = ""; - strcpy_s(temp, cmd_list); - int len = (int)strlen(cmd_list); - if(len >= deflen) - return false; - for(int i = 0; i < len; i++) - if(temp[i] == 1) - temp[i] = 0; - if(!_stricmp(temp, cmd)) - return true; - for(int i = (int)strlen(temp); i < len; i++) - { - if(!temp[i]) - { - if(!_stricmp(temp + i + 1, cmd)) - return true; - i += (int)strlen(temp + i + 1); - } - } - return false; -} - -/** -\brief Compares two strings without case-sensitivity. -\param a The first string. -\param b The second string. -\return true if the strings are equal (case-insensitive). -*/ -bool scmp(const char* a, const char* b) -{ - if(_stricmp(a, b)) - return false; - return true; -} - -/** -\brief Formats a string to hexadecimal format (removes all non-hex characters). -\param [in,out] String to format. -*/ -void formathex(char* string) -{ - int len = (int)strlen(string); - _strupr(string); - Memory new_string(len + 1, "formathex:new_string"); - for(int i = 0, j = 0; i < len; i++) - if(isxdigit(string[i])) - j += sprintf(new_string() + j, "%c", string[i]); - strcpy_s(string, len + 1, new_string()); -} - -/** -\brief Formats a string to decimal format (removed all non-numeric characters). -\param [in,out] String to format. -*/ -void formatdec(char* string) -{ - int len = (int)strlen(string); - _strupr(string); - Memory new_string(len + 1, "formatdec:new_string"); - for(int i = 0, j = 0; i < len; i++) - if(isdigit(string[i])) - j += sprintf(new_string() + j, "%c", string[i]); - strcpy_s(string, len + 1, new_string()); -} - -/** -\brief Queries if a given file exists. -\param file Path to the file to check (UTF-8). -\return true if the file exists on the hard drive. -*/ -bool FileExists(const char* file) -{ - DWORD attrib = GetFileAttributesW(StringUtils::Utf8ToUtf16(file).c_str()); - return (attrib != INVALID_FILE_ATTRIBUTES && !(attrib & FILE_ATTRIBUTE_DIRECTORY)); -} - -/** -\brief Queries if a given directory exists. -\param dir Path to the directory to check (UTF-8). -\return true if the directory exists. -*/ -bool DirExists(const char* dir) -{ - DWORD attrib = GetFileAttributesW(StringUtils::Utf8ToUtf16(dir).c_str()); - return (attrib == FILE_ATTRIBUTE_DIRECTORY); -} - -/** -\brief Gets file path from a file handle. -\param hFile File handle to get the path from. -\param [in,out] szFileName Buffer of size MAX_PATH. -\return true if it succeeds, false if it fails. -*/ -bool GetFileNameFromHandle(HANDLE hFile, char* szFileName) -{ - wchar_t wszFileName[MAX_PATH] = L""; - if(!PathFromFileHandleW(hFile, wszFileName, sizeof(wszFileName))) - return false; - strcpy_s(szFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str()); - return true; -} - -/** -\brief Get a boolean setting from the configuration file. -\param section The section of the setting (UTF-8). -\param name The name of the setting (UTF-8). -\return true if the setting was set and equals to true, otherwise returns false. -*/ -bool settingboolget(const char* section, const char* name) -{ - duint setting; - if(!BridgeSettingGetUint(section, name, &setting)) - return false; - if(setting) - return true; - return false; -} - -/** -\brief Gets file architecture. -\param szFileName UTF-8 encoded file path. -\return The file architecture (::arch). -*/ -arch GetFileArchitecture(const char* szFileName) -{ - arch retval = notfound; - Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(szFileName).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); - if(hFile != INVALID_HANDLE_VALUE) - { - unsigned char data[0x1000]; - DWORD read = 0; - DWORD fileSize = GetFileSize(hFile, 0); - DWORD readSize = sizeof(data); - if(readSize > fileSize) - readSize = fileSize; - if(ReadFile(hFile, data, readSize, &read, 0)) - { - retval = invalid; - IMAGE_DOS_HEADER* pdh = (IMAGE_DOS_HEADER*)data; - if(pdh->e_magic == IMAGE_DOS_SIGNATURE && (size_t)pdh->e_lfanew < readSize) - { - IMAGE_NT_HEADERS* pnth = (IMAGE_NT_HEADERS*)(data + pdh->e_lfanew); - if(pnth->Signature == IMAGE_NT_SIGNATURE) - { - if(pnth->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) //x32 - retval = x32; - else if(pnth->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) //x64 - retval = x64; - } - } - } - } - return retval; -} - -/** -\brief Query if x64dbg is running in Wow64 mode. -\return true if running in Wow64, false otherwise. -*/ -bool IsWow64() -{ - BOOL bIsWow64Process = FALSE; - //x64dbg supports WinXP SP3 and later only, so ignore the GetProcAddress crap :D - IsWow64Process(GetCurrentProcess(), &bIsWow64Process); - return !!bIsWow64Process; -} - -//Taken from: http://www.cplusplus.com/forum/windows/64088/ -bool ResolveShortcut(HWND hwnd, const wchar_t* szShortcutPath, char* szResolvedPath, size_t nSize) -{ - if(szResolvedPath == NULL) - return SUCCEEDED(E_INVALIDARG); - - //Initialize COM stuff - CoInitialize(NULL); - - //Get a pointer to the IShellLink interface. - IShellLink* psl = NULL; - HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); - if(SUCCEEDED(hres)) - { - //Get a pointer to the IPersistFile interface. - IPersistFile* ppf = NULL; - hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); - if(SUCCEEDED(hres)) - { - //Load the shortcut. - hres = ppf->Load(szShortcutPath, STGM_READ); - - if(SUCCEEDED(hres)) - { - //Resolve the link. - hres = psl->Resolve(hwnd, 0); - - if(SUCCEEDED(hres)) - { - //Get the path to the link target. - char szGotPath[MAX_PATH] = {0}; - hres = psl->GetPath(szGotPath, _countof(szGotPath), NULL, SLGP_SHORTPATH); - - if(SUCCEEDED(hres)) - { - strcpy_s(szResolvedPath, nSize, szGotPath); - } - } - } - - //Release the pointer to the IPersistFile interface. - ppf->Release(); - } - - //Release the pointer to the IShellLink interface. - psl->Release(); - } - - //Uninitialize COM stuff - CoUninitialize(); - return SUCCEEDED(hres); -} - -void WaitForThreadTermination(HANDLE hThread) -{ - WaitForSingleObject(hThread, INFINITE); - CloseHandle(hThread); +/** +\file _global.cpp +\brief Implements the global class. +*/ + +#include "_global.h" +#include +#include + +/** +\brief x64dbg library instance. +*/ +HINSTANCE hInst; + +/** +\brief Number of allocated buffers by emalloc(). This should be 0 when x64dbg ends. +*/ +static int emalloc_count = 0; + +/** +\brief Path for debugging, used to create an allocation trace file on emalloc() or efree(). Not used. +*/ +static char alloctrace[MAX_PATH] = ""; + +/** +\brief Allocates a new buffer. +\param size The size of the buffer to allocate (in bytes). +\param reason The reason for allocation (can be used for memory allocation tracking). +\return Always returns a valid pointer to the buffer you requested. Will quit the application on errors. +*/ +void* emalloc(size_t size, const char* reason) +{ + ASSERT_NONZERO(size); + + unsigned char* a = (unsigned char*)GlobalAlloc(GMEM_FIXED, size); + if(!a) + { + MessageBoxA(0, "Could not allocate memory", "Error", MB_ICONERROR); + ExitProcess(1); + } + memset(a, 0, size); + emalloc_count++; + /* + FILE* file = fopen(alloctrace, "a+"); + fprintf(file, "DBG%.5d: alloc:" fhex ":%s:" fhex "\n", emalloc_count, a, reason, size); + fclose(file); + */ + return a; +} + +/** +\brief Reallocates a buffer allocated with emalloc(). +\param [in] Pointer to memory previously allocated with emalloc(). When NULL a new buffer will be allocated by emalloc(). +\param size The new memory size. +\param reason The reason for allocation (can be used for memory allocation tracking). +\return Always returns a valid pointer to the buffer you requested. Will quit the application on errors. +*/ +void* erealloc(void* ptr, size_t size, const char* reason) +{ + ASSERT_NONZERO(size); + + // Free the memory if the pointer was set (as per documentation). + if (ptr) + efree(ptr); + + return emalloc(size, reason); +} + +/** +\brief Free memory previously allocated with emalloc(). +\param [in] Pointer to the memory to free. +\param reason The reason for freeing, should be the same as the reason for allocating. +*/ +void efree(void* ptr, const char* reason) +{ + emalloc_count--; + /* + FILE* file = fopen(alloctrace, "a+"); + fprintf(file, "DBG%.5d: free:" fhex ":%s\n", emalloc_count, ptr, reason); + fclose(file); + */ + GlobalFree(ptr); +} + +void* json_malloc(size_t size) +{ + return emalloc(size, "json:ptr"); +} + +void json_free(void* ptr) +{ + efree(ptr, "json:ptr"); +} + +/** +\brief Gets the number of memory leaks. This number is only valid in _dbg_dbgexitsignal(). +\return The number of memory leaks. +*/ +int memleaks() +{ + return emalloc_count; +} + +/** +\brief Sets the path for the allocation trace file. +\param file UTF-8 filepath. +*/ +void setalloctrace(const char* file) +{ + strcpy_s(alloctrace, file); +} + +/** +\brief A function to determine if a string is contained in a specifically formatted 'array string'. +\param cmd_list Array of strings separated by '\1'. +\param cmd The string to look for. +\return true if \p cmd is contained in \p cmd_list. +*/ +bool arraycontains(const char* cmd_list, const char* cmd) +{ + //TODO: fix this function a little + if(!cmd_list || !cmd) + return false; + char temp[deflen] = ""; + strcpy_s(temp, cmd_list); + int len = (int)strlen(cmd_list); + if(len >= deflen) + return false; + for(int i = 0; i < len; i++) + if(temp[i] == 1) + temp[i] = 0; + if(!_stricmp(temp, cmd)) + return true; + for(int i = (int)strlen(temp); i < len; i++) + { + if(!temp[i]) + { + if(!_stricmp(temp + i + 1, cmd)) + return true; + i += (int)strlen(temp + i + 1); + } + } + return false; +} + +/** +\brief Compares two strings without case-sensitivity. +\param a The first string. +\param b The second string. +\return true if the strings are equal (case-insensitive). +*/ +bool scmp(const char* a, const char* b) +{ + if(_stricmp(a, b)) + return false; + return true; +} + +/** +\brief Formats a string to hexadecimal format (removes all non-hex characters). +\param [in,out] String to format. +*/ +void formathex(char* string) +{ + int len = (int)strlen(string); + _strupr(string); + Memory new_string(len + 1, "formathex:new_string"); + for(int i = 0, j = 0; i < len; i++) + if(isxdigit(string[i])) + j += sprintf(new_string() + j, "%c", string[i]); + strcpy_s(string, len + 1, new_string()); +} + +/** +\brief Formats a string to decimal format (removed all non-numeric characters). +\param [in,out] String to format. +*/ +void formatdec(char* string) +{ + int len = (int)strlen(string); + _strupr(string); + Memory new_string(len + 1, "formatdec:new_string"); + for(int i = 0, j = 0; i < len; i++) + if(isdigit(string[i])) + j += sprintf(new_string() + j, "%c", string[i]); + strcpy_s(string, len + 1, new_string()); +} + +/** +\brief Queries if a given file exists. +\param file Path to the file to check (UTF-8). +\return true if the file exists on the hard drive. +*/ +bool FileExists(const char* file) +{ + DWORD attrib = GetFileAttributesW(StringUtils::Utf8ToUtf16(file).c_str()); + return (attrib != INVALID_FILE_ATTRIBUTES && !(attrib & FILE_ATTRIBUTE_DIRECTORY)); +} + +/** +\brief Queries if a given directory exists. +\param dir Path to the directory to check (UTF-8). +\return true if the directory exists. +*/ +bool DirExists(const char* dir) +{ + DWORD attrib = GetFileAttributesW(StringUtils::Utf8ToUtf16(dir).c_str()); + return (attrib == FILE_ATTRIBUTE_DIRECTORY); +} + +/** +\brief Gets file path from a file handle. +\param hFile File handle to get the path from. +\param [in,out] szFileName Buffer of size MAX_PATH. +\return true if it succeeds, false if it fails. +*/ +bool GetFileNameFromHandle(HANDLE hFile, char* szFileName) +{ + wchar_t wszFileName[MAX_PATH] = L""; + if(!PathFromFileHandleW(hFile, wszFileName, sizeof(wszFileName))) + return false; + strcpy_s(szFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str()); + return true; +} + +/** +\brief Get a boolean setting from the configuration file. +\param section The section of the setting (UTF-8). +\param name The name of the setting (UTF-8). +\return true if the setting was set and equals to true, otherwise returns false. +*/ +bool settingboolget(const char* section, const char* name) +{ + duint setting; + if(!BridgeSettingGetUint(section, name, &setting)) + return false; + if(setting) + return true; + return false; +} + +/** +\brief Gets file architecture. +\param szFileName UTF-8 encoded file path. +\return The file architecture (::arch). +*/ +arch GetFileArchitecture(const char* szFileName) +{ + arch retval = notfound; + Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(szFileName).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + if(hFile != INVALID_HANDLE_VALUE) + { + unsigned char data[0x1000]; + DWORD read = 0; + DWORD fileSize = GetFileSize(hFile, 0); + DWORD readSize = sizeof(data); + if(readSize > fileSize) + readSize = fileSize; + if(ReadFile(hFile, data, readSize, &read, 0)) + { + retval = invalid; + IMAGE_DOS_HEADER* pdh = (IMAGE_DOS_HEADER*)data; + if(pdh->e_magic == IMAGE_DOS_SIGNATURE && (size_t)pdh->e_lfanew < readSize) + { + IMAGE_NT_HEADERS* pnth = (IMAGE_NT_HEADERS*)(data + pdh->e_lfanew); + if(pnth->Signature == IMAGE_NT_SIGNATURE) + { + if(pnth->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) //x32 + retval = x32; + else if(pnth->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) //x64 + retval = x64; + } + } + } + } + return retval; +} + +/** +\brief Query if x64dbg is running in Wow64 mode. +\return true if running in Wow64, false otherwise. +*/ +bool IsWow64() +{ + BOOL bIsWow64Process = FALSE; + //x64dbg supports WinXP SP3 and later only, so ignore the GetProcAddress crap :D + IsWow64Process(GetCurrentProcess(), &bIsWow64Process); + return !!bIsWow64Process; +} + +//Taken from: http://www.cplusplus.com/forum/windows/64088/ +bool ResolveShortcut(HWND hwnd, const wchar_t* szShortcutPath, char* szResolvedPath, size_t nSize) +{ + if(szResolvedPath == NULL) + return SUCCEEDED(E_INVALIDARG); + + //Initialize COM stuff + CoInitialize(NULL); + + //Get a pointer to the IShellLink interface. + IShellLink* psl = NULL; + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); + if(SUCCEEDED(hres)) + { + //Get a pointer to the IPersistFile interface. + IPersistFile* ppf = NULL; + hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); + if(SUCCEEDED(hres)) + { + //Load the shortcut. + hres = ppf->Load(szShortcutPath, STGM_READ); + + if(SUCCEEDED(hres)) + { + //Resolve the link. + hres = psl->Resolve(hwnd, 0); + + if(SUCCEEDED(hres)) + { + //Get the path to the link target. + char szGotPath[MAX_PATH] = {0}; + hres = psl->GetPath(szGotPath, _countof(szGotPath), NULL, SLGP_SHORTPATH); + + if(SUCCEEDED(hres)) + { + strcpy_s(szResolvedPath, nSize, szGotPath); + } + } + } + + //Release the pointer to the IPersistFile interface. + ppf->Release(); + } + + //Release the pointer to the IShellLink interface. + psl->Release(); + } + + //Uninitialize COM stuff + CoUninitialize(); + return SUCCEEDED(hres); +} + +void WaitForThreadTermination(HANDLE hThread) +{ + WaitForSingleObject(hThread, INFINITE); + CloseHandle(hThread); } \ No newline at end of file diff --git a/src/dbg/_global.h b/src/dbg/_global.h index 1238832b..37416281 100644 --- a/src/dbg/_global.h +++ b/src/dbg/_global.h @@ -1,84 +1,84 @@ -#ifndef _GLOBAL_H -#define _GLOBAL_H - -#define _WIN32_WINNT 0x0501 -#define WINVER 0x0501 -#define _WIN32_IE 0x0500 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "..\dbg_types.h" -#include "..\dbg_assert.h" -#include "..\bridge\bridgemain.h" -#include "jansson\jansson.h" -#include "jansson\jansson_x64dbg.h" -#include "yara\yara.h" -#include "DeviceNameResolver\DeviceNameResolver.h" -#include "handle.h" -#include "stringutils.h" -#include "dbghelp_safe.h" - -#ifndef DLL_EXPORT -#define DLL_EXPORT __declspec(dllexport) -#endif //DLL_IMPORT -#ifndef DLL_IMPORT -#define DLL_IMPORT __declspec(dllimport) -#endif //DLL_IMPORT - -//defines -#define deflen 1024 - -#ifdef _WIN64 //defined by default -#define fhex "%.16llX" -#define fext "ll" -#else -#define fhex "%.8X" -#define fext "" -#endif // _WIN64 - -enum arch -{ - notfound, - invalid, - x32, - x64 -}; - -//superglobal variables -extern HINSTANCE hInst; - -//functions -void* emalloc(size_t size, const char* reason = "emalloc:???"); -void* erealloc(void* ptr, size_t size, const char* reason = "erealloc:???"); -void efree(void* ptr, const char* reason = "efree:???"); -void* json_malloc(size_t size); -void json_free(void* ptr); -int memleaks(); -void setalloctrace(const char* file); -bool arraycontains(const char* cmd_list, const char* cmd); -bool scmp(const char* a, const char* b); -void formathex(char* string); -void formatdec(char* string); -bool FileExists(const char* file); -bool DirExists(const char* dir); -bool GetFileNameFromHandle(HANDLE hFile, char* szFileName); -bool settingboolget(const char* section, const char* name); -arch GetFileArchitecture(const char* szFileName); -bool IsWow64(); -bool ResolveShortcut(HWND hwnd, const wchar_t* szShortcutPath, char* szResolvedPath, size_t nSize); -void WaitForThreadTermination(HANDLE hThread); - -#include "dynamicmem.h" - -#endif // _GLOBAL_H +#ifndef _GLOBAL_H +#define _GLOBAL_H + +#define _WIN32_WINNT 0x0501 +#define WINVER 0x0501 +#define _WIN32_IE 0x0500 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "..\dbg_types.h" +#include "..\dbg_assert.h" +#include "..\bridge\bridgemain.h" +#include "jansson\jansson.h" +#include "jansson\jansson_x64dbg.h" +#include "yara\yara.h" +#include "DeviceNameResolver\DeviceNameResolver.h" +#include "handle.h" +#include "stringutils.h" +#include "dbghelp_safe.h" + +#ifndef DLL_EXPORT +#define DLL_EXPORT __declspec(dllexport) +#endif //DLL_IMPORT +#ifndef DLL_IMPORT +#define DLL_IMPORT __declspec(dllimport) +#endif //DLL_IMPORT + +//defines +#define deflen 1024 + +#ifdef _WIN64 //defined by default +#define fhex "%.16llX" +#define fext "ll" +#else +#define fhex "%.8X" +#define fext "" +#endif // _WIN64 + +enum arch +{ + notfound, + invalid, + x32, + x64 +}; + +//superglobal variables +extern HINSTANCE hInst; + +//functions +void* emalloc(size_t size, const char* reason = "emalloc:???"); +void* erealloc(void* ptr, size_t size, const char* reason = "erealloc:???"); +void efree(void* ptr, const char* reason = "efree:???"); +void* json_malloc(size_t size); +void json_free(void* ptr); +int memleaks(); +void setalloctrace(const char* file); +bool arraycontains(const char* cmd_list, const char* cmd); +bool scmp(const char* a, const char* b); +void formathex(char* string); +void formatdec(char* string); +bool FileExists(const char* file); +bool DirExists(const char* dir); +bool GetFileNameFromHandle(HANDLE hFile, char* szFileName); +bool settingboolget(const char* section, const char* name); +arch GetFileArchitecture(const char* szFileName); +bool IsWow64(); +bool ResolveShortcut(HWND hwnd, const wchar_t* szShortcutPath, char* szResolvedPath, size_t nSize); +void WaitForThreadTermination(HANDLE hThread); + +#include "dynamicmem.h" + +#endif // _GLOBAL_H diff --git a/src/dbg/_plugin_types.h b/src/dbg/_plugin_types.h index 0ba2ab4e..6dcf7989 100644 --- a/src/dbg/_plugin_types.h +++ b/src/dbg/_plugin_types.h @@ -1,25 +1,25 @@ -#ifndef _PLUGIN_DATA_H -#define _PLUGIN_DATA_H - -#ifdef BUILD_DBG - -#include "_global.h" - -#else - -#ifdef __GNUC__ -#include "dbghelp\dbghelp.h" -#else -#include -#endif // __GNUC__ - -#ifndef deflen -#define deflen 1024 -#endif // deflen - -#include "bridgemain.h" -#include "_dbgfunctions.h" - -#endif // BUILD_DBG - -#endif // _PLUGIN_DATA_H +#ifndef _PLUGIN_DATA_H +#define _PLUGIN_DATA_H + +#ifdef BUILD_DBG + +#include "_global.h" + +#else + +#ifdef __GNUC__ +#include "dbghelp\dbghelp.h" +#else +#include +#endif // __GNUC__ + +#ifndef deflen +#define deflen 1024 +#endif // deflen + +#include "bridgemain.h" +#include "_dbgfunctions.h" + +#endif // BUILD_DBG + +#endif // _PLUGIN_DATA_H diff --git a/src/dbg/_plugins.cpp b/src/dbg/_plugins.cpp index 9f041201..ebd70cff 100644 --- a/src/dbg/_plugins.cpp +++ b/src/dbg/_plugins.cpp @@ -1,103 +1,103 @@ -/** - @file _plugins.cpp - - @brief Implements the plugins class. - */ - -#include "_plugins.h" -#include "plugin_loader.h" -#include "console.h" -#include "debugger.h" -#include "threading.h" - -///debugger plugin exports (wrappers) -PLUG_IMPEXP void _plugin_registercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin) -{ - pluginregistercallback(pluginHandle, cbType, cbPlugin); -} - -PLUG_IMPEXP bool _plugin_unregistercallback(int pluginHandle, CBTYPE cbType) -{ - return pluginunregistercallback(pluginHandle, cbType); -} - -PLUG_IMPEXP bool _plugin_registercommand(int pluginHandle, const char* command, CBPLUGINCOMMAND cbCommand, bool debugonly) -{ - return plugincmdregister(pluginHandle, command, cbCommand, debugonly); -} - -PLUG_IMPEXP bool _plugin_unregistercommand(int pluginHandle, const char* command) -{ - return plugincmdunregister(pluginHandle, command); -} - -PLUG_IMPEXP void _plugin_logprintf(const char* format, ...) -{ - va_list args; - - va_start(args, format); - dprintf_args(format, args); - va_end(args); -} - -PLUG_IMPEXP void _plugin_logputs(const char* text) -{ - dputs(text); -} - -PLUG_IMPEXP void _plugin_debugpause() -{ - GuiSetDebugState(paused); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - dbgsetskipexceptions(false); - wait(WAITID_RUN); -} - -PLUG_IMPEXP void _plugin_debugskipexceptions(bool skip) -{ - dbgsetskipexceptions(skip); -} - -PLUG_IMPEXP int _plugin_menuadd(int hMenu, const char* title) -{ - return pluginmenuadd(hMenu, title); -} - -PLUG_IMPEXP bool _plugin_menuaddentry(int hMenu, int hEntry, const char* title) -{ - return pluginmenuaddentry(hMenu, hEntry, title); -} - -PLUG_IMPEXP bool _plugin_menuaddseparator(int hMenu) -{ - return pluginmenuaddseparator(hMenu); -} - -PLUG_IMPEXP bool _plugin_menuclear(int hMenu) -{ - return pluginmenuclear(hMenu); -} - -PLUG_IMPEXP void _plugin_menuseticon(int hMenu, const ICONDATA* icon) -{ - pluginmenuseticon(hMenu, icon); -} - -PLUG_IMPEXP void _plugin_menuentryseticon(int pluginHandle, int hEntry, const ICONDATA* icon) -{ - pluginmenuentryseticon(pluginHandle, hEntry, icon); -} - -PLUG_IMPEXP void _plugin_startscript(CBPLUGINSCRIPT cbScript) -{ - dbgstartscriptthread(cbScript); -} - -PLUG_IMPEXP bool _plugin_waituntilpaused() -{ - while(DbgIsDebugging() && dbgisrunning()) //wait until the debugger paused - Sleep(1); - return DbgIsDebugging(); +/** + @file _plugins.cpp + + @brief Implements the plugins class. + */ + +#include "_plugins.h" +#include "plugin_loader.h" +#include "console.h" +#include "debugger.h" +#include "threading.h" + +///debugger plugin exports (wrappers) +PLUG_IMPEXP void _plugin_registercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin) +{ + pluginregistercallback(pluginHandle, cbType, cbPlugin); +} + +PLUG_IMPEXP bool _plugin_unregistercallback(int pluginHandle, CBTYPE cbType) +{ + return pluginunregistercallback(pluginHandle, cbType); +} + +PLUG_IMPEXP bool _plugin_registercommand(int pluginHandle, const char* command, CBPLUGINCOMMAND cbCommand, bool debugonly) +{ + return plugincmdregister(pluginHandle, command, cbCommand, debugonly); +} + +PLUG_IMPEXP bool _plugin_unregistercommand(int pluginHandle, const char* command) +{ + return plugincmdunregister(pluginHandle, command); +} + +PLUG_IMPEXP void _plugin_logprintf(const char* format, ...) +{ + va_list args; + + va_start(args, format); + dprintf_args(format, args); + va_end(args); +} + +PLUG_IMPEXP void _plugin_logputs(const char* text) +{ + dputs(text); +} + +PLUG_IMPEXP void _plugin_debugpause() +{ + GuiSetDebugState(paused); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + dbgsetskipexceptions(false); + wait(WAITID_RUN); +} + +PLUG_IMPEXP void _plugin_debugskipexceptions(bool skip) +{ + dbgsetskipexceptions(skip); +} + +PLUG_IMPEXP int _plugin_menuadd(int hMenu, const char* title) +{ + return pluginmenuadd(hMenu, title); +} + +PLUG_IMPEXP bool _plugin_menuaddentry(int hMenu, int hEntry, const char* title) +{ + return pluginmenuaddentry(hMenu, hEntry, title); +} + +PLUG_IMPEXP bool _plugin_menuaddseparator(int hMenu) +{ + return pluginmenuaddseparator(hMenu); +} + +PLUG_IMPEXP bool _plugin_menuclear(int hMenu) +{ + return pluginmenuclear(hMenu); +} + +PLUG_IMPEXP void _plugin_menuseticon(int hMenu, const ICONDATA* icon) +{ + pluginmenuseticon(hMenu, icon); +} + +PLUG_IMPEXP void _plugin_menuentryseticon(int pluginHandle, int hEntry, const ICONDATA* icon) +{ + pluginmenuentryseticon(pluginHandle, hEntry, icon); +} + +PLUG_IMPEXP void _plugin_startscript(CBPLUGINSCRIPT cbScript) +{ + dbgstartscriptthread(cbScript); +} + +PLUG_IMPEXP bool _plugin_waituntilpaused() +{ + while(DbgIsDebugging() && dbgisrunning()) //wait until the debugger paused + Sleep(1); + return DbgIsDebugging(); } \ No newline at end of file diff --git a/src/dbg/_plugins.h b/src/dbg/_plugins.h index 1dfef859..7b13ecf5 100644 --- a/src/dbg/_plugins.h +++ b/src/dbg/_plugins.h @@ -1,230 +1,230 @@ -#ifndef _PLUGINS_H -#define _PLUGINS_H - -#ifndef __cplusplus -#include -#endif - -#ifndef PLUG_IMPEXP -#ifdef BUILD_DBG -#define PLUG_IMPEXP __declspec(dllexport) -#else -#define PLUG_IMPEXP __declspec(dllimport) -#endif //BUILD_DBG -#endif //PLUG_IMPEXP - -#include "_plugin_types.h" - -//default structure alignments forced -#ifdef _WIN64 -#pragma pack(push, 16) -#else //x86 -#pragma pack(push, 8) -#endif //_WIN64 - -//defines -#define PLUG_SDKVERSION 1 - -//structures -typedef struct -{ - //provided by the debugger - int pluginHandle; - //provided by the pluginit function - int sdkVersion; - int pluginVersion; - char pluginName[256]; -} PLUG_INITSTRUCT; - -typedef struct -{ - //provided by the debugger - HWND hwndDlg; //gui window handle - int hMenu; //plugin menu handle - int hMenuDisasm; //plugin disasm menu handle - int hMenuDump; //plugin dump menu handle - int hMenuStack; //plugin stack menu handle -} PLUG_SETUPSTRUCT; - -typedef struct -{ - void* data; //user data -} PLUG_SCRIPTSTRUCT; - -//callback structures -typedef struct -{ - const char* szFileName; -} PLUG_CB_INITDEBUG; - -typedef struct -{ - void* reserved; -} PLUG_CB_STOPDEBUG; - -typedef struct -{ - CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo; - IMAGEHLP_MODULE64* modInfo; - const char* DebugFileName; - PROCESS_INFORMATION* fdProcessInfo; -} PLUG_CB_CREATEPROCESS; - -typedef struct -{ - EXIT_PROCESS_DEBUG_INFO* ExitProcess; -} PLUG_CB_EXITPROCESS; - -typedef struct -{ - CREATE_THREAD_DEBUG_INFO* CreateThread; - DWORD dwThreadId; -} PLUG_CB_CREATETHREAD; - -typedef struct -{ - EXIT_THREAD_DEBUG_INFO* ExitThread; - DWORD dwThreadId; -} PLUG_CB_EXITTHREAD; - -typedef struct -{ - void* reserved; -} PLUG_CB_SYSTEMBREAKPOINT; - -typedef struct -{ - LOAD_DLL_DEBUG_INFO* LoadDll; - IMAGEHLP_MODULE64* modInfo; - const char* modname; -} PLUG_CB_LOADDLL; - -typedef struct -{ - UNLOAD_DLL_DEBUG_INFO* UnloadDll; -} PLUG_CB_UNLOADDLL; - -typedef struct -{ - OUTPUT_DEBUG_STRING_INFO* DebugString; -} PLUG_CB_OUTPUTDEBUGSTRING; - -typedef struct -{ - EXCEPTION_DEBUG_INFO* Exception; -} PLUG_CB_EXCEPTION; - -typedef struct -{ - BRIDGEBP* breakpoint; -} PLUG_CB_BREAKPOINT; - -typedef struct -{ - void* reserved; -} PLUG_CB_PAUSEDEBUG; - -typedef struct -{ - void* reserved; -} PLUG_CB_RESUMEDEBUG; - -typedef struct -{ - void* reserved; -} PLUG_CB_STEPPED; - -typedef struct -{ - DWORD dwProcessId; -} PLUG_CB_ATTACH; - -typedef struct -{ - PROCESS_INFORMATION* fdProcessInfo; -} PLUG_CB_DETACH; - -typedef struct -{ - DEBUG_EVENT* DebugEvent; -} PLUG_CB_DEBUGEVENT; - -typedef struct -{ - int hEntry; -} PLUG_CB_MENUENTRY; - -typedef struct -{ - MSG* message; - long* result; - bool retval; -} PLUG_CB_WINEVENT; - -typedef struct -{ - MSG* message; - bool retval; -} PLUG_CB_WINEVENTGLOBAL; - -//enums -typedef enum -{ - CB_INITDEBUG, //PLUG_CB_INITDEBUG - CB_STOPDEBUG, //PLUG_CB_STOPDEBUG - CB_CREATEPROCESS, //PLUG_CB_CREATEPROCESS - CB_EXITPROCESS, //PLUG_CB_EXITPROCESS - CB_CREATETHREAD, //PLUG_CB_CREATETHREAD - CB_EXITTHREAD, //PLUG_CB_EXITTHREAD - CB_SYSTEMBREAKPOINT, //PLUG_CB_SYSTEMBREAKPOINT - CB_LOADDLL, //PLUG_CB_LOADDLL - CB_UNLOADDLL, //PLUG_CB_UNLOADDLL - CB_OUTPUTDEBUGSTRING, //PLUG_CB_OUTPUTDEBUGSTRING - CB_EXCEPTION, //PLUG_CB_EXCEPTION - CB_BREAKPOINT, //PLUG_CB_BREAKPOINT - CB_PAUSEDEBUG, //PLUG_CB_PAUSEDEBUG - CB_RESUMEDEBUG, //PLUG_CB_RESUMEDEBUG - CB_STEPPED, //PLUG_CB_STEPPED - CB_ATTACH, //PLUG_CB_ATTACHED (before attaching, after CB_INITDEBUG) - CB_DETACH, //PLUG_CB_DETACH (before detaching, before CB_STOPDEBUG) - CB_DEBUGEVENT, //PLUG_CB_DEBUGEVENT (called on any debug event) - CB_MENUENTRY, //PLUG_CB_MENUENTRY - CB_WINEVENT, //PLUG_CB_WINEVENT - CB_WINEVENTGLOBAL //PLUG_CB_WINEVENTGLOBAL -} CBTYPE; - -//typedefs -typedef void (*CBPLUGIN)(CBTYPE cbType, void* callbackInfo); -typedef bool (*CBPLUGINCOMMAND)(int, char**); -typedef void (*CBPLUGINSCRIPT)(); - -//exports -#ifdef __cplusplus -extern "C" -{ -#endif - -PLUG_IMPEXP void _plugin_registercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin); -PLUG_IMPEXP bool _plugin_unregistercallback(int pluginHandle, CBTYPE cbType); -PLUG_IMPEXP bool _plugin_registercommand(int pluginHandle, const char* command, CBPLUGINCOMMAND cbCommand, bool debugonly); -PLUG_IMPEXP bool _plugin_unregistercommand(int pluginHandle, const char* command); -PLUG_IMPEXP void _plugin_logprintf(const char* format, ...); -PLUG_IMPEXP void _plugin_logputs(const char* text); -PLUG_IMPEXP void _plugin_debugpause(); -PLUG_IMPEXP void _plugin_debugskipexceptions(bool skip); -PLUG_IMPEXP int _plugin_menuadd(int hMenu, const char* title); -PLUG_IMPEXP bool _plugin_menuaddentry(int hMenu, int hEntry, const char* title); -PLUG_IMPEXP bool _plugin_menuaddseparator(int hMenu); -PLUG_IMPEXP bool _plugin_menuclear(int hMenu); -PLUG_IMPEXP void _plugin_menuseticon(int hMenu, const ICONDATA* icon); -PLUG_IMPEXP void _plugin_menuentryseticon(int pluginHandle, int hEntry, const ICONDATA* icon); -PLUG_IMPEXP void _plugin_startscript(CBPLUGINSCRIPT cbScript); -PLUG_IMPEXP bool _plugin_waituntilpaused(); - -#ifdef __cplusplus -} -#endif - -#pragma pack(pop) - -#endif // _PLUGINS_H +#ifndef _PLUGINS_H +#define _PLUGINS_H + +#ifndef __cplusplus +#include +#endif + +#ifndef PLUG_IMPEXP +#ifdef BUILD_DBG +#define PLUG_IMPEXP __declspec(dllexport) +#else +#define PLUG_IMPEXP __declspec(dllimport) +#endif //BUILD_DBG +#endif //PLUG_IMPEXP + +#include "_plugin_types.h" + +//default structure alignments forced +#ifdef _WIN64 +#pragma pack(push, 16) +#else //x86 +#pragma pack(push, 8) +#endif //_WIN64 + +//defines +#define PLUG_SDKVERSION 1 + +//structures +typedef struct +{ + //provided by the debugger + int pluginHandle; + //provided by the pluginit function + int sdkVersion; + int pluginVersion; + char pluginName[256]; +} PLUG_INITSTRUCT; + +typedef struct +{ + //provided by the debugger + HWND hwndDlg; //gui window handle + int hMenu; //plugin menu handle + int hMenuDisasm; //plugin disasm menu handle + int hMenuDump; //plugin dump menu handle + int hMenuStack; //plugin stack menu handle +} PLUG_SETUPSTRUCT; + +typedef struct +{ + void* data; //user data +} PLUG_SCRIPTSTRUCT; + +//callback structures +typedef struct +{ + const char* szFileName; +} PLUG_CB_INITDEBUG; + +typedef struct +{ + void* reserved; +} PLUG_CB_STOPDEBUG; + +typedef struct +{ + CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo; + IMAGEHLP_MODULE64* modInfo; + const char* DebugFileName; + PROCESS_INFORMATION* fdProcessInfo; +} PLUG_CB_CREATEPROCESS; + +typedef struct +{ + EXIT_PROCESS_DEBUG_INFO* ExitProcess; +} PLUG_CB_EXITPROCESS; + +typedef struct +{ + CREATE_THREAD_DEBUG_INFO* CreateThread; + DWORD dwThreadId; +} PLUG_CB_CREATETHREAD; + +typedef struct +{ + EXIT_THREAD_DEBUG_INFO* ExitThread; + DWORD dwThreadId; +} PLUG_CB_EXITTHREAD; + +typedef struct +{ + void* reserved; +} PLUG_CB_SYSTEMBREAKPOINT; + +typedef struct +{ + LOAD_DLL_DEBUG_INFO* LoadDll; + IMAGEHLP_MODULE64* modInfo; + const char* modname; +} PLUG_CB_LOADDLL; + +typedef struct +{ + UNLOAD_DLL_DEBUG_INFO* UnloadDll; +} PLUG_CB_UNLOADDLL; + +typedef struct +{ + OUTPUT_DEBUG_STRING_INFO* DebugString; +} PLUG_CB_OUTPUTDEBUGSTRING; + +typedef struct +{ + EXCEPTION_DEBUG_INFO* Exception; +} PLUG_CB_EXCEPTION; + +typedef struct +{ + BRIDGEBP* breakpoint; +} PLUG_CB_BREAKPOINT; + +typedef struct +{ + void* reserved; +} PLUG_CB_PAUSEDEBUG; + +typedef struct +{ + void* reserved; +} PLUG_CB_RESUMEDEBUG; + +typedef struct +{ + void* reserved; +} PLUG_CB_STEPPED; + +typedef struct +{ + DWORD dwProcessId; +} PLUG_CB_ATTACH; + +typedef struct +{ + PROCESS_INFORMATION* fdProcessInfo; +} PLUG_CB_DETACH; + +typedef struct +{ + DEBUG_EVENT* DebugEvent; +} PLUG_CB_DEBUGEVENT; + +typedef struct +{ + int hEntry; +} PLUG_CB_MENUENTRY; + +typedef struct +{ + MSG* message; + long* result; + bool retval; +} PLUG_CB_WINEVENT; + +typedef struct +{ + MSG* message; + bool retval; +} PLUG_CB_WINEVENTGLOBAL; + +//enums +typedef enum +{ + CB_INITDEBUG, //PLUG_CB_INITDEBUG + CB_STOPDEBUG, //PLUG_CB_STOPDEBUG + CB_CREATEPROCESS, //PLUG_CB_CREATEPROCESS + CB_EXITPROCESS, //PLUG_CB_EXITPROCESS + CB_CREATETHREAD, //PLUG_CB_CREATETHREAD + CB_EXITTHREAD, //PLUG_CB_EXITTHREAD + CB_SYSTEMBREAKPOINT, //PLUG_CB_SYSTEMBREAKPOINT + CB_LOADDLL, //PLUG_CB_LOADDLL + CB_UNLOADDLL, //PLUG_CB_UNLOADDLL + CB_OUTPUTDEBUGSTRING, //PLUG_CB_OUTPUTDEBUGSTRING + CB_EXCEPTION, //PLUG_CB_EXCEPTION + CB_BREAKPOINT, //PLUG_CB_BREAKPOINT + CB_PAUSEDEBUG, //PLUG_CB_PAUSEDEBUG + CB_RESUMEDEBUG, //PLUG_CB_RESUMEDEBUG + CB_STEPPED, //PLUG_CB_STEPPED + CB_ATTACH, //PLUG_CB_ATTACHED (before attaching, after CB_INITDEBUG) + CB_DETACH, //PLUG_CB_DETACH (before detaching, before CB_STOPDEBUG) + CB_DEBUGEVENT, //PLUG_CB_DEBUGEVENT (called on any debug event) + CB_MENUENTRY, //PLUG_CB_MENUENTRY + CB_WINEVENT, //PLUG_CB_WINEVENT + CB_WINEVENTGLOBAL //PLUG_CB_WINEVENTGLOBAL +} CBTYPE; + +//typedefs +typedef void (*CBPLUGIN)(CBTYPE cbType, void* callbackInfo); +typedef bool (*CBPLUGINCOMMAND)(int, char**); +typedef void (*CBPLUGINSCRIPT)(); + +//exports +#ifdef __cplusplus +extern "C" +{ +#endif + +PLUG_IMPEXP void _plugin_registercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin); +PLUG_IMPEXP bool _plugin_unregistercallback(int pluginHandle, CBTYPE cbType); +PLUG_IMPEXP bool _plugin_registercommand(int pluginHandle, const char* command, CBPLUGINCOMMAND cbCommand, bool debugonly); +PLUG_IMPEXP bool _plugin_unregistercommand(int pluginHandle, const char* command); +PLUG_IMPEXP void _plugin_logprintf(const char* format, ...); +PLUG_IMPEXP void _plugin_logputs(const char* text); +PLUG_IMPEXP void _plugin_debugpause(); +PLUG_IMPEXP void _plugin_debugskipexceptions(bool skip); +PLUG_IMPEXP int _plugin_menuadd(int hMenu, const char* title); +PLUG_IMPEXP bool _plugin_menuaddentry(int hMenu, int hEntry, const char* title); +PLUG_IMPEXP bool _plugin_menuaddseparator(int hMenu); +PLUG_IMPEXP bool _plugin_menuclear(int hMenu); +PLUG_IMPEXP void _plugin_menuseticon(int hMenu, const ICONDATA* icon); +PLUG_IMPEXP void _plugin_menuentryseticon(int pluginHandle, int hEntry, const ICONDATA* icon); +PLUG_IMPEXP void _plugin_startscript(CBPLUGINSCRIPT cbScript); +PLUG_IMPEXP bool _plugin_waituntilpaused(); + +#ifdef __cplusplus +} +#endif + +#pragma pack(pop) + +#endif // _PLUGINS_H diff --git a/src/dbg/_scriptapi.h b/src/dbg/_scriptapi.h index f6460d95..783c6776 100644 --- a/src/dbg/_scriptapi.h +++ b/src/dbg/_scriptapi.h @@ -1,8 +1,8 @@ -#ifndef _SCRIPT_API_H -#define _SCRIPT_API_H - -#include "_plugins.h" - -#define SCRIPT_EXPORT PLUG_IMPEXP - +#ifndef _SCRIPT_API_H +#define _SCRIPT_API_H + +#include "_plugins.h" + +#define SCRIPT_EXPORT PLUG_IMPEXP + #endif //_SCRIPT_API_H \ No newline at end of file diff --git a/src/dbg/_scriptapi_assembler.cpp b/src/dbg/_scriptapi_assembler.cpp index 0da96409..3bce70b5 100644 --- a/src/dbg/_scriptapi_assembler.cpp +++ b/src/dbg/_scriptapi_assembler.cpp @@ -1,22 +1,22 @@ -#include "_scriptapi_assembler.h" -#include "assemble.h" - -SCRIPT_EXPORT bool Script::Assembler::Assemble(duint addr, unsigned char* dest, int* size, const char* instruction) -{ - return assemble(addr, dest, size, instruction, nullptr); -} - -SCRIPT_EXPORT bool Script::Assembler::AssembleEx(duint addr, unsigned char* dest, int* size, const char* instruction, char* error) -{ - return assemble(addr, dest, size, instruction, error); -} - -SCRIPT_EXPORT bool Script::Assembler::AssembleMem(duint addr, const char* instruction) -{ - return assembleat(addr, instruction, nullptr, nullptr, false); -} - -SCRIPT_EXPORT bool Script::Assembler::AssembleMemEx(duint addr, const char* instruction, int* size, char* error, bool fillnop) -{ - return assembleat(addr, instruction, size, error, fillnop); +#include "_scriptapi_assembler.h" +#include "assemble.h" + +SCRIPT_EXPORT bool Script::Assembler::Assemble(duint addr, unsigned char* dest, int* size, const char* instruction) +{ + return assemble(addr, dest, size, instruction, nullptr); +} + +SCRIPT_EXPORT bool Script::Assembler::AssembleEx(duint addr, unsigned char* dest, int* size, const char* instruction, char* error) +{ + return assemble(addr, dest, size, instruction, error); +} + +SCRIPT_EXPORT bool Script::Assembler::AssembleMem(duint addr, const char* instruction) +{ + return assembleat(addr, instruction, nullptr, nullptr, false); +} + +SCRIPT_EXPORT bool Script::Assembler::AssembleMemEx(duint addr, const char* instruction, int* size, char* error, bool fillnop) +{ + return assembleat(addr, instruction, size, error, fillnop); } \ No newline at end of file diff --git a/src/dbg/_scriptapi_assembler.h b/src/dbg/_scriptapi_assembler.h index 45cca5e9..f731724e 100644 --- a/src/dbg/_scriptapi_assembler.h +++ b/src/dbg/_scriptapi_assembler.h @@ -1,17 +1,17 @@ -#ifndef _SCRIPTAPI_ASSEMBLER_H -#define _SCRIPTAPI_ASSEMBLER_H - -#include "_scriptapi.h" - -namespace Script -{ -namespace Assembler -{ -SCRIPT_EXPORT bool Assemble(duint addr, unsigned char* dest, int* size, const char* instruction); //dest[16] -SCRIPT_EXPORT bool AssembleEx(duint addr, unsigned char* dest, int* size, const char* instruction, char* error); //dest[16], error[MAX_ERROR_SIZE] -SCRIPT_EXPORT bool AssembleMem(duint addr, const char* instruction); -SCRIPT_EXPORT bool AssembleMemEx(duint addr, const char* instruction, int* size, char* error, bool fillnop); //error[MAX_ERROR_SIZE] -}; //Assembler -}; //Script - +#ifndef _SCRIPTAPI_ASSEMBLER_H +#define _SCRIPTAPI_ASSEMBLER_H + +#include "_scriptapi.h" + +namespace Script +{ +namespace Assembler +{ +SCRIPT_EXPORT bool Assemble(duint addr, unsigned char* dest, int* size, const char* instruction); //dest[16] +SCRIPT_EXPORT bool AssembleEx(duint addr, unsigned char* dest, int* size, const char* instruction, char* error); //dest[16], error[MAX_ERROR_SIZE] +SCRIPT_EXPORT bool AssembleMem(duint addr, const char* instruction); +SCRIPT_EXPORT bool AssembleMemEx(duint addr, const char* instruction, int* size, char* error, bool fillnop); //error[MAX_ERROR_SIZE] +}; //Assembler +}; //Script + #endif //_SCRIPTAPI_ASSEMBLER_H \ No newline at end of file diff --git a/src/dbg/_scriptapi_debug.cpp b/src/dbg/_scriptapi_debug.cpp index ae6be48f..cebf9706 100644 --- a/src/dbg/_scriptapi_debug.cpp +++ b/src/dbg/_scriptapi_debug.cpp @@ -1,71 +1,71 @@ -#include "_scriptapi_debug.h" - -SCRIPT_EXPORT void Script::Debug::Wait() -{ - _plugin_waituntilpaused(); -} - -SCRIPT_EXPORT void Script::Debug::Run() -{ - DbgCmdExecDirect("run"); - Wait(); -} - -SCRIPT_EXPORT void Script::Debug::Pause() -{ - DbgCmdExecDirect("pause"); - Wait(); -} - -SCRIPT_EXPORT void Script::Debug::Stop() -{ - DbgCmdExecDirect("StopDebug"); - Wait(); -} - -SCRIPT_EXPORT void Script::Debug::StepIn() -{ - DbgCmdExecDirect("StepInto"); - Wait(); -} - -SCRIPT_EXPORT void Script::Debug::StepOver() -{ - DbgCmdExecDirect("StepOver"); - Wait(); -} - -SCRIPT_EXPORT void Script::Debug::StepOut() -{ - DbgCmdExecDirect("StepOut"); - Wait(); -} - -SCRIPT_EXPORT bool Script::Debug::SetBreakpoint(duint address) -{ - char command[128] = ""; - sprintf_s(command, "bp %p", address); - return DbgCmdExecDirect(command); -} - -SCRIPT_EXPORT bool Script::Debug::DeleteBreakpoint(duint address) -{ - char command[128] = ""; - sprintf_s(command, "bc %p", address); - return DbgCmdExecDirect(command); -} - -SCRIPT_EXPORT bool Script::Debug::SetHardwareBreakpoint(duint address, HardwareType type) -{ - char command[128] = ""; - const char* types[] = { "rw", "w", "x" }; - sprintf_s(command, "bphws %p, %s", address, types[type]); - return DbgCmdExecDirect(command); -} - -SCRIPT_EXPORT bool Script::Debug::DeleteHardwareBreakpoint(duint address) -{ - char command[128] = ""; - sprintf_s(command, "bphwc %p", address); - return DbgCmdExecDirect(command); +#include "_scriptapi_debug.h" + +SCRIPT_EXPORT void Script::Debug::Wait() +{ + _plugin_waituntilpaused(); +} + +SCRIPT_EXPORT void Script::Debug::Run() +{ + DbgCmdExecDirect("run"); + Wait(); +} + +SCRIPT_EXPORT void Script::Debug::Pause() +{ + DbgCmdExecDirect("pause"); + Wait(); +} + +SCRIPT_EXPORT void Script::Debug::Stop() +{ + DbgCmdExecDirect("StopDebug"); + Wait(); +} + +SCRIPT_EXPORT void Script::Debug::StepIn() +{ + DbgCmdExecDirect("StepInto"); + Wait(); +} + +SCRIPT_EXPORT void Script::Debug::StepOver() +{ + DbgCmdExecDirect("StepOver"); + Wait(); +} + +SCRIPT_EXPORT void Script::Debug::StepOut() +{ + DbgCmdExecDirect("StepOut"); + Wait(); +} + +SCRIPT_EXPORT bool Script::Debug::SetBreakpoint(duint address) +{ + char command[128] = ""; + sprintf_s(command, "bp %p", address); + return DbgCmdExecDirect(command); +} + +SCRIPT_EXPORT bool Script::Debug::DeleteBreakpoint(duint address) +{ + char command[128] = ""; + sprintf_s(command, "bc %p", address); + return DbgCmdExecDirect(command); +} + +SCRIPT_EXPORT bool Script::Debug::SetHardwareBreakpoint(duint address, HardwareType type) +{ + char command[128] = ""; + const char* types[] = { "rw", "w", "x" }; + sprintf_s(command, "bphws %p, %s", address, types[type]); + return DbgCmdExecDirect(command); +} + +SCRIPT_EXPORT bool Script::Debug::DeleteHardwareBreakpoint(duint address) +{ + char command[128] = ""; + sprintf_s(command, "bphwc %p", address); + return DbgCmdExecDirect(command); } \ No newline at end of file diff --git a/src/dbg/_scriptapi_debug.h b/src/dbg/_scriptapi_debug.h index 91c80fa7..49a970bf 100644 --- a/src/dbg/_scriptapi_debug.h +++ b/src/dbg/_scriptapi_debug.h @@ -1,31 +1,31 @@ -#ifndef _SCRIPTAPI_DEBUG_H -#define _SCRIPTAPI_DEBUG_H - -#include "_scriptapi.h" - -namespace Script -{ -namespace Debug -{ -enum HardwareType -{ - HardwareAccess, - HardwareWrite, - HardwareExecute -}; - -SCRIPT_EXPORT void Wait(); -SCRIPT_EXPORT void Run(); -SCRIPT_EXPORT void Pause(); -SCRIPT_EXPORT void Stop(); -SCRIPT_EXPORT void StepIn(); -SCRIPT_EXPORT void StepOver(); -SCRIPT_EXPORT void StepOut(); -SCRIPT_EXPORT bool SetBreakpoint(duint address); -SCRIPT_EXPORT bool DeleteBreakpoint(duint address); -SCRIPT_EXPORT bool SetHardwareBreakpoint(duint address, HardwareType type = HardwareExecute); -SCRIPT_EXPORT bool DeleteHardwareBreakpoint(duint address); -}; //Debug -}; //Script - +#ifndef _SCRIPTAPI_DEBUG_H +#define _SCRIPTAPI_DEBUG_H + +#include "_scriptapi.h" + +namespace Script +{ +namespace Debug +{ +enum HardwareType +{ + HardwareAccess, + HardwareWrite, + HardwareExecute +}; + +SCRIPT_EXPORT void Wait(); +SCRIPT_EXPORT void Run(); +SCRIPT_EXPORT void Pause(); +SCRIPT_EXPORT void Stop(); +SCRIPT_EXPORT void StepIn(); +SCRIPT_EXPORT void StepOver(); +SCRIPT_EXPORT void StepOut(); +SCRIPT_EXPORT bool SetBreakpoint(duint address); +SCRIPT_EXPORT bool DeleteBreakpoint(duint address); +SCRIPT_EXPORT bool SetHardwareBreakpoint(duint address, HardwareType type = HardwareExecute); +SCRIPT_EXPORT bool DeleteHardwareBreakpoint(duint address); +}; //Debug +}; //Script + #endif //_SCRIPTAPI_DEBUG_H \ No newline at end of file diff --git a/src/dbg/_scriptapi_flag.cpp b/src/dbg/_scriptapi_flag.cpp index 91d5b45d..68c317d4 100644 --- a/src/dbg/_scriptapi_flag.cpp +++ b/src/dbg/_scriptapi_flag.cpp @@ -1,116 +1,116 @@ -#include "_scriptapi_flag.h" -#include "value.h" - -static const char* flagTable[] = -{ - "ZF", - "OF", - "CF", - "PF", - "SF", - "TF", - "AF", - "DF", - "IF" -}; - -SCRIPT_EXPORT bool Script::Flag::Get(FlagEnum flag) -{ - duint value; - return valfromstring(flagTable[flag], &value) ? !!value : false; -} - -SCRIPT_EXPORT bool Script::Flag::Set(FlagEnum flag, bool value) -{ - return setflag(flagTable[flag], value); -} - -SCRIPT_EXPORT bool Script::Flag::GetZF() -{ - return Get(ZF); -} - -SCRIPT_EXPORT bool Script::Flag::SetZF(bool value) -{ - return Set(ZF, value); -} - -SCRIPT_EXPORT bool Script::Flag::GetOF() -{ - return Get(OF); -} - -SCRIPT_EXPORT bool Script::Flag::SetOF(bool value) -{ - return Set(OF, value); -} - -SCRIPT_EXPORT bool Script::Flag::GetCF() -{ - return Get(CF); -} - -SCRIPT_EXPORT bool Script::Flag::SetCF(bool value) -{ - return Set(CF, value); -} - -SCRIPT_EXPORT bool Script::Flag::GetPF() -{ - return Get(PF); -} - -SCRIPT_EXPORT bool Script::Flag::SetPF(bool value) -{ - return Set(PF, value); -} - -SCRIPT_EXPORT bool Script::Flag::GetSF() -{ - return Get(SF); -} - -SCRIPT_EXPORT bool Script::Flag::SetSF(bool value) -{ - return Set(SF, value); -} - -SCRIPT_EXPORT bool Script::Flag::GetTF() -{ - return Get(TF); -} - -SCRIPT_EXPORT bool Script::Flag::SetTF(bool value) -{ - return Set(TF, value); -} - -SCRIPT_EXPORT bool Script::Flag::GetAF() -{ - return Get(AF); -} - -SCRIPT_EXPORT bool Script::Flag::SetAF(bool value) -{ - return Set(AF, value); -} - -SCRIPT_EXPORT bool Script::Flag::GetDF() -{ - return Get(DF); -} - -SCRIPT_EXPORT bool Script::Flag::SetDF(bool value) -{ - return Set(DF, value); -} - -SCRIPT_EXPORT bool Script::Flag::GetIF() -{ - return Get(IF); -} - -SCRIPT_EXPORT bool Script::Flag::SetIF(bool value) -{ - return Set(IF, value); +#include "_scriptapi_flag.h" +#include "value.h" + +static const char* flagTable[] = +{ + "ZF", + "OF", + "CF", + "PF", + "SF", + "TF", + "AF", + "DF", + "IF" +}; + +SCRIPT_EXPORT bool Script::Flag::Get(FlagEnum flag) +{ + duint value; + return valfromstring(flagTable[flag], &value) ? !!value : false; +} + +SCRIPT_EXPORT bool Script::Flag::Set(FlagEnum flag, bool value) +{ + return setflag(flagTable[flag], value); +} + +SCRIPT_EXPORT bool Script::Flag::GetZF() +{ + return Get(ZF); +} + +SCRIPT_EXPORT bool Script::Flag::SetZF(bool value) +{ + return Set(ZF, value); +} + +SCRIPT_EXPORT bool Script::Flag::GetOF() +{ + return Get(OF); +} + +SCRIPT_EXPORT bool Script::Flag::SetOF(bool value) +{ + return Set(OF, value); +} + +SCRIPT_EXPORT bool Script::Flag::GetCF() +{ + return Get(CF); +} + +SCRIPT_EXPORT bool Script::Flag::SetCF(bool value) +{ + return Set(CF, value); +} + +SCRIPT_EXPORT bool Script::Flag::GetPF() +{ + return Get(PF); +} + +SCRIPT_EXPORT bool Script::Flag::SetPF(bool value) +{ + return Set(PF, value); +} + +SCRIPT_EXPORT bool Script::Flag::GetSF() +{ + return Get(SF); +} + +SCRIPT_EXPORT bool Script::Flag::SetSF(bool value) +{ + return Set(SF, value); +} + +SCRIPT_EXPORT bool Script::Flag::GetTF() +{ + return Get(TF); +} + +SCRIPT_EXPORT bool Script::Flag::SetTF(bool value) +{ + return Set(TF, value); +} + +SCRIPT_EXPORT bool Script::Flag::GetAF() +{ + return Get(AF); +} + +SCRIPT_EXPORT bool Script::Flag::SetAF(bool value) +{ + return Set(AF, value); +} + +SCRIPT_EXPORT bool Script::Flag::GetDF() +{ + return Get(DF); +} + +SCRIPT_EXPORT bool Script::Flag::SetDF(bool value) +{ + return Set(DF, value); +} + +SCRIPT_EXPORT bool Script::Flag::GetIF() +{ + return Get(IF); +} + +SCRIPT_EXPORT bool Script::Flag::SetIF(bool value) +{ + return Set(IF, value); } \ No newline at end of file diff --git a/src/dbg/_scriptapi_flag.h b/src/dbg/_scriptapi_flag.h index a9f5bf0a..3cce3996 100644 --- a/src/dbg/_scriptapi_flag.h +++ b/src/dbg/_scriptapi_flag.h @@ -1,47 +1,47 @@ -#ifndef _SCRIPTAPI_FLAG_H -#define _SCRIPTAPI_FLAG_H - -#include "_scriptapi.h" - -namespace Script -{ -namespace Flag -{ -enum FlagEnum -{ - ZF, - OF, - CF, - PF, - SF, - TF, - AF, - DF, - IF -}; - -SCRIPT_EXPORT bool Get(FlagEnum flag); -SCRIPT_EXPORT bool Set(FlagEnum flag, bool value); - -SCRIPT_EXPORT bool GetZF(); -SCRIPT_EXPORT bool SetZF(bool value); -SCRIPT_EXPORT bool GetOF(); -SCRIPT_EXPORT bool SetOF(bool value); -SCRIPT_EXPORT bool GetCF(); -SCRIPT_EXPORT bool SetCF(bool value); -SCRIPT_EXPORT bool GetPF(); -SCRIPT_EXPORT bool SetPF(bool value); -SCRIPT_EXPORT bool GetSF(); -SCRIPT_EXPORT bool SetSF(bool value); -SCRIPT_EXPORT bool GetTF(); -SCRIPT_EXPORT bool SetTF(bool value); -SCRIPT_EXPORT bool GetAF(); -SCRIPT_EXPORT bool SetAF(bool value); -SCRIPT_EXPORT bool GetDF(); -SCRIPT_EXPORT bool SetDF(bool value); -SCRIPT_EXPORT bool GetIF(); -SCRIPT_EXPORT bool SetIF(bool value); -}; -}; - +#ifndef _SCRIPTAPI_FLAG_H +#define _SCRIPTAPI_FLAG_H + +#include "_scriptapi.h" + +namespace Script +{ +namespace Flag +{ +enum FlagEnum +{ + ZF, + OF, + CF, + PF, + SF, + TF, + AF, + DF, + IF +}; + +SCRIPT_EXPORT bool Get(FlagEnum flag); +SCRIPT_EXPORT bool Set(FlagEnum flag, bool value); + +SCRIPT_EXPORT bool GetZF(); +SCRIPT_EXPORT bool SetZF(bool value); +SCRIPT_EXPORT bool GetOF(); +SCRIPT_EXPORT bool SetOF(bool value); +SCRIPT_EXPORT bool GetCF(); +SCRIPT_EXPORT bool SetCF(bool value); +SCRIPT_EXPORT bool GetPF(); +SCRIPT_EXPORT bool SetPF(bool value); +SCRIPT_EXPORT bool GetSF(); +SCRIPT_EXPORT bool SetSF(bool value); +SCRIPT_EXPORT bool GetTF(); +SCRIPT_EXPORT bool SetTF(bool value); +SCRIPT_EXPORT bool GetAF(); +SCRIPT_EXPORT bool SetAF(bool value); +SCRIPT_EXPORT bool GetDF(); +SCRIPT_EXPORT bool SetDF(bool value); +SCRIPT_EXPORT bool GetIF(); +SCRIPT_EXPORT bool SetIF(bool value); +}; +}; + #endif //_SCRIPTAPI_FLAG_H \ No newline at end of file diff --git a/src/dbg/_scriptapi_gui.cpp b/src/dbg/_scriptapi_gui.cpp index 87797c4d..018b9267 100644 --- a/src/dbg/_scriptapi_gui.cpp +++ b/src/dbg/_scriptapi_gui.cpp @@ -1,152 +1,152 @@ -#include "_scriptapi_gui.h" -#include "_scriptapi_misc.h" - -SCRIPT_EXPORT bool Script::Gui::Disassembly::SelectionGet(duint* start, duint* end) -{ - return Gui::SelectionGet(DisassemblyWindow, start, end); -} - -SCRIPT_EXPORT bool Script::Gui::Disassembly::SelectionSet(duint start, duint end) -{ - return Gui::SelectionSet(DisassemblyWindow, start, end); -} - -SCRIPT_EXPORT duint Script::Gui::Disassembly::SelectionGetStart() -{ - return Gui::SelectionGetStart(DisassemblyWindow); -} - -SCRIPT_EXPORT duint Script::Gui::Disassembly::SelectionGetEnd() -{ - return Gui::SelectionGetEnd(DisassemblyWindow); -} - -SCRIPT_EXPORT bool Script::Gui::Dump::SelectionGet(duint* start, duint* end) -{ - return Gui::SelectionGet(DumpWindow, start, end); -} - -SCRIPT_EXPORT bool Script::Gui::Dump::SelectionSet(duint start, duint end) -{ - return Gui::SelectionSet(DumpWindow, start, end); -} - -SCRIPT_EXPORT duint Script::Gui::Dump::SelectionGetStart() -{ - return Gui::SelectionGetStart(DumpWindow); -} - -SCRIPT_EXPORT duint Script::Gui::Dump::SelectionGetEnd() -{ - return Gui::SelectionGetEnd(DumpWindow); -} - -SCRIPT_EXPORT bool Script::Gui::Stack::SelectionGet(duint* start, duint* end) -{ - return Gui::SelectionGet(StackWindow, start, end); -} - -SCRIPT_EXPORT bool Script::Gui::Stack::SelectionSet(duint start, duint end) -{ - return Gui::SelectionSet(StackWindow, start, end); -} - -SCRIPT_EXPORT duint Script::Gui::Stack::SelectionGetStart() -{ - return Gui::SelectionGetStart(StackWindow); -} - -SCRIPT_EXPORT duint Script::Gui::Stack::SelectionGetEnd() -{ - return Gui::SelectionGetEnd(StackWindow); -} - -static inline int windowToBridge(Script::Gui::Window window) -{ - switch(window) - { - case Script::Gui::DisassemblyWindow: - return GUI_DISASSEMBLY; - case Script::Gui::DumpWindow: - return GUI_DUMP; - case Script::Gui::StackWindow: - return GUI_STACK; - default: - return GUI_DISASSEMBLY; - } -} - -SCRIPT_EXPORT bool Script::Gui::SelectionGet(Script::Gui::Window window, duint* start, duint* end) -{ - SELECTIONDATA selection; - if(!GuiSelectionGet(windowToBridge(window), &selection)) - return false; - if(start) - *start = selection.start; - if(end) - *end = selection.end; - return true; -} - -SCRIPT_EXPORT bool Script::Gui::SelectionSet(Script::Gui::Window window, duint start, duint end) -{ - SELECTIONDATA selection; - selection.start = start; - selection.end = end; - return GuiSelectionSet(windowToBridge(window), &selection); -} - -SCRIPT_EXPORT duint Script::Gui::SelectionGetStart(Script::Gui::Window window) -{ - duint start; - return Gui::SelectionGet(window, &start, nullptr) ? start : 0; -} - -SCRIPT_EXPORT duint Script::Gui::SelectionGetEnd(Script::Gui::Window window) -{ - duint end; - return Gui::SelectionGet(window, nullptr, &end) ? end : 0; -} - -SCRIPT_EXPORT void Script::Gui::Message(const char* message) -{ - GuiScriptMessage(message); -} - -SCRIPT_EXPORT bool Script::Gui::MessageYesNo(const char* message) -{ - return !!GuiScriptMsgyn(message); -} - -SCRIPT_EXPORT bool Script::Gui::InputLine(const char* title, char* text) -{ - return GuiGetLineWindow(title, text); -} - -SCRIPT_EXPORT bool Script::Gui::InputValue(const char* title, duint* value) -{ - Memory line(GUI_MAX_LINE_SIZE); - if(!GuiGetLineWindow(title, line())) - return false; - return Misc::ParseExpression(line(), value); -} - -SCRIPT_EXPORT void Script::Gui::Refresh() -{ - GuiUpdateAllViews(); -} - -SCRIPT_EXPORT void Script::Gui::AddQWidgetTab(void* qWidget) -{ - GuiAddQWidgetTab(qWidget); -} - -SCRIPT_EXPORT void Script::Gui::ShowQWidgetTab(void* qWidget) -{ - GuiShowQWidgetTab(qWidget); -} - -SCRIPT_EXPORT void Script::Gui::CloseQWidgetTab(void* qWidget) -{ - GuiCloseQWidgetTab(qWidget); +#include "_scriptapi_gui.h" +#include "_scriptapi_misc.h" + +SCRIPT_EXPORT bool Script::Gui::Disassembly::SelectionGet(duint* start, duint* end) +{ + return Gui::SelectionGet(DisassemblyWindow, start, end); +} + +SCRIPT_EXPORT bool Script::Gui::Disassembly::SelectionSet(duint start, duint end) +{ + return Gui::SelectionSet(DisassemblyWindow, start, end); +} + +SCRIPT_EXPORT duint Script::Gui::Disassembly::SelectionGetStart() +{ + return Gui::SelectionGetStart(DisassemblyWindow); +} + +SCRIPT_EXPORT duint Script::Gui::Disassembly::SelectionGetEnd() +{ + return Gui::SelectionGetEnd(DisassemblyWindow); +} + +SCRIPT_EXPORT bool Script::Gui::Dump::SelectionGet(duint* start, duint* end) +{ + return Gui::SelectionGet(DumpWindow, start, end); +} + +SCRIPT_EXPORT bool Script::Gui::Dump::SelectionSet(duint start, duint end) +{ + return Gui::SelectionSet(DumpWindow, start, end); +} + +SCRIPT_EXPORT duint Script::Gui::Dump::SelectionGetStart() +{ + return Gui::SelectionGetStart(DumpWindow); +} + +SCRIPT_EXPORT duint Script::Gui::Dump::SelectionGetEnd() +{ + return Gui::SelectionGetEnd(DumpWindow); +} + +SCRIPT_EXPORT bool Script::Gui::Stack::SelectionGet(duint* start, duint* end) +{ + return Gui::SelectionGet(StackWindow, start, end); +} + +SCRIPT_EXPORT bool Script::Gui::Stack::SelectionSet(duint start, duint end) +{ + return Gui::SelectionSet(StackWindow, start, end); +} + +SCRIPT_EXPORT duint Script::Gui::Stack::SelectionGetStart() +{ + return Gui::SelectionGetStart(StackWindow); +} + +SCRIPT_EXPORT duint Script::Gui::Stack::SelectionGetEnd() +{ + return Gui::SelectionGetEnd(StackWindow); +} + +static inline int windowToBridge(Script::Gui::Window window) +{ + switch(window) + { + case Script::Gui::DisassemblyWindow: + return GUI_DISASSEMBLY; + case Script::Gui::DumpWindow: + return GUI_DUMP; + case Script::Gui::StackWindow: + return GUI_STACK; + default: + return GUI_DISASSEMBLY; + } +} + +SCRIPT_EXPORT bool Script::Gui::SelectionGet(Script::Gui::Window window, duint* start, duint* end) +{ + SELECTIONDATA selection; + if(!GuiSelectionGet(windowToBridge(window), &selection)) + return false; + if(start) + *start = selection.start; + if(end) + *end = selection.end; + return true; +} + +SCRIPT_EXPORT bool Script::Gui::SelectionSet(Script::Gui::Window window, duint start, duint end) +{ + SELECTIONDATA selection; + selection.start = start; + selection.end = end; + return GuiSelectionSet(windowToBridge(window), &selection); +} + +SCRIPT_EXPORT duint Script::Gui::SelectionGetStart(Script::Gui::Window window) +{ + duint start; + return Gui::SelectionGet(window, &start, nullptr) ? start : 0; +} + +SCRIPT_EXPORT duint Script::Gui::SelectionGetEnd(Script::Gui::Window window) +{ + duint end; + return Gui::SelectionGet(window, nullptr, &end) ? end : 0; +} + +SCRIPT_EXPORT void Script::Gui::Message(const char* message) +{ + GuiScriptMessage(message); +} + +SCRIPT_EXPORT bool Script::Gui::MessageYesNo(const char* message) +{ + return !!GuiScriptMsgyn(message); +} + +SCRIPT_EXPORT bool Script::Gui::InputLine(const char* title, char* text) +{ + return GuiGetLineWindow(title, text); +} + +SCRIPT_EXPORT bool Script::Gui::InputValue(const char* title, duint* value) +{ + Memory line(GUI_MAX_LINE_SIZE); + if(!GuiGetLineWindow(title, line())) + return false; + return Misc::ParseExpression(line(), value); +} + +SCRIPT_EXPORT void Script::Gui::Refresh() +{ + GuiUpdateAllViews(); +} + +SCRIPT_EXPORT void Script::Gui::AddQWidgetTab(void* qWidget) +{ + GuiAddQWidgetTab(qWidget); +} + +SCRIPT_EXPORT void Script::Gui::ShowQWidgetTab(void* qWidget) +{ + GuiShowQWidgetTab(qWidget); +} + +SCRIPT_EXPORT void Script::Gui::CloseQWidgetTab(void* qWidget) +{ + GuiCloseQWidgetTab(qWidget); } \ No newline at end of file diff --git a/src/dbg/_scriptapi_gui.h b/src/dbg/_scriptapi_gui.h index 844f902e..1b353ec4 100644 --- a/src/dbg/_scriptapi_gui.h +++ b/src/dbg/_scriptapi_gui.h @@ -1,60 +1,60 @@ -#ifndef _SCRIPTAPI_GUI_H -#define _SCRIPTAPI_GUI_H - -#include "_scriptapi.h" - -namespace Script -{ -namespace Gui -{ -namespace Disassembly -{ -SCRIPT_EXPORT bool SelectionGet(duint* start, duint* end); -SCRIPT_EXPORT bool SelectionSet(duint start, duint end); -SCRIPT_EXPORT duint SelectionGetStart(); -SCRIPT_EXPORT duint SelectionGetEnd(); -}; //Disassembly - -namespace Dump -{ -SCRIPT_EXPORT bool SelectionGet(duint* start, duint* end); -SCRIPT_EXPORT bool SelectionSet(duint start, duint end); -SCRIPT_EXPORT duint SelectionGetStart(); -SCRIPT_EXPORT duint SelectionGetEnd(); -}; //Dump - -namespace Stack -{ -SCRIPT_EXPORT bool SelectionGet(duint* start, duint* end); -SCRIPT_EXPORT bool SelectionSet(duint start, duint end); -SCRIPT_EXPORT duint SelectionGetStart(); -SCRIPT_EXPORT duint SelectionGetEnd(); -}; //Stack -}; //Gui - -namespace Gui -{ -enum Window -{ - DisassemblyWindow, - DumpWindow, - StackWindow -}; - -SCRIPT_EXPORT bool SelectionGet(Window window, duint* start, duint* end); -SCRIPT_EXPORT bool SelectionSet(Window window, duint start, duint end); -SCRIPT_EXPORT duint SelectionGetStart(Window window); -SCRIPT_EXPORT duint SelectionGetEnd(Window window); -SCRIPT_EXPORT void Message(const char* message); -SCRIPT_EXPORT bool MessageYesNo(const char* message); -SCRIPT_EXPORT bool InputLine(const char* title, char* text); //text[GUI_MAX_LINE_SIZE] -SCRIPT_EXPORT bool InputValue(const char* title, duint* value); -SCRIPT_EXPORT void Refresh(); -SCRIPT_EXPORT void AddQWidgetTab(void* qWidget); -SCRIPT_EXPORT void ShowQWidgetTab(void* qWidget); -SCRIPT_EXPORT void CloseQWidgetTab(void* qWidget); - -}; //Gui -}; //Script - +#ifndef _SCRIPTAPI_GUI_H +#define _SCRIPTAPI_GUI_H + +#include "_scriptapi.h" + +namespace Script +{ +namespace Gui +{ +namespace Disassembly +{ +SCRIPT_EXPORT bool SelectionGet(duint* start, duint* end); +SCRIPT_EXPORT bool SelectionSet(duint start, duint end); +SCRIPT_EXPORT duint SelectionGetStart(); +SCRIPT_EXPORT duint SelectionGetEnd(); +}; //Disassembly + +namespace Dump +{ +SCRIPT_EXPORT bool SelectionGet(duint* start, duint* end); +SCRIPT_EXPORT bool SelectionSet(duint start, duint end); +SCRIPT_EXPORT duint SelectionGetStart(); +SCRIPT_EXPORT duint SelectionGetEnd(); +}; //Dump + +namespace Stack +{ +SCRIPT_EXPORT bool SelectionGet(duint* start, duint* end); +SCRIPT_EXPORT bool SelectionSet(duint start, duint end); +SCRIPT_EXPORT duint SelectionGetStart(); +SCRIPT_EXPORT duint SelectionGetEnd(); +}; //Stack +}; //Gui + +namespace Gui +{ +enum Window +{ + DisassemblyWindow, + DumpWindow, + StackWindow +}; + +SCRIPT_EXPORT bool SelectionGet(Window window, duint* start, duint* end); +SCRIPT_EXPORT bool SelectionSet(Window window, duint start, duint end); +SCRIPT_EXPORT duint SelectionGetStart(Window window); +SCRIPT_EXPORT duint SelectionGetEnd(Window window); +SCRIPT_EXPORT void Message(const char* message); +SCRIPT_EXPORT bool MessageYesNo(const char* message); +SCRIPT_EXPORT bool InputLine(const char* title, char* text); //text[GUI_MAX_LINE_SIZE] +SCRIPT_EXPORT bool InputValue(const char* title, duint* value); +SCRIPT_EXPORT void Refresh(); +SCRIPT_EXPORT void AddQWidgetTab(void* qWidget); +SCRIPT_EXPORT void ShowQWidgetTab(void* qWidget); +SCRIPT_EXPORT void CloseQWidgetTab(void* qWidget); + +}; //Gui +}; //Script + #endif //_SCRIPTAPI_GUI_H \ No newline at end of file diff --git a/src/dbg/_scriptapi_memory.cpp b/src/dbg/_scriptapi_memory.cpp index ca0fc696..1b4e713e 100644 --- a/src/dbg/_scriptapi_memory.cpp +++ b/src/dbg/_scriptapi_memory.cpp @@ -1,87 +1,87 @@ -#include "_scriptapi_memory.h" -#include "memory.h" - -SCRIPT_EXPORT bool Script::Memory::Read(duint addr, void* data, duint size, duint* sizeRead) -{ - return MemRead(addr, data, size, sizeRead); -} - -SCRIPT_EXPORT bool Script::Memory::Write(duint addr, const void* data, duint size, duint* sizeWritten) -{ - return MemWrite(addr, (void*)data, size, sizeWritten); -} - -SCRIPT_EXPORT bool Script::Memory::IsValidPtr(duint addr) -{ - return MemIsValidReadPtr(addr); -} - -SCRIPT_EXPORT duint Script::Memory::RemoteAlloc(duint addr, duint size) -{ - return (duint)MemAllocRemote(addr, size); -} - -SCRIPT_EXPORT bool Script::Memory::RemoteFree(duint addr) -{ - return MemFreeRemote(addr); -} - -SCRIPT_EXPORT unsigned char Script::Memory::ReadByte(duint addr) -{ - unsigned char data; - Read(addr, &data, sizeof(data), nullptr); - return data; -} - -SCRIPT_EXPORT bool Script::Memory::WriteByte(duint addr, unsigned char data) -{ - return Write(addr, &data, sizeof(data), nullptr); -} - -SCRIPT_EXPORT unsigned short Script::Memory::ReadWord(duint addr) -{ - unsigned short data; - Read(addr, &data, sizeof(data), nullptr); - return data; -} - -SCRIPT_EXPORT bool Script::Memory::WriteWord(duint addr, unsigned short data) -{ - return Write(addr, &data, sizeof(data), nullptr); -} - -SCRIPT_EXPORT unsigned int Script::Memory::ReadDword(duint addr) -{ - unsigned int data; - Read(addr, &data, sizeof(data), nullptr); - return data; -} - -SCRIPT_EXPORT bool Script::Memory::WriteDword(duint addr, unsigned int data) -{ - return Write(addr, &data, sizeof(data), nullptr); -} - -SCRIPT_EXPORT unsigned long long Script::Memory::ReadQword(duint addr) -{ - unsigned long long data; - Read(addr, &data, sizeof(data), nullptr); - return data; -} - -SCRIPT_EXPORT bool Script::Memory::WriteQword(duint addr, unsigned long long data) -{ - return Write(addr, &data, sizeof(data), nullptr); -} - -SCRIPT_EXPORT duint Script::Memory::ReadPtr(duint addr) -{ - duint data; - Read(addr, &data, sizeof(data), nullptr); - return data; -} - -SCRIPT_EXPORT bool Script::Memory::WritePtr(duint addr, duint data) -{ - return Write(addr, &data, sizeof(data), nullptr); +#include "_scriptapi_memory.h" +#include "memory.h" + +SCRIPT_EXPORT bool Script::Memory::Read(duint addr, void* data, duint size, duint* sizeRead) +{ + return MemRead(addr, data, size, sizeRead); +} + +SCRIPT_EXPORT bool Script::Memory::Write(duint addr, const void* data, duint size, duint* sizeWritten) +{ + return MemWrite(addr, (void*)data, size, sizeWritten); +} + +SCRIPT_EXPORT bool Script::Memory::IsValidPtr(duint addr) +{ + return MemIsValidReadPtr(addr); +} + +SCRIPT_EXPORT duint Script::Memory::RemoteAlloc(duint addr, duint size) +{ + return (duint)MemAllocRemote(addr, size); +} + +SCRIPT_EXPORT bool Script::Memory::RemoteFree(duint addr) +{ + return MemFreeRemote(addr); +} + +SCRIPT_EXPORT unsigned char Script::Memory::ReadByte(duint addr) +{ + unsigned char data; + Read(addr, &data, sizeof(data), nullptr); + return data; +} + +SCRIPT_EXPORT bool Script::Memory::WriteByte(duint addr, unsigned char data) +{ + return Write(addr, &data, sizeof(data), nullptr); +} + +SCRIPT_EXPORT unsigned short Script::Memory::ReadWord(duint addr) +{ + unsigned short data; + Read(addr, &data, sizeof(data), nullptr); + return data; +} + +SCRIPT_EXPORT bool Script::Memory::WriteWord(duint addr, unsigned short data) +{ + return Write(addr, &data, sizeof(data), nullptr); +} + +SCRIPT_EXPORT unsigned int Script::Memory::ReadDword(duint addr) +{ + unsigned int data; + Read(addr, &data, sizeof(data), nullptr); + return data; +} + +SCRIPT_EXPORT bool Script::Memory::WriteDword(duint addr, unsigned int data) +{ + return Write(addr, &data, sizeof(data), nullptr); +} + +SCRIPT_EXPORT unsigned long long Script::Memory::ReadQword(duint addr) +{ + unsigned long long data; + Read(addr, &data, sizeof(data), nullptr); + return data; +} + +SCRIPT_EXPORT bool Script::Memory::WriteQword(duint addr, unsigned long long data) +{ + return Write(addr, &data, sizeof(data), nullptr); +} + +SCRIPT_EXPORT duint Script::Memory::ReadPtr(duint addr) +{ + duint data; + Read(addr, &data, sizeof(data), nullptr); + return data; +} + +SCRIPT_EXPORT bool Script::Memory::WritePtr(duint addr, duint data) +{ + return Write(addr, &data, sizeof(data), nullptr); } \ No newline at end of file diff --git a/src/dbg/_scriptapi_memory.h b/src/dbg/_scriptapi_memory.h index 445a5965..bb39c2ab 100644 --- a/src/dbg/_scriptapi_memory.h +++ b/src/dbg/_scriptapi_memory.h @@ -1,29 +1,29 @@ -#ifndef _SCRIPTAPI_MEMORY_H -#define _SCRIPTAPI_MEMORY_H - -#include "_scriptapi.h" - -namespace Script -{ -namespace Memory -{ -SCRIPT_EXPORT bool Read(duint addr, void* data, duint size, duint* sizeRead); -SCRIPT_EXPORT bool Write(duint addr, const void* data, duint size, duint* sizeWritten); -SCRIPT_EXPORT bool IsValidPtr(duint addr); -SCRIPT_EXPORT duint RemoteAlloc(duint addr, duint size); -SCRIPT_EXPORT bool RemoteFree(duint addr); - -SCRIPT_EXPORT unsigned char ReadByte(duint addr); -SCRIPT_EXPORT bool WriteByte(duint addr, unsigned char data); -SCRIPT_EXPORT unsigned short ReadWord(duint addr); -SCRIPT_EXPORT bool WriteWord(duint addr, unsigned short data); -SCRIPT_EXPORT unsigned int ReadDword(duint addr); -SCRIPT_EXPORT bool WriteDword(duint addr, unsigned int data); -SCRIPT_EXPORT unsigned long long ReadQword(duint addr); -SCRIPT_EXPORT bool WriteQword(duint addr, unsigned long long data); -SCRIPT_EXPORT duint ReadPtr(duint addr); -SCRIPT_EXPORT bool WritePtr(duint addr, duint data); -}; //Memory -}; //Script - +#ifndef _SCRIPTAPI_MEMORY_H +#define _SCRIPTAPI_MEMORY_H + +#include "_scriptapi.h" + +namespace Script +{ +namespace Memory +{ +SCRIPT_EXPORT bool Read(duint addr, void* data, duint size, duint* sizeRead); +SCRIPT_EXPORT bool Write(duint addr, const void* data, duint size, duint* sizeWritten); +SCRIPT_EXPORT bool IsValidPtr(duint addr); +SCRIPT_EXPORT duint RemoteAlloc(duint addr, duint size); +SCRIPT_EXPORT bool RemoteFree(duint addr); + +SCRIPT_EXPORT unsigned char ReadByte(duint addr); +SCRIPT_EXPORT bool WriteByte(duint addr, unsigned char data); +SCRIPT_EXPORT unsigned short ReadWord(duint addr); +SCRIPT_EXPORT bool WriteWord(duint addr, unsigned short data); +SCRIPT_EXPORT unsigned int ReadDword(duint addr); +SCRIPT_EXPORT bool WriteDword(duint addr, unsigned int data); +SCRIPT_EXPORT unsigned long long ReadQword(duint addr); +SCRIPT_EXPORT bool WriteQword(duint addr, unsigned long long data); +SCRIPT_EXPORT duint ReadPtr(duint addr); +SCRIPT_EXPORT bool WritePtr(duint addr, duint data); +}; //Memory +}; //Script + #endif //_SCRIPTAPI_MEMORY_H \ No newline at end of file diff --git a/src/dbg/_scriptapi_misc.cpp b/src/dbg/_scriptapi_misc.cpp index 22a2ad56..93bc5693 100644 --- a/src/dbg/_scriptapi_misc.cpp +++ b/src/dbg/_scriptapi_misc.cpp @@ -1,33 +1,33 @@ -#include "_scriptapi_misc.h" -#include "value.h" - -SCRIPT_EXPORT bool Script::Misc::ParseExpression(const char* expression, duint* value) -{ - return valfromstring(expression, value); -} - -SCRIPT_EXPORT duint Script::Misc::RemoteGetProcAddress(const char* module, const char* api) -{ - duint value; - if(!ParseExpression(StringUtils::sprintf("%s:%s", module, api).c_str(), &value)) - return 0; - return value; -} - -SCRIPT_EXPORT duint Script::Misc::ResolveLabel(const char* label) -{ - duint value; - if(!ParseExpression(label, &value)) - return 0; - return value; -} - -SCRIPT_EXPORT void* Script::Misc::Alloc(duint size) -{ - return BridgeAlloc(size); -} - -SCRIPT_EXPORT void Script::Misc::Free(void* ptr) -{ - return BridgeFree(ptr); +#include "_scriptapi_misc.h" +#include "value.h" + +SCRIPT_EXPORT bool Script::Misc::ParseExpression(const char* expression, duint* value) +{ + return valfromstring(expression, value); +} + +SCRIPT_EXPORT duint Script::Misc::RemoteGetProcAddress(const char* module, const char* api) +{ + duint value; + if(!ParseExpression(StringUtils::sprintf("%s:%s", module, api).c_str(), &value)) + return 0; + return value; +} + +SCRIPT_EXPORT duint Script::Misc::ResolveLabel(const char* label) +{ + duint value; + if(!ParseExpression(label, &value)) + return 0; + return value; +} + +SCRIPT_EXPORT void* Script::Misc::Alloc(duint size) +{ + return BridgeAlloc(size); +} + +SCRIPT_EXPORT void Script::Misc::Free(void* ptr) +{ + return BridgeFree(ptr); } \ No newline at end of file diff --git a/src/dbg/_scriptapi_misc.h b/src/dbg/_scriptapi_misc.h index 4afc618a..d57911b9 100644 --- a/src/dbg/_scriptapi_misc.h +++ b/src/dbg/_scriptapi_misc.h @@ -1,18 +1,18 @@ -#ifndef _SCRIPTAPI_MISC_H -#define _SCRIPTAPI_MISC_H - -#include "_scriptapi.h" - -namespace Script -{ -namespace Misc -{ -SCRIPT_EXPORT bool ParseExpression(const char* expression, duint* value); -SCRIPT_EXPORT duint RemoteGetProcAddress(const char* module, const char* api); -SCRIPT_EXPORT duint ResolveLabel(const char* label); -SCRIPT_EXPORT void* Alloc(duint size); -SCRIPT_EXPORT void Free(void* ptr); -}; //Misc -}; //Script - +#ifndef _SCRIPTAPI_MISC_H +#define _SCRIPTAPI_MISC_H + +#include "_scriptapi.h" + +namespace Script +{ +namespace Misc +{ +SCRIPT_EXPORT bool ParseExpression(const char* expression, duint* value); +SCRIPT_EXPORT duint RemoteGetProcAddress(const char* module, const char* api); +SCRIPT_EXPORT duint ResolveLabel(const char* label); +SCRIPT_EXPORT void* Alloc(duint size); +SCRIPT_EXPORT void Free(void* ptr); +}; //Misc +}; //Script + #endif //_SCRIPTAPI_MISC_H \ No newline at end of file diff --git a/src/dbg/_scriptapi_module.cpp b/src/dbg/_scriptapi_module.cpp index 19a429de..8fcdb8cf 100644 --- a/src/dbg/_scriptapi_module.cpp +++ b/src/dbg/_scriptapi_module.cpp @@ -1,185 +1,185 @@ -#include "_scriptapi_module.h" -#include "threading.h" -#include "module.h" -#include "debugger.h" - -SCRIPT_EXPORT bool Script::Module::InfoFromAddr(duint addr, Script::Module::ModuleInfo* info) -{ - SHARED_ACQUIRE(LockModules); - MODINFO* modInfo = ModInfoFromAddr(addr); - if(!info || !modInfo) - return false; - info->base = modInfo->base; - info->size = modInfo->size; - info->entry = modInfo->entry; - info->sectionCount = int(modInfo->sections.size()); - strcpy_s(info->name, modInfo->name); - strcat_s(info->name, modInfo->extension); - strcpy_s(info->path, modInfo->path); - return true; -} - -SCRIPT_EXPORT bool Script::Module::InfoFromName(const char* name, Script::Module::ModuleInfo* info) -{ - return Module::InfoFromAddr(Module::BaseFromName(name), info); -} - -SCRIPT_EXPORT duint Script::Module::BaseFromAddr(duint addr) -{ - return ModBaseFromAddr(addr); -} - -SCRIPT_EXPORT duint Script::Module::BaseFromName(const char* name) -{ - return ModBaseFromName(name); -} - -SCRIPT_EXPORT duint Script::Module::SizeFromAddr(duint addr) -{ - return ModSizeFromAddr(addr); -} - -SCRIPT_EXPORT duint Script::Module::SizeFromName(const char* name) -{ - return Module::SizeFromAddr(Module::BaseFromName(name)); -} - -SCRIPT_EXPORT bool Script::Module::NameFromAddr(duint addr, char* name) -{ - return ModNameFromAddr(addr, name, true); -} - -SCRIPT_EXPORT bool Script::Module::PathFromAddr(duint addr, char* path) -{ - return !!ModPathFromAddr(addr, path, MAX_PATH); -} - -SCRIPT_EXPORT bool Script::Module::PathFromName(const char* name, char* path) -{ - return Module::PathFromAddr(Module::BaseFromName(name), path); -} - -SCRIPT_EXPORT duint Script::Module::EntryFromAddr(duint addr) -{ - return ModEntryFromAddr(addr); -} - -SCRIPT_EXPORT duint Script::Module::EntryFromName(const char* name) -{ - return Module::EntryFromAddr(Module::BaseFromName(name)); -} - -SCRIPT_EXPORT int Script::Module::SectionCountFromAddr(duint addr) -{ - SHARED_ACQUIRE(LockModules); - MODINFO* modInfo = ModInfoFromAddr(addr); - return modInfo ? int(modInfo->sections.size()) : 0; -} - -SCRIPT_EXPORT int Script::Module::SectionCountFromName(const char* name) -{ - return Module::SectionCountFromAddr(Module::BaseFromName(name)); -} - -SCRIPT_EXPORT bool Script::Module::SectionFromAddr(duint addr, int number, ModuleSectionInfo* section) -{ - SHARED_ACQUIRE(LockModules); - MODINFO* modInfo = ModInfoFromAddr(addr); - if(!section || !modInfo || number < 0 || number >= int(modInfo->sections.size())) - return false; - const MODSECTIONINFO & secInfo = modInfo->sections.at(number); - section->addr = secInfo.addr; - section->size = secInfo.size; - strcpy_s(section->name, secInfo.name); - return true; -} - -SCRIPT_EXPORT bool Script::Module::SectionFromName(const char* name, int number, ModuleSectionInfo* section) -{ - return Module::SectionFromAddr(Module::BaseFromName(name), number, section); -} - -SCRIPT_EXPORT bool Script::Module::SectionListFromAddr(duint addr, ListOf(ModuleSectionInfo) listInfo) -{ - SHARED_ACQUIRE(LockModules); - MODINFO* modInfo = ModInfoFromAddr(addr); - if(!modInfo) - return false; - std::vector scriptSectionList; - scriptSectionList.reserve(modInfo->sections.size()); - for(const auto & section : modInfo->sections) - { - ModuleSectionInfo scriptSection; - scriptSection.addr = section.addr; - scriptSection.size = section.size; - strcpy_s(scriptSection.name, section.name); - scriptSectionList.push_back(scriptSection); - } - return List::CopyData(listInfo, scriptSectionList); -} - -SCRIPT_EXPORT bool Script::Module::SectionListFromName(const char* name, ListOf(ModuleSectionInfo) listInfo) -{ - return Module::SectionListFromAddr(Module::BaseFromName(name), listInfo); -} - -SCRIPT_EXPORT bool Script::Module::GetMainModuleInfo(ModuleInfo* info) -{ - return Module::InfoFromAddr(Module::GetMainModuleBase(), info); -} - -SCRIPT_EXPORT duint Script::Module::GetMainModuleBase() -{ - return dbggetdebuggedbase(); -} - -SCRIPT_EXPORT duint Script::Module::GetMainModuleSize() -{ - return Module::SizeFromAddr(Module::GetMainModuleBase()); -} - -SCRIPT_EXPORT duint Script::Module::GetMainModuleEntry() -{ - return Module::EntryFromAddr(Module::GetMainModuleBase()); -} - -SCRIPT_EXPORT int Script::Module::GetMainModuleSectionCount() -{ - return Module::SectionCountFromAddr(Module::GetMainModuleBase()); -} - -SCRIPT_EXPORT bool Script::Module::GetMainModuleName(char* name) -{ - return Module::NameFromAddr(Module::GetMainModuleBase(), name); -} - -SCRIPT_EXPORT bool Script::Module::GetMainModulePath(char* path) -{ - return Module::PathFromAddr(Module::GetMainModuleBase(), path); -} - -SCRIPT_EXPORT bool Script::Module::GetMainModuleSectionList(ListOf(ModuleSectionInfo) listInfo) -{ - return Module::SectionListFromAddr(Module::GetMainModuleBase(), listInfo); -} - -SCRIPT_EXPORT bool Script::Module::GetList(ListOf(ModuleInfo) listInfo) -{ - std::vector modList; - ModGetList(modList); - std::vector modScriptList; - modScriptList.reserve(modList.size()); - for(const auto & mod : modList) - { - ModuleInfo scriptMod; - scriptMod.base = mod.base; - scriptMod.size = mod.size; - scriptMod.entry = mod.entry; - scriptMod.sectionCount = int(mod.sections.size()); - strcpy_s(scriptMod.name, mod.name); - strcat_s(scriptMod.name, mod.extension); - strcpy_s(scriptMod.path, mod.path); - modScriptList.push_back(scriptMod); - } - return List::CopyData(listInfo, modScriptList); +#include "_scriptapi_module.h" +#include "threading.h" +#include "module.h" +#include "debugger.h" + +SCRIPT_EXPORT bool Script::Module::InfoFromAddr(duint addr, Script::Module::ModuleInfo* info) +{ + SHARED_ACQUIRE(LockModules); + MODINFO* modInfo = ModInfoFromAddr(addr); + if(!info || !modInfo) + return false; + info->base = modInfo->base; + info->size = modInfo->size; + info->entry = modInfo->entry; + info->sectionCount = int(modInfo->sections.size()); + strcpy_s(info->name, modInfo->name); + strcat_s(info->name, modInfo->extension); + strcpy_s(info->path, modInfo->path); + return true; +} + +SCRIPT_EXPORT bool Script::Module::InfoFromName(const char* name, Script::Module::ModuleInfo* info) +{ + return Module::InfoFromAddr(Module::BaseFromName(name), info); +} + +SCRIPT_EXPORT duint Script::Module::BaseFromAddr(duint addr) +{ + return ModBaseFromAddr(addr); +} + +SCRIPT_EXPORT duint Script::Module::BaseFromName(const char* name) +{ + return ModBaseFromName(name); +} + +SCRIPT_EXPORT duint Script::Module::SizeFromAddr(duint addr) +{ + return ModSizeFromAddr(addr); +} + +SCRIPT_EXPORT duint Script::Module::SizeFromName(const char* name) +{ + return Module::SizeFromAddr(Module::BaseFromName(name)); +} + +SCRIPT_EXPORT bool Script::Module::NameFromAddr(duint addr, char* name) +{ + return ModNameFromAddr(addr, name, true); +} + +SCRIPT_EXPORT bool Script::Module::PathFromAddr(duint addr, char* path) +{ + return !!ModPathFromAddr(addr, path, MAX_PATH); +} + +SCRIPT_EXPORT bool Script::Module::PathFromName(const char* name, char* path) +{ + return Module::PathFromAddr(Module::BaseFromName(name), path); +} + +SCRIPT_EXPORT duint Script::Module::EntryFromAddr(duint addr) +{ + return ModEntryFromAddr(addr); +} + +SCRIPT_EXPORT duint Script::Module::EntryFromName(const char* name) +{ + return Module::EntryFromAddr(Module::BaseFromName(name)); +} + +SCRIPT_EXPORT int Script::Module::SectionCountFromAddr(duint addr) +{ + SHARED_ACQUIRE(LockModules); + MODINFO* modInfo = ModInfoFromAddr(addr); + return modInfo ? int(modInfo->sections.size()) : 0; +} + +SCRIPT_EXPORT int Script::Module::SectionCountFromName(const char* name) +{ + return Module::SectionCountFromAddr(Module::BaseFromName(name)); +} + +SCRIPT_EXPORT bool Script::Module::SectionFromAddr(duint addr, int number, ModuleSectionInfo* section) +{ + SHARED_ACQUIRE(LockModules); + MODINFO* modInfo = ModInfoFromAddr(addr); + if(!section || !modInfo || number < 0 || number >= int(modInfo->sections.size())) + return false; + const MODSECTIONINFO & secInfo = modInfo->sections.at(number); + section->addr = secInfo.addr; + section->size = secInfo.size; + strcpy_s(section->name, secInfo.name); + return true; +} + +SCRIPT_EXPORT bool Script::Module::SectionFromName(const char* name, int number, ModuleSectionInfo* section) +{ + return Module::SectionFromAddr(Module::BaseFromName(name), number, section); +} + +SCRIPT_EXPORT bool Script::Module::SectionListFromAddr(duint addr, ListOf(ModuleSectionInfo) listInfo) +{ + SHARED_ACQUIRE(LockModules); + MODINFO* modInfo = ModInfoFromAddr(addr); + if(!modInfo) + return false; + std::vector scriptSectionList; + scriptSectionList.reserve(modInfo->sections.size()); + for(const auto & section : modInfo->sections) + { + ModuleSectionInfo scriptSection; + scriptSection.addr = section.addr; + scriptSection.size = section.size; + strcpy_s(scriptSection.name, section.name); + scriptSectionList.push_back(scriptSection); + } + return List::CopyData(listInfo, scriptSectionList); +} + +SCRIPT_EXPORT bool Script::Module::SectionListFromName(const char* name, ListOf(ModuleSectionInfo) listInfo) +{ + return Module::SectionListFromAddr(Module::BaseFromName(name), listInfo); +} + +SCRIPT_EXPORT bool Script::Module::GetMainModuleInfo(ModuleInfo* info) +{ + return Module::InfoFromAddr(Module::GetMainModuleBase(), info); +} + +SCRIPT_EXPORT duint Script::Module::GetMainModuleBase() +{ + return dbggetdebuggedbase(); +} + +SCRIPT_EXPORT duint Script::Module::GetMainModuleSize() +{ + return Module::SizeFromAddr(Module::GetMainModuleBase()); +} + +SCRIPT_EXPORT duint Script::Module::GetMainModuleEntry() +{ + return Module::EntryFromAddr(Module::GetMainModuleBase()); +} + +SCRIPT_EXPORT int Script::Module::GetMainModuleSectionCount() +{ + return Module::SectionCountFromAddr(Module::GetMainModuleBase()); +} + +SCRIPT_EXPORT bool Script::Module::GetMainModuleName(char* name) +{ + return Module::NameFromAddr(Module::GetMainModuleBase(), name); +} + +SCRIPT_EXPORT bool Script::Module::GetMainModulePath(char* path) +{ + return Module::PathFromAddr(Module::GetMainModuleBase(), path); +} + +SCRIPT_EXPORT bool Script::Module::GetMainModuleSectionList(ListOf(ModuleSectionInfo) listInfo) +{ + return Module::SectionListFromAddr(Module::GetMainModuleBase(), listInfo); +} + +SCRIPT_EXPORT bool Script::Module::GetList(ListOf(ModuleInfo) listInfo) +{ + std::vector modList; + ModGetList(modList); + std::vector modScriptList; + modScriptList.reserve(modList.size()); + for(const auto & mod : modList) + { + ModuleInfo scriptMod; + scriptMod.base = mod.base; + scriptMod.size = mod.size; + scriptMod.entry = mod.entry; + scriptMod.sectionCount = int(mod.sections.size()); + strcpy_s(scriptMod.name, mod.name); + strcat_s(scriptMod.name, mod.extension); + strcpy_s(scriptMod.path, mod.path); + modScriptList.push_back(scriptMod); + } + return List::CopyData(listInfo, modScriptList); } \ No newline at end of file diff --git a/src/dbg/_scriptapi_module.h b/src/dbg/_scriptapi_module.h index cddc3a92..800344e6 100644 --- a/src/dbg/_scriptapi_module.h +++ b/src/dbg/_scriptapi_module.h @@ -1,56 +1,56 @@ -#ifndef _SCRIPTAPI_MODULE_H -#define _SCRIPTAPI_MODULE_H - -#include "_scriptapi.h" - -namespace Script -{ -namespace Module -{ -struct ModuleInfo -{ - duint base; - duint size; - duint entry; - int sectionCount; - char name[MAX_MODULE_SIZE]; - char path[MAX_PATH]; -}; - -struct ModuleSectionInfo -{ - duint addr; - duint size; - char name[MAX_SECTION_SIZE * 5]; -}; - -SCRIPT_EXPORT bool InfoFromAddr(duint addr, ModuleInfo* info); -SCRIPT_EXPORT bool InfoFromName(const char* name, ModuleInfo* info); -SCRIPT_EXPORT duint BaseFromAddr(duint addr); -SCRIPT_EXPORT duint BaseFromName(const char* name); -SCRIPT_EXPORT duint SizeFromAddr(duint addr); -SCRIPT_EXPORT duint SizeFromName(const char* name); -SCRIPT_EXPORT bool NameFromAddr(duint addr, char* name); //name[MAX_MODULE_SIZE] -SCRIPT_EXPORT bool PathFromAddr(duint addr, char* path); //path[MAX_MODULE_PATH_SIZE] -SCRIPT_EXPORT bool PathFromName(const char* name, char* path); //path[MAX_PATH] -SCRIPT_EXPORT duint EntryFromAddr(duint addr); -SCRIPT_EXPORT duint EntryFromName(const char* name); -SCRIPT_EXPORT int SectionCountFromAddr(duint addr); -SCRIPT_EXPORT int SectionCountFromName(const char* name); -SCRIPT_EXPORT bool SectionFromAddr(duint addr, int number, ModuleSectionInfo* section); -SCRIPT_EXPORT bool SectionFromName(const char* name, int number, ModuleSectionInfo* section); -SCRIPT_EXPORT bool SectionListFromAddr(duint addr, ListOf(ModuleSectionInfo) listInfo); -SCRIPT_EXPORT bool SectionListFromName(const char* name, ListOf(ModuleSectionInfo) listInfo); -SCRIPT_EXPORT bool GetMainModuleInfo(ModuleInfo* info); -SCRIPT_EXPORT duint GetMainModuleBase(); -SCRIPT_EXPORT duint GetMainModuleSize(); -SCRIPT_EXPORT duint GetMainModuleEntry(); -SCRIPT_EXPORT int GetMainModuleSectionCount(); -SCRIPT_EXPORT bool GetMainModuleName(char* name); //name[MAX_MODULE_SIZE] -SCRIPT_EXPORT bool GetMainModulePath(char* path); //path[MAX_PATH] -SCRIPT_EXPORT bool GetMainModuleSectionList(ListOf(ModuleSectionInfo) listInfo); //caller has the responsibility to free the list -SCRIPT_EXPORT bool GetList(ListOf(ModuleInfo) listInfo); //caller has the responsibility to free the list -}; //Module -}; //Script - +#ifndef _SCRIPTAPI_MODULE_H +#define _SCRIPTAPI_MODULE_H + +#include "_scriptapi.h" + +namespace Script +{ +namespace Module +{ +struct ModuleInfo +{ + duint base; + duint size; + duint entry; + int sectionCount; + char name[MAX_MODULE_SIZE]; + char path[MAX_PATH]; +}; + +struct ModuleSectionInfo +{ + duint addr; + duint size; + char name[MAX_SECTION_SIZE * 5]; +}; + +SCRIPT_EXPORT bool InfoFromAddr(duint addr, ModuleInfo* info); +SCRIPT_EXPORT bool InfoFromName(const char* name, ModuleInfo* info); +SCRIPT_EXPORT duint BaseFromAddr(duint addr); +SCRIPT_EXPORT duint BaseFromName(const char* name); +SCRIPT_EXPORT duint SizeFromAddr(duint addr); +SCRIPT_EXPORT duint SizeFromName(const char* name); +SCRIPT_EXPORT bool NameFromAddr(duint addr, char* name); //name[MAX_MODULE_SIZE] +SCRIPT_EXPORT bool PathFromAddr(duint addr, char* path); //path[MAX_MODULE_PATH_SIZE] +SCRIPT_EXPORT bool PathFromName(const char* name, char* path); //path[MAX_PATH] +SCRIPT_EXPORT duint EntryFromAddr(duint addr); +SCRIPT_EXPORT duint EntryFromName(const char* name); +SCRIPT_EXPORT int SectionCountFromAddr(duint addr); +SCRIPT_EXPORT int SectionCountFromName(const char* name); +SCRIPT_EXPORT bool SectionFromAddr(duint addr, int number, ModuleSectionInfo* section); +SCRIPT_EXPORT bool SectionFromName(const char* name, int number, ModuleSectionInfo* section); +SCRIPT_EXPORT bool SectionListFromAddr(duint addr, ListOf(ModuleSectionInfo) listInfo); +SCRIPT_EXPORT bool SectionListFromName(const char* name, ListOf(ModuleSectionInfo) listInfo); +SCRIPT_EXPORT bool GetMainModuleInfo(ModuleInfo* info); +SCRIPT_EXPORT duint GetMainModuleBase(); +SCRIPT_EXPORT duint GetMainModuleSize(); +SCRIPT_EXPORT duint GetMainModuleEntry(); +SCRIPT_EXPORT int GetMainModuleSectionCount(); +SCRIPT_EXPORT bool GetMainModuleName(char* name); //name[MAX_MODULE_SIZE] +SCRIPT_EXPORT bool GetMainModulePath(char* path); //path[MAX_PATH] +SCRIPT_EXPORT bool GetMainModuleSectionList(ListOf(ModuleSectionInfo) listInfo); //caller has the responsibility to free the list +SCRIPT_EXPORT bool GetList(ListOf(ModuleInfo) listInfo); //caller has the responsibility to free the list +}; //Module +}; //Script + #endif //_SCRIPTAPI_MODULE_H \ No newline at end of file diff --git a/src/dbg/_scriptapi_pattern.cpp b/src/dbg/_scriptapi_pattern.cpp index d764aa21..82f479ae 100644 --- a/src/dbg/_scriptapi_pattern.cpp +++ b/src/dbg/_scriptapi_pattern.cpp @@ -1,48 +1,48 @@ -#include "_scriptapi_pattern.h" -#include "patternfind.h" -#include "memory.h" - -SCRIPT_EXPORT duint Script::Pattern::Find(unsigned char* data, duint datasize, const char* pattern) -{ - return patternfind(data, datasize, pattern); -} - -SCRIPT_EXPORT duint Script::Pattern::FindMem(duint start, duint size, const char* pattern) -{ - Memory data(size, "Script::Pattern::FindMem::data"); - if(!MemRead(start, data(), size)) - return -1; - return Pattern::Find(data(), data.size(), pattern) + start; -} - -SCRIPT_EXPORT void Script::Pattern::Write(unsigned char* data, duint datasize, const char* pattern) -{ - patternwrite(data, datasize, pattern); -} - -SCRIPT_EXPORT void Script::Pattern::WriteMem(duint start, duint size, const char* pattern) -{ - Memory data(size, "Script::Pattern::WriteMem::data"); - if(!MemRead(start, data(), data.size())) - return; - patternwrite(data(), data.size(), pattern); - MemWrite(start, data(), data.size()); -} - -SCRIPT_EXPORT bool Script::Pattern::SearchAndReplace(unsigned char* data, duint datasize, const char* searchpattern, const char* replacepattern) -{ - return patternsnr(data, datasize, searchpattern, replacepattern); -} - -SCRIPT_EXPORT bool Script::Pattern::SearchAndReplaceMem(duint start, duint size, const char* searchpattern, const char* replacepattern) -{ - Memory data(size, "Script::Pattern::SearchAndReplaceMem::data"); - if(!MemRead(start, data(), size)) - return false; - duint found = patternfind(data(), data.size(), searchpattern); - if(found == -1) - return false; - patternwrite(data() + found, data.size() - found, replacepattern); - MemWrite((start + found), data() + found, data.size() - found); - return true; +#include "_scriptapi_pattern.h" +#include "patternfind.h" +#include "memory.h" + +SCRIPT_EXPORT duint Script::Pattern::Find(unsigned char* data, duint datasize, const char* pattern) +{ + return patternfind(data, datasize, pattern); +} + +SCRIPT_EXPORT duint Script::Pattern::FindMem(duint start, duint size, const char* pattern) +{ + Memory data(size, "Script::Pattern::FindMem::data"); + if(!MemRead(start, data(), size)) + return -1; + return Pattern::Find(data(), data.size(), pattern) + start; +} + +SCRIPT_EXPORT void Script::Pattern::Write(unsigned char* data, duint datasize, const char* pattern) +{ + patternwrite(data, datasize, pattern); +} + +SCRIPT_EXPORT void Script::Pattern::WriteMem(duint start, duint size, const char* pattern) +{ + Memory data(size, "Script::Pattern::WriteMem::data"); + if(!MemRead(start, data(), data.size())) + return; + patternwrite(data(), data.size(), pattern); + MemWrite(start, data(), data.size()); +} + +SCRIPT_EXPORT bool Script::Pattern::SearchAndReplace(unsigned char* data, duint datasize, const char* searchpattern, const char* replacepattern) +{ + return patternsnr(data, datasize, searchpattern, replacepattern); +} + +SCRIPT_EXPORT bool Script::Pattern::SearchAndReplaceMem(duint start, duint size, const char* searchpattern, const char* replacepattern) +{ + Memory data(size, "Script::Pattern::SearchAndReplaceMem::data"); + if(!MemRead(start, data(), size)) + return false; + duint found = patternfind(data(), data.size(), searchpattern); + if(found == -1) + return false; + patternwrite(data() + found, data.size() - found, replacepattern); + MemWrite((start + found), data() + found, data.size() - found); + return true; } \ No newline at end of file diff --git a/src/dbg/_scriptapi_pattern.h b/src/dbg/_scriptapi_pattern.h index 79b56700..b8af7dfd 100644 --- a/src/dbg/_scriptapi_pattern.h +++ b/src/dbg/_scriptapi_pattern.h @@ -1,19 +1,19 @@ -#ifndef _SCRIPTAPI_PATTERN_H -#define _SCRIPTAPI_PATTERN_H - -#include "_scriptapi.h" - -namespace Script -{ -namespace Pattern -{ -SCRIPT_EXPORT duint Find(unsigned char* data, duint datasize, const char* pattern); -SCRIPT_EXPORT duint FindMem(duint start, duint size, const char* pattern); -SCRIPT_EXPORT void Write(unsigned char* data, duint datasize, const char* pattern); -SCRIPT_EXPORT void WriteMem(duint start, duint size, const char* pattern); -SCRIPT_EXPORT bool SearchAndReplace(unsigned char* data, duint datasize, const char* searchpattern, const char* replacepattern); -SCRIPT_EXPORT bool SearchAndReplaceMem(duint start, duint size, const char* searchpattern, const char* replacepattern); -}; -}; - +#ifndef _SCRIPTAPI_PATTERN_H +#define _SCRIPTAPI_PATTERN_H + +#include "_scriptapi.h" + +namespace Script +{ +namespace Pattern +{ +SCRIPT_EXPORT duint Find(unsigned char* data, duint datasize, const char* pattern); +SCRIPT_EXPORT duint FindMem(duint start, duint size, const char* pattern); +SCRIPT_EXPORT void Write(unsigned char* data, duint datasize, const char* pattern); +SCRIPT_EXPORT void WriteMem(duint start, duint size, const char* pattern); +SCRIPT_EXPORT bool SearchAndReplace(unsigned char* data, duint datasize, const char* searchpattern, const char* replacepattern); +SCRIPT_EXPORT bool SearchAndReplaceMem(duint start, duint size, const char* searchpattern, const char* replacepattern); +}; +}; + #endif //_SCRIPTAPI_FIND_H \ No newline at end of file diff --git a/src/dbg/_scriptapi_register.cpp b/src/dbg/_scriptapi_register.cpp index ed7caf9b..0c620ea8 100644 --- a/src/dbg/_scriptapi_register.cpp +++ b/src/dbg/_scriptapi_register.cpp @@ -1,892 +1,892 @@ -#include "_scriptapi_register.h" -#include "value.h" - -static const char* regTable[] = -{ - "DR0", - "DR1", - "DR2", - "DR3", - "DR6", - "DR7", - - "EAX", - "AX", - "AH", - "AL", - "EBX", - "BX", - "BH", - "BL", - "ECX", - "CX", - "CH", - "CL", - "EDX", - "DX", - "DH", - "DL", - "EDI", - "DI", - "ESI", - "SI", - "EBP", - "BP", - "ESP", - "SP", - "EIP", - -#ifdef _WIN64 - "RAX", - "RBX", - "RCX", - "RDX", - "RSI", - "SIL", - "RDI", - "DIL", - "RBP", - "BPL", - "RSP", - "SPL", - "RIP", - "R8", - "R8D", - "R8W", - "R8B", - "R9", - "R9D", - "R9W", - "R9B", - "R10", - "R10D", - "R10W", - "R10B", - "R11", - "R11D", - "R11W", - "R11B", - "R12", - "R12D", - "R12W", - "R12B", - "R13", - "R13D", - "R13W", - "R13B", - "R14", - "R14D", - "R14W", - "R14B", - "R15", - "R15D", - "R15W", - "R15", -#endif //_WIN64 - -#ifdef _WIN64 - "RIP", - "RSP" -#else //x32 - "EIP", - "ESP" -#endif //_WIN64 -}; - -SCRIPT_EXPORT duint Script::Register::Get(Script::Register::RegisterEnum reg) -{ - duint value; - return valfromstring(regTable[reg], &value) ? value : 0; -} - -SCRIPT_EXPORT bool Script::Register::Set(Script::Register::RegisterEnum reg, duint value) -{ - return setregister(regTable[reg], value); -} - -SCRIPT_EXPORT int Script::Register::Size() -{ - return (int)sizeof(duint); -} - -SCRIPT_EXPORT duint Script::Register::GetDR0() -{ - return Get(DR0); -} - -SCRIPT_EXPORT bool Script::Register::SetDR0(duint value) -{ - return Set(DR0, value); -} - -SCRIPT_EXPORT duint Script::Register::GetDR1() -{ - return Get(DR1); -} - -SCRIPT_EXPORT bool Script::Register::SetDR1(duint value) -{ - return Set(DR1, value); -} - -SCRIPT_EXPORT duint Script::Register::GetDR2() -{ - return Get(DR2); -} - -SCRIPT_EXPORT bool Script::Register::SetDR2(duint value) -{ - return Set(DR2, value); -} - -SCRIPT_EXPORT duint Script::Register::GetDR3() -{ - return Get(DR3); -} - -SCRIPT_EXPORT bool Script::Register::SetDR3(duint value) -{ - return Set(DR3, value); -} - -SCRIPT_EXPORT duint Script::Register::GetDR6() -{ - return Get(DR6); -} - -SCRIPT_EXPORT bool Script::Register::SetDR6(duint value) -{ - return Set(DR6, value); -} - -SCRIPT_EXPORT duint Script::Register::GetDR7() -{ - return Get(DR7); -} - -SCRIPT_EXPORT bool Script::Register::SetDR7(duint value) -{ - return Set(DR7, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetEAX() -{ - return (unsigned int)Get(EAX); -} - -SCRIPT_EXPORT bool Script::Register::SetEAX(unsigned int value) -{ - return Set(EAX, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetAX() -{ - return (unsigned short)Get(AX); -} - -SCRIPT_EXPORT bool Script::Register::SetAX(unsigned short value) -{ - return Set(AX, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetAH() -{ - return (unsigned char)Get(AH); -} - -SCRIPT_EXPORT bool Script::Register::SetAH(unsigned char value) -{ - return Set(AH, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetAL() -{ - return (unsigned char)Get(AL); -} - -SCRIPT_EXPORT bool Script::Register::SetAL(unsigned char value) -{ - return Set(AL, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetEBX() -{ - return (unsigned int)Get(EBX); -} - -SCRIPT_EXPORT bool Script::Register::SetEBX(unsigned int value) -{ - return Set(EBX, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetBX() -{ - return (unsigned short)Get(BX); -} - -SCRIPT_EXPORT bool Script::Register::SetBX(unsigned short value) -{ - return Set(BX, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetBH() -{ - return (unsigned char)Get(BH); -} - -SCRIPT_EXPORT bool Script::Register::SetBH(unsigned char value) -{ - return Set(BH, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetBL() -{ - return (unsigned char)Get(BL); -} - -SCRIPT_EXPORT bool Script::Register::SetBL(unsigned char value) -{ - return Set(BL, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetECX() -{ - return (unsigned int)Get(ECX); -} - -SCRIPT_EXPORT bool Script::Register::SetECX(unsigned int value) -{ - return Set(ECX, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetCX() -{ - return (unsigned short)Get(CX); -} - -SCRIPT_EXPORT bool Script::Register::SetCX(unsigned short value) -{ - return Set(CX, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetCH() -{ - return (unsigned char)Get(CH); -} - -SCRIPT_EXPORT bool Script::Register::SetCH(unsigned char value) -{ - return Set(CH, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetCL() -{ - return (unsigned char)Get(CL); -} - -SCRIPT_EXPORT bool Script::Register::SetCL(unsigned char value) -{ - return Set(CL, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetEDX() -{ - return (unsigned int)Get(EDX); -} - -SCRIPT_EXPORT bool Script::Register::SetEDX(unsigned int value) -{ - return Set(EDX, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetDX() -{ - return (unsigned short)Get(DX); -} - -SCRIPT_EXPORT bool Script::Register::SetDX(unsigned short value) -{ - return Set(DX, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetDH() -{ - return (unsigned char)Get(DH); -} - -SCRIPT_EXPORT bool Script::Register::SetDH(unsigned char value) -{ - return Set(DH, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetDL() -{ - return (unsigned char)Get(DL); -} - -SCRIPT_EXPORT bool Script::Register::SetDL(unsigned char value) -{ - return Set(DL, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetEDI() -{ - return (unsigned int)Get(EDI); -} - -SCRIPT_EXPORT bool Script::Register::SetEDI(unsigned int value) -{ - return Set(EDI, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetDI() -{ - return (unsigned short)Get(DI); -} - -SCRIPT_EXPORT bool Script::Register::SetDI(unsigned short value) -{ - return Set(DI, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetESI() -{ - return (unsigned int)Get(ESI); -} - -SCRIPT_EXPORT bool Script::Register::SetESI(unsigned int value) -{ - return Set(ESI, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetSI() -{ - return (unsigned short)Get(SI); -} - -SCRIPT_EXPORT bool Script::Register::SetSI(unsigned short value) -{ - return Set(SI, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetEBP() -{ - return (unsigned int)Get(EBP); -} - -SCRIPT_EXPORT bool Script::Register::SetEBP(unsigned int value) -{ - return Set(EBP, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetBP() -{ - return (unsigned short)Get(BP); -} - -SCRIPT_EXPORT bool Script::Register::SetBP(unsigned short value) -{ - return Set(BP, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetESP() -{ - return (unsigned int)Get(ESP); -} - -SCRIPT_EXPORT bool Script::Register::SetESP(unsigned int value) -{ - return Set(ESP, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetSP() -{ - return (unsigned short)Get(SP); -} - -SCRIPT_EXPORT bool Script::Register::SetSP(unsigned short value) -{ - return Set(SP, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetEIP() -{ - return (unsigned int)Get(EIP); -} - -SCRIPT_EXPORT bool Script::Register::SetEIP(unsigned int value) -{ - return Set(EIP, value); -} - -#ifdef _WIN64 -SCRIPT_EXPORT unsigned long long Script::Register::GetRAX() -{ - return (unsigned long long)Get(RAX); -} - -SCRIPT_EXPORT bool Script::Register::SetRAX(unsigned long long value) -{ - return Set(RAX, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetRBX() -{ - return (unsigned long long)Get(RBX); -} - -SCRIPT_EXPORT bool Script::Register::SetRBX(unsigned long long value) -{ - return Set(RBX, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetRCX() -{ - return (unsigned long long)Get(RCX); -} - -SCRIPT_EXPORT bool Script::Register::SetRCX(unsigned long long value) -{ - return Set(RCX, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetRDX() -{ - return (unsigned long long)Get(RDX); -} - -SCRIPT_EXPORT bool Script::Register::SetRDX(unsigned long long value) -{ - return Set(RDX, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetRSI() -{ - return (unsigned long long)Get(RSI); -} - -SCRIPT_EXPORT bool Script::Register::SetRSI(unsigned long long value) -{ - return Set(RSI, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetSIL() -{ - return (unsigned char)Get(SIL); -} - -SCRIPT_EXPORT bool Script::Register::SetSIL(unsigned char value) -{ - return Set(SIL, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetRDI() -{ - return (unsigned long long)Get(RDI); -} - -SCRIPT_EXPORT bool Script::Register::SetRDI(unsigned long long value) -{ - return Set(RDI, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetDIL() -{ - return (unsigned char)Get(DIL); -} - -SCRIPT_EXPORT bool Script::Register::SetDIL(unsigned char value) -{ - return Set(DIL, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetRBP() -{ - return (unsigned long long)Get(RBP); -} - -SCRIPT_EXPORT bool Script::Register::SetRBP(unsigned long long value) -{ - return Set(RBP, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetBPL() -{ - return (unsigned char)Get(BPL); -} - -SCRIPT_EXPORT bool Script::Register::SetBPL(unsigned char value) -{ - return Set(BPL, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetRSP() -{ - return (unsigned long long)Get(RSP); -} - -SCRIPT_EXPORT bool Script::Register::SetRSP(unsigned long long value) -{ - return Set(RSP, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetSPL() -{ - return (unsigned char)Get(SPL); -} - -SCRIPT_EXPORT bool Script::Register::SetSPL(unsigned char value) -{ - return Set(SPL, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetRIP() -{ - return (unsigned long long)Get(RIP); -} - -SCRIPT_EXPORT bool Script::Register::SetRIP(unsigned long long value) -{ - return Set(RIP, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetR8() -{ - return (unsigned long long)Get(R8); -} - -SCRIPT_EXPORT bool Script::Register::SetR8(unsigned long long value) -{ - return Set(R8, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetR8D() -{ - return (unsigned int)Get(R8D); -} - -SCRIPT_EXPORT bool Script::Register::SetR8D(unsigned int value) -{ - return Set(R8D, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetR8W() -{ - return (unsigned short)Get(R8W); -} - -SCRIPT_EXPORT bool Script::Register::SetR8W(unsigned short value) -{ - return Set(R8W, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetR8B() -{ - return (unsigned char)Get(R8B); -} - -SCRIPT_EXPORT bool Script::Register::SetR8B(unsigned char value) -{ - return Set(R8B, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetR9() -{ - return (unsigned long long)Get(R9); -} - -SCRIPT_EXPORT bool Script::Register::SetR9(unsigned long long value) -{ - return Set(R9, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetR9D() -{ - return (unsigned int)Get(R9D); -} - -SCRIPT_EXPORT bool Script::Register::SetR9D(unsigned int value) -{ - return Set(R9D, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetR9W() -{ - return (unsigned short)Get(R9W); -} - -SCRIPT_EXPORT bool Script::Register::SetR9W(unsigned short value) -{ - return Set(R9W, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetR9B() -{ - return (unsigned char)Get(R9B); -} - -SCRIPT_EXPORT bool Script::Register::SetR9B(unsigned char value) -{ - return Set(R9B, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetR10() -{ - return (unsigned long long)Get(R10); -} - -SCRIPT_EXPORT bool Script::Register::SetR10(unsigned long long value) -{ - return Set(R10, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetR10D() -{ - return (unsigned int)Get(R10D); -} - -SCRIPT_EXPORT bool Script::Register::SetR10D(unsigned int value) -{ - return Set(R10D, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetR10W() -{ - return (unsigned short)Get(R10W); -} - -SCRIPT_EXPORT bool Script::Register::SetR10W(unsigned short value) -{ - return Set(R10W, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetR10B() -{ - return (unsigned char)Get(R10B); -} - -SCRIPT_EXPORT bool Script::Register::SetR10B(unsigned char value) -{ - return Set(R10B, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetR11() -{ - return (unsigned long long)Get(R11); -} - -SCRIPT_EXPORT bool Script::Register::SetR11(unsigned long long value) -{ - return Set(R11, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetR11D() -{ - return (unsigned int)Get(R11D); -} - -SCRIPT_EXPORT bool Script::Register::SetR11D(unsigned int value) -{ - return Set(R11D, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetR11W() -{ - return (unsigned short)Get(R11W); -} - -SCRIPT_EXPORT bool Script::Register::SetR11W(unsigned short value) -{ - return Set(R11W, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetR11B() -{ - return (unsigned char)Get(R11B); -} - -SCRIPT_EXPORT bool Script::Register::SetR11B(unsigned char value) -{ - return Set(R11B, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetR12() -{ - return (unsigned long long)Get(R12); -} - -SCRIPT_EXPORT bool Script::Register::SetR12(unsigned long long value) -{ - return Set(R12, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetR12D() -{ - return (unsigned int)Get(R12D); -} - -SCRIPT_EXPORT bool Script::Register::SetR12D(unsigned int value) -{ - return Set(R12D, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetR12W() -{ - return (unsigned short)Get(R12W); -} - -SCRIPT_EXPORT bool Script::Register::SetR12W(unsigned short value) -{ - return Set(R12W, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetR12B() -{ - return (unsigned char)Get(R12B); -} - -SCRIPT_EXPORT bool Script::Register::SetR12B(unsigned char value) -{ - return Set(R12B, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetR13() -{ - return (unsigned long long)Get(R13); -} - -SCRIPT_EXPORT bool Script::Register::SetR13(unsigned long long value) -{ - return Set(R13, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetR13D() -{ - return (unsigned int)Get(R13D); -} - -SCRIPT_EXPORT bool Script::Register::SetR13D(unsigned int value) -{ - return Set(R13D, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetR13W() -{ - return (unsigned short)Get(R13W); -} - -SCRIPT_EXPORT bool Script::Register::SetR13W(unsigned short value) -{ - return Set(R13W, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetR13B() -{ - return (unsigned char)Get(R13B); -} - -SCRIPT_EXPORT bool Script::Register::SetR13B(unsigned char value) -{ - return Set(R13B, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetR14() -{ - return (unsigned long long)Get(R14); -} - -SCRIPT_EXPORT bool Script::Register::SetR14(unsigned long long value) -{ - return Set(R14, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetR14D() -{ - return (unsigned int)Get(R14D); -} - -SCRIPT_EXPORT bool Script::Register::SetR14D(unsigned int value) -{ - return Set(R14D, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetR14W() -{ - return (unsigned short)Get(R14W); -} - -SCRIPT_EXPORT bool Script::Register::SetR14W(unsigned short value) -{ - return Set(R14W, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetR14B() -{ - return (unsigned char)Get(R14B); -} - -SCRIPT_EXPORT bool Script::Register::SetR14B(unsigned char value) -{ - return Set(R14B, value); -} - -SCRIPT_EXPORT unsigned long long Script::Register::GetR15() -{ - return (unsigned long long)Get(R15); -} - -SCRIPT_EXPORT bool Script::Register::SetR15(unsigned long long value) -{ - return Set(R15, value); -} - -SCRIPT_EXPORT unsigned int Script::Register::GetR15D() -{ - return (unsigned int)Get(R15D); -} - -SCRIPT_EXPORT bool Script::Register::SetR15D(unsigned int value) -{ - return Set(R15D, value); -} - -SCRIPT_EXPORT unsigned short Script::Register::GetR15W() -{ - return (unsigned short)Get(R15W); -} - -SCRIPT_EXPORT bool Script::Register::SetR15W(unsigned short value) -{ - return Set(R15W, value); -} - -SCRIPT_EXPORT unsigned char Script::Register::GetR15B() -{ - return (unsigned char)Get(R15B); -} - -SCRIPT_EXPORT bool Script::Register::SetR15B(unsigned char value) -{ - return Set(R15B, value); -} -#endif //_WIN64 - -SCRIPT_EXPORT duint Script::Register::GetCIP() -{ - return Get(CIP); -} - -SCRIPT_EXPORT bool Script::Register::SetCIP(duint value) -{ - return Set(CIP, value); -} - -SCRIPT_EXPORT duint Script::Register::GetCSP() -{ - return Get(CSP); -} - -SCRIPT_EXPORT bool Script::Register::SetCSP(duint value) -{ - return Set(CSP, value); +#include "_scriptapi_register.h" +#include "value.h" + +static const char* regTable[] = +{ + "DR0", + "DR1", + "DR2", + "DR3", + "DR6", + "DR7", + + "EAX", + "AX", + "AH", + "AL", + "EBX", + "BX", + "BH", + "BL", + "ECX", + "CX", + "CH", + "CL", + "EDX", + "DX", + "DH", + "DL", + "EDI", + "DI", + "ESI", + "SI", + "EBP", + "BP", + "ESP", + "SP", + "EIP", + +#ifdef _WIN64 + "RAX", + "RBX", + "RCX", + "RDX", + "RSI", + "SIL", + "RDI", + "DIL", + "RBP", + "BPL", + "RSP", + "SPL", + "RIP", + "R8", + "R8D", + "R8W", + "R8B", + "R9", + "R9D", + "R9W", + "R9B", + "R10", + "R10D", + "R10W", + "R10B", + "R11", + "R11D", + "R11W", + "R11B", + "R12", + "R12D", + "R12W", + "R12B", + "R13", + "R13D", + "R13W", + "R13B", + "R14", + "R14D", + "R14W", + "R14B", + "R15", + "R15D", + "R15W", + "R15", +#endif //_WIN64 + +#ifdef _WIN64 + "RIP", + "RSP" +#else //x32 + "EIP", + "ESP" +#endif //_WIN64 +}; + +SCRIPT_EXPORT duint Script::Register::Get(Script::Register::RegisterEnum reg) +{ + duint value; + return valfromstring(regTable[reg], &value) ? value : 0; +} + +SCRIPT_EXPORT bool Script::Register::Set(Script::Register::RegisterEnum reg, duint value) +{ + return setregister(regTable[reg], value); +} + +SCRIPT_EXPORT int Script::Register::Size() +{ + return (int)sizeof(duint); +} + +SCRIPT_EXPORT duint Script::Register::GetDR0() +{ + return Get(DR0); +} + +SCRIPT_EXPORT bool Script::Register::SetDR0(duint value) +{ + return Set(DR0, value); +} + +SCRIPT_EXPORT duint Script::Register::GetDR1() +{ + return Get(DR1); +} + +SCRIPT_EXPORT bool Script::Register::SetDR1(duint value) +{ + return Set(DR1, value); +} + +SCRIPT_EXPORT duint Script::Register::GetDR2() +{ + return Get(DR2); +} + +SCRIPT_EXPORT bool Script::Register::SetDR2(duint value) +{ + return Set(DR2, value); +} + +SCRIPT_EXPORT duint Script::Register::GetDR3() +{ + return Get(DR3); +} + +SCRIPT_EXPORT bool Script::Register::SetDR3(duint value) +{ + return Set(DR3, value); +} + +SCRIPT_EXPORT duint Script::Register::GetDR6() +{ + return Get(DR6); +} + +SCRIPT_EXPORT bool Script::Register::SetDR6(duint value) +{ + return Set(DR6, value); +} + +SCRIPT_EXPORT duint Script::Register::GetDR7() +{ + return Get(DR7); +} + +SCRIPT_EXPORT bool Script::Register::SetDR7(duint value) +{ + return Set(DR7, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetEAX() +{ + return (unsigned int)Get(EAX); +} + +SCRIPT_EXPORT bool Script::Register::SetEAX(unsigned int value) +{ + return Set(EAX, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetAX() +{ + return (unsigned short)Get(AX); +} + +SCRIPT_EXPORT bool Script::Register::SetAX(unsigned short value) +{ + return Set(AX, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetAH() +{ + return (unsigned char)Get(AH); +} + +SCRIPT_EXPORT bool Script::Register::SetAH(unsigned char value) +{ + return Set(AH, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetAL() +{ + return (unsigned char)Get(AL); +} + +SCRIPT_EXPORT bool Script::Register::SetAL(unsigned char value) +{ + return Set(AL, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetEBX() +{ + return (unsigned int)Get(EBX); +} + +SCRIPT_EXPORT bool Script::Register::SetEBX(unsigned int value) +{ + return Set(EBX, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetBX() +{ + return (unsigned short)Get(BX); +} + +SCRIPT_EXPORT bool Script::Register::SetBX(unsigned short value) +{ + return Set(BX, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetBH() +{ + return (unsigned char)Get(BH); +} + +SCRIPT_EXPORT bool Script::Register::SetBH(unsigned char value) +{ + return Set(BH, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetBL() +{ + return (unsigned char)Get(BL); +} + +SCRIPT_EXPORT bool Script::Register::SetBL(unsigned char value) +{ + return Set(BL, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetECX() +{ + return (unsigned int)Get(ECX); +} + +SCRIPT_EXPORT bool Script::Register::SetECX(unsigned int value) +{ + return Set(ECX, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetCX() +{ + return (unsigned short)Get(CX); +} + +SCRIPT_EXPORT bool Script::Register::SetCX(unsigned short value) +{ + return Set(CX, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetCH() +{ + return (unsigned char)Get(CH); +} + +SCRIPT_EXPORT bool Script::Register::SetCH(unsigned char value) +{ + return Set(CH, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetCL() +{ + return (unsigned char)Get(CL); +} + +SCRIPT_EXPORT bool Script::Register::SetCL(unsigned char value) +{ + return Set(CL, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetEDX() +{ + return (unsigned int)Get(EDX); +} + +SCRIPT_EXPORT bool Script::Register::SetEDX(unsigned int value) +{ + return Set(EDX, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetDX() +{ + return (unsigned short)Get(DX); +} + +SCRIPT_EXPORT bool Script::Register::SetDX(unsigned short value) +{ + return Set(DX, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetDH() +{ + return (unsigned char)Get(DH); +} + +SCRIPT_EXPORT bool Script::Register::SetDH(unsigned char value) +{ + return Set(DH, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetDL() +{ + return (unsigned char)Get(DL); +} + +SCRIPT_EXPORT bool Script::Register::SetDL(unsigned char value) +{ + return Set(DL, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetEDI() +{ + return (unsigned int)Get(EDI); +} + +SCRIPT_EXPORT bool Script::Register::SetEDI(unsigned int value) +{ + return Set(EDI, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetDI() +{ + return (unsigned short)Get(DI); +} + +SCRIPT_EXPORT bool Script::Register::SetDI(unsigned short value) +{ + return Set(DI, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetESI() +{ + return (unsigned int)Get(ESI); +} + +SCRIPT_EXPORT bool Script::Register::SetESI(unsigned int value) +{ + return Set(ESI, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetSI() +{ + return (unsigned short)Get(SI); +} + +SCRIPT_EXPORT bool Script::Register::SetSI(unsigned short value) +{ + return Set(SI, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetEBP() +{ + return (unsigned int)Get(EBP); +} + +SCRIPT_EXPORT bool Script::Register::SetEBP(unsigned int value) +{ + return Set(EBP, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetBP() +{ + return (unsigned short)Get(BP); +} + +SCRIPT_EXPORT bool Script::Register::SetBP(unsigned short value) +{ + return Set(BP, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetESP() +{ + return (unsigned int)Get(ESP); +} + +SCRIPT_EXPORT bool Script::Register::SetESP(unsigned int value) +{ + return Set(ESP, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetSP() +{ + return (unsigned short)Get(SP); +} + +SCRIPT_EXPORT bool Script::Register::SetSP(unsigned short value) +{ + return Set(SP, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetEIP() +{ + return (unsigned int)Get(EIP); +} + +SCRIPT_EXPORT bool Script::Register::SetEIP(unsigned int value) +{ + return Set(EIP, value); +} + +#ifdef _WIN64 +SCRIPT_EXPORT unsigned long long Script::Register::GetRAX() +{ + return (unsigned long long)Get(RAX); +} + +SCRIPT_EXPORT bool Script::Register::SetRAX(unsigned long long value) +{ + return Set(RAX, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetRBX() +{ + return (unsigned long long)Get(RBX); +} + +SCRIPT_EXPORT bool Script::Register::SetRBX(unsigned long long value) +{ + return Set(RBX, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetRCX() +{ + return (unsigned long long)Get(RCX); +} + +SCRIPT_EXPORT bool Script::Register::SetRCX(unsigned long long value) +{ + return Set(RCX, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetRDX() +{ + return (unsigned long long)Get(RDX); +} + +SCRIPT_EXPORT bool Script::Register::SetRDX(unsigned long long value) +{ + return Set(RDX, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetRSI() +{ + return (unsigned long long)Get(RSI); +} + +SCRIPT_EXPORT bool Script::Register::SetRSI(unsigned long long value) +{ + return Set(RSI, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetSIL() +{ + return (unsigned char)Get(SIL); +} + +SCRIPT_EXPORT bool Script::Register::SetSIL(unsigned char value) +{ + return Set(SIL, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetRDI() +{ + return (unsigned long long)Get(RDI); +} + +SCRIPT_EXPORT bool Script::Register::SetRDI(unsigned long long value) +{ + return Set(RDI, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetDIL() +{ + return (unsigned char)Get(DIL); +} + +SCRIPT_EXPORT bool Script::Register::SetDIL(unsigned char value) +{ + return Set(DIL, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetRBP() +{ + return (unsigned long long)Get(RBP); +} + +SCRIPT_EXPORT bool Script::Register::SetRBP(unsigned long long value) +{ + return Set(RBP, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetBPL() +{ + return (unsigned char)Get(BPL); +} + +SCRIPT_EXPORT bool Script::Register::SetBPL(unsigned char value) +{ + return Set(BPL, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetRSP() +{ + return (unsigned long long)Get(RSP); +} + +SCRIPT_EXPORT bool Script::Register::SetRSP(unsigned long long value) +{ + return Set(RSP, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetSPL() +{ + return (unsigned char)Get(SPL); +} + +SCRIPT_EXPORT bool Script::Register::SetSPL(unsigned char value) +{ + return Set(SPL, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetRIP() +{ + return (unsigned long long)Get(RIP); +} + +SCRIPT_EXPORT bool Script::Register::SetRIP(unsigned long long value) +{ + return Set(RIP, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetR8() +{ + return (unsigned long long)Get(R8); +} + +SCRIPT_EXPORT bool Script::Register::SetR8(unsigned long long value) +{ + return Set(R8, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetR8D() +{ + return (unsigned int)Get(R8D); +} + +SCRIPT_EXPORT bool Script::Register::SetR8D(unsigned int value) +{ + return Set(R8D, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetR8W() +{ + return (unsigned short)Get(R8W); +} + +SCRIPT_EXPORT bool Script::Register::SetR8W(unsigned short value) +{ + return Set(R8W, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetR8B() +{ + return (unsigned char)Get(R8B); +} + +SCRIPT_EXPORT bool Script::Register::SetR8B(unsigned char value) +{ + return Set(R8B, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetR9() +{ + return (unsigned long long)Get(R9); +} + +SCRIPT_EXPORT bool Script::Register::SetR9(unsigned long long value) +{ + return Set(R9, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetR9D() +{ + return (unsigned int)Get(R9D); +} + +SCRIPT_EXPORT bool Script::Register::SetR9D(unsigned int value) +{ + return Set(R9D, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetR9W() +{ + return (unsigned short)Get(R9W); +} + +SCRIPT_EXPORT bool Script::Register::SetR9W(unsigned short value) +{ + return Set(R9W, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetR9B() +{ + return (unsigned char)Get(R9B); +} + +SCRIPT_EXPORT bool Script::Register::SetR9B(unsigned char value) +{ + return Set(R9B, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetR10() +{ + return (unsigned long long)Get(R10); +} + +SCRIPT_EXPORT bool Script::Register::SetR10(unsigned long long value) +{ + return Set(R10, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetR10D() +{ + return (unsigned int)Get(R10D); +} + +SCRIPT_EXPORT bool Script::Register::SetR10D(unsigned int value) +{ + return Set(R10D, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetR10W() +{ + return (unsigned short)Get(R10W); +} + +SCRIPT_EXPORT bool Script::Register::SetR10W(unsigned short value) +{ + return Set(R10W, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetR10B() +{ + return (unsigned char)Get(R10B); +} + +SCRIPT_EXPORT bool Script::Register::SetR10B(unsigned char value) +{ + return Set(R10B, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetR11() +{ + return (unsigned long long)Get(R11); +} + +SCRIPT_EXPORT bool Script::Register::SetR11(unsigned long long value) +{ + return Set(R11, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetR11D() +{ + return (unsigned int)Get(R11D); +} + +SCRIPT_EXPORT bool Script::Register::SetR11D(unsigned int value) +{ + return Set(R11D, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetR11W() +{ + return (unsigned short)Get(R11W); +} + +SCRIPT_EXPORT bool Script::Register::SetR11W(unsigned short value) +{ + return Set(R11W, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetR11B() +{ + return (unsigned char)Get(R11B); +} + +SCRIPT_EXPORT bool Script::Register::SetR11B(unsigned char value) +{ + return Set(R11B, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetR12() +{ + return (unsigned long long)Get(R12); +} + +SCRIPT_EXPORT bool Script::Register::SetR12(unsigned long long value) +{ + return Set(R12, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetR12D() +{ + return (unsigned int)Get(R12D); +} + +SCRIPT_EXPORT bool Script::Register::SetR12D(unsigned int value) +{ + return Set(R12D, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetR12W() +{ + return (unsigned short)Get(R12W); +} + +SCRIPT_EXPORT bool Script::Register::SetR12W(unsigned short value) +{ + return Set(R12W, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetR12B() +{ + return (unsigned char)Get(R12B); +} + +SCRIPT_EXPORT bool Script::Register::SetR12B(unsigned char value) +{ + return Set(R12B, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetR13() +{ + return (unsigned long long)Get(R13); +} + +SCRIPT_EXPORT bool Script::Register::SetR13(unsigned long long value) +{ + return Set(R13, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetR13D() +{ + return (unsigned int)Get(R13D); +} + +SCRIPT_EXPORT bool Script::Register::SetR13D(unsigned int value) +{ + return Set(R13D, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetR13W() +{ + return (unsigned short)Get(R13W); +} + +SCRIPT_EXPORT bool Script::Register::SetR13W(unsigned short value) +{ + return Set(R13W, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetR13B() +{ + return (unsigned char)Get(R13B); +} + +SCRIPT_EXPORT bool Script::Register::SetR13B(unsigned char value) +{ + return Set(R13B, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetR14() +{ + return (unsigned long long)Get(R14); +} + +SCRIPT_EXPORT bool Script::Register::SetR14(unsigned long long value) +{ + return Set(R14, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetR14D() +{ + return (unsigned int)Get(R14D); +} + +SCRIPT_EXPORT bool Script::Register::SetR14D(unsigned int value) +{ + return Set(R14D, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetR14W() +{ + return (unsigned short)Get(R14W); +} + +SCRIPT_EXPORT bool Script::Register::SetR14W(unsigned short value) +{ + return Set(R14W, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetR14B() +{ + return (unsigned char)Get(R14B); +} + +SCRIPT_EXPORT bool Script::Register::SetR14B(unsigned char value) +{ + return Set(R14B, value); +} + +SCRIPT_EXPORT unsigned long long Script::Register::GetR15() +{ + return (unsigned long long)Get(R15); +} + +SCRIPT_EXPORT bool Script::Register::SetR15(unsigned long long value) +{ + return Set(R15, value); +} + +SCRIPT_EXPORT unsigned int Script::Register::GetR15D() +{ + return (unsigned int)Get(R15D); +} + +SCRIPT_EXPORT bool Script::Register::SetR15D(unsigned int value) +{ + return Set(R15D, value); +} + +SCRIPT_EXPORT unsigned short Script::Register::GetR15W() +{ + return (unsigned short)Get(R15W); +} + +SCRIPT_EXPORT bool Script::Register::SetR15W(unsigned short value) +{ + return Set(R15W, value); +} + +SCRIPT_EXPORT unsigned char Script::Register::GetR15B() +{ + return (unsigned char)Get(R15B); +} + +SCRIPT_EXPORT bool Script::Register::SetR15B(unsigned char value) +{ + return Set(R15B, value); +} +#endif //_WIN64 + +SCRIPT_EXPORT duint Script::Register::GetCIP() +{ + return Get(CIP); +} + +SCRIPT_EXPORT bool Script::Register::SetCIP(duint value) +{ + return Set(CIP, value); +} + +SCRIPT_EXPORT duint Script::Register::GetCSP() +{ + return Get(CSP); +} + +SCRIPT_EXPORT bool Script::Register::SetCSP(duint value) +{ + return Set(CSP, value); } \ No newline at end of file diff --git a/src/dbg/_scriptapi_register.h b/src/dbg/_scriptapi_register.h index e7fac174..657b24b0 100644 --- a/src/dbg/_scriptapi_register.h +++ b/src/dbg/_scriptapi_register.h @@ -1,265 +1,265 @@ -#ifndef _SCRIPTAPI_REGISTER_H -#define _SCRIPTAPI_REGISTER_H - -#include "_scriptapi.h" - -namespace Script -{ -namespace Register -{ -enum RegisterEnum -{ - DR0, - DR1, - DR2, - DR3, - DR6, - DR7, - - EAX, - AX, - AH, - AL, - EBX, - BX, - BH, - BL, - ECX, - CX, - CH, - CL, - EDX, - DX, - DH, - DL, - EDI, - DI, - ESI, - SI, - EBP, - BP, - ESP, - SP, - EIP, - -#ifdef _WIN64 - RAX, - RBX, - RCX, - RDX, - RSI, - SIL, - RDI, - DIL, - RBP, - BPL, - RSP, - SPL, - RIP, - R8, - R8D, - R8W, - R8B, - R9, - R9D, - R9W, - R9B, - R10, - R10D, - R10W, - R10B, - R11, - R11D, - R11W, - R11B, - R12, - R12D, - R12W, - R12B, - R13, - R13D, - R13W, - R13B, - R14, - R14D, - R14W, - R14B, - R15, - R15D, - R15W, - R15B, -#endif //_WIN64 - - CIP, - CSP, -}; //RegisterEnum - -SCRIPT_EXPORT duint Get(RegisterEnum reg); -SCRIPT_EXPORT bool Set(RegisterEnum reg, duint value); -SCRIPT_EXPORT int Size(); //gets architecture register size in bytes - -SCRIPT_EXPORT duint GetDR0(); -SCRIPT_EXPORT bool SetDR0(duint value); -SCRIPT_EXPORT duint GetDR1(); -SCRIPT_EXPORT bool SetDR1(duint value); -SCRIPT_EXPORT duint GetDR2(); -SCRIPT_EXPORT bool SetDR2(duint value); -SCRIPT_EXPORT duint GetDR3(); -SCRIPT_EXPORT bool SetDR3(duint value); -SCRIPT_EXPORT duint GetDR6(); -SCRIPT_EXPORT bool SetDR6(duint value); -SCRIPT_EXPORT duint GetDR7(); -SCRIPT_EXPORT bool SetDR7(duint value); - -SCRIPT_EXPORT unsigned int GetEAX(); -SCRIPT_EXPORT bool SetEAX(unsigned int value); -SCRIPT_EXPORT unsigned short GetAX(); -SCRIPT_EXPORT bool SetAX(unsigned short value); -SCRIPT_EXPORT unsigned char GetAH(); -SCRIPT_EXPORT bool SetAH(unsigned char value); -SCRIPT_EXPORT unsigned char GetAL(); -SCRIPT_EXPORT bool SetAL(unsigned char value); -SCRIPT_EXPORT unsigned int GetEBX(); -SCRIPT_EXPORT bool SetEBX(unsigned int value); -SCRIPT_EXPORT unsigned short GetBX(); -SCRIPT_EXPORT bool SetBX(unsigned short value); -SCRIPT_EXPORT unsigned char GetBH(); -SCRIPT_EXPORT bool SetBH(unsigned char value); -SCRIPT_EXPORT unsigned char GetBL(); -SCRIPT_EXPORT bool SetBL(unsigned char value); -SCRIPT_EXPORT unsigned int GetECX(); -SCRIPT_EXPORT bool SetECX(unsigned int value); -SCRIPT_EXPORT unsigned short GetCX(); -SCRIPT_EXPORT bool SetCX(unsigned short value); -SCRIPT_EXPORT unsigned char GetCH(); -SCRIPT_EXPORT bool SetCH(unsigned char value); -SCRIPT_EXPORT unsigned char GetCL(); -SCRIPT_EXPORT bool SetCL(unsigned char value); -SCRIPT_EXPORT unsigned int GetEDX(); -SCRIPT_EXPORT bool SetEDX(unsigned int value); -SCRIPT_EXPORT unsigned short GetDX(); -SCRIPT_EXPORT bool SetDX(unsigned short value); -SCRIPT_EXPORT unsigned char GetDH(); -SCRIPT_EXPORT bool SetDH(unsigned char value); -SCRIPT_EXPORT unsigned char GetDL(); -SCRIPT_EXPORT bool SetDL(unsigned char value); -SCRIPT_EXPORT unsigned int GetEDI(); -SCRIPT_EXPORT bool SetEDI(unsigned int value); -SCRIPT_EXPORT unsigned short GetDI(); -SCRIPT_EXPORT bool SetDI(unsigned short value); -SCRIPT_EXPORT unsigned int GetESI(); -SCRIPT_EXPORT bool SetESI(unsigned int value); -SCRIPT_EXPORT unsigned short GetSI(); -SCRIPT_EXPORT bool SetSI(unsigned short value); -SCRIPT_EXPORT unsigned int GetEBP(); -SCRIPT_EXPORT bool SetEBP(unsigned int value); -SCRIPT_EXPORT unsigned short GetBP(); -SCRIPT_EXPORT bool SetBP(unsigned short value); -SCRIPT_EXPORT unsigned int GetESP(); -SCRIPT_EXPORT bool SetESP(unsigned int value); -SCRIPT_EXPORT unsigned short GetSP(); -SCRIPT_EXPORT bool SetSP(unsigned short value); -SCRIPT_EXPORT unsigned int GetEIP(); -SCRIPT_EXPORT bool SetEIP(unsigned int value); - -#ifdef _WIN64 -SCRIPT_EXPORT unsigned long long GetRAX(); -SCRIPT_EXPORT bool SetRAX(unsigned long long value); -SCRIPT_EXPORT unsigned long long GetRBX(); -SCRIPT_EXPORT bool SetRBX(unsigned long long value); -SCRIPT_EXPORT unsigned long long GetRCX(); -SCRIPT_EXPORT bool SetRCX(unsigned long long value); -SCRIPT_EXPORT unsigned long long GetRDX(); -SCRIPT_EXPORT bool SetRDX(unsigned long long value); -SCRIPT_EXPORT unsigned long long GetRSI(); -SCRIPT_EXPORT bool SetRSI(unsigned long long value); -SCRIPT_EXPORT unsigned char GetSIL(); -SCRIPT_EXPORT bool SetSIL(unsigned char value); -SCRIPT_EXPORT unsigned long long GetRDI(); -SCRIPT_EXPORT bool SetRDI(unsigned long long value); -SCRIPT_EXPORT unsigned char GetDIL(); -SCRIPT_EXPORT bool SetDIL(unsigned char value); -SCRIPT_EXPORT unsigned long long GetRBP(); -SCRIPT_EXPORT bool SetRBP(unsigned long long value); -SCRIPT_EXPORT unsigned char GetBPL(); -SCRIPT_EXPORT bool SetBPL(unsigned char value); -SCRIPT_EXPORT unsigned long long GetRSP(); -SCRIPT_EXPORT bool SetRSP(unsigned long long value); -SCRIPT_EXPORT unsigned char GetSPL(); -SCRIPT_EXPORT bool SetSPL(unsigned char value); -SCRIPT_EXPORT unsigned long long GetRIP(); -SCRIPT_EXPORT bool SetRIP(unsigned long long value); -SCRIPT_EXPORT unsigned long long GetR8(); -SCRIPT_EXPORT bool SetR8(unsigned long long value); -SCRIPT_EXPORT unsigned int GetR8D(); -SCRIPT_EXPORT bool SetR8D(unsigned int value); -SCRIPT_EXPORT unsigned short GetR8W(); -SCRIPT_EXPORT bool SetR8W(unsigned short value); -SCRIPT_EXPORT unsigned char GetR8B(); -SCRIPT_EXPORT bool SetR8B(unsigned char value); -SCRIPT_EXPORT unsigned long long GetR9(); -SCRIPT_EXPORT bool SetR9(unsigned long long value); -SCRIPT_EXPORT unsigned int GetR9D(); -SCRIPT_EXPORT bool SetR9D(unsigned int value); -SCRIPT_EXPORT unsigned short GetR9W(); -SCRIPT_EXPORT bool SetR9W(unsigned short value); -SCRIPT_EXPORT unsigned char GetR9B(); -SCRIPT_EXPORT bool SetR9B(unsigned char value); -SCRIPT_EXPORT unsigned long long GetR10(); -SCRIPT_EXPORT bool SetR10(unsigned long long value); -SCRIPT_EXPORT unsigned int GetR10D(); -SCRIPT_EXPORT bool SetR10D(unsigned int value); -SCRIPT_EXPORT unsigned short GetR10W(); -SCRIPT_EXPORT bool SetR10W(unsigned short value); -SCRIPT_EXPORT unsigned char GetR10B(); -SCRIPT_EXPORT bool SetR10B(unsigned char value); -SCRIPT_EXPORT unsigned long long GetR11(); -SCRIPT_EXPORT bool SetR11(unsigned long long value); -SCRIPT_EXPORT unsigned int GetR11D(); -SCRIPT_EXPORT bool SetR11D(unsigned int value); -SCRIPT_EXPORT unsigned short GetR11W(); -SCRIPT_EXPORT bool SetR11W(unsigned short value); -SCRIPT_EXPORT unsigned char GetR11B(); -SCRIPT_EXPORT bool SetR11B(unsigned char value); -SCRIPT_EXPORT unsigned long long GetR12(); -SCRIPT_EXPORT bool SetR12(unsigned long long value); -SCRIPT_EXPORT unsigned int GetR12D(); -SCRIPT_EXPORT bool SetR12D(unsigned int value); -SCRIPT_EXPORT unsigned short GetR12W(); -SCRIPT_EXPORT bool SetR12W(unsigned short value); -SCRIPT_EXPORT unsigned char GetR12B(); -SCRIPT_EXPORT bool SetR12B(unsigned char value); -SCRIPT_EXPORT unsigned long long GetR13(); -SCRIPT_EXPORT bool SetR13(unsigned long long value); -SCRIPT_EXPORT unsigned int GetR13D(); -SCRIPT_EXPORT bool SetR13D(unsigned int value); -SCRIPT_EXPORT unsigned short GetR13W(); -SCRIPT_EXPORT bool SetR13W(unsigned short value); -SCRIPT_EXPORT unsigned char GetR13B(); -SCRIPT_EXPORT bool SetR13B(unsigned char value); -SCRIPT_EXPORT unsigned long long GetR14(); -SCRIPT_EXPORT bool SetR14(unsigned long long value); -SCRIPT_EXPORT unsigned int GetR14D(); -SCRIPT_EXPORT bool SetR14D(unsigned int value); -SCRIPT_EXPORT unsigned short GetR14W(); -SCRIPT_EXPORT bool SetR14W(unsigned short value); -SCRIPT_EXPORT unsigned char GetR14B(); -SCRIPT_EXPORT bool SetR14B(unsigned char value); -SCRIPT_EXPORT unsigned long long GetR15(); -SCRIPT_EXPORT bool SetR15(unsigned long long value); -SCRIPT_EXPORT unsigned int GetR15D(); -SCRIPT_EXPORT bool SetR15D(unsigned int value); -SCRIPT_EXPORT unsigned short GetR15W(); -SCRIPT_EXPORT bool SetR15W(unsigned short value); -SCRIPT_EXPORT unsigned char GetR15B(); -SCRIPT_EXPORT bool SetR15B(unsigned char value); -#endif //_WIN64 - -SCRIPT_EXPORT duint GetCIP(); -SCRIPT_EXPORT bool SetCIP(duint value); -SCRIPT_EXPORT duint GetCSP(); -SCRIPT_EXPORT bool SetCSP(duint value); -}; //Register -}; //Script - +#ifndef _SCRIPTAPI_REGISTER_H +#define _SCRIPTAPI_REGISTER_H + +#include "_scriptapi.h" + +namespace Script +{ +namespace Register +{ +enum RegisterEnum +{ + DR0, + DR1, + DR2, + DR3, + DR6, + DR7, + + EAX, + AX, + AH, + AL, + EBX, + BX, + BH, + BL, + ECX, + CX, + CH, + CL, + EDX, + DX, + DH, + DL, + EDI, + DI, + ESI, + SI, + EBP, + BP, + ESP, + SP, + EIP, + +#ifdef _WIN64 + RAX, + RBX, + RCX, + RDX, + RSI, + SIL, + RDI, + DIL, + RBP, + BPL, + RSP, + SPL, + RIP, + R8, + R8D, + R8W, + R8B, + R9, + R9D, + R9W, + R9B, + R10, + R10D, + R10W, + R10B, + R11, + R11D, + R11W, + R11B, + R12, + R12D, + R12W, + R12B, + R13, + R13D, + R13W, + R13B, + R14, + R14D, + R14W, + R14B, + R15, + R15D, + R15W, + R15B, +#endif //_WIN64 + + CIP, + CSP, +}; //RegisterEnum + +SCRIPT_EXPORT duint Get(RegisterEnum reg); +SCRIPT_EXPORT bool Set(RegisterEnum reg, duint value); +SCRIPT_EXPORT int Size(); //gets architecture register size in bytes + +SCRIPT_EXPORT duint GetDR0(); +SCRIPT_EXPORT bool SetDR0(duint value); +SCRIPT_EXPORT duint GetDR1(); +SCRIPT_EXPORT bool SetDR1(duint value); +SCRIPT_EXPORT duint GetDR2(); +SCRIPT_EXPORT bool SetDR2(duint value); +SCRIPT_EXPORT duint GetDR3(); +SCRIPT_EXPORT bool SetDR3(duint value); +SCRIPT_EXPORT duint GetDR6(); +SCRIPT_EXPORT bool SetDR6(duint value); +SCRIPT_EXPORT duint GetDR7(); +SCRIPT_EXPORT bool SetDR7(duint value); + +SCRIPT_EXPORT unsigned int GetEAX(); +SCRIPT_EXPORT bool SetEAX(unsigned int value); +SCRIPT_EXPORT unsigned short GetAX(); +SCRIPT_EXPORT bool SetAX(unsigned short value); +SCRIPT_EXPORT unsigned char GetAH(); +SCRIPT_EXPORT bool SetAH(unsigned char value); +SCRIPT_EXPORT unsigned char GetAL(); +SCRIPT_EXPORT bool SetAL(unsigned char value); +SCRIPT_EXPORT unsigned int GetEBX(); +SCRIPT_EXPORT bool SetEBX(unsigned int value); +SCRIPT_EXPORT unsigned short GetBX(); +SCRIPT_EXPORT bool SetBX(unsigned short value); +SCRIPT_EXPORT unsigned char GetBH(); +SCRIPT_EXPORT bool SetBH(unsigned char value); +SCRIPT_EXPORT unsigned char GetBL(); +SCRIPT_EXPORT bool SetBL(unsigned char value); +SCRIPT_EXPORT unsigned int GetECX(); +SCRIPT_EXPORT bool SetECX(unsigned int value); +SCRIPT_EXPORT unsigned short GetCX(); +SCRIPT_EXPORT bool SetCX(unsigned short value); +SCRIPT_EXPORT unsigned char GetCH(); +SCRIPT_EXPORT bool SetCH(unsigned char value); +SCRIPT_EXPORT unsigned char GetCL(); +SCRIPT_EXPORT bool SetCL(unsigned char value); +SCRIPT_EXPORT unsigned int GetEDX(); +SCRIPT_EXPORT bool SetEDX(unsigned int value); +SCRIPT_EXPORT unsigned short GetDX(); +SCRIPT_EXPORT bool SetDX(unsigned short value); +SCRIPT_EXPORT unsigned char GetDH(); +SCRIPT_EXPORT bool SetDH(unsigned char value); +SCRIPT_EXPORT unsigned char GetDL(); +SCRIPT_EXPORT bool SetDL(unsigned char value); +SCRIPT_EXPORT unsigned int GetEDI(); +SCRIPT_EXPORT bool SetEDI(unsigned int value); +SCRIPT_EXPORT unsigned short GetDI(); +SCRIPT_EXPORT bool SetDI(unsigned short value); +SCRIPT_EXPORT unsigned int GetESI(); +SCRIPT_EXPORT bool SetESI(unsigned int value); +SCRIPT_EXPORT unsigned short GetSI(); +SCRIPT_EXPORT bool SetSI(unsigned short value); +SCRIPT_EXPORT unsigned int GetEBP(); +SCRIPT_EXPORT bool SetEBP(unsigned int value); +SCRIPT_EXPORT unsigned short GetBP(); +SCRIPT_EXPORT bool SetBP(unsigned short value); +SCRIPT_EXPORT unsigned int GetESP(); +SCRIPT_EXPORT bool SetESP(unsigned int value); +SCRIPT_EXPORT unsigned short GetSP(); +SCRIPT_EXPORT bool SetSP(unsigned short value); +SCRIPT_EXPORT unsigned int GetEIP(); +SCRIPT_EXPORT bool SetEIP(unsigned int value); + +#ifdef _WIN64 +SCRIPT_EXPORT unsigned long long GetRAX(); +SCRIPT_EXPORT bool SetRAX(unsigned long long value); +SCRIPT_EXPORT unsigned long long GetRBX(); +SCRIPT_EXPORT bool SetRBX(unsigned long long value); +SCRIPT_EXPORT unsigned long long GetRCX(); +SCRIPT_EXPORT bool SetRCX(unsigned long long value); +SCRIPT_EXPORT unsigned long long GetRDX(); +SCRIPT_EXPORT bool SetRDX(unsigned long long value); +SCRIPT_EXPORT unsigned long long GetRSI(); +SCRIPT_EXPORT bool SetRSI(unsigned long long value); +SCRIPT_EXPORT unsigned char GetSIL(); +SCRIPT_EXPORT bool SetSIL(unsigned char value); +SCRIPT_EXPORT unsigned long long GetRDI(); +SCRIPT_EXPORT bool SetRDI(unsigned long long value); +SCRIPT_EXPORT unsigned char GetDIL(); +SCRIPT_EXPORT bool SetDIL(unsigned char value); +SCRIPT_EXPORT unsigned long long GetRBP(); +SCRIPT_EXPORT bool SetRBP(unsigned long long value); +SCRIPT_EXPORT unsigned char GetBPL(); +SCRIPT_EXPORT bool SetBPL(unsigned char value); +SCRIPT_EXPORT unsigned long long GetRSP(); +SCRIPT_EXPORT bool SetRSP(unsigned long long value); +SCRIPT_EXPORT unsigned char GetSPL(); +SCRIPT_EXPORT bool SetSPL(unsigned char value); +SCRIPT_EXPORT unsigned long long GetRIP(); +SCRIPT_EXPORT bool SetRIP(unsigned long long value); +SCRIPT_EXPORT unsigned long long GetR8(); +SCRIPT_EXPORT bool SetR8(unsigned long long value); +SCRIPT_EXPORT unsigned int GetR8D(); +SCRIPT_EXPORT bool SetR8D(unsigned int value); +SCRIPT_EXPORT unsigned short GetR8W(); +SCRIPT_EXPORT bool SetR8W(unsigned short value); +SCRIPT_EXPORT unsigned char GetR8B(); +SCRIPT_EXPORT bool SetR8B(unsigned char value); +SCRIPT_EXPORT unsigned long long GetR9(); +SCRIPT_EXPORT bool SetR9(unsigned long long value); +SCRIPT_EXPORT unsigned int GetR9D(); +SCRIPT_EXPORT bool SetR9D(unsigned int value); +SCRIPT_EXPORT unsigned short GetR9W(); +SCRIPT_EXPORT bool SetR9W(unsigned short value); +SCRIPT_EXPORT unsigned char GetR9B(); +SCRIPT_EXPORT bool SetR9B(unsigned char value); +SCRIPT_EXPORT unsigned long long GetR10(); +SCRIPT_EXPORT bool SetR10(unsigned long long value); +SCRIPT_EXPORT unsigned int GetR10D(); +SCRIPT_EXPORT bool SetR10D(unsigned int value); +SCRIPT_EXPORT unsigned short GetR10W(); +SCRIPT_EXPORT bool SetR10W(unsigned short value); +SCRIPT_EXPORT unsigned char GetR10B(); +SCRIPT_EXPORT bool SetR10B(unsigned char value); +SCRIPT_EXPORT unsigned long long GetR11(); +SCRIPT_EXPORT bool SetR11(unsigned long long value); +SCRIPT_EXPORT unsigned int GetR11D(); +SCRIPT_EXPORT bool SetR11D(unsigned int value); +SCRIPT_EXPORT unsigned short GetR11W(); +SCRIPT_EXPORT bool SetR11W(unsigned short value); +SCRIPT_EXPORT unsigned char GetR11B(); +SCRIPT_EXPORT bool SetR11B(unsigned char value); +SCRIPT_EXPORT unsigned long long GetR12(); +SCRIPT_EXPORT bool SetR12(unsigned long long value); +SCRIPT_EXPORT unsigned int GetR12D(); +SCRIPT_EXPORT bool SetR12D(unsigned int value); +SCRIPT_EXPORT unsigned short GetR12W(); +SCRIPT_EXPORT bool SetR12W(unsigned short value); +SCRIPT_EXPORT unsigned char GetR12B(); +SCRIPT_EXPORT bool SetR12B(unsigned char value); +SCRIPT_EXPORT unsigned long long GetR13(); +SCRIPT_EXPORT bool SetR13(unsigned long long value); +SCRIPT_EXPORT unsigned int GetR13D(); +SCRIPT_EXPORT bool SetR13D(unsigned int value); +SCRIPT_EXPORT unsigned short GetR13W(); +SCRIPT_EXPORT bool SetR13W(unsigned short value); +SCRIPT_EXPORT unsigned char GetR13B(); +SCRIPT_EXPORT bool SetR13B(unsigned char value); +SCRIPT_EXPORT unsigned long long GetR14(); +SCRIPT_EXPORT bool SetR14(unsigned long long value); +SCRIPT_EXPORT unsigned int GetR14D(); +SCRIPT_EXPORT bool SetR14D(unsigned int value); +SCRIPT_EXPORT unsigned short GetR14W(); +SCRIPT_EXPORT bool SetR14W(unsigned short value); +SCRIPT_EXPORT unsigned char GetR14B(); +SCRIPT_EXPORT bool SetR14B(unsigned char value); +SCRIPT_EXPORT unsigned long long GetR15(); +SCRIPT_EXPORT bool SetR15(unsigned long long value); +SCRIPT_EXPORT unsigned int GetR15D(); +SCRIPT_EXPORT bool SetR15D(unsigned int value); +SCRIPT_EXPORT unsigned short GetR15W(); +SCRIPT_EXPORT bool SetR15W(unsigned short value); +SCRIPT_EXPORT unsigned char GetR15B(); +SCRIPT_EXPORT bool SetR15B(unsigned char value); +#endif //_WIN64 + +SCRIPT_EXPORT duint GetCIP(); +SCRIPT_EXPORT bool SetCIP(duint value); +SCRIPT_EXPORT duint GetCSP(); +SCRIPT_EXPORT bool SetCSP(duint value); +}; //Register +}; //Script + #endif //_SCRIPTAPI_REGISTER_H \ No newline at end of file diff --git a/src/dbg/_scriptapi_stack.cpp b/src/dbg/_scriptapi_stack.cpp index d60d1c9e..aef097d8 100644 --- a/src/dbg/_scriptapi_stack.cpp +++ b/src/dbg/_scriptapi_stack.cpp @@ -1,24 +1,24 @@ -#include "_scriptapi_stack.h" -#include "_scriptapi_memory.h" -#include "_scriptapi_register.h" - -SCRIPT_EXPORT duint Script::Stack::Pop() -{ - duint csp = Register::GetCSP(); - duint top = Memory::ReadPtr(csp); - Register::SetCSP(csp + sizeof(duint)); - return top; -} - -SCRIPT_EXPORT duint Script::Stack::Push(duint value) -{ - duint csp = Register::GetCSP(); - Register::SetCSP(csp - sizeof(duint)); - Memory::WritePtr(csp - sizeof(duint), value); - return Memory::ReadPtr(csp); -} - -SCRIPT_EXPORT duint Script::Stack::Peek(int offset) -{ - return Memory::ReadPtr(Register::GetCSP() + offset * sizeof(duint)); +#include "_scriptapi_stack.h" +#include "_scriptapi_memory.h" +#include "_scriptapi_register.h" + +SCRIPT_EXPORT duint Script::Stack::Pop() +{ + duint csp = Register::GetCSP(); + duint top = Memory::ReadPtr(csp); + Register::SetCSP(csp + sizeof(duint)); + return top; +} + +SCRIPT_EXPORT duint Script::Stack::Push(duint value) +{ + duint csp = Register::GetCSP(); + Register::SetCSP(csp - sizeof(duint)); + Memory::WritePtr(csp - sizeof(duint), value); + return Memory::ReadPtr(csp); +} + +SCRIPT_EXPORT duint Script::Stack::Peek(int offset) +{ + return Memory::ReadPtr(Register::GetCSP() + offset * sizeof(duint)); } \ No newline at end of file diff --git a/src/dbg/_scriptapi_stack.h b/src/dbg/_scriptapi_stack.h index ea658981..47d714de 100644 --- a/src/dbg/_scriptapi_stack.h +++ b/src/dbg/_scriptapi_stack.h @@ -1,16 +1,16 @@ -#ifndef _SCRIPTAPI_STACK_H -#define _SCRIPTAPI_STACK_H - -#include "_scriptapi.h" - -namespace Script -{ -namespace Stack -{ -SCRIPT_EXPORT duint Pop(); -SCRIPT_EXPORT duint Push(duint value); //returns the previous top, equal to Peek(1) -SCRIPT_EXPORT duint Peek(int offset = 0); //offset is in multiples of Register::Size(), for easy x32/x64 portability -}; //Stack -}; //Script - +#ifndef _SCRIPTAPI_STACK_H +#define _SCRIPTAPI_STACK_H + +#include "_scriptapi.h" + +namespace Script +{ +namespace Stack +{ +SCRIPT_EXPORT duint Pop(); +SCRIPT_EXPORT duint Push(duint value); //returns the previous top, equal to Peek(1) +SCRIPT_EXPORT duint Peek(int offset = 0); //offset is in multiples of Register::Size(), for easy x32/x64 portability +}; //Stack +}; //Script + #endif //_SCRIPTAPI_STACK_H \ No newline at end of file diff --git a/src/dbg/addrinfo.cpp b/src/dbg/addrinfo.cpp index b6bea7f9..32f33e6a 100644 --- a/src/dbg/addrinfo.cpp +++ b/src/dbg/addrinfo.cpp @@ -1,91 +1,91 @@ -/** - @file addrinfo.cpp - - @brief Implements the addrinfo class. - */ - -#include "addrinfo.h" -#include "debugger.h" -#include "console.h" -#include "memory.h" -#include "breakpoint.h" -#include "lz4\lz4file.h" -#include "patches.h" -#include "module.h" -#include "comment.h" -#include "label.h" -#include "bookmark.h" -#include "function.h" -#include "loop.h" - -///api functions -bool apienumexports(duint base, EXPORTENUMCALLBACK cbEnum) -{ - MEMORY_BASIC_INFORMATION mbi; - VirtualQueryEx(fdProcessInfo->hProcess, (const void*)base, &mbi, sizeof(mbi)); - duint size = mbi.RegionSize; - Memory buffer(size, "apienumexports:buffer"); - if(!MemRead(base, buffer(), size)) - return false; - IMAGE_NT_HEADERS* pnth = (IMAGE_NT_HEADERS*)((duint)buffer() + GetPE32DataFromMappedFile((ULONG_PTR)buffer(), 0, UE_PE_OFFSET)); - duint export_dir_rva = pnth->OptionalHeader.DataDirectory[0].VirtualAddress; - duint export_dir_size = pnth->OptionalHeader.DataDirectory[0].Size; - IMAGE_EXPORT_DIRECTORY export_dir; - memset(&export_dir, 0, sizeof(export_dir)); - MemRead((export_dir_rva + base), &export_dir, sizeof(export_dir)); - unsigned int NumberOfNames = export_dir.NumberOfNames; - if(!export_dir.NumberOfFunctions || !NumberOfNames) //no named exports - return false; - char modname[MAX_MODULE_SIZE] = ""; - ModNameFromAddr(base, modname, true); - duint original_name_va = export_dir.Name + base; - char original_name[deflen] = ""; - memset(original_name, 0, sizeof(original_name)); - MemRead(original_name_va, original_name, deflen); - char* AddrOfFunctions_va = (char*)(export_dir.AddressOfFunctions + base); //not a valid local pointer - char* AddrOfNames_va = (char*)(export_dir.AddressOfNames + base); //not a valid local pointer - char* AddrOfNameOrdinals_va = (char*)(export_dir.AddressOfNameOrdinals + base); //not a valid local pointer - for(DWORD i = 0; i < NumberOfNames; i++) - { - DWORD curAddrOfName = 0; - MemRead((duint)(AddrOfNames_va + sizeof(DWORD)*i), &curAddrOfName, sizeof(DWORD)); - char* cur_name_va = (char*)(curAddrOfName + base); - char cur_name[deflen] = ""; - memset(cur_name, 0, deflen); - MemRead((duint)cur_name_va, cur_name, deflen); - WORD curAddrOfNameOrdinals = 0; - MemRead((duint)(AddrOfNameOrdinals_va + sizeof(WORD)*i), &curAddrOfNameOrdinals, sizeof(WORD)); - DWORD curFunctionRva = 0; - MemRead((duint)(AddrOfFunctions_va + sizeof(DWORD)*curAddrOfNameOrdinals), &curFunctionRva, sizeof(DWORD)); - - if(curFunctionRva >= export_dir_rva && curFunctionRva < export_dir_rva + export_dir_size) - { - char forwarded_api[deflen] = ""; - memset(forwarded_api, 0, deflen); - MemRead((curFunctionRva + base), forwarded_api, deflen); - int len = (int)strlen(forwarded_api); - int j = 0; - while(forwarded_api[j] != '.' && j < len) - j++; - if(forwarded_api[j] == '.') - { - forwarded_api[j] = 0; - HINSTANCE hTempDll = LoadLibraryExA(forwarded_api, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); - if(hTempDll) - { - duint local_addr = (duint)GetProcAddress(hTempDll, forwarded_api + j + 1); - if(local_addr) - { - duint remote_addr = ImporterGetRemoteAPIAddress(fdProcessInfo->hProcess, local_addr); - cbEnum(base, modname, cur_name, remote_addr); - } - } - } - } - else - { - cbEnum(base, modname, cur_name, curFunctionRva + base); - } - } - return true; +/** + @file addrinfo.cpp + + @brief Implements the addrinfo class. + */ + +#include "addrinfo.h" +#include "debugger.h" +#include "console.h" +#include "memory.h" +#include "breakpoint.h" +#include "lz4\lz4file.h" +#include "patches.h" +#include "module.h" +#include "comment.h" +#include "label.h" +#include "bookmark.h" +#include "function.h" +#include "loop.h" + +///api functions +bool apienumexports(duint base, EXPORTENUMCALLBACK cbEnum) +{ + MEMORY_BASIC_INFORMATION mbi; + VirtualQueryEx(fdProcessInfo->hProcess, (const void*)base, &mbi, sizeof(mbi)); + duint size = mbi.RegionSize; + Memory buffer(size, "apienumexports:buffer"); + if(!MemRead(base, buffer(), size)) + return false; + IMAGE_NT_HEADERS* pnth = (IMAGE_NT_HEADERS*)((duint)buffer() + GetPE32DataFromMappedFile((ULONG_PTR)buffer(), 0, UE_PE_OFFSET)); + duint export_dir_rva = pnth->OptionalHeader.DataDirectory[0].VirtualAddress; + duint export_dir_size = pnth->OptionalHeader.DataDirectory[0].Size; + IMAGE_EXPORT_DIRECTORY export_dir; + memset(&export_dir, 0, sizeof(export_dir)); + MemRead((export_dir_rva + base), &export_dir, sizeof(export_dir)); + unsigned int NumberOfNames = export_dir.NumberOfNames; + if(!export_dir.NumberOfFunctions || !NumberOfNames) //no named exports + return false; + char modname[MAX_MODULE_SIZE] = ""; + ModNameFromAddr(base, modname, true); + duint original_name_va = export_dir.Name + base; + char original_name[deflen] = ""; + memset(original_name, 0, sizeof(original_name)); + MemRead(original_name_va, original_name, deflen); + char* AddrOfFunctions_va = (char*)(export_dir.AddressOfFunctions + base); //not a valid local pointer + char* AddrOfNames_va = (char*)(export_dir.AddressOfNames + base); //not a valid local pointer + char* AddrOfNameOrdinals_va = (char*)(export_dir.AddressOfNameOrdinals + base); //not a valid local pointer + for(DWORD i = 0; i < NumberOfNames; i++) + { + DWORD curAddrOfName = 0; + MemRead((duint)(AddrOfNames_va + sizeof(DWORD)*i), &curAddrOfName, sizeof(DWORD)); + char* cur_name_va = (char*)(curAddrOfName + base); + char cur_name[deflen] = ""; + memset(cur_name, 0, deflen); + MemRead((duint)cur_name_va, cur_name, deflen); + WORD curAddrOfNameOrdinals = 0; + MemRead((duint)(AddrOfNameOrdinals_va + sizeof(WORD)*i), &curAddrOfNameOrdinals, sizeof(WORD)); + DWORD curFunctionRva = 0; + MemRead((duint)(AddrOfFunctions_va + sizeof(DWORD)*curAddrOfNameOrdinals), &curFunctionRva, sizeof(DWORD)); + + if(curFunctionRva >= export_dir_rva && curFunctionRva < export_dir_rva + export_dir_size) + { + char forwarded_api[deflen] = ""; + memset(forwarded_api, 0, deflen); + MemRead((curFunctionRva + base), forwarded_api, deflen); + int len = (int)strlen(forwarded_api); + int j = 0; + while(forwarded_api[j] != '.' && j < len) + j++; + if(forwarded_api[j] == '.') + { + forwarded_api[j] = 0; + HINSTANCE hTempDll = LoadLibraryExA(forwarded_api, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); + if(hTempDll) + { + duint local_addr = (duint)GetProcAddress(hTempDll, forwarded_api + j + 1); + if(local_addr) + { + duint remote_addr = ImporterGetRemoteAPIAddress(fdProcessInfo->hProcess, local_addr); + cbEnum(base, modname, cur_name, remote_addr); + } + } + } + } + else + { + cbEnum(base, modname, cur_name, curFunctionRva + base); + } + } + return true; } \ No newline at end of file diff --git a/src/dbg/addrinfo.h b/src/dbg/addrinfo.h index c552a57d..da182641 100644 --- a/src/dbg/addrinfo.h +++ b/src/dbg/addrinfo.h @@ -1,61 +1,61 @@ -#ifndef _ADDRINFO_H -#define _ADDRINFO_H - -#include "_global.h" -#include - -//ranges -typedef std::pair Range; -typedef std::pair ModuleRange; //modhash + RVA range -typedef std::pair DepthModuleRange; //depth + modulerange - -struct RangeCompare -{ - bool operator()(const Range & a, const Range & b) //a before b? - { - return a.second < b.first; - } -}; - -struct OverlappingRangeCompare -{ - bool operator()(const Range & a, const Range & b) //a before b? - { - return a.second < b.first || a.second < b.second; - } -}; - -struct ModuleRangeCompare -{ - bool operator()(const ModuleRange & a, const ModuleRange & b) - { - if(a.first < b.first) //module hash is smaller - return true; - if(a.first != b.first) //module hashes are not equal - return false; - return a.second.second < b.second.first; //a.second is before b.second - } -}; - -struct DepthModuleRangeCompare -{ - bool operator()(const DepthModuleRange & a, const DepthModuleRange & b) - { - if(a.first < b.first) //module depth is smaller - return true; - if(a.first != b.first) //module depths are not equal - return false; - if(a.second.first < b.second.first) //module hash is smaller - return true; - if(a.second.first != b.second.first) //module hashes are not equal - return false; - return a.second.second.second < b.second.second.first; //a.second.second is before b.second.second - } -}; - -//typedefs -typedef std::function EXPORTENUMCALLBACK; - -bool apienumexports(duint base, EXPORTENUMCALLBACK cbEnum); - -#endif // _ADDRINFO_H +#ifndef _ADDRINFO_H +#define _ADDRINFO_H + +#include "_global.h" +#include + +//ranges +typedef std::pair Range; +typedef std::pair ModuleRange; //modhash + RVA range +typedef std::pair DepthModuleRange; //depth + modulerange + +struct RangeCompare +{ + bool operator()(const Range & a, const Range & b) //a before b? + { + return a.second < b.first; + } +}; + +struct OverlappingRangeCompare +{ + bool operator()(const Range & a, const Range & b) //a before b? + { + return a.second < b.first || a.second < b.second; + } +}; + +struct ModuleRangeCompare +{ + bool operator()(const ModuleRange & a, const ModuleRange & b) + { + if(a.first < b.first) //module hash is smaller + return true; + if(a.first != b.first) //module hashes are not equal + return false; + return a.second.second < b.second.first; //a.second is before b.second + } +}; + +struct DepthModuleRangeCompare +{ + bool operator()(const DepthModuleRange & a, const DepthModuleRange & b) + { + if(a.first < b.first) //module depth is smaller + return true; + if(a.first != b.first) //module depths are not equal + return false; + if(a.second.first < b.second.first) //module hash is smaller + return true; + if(a.second.first != b.second.first) //module hashes are not equal + return false; + return a.second.second.second < b.second.second.first; //a.second.second is before b.second.second + } +}; + +//typedefs +typedef std::function EXPORTENUMCALLBACK; + +bool apienumexports(duint base, EXPORTENUMCALLBACK cbEnum); + +#endif // _ADDRINFO_H diff --git a/src/dbg/analysis.cpp b/src/dbg/analysis.cpp index f95ec316..53d0b43a 100644 --- a/src/dbg/analysis.cpp +++ b/src/dbg/analysis.cpp @@ -1,25 +1,25 @@ -#include "analysis.h" -#include "memory.h" - -Analysis::Analysis(duint base, duint size) -{ - _base = base; - _size = size; - _data = new unsigned char[_size + MAX_DISASM_BUFFER]; - MemRead(_base, _data, _size); -} - -Analysis::~Analysis() -{ - delete[] _data; -} - -bool Analysis::IsValidAddress(duint addr) -{ - return addr >= _base && addr < _base + _size; -} - -const unsigned char* Analysis::TranslateAddress(duint addr) -{ - return IsValidAddress(addr) ? _data + (addr - _base) : nullptr; +#include "analysis.h" +#include "memory.h" + +Analysis::Analysis(duint base, duint size) +{ + _base = base; + _size = size; + _data = new unsigned char[_size + MAX_DISASM_BUFFER]; + MemRead(_base, _data, _size); +} + +Analysis::~Analysis() +{ + delete[] _data; +} + +bool Analysis::IsValidAddress(duint addr) +{ + return addr >= _base && addr < _base + _size; +} + +const unsigned char* Analysis::TranslateAddress(duint addr) +{ + return IsValidAddress(addr) ? _data + (addr - _base) : nullptr; } \ No newline at end of file diff --git a/src/dbg/analysis.h b/src/dbg/analysis.h index a19a77a4..ce645907 100644 --- a/src/dbg/analysis.h +++ b/src/dbg/analysis.h @@ -1,26 +1,26 @@ -#ifndef _ANALYSIS_H -#define _ANALYSIS_H - -#include "_global.h" -#include - -class Analysis -{ -public: - explicit Analysis(duint base, duint size); - Analysis(const Analysis & that) = delete; - virtual ~Analysis(); - virtual void Analyse() = 0; - virtual void SetMarkers() = 0; - -protected: - duint _base; - duint _size; - unsigned char* _data; - Capstone _cp; - - bool IsValidAddress(duint addr); - const unsigned char* TranslateAddress(duint addr); -}; - +#ifndef _ANALYSIS_H +#define _ANALYSIS_H + +#include "_global.h" +#include + +class Analysis +{ +public: + explicit Analysis(duint base, duint size); + Analysis(const Analysis & that) = delete; + virtual ~Analysis(); + virtual void Analyse() = 0; + virtual void SetMarkers() = 0; + +protected: + duint _base; + duint _size; + unsigned char* _data; + Capstone _cp; + + bool IsValidAddress(duint addr); + const unsigned char* TranslateAddress(duint addr); +}; + #endif //_ANALYSIS_H \ No newline at end of file diff --git a/src/dbg/analysis_nukem.cpp b/src/dbg/analysis_nukem.cpp index cdfd87be..ac5bb38d 100644 --- a/src/dbg/analysis_nukem.cpp +++ b/src/dbg/analysis_nukem.cpp @@ -1,23 +1,23 @@ -#include "analysis_nukem.h" -#include "BasicBlock.h" -#include "LinearPass.h" -#include "FunctionPass.h" -#include "console.h" - -void Analyse_nukem(duint base, duint size) -{ - dputs("Starting analysis (Nukem)..."); - DWORD ticks = GetTickCount(); - - duint end = base + size; - - BBlockArray blocks; - - LinearPass* pass1 = new LinearPass(base, end, blocks); - pass1->Analyse(); - - FunctionPass* pass2 = new FunctionPass(base, end, blocks); - pass2->Analyse(); - - dprintf("Analysis finished in %ums!\n", GetTickCount() - ticks); +#include "analysis_nukem.h" +#include "BasicBlock.h" +#include "LinearPass.h" +#include "FunctionPass.h" +#include "console.h" + +void Analyse_nukem(duint base, duint size) +{ + dputs("Starting analysis (Nukem)..."); + DWORD ticks = GetTickCount(); + + duint end = base + size; + + BBlockArray blocks; + + LinearPass* pass1 = new LinearPass(base, end, blocks); + pass1->Analyse(); + + FunctionPass* pass2 = new FunctionPass(base, end, blocks); + pass2->Analyse(); + + dprintf("Analysis finished in %ums!\n", GetTickCount() - ticks); } \ No newline at end of file diff --git a/src/dbg/analysis_nukem.h b/src/dbg/analysis_nukem.h index dbb2cecb..b5abae92 100644 --- a/src/dbg/analysis_nukem.h +++ b/src/dbg/analysis_nukem.h @@ -1,5 +1,5 @@ -#pragma once - -#include "_global.h" - +#pragma once + +#include "_global.h" + void Analyse_nukem(duint base, duint size); \ No newline at end of file diff --git a/src/dbg/assemble.cpp b/src/dbg/assemble.cpp index d3c571d5..66a4300e 100644 --- a/src/dbg/assemble.cpp +++ b/src/dbg/assemble.cpp @@ -1,93 +1,93 @@ -/** - @file assemble.cpp - - @brief Implements the assemble class. - */ - -#include "assemble.h" -#include "memory.h" -#include "XEDParse\XEDParse.h" -#include "value.h" -#include "disasm_helper.h" - -static bool cbUnknown(const char* text, ULONGLONG* value) -{ - if(!text || !value) - return false; - duint val; - if(!valfromstring(text, &val)) - return false; - *value = val; - return true; -} - -bool assemble(duint addr, unsigned char* dest, int* size, const char* instruction, char* error) -{ - if(strlen(instruction) >= XEDPARSE_MAXBUFSIZE) - return false; - XEDPARSE parse; - memset(&parse, 0, sizeof(parse)); -#ifdef _WIN64 - parse.x64 = true; -#else //x86 - parse.x64 = false; -#endif - parse.cbUnknown = cbUnknown; - parse.cip = addr; - strcpy_s(parse.instr, instruction); - if(XEDParseAssemble(&parse) == XEDPARSE_ERROR) - { - if(error) - strcpy_s(error, MAX_ERROR_SIZE, parse.error); - return false; - } - - if(dest) - memcpy(dest, parse.dest, parse.dest_size); - if(size) - *size = parse.dest_size; - - return true; -} - -bool assembleat(duint addr, const char* instruction, int* size, char* error, bool fillnop) -{ - int destSize; - unsigned char dest[16]; - if(!assemble(addr, dest, &destSize, instruction, error)) - return false; - //calculate the number of NOPs to insert - int origLen = disasmgetsize(addr); - while(origLen < destSize) - origLen += disasmgetsize(addr + origLen); - int nopsize = origLen - destSize; - unsigned char nops[16]; - memset(nops, 0x90, sizeof(nops)); - - if(size) - *size = destSize; - - bool ret = MemPatch(addr, dest, destSize); - - if (ret) - { - if (fillnop && nopsize) - { - if (size) - *size += nopsize; - - // Ignored if the memory patch for NOPs fail (although it should not) - MemPatch(addr + destSize, nops, nopsize); - } - - // Update GUI if any patching succeeded - GuiUpdatePatches(); - } - else - { - // Tell the user writing is blocked - strcpy_s(error, MAX_ERROR_SIZE, "Error while writing process memory"); - } - - return ret; -} +/** + @file assemble.cpp + + @brief Implements the assemble class. + */ + +#include "assemble.h" +#include "memory.h" +#include "XEDParse\XEDParse.h" +#include "value.h" +#include "disasm_helper.h" + +static bool cbUnknown(const char* text, ULONGLONG* value) +{ + if(!text || !value) + return false; + duint val; + if(!valfromstring(text, &val)) + return false; + *value = val; + return true; +} + +bool assemble(duint addr, unsigned char* dest, int* size, const char* instruction, char* error) +{ + if(strlen(instruction) >= XEDPARSE_MAXBUFSIZE) + return false; + XEDPARSE parse; + memset(&parse, 0, sizeof(parse)); +#ifdef _WIN64 + parse.x64 = true; +#else //x86 + parse.x64 = false; +#endif + parse.cbUnknown = cbUnknown; + parse.cip = addr; + strcpy_s(parse.instr, instruction); + if(XEDParseAssemble(&parse) == XEDPARSE_ERROR) + { + if(error) + strcpy_s(error, MAX_ERROR_SIZE, parse.error); + return false; + } + + if(dest) + memcpy(dest, parse.dest, parse.dest_size); + if(size) + *size = parse.dest_size; + + return true; +} + +bool assembleat(duint addr, const char* instruction, int* size, char* error, bool fillnop) +{ + int destSize; + unsigned char dest[16]; + if(!assemble(addr, dest, &destSize, instruction, error)) + return false; + //calculate the number of NOPs to insert + int origLen = disasmgetsize(addr); + while(origLen < destSize) + origLen += disasmgetsize(addr + origLen); + int nopsize = origLen - destSize; + unsigned char nops[16]; + memset(nops, 0x90, sizeof(nops)); + + if(size) + *size = destSize; + + bool ret = MemPatch(addr, dest, destSize); + + if (ret) + { + if (fillnop && nopsize) + { + if (size) + *size += nopsize; + + // Ignored if the memory patch for NOPs fail (although it should not) + MemPatch(addr + destSize, nops, nopsize); + } + + // Update GUI if any patching succeeded + GuiUpdatePatches(); + } + else + { + // Tell the user writing is blocked + strcpy_s(error, MAX_ERROR_SIZE, "Error while writing process memory"); + } + + return ret; +} diff --git a/src/dbg/assemble.h b/src/dbg/assemble.h index 63b6248b..89865a55 100644 --- a/src/dbg/assemble.h +++ b/src/dbg/assemble.h @@ -1,9 +1,9 @@ -#ifndef _ASSEMBLE_H -#define _ASSEMBLE_H - -#include "_global.h" - -bool assemble(duint addr, unsigned char* dest, int* size, const char* instruction, char* error); -bool assembleat(duint addr, const char* instruction, int* size, char* error, bool fillnop); - -#endif // _ASSEMBLE_H +#ifndef _ASSEMBLE_H +#define _ASSEMBLE_H + +#include "_global.h" + +bool assemble(duint addr, unsigned char* dest, int* size, const char* instruction, char* error); +bool assembleat(duint addr, const char* instruction, int* size, char* error, bool fillnop); + +#endif // _ASSEMBLE_H diff --git a/src/dbg/bookmark.cpp b/src/dbg/bookmark.cpp index bfdb37f2..bf634b14 100644 --- a/src/dbg/bookmark.cpp +++ b/src/dbg/bookmark.cpp @@ -1,199 +1,199 @@ -#include "bookmark.h" -#include "threading.h" -#include "module.h" -#include "memory.h" - -std::unordered_map bookmarks; - -bool BookmarkSet(duint Address, bool Manual) -{ - ASSERT_DEBUGGING("Export call"); - - // Validate the incoming address - if(!MemIsValidReadPtr(Address)) - return false; - - BOOKMARKSINFO bookmark; - ModNameFromAddr(Address, bookmark.mod, true); - bookmark.addr = Address - ModBaseFromAddr(Address); - bookmark.manual = Manual; - - // Exclusive lock to insert new data - EXCLUSIVE_ACQUIRE(LockBookmarks); - - if(!bookmarks.insert(std::make_pair(ModHashFromAddr(Address), bookmark)).second) - { - EXCLUSIVE_RELEASE(); - return BookmarkDelete(Address); - } - - return true; -} - -bool BookmarkGet(duint Address) -{ - ASSERT_DEBUGGING("Export call"); - SHARED_ACQUIRE(LockBookmarks); - - return (bookmarks.count(ModHashFromAddr(Address)) > 0); -} - -bool BookmarkDelete(duint Address) -{ - ASSERT_DEBUGGING("Export call"); - EXCLUSIVE_ACQUIRE(LockBookmarks); - - return (bookmarks.erase(ModHashFromAddr(Address)) > 0); -} - -void BookmarkDelRange(duint Start, duint End) -{ - ASSERT_DEBUGGING("Export call"); - - // Are all bookmarks going to be deleted? - // 0x00000000 - 0xFFFFFFFF - if(Start == 0 && End == ~0) - { - BookmarkClear(); - } - else - { - // Make sure 'Start' and 'End' reference the same module - duint moduleBase = ModBaseFromAddr(Start); - - if(moduleBase != ModBaseFromAddr(End)) - return; - - // Virtual -> relative offset - Start -= moduleBase; - End -= moduleBase; - - EXCLUSIVE_ACQUIRE(LockBookmarks); - for(auto itr = bookmarks.begin(); itr != bookmarks.end();) - { - const auto & currentBookmark = itr->second; - - // Ignore manually set entries - if(currentBookmark.manual) - { - ++itr; - continue; - } - - // [Start, End) - if(currentBookmark.addr >= Start && currentBookmark.addr < End) - itr = bookmarks.erase(itr); - else - ++itr; - } - } -} - -void BookmarkCacheSave(JSON Root) -{ - EXCLUSIVE_ACQUIRE(LockBookmarks); - - const JSON jsonBookmarks = json_array(); - const JSON jsonAutoBookmarks = json_array(); - - // Save to the JSON root - for(auto & itr : bookmarks) - { - JSON currentBookmark = json_object(); - - json_object_set_new(currentBookmark, "module", json_string(itr.second.mod)); - json_object_set_new(currentBookmark, "address", json_hex(itr.second.addr)); - - if(itr.second.manual) - json_array_append_new(jsonBookmarks, currentBookmark); - else - json_array_append_new(jsonAutoBookmarks, currentBookmark); - } - - if(json_array_size(jsonBookmarks)) - json_object_set(Root, "bookmarks", jsonBookmarks); - - if(json_array_size(jsonAutoBookmarks)) - json_object_set(Root, "autobookmarks", jsonAutoBookmarks); - - json_decref(jsonBookmarks); - json_decref(jsonAutoBookmarks); -} - -void BookmarkCacheLoad(JSON Root) -{ - EXCLUSIVE_ACQUIRE(LockBookmarks); - - // Inline lambda to parse each JSON entry - auto AddBookmarks = [](const JSON Object, bool Manual) - { - size_t i; - JSON value; - - json_array_foreach(Object, i, value) - { - BOOKMARKSINFO bookmarkInfo; - memset(&bookmarkInfo, 0, sizeof(BOOKMARKSINFO)); - - // Load the module name - const char* mod = json_string_value(json_object_get(value, "module")); - - if(mod && strlen(mod) < MAX_MODULE_SIZE) - strcpy_s(bookmarkInfo.mod, mod); - - // Load address and set auto-generated flag - bookmarkInfo.addr = (duint)json_hex_value(json_object_get(value, "address")); - bookmarkInfo.manual = Manual; - - const duint key = ModHashFromName(bookmarkInfo.mod) + bookmarkInfo.addr; - bookmarks.insert(std::make_pair(key, bookmarkInfo)); - } - }; - - // Remove existing entries - bookmarks.clear(); - - const JSON jsonBookmarks = json_object_get(Root, "bookmarks"); - const JSON jsonAutoBookmarks = json_object_get(Root, "autobookmarks"); - - // Load user-set bookmarks - if(jsonBookmarks) - AddBookmarks(jsonBookmarks, true); - - // Load auto-set bookmarks - if(jsonAutoBookmarks) - AddBookmarks(jsonAutoBookmarks, false); -} - -bool BookmarkEnum(BOOKMARKSINFO* List, size_t* Size) -{ - // The array container must be set, or the size must be set, or both - ASSERT_FALSE(!List && !Size); - SHARED_ACQUIRE(LockBookmarks); - - // Return the size if set - if(Size) - { - *Size = bookmarks.size() * sizeof(BOOKMARKSINFO); - - if(!List) - return true; - } - - // Copy struct and adjust the relative offset to a virtual address - for(auto & itr : bookmarks) - { - *List = itr.second; - List->addr += ModBaseFromName(List->mod); - - List++; - } - - return true; -} - -void BookmarkClear() -{ - EXCLUSIVE_ACQUIRE(LockBookmarks); - bookmarks.clear(); +#include "bookmark.h" +#include "threading.h" +#include "module.h" +#include "memory.h" + +std::unordered_map bookmarks; + +bool BookmarkSet(duint Address, bool Manual) +{ + ASSERT_DEBUGGING("Export call"); + + // Validate the incoming address + if(!MemIsValidReadPtr(Address)) + return false; + + BOOKMARKSINFO bookmark; + ModNameFromAddr(Address, bookmark.mod, true); + bookmark.addr = Address - ModBaseFromAddr(Address); + bookmark.manual = Manual; + + // Exclusive lock to insert new data + EXCLUSIVE_ACQUIRE(LockBookmarks); + + if(!bookmarks.insert(std::make_pair(ModHashFromAddr(Address), bookmark)).second) + { + EXCLUSIVE_RELEASE(); + return BookmarkDelete(Address); + } + + return true; +} + +bool BookmarkGet(duint Address) +{ + ASSERT_DEBUGGING("Export call"); + SHARED_ACQUIRE(LockBookmarks); + + return (bookmarks.count(ModHashFromAddr(Address)) > 0); +} + +bool BookmarkDelete(duint Address) +{ + ASSERT_DEBUGGING("Export call"); + EXCLUSIVE_ACQUIRE(LockBookmarks); + + return (bookmarks.erase(ModHashFromAddr(Address)) > 0); +} + +void BookmarkDelRange(duint Start, duint End) +{ + ASSERT_DEBUGGING("Export call"); + + // Are all bookmarks going to be deleted? + // 0x00000000 - 0xFFFFFFFF + if(Start == 0 && End == ~0) + { + BookmarkClear(); + } + else + { + // Make sure 'Start' and 'End' reference the same module + duint moduleBase = ModBaseFromAddr(Start); + + if(moduleBase != ModBaseFromAddr(End)) + return; + + // Virtual -> relative offset + Start -= moduleBase; + End -= moduleBase; + + EXCLUSIVE_ACQUIRE(LockBookmarks); + for(auto itr = bookmarks.begin(); itr != bookmarks.end();) + { + const auto & currentBookmark = itr->second; + + // Ignore manually set entries + if(currentBookmark.manual) + { + ++itr; + continue; + } + + // [Start, End) + if(currentBookmark.addr >= Start && currentBookmark.addr < End) + itr = bookmarks.erase(itr); + else + ++itr; + } + } +} + +void BookmarkCacheSave(JSON Root) +{ + EXCLUSIVE_ACQUIRE(LockBookmarks); + + const JSON jsonBookmarks = json_array(); + const JSON jsonAutoBookmarks = json_array(); + + // Save to the JSON root + for(auto & itr : bookmarks) + { + JSON currentBookmark = json_object(); + + json_object_set_new(currentBookmark, "module", json_string(itr.second.mod)); + json_object_set_new(currentBookmark, "address", json_hex(itr.second.addr)); + + if(itr.second.manual) + json_array_append_new(jsonBookmarks, currentBookmark); + else + json_array_append_new(jsonAutoBookmarks, currentBookmark); + } + + if(json_array_size(jsonBookmarks)) + json_object_set(Root, "bookmarks", jsonBookmarks); + + if(json_array_size(jsonAutoBookmarks)) + json_object_set(Root, "autobookmarks", jsonAutoBookmarks); + + json_decref(jsonBookmarks); + json_decref(jsonAutoBookmarks); +} + +void BookmarkCacheLoad(JSON Root) +{ + EXCLUSIVE_ACQUIRE(LockBookmarks); + + // Inline lambda to parse each JSON entry + auto AddBookmarks = [](const JSON Object, bool Manual) + { + size_t i; + JSON value; + + json_array_foreach(Object, i, value) + { + BOOKMARKSINFO bookmarkInfo; + memset(&bookmarkInfo, 0, sizeof(BOOKMARKSINFO)); + + // Load the module name + const char* mod = json_string_value(json_object_get(value, "module")); + + if(mod && strlen(mod) < MAX_MODULE_SIZE) + strcpy_s(bookmarkInfo.mod, mod); + + // Load address and set auto-generated flag + bookmarkInfo.addr = (duint)json_hex_value(json_object_get(value, "address")); + bookmarkInfo.manual = Manual; + + const duint key = ModHashFromName(bookmarkInfo.mod) + bookmarkInfo.addr; + bookmarks.insert(std::make_pair(key, bookmarkInfo)); + } + }; + + // Remove existing entries + bookmarks.clear(); + + const JSON jsonBookmarks = json_object_get(Root, "bookmarks"); + const JSON jsonAutoBookmarks = json_object_get(Root, "autobookmarks"); + + // Load user-set bookmarks + if(jsonBookmarks) + AddBookmarks(jsonBookmarks, true); + + // Load auto-set bookmarks + if(jsonAutoBookmarks) + AddBookmarks(jsonAutoBookmarks, false); +} + +bool BookmarkEnum(BOOKMARKSINFO* List, size_t* Size) +{ + // The array container must be set, or the size must be set, or both + ASSERT_FALSE(!List && !Size); + SHARED_ACQUIRE(LockBookmarks); + + // Return the size if set + if(Size) + { + *Size = bookmarks.size() * sizeof(BOOKMARKSINFO); + + if(!List) + return true; + } + + // Copy struct and adjust the relative offset to a virtual address + for(auto & itr : bookmarks) + { + *List = itr.second; + List->addr += ModBaseFromName(List->mod); + + List++; + } + + return true; +} + +void BookmarkClear() +{ + EXCLUSIVE_ACQUIRE(LockBookmarks); + bookmarks.clear(); } \ No newline at end of file diff --git a/src/dbg/bookmark.h b/src/dbg/bookmark.h index 9655b65f..da06325e 100644 --- a/src/dbg/bookmark.h +++ b/src/dbg/bookmark.h @@ -1,19 +1,19 @@ -#pragma once - -#include "_global.h" - -struct BOOKMARKSINFO -{ - char mod[MAX_MODULE_SIZE]; - duint addr; - bool manual; -}; - -bool BookmarkSet(duint Address, bool Manual); -bool BookmarkGet(duint Address); -bool BookmarkDelete(duint Address); -void BookmarkDelRange(duint Start, duint End); -void BookmarkCacheSave(JSON Root); -void BookmarkCacheLoad(JSON Root); -bool BookmarkEnum(BOOKMARKSINFO* List, size_t* Size); +#pragma once + +#include "_global.h" + +struct BOOKMARKSINFO +{ + char mod[MAX_MODULE_SIZE]; + duint addr; + bool manual; +}; + +bool BookmarkSet(duint Address, bool Manual); +bool BookmarkGet(duint Address); +bool BookmarkDelete(duint Address); +void BookmarkDelRange(duint Start, duint End); +void BookmarkCacheSave(JSON Root); +void BookmarkCacheLoad(JSON Root); +bool BookmarkEnum(BOOKMARKSINFO* List, size_t* Size); void BookmarkClear(); \ No newline at end of file diff --git a/src/dbg/breakpoint.cpp b/src/dbg/breakpoint.cpp index 4da1fefc..31c3ef46 100644 --- a/src/dbg/breakpoint.cpp +++ b/src/dbg/breakpoint.cpp @@ -1,381 +1,381 @@ -/** - @file breakpoint.cpp - - @brief Implements the breakpoint class. - */ - -#include "breakpoint.h" -#include "memory.h" -#include "threading.h" -#include "module.h" - -typedef std::pair BreakpointKey; -std::map breakpoints; - -BREAKPOINT* BpInfoFromAddr(BP_TYPE Type, duint Address) -{ - // - // NOTE: THIS DOES _NOT_ USE LOCKS - // - auto found = breakpoints.find(BreakpointKey(Type, ModHashFromAddr(Address))); - - // Was the module found with this address? - if(found == breakpoints.end()) - return nullptr; - - return &found->second; -} - -int BpGetList(std::vector* List) -{ - SHARED_ACQUIRE(LockBreakpoints); - - // Did the caller request an output? - if(List) - { - // Enumerate all breakpoints in the global list, fixing the relative - // offset to a virtual address - for(auto & i : breakpoints) - { - BREAKPOINT currentBp = i.second; - currentBp.addr += ModBaseFromName(currentBp.mod); - currentBp.active = MemIsValidReadPtr(currentBp.addr); - - List->push_back(currentBp); - } - } - - return (int)breakpoints.size(); -} - -bool BpNew(duint Address, bool Enable, bool Singleshot, short OldBytes, BP_TYPE Type, DWORD TitanType, const char* Name) -{ - ASSERT_DEBUGGING("Export call"); - - // Fail if the address is a bad memory region - if(!MemIsValidReadPtr(Address)) - return false; - - // Fail if the breakpoint already exists - if(BpGet(Address, Type, Name, nullptr)) - return false; - - // Default to an empty name if one wasn't supplied - if(!Name) - Name = ""; - - BREAKPOINT bp; - memset(&bp, 0, sizeof(BREAKPOINT)); - - ModNameFromAddr(Address, bp.mod, true); - strcpy_s(bp.name, Name); - - bp.active = true; - bp.addr = Address - ModBaseFromAddr(Address); - bp.enabled = Enable; - bp.oldbytes = OldBytes; - bp.singleshoot = Singleshot; - bp.titantype = TitanType; - bp.type = Type; - - // Insert new entry to the global list - EXCLUSIVE_ACQUIRE(LockBreakpoints); - - breakpoints.insert(std::make_pair(BreakpointKey(Type, ModHashFromAddr(Address)), bp)); - return true; -} - -bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp) -{ - ASSERT_DEBUGGING("Export call"); - SHARED_ACQUIRE(LockBreakpoints); - - // Name is optional - if(!Name || Name[0] == '\0') - { - // Perform a lookup by address only - BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address); - - if(!bpInfo) - return false; - - // Succeed even if the user didn't request anything - if(!Bp) - return true; - - *Bp = *bpInfo; - Bp->addr += ModBaseFromAddr(Address); - Bp->active = MemIsValidReadPtr(Bp->addr); - return true; - } - - // Do a lookup by breakpoint name - for(auto & i : breakpoints) - { - // Do the names match? - if(strcmp(Name, i.second.name) != 0) - continue; - - // Fill out the optional user buffer - if(Bp) - { - *Bp = i.second; - Bp->addr += ModBaseFromAddr(Address); - Bp->active = MemIsValidReadPtr(Bp->addr); - } - - // Return true if the name was found at all - return true; - } - - return false; -} - -bool BpDelete(duint Address, BP_TYPE Type) -{ - ASSERT_DEBUGGING("Command function call"); - EXCLUSIVE_ACQUIRE(LockBreakpoints); - - // Erase the index from the global list - return (breakpoints.erase(BreakpointKey(Type, ModHashFromAddr(Address))) > 0); -} - -bool BpEnable(duint Address, BP_TYPE Type, bool Enable) -{ - ASSERT_DEBUGGING("Command function call"); - EXCLUSIVE_ACQUIRE(LockBreakpoints); - - // Check if the breakpoint exists first - BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address); - - if(!bpInfo) - return false; - - bpInfo->enabled = Enable; - return true; -} - -bool BpSetName(duint Address, BP_TYPE Type, const char* Name) -{ - ASSERT_DEBUGGING("Future(?): This is not used anywhere"); - EXCLUSIVE_ACQUIRE(LockBreakpoints); - - // If a name wasn't supplied, set to nothing - if(!Name) - Name = ""; - - // Check if the breakpoint exists first - BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address); - - if(!bpInfo) - return false; - - strcpy_s(bpInfo->name, Name); - return true; -} - -bool BpSetTitanType(duint Address, BP_TYPE Type, int TitanType) -{ - ASSERT_DEBUGGING("Command function call"); - EXCLUSIVE_ACQUIRE(LockBreakpoints); - - // Set the TitanEngine type, separate from BP_TYPE - BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address); - - if(!bpInfo) - return false; - - bpInfo->titantype = TitanType; - return true; -} - -bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module) -{ - ASSERT_DEBUGGING("Export call"); - SHARED_ACQUIRE(LockBreakpoints); - - // Loop each entry, executing the user's callback - bool callbackStatus = true; - - for (auto i = breakpoints.begin(); i != breakpoints.end();) - { - auto j = i; - ++i; // Increment here, because the callback might remove the current entry - - // If a module name was sent, check it - if(Module && Module[0] != '\0') - { - if(strcmp(j->second.mod, Module) != 0) - continue; - } - - BREAKPOINT bpInfo = j->second; - bpInfo.addr += ModBaseFromName(bpInfo.mod); - bpInfo.active = MemIsValidReadPtr(bpInfo.addr); - - // Lock must be released due to callback sub-locks - SHARED_RELEASE(); - - // Execute the callback - if(!EnumCallback(&bpInfo)) - callbackStatus = false; - - // Restore the breakpoint map lock - SHARED_REACQUIRE(); - } - - return callbackStatus; -} - -bool BpEnumAll(BPENUMCALLBACK EnumCallback) -{ - return BpEnumAll(EnumCallback, nullptr); -} - -int BpGetCount(BP_TYPE Type, bool EnabledOnly) -{ - SHARED_ACQUIRE(LockBreakpoints); - - // Count the number of enabled/disabled breakpoint types - int count = 0; - - for(auto & i : breakpoints) - { - // Check if the type matches - if(i.first.first != Type) - continue; - - // If it's not enabled, skip it - if(EnabledOnly && !i.second.enabled) - continue; - - count++; - } - - return count; -} - -void BpToBridge(const BREAKPOINT* Bp, BRIDGEBP* BridgeBp) -{ - // - // Convert a debugger breakpoint to an open/exported - // bridge breakpoint - // - ASSERT_NONNULL(Bp); - ASSERT_NONNULL(BridgeBp); - - memset(BridgeBp, 0, sizeof(BRIDGEBP)); - strcpy_s(BridgeBp->mod, Bp->mod); - strcpy_s(BridgeBp->name, Bp->name); - - BridgeBp->active = Bp->active; - BridgeBp->addr = Bp->addr; - BridgeBp->enabled = Bp->enabled; - BridgeBp->singleshoot = Bp->singleshoot; - - switch(Bp->type) - { - case BPNORMAL: - BridgeBp->type = bp_normal; - break; - case BPHARDWARE: - BridgeBp->type = bp_hardware; - break; - case BPMEMORY: - BridgeBp->type = bp_memory; - break; - default: - BridgeBp->type = bp_none; - break; - } -} - -void BpCacheSave(JSON Root) -{ - EXCLUSIVE_ACQUIRE(LockBreakpoints); - - // Create a JSON array to store each sub-object with a breakpoint - const JSON jsonBreakpoints = json_array(); - - // Loop all breakpoints - for(auto & i : breakpoints) - { - auto & breakpoint = i.second; - - // Ignore single-shot breakpoints - if(breakpoint.singleshoot) - continue; - - JSON jsonObj = json_object(); - json_object_set_new(jsonObj, "address", json_hex(breakpoint.addr)); - json_object_set_new(jsonObj, "enabled", json_boolean(breakpoint.enabled)); - - // "Normal" breakpoints save the old data - if(breakpoint.type == BPNORMAL) - json_object_set_new(jsonObj, "oldbytes", json_hex(breakpoint.oldbytes)); - - json_object_set_new(jsonObj, "type", json_integer(breakpoint.type)); - json_object_set_new(jsonObj, "titantype", json_hex(breakpoint.titantype)); - json_object_set_new(jsonObj, "name", json_string(breakpoint.name)); - json_object_set_new(jsonObj, "module", json_string(breakpoint.mod)); - json_array_append_new(jsonBreakpoints, jsonObj); - } - - if(json_array_size(jsonBreakpoints)) - json_object_set(Root, "breakpoints", jsonBreakpoints); - - // Notify garbage collector - json_decref(jsonBreakpoints); -} - -void BpCacheLoad(JSON Root) -{ - EXCLUSIVE_ACQUIRE(LockBreakpoints); - - // Remove all existing elements - breakpoints.clear(); - - // Get a handle to the root object -> breakpoints subtree - const JSON jsonBreakpoints = json_object_get(Root, "breakpoints"); - - // Return if there was nothing to load - if(!jsonBreakpoints) - return; - - size_t i; - JSON value; - json_array_foreach(jsonBreakpoints, i, value) - { - BREAKPOINT breakpoint; - memset(&breakpoint, 0, sizeof(BREAKPOINT)); - - if(breakpoint.type == BPNORMAL) - breakpoint.oldbytes = (short)json_hex_value(json_object_get(value, "oldbytes")); - breakpoint.type = (BP_TYPE)json_integer_value(json_object_get(value, "type")); - breakpoint.addr = (duint)json_hex_value(json_object_get(value, "address")); - breakpoint.enabled = json_boolean_value(json_object_get(value, "enabled")); - breakpoint.titantype = (DWORD)json_hex_value(json_object_get(value, "titantype")); - - // Name - const char* name = json_string_value(json_object_get(value, "name")); - - if(name) - strcpy_s(breakpoint.name, name); - - // Module - const char* mod = json_string_value(json_object_get(value, "module")); - - if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE) - strcpy_s(breakpoint.mod, mod); - - // Build the hash map key: MOD_HASH + ADDRESS - const duint key = ModHashFromName(breakpoint.mod) + breakpoint.addr; - breakpoints.insert(std::make_pair(BreakpointKey(breakpoint.type, key), breakpoint)); - } -} - -void BpClear() -{ - EXCLUSIVE_ACQUIRE(LockBreakpoints); - breakpoints.clear(); +/** + @file breakpoint.cpp + + @brief Implements the breakpoint class. + */ + +#include "breakpoint.h" +#include "memory.h" +#include "threading.h" +#include "module.h" + +typedef std::pair BreakpointKey; +std::map breakpoints; + +BREAKPOINT* BpInfoFromAddr(BP_TYPE Type, duint Address) +{ + // + // NOTE: THIS DOES _NOT_ USE LOCKS + // + auto found = breakpoints.find(BreakpointKey(Type, ModHashFromAddr(Address))); + + // Was the module found with this address? + if(found == breakpoints.end()) + return nullptr; + + return &found->second; +} + +int BpGetList(std::vector* List) +{ + SHARED_ACQUIRE(LockBreakpoints); + + // Did the caller request an output? + if(List) + { + // Enumerate all breakpoints in the global list, fixing the relative + // offset to a virtual address + for(auto & i : breakpoints) + { + BREAKPOINT currentBp = i.second; + currentBp.addr += ModBaseFromName(currentBp.mod); + currentBp.active = MemIsValidReadPtr(currentBp.addr); + + List->push_back(currentBp); + } + } + + return (int)breakpoints.size(); +} + +bool BpNew(duint Address, bool Enable, bool Singleshot, short OldBytes, BP_TYPE Type, DWORD TitanType, const char* Name) +{ + ASSERT_DEBUGGING("Export call"); + + // Fail if the address is a bad memory region + if(!MemIsValidReadPtr(Address)) + return false; + + // Fail if the breakpoint already exists + if(BpGet(Address, Type, Name, nullptr)) + return false; + + // Default to an empty name if one wasn't supplied + if(!Name) + Name = ""; + + BREAKPOINT bp; + memset(&bp, 0, sizeof(BREAKPOINT)); + + ModNameFromAddr(Address, bp.mod, true); + strcpy_s(bp.name, Name); + + bp.active = true; + bp.addr = Address - ModBaseFromAddr(Address); + bp.enabled = Enable; + bp.oldbytes = OldBytes; + bp.singleshoot = Singleshot; + bp.titantype = TitanType; + bp.type = Type; + + // Insert new entry to the global list + EXCLUSIVE_ACQUIRE(LockBreakpoints); + + breakpoints.insert(std::make_pair(BreakpointKey(Type, ModHashFromAddr(Address)), bp)); + return true; +} + +bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp) +{ + ASSERT_DEBUGGING("Export call"); + SHARED_ACQUIRE(LockBreakpoints); + + // Name is optional + if(!Name || Name[0] == '\0') + { + // Perform a lookup by address only + BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address); + + if(!bpInfo) + return false; + + // Succeed even if the user didn't request anything + if(!Bp) + return true; + + *Bp = *bpInfo; + Bp->addr += ModBaseFromAddr(Address); + Bp->active = MemIsValidReadPtr(Bp->addr); + return true; + } + + // Do a lookup by breakpoint name + for(auto & i : breakpoints) + { + // Do the names match? + if(strcmp(Name, i.second.name) != 0) + continue; + + // Fill out the optional user buffer + if(Bp) + { + *Bp = i.second; + Bp->addr += ModBaseFromAddr(Address); + Bp->active = MemIsValidReadPtr(Bp->addr); + } + + // Return true if the name was found at all + return true; + } + + return false; +} + +bool BpDelete(duint Address, BP_TYPE Type) +{ + ASSERT_DEBUGGING("Command function call"); + EXCLUSIVE_ACQUIRE(LockBreakpoints); + + // Erase the index from the global list + return (breakpoints.erase(BreakpointKey(Type, ModHashFromAddr(Address))) > 0); +} + +bool BpEnable(duint Address, BP_TYPE Type, bool Enable) +{ + ASSERT_DEBUGGING("Command function call"); + EXCLUSIVE_ACQUIRE(LockBreakpoints); + + // Check if the breakpoint exists first + BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address); + + if(!bpInfo) + return false; + + bpInfo->enabled = Enable; + return true; +} + +bool BpSetName(duint Address, BP_TYPE Type, const char* Name) +{ + ASSERT_DEBUGGING("Future(?): This is not used anywhere"); + EXCLUSIVE_ACQUIRE(LockBreakpoints); + + // If a name wasn't supplied, set to nothing + if(!Name) + Name = ""; + + // Check if the breakpoint exists first + BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address); + + if(!bpInfo) + return false; + + strcpy_s(bpInfo->name, Name); + return true; +} + +bool BpSetTitanType(duint Address, BP_TYPE Type, int TitanType) +{ + ASSERT_DEBUGGING("Command function call"); + EXCLUSIVE_ACQUIRE(LockBreakpoints); + + // Set the TitanEngine type, separate from BP_TYPE + BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address); + + if(!bpInfo) + return false; + + bpInfo->titantype = TitanType; + return true; +} + +bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module) +{ + ASSERT_DEBUGGING("Export call"); + SHARED_ACQUIRE(LockBreakpoints); + + // Loop each entry, executing the user's callback + bool callbackStatus = true; + + for (auto i = breakpoints.begin(); i != breakpoints.end();) + { + auto j = i; + ++i; // Increment here, because the callback might remove the current entry + + // If a module name was sent, check it + if(Module && Module[0] != '\0') + { + if(strcmp(j->second.mod, Module) != 0) + continue; + } + + BREAKPOINT bpInfo = j->second; + bpInfo.addr += ModBaseFromName(bpInfo.mod); + bpInfo.active = MemIsValidReadPtr(bpInfo.addr); + + // Lock must be released due to callback sub-locks + SHARED_RELEASE(); + + // Execute the callback + if(!EnumCallback(&bpInfo)) + callbackStatus = false; + + // Restore the breakpoint map lock + SHARED_REACQUIRE(); + } + + return callbackStatus; +} + +bool BpEnumAll(BPENUMCALLBACK EnumCallback) +{ + return BpEnumAll(EnumCallback, nullptr); +} + +int BpGetCount(BP_TYPE Type, bool EnabledOnly) +{ + SHARED_ACQUIRE(LockBreakpoints); + + // Count the number of enabled/disabled breakpoint types + int count = 0; + + for(auto & i : breakpoints) + { + // Check if the type matches + if(i.first.first != Type) + continue; + + // If it's not enabled, skip it + if(EnabledOnly && !i.second.enabled) + continue; + + count++; + } + + return count; +} + +void BpToBridge(const BREAKPOINT* Bp, BRIDGEBP* BridgeBp) +{ + // + // Convert a debugger breakpoint to an open/exported + // bridge breakpoint + // + ASSERT_NONNULL(Bp); + ASSERT_NONNULL(BridgeBp); + + memset(BridgeBp, 0, sizeof(BRIDGEBP)); + strcpy_s(BridgeBp->mod, Bp->mod); + strcpy_s(BridgeBp->name, Bp->name); + + BridgeBp->active = Bp->active; + BridgeBp->addr = Bp->addr; + BridgeBp->enabled = Bp->enabled; + BridgeBp->singleshoot = Bp->singleshoot; + + switch(Bp->type) + { + case BPNORMAL: + BridgeBp->type = bp_normal; + break; + case BPHARDWARE: + BridgeBp->type = bp_hardware; + break; + case BPMEMORY: + BridgeBp->type = bp_memory; + break; + default: + BridgeBp->type = bp_none; + break; + } +} + +void BpCacheSave(JSON Root) +{ + EXCLUSIVE_ACQUIRE(LockBreakpoints); + + // Create a JSON array to store each sub-object with a breakpoint + const JSON jsonBreakpoints = json_array(); + + // Loop all breakpoints + for(auto & i : breakpoints) + { + auto & breakpoint = i.second; + + // Ignore single-shot breakpoints + if(breakpoint.singleshoot) + continue; + + JSON jsonObj = json_object(); + json_object_set_new(jsonObj, "address", json_hex(breakpoint.addr)); + json_object_set_new(jsonObj, "enabled", json_boolean(breakpoint.enabled)); + + // "Normal" breakpoints save the old data + if(breakpoint.type == BPNORMAL) + json_object_set_new(jsonObj, "oldbytes", json_hex(breakpoint.oldbytes)); + + json_object_set_new(jsonObj, "type", json_integer(breakpoint.type)); + json_object_set_new(jsonObj, "titantype", json_hex(breakpoint.titantype)); + json_object_set_new(jsonObj, "name", json_string(breakpoint.name)); + json_object_set_new(jsonObj, "module", json_string(breakpoint.mod)); + json_array_append_new(jsonBreakpoints, jsonObj); + } + + if(json_array_size(jsonBreakpoints)) + json_object_set(Root, "breakpoints", jsonBreakpoints); + + // Notify garbage collector + json_decref(jsonBreakpoints); +} + +void BpCacheLoad(JSON Root) +{ + EXCLUSIVE_ACQUIRE(LockBreakpoints); + + // Remove all existing elements + breakpoints.clear(); + + // Get a handle to the root object -> breakpoints subtree + const JSON jsonBreakpoints = json_object_get(Root, "breakpoints"); + + // Return if there was nothing to load + if(!jsonBreakpoints) + return; + + size_t i; + JSON value; + json_array_foreach(jsonBreakpoints, i, value) + { + BREAKPOINT breakpoint; + memset(&breakpoint, 0, sizeof(BREAKPOINT)); + + if(breakpoint.type == BPNORMAL) + breakpoint.oldbytes = (short)json_hex_value(json_object_get(value, "oldbytes")); + breakpoint.type = (BP_TYPE)json_integer_value(json_object_get(value, "type")); + breakpoint.addr = (duint)json_hex_value(json_object_get(value, "address")); + breakpoint.enabled = json_boolean_value(json_object_get(value, "enabled")); + breakpoint.titantype = (DWORD)json_hex_value(json_object_get(value, "titantype")); + + // Name + const char* name = json_string_value(json_object_get(value, "name")); + + if(name) + strcpy_s(breakpoint.name, name); + + // Module + const char* mod = json_string_value(json_object_get(value, "module")); + + if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE) + strcpy_s(breakpoint.mod, mod); + + // Build the hash map key: MOD_HASH + ADDRESS + const duint key = ModHashFromName(breakpoint.mod) + breakpoint.addr; + breakpoints.insert(std::make_pair(BreakpointKey(breakpoint.type, key), breakpoint)); + } +} + +void BpClear() +{ + EXCLUSIVE_ACQUIRE(LockBreakpoints); + breakpoints.clear(); } \ No newline at end of file diff --git a/src/dbg/breakpoint.h b/src/dbg/breakpoint.h index 782744dd..fa6ae86c 100644 --- a/src/dbg/breakpoint.h +++ b/src/dbg/breakpoint.h @@ -1,49 +1,49 @@ -#pragma once - -#include "_global.h" - -#define TITANSETDRX(titantype, drx) titantype &= 0x0FF; titantype |= (drx<<8) -#define TITANGETDRX(titantype) (titantype >> 8) & 0xF -#define TITANSETTYPE(titantype, type) titantype &= 0xF0F; titantype |= (type<<4) -#define TITANGETTYPE(titantype) (titantype >> 4) & 0xF -#define TITANSETSIZE(titantype, size) titantype &= 0xFF0; titantype |= size; -#define TITANGETSIZE(titantype) titantype & 0xF - -enum BP_TYPE -{ - BPNORMAL = 0, - BPHARDWARE = 1, - BPMEMORY = 2 -}; - -struct BREAKPOINT -{ - duint addr; - bool enabled; - bool singleshoot; - bool active; - short oldbytes; - BP_TYPE type; - DWORD titantype; - char name[MAX_BREAKPOINT_SIZE]; - char mod[MAX_MODULE_SIZE]; -}; - -// Breakpoint enumeration callback -typedef bool (*BPENUMCALLBACK)(const BREAKPOINT* bp); - -BREAKPOINT* BpInfoFromAddr(BP_TYPE Type, duint Address); -int BpGetList(std::vector* List); -bool BpNew(duint Address, bool Enable, bool Singleshot, short OldBytes, BP_TYPE Type, DWORD TitanType, const char* Name); -bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp); -bool BpDelete(duint Address, BP_TYPE Type); -bool BpEnable(duint Address, BP_TYPE Type, bool Enable); -bool BpSetName(duint Address, BP_TYPE Type, const char* Name); -bool BpSetTitanType(duint Address, BP_TYPE Type, int TitanType); -bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module); -bool BpEnumAll(BPENUMCALLBACK EnumCallback); -int BpGetCount(BP_TYPE Type, bool EnabledOnly = false); -void BpToBridge(const BREAKPOINT* Bp, BRIDGEBP* BridgeBp); -void BpCacheSave(JSON Root); -void BpCacheLoad(JSON Root); +#pragma once + +#include "_global.h" + +#define TITANSETDRX(titantype, drx) titantype &= 0x0FF; titantype |= (drx<<8) +#define TITANGETDRX(titantype) (titantype >> 8) & 0xF +#define TITANSETTYPE(titantype, type) titantype &= 0xF0F; titantype |= (type<<4) +#define TITANGETTYPE(titantype) (titantype >> 4) & 0xF +#define TITANSETSIZE(titantype, size) titantype &= 0xFF0; titantype |= size; +#define TITANGETSIZE(titantype) titantype & 0xF + +enum BP_TYPE +{ + BPNORMAL = 0, + BPHARDWARE = 1, + BPMEMORY = 2 +}; + +struct BREAKPOINT +{ + duint addr; + bool enabled; + bool singleshoot; + bool active; + short oldbytes; + BP_TYPE type; + DWORD titantype; + char name[MAX_BREAKPOINT_SIZE]; + char mod[MAX_MODULE_SIZE]; +}; + +// Breakpoint enumeration callback +typedef bool (*BPENUMCALLBACK)(const BREAKPOINT* bp); + +BREAKPOINT* BpInfoFromAddr(BP_TYPE Type, duint Address); +int BpGetList(std::vector* List); +bool BpNew(duint Address, bool Enable, bool Singleshot, short OldBytes, BP_TYPE Type, DWORD TitanType, const char* Name); +bool BpGet(duint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp); +bool BpDelete(duint Address, BP_TYPE Type); +bool BpEnable(duint Address, BP_TYPE Type, bool Enable); +bool BpSetName(duint Address, BP_TYPE Type, const char* Name); +bool BpSetTitanType(duint Address, BP_TYPE Type, int TitanType); +bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module); +bool BpEnumAll(BPENUMCALLBACK EnumCallback); +int BpGetCount(BP_TYPE Type, bool EnabledOnly = false); +void BpToBridge(const BREAKPOINT* Bp, BRIDGEBP* BridgeBp); +void BpCacheSave(JSON Root); +void BpCacheLoad(JSON Root); void BpClear(); \ No newline at end of file diff --git a/src/dbg/capstone/arm.h b/src/dbg/capstone/arm.h index 588dae2a..a60373dc 100644 --- a/src/dbg/capstone/arm.h +++ b/src/dbg/capstone/arm.h @@ -1,897 +1,897 @@ -#ifndef CAPSTONE_ARM_H -#define CAPSTONE_ARM_H - -/* Capstone Disassembly Engine */ -/* By Nguyen Anh Quynh , 2013-2014 */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "platform.h" - -#ifdef _MSC_VER -#pragma warning(disable:4201) -#endif - -//> ARM shift type -typedef enum arm_shifter -{ - ARM_SFT_INVALID = 0, - ARM_SFT_ASR, // shift with immediate const - ARM_SFT_LSL, // shift with immediate const - ARM_SFT_LSR, // shift with immediate const - ARM_SFT_ROR, // shift with immediate const - ARM_SFT_RRX, // shift with immediate const - ARM_SFT_ASR_REG, // shift with register - ARM_SFT_LSL_REG, // shift with register - ARM_SFT_LSR_REG, // shift with register - ARM_SFT_ROR_REG, // shift with register - ARM_SFT_RRX_REG, // shift with register -} arm_shifter; - -//> ARM condition code -typedef enum arm_cc -{ - ARM_CC_INVALID = 0, - ARM_CC_EQ, // Equal Equal - ARM_CC_NE, // Not equal Not equal, or unordered - ARM_CC_HS, // Carry set >, ==, or unordered - ARM_CC_LO, // Carry clear Less than - ARM_CC_MI, // Minus, negative Less than - ARM_CC_PL, // Plus, positive or zero >, ==, or unordered - ARM_CC_VS, // Overflow Unordered - ARM_CC_VC, // No overflow Not unordered - ARM_CC_HI, // Unsigned higher Greater than, or unordered - ARM_CC_LS, // Unsigned lower or same Less than or equal - ARM_CC_GE, // Greater than or equal Greater than or equal - ARM_CC_LT, // Less than Less than, or unordered - ARM_CC_GT, // Greater than Greater than - ARM_CC_LE, // Less than or equal <, ==, or unordered - ARM_CC_AL // Always (unconditional) Always (unconditional) -} arm_cc; - -typedef enum arm_sysreg -{ - //> Special registers for MSR - ARM_SYSREG_INVALID = 0, - - // SPSR* registers can be OR combined - ARM_SYSREG_SPSR_C = 1, - ARM_SYSREG_SPSR_X = 2, - ARM_SYSREG_SPSR_S = 4, - ARM_SYSREG_SPSR_F = 8, - - // CPSR* registers can be OR combined - ARM_SYSREG_CPSR_C = 16, - ARM_SYSREG_CPSR_X = 32, - ARM_SYSREG_CPSR_S = 64, - ARM_SYSREG_CPSR_F = 128, - - // independent registers - ARM_SYSREG_APSR = 256, - ARM_SYSREG_APSR_G, - ARM_SYSREG_APSR_NZCVQ, - ARM_SYSREG_APSR_NZCVQG, - - ARM_SYSREG_IAPSR, - ARM_SYSREG_IAPSR_G, - ARM_SYSREG_IAPSR_NZCVQG, - - ARM_SYSREG_EAPSR, - ARM_SYSREG_EAPSR_G, - ARM_SYSREG_EAPSR_NZCVQG, - - ARM_SYSREG_XPSR, - ARM_SYSREG_XPSR_G, - ARM_SYSREG_XPSR_NZCVQG, - - ARM_SYSREG_IPSR, - ARM_SYSREG_EPSR, - ARM_SYSREG_IEPSR, - - ARM_SYSREG_MSP, - ARM_SYSREG_PSP, - ARM_SYSREG_PRIMASK, - ARM_SYSREG_BASEPRI, - ARM_SYSREG_BASEPRI_MAX, - ARM_SYSREG_FAULTMASK, - ARM_SYSREG_CONTROL, -} arm_sysreg; - -//> The memory barrier constants map directly to the 4-bit encoding of -//> the option field for Memory Barrier operations. -typedef enum arm_mem_barrier -{ - ARM_MB_INVALID = 0, - ARM_MB_RESERVED_0, - ARM_MB_OSHLD, - ARM_MB_OSHST, - ARM_MB_OSH, - ARM_MB_RESERVED_4, - ARM_MB_NSHLD, - ARM_MB_NSHST, - ARM_MB_NSH, - ARM_MB_RESERVED_8, - ARM_MB_ISHLD, - ARM_MB_ISHST, - ARM_MB_ISH, - ARM_MB_RESERVED_12, - ARM_MB_LD, - ARM_MB_ST, - ARM_MB_SY, -} arm_mem_barrier; - -//> Operand type for instruction's operands -typedef enum arm_op_type -{ - ARM_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). - ARM_OP_REG, // = CS_OP_REG (Register operand). - ARM_OP_IMM, // = CS_OP_IMM (Immediate operand). - ARM_OP_MEM, // = CS_OP_MEM (Memory operand). - ARM_OP_FP, // = CS_OP_FP (Floating-Point operand). - ARM_OP_CIMM = 64, // C-Immediate (coprocessor registers) - ARM_OP_PIMM, // P-Immediate (coprocessor registers) - ARM_OP_SETEND, // operand for SETEND instruction - ARM_OP_SYSREG, // MSR/MSR special register operand -} arm_op_type; - -//> Operand type for SETEND instruction -typedef enum arm_setend_type -{ - ARM_SETEND_INVALID = 0, // Uninitialized. - ARM_SETEND_BE, // BE operand. - ARM_SETEND_LE, // LE operand -} arm_setend_type; - -typedef enum arm_cpsmode_type -{ - ARM_CPSMODE_INVALID = 0, - ARM_CPSMODE_IE = 2, - ARM_CPSMODE_ID = 3 -} arm_cpsmode_type; - -//> Operand type for SETEND instruction -typedef enum arm_cpsflag_type -{ - ARM_CPSFLAG_INVALID = 0, - ARM_CPSFLAG_F = 1, - ARM_CPSFLAG_I = 2, - ARM_CPSFLAG_A = 4, - ARM_CPSFLAG_NONE = 16, // no flag -} arm_cpsflag_type; - -//> Data type for elements of vector instructions. -typedef enum arm_vectordata_type -{ - ARM_VECTORDATA_INVALID = 0, - - // Integer type - ARM_VECTORDATA_I8, - ARM_VECTORDATA_I16, - ARM_VECTORDATA_I32, - ARM_VECTORDATA_I64, - - // Signed integer type - ARM_VECTORDATA_S8, - ARM_VECTORDATA_S16, - ARM_VECTORDATA_S32, - ARM_VECTORDATA_S64, - - // Unsigned integer type - ARM_VECTORDATA_U8, - ARM_VECTORDATA_U16, - ARM_VECTORDATA_U32, - ARM_VECTORDATA_U64, - - // Data type for VMUL/VMULL - ARM_VECTORDATA_P8, - - // Floating type - ARM_VECTORDATA_F32, - ARM_VECTORDATA_F64, - - // Convert float <-> float - ARM_VECTORDATA_F16F64, // f16.f64 - ARM_VECTORDATA_F64F16, // f64.f16 - ARM_VECTORDATA_F32F16, // f32.f16 - ARM_VECTORDATA_F16F32, // f32.f16 - ARM_VECTORDATA_F64F32, // f64.f32 - ARM_VECTORDATA_F32F64, // f32.f64 - - // Convert integer <-> float - ARM_VECTORDATA_S32F32, // s32.f32 - ARM_VECTORDATA_U32F32, // u32.f32 - ARM_VECTORDATA_F32S32, // f32.s32 - ARM_VECTORDATA_F32U32, // f32.u32 - ARM_VECTORDATA_F64S16, // f64.s16 - ARM_VECTORDATA_F32S16, // f32.s16 - ARM_VECTORDATA_F64S32, // f64.s32 - ARM_VECTORDATA_S16F64, // s16.f64 - ARM_VECTORDATA_S16F32, // s16.f64 - ARM_VECTORDATA_S32F64, // s32.f64 - ARM_VECTORDATA_U16F64, // u16.f64 - ARM_VECTORDATA_U16F32, // u16.f32 - ARM_VECTORDATA_U32F64, // u32.f64 - ARM_VECTORDATA_F64U16, // f64.u16 - ARM_VECTORDATA_F32U16, // f32.u16 - ARM_VECTORDATA_F64U32, // f64.u32 -} arm_vectordata_type; - -// Instruction's operand referring to memory -// This is associated with ARM_OP_MEM operand type above -typedef struct arm_op_mem -{ - unsigned int base; // base register - unsigned int index; // index register - int scale; // scale for index register (can be 1, or -1) - int disp; // displacement/offset value -} arm_op_mem; - -// Instruction operand -typedef struct cs_arm_op -{ - int vector_index; // Vector Index for some vector operands (or -1 if irrelevant) - struct - { - arm_shifter type; - unsigned int value; - } shift; - arm_op_type type; // operand type - union - { - unsigned int reg; // register value for REG/SYSREG operand - int32_t imm; // immediate value for C-IMM, P-IMM or IMM operand - double fp; // floating point value for FP operand - arm_op_mem mem; // base/index/scale/disp value for MEM operand - arm_setend_type setend; // SETEND instruction's operand type - }; - // in some instructions, an operand can be subtracted or added to - // the base register, - bool subtracted; // if TRUE, this operand is subtracted. otherwise, it is added. -} cs_arm_op; - -// Instruction structure -typedef struct cs_arm -{ - bool usermode; // User-mode registers to be loaded (for LDM/STM instructions) - int vector_size; // Scalar size for vector instructions - arm_vectordata_type vector_data; // Data type for elements of vector instructions - arm_cpsmode_type cps_mode; // CPS mode for CPS instruction - arm_cpsflag_type cps_flag; // CPS mode for CPS instruction - arm_cc cc; // conditional code for this insn - bool update_flags; // does this insn update flags? - bool writeback; // does this insn write-back? - arm_mem_barrier mem_barrier; // Option for some memory barrier instructions - - // Number of operands of this instruction, - // or 0 when instruction has no operand. - uint8_t op_count; - - cs_arm_op operands[36]; // operands for this instruction. -} cs_arm; - -//> ARM registers -typedef enum arm_reg -{ - ARM_REG_INVALID = 0, - ARM_REG_APSR, - ARM_REG_APSR_NZCV, - ARM_REG_CPSR, - ARM_REG_FPEXC, - ARM_REG_FPINST, - ARM_REG_FPSCR, - ARM_REG_FPSCR_NZCV, - ARM_REG_FPSID, - ARM_REG_ITSTATE, - ARM_REG_LR, - ARM_REG_PC, - ARM_REG_SP, - ARM_REG_SPSR, - ARM_REG_D0, - ARM_REG_D1, - ARM_REG_D2, - ARM_REG_D3, - ARM_REG_D4, - ARM_REG_D5, - ARM_REG_D6, - ARM_REG_D7, - ARM_REG_D8, - ARM_REG_D9, - ARM_REG_D10, - ARM_REG_D11, - ARM_REG_D12, - ARM_REG_D13, - ARM_REG_D14, - ARM_REG_D15, - ARM_REG_D16, - ARM_REG_D17, - ARM_REG_D18, - ARM_REG_D19, - ARM_REG_D20, - ARM_REG_D21, - ARM_REG_D22, - ARM_REG_D23, - ARM_REG_D24, - ARM_REG_D25, - ARM_REG_D26, - ARM_REG_D27, - ARM_REG_D28, - ARM_REG_D29, - ARM_REG_D30, - ARM_REG_D31, - ARM_REG_FPINST2, - ARM_REG_MVFR0, - ARM_REG_MVFR1, - ARM_REG_MVFR2, - ARM_REG_Q0, - ARM_REG_Q1, - ARM_REG_Q2, - ARM_REG_Q3, - ARM_REG_Q4, - ARM_REG_Q5, - ARM_REG_Q6, - ARM_REG_Q7, - ARM_REG_Q8, - ARM_REG_Q9, - ARM_REG_Q10, - ARM_REG_Q11, - ARM_REG_Q12, - ARM_REG_Q13, - ARM_REG_Q14, - ARM_REG_Q15, - ARM_REG_R0, - ARM_REG_R1, - ARM_REG_R2, - ARM_REG_R3, - ARM_REG_R4, - ARM_REG_R5, - ARM_REG_R6, - ARM_REG_R7, - ARM_REG_R8, - ARM_REG_R9, - ARM_REG_R10, - ARM_REG_R11, - ARM_REG_R12, - ARM_REG_S0, - ARM_REG_S1, - ARM_REG_S2, - ARM_REG_S3, - ARM_REG_S4, - ARM_REG_S5, - ARM_REG_S6, - ARM_REG_S7, - ARM_REG_S8, - ARM_REG_S9, - ARM_REG_S10, - ARM_REG_S11, - ARM_REG_S12, - ARM_REG_S13, - ARM_REG_S14, - ARM_REG_S15, - ARM_REG_S16, - ARM_REG_S17, - ARM_REG_S18, - ARM_REG_S19, - ARM_REG_S20, - ARM_REG_S21, - ARM_REG_S22, - ARM_REG_S23, - ARM_REG_S24, - ARM_REG_S25, - ARM_REG_S26, - ARM_REG_S27, - ARM_REG_S28, - ARM_REG_S29, - ARM_REG_S30, - ARM_REG_S31, - - ARM_REG_ENDING, // <-- mark the end of the list or registers - - //> alias registers - ARM_REG_R13 = ARM_REG_SP, - ARM_REG_R14 = ARM_REG_LR, - ARM_REG_R15 = ARM_REG_PC, - - ARM_REG_SB = ARM_REG_R9, - ARM_REG_SL = ARM_REG_R10, - ARM_REG_FP = ARM_REG_R11, - ARM_REG_IP = ARM_REG_R12, -} arm_reg; - -//> ARM instruction -typedef enum arm_insn -{ - ARM_INS_INVALID = 0, - - ARM_INS_ADC, - ARM_INS_ADD, - ARM_INS_ADR, - ARM_INS_AESD, - ARM_INS_AESE, - ARM_INS_AESIMC, - ARM_INS_AESMC, - ARM_INS_AND, - ARM_INS_BFC, - ARM_INS_BFI, - ARM_INS_BIC, - ARM_INS_BKPT, - ARM_INS_BL, - ARM_INS_BLX, - ARM_INS_BX, - ARM_INS_BXJ, - ARM_INS_B, - ARM_INS_CDP, - ARM_INS_CDP2, - ARM_INS_CLREX, - ARM_INS_CLZ, - ARM_INS_CMN, - ARM_INS_CMP, - ARM_INS_CPS, - ARM_INS_CRC32B, - ARM_INS_CRC32CB, - ARM_INS_CRC32CH, - ARM_INS_CRC32CW, - ARM_INS_CRC32H, - ARM_INS_CRC32W, - ARM_INS_DBG, - ARM_INS_DMB, - ARM_INS_DSB, - ARM_INS_EOR, - ARM_INS_VMOV, - ARM_INS_FLDMDBX, - ARM_INS_FLDMIAX, - ARM_INS_VMRS, - ARM_INS_FSTMDBX, - ARM_INS_FSTMIAX, - ARM_INS_HINT, - ARM_INS_HLT, - ARM_INS_ISB, - ARM_INS_LDA, - ARM_INS_LDAB, - ARM_INS_LDAEX, - ARM_INS_LDAEXB, - ARM_INS_LDAEXD, - ARM_INS_LDAEXH, - ARM_INS_LDAH, - ARM_INS_LDC2L, - ARM_INS_LDC2, - ARM_INS_LDCL, - ARM_INS_LDC, - ARM_INS_LDMDA, - ARM_INS_LDMDB, - ARM_INS_LDM, - ARM_INS_LDMIB, - ARM_INS_LDRBT, - ARM_INS_LDRB, - ARM_INS_LDRD, - ARM_INS_LDREX, - ARM_INS_LDREXB, - ARM_INS_LDREXD, - ARM_INS_LDREXH, - ARM_INS_LDRH, - ARM_INS_LDRHT, - ARM_INS_LDRSB, - ARM_INS_LDRSBT, - ARM_INS_LDRSH, - ARM_INS_LDRSHT, - ARM_INS_LDRT, - ARM_INS_LDR, - ARM_INS_MCR, - ARM_INS_MCR2, - ARM_INS_MCRR, - ARM_INS_MCRR2, - ARM_INS_MLA, - ARM_INS_MLS, - ARM_INS_MOV, - ARM_INS_MOVT, - ARM_INS_MOVW, - ARM_INS_MRC, - ARM_INS_MRC2, - ARM_INS_MRRC, - ARM_INS_MRRC2, - ARM_INS_MRS, - ARM_INS_MSR, - ARM_INS_MUL, - ARM_INS_MVN, - ARM_INS_ORR, - ARM_INS_PKHBT, - ARM_INS_PKHTB, - ARM_INS_PLDW, - ARM_INS_PLD, - ARM_INS_PLI, - ARM_INS_QADD, - ARM_INS_QADD16, - ARM_INS_QADD8, - ARM_INS_QASX, - ARM_INS_QDADD, - ARM_INS_QDSUB, - ARM_INS_QSAX, - ARM_INS_QSUB, - ARM_INS_QSUB16, - ARM_INS_QSUB8, - ARM_INS_RBIT, - ARM_INS_REV, - ARM_INS_REV16, - ARM_INS_REVSH, - ARM_INS_RFEDA, - ARM_INS_RFEDB, - ARM_INS_RFEIA, - ARM_INS_RFEIB, - ARM_INS_RSB, - ARM_INS_RSC, - ARM_INS_SADD16, - ARM_INS_SADD8, - ARM_INS_SASX, - ARM_INS_SBC, - ARM_INS_SBFX, - ARM_INS_SDIV, - ARM_INS_SEL, - ARM_INS_SETEND, - ARM_INS_SHA1C, - ARM_INS_SHA1H, - ARM_INS_SHA1M, - ARM_INS_SHA1P, - ARM_INS_SHA1SU0, - ARM_INS_SHA1SU1, - ARM_INS_SHA256H, - ARM_INS_SHA256H2, - ARM_INS_SHA256SU0, - ARM_INS_SHA256SU1, - ARM_INS_SHADD16, - ARM_INS_SHADD8, - ARM_INS_SHASX, - ARM_INS_SHSAX, - ARM_INS_SHSUB16, - ARM_INS_SHSUB8, - ARM_INS_SMC, - ARM_INS_SMLABB, - ARM_INS_SMLABT, - ARM_INS_SMLAD, - ARM_INS_SMLADX, - ARM_INS_SMLAL, - ARM_INS_SMLALBB, - ARM_INS_SMLALBT, - ARM_INS_SMLALD, - ARM_INS_SMLALDX, - ARM_INS_SMLALTB, - ARM_INS_SMLALTT, - ARM_INS_SMLATB, - ARM_INS_SMLATT, - ARM_INS_SMLAWB, - ARM_INS_SMLAWT, - ARM_INS_SMLSD, - ARM_INS_SMLSDX, - ARM_INS_SMLSLD, - ARM_INS_SMLSLDX, - ARM_INS_SMMLA, - ARM_INS_SMMLAR, - ARM_INS_SMMLS, - ARM_INS_SMMLSR, - ARM_INS_SMMUL, - ARM_INS_SMMULR, - ARM_INS_SMUAD, - ARM_INS_SMUADX, - ARM_INS_SMULBB, - ARM_INS_SMULBT, - ARM_INS_SMULL, - ARM_INS_SMULTB, - ARM_INS_SMULTT, - ARM_INS_SMULWB, - ARM_INS_SMULWT, - ARM_INS_SMUSD, - ARM_INS_SMUSDX, - ARM_INS_SRSDA, - ARM_INS_SRSDB, - ARM_INS_SRSIA, - ARM_INS_SRSIB, - ARM_INS_SSAT, - ARM_INS_SSAT16, - ARM_INS_SSAX, - ARM_INS_SSUB16, - ARM_INS_SSUB8, - ARM_INS_STC2L, - ARM_INS_STC2, - ARM_INS_STCL, - ARM_INS_STC, - ARM_INS_STL, - ARM_INS_STLB, - ARM_INS_STLEX, - ARM_INS_STLEXB, - ARM_INS_STLEXD, - ARM_INS_STLEXH, - ARM_INS_STLH, - ARM_INS_STMDA, - ARM_INS_STMDB, - ARM_INS_STM, - ARM_INS_STMIB, - ARM_INS_STRBT, - ARM_INS_STRB, - ARM_INS_STRD, - ARM_INS_STREX, - ARM_INS_STREXB, - ARM_INS_STREXD, - ARM_INS_STREXH, - ARM_INS_STRH, - ARM_INS_STRHT, - ARM_INS_STRT, - ARM_INS_STR, - ARM_INS_SUB, - ARM_INS_SVC, - ARM_INS_SWP, - ARM_INS_SWPB, - ARM_INS_SXTAB, - ARM_INS_SXTAB16, - ARM_INS_SXTAH, - ARM_INS_SXTB, - ARM_INS_SXTB16, - ARM_INS_SXTH, - ARM_INS_TEQ, - ARM_INS_TRAP, - ARM_INS_TST, - ARM_INS_UADD16, - ARM_INS_UADD8, - ARM_INS_UASX, - ARM_INS_UBFX, - ARM_INS_UDF, - ARM_INS_UDIV, - ARM_INS_UHADD16, - ARM_INS_UHADD8, - ARM_INS_UHASX, - ARM_INS_UHSAX, - ARM_INS_UHSUB16, - ARM_INS_UHSUB8, - ARM_INS_UMAAL, - ARM_INS_UMLAL, - ARM_INS_UMULL, - ARM_INS_UQADD16, - ARM_INS_UQADD8, - ARM_INS_UQASX, - ARM_INS_UQSAX, - ARM_INS_UQSUB16, - ARM_INS_UQSUB8, - ARM_INS_USAD8, - ARM_INS_USADA8, - ARM_INS_USAT, - ARM_INS_USAT16, - ARM_INS_USAX, - ARM_INS_USUB16, - ARM_INS_USUB8, - ARM_INS_UXTAB, - ARM_INS_UXTAB16, - ARM_INS_UXTAH, - ARM_INS_UXTB, - ARM_INS_UXTB16, - ARM_INS_UXTH, - ARM_INS_VABAL, - ARM_INS_VABA, - ARM_INS_VABDL, - ARM_INS_VABD, - ARM_INS_VABS, - ARM_INS_VACGE, - ARM_INS_VACGT, - ARM_INS_VADD, - ARM_INS_VADDHN, - ARM_INS_VADDL, - ARM_INS_VADDW, - ARM_INS_VAND, - ARM_INS_VBIC, - ARM_INS_VBIF, - ARM_INS_VBIT, - ARM_INS_VBSL, - ARM_INS_VCEQ, - ARM_INS_VCGE, - ARM_INS_VCGT, - ARM_INS_VCLE, - ARM_INS_VCLS, - ARM_INS_VCLT, - ARM_INS_VCLZ, - ARM_INS_VCMP, - ARM_INS_VCMPE, - ARM_INS_VCNT, - ARM_INS_VCVTA, - ARM_INS_VCVTB, - ARM_INS_VCVT, - ARM_INS_VCVTM, - ARM_INS_VCVTN, - ARM_INS_VCVTP, - ARM_INS_VCVTT, - ARM_INS_VDIV, - ARM_INS_VDUP, - ARM_INS_VEOR, - ARM_INS_VEXT, - ARM_INS_VFMA, - ARM_INS_VFMS, - ARM_INS_VFNMA, - ARM_INS_VFNMS, - ARM_INS_VHADD, - ARM_INS_VHSUB, - ARM_INS_VLD1, - ARM_INS_VLD2, - ARM_INS_VLD3, - ARM_INS_VLD4, - ARM_INS_VLDMDB, - ARM_INS_VLDMIA, - ARM_INS_VLDR, - ARM_INS_VMAXNM, - ARM_INS_VMAX, - ARM_INS_VMINNM, - ARM_INS_VMIN, - ARM_INS_VMLA, - ARM_INS_VMLAL, - ARM_INS_VMLS, - ARM_INS_VMLSL, - ARM_INS_VMOVL, - ARM_INS_VMOVN, - ARM_INS_VMSR, - ARM_INS_VMUL, - ARM_INS_VMULL, - ARM_INS_VMVN, - ARM_INS_VNEG, - ARM_INS_VNMLA, - ARM_INS_VNMLS, - ARM_INS_VNMUL, - ARM_INS_VORN, - ARM_INS_VORR, - ARM_INS_VPADAL, - ARM_INS_VPADDL, - ARM_INS_VPADD, - ARM_INS_VPMAX, - ARM_INS_VPMIN, - ARM_INS_VQABS, - ARM_INS_VQADD, - ARM_INS_VQDMLAL, - ARM_INS_VQDMLSL, - ARM_INS_VQDMULH, - ARM_INS_VQDMULL, - ARM_INS_VQMOVUN, - ARM_INS_VQMOVN, - ARM_INS_VQNEG, - ARM_INS_VQRDMULH, - ARM_INS_VQRSHL, - ARM_INS_VQRSHRN, - ARM_INS_VQRSHRUN, - ARM_INS_VQSHL, - ARM_INS_VQSHLU, - ARM_INS_VQSHRN, - ARM_INS_VQSHRUN, - ARM_INS_VQSUB, - ARM_INS_VRADDHN, - ARM_INS_VRECPE, - ARM_INS_VRECPS, - ARM_INS_VREV16, - ARM_INS_VREV32, - ARM_INS_VREV64, - ARM_INS_VRHADD, - ARM_INS_VRINTA, - ARM_INS_VRINTM, - ARM_INS_VRINTN, - ARM_INS_VRINTP, - ARM_INS_VRINTR, - ARM_INS_VRINTX, - ARM_INS_VRINTZ, - ARM_INS_VRSHL, - ARM_INS_VRSHRN, - ARM_INS_VRSHR, - ARM_INS_VRSQRTE, - ARM_INS_VRSQRTS, - ARM_INS_VRSRA, - ARM_INS_VRSUBHN, - ARM_INS_VSELEQ, - ARM_INS_VSELGE, - ARM_INS_VSELGT, - ARM_INS_VSELVS, - ARM_INS_VSHLL, - ARM_INS_VSHL, - ARM_INS_VSHRN, - ARM_INS_VSHR, - ARM_INS_VSLI, - ARM_INS_VSQRT, - ARM_INS_VSRA, - ARM_INS_VSRI, - ARM_INS_VST1, - ARM_INS_VST2, - ARM_INS_VST3, - ARM_INS_VST4, - ARM_INS_VSTMDB, - ARM_INS_VSTMIA, - ARM_INS_VSTR, - ARM_INS_VSUB, - ARM_INS_VSUBHN, - ARM_INS_VSUBL, - ARM_INS_VSUBW, - ARM_INS_VSWP, - ARM_INS_VTBL, - ARM_INS_VTBX, - ARM_INS_VCVTR, - ARM_INS_VTRN, - ARM_INS_VTST, - ARM_INS_VUZP, - ARM_INS_VZIP, - ARM_INS_ADDW, - ARM_INS_ASR, - ARM_INS_DCPS1, - ARM_INS_DCPS2, - ARM_INS_DCPS3, - ARM_INS_IT, - ARM_INS_LSL, - ARM_INS_LSR, - ARM_INS_ASRS, - ARM_INS_LSRS, - ARM_INS_ORN, - ARM_INS_ROR, - ARM_INS_RRX, - ARM_INS_SUBS, - ARM_INS_SUBW, - ARM_INS_TBB, - ARM_INS_TBH, - ARM_INS_CBNZ, - ARM_INS_CBZ, - ARM_INS_MOVS, - ARM_INS_POP, - ARM_INS_PUSH, - - // special instructions - ARM_INS_NOP, - ARM_INS_YIELD, - ARM_INS_WFE, - ARM_INS_WFI, - ARM_INS_SEV, - ARM_INS_SEVL, - ARM_INS_VPUSH, - ARM_INS_VPOP, - - ARM_INS_ENDING, // <-- mark the end of the list of instructions -} arm_insn; - -//> Group of ARM instructions -typedef enum arm_insn_group -{ - ARM_GRP_INVALID = 0, // = CS_GRP_INVALID - - //> Generic groups - // all jump instructions (conditional+direct+indirect jumps) - ARM_GRP_JUMP, // = CS_GRP_JUMP - - //> Architecture-specific groups - ARM_GRP_CRYPTO = 128, - ARM_GRP_DATABARRIER, - ARM_GRP_DIVIDE, - ARM_GRP_FPARMV8, - ARM_GRP_MULTPRO, - ARM_GRP_NEON, - ARM_GRP_T2EXTRACTPACK, - ARM_GRP_THUMB2DSP, - ARM_GRP_TRUSTZONE, - ARM_GRP_V4T, - ARM_GRP_V5T, - ARM_GRP_V5TE, - ARM_GRP_V6, - ARM_GRP_V6T2, - ARM_GRP_V7, - ARM_GRP_V8, - ARM_GRP_VFP2, - ARM_GRP_VFP3, - ARM_GRP_VFP4, - ARM_GRP_ARM, - ARM_GRP_MCLASS, - ARM_GRP_NOTMCLASS, - ARM_GRP_THUMB, - ARM_GRP_THUMB1ONLY, - ARM_GRP_THUMB2, - ARM_GRP_PREV8, - ARM_GRP_FPVMLX, - ARM_GRP_MULOPS, - ARM_GRP_CRC, - ARM_GRP_DPVFP, - ARM_GRP_V6M, - - ARM_GRP_ENDING, -} arm_insn_group; - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef CAPSTONE_ARM_H +#define CAPSTONE_ARM_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "platform.h" + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> ARM shift type +typedef enum arm_shifter +{ + ARM_SFT_INVALID = 0, + ARM_SFT_ASR, // shift with immediate const + ARM_SFT_LSL, // shift with immediate const + ARM_SFT_LSR, // shift with immediate const + ARM_SFT_ROR, // shift with immediate const + ARM_SFT_RRX, // shift with immediate const + ARM_SFT_ASR_REG, // shift with register + ARM_SFT_LSL_REG, // shift with register + ARM_SFT_LSR_REG, // shift with register + ARM_SFT_ROR_REG, // shift with register + ARM_SFT_RRX_REG, // shift with register +} arm_shifter; + +//> ARM condition code +typedef enum arm_cc +{ + ARM_CC_INVALID = 0, + ARM_CC_EQ, // Equal Equal + ARM_CC_NE, // Not equal Not equal, or unordered + ARM_CC_HS, // Carry set >, ==, or unordered + ARM_CC_LO, // Carry clear Less than + ARM_CC_MI, // Minus, negative Less than + ARM_CC_PL, // Plus, positive or zero >, ==, or unordered + ARM_CC_VS, // Overflow Unordered + ARM_CC_VC, // No overflow Not unordered + ARM_CC_HI, // Unsigned higher Greater than, or unordered + ARM_CC_LS, // Unsigned lower or same Less than or equal + ARM_CC_GE, // Greater than or equal Greater than or equal + ARM_CC_LT, // Less than Less than, or unordered + ARM_CC_GT, // Greater than Greater than + ARM_CC_LE, // Less than or equal <, ==, or unordered + ARM_CC_AL // Always (unconditional) Always (unconditional) +} arm_cc; + +typedef enum arm_sysreg +{ + //> Special registers for MSR + ARM_SYSREG_INVALID = 0, + + // SPSR* registers can be OR combined + ARM_SYSREG_SPSR_C = 1, + ARM_SYSREG_SPSR_X = 2, + ARM_SYSREG_SPSR_S = 4, + ARM_SYSREG_SPSR_F = 8, + + // CPSR* registers can be OR combined + ARM_SYSREG_CPSR_C = 16, + ARM_SYSREG_CPSR_X = 32, + ARM_SYSREG_CPSR_S = 64, + ARM_SYSREG_CPSR_F = 128, + + // independent registers + ARM_SYSREG_APSR = 256, + ARM_SYSREG_APSR_G, + ARM_SYSREG_APSR_NZCVQ, + ARM_SYSREG_APSR_NZCVQG, + + ARM_SYSREG_IAPSR, + ARM_SYSREG_IAPSR_G, + ARM_SYSREG_IAPSR_NZCVQG, + + ARM_SYSREG_EAPSR, + ARM_SYSREG_EAPSR_G, + ARM_SYSREG_EAPSR_NZCVQG, + + ARM_SYSREG_XPSR, + ARM_SYSREG_XPSR_G, + ARM_SYSREG_XPSR_NZCVQG, + + ARM_SYSREG_IPSR, + ARM_SYSREG_EPSR, + ARM_SYSREG_IEPSR, + + ARM_SYSREG_MSP, + ARM_SYSREG_PSP, + ARM_SYSREG_PRIMASK, + ARM_SYSREG_BASEPRI, + ARM_SYSREG_BASEPRI_MAX, + ARM_SYSREG_FAULTMASK, + ARM_SYSREG_CONTROL, +} arm_sysreg; + +//> The memory barrier constants map directly to the 4-bit encoding of +//> the option field for Memory Barrier operations. +typedef enum arm_mem_barrier +{ + ARM_MB_INVALID = 0, + ARM_MB_RESERVED_0, + ARM_MB_OSHLD, + ARM_MB_OSHST, + ARM_MB_OSH, + ARM_MB_RESERVED_4, + ARM_MB_NSHLD, + ARM_MB_NSHST, + ARM_MB_NSH, + ARM_MB_RESERVED_8, + ARM_MB_ISHLD, + ARM_MB_ISHST, + ARM_MB_ISH, + ARM_MB_RESERVED_12, + ARM_MB_LD, + ARM_MB_ST, + ARM_MB_SY, +} arm_mem_barrier; + +//> Operand type for instruction's operands +typedef enum arm_op_type +{ + ARM_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + ARM_OP_REG, // = CS_OP_REG (Register operand). + ARM_OP_IMM, // = CS_OP_IMM (Immediate operand). + ARM_OP_MEM, // = CS_OP_MEM (Memory operand). + ARM_OP_FP, // = CS_OP_FP (Floating-Point operand). + ARM_OP_CIMM = 64, // C-Immediate (coprocessor registers) + ARM_OP_PIMM, // P-Immediate (coprocessor registers) + ARM_OP_SETEND, // operand for SETEND instruction + ARM_OP_SYSREG, // MSR/MSR special register operand +} arm_op_type; + +//> Operand type for SETEND instruction +typedef enum arm_setend_type +{ + ARM_SETEND_INVALID = 0, // Uninitialized. + ARM_SETEND_BE, // BE operand. + ARM_SETEND_LE, // LE operand +} arm_setend_type; + +typedef enum arm_cpsmode_type +{ + ARM_CPSMODE_INVALID = 0, + ARM_CPSMODE_IE = 2, + ARM_CPSMODE_ID = 3 +} arm_cpsmode_type; + +//> Operand type for SETEND instruction +typedef enum arm_cpsflag_type +{ + ARM_CPSFLAG_INVALID = 0, + ARM_CPSFLAG_F = 1, + ARM_CPSFLAG_I = 2, + ARM_CPSFLAG_A = 4, + ARM_CPSFLAG_NONE = 16, // no flag +} arm_cpsflag_type; + +//> Data type for elements of vector instructions. +typedef enum arm_vectordata_type +{ + ARM_VECTORDATA_INVALID = 0, + + // Integer type + ARM_VECTORDATA_I8, + ARM_VECTORDATA_I16, + ARM_VECTORDATA_I32, + ARM_VECTORDATA_I64, + + // Signed integer type + ARM_VECTORDATA_S8, + ARM_VECTORDATA_S16, + ARM_VECTORDATA_S32, + ARM_VECTORDATA_S64, + + // Unsigned integer type + ARM_VECTORDATA_U8, + ARM_VECTORDATA_U16, + ARM_VECTORDATA_U32, + ARM_VECTORDATA_U64, + + // Data type for VMUL/VMULL + ARM_VECTORDATA_P8, + + // Floating type + ARM_VECTORDATA_F32, + ARM_VECTORDATA_F64, + + // Convert float <-> float + ARM_VECTORDATA_F16F64, // f16.f64 + ARM_VECTORDATA_F64F16, // f64.f16 + ARM_VECTORDATA_F32F16, // f32.f16 + ARM_VECTORDATA_F16F32, // f32.f16 + ARM_VECTORDATA_F64F32, // f64.f32 + ARM_VECTORDATA_F32F64, // f32.f64 + + // Convert integer <-> float + ARM_VECTORDATA_S32F32, // s32.f32 + ARM_VECTORDATA_U32F32, // u32.f32 + ARM_VECTORDATA_F32S32, // f32.s32 + ARM_VECTORDATA_F32U32, // f32.u32 + ARM_VECTORDATA_F64S16, // f64.s16 + ARM_VECTORDATA_F32S16, // f32.s16 + ARM_VECTORDATA_F64S32, // f64.s32 + ARM_VECTORDATA_S16F64, // s16.f64 + ARM_VECTORDATA_S16F32, // s16.f64 + ARM_VECTORDATA_S32F64, // s32.f64 + ARM_VECTORDATA_U16F64, // u16.f64 + ARM_VECTORDATA_U16F32, // u16.f32 + ARM_VECTORDATA_U32F64, // u32.f64 + ARM_VECTORDATA_F64U16, // f64.u16 + ARM_VECTORDATA_F32U16, // f32.u16 + ARM_VECTORDATA_F64U32, // f64.u32 +} arm_vectordata_type; + +// Instruction's operand referring to memory +// This is associated with ARM_OP_MEM operand type above +typedef struct arm_op_mem +{ + unsigned int base; // base register + unsigned int index; // index register + int scale; // scale for index register (can be 1, or -1) + int disp; // displacement/offset value +} arm_op_mem; + +// Instruction operand +typedef struct cs_arm_op +{ + int vector_index; // Vector Index for some vector operands (or -1 if irrelevant) + struct + { + arm_shifter type; + unsigned int value; + } shift; + arm_op_type type; // operand type + union + { + unsigned int reg; // register value for REG/SYSREG operand + int32_t imm; // immediate value for C-IMM, P-IMM or IMM operand + double fp; // floating point value for FP operand + arm_op_mem mem; // base/index/scale/disp value for MEM operand + arm_setend_type setend; // SETEND instruction's operand type + }; + // in some instructions, an operand can be subtracted or added to + // the base register, + bool subtracted; // if TRUE, this operand is subtracted. otherwise, it is added. +} cs_arm_op; + +// Instruction structure +typedef struct cs_arm +{ + bool usermode; // User-mode registers to be loaded (for LDM/STM instructions) + int vector_size; // Scalar size for vector instructions + arm_vectordata_type vector_data; // Data type for elements of vector instructions + arm_cpsmode_type cps_mode; // CPS mode for CPS instruction + arm_cpsflag_type cps_flag; // CPS mode for CPS instruction + arm_cc cc; // conditional code for this insn + bool update_flags; // does this insn update flags? + bool writeback; // does this insn write-back? + arm_mem_barrier mem_barrier; // Option for some memory barrier instructions + + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + + cs_arm_op operands[36]; // operands for this instruction. +} cs_arm; + +//> ARM registers +typedef enum arm_reg +{ + ARM_REG_INVALID = 0, + ARM_REG_APSR, + ARM_REG_APSR_NZCV, + ARM_REG_CPSR, + ARM_REG_FPEXC, + ARM_REG_FPINST, + ARM_REG_FPSCR, + ARM_REG_FPSCR_NZCV, + ARM_REG_FPSID, + ARM_REG_ITSTATE, + ARM_REG_LR, + ARM_REG_PC, + ARM_REG_SP, + ARM_REG_SPSR, + ARM_REG_D0, + ARM_REG_D1, + ARM_REG_D2, + ARM_REG_D3, + ARM_REG_D4, + ARM_REG_D5, + ARM_REG_D6, + ARM_REG_D7, + ARM_REG_D8, + ARM_REG_D9, + ARM_REG_D10, + ARM_REG_D11, + ARM_REG_D12, + ARM_REG_D13, + ARM_REG_D14, + ARM_REG_D15, + ARM_REG_D16, + ARM_REG_D17, + ARM_REG_D18, + ARM_REG_D19, + ARM_REG_D20, + ARM_REG_D21, + ARM_REG_D22, + ARM_REG_D23, + ARM_REG_D24, + ARM_REG_D25, + ARM_REG_D26, + ARM_REG_D27, + ARM_REG_D28, + ARM_REG_D29, + ARM_REG_D30, + ARM_REG_D31, + ARM_REG_FPINST2, + ARM_REG_MVFR0, + ARM_REG_MVFR1, + ARM_REG_MVFR2, + ARM_REG_Q0, + ARM_REG_Q1, + ARM_REG_Q2, + ARM_REG_Q3, + ARM_REG_Q4, + ARM_REG_Q5, + ARM_REG_Q6, + ARM_REG_Q7, + ARM_REG_Q8, + ARM_REG_Q9, + ARM_REG_Q10, + ARM_REG_Q11, + ARM_REG_Q12, + ARM_REG_Q13, + ARM_REG_Q14, + ARM_REG_Q15, + ARM_REG_R0, + ARM_REG_R1, + ARM_REG_R2, + ARM_REG_R3, + ARM_REG_R4, + ARM_REG_R5, + ARM_REG_R6, + ARM_REG_R7, + ARM_REG_R8, + ARM_REG_R9, + ARM_REG_R10, + ARM_REG_R11, + ARM_REG_R12, + ARM_REG_S0, + ARM_REG_S1, + ARM_REG_S2, + ARM_REG_S3, + ARM_REG_S4, + ARM_REG_S5, + ARM_REG_S6, + ARM_REG_S7, + ARM_REG_S8, + ARM_REG_S9, + ARM_REG_S10, + ARM_REG_S11, + ARM_REG_S12, + ARM_REG_S13, + ARM_REG_S14, + ARM_REG_S15, + ARM_REG_S16, + ARM_REG_S17, + ARM_REG_S18, + ARM_REG_S19, + ARM_REG_S20, + ARM_REG_S21, + ARM_REG_S22, + ARM_REG_S23, + ARM_REG_S24, + ARM_REG_S25, + ARM_REG_S26, + ARM_REG_S27, + ARM_REG_S28, + ARM_REG_S29, + ARM_REG_S30, + ARM_REG_S31, + + ARM_REG_ENDING, // <-- mark the end of the list or registers + + //> alias registers + ARM_REG_R13 = ARM_REG_SP, + ARM_REG_R14 = ARM_REG_LR, + ARM_REG_R15 = ARM_REG_PC, + + ARM_REG_SB = ARM_REG_R9, + ARM_REG_SL = ARM_REG_R10, + ARM_REG_FP = ARM_REG_R11, + ARM_REG_IP = ARM_REG_R12, +} arm_reg; + +//> ARM instruction +typedef enum arm_insn +{ + ARM_INS_INVALID = 0, + + ARM_INS_ADC, + ARM_INS_ADD, + ARM_INS_ADR, + ARM_INS_AESD, + ARM_INS_AESE, + ARM_INS_AESIMC, + ARM_INS_AESMC, + ARM_INS_AND, + ARM_INS_BFC, + ARM_INS_BFI, + ARM_INS_BIC, + ARM_INS_BKPT, + ARM_INS_BL, + ARM_INS_BLX, + ARM_INS_BX, + ARM_INS_BXJ, + ARM_INS_B, + ARM_INS_CDP, + ARM_INS_CDP2, + ARM_INS_CLREX, + ARM_INS_CLZ, + ARM_INS_CMN, + ARM_INS_CMP, + ARM_INS_CPS, + ARM_INS_CRC32B, + ARM_INS_CRC32CB, + ARM_INS_CRC32CH, + ARM_INS_CRC32CW, + ARM_INS_CRC32H, + ARM_INS_CRC32W, + ARM_INS_DBG, + ARM_INS_DMB, + ARM_INS_DSB, + ARM_INS_EOR, + ARM_INS_VMOV, + ARM_INS_FLDMDBX, + ARM_INS_FLDMIAX, + ARM_INS_VMRS, + ARM_INS_FSTMDBX, + ARM_INS_FSTMIAX, + ARM_INS_HINT, + ARM_INS_HLT, + ARM_INS_ISB, + ARM_INS_LDA, + ARM_INS_LDAB, + ARM_INS_LDAEX, + ARM_INS_LDAEXB, + ARM_INS_LDAEXD, + ARM_INS_LDAEXH, + ARM_INS_LDAH, + ARM_INS_LDC2L, + ARM_INS_LDC2, + ARM_INS_LDCL, + ARM_INS_LDC, + ARM_INS_LDMDA, + ARM_INS_LDMDB, + ARM_INS_LDM, + ARM_INS_LDMIB, + ARM_INS_LDRBT, + ARM_INS_LDRB, + ARM_INS_LDRD, + ARM_INS_LDREX, + ARM_INS_LDREXB, + ARM_INS_LDREXD, + ARM_INS_LDREXH, + ARM_INS_LDRH, + ARM_INS_LDRHT, + ARM_INS_LDRSB, + ARM_INS_LDRSBT, + ARM_INS_LDRSH, + ARM_INS_LDRSHT, + ARM_INS_LDRT, + ARM_INS_LDR, + ARM_INS_MCR, + ARM_INS_MCR2, + ARM_INS_MCRR, + ARM_INS_MCRR2, + ARM_INS_MLA, + ARM_INS_MLS, + ARM_INS_MOV, + ARM_INS_MOVT, + ARM_INS_MOVW, + ARM_INS_MRC, + ARM_INS_MRC2, + ARM_INS_MRRC, + ARM_INS_MRRC2, + ARM_INS_MRS, + ARM_INS_MSR, + ARM_INS_MUL, + ARM_INS_MVN, + ARM_INS_ORR, + ARM_INS_PKHBT, + ARM_INS_PKHTB, + ARM_INS_PLDW, + ARM_INS_PLD, + ARM_INS_PLI, + ARM_INS_QADD, + ARM_INS_QADD16, + ARM_INS_QADD8, + ARM_INS_QASX, + ARM_INS_QDADD, + ARM_INS_QDSUB, + ARM_INS_QSAX, + ARM_INS_QSUB, + ARM_INS_QSUB16, + ARM_INS_QSUB8, + ARM_INS_RBIT, + ARM_INS_REV, + ARM_INS_REV16, + ARM_INS_REVSH, + ARM_INS_RFEDA, + ARM_INS_RFEDB, + ARM_INS_RFEIA, + ARM_INS_RFEIB, + ARM_INS_RSB, + ARM_INS_RSC, + ARM_INS_SADD16, + ARM_INS_SADD8, + ARM_INS_SASX, + ARM_INS_SBC, + ARM_INS_SBFX, + ARM_INS_SDIV, + ARM_INS_SEL, + ARM_INS_SETEND, + ARM_INS_SHA1C, + ARM_INS_SHA1H, + ARM_INS_SHA1M, + ARM_INS_SHA1P, + ARM_INS_SHA1SU0, + ARM_INS_SHA1SU1, + ARM_INS_SHA256H, + ARM_INS_SHA256H2, + ARM_INS_SHA256SU0, + ARM_INS_SHA256SU1, + ARM_INS_SHADD16, + ARM_INS_SHADD8, + ARM_INS_SHASX, + ARM_INS_SHSAX, + ARM_INS_SHSUB16, + ARM_INS_SHSUB8, + ARM_INS_SMC, + ARM_INS_SMLABB, + ARM_INS_SMLABT, + ARM_INS_SMLAD, + ARM_INS_SMLADX, + ARM_INS_SMLAL, + ARM_INS_SMLALBB, + ARM_INS_SMLALBT, + ARM_INS_SMLALD, + ARM_INS_SMLALDX, + ARM_INS_SMLALTB, + ARM_INS_SMLALTT, + ARM_INS_SMLATB, + ARM_INS_SMLATT, + ARM_INS_SMLAWB, + ARM_INS_SMLAWT, + ARM_INS_SMLSD, + ARM_INS_SMLSDX, + ARM_INS_SMLSLD, + ARM_INS_SMLSLDX, + ARM_INS_SMMLA, + ARM_INS_SMMLAR, + ARM_INS_SMMLS, + ARM_INS_SMMLSR, + ARM_INS_SMMUL, + ARM_INS_SMMULR, + ARM_INS_SMUAD, + ARM_INS_SMUADX, + ARM_INS_SMULBB, + ARM_INS_SMULBT, + ARM_INS_SMULL, + ARM_INS_SMULTB, + ARM_INS_SMULTT, + ARM_INS_SMULWB, + ARM_INS_SMULWT, + ARM_INS_SMUSD, + ARM_INS_SMUSDX, + ARM_INS_SRSDA, + ARM_INS_SRSDB, + ARM_INS_SRSIA, + ARM_INS_SRSIB, + ARM_INS_SSAT, + ARM_INS_SSAT16, + ARM_INS_SSAX, + ARM_INS_SSUB16, + ARM_INS_SSUB8, + ARM_INS_STC2L, + ARM_INS_STC2, + ARM_INS_STCL, + ARM_INS_STC, + ARM_INS_STL, + ARM_INS_STLB, + ARM_INS_STLEX, + ARM_INS_STLEXB, + ARM_INS_STLEXD, + ARM_INS_STLEXH, + ARM_INS_STLH, + ARM_INS_STMDA, + ARM_INS_STMDB, + ARM_INS_STM, + ARM_INS_STMIB, + ARM_INS_STRBT, + ARM_INS_STRB, + ARM_INS_STRD, + ARM_INS_STREX, + ARM_INS_STREXB, + ARM_INS_STREXD, + ARM_INS_STREXH, + ARM_INS_STRH, + ARM_INS_STRHT, + ARM_INS_STRT, + ARM_INS_STR, + ARM_INS_SUB, + ARM_INS_SVC, + ARM_INS_SWP, + ARM_INS_SWPB, + ARM_INS_SXTAB, + ARM_INS_SXTAB16, + ARM_INS_SXTAH, + ARM_INS_SXTB, + ARM_INS_SXTB16, + ARM_INS_SXTH, + ARM_INS_TEQ, + ARM_INS_TRAP, + ARM_INS_TST, + ARM_INS_UADD16, + ARM_INS_UADD8, + ARM_INS_UASX, + ARM_INS_UBFX, + ARM_INS_UDF, + ARM_INS_UDIV, + ARM_INS_UHADD16, + ARM_INS_UHADD8, + ARM_INS_UHASX, + ARM_INS_UHSAX, + ARM_INS_UHSUB16, + ARM_INS_UHSUB8, + ARM_INS_UMAAL, + ARM_INS_UMLAL, + ARM_INS_UMULL, + ARM_INS_UQADD16, + ARM_INS_UQADD8, + ARM_INS_UQASX, + ARM_INS_UQSAX, + ARM_INS_UQSUB16, + ARM_INS_UQSUB8, + ARM_INS_USAD8, + ARM_INS_USADA8, + ARM_INS_USAT, + ARM_INS_USAT16, + ARM_INS_USAX, + ARM_INS_USUB16, + ARM_INS_USUB8, + ARM_INS_UXTAB, + ARM_INS_UXTAB16, + ARM_INS_UXTAH, + ARM_INS_UXTB, + ARM_INS_UXTB16, + ARM_INS_UXTH, + ARM_INS_VABAL, + ARM_INS_VABA, + ARM_INS_VABDL, + ARM_INS_VABD, + ARM_INS_VABS, + ARM_INS_VACGE, + ARM_INS_VACGT, + ARM_INS_VADD, + ARM_INS_VADDHN, + ARM_INS_VADDL, + ARM_INS_VADDW, + ARM_INS_VAND, + ARM_INS_VBIC, + ARM_INS_VBIF, + ARM_INS_VBIT, + ARM_INS_VBSL, + ARM_INS_VCEQ, + ARM_INS_VCGE, + ARM_INS_VCGT, + ARM_INS_VCLE, + ARM_INS_VCLS, + ARM_INS_VCLT, + ARM_INS_VCLZ, + ARM_INS_VCMP, + ARM_INS_VCMPE, + ARM_INS_VCNT, + ARM_INS_VCVTA, + ARM_INS_VCVTB, + ARM_INS_VCVT, + ARM_INS_VCVTM, + ARM_INS_VCVTN, + ARM_INS_VCVTP, + ARM_INS_VCVTT, + ARM_INS_VDIV, + ARM_INS_VDUP, + ARM_INS_VEOR, + ARM_INS_VEXT, + ARM_INS_VFMA, + ARM_INS_VFMS, + ARM_INS_VFNMA, + ARM_INS_VFNMS, + ARM_INS_VHADD, + ARM_INS_VHSUB, + ARM_INS_VLD1, + ARM_INS_VLD2, + ARM_INS_VLD3, + ARM_INS_VLD4, + ARM_INS_VLDMDB, + ARM_INS_VLDMIA, + ARM_INS_VLDR, + ARM_INS_VMAXNM, + ARM_INS_VMAX, + ARM_INS_VMINNM, + ARM_INS_VMIN, + ARM_INS_VMLA, + ARM_INS_VMLAL, + ARM_INS_VMLS, + ARM_INS_VMLSL, + ARM_INS_VMOVL, + ARM_INS_VMOVN, + ARM_INS_VMSR, + ARM_INS_VMUL, + ARM_INS_VMULL, + ARM_INS_VMVN, + ARM_INS_VNEG, + ARM_INS_VNMLA, + ARM_INS_VNMLS, + ARM_INS_VNMUL, + ARM_INS_VORN, + ARM_INS_VORR, + ARM_INS_VPADAL, + ARM_INS_VPADDL, + ARM_INS_VPADD, + ARM_INS_VPMAX, + ARM_INS_VPMIN, + ARM_INS_VQABS, + ARM_INS_VQADD, + ARM_INS_VQDMLAL, + ARM_INS_VQDMLSL, + ARM_INS_VQDMULH, + ARM_INS_VQDMULL, + ARM_INS_VQMOVUN, + ARM_INS_VQMOVN, + ARM_INS_VQNEG, + ARM_INS_VQRDMULH, + ARM_INS_VQRSHL, + ARM_INS_VQRSHRN, + ARM_INS_VQRSHRUN, + ARM_INS_VQSHL, + ARM_INS_VQSHLU, + ARM_INS_VQSHRN, + ARM_INS_VQSHRUN, + ARM_INS_VQSUB, + ARM_INS_VRADDHN, + ARM_INS_VRECPE, + ARM_INS_VRECPS, + ARM_INS_VREV16, + ARM_INS_VREV32, + ARM_INS_VREV64, + ARM_INS_VRHADD, + ARM_INS_VRINTA, + ARM_INS_VRINTM, + ARM_INS_VRINTN, + ARM_INS_VRINTP, + ARM_INS_VRINTR, + ARM_INS_VRINTX, + ARM_INS_VRINTZ, + ARM_INS_VRSHL, + ARM_INS_VRSHRN, + ARM_INS_VRSHR, + ARM_INS_VRSQRTE, + ARM_INS_VRSQRTS, + ARM_INS_VRSRA, + ARM_INS_VRSUBHN, + ARM_INS_VSELEQ, + ARM_INS_VSELGE, + ARM_INS_VSELGT, + ARM_INS_VSELVS, + ARM_INS_VSHLL, + ARM_INS_VSHL, + ARM_INS_VSHRN, + ARM_INS_VSHR, + ARM_INS_VSLI, + ARM_INS_VSQRT, + ARM_INS_VSRA, + ARM_INS_VSRI, + ARM_INS_VST1, + ARM_INS_VST2, + ARM_INS_VST3, + ARM_INS_VST4, + ARM_INS_VSTMDB, + ARM_INS_VSTMIA, + ARM_INS_VSTR, + ARM_INS_VSUB, + ARM_INS_VSUBHN, + ARM_INS_VSUBL, + ARM_INS_VSUBW, + ARM_INS_VSWP, + ARM_INS_VTBL, + ARM_INS_VTBX, + ARM_INS_VCVTR, + ARM_INS_VTRN, + ARM_INS_VTST, + ARM_INS_VUZP, + ARM_INS_VZIP, + ARM_INS_ADDW, + ARM_INS_ASR, + ARM_INS_DCPS1, + ARM_INS_DCPS2, + ARM_INS_DCPS3, + ARM_INS_IT, + ARM_INS_LSL, + ARM_INS_LSR, + ARM_INS_ASRS, + ARM_INS_LSRS, + ARM_INS_ORN, + ARM_INS_ROR, + ARM_INS_RRX, + ARM_INS_SUBS, + ARM_INS_SUBW, + ARM_INS_TBB, + ARM_INS_TBH, + ARM_INS_CBNZ, + ARM_INS_CBZ, + ARM_INS_MOVS, + ARM_INS_POP, + ARM_INS_PUSH, + + // special instructions + ARM_INS_NOP, + ARM_INS_YIELD, + ARM_INS_WFE, + ARM_INS_WFI, + ARM_INS_SEV, + ARM_INS_SEVL, + ARM_INS_VPUSH, + ARM_INS_VPOP, + + ARM_INS_ENDING, // <-- mark the end of the list of instructions +} arm_insn; + +//> Group of ARM instructions +typedef enum arm_insn_group +{ + ARM_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + ARM_GRP_JUMP, // = CS_GRP_JUMP + + //> Architecture-specific groups + ARM_GRP_CRYPTO = 128, + ARM_GRP_DATABARRIER, + ARM_GRP_DIVIDE, + ARM_GRP_FPARMV8, + ARM_GRP_MULTPRO, + ARM_GRP_NEON, + ARM_GRP_T2EXTRACTPACK, + ARM_GRP_THUMB2DSP, + ARM_GRP_TRUSTZONE, + ARM_GRP_V4T, + ARM_GRP_V5T, + ARM_GRP_V5TE, + ARM_GRP_V6, + ARM_GRP_V6T2, + ARM_GRP_V7, + ARM_GRP_V8, + ARM_GRP_VFP2, + ARM_GRP_VFP3, + ARM_GRP_VFP4, + ARM_GRP_ARM, + ARM_GRP_MCLASS, + ARM_GRP_NOTMCLASS, + ARM_GRP_THUMB, + ARM_GRP_THUMB1ONLY, + ARM_GRP_THUMB2, + ARM_GRP_PREV8, + ARM_GRP_FPVMLX, + ARM_GRP_MULOPS, + ARM_GRP_CRC, + ARM_GRP_DPVFP, + ARM_GRP_V6M, + + ARM_GRP_ENDING, +} arm_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dbg/capstone/arm64.h b/src/dbg/capstone/arm64.h index f6f84018..4b6354fc 100644 --- a/src/dbg/capstone/arm64.h +++ b/src/dbg/capstone/arm64.h @@ -1,1174 +1,1174 @@ -#ifndef CAPSTONE_ARM64_H -#define CAPSTONE_ARM64_H - -/* Capstone Disassembly Engine */ -/* By Nguyen Anh Quynh , 2013-2014 */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "platform.h" - -#ifdef _MSC_VER -#pragma warning(disable:4201) -#endif - -//> ARM64 shift type -typedef enum arm64_shifter -{ - ARM64_SFT_INVALID = 0, - ARM64_SFT_LSL = 1, - ARM64_SFT_MSL = 2, - ARM64_SFT_LSR = 3, - ARM64_SFT_ASR = 4, - ARM64_SFT_ROR = 5, -} arm64_shifter; - -//> ARM64 extender type -typedef enum arm64_extender -{ - ARM64_EXT_INVALID = 0, - ARM64_EXT_UXTB = 1, - ARM64_EXT_UXTH = 2, - ARM64_EXT_UXTW = 3, - ARM64_EXT_UXTX = 4, - ARM64_EXT_SXTB = 5, - ARM64_EXT_SXTH = 6, - ARM64_EXT_SXTW = 7, - ARM64_EXT_SXTX = 8, -} arm64_extender; - -//> ARM64 condition code -typedef enum arm64_cc -{ - ARM64_CC_INVALID = 0, - ARM64_CC_EQ = 1, // Equal - ARM64_CC_NE = 2, // Not equal: Not equal, or unordered - ARM64_CC_HS = 3, // Unsigned higher or same: >, ==, or unordered - ARM64_CC_LO = 4, // Unsigned lower or same: Less than - ARM64_CC_MI = 5, // Minus, negative: Less than - ARM64_CC_PL = 6, // Plus, positive or zero: >, ==, or unordered - ARM64_CC_VS = 7, // Overflow: Unordered - ARM64_CC_VC = 8, // No overflow: Ordered - ARM64_CC_HI = 9, // Unsigned higher: Greater than, or unordered - ARM64_CC_LS = 10, // Unsigned lower or same: Less than or equal - ARM64_CC_GE = 11, // Greater than or equal: Greater than or equal - ARM64_CC_LT = 12, // Less than: Less than, or unordered - ARM64_CC_GT = 13, // Signed greater than: Greater than - ARM64_CC_LE = 14, // Signed less than or equal: <, ==, or unordered - ARM64_CC_AL = 15, // Always (unconditional): Always (unconditional) - ARM64_CC_NV = 16, // Always (unconditional): Always (unconditional) - // Note the NV exists purely to disassemble 0b1111. Execution - // is "always". -} arm64_cc; - -//> System registers -typedef enum arm64_mrs_reg -{ - //> System registers for MRS - ARM64_SYSREG_INVALID = 0, - ARM64_SYSREG_MDCCSR_EL0 = 0x9808, // 10 011 0000 0001 000 - ARM64_SYSREG_DBGDTRRX_EL0 = 0x9828, // 10 011 0000 0101 000 - ARM64_SYSREG_MDRAR_EL1 = 0x8080, // 10 000 0001 0000 000 - ARM64_SYSREG_OSLSR_EL1 = 0x808c, // 10 000 0001 0001 100 - ARM64_SYSREG_DBGAUTHSTATUS_EL1 = 0x83f6, // 10 000 0111 1110 110 - ARM64_SYSREG_PMCEID0_EL0 = 0xdce6, // 11 011 1001 1100 110 - ARM64_SYSREG_PMCEID1_EL0 = 0xdce7, // 11 011 1001 1100 111 - ARM64_SYSREG_MIDR_EL1 = 0xc000, // 11 000 0000 0000 000 - ARM64_SYSREG_CCSIDR_EL1 = 0xc800, // 11 001 0000 0000 000 - ARM64_SYSREG_CLIDR_EL1 = 0xc801, // 11 001 0000 0000 001 - ARM64_SYSREG_CTR_EL0 = 0xd801, // 11 011 0000 0000 001 - ARM64_SYSREG_MPIDR_EL1 = 0xc005, // 11 000 0000 0000 101 - ARM64_SYSREG_REVIDR_EL1 = 0xc006, // 11 000 0000 0000 110 - ARM64_SYSREG_AIDR_EL1 = 0xc807, // 11 001 0000 0000 111 - ARM64_SYSREG_DCZID_EL0 = 0xd807, // 11 011 0000 0000 111 - ARM64_SYSREG_ID_PFR0_EL1 = 0xc008, // 11 000 0000 0001 000 - ARM64_SYSREG_ID_PFR1_EL1 = 0xc009, // 11 000 0000 0001 001 - ARM64_SYSREG_ID_DFR0_EL1 = 0xc00a, // 11 000 0000 0001 010 - ARM64_SYSREG_ID_AFR0_EL1 = 0xc00b, // 11 000 0000 0001 011 - ARM64_SYSREG_ID_MMFR0_EL1 = 0xc00c, // 11 000 0000 0001 100 - ARM64_SYSREG_ID_MMFR1_EL1 = 0xc00d, // 11 000 0000 0001 101 - ARM64_SYSREG_ID_MMFR2_EL1 = 0xc00e, // 11 000 0000 0001 110 - ARM64_SYSREG_ID_MMFR3_EL1 = 0xc00f, // 11 000 0000 0001 111 - ARM64_SYSREG_ID_ISAR0_EL1 = 0xc010, // 11 000 0000 0010 000 - ARM64_SYSREG_ID_ISAR1_EL1 = 0xc011, // 11 000 0000 0010 001 - ARM64_SYSREG_ID_ISAR2_EL1 = 0xc012, // 11 000 0000 0010 010 - ARM64_SYSREG_ID_ISAR3_EL1 = 0xc013, // 11 000 0000 0010 011 - ARM64_SYSREG_ID_ISAR4_EL1 = 0xc014, // 11 000 0000 0010 100 - ARM64_SYSREG_ID_ISAR5_EL1 = 0xc015, // 11 000 0000 0010 101 - ARM64_SYSREG_ID_A64PFR0_EL1 = 0xc020, // 11 000 0000 0100 000 - ARM64_SYSREG_ID_A64PFR1_EL1 = 0xc021, // 11 000 0000 0100 001 - ARM64_SYSREG_ID_A64DFR0_EL1 = 0xc028, // 11 000 0000 0101 000 - ARM64_SYSREG_ID_A64DFR1_EL1 = 0xc029, // 11 000 0000 0101 001 - ARM64_SYSREG_ID_A64AFR0_EL1 = 0xc02c, // 11 000 0000 0101 100 - ARM64_SYSREG_ID_A64AFR1_EL1 = 0xc02d, // 11 000 0000 0101 101 - ARM64_SYSREG_ID_A64ISAR0_EL1 = 0xc030, // 11 000 0000 0110 000 - ARM64_SYSREG_ID_A64ISAR1_EL1 = 0xc031, // 11 000 0000 0110 001 - ARM64_SYSREG_ID_A64MMFR0_EL1 = 0xc038, // 11 000 0000 0111 000 - ARM64_SYSREG_ID_A64MMFR1_EL1 = 0xc039, // 11 000 0000 0111 001 - ARM64_SYSREG_MVFR0_EL1 = 0xc018, // 11 000 0000 0011 000 - ARM64_SYSREG_MVFR1_EL1 = 0xc019, // 11 000 0000 0011 001 - ARM64_SYSREG_MVFR2_EL1 = 0xc01a, // 11 000 0000 0011 010 - ARM64_SYSREG_RVBAR_EL1 = 0xc601, // 11 000 1100 0000 001 - ARM64_SYSREG_RVBAR_EL2 = 0xe601, // 11 100 1100 0000 001 - ARM64_SYSREG_RVBAR_EL3 = 0xf601, // 11 110 1100 0000 001 - ARM64_SYSREG_ISR_EL1 = 0xc608, // 11 000 1100 0001 000 - ARM64_SYSREG_CNTPCT_EL0 = 0xdf01, // 11 011 1110 0000 001 - ARM64_SYSREG_CNTVCT_EL0 = 0xdf02, // 11 011 1110 0000 010 - - // Trace registers - ARM64_SYSREG_TRCSTATR = 0x8818, // 10 001 0000 0011 000 - ARM64_SYSREG_TRCIDR8 = 0x8806, // 10 001 0000 0000 110 - ARM64_SYSREG_TRCIDR9 = 0x880e, // 10 001 0000 0001 110 - ARM64_SYSREG_TRCIDR10 = 0x8816, // 10 001 0000 0010 110 - ARM64_SYSREG_TRCIDR11 = 0x881e, // 10 001 0000 0011 110 - ARM64_SYSREG_TRCIDR12 = 0x8826, // 10 001 0000 0100 110 - ARM64_SYSREG_TRCIDR13 = 0x882e, // 10 001 0000 0101 110 - ARM64_SYSREG_TRCIDR0 = 0x8847, // 10 001 0000 1000 111 - ARM64_SYSREG_TRCIDR1 = 0x884f, // 10 001 0000 1001 111 - ARM64_SYSREG_TRCIDR2 = 0x8857, // 10 001 0000 1010 111 - ARM64_SYSREG_TRCIDR3 = 0x885f, // 10 001 0000 1011 111 - ARM64_SYSREG_TRCIDR4 = 0x8867, // 10 001 0000 1100 111 - ARM64_SYSREG_TRCIDR5 = 0x886f, // 10 001 0000 1101 111 - ARM64_SYSREG_TRCIDR6 = 0x8877, // 10 001 0000 1110 111 - ARM64_SYSREG_TRCIDR7 = 0x887f, // 10 001 0000 1111 111 - ARM64_SYSREG_TRCOSLSR = 0x888c, // 10 001 0001 0001 100 - ARM64_SYSREG_TRCPDSR = 0x88ac, // 10 001 0001 0101 100 - ARM64_SYSREG_TRCDEVAFF0 = 0x8bd6, // 10 001 0111 1010 110 - ARM64_SYSREG_TRCDEVAFF1 = 0x8bde, // 10 001 0111 1011 110 - ARM64_SYSREG_TRCLSR = 0x8bee, // 10 001 0111 1101 110 - ARM64_SYSREG_TRCAUTHSTATUS = 0x8bf6, // 10 001 0111 1110 110 - ARM64_SYSREG_TRCDEVARCH = 0x8bfe, // 10 001 0111 1111 110 - ARM64_SYSREG_TRCDEVID = 0x8b97, // 10 001 0111 0010 111 - ARM64_SYSREG_TRCDEVTYPE = 0x8b9f, // 10 001 0111 0011 111 - ARM64_SYSREG_TRCPIDR4 = 0x8ba7, // 10 001 0111 0100 111 - ARM64_SYSREG_TRCPIDR5 = 0x8baf, // 10 001 0111 0101 111 - ARM64_SYSREG_TRCPIDR6 = 0x8bb7, // 10 001 0111 0110 111 - ARM64_SYSREG_TRCPIDR7 = 0x8bbf, // 10 001 0111 0111 111 - ARM64_SYSREG_TRCPIDR0 = 0x8bc7, // 10 001 0111 1000 111 - ARM64_SYSREG_TRCPIDR1 = 0x8bcf, // 10 001 0111 1001 111 - ARM64_SYSREG_TRCPIDR2 = 0x8bd7, // 10 001 0111 1010 111 - ARM64_SYSREG_TRCPIDR3 = 0x8bdf, // 10 001 0111 1011 111 - ARM64_SYSREG_TRCCIDR0 = 0x8be7, // 10 001 0111 1100 111 - ARM64_SYSREG_TRCCIDR1 = 0x8bef, // 10 001 0111 1101 111 - ARM64_SYSREG_TRCCIDR2 = 0x8bf7, // 10 001 0111 1110 111 - ARM64_SYSREG_TRCCIDR3 = 0x8bff, // 10 001 0111 1111 111 - - // GICv3 registers - ARM64_SYSREG_ICC_IAR1_EL1 = 0xc660, // 11 000 1100 1100 000 - ARM64_SYSREG_ICC_IAR0_EL1 = 0xc640, // 11 000 1100 1000 000 - ARM64_SYSREG_ICC_HPPIR1_EL1 = 0xc662, // 11 000 1100 1100 010 - ARM64_SYSREG_ICC_HPPIR0_EL1 = 0xc642, // 11 000 1100 1000 010 - ARM64_SYSREG_ICC_RPR_EL1 = 0xc65b, // 11 000 1100 1011 011 - ARM64_SYSREG_ICH_VTR_EL2 = 0xe659, // 11 100 1100 1011 001 - ARM64_SYSREG_ICH_EISR_EL2 = 0xe65b, // 11 100 1100 1011 011 - ARM64_SYSREG_ICH_ELSR_EL2 = 0xe65d, // 11 100 1100 1011 101 -} arm64_sysreg; - -typedef enum arm64_msr_reg -{ - //> System registers for MSR - ARM64_SYSREG_DBGDTRTX_EL0 = 0x9828, // 10 011 0000 0101 000 - ARM64_SYSREG_OSLAR_EL1 = 0x8084, // 10 000 0001 0000 100 - ARM64_SYSREG_PMSWINC_EL0 = 0xdce4, // 11 011 1001 1100 100 - - // Trace Registers - ARM64_SYSREG_TRCOSLAR = 0x8884, // 10 001 0001 0000 100 - ARM64_SYSREG_TRCLAR = 0x8be6, // 10 001 0111 1100 110 - - // GICv3 registers - ARM64_SYSREG_ICC_EOIR1_EL1 = 0xc661, // 11 000 1100 1100 001 - ARM64_SYSREG_ICC_EOIR0_EL1 = 0xc641, // 11 000 1100 1000 001 - ARM64_SYSREG_ICC_DIR_EL1 = 0xc659, // 11 000 1100 1011 001 - ARM64_SYSREG_ICC_SGI1R_EL1 = 0xc65d, // 11 000 1100 1011 101 - ARM64_SYSREG_ICC_ASGI1R_EL1 = 0xc65e, // 11 000 1100 1011 110 - ARM64_SYSREG_ICC_SGI0R_EL1 = 0xc65f, // 11 000 1100 1011 111 -} arm64_msr_reg; - -//> System PState Field (MSR instruction) -typedef enum arm64_pstate -{ - ARM64_PSTATE_INVALID = 0, - ARM64_PSTATE_SPSEL = 0x05, - ARM64_PSTATE_DAIFSET = 0x1e, - ARM64_PSTATE_DAIFCLR = 0x1f -} arm64_pstate; - -//> Vector arrangement specifier (for FloatingPoint/Advanced SIMD insn) -typedef enum arm64_vas -{ - ARM64_VAS_INVALID = 0, - ARM64_VAS_8B, - ARM64_VAS_16B, - ARM64_VAS_4H, - ARM64_VAS_8H, - ARM64_VAS_2S, - ARM64_VAS_4S, - ARM64_VAS_1D, - ARM64_VAS_2D, - ARM64_VAS_1Q, -} arm64_vas; - -//> Vector element size specifier -typedef enum arm64_vess -{ - ARM64_VESS_INVALID = 0, - ARM64_VESS_B, - ARM64_VESS_H, - ARM64_VESS_S, - ARM64_VESS_D, -} arm64_vess; - -//> Memory barrier operands -typedef enum arm64_barrier_op -{ - ARM64_BARRIER_INVALID = 0, - ARM64_BARRIER_OSHLD = 0x1, - ARM64_BARRIER_OSHST = 0x2, - ARM64_BARRIER_OSH = 0x3, - ARM64_BARRIER_NSHLD = 0x5, - ARM64_BARRIER_NSHST = 0x6, - ARM64_BARRIER_NSH = 0x7, - ARM64_BARRIER_ISHLD = 0x9, - ARM64_BARRIER_ISHST = 0xa, - ARM64_BARRIER_ISH = 0xb, - ARM64_BARRIER_LD = 0xd, - ARM64_BARRIER_ST = 0xe, - ARM64_BARRIER_SY = 0xf -} arm64_barrier_op; - -//> Operand type for instruction's operands -typedef enum arm64_op_type -{ - ARM64_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). - ARM64_OP_REG, // = CS_OP_REG (Register operand). - ARM64_OP_IMM, // = CS_OP_IMM (Immediate operand). - ARM64_OP_MEM, // = CS_OP_MEM (Memory operand). - ARM64_OP_FP, // = CS_OP_FP (Floating-Point operand). - ARM64_OP_CIMM = 64, // C-Immediate - ARM64_OP_REG_MRS, // MRS register operand. - ARM64_OP_REG_MSR, // MSR register operand. - ARM64_OP_PSTATE, // PState operand. - ARM64_OP_SYS, // SYS operand for IC/DC/AT/TLBI instructions. - ARM64_OP_PREFETCH, // Prefetch operand (PRFM). - ARM64_OP_BARRIER, // Memory barrier operand (ISB/DMB/DSB instructions). -} arm64_op_type; - -//> TLBI operations -typedef enum arm64_tlbi_op -{ - ARM64_TLBI_INVALID = 0, - ARM64_TLBI_VMALLE1IS, - ARM64_TLBI_VAE1IS, - ARM64_TLBI_ASIDE1IS, - ARM64_TLBI_VAAE1IS, - ARM64_TLBI_VALE1IS, - ARM64_TLBI_VAALE1IS, - ARM64_TLBI_ALLE2IS, - ARM64_TLBI_VAE2IS, - ARM64_TLBI_ALLE1IS, - ARM64_TLBI_VALE2IS, - ARM64_TLBI_VMALLS12E1IS, - ARM64_TLBI_ALLE3IS, - ARM64_TLBI_VAE3IS, - ARM64_TLBI_VALE3IS, - ARM64_TLBI_IPAS2E1IS, - ARM64_TLBI_IPAS2LE1IS, - ARM64_TLBI_IPAS2E1, - ARM64_TLBI_IPAS2LE1, - ARM64_TLBI_VMALLE1, - ARM64_TLBI_VAE1, - ARM64_TLBI_ASIDE1, - ARM64_TLBI_VAAE1, - ARM64_TLBI_VALE1, - ARM64_TLBI_VAALE1, - ARM64_TLBI_ALLE2, - ARM64_TLBI_VAE2, - ARM64_TLBI_ALLE1, - ARM64_TLBI_VALE2, - ARM64_TLBI_VMALLS12E1, - ARM64_TLBI_ALLE3, - ARM64_TLBI_VAE3, - ARM64_TLBI_VALE3, -} arm64_tlbi_op; - -//> AT operations -typedef enum arm64_at_op -{ - ARM64_AT_S1E1R, - ARM64_AT_S1E1W, - ARM64_AT_S1E0R, - ARM64_AT_S1E0W, - ARM64_AT_S1E2R, - ARM64_AT_S1E2W, - ARM64_AT_S12E1R, - ARM64_AT_S12E1W, - ARM64_AT_S12E0R, - ARM64_AT_S12E0W, - ARM64_AT_S1E3R, - ARM64_AT_S1E3W, -} arm64_at_op; - -//> DC operations -typedef enum arm64_dc_op -{ - ARM64_DC_INVALID = 0, - ARM64_DC_ZVA, - ARM64_DC_IVAC, - ARM64_DC_ISW, - ARM64_DC_CVAC, - ARM64_DC_CSW, - ARM64_DC_CVAU, - ARM64_DC_CIVAC, - ARM64_DC_CISW, -} arm64_dc_op; - -//> IC operations -typedef enum arm64_ic_op -{ - ARM64_IC_INVALID = 0, - ARM64_IC_IALLUIS, - ARM64_IC_IALLU, - ARM64_IC_IVAU, -} arm64_ic_op; - -//> Prefetch operations (PRFM) -typedef enum arm64_prefetch_op -{ - ARM64_PRFM_INVALID = 0, - ARM64_PRFM_PLDL1KEEP = 0x00 + 1, - ARM64_PRFM_PLDL1STRM = 0x01 + 1, - ARM64_PRFM_PLDL2KEEP = 0x02 + 1, - ARM64_PRFM_PLDL2STRM = 0x03 + 1, - ARM64_PRFM_PLDL3KEEP = 0x04 + 1, - ARM64_PRFM_PLDL3STRM = 0x05 + 1, - ARM64_PRFM_PLIL1KEEP = 0x08 + 1, - ARM64_PRFM_PLIL1STRM = 0x09 + 1, - ARM64_PRFM_PLIL2KEEP = 0x0a + 1, - ARM64_PRFM_PLIL2STRM = 0x0b + 1, - ARM64_PRFM_PLIL3KEEP = 0x0c + 1, - ARM64_PRFM_PLIL3STRM = 0x0d + 1, - ARM64_PRFM_PSTL1KEEP = 0x10 + 1, - ARM64_PRFM_PSTL1STRM = 0x11 + 1, - ARM64_PRFM_PSTL2KEEP = 0x12 + 1, - ARM64_PRFM_PSTL2STRM = 0x13 + 1, - ARM64_PRFM_PSTL3KEEP = 0x14 + 1, - ARM64_PRFM_PSTL3STRM = 0x15 + 1, -} arm64_prefetch_op; - -// Instruction's operand referring to memory -// This is associated with ARM64_OP_MEM operand type above -typedef struct arm64_op_mem -{ - unsigned int base; // base register - unsigned int index; // index register - int32_t disp; // displacement/offset value -} arm64_op_mem; - -// Instruction operand -typedef struct cs_arm64_op -{ - int vector_index; // Vector Index for some vector operands (or -1 if irrelevant) - arm64_vas vas; // Vector Arrangement Specifier - arm64_vess vess; // Vector Element Size Specifier - struct - { - arm64_shifter type; // shifter type of this operand - unsigned int value; // shifter value of this operand - } shift; - arm64_extender ext; // extender type of this operand - arm64_op_type type; // operand type - union - { - unsigned int reg; // register value for REG operand - int64_t imm; // immediate value, or index for C-IMM or IMM operand - double fp; // floating point value for FP operand - arm64_op_mem mem; // base/index/scale/disp value for MEM operand - arm64_pstate pstate; // PState field of MSR instruction. - unsigned int sys; // IC/DC/AT/TLBI operation (see arm64_ic_op, arm64_dc_op, arm64_at_op, arm64_tlbi_op) - arm64_prefetch_op prefetch; // PRFM operation. - arm64_barrier_op barrier; // Memory barrier operation (ISB/DMB/DSB instructions). - }; -} cs_arm64_op; - -// Instruction structure -typedef struct cs_arm64 -{ - arm64_cc cc; // conditional code for this insn - bool update_flags; // does this insn update flags? - bool writeback; // does this insn request writeback? 'True' means 'yes' - - // Number of operands of this instruction, - // or 0 when instruction has no operand. - uint8_t op_count; - - cs_arm64_op operands[8]; // operands for this instruction. -} cs_arm64; - -//> ARM64 registers -typedef enum arm64_reg -{ - ARM64_REG_INVALID = 0, - - ARM64_REG_X29, - ARM64_REG_X30, - ARM64_REG_NZCV, - ARM64_REG_SP, - ARM64_REG_WSP, - ARM64_REG_WZR, - ARM64_REG_XZR, - ARM64_REG_B0, - ARM64_REG_B1, - ARM64_REG_B2, - ARM64_REG_B3, - ARM64_REG_B4, - ARM64_REG_B5, - ARM64_REG_B6, - ARM64_REG_B7, - ARM64_REG_B8, - ARM64_REG_B9, - ARM64_REG_B10, - ARM64_REG_B11, - ARM64_REG_B12, - ARM64_REG_B13, - ARM64_REG_B14, - ARM64_REG_B15, - ARM64_REG_B16, - ARM64_REG_B17, - ARM64_REG_B18, - ARM64_REG_B19, - ARM64_REG_B20, - ARM64_REG_B21, - ARM64_REG_B22, - ARM64_REG_B23, - ARM64_REG_B24, - ARM64_REG_B25, - ARM64_REG_B26, - ARM64_REG_B27, - ARM64_REG_B28, - ARM64_REG_B29, - ARM64_REG_B30, - ARM64_REG_B31, - ARM64_REG_D0, - ARM64_REG_D1, - ARM64_REG_D2, - ARM64_REG_D3, - ARM64_REG_D4, - ARM64_REG_D5, - ARM64_REG_D6, - ARM64_REG_D7, - ARM64_REG_D8, - ARM64_REG_D9, - ARM64_REG_D10, - ARM64_REG_D11, - ARM64_REG_D12, - ARM64_REG_D13, - ARM64_REG_D14, - ARM64_REG_D15, - ARM64_REG_D16, - ARM64_REG_D17, - ARM64_REG_D18, - ARM64_REG_D19, - ARM64_REG_D20, - ARM64_REG_D21, - ARM64_REG_D22, - ARM64_REG_D23, - ARM64_REG_D24, - ARM64_REG_D25, - ARM64_REG_D26, - ARM64_REG_D27, - ARM64_REG_D28, - ARM64_REG_D29, - ARM64_REG_D30, - ARM64_REG_D31, - ARM64_REG_H0, - ARM64_REG_H1, - ARM64_REG_H2, - ARM64_REG_H3, - ARM64_REG_H4, - ARM64_REG_H5, - ARM64_REG_H6, - ARM64_REG_H7, - ARM64_REG_H8, - ARM64_REG_H9, - ARM64_REG_H10, - ARM64_REG_H11, - ARM64_REG_H12, - ARM64_REG_H13, - ARM64_REG_H14, - ARM64_REG_H15, - ARM64_REG_H16, - ARM64_REG_H17, - ARM64_REG_H18, - ARM64_REG_H19, - ARM64_REG_H20, - ARM64_REG_H21, - ARM64_REG_H22, - ARM64_REG_H23, - ARM64_REG_H24, - ARM64_REG_H25, - ARM64_REG_H26, - ARM64_REG_H27, - ARM64_REG_H28, - ARM64_REG_H29, - ARM64_REG_H30, - ARM64_REG_H31, - ARM64_REG_Q0, - ARM64_REG_Q1, - ARM64_REG_Q2, - ARM64_REG_Q3, - ARM64_REG_Q4, - ARM64_REG_Q5, - ARM64_REG_Q6, - ARM64_REG_Q7, - ARM64_REG_Q8, - ARM64_REG_Q9, - ARM64_REG_Q10, - ARM64_REG_Q11, - ARM64_REG_Q12, - ARM64_REG_Q13, - ARM64_REG_Q14, - ARM64_REG_Q15, - ARM64_REG_Q16, - ARM64_REG_Q17, - ARM64_REG_Q18, - ARM64_REG_Q19, - ARM64_REG_Q20, - ARM64_REG_Q21, - ARM64_REG_Q22, - ARM64_REG_Q23, - ARM64_REG_Q24, - ARM64_REG_Q25, - ARM64_REG_Q26, - ARM64_REG_Q27, - ARM64_REG_Q28, - ARM64_REG_Q29, - ARM64_REG_Q30, - ARM64_REG_Q31, - ARM64_REG_S0, - ARM64_REG_S1, - ARM64_REG_S2, - ARM64_REG_S3, - ARM64_REG_S4, - ARM64_REG_S5, - ARM64_REG_S6, - ARM64_REG_S7, - ARM64_REG_S8, - ARM64_REG_S9, - ARM64_REG_S10, - ARM64_REG_S11, - ARM64_REG_S12, - ARM64_REG_S13, - ARM64_REG_S14, - ARM64_REG_S15, - ARM64_REG_S16, - ARM64_REG_S17, - ARM64_REG_S18, - ARM64_REG_S19, - ARM64_REG_S20, - ARM64_REG_S21, - ARM64_REG_S22, - ARM64_REG_S23, - ARM64_REG_S24, - ARM64_REG_S25, - ARM64_REG_S26, - ARM64_REG_S27, - ARM64_REG_S28, - ARM64_REG_S29, - ARM64_REG_S30, - ARM64_REG_S31, - ARM64_REG_W0, - ARM64_REG_W1, - ARM64_REG_W2, - ARM64_REG_W3, - ARM64_REG_W4, - ARM64_REG_W5, - ARM64_REG_W6, - ARM64_REG_W7, - ARM64_REG_W8, - ARM64_REG_W9, - ARM64_REG_W10, - ARM64_REG_W11, - ARM64_REG_W12, - ARM64_REG_W13, - ARM64_REG_W14, - ARM64_REG_W15, - ARM64_REG_W16, - ARM64_REG_W17, - ARM64_REG_W18, - ARM64_REG_W19, - ARM64_REG_W20, - ARM64_REG_W21, - ARM64_REG_W22, - ARM64_REG_W23, - ARM64_REG_W24, - ARM64_REG_W25, - ARM64_REG_W26, - ARM64_REG_W27, - ARM64_REG_W28, - ARM64_REG_W29, - ARM64_REG_W30, - ARM64_REG_X0, - ARM64_REG_X1, - ARM64_REG_X2, - ARM64_REG_X3, - ARM64_REG_X4, - ARM64_REG_X5, - ARM64_REG_X6, - ARM64_REG_X7, - ARM64_REG_X8, - ARM64_REG_X9, - ARM64_REG_X10, - ARM64_REG_X11, - ARM64_REG_X12, - ARM64_REG_X13, - ARM64_REG_X14, - ARM64_REG_X15, - ARM64_REG_X16, - ARM64_REG_X17, - ARM64_REG_X18, - ARM64_REG_X19, - ARM64_REG_X20, - ARM64_REG_X21, - ARM64_REG_X22, - ARM64_REG_X23, - ARM64_REG_X24, - ARM64_REG_X25, - ARM64_REG_X26, - ARM64_REG_X27, - ARM64_REG_X28, - - ARM64_REG_V0, - ARM64_REG_V1, - ARM64_REG_V2, - ARM64_REG_V3, - ARM64_REG_V4, - ARM64_REG_V5, - ARM64_REG_V6, - ARM64_REG_V7, - ARM64_REG_V8, - ARM64_REG_V9, - ARM64_REG_V10, - ARM64_REG_V11, - ARM64_REG_V12, - ARM64_REG_V13, - ARM64_REG_V14, - ARM64_REG_V15, - ARM64_REG_V16, - ARM64_REG_V17, - ARM64_REG_V18, - ARM64_REG_V19, - ARM64_REG_V20, - ARM64_REG_V21, - ARM64_REG_V22, - ARM64_REG_V23, - ARM64_REG_V24, - ARM64_REG_V25, - ARM64_REG_V26, - ARM64_REG_V27, - ARM64_REG_V28, - ARM64_REG_V29, - ARM64_REG_V30, - ARM64_REG_V31, - - ARM64_REG_ENDING, // <-- mark the end of the list of registers - - //> alias registers - - ARM64_REG_IP1 = ARM64_REG_X16, - ARM64_REG_IP0 = ARM64_REG_X17, - ARM64_REG_FP = ARM64_REG_X29, - ARM64_REG_LR = ARM64_REG_X30, -} arm64_reg; - -//> ARM64 instruction -typedef enum arm64_insn -{ - ARM64_INS_INVALID = 0, - - ARM64_INS_ABS, - ARM64_INS_ADC, - ARM64_INS_ADDHN, - ARM64_INS_ADDHN2, - ARM64_INS_ADDP, - ARM64_INS_ADD, - ARM64_INS_ADDV, - ARM64_INS_ADR, - ARM64_INS_ADRP, - ARM64_INS_AESD, - ARM64_INS_AESE, - ARM64_INS_AESIMC, - ARM64_INS_AESMC, - ARM64_INS_AND, - ARM64_INS_ASR, - ARM64_INS_B, - ARM64_INS_BFM, - ARM64_INS_BIC, - ARM64_INS_BIF, - ARM64_INS_BIT, - ARM64_INS_BL, - ARM64_INS_BLR, - ARM64_INS_BR, - ARM64_INS_BRK, - ARM64_INS_BSL, - ARM64_INS_CBNZ, - ARM64_INS_CBZ, - ARM64_INS_CCMN, - ARM64_INS_CCMP, - ARM64_INS_CLREX, - ARM64_INS_CLS, - ARM64_INS_CLZ, - ARM64_INS_CMEQ, - ARM64_INS_CMGE, - ARM64_INS_CMGT, - ARM64_INS_CMHI, - ARM64_INS_CMHS, - ARM64_INS_CMLE, - ARM64_INS_CMLT, - ARM64_INS_CMTST, - ARM64_INS_CNT, - ARM64_INS_MOV, - ARM64_INS_CRC32B, - ARM64_INS_CRC32CB, - ARM64_INS_CRC32CH, - ARM64_INS_CRC32CW, - ARM64_INS_CRC32CX, - ARM64_INS_CRC32H, - ARM64_INS_CRC32W, - ARM64_INS_CRC32X, - ARM64_INS_CSEL, - ARM64_INS_CSINC, - ARM64_INS_CSINV, - ARM64_INS_CSNEG, - ARM64_INS_DCPS1, - ARM64_INS_DCPS2, - ARM64_INS_DCPS3, - ARM64_INS_DMB, - ARM64_INS_DRPS, - ARM64_INS_DSB, - ARM64_INS_DUP, - ARM64_INS_EON, - ARM64_INS_EOR, - ARM64_INS_ERET, - ARM64_INS_EXTR, - ARM64_INS_EXT, - ARM64_INS_FABD, - ARM64_INS_FABS, - ARM64_INS_FACGE, - ARM64_INS_FACGT, - ARM64_INS_FADD, - ARM64_INS_FADDP, - ARM64_INS_FCCMP, - ARM64_INS_FCCMPE, - ARM64_INS_FCMEQ, - ARM64_INS_FCMGE, - ARM64_INS_FCMGT, - ARM64_INS_FCMLE, - ARM64_INS_FCMLT, - ARM64_INS_FCMP, - ARM64_INS_FCMPE, - ARM64_INS_FCSEL, - ARM64_INS_FCVTAS, - ARM64_INS_FCVTAU, - ARM64_INS_FCVT, - ARM64_INS_FCVTL, - ARM64_INS_FCVTL2, - ARM64_INS_FCVTMS, - ARM64_INS_FCVTMU, - ARM64_INS_FCVTNS, - ARM64_INS_FCVTNU, - ARM64_INS_FCVTN, - ARM64_INS_FCVTN2, - ARM64_INS_FCVTPS, - ARM64_INS_FCVTPU, - ARM64_INS_FCVTXN, - ARM64_INS_FCVTXN2, - ARM64_INS_FCVTZS, - ARM64_INS_FCVTZU, - ARM64_INS_FDIV, - ARM64_INS_FMADD, - ARM64_INS_FMAX, - ARM64_INS_FMAXNM, - ARM64_INS_FMAXNMP, - ARM64_INS_FMAXNMV, - ARM64_INS_FMAXP, - ARM64_INS_FMAXV, - ARM64_INS_FMIN, - ARM64_INS_FMINNM, - ARM64_INS_FMINNMP, - ARM64_INS_FMINNMV, - ARM64_INS_FMINP, - ARM64_INS_FMINV, - ARM64_INS_FMLA, - ARM64_INS_FMLS, - ARM64_INS_FMOV, - ARM64_INS_FMSUB, - ARM64_INS_FMUL, - ARM64_INS_FMULX, - ARM64_INS_FNEG, - ARM64_INS_FNMADD, - ARM64_INS_FNMSUB, - ARM64_INS_FNMUL, - ARM64_INS_FRECPE, - ARM64_INS_FRECPS, - ARM64_INS_FRECPX, - ARM64_INS_FRINTA, - ARM64_INS_FRINTI, - ARM64_INS_FRINTM, - ARM64_INS_FRINTN, - ARM64_INS_FRINTP, - ARM64_INS_FRINTX, - ARM64_INS_FRINTZ, - ARM64_INS_FRSQRTE, - ARM64_INS_FRSQRTS, - ARM64_INS_FSQRT, - ARM64_INS_FSUB, - ARM64_INS_HINT, - ARM64_INS_HLT, - ARM64_INS_HVC, - ARM64_INS_INS, - - ARM64_INS_ISB, - ARM64_INS_LD1, - ARM64_INS_LD1R, - ARM64_INS_LD2R, - ARM64_INS_LD2, - ARM64_INS_LD3R, - ARM64_INS_LD3, - ARM64_INS_LD4, - ARM64_INS_LD4R, - - ARM64_INS_LDARB, - ARM64_INS_LDARH, - ARM64_INS_LDAR, - ARM64_INS_LDAXP, - ARM64_INS_LDAXRB, - ARM64_INS_LDAXRH, - ARM64_INS_LDAXR, - ARM64_INS_LDNP, - ARM64_INS_LDP, - ARM64_INS_LDPSW, - ARM64_INS_LDRB, - ARM64_INS_LDR, - ARM64_INS_LDRH, - ARM64_INS_LDRSB, - ARM64_INS_LDRSH, - ARM64_INS_LDRSW, - ARM64_INS_LDTRB, - ARM64_INS_LDTRH, - ARM64_INS_LDTRSB, - - ARM64_INS_LDTRSH, - ARM64_INS_LDTRSW, - ARM64_INS_LDTR, - ARM64_INS_LDURB, - ARM64_INS_LDUR, - ARM64_INS_LDURH, - ARM64_INS_LDURSB, - ARM64_INS_LDURSH, - ARM64_INS_LDURSW, - ARM64_INS_LDXP, - ARM64_INS_LDXRB, - ARM64_INS_LDXRH, - ARM64_INS_LDXR, - ARM64_INS_LSL, - ARM64_INS_LSR, - ARM64_INS_MADD, - ARM64_INS_MLA, - ARM64_INS_MLS, - ARM64_INS_MOVI, - ARM64_INS_MOVK, - ARM64_INS_MOVN, - ARM64_INS_MOVZ, - ARM64_INS_MRS, - ARM64_INS_MSR, - ARM64_INS_MSUB, - ARM64_INS_MUL, - ARM64_INS_MVNI, - ARM64_INS_NEG, - ARM64_INS_NOT, - ARM64_INS_ORN, - ARM64_INS_ORR, - ARM64_INS_PMULL2, - ARM64_INS_PMULL, - ARM64_INS_PMUL, - ARM64_INS_PRFM, - ARM64_INS_PRFUM, - ARM64_INS_RADDHN, - ARM64_INS_RADDHN2, - ARM64_INS_RBIT, - ARM64_INS_RET, - ARM64_INS_REV16, - ARM64_INS_REV32, - ARM64_INS_REV64, - ARM64_INS_REV, - ARM64_INS_ROR, - ARM64_INS_RSHRN2, - ARM64_INS_RSHRN, - ARM64_INS_RSUBHN, - ARM64_INS_RSUBHN2, - ARM64_INS_SABAL2, - ARM64_INS_SABAL, - - ARM64_INS_SABA, - ARM64_INS_SABDL2, - ARM64_INS_SABDL, - ARM64_INS_SABD, - ARM64_INS_SADALP, - ARM64_INS_SADDLP, - ARM64_INS_SADDLV, - ARM64_INS_SADDL2, - ARM64_INS_SADDL, - ARM64_INS_SADDW2, - ARM64_INS_SADDW, - ARM64_INS_SBC, - ARM64_INS_SBFM, - ARM64_INS_SCVTF, - ARM64_INS_SDIV, - ARM64_INS_SHA1C, - ARM64_INS_SHA1H, - ARM64_INS_SHA1M, - ARM64_INS_SHA1P, - ARM64_INS_SHA1SU0, - ARM64_INS_SHA1SU1, - ARM64_INS_SHA256H2, - ARM64_INS_SHA256H, - ARM64_INS_SHA256SU0, - ARM64_INS_SHA256SU1, - ARM64_INS_SHADD, - ARM64_INS_SHLL2, - ARM64_INS_SHLL, - ARM64_INS_SHL, - ARM64_INS_SHRN2, - ARM64_INS_SHRN, - ARM64_INS_SHSUB, - ARM64_INS_SLI, - ARM64_INS_SMADDL, - ARM64_INS_SMAXP, - ARM64_INS_SMAXV, - ARM64_INS_SMAX, - ARM64_INS_SMC, - ARM64_INS_SMINP, - ARM64_INS_SMINV, - ARM64_INS_SMIN, - ARM64_INS_SMLAL2, - ARM64_INS_SMLAL, - ARM64_INS_SMLSL2, - ARM64_INS_SMLSL, - ARM64_INS_SMOV, - ARM64_INS_SMSUBL, - ARM64_INS_SMULH, - ARM64_INS_SMULL2, - ARM64_INS_SMULL, - ARM64_INS_SQABS, - ARM64_INS_SQADD, - ARM64_INS_SQDMLAL, - ARM64_INS_SQDMLAL2, - ARM64_INS_SQDMLSL, - ARM64_INS_SQDMLSL2, - ARM64_INS_SQDMULH, - ARM64_INS_SQDMULL, - ARM64_INS_SQDMULL2, - ARM64_INS_SQNEG, - ARM64_INS_SQRDMULH, - ARM64_INS_SQRSHL, - ARM64_INS_SQRSHRN, - ARM64_INS_SQRSHRN2, - ARM64_INS_SQRSHRUN, - ARM64_INS_SQRSHRUN2, - ARM64_INS_SQSHLU, - ARM64_INS_SQSHL, - ARM64_INS_SQSHRN, - ARM64_INS_SQSHRN2, - ARM64_INS_SQSHRUN, - ARM64_INS_SQSHRUN2, - ARM64_INS_SQSUB, - ARM64_INS_SQXTN2, - ARM64_INS_SQXTN, - ARM64_INS_SQXTUN2, - ARM64_INS_SQXTUN, - ARM64_INS_SRHADD, - ARM64_INS_SRI, - ARM64_INS_SRSHL, - ARM64_INS_SRSHR, - ARM64_INS_SRSRA, - ARM64_INS_SSHLL2, - ARM64_INS_SSHLL, - ARM64_INS_SSHL, - ARM64_INS_SSHR, - ARM64_INS_SSRA, - ARM64_INS_SSUBL2, - ARM64_INS_SSUBL, - ARM64_INS_SSUBW2, - ARM64_INS_SSUBW, - ARM64_INS_ST1, - ARM64_INS_ST2, - ARM64_INS_ST3, - ARM64_INS_ST4, - ARM64_INS_STLRB, - ARM64_INS_STLRH, - ARM64_INS_STLR, - ARM64_INS_STLXP, - ARM64_INS_STLXRB, - ARM64_INS_STLXRH, - ARM64_INS_STLXR, - ARM64_INS_STNP, - ARM64_INS_STP, - ARM64_INS_STRB, - ARM64_INS_STR, - ARM64_INS_STRH, - ARM64_INS_STTRB, - ARM64_INS_STTRH, - ARM64_INS_STTR, - ARM64_INS_STURB, - ARM64_INS_STUR, - ARM64_INS_STURH, - ARM64_INS_STXP, - ARM64_INS_STXRB, - ARM64_INS_STXRH, - ARM64_INS_STXR, - ARM64_INS_SUBHN, - ARM64_INS_SUBHN2, - ARM64_INS_SUB, - ARM64_INS_SUQADD, - ARM64_INS_SVC, - ARM64_INS_SYSL, - ARM64_INS_SYS, - ARM64_INS_TBL, - ARM64_INS_TBNZ, - ARM64_INS_TBX, - ARM64_INS_TBZ, - ARM64_INS_TRN1, - ARM64_INS_TRN2, - ARM64_INS_UABAL2, - ARM64_INS_UABAL, - ARM64_INS_UABA, - ARM64_INS_UABDL2, - ARM64_INS_UABDL, - ARM64_INS_UABD, - ARM64_INS_UADALP, - ARM64_INS_UADDLP, - ARM64_INS_UADDLV, - ARM64_INS_UADDL2, - ARM64_INS_UADDL, - ARM64_INS_UADDW2, - ARM64_INS_UADDW, - ARM64_INS_UBFM, - ARM64_INS_UCVTF, - ARM64_INS_UDIV, - ARM64_INS_UHADD, - ARM64_INS_UHSUB, - ARM64_INS_UMADDL, - ARM64_INS_UMAXP, - ARM64_INS_UMAXV, - ARM64_INS_UMAX, - ARM64_INS_UMINP, - ARM64_INS_UMINV, - ARM64_INS_UMIN, - ARM64_INS_UMLAL2, - ARM64_INS_UMLAL, - ARM64_INS_UMLSL2, - ARM64_INS_UMLSL, - ARM64_INS_UMOV, - ARM64_INS_UMSUBL, - ARM64_INS_UMULH, - ARM64_INS_UMULL2, - ARM64_INS_UMULL, - ARM64_INS_UQADD, - ARM64_INS_UQRSHL, - ARM64_INS_UQRSHRN, - ARM64_INS_UQRSHRN2, - ARM64_INS_UQSHL, - ARM64_INS_UQSHRN, - ARM64_INS_UQSHRN2, - ARM64_INS_UQSUB, - ARM64_INS_UQXTN2, - ARM64_INS_UQXTN, - ARM64_INS_URECPE, - ARM64_INS_URHADD, - ARM64_INS_URSHL, - ARM64_INS_URSHR, - ARM64_INS_URSQRTE, - ARM64_INS_URSRA, - ARM64_INS_USHLL2, - ARM64_INS_USHLL, - ARM64_INS_USHL, - ARM64_INS_USHR, - ARM64_INS_USQADD, - ARM64_INS_USRA, - ARM64_INS_USUBL2, - ARM64_INS_USUBL, - ARM64_INS_USUBW2, - ARM64_INS_USUBW, - ARM64_INS_UZP1, - ARM64_INS_UZP2, - ARM64_INS_XTN2, - ARM64_INS_XTN, - ARM64_INS_ZIP1, - ARM64_INS_ZIP2, - - // alias insn - ARM64_INS_MNEG, - ARM64_INS_UMNEGL, - ARM64_INS_SMNEGL, - ARM64_INS_NOP, - ARM64_INS_YIELD, - ARM64_INS_WFE, - ARM64_INS_WFI, - ARM64_INS_SEV, - ARM64_INS_SEVL, - ARM64_INS_NGC, - ARM64_INS_SBFIZ, - ARM64_INS_UBFIZ, - ARM64_INS_SBFX, - ARM64_INS_UBFX, - ARM64_INS_BFI, - ARM64_INS_BFXIL, - ARM64_INS_CMN, - ARM64_INS_MVN, - ARM64_INS_TST, - ARM64_INS_CSET, - ARM64_INS_CINC, - ARM64_INS_CSETM, - ARM64_INS_CINV, - ARM64_INS_CNEG, - ARM64_INS_SXTB, - ARM64_INS_SXTH, - ARM64_INS_SXTW, - ARM64_INS_CMP, - ARM64_INS_UXTB, - ARM64_INS_UXTH, - ARM64_INS_UXTW, - ARM64_INS_IC, - ARM64_INS_DC, - ARM64_INS_AT, - ARM64_INS_TLBI, - - ARM64_INS_ENDING, // <-- mark the end of the list of insn -} arm64_insn; - -//> Group of ARM64 instructions -typedef enum arm64_insn_group -{ - ARM64_GRP_INVALID = 0, // = CS_GRP_INVALID - - //> Generic groups - // all jump instructions (conditional+direct+indirect jumps) - ARM64_GRP_JUMP, // = CS_GRP_JUMP - - //> Architecture-specific groups - ARM64_GRP_CRYPTO = 128, - ARM64_GRP_FPARMV8, - ARM64_GRP_NEON, - ARM64_GRP_CRC, - - ARM64_GRP_ENDING, // <-- mark the end of the list of groups -} arm64_insn_group; - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef CAPSTONE_ARM64_H +#define CAPSTONE_ARM64_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "platform.h" + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> ARM64 shift type +typedef enum arm64_shifter +{ + ARM64_SFT_INVALID = 0, + ARM64_SFT_LSL = 1, + ARM64_SFT_MSL = 2, + ARM64_SFT_LSR = 3, + ARM64_SFT_ASR = 4, + ARM64_SFT_ROR = 5, +} arm64_shifter; + +//> ARM64 extender type +typedef enum arm64_extender +{ + ARM64_EXT_INVALID = 0, + ARM64_EXT_UXTB = 1, + ARM64_EXT_UXTH = 2, + ARM64_EXT_UXTW = 3, + ARM64_EXT_UXTX = 4, + ARM64_EXT_SXTB = 5, + ARM64_EXT_SXTH = 6, + ARM64_EXT_SXTW = 7, + ARM64_EXT_SXTX = 8, +} arm64_extender; + +//> ARM64 condition code +typedef enum arm64_cc +{ + ARM64_CC_INVALID = 0, + ARM64_CC_EQ = 1, // Equal + ARM64_CC_NE = 2, // Not equal: Not equal, or unordered + ARM64_CC_HS = 3, // Unsigned higher or same: >, ==, or unordered + ARM64_CC_LO = 4, // Unsigned lower or same: Less than + ARM64_CC_MI = 5, // Minus, negative: Less than + ARM64_CC_PL = 6, // Plus, positive or zero: >, ==, or unordered + ARM64_CC_VS = 7, // Overflow: Unordered + ARM64_CC_VC = 8, // No overflow: Ordered + ARM64_CC_HI = 9, // Unsigned higher: Greater than, or unordered + ARM64_CC_LS = 10, // Unsigned lower or same: Less than or equal + ARM64_CC_GE = 11, // Greater than or equal: Greater than or equal + ARM64_CC_LT = 12, // Less than: Less than, or unordered + ARM64_CC_GT = 13, // Signed greater than: Greater than + ARM64_CC_LE = 14, // Signed less than or equal: <, ==, or unordered + ARM64_CC_AL = 15, // Always (unconditional): Always (unconditional) + ARM64_CC_NV = 16, // Always (unconditional): Always (unconditional) + // Note the NV exists purely to disassemble 0b1111. Execution + // is "always". +} arm64_cc; + +//> System registers +typedef enum arm64_mrs_reg +{ + //> System registers for MRS + ARM64_SYSREG_INVALID = 0, + ARM64_SYSREG_MDCCSR_EL0 = 0x9808, // 10 011 0000 0001 000 + ARM64_SYSREG_DBGDTRRX_EL0 = 0x9828, // 10 011 0000 0101 000 + ARM64_SYSREG_MDRAR_EL1 = 0x8080, // 10 000 0001 0000 000 + ARM64_SYSREG_OSLSR_EL1 = 0x808c, // 10 000 0001 0001 100 + ARM64_SYSREG_DBGAUTHSTATUS_EL1 = 0x83f6, // 10 000 0111 1110 110 + ARM64_SYSREG_PMCEID0_EL0 = 0xdce6, // 11 011 1001 1100 110 + ARM64_SYSREG_PMCEID1_EL0 = 0xdce7, // 11 011 1001 1100 111 + ARM64_SYSREG_MIDR_EL1 = 0xc000, // 11 000 0000 0000 000 + ARM64_SYSREG_CCSIDR_EL1 = 0xc800, // 11 001 0000 0000 000 + ARM64_SYSREG_CLIDR_EL1 = 0xc801, // 11 001 0000 0000 001 + ARM64_SYSREG_CTR_EL0 = 0xd801, // 11 011 0000 0000 001 + ARM64_SYSREG_MPIDR_EL1 = 0xc005, // 11 000 0000 0000 101 + ARM64_SYSREG_REVIDR_EL1 = 0xc006, // 11 000 0000 0000 110 + ARM64_SYSREG_AIDR_EL1 = 0xc807, // 11 001 0000 0000 111 + ARM64_SYSREG_DCZID_EL0 = 0xd807, // 11 011 0000 0000 111 + ARM64_SYSREG_ID_PFR0_EL1 = 0xc008, // 11 000 0000 0001 000 + ARM64_SYSREG_ID_PFR1_EL1 = 0xc009, // 11 000 0000 0001 001 + ARM64_SYSREG_ID_DFR0_EL1 = 0xc00a, // 11 000 0000 0001 010 + ARM64_SYSREG_ID_AFR0_EL1 = 0xc00b, // 11 000 0000 0001 011 + ARM64_SYSREG_ID_MMFR0_EL1 = 0xc00c, // 11 000 0000 0001 100 + ARM64_SYSREG_ID_MMFR1_EL1 = 0xc00d, // 11 000 0000 0001 101 + ARM64_SYSREG_ID_MMFR2_EL1 = 0xc00e, // 11 000 0000 0001 110 + ARM64_SYSREG_ID_MMFR3_EL1 = 0xc00f, // 11 000 0000 0001 111 + ARM64_SYSREG_ID_ISAR0_EL1 = 0xc010, // 11 000 0000 0010 000 + ARM64_SYSREG_ID_ISAR1_EL1 = 0xc011, // 11 000 0000 0010 001 + ARM64_SYSREG_ID_ISAR2_EL1 = 0xc012, // 11 000 0000 0010 010 + ARM64_SYSREG_ID_ISAR3_EL1 = 0xc013, // 11 000 0000 0010 011 + ARM64_SYSREG_ID_ISAR4_EL1 = 0xc014, // 11 000 0000 0010 100 + ARM64_SYSREG_ID_ISAR5_EL1 = 0xc015, // 11 000 0000 0010 101 + ARM64_SYSREG_ID_A64PFR0_EL1 = 0xc020, // 11 000 0000 0100 000 + ARM64_SYSREG_ID_A64PFR1_EL1 = 0xc021, // 11 000 0000 0100 001 + ARM64_SYSREG_ID_A64DFR0_EL1 = 0xc028, // 11 000 0000 0101 000 + ARM64_SYSREG_ID_A64DFR1_EL1 = 0xc029, // 11 000 0000 0101 001 + ARM64_SYSREG_ID_A64AFR0_EL1 = 0xc02c, // 11 000 0000 0101 100 + ARM64_SYSREG_ID_A64AFR1_EL1 = 0xc02d, // 11 000 0000 0101 101 + ARM64_SYSREG_ID_A64ISAR0_EL1 = 0xc030, // 11 000 0000 0110 000 + ARM64_SYSREG_ID_A64ISAR1_EL1 = 0xc031, // 11 000 0000 0110 001 + ARM64_SYSREG_ID_A64MMFR0_EL1 = 0xc038, // 11 000 0000 0111 000 + ARM64_SYSREG_ID_A64MMFR1_EL1 = 0xc039, // 11 000 0000 0111 001 + ARM64_SYSREG_MVFR0_EL1 = 0xc018, // 11 000 0000 0011 000 + ARM64_SYSREG_MVFR1_EL1 = 0xc019, // 11 000 0000 0011 001 + ARM64_SYSREG_MVFR2_EL1 = 0xc01a, // 11 000 0000 0011 010 + ARM64_SYSREG_RVBAR_EL1 = 0xc601, // 11 000 1100 0000 001 + ARM64_SYSREG_RVBAR_EL2 = 0xe601, // 11 100 1100 0000 001 + ARM64_SYSREG_RVBAR_EL3 = 0xf601, // 11 110 1100 0000 001 + ARM64_SYSREG_ISR_EL1 = 0xc608, // 11 000 1100 0001 000 + ARM64_SYSREG_CNTPCT_EL0 = 0xdf01, // 11 011 1110 0000 001 + ARM64_SYSREG_CNTVCT_EL0 = 0xdf02, // 11 011 1110 0000 010 + + // Trace registers + ARM64_SYSREG_TRCSTATR = 0x8818, // 10 001 0000 0011 000 + ARM64_SYSREG_TRCIDR8 = 0x8806, // 10 001 0000 0000 110 + ARM64_SYSREG_TRCIDR9 = 0x880e, // 10 001 0000 0001 110 + ARM64_SYSREG_TRCIDR10 = 0x8816, // 10 001 0000 0010 110 + ARM64_SYSREG_TRCIDR11 = 0x881e, // 10 001 0000 0011 110 + ARM64_SYSREG_TRCIDR12 = 0x8826, // 10 001 0000 0100 110 + ARM64_SYSREG_TRCIDR13 = 0x882e, // 10 001 0000 0101 110 + ARM64_SYSREG_TRCIDR0 = 0x8847, // 10 001 0000 1000 111 + ARM64_SYSREG_TRCIDR1 = 0x884f, // 10 001 0000 1001 111 + ARM64_SYSREG_TRCIDR2 = 0x8857, // 10 001 0000 1010 111 + ARM64_SYSREG_TRCIDR3 = 0x885f, // 10 001 0000 1011 111 + ARM64_SYSREG_TRCIDR4 = 0x8867, // 10 001 0000 1100 111 + ARM64_SYSREG_TRCIDR5 = 0x886f, // 10 001 0000 1101 111 + ARM64_SYSREG_TRCIDR6 = 0x8877, // 10 001 0000 1110 111 + ARM64_SYSREG_TRCIDR7 = 0x887f, // 10 001 0000 1111 111 + ARM64_SYSREG_TRCOSLSR = 0x888c, // 10 001 0001 0001 100 + ARM64_SYSREG_TRCPDSR = 0x88ac, // 10 001 0001 0101 100 + ARM64_SYSREG_TRCDEVAFF0 = 0x8bd6, // 10 001 0111 1010 110 + ARM64_SYSREG_TRCDEVAFF1 = 0x8bde, // 10 001 0111 1011 110 + ARM64_SYSREG_TRCLSR = 0x8bee, // 10 001 0111 1101 110 + ARM64_SYSREG_TRCAUTHSTATUS = 0x8bf6, // 10 001 0111 1110 110 + ARM64_SYSREG_TRCDEVARCH = 0x8bfe, // 10 001 0111 1111 110 + ARM64_SYSREG_TRCDEVID = 0x8b97, // 10 001 0111 0010 111 + ARM64_SYSREG_TRCDEVTYPE = 0x8b9f, // 10 001 0111 0011 111 + ARM64_SYSREG_TRCPIDR4 = 0x8ba7, // 10 001 0111 0100 111 + ARM64_SYSREG_TRCPIDR5 = 0x8baf, // 10 001 0111 0101 111 + ARM64_SYSREG_TRCPIDR6 = 0x8bb7, // 10 001 0111 0110 111 + ARM64_SYSREG_TRCPIDR7 = 0x8bbf, // 10 001 0111 0111 111 + ARM64_SYSREG_TRCPIDR0 = 0x8bc7, // 10 001 0111 1000 111 + ARM64_SYSREG_TRCPIDR1 = 0x8bcf, // 10 001 0111 1001 111 + ARM64_SYSREG_TRCPIDR2 = 0x8bd7, // 10 001 0111 1010 111 + ARM64_SYSREG_TRCPIDR3 = 0x8bdf, // 10 001 0111 1011 111 + ARM64_SYSREG_TRCCIDR0 = 0x8be7, // 10 001 0111 1100 111 + ARM64_SYSREG_TRCCIDR1 = 0x8bef, // 10 001 0111 1101 111 + ARM64_SYSREG_TRCCIDR2 = 0x8bf7, // 10 001 0111 1110 111 + ARM64_SYSREG_TRCCIDR3 = 0x8bff, // 10 001 0111 1111 111 + + // GICv3 registers + ARM64_SYSREG_ICC_IAR1_EL1 = 0xc660, // 11 000 1100 1100 000 + ARM64_SYSREG_ICC_IAR0_EL1 = 0xc640, // 11 000 1100 1000 000 + ARM64_SYSREG_ICC_HPPIR1_EL1 = 0xc662, // 11 000 1100 1100 010 + ARM64_SYSREG_ICC_HPPIR0_EL1 = 0xc642, // 11 000 1100 1000 010 + ARM64_SYSREG_ICC_RPR_EL1 = 0xc65b, // 11 000 1100 1011 011 + ARM64_SYSREG_ICH_VTR_EL2 = 0xe659, // 11 100 1100 1011 001 + ARM64_SYSREG_ICH_EISR_EL2 = 0xe65b, // 11 100 1100 1011 011 + ARM64_SYSREG_ICH_ELSR_EL2 = 0xe65d, // 11 100 1100 1011 101 +} arm64_sysreg; + +typedef enum arm64_msr_reg +{ + //> System registers for MSR + ARM64_SYSREG_DBGDTRTX_EL0 = 0x9828, // 10 011 0000 0101 000 + ARM64_SYSREG_OSLAR_EL1 = 0x8084, // 10 000 0001 0000 100 + ARM64_SYSREG_PMSWINC_EL0 = 0xdce4, // 11 011 1001 1100 100 + + // Trace Registers + ARM64_SYSREG_TRCOSLAR = 0x8884, // 10 001 0001 0000 100 + ARM64_SYSREG_TRCLAR = 0x8be6, // 10 001 0111 1100 110 + + // GICv3 registers + ARM64_SYSREG_ICC_EOIR1_EL1 = 0xc661, // 11 000 1100 1100 001 + ARM64_SYSREG_ICC_EOIR0_EL1 = 0xc641, // 11 000 1100 1000 001 + ARM64_SYSREG_ICC_DIR_EL1 = 0xc659, // 11 000 1100 1011 001 + ARM64_SYSREG_ICC_SGI1R_EL1 = 0xc65d, // 11 000 1100 1011 101 + ARM64_SYSREG_ICC_ASGI1R_EL1 = 0xc65e, // 11 000 1100 1011 110 + ARM64_SYSREG_ICC_SGI0R_EL1 = 0xc65f, // 11 000 1100 1011 111 +} arm64_msr_reg; + +//> System PState Field (MSR instruction) +typedef enum arm64_pstate +{ + ARM64_PSTATE_INVALID = 0, + ARM64_PSTATE_SPSEL = 0x05, + ARM64_PSTATE_DAIFSET = 0x1e, + ARM64_PSTATE_DAIFCLR = 0x1f +} arm64_pstate; + +//> Vector arrangement specifier (for FloatingPoint/Advanced SIMD insn) +typedef enum arm64_vas +{ + ARM64_VAS_INVALID = 0, + ARM64_VAS_8B, + ARM64_VAS_16B, + ARM64_VAS_4H, + ARM64_VAS_8H, + ARM64_VAS_2S, + ARM64_VAS_4S, + ARM64_VAS_1D, + ARM64_VAS_2D, + ARM64_VAS_1Q, +} arm64_vas; + +//> Vector element size specifier +typedef enum arm64_vess +{ + ARM64_VESS_INVALID = 0, + ARM64_VESS_B, + ARM64_VESS_H, + ARM64_VESS_S, + ARM64_VESS_D, +} arm64_vess; + +//> Memory barrier operands +typedef enum arm64_barrier_op +{ + ARM64_BARRIER_INVALID = 0, + ARM64_BARRIER_OSHLD = 0x1, + ARM64_BARRIER_OSHST = 0x2, + ARM64_BARRIER_OSH = 0x3, + ARM64_BARRIER_NSHLD = 0x5, + ARM64_BARRIER_NSHST = 0x6, + ARM64_BARRIER_NSH = 0x7, + ARM64_BARRIER_ISHLD = 0x9, + ARM64_BARRIER_ISHST = 0xa, + ARM64_BARRIER_ISH = 0xb, + ARM64_BARRIER_LD = 0xd, + ARM64_BARRIER_ST = 0xe, + ARM64_BARRIER_SY = 0xf +} arm64_barrier_op; + +//> Operand type for instruction's operands +typedef enum arm64_op_type +{ + ARM64_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + ARM64_OP_REG, // = CS_OP_REG (Register operand). + ARM64_OP_IMM, // = CS_OP_IMM (Immediate operand). + ARM64_OP_MEM, // = CS_OP_MEM (Memory operand). + ARM64_OP_FP, // = CS_OP_FP (Floating-Point operand). + ARM64_OP_CIMM = 64, // C-Immediate + ARM64_OP_REG_MRS, // MRS register operand. + ARM64_OP_REG_MSR, // MSR register operand. + ARM64_OP_PSTATE, // PState operand. + ARM64_OP_SYS, // SYS operand for IC/DC/AT/TLBI instructions. + ARM64_OP_PREFETCH, // Prefetch operand (PRFM). + ARM64_OP_BARRIER, // Memory barrier operand (ISB/DMB/DSB instructions). +} arm64_op_type; + +//> TLBI operations +typedef enum arm64_tlbi_op +{ + ARM64_TLBI_INVALID = 0, + ARM64_TLBI_VMALLE1IS, + ARM64_TLBI_VAE1IS, + ARM64_TLBI_ASIDE1IS, + ARM64_TLBI_VAAE1IS, + ARM64_TLBI_VALE1IS, + ARM64_TLBI_VAALE1IS, + ARM64_TLBI_ALLE2IS, + ARM64_TLBI_VAE2IS, + ARM64_TLBI_ALLE1IS, + ARM64_TLBI_VALE2IS, + ARM64_TLBI_VMALLS12E1IS, + ARM64_TLBI_ALLE3IS, + ARM64_TLBI_VAE3IS, + ARM64_TLBI_VALE3IS, + ARM64_TLBI_IPAS2E1IS, + ARM64_TLBI_IPAS2LE1IS, + ARM64_TLBI_IPAS2E1, + ARM64_TLBI_IPAS2LE1, + ARM64_TLBI_VMALLE1, + ARM64_TLBI_VAE1, + ARM64_TLBI_ASIDE1, + ARM64_TLBI_VAAE1, + ARM64_TLBI_VALE1, + ARM64_TLBI_VAALE1, + ARM64_TLBI_ALLE2, + ARM64_TLBI_VAE2, + ARM64_TLBI_ALLE1, + ARM64_TLBI_VALE2, + ARM64_TLBI_VMALLS12E1, + ARM64_TLBI_ALLE3, + ARM64_TLBI_VAE3, + ARM64_TLBI_VALE3, +} arm64_tlbi_op; + +//> AT operations +typedef enum arm64_at_op +{ + ARM64_AT_S1E1R, + ARM64_AT_S1E1W, + ARM64_AT_S1E0R, + ARM64_AT_S1E0W, + ARM64_AT_S1E2R, + ARM64_AT_S1E2W, + ARM64_AT_S12E1R, + ARM64_AT_S12E1W, + ARM64_AT_S12E0R, + ARM64_AT_S12E0W, + ARM64_AT_S1E3R, + ARM64_AT_S1E3W, +} arm64_at_op; + +//> DC operations +typedef enum arm64_dc_op +{ + ARM64_DC_INVALID = 0, + ARM64_DC_ZVA, + ARM64_DC_IVAC, + ARM64_DC_ISW, + ARM64_DC_CVAC, + ARM64_DC_CSW, + ARM64_DC_CVAU, + ARM64_DC_CIVAC, + ARM64_DC_CISW, +} arm64_dc_op; + +//> IC operations +typedef enum arm64_ic_op +{ + ARM64_IC_INVALID = 0, + ARM64_IC_IALLUIS, + ARM64_IC_IALLU, + ARM64_IC_IVAU, +} arm64_ic_op; + +//> Prefetch operations (PRFM) +typedef enum arm64_prefetch_op +{ + ARM64_PRFM_INVALID = 0, + ARM64_PRFM_PLDL1KEEP = 0x00 + 1, + ARM64_PRFM_PLDL1STRM = 0x01 + 1, + ARM64_PRFM_PLDL2KEEP = 0x02 + 1, + ARM64_PRFM_PLDL2STRM = 0x03 + 1, + ARM64_PRFM_PLDL3KEEP = 0x04 + 1, + ARM64_PRFM_PLDL3STRM = 0x05 + 1, + ARM64_PRFM_PLIL1KEEP = 0x08 + 1, + ARM64_PRFM_PLIL1STRM = 0x09 + 1, + ARM64_PRFM_PLIL2KEEP = 0x0a + 1, + ARM64_PRFM_PLIL2STRM = 0x0b + 1, + ARM64_PRFM_PLIL3KEEP = 0x0c + 1, + ARM64_PRFM_PLIL3STRM = 0x0d + 1, + ARM64_PRFM_PSTL1KEEP = 0x10 + 1, + ARM64_PRFM_PSTL1STRM = 0x11 + 1, + ARM64_PRFM_PSTL2KEEP = 0x12 + 1, + ARM64_PRFM_PSTL2STRM = 0x13 + 1, + ARM64_PRFM_PSTL3KEEP = 0x14 + 1, + ARM64_PRFM_PSTL3STRM = 0x15 + 1, +} arm64_prefetch_op; + +// Instruction's operand referring to memory +// This is associated with ARM64_OP_MEM operand type above +typedef struct arm64_op_mem +{ + unsigned int base; // base register + unsigned int index; // index register + int32_t disp; // displacement/offset value +} arm64_op_mem; + +// Instruction operand +typedef struct cs_arm64_op +{ + int vector_index; // Vector Index for some vector operands (or -1 if irrelevant) + arm64_vas vas; // Vector Arrangement Specifier + arm64_vess vess; // Vector Element Size Specifier + struct + { + arm64_shifter type; // shifter type of this operand + unsigned int value; // shifter value of this operand + } shift; + arm64_extender ext; // extender type of this operand + arm64_op_type type; // operand type + union + { + unsigned int reg; // register value for REG operand + int64_t imm; // immediate value, or index for C-IMM or IMM operand + double fp; // floating point value for FP operand + arm64_op_mem mem; // base/index/scale/disp value for MEM operand + arm64_pstate pstate; // PState field of MSR instruction. + unsigned int sys; // IC/DC/AT/TLBI operation (see arm64_ic_op, arm64_dc_op, arm64_at_op, arm64_tlbi_op) + arm64_prefetch_op prefetch; // PRFM operation. + arm64_barrier_op barrier; // Memory barrier operation (ISB/DMB/DSB instructions). + }; +} cs_arm64_op; + +// Instruction structure +typedef struct cs_arm64 +{ + arm64_cc cc; // conditional code for this insn + bool update_flags; // does this insn update flags? + bool writeback; // does this insn request writeback? 'True' means 'yes' + + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + + cs_arm64_op operands[8]; // operands for this instruction. +} cs_arm64; + +//> ARM64 registers +typedef enum arm64_reg +{ + ARM64_REG_INVALID = 0, + + ARM64_REG_X29, + ARM64_REG_X30, + ARM64_REG_NZCV, + ARM64_REG_SP, + ARM64_REG_WSP, + ARM64_REG_WZR, + ARM64_REG_XZR, + ARM64_REG_B0, + ARM64_REG_B1, + ARM64_REG_B2, + ARM64_REG_B3, + ARM64_REG_B4, + ARM64_REG_B5, + ARM64_REG_B6, + ARM64_REG_B7, + ARM64_REG_B8, + ARM64_REG_B9, + ARM64_REG_B10, + ARM64_REG_B11, + ARM64_REG_B12, + ARM64_REG_B13, + ARM64_REG_B14, + ARM64_REG_B15, + ARM64_REG_B16, + ARM64_REG_B17, + ARM64_REG_B18, + ARM64_REG_B19, + ARM64_REG_B20, + ARM64_REG_B21, + ARM64_REG_B22, + ARM64_REG_B23, + ARM64_REG_B24, + ARM64_REG_B25, + ARM64_REG_B26, + ARM64_REG_B27, + ARM64_REG_B28, + ARM64_REG_B29, + ARM64_REG_B30, + ARM64_REG_B31, + ARM64_REG_D0, + ARM64_REG_D1, + ARM64_REG_D2, + ARM64_REG_D3, + ARM64_REG_D4, + ARM64_REG_D5, + ARM64_REG_D6, + ARM64_REG_D7, + ARM64_REG_D8, + ARM64_REG_D9, + ARM64_REG_D10, + ARM64_REG_D11, + ARM64_REG_D12, + ARM64_REG_D13, + ARM64_REG_D14, + ARM64_REG_D15, + ARM64_REG_D16, + ARM64_REG_D17, + ARM64_REG_D18, + ARM64_REG_D19, + ARM64_REG_D20, + ARM64_REG_D21, + ARM64_REG_D22, + ARM64_REG_D23, + ARM64_REG_D24, + ARM64_REG_D25, + ARM64_REG_D26, + ARM64_REG_D27, + ARM64_REG_D28, + ARM64_REG_D29, + ARM64_REG_D30, + ARM64_REG_D31, + ARM64_REG_H0, + ARM64_REG_H1, + ARM64_REG_H2, + ARM64_REG_H3, + ARM64_REG_H4, + ARM64_REG_H5, + ARM64_REG_H6, + ARM64_REG_H7, + ARM64_REG_H8, + ARM64_REG_H9, + ARM64_REG_H10, + ARM64_REG_H11, + ARM64_REG_H12, + ARM64_REG_H13, + ARM64_REG_H14, + ARM64_REG_H15, + ARM64_REG_H16, + ARM64_REG_H17, + ARM64_REG_H18, + ARM64_REG_H19, + ARM64_REG_H20, + ARM64_REG_H21, + ARM64_REG_H22, + ARM64_REG_H23, + ARM64_REG_H24, + ARM64_REG_H25, + ARM64_REG_H26, + ARM64_REG_H27, + ARM64_REG_H28, + ARM64_REG_H29, + ARM64_REG_H30, + ARM64_REG_H31, + ARM64_REG_Q0, + ARM64_REG_Q1, + ARM64_REG_Q2, + ARM64_REG_Q3, + ARM64_REG_Q4, + ARM64_REG_Q5, + ARM64_REG_Q6, + ARM64_REG_Q7, + ARM64_REG_Q8, + ARM64_REG_Q9, + ARM64_REG_Q10, + ARM64_REG_Q11, + ARM64_REG_Q12, + ARM64_REG_Q13, + ARM64_REG_Q14, + ARM64_REG_Q15, + ARM64_REG_Q16, + ARM64_REG_Q17, + ARM64_REG_Q18, + ARM64_REG_Q19, + ARM64_REG_Q20, + ARM64_REG_Q21, + ARM64_REG_Q22, + ARM64_REG_Q23, + ARM64_REG_Q24, + ARM64_REG_Q25, + ARM64_REG_Q26, + ARM64_REG_Q27, + ARM64_REG_Q28, + ARM64_REG_Q29, + ARM64_REG_Q30, + ARM64_REG_Q31, + ARM64_REG_S0, + ARM64_REG_S1, + ARM64_REG_S2, + ARM64_REG_S3, + ARM64_REG_S4, + ARM64_REG_S5, + ARM64_REG_S6, + ARM64_REG_S7, + ARM64_REG_S8, + ARM64_REG_S9, + ARM64_REG_S10, + ARM64_REG_S11, + ARM64_REG_S12, + ARM64_REG_S13, + ARM64_REG_S14, + ARM64_REG_S15, + ARM64_REG_S16, + ARM64_REG_S17, + ARM64_REG_S18, + ARM64_REG_S19, + ARM64_REG_S20, + ARM64_REG_S21, + ARM64_REG_S22, + ARM64_REG_S23, + ARM64_REG_S24, + ARM64_REG_S25, + ARM64_REG_S26, + ARM64_REG_S27, + ARM64_REG_S28, + ARM64_REG_S29, + ARM64_REG_S30, + ARM64_REG_S31, + ARM64_REG_W0, + ARM64_REG_W1, + ARM64_REG_W2, + ARM64_REG_W3, + ARM64_REG_W4, + ARM64_REG_W5, + ARM64_REG_W6, + ARM64_REG_W7, + ARM64_REG_W8, + ARM64_REG_W9, + ARM64_REG_W10, + ARM64_REG_W11, + ARM64_REG_W12, + ARM64_REG_W13, + ARM64_REG_W14, + ARM64_REG_W15, + ARM64_REG_W16, + ARM64_REG_W17, + ARM64_REG_W18, + ARM64_REG_W19, + ARM64_REG_W20, + ARM64_REG_W21, + ARM64_REG_W22, + ARM64_REG_W23, + ARM64_REG_W24, + ARM64_REG_W25, + ARM64_REG_W26, + ARM64_REG_W27, + ARM64_REG_W28, + ARM64_REG_W29, + ARM64_REG_W30, + ARM64_REG_X0, + ARM64_REG_X1, + ARM64_REG_X2, + ARM64_REG_X3, + ARM64_REG_X4, + ARM64_REG_X5, + ARM64_REG_X6, + ARM64_REG_X7, + ARM64_REG_X8, + ARM64_REG_X9, + ARM64_REG_X10, + ARM64_REG_X11, + ARM64_REG_X12, + ARM64_REG_X13, + ARM64_REG_X14, + ARM64_REG_X15, + ARM64_REG_X16, + ARM64_REG_X17, + ARM64_REG_X18, + ARM64_REG_X19, + ARM64_REG_X20, + ARM64_REG_X21, + ARM64_REG_X22, + ARM64_REG_X23, + ARM64_REG_X24, + ARM64_REG_X25, + ARM64_REG_X26, + ARM64_REG_X27, + ARM64_REG_X28, + + ARM64_REG_V0, + ARM64_REG_V1, + ARM64_REG_V2, + ARM64_REG_V3, + ARM64_REG_V4, + ARM64_REG_V5, + ARM64_REG_V6, + ARM64_REG_V7, + ARM64_REG_V8, + ARM64_REG_V9, + ARM64_REG_V10, + ARM64_REG_V11, + ARM64_REG_V12, + ARM64_REG_V13, + ARM64_REG_V14, + ARM64_REG_V15, + ARM64_REG_V16, + ARM64_REG_V17, + ARM64_REG_V18, + ARM64_REG_V19, + ARM64_REG_V20, + ARM64_REG_V21, + ARM64_REG_V22, + ARM64_REG_V23, + ARM64_REG_V24, + ARM64_REG_V25, + ARM64_REG_V26, + ARM64_REG_V27, + ARM64_REG_V28, + ARM64_REG_V29, + ARM64_REG_V30, + ARM64_REG_V31, + + ARM64_REG_ENDING, // <-- mark the end of the list of registers + + //> alias registers + + ARM64_REG_IP1 = ARM64_REG_X16, + ARM64_REG_IP0 = ARM64_REG_X17, + ARM64_REG_FP = ARM64_REG_X29, + ARM64_REG_LR = ARM64_REG_X30, +} arm64_reg; + +//> ARM64 instruction +typedef enum arm64_insn +{ + ARM64_INS_INVALID = 0, + + ARM64_INS_ABS, + ARM64_INS_ADC, + ARM64_INS_ADDHN, + ARM64_INS_ADDHN2, + ARM64_INS_ADDP, + ARM64_INS_ADD, + ARM64_INS_ADDV, + ARM64_INS_ADR, + ARM64_INS_ADRP, + ARM64_INS_AESD, + ARM64_INS_AESE, + ARM64_INS_AESIMC, + ARM64_INS_AESMC, + ARM64_INS_AND, + ARM64_INS_ASR, + ARM64_INS_B, + ARM64_INS_BFM, + ARM64_INS_BIC, + ARM64_INS_BIF, + ARM64_INS_BIT, + ARM64_INS_BL, + ARM64_INS_BLR, + ARM64_INS_BR, + ARM64_INS_BRK, + ARM64_INS_BSL, + ARM64_INS_CBNZ, + ARM64_INS_CBZ, + ARM64_INS_CCMN, + ARM64_INS_CCMP, + ARM64_INS_CLREX, + ARM64_INS_CLS, + ARM64_INS_CLZ, + ARM64_INS_CMEQ, + ARM64_INS_CMGE, + ARM64_INS_CMGT, + ARM64_INS_CMHI, + ARM64_INS_CMHS, + ARM64_INS_CMLE, + ARM64_INS_CMLT, + ARM64_INS_CMTST, + ARM64_INS_CNT, + ARM64_INS_MOV, + ARM64_INS_CRC32B, + ARM64_INS_CRC32CB, + ARM64_INS_CRC32CH, + ARM64_INS_CRC32CW, + ARM64_INS_CRC32CX, + ARM64_INS_CRC32H, + ARM64_INS_CRC32W, + ARM64_INS_CRC32X, + ARM64_INS_CSEL, + ARM64_INS_CSINC, + ARM64_INS_CSINV, + ARM64_INS_CSNEG, + ARM64_INS_DCPS1, + ARM64_INS_DCPS2, + ARM64_INS_DCPS3, + ARM64_INS_DMB, + ARM64_INS_DRPS, + ARM64_INS_DSB, + ARM64_INS_DUP, + ARM64_INS_EON, + ARM64_INS_EOR, + ARM64_INS_ERET, + ARM64_INS_EXTR, + ARM64_INS_EXT, + ARM64_INS_FABD, + ARM64_INS_FABS, + ARM64_INS_FACGE, + ARM64_INS_FACGT, + ARM64_INS_FADD, + ARM64_INS_FADDP, + ARM64_INS_FCCMP, + ARM64_INS_FCCMPE, + ARM64_INS_FCMEQ, + ARM64_INS_FCMGE, + ARM64_INS_FCMGT, + ARM64_INS_FCMLE, + ARM64_INS_FCMLT, + ARM64_INS_FCMP, + ARM64_INS_FCMPE, + ARM64_INS_FCSEL, + ARM64_INS_FCVTAS, + ARM64_INS_FCVTAU, + ARM64_INS_FCVT, + ARM64_INS_FCVTL, + ARM64_INS_FCVTL2, + ARM64_INS_FCVTMS, + ARM64_INS_FCVTMU, + ARM64_INS_FCVTNS, + ARM64_INS_FCVTNU, + ARM64_INS_FCVTN, + ARM64_INS_FCVTN2, + ARM64_INS_FCVTPS, + ARM64_INS_FCVTPU, + ARM64_INS_FCVTXN, + ARM64_INS_FCVTXN2, + ARM64_INS_FCVTZS, + ARM64_INS_FCVTZU, + ARM64_INS_FDIV, + ARM64_INS_FMADD, + ARM64_INS_FMAX, + ARM64_INS_FMAXNM, + ARM64_INS_FMAXNMP, + ARM64_INS_FMAXNMV, + ARM64_INS_FMAXP, + ARM64_INS_FMAXV, + ARM64_INS_FMIN, + ARM64_INS_FMINNM, + ARM64_INS_FMINNMP, + ARM64_INS_FMINNMV, + ARM64_INS_FMINP, + ARM64_INS_FMINV, + ARM64_INS_FMLA, + ARM64_INS_FMLS, + ARM64_INS_FMOV, + ARM64_INS_FMSUB, + ARM64_INS_FMUL, + ARM64_INS_FMULX, + ARM64_INS_FNEG, + ARM64_INS_FNMADD, + ARM64_INS_FNMSUB, + ARM64_INS_FNMUL, + ARM64_INS_FRECPE, + ARM64_INS_FRECPS, + ARM64_INS_FRECPX, + ARM64_INS_FRINTA, + ARM64_INS_FRINTI, + ARM64_INS_FRINTM, + ARM64_INS_FRINTN, + ARM64_INS_FRINTP, + ARM64_INS_FRINTX, + ARM64_INS_FRINTZ, + ARM64_INS_FRSQRTE, + ARM64_INS_FRSQRTS, + ARM64_INS_FSQRT, + ARM64_INS_FSUB, + ARM64_INS_HINT, + ARM64_INS_HLT, + ARM64_INS_HVC, + ARM64_INS_INS, + + ARM64_INS_ISB, + ARM64_INS_LD1, + ARM64_INS_LD1R, + ARM64_INS_LD2R, + ARM64_INS_LD2, + ARM64_INS_LD3R, + ARM64_INS_LD3, + ARM64_INS_LD4, + ARM64_INS_LD4R, + + ARM64_INS_LDARB, + ARM64_INS_LDARH, + ARM64_INS_LDAR, + ARM64_INS_LDAXP, + ARM64_INS_LDAXRB, + ARM64_INS_LDAXRH, + ARM64_INS_LDAXR, + ARM64_INS_LDNP, + ARM64_INS_LDP, + ARM64_INS_LDPSW, + ARM64_INS_LDRB, + ARM64_INS_LDR, + ARM64_INS_LDRH, + ARM64_INS_LDRSB, + ARM64_INS_LDRSH, + ARM64_INS_LDRSW, + ARM64_INS_LDTRB, + ARM64_INS_LDTRH, + ARM64_INS_LDTRSB, + + ARM64_INS_LDTRSH, + ARM64_INS_LDTRSW, + ARM64_INS_LDTR, + ARM64_INS_LDURB, + ARM64_INS_LDUR, + ARM64_INS_LDURH, + ARM64_INS_LDURSB, + ARM64_INS_LDURSH, + ARM64_INS_LDURSW, + ARM64_INS_LDXP, + ARM64_INS_LDXRB, + ARM64_INS_LDXRH, + ARM64_INS_LDXR, + ARM64_INS_LSL, + ARM64_INS_LSR, + ARM64_INS_MADD, + ARM64_INS_MLA, + ARM64_INS_MLS, + ARM64_INS_MOVI, + ARM64_INS_MOVK, + ARM64_INS_MOVN, + ARM64_INS_MOVZ, + ARM64_INS_MRS, + ARM64_INS_MSR, + ARM64_INS_MSUB, + ARM64_INS_MUL, + ARM64_INS_MVNI, + ARM64_INS_NEG, + ARM64_INS_NOT, + ARM64_INS_ORN, + ARM64_INS_ORR, + ARM64_INS_PMULL2, + ARM64_INS_PMULL, + ARM64_INS_PMUL, + ARM64_INS_PRFM, + ARM64_INS_PRFUM, + ARM64_INS_RADDHN, + ARM64_INS_RADDHN2, + ARM64_INS_RBIT, + ARM64_INS_RET, + ARM64_INS_REV16, + ARM64_INS_REV32, + ARM64_INS_REV64, + ARM64_INS_REV, + ARM64_INS_ROR, + ARM64_INS_RSHRN2, + ARM64_INS_RSHRN, + ARM64_INS_RSUBHN, + ARM64_INS_RSUBHN2, + ARM64_INS_SABAL2, + ARM64_INS_SABAL, + + ARM64_INS_SABA, + ARM64_INS_SABDL2, + ARM64_INS_SABDL, + ARM64_INS_SABD, + ARM64_INS_SADALP, + ARM64_INS_SADDLP, + ARM64_INS_SADDLV, + ARM64_INS_SADDL2, + ARM64_INS_SADDL, + ARM64_INS_SADDW2, + ARM64_INS_SADDW, + ARM64_INS_SBC, + ARM64_INS_SBFM, + ARM64_INS_SCVTF, + ARM64_INS_SDIV, + ARM64_INS_SHA1C, + ARM64_INS_SHA1H, + ARM64_INS_SHA1M, + ARM64_INS_SHA1P, + ARM64_INS_SHA1SU0, + ARM64_INS_SHA1SU1, + ARM64_INS_SHA256H2, + ARM64_INS_SHA256H, + ARM64_INS_SHA256SU0, + ARM64_INS_SHA256SU1, + ARM64_INS_SHADD, + ARM64_INS_SHLL2, + ARM64_INS_SHLL, + ARM64_INS_SHL, + ARM64_INS_SHRN2, + ARM64_INS_SHRN, + ARM64_INS_SHSUB, + ARM64_INS_SLI, + ARM64_INS_SMADDL, + ARM64_INS_SMAXP, + ARM64_INS_SMAXV, + ARM64_INS_SMAX, + ARM64_INS_SMC, + ARM64_INS_SMINP, + ARM64_INS_SMINV, + ARM64_INS_SMIN, + ARM64_INS_SMLAL2, + ARM64_INS_SMLAL, + ARM64_INS_SMLSL2, + ARM64_INS_SMLSL, + ARM64_INS_SMOV, + ARM64_INS_SMSUBL, + ARM64_INS_SMULH, + ARM64_INS_SMULL2, + ARM64_INS_SMULL, + ARM64_INS_SQABS, + ARM64_INS_SQADD, + ARM64_INS_SQDMLAL, + ARM64_INS_SQDMLAL2, + ARM64_INS_SQDMLSL, + ARM64_INS_SQDMLSL2, + ARM64_INS_SQDMULH, + ARM64_INS_SQDMULL, + ARM64_INS_SQDMULL2, + ARM64_INS_SQNEG, + ARM64_INS_SQRDMULH, + ARM64_INS_SQRSHL, + ARM64_INS_SQRSHRN, + ARM64_INS_SQRSHRN2, + ARM64_INS_SQRSHRUN, + ARM64_INS_SQRSHRUN2, + ARM64_INS_SQSHLU, + ARM64_INS_SQSHL, + ARM64_INS_SQSHRN, + ARM64_INS_SQSHRN2, + ARM64_INS_SQSHRUN, + ARM64_INS_SQSHRUN2, + ARM64_INS_SQSUB, + ARM64_INS_SQXTN2, + ARM64_INS_SQXTN, + ARM64_INS_SQXTUN2, + ARM64_INS_SQXTUN, + ARM64_INS_SRHADD, + ARM64_INS_SRI, + ARM64_INS_SRSHL, + ARM64_INS_SRSHR, + ARM64_INS_SRSRA, + ARM64_INS_SSHLL2, + ARM64_INS_SSHLL, + ARM64_INS_SSHL, + ARM64_INS_SSHR, + ARM64_INS_SSRA, + ARM64_INS_SSUBL2, + ARM64_INS_SSUBL, + ARM64_INS_SSUBW2, + ARM64_INS_SSUBW, + ARM64_INS_ST1, + ARM64_INS_ST2, + ARM64_INS_ST3, + ARM64_INS_ST4, + ARM64_INS_STLRB, + ARM64_INS_STLRH, + ARM64_INS_STLR, + ARM64_INS_STLXP, + ARM64_INS_STLXRB, + ARM64_INS_STLXRH, + ARM64_INS_STLXR, + ARM64_INS_STNP, + ARM64_INS_STP, + ARM64_INS_STRB, + ARM64_INS_STR, + ARM64_INS_STRH, + ARM64_INS_STTRB, + ARM64_INS_STTRH, + ARM64_INS_STTR, + ARM64_INS_STURB, + ARM64_INS_STUR, + ARM64_INS_STURH, + ARM64_INS_STXP, + ARM64_INS_STXRB, + ARM64_INS_STXRH, + ARM64_INS_STXR, + ARM64_INS_SUBHN, + ARM64_INS_SUBHN2, + ARM64_INS_SUB, + ARM64_INS_SUQADD, + ARM64_INS_SVC, + ARM64_INS_SYSL, + ARM64_INS_SYS, + ARM64_INS_TBL, + ARM64_INS_TBNZ, + ARM64_INS_TBX, + ARM64_INS_TBZ, + ARM64_INS_TRN1, + ARM64_INS_TRN2, + ARM64_INS_UABAL2, + ARM64_INS_UABAL, + ARM64_INS_UABA, + ARM64_INS_UABDL2, + ARM64_INS_UABDL, + ARM64_INS_UABD, + ARM64_INS_UADALP, + ARM64_INS_UADDLP, + ARM64_INS_UADDLV, + ARM64_INS_UADDL2, + ARM64_INS_UADDL, + ARM64_INS_UADDW2, + ARM64_INS_UADDW, + ARM64_INS_UBFM, + ARM64_INS_UCVTF, + ARM64_INS_UDIV, + ARM64_INS_UHADD, + ARM64_INS_UHSUB, + ARM64_INS_UMADDL, + ARM64_INS_UMAXP, + ARM64_INS_UMAXV, + ARM64_INS_UMAX, + ARM64_INS_UMINP, + ARM64_INS_UMINV, + ARM64_INS_UMIN, + ARM64_INS_UMLAL2, + ARM64_INS_UMLAL, + ARM64_INS_UMLSL2, + ARM64_INS_UMLSL, + ARM64_INS_UMOV, + ARM64_INS_UMSUBL, + ARM64_INS_UMULH, + ARM64_INS_UMULL2, + ARM64_INS_UMULL, + ARM64_INS_UQADD, + ARM64_INS_UQRSHL, + ARM64_INS_UQRSHRN, + ARM64_INS_UQRSHRN2, + ARM64_INS_UQSHL, + ARM64_INS_UQSHRN, + ARM64_INS_UQSHRN2, + ARM64_INS_UQSUB, + ARM64_INS_UQXTN2, + ARM64_INS_UQXTN, + ARM64_INS_URECPE, + ARM64_INS_URHADD, + ARM64_INS_URSHL, + ARM64_INS_URSHR, + ARM64_INS_URSQRTE, + ARM64_INS_URSRA, + ARM64_INS_USHLL2, + ARM64_INS_USHLL, + ARM64_INS_USHL, + ARM64_INS_USHR, + ARM64_INS_USQADD, + ARM64_INS_USRA, + ARM64_INS_USUBL2, + ARM64_INS_USUBL, + ARM64_INS_USUBW2, + ARM64_INS_USUBW, + ARM64_INS_UZP1, + ARM64_INS_UZP2, + ARM64_INS_XTN2, + ARM64_INS_XTN, + ARM64_INS_ZIP1, + ARM64_INS_ZIP2, + + // alias insn + ARM64_INS_MNEG, + ARM64_INS_UMNEGL, + ARM64_INS_SMNEGL, + ARM64_INS_NOP, + ARM64_INS_YIELD, + ARM64_INS_WFE, + ARM64_INS_WFI, + ARM64_INS_SEV, + ARM64_INS_SEVL, + ARM64_INS_NGC, + ARM64_INS_SBFIZ, + ARM64_INS_UBFIZ, + ARM64_INS_SBFX, + ARM64_INS_UBFX, + ARM64_INS_BFI, + ARM64_INS_BFXIL, + ARM64_INS_CMN, + ARM64_INS_MVN, + ARM64_INS_TST, + ARM64_INS_CSET, + ARM64_INS_CINC, + ARM64_INS_CSETM, + ARM64_INS_CINV, + ARM64_INS_CNEG, + ARM64_INS_SXTB, + ARM64_INS_SXTH, + ARM64_INS_SXTW, + ARM64_INS_CMP, + ARM64_INS_UXTB, + ARM64_INS_UXTH, + ARM64_INS_UXTW, + ARM64_INS_IC, + ARM64_INS_DC, + ARM64_INS_AT, + ARM64_INS_TLBI, + + ARM64_INS_ENDING, // <-- mark the end of the list of insn +} arm64_insn; + +//> Group of ARM64 instructions +typedef enum arm64_insn_group +{ + ARM64_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + ARM64_GRP_JUMP, // = CS_GRP_JUMP + + //> Architecture-specific groups + ARM64_GRP_CRYPTO = 128, + ARM64_GRP_FPARMV8, + ARM64_GRP_NEON, + ARM64_GRP_CRC, + + ARM64_GRP_ENDING, // <-- mark the end of the list of groups +} arm64_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dbg/capstone/capstone.h b/src/dbg/capstone/capstone.h index 3e17db3b..bdf37640 100644 --- a/src/dbg/capstone/capstone.h +++ b/src/dbg/capstone/capstone.h @@ -1,675 +1,675 @@ -#ifndef CAPSTONE_ENGINE_H -#define CAPSTONE_ENGINE_H - -/* Capstone Disassembly Engine */ -/* By Nguyen Anh Quynh , 2013-2014 */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#if defined(CAPSTONE_HAS_OSXKERNEL) -#include -#else -#include -#include -#endif - -#include "platform.h" - -#ifdef _MSC_VER -#pragma warning(disable:4201) -#pragma warning(disable:4100) -#ifdef CAPSTONE_SHARED -#define CAPSTONE_EXPORT __declspec(dllexport) -#else // defined(CAPSTONE_STATIC) -#define CAPSTONE_EXPORT -#endif -#else -#ifdef __GNUC__ -#define CAPSTONE_EXPORT __attribute__((visibility("default"))) -#else -#define CAPSTONE_EXPORT -#endif -#endif - -#ifdef __GNUC__ -#define CAPSTONE_DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) -#define CAPSTONE_DEPRECATED __declspec(deprecated) -#else -#pragma message("WARNING: You need to implement CAPSTONE_DEPRECATED for this compiler") -#define CAPSTONE_DEPRECATED -#endif - -// Capstone API version -#define CS_API_MAJOR 3 -#define CS_API_MINOR 0 - -// Macro to create combined version which can be compared to -// result of cs_version() API. -#define CS_MAKE_VERSION(major, minor) ((major << 8) + minor) - -// Handle using with all API -typedef size_t csh; - -// Architecture type -typedef enum cs_arch -{ - CS_ARCH_ARM = 0, // ARM architecture (including Thumb, Thumb-2) - CS_ARCH_ARM64, // ARM-64, also called AArch64 - CS_ARCH_MIPS, // Mips architecture - CS_ARCH_X86, // X86 architecture (including x86 & x86-64) - CS_ARCH_PPC, // PowerPC architecture - CS_ARCH_SPARC, // Sparc architecture - CS_ARCH_SYSZ, // SystemZ architecture - CS_ARCH_XCORE, // XCore architecture - CS_ARCH_MAX, - CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support() -} cs_arch; - -// Support value to verify diet mode of the engine. -// If cs_support(CS_SUPPORT_DIET) return True, the engine was compiled -// in diet mode. -#define CS_SUPPORT_DIET (CS_ARCH_ALL + 1) - -// Support value to verify X86 reduce mode of the engine. -// If cs_support(CS_SUPPORT_X86_REDUCE) return True, the engine was compiled -// in X86 reduce mode. -#define CS_SUPPORT_X86_REDUCE (CS_ARCH_ALL + 2) - -// Mode type -typedef enum cs_mode -{ - CS_MODE_LITTLE_ENDIAN = 0, // little-endian mode (default mode) - CS_MODE_ARM = 0, // 32-bit ARM - CS_MODE_16 = 1 << 1, // 16-bit mode (X86) - CS_MODE_32 = 1 << 2, // 32-bit mode (X86) - CS_MODE_64 = 1 << 3, // 64-bit mode (X86, PPC) - CS_MODE_THUMB = 1 << 4, // ARM's Thumb mode, including Thumb-2 - CS_MODE_MCLASS = 1 << 5, // ARM's Cortex-M series - CS_MODE_V8 = 1 << 6, // ARMv8 A32 encodings for ARM - CS_MODE_MICRO = 1 << 4, // MicroMips mode (MIPS) - CS_MODE_MIPS3 = 1 << 5, // Mips III ISA - CS_MODE_MIPS32R6 = 1 << 6, // Mips32r6 ISA - CS_MODE_MIPSGP64 = 1 << 7, // General Purpose Registers are 64-bit wide (MIPS) - CS_MODE_V9 = 1 << 4, // SparcV9 mode (Sparc) - CS_MODE_BIG_ENDIAN = 1 << 31, // big-endian mode - CS_MODE_MIPS32 = CS_MODE_32, // Mips32 ISA (Mips) - CS_MODE_MIPS64 = CS_MODE_64, // Mips64 ISA (Mips) -} cs_mode; - -typedef void* (*cs_malloc_t)(size_t size); -typedef void* (*cs_calloc_t)(size_t nmemb, size_t size); -typedef void* (*cs_realloc_t)(void* ptr, size_t size); -typedef void (*cs_free_t)(void* ptr); -typedef int (*cs_vsnprintf_t)(char* str, size_t size, const char* format, va_list ap); - - -// User-defined dynamic memory related functions: malloc/calloc/realloc/free/vsnprintf() -// By default, Capstone uses system's malloc(), calloc(), realloc(), free() & vsnprintf(). -typedef struct cs_opt_mem -{ - cs_malloc_t malloc; - cs_calloc_t calloc; - cs_realloc_t realloc; - cs_free_t free; - cs_vsnprintf_t vsnprintf; -} cs_opt_mem; - -// Runtime option for the disassembled engine -typedef enum cs_opt_type -{ - CS_OPT_SYNTAX = 1, // Assembly output syntax - CS_OPT_DETAIL, // Break down instruction structure into details - CS_OPT_MODE, // Change engine's mode at run-time - CS_OPT_MEM, // User-defined dynamic memory related functions - CS_OPT_SKIPDATA, // Skip data when disassembling. Then engine is in SKIPDATA mode. - CS_OPT_SKIPDATA_SETUP, // Setup user-defined function for SKIPDATA option -} cs_opt_type; - -// Runtime option value (associated with option type above) -typedef enum cs_opt_value -{ - CS_OPT_OFF = 0, // Turn OFF an option - default option of CS_OPT_DETAIL, CS_OPT_SKIPDATA. - CS_OPT_ON = 3, // Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA). - CS_OPT_SYNTAX_DEFAULT = 0, // Default asm syntax (CS_OPT_SYNTAX). - CS_OPT_SYNTAX_INTEL, // X86 Intel asm syntax - default on X86 (CS_OPT_SYNTAX). - CS_OPT_SYNTAX_ATT, // X86 ATT asm syntax (CS_OPT_SYNTAX). - CS_OPT_SYNTAX_NOREGNAME, // Prints register name with only number (CS_OPT_SYNTAX) -} cs_opt_value; - -//> Common instruction operand types - to be consistent across all architectures. -typedef enum cs_op_type -{ - CS_OP_INVALID = 0, // uninitialized/invalid operand. - CS_OP_REG, // Register operand. - CS_OP_IMM, // Immediate operand. - CS_OP_MEM, // Memory operand. - CS_OP_FP, // Floating-Point operand. -} cs_op_type; - -//> Common instruction groups - to be consistent across all architectures. -typedef enum cs_group_type -{ - CS_GRP_INVALID = 0, // uninitialized/invalid group. - CS_GRP_JUMP, // all jump instructions (conditional+direct+indirect jumps) - CS_GRP_CALL, // all call instructions - CS_GRP_RET, // all return instructions - CS_GRP_INT, // all interrupt instructions (int+syscall) - CS_GRP_IRET, // all interrupt return instructions -} cs_group_type; - -/* - User-defined callback function for SKIPDATA option. - See tests/test_skipdata.c for sample code demonstrating this API. - - @code: the input buffer containing code to be disassembled. - This is the same buffer passed to cs_disasm(). - @code_size: size (in bytes) of the above @code buffer. - @offset: the position of the currently-examining byte in the input - buffer @code mentioned above. - @user_data: user-data passed to cs_option() via @user_data field in - cs_opt_skipdata struct below. - - @return: return number of bytes to skip, or 0 to immediately stop disassembling. -*/ -typedef size_t (*cs_skipdata_cb_t)(const uint8_t* code, size_t code_size, size_t offset, void* user_data); - -// User-customized setup for SKIPDATA option -typedef struct cs_opt_skipdata -{ - // Capstone considers data to skip as special "instructions". - // User can specify the string for this instruction's "mnemonic" here. - // By default (if @mnemonic is NULL), Capstone use ".byte". - const char* mnemonic; - - // User-defined callback function to be called when Capstone hits data. - // If the returned value from this callback is positive (>0), Capstone - // will skip exactly that number of bytes & continue. Otherwise, if - // the callback returns 0, Capstone stops disassembling and returns - // immediately from cs_disasm() - // NOTE: if this callback pointer is NULL, Capstone would skip a number - // of bytes depending on architectures, as following: - // Arm: 2 bytes (Thumb mode) or 4 bytes. - // Arm64: 4 bytes. - // Mips: 4 bytes. - // PowerPC: 4 bytes. - // Sparc: 4 bytes. - // SystemZ: 2 bytes. - // X86: 1 bytes. - // XCore: 2 bytes. - cs_skipdata_cb_t callback; // default value is NULL - - // User-defined data to be passed to @callback function pointer. - void* user_data; -} cs_opt_skipdata; - - -#include "arm.h" -#include "arm64.h" -#include "mips.h" -#include "ppc.h" -#include "sparc.h" -#include "systemz.h" -#include "x86.h" -#include "xcore.h" - -// NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON -typedef struct cs_detail -{ - uint8_t regs_read[12]; // list of implicit registers read by this insn - uint8_t regs_read_count; // number of implicit registers read by this insn - - uint8_t regs_write[20]; // list of implicit registers modified by this insn - uint8_t regs_write_count; // number of implicit registers modified by this insn - - uint8_t groups[8]; // list of group this instruction belong to - uint8_t groups_count; // number of groups this insn belongs to - - // Architecture-specific instruction info - union - { - cs_x86 x86; // X86 architecture, including 16-bit, 32-bit & 64-bit mode - cs_arm64 arm64; // ARM64 architecture (aka AArch64) - cs_arm arm; // ARM architecture (including Thumb/Thumb2) - cs_mips mips; // MIPS architecture - cs_ppc ppc; // PowerPC architecture - cs_sparc sparc; // Sparc architecture - cs_sysz sysz; // SystemZ architecture - cs_xcore xcore; // XCore architecture - }; -} cs_detail; - -// Detail information of disassembled instruction -typedef struct cs_insn -{ - // Instruction ID (basically a numeric ID for the instruction mnemonic) - // Find the instruction id in the '[ARCH]_insn' enum in the header file - // of corresponding architecture, such as 'arm_insn' in arm.h for ARM, - // 'x86_insn' in x86.h for X86, etc... - // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF - // NOTE: in Skipdata mode, "data" instruction has 0 for this id field. - unsigned int id; - - // Address (EIP) of this instruction - // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF - uint64_t address; - - // Size of this instruction - // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF - uint16_t size; - // Machine bytes of this instruction, with number of bytes indicated by @size above - // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF - uint8_t bytes[16]; - - // Ascii text of instruction mnemonic - // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF - char mnemonic[32]; - - // Ascii text of instruction operands - // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF - char op_str[160]; - - // Pointer to cs_detail. - // NOTE: detail pointer is only valid when both requirements below are met: - // (1) CS_OP_DETAIL = CS_OPT_ON - // (2) Engine is not in Skipdata mode (CS_OP_SKIPDATA option set to CS_OPT_ON) - // - // NOTE 2: when in Skipdata mode, or when detail mode is OFF, even if this pointer - // is not NULL, its content is still irrelevant. - cs_detail* detail; -} cs_insn; - - -// Calculate the offset of a disassembled instruction in its buffer, given its position -// in its array of disassembled insn -// NOTE: this macro works with position (>=1), not index -#define CS_INSN_OFFSET(insns, post) (insns[post - 1].address - insns[0].address) - - -// All type of errors encountered by Capstone API. -// These are values returned by cs_errno() -typedef enum cs_err -{ - CS_ERR_OK = 0, // No error: everything was fine - CS_ERR_MEM, // Out-Of-Memory error: cs_open(), cs_disasm(), cs_disasm_iter() - CS_ERR_ARCH, // Unsupported architecture: cs_open() - CS_ERR_HANDLE, // Invalid handle: cs_op_count(), cs_op_index() - CS_ERR_CSH, // Invalid csh argument: cs_close(), cs_errno(), cs_option() - CS_ERR_MODE, // Invalid/unsupported mode: cs_open() - CS_ERR_OPTION, // Invalid/unsupported option: cs_option() - CS_ERR_DETAIL, // Information is unavailable because detail option is OFF - CS_ERR_MEMSETUP, // Dynamic memory management uninitialized (see CS_OPT_MEM) - CS_ERR_VERSION, // Unsupported version (bindings) - CS_ERR_DIET, // Access irrelevant data in "diet" engine - CS_ERR_SKIPDATA, // Access irrelevant data for "data" instruction in SKIPDATA mode - CS_ERR_X86_ATT, // X86 AT&T syntax is unsupported (opt-out at compile time) - CS_ERR_X86_INTEL, // X86 Intel syntax is unsupported (opt-out at compile time) -} cs_err; - -/* - Return combined API version & major and minor version numbers. - - @major: major number of API version - @minor: minor number of API version - - @return hexical number as (major << 8 | minor), which encodes both - major & minor versions. - NOTE: This returned value can be compared with version number made - with macro CS_MAKE_VERSION - - For example, second API version would return 1 in @major, and 1 in @minor - The return value would be 0x0101 - - NOTE: if you only care about returned value, but not major and minor values, - set both @major & @minor arguments to NULL. -*/ -CAPSTONE_EXPORT -unsigned int cs_version(int* major, int* minor); - - -/* - This API can be used to either ask for archs supported by this library, - or check to see if the library was compile with 'diet' option (or called - in 'diet' mode). - - To check if a particular arch is supported by this library, set @query to - arch mode (CS_ARCH_* value). - To verify if this library supports all the archs, use CS_ARCH_ALL. - - To check if this library is in 'diet' mode, set @query to CS_SUPPORT_DIET. - - @return True if this library supports the given arch, or in 'diet' mode. -*/ -CAPSTONE_EXPORT -bool cs_support(int query); - -/* - Initialize CS handle: this must be done before any usage of CS. - - @arch: architecture type (CS_ARCH_*) - @mode: hardware mode. This is combined of CS_MODE_* - @handle: pointer to handle, which will be updated at return time - - @return CS_ERR_OK on success, or other value on failure (refer to cs_err enum - for detailed error). -*/ -CAPSTONE_EXPORT -cs_err cs_open(cs_arch arch, cs_mode mode, csh* handle); - -/* - Close CS handle: MUST do to release the handle when it is not used anymore. - NOTE: this must be only called when there is no longer usage of Capstone, - not even access to cs_insn array. The reason is the this API releases some - cached memory, thus access to any Capstone API after cs_close() might crash - your application. - - In fact,this API invalidate @handle by ZERO out its value (i.e *handle = 0). - - @handle: pointer to a handle returned by cs_open() - - @return CS_ERR_OK on success, or other value on failure (refer to cs_err enum - for detailed error). -*/ -CAPSTONE_EXPORT -cs_err cs_close(csh* handle); - -/* - Set option for disassembling engine at runtime - - @handle: handle returned by cs_open() - @type: type of option to be set - @value: option value corresponding with @type - - @return: CS_ERR_OK on success, or other value on failure. - Refer to cs_err enum for detailed error. - - NOTE: in the case of CS_OPT_MEM, handle's value can be anything, - so that cs_option(handle, CS_OPT_MEM, value) can (i.e must) be called - even before cs_open() -*/ -CAPSTONE_EXPORT -cs_err cs_option(csh handle, cs_opt_type type, size_t value); - -/* - Report the last error number when some API function fail. - Like glibc's errno, cs_errno might not retain its old value once accessed. - - @handle: handle returned by cs_open() - - @return: error code of cs_err enum type (CS_ERR_*, see above) -*/ -CAPSTONE_EXPORT -cs_err cs_errno(csh handle); - - -/* - Return a string describing given error code. - - @code: error code (see CS_ERR_* above) - - @return: returns a pointer to a string that describes the error code - passed in the argument @code -*/ -CAPSTONE_EXPORT -const char* cs_strerror(cs_err code); - -/* - Disassemble binary code, given the code buffer, size, address and number - of instructions to be decoded. - This API dynamically allocate memory to contain disassembled instruction. - Resulted instructions will be put into @*insn - - NOTE 1: this API will automatically determine memory needed to contain - output disassembled instructions in @insn. - - NOTE 2: caller must free the allocated memory itself to avoid memory leaking. - - NOTE 3: for system with scarce memory to be dynamically allocated such as - OS kernel or firmware, the API cs_disasm_iter() might be a better choice than - cs_disasm(). The reason is that with cs_disasm(), based on limited available - memory, we have to calculate in advance how many instructions to be disassembled, - which complicates things. This is especially troublesome for the case @count=0, - when cs_disasm() runs uncontrollably (until either end of input buffer, or - when it encounters an invalid instruction). - - @handle: handle returned by cs_open() - @code: buffer containing raw binary code to be disassembled. - @code_size: size of the above code buffer. - @address: address of the first instruction in given raw code buffer. - @insn: array of instructions filled in by this API. - NOTE: @insn will be allocated by this function, and should be freed - with cs_free() API. - @count: number of instructions to be disassembled, or 0 to get all of them - - @return: the number of successfully disassembled instructions, - or 0 if this function failed to disassemble the given code - - On failure, call cs_errno() for error code. -*/ -CAPSTONE_EXPORT -size_t cs_disasm(csh handle, - const uint8_t* code, size_t code_size, - uint64_t address, - size_t count, - cs_insn** insn); - -/* - Deprecated function - to be retired in the next version! - Use cs_disasm() instead of cs_disasm_ex() -*/ -CAPSTONE_EXPORT -CAPSTONE_DEPRECATED -size_t cs_disasm_ex(csh handle, - const uint8_t* code, size_t code_size, - uint64_t address, - size_t count, - cs_insn** insn); - -/* - Free memory allocated by cs_malloc() or cs_disasm() (argument @insn) - - @insn: pointer returned by @insn argument in cs_disasm() or cs_malloc() - @count: number of cs_insn structures returned by cs_disasm(), or 1 - to free memory allocated by cs_malloc(). -*/ -CAPSTONE_EXPORT -void cs_free(cs_insn* insn, size_t count); - - -/* - Allocate memory for 1 instruction to be used by cs_disasm_iter(). - - @handle: handle returned by cs_open() - - NOTE: when no longer in use, you can reclaim the memory allocated for - this instruction with cs_free(insn, 1) -*/ -CAPSTONE_EXPORT -cs_insn* cs_malloc(csh handle); - -/* - Fast API to disassemble binary code, given the code buffer, size, address - and number of instructions to be decoded. - This API put the resulted instruction into a given cache in @insn. - See tests/test_iter.c for sample code demonstrating this API. - - NOTE 1: this API will update @code, @size & @address to point to the next - instruction in the input buffer. Therefore, it is convenient to use - cs_disasm_iter() inside a loop to quickly iterate all the instructions. - While decoding one instruction at a time can also be achieved with - cs_disasm(count=1), some benchmarks shown that cs_disasm_iter() can be 30% - faster on random input. - - NOTE 2: the cache in @insn can be created with cs_malloc() API. - - NOTE 3: for system with scarce memory to be dynamically allocated such as - OS kernel or firmware, this API is recommended over cs_disasm(), which - allocates memory based on the number of instructions to be disassembled. - The reason is that with cs_disasm(), based on limited available memory, - we have to calculate in advance how many instructions to be disassembled, - which complicates things. This is especially troublesome for the case - @count=0, when cs_disasm() runs uncontrollably (until either end of input - buffer, or when it encounters an invalid instruction). - - @handle: handle returned by cs_open() - @code: buffer containing raw binary code to be disassembled - @code_size: size of above code - @address: address of the first insn in given raw code buffer - @insn: pointer to instruction to be filled in by this API. - - @return: true if this API successfully decode 1 instruction, - or false otherwise. - - On failure, call cs_errno() for error code. -*/ -CAPSTONE_EXPORT -bool cs_disasm_iter(csh handle, - const uint8_t** code, size_t* size, - uint64_t* address, cs_insn* insn); - -/* - Return friendly name of register in a string. - Find the instruction id from header file of corresponding architecture (arm.h for ARM, - x86.h for X86, ...) - - WARN: when in 'diet' mode, this API is irrelevant because engine does not - store register name. - - @handle: handle returned by cs_open() - @reg_id: register id - - @return: string name of the register, or NULL if @reg_id is invalid. -*/ -CAPSTONE_EXPORT -const char* cs_reg_name(csh handle, unsigned int reg_id); - -/* - Return friendly name of an instruction in a string. - Find the instruction id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) - - WARN: when in 'diet' mode, this API is irrelevant because the engine does not - store instruction name. - - @handle: handle returned by cs_open() - @insn_id: instruction id - - @return: string name of the instruction, or NULL if @insn_id is invalid. -*/ -CAPSTONE_EXPORT -const char* cs_insn_name(csh handle, unsigned int insn_id); - -/* - Return friendly name of a group id (that an instruction can belong to) - Find the group id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) - - WARN: when in 'diet' mode, this API is irrelevant because the engine does not - store group name. - - @handle: handle returned by cs_open() - @group_id: group id - - @return: string name of the group, or NULL if @group_id is invalid. -*/ -CAPSTONE_EXPORT -const char* cs_group_name(csh handle, unsigned int group_id); - -/* - Check if a disassembled instruction belong to a particular group. - Find the group id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) - Internally, this simply verifies if @group_id matches any member of insn->groups array. - - NOTE: this API is only valid when detail option is ON (which is OFF by default). - - WARN: when in 'diet' mode, this API is irrelevant because the engine does not - update @groups array. - - @handle: handle returned by cs_open() - @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() - @group_id: group that you want to check if this instruction belong to. - - @return: true if this instruction indeed belongs to aboved group, or false otherwise. -*/ -CAPSTONE_EXPORT -bool cs_insn_group(csh handle, const cs_insn* insn, unsigned int group_id); - -/* - Check if a disassembled instruction IMPLICITLY used a particular register. - Find the register id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) - Internally, this simply verifies if @reg_id matches any member of insn->regs_read array. - - NOTE: this API is only valid when detail option is ON (which is OFF by default) - - WARN: when in 'diet' mode, this API is irrelevant because the engine does not - update @regs_read array. - - @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() - @reg_id: register that you want to check if this instruction used it. - - @return: true if this instruction indeed implicitly used aboved register, or false otherwise. -*/ -CAPSTONE_EXPORT -bool cs_reg_read(csh handle, const cs_insn* insn, unsigned int reg_id); - -/* - Check if a disassembled instruction IMPLICITLY modified a particular register. - Find the register id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) - Internally, this simply verifies if @reg_id matches any member of insn->regs_write array. - - NOTE: this API is only valid when detail option is ON (which is OFF by default) - - WARN: when in 'diet' mode, this API is irrelevant because the engine does not - update @regs_write array. - - @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() - @reg_id: register that you want to check if this instruction modified it. - - @return: true if this instruction indeed implicitly modified aboved register, or false otherwise. -*/ -CAPSTONE_EXPORT -bool cs_reg_write(csh handle, const cs_insn* insn, unsigned int reg_id); - -/* - Count the number of operands of a given type. - Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) - - NOTE: this API is only valid when detail option is ON (which is OFF by default) - - @handle: handle returned by cs_open() - @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() - @op_type: Operand type to be found. - - @return: number of operands of given type @op_type in instruction @insn, - or -1 on failure. -*/ -CAPSTONE_EXPORT -int cs_op_count(csh handle, const cs_insn* insn, unsigned int op_type); - -/* - Retrieve the position of operand of given type in .operands[] array. - Later, the operand can be accessed using the returned position. - Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) - - NOTE: this API is only valid when detail option is ON (which is OFF by default) - - @handle: handle returned by cs_open() - @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() - @op_type: Operand type to be found. - @position: position of the operand to be found. This must be in the range - [1, cs_op_count(handle, insn, op_type)] - - @return: index of operand of given type @op_type in .operands[] array - in instruction @insn, or -1 on failure. -*/ -CAPSTONE_EXPORT -int cs_op_index(csh handle, const cs_insn* insn, unsigned int op_type, - unsigned int position); - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef CAPSTONE_ENGINE_H +#define CAPSTONE_ENGINE_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#if defined(CAPSTONE_HAS_OSXKERNEL) +#include +#else +#include +#include +#endif + +#include "platform.h" + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#pragma warning(disable:4100) +#ifdef CAPSTONE_SHARED +#define CAPSTONE_EXPORT __declspec(dllexport) +#else // defined(CAPSTONE_STATIC) +#define CAPSTONE_EXPORT +#endif +#else +#ifdef __GNUC__ +#define CAPSTONE_EXPORT __attribute__((visibility("default"))) +#else +#define CAPSTONE_EXPORT +#endif +#endif + +#ifdef __GNUC__ +#define CAPSTONE_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define CAPSTONE_DEPRECATED __declspec(deprecated) +#else +#pragma message("WARNING: You need to implement CAPSTONE_DEPRECATED for this compiler") +#define CAPSTONE_DEPRECATED +#endif + +// Capstone API version +#define CS_API_MAJOR 3 +#define CS_API_MINOR 0 + +// Macro to create combined version which can be compared to +// result of cs_version() API. +#define CS_MAKE_VERSION(major, minor) ((major << 8) + minor) + +// Handle using with all API +typedef size_t csh; + +// Architecture type +typedef enum cs_arch +{ + CS_ARCH_ARM = 0, // ARM architecture (including Thumb, Thumb-2) + CS_ARCH_ARM64, // ARM-64, also called AArch64 + CS_ARCH_MIPS, // Mips architecture + CS_ARCH_X86, // X86 architecture (including x86 & x86-64) + CS_ARCH_PPC, // PowerPC architecture + CS_ARCH_SPARC, // Sparc architecture + CS_ARCH_SYSZ, // SystemZ architecture + CS_ARCH_XCORE, // XCore architecture + CS_ARCH_MAX, + CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support() +} cs_arch; + +// Support value to verify diet mode of the engine. +// If cs_support(CS_SUPPORT_DIET) return True, the engine was compiled +// in diet mode. +#define CS_SUPPORT_DIET (CS_ARCH_ALL + 1) + +// Support value to verify X86 reduce mode of the engine. +// If cs_support(CS_SUPPORT_X86_REDUCE) return True, the engine was compiled +// in X86 reduce mode. +#define CS_SUPPORT_X86_REDUCE (CS_ARCH_ALL + 2) + +// Mode type +typedef enum cs_mode +{ + CS_MODE_LITTLE_ENDIAN = 0, // little-endian mode (default mode) + CS_MODE_ARM = 0, // 32-bit ARM + CS_MODE_16 = 1 << 1, // 16-bit mode (X86) + CS_MODE_32 = 1 << 2, // 32-bit mode (X86) + CS_MODE_64 = 1 << 3, // 64-bit mode (X86, PPC) + CS_MODE_THUMB = 1 << 4, // ARM's Thumb mode, including Thumb-2 + CS_MODE_MCLASS = 1 << 5, // ARM's Cortex-M series + CS_MODE_V8 = 1 << 6, // ARMv8 A32 encodings for ARM + CS_MODE_MICRO = 1 << 4, // MicroMips mode (MIPS) + CS_MODE_MIPS3 = 1 << 5, // Mips III ISA + CS_MODE_MIPS32R6 = 1 << 6, // Mips32r6 ISA + CS_MODE_MIPSGP64 = 1 << 7, // General Purpose Registers are 64-bit wide (MIPS) + CS_MODE_V9 = 1 << 4, // SparcV9 mode (Sparc) + CS_MODE_BIG_ENDIAN = 1 << 31, // big-endian mode + CS_MODE_MIPS32 = CS_MODE_32, // Mips32 ISA (Mips) + CS_MODE_MIPS64 = CS_MODE_64, // Mips64 ISA (Mips) +} cs_mode; + +typedef void* (*cs_malloc_t)(size_t size); +typedef void* (*cs_calloc_t)(size_t nmemb, size_t size); +typedef void* (*cs_realloc_t)(void* ptr, size_t size); +typedef void (*cs_free_t)(void* ptr); +typedef int (*cs_vsnprintf_t)(char* str, size_t size, const char* format, va_list ap); + + +// User-defined dynamic memory related functions: malloc/calloc/realloc/free/vsnprintf() +// By default, Capstone uses system's malloc(), calloc(), realloc(), free() & vsnprintf(). +typedef struct cs_opt_mem +{ + cs_malloc_t malloc; + cs_calloc_t calloc; + cs_realloc_t realloc; + cs_free_t free; + cs_vsnprintf_t vsnprintf; +} cs_opt_mem; + +// Runtime option for the disassembled engine +typedef enum cs_opt_type +{ + CS_OPT_SYNTAX = 1, // Assembly output syntax + CS_OPT_DETAIL, // Break down instruction structure into details + CS_OPT_MODE, // Change engine's mode at run-time + CS_OPT_MEM, // User-defined dynamic memory related functions + CS_OPT_SKIPDATA, // Skip data when disassembling. Then engine is in SKIPDATA mode. + CS_OPT_SKIPDATA_SETUP, // Setup user-defined function for SKIPDATA option +} cs_opt_type; + +// Runtime option value (associated with option type above) +typedef enum cs_opt_value +{ + CS_OPT_OFF = 0, // Turn OFF an option - default option of CS_OPT_DETAIL, CS_OPT_SKIPDATA. + CS_OPT_ON = 3, // Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA). + CS_OPT_SYNTAX_DEFAULT = 0, // Default asm syntax (CS_OPT_SYNTAX). + CS_OPT_SYNTAX_INTEL, // X86 Intel asm syntax - default on X86 (CS_OPT_SYNTAX). + CS_OPT_SYNTAX_ATT, // X86 ATT asm syntax (CS_OPT_SYNTAX). + CS_OPT_SYNTAX_NOREGNAME, // Prints register name with only number (CS_OPT_SYNTAX) +} cs_opt_value; + +//> Common instruction operand types - to be consistent across all architectures. +typedef enum cs_op_type +{ + CS_OP_INVALID = 0, // uninitialized/invalid operand. + CS_OP_REG, // Register operand. + CS_OP_IMM, // Immediate operand. + CS_OP_MEM, // Memory operand. + CS_OP_FP, // Floating-Point operand. +} cs_op_type; + +//> Common instruction groups - to be consistent across all architectures. +typedef enum cs_group_type +{ + CS_GRP_INVALID = 0, // uninitialized/invalid group. + CS_GRP_JUMP, // all jump instructions (conditional+direct+indirect jumps) + CS_GRP_CALL, // all call instructions + CS_GRP_RET, // all return instructions + CS_GRP_INT, // all interrupt instructions (int+syscall) + CS_GRP_IRET, // all interrupt return instructions +} cs_group_type; + +/* + User-defined callback function for SKIPDATA option. + See tests/test_skipdata.c for sample code demonstrating this API. + + @code: the input buffer containing code to be disassembled. + This is the same buffer passed to cs_disasm(). + @code_size: size (in bytes) of the above @code buffer. + @offset: the position of the currently-examining byte in the input + buffer @code mentioned above. + @user_data: user-data passed to cs_option() via @user_data field in + cs_opt_skipdata struct below. + + @return: return number of bytes to skip, or 0 to immediately stop disassembling. +*/ +typedef size_t (*cs_skipdata_cb_t)(const uint8_t* code, size_t code_size, size_t offset, void* user_data); + +// User-customized setup for SKIPDATA option +typedef struct cs_opt_skipdata +{ + // Capstone considers data to skip as special "instructions". + // User can specify the string for this instruction's "mnemonic" here. + // By default (if @mnemonic is NULL), Capstone use ".byte". + const char* mnemonic; + + // User-defined callback function to be called when Capstone hits data. + // If the returned value from this callback is positive (>0), Capstone + // will skip exactly that number of bytes & continue. Otherwise, if + // the callback returns 0, Capstone stops disassembling and returns + // immediately from cs_disasm() + // NOTE: if this callback pointer is NULL, Capstone would skip a number + // of bytes depending on architectures, as following: + // Arm: 2 bytes (Thumb mode) or 4 bytes. + // Arm64: 4 bytes. + // Mips: 4 bytes. + // PowerPC: 4 bytes. + // Sparc: 4 bytes. + // SystemZ: 2 bytes. + // X86: 1 bytes. + // XCore: 2 bytes. + cs_skipdata_cb_t callback; // default value is NULL + + // User-defined data to be passed to @callback function pointer. + void* user_data; +} cs_opt_skipdata; + + +#include "arm.h" +#include "arm64.h" +#include "mips.h" +#include "ppc.h" +#include "sparc.h" +#include "systemz.h" +#include "x86.h" +#include "xcore.h" + +// NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON +typedef struct cs_detail +{ + uint8_t regs_read[12]; // list of implicit registers read by this insn + uint8_t regs_read_count; // number of implicit registers read by this insn + + uint8_t regs_write[20]; // list of implicit registers modified by this insn + uint8_t regs_write_count; // number of implicit registers modified by this insn + + uint8_t groups[8]; // list of group this instruction belong to + uint8_t groups_count; // number of groups this insn belongs to + + // Architecture-specific instruction info + union + { + cs_x86 x86; // X86 architecture, including 16-bit, 32-bit & 64-bit mode + cs_arm64 arm64; // ARM64 architecture (aka AArch64) + cs_arm arm; // ARM architecture (including Thumb/Thumb2) + cs_mips mips; // MIPS architecture + cs_ppc ppc; // PowerPC architecture + cs_sparc sparc; // Sparc architecture + cs_sysz sysz; // SystemZ architecture + cs_xcore xcore; // XCore architecture + }; +} cs_detail; + +// Detail information of disassembled instruction +typedef struct cs_insn +{ + // Instruction ID (basically a numeric ID for the instruction mnemonic) + // Find the instruction id in the '[ARCH]_insn' enum in the header file + // of corresponding architecture, such as 'arm_insn' in arm.h for ARM, + // 'x86_insn' in x86.h for X86, etc... + // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF + // NOTE: in Skipdata mode, "data" instruction has 0 for this id field. + unsigned int id; + + // Address (EIP) of this instruction + // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF + uint64_t address; + + // Size of this instruction + // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF + uint16_t size; + // Machine bytes of this instruction, with number of bytes indicated by @size above + // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF + uint8_t bytes[16]; + + // Ascii text of instruction mnemonic + // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF + char mnemonic[32]; + + // Ascii text of instruction operands + // This information is available even when CS_OPT_DETAIL = CS_OPT_OFF + char op_str[160]; + + // Pointer to cs_detail. + // NOTE: detail pointer is only valid when both requirements below are met: + // (1) CS_OP_DETAIL = CS_OPT_ON + // (2) Engine is not in Skipdata mode (CS_OP_SKIPDATA option set to CS_OPT_ON) + // + // NOTE 2: when in Skipdata mode, or when detail mode is OFF, even if this pointer + // is not NULL, its content is still irrelevant. + cs_detail* detail; +} cs_insn; + + +// Calculate the offset of a disassembled instruction in its buffer, given its position +// in its array of disassembled insn +// NOTE: this macro works with position (>=1), not index +#define CS_INSN_OFFSET(insns, post) (insns[post - 1].address - insns[0].address) + + +// All type of errors encountered by Capstone API. +// These are values returned by cs_errno() +typedef enum cs_err +{ + CS_ERR_OK = 0, // No error: everything was fine + CS_ERR_MEM, // Out-Of-Memory error: cs_open(), cs_disasm(), cs_disasm_iter() + CS_ERR_ARCH, // Unsupported architecture: cs_open() + CS_ERR_HANDLE, // Invalid handle: cs_op_count(), cs_op_index() + CS_ERR_CSH, // Invalid csh argument: cs_close(), cs_errno(), cs_option() + CS_ERR_MODE, // Invalid/unsupported mode: cs_open() + CS_ERR_OPTION, // Invalid/unsupported option: cs_option() + CS_ERR_DETAIL, // Information is unavailable because detail option is OFF + CS_ERR_MEMSETUP, // Dynamic memory management uninitialized (see CS_OPT_MEM) + CS_ERR_VERSION, // Unsupported version (bindings) + CS_ERR_DIET, // Access irrelevant data in "diet" engine + CS_ERR_SKIPDATA, // Access irrelevant data for "data" instruction in SKIPDATA mode + CS_ERR_X86_ATT, // X86 AT&T syntax is unsupported (opt-out at compile time) + CS_ERR_X86_INTEL, // X86 Intel syntax is unsupported (opt-out at compile time) +} cs_err; + +/* + Return combined API version & major and minor version numbers. + + @major: major number of API version + @minor: minor number of API version + + @return hexical number as (major << 8 | minor), which encodes both + major & minor versions. + NOTE: This returned value can be compared with version number made + with macro CS_MAKE_VERSION + + For example, second API version would return 1 in @major, and 1 in @minor + The return value would be 0x0101 + + NOTE: if you only care about returned value, but not major and minor values, + set both @major & @minor arguments to NULL. +*/ +CAPSTONE_EXPORT +unsigned int cs_version(int* major, int* minor); + + +/* + This API can be used to either ask for archs supported by this library, + or check to see if the library was compile with 'diet' option (or called + in 'diet' mode). + + To check if a particular arch is supported by this library, set @query to + arch mode (CS_ARCH_* value). + To verify if this library supports all the archs, use CS_ARCH_ALL. + + To check if this library is in 'diet' mode, set @query to CS_SUPPORT_DIET. + + @return True if this library supports the given arch, or in 'diet' mode. +*/ +CAPSTONE_EXPORT +bool cs_support(int query); + +/* + Initialize CS handle: this must be done before any usage of CS. + + @arch: architecture type (CS_ARCH_*) + @mode: hardware mode. This is combined of CS_MODE_* + @handle: pointer to handle, which will be updated at return time + + @return CS_ERR_OK on success, or other value on failure (refer to cs_err enum + for detailed error). +*/ +CAPSTONE_EXPORT +cs_err cs_open(cs_arch arch, cs_mode mode, csh* handle); + +/* + Close CS handle: MUST do to release the handle when it is not used anymore. + NOTE: this must be only called when there is no longer usage of Capstone, + not even access to cs_insn array. The reason is the this API releases some + cached memory, thus access to any Capstone API after cs_close() might crash + your application. + + In fact,this API invalidate @handle by ZERO out its value (i.e *handle = 0). + + @handle: pointer to a handle returned by cs_open() + + @return CS_ERR_OK on success, or other value on failure (refer to cs_err enum + for detailed error). +*/ +CAPSTONE_EXPORT +cs_err cs_close(csh* handle); + +/* + Set option for disassembling engine at runtime + + @handle: handle returned by cs_open() + @type: type of option to be set + @value: option value corresponding with @type + + @return: CS_ERR_OK on success, or other value on failure. + Refer to cs_err enum for detailed error. + + NOTE: in the case of CS_OPT_MEM, handle's value can be anything, + so that cs_option(handle, CS_OPT_MEM, value) can (i.e must) be called + even before cs_open() +*/ +CAPSTONE_EXPORT +cs_err cs_option(csh handle, cs_opt_type type, size_t value); + +/* + Report the last error number when some API function fail. + Like glibc's errno, cs_errno might not retain its old value once accessed. + + @handle: handle returned by cs_open() + + @return: error code of cs_err enum type (CS_ERR_*, see above) +*/ +CAPSTONE_EXPORT +cs_err cs_errno(csh handle); + + +/* + Return a string describing given error code. + + @code: error code (see CS_ERR_* above) + + @return: returns a pointer to a string that describes the error code + passed in the argument @code +*/ +CAPSTONE_EXPORT +const char* cs_strerror(cs_err code); + +/* + Disassemble binary code, given the code buffer, size, address and number + of instructions to be decoded. + This API dynamically allocate memory to contain disassembled instruction. + Resulted instructions will be put into @*insn + + NOTE 1: this API will automatically determine memory needed to contain + output disassembled instructions in @insn. + + NOTE 2: caller must free the allocated memory itself to avoid memory leaking. + + NOTE 3: for system with scarce memory to be dynamically allocated such as + OS kernel or firmware, the API cs_disasm_iter() might be a better choice than + cs_disasm(). The reason is that with cs_disasm(), based on limited available + memory, we have to calculate in advance how many instructions to be disassembled, + which complicates things. This is especially troublesome for the case @count=0, + when cs_disasm() runs uncontrollably (until either end of input buffer, or + when it encounters an invalid instruction). + + @handle: handle returned by cs_open() + @code: buffer containing raw binary code to be disassembled. + @code_size: size of the above code buffer. + @address: address of the first instruction in given raw code buffer. + @insn: array of instructions filled in by this API. + NOTE: @insn will be allocated by this function, and should be freed + with cs_free() API. + @count: number of instructions to be disassembled, or 0 to get all of them + + @return: the number of successfully disassembled instructions, + or 0 if this function failed to disassemble the given code + + On failure, call cs_errno() for error code. +*/ +CAPSTONE_EXPORT +size_t cs_disasm(csh handle, + const uint8_t* code, size_t code_size, + uint64_t address, + size_t count, + cs_insn** insn); + +/* + Deprecated function - to be retired in the next version! + Use cs_disasm() instead of cs_disasm_ex() +*/ +CAPSTONE_EXPORT +CAPSTONE_DEPRECATED +size_t cs_disasm_ex(csh handle, + const uint8_t* code, size_t code_size, + uint64_t address, + size_t count, + cs_insn** insn); + +/* + Free memory allocated by cs_malloc() or cs_disasm() (argument @insn) + + @insn: pointer returned by @insn argument in cs_disasm() or cs_malloc() + @count: number of cs_insn structures returned by cs_disasm(), or 1 + to free memory allocated by cs_malloc(). +*/ +CAPSTONE_EXPORT +void cs_free(cs_insn* insn, size_t count); + + +/* + Allocate memory for 1 instruction to be used by cs_disasm_iter(). + + @handle: handle returned by cs_open() + + NOTE: when no longer in use, you can reclaim the memory allocated for + this instruction with cs_free(insn, 1) +*/ +CAPSTONE_EXPORT +cs_insn* cs_malloc(csh handle); + +/* + Fast API to disassemble binary code, given the code buffer, size, address + and number of instructions to be decoded. + This API put the resulted instruction into a given cache in @insn. + See tests/test_iter.c for sample code demonstrating this API. + + NOTE 1: this API will update @code, @size & @address to point to the next + instruction in the input buffer. Therefore, it is convenient to use + cs_disasm_iter() inside a loop to quickly iterate all the instructions. + While decoding one instruction at a time can also be achieved with + cs_disasm(count=1), some benchmarks shown that cs_disasm_iter() can be 30% + faster on random input. + + NOTE 2: the cache in @insn can be created with cs_malloc() API. + + NOTE 3: for system with scarce memory to be dynamically allocated such as + OS kernel or firmware, this API is recommended over cs_disasm(), which + allocates memory based on the number of instructions to be disassembled. + The reason is that with cs_disasm(), based on limited available memory, + we have to calculate in advance how many instructions to be disassembled, + which complicates things. This is especially troublesome for the case + @count=0, when cs_disasm() runs uncontrollably (until either end of input + buffer, or when it encounters an invalid instruction). + + @handle: handle returned by cs_open() + @code: buffer containing raw binary code to be disassembled + @code_size: size of above code + @address: address of the first insn in given raw code buffer + @insn: pointer to instruction to be filled in by this API. + + @return: true if this API successfully decode 1 instruction, + or false otherwise. + + On failure, call cs_errno() for error code. +*/ +CAPSTONE_EXPORT +bool cs_disasm_iter(csh handle, + const uint8_t** code, size_t* size, + uint64_t* address, cs_insn* insn); + +/* + Return friendly name of register in a string. + Find the instruction id from header file of corresponding architecture (arm.h for ARM, + x86.h for X86, ...) + + WARN: when in 'diet' mode, this API is irrelevant because engine does not + store register name. + + @handle: handle returned by cs_open() + @reg_id: register id + + @return: string name of the register, or NULL if @reg_id is invalid. +*/ +CAPSTONE_EXPORT +const char* cs_reg_name(csh handle, unsigned int reg_id); + +/* + Return friendly name of an instruction in a string. + Find the instruction id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + + WARN: when in 'diet' mode, this API is irrelevant because the engine does not + store instruction name. + + @handle: handle returned by cs_open() + @insn_id: instruction id + + @return: string name of the instruction, or NULL if @insn_id is invalid. +*/ +CAPSTONE_EXPORT +const char* cs_insn_name(csh handle, unsigned int insn_id); + +/* + Return friendly name of a group id (that an instruction can belong to) + Find the group id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + + WARN: when in 'diet' mode, this API is irrelevant because the engine does not + store group name. + + @handle: handle returned by cs_open() + @group_id: group id + + @return: string name of the group, or NULL if @group_id is invalid. +*/ +CAPSTONE_EXPORT +const char* cs_group_name(csh handle, unsigned int group_id); + +/* + Check if a disassembled instruction belong to a particular group. + Find the group id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + Internally, this simply verifies if @group_id matches any member of insn->groups array. + + NOTE: this API is only valid when detail option is ON (which is OFF by default). + + WARN: when in 'diet' mode, this API is irrelevant because the engine does not + update @groups array. + + @handle: handle returned by cs_open() + @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() + @group_id: group that you want to check if this instruction belong to. + + @return: true if this instruction indeed belongs to aboved group, or false otherwise. +*/ +CAPSTONE_EXPORT +bool cs_insn_group(csh handle, const cs_insn* insn, unsigned int group_id); + +/* + Check if a disassembled instruction IMPLICITLY used a particular register. + Find the register id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + Internally, this simply verifies if @reg_id matches any member of insn->regs_read array. + + NOTE: this API is only valid when detail option is ON (which is OFF by default) + + WARN: when in 'diet' mode, this API is irrelevant because the engine does not + update @regs_read array. + + @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() + @reg_id: register that you want to check if this instruction used it. + + @return: true if this instruction indeed implicitly used aboved register, or false otherwise. +*/ +CAPSTONE_EXPORT +bool cs_reg_read(csh handle, const cs_insn* insn, unsigned int reg_id); + +/* + Check if a disassembled instruction IMPLICITLY modified a particular register. + Find the register id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + Internally, this simply verifies if @reg_id matches any member of insn->regs_write array. + + NOTE: this API is only valid when detail option is ON (which is OFF by default) + + WARN: when in 'diet' mode, this API is irrelevant because the engine does not + update @regs_write array. + + @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() + @reg_id: register that you want to check if this instruction modified it. + + @return: true if this instruction indeed implicitly modified aboved register, or false otherwise. +*/ +CAPSTONE_EXPORT +bool cs_reg_write(csh handle, const cs_insn* insn, unsigned int reg_id); + +/* + Count the number of operands of a given type. + Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + + NOTE: this API is only valid when detail option is ON (which is OFF by default) + + @handle: handle returned by cs_open() + @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() + @op_type: Operand type to be found. + + @return: number of operands of given type @op_type in instruction @insn, + or -1 on failure. +*/ +CAPSTONE_EXPORT +int cs_op_count(csh handle, const cs_insn* insn, unsigned int op_type); + +/* + Retrieve the position of operand of given type in .operands[] array. + Later, the operand can be accessed using the returned position. + Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...) + + NOTE: this API is only valid when detail option is ON (which is OFF by default) + + @handle: handle returned by cs_open() + @insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter() + @op_type: Operand type to be found. + @position: position of the operand to be found. This must be in the range + [1, cs_op_count(handle, insn, op_type)] + + @return: index of operand of given type @op_type in .operands[] array + in instruction @insn, or -1 on failure. +*/ +CAPSTONE_EXPORT +int cs_op_index(csh handle, const cs_insn* insn, unsigned int op_type, + unsigned int position); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dbg/capstone/mips.h b/src/dbg/capstone/mips.h index d63d6eb3..2fe5ff42 100644 --- a/src/dbg/capstone/mips.h +++ b/src/dbg/capstone/mips.h @@ -1,911 +1,911 @@ -#ifndef CAPSTONE_MIPS_H -#define CAPSTONE_MIPS_H - -/* Capstone Disassembly Engine */ -/* By Nguyen Anh Quynh , 2013-2014 */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "platform.h" - -// GCC MIPS toolchain has a default macro called "mips" which breaks -// compilation -#undef mips - -#ifdef _MSC_VER -#pragma warning(disable:4201) -#endif - -//> Operand type for instruction's operands -typedef enum mips_op_type -{ - MIPS_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). - MIPS_OP_REG, // = CS_OP_REG (Register operand). - MIPS_OP_IMM, // = CS_OP_IMM (Immediate operand). - MIPS_OP_MEM, // = CS_OP_MEM (Memory operand). -} mips_op_type; - -// Instruction's operand referring to memory -// This is associated with MIPS_OP_MEM operand type above -typedef struct mips_op_mem -{ - unsigned int base; // base register - int64_t disp; // displacement/offset value -} mips_op_mem; - -// Instruction operand -typedef struct cs_mips_op -{ - mips_op_type type; // operand type - union - { - unsigned int reg; // register value for REG operand - int64_t imm; // immediate value for IMM operand - mips_op_mem mem; // base/index/scale/disp value for MEM operand - }; -} cs_mips_op; - -// Instruction structure -typedef struct cs_mips -{ - // Number of operands of this instruction, - // or 0 when instruction has no operand. - uint8_t op_count; - cs_mips_op operands[8]; // operands for this instruction. -} cs_mips; - -//> MIPS registers -typedef enum mips_reg -{ - MIPS_REG_INVALID = 0, - //> General purpose registers - MIPS_REG_0, - MIPS_REG_1, - MIPS_REG_2, - MIPS_REG_3, - MIPS_REG_4, - MIPS_REG_5, - MIPS_REG_6, - MIPS_REG_7, - MIPS_REG_8, - MIPS_REG_9, - MIPS_REG_10, - MIPS_REG_11, - MIPS_REG_12, - MIPS_REG_13, - MIPS_REG_14, - MIPS_REG_15, - MIPS_REG_16, - MIPS_REG_17, - MIPS_REG_18, - MIPS_REG_19, - MIPS_REG_20, - MIPS_REG_21, - MIPS_REG_22, - MIPS_REG_23, - MIPS_REG_24, - MIPS_REG_25, - MIPS_REG_26, - MIPS_REG_27, - MIPS_REG_28, - MIPS_REG_29, - MIPS_REG_30, - MIPS_REG_31, - - //> DSP registers - MIPS_REG_DSPCCOND, - MIPS_REG_DSPCARRY, - MIPS_REG_DSPEFI, - MIPS_REG_DSPOUTFLAG, - MIPS_REG_DSPOUTFLAG16_19, - MIPS_REG_DSPOUTFLAG20, - MIPS_REG_DSPOUTFLAG21, - MIPS_REG_DSPOUTFLAG22, - MIPS_REG_DSPOUTFLAG23, - MIPS_REG_DSPPOS, - MIPS_REG_DSPSCOUNT, - - //> ACC registers - MIPS_REG_AC0, - MIPS_REG_AC1, - MIPS_REG_AC2, - MIPS_REG_AC3, - - //> COP registers - MIPS_REG_CC0, - MIPS_REG_CC1, - MIPS_REG_CC2, - MIPS_REG_CC3, - MIPS_REG_CC4, - MIPS_REG_CC5, - MIPS_REG_CC6, - MIPS_REG_CC7, - - //> FPU registers - MIPS_REG_F0, - MIPS_REG_F1, - MIPS_REG_F2, - MIPS_REG_F3, - MIPS_REG_F4, - MIPS_REG_F5, - MIPS_REG_F6, - MIPS_REG_F7, - MIPS_REG_F8, - MIPS_REG_F9, - MIPS_REG_F10, - MIPS_REG_F11, - MIPS_REG_F12, - MIPS_REG_F13, - MIPS_REG_F14, - MIPS_REG_F15, - MIPS_REG_F16, - MIPS_REG_F17, - MIPS_REG_F18, - MIPS_REG_F19, - MIPS_REG_F20, - MIPS_REG_F21, - MIPS_REG_F22, - MIPS_REG_F23, - MIPS_REG_F24, - MIPS_REG_F25, - MIPS_REG_F26, - MIPS_REG_F27, - MIPS_REG_F28, - MIPS_REG_F29, - MIPS_REG_F30, - MIPS_REG_F31, - - MIPS_REG_FCC0, - MIPS_REG_FCC1, - MIPS_REG_FCC2, - MIPS_REG_FCC3, - MIPS_REG_FCC4, - MIPS_REG_FCC5, - MIPS_REG_FCC6, - MIPS_REG_FCC7, - - //> AFPR128 - MIPS_REG_W0, - MIPS_REG_W1, - MIPS_REG_W2, - MIPS_REG_W3, - MIPS_REG_W4, - MIPS_REG_W5, - MIPS_REG_W6, - MIPS_REG_W7, - MIPS_REG_W8, - MIPS_REG_W9, - MIPS_REG_W10, - MIPS_REG_W11, - MIPS_REG_W12, - MIPS_REG_W13, - MIPS_REG_W14, - MIPS_REG_W15, - MIPS_REG_W16, - MIPS_REG_W17, - MIPS_REG_W18, - MIPS_REG_W19, - MIPS_REG_W20, - MIPS_REG_W21, - MIPS_REG_W22, - MIPS_REG_W23, - MIPS_REG_W24, - MIPS_REG_W25, - MIPS_REG_W26, - MIPS_REG_W27, - MIPS_REG_W28, - MIPS_REG_W29, - MIPS_REG_W30, - MIPS_REG_W31, - - MIPS_REG_HI, - MIPS_REG_LO, - - MIPS_REG_P0, - MIPS_REG_P1, - MIPS_REG_P2, - - MIPS_REG_MPL0, - MIPS_REG_MPL1, - MIPS_REG_MPL2, - - MIPS_REG_ENDING, // <-- mark the end of the list or registers - - // alias registers - MIPS_REG_ZERO = MIPS_REG_0, - MIPS_REG_AT = MIPS_REG_1, - MIPS_REG_V0 = MIPS_REG_2, - MIPS_REG_V1 = MIPS_REG_3, - MIPS_REG_A0 = MIPS_REG_4, - MIPS_REG_A1 = MIPS_REG_5, - MIPS_REG_A2 = MIPS_REG_6, - MIPS_REG_A3 = MIPS_REG_7, - MIPS_REG_T0 = MIPS_REG_8, - MIPS_REG_T1 = MIPS_REG_9, - MIPS_REG_T2 = MIPS_REG_10, - MIPS_REG_T3 = MIPS_REG_11, - MIPS_REG_T4 = MIPS_REG_12, - MIPS_REG_T5 = MIPS_REG_13, - MIPS_REG_T6 = MIPS_REG_14, - MIPS_REG_T7 = MIPS_REG_15, - MIPS_REG_S0 = MIPS_REG_16, - MIPS_REG_S1 = MIPS_REG_17, - MIPS_REG_S2 = MIPS_REG_18, - MIPS_REG_S3 = MIPS_REG_19, - MIPS_REG_S4 = MIPS_REG_20, - MIPS_REG_S5 = MIPS_REG_21, - MIPS_REG_S6 = MIPS_REG_22, - MIPS_REG_S7 = MIPS_REG_23, - MIPS_REG_T8 = MIPS_REG_24, - MIPS_REG_T9 = MIPS_REG_25, - MIPS_REG_K0 = MIPS_REG_26, - MIPS_REG_K1 = MIPS_REG_27, - MIPS_REG_GP = MIPS_REG_28, - MIPS_REG_SP = MIPS_REG_29, - MIPS_REG_FP = MIPS_REG_30, MIPS_REG_S8 = MIPS_REG_30, - MIPS_REG_RA = MIPS_REG_31, - - MIPS_REG_HI0 = MIPS_REG_AC0, - MIPS_REG_HI1 = MIPS_REG_AC1, - MIPS_REG_HI2 = MIPS_REG_AC2, - MIPS_REG_HI3 = MIPS_REG_AC3, - - MIPS_REG_LO0 = MIPS_REG_HI0, - MIPS_REG_LO1 = MIPS_REG_HI1, - MIPS_REG_LO2 = MIPS_REG_HI2, - MIPS_REG_LO3 = MIPS_REG_HI3, -} mips_reg; - -//> MIPS instruction -typedef enum mips_insn -{ - MIPS_INS_INVALID = 0, - - MIPS_INS_ABSQ_S, - MIPS_INS_ADD, - MIPS_INS_ADDIUPC, - MIPS_INS_ADDQH, - MIPS_INS_ADDQH_R, - MIPS_INS_ADDQ, - MIPS_INS_ADDQ_S, - MIPS_INS_ADDSC, - MIPS_INS_ADDS_A, - MIPS_INS_ADDS_S, - MIPS_INS_ADDS_U, - MIPS_INS_ADDUH, - MIPS_INS_ADDUH_R, - MIPS_INS_ADDU, - MIPS_INS_ADDU_S, - MIPS_INS_ADDVI, - MIPS_INS_ADDV, - MIPS_INS_ADDWC, - MIPS_INS_ADD_A, - MIPS_INS_ADDI, - MIPS_INS_ADDIU, - MIPS_INS_ALIGN, - MIPS_INS_ALUIPC, - MIPS_INS_AND, - MIPS_INS_ANDI, - MIPS_INS_APPEND, - MIPS_INS_ASUB_S, - MIPS_INS_ASUB_U, - MIPS_INS_AUI, - MIPS_INS_AUIPC, - MIPS_INS_AVER_S, - MIPS_INS_AVER_U, - MIPS_INS_AVE_S, - MIPS_INS_AVE_U, - MIPS_INS_BADDU, - MIPS_INS_BAL, - MIPS_INS_BALC, - MIPS_INS_BALIGN, - MIPS_INS_BC, - MIPS_INS_BC0F, - MIPS_INS_BC0FL, - MIPS_INS_BC0T, - MIPS_INS_BC0TL, - MIPS_INS_BC1EQZ, - MIPS_INS_BC1F, - MIPS_INS_BC1FL, - MIPS_INS_BC1NEZ, - MIPS_INS_BC1T, - MIPS_INS_BC1TL, - MIPS_INS_BC2EQZ, - MIPS_INS_BC2F, - MIPS_INS_BC2FL, - MIPS_INS_BC2NEZ, - MIPS_INS_BC2T, - MIPS_INS_BC2TL, - MIPS_INS_BC3F, - MIPS_INS_BC3FL, - MIPS_INS_BC3T, - MIPS_INS_BC3TL, - MIPS_INS_BCLRI, - MIPS_INS_BCLR, - MIPS_INS_BEQ, - MIPS_INS_BEQC, - MIPS_INS_BEQL, - MIPS_INS_BEQZALC, - MIPS_INS_BEQZC, - MIPS_INS_BGEC, - MIPS_INS_BGEUC, - MIPS_INS_BGEZ, - MIPS_INS_BGEZAL, - MIPS_INS_BGEZALC, - MIPS_INS_BGEZALL, - MIPS_INS_BGEZALS, - MIPS_INS_BGEZC, - MIPS_INS_BGEZL, - MIPS_INS_BGTZ, - MIPS_INS_BGTZALC, - MIPS_INS_BGTZC, - MIPS_INS_BGTZL, - MIPS_INS_BINSLI, - MIPS_INS_BINSL, - MIPS_INS_BINSRI, - MIPS_INS_BINSR, - MIPS_INS_BITREV, - MIPS_INS_BITSWAP, - MIPS_INS_BLEZ, - MIPS_INS_BLEZALC, - MIPS_INS_BLEZC, - MIPS_INS_BLEZL, - MIPS_INS_BLTC, - MIPS_INS_BLTUC, - MIPS_INS_BLTZ, - MIPS_INS_BLTZAL, - MIPS_INS_BLTZALC, - MIPS_INS_BLTZALL, - MIPS_INS_BLTZALS, - MIPS_INS_BLTZC, - MIPS_INS_BLTZL, - MIPS_INS_BMNZI, - MIPS_INS_BMNZ, - MIPS_INS_BMZI, - MIPS_INS_BMZ, - MIPS_INS_BNE, - MIPS_INS_BNEC, - MIPS_INS_BNEGI, - MIPS_INS_BNEG, - MIPS_INS_BNEL, - MIPS_INS_BNEZALC, - MIPS_INS_BNEZC, - MIPS_INS_BNVC, - MIPS_INS_BNZ, - MIPS_INS_BOVC, - MIPS_INS_BPOSGE32, - MIPS_INS_BREAK, - MIPS_INS_BSELI, - MIPS_INS_BSEL, - MIPS_INS_BSETI, - MIPS_INS_BSET, - MIPS_INS_BZ, - MIPS_INS_BEQZ, - MIPS_INS_B, - MIPS_INS_BNEZ, - MIPS_INS_BTEQZ, - MIPS_INS_BTNEZ, - MIPS_INS_CACHE, - MIPS_INS_CEIL, - MIPS_INS_CEQI, - MIPS_INS_CEQ, - MIPS_INS_CFC1, - MIPS_INS_CFCMSA, - MIPS_INS_CINS, - MIPS_INS_CINS32, - MIPS_INS_CLASS, - MIPS_INS_CLEI_S, - MIPS_INS_CLEI_U, - MIPS_INS_CLE_S, - MIPS_INS_CLE_U, - MIPS_INS_CLO, - MIPS_INS_CLTI_S, - MIPS_INS_CLTI_U, - MIPS_INS_CLT_S, - MIPS_INS_CLT_U, - MIPS_INS_CLZ, - MIPS_INS_CMPGDU, - MIPS_INS_CMPGU, - MIPS_INS_CMPU, - MIPS_INS_CMP, - MIPS_INS_COPY_S, - MIPS_INS_COPY_U, - MIPS_INS_CTC1, - MIPS_INS_CTCMSA, - MIPS_INS_CVT, - MIPS_INS_C, - MIPS_INS_CMPI, - MIPS_INS_DADD, - MIPS_INS_DADDI, - MIPS_INS_DADDIU, - MIPS_INS_DADDU, - MIPS_INS_DAHI, - MIPS_INS_DALIGN, - MIPS_INS_DATI, - MIPS_INS_DAUI, - MIPS_INS_DBITSWAP, - MIPS_INS_DCLO, - MIPS_INS_DCLZ, - MIPS_INS_DDIV, - MIPS_INS_DDIVU, - MIPS_INS_DERET, - MIPS_INS_DEXT, - MIPS_INS_DEXTM, - MIPS_INS_DEXTU, - MIPS_INS_DI, - MIPS_INS_DINS, - MIPS_INS_DINSM, - MIPS_INS_DINSU, - MIPS_INS_DIV, - MIPS_INS_DIVU, - MIPS_INS_DIV_S, - MIPS_INS_DIV_U, - MIPS_INS_DLSA, - MIPS_INS_DMFC0, - MIPS_INS_DMFC1, - MIPS_INS_DMFC2, - MIPS_INS_DMOD, - MIPS_INS_DMODU, - MIPS_INS_DMTC0, - MIPS_INS_DMTC1, - MIPS_INS_DMTC2, - MIPS_INS_DMUH, - MIPS_INS_DMUHU, - MIPS_INS_DMUL, - MIPS_INS_DMULT, - MIPS_INS_DMULTU, - MIPS_INS_DMULU, - MIPS_INS_DOTP_S, - MIPS_INS_DOTP_U, - MIPS_INS_DPADD_S, - MIPS_INS_DPADD_U, - MIPS_INS_DPAQX_SA, - MIPS_INS_DPAQX_S, - MIPS_INS_DPAQ_SA, - MIPS_INS_DPAQ_S, - MIPS_INS_DPAU, - MIPS_INS_DPAX, - MIPS_INS_DPA, - MIPS_INS_DPOP, - MIPS_INS_DPSQX_SA, - MIPS_INS_DPSQX_S, - MIPS_INS_DPSQ_SA, - MIPS_INS_DPSQ_S, - MIPS_INS_DPSUB_S, - MIPS_INS_DPSUB_U, - MIPS_INS_DPSU, - MIPS_INS_DPSX, - MIPS_INS_DPS, - MIPS_INS_DROTR, - MIPS_INS_DROTR32, - MIPS_INS_DROTRV, - MIPS_INS_DSBH, - MIPS_INS_DSHD, - MIPS_INS_DSLL, - MIPS_INS_DSLL32, - MIPS_INS_DSLLV, - MIPS_INS_DSRA, - MIPS_INS_DSRA32, - MIPS_INS_DSRAV, - MIPS_INS_DSRL, - MIPS_INS_DSRL32, - MIPS_INS_DSRLV, - MIPS_INS_DSUB, - MIPS_INS_DSUBU, - MIPS_INS_EHB, - MIPS_INS_EI, - MIPS_INS_ERET, - MIPS_INS_EXT, - MIPS_INS_EXTP, - MIPS_INS_EXTPDP, - MIPS_INS_EXTPDPV, - MIPS_INS_EXTPV, - MIPS_INS_EXTRV_RS, - MIPS_INS_EXTRV_R, - MIPS_INS_EXTRV_S, - MIPS_INS_EXTRV, - MIPS_INS_EXTR_RS, - MIPS_INS_EXTR_R, - MIPS_INS_EXTR_S, - MIPS_INS_EXTR, - MIPS_INS_EXTS, - MIPS_INS_EXTS32, - MIPS_INS_ABS, - MIPS_INS_FADD, - MIPS_INS_FCAF, - MIPS_INS_FCEQ, - MIPS_INS_FCLASS, - MIPS_INS_FCLE, - MIPS_INS_FCLT, - MIPS_INS_FCNE, - MIPS_INS_FCOR, - MIPS_INS_FCUEQ, - MIPS_INS_FCULE, - MIPS_INS_FCULT, - MIPS_INS_FCUNE, - MIPS_INS_FCUN, - MIPS_INS_FDIV, - MIPS_INS_FEXDO, - MIPS_INS_FEXP2, - MIPS_INS_FEXUPL, - MIPS_INS_FEXUPR, - MIPS_INS_FFINT_S, - MIPS_INS_FFINT_U, - MIPS_INS_FFQL, - MIPS_INS_FFQR, - MIPS_INS_FILL, - MIPS_INS_FLOG2, - MIPS_INS_FLOOR, - MIPS_INS_FMADD, - MIPS_INS_FMAX_A, - MIPS_INS_FMAX, - MIPS_INS_FMIN_A, - MIPS_INS_FMIN, - MIPS_INS_MOV, - MIPS_INS_FMSUB, - MIPS_INS_FMUL, - MIPS_INS_MUL, - MIPS_INS_NEG, - MIPS_INS_FRCP, - MIPS_INS_FRINT, - MIPS_INS_FRSQRT, - MIPS_INS_FSAF, - MIPS_INS_FSEQ, - MIPS_INS_FSLE, - MIPS_INS_FSLT, - MIPS_INS_FSNE, - MIPS_INS_FSOR, - MIPS_INS_FSQRT, - MIPS_INS_SQRT, - MIPS_INS_FSUB, - MIPS_INS_SUB, - MIPS_INS_FSUEQ, - MIPS_INS_FSULE, - MIPS_INS_FSULT, - MIPS_INS_FSUNE, - MIPS_INS_FSUN, - MIPS_INS_FTINT_S, - MIPS_INS_FTINT_U, - MIPS_INS_FTQ, - MIPS_INS_FTRUNC_S, - MIPS_INS_FTRUNC_U, - MIPS_INS_HADD_S, - MIPS_INS_HADD_U, - MIPS_INS_HSUB_S, - MIPS_INS_HSUB_U, - MIPS_INS_ILVEV, - MIPS_INS_ILVL, - MIPS_INS_ILVOD, - MIPS_INS_ILVR, - MIPS_INS_INS, - MIPS_INS_INSERT, - MIPS_INS_INSV, - MIPS_INS_INSVE, - MIPS_INS_J, - MIPS_INS_JAL, - MIPS_INS_JALR, - MIPS_INS_JALRS, - MIPS_INS_JALS, - MIPS_INS_JALX, - MIPS_INS_JIALC, - MIPS_INS_JIC, - MIPS_INS_JR, - MIPS_INS_JRADDIUSP, - MIPS_INS_JRC, - MIPS_INS_JALRC, - MIPS_INS_LB, - MIPS_INS_LBUX, - MIPS_INS_LBU, - MIPS_INS_LD, - MIPS_INS_LDC1, - MIPS_INS_LDC2, - MIPS_INS_LDC3, - MIPS_INS_LDI, - MIPS_INS_LDL, - MIPS_INS_LDPC, - MIPS_INS_LDR, - MIPS_INS_LDXC1, - MIPS_INS_LH, - MIPS_INS_LHX, - MIPS_INS_LHU, - MIPS_INS_LL, - MIPS_INS_LLD, - MIPS_INS_LSA, - MIPS_INS_LUXC1, - MIPS_INS_LUI, - MIPS_INS_LW, - MIPS_INS_LWC1, - MIPS_INS_LWC2, - MIPS_INS_LWC3, - MIPS_INS_LWL, - MIPS_INS_LWPC, - MIPS_INS_LWR, - MIPS_INS_LWUPC, - MIPS_INS_LWU, - MIPS_INS_LWX, - MIPS_INS_LWXC1, - MIPS_INS_LI, - MIPS_INS_MADD, - MIPS_INS_MADDF, - MIPS_INS_MADDR_Q, - MIPS_INS_MADDU, - MIPS_INS_MADDV, - MIPS_INS_MADD_Q, - MIPS_INS_MAQ_SA, - MIPS_INS_MAQ_S, - MIPS_INS_MAXA, - MIPS_INS_MAXI_S, - MIPS_INS_MAXI_U, - MIPS_INS_MAX_A, - MIPS_INS_MAX, - MIPS_INS_MAX_S, - MIPS_INS_MAX_U, - MIPS_INS_MFC0, - MIPS_INS_MFC1, - MIPS_INS_MFC2, - MIPS_INS_MFHC1, - MIPS_INS_MFHI, - MIPS_INS_MFLO, - MIPS_INS_MINA, - MIPS_INS_MINI_S, - MIPS_INS_MINI_U, - MIPS_INS_MIN_A, - MIPS_INS_MIN, - MIPS_INS_MIN_S, - MIPS_INS_MIN_U, - MIPS_INS_MOD, - MIPS_INS_MODSUB, - MIPS_INS_MODU, - MIPS_INS_MOD_S, - MIPS_INS_MOD_U, - MIPS_INS_MOVE, - MIPS_INS_MOVF, - MIPS_INS_MOVN, - MIPS_INS_MOVT, - MIPS_INS_MOVZ, - MIPS_INS_MSUB, - MIPS_INS_MSUBF, - MIPS_INS_MSUBR_Q, - MIPS_INS_MSUBU, - MIPS_INS_MSUBV, - MIPS_INS_MSUB_Q, - MIPS_INS_MTC0, - MIPS_INS_MTC1, - MIPS_INS_MTC2, - MIPS_INS_MTHC1, - MIPS_INS_MTHI, - MIPS_INS_MTHLIP, - MIPS_INS_MTLO, - MIPS_INS_MTM0, - MIPS_INS_MTM1, - MIPS_INS_MTM2, - MIPS_INS_MTP0, - MIPS_INS_MTP1, - MIPS_INS_MTP2, - MIPS_INS_MUH, - MIPS_INS_MUHU, - MIPS_INS_MULEQ_S, - MIPS_INS_MULEU_S, - MIPS_INS_MULQ_RS, - MIPS_INS_MULQ_S, - MIPS_INS_MULR_Q, - MIPS_INS_MULSAQ_S, - MIPS_INS_MULSA, - MIPS_INS_MULT, - MIPS_INS_MULTU, - MIPS_INS_MULU, - MIPS_INS_MULV, - MIPS_INS_MUL_Q, - MIPS_INS_MUL_S, - MIPS_INS_NLOC, - MIPS_INS_NLZC, - MIPS_INS_NMADD, - MIPS_INS_NMSUB, - MIPS_INS_NOR, - MIPS_INS_NORI, - MIPS_INS_NOT, - MIPS_INS_OR, - MIPS_INS_ORI, - MIPS_INS_PACKRL, - MIPS_INS_PAUSE, - MIPS_INS_PCKEV, - MIPS_INS_PCKOD, - MIPS_INS_PCNT, - MIPS_INS_PICK, - MIPS_INS_POP, - MIPS_INS_PRECEQU, - MIPS_INS_PRECEQ, - MIPS_INS_PRECEU, - MIPS_INS_PRECRQU_S, - MIPS_INS_PRECRQ, - MIPS_INS_PRECRQ_RS, - MIPS_INS_PRECR, - MIPS_INS_PRECR_SRA, - MIPS_INS_PRECR_SRA_R, - MIPS_INS_PREF, - MIPS_INS_PREPEND, - MIPS_INS_RADDU, - MIPS_INS_RDDSP, - MIPS_INS_RDHWR, - MIPS_INS_REPLV, - MIPS_INS_REPL, - MIPS_INS_RINT, - MIPS_INS_ROTR, - MIPS_INS_ROTRV, - MIPS_INS_ROUND, - MIPS_INS_SAT_S, - MIPS_INS_SAT_U, - MIPS_INS_SB, - MIPS_INS_SC, - MIPS_INS_SCD, - MIPS_INS_SD, - MIPS_INS_SDBBP, - MIPS_INS_SDC1, - MIPS_INS_SDC2, - MIPS_INS_SDC3, - MIPS_INS_SDL, - MIPS_INS_SDR, - MIPS_INS_SDXC1, - MIPS_INS_SEB, - MIPS_INS_SEH, - MIPS_INS_SELEQZ, - MIPS_INS_SELNEZ, - MIPS_INS_SEL, - MIPS_INS_SEQ, - MIPS_INS_SEQI, - MIPS_INS_SH, - MIPS_INS_SHF, - MIPS_INS_SHILO, - MIPS_INS_SHILOV, - MIPS_INS_SHLLV, - MIPS_INS_SHLLV_S, - MIPS_INS_SHLL, - MIPS_INS_SHLL_S, - MIPS_INS_SHRAV, - MIPS_INS_SHRAV_R, - MIPS_INS_SHRA, - MIPS_INS_SHRA_R, - MIPS_INS_SHRLV, - MIPS_INS_SHRL, - MIPS_INS_SLDI, - MIPS_INS_SLD, - MIPS_INS_SLL, - MIPS_INS_SLLI, - MIPS_INS_SLLV, - MIPS_INS_SLT, - MIPS_INS_SLTI, - MIPS_INS_SLTIU, - MIPS_INS_SLTU, - MIPS_INS_SNE, - MIPS_INS_SNEI, - MIPS_INS_SPLATI, - MIPS_INS_SPLAT, - MIPS_INS_SRA, - MIPS_INS_SRAI, - MIPS_INS_SRARI, - MIPS_INS_SRAR, - MIPS_INS_SRAV, - MIPS_INS_SRL, - MIPS_INS_SRLI, - MIPS_INS_SRLRI, - MIPS_INS_SRLR, - MIPS_INS_SRLV, - MIPS_INS_SSNOP, - MIPS_INS_ST, - MIPS_INS_SUBQH, - MIPS_INS_SUBQH_R, - MIPS_INS_SUBQ, - MIPS_INS_SUBQ_S, - MIPS_INS_SUBSUS_U, - MIPS_INS_SUBSUU_S, - MIPS_INS_SUBS_S, - MIPS_INS_SUBS_U, - MIPS_INS_SUBUH, - MIPS_INS_SUBUH_R, - MIPS_INS_SUBU, - MIPS_INS_SUBU_S, - MIPS_INS_SUBVI, - MIPS_INS_SUBV, - MIPS_INS_SUXC1, - MIPS_INS_SW, - MIPS_INS_SWC1, - MIPS_INS_SWC2, - MIPS_INS_SWC3, - MIPS_INS_SWL, - MIPS_INS_SWR, - MIPS_INS_SWXC1, - MIPS_INS_SYNC, - MIPS_INS_SYSCALL, - MIPS_INS_TEQ, - MIPS_INS_TEQI, - MIPS_INS_TGE, - MIPS_INS_TGEI, - MIPS_INS_TGEIU, - MIPS_INS_TGEU, - MIPS_INS_TLBP, - MIPS_INS_TLBR, - MIPS_INS_TLBWI, - MIPS_INS_TLBWR, - MIPS_INS_TLT, - MIPS_INS_TLTI, - MIPS_INS_TLTIU, - MIPS_INS_TLTU, - MIPS_INS_TNE, - MIPS_INS_TNEI, - MIPS_INS_TRUNC, - MIPS_INS_V3MULU, - MIPS_INS_VMM0, - MIPS_INS_VMULU, - MIPS_INS_VSHF, - MIPS_INS_WAIT, - MIPS_INS_WRDSP, - MIPS_INS_WSBH, - MIPS_INS_XOR, - MIPS_INS_XORI, - - //> some alias instructions - MIPS_INS_NOP, - MIPS_INS_NEGU, - - //> special instructions - MIPS_INS_JALR_HB, // jump and link with Hazard Barrier - MIPS_INS_JR_HB, // jump register with Hazard Barrier - - MIPS_INS_ENDING, -} mips_insn; - -//> Group of MIPS instructions -typedef enum mips_insn_group -{ - MIPS_GRP_INVALID = 0, // = CS_GRP_INVALID - - //> Generic groups - // all jump instructions (conditional+direct+indirect jumps) - MIPS_GRP_JUMP, // = CS_GRP_JUMP - - //> Architecture-specific groups - MIPS_GRP_BITCOUNT = 128, - MIPS_GRP_DSP, - MIPS_GRP_DSPR2, - MIPS_GRP_FPIDX, - MIPS_GRP_MSA, - MIPS_GRP_MIPS32R2, - MIPS_GRP_MIPS64, - MIPS_GRP_MIPS64R2, - MIPS_GRP_SEINREG, - MIPS_GRP_STDENC, - MIPS_GRP_SWAP, - MIPS_GRP_MICROMIPS, - MIPS_GRP_MIPS16MODE, - MIPS_GRP_FP64BIT, - MIPS_GRP_NONANSFPMATH, - MIPS_GRP_NOTFP64BIT, - MIPS_GRP_NOTINMICROMIPS, - MIPS_GRP_NOTNACL, - MIPS_GRP_NOTMIPS32R6, - MIPS_GRP_NOTMIPS64R6, - MIPS_GRP_CNMIPS, - MIPS_GRP_MIPS32, - MIPS_GRP_MIPS32R6, - MIPS_GRP_MIPS64R6, - MIPS_GRP_MIPS2, - MIPS_GRP_MIPS3, - MIPS_GRP_MIPS3_32, - MIPS_GRP_MIPS3_32R2, - MIPS_GRP_MIPS4_32, - MIPS_GRP_MIPS4_32R2, - MIPS_GRP_MIPS5_32R2, - MIPS_GRP_GP32BIT, - MIPS_GRP_GP64BIT, - - MIPS_GRP_ENDING, -} mips_insn_group; - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef CAPSTONE_MIPS_H +#define CAPSTONE_MIPS_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "platform.h" + +// GCC MIPS toolchain has a default macro called "mips" which breaks +// compilation +#undef mips + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> Operand type for instruction's operands +typedef enum mips_op_type +{ + MIPS_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + MIPS_OP_REG, // = CS_OP_REG (Register operand). + MIPS_OP_IMM, // = CS_OP_IMM (Immediate operand). + MIPS_OP_MEM, // = CS_OP_MEM (Memory operand). +} mips_op_type; + +// Instruction's operand referring to memory +// This is associated with MIPS_OP_MEM operand type above +typedef struct mips_op_mem +{ + unsigned int base; // base register + int64_t disp; // displacement/offset value +} mips_op_mem; + +// Instruction operand +typedef struct cs_mips_op +{ + mips_op_type type; // operand type + union + { + unsigned int reg; // register value for REG operand + int64_t imm; // immediate value for IMM operand + mips_op_mem mem; // base/index/scale/disp value for MEM operand + }; +} cs_mips_op; + +// Instruction structure +typedef struct cs_mips +{ + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + cs_mips_op operands[8]; // operands for this instruction. +} cs_mips; + +//> MIPS registers +typedef enum mips_reg +{ + MIPS_REG_INVALID = 0, + //> General purpose registers + MIPS_REG_0, + MIPS_REG_1, + MIPS_REG_2, + MIPS_REG_3, + MIPS_REG_4, + MIPS_REG_5, + MIPS_REG_6, + MIPS_REG_7, + MIPS_REG_8, + MIPS_REG_9, + MIPS_REG_10, + MIPS_REG_11, + MIPS_REG_12, + MIPS_REG_13, + MIPS_REG_14, + MIPS_REG_15, + MIPS_REG_16, + MIPS_REG_17, + MIPS_REG_18, + MIPS_REG_19, + MIPS_REG_20, + MIPS_REG_21, + MIPS_REG_22, + MIPS_REG_23, + MIPS_REG_24, + MIPS_REG_25, + MIPS_REG_26, + MIPS_REG_27, + MIPS_REG_28, + MIPS_REG_29, + MIPS_REG_30, + MIPS_REG_31, + + //> DSP registers + MIPS_REG_DSPCCOND, + MIPS_REG_DSPCARRY, + MIPS_REG_DSPEFI, + MIPS_REG_DSPOUTFLAG, + MIPS_REG_DSPOUTFLAG16_19, + MIPS_REG_DSPOUTFLAG20, + MIPS_REG_DSPOUTFLAG21, + MIPS_REG_DSPOUTFLAG22, + MIPS_REG_DSPOUTFLAG23, + MIPS_REG_DSPPOS, + MIPS_REG_DSPSCOUNT, + + //> ACC registers + MIPS_REG_AC0, + MIPS_REG_AC1, + MIPS_REG_AC2, + MIPS_REG_AC3, + + //> COP registers + MIPS_REG_CC0, + MIPS_REG_CC1, + MIPS_REG_CC2, + MIPS_REG_CC3, + MIPS_REG_CC4, + MIPS_REG_CC5, + MIPS_REG_CC6, + MIPS_REG_CC7, + + //> FPU registers + MIPS_REG_F0, + MIPS_REG_F1, + MIPS_REG_F2, + MIPS_REG_F3, + MIPS_REG_F4, + MIPS_REG_F5, + MIPS_REG_F6, + MIPS_REG_F7, + MIPS_REG_F8, + MIPS_REG_F9, + MIPS_REG_F10, + MIPS_REG_F11, + MIPS_REG_F12, + MIPS_REG_F13, + MIPS_REG_F14, + MIPS_REG_F15, + MIPS_REG_F16, + MIPS_REG_F17, + MIPS_REG_F18, + MIPS_REG_F19, + MIPS_REG_F20, + MIPS_REG_F21, + MIPS_REG_F22, + MIPS_REG_F23, + MIPS_REG_F24, + MIPS_REG_F25, + MIPS_REG_F26, + MIPS_REG_F27, + MIPS_REG_F28, + MIPS_REG_F29, + MIPS_REG_F30, + MIPS_REG_F31, + + MIPS_REG_FCC0, + MIPS_REG_FCC1, + MIPS_REG_FCC2, + MIPS_REG_FCC3, + MIPS_REG_FCC4, + MIPS_REG_FCC5, + MIPS_REG_FCC6, + MIPS_REG_FCC7, + + //> AFPR128 + MIPS_REG_W0, + MIPS_REG_W1, + MIPS_REG_W2, + MIPS_REG_W3, + MIPS_REG_W4, + MIPS_REG_W5, + MIPS_REG_W6, + MIPS_REG_W7, + MIPS_REG_W8, + MIPS_REG_W9, + MIPS_REG_W10, + MIPS_REG_W11, + MIPS_REG_W12, + MIPS_REG_W13, + MIPS_REG_W14, + MIPS_REG_W15, + MIPS_REG_W16, + MIPS_REG_W17, + MIPS_REG_W18, + MIPS_REG_W19, + MIPS_REG_W20, + MIPS_REG_W21, + MIPS_REG_W22, + MIPS_REG_W23, + MIPS_REG_W24, + MIPS_REG_W25, + MIPS_REG_W26, + MIPS_REG_W27, + MIPS_REG_W28, + MIPS_REG_W29, + MIPS_REG_W30, + MIPS_REG_W31, + + MIPS_REG_HI, + MIPS_REG_LO, + + MIPS_REG_P0, + MIPS_REG_P1, + MIPS_REG_P2, + + MIPS_REG_MPL0, + MIPS_REG_MPL1, + MIPS_REG_MPL2, + + MIPS_REG_ENDING, // <-- mark the end of the list or registers + + // alias registers + MIPS_REG_ZERO = MIPS_REG_0, + MIPS_REG_AT = MIPS_REG_1, + MIPS_REG_V0 = MIPS_REG_2, + MIPS_REG_V1 = MIPS_REG_3, + MIPS_REG_A0 = MIPS_REG_4, + MIPS_REG_A1 = MIPS_REG_5, + MIPS_REG_A2 = MIPS_REG_6, + MIPS_REG_A3 = MIPS_REG_7, + MIPS_REG_T0 = MIPS_REG_8, + MIPS_REG_T1 = MIPS_REG_9, + MIPS_REG_T2 = MIPS_REG_10, + MIPS_REG_T3 = MIPS_REG_11, + MIPS_REG_T4 = MIPS_REG_12, + MIPS_REG_T5 = MIPS_REG_13, + MIPS_REG_T6 = MIPS_REG_14, + MIPS_REG_T7 = MIPS_REG_15, + MIPS_REG_S0 = MIPS_REG_16, + MIPS_REG_S1 = MIPS_REG_17, + MIPS_REG_S2 = MIPS_REG_18, + MIPS_REG_S3 = MIPS_REG_19, + MIPS_REG_S4 = MIPS_REG_20, + MIPS_REG_S5 = MIPS_REG_21, + MIPS_REG_S6 = MIPS_REG_22, + MIPS_REG_S7 = MIPS_REG_23, + MIPS_REG_T8 = MIPS_REG_24, + MIPS_REG_T9 = MIPS_REG_25, + MIPS_REG_K0 = MIPS_REG_26, + MIPS_REG_K1 = MIPS_REG_27, + MIPS_REG_GP = MIPS_REG_28, + MIPS_REG_SP = MIPS_REG_29, + MIPS_REG_FP = MIPS_REG_30, MIPS_REG_S8 = MIPS_REG_30, + MIPS_REG_RA = MIPS_REG_31, + + MIPS_REG_HI0 = MIPS_REG_AC0, + MIPS_REG_HI1 = MIPS_REG_AC1, + MIPS_REG_HI2 = MIPS_REG_AC2, + MIPS_REG_HI3 = MIPS_REG_AC3, + + MIPS_REG_LO0 = MIPS_REG_HI0, + MIPS_REG_LO1 = MIPS_REG_HI1, + MIPS_REG_LO2 = MIPS_REG_HI2, + MIPS_REG_LO3 = MIPS_REG_HI3, +} mips_reg; + +//> MIPS instruction +typedef enum mips_insn +{ + MIPS_INS_INVALID = 0, + + MIPS_INS_ABSQ_S, + MIPS_INS_ADD, + MIPS_INS_ADDIUPC, + MIPS_INS_ADDQH, + MIPS_INS_ADDQH_R, + MIPS_INS_ADDQ, + MIPS_INS_ADDQ_S, + MIPS_INS_ADDSC, + MIPS_INS_ADDS_A, + MIPS_INS_ADDS_S, + MIPS_INS_ADDS_U, + MIPS_INS_ADDUH, + MIPS_INS_ADDUH_R, + MIPS_INS_ADDU, + MIPS_INS_ADDU_S, + MIPS_INS_ADDVI, + MIPS_INS_ADDV, + MIPS_INS_ADDWC, + MIPS_INS_ADD_A, + MIPS_INS_ADDI, + MIPS_INS_ADDIU, + MIPS_INS_ALIGN, + MIPS_INS_ALUIPC, + MIPS_INS_AND, + MIPS_INS_ANDI, + MIPS_INS_APPEND, + MIPS_INS_ASUB_S, + MIPS_INS_ASUB_U, + MIPS_INS_AUI, + MIPS_INS_AUIPC, + MIPS_INS_AVER_S, + MIPS_INS_AVER_U, + MIPS_INS_AVE_S, + MIPS_INS_AVE_U, + MIPS_INS_BADDU, + MIPS_INS_BAL, + MIPS_INS_BALC, + MIPS_INS_BALIGN, + MIPS_INS_BC, + MIPS_INS_BC0F, + MIPS_INS_BC0FL, + MIPS_INS_BC0T, + MIPS_INS_BC0TL, + MIPS_INS_BC1EQZ, + MIPS_INS_BC1F, + MIPS_INS_BC1FL, + MIPS_INS_BC1NEZ, + MIPS_INS_BC1T, + MIPS_INS_BC1TL, + MIPS_INS_BC2EQZ, + MIPS_INS_BC2F, + MIPS_INS_BC2FL, + MIPS_INS_BC2NEZ, + MIPS_INS_BC2T, + MIPS_INS_BC2TL, + MIPS_INS_BC3F, + MIPS_INS_BC3FL, + MIPS_INS_BC3T, + MIPS_INS_BC3TL, + MIPS_INS_BCLRI, + MIPS_INS_BCLR, + MIPS_INS_BEQ, + MIPS_INS_BEQC, + MIPS_INS_BEQL, + MIPS_INS_BEQZALC, + MIPS_INS_BEQZC, + MIPS_INS_BGEC, + MIPS_INS_BGEUC, + MIPS_INS_BGEZ, + MIPS_INS_BGEZAL, + MIPS_INS_BGEZALC, + MIPS_INS_BGEZALL, + MIPS_INS_BGEZALS, + MIPS_INS_BGEZC, + MIPS_INS_BGEZL, + MIPS_INS_BGTZ, + MIPS_INS_BGTZALC, + MIPS_INS_BGTZC, + MIPS_INS_BGTZL, + MIPS_INS_BINSLI, + MIPS_INS_BINSL, + MIPS_INS_BINSRI, + MIPS_INS_BINSR, + MIPS_INS_BITREV, + MIPS_INS_BITSWAP, + MIPS_INS_BLEZ, + MIPS_INS_BLEZALC, + MIPS_INS_BLEZC, + MIPS_INS_BLEZL, + MIPS_INS_BLTC, + MIPS_INS_BLTUC, + MIPS_INS_BLTZ, + MIPS_INS_BLTZAL, + MIPS_INS_BLTZALC, + MIPS_INS_BLTZALL, + MIPS_INS_BLTZALS, + MIPS_INS_BLTZC, + MIPS_INS_BLTZL, + MIPS_INS_BMNZI, + MIPS_INS_BMNZ, + MIPS_INS_BMZI, + MIPS_INS_BMZ, + MIPS_INS_BNE, + MIPS_INS_BNEC, + MIPS_INS_BNEGI, + MIPS_INS_BNEG, + MIPS_INS_BNEL, + MIPS_INS_BNEZALC, + MIPS_INS_BNEZC, + MIPS_INS_BNVC, + MIPS_INS_BNZ, + MIPS_INS_BOVC, + MIPS_INS_BPOSGE32, + MIPS_INS_BREAK, + MIPS_INS_BSELI, + MIPS_INS_BSEL, + MIPS_INS_BSETI, + MIPS_INS_BSET, + MIPS_INS_BZ, + MIPS_INS_BEQZ, + MIPS_INS_B, + MIPS_INS_BNEZ, + MIPS_INS_BTEQZ, + MIPS_INS_BTNEZ, + MIPS_INS_CACHE, + MIPS_INS_CEIL, + MIPS_INS_CEQI, + MIPS_INS_CEQ, + MIPS_INS_CFC1, + MIPS_INS_CFCMSA, + MIPS_INS_CINS, + MIPS_INS_CINS32, + MIPS_INS_CLASS, + MIPS_INS_CLEI_S, + MIPS_INS_CLEI_U, + MIPS_INS_CLE_S, + MIPS_INS_CLE_U, + MIPS_INS_CLO, + MIPS_INS_CLTI_S, + MIPS_INS_CLTI_U, + MIPS_INS_CLT_S, + MIPS_INS_CLT_U, + MIPS_INS_CLZ, + MIPS_INS_CMPGDU, + MIPS_INS_CMPGU, + MIPS_INS_CMPU, + MIPS_INS_CMP, + MIPS_INS_COPY_S, + MIPS_INS_COPY_U, + MIPS_INS_CTC1, + MIPS_INS_CTCMSA, + MIPS_INS_CVT, + MIPS_INS_C, + MIPS_INS_CMPI, + MIPS_INS_DADD, + MIPS_INS_DADDI, + MIPS_INS_DADDIU, + MIPS_INS_DADDU, + MIPS_INS_DAHI, + MIPS_INS_DALIGN, + MIPS_INS_DATI, + MIPS_INS_DAUI, + MIPS_INS_DBITSWAP, + MIPS_INS_DCLO, + MIPS_INS_DCLZ, + MIPS_INS_DDIV, + MIPS_INS_DDIVU, + MIPS_INS_DERET, + MIPS_INS_DEXT, + MIPS_INS_DEXTM, + MIPS_INS_DEXTU, + MIPS_INS_DI, + MIPS_INS_DINS, + MIPS_INS_DINSM, + MIPS_INS_DINSU, + MIPS_INS_DIV, + MIPS_INS_DIVU, + MIPS_INS_DIV_S, + MIPS_INS_DIV_U, + MIPS_INS_DLSA, + MIPS_INS_DMFC0, + MIPS_INS_DMFC1, + MIPS_INS_DMFC2, + MIPS_INS_DMOD, + MIPS_INS_DMODU, + MIPS_INS_DMTC0, + MIPS_INS_DMTC1, + MIPS_INS_DMTC2, + MIPS_INS_DMUH, + MIPS_INS_DMUHU, + MIPS_INS_DMUL, + MIPS_INS_DMULT, + MIPS_INS_DMULTU, + MIPS_INS_DMULU, + MIPS_INS_DOTP_S, + MIPS_INS_DOTP_U, + MIPS_INS_DPADD_S, + MIPS_INS_DPADD_U, + MIPS_INS_DPAQX_SA, + MIPS_INS_DPAQX_S, + MIPS_INS_DPAQ_SA, + MIPS_INS_DPAQ_S, + MIPS_INS_DPAU, + MIPS_INS_DPAX, + MIPS_INS_DPA, + MIPS_INS_DPOP, + MIPS_INS_DPSQX_SA, + MIPS_INS_DPSQX_S, + MIPS_INS_DPSQ_SA, + MIPS_INS_DPSQ_S, + MIPS_INS_DPSUB_S, + MIPS_INS_DPSUB_U, + MIPS_INS_DPSU, + MIPS_INS_DPSX, + MIPS_INS_DPS, + MIPS_INS_DROTR, + MIPS_INS_DROTR32, + MIPS_INS_DROTRV, + MIPS_INS_DSBH, + MIPS_INS_DSHD, + MIPS_INS_DSLL, + MIPS_INS_DSLL32, + MIPS_INS_DSLLV, + MIPS_INS_DSRA, + MIPS_INS_DSRA32, + MIPS_INS_DSRAV, + MIPS_INS_DSRL, + MIPS_INS_DSRL32, + MIPS_INS_DSRLV, + MIPS_INS_DSUB, + MIPS_INS_DSUBU, + MIPS_INS_EHB, + MIPS_INS_EI, + MIPS_INS_ERET, + MIPS_INS_EXT, + MIPS_INS_EXTP, + MIPS_INS_EXTPDP, + MIPS_INS_EXTPDPV, + MIPS_INS_EXTPV, + MIPS_INS_EXTRV_RS, + MIPS_INS_EXTRV_R, + MIPS_INS_EXTRV_S, + MIPS_INS_EXTRV, + MIPS_INS_EXTR_RS, + MIPS_INS_EXTR_R, + MIPS_INS_EXTR_S, + MIPS_INS_EXTR, + MIPS_INS_EXTS, + MIPS_INS_EXTS32, + MIPS_INS_ABS, + MIPS_INS_FADD, + MIPS_INS_FCAF, + MIPS_INS_FCEQ, + MIPS_INS_FCLASS, + MIPS_INS_FCLE, + MIPS_INS_FCLT, + MIPS_INS_FCNE, + MIPS_INS_FCOR, + MIPS_INS_FCUEQ, + MIPS_INS_FCULE, + MIPS_INS_FCULT, + MIPS_INS_FCUNE, + MIPS_INS_FCUN, + MIPS_INS_FDIV, + MIPS_INS_FEXDO, + MIPS_INS_FEXP2, + MIPS_INS_FEXUPL, + MIPS_INS_FEXUPR, + MIPS_INS_FFINT_S, + MIPS_INS_FFINT_U, + MIPS_INS_FFQL, + MIPS_INS_FFQR, + MIPS_INS_FILL, + MIPS_INS_FLOG2, + MIPS_INS_FLOOR, + MIPS_INS_FMADD, + MIPS_INS_FMAX_A, + MIPS_INS_FMAX, + MIPS_INS_FMIN_A, + MIPS_INS_FMIN, + MIPS_INS_MOV, + MIPS_INS_FMSUB, + MIPS_INS_FMUL, + MIPS_INS_MUL, + MIPS_INS_NEG, + MIPS_INS_FRCP, + MIPS_INS_FRINT, + MIPS_INS_FRSQRT, + MIPS_INS_FSAF, + MIPS_INS_FSEQ, + MIPS_INS_FSLE, + MIPS_INS_FSLT, + MIPS_INS_FSNE, + MIPS_INS_FSOR, + MIPS_INS_FSQRT, + MIPS_INS_SQRT, + MIPS_INS_FSUB, + MIPS_INS_SUB, + MIPS_INS_FSUEQ, + MIPS_INS_FSULE, + MIPS_INS_FSULT, + MIPS_INS_FSUNE, + MIPS_INS_FSUN, + MIPS_INS_FTINT_S, + MIPS_INS_FTINT_U, + MIPS_INS_FTQ, + MIPS_INS_FTRUNC_S, + MIPS_INS_FTRUNC_U, + MIPS_INS_HADD_S, + MIPS_INS_HADD_U, + MIPS_INS_HSUB_S, + MIPS_INS_HSUB_U, + MIPS_INS_ILVEV, + MIPS_INS_ILVL, + MIPS_INS_ILVOD, + MIPS_INS_ILVR, + MIPS_INS_INS, + MIPS_INS_INSERT, + MIPS_INS_INSV, + MIPS_INS_INSVE, + MIPS_INS_J, + MIPS_INS_JAL, + MIPS_INS_JALR, + MIPS_INS_JALRS, + MIPS_INS_JALS, + MIPS_INS_JALX, + MIPS_INS_JIALC, + MIPS_INS_JIC, + MIPS_INS_JR, + MIPS_INS_JRADDIUSP, + MIPS_INS_JRC, + MIPS_INS_JALRC, + MIPS_INS_LB, + MIPS_INS_LBUX, + MIPS_INS_LBU, + MIPS_INS_LD, + MIPS_INS_LDC1, + MIPS_INS_LDC2, + MIPS_INS_LDC3, + MIPS_INS_LDI, + MIPS_INS_LDL, + MIPS_INS_LDPC, + MIPS_INS_LDR, + MIPS_INS_LDXC1, + MIPS_INS_LH, + MIPS_INS_LHX, + MIPS_INS_LHU, + MIPS_INS_LL, + MIPS_INS_LLD, + MIPS_INS_LSA, + MIPS_INS_LUXC1, + MIPS_INS_LUI, + MIPS_INS_LW, + MIPS_INS_LWC1, + MIPS_INS_LWC2, + MIPS_INS_LWC3, + MIPS_INS_LWL, + MIPS_INS_LWPC, + MIPS_INS_LWR, + MIPS_INS_LWUPC, + MIPS_INS_LWU, + MIPS_INS_LWX, + MIPS_INS_LWXC1, + MIPS_INS_LI, + MIPS_INS_MADD, + MIPS_INS_MADDF, + MIPS_INS_MADDR_Q, + MIPS_INS_MADDU, + MIPS_INS_MADDV, + MIPS_INS_MADD_Q, + MIPS_INS_MAQ_SA, + MIPS_INS_MAQ_S, + MIPS_INS_MAXA, + MIPS_INS_MAXI_S, + MIPS_INS_MAXI_U, + MIPS_INS_MAX_A, + MIPS_INS_MAX, + MIPS_INS_MAX_S, + MIPS_INS_MAX_U, + MIPS_INS_MFC0, + MIPS_INS_MFC1, + MIPS_INS_MFC2, + MIPS_INS_MFHC1, + MIPS_INS_MFHI, + MIPS_INS_MFLO, + MIPS_INS_MINA, + MIPS_INS_MINI_S, + MIPS_INS_MINI_U, + MIPS_INS_MIN_A, + MIPS_INS_MIN, + MIPS_INS_MIN_S, + MIPS_INS_MIN_U, + MIPS_INS_MOD, + MIPS_INS_MODSUB, + MIPS_INS_MODU, + MIPS_INS_MOD_S, + MIPS_INS_MOD_U, + MIPS_INS_MOVE, + MIPS_INS_MOVF, + MIPS_INS_MOVN, + MIPS_INS_MOVT, + MIPS_INS_MOVZ, + MIPS_INS_MSUB, + MIPS_INS_MSUBF, + MIPS_INS_MSUBR_Q, + MIPS_INS_MSUBU, + MIPS_INS_MSUBV, + MIPS_INS_MSUB_Q, + MIPS_INS_MTC0, + MIPS_INS_MTC1, + MIPS_INS_MTC2, + MIPS_INS_MTHC1, + MIPS_INS_MTHI, + MIPS_INS_MTHLIP, + MIPS_INS_MTLO, + MIPS_INS_MTM0, + MIPS_INS_MTM1, + MIPS_INS_MTM2, + MIPS_INS_MTP0, + MIPS_INS_MTP1, + MIPS_INS_MTP2, + MIPS_INS_MUH, + MIPS_INS_MUHU, + MIPS_INS_MULEQ_S, + MIPS_INS_MULEU_S, + MIPS_INS_MULQ_RS, + MIPS_INS_MULQ_S, + MIPS_INS_MULR_Q, + MIPS_INS_MULSAQ_S, + MIPS_INS_MULSA, + MIPS_INS_MULT, + MIPS_INS_MULTU, + MIPS_INS_MULU, + MIPS_INS_MULV, + MIPS_INS_MUL_Q, + MIPS_INS_MUL_S, + MIPS_INS_NLOC, + MIPS_INS_NLZC, + MIPS_INS_NMADD, + MIPS_INS_NMSUB, + MIPS_INS_NOR, + MIPS_INS_NORI, + MIPS_INS_NOT, + MIPS_INS_OR, + MIPS_INS_ORI, + MIPS_INS_PACKRL, + MIPS_INS_PAUSE, + MIPS_INS_PCKEV, + MIPS_INS_PCKOD, + MIPS_INS_PCNT, + MIPS_INS_PICK, + MIPS_INS_POP, + MIPS_INS_PRECEQU, + MIPS_INS_PRECEQ, + MIPS_INS_PRECEU, + MIPS_INS_PRECRQU_S, + MIPS_INS_PRECRQ, + MIPS_INS_PRECRQ_RS, + MIPS_INS_PRECR, + MIPS_INS_PRECR_SRA, + MIPS_INS_PRECR_SRA_R, + MIPS_INS_PREF, + MIPS_INS_PREPEND, + MIPS_INS_RADDU, + MIPS_INS_RDDSP, + MIPS_INS_RDHWR, + MIPS_INS_REPLV, + MIPS_INS_REPL, + MIPS_INS_RINT, + MIPS_INS_ROTR, + MIPS_INS_ROTRV, + MIPS_INS_ROUND, + MIPS_INS_SAT_S, + MIPS_INS_SAT_U, + MIPS_INS_SB, + MIPS_INS_SC, + MIPS_INS_SCD, + MIPS_INS_SD, + MIPS_INS_SDBBP, + MIPS_INS_SDC1, + MIPS_INS_SDC2, + MIPS_INS_SDC3, + MIPS_INS_SDL, + MIPS_INS_SDR, + MIPS_INS_SDXC1, + MIPS_INS_SEB, + MIPS_INS_SEH, + MIPS_INS_SELEQZ, + MIPS_INS_SELNEZ, + MIPS_INS_SEL, + MIPS_INS_SEQ, + MIPS_INS_SEQI, + MIPS_INS_SH, + MIPS_INS_SHF, + MIPS_INS_SHILO, + MIPS_INS_SHILOV, + MIPS_INS_SHLLV, + MIPS_INS_SHLLV_S, + MIPS_INS_SHLL, + MIPS_INS_SHLL_S, + MIPS_INS_SHRAV, + MIPS_INS_SHRAV_R, + MIPS_INS_SHRA, + MIPS_INS_SHRA_R, + MIPS_INS_SHRLV, + MIPS_INS_SHRL, + MIPS_INS_SLDI, + MIPS_INS_SLD, + MIPS_INS_SLL, + MIPS_INS_SLLI, + MIPS_INS_SLLV, + MIPS_INS_SLT, + MIPS_INS_SLTI, + MIPS_INS_SLTIU, + MIPS_INS_SLTU, + MIPS_INS_SNE, + MIPS_INS_SNEI, + MIPS_INS_SPLATI, + MIPS_INS_SPLAT, + MIPS_INS_SRA, + MIPS_INS_SRAI, + MIPS_INS_SRARI, + MIPS_INS_SRAR, + MIPS_INS_SRAV, + MIPS_INS_SRL, + MIPS_INS_SRLI, + MIPS_INS_SRLRI, + MIPS_INS_SRLR, + MIPS_INS_SRLV, + MIPS_INS_SSNOP, + MIPS_INS_ST, + MIPS_INS_SUBQH, + MIPS_INS_SUBQH_R, + MIPS_INS_SUBQ, + MIPS_INS_SUBQ_S, + MIPS_INS_SUBSUS_U, + MIPS_INS_SUBSUU_S, + MIPS_INS_SUBS_S, + MIPS_INS_SUBS_U, + MIPS_INS_SUBUH, + MIPS_INS_SUBUH_R, + MIPS_INS_SUBU, + MIPS_INS_SUBU_S, + MIPS_INS_SUBVI, + MIPS_INS_SUBV, + MIPS_INS_SUXC1, + MIPS_INS_SW, + MIPS_INS_SWC1, + MIPS_INS_SWC2, + MIPS_INS_SWC3, + MIPS_INS_SWL, + MIPS_INS_SWR, + MIPS_INS_SWXC1, + MIPS_INS_SYNC, + MIPS_INS_SYSCALL, + MIPS_INS_TEQ, + MIPS_INS_TEQI, + MIPS_INS_TGE, + MIPS_INS_TGEI, + MIPS_INS_TGEIU, + MIPS_INS_TGEU, + MIPS_INS_TLBP, + MIPS_INS_TLBR, + MIPS_INS_TLBWI, + MIPS_INS_TLBWR, + MIPS_INS_TLT, + MIPS_INS_TLTI, + MIPS_INS_TLTIU, + MIPS_INS_TLTU, + MIPS_INS_TNE, + MIPS_INS_TNEI, + MIPS_INS_TRUNC, + MIPS_INS_V3MULU, + MIPS_INS_VMM0, + MIPS_INS_VMULU, + MIPS_INS_VSHF, + MIPS_INS_WAIT, + MIPS_INS_WRDSP, + MIPS_INS_WSBH, + MIPS_INS_XOR, + MIPS_INS_XORI, + + //> some alias instructions + MIPS_INS_NOP, + MIPS_INS_NEGU, + + //> special instructions + MIPS_INS_JALR_HB, // jump and link with Hazard Barrier + MIPS_INS_JR_HB, // jump register with Hazard Barrier + + MIPS_INS_ENDING, +} mips_insn; + +//> Group of MIPS instructions +typedef enum mips_insn_group +{ + MIPS_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + MIPS_GRP_JUMP, // = CS_GRP_JUMP + + //> Architecture-specific groups + MIPS_GRP_BITCOUNT = 128, + MIPS_GRP_DSP, + MIPS_GRP_DSPR2, + MIPS_GRP_FPIDX, + MIPS_GRP_MSA, + MIPS_GRP_MIPS32R2, + MIPS_GRP_MIPS64, + MIPS_GRP_MIPS64R2, + MIPS_GRP_SEINREG, + MIPS_GRP_STDENC, + MIPS_GRP_SWAP, + MIPS_GRP_MICROMIPS, + MIPS_GRP_MIPS16MODE, + MIPS_GRP_FP64BIT, + MIPS_GRP_NONANSFPMATH, + MIPS_GRP_NOTFP64BIT, + MIPS_GRP_NOTINMICROMIPS, + MIPS_GRP_NOTNACL, + MIPS_GRP_NOTMIPS32R6, + MIPS_GRP_NOTMIPS64R6, + MIPS_GRP_CNMIPS, + MIPS_GRP_MIPS32, + MIPS_GRP_MIPS32R6, + MIPS_GRP_MIPS64R6, + MIPS_GRP_MIPS2, + MIPS_GRP_MIPS3, + MIPS_GRP_MIPS3_32, + MIPS_GRP_MIPS3_32R2, + MIPS_GRP_MIPS4_32, + MIPS_GRP_MIPS4_32R2, + MIPS_GRP_MIPS5_32R2, + MIPS_GRP_GP32BIT, + MIPS_GRP_GP64BIT, + + MIPS_GRP_ENDING, +} mips_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dbg/capstone/platform.h b/src/dbg/capstone/platform.h index 1a0f07a7..92a7dace 100644 --- a/src/dbg/capstone/platform.h +++ b/src/dbg/capstone/platform.h @@ -1,28 +1,28 @@ -/* Capstone Disassembly Engine */ -/* By Axel Souchet & Nguyen Anh Quynh, 2014 */ - -// handle C99 issue (for pre-2013 VisualStudio) -#ifndef CAPSTONE_PLATFORM_H -#define CAPSTONE_PLATFORM_H - -#if !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)) -// MSVC - -// stdbool.h -#if (_MSC_VER < 1800) -#ifndef __cplusplus -typedef unsigned char bool; -#define false 0 -#define true 1 -#endif - -#else -// VisualStudio 2013+ -> C99 is supported -#include -#endif - -#else // not MSVC -> C99 is supported -#include -#endif - -#endif +/* Capstone Disassembly Engine */ +/* By Axel Souchet & Nguyen Anh Quynh, 2014 */ + +// handle C99 issue (for pre-2013 VisualStudio) +#ifndef CAPSTONE_PLATFORM_H +#define CAPSTONE_PLATFORM_H + +#if !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)) +// MSVC + +// stdbool.h +#if (_MSC_VER < 1800) +#ifndef __cplusplus +typedef unsigned char bool; +#define false 0 +#define true 1 +#endif + +#else +// VisualStudio 2013+ -> C99 is supported +#include +#endif + +#else // not MSVC -> C99 is supported +#include +#endif + +#endif diff --git a/src/dbg/capstone/ppc.h b/src/dbg/capstone/ppc.h index 5f11a25a..1c3e54c5 100644 --- a/src/dbg/capstone/ppc.h +++ b/src/dbg/capstone/ppc.h @@ -1,1261 +1,1261 @@ -#ifndef CAPSTONE_PPC_H -#define CAPSTONE_PPC_H - -/* Capstone Disassembly Engine */ -/* By Nguyen Anh Quynh , 2013-2014 */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "platform.h" - -#ifdef _MSC_VER -#pragma warning(disable:4201) -#endif - -//> PPC branch codes for some branch instructions -typedef enum ppc_bc -{ - PPC_BC_INVALID = 0, - PPC_BC_LT = (0 << 5) | 12, - PPC_BC_LE = (1 << 5) | 4, - PPC_BC_EQ = (2 << 5) | 12, - PPC_BC_GE = (0 << 5) | 4, - PPC_BC_GT = (1 << 5) | 12, - PPC_BC_NE = (2 << 5) | 4, - PPC_BC_UN = (3 << 5) | 12, - PPC_BC_NU = (3 << 5) | 4, - - // extra conditions - PPC_BC_SO = (4 << 5) | 12, // summary overflow - PPC_BC_NS = (4 << 5) | 4, // not summary overflow -} ppc_bc; - -//> PPC branch hint for some branch instructions -typedef enum ppc_bh -{ - PPC_BH_INVALID = 0, // no hint - PPC_BH_PLUS, // PLUS hint - PPC_BH_MINUS, // MINUS hint -} ppc_bh; - -//> Operand type for instruction's operands -typedef enum ppc_op_type -{ - PPC_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). - PPC_OP_REG, // = CS_OP_REG (Register operand). - PPC_OP_IMM, // = CS_OP_IMM (Immediate operand). - PPC_OP_MEM, // = CS_OP_MEM (Memory operand). - PPC_OP_CRX = 64, // Condition Register field -} ppc_op_type; - -// Instruction's operand referring to memory -// This is associated with PPC_OP_MEM operand type above -typedef struct ppc_op_mem -{ - unsigned int base; // base register - int32_t disp; // displacement/offset value -} ppc_op_mem; - -typedef struct ppc_op_crx -{ - unsigned int scale; - unsigned int reg; - ppc_bc cond; -} ppc_op_crx; - -// Instruction operand -typedef struct cs_ppc_op -{ - ppc_op_type type; // operand type - union - { - unsigned int reg; // register value for REG operand - int32_t imm; // immediate value for IMM operand - ppc_op_mem mem; // base/disp value for MEM operand - ppc_op_crx crx; // operand with condition register - }; -} cs_ppc_op; - -// Instruction structure -typedef struct cs_ppc -{ - // branch code for branch instructions - ppc_bc bc; - - // branch hint for branch instructions - ppc_bh bh; - - // if update_cr0 = True, then this 'dot' insn updates CR0 - bool update_cr0; - - // Number of operands of this instruction, - // or 0 when instruction has no operand. - uint8_t op_count; - cs_ppc_op operands[8]; // operands for this instruction. -} cs_ppc; - -//> PPC registers -typedef enum ppc_reg -{ - PPC_REG_INVALID = 0, - - PPC_REG_CARRY, - PPC_REG_CC, - PPC_REG_CR0, - PPC_REG_CR1, - PPC_REG_CR2, - PPC_REG_CR3, - PPC_REG_CR4, - PPC_REG_CR5, - PPC_REG_CR6, - PPC_REG_CR7, - PPC_REG_CTR, - PPC_REG_F0, - PPC_REG_F1, - PPC_REG_F2, - PPC_REG_F3, - PPC_REG_F4, - PPC_REG_F5, - PPC_REG_F6, - PPC_REG_F7, - PPC_REG_F8, - PPC_REG_F9, - PPC_REG_F10, - PPC_REG_F11, - PPC_REG_F12, - PPC_REG_F13, - PPC_REG_F14, - PPC_REG_F15, - PPC_REG_F16, - PPC_REG_F17, - PPC_REG_F18, - PPC_REG_F19, - PPC_REG_F20, - PPC_REG_F21, - PPC_REG_F22, - PPC_REG_F23, - PPC_REG_F24, - PPC_REG_F25, - PPC_REG_F26, - PPC_REG_F27, - PPC_REG_F28, - PPC_REG_F29, - PPC_REG_F30, - PPC_REG_F31, - PPC_REG_LR, - PPC_REG_R0, - PPC_REG_R1, - PPC_REG_R2, - PPC_REG_R3, - PPC_REG_R4, - PPC_REG_R5, - PPC_REG_R6, - PPC_REG_R7, - PPC_REG_R8, - PPC_REG_R9, - PPC_REG_R10, - PPC_REG_R11, - PPC_REG_R12, - PPC_REG_R13, - PPC_REG_R14, - PPC_REG_R15, - PPC_REG_R16, - PPC_REG_R17, - PPC_REG_R18, - PPC_REG_R19, - PPC_REG_R20, - PPC_REG_R21, - PPC_REG_R22, - PPC_REG_R23, - PPC_REG_R24, - PPC_REG_R25, - PPC_REG_R26, - PPC_REG_R27, - PPC_REG_R28, - PPC_REG_R29, - PPC_REG_R30, - PPC_REG_R31, - PPC_REG_V0, - PPC_REG_V1, - PPC_REG_V2, - PPC_REG_V3, - PPC_REG_V4, - PPC_REG_V5, - PPC_REG_V6, - PPC_REG_V7, - PPC_REG_V8, - PPC_REG_V9, - PPC_REG_V10, - PPC_REG_V11, - PPC_REG_V12, - PPC_REG_V13, - PPC_REG_V14, - PPC_REG_V15, - PPC_REG_V16, - PPC_REG_V17, - PPC_REG_V18, - PPC_REG_V19, - PPC_REG_V20, - PPC_REG_V21, - PPC_REG_V22, - PPC_REG_V23, - PPC_REG_V24, - PPC_REG_V25, - PPC_REG_V26, - PPC_REG_V27, - PPC_REG_V28, - PPC_REG_V29, - PPC_REG_V30, - PPC_REG_V31, - PPC_REG_VRSAVE, - PPC_REG_VS0, - PPC_REG_VS1, - PPC_REG_VS2, - PPC_REG_VS3, - PPC_REG_VS4, - PPC_REG_VS5, - PPC_REG_VS6, - PPC_REG_VS7, - PPC_REG_VS8, - PPC_REG_VS9, - PPC_REG_VS10, - PPC_REG_VS11, - PPC_REG_VS12, - PPC_REG_VS13, - PPC_REG_VS14, - PPC_REG_VS15, - PPC_REG_VS16, - PPC_REG_VS17, - PPC_REG_VS18, - PPC_REG_VS19, - PPC_REG_VS20, - PPC_REG_VS21, - PPC_REG_VS22, - PPC_REG_VS23, - PPC_REG_VS24, - PPC_REG_VS25, - PPC_REG_VS26, - PPC_REG_VS27, - PPC_REG_VS28, - PPC_REG_VS29, - PPC_REG_VS30, - PPC_REG_VS31, - PPC_REG_VS32, - PPC_REG_VS33, - PPC_REG_VS34, - PPC_REG_VS35, - PPC_REG_VS36, - PPC_REG_VS37, - PPC_REG_VS38, - PPC_REG_VS39, - PPC_REG_VS40, - PPC_REG_VS41, - PPC_REG_VS42, - PPC_REG_VS43, - PPC_REG_VS44, - PPC_REG_VS45, - PPC_REG_VS46, - PPC_REG_VS47, - PPC_REG_VS48, - PPC_REG_VS49, - PPC_REG_VS50, - PPC_REG_VS51, - PPC_REG_VS52, - PPC_REG_VS53, - PPC_REG_VS54, - PPC_REG_VS55, - PPC_REG_VS56, - PPC_REG_VS57, - PPC_REG_VS58, - PPC_REG_VS59, - PPC_REG_VS60, - PPC_REG_VS61, - PPC_REG_VS62, - PPC_REG_VS63, - - // extra registers for PPCMapping.c - PPC_REG_RM, - PPC_REG_CTR8, - PPC_REG_LR8, - PPC_REG_CR1EQ, - - PPC_REG_ENDING, // <-- mark the end of the list of registers -} ppc_reg; - -//> PPC instruction -typedef enum ppc_insn -{ - PPC_INS_INVALID = 0, - - PPC_INS_ADD, - PPC_INS_ADDC, - PPC_INS_ADDE, - PPC_INS_ADDI, - PPC_INS_ADDIC, - PPC_INS_ADDIS, - PPC_INS_ADDME, - PPC_INS_ADDZE, - PPC_INS_AND, - PPC_INS_ANDC, - PPC_INS_ANDIS, - PPC_INS_ANDI, - PPC_INS_B, - PPC_INS_BA, - PPC_INS_BC, - PPC_INS_BCCTR, - PPC_INS_BCCTRL, - PPC_INS_BCL, - PPC_INS_BCLR, - PPC_INS_BCLRL, - PPC_INS_BCTR, - PPC_INS_BCTRL, - PPC_INS_BDNZ, - PPC_INS_BDNZA, - PPC_INS_BDNZL, - PPC_INS_BDNZLA, - PPC_INS_BDNZLR, - PPC_INS_BDNZLRL, - PPC_INS_BDZ, - PPC_INS_BDZA, - PPC_INS_BDZL, - PPC_INS_BDZLA, - PPC_INS_BDZLR, - PPC_INS_BDZLRL, - PPC_INS_BL, - PPC_INS_BLA, - PPC_INS_BLR, - PPC_INS_BLRL, - PPC_INS_BRINC, - PPC_INS_CMPD, - PPC_INS_CMPDI, - PPC_INS_CMPLD, - PPC_INS_CMPLDI, - PPC_INS_CMPLW, - PPC_INS_CMPLWI, - PPC_INS_CMPW, - PPC_INS_CMPWI, - PPC_INS_CNTLZD, - PPC_INS_CNTLZW, - PPC_INS_CREQV, - PPC_INS_CRXOR, - PPC_INS_CRAND, - PPC_INS_CRANDC, - PPC_INS_CRNAND, - PPC_INS_CRNOR, - PPC_INS_CROR, - PPC_INS_CRORC, - PPC_INS_DCBA, - PPC_INS_DCBF, - PPC_INS_DCBI, - PPC_INS_DCBST, - PPC_INS_DCBT, - PPC_INS_DCBTST, - PPC_INS_DCBZ, - PPC_INS_DCBZL, - PPC_INS_DCCCI, - PPC_INS_DIVD, - PPC_INS_DIVDU, - PPC_INS_DIVW, - PPC_INS_DIVWU, - PPC_INS_DSS, - PPC_INS_DSSALL, - PPC_INS_DST, - PPC_INS_DSTST, - PPC_INS_DSTSTT, - PPC_INS_DSTT, - PPC_INS_EIEIO, - PPC_INS_EQV, - PPC_INS_EVABS, - PPC_INS_EVADDIW, - PPC_INS_EVADDSMIAAW, - PPC_INS_EVADDSSIAAW, - PPC_INS_EVADDUMIAAW, - PPC_INS_EVADDUSIAAW, - PPC_INS_EVADDW, - PPC_INS_EVAND, - PPC_INS_EVANDC, - PPC_INS_EVCMPEQ, - PPC_INS_EVCMPGTS, - PPC_INS_EVCMPGTU, - PPC_INS_EVCMPLTS, - PPC_INS_EVCMPLTU, - PPC_INS_EVCNTLSW, - PPC_INS_EVCNTLZW, - PPC_INS_EVDIVWS, - PPC_INS_EVDIVWU, - PPC_INS_EVEQV, - PPC_INS_EVEXTSB, - PPC_INS_EVEXTSH, - PPC_INS_EVLDD, - PPC_INS_EVLDDX, - PPC_INS_EVLDH, - PPC_INS_EVLDHX, - PPC_INS_EVLDW, - PPC_INS_EVLDWX, - PPC_INS_EVLHHESPLAT, - PPC_INS_EVLHHESPLATX, - PPC_INS_EVLHHOSSPLAT, - PPC_INS_EVLHHOSSPLATX, - PPC_INS_EVLHHOUSPLAT, - PPC_INS_EVLHHOUSPLATX, - PPC_INS_EVLWHE, - PPC_INS_EVLWHEX, - PPC_INS_EVLWHOS, - PPC_INS_EVLWHOSX, - PPC_INS_EVLWHOU, - PPC_INS_EVLWHOUX, - PPC_INS_EVLWHSPLAT, - PPC_INS_EVLWHSPLATX, - PPC_INS_EVLWWSPLAT, - PPC_INS_EVLWWSPLATX, - PPC_INS_EVMERGEHI, - PPC_INS_EVMERGEHILO, - PPC_INS_EVMERGELO, - PPC_INS_EVMERGELOHI, - PPC_INS_EVMHEGSMFAA, - PPC_INS_EVMHEGSMFAN, - PPC_INS_EVMHEGSMIAA, - PPC_INS_EVMHEGSMIAN, - PPC_INS_EVMHEGUMIAA, - PPC_INS_EVMHEGUMIAN, - PPC_INS_EVMHESMF, - PPC_INS_EVMHESMFA, - PPC_INS_EVMHESMFAAW, - PPC_INS_EVMHESMFANW, - PPC_INS_EVMHESMI, - PPC_INS_EVMHESMIA, - PPC_INS_EVMHESMIAAW, - PPC_INS_EVMHESMIANW, - PPC_INS_EVMHESSF, - PPC_INS_EVMHESSFA, - PPC_INS_EVMHESSFAAW, - PPC_INS_EVMHESSFANW, - PPC_INS_EVMHESSIAAW, - PPC_INS_EVMHESSIANW, - PPC_INS_EVMHEUMI, - PPC_INS_EVMHEUMIA, - PPC_INS_EVMHEUMIAAW, - PPC_INS_EVMHEUMIANW, - PPC_INS_EVMHEUSIAAW, - PPC_INS_EVMHEUSIANW, - PPC_INS_EVMHOGSMFAA, - PPC_INS_EVMHOGSMFAN, - PPC_INS_EVMHOGSMIAA, - PPC_INS_EVMHOGSMIAN, - PPC_INS_EVMHOGUMIAA, - PPC_INS_EVMHOGUMIAN, - PPC_INS_EVMHOSMF, - PPC_INS_EVMHOSMFA, - PPC_INS_EVMHOSMFAAW, - PPC_INS_EVMHOSMFANW, - PPC_INS_EVMHOSMI, - PPC_INS_EVMHOSMIA, - PPC_INS_EVMHOSMIAAW, - PPC_INS_EVMHOSMIANW, - PPC_INS_EVMHOSSF, - PPC_INS_EVMHOSSFA, - PPC_INS_EVMHOSSFAAW, - PPC_INS_EVMHOSSFANW, - PPC_INS_EVMHOSSIAAW, - PPC_INS_EVMHOSSIANW, - PPC_INS_EVMHOUMI, - PPC_INS_EVMHOUMIA, - PPC_INS_EVMHOUMIAAW, - PPC_INS_EVMHOUMIANW, - PPC_INS_EVMHOUSIAAW, - PPC_INS_EVMHOUSIANW, - PPC_INS_EVMRA, - PPC_INS_EVMWHSMF, - PPC_INS_EVMWHSMFA, - PPC_INS_EVMWHSMI, - PPC_INS_EVMWHSMIA, - PPC_INS_EVMWHSSF, - PPC_INS_EVMWHSSFA, - PPC_INS_EVMWHUMI, - PPC_INS_EVMWHUMIA, - PPC_INS_EVMWLSMIAAW, - PPC_INS_EVMWLSMIANW, - PPC_INS_EVMWLSSIAAW, - PPC_INS_EVMWLSSIANW, - PPC_INS_EVMWLUMI, - PPC_INS_EVMWLUMIA, - PPC_INS_EVMWLUMIAAW, - PPC_INS_EVMWLUMIANW, - PPC_INS_EVMWLUSIAAW, - PPC_INS_EVMWLUSIANW, - PPC_INS_EVMWSMF, - PPC_INS_EVMWSMFA, - PPC_INS_EVMWSMFAA, - PPC_INS_EVMWSMFAN, - PPC_INS_EVMWSMI, - PPC_INS_EVMWSMIA, - PPC_INS_EVMWSMIAA, - PPC_INS_EVMWSMIAN, - PPC_INS_EVMWSSF, - PPC_INS_EVMWSSFA, - PPC_INS_EVMWSSFAA, - PPC_INS_EVMWSSFAN, - PPC_INS_EVMWUMI, - PPC_INS_EVMWUMIA, - PPC_INS_EVMWUMIAA, - PPC_INS_EVMWUMIAN, - PPC_INS_EVNAND, - PPC_INS_EVNEG, - PPC_INS_EVNOR, - PPC_INS_EVOR, - PPC_INS_EVORC, - PPC_INS_EVRLW, - PPC_INS_EVRLWI, - PPC_INS_EVRNDW, - PPC_INS_EVSLW, - PPC_INS_EVSLWI, - PPC_INS_EVSPLATFI, - PPC_INS_EVSPLATI, - PPC_INS_EVSRWIS, - PPC_INS_EVSRWIU, - PPC_INS_EVSRWS, - PPC_INS_EVSRWU, - PPC_INS_EVSTDD, - PPC_INS_EVSTDDX, - PPC_INS_EVSTDH, - PPC_INS_EVSTDHX, - PPC_INS_EVSTDW, - PPC_INS_EVSTDWX, - PPC_INS_EVSTWHE, - PPC_INS_EVSTWHEX, - PPC_INS_EVSTWHO, - PPC_INS_EVSTWHOX, - PPC_INS_EVSTWWE, - PPC_INS_EVSTWWEX, - PPC_INS_EVSTWWO, - PPC_INS_EVSTWWOX, - PPC_INS_EVSUBFSMIAAW, - PPC_INS_EVSUBFSSIAAW, - PPC_INS_EVSUBFUMIAAW, - PPC_INS_EVSUBFUSIAAW, - PPC_INS_EVSUBFW, - PPC_INS_EVSUBIFW, - PPC_INS_EVXOR, - PPC_INS_EXTSB, - PPC_INS_EXTSH, - PPC_INS_EXTSW, - PPC_INS_FABS, - PPC_INS_FADD, - PPC_INS_FADDS, - PPC_INS_FCFID, - PPC_INS_FCFIDS, - PPC_INS_FCFIDU, - PPC_INS_FCFIDUS, - PPC_INS_FCMPU, - PPC_INS_FCPSGN, - PPC_INS_FCTID, - PPC_INS_FCTIDUZ, - PPC_INS_FCTIDZ, - PPC_INS_FCTIW, - PPC_INS_FCTIWUZ, - PPC_INS_FCTIWZ, - PPC_INS_FDIV, - PPC_INS_FDIVS, - PPC_INS_FMADD, - PPC_INS_FMADDS, - PPC_INS_FMR, - PPC_INS_FMSUB, - PPC_INS_FMSUBS, - PPC_INS_FMUL, - PPC_INS_FMULS, - PPC_INS_FNABS, - PPC_INS_FNEG, - PPC_INS_FNMADD, - PPC_INS_FNMADDS, - PPC_INS_FNMSUB, - PPC_INS_FNMSUBS, - PPC_INS_FRE, - PPC_INS_FRES, - PPC_INS_FRIM, - PPC_INS_FRIN, - PPC_INS_FRIP, - PPC_INS_FRIZ, - PPC_INS_FRSP, - PPC_INS_FRSQRTE, - PPC_INS_FRSQRTES, - PPC_INS_FSEL, - PPC_INS_FSQRT, - PPC_INS_FSQRTS, - PPC_INS_FSUB, - PPC_INS_FSUBS, - PPC_INS_ICBI, - PPC_INS_ICCCI, - PPC_INS_ISEL, - PPC_INS_ISYNC, - PPC_INS_LA, - PPC_INS_LBZ, - PPC_INS_LBZU, - PPC_INS_LBZUX, - PPC_INS_LBZX, - PPC_INS_LD, - PPC_INS_LDARX, - PPC_INS_LDBRX, - PPC_INS_LDU, - PPC_INS_LDUX, - PPC_INS_LDX, - PPC_INS_LFD, - PPC_INS_LFDU, - PPC_INS_LFDUX, - PPC_INS_LFDX, - PPC_INS_LFIWAX, - PPC_INS_LFIWZX, - PPC_INS_LFS, - PPC_INS_LFSU, - PPC_INS_LFSUX, - PPC_INS_LFSX, - PPC_INS_LHA, - PPC_INS_LHAU, - PPC_INS_LHAUX, - PPC_INS_LHAX, - PPC_INS_LHBRX, - PPC_INS_LHZ, - PPC_INS_LHZU, - PPC_INS_LHZUX, - PPC_INS_LHZX, - PPC_INS_LI, - PPC_INS_LIS, - PPC_INS_LMW, - PPC_INS_LSWI, - PPC_INS_LVEBX, - PPC_INS_LVEHX, - PPC_INS_LVEWX, - PPC_INS_LVSL, - PPC_INS_LVSR, - PPC_INS_LVX, - PPC_INS_LVXL, - PPC_INS_LWA, - PPC_INS_LWARX, - PPC_INS_LWAUX, - PPC_INS_LWAX, - PPC_INS_LWBRX, - PPC_INS_LWZ, - PPC_INS_LWZU, - PPC_INS_LWZUX, - PPC_INS_LWZX, - PPC_INS_LXSDX, - PPC_INS_LXVD2X, - PPC_INS_LXVDSX, - PPC_INS_LXVW4X, - PPC_INS_MBAR, - PPC_INS_MCRF, - PPC_INS_MFCR, - PPC_INS_MFCTR, - PPC_INS_MFDCR, - PPC_INS_MFFS, - PPC_INS_MFLR, - PPC_INS_MFMSR, - PPC_INS_MFOCRF, - PPC_INS_MFSPR, - PPC_INS_MFSR, - PPC_INS_MFSRIN, - PPC_INS_MFTB, - PPC_INS_MFVSCR, - PPC_INS_MSYNC, - PPC_INS_MTCRF, - PPC_INS_MTCTR, - PPC_INS_MTDCR, - PPC_INS_MTFSB0, - PPC_INS_MTFSB1, - PPC_INS_MTFSF, - PPC_INS_MTLR, - PPC_INS_MTMSR, - PPC_INS_MTMSRD, - PPC_INS_MTOCRF, - PPC_INS_MTSPR, - PPC_INS_MTSR, - PPC_INS_MTSRIN, - PPC_INS_MTVSCR, - PPC_INS_MULHD, - PPC_INS_MULHDU, - PPC_INS_MULHW, - PPC_INS_MULHWU, - PPC_INS_MULLD, - PPC_INS_MULLI, - PPC_INS_MULLW, - PPC_INS_NAND, - PPC_INS_NEG, - PPC_INS_NOP, - PPC_INS_ORI, - PPC_INS_NOR, - PPC_INS_OR, - PPC_INS_ORC, - PPC_INS_ORIS, - PPC_INS_POPCNTD, - PPC_INS_POPCNTW, - PPC_INS_RFCI, - PPC_INS_RFDI, - PPC_INS_RFI, - PPC_INS_RFID, - PPC_INS_RFMCI, - PPC_INS_RLDCL, - PPC_INS_RLDCR, - PPC_INS_RLDIC, - PPC_INS_RLDICL, - PPC_INS_RLDICR, - PPC_INS_RLDIMI, - PPC_INS_RLWIMI, - PPC_INS_RLWINM, - PPC_INS_RLWNM, - PPC_INS_SC, - PPC_INS_SLBIA, - PPC_INS_SLBIE, - PPC_INS_SLBMFEE, - PPC_INS_SLBMTE, - PPC_INS_SLD, - PPC_INS_SLW, - PPC_INS_SRAD, - PPC_INS_SRADI, - PPC_INS_SRAW, - PPC_INS_SRAWI, - PPC_INS_SRD, - PPC_INS_SRW, - PPC_INS_STB, - PPC_INS_STBU, - PPC_INS_STBUX, - PPC_INS_STBX, - PPC_INS_STD, - PPC_INS_STDBRX, - PPC_INS_STDCX, - PPC_INS_STDU, - PPC_INS_STDUX, - PPC_INS_STDX, - PPC_INS_STFD, - PPC_INS_STFDU, - PPC_INS_STFDUX, - PPC_INS_STFDX, - PPC_INS_STFIWX, - PPC_INS_STFS, - PPC_INS_STFSU, - PPC_INS_STFSUX, - PPC_INS_STFSX, - PPC_INS_STH, - PPC_INS_STHBRX, - PPC_INS_STHU, - PPC_INS_STHUX, - PPC_INS_STHX, - PPC_INS_STMW, - PPC_INS_STSWI, - PPC_INS_STVEBX, - PPC_INS_STVEHX, - PPC_INS_STVEWX, - PPC_INS_STVX, - PPC_INS_STVXL, - PPC_INS_STW, - PPC_INS_STWBRX, - PPC_INS_STWCX, - PPC_INS_STWU, - PPC_INS_STWUX, - PPC_INS_STWX, - PPC_INS_STXSDX, - PPC_INS_STXVD2X, - PPC_INS_STXVW4X, - PPC_INS_SUBF, - PPC_INS_SUBFC, - PPC_INS_SUBFE, - PPC_INS_SUBFIC, - PPC_INS_SUBFME, - PPC_INS_SUBFZE, - PPC_INS_SYNC, - PPC_INS_TD, - PPC_INS_TDI, - PPC_INS_TLBIA, - PPC_INS_TLBIE, - PPC_INS_TLBIEL, - PPC_INS_TLBIVAX, - PPC_INS_TLBLD, - PPC_INS_TLBLI, - PPC_INS_TLBRE, - PPC_INS_TLBSX, - PPC_INS_TLBSYNC, - PPC_INS_TLBWE, - PPC_INS_TRAP, - PPC_INS_TW, - PPC_INS_TWI, - PPC_INS_VADDCUW, - PPC_INS_VADDFP, - PPC_INS_VADDSBS, - PPC_INS_VADDSHS, - PPC_INS_VADDSWS, - PPC_INS_VADDUBM, - PPC_INS_VADDUBS, - PPC_INS_VADDUHM, - PPC_INS_VADDUHS, - PPC_INS_VADDUWM, - PPC_INS_VADDUWS, - PPC_INS_VAND, - PPC_INS_VANDC, - PPC_INS_VAVGSB, - PPC_INS_VAVGSH, - PPC_INS_VAVGSW, - PPC_INS_VAVGUB, - PPC_INS_VAVGUH, - PPC_INS_VAVGUW, - PPC_INS_VCFSX, - PPC_INS_VCFUX, - PPC_INS_VCMPBFP, - PPC_INS_VCMPEQFP, - PPC_INS_VCMPEQUB, - PPC_INS_VCMPEQUH, - PPC_INS_VCMPEQUW, - PPC_INS_VCMPGEFP, - PPC_INS_VCMPGTFP, - PPC_INS_VCMPGTSB, - PPC_INS_VCMPGTSH, - PPC_INS_VCMPGTSW, - PPC_INS_VCMPGTUB, - PPC_INS_VCMPGTUH, - PPC_INS_VCMPGTUW, - PPC_INS_VCTSXS, - PPC_INS_VCTUXS, - PPC_INS_VEXPTEFP, - PPC_INS_VLOGEFP, - PPC_INS_VMADDFP, - PPC_INS_VMAXFP, - PPC_INS_VMAXSB, - PPC_INS_VMAXSH, - PPC_INS_VMAXSW, - PPC_INS_VMAXUB, - PPC_INS_VMAXUH, - PPC_INS_VMAXUW, - PPC_INS_VMHADDSHS, - PPC_INS_VMHRADDSHS, - PPC_INS_VMINFP, - PPC_INS_VMINSB, - PPC_INS_VMINSH, - PPC_INS_VMINSW, - PPC_INS_VMINUB, - PPC_INS_VMINUH, - PPC_INS_VMINUW, - PPC_INS_VMLADDUHM, - PPC_INS_VMRGHB, - PPC_INS_VMRGHH, - PPC_INS_VMRGHW, - PPC_INS_VMRGLB, - PPC_INS_VMRGLH, - PPC_INS_VMRGLW, - PPC_INS_VMSUMMBM, - PPC_INS_VMSUMSHM, - PPC_INS_VMSUMSHS, - PPC_INS_VMSUMUBM, - PPC_INS_VMSUMUHM, - PPC_INS_VMSUMUHS, - PPC_INS_VMULESB, - PPC_INS_VMULESH, - PPC_INS_VMULEUB, - PPC_INS_VMULEUH, - PPC_INS_VMULOSB, - PPC_INS_VMULOSH, - PPC_INS_VMULOUB, - PPC_INS_VMULOUH, - PPC_INS_VNMSUBFP, - PPC_INS_VNOR, - PPC_INS_VOR, - PPC_INS_VPERM, - PPC_INS_VPKPX, - PPC_INS_VPKSHSS, - PPC_INS_VPKSHUS, - PPC_INS_VPKSWSS, - PPC_INS_VPKSWUS, - PPC_INS_VPKUHUM, - PPC_INS_VPKUHUS, - PPC_INS_VPKUWUM, - PPC_INS_VPKUWUS, - PPC_INS_VREFP, - PPC_INS_VRFIM, - PPC_INS_VRFIN, - PPC_INS_VRFIP, - PPC_INS_VRFIZ, - PPC_INS_VRLB, - PPC_INS_VRLH, - PPC_INS_VRLW, - PPC_INS_VRSQRTEFP, - PPC_INS_VSEL, - PPC_INS_VSL, - PPC_INS_VSLB, - PPC_INS_VSLDOI, - PPC_INS_VSLH, - PPC_INS_VSLO, - PPC_INS_VSLW, - PPC_INS_VSPLTB, - PPC_INS_VSPLTH, - PPC_INS_VSPLTISB, - PPC_INS_VSPLTISH, - PPC_INS_VSPLTISW, - PPC_INS_VSPLTW, - PPC_INS_VSR, - PPC_INS_VSRAB, - PPC_INS_VSRAH, - PPC_INS_VSRAW, - PPC_INS_VSRB, - PPC_INS_VSRH, - PPC_INS_VSRO, - PPC_INS_VSRW, - PPC_INS_VSUBCUW, - PPC_INS_VSUBFP, - PPC_INS_VSUBSBS, - PPC_INS_VSUBSHS, - PPC_INS_VSUBSWS, - PPC_INS_VSUBUBM, - PPC_INS_VSUBUBS, - PPC_INS_VSUBUHM, - PPC_INS_VSUBUHS, - PPC_INS_VSUBUWM, - PPC_INS_VSUBUWS, - PPC_INS_VSUM2SWS, - PPC_INS_VSUM4SBS, - PPC_INS_VSUM4SHS, - PPC_INS_VSUM4UBS, - PPC_INS_VSUMSWS, - PPC_INS_VUPKHPX, - PPC_INS_VUPKHSB, - PPC_INS_VUPKHSH, - PPC_INS_VUPKLPX, - PPC_INS_VUPKLSB, - PPC_INS_VUPKLSH, - PPC_INS_VXOR, - PPC_INS_WAIT, - PPC_INS_WRTEE, - PPC_INS_WRTEEI, - PPC_INS_XOR, - PPC_INS_XORI, - PPC_INS_XORIS, - PPC_INS_XSABSDP, - PPC_INS_XSADDDP, - PPC_INS_XSCMPODP, - PPC_INS_XSCMPUDP, - PPC_INS_XSCPSGNDP, - PPC_INS_XSCVDPSP, - PPC_INS_XSCVDPSXDS, - PPC_INS_XSCVDPSXWS, - PPC_INS_XSCVDPUXDS, - PPC_INS_XSCVDPUXWS, - PPC_INS_XSCVSPDP, - PPC_INS_XSCVSXDDP, - PPC_INS_XSCVUXDDP, - PPC_INS_XSDIVDP, - PPC_INS_XSMADDADP, - PPC_INS_XSMADDMDP, - PPC_INS_XSMAXDP, - PPC_INS_XSMINDP, - PPC_INS_XSMSUBADP, - PPC_INS_XSMSUBMDP, - PPC_INS_XSMULDP, - PPC_INS_XSNABSDP, - PPC_INS_XSNEGDP, - PPC_INS_XSNMADDADP, - PPC_INS_XSNMADDMDP, - PPC_INS_XSNMSUBADP, - PPC_INS_XSNMSUBMDP, - PPC_INS_XSRDPI, - PPC_INS_XSRDPIC, - PPC_INS_XSRDPIM, - PPC_INS_XSRDPIP, - PPC_INS_XSRDPIZ, - PPC_INS_XSREDP, - PPC_INS_XSRSQRTEDP, - PPC_INS_XSSQRTDP, - PPC_INS_XSSUBDP, - PPC_INS_XSTDIVDP, - PPC_INS_XSTSQRTDP, - PPC_INS_XVABSDP, - PPC_INS_XVABSSP, - PPC_INS_XVADDDP, - PPC_INS_XVADDSP, - PPC_INS_XVCMPEQDP, - PPC_INS_XVCMPEQSP, - PPC_INS_XVCMPGEDP, - PPC_INS_XVCMPGESP, - PPC_INS_XVCMPGTDP, - PPC_INS_XVCMPGTSP, - PPC_INS_XVCPSGNDP, - PPC_INS_XVCPSGNSP, - PPC_INS_XVCVDPSP, - PPC_INS_XVCVDPSXDS, - PPC_INS_XVCVDPSXWS, - PPC_INS_XVCVDPUXDS, - PPC_INS_XVCVDPUXWS, - PPC_INS_XVCVSPDP, - PPC_INS_XVCVSPSXDS, - PPC_INS_XVCVSPSXWS, - PPC_INS_XVCVSPUXDS, - PPC_INS_XVCVSPUXWS, - PPC_INS_XVCVSXDDP, - PPC_INS_XVCVSXDSP, - PPC_INS_XVCVSXWDP, - PPC_INS_XVCVSXWSP, - PPC_INS_XVCVUXDDP, - PPC_INS_XVCVUXDSP, - PPC_INS_XVCVUXWDP, - PPC_INS_XVCVUXWSP, - PPC_INS_XVDIVDP, - PPC_INS_XVDIVSP, - PPC_INS_XVMADDADP, - PPC_INS_XVMADDASP, - PPC_INS_XVMADDMDP, - PPC_INS_XVMADDMSP, - PPC_INS_XVMAXDP, - PPC_INS_XVMAXSP, - PPC_INS_XVMINDP, - PPC_INS_XVMINSP, - PPC_INS_XVMSUBADP, - PPC_INS_XVMSUBASP, - PPC_INS_XVMSUBMDP, - PPC_INS_XVMSUBMSP, - PPC_INS_XVMULDP, - PPC_INS_XVMULSP, - PPC_INS_XVNABSDP, - PPC_INS_XVNABSSP, - PPC_INS_XVNEGDP, - PPC_INS_XVNEGSP, - PPC_INS_XVNMADDADP, - PPC_INS_XVNMADDASP, - PPC_INS_XVNMADDMDP, - PPC_INS_XVNMADDMSP, - PPC_INS_XVNMSUBADP, - PPC_INS_XVNMSUBASP, - PPC_INS_XVNMSUBMDP, - PPC_INS_XVNMSUBMSP, - PPC_INS_XVRDPI, - PPC_INS_XVRDPIC, - PPC_INS_XVRDPIM, - PPC_INS_XVRDPIP, - PPC_INS_XVRDPIZ, - PPC_INS_XVREDP, - PPC_INS_XVRESP, - PPC_INS_XVRSPI, - PPC_INS_XVRSPIC, - PPC_INS_XVRSPIM, - PPC_INS_XVRSPIP, - PPC_INS_XVRSPIZ, - PPC_INS_XVRSQRTEDP, - PPC_INS_XVRSQRTESP, - PPC_INS_XVSQRTDP, - PPC_INS_XVSQRTSP, - PPC_INS_XVSUBDP, - PPC_INS_XVSUBSP, - PPC_INS_XVTDIVDP, - PPC_INS_XVTDIVSP, - PPC_INS_XVTSQRTDP, - PPC_INS_XVTSQRTSP, - PPC_INS_XXLAND, - PPC_INS_XXLANDC, - PPC_INS_XXLNOR, - PPC_INS_XXLOR, - PPC_INS_XXLXOR, - PPC_INS_XXMRGHW, - PPC_INS_XXMRGLW, - PPC_INS_XXPERMDI, - PPC_INS_XXSEL, - PPC_INS_XXSLDWI, - PPC_INS_XXSPLTW, - PPC_INS_BCA, - PPC_INS_BCLA, - - // extra & alias instructions - PPC_INS_SLWI, - PPC_INS_SRWI, - PPC_INS_SLDI, - - PPC_INS_BTA, - PPC_INS_CRSET, - PPC_INS_CRNOT, - PPC_INS_CRMOVE, - PPC_INS_CRCLR, - PPC_INS_MFBR0, - PPC_INS_MFBR1, - PPC_INS_MFBR2, - PPC_INS_MFBR3, - PPC_INS_MFBR4, - PPC_INS_MFBR5, - PPC_INS_MFBR6, - PPC_INS_MFBR7, - PPC_INS_MFXER, - PPC_INS_MFRTCU, - PPC_INS_MFRTCL, - PPC_INS_MFDSCR, - PPC_INS_MFDSISR, - PPC_INS_MFDAR, - PPC_INS_MFSRR2, - PPC_INS_MFSRR3, - PPC_INS_MFCFAR, - PPC_INS_MFAMR, - PPC_INS_MFPID, - PPC_INS_MFTBLO, - PPC_INS_MFTBHI, - PPC_INS_MFDBATU, - PPC_INS_MFDBATL, - PPC_INS_MFIBATU, - PPC_INS_MFIBATL, - PPC_INS_MFDCCR, - PPC_INS_MFICCR, - PPC_INS_MFDEAR, - PPC_INS_MFESR, - PPC_INS_MFSPEFSCR, - PPC_INS_MFTCR, - PPC_INS_MFASR, - PPC_INS_MFPVR, - PPC_INS_MFTBU, - PPC_INS_MTCR, - PPC_INS_MTBR0, - PPC_INS_MTBR1, - PPC_INS_MTBR2, - PPC_INS_MTBR3, - PPC_INS_MTBR4, - PPC_INS_MTBR5, - PPC_INS_MTBR6, - PPC_INS_MTBR7, - PPC_INS_MTXER, - PPC_INS_MTDSCR, - PPC_INS_MTDSISR, - PPC_INS_MTDAR, - PPC_INS_MTSRR2, - PPC_INS_MTSRR3, - PPC_INS_MTCFAR, - PPC_INS_MTAMR, - PPC_INS_MTPID, - PPC_INS_MTTBL, - PPC_INS_MTTBU, - PPC_INS_MTTBLO, - PPC_INS_MTTBHI, - PPC_INS_MTDBATU, - PPC_INS_MTDBATL, - PPC_INS_MTIBATU, - PPC_INS_MTIBATL, - PPC_INS_MTDCCR, - PPC_INS_MTICCR, - PPC_INS_MTDEAR, - PPC_INS_MTESR, - PPC_INS_MTSPEFSCR, - PPC_INS_MTTCR, - PPC_INS_NOT, - PPC_INS_MR, - PPC_INS_ROTLD, - PPC_INS_ROTLDI, - PPC_INS_CLRLDI, - PPC_INS_ROTLWI, - PPC_INS_CLRLWI, - PPC_INS_ROTLW, - PPC_INS_SUB, - PPC_INS_SUBC, - PPC_INS_LWSYNC, - PPC_INS_PTESYNC, - PPC_INS_TDLT, - PPC_INS_TDEQ, - PPC_INS_TDGT, - PPC_INS_TDNE, - PPC_INS_TDLLT, - PPC_INS_TDLGT, - PPC_INS_TDU, - PPC_INS_TDLTI, - PPC_INS_TDEQI, - PPC_INS_TDGTI, - PPC_INS_TDNEI, - PPC_INS_TDLLTI, - PPC_INS_TDLGTI, - PPC_INS_TDUI, - PPC_INS_TLBREHI, - PPC_INS_TLBRELO, - PPC_INS_TLBWEHI, - PPC_INS_TLBWELO, - PPC_INS_TWLT, - PPC_INS_TWEQ, - PPC_INS_TWGT, - PPC_INS_TWNE, - PPC_INS_TWLLT, - PPC_INS_TWLGT, - PPC_INS_TWU, - PPC_INS_TWLTI, - PPC_INS_TWEQI, - PPC_INS_TWGTI, - PPC_INS_TWNEI, - PPC_INS_TWLLTI, - PPC_INS_TWLGTI, - PPC_INS_TWUI, - PPC_INS_WAITRSV, - PPC_INS_WAITIMPL, - PPC_INS_XNOP, - PPC_INS_XVMOVDP, - PPC_INS_XVMOVSP, - PPC_INS_XXSPLTD, - PPC_INS_XXMRGHD, - PPC_INS_XXMRGLD, - PPC_INS_XXSWAPD, - PPC_INS_BT, - PPC_INS_BF, - PPC_INS_BDNZT, - PPC_INS_BDNZF, - PPC_INS_BDZF, - PPC_INS_BDZT, - PPC_INS_BFA, - PPC_INS_BDNZTA, - PPC_INS_BDNZFA, - PPC_INS_BDZTA, - PPC_INS_BDZFA, - PPC_INS_BTCTR, - PPC_INS_BFCTR, - PPC_INS_BTCTRL, - PPC_INS_BFCTRL, - PPC_INS_BTL, - PPC_INS_BFL, - PPC_INS_BDNZTL, - PPC_INS_BDNZFL, - PPC_INS_BDZTL, - PPC_INS_BDZFL, - PPC_INS_BTLA, - PPC_INS_BFLA, - PPC_INS_BDNZTLA, - PPC_INS_BDNZFLA, - PPC_INS_BDZTLA, - PPC_INS_BDZFLA, - PPC_INS_BTLR, - PPC_INS_BFLR, - PPC_INS_BDNZTLR, - PPC_INS_BDZTLR, - PPC_INS_BDZFLR, - PPC_INS_BTLRL, - PPC_INS_BFLRL, - PPC_INS_BDNZTLRL, - PPC_INS_BDNZFLRL, - PPC_INS_BDZTLRL, - PPC_INS_BDZFLRL, - - PPC_INS_ENDING, // <-- mark the end of the list of instructions -} ppc_insn; - -//> Group of PPC instructions -typedef enum ppc_insn_group -{ - PPC_GRP_INVALID = 0, // = CS_GRP_INVALID - - //> Generic groups - // all jump instructions (conditional+direct+indirect jumps) - PPC_GRP_JUMP, // = CS_GRP_JUMP - - //> Architecture-specific groups - PPC_GRP_ALTIVEC = 128, - PPC_GRP_MODE32, - PPC_GRP_MODE64, - PPC_GRP_BOOKE, - PPC_GRP_NOTBOOKE, - PPC_GRP_SPE, - PPC_GRP_VSX, - PPC_GRP_E500, - PPC_GRP_PPC4XX, - PPC_GRP_PPC6XX, - - PPC_GRP_ENDING, // <-- mark the end of the list of groups -} ppc_insn_group; - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef CAPSTONE_PPC_H +#define CAPSTONE_PPC_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "platform.h" + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> PPC branch codes for some branch instructions +typedef enum ppc_bc +{ + PPC_BC_INVALID = 0, + PPC_BC_LT = (0 << 5) | 12, + PPC_BC_LE = (1 << 5) | 4, + PPC_BC_EQ = (2 << 5) | 12, + PPC_BC_GE = (0 << 5) | 4, + PPC_BC_GT = (1 << 5) | 12, + PPC_BC_NE = (2 << 5) | 4, + PPC_BC_UN = (3 << 5) | 12, + PPC_BC_NU = (3 << 5) | 4, + + // extra conditions + PPC_BC_SO = (4 << 5) | 12, // summary overflow + PPC_BC_NS = (4 << 5) | 4, // not summary overflow +} ppc_bc; + +//> PPC branch hint for some branch instructions +typedef enum ppc_bh +{ + PPC_BH_INVALID = 0, // no hint + PPC_BH_PLUS, // PLUS hint + PPC_BH_MINUS, // MINUS hint +} ppc_bh; + +//> Operand type for instruction's operands +typedef enum ppc_op_type +{ + PPC_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + PPC_OP_REG, // = CS_OP_REG (Register operand). + PPC_OP_IMM, // = CS_OP_IMM (Immediate operand). + PPC_OP_MEM, // = CS_OP_MEM (Memory operand). + PPC_OP_CRX = 64, // Condition Register field +} ppc_op_type; + +// Instruction's operand referring to memory +// This is associated with PPC_OP_MEM operand type above +typedef struct ppc_op_mem +{ + unsigned int base; // base register + int32_t disp; // displacement/offset value +} ppc_op_mem; + +typedef struct ppc_op_crx +{ + unsigned int scale; + unsigned int reg; + ppc_bc cond; +} ppc_op_crx; + +// Instruction operand +typedef struct cs_ppc_op +{ + ppc_op_type type; // operand type + union + { + unsigned int reg; // register value for REG operand + int32_t imm; // immediate value for IMM operand + ppc_op_mem mem; // base/disp value for MEM operand + ppc_op_crx crx; // operand with condition register + }; +} cs_ppc_op; + +// Instruction structure +typedef struct cs_ppc +{ + // branch code for branch instructions + ppc_bc bc; + + // branch hint for branch instructions + ppc_bh bh; + + // if update_cr0 = True, then this 'dot' insn updates CR0 + bool update_cr0; + + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + cs_ppc_op operands[8]; // operands for this instruction. +} cs_ppc; + +//> PPC registers +typedef enum ppc_reg +{ + PPC_REG_INVALID = 0, + + PPC_REG_CARRY, + PPC_REG_CC, + PPC_REG_CR0, + PPC_REG_CR1, + PPC_REG_CR2, + PPC_REG_CR3, + PPC_REG_CR4, + PPC_REG_CR5, + PPC_REG_CR6, + PPC_REG_CR7, + PPC_REG_CTR, + PPC_REG_F0, + PPC_REG_F1, + PPC_REG_F2, + PPC_REG_F3, + PPC_REG_F4, + PPC_REG_F5, + PPC_REG_F6, + PPC_REG_F7, + PPC_REG_F8, + PPC_REG_F9, + PPC_REG_F10, + PPC_REG_F11, + PPC_REG_F12, + PPC_REG_F13, + PPC_REG_F14, + PPC_REG_F15, + PPC_REG_F16, + PPC_REG_F17, + PPC_REG_F18, + PPC_REG_F19, + PPC_REG_F20, + PPC_REG_F21, + PPC_REG_F22, + PPC_REG_F23, + PPC_REG_F24, + PPC_REG_F25, + PPC_REG_F26, + PPC_REG_F27, + PPC_REG_F28, + PPC_REG_F29, + PPC_REG_F30, + PPC_REG_F31, + PPC_REG_LR, + PPC_REG_R0, + PPC_REG_R1, + PPC_REG_R2, + PPC_REG_R3, + PPC_REG_R4, + PPC_REG_R5, + PPC_REG_R6, + PPC_REG_R7, + PPC_REG_R8, + PPC_REG_R9, + PPC_REG_R10, + PPC_REG_R11, + PPC_REG_R12, + PPC_REG_R13, + PPC_REG_R14, + PPC_REG_R15, + PPC_REG_R16, + PPC_REG_R17, + PPC_REG_R18, + PPC_REG_R19, + PPC_REG_R20, + PPC_REG_R21, + PPC_REG_R22, + PPC_REG_R23, + PPC_REG_R24, + PPC_REG_R25, + PPC_REG_R26, + PPC_REG_R27, + PPC_REG_R28, + PPC_REG_R29, + PPC_REG_R30, + PPC_REG_R31, + PPC_REG_V0, + PPC_REG_V1, + PPC_REG_V2, + PPC_REG_V3, + PPC_REG_V4, + PPC_REG_V5, + PPC_REG_V6, + PPC_REG_V7, + PPC_REG_V8, + PPC_REG_V9, + PPC_REG_V10, + PPC_REG_V11, + PPC_REG_V12, + PPC_REG_V13, + PPC_REG_V14, + PPC_REG_V15, + PPC_REG_V16, + PPC_REG_V17, + PPC_REG_V18, + PPC_REG_V19, + PPC_REG_V20, + PPC_REG_V21, + PPC_REG_V22, + PPC_REG_V23, + PPC_REG_V24, + PPC_REG_V25, + PPC_REG_V26, + PPC_REG_V27, + PPC_REG_V28, + PPC_REG_V29, + PPC_REG_V30, + PPC_REG_V31, + PPC_REG_VRSAVE, + PPC_REG_VS0, + PPC_REG_VS1, + PPC_REG_VS2, + PPC_REG_VS3, + PPC_REG_VS4, + PPC_REG_VS5, + PPC_REG_VS6, + PPC_REG_VS7, + PPC_REG_VS8, + PPC_REG_VS9, + PPC_REG_VS10, + PPC_REG_VS11, + PPC_REG_VS12, + PPC_REG_VS13, + PPC_REG_VS14, + PPC_REG_VS15, + PPC_REG_VS16, + PPC_REG_VS17, + PPC_REG_VS18, + PPC_REG_VS19, + PPC_REG_VS20, + PPC_REG_VS21, + PPC_REG_VS22, + PPC_REG_VS23, + PPC_REG_VS24, + PPC_REG_VS25, + PPC_REG_VS26, + PPC_REG_VS27, + PPC_REG_VS28, + PPC_REG_VS29, + PPC_REG_VS30, + PPC_REG_VS31, + PPC_REG_VS32, + PPC_REG_VS33, + PPC_REG_VS34, + PPC_REG_VS35, + PPC_REG_VS36, + PPC_REG_VS37, + PPC_REG_VS38, + PPC_REG_VS39, + PPC_REG_VS40, + PPC_REG_VS41, + PPC_REG_VS42, + PPC_REG_VS43, + PPC_REG_VS44, + PPC_REG_VS45, + PPC_REG_VS46, + PPC_REG_VS47, + PPC_REG_VS48, + PPC_REG_VS49, + PPC_REG_VS50, + PPC_REG_VS51, + PPC_REG_VS52, + PPC_REG_VS53, + PPC_REG_VS54, + PPC_REG_VS55, + PPC_REG_VS56, + PPC_REG_VS57, + PPC_REG_VS58, + PPC_REG_VS59, + PPC_REG_VS60, + PPC_REG_VS61, + PPC_REG_VS62, + PPC_REG_VS63, + + // extra registers for PPCMapping.c + PPC_REG_RM, + PPC_REG_CTR8, + PPC_REG_LR8, + PPC_REG_CR1EQ, + + PPC_REG_ENDING, // <-- mark the end of the list of registers +} ppc_reg; + +//> PPC instruction +typedef enum ppc_insn +{ + PPC_INS_INVALID = 0, + + PPC_INS_ADD, + PPC_INS_ADDC, + PPC_INS_ADDE, + PPC_INS_ADDI, + PPC_INS_ADDIC, + PPC_INS_ADDIS, + PPC_INS_ADDME, + PPC_INS_ADDZE, + PPC_INS_AND, + PPC_INS_ANDC, + PPC_INS_ANDIS, + PPC_INS_ANDI, + PPC_INS_B, + PPC_INS_BA, + PPC_INS_BC, + PPC_INS_BCCTR, + PPC_INS_BCCTRL, + PPC_INS_BCL, + PPC_INS_BCLR, + PPC_INS_BCLRL, + PPC_INS_BCTR, + PPC_INS_BCTRL, + PPC_INS_BDNZ, + PPC_INS_BDNZA, + PPC_INS_BDNZL, + PPC_INS_BDNZLA, + PPC_INS_BDNZLR, + PPC_INS_BDNZLRL, + PPC_INS_BDZ, + PPC_INS_BDZA, + PPC_INS_BDZL, + PPC_INS_BDZLA, + PPC_INS_BDZLR, + PPC_INS_BDZLRL, + PPC_INS_BL, + PPC_INS_BLA, + PPC_INS_BLR, + PPC_INS_BLRL, + PPC_INS_BRINC, + PPC_INS_CMPD, + PPC_INS_CMPDI, + PPC_INS_CMPLD, + PPC_INS_CMPLDI, + PPC_INS_CMPLW, + PPC_INS_CMPLWI, + PPC_INS_CMPW, + PPC_INS_CMPWI, + PPC_INS_CNTLZD, + PPC_INS_CNTLZW, + PPC_INS_CREQV, + PPC_INS_CRXOR, + PPC_INS_CRAND, + PPC_INS_CRANDC, + PPC_INS_CRNAND, + PPC_INS_CRNOR, + PPC_INS_CROR, + PPC_INS_CRORC, + PPC_INS_DCBA, + PPC_INS_DCBF, + PPC_INS_DCBI, + PPC_INS_DCBST, + PPC_INS_DCBT, + PPC_INS_DCBTST, + PPC_INS_DCBZ, + PPC_INS_DCBZL, + PPC_INS_DCCCI, + PPC_INS_DIVD, + PPC_INS_DIVDU, + PPC_INS_DIVW, + PPC_INS_DIVWU, + PPC_INS_DSS, + PPC_INS_DSSALL, + PPC_INS_DST, + PPC_INS_DSTST, + PPC_INS_DSTSTT, + PPC_INS_DSTT, + PPC_INS_EIEIO, + PPC_INS_EQV, + PPC_INS_EVABS, + PPC_INS_EVADDIW, + PPC_INS_EVADDSMIAAW, + PPC_INS_EVADDSSIAAW, + PPC_INS_EVADDUMIAAW, + PPC_INS_EVADDUSIAAW, + PPC_INS_EVADDW, + PPC_INS_EVAND, + PPC_INS_EVANDC, + PPC_INS_EVCMPEQ, + PPC_INS_EVCMPGTS, + PPC_INS_EVCMPGTU, + PPC_INS_EVCMPLTS, + PPC_INS_EVCMPLTU, + PPC_INS_EVCNTLSW, + PPC_INS_EVCNTLZW, + PPC_INS_EVDIVWS, + PPC_INS_EVDIVWU, + PPC_INS_EVEQV, + PPC_INS_EVEXTSB, + PPC_INS_EVEXTSH, + PPC_INS_EVLDD, + PPC_INS_EVLDDX, + PPC_INS_EVLDH, + PPC_INS_EVLDHX, + PPC_INS_EVLDW, + PPC_INS_EVLDWX, + PPC_INS_EVLHHESPLAT, + PPC_INS_EVLHHESPLATX, + PPC_INS_EVLHHOSSPLAT, + PPC_INS_EVLHHOSSPLATX, + PPC_INS_EVLHHOUSPLAT, + PPC_INS_EVLHHOUSPLATX, + PPC_INS_EVLWHE, + PPC_INS_EVLWHEX, + PPC_INS_EVLWHOS, + PPC_INS_EVLWHOSX, + PPC_INS_EVLWHOU, + PPC_INS_EVLWHOUX, + PPC_INS_EVLWHSPLAT, + PPC_INS_EVLWHSPLATX, + PPC_INS_EVLWWSPLAT, + PPC_INS_EVLWWSPLATX, + PPC_INS_EVMERGEHI, + PPC_INS_EVMERGEHILO, + PPC_INS_EVMERGELO, + PPC_INS_EVMERGELOHI, + PPC_INS_EVMHEGSMFAA, + PPC_INS_EVMHEGSMFAN, + PPC_INS_EVMHEGSMIAA, + PPC_INS_EVMHEGSMIAN, + PPC_INS_EVMHEGUMIAA, + PPC_INS_EVMHEGUMIAN, + PPC_INS_EVMHESMF, + PPC_INS_EVMHESMFA, + PPC_INS_EVMHESMFAAW, + PPC_INS_EVMHESMFANW, + PPC_INS_EVMHESMI, + PPC_INS_EVMHESMIA, + PPC_INS_EVMHESMIAAW, + PPC_INS_EVMHESMIANW, + PPC_INS_EVMHESSF, + PPC_INS_EVMHESSFA, + PPC_INS_EVMHESSFAAW, + PPC_INS_EVMHESSFANW, + PPC_INS_EVMHESSIAAW, + PPC_INS_EVMHESSIANW, + PPC_INS_EVMHEUMI, + PPC_INS_EVMHEUMIA, + PPC_INS_EVMHEUMIAAW, + PPC_INS_EVMHEUMIANW, + PPC_INS_EVMHEUSIAAW, + PPC_INS_EVMHEUSIANW, + PPC_INS_EVMHOGSMFAA, + PPC_INS_EVMHOGSMFAN, + PPC_INS_EVMHOGSMIAA, + PPC_INS_EVMHOGSMIAN, + PPC_INS_EVMHOGUMIAA, + PPC_INS_EVMHOGUMIAN, + PPC_INS_EVMHOSMF, + PPC_INS_EVMHOSMFA, + PPC_INS_EVMHOSMFAAW, + PPC_INS_EVMHOSMFANW, + PPC_INS_EVMHOSMI, + PPC_INS_EVMHOSMIA, + PPC_INS_EVMHOSMIAAW, + PPC_INS_EVMHOSMIANW, + PPC_INS_EVMHOSSF, + PPC_INS_EVMHOSSFA, + PPC_INS_EVMHOSSFAAW, + PPC_INS_EVMHOSSFANW, + PPC_INS_EVMHOSSIAAW, + PPC_INS_EVMHOSSIANW, + PPC_INS_EVMHOUMI, + PPC_INS_EVMHOUMIA, + PPC_INS_EVMHOUMIAAW, + PPC_INS_EVMHOUMIANW, + PPC_INS_EVMHOUSIAAW, + PPC_INS_EVMHOUSIANW, + PPC_INS_EVMRA, + PPC_INS_EVMWHSMF, + PPC_INS_EVMWHSMFA, + PPC_INS_EVMWHSMI, + PPC_INS_EVMWHSMIA, + PPC_INS_EVMWHSSF, + PPC_INS_EVMWHSSFA, + PPC_INS_EVMWHUMI, + PPC_INS_EVMWHUMIA, + PPC_INS_EVMWLSMIAAW, + PPC_INS_EVMWLSMIANW, + PPC_INS_EVMWLSSIAAW, + PPC_INS_EVMWLSSIANW, + PPC_INS_EVMWLUMI, + PPC_INS_EVMWLUMIA, + PPC_INS_EVMWLUMIAAW, + PPC_INS_EVMWLUMIANW, + PPC_INS_EVMWLUSIAAW, + PPC_INS_EVMWLUSIANW, + PPC_INS_EVMWSMF, + PPC_INS_EVMWSMFA, + PPC_INS_EVMWSMFAA, + PPC_INS_EVMWSMFAN, + PPC_INS_EVMWSMI, + PPC_INS_EVMWSMIA, + PPC_INS_EVMWSMIAA, + PPC_INS_EVMWSMIAN, + PPC_INS_EVMWSSF, + PPC_INS_EVMWSSFA, + PPC_INS_EVMWSSFAA, + PPC_INS_EVMWSSFAN, + PPC_INS_EVMWUMI, + PPC_INS_EVMWUMIA, + PPC_INS_EVMWUMIAA, + PPC_INS_EVMWUMIAN, + PPC_INS_EVNAND, + PPC_INS_EVNEG, + PPC_INS_EVNOR, + PPC_INS_EVOR, + PPC_INS_EVORC, + PPC_INS_EVRLW, + PPC_INS_EVRLWI, + PPC_INS_EVRNDW, + PPC_INS_EVSLW, + PPC_INS_EVSLWI, + PPC_INS_EVSPLATFI, + PPC_INS_EVSPLATI, + PPC_INS_EVSRWIS, + PPC_INS_EVSRWIU, + PPC_INS_EVSRWS, + PPC_INS_EVSRWU, + PPC_INS_EVSTDD, + PPC_INS_EVSTDDX, + PPC_INS_EVSTDH, + PPC_INS_EVSTDHX, + PPC_INS_EVSTDW, + PPC_INS_EVSTDWX, + PPC_INS_EVSTWHE, + PPC_INS_EVSTWHEX, + PPC_INS_EVSTWHO, + PPC_INS_EVSTWHOX, + PPC_INS_EVSTWWE, + PPC_INS_EVSTWWEX, + PPC_INS_EVSTWWO, + PPC_INS_EVSTWWOX, + PPC_INS_EVSUBFSMIAAW, + PPC_INS_EVSUBFSSIAAW, + PPC_INS_EVSUBFUMIAAW, + PPC_INS_EVSUBFUSIAAW, + PPC_INS_EVSUBFW, + PPC_INS_EVSUBIFW, + PPC_INS_EVXOR, + PPC_INS_EXTSB, + PPC_INS_EXTSH, + PPC_INS_EXTSW, + PPC_INS_FABS, + PPC_INS_FADD, + PPC_INS_FADDS, + PPC_INS_FCFID, + PPC_INS_FCFIDS, + PPC_INS_FCFIDU, + PPC_INS_FCFIDUS, + PPC_INS_FCMPU, + PPC_INS_FCPSGN, + PPC_INS_FCTID, + PPC_INS_FCTIDUZ, + PPC_INS_FCTIDZ, + PPC_INS_FCTIW, + PPC_INS_FCTIWUZ, + PPC_INS_FCTIWZ, + PPC_INS_FDIV, + PPC_INS_FDIVS, + PPC_INS_FMADD, + PPC_INS_FMADDS, + PPC_INS_FMR, + PPC_INS_FMSUB, + PPC_INS_FMSUBS, + PPC_INS_FMUL, + PPC_INS_FMULS, + PPC_INS_FNABS, + PPC_INS_FNEG, + PPC_INS_FNMADD, + PPC_INS_FNMADDS, + PPC_INS_FNMSUB, + PPC_INS_FNMSUBS, + PPC_INS_FRE, + PPC_INS_FRES, + PPC_INS_FRIM, + PPC_INS_FRIN, + PPC_INS_FRIP, + PPC_INS_FRIZ, + PPC_INS_FRSP, + PPC_INS_FRSQRTE, + PPC_INS_FRSQRTES, + PPC_INS_FSEL, + PPC_INS_FSQRT, + PPC_INS_FSQRTS, + PPC_INS_FSUB, + PPC_INS_FSUBS, + PPC_INS_ICBI, + PPC_INS_ICCCI, + PPC_INS_ISEL, + PPC_INS_ISYNC, + PPC_INS_LA, + PPC_INS_LBZ, + PPC_INS_LBZU, + PPC_INS_LBZUX, + PPC_INS_LBZX, + PPC_INS_LD, + PPC_INS_LDARX, + PPC_INS_LDBRX, + PPC_INS_LDU, + PPC_INS_LDUX, + PPC_INS_LDX, + PPC_INS_LFD, + PPC_INS_LFDU, + PPC_INS_LFDUX, + PPC_INS_LFDX, + PPC_INS_LFIWAX, + PPC_INS_LFIWZX, + PPC_INS_LFS, + PPC_INS_LFSU, + PPC_INS_LFSUX, + PPC_INS_LFSX, + PPC_INS_LHA, + PPC_INS_LHAU, + PPC_INS_LHAUX, + PPC_INS_LHAX, + PPC_INS_LHBRX, + PPC_INS_LHZ, + PPC_INS_LHZU, + PPC_INS_LHZUX, + PPC_INS_LHZX, + PPC_INS_LI, + PPC_INS_LIS, + PPC_INS_LMW, + PPC_INS_LSWI, + PPC_INS_LVEBX, + PPC_INS_LVEHX, + PPC_INS_LVEWX, + PPC_INS_LVSL, + PPC_INS_LVSR, + PPC_INS_LVX, + PPC_INS_LVXL, + PPC_INS_LWA, + PPC_INS_LWARX, + PPC_INS_LWAUX, + PPC_INS_LWAX, + PPC_INS_LWBRX, + PPC_INS_LWZ, + PPC_INS_LWZU, + PPC_INS_LWZUX, + PPC_INS_LWZX, + PPC_INS_LXSDX, + PPC_INS_LXVD2X, + PPC_INS_LXVDSX, + PPC_INS_LXVW4X, + PPC_INS_MBAR, + PPC_INS_MCRF, + PPC_INS_MFCR, + PPC_INS_MFCTR, + PPC_INS_MFDCR, + PPC_INS_MFFS, + PPC_INS_MFLR, + PPC_INS_MFMSR, + PPC_INS_MFOCRF, + PPC_INS_MFSPR, + PPC_INS_MFSR, + PPC_INS_MFSRIN, + PPC_INS_MFTB, + PPC_INS_MFVSCR, + PPC_INS_MSYNC, + PPC_INS_MTCRF, + PPC_INS_MTCTR, + PPC_INS_MTDCR, + PPC_INS_MTFSB0, + PPC_INS_MTFSB1, + PPC_INS_MTFSF, + PPC_INS_MTLR, + PPC_INS_MTMSR, + PPC_INS_MTMSRD, + PPC_INS_MTOCRF, + PPC_INS_MTSPR, + PPC_INS_MTSR, + PPC_INS_MTSRIN, + PPC_INS_MTVSCR, + PPC_INS_MULHD, + PPC_INS_MULHDU, + PPC_INS_MULHW, + PPC_INS_MULHWU, + PPC_INS_MULLD, + PPC_INS_MULLI, + PPC_INS_MULLW, + PPC_INS_NAND, + PPC_INS_NEG, + PPC_INS_NOP, + PPC_INS_ORI, + PPC_INS_NOR, + PPC_INS_OR, + PPC_INS_ORC, + PPC_INS_ORIS, + PPC_INS_POPCNTD, + PPC_INS_POPCNTW, + PPC_INS_RFCI, + PPC_INS_RFDI, + PPC_INS_RFI, + PPC_INS_RFID, + PPC_INS_RFMCI, + PPC_INS_RLDCL, + PPC_INS_RLDCR, + PPC_INS_RLDIC, + PPC_INS_RLDICL, + PPC_INS_RLDICR, + PPC_INS_RLDIMI, + PPC_INS_RLWIMI, + PPC_INS_RLWINM, + PPC_INS_RLWNM, + PPC_INS_SC, + PPC_INS_SLBIA, + PPC_INS_SLBIE, + PPC_INS_SLBMFEE, + PPC_INS_SLBMTE, + PPC_INS_SLD, + PPC_INS_SLW, + PPC_INS_SRAD, + PPC_INS_SRADI, + PPC_INS_SRAW, + PPC_INS_SRAWI, + PPC_INS_SRD, + PPC_INS_SRW, + PPC_INS_STB, + PPC_INS_STBU, + PPC_INS_STBUX, + PPC_INS_STBX, + PPC_INS_STD, + PPC_INS_STDBRX, + PPC_INS_STDCX, + PPC_INS_STDU, + PPC_INS_STDUX, + PPC_INS_STDX, + PPC_INS_STFD, + PPC_INS_STFDU, + PPC_INS_STFDUX, + PPC_INS_STFDX, + PPC_INS_STFIWX, + PPC_INS_STFS, + PPC_INS_STFSU, + PPC_INS_STFSUX, + PPC_INS_STFSX, + PPC_INS_STH, + PPC_INS_STHBRX, + PPC_INS_STHU, + PPC_INS_STHUX, + PPC_INS_STHX, + PPC_INS_STMW, + PPC_INS_STSWI, + PPC_INS_STVEBX, + PPC_INS_STVEHX, + PPC_INS_STVEWX, + PPC_INS_STVX, + PPC_INS_STVXL, + PPC_INS_STW, + PPC_INS_STWBRX, + PPC_INS_STWCX, + PPC_INS_STWU, + PPC_INS_STWUX, + PPC_INS_STWX, + PPC_INS_STXSDX, + PPC_INS_STXVD2X, + PPC_INS_STXVW4X, + PPC_INS_SUBF, + PPC_INS_SUBFC, + PPC_INS_SUBFE, + PPC_INS_SUBFIC, + PPC_INS_SUBFME, + PPC_INS_SUBFZE, + PPC_INS_SYNC, + PPC_INS_TD, + PPC_INS_TDI, + PPC_INS_TLBIA, + PPC_INS_TLBIE, + PPC_INS_TLBIEL, + PPC_INS_TLBIVAX, + PPC_INS_TLBLD, + PPC_INS_TLBLI, + PPC_INS_TLBRE, + PPC_INS_TLBSX, + PPC_INS_TLBSYNC, + PPC_INS_TLBWE, + PPC_INS_TRAP, + PPC_INS_TW, + PPC_INS_TWI, + PPC_INS_VADDCUW, + PPC_INS_VADDFP, + PPC_INS_VADDSBS, + PPC_INS_VADDSHS, + PPC_INS_VADDSWS, + PPC_INS_VADDUBM, + PPC_INS_VADDUBS, + PPC_INS_VADDUHM, + PPC_INS_VADDUHS, + PPC_INS_VADDUWM, + PPC_INS_VADDUWS, + PPC_INS_VAND, + PPC_INS_VANDC, + PPC_INS_VAVGSB, + PPC_INS_VAVGSH, + PPC_INS_VAVGSW, + PPC_INS_VAVGUB, + PPC_INS_VAVGUH, + PPC_INS_VAVGUW, + PPC_INS_VCFSX, + PPC_INS_VCFUX, + PPC_INS_VCMPBFP, + PPC_INS_VCMPEQFP, + PPC_INS_VCMPEQUB, + PPC_INS_VCMPEQUH, + PPC_INS_VCMPEQUW, + PPC_INS_VCMPGEFP, + PPC_INS_VCMPGTFP, + PPC_INS_VCMPGTSB, + PPC_INS_VCMPGTSH, + PPC_INS_VCMPGTSW, + PPC_INS_VCMPGTUB, + PPC_INS_VCMPGTUH, + PPC_INS_VCMPGTUW, + PPC_INS_VCTSXS, + PPC_INS_VCTUXS, + PPC_INS_VEXPTEFP, + PPC_INS_VLOGEFP, + PPC_INS_VMADDFP, + PPC_INS_VMAXFP, + PPC_INS_VMAXSB, + PPC_INS_VMAXSH, + PPC_INS_VMAXSW, + PPC_INS_VMAXUB, + PPC_INS_VMAXUH, + PPC_INS_VMAXUW, + PPC_INS_VMHADDSHS, + PPC_INS_VMHRADDSHS, + PPC_INS_VMINFP, + PPC_INS_VMINSB, + PPC_INS_VMINSH, + PPC_INS_VMINSW, + PPC_INS_VMINUB, + PPC_INS_VMINUH, + PPC_INS_VMINUW, + PPC_INS_VMLADDUHM, + PPC_INS_VMRGHB, + PPC_INS_VMRGHH, + PPC_INS_VMRGHW, + PPC_INS_VMRGLB, + PPC_INS_VMRGLH, + PPC_INS_VMRGLW, + PPC_INS_VMSUMMBM, + PPC_INS_VMSUMSHM, + PPC_INS_VMSUMSHS, + PPC_INS_VMSUMUBM, + PPC_INS_VMSUMUHM, + PPC_INS_VMSUMUHS, + PPC_INS_VMULESB, + PPC_INS_VMULESH, + PPC_INS_VMULEUB, + PPC_INS_VMULEUH, + PPC_INS_VMULOSB, + PPC_INS_VMULOSH, + PPC_INS_VMULOUB, + PPC_INS_VMULOUH, + PPC_INS_VNMSUBFP, + PPC_INS_VNOR, + PPC_INS_VOR, + PPC_INS_VPERM, + PPC_INS_VPKPX, + PPC_INS_VPKSHSS, + PPC_INS_VPKSHUS, + PPC_INS_VPKSWSS, + PPC_INS_VPKSWUS, + PPC_INS_VPKUHUM, + PPC_INS_VPKUHUS, + PPC_INS_VPKUWUM, + PPC_INS_VPKUWUS, + PPC_INS_VREFP, + PPC_INS_VRFIM, + PPC_INS_VRFIN, + PPC_INS_VRFIP, + PPC_INS_VRFIZ, + PPC_INS_VRLB, + PPC_INS_VRLH, + PPC_INS_VRLW, + PPC_INS_VRSQRTEFP, + PPC_INS_VSEL, + PPC_INS_VSL, + PPC_INS_VSLB, + PPC_INS_VSLDOI, + PPC_INS_VSLH, + PPC_INS_VSLO, + PPC_INS_VSLW, + PPC_INS_VSPLTB, + PPC_INS_VSPLTH, + PPC_INS_VSPLTISB, + PPC_INS_VSPLTISH, + PPC_INS_VSPLTISW, + PPC_INS_VSPLTW, + PPC_INS_VSR, + PPC_INS_VSRAB, + PPC_INS_VSRAH, + PPC_INS_VSRAW, + PPC_INS_VSRB, + PPC_INS_VSRH, + PPC_INS_VSRO, + PPC_INS_VSRW, + PPC_INS_VSUBCUW, + PPC_INS_VSUBFP, + PPC_INS_VSUBSBS, + PPC_INS_VSUBSHS, + PPC_INS_VSUBSWS, + PPC_INS_VSUBUBM, + PPC_INS_VSUBUBS, + PPC_INS_VSUBUHM, + PPC_INS_VSUBUHS, + PPC_INS_VSUBUWM, + PPC_INS_VSUBUWS, + PPC_INS_VSUM2SWS, + PPC_INS_VSUM4SBS, + PPC_INS_VSUM4SHS, + PPC_INS_VSUM4UBS, + PPC_INS_VSUMSWS, + PPC_INS_VUPKHPX, + PPC_INS_VUPKHSB, + PPC_INS_VUPKHSH, + PPC_INS_VUPKLPX, + PPC_INS_VUPKLSB, + PPC_INS_VUPKLSH, + PPC_INS_VXOR, + PPC_INS_WAIT, + PPC_INS_WRTEE, + PPC_INS_WRTEEI, + PPC_INS_XOR, + PPC_INS_XORI, + PPC_INS_XORIS, + PPC_INS_XSABSDP, + PPC_INS_XSADDDP, + PPC_INS_XSCMPODP, + PPC_INS_XSCMPUDP, + PPC_INS_XSCPSGNDP, + PPC_INS_XSCVDPSP, + PPC_INS_XSCVDPSXDS, + PPC_INS_XSCVDPSXWS, + PPC_INS_XSCVDPUXDS, + PPC_INS_XSCVDPUXWS, + PPC_INS_XSCVSPDP, + PPC_INS_XSCVSXDDP, + PPC_INS_XSCVUXDDP, + PPC_INS_XSDIVDP, + PPC_INS_XSMADDADP, + PPC_INS_XSMADDMDP, + PPC_INS_XSMAXDP, + PPC_INS_XSMINDP, + PPC_INS_XSMSUBADP, + PPC_INS_XSMSUBMDP, + PPC_INS_XSMULDP, + PPC_INS_XSNABSDP, + PPC_INS_XSNEGDP, + PPC_INS_XSNMADDADP, + PPC_INS_XSNMADDMDP, + PPC_INS_XSNMSUBADP, + PPC_INS_XSNMSUBMDP, + PPC_INS_XSRDPI, + PPC_INS_XSRDPIC, + PPC_INS_XSRDPIM, + PPC_INS_XSRDPIP, + PPC_INS_XSRDPIZ, + PPC_INS_XSREDP, + PPC_INS_XSRSQRTEDP, + PPC_INS_XSSQRTDP, + PPC_INS_XSSUBDP, + PPC_INS_XSTDIVDP, + PPC_INS_XSTSQRTDP, + PPC_INS_XVABSDP, + PPC_INS_XVABSSP, + PPC_INS_XVADDDP, + PPC_INS_XVADDSP, + PPC_INS_XVCMPEQDP, + PPC_INS_XVCMPEQSP, + PPC_INS_XVCMPGEDP, + PPC_INS_XVCMPGESP, + PPC_INS_XVCMPGTDP, + PPC_INS_XVCMPGTSP, + PPC_INS_XVCPSGNDP, + PPC_INS_XVCPSGNSP, + PPC_INS_XVCVDPSP, + PPC_INS_XVCVDPSXDS, + PPC_INS_XVCVDPSXWS, + PPC_INS_XVCVDPUXDS, + PPC_INS_XVCVDPUXWS, + PPC_INS_XVCVSPDP, + PPC_INS_XVCVSPSXDS, + PPC_INS_XVCVSPSXWS, + PPC_INS_XVCVSPUXDS, + PPC_INS_XVCVSPUXWS, + PPC_INS_XVCVSXDDP, + PPC_INS_XVCVSXDSP, + PPC_INS_XVCVSXWDP, + PPC_INS_XVCVSXWSP, + PPC_INS_XVCVUXDDP, + PPC_INS_XVCVUXDSP, + PPC_INS_XVCVUXWDP, + PPC_INS_XVCVUXWSP, + PPC_INS_XVDIVDP, + PPC_INS_XVDIVSP, + PPC_INS_XVMADDADP, + PPC_INS_XVMADDASP, + PPC_INS_XVMADDMDP, + PPC_INS_XVMADDMSP, + PPC_INS_XVMAXDP, + PPC_INS_XVMAXSP, + PPC_INS_XVMINDP, + PPC_INS_XVMINSP, + PPC_INS_XVMSUBADP, + PPC_INS_XVMSUBASP, + PPC_INS_XVMSUBMDP, + PPC_INS_XVMSUBMSP, + PPC_INS_XVMULDP, + PPC_INS_XVMULSP, + PPC_INS_XVNABSDP, + PPC_INS_XVNABSSP, + PPC_INS_XVNEGDP, + PPC_INS_XVNEGSP, + PPC_INS_XVNMADDADP, + PPC_INS_XVNMADDASP, + PPC_INS_XVNMADDMDP, + PPC_INS_XVNMADDMSP, + PPC_INS_XVNMSUBADP, + PPC_INS_XVNMSUBASP, + PPC_INS_XVNMSUBMDP, + PPC_INS_XVNMSUBMSP, + PPC_INS_XVRDPI, + PPC_INS_XVRDPIC, + PPC_INS_XVRDPIM, + PPC_INS_XVRDPIP, + PPC_INS_XVRDPIZ, + PPC_INS_XVREDP, + PPC_INS_XVRESP, + PPC_INS_XVRSPI, + PPC_INS_XVRSPIC, + PPC_INS_XVRSPIM, + PPC_INS_XVRSPIP, + PPC_INS_XVRSPIZ, + PPC_INS_XVRSQRTEDP, + PPC_INS_XVRSQRTESP, + PPC_INS_XVSQRTDP, + PPC_INS_XVSQRTSP, + PPC_INS_XVSUBDP, + PPC_INS_XVSUBSP, + PPC_INS_XVTDIVDP, + PPC_INS_XVTDIVSP, + PPC_INS_XVTSQRTDP, + PPC_INS_XVTSQRTSP, + PPC_INS_XXLAND, + PPC_INS_XXLANDC, + PPC_INS_XXLNOR, + PPC_INS_XXLOR, + PPC_INS_XXLXOR, + PPC_INS_XXMRGHW, + PPC_INS_XXMRGLW, + PPC_INS_XXPERMDI, + PPC_INS_XXSEL, + PPC_INS_XXSLDWI, + PPC_INS_XXSPLTW, + PPC_INS_BCA, + PPC_INS_BCLA, + + // extra & alias instructions + PPC_INS_SLWI, + PPC_INS_SRWI, + PPC_INS_SLDI, + + PPC_INS_BTA, + PPC_INS_CRSET, + PPC_INS_CRNOT, + PPC_INS_CRMOVE, + PPC_INS_CRCLR, + PPC_INS_MFBR0, + PPC_INS_MFBR1, + PPC_INS_MFBR2, + PPC_INS_MFBR3, + PPC_INS_MFBR4, + PPC_INS_MFBR5, + PPC_INS_MFBR6, + PPC_INS_MFBR7, + PPC_INS_MFXER, + PPC_INS_MFRTCU, + PPC_INS_MFRTCL, + PPC_INS_MFDSCR, + PPC_INS_MFDSISR, + PPC_INS_MFDAR, + PPC_INS_MFSRR2, + PPC_INS_MFSRR3, + PPC_INS_MFCFAR, + PPC_INS_MFAMR, + PPC_INS_MFPID, + PPC_INS_MFTBLO, + PPC_INS_MFTBHI, + PPC_INS_MFDBATU, + PPC_INS_MFDBATL, + PPC_INS_MFIBATU, + PPC_INS_MFIBATL, + PPC_INS_MFDCCR, + PPC_INS_MFICCR, + PPC_INS_MFDEAR, + PPC_INS_MFESR, + PPC_INS_MFSPEFSCR, + PPC_INS_MFTCR, + PPC_INS_MFASR, + PPC_INS_MFPVR, + PPC_INS_MFTBU, + PPC_INS_MTCR, + PPC_INS_MTBR0, + PPC_INS_MTBR1, + PPC_INS_MTBR2, + PPC_INS_MTBR3, + PPC_INS_MTBR4, + PPC_INS_MTBR5, + PPC_INS_MTBR6, + PPC_INS_MTBR7, + PPC_INS_MTXER, + PPC_INS_MTDSCR, + PPC_INS_MTDSISR, + PPC_INS_MTDAR, + PPC_INS_MTSRR2, + PPC_INS_MTSRR3, + PPC_INS_MTCFAR, + PPC_INS_MTAMR, + PPC_INS_MTPID, + PPC_INS_MTTBL, + PPC_INS_MTTBU, + PPC_INS_MTTBLO, + PPC_INS_MTTBHI, + PPC_INS_MTDBATU, + PPC_INS_MTDBATL, + PPC_INS_MTIBATU, + PPC_INS_MTIBATL, + PPC_INS_MTDCCR, + PPC_INS_MTICCR, + PPC_INS_MTDEAR, + PPC_INS_MTESR, + PPC_INS_MTSPEFSCR, + PPC_INS_MTTCR, + PPC_INS_NOT, + PPC_INS_MR, + PPC_INS_ROTLD, + PPC_INS_ROTLDI, + PPC_INS_CLRLDI, + PPC_INS_ROTLWI, + PPC_INS_CLRLWI, + PPC_INS_ROTLW, + PPC_INS_SUB, + PPC_INS_SUBC, + PPC_INS_LWSYNC, + PPC_INS_PTESYNC, + PPC_INS_TDLT, + PPC_INS_TDEQ, + PPC_INS_TDGT, + PPC_INS_TDNE, + PPC_INS_TDLLT, + PPC_INS_TDLGT, + PPC_INS_TDU, + PPC_INS_TDLTI, + PPC_INS_TDEQI, + PPC_INS_TDGTI, + PPC_INS_TDNEI, + PPC_INS_TDLLTI, + PPC_INS_TDLGTI, + PPC_INS_TDUI, + PPC_INS_TLBREHI, + PPC_INS_TLBRELO, + PPC_INS_TLBWEHI, + PPC_INS_TLBWELO, + PPC_INS_TWLT, + PPC_INS_TWEQ, + PPC_INS_TWGT, + PPC_INS_TWNE, + PPC_INS_TWLLT, + PPC_INS_TWLGT, + PPC_INS_TWU, + PPC_INS_TWLTI, + PPC_INS_TWEQI, + PPC_INS_TWGTI, + PPC_INS_TWNEI, + PPC_INS_TWLLTI, + PPC_INS_TWLGTI, + PPC_INS_TWUI, + PPC_INS_WAITRSV, + PPC_INS_WAITIMPL, + PPC_INS_XNOP, + PPC_INS_XVMOVDP, + PPC_INS_XVMOVSP, + PPC_INS_XXSPLTD, + PPC_INS_XXMRGHD, + PPC_INS_XXMRGLD, + PPC_INS_XXSWAPD, + PPC_INS_BT, + PPC_INS_BF, + PPC_INS_BDNZT, + PPC_INS_BDNZF, + PPC_INS_BDZF, + PPC_INS_BDZT, + PPC_INS_BFA, + PPC_INS_BDNZTA, + PPC_INS_BDNZFA, + PPC_INS_BDZTA, + PPC_INS_BDZFA, + PPC_INS_BTCTR, + PPC_INS_BFCTR, + PPC_INS_BTCTRL, + PPC_INS_BFCTRL, + PPC_INS_BTL, + PPC_INS_BFL, + PPC_INS_BDNZTL, + PPC_INS_BDNZFL, + PPC_INS_BDZTL, + PPC_INS_BDZFL, + PPC_INS_BTLA, + PPC_INS_BFLA, + PPC_INS_BDNZTLA, + PPC_INS_BDNZFLA, + PPC_INS_BDZTLA, + PPC_INS_BDZFLA, + PPC_INS_BTLR, + PPC_INS_BFLR, + PPC_INS_BDNZTLR, + PPC_INS_BDZTLR, + PPC_INS_BDZFLR, + PPC_INS_BTLRL, + PPC_INS_BFLRL, + PPC_INS_BDNZTLRL, + PPC_INS_BDNZFLRL, + PPC_INS_BDZTLRL, + PPC_INS_BDZFLRL, + + PPC_INS_ENDING, // <-- mark the end of the list of instructions +} ppc_insn; + +//> Group of PPC instructions +typedef enum ppc_insn_group +{ + PPC_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + PPC_GRP_JUMP, // = CS_GRP_JUMP + + //> Architecture-specific groups + PPC_GRP_ALTIVEC = 128, + PPC_GRP_MODE32, + PPC_GRP_MODE64, + PPC_GRP_BOOKE, + PPC_GRP_NOTBOOKE, + PPC_GRP_SPE, + PPC_GRP_VSX, + PPC_GRP_E500, + PPC_GRP_PPC4XX, + PPC_GRP_PPC6XX, + + PPC_GRP_ENDING, // <-- mark the end of the list of groups +} ppc_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dbg/capstone/sparc.h b/src/dbg/capstone/sparc.h index a1cce986..ddb945ad 100644 --- a/src/dbg/capstone/sparc.h +++ b/src/dbg/capstone/sparc.h @@ -1,529 +1,529 @@ -#ifndef CAPSTONE_SPARC_H -#define CAPSTONE_SPARC_H - -/* Capstone Disassembly Engine */ -/* By Nguyen Anh Quynh , 2014 */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "platform.h" - -// GCC SPARC toolchain has a default macro called "sparc" which breaks -// compilation -#undef sparc - -#ifdef _MSC_VER -#pragma warning(disable:4201) -#endif - -//> Enums corresponding to Sparc condition codes, both icc's and fcc's. -typedef enum sparc_cc -{ - SPARC_CC_INVALID = 0, // invalid CC (default) - //> Integer condition codes - SPARC_CC_ICC_A = 8 + 256, // Always - SPARC_CC_ICC_N = 0 + 256, // Never - SPARC_CC_ICC_NE = 9 + 256, // Not Equal - SPARC_CC_ICC_E = 1 + 256, // Equal - SPARC_CC_ICC_G = 10 + 256, // Greater - SPARC_CC_ICC_LE = 2 + 256, // Less or Equal - SPARC_CC_ICC_GE = 11 + 256, // Greater or Equal - SPARC_CC_ICC_L = 3 + 256, // Less - SPARC_CC_ICC_GU = 12 + 256, // Greater Unsigned - SPARC_CC_ICC_LEU = 4 + 256, // Less or Equal Unsigned - SPARC_CC_ICC_CC = 13 + 256, // Carry Clear/Great or Equal Unsigned - SPARC_CC_ICC_CS = 5 + 256, // Carry Set/Less Unsigned - SPARC_CC_ICC_POS = 14 + 256, // Positive - SPARC_CC_ICC_NEG = 6 + 256, // Negative - SPARC_CC_ICC_VC = 15 + 256, // Overflow Clear - SPARC_CC_ICC_VS = 7 + 256, // Overflow Set - - //> Floating condition codes - SPARC_CC_FCC_A = 8 + 16 + 256, // Always - SPARC_CC_FCC_N = 0 + 16 + 256, // Never - SPARC_CC_FCC_U = 7 + 16 + 256, // Unordered - SPARC_CC_FCC_G = 6 + 16 + 256, // Greater - SPARC_CC_FCC_UG = 5 + 16 + 256, // Unordered or Greater - SPARC_CC_FCC_L = 4 + 16 + 256, // Less - SPARC_CC_FCC_UL = 3 + 16 + 256, // Unordered or Less - SPARC_CC_FCC_LG = 2 + 16 + 256, // Less or Greater - SPARC_CC_FCC_NE = 1 + 16 + 256, // Not Equal - SPARC_CC_FCC_E = 9 + 16 + 256, // Equal - SPARC_CC_FCC_UE = 10 + 16 + 256, // Unordered or Equal - SPARC_CC_FCC_GE = 11 + 16 + 256, // Greater or Equal - SPARC_CC_FCC_UGE = 12 + 16 + 256, // Unordered or Greater or Equal - SPARC_CC_FCC_LE = 13 + 16 + 256, // Less or Equal - SPARC_CC_FCC_ULE = 14 + 16 + 256, // Unordered or Less or Equal - SPARC_CC_FCC_O = 15 + 16 + 256, // Ordered -} sparc_cc; - -//> Branch hint -typedef enum sparc_hint -{ - SPARC_HINT_INVALID = 0, // no hint - SPARC_HINT_A = 1 << 0, // annul delay slot instruction - SPARC_HINT_PT = 1 << 1, // branch taken - SPARC_HINT_PN = 1 << 2, // branch NOT taken -} sparc_hint; - -//> Operand type for instruction's operands -typedef enum sparc_op_type -{ - SPARC_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). - SPARC_OP_REG, // = CS_OP_REG (Register operand). - SPARC_OP_IMM, // = CS_OP_IMM (Immediate operand). - SPARC_OP_MEM, // = CS_OP_MEM (Memory operand). -} sparc_op_type; - -// Instruction's operand referring to memory -// This is associated with SPARC_OP_MEM operand type above -typedef struct sparc_op_mem -{ - uint8_t base; // base register - uint8_t index; // index register - int32_t disp; // displacement/offset value -} sparc_op_mem; - -// Instruction operand -typedef struct cs_sparc_op -{ - sparc_op_type type; // operand type - union - { - unsigned int reg; // register value for REG operand - int32_t imm; // immediate value for IMM operand - sparc_op_mem mem; // base/disp value for MEM operand - }; -} cs_sparc_op; - -// Instruction structure -typedef struct cs_sparc -{ - sparc_cc cc; // code condition for this insn - sparc_hint hint; // branch hint: encoding as bitwise OR of sparc_hint. - // Number of operands of this instruction, - // or 0 when instruction has no operand. - uint8_t op_count; - cs_sparc_op operands[4]; // operands for this instruction. -} cs_sparc; - -//> SPARC registers -typedef enum sparc_reg -{ - SPARC_REG_INVALID = 0, - - SPARC_REG_F0, - SPARC_REG_F1, - SPARC_REG_F2, - SPARC_REG_F3, - SPARC_REG_F4, - SPARC_REG_F5, - SPARC_REG_F6, - SPARC_REG_F7, - SPARC_REG_F8, - SPARC_REG_F9, - SPARC_REG_F10, - SPARC_REG_F11, - SPARC_REG_F12, - SPARC_REG_F13, - SPARC_REG_F14, - SPARC_REG_F15, - SPARC_REG_F16, - SPARC_REG_F17, - SPARC_REG_F18, - SPARC_REG_F19, - SPARC_REG_F20, - SPARC_REG_F21, - SPARC_REG_F22, - SPARC_REG_F23, - SPARC_REG_F24, - SPARC_REG_F25, - SPARC_REG_F26, - SPARC_REG_F27, - SPARC_REG_F28, - SPARC_REG_F29, - SPARC_REG_F30, - SPARC_REG_F31, - SPARC_REG_F32, - SPARC_REG_F34, - SPARC_REG_F36, - SPARC_REG_F38, - SPARC_REG_F40, - SPARC_REG_F42, - SPARC_REG_F44, - SPARC_REG_F46, - SPARC_REG_F48, - SPARC_REG_F50, - SPARC_REG_F52, - SPARC_REG_F54, - SPARC_REG_F56, - SPARC_REG_F58, - SPARC_REG_F60, - SPARC_REG_F62, - SPARC_REG_FCC0, // Floating condition codes - SPARC_REG_FCC1, - SPARC_REG_FCC2, - SPARC_REG_FCC3, - SPARC_REG_FP, - SPARC_REG_G0, - SPARC_REG_G1, - SPARC_REG_G2, - SPARC_REG_G3, - SPARC_REG_G4, - SPARC_REG_G5, - SPARC_REG_G6, - SPARC_REG_G7, - SPARC_REG_I0, - SPARC_REG_I1, - SPARC_REG_I2, - SPARC_REG_I3, - SPARC_REG_I4, - SPARC_REG_I5, - SPARC_REG_I7, - SPARC_REG_ICC, // Integer condition codes - SPARC_REG_L0, - SPARC_REG_L1, - SPARC_REG_L2, - SPARC_REG_L3, - SPARC_REG_L4, - SPARC_REG_L5, - SPARC_REG_L6, - SPARC_REG_L7, - SPARC_REG_O0, - SPARC_REG_O1, - SPARC_REG_O2, - SPARC_REG_O3, - SPARC_REG_O4, - SPARC_REG_O5, - SPARC_REG_O7, - SPARC_REG_SP, - SPARC_REG_Y, - - // special register - SPARC_REG_XCC, - - SPARC_REG_ENDING, // <-- mark the end of the list of registers - - // extras - SPARC_REG_O6 = SPARC_REG_SP, - SPARC_REG_I6 = SPARC_REG_FP, -} sparc_reg; - -//> SPARC instruction -typedef enum sparc_insn -{ - SPARC_INS_INVALID = 0, - - SPARC_INS_ADDCC, - SPARC_INS_ADDX, - SPARC_INS_ADDXCC, - SPARC_INS_ADDXC, - SPARC_INS_ADDXCCC, - SPARC_INS_ADD, - SPARC_INS_ALIGNADDR, - SPARC_INS_ALIGNADDRL, - SPARC_INS_ANDCC, - SPARC_INS_ANDNCC, - SPARC_INS_ANDN, - SPARC_INS_AND, - SPARC_INS_ARRAY16, - SPARC_INS_ARRAY32, - SPARC_INS_ARRAY8, - SPARC_INS_B, - SPARC_INS_JMP, - SPARC_INS_BMASK, - SPARC_INS_FB, - SPARC_INS_BRGEZ, - SPARC_INS_BRGZ, - SPARC_INS_BRLEZ, - SPARC_INS_BRLZ, - SPARC_INS_BRNZ, - SPARC_INS_BRZ, - SPARC_INS_BSHUFFLE, - SPARC_INS_CALL, - SPARC_INS_CASX, - SPARC_INS_CAS, - SPARC_INS_CMASK16, - SPARC_INS_CMASK32, - SPARC_INS_CMASK8, - SPARC_INS_CMP, - SPARC_INS_EDGE16, - SPARC_INS_EDGE16L, - SPARC_INS_EDGE16LN, - SPARC_INS_EDGE16N, - SPARC_INS_EDGE32, - SPARC_INS_EDGE32L, - SPARC_INS_EDGE32LN, - SPARC_INS_EDGE32N, - SPARC_INS_EDGE8, - SPARC_INS_EDGE8L, - SPARC_INS_EDGE8LN, - SPARC_INS_EDGE8N, - SPARC_INS_FABSD, - SPARC_INS_FABSQ, - SPARC_INS_FABSS, - SPARC_INS_FADDD, - SPARC_INS_FADDQ, - SPARC_INS_FADDS, - SPARC_INS_FALIGNDATA, - SPARC_INS_FAND, - SPARC_INS_FANDNOT1, - SPARC_INS_FANDNOT1S, - SPARC_INS_FANDNOT2, - SPARC_INS_FANDNOT2S, - SPARC_INS_FANDS, - SPARC_INS_FCHKSM16, - SPARC_INS_FCMPD, - SPARC_INS_FCMPEQ16, - SPARC_INS_FCMPEQ32, - SPARC_INS_FCMPGT16, - SPARC_INS_FCMPGT32, - SPARC_INS_FCMPLE16, - SPARC_INS_FCMPLE32, - SPARC_INS_FCMPNE16, - SPARC_INS_FCMPNE32, - SPARC_INS_FCMPQ, - SPARC_INS_FCMPS, - SPARC_INS_FDIVD, - SPARC_INS_FDIVQ, - SPARC_INS_FDIVS, - SPARC_INS_FDMULQ, - SPARC_INS_FDTOI, - SPARC_INS_FDTOQ, - SPARC_INS_FDTOS, - SPARC_INS_FDTOX, - SPARC_INS_FEXPAND, - SPARC_INS_FHADDD, - SPARC_INS_FHADDS, - SPARC_INS_FHSUBD, - SPARC_INS_FHSUBS, - SPARC_INS_FITOD, - SPARC_INS_FITOQ, - SPARC_INS_FITOS, - SPARC_INS_FLCMPD, - SPARC_INS_FLCMPS, - SPARC_INS_FLUSHW, - SPARC_INS_FMEAN16, - SPARC_INS_FMOVD, - SPARC_INS_FMOVQ, - SPARC_INS_FMOVRDGEZ, - SPARC_INS_FMOVRQGEZ, - SPARC_INS_FMOVRSGEZ, - SPARC_INS_FMOVRDGZ, - SPARC_INS_FMOVRQGZ, - SPARC_INS_FMOVRSGZ, - SPARC_INS_FMOVRDLEZ, - SPARC_INS_FMOVRQLEZ, - SPARC_INS_FMOVRSLEZ, - SPARC_INS_FMOVRDLZ, - SPARC_INS_FMOVRQLZ, - SPARC_INS_FMOVRSLZ, - SPARC_INS_FMOVRDNZ, - SPARC_INS_FMOVRQNZ, - SPARC_INS_FMOVRSNZ, - SPARC_INS_FMOVRDZ, - SPARC_INS_FMOVRQZ, - SPARC_INS_FMOVRSZ, - SPARC_INS_FMOVS, - SPARC_INS_FMUL8SUX16, - SPARC_INS_FMUL8ULX16, - SPARC_INS_FMUL8X16, - SPARC_INS_FMUL8X16AL, - SPARC_INS_FMUL8X16AU, - SPARC_INS_FMULD, - SPARC_INS_FMULD8SUX16, - SPARC_INS_FMULD8ULX16, - SPARC_INS_FMULQ, - SPARC_INS_FMULS, - SPARC_INS_FNADDD, - SPARC_INS_FNADDS, - SPARC_INS_FNAND, - SPARC_INS_FNANDS, - SPARC_INS_FNEGD, - SPARC_INS_FNEGQ, - SPARC_INS_FNEGS, - SPARC_INS_FNHADDD, - SPARC_INS_FNHADDS, - SPARC_INS_FNOR, - SPARC_INS_FNORS, - SPARC_INS_FNOT1, - SPARC_INS_FNOT1S, - SPARC_INS_FNOT2, - SPARC_INS_FNOT2S, - SPARC_INS_FONE, - SPARC_INS_FONES, - SPARC_INS_FOR, - SPARC_INS_FORNOT1, - SPARC_INS_FORNOT1S, - SPARC_INS_FORNOT2, - SPARC_INS_FORNOT2S, - SPARC_INS_FORS, - SPARC_INS_FPACK16, - SPARC_INS_FPACK32, - SPARC_INS_FPACKFIX, - SPARC_INS_FPADD16, - SPARC_INS_FPADD16S, - SPARC_INS_FPADD32, - SPARC_INS_FPADD32S, - SPARC_INS_FPADD64, - SPARC_INS_FPMERGE, - SPARC_INS_FPSUB16, - SPARC_INS_FPSUB16S, - SPARC_INS_FPSUB32, - SPARC_INS_FPSUB32S, - SPARC_INS_FQTOD, - SPARC_INS_FQTOI, - SPARC_INS_FQTOS, - SPARC_INS_FQTOX, - SPARC_INS_FSLAS16, - SPARC_INS_FSLAS32, - SPARC_INS_FSLL16, - SPARC_INS_FSLL32, - SPARC_INS_FSMULD, - SPARC_INS_FSQRTD, - SPARC_INS_FSQRTQ, - SPARC_INS_FSQRTS, - SPARC_INS_FSRA16, - SPARC_INS_FSRA32, - SPARC_INS_FSRC1, - SPARC_INS_FSRC1S, - SPARC_INS_FSRC2, - SPARC_INS_FSRC2S, - SPARC_INS_FSRL16, - SPARC_INS_FSRL32, - SPARC_INS_FSTOD, - SPARC_INS_FSTOI, - SPARC_INS_FSTOQ, - SPARC_INS_FSTOX, - SPARC_INS_FSUBD, - SPARC_INS_FSUBQ, - SPARC_INS_FSUBS, - SPARC_INS_FXNOR, - SPARC_INS_FXNORS, - SPARC_INS_FXOR, - SPARC_INS_FXORS, - SPARC_INS_FXTOD, - SPARC_INS_FXTOQ, - SPARC_INS_FXTOS, - SPARC_INS_FZERO, - SPARC_INS_FZEROS, - SPARC_INS_JMPL, - SPARC_INS_LDD, - SPARC_INS_LD, - SPARC_INS_LDQ, - SPARC_INS_LDSB, - SPARC_INS_LDSH, - SPARC_INS_LDSW, - SPARC_INS_LDUB, - SPARC_INS_LDUH, - SPARC_INS_LDX, - SPARC_INS_LZCNT, - SPARC_INS_MEMBAR, - SPARC_INS_MOVDTOX, - SPARC_INS_MOV, - SPARC_INS_MOVRGEZ, - SPARC_INS_MOVRGZ, - SPARC_INS_MOVRLEZ, - SPARC_INS_MOVRLZ, - SPARC_INS_MOVRNZ, - SPARC_INS_MOVRZ, - SPARC_INS_MOVSTOSW, - SPARC_INS_MOVSTOUW, - SPARC_INS_MULX, - SPARC_INS_NOP, - SPARC_INS_ORCC, - SPARC_INS_ORNCC, - SPARC_INS_ORN, - SPARC_INS_OR, - SPARC_INS_PDIST, - SPARC_INS_PDISTN, - SPARC_INS_POPC, - SPARC_INS_RD, - SPARC_INS_RESTORE, - SPARC_INS_RETT, - SPARC_INS_SAVE, - SPARC_INS_SDIVCC, - SPARC_INS_SDIVX, - SPARC_INS_SDIV, - SPARC_INS_SETHI, - SPARC_INS_SHUTDOWN, - SPARC_INS_SIAM, - SPARC_INS_SLLX, - SPARC_INS_SLL, - SPARC_INS_SMULCC, - SPARC_INS_SMUL, - SPARC_INS_SRAX, - SPARC_INS_SRA, - SPARC_INS_SRLX, - SPARC_INS_SRL, - SPARC_INS_STBAR, - SPARC_INS_STB, - SPARC_INS_STD, - SPARC_INS_ST, - SPARC_INS_STH, - SPARC_INS_STQ, - SPARC_INS_STX, - SPARC_INS_SUBCC, - SPARC_INS_SUBX, - SPARC_INS_SUBXCC, - SPARC_INS_SUB, - SPARC_INS_SWAP, - SPARC_INS_TADDCCTV, - SPARC_INS_TADDCC, - SPARC_INS_T, - SPARC_INS_TSUBCCTV, - SPARC_INS_TSUBCC, - SPARC_INS_UDIVCC, - SPARC_INS_UDIVX, - SPARC_INS_UDIV, - SPARC_INS_UMULCC, - SPARC_INS_UMULXHI, - SPARC_INS_UMUL, - SPARC_INS_UNIMP, - SPARC_INS_FCMPED, - SPARC_INS_FCMPEQ, - SPARC_INS_FCMPES, - SPARC_INS_WR, - SPARC_INS_XMULX, - SPARC_INS_XMULXHI, - SPARC_INS_XNORCC, - SPARC_INS_XNOR, - SPARC_INS_XORCC, - SPARC_INS_XOR, - - // alias instructions - SPARC_INS_RET, - SPARC_INS_RETL, - - SPARC_INS_ENDING, // <-- mark the end of the list of instructions -} sparc_insn; - -//> Group of SPARC instructions -typedef enum sparc_insn_group -{ - SPARC_GRP_INVALID = 0, // = CS_GRP_INVALID - - //> Generic groups - // all jump instructions (conditional+direct+indirect jumps) - SPARC_GRP_JUMP, // = CS_GRP_JUMP - - //> Architecture-specific groups - SPARC_GRP_HARDQUAD = 128, - SPARC_GRP_V9, - SPARC_GRP_VIS, - SPARC_GRP_VIS2, - SPARC_GRP_VIS3, - SPARC_GRP_32BIT, - SPARC_GRP_64BIT, - - SPARC_GRP_ENDING, // <-- mark the end of the list of groups -} sparc_insn_group; - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef CAPSTONE_SPARC_H +#define CAPSTONE_SPARC_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "platform.h" + +// GCC SPARC toolchain has a default macro called "sparc" which breaks +// compilation +#undef sparc + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> Enums corresponding to Sparc condition codes, both icc's and fcc's. +typedef enum sparc_cc +{ + SPARC_CC_INVALID = 0, // invalid CC (default) + //> Integer condition codes + SPARC_CC_ICC_A = 8 + 256, // Always + SPARC_CC_ICC_N = 0 + 256, // Never + SPARC_CC_ICC_NE = 9 + 256, // Not Equal + SPARC_CC_ICC_E = 1 + 256, // Equal + SPARC_CC_ICC_G = 10 + 256, // Greater + SPARC_CC_ICC_LE = 2 + 256, // Less or Equal + SPARC_CC_ICC_GE = 11 + 256, // Greater or Equal + SPARC_CC_ICC_L = 3 + 256, // Less + SPARC_CC_ICC_GU = 12 + 256, // Greater Unsigned + SPARC_CC_ICC_LEU = 4 + 256, // Less or Equal Unsigned + SPARC_CC_ICC_CC = 13 + 256, // Carry Clear/Great or Equal Unsigned + SPARC_CC_ICC_CS = 5 + 256, // Carry Set/Less Unsigned + SPARC_CC_ICC_POS = 14 + 256, // Positive + SPARC_CC_ICC_NEG = 6 + 256, // Negative + SPARC_CC_ICC_VC = 15 + 256, // Overflow Clear + SPARC_CC_ICC_VS = 7 + 256, // Overflow Set + + //> Floating condition codes + SPARC_CC_FCC_A = 8 + 16 + 256, // Always + SPARC_CC_FCC_N = 0 + 16 + 256, // Never + SPARC_CC_FCC_U = 7 + 16 + 256, // Unordered + SPARC_CC_FCC_G = 6 + 16 + 256, // Greater + SPARC_CC_FCC_UG = 5 + 16 + 256, // Unordered or Greater + SPARC_CC_FCC_L = 4 + 16 + 256, // Less + SPARC_CC_FCC_UL = 3 + 16 + 256, // Unordered or Less + SPARC_CC_FCC_LG = 2 + 16 + 256, // Less or Greater + SPARC_CC_FCC_NE = 1 + 16 + 256, // Not Equal + SPARC_CC_FCC_E = 9 + 16 + 256, // Equal + SPARC_CC_FCC_UE = 10 + 16 + 256, // Unordered or Equal + SPARC_CC_FCC_GE = 11 + 16 + 256, // Greater or Equal + SPARC_CC_FCC_UGE = 12 + 16 + 256, // Unordered or Greater or Equal + SPARC_CC_FCC_LE = 13 + 16 + 256, // Less or Equal + SPARC_CC_FCC_ULE = 14 + 16 + 256, // Unordered or Less or Equal + SPARC_CC_FCC_O = 15 + 16 + 256, // Ordered +} sparc_cc; + +//> Branch hint +typedef enum sparc_hint +{ + SPARC_HINT_INVALID = 0, // no hint + SPARC_HINT_A = 1 << 0, // annul delay slot instruction + SPARC_HINT_PT = 1 << 1, // branch taken + SPARC_HINT_PN = 1 << 2, // branch NOT taken +} sparc_hint; + +//> Operand type for instruction's operands +typedef enum sparc_op_type +{ + SPARC_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + SPARC_OP_REG, // = CS_OP_REG (Register operand). + SPARC_OP_IMM, // = CS_OP_IMM (Immediate operand). + SPARC_OP_MEM, // = CS_OP_MEM (Memory operand). +} sparc_op_type; + +// Instruction's operand referring to memory +// This is associated with SPARC_OP_MEM operand type above +typedef struct sparc_op_mem +{ + uint8_t base; // base register + uint8_t index; // index register + int32_t disp; // displacement/offset value +} sparc_op_mem; + +// Instruction operand +typedef struct cs_sparc_op +{ + sparc_op_type type; // operand type + union + { + unsigned int reg; // register value for REG operand + int32_t imm; // immediate value for IMM operand + sparc_op_mem mem; // base/disp value for MEM operand + }; +} cs_sparc_op; + +// Instruction structure +typedef struct cs_sparc +{ + sparc_cc cc; // code condition for this insn + sparc_hint hint; // branch hint: encoding as bitwise OR of sparc_hint. + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + cs_sparc_op operands[4]; // operands for this instruction. +} cs_sparc; + +//> SPARC registers +typedef enum sparc_reg +{ + SPARC_REG_INVALID = 0, + + SPARC_REG_F0, + SPARC_REG_F1, + SPARC_REG_F2, + SPARC_REG_F3, + SPARC_REG_F4, + SPARC_REG_F5, + SPARC_REG_F6, + SPARC_REG_F7, + SPARC_REG_F8, + SPARC_REG_F9, + SPARC_REG_F10, + SPARC_REG_F11, + SPARC_REG_F12, + SPARC_REG_F13, + SPARC_REG_F14, + SPARC_REG_F15, + SPARC_REG_F16, + SPARC_REG_F17, + SPARC_REG_F18, + SPARC_REG_F19, + SPARC_REG_F20, + SPARC_REG_F21, + SPARC_REG_F22, + SPARC_REG_F23, + SPARC_REG_F24, + SPARC_REG_F25, + SPARC_REG_F26, + SPARC_REG_F27, + SPARC_REG_F28, + SPARC_REG_F29, + SPARC_REG_F30, + SPARC_REG_F31, + SPARC_REG_F32, + SPARC_REG_F34, + SPARC_REG_F36, + SPARC_REG_F38, + SPARC_REG_F40, + SPARC_REG_F42, + SPARC_REG_F44, + SPARC_REG_F46, + SPARC_REG_F48, + SPARC_REG_F50, + SPARC_REG_F52, + SPARC_REG_F54, + SPARC_REG_F56, + SPARC_REG_F58, + SPARC_REG_F60, + SPARC_REG_F62, + SPARC_REG_FCC0, // Floating condition codes + SPARC_REG_FCC1, + SPARC_REG_FCC2, + SPARC_REG_FCC3, + SPARC_REG_FP, + SPARC_REG_G0, + SPARC_REG_G1, + SPARC_REG_G2, + SPARC_REG_G3, + SPARC_REG_G4, + SPARC_REG_G5, + SPARC_REG_G6, + SPARC_REG_G7, + SPARC_REG_I0, + SPARC_REG_I1, + SPARC_REG_I2, + SPARC_REG_I3, + SPARC_REG_I4, + SPARC_REG_I5, + SPARC_REG_I7, + SPARC_REG_ICC, // Integer condition codes + SPARC_REG_L0, + SPARC_REG_L1, + SPARC_REG_L2, + SPARC_REG_L3, + SPARC_REG_L4, + SPARC_REG_L5, + SPARC_REG_L6, + SPARC_REG_L7, + SPARC_REG_O0, + SPARC_REG_O1, + SPARC_REG_O2, + SPARC_REG_O3, + SPARC_REG_O4, + SPARC_REG_O5, + SPARC_REG_O7, + SPARC_REG_SP, + SPARC_REG_Y, + + // special register + SPARC_REG_XCC, + + SPARC_REG_ENDING, // <-- mark the end of the list of registers + + // extras + SPARC_REG_O6 = SPARC_REG_SP, + SPARC_REG_I6 = SPARC_REG_FP, +} sparc_reg; + +//> SPARC instruction +typedef enum sparc_insn +{ + SPARC_INS_INVALID = 0, + + SPARC_INS_ADDCC, + SPARC_INS_ADDX, + SPARC_INS_ADDXCC, + SPARC_INS_ADDXC, + SPARC_INS_ADDXCCC, + SPARC_INS_ADD, + SPARC_INS_ALIGNADDR, + SPARC_INS_ALIGNADDRL, + SPARC_INS_ANDCC, + SPARC_INS_ANDNCC, + SPARC_INS_ANDN, + SPARC_INS_AND, + SPARC_INS_ARRAY16, + SPARC_INS_ARRAY32, + SPARC_INS_ARRAY8, + SPARC_INS_B, + SPARC_INS_JMP, + SPARC_INS_BMASK, + SPARC_INS_FB, + SPARC_INS_BRGEZ, + SPARC_INS_BRGZ, + SPARC_INS_BRLEZ, + SPARC_INS_BRLZ, + SPARC_INS_BRNZ, + SPARC_INS_BRZ, + SPARC_INS_BSHUFFLE, + SPARC_INS_CALL, + SPARC_INS_CASX, + SPARC_INS_CAS, + SPARC_INS_CMASK16, + SPARC_INS_CMASK32, + SPARC_INS_CMASK8, + SPARC_INS_CMP, + SPARC_INS_EDGE16, + SPARC_INS_EDGE16L, + SPARC_INS_EDGE16LN, + SPARC_INS_EDGE16N, + SPARC_INS_EDGE32, + SPARC_INS_EDGE32L, + SPARC_INS_EDGE32LN, + SPARC_INS_EDGE32N, + SPARC_INS_EDGE8, + SPARC_INS_EDGE8L, + SPARC_INS_EDGE8LN, + SPARC_INS_EDGE8N, + SPARC_INS_FABSD, + SPARC_INS_FABSQ, + SPARC_INS_FABSS, + SPARC_INS_FADDD, + SPARC_INS_FADDQ, + SPARC_INS_FADDS, + SPARC_INS_FALIGNDATA, + SPARC_INS_FAND, + SPARC_INS_FANDNOT1, + SPARC_INS_FANDNOT1S, + SPARC_INS_FANDNOT2, + SPARC_INS_FANDNOT2S, + SPARC_INS_FANDS, + SPARC_INS_FCHKSM16, + SPARC_INS_FCMPD, + SPARC_INS_FCMPEQ16, + SPARC_INS_FCMPEQ32, + SPARC_INS_FCMPGT16, + SPARC_INS_FCMPGT32, + SPARC_INS_FCMPLE16, + SPARC_INS_FCMPLE32, + SPARC_INS_FCMPNE16, + SPARC_INS_FCMPNE32, + SPARC_INS_FCMPQ, + SPARC_INS_FCMPS, + SPARC_INS_FDIVD, + SPARC_INS_FDIVQ, + SPARC_INS_FDIVS, + SPARC_INS_FDMULQ, + SPARC_INS_FDTOI, + SPARC_INS_FDTOQ, + SPARC_INS_FDTOS, + SPARC_INS_FDTOX, + SPARC_INS_FEXPAND, + SPARC_INS_FHADDD, + SPARC_INS_FHADDS, + SPARC_INS_FHSUBD, + SPARC_INS_FHSUBS, + SPARC_INS_FITOD, + SPARC_INS_FITOQ, + SPARC_INS_FITOS, + SPARC_INS_FLCMPD, + SPARC_INS_FLCMPS, + SPARC_INS_FLUSHW, + SPARC_INS_FMEAN16, + SPARC_INS_FMOVD, + SPARC_INS_FMOVQ, + SPARC_INS_FMOVRDGEZ, + SPARC_INS_FMOVRQGEZ, + SPARC_INS_FMOVRSGEZ, + SPARC_INS_FMOVRDGZ, + SPARC_INS_FMOVRQGZ, + SPARC_INS_FMOVRSGZ, + SPARC_INS_FMOVRDLEZ, + SPARC_INS_FMOVRQLEZ, + SPARC_INS_FMOVRSLEZ, + SPARC_INS_FMOVRDLZ, + SPARC_INS_FMOVRQLZ, + SPARC_INS_FMOVRSLZ, + SPARC_INS_FMOVRDNZ, + SPARC_INS_FMOVRQNZ, + SPARC_INS_FMOVRSNZ, + SPARC_INS_FMOVRDZ, + SPARC_INS_FMOVRQZ, + SPARC_INS_FMOVRSZ, + SPARC_INS_FMOVS, + SPARC_INS_FMUL8SUX16, + SPARC_INS_FMUL8ULX16, + SPARC_INS_FMUL8X16, + SPARC_INS_FMUL8X16AL, + SPARC_INS_FMUL8X16AU, + SPARC_INS_FMULD, + SPARC_INS_FMULD8SUX16, + SPARC_INS_FMULD8ULX16, + SPARC_INS_FMULQ, + SPARC_INS_FMULS, + SPARC_INS_FNADDD, + SPARC_INS_FNADDS, + SPARC_INS_FNAND, + SPARC_INS_FNANDS, + SPARC_INS_FNEGD, + SPARC_INS_FNEGQ, + SPARC_INS_FNEGS, + SPARC_INS_FNHADDD, + SPARC_INS_FNHADDS, + SPARC_INS_FNOR, + SPARC_INS_FNORS, + SPARC_INS_FNOT1, + SPARC_INS_FNOT1S, + SPARC_INS_FNOT2, + SPARC_INS_FNOT2S, + SPARC_INS_FONE, + SPARC_INS_FONES, + SPARC_INS_FOR, + SPARC_INS_FORNOT1, + SPARC_INS_FORNOT1S, + SPARC_INS_FORNOT2, + SPARC_INS_FORNOT2S, + SPARC_INS_FORS, + SPARC_INS_FPACK16, + SPARC_INS_FPACK32, + SPARC_INS_FPACKFIX, + SPARC_INS_FPADD16, + SPARC_INS_FPADD16S, + SPARC_INS_FPADD32, + SPARC_INS_FPADD32S, + SPARC_INS_FPADD64, + SPARC_INS_FPMERGE, + SPARC_INS_FPSUB16, + SPARC_INS_FPSUB16S, + SPARC_INS_FPSUB32, + SPARC_INS_FPSUB32S, + SPARC_INS_FQTOD, + SPARC_INS_FQTOI, + SPARC_INS_FQTOS, + SPARC_INS_FQTOX, + SPARC_INS_FSLAS16, + SPARC_INS_FSLAS32, + SPARC_INS_FSLL16, + SPARC_INS_FSLL32, + SPARC_INS_FSMULD, + SPARC_INS_FSQRTD, + SPARC_INS_FSQRTQ, + SPARC_INS_FSQRTS, + SPARC_INS_FSRA16, + SPARC_INS_FSRA32, + SPARC_INS_FSRC1, + SPARC_INS_FSRC1S, + SPARC_INS_FSRC2, + SPARC_INS_FSRC2S, + SPARC_INS_FSRL16, + SPARC_INS_FSRL32, + SPARC_INS_FSTOD, + SPARC_INS_FSTOI, + SPARC_INS_FSTOQ, + SPARC_INS_FSTOX, + SPARC_INS_FSUBD, + SPARC_INS_FSUBQ, + SPARC_INS_FSUBS, + SPARC_INS_FXNOR, + SPARC_INS_FXNORS, + SPARC_INS_FXOR, + SPARC_INS_FXORS, + SPARC_INS_FXTOD, + SPARC_INS_FXTOQ, + SPARC_INS_FXTOS, + SPARC_INS_FZERO, + SPARC_INS_FZEROS, + SPARC_INS_JMPL, + SPARC_INS_LDD, + SPARC_INS_LD, + SPARC_INS_LDQ, + SPARC_INS_LDSB, + SPARC_INS_LDSH, + SPARC_INS_LDSW, + SPARC_INS_LDUB, + SPARC_INS_LDUH, + SPARC_INS_LDX, + SPARC_INS_LZCNT, + SPARC_INS_MEMBAR, + SPARC_INS_MOVDTOX, + SPARC_INS_MOV, + SPARC_INS_MOVRGEZ, + SPARC_INS_MOVRGZ, + SPARC_INS_MOVRLEZ, + SPARC_INS_MOVRLZ, + SPARC_INS_MOVRNZ, + SPARC_INS_MOVRZ, + SPARC_INS_MOVSTOSW, + SPARC_INS_MOVSTOUW, + SPARC_INS_MULX, + SPARC_INS_NOP, + SPARC_INS_ORCC, + SPARC_INS_ORNCC, + SPARC_INS_ORN, + SPARC_INS_OR, + SPARC_INS_PDIST, + SPARC_INS_PDISTN, + SPARC_INS_POPC, + SPARC_INS_RD, + SPARC_INS_RESTORE, + SPARC_INS_RETT, + SPARC_INS_SAVE, + SPARC_INS_SDIVCC, + SPARC_INS_SDIVX, + SPARC_INS_SDIV, + SPARC_INS_SETHI, + SPARC_INS_SHUTDOWN, + SPARC_INS_SIAM, + SPARC_INS_SLLX, + SPARC_INS_SLL, + SPARC_INS_SMULCC, + SPARC_INS_SMUL, + SPARC_INS_SRAX, + SPARC_INS_SRA, + SPARC_INS_SRLX, + SPARC_INS_SRL, + SPARC_INS_STBAR, + SPARC_INS_STB, + SPARC_INS_STD, + SPARC_INS_ST, + SPARC_INS_STH, + SPARC_INS_STQ, + SPARC_INS_STX, + SPARC_INS_SUBCC, + SPARC_INS_SUBX, + SPARC_INS_SUBXCC, + SPARC_INS_SUB, + SPARC_INS_SWAP, + SPARC_INS_TADDCCTV, + SPARC_INS_TADDCC, + SPARC_INS_T, + SPARC_INS_TSUBCCTV, + SPARC_INS_TSUBCC, + SPARC_INS_UDIVCC, + SPARC_INS_UDIVX, + SPARC_INS_UDIV, + SPARC_INS_UMULCC, + SPARC_INS_UMULXHI, + SPARC_INS_UMUL, + SPARC_INS_UNIMP, + SPARC_INS_FCMPED, + SPARC_INS_FCMPEQ, + SPARC_INS_FCMPES, + SPARC_INS_WR, + SPARC_INS_XMULX, + SPARC_INS_XMULXHI, + SPARC_INS_XNORCC, + SPARC_INS_XNOR, + SPARC_INS_XORCC, + SPARC_INS_XOR, + + // alias instructions + SPARC_INS_RET, + SPARC_INS_RETL, + + SPARC_INS_ENDING, // <-- mark the end of the list of instructions +} sparc_insn; + +//> Group of SPARC instructions +typedef enum sparc_insn_group +{ + SPARC_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + SPARC_GRP_JUMP, // = CS_GRP_JUMP + + //> Architecture-specific groups + SPARC_GRP_HARDQUAD = 128, + SPARC_GRP_V9, + SPARC_GRP_VIS, + SPARC_GRP_VIS2, + SPARC_GRP_VIS3, + SPARC_GRP_32BIT, + SPARC_GRP_64BIT, + + SPARC_GRP_ENDING, // <-- mark the end of the list of groups +} sparc_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dbg/capstone/systemz.h b/src/dbg/capstone/systemz.h index e1db382e..0db8cc24 100644 --- a/src/dbg/capstone/systemz.h +++ b/src/dbg/capstone/systemz.h @@ -1,838 +1,838 @@ -#ifndef CAPSTONE_SYSTEMZ_H -#define CAPSTONE_SYSTEMZ_H - -/* Capstone Disassembly Engine */ -/* By Nguyen Anh Quynh , 2014 */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "platform.h" - -#ifdef _MSC_VER -#pragma warning(disable:4201) -#endif - -//> Enums corresponding to SystemZ condition codes -typedef enum sysz_cc -{ - SYSZ_CC_INVALID = 0, // invalid CC (default) - - SYSZ_CC_O, - SYSZ_CC_H, - SYSZ_CC_NLE, - SYSZ_CC_L, - SYSZ_CC_NHE, - SYSZ_CC_LH, - SYSZ_CC_NE, - SYSZ_CC_E, - SYSZ_CC_NLH, - SYSZ_CC_HE, - SYSZ_CC_NL, - SYSZ_CC_LE, - SYSZ_CC_NH, - SYSZ_CC_NO, -} sysz_cc; - -//> Operand type for instruction's operands -typedef enum sysz_op_type -{ - SYSZ_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). - SYSZ_OP_REG, // = CS_OP_REG (Register operand). - SYSZ_OP_IMM, // = CS_OP_IMM (Immediate operand). - SYSZ_OP_MEM, // = CS_OP_MEM (Memory operand). - SYSZ_OP_ACREG = 64, // Access register operand. -} sysz_op_type; - -// Instruction's operand referring to memory -// This is associated with SYSZ_OP_MEM operand type above -typedef struct sysz_op_mem -{ - uint8_t base; // base register - uint8_t index; // index register - uint64_t length; // BDLAddr operand - int64_t disp; // displacement/offset value -} sysz_op_mem; - -// Instruction operand -typedef struct cs_sysz_op -{ - sysz_op_type type; // operand type - union - { - unsigned int reg; // register value for REG operand - int64_t imm; // immediate value for IMM operand - sysz_op_mem mem; // base/disp value for MEM operand - }; -} cs_sysz_op; - -// Instruction structure -typedef struct cs_sysz -{ - sysz_cc cc; // Code condition - // Number of operands of this instruction, - // or 0 when instruction has no operand. - uint8_t op_count; - cs_sysz_op operands[6]; // operands for this instruction. -} cs_sysz; - -//> SystemZ registers -typedef enum sysz_reg -{ - SYSZ_REG_INVALID = 0, - - SYSZ_REG_0, - SYSZ_REG_1, - SYSZ_REG_2, - SYSZ_REG_3, - SYSZ_REG_4, - SYSZ_REG_5, - SYSZ_REG_6, - SYSZ_REG_7, - SYSZ_REG_8, - SYSZ_REG_9, - SYSZ_REG_10, - SYSZ_REG_11, - SYSZ_REG_12, - SYSZ_REG_13, - SYSZ_REG_14, - SYSZ_REG_15, - SYSZ_REG_CC, - SYSZ_REG_F0, - SYSZ_REG_F1, - SYSZ_REG_F2, - SYSZ_REG_F3, - SYSZ_REG_F4, - SYSZ_REG_F5, - SYSZ_REG_F6, - SYSZ_REG_F7, - SYSZ_REG_F8, - SYSZ_REG_F9, - SYSZ_REG_F10, - SYSZ_REG_F11, - SYSZ_REG_F12, - SYSZ_REG_F13, - SYSZ_REG_F14, - SYSZ_REG_F15, - - SYSZ_REG_R0L, - - SYSZ_REG_ENDING, -} sysz_reg; - -//> SystemZ instruction -typedef enum sysz_insn -{ - SYSZ_INS_INVALID = 0, - - SYSZ_INS_A, - SYSZ_INS_ADB, - SYSZ_INS_ADBR, - SYSZ_INS_AEB, - SYSZ_INS_AEBR, - SYSZ_INS_AFI, - SYSZ_INS_AG, - SYSZ_INS_AGF, - SYSZ_INS_AGFI, - SYSZ_INS_AGFR, - SYSZ_INS_AGHI, - SYSZ_INS_AGHIK, - SYSZ_INS_AGR, - SYSZ_INS_AGRK, - SYSZ_INS_AGSI, - SYSZ_INS_AH, - SYSZ_INS_AHI, - SYSZ_INS_AHIK, - SYSZ_INS_AHY, - SYSZ_INS_AIH, - SYSZ_INS_AL, - SYSZ_INS_ALC, - SYSZ_INS_ALCG, - SYSZ_INS_ALCGR, - SYSZ_INS_ALCR, - SYSZ_INS_ALFI, - SYSZ_INS_ALG, - SYSZ_INS_ALGF, - SYSZ_INS_ALGFI, - SYSZ_INS_ALGFR, - SYSZ_INS_ALGHSIK, - SYSZ_INS_ALGR, - SYSZ_INS_ALGRK, - SYSZ_INS_ALHSIK, - SYSZ_INS_ALR, - SYSZ_INS_ALRK, - SYSZ_INS_ALY, - SYSZ_INS_AR, - SYSZ_INS_ARK, - SYSZ_INS_ASI, - SYSZ_INS_AXBR, - SYSZ_INS_AY, - SYSZ_INS_BCR, - SYSZ_INS_BRC, - SYSZ_INS_BRCL, - SYSZ_INS_CGIJ, - SYSZ_INS_CGRJ, - SYSZ_INS_CIJ, - SYSZ_INS_CLGIJ, - SYSZ_INS_CLGRJ, - SYSZ_INS_CLIJ, - SYSZ_INS_CLRJ, - SYSZ_INS_CRJ, - SYSZ_INS_BER, - SYSZ_INS_JE, - SYSZ_INS_JGE, - SYSZ_INS_LOCE, - SYSZ_INS_LOCGE, - SYSZ_INS_LOCGRE, - SYSZ_INS_LOCRE, - SYSZ_INS_STOCE, - SYSZ_INS_STOCGE, - SYSZ_INS_BHR, - SYSZ_INS_BHER, - SYSZ_INS_JHE, - SYSZ_INS_JGHE, - SYSZ_INS_LOCHE, - SYSZ_INS_LOCGHE, - SYSZ_INS_LOCGRHE, - SYSZ_INS_LOCRHE, - SYSZ_INS_STOCHE, - SYSZ_INS_STOCGHE, - SYSZ_INS_JH, - SYSZ_INS_JGH, - SYSZ_INS_LOCH, - SYSZ_INS_LOCGH, - SYSZ_INS_LOCGRH, - SYSZ_INS_LOCRH, - SYSZ_INS_STOCH, - SYSZ_INS_STOCGH, - SYSZ_INS_CGIJNLH, - SYSZ_INS_CGRJNLH, - SYSZ_INS_CIJNLH, - SYSZ_INS_CLGIJNLH, - SYSZ_INS_CLGRJNLH, - SYSZ_INS_CLIJNLH, - SYSZ_INS_CLRJNLH, - SYSZ_INS_CRJNLH, - SYSZ_INS_CGIJE, - SYSZ_INS_CGRJE, - SYSZ_INS_CIJE, - SYSZ_INS_CLGIJE, - SYSZ_INS_CLGRJE, - SYSZ_INS_CLIJE, - SYSZ_INS_CLRJE, - SYSZ_INS_CRJE, - SYSZ_INS_CGIJNLE, - SYSZ_INS_CGRJNLE, - SYSZ_INS_CIJNLE, - SYSZ_INS_CLGIJNLE, - SYSZ_INS_CLGRJNLE, - SYSZ_INS_CLIJNLE, - SYSZ_INS_CLRJNLE, - SYSZ_INS_CRJNLE, - SYSZ_INS_CGIJH, - SYSZ_INS_CGRJH, - SYSZ_INS_CIJH, - SYSZ_INS_CLGIJH, - SYSZ_INS_CLGRJH, - SYSZ_INS_CLIJH, - SYSZ_INS_CLRJH, - SYSZ_INS_CRJH, - SYSZ_INS_CGIJNL, - SYSZ_INS_CGRJNL, - SYSZ_INS_CIJNL, - SYSZ_INS_CLGIJNL, - SYSZ_INS_CLGRJNL, - SYSZ_INS_CLIJNL, - SYSZ_INS_CLRJNL, - SYSZ_INS_CRJNL, - SYSZ_INS_CGIJHE, - SYSZ_INS_CGRJHE, - SYSZ_INS_CIJHE, - SYSZ_INS_CLGIJHE, - SYSZ_INS_CLGRJHE, - SYSZ_INS_CLIJHE, - SYSZ_INS_CLRJHE, - SYSZ_INS_CRJHE, - SYSZ_INS_CGIJNHE, - SYSZ_INS_CGRJNHE, - SYSZ_INS_CIJNHE, - SYSZ_INS_CLGIJNHE, - SYSZ_INS_CLGRJNHE, - SYSZ_INS_CLIJNHE, - SYSZ_INS_CLRJNHE, - SYSZ_INS_CRJNHE, - SYSZ_INS_CGIJL, - SYSZ_INS_CGRJL, - SYSZ_INS_CIJL, - SYSZ_INS_CLGIJL, - SYSZ_INS_CLGRJL, - SYSZ_INS_CLIJL, - SYSZ_INS_CLRJL, - SYSZ_INS_CRJL, - SYSZ_INS_CGIJNH, - SYSZ_INS_CGRJNH, - SYSZ_INS_CIJNH, - SYSZ_INS_CLGIJNH, - SYSZ_INS_CLGRJNH, - SYSZ_INS_CLIJNH, - SYSZ_INS_CLRJNH, - SYSZ_INS_CRJNH, - SYSZ_INS_CGIJLE, - SYSZ_INS_CGRJLE, - SYSZ_INS_CIJLE, - SYSZ_INS_CLGIJLE, - SYSZ_INS_CLGRJLE, - SYSZ_INS_CLIJLE, - SYSZ_INS_CLRJLE, - SYSZ_INS_CRJLE, - SYSZ_INS_CGIJNE, - SYSZ_INS_CGRJNE, - SYSZ_INS_CIJNE, - SYSZ_INS_CLGIJNE, - SYSZ_INS_CLGRJNE, - SYSZ_INS_CLIJNE, - SYSZ_INS_CLRJNE, - SYSZ_INS_CRJNE, - SYSZ_INS_CGIJLH, - SYSZ_INS_CGRJLH, - SYSZ_INS_CIJLH, - SYSZ_INS_CLGIJLH, - SYSZ_INS_CLGRJLH, - SYSZ_INS_CLIJLH, - SYSZ_INS_CLRJLH, - SYSZ_INS_CRJLH, - SYSZ_INS_BLR, - SYSZ_INS_BLER, - SYSZ_INS_JLE, - SYSZ_INS_JGLE, - SYSZ_INS_LOCLE, - SYSZ_INS_LOCGLE, - SYSZ_INS_LOCGRLE, - SYSZ_INS_LOCRLE, - SYSZ_INS_STOCLE, - SYSZ_INS_STOCGLE, - SYSZ_INS_BLHR, - SYSZ_INS_JLH, - SYSZ_INS_JGLH, - SYSZ_INS_LOCLH, - SYSZ_INS_LOCGLH, - SYSZ_INS_LOCGRLH, - SYSZ_INS_LOCRLH, - SYSZ_INS_STOCLH, - SYSZ_INS_STOCGLH, - SYSZ_INS_JL, - SYSZ_INS_JGL, - SYSZ_INS_LOCL, - SYSZ_INS_LOCGL, - SYSZ_INS_LOCGRL, - SYSZ_INS_LOCRL, - SYSZ_INS_LOC, - SYSZ_INS_LOCG, - SYSZ_INS_LOCGR, - SYSZ_INS_LOCR, - SYSZ_INS_STOCL, - SYSZ_INS_STOCGL, - SYSZ_INS_BNER, - SYSZ_INS_JNE, - SYSZ_INS_JGNE, - SYSZ_INS_LOCNE, - SYSZ_INS_LOCGNE, - SYSZ_INS_LOCGRNE, - SYSZ_INS_LOCRNE, - SYSZ_INS_STOCNE, - SYSZ_INS_STOCGNE, - SYSZ_INS_BNHR, - SYSZ_INS_BNHER, - SYSZ_INS_JNHE, - SYSZ_INS_JGNHE, - SYSZ_INS_LOCNHE, - SYSZ_INS_LOCGNHE, - SYSZ_INS_LOCGRNHE, - SYSZ_INS_LOCRNHE, - SYSZ_INS_STOCNHE, - SYSZ_INS_STOCGNHE, - SYSZ_INS_JNH, - SYSZ_INS_JGNH, - SYSZ_INS_LOCNH, - SYSZ_INS_LOCGNH, - SYSZ_INS_LOCGRNH, - SYSZ_INS_LOCRNH, - SYSZ_INS_STOCNH, - SYSZ_INS_STOCGNH, - SYSZ_INS_BNLR, - SYSZ_INS_BNLER, - SYSZ_INS_JNLE, - SYSZ_INS_JGNLE, - SYSZ_INS_LOCNLE, - SYSZ_INS_LOCGNLE, - SYSZ_INS_LOCGRNLE, - SYSZ_INS_LOCRNLE, - SYSZ_INS_STOCNLE, - SYSZ_INS_STOCGNLE, - SYSZ_INS_BNLHR, - SYSZ_INS_JNLH, - SYSZ_INS_JGNLH, - SYSZ_INS_LOCNLH, - SYSZ_INS_LOCGNLH, - SYSZ_INS_LOCGRNLH, - SYSZ_INS_LOCRNLH, - SYSZ_INS_STOCNLH, - SYSZ_INS_STOCGNLH, - SYSZ_INS_JNL, - SYSZ_INS_JGNL, - SYSZ_INS_LOCNL, - SYSZ_INS_LOCGNL, - SYSZ_INS_LOCGRNL, - SYSZ_INS_LOCRNL, - SYSZ_INS_STOCNL, - SYSZ_INS_STOCGNL, - SYSZ_INS_BNOR, - SYSZ_INS_JNO, - SYSZ_INS_JGNO, - SYSZ_INS_LOCNO, - SYSZ_INS_LOCGNO, - SYSZ_INS_LOCGRNO, - SYSZ_INS_LOCRNO, - SYSZ_INS_STOCNO, - SYSZ_INS_STOCGNO, - SYSZ_INS_BOR, - SYSZ_INS_JO, - SYSZ_INS_JGO, - SYSZ_INS_LOCO, - SYSZ_INS_LOCGO, - SYSZ_INS_LOCGRO, - SYSZ_INS_LOCRO, - SYSZ_INS_STOCO, - SYSZ_INS_STOCGO, - SYSZ_INS_STOC, - SYSZ_INS_STOCG, - SYSZ_INS_BASR, - SYSZ_INS_BR, - SYSZ_INS_BRAS, - SYSZ_INS_BRASL, - SYSZ_INS_J, - SYSZ_INS_JG, - SYSZ_INS_BRCT, - SYSZ_INS_BRCTG, - SYSZ_INS_C, - SYSZ_INS_CDB, - SYSZ_INS_CDBR, - SYSZ_INS_CDFBR, - SYSZ_INS_CDGBR, - SYSZ_INS_CDLFBR, - SYSZ_INS_CDLGBR, - SYSZ_INS_CEB, - SYSZ_INS_CEBR, - SYSZ_INS_CEFBR, - SYSZ_INS_CEGBR, - SYSZ_INS_CELFBR, - SYSZ_INS_CELGBR, - SYSZ_INS_CFDBR, - SYSZ_INS_CFEBR, - SYSZ_INS_CFI, - SYSZ_INS_CFXBR, - SYSZ_INS_CG, - SYSZ_INS_CGDBR, - SYSZ_INS_CGEBR, - SYSZ_INS_CGF, - SYSZ_INS_CGFI, - SYSZ_INS_CGFR, - SYSZ_INS_CGFRL, - SYSZ_INS_CGH, - SYSZ_INS_CGHI, - SYSZ_INS_CGHRL, - SYSZ_INS_CGHSI, - SYSZ_INS_CGR, - SYSZ_INS_CGRL, - SYSZ_INS_CGXBR, - SYSZ_INS_CH, - SYSZ_INS_CHF, - SYSZ_INS_CHHSI, - SYSZ_INS_CHI, - SYSZ_INS_CHRL, - SYSZ_INS_CHSI, - SYSZ_INS_CHY, - SYSZ_INS_CIH, - SYSZ_INS_CL, - SYSZ_INS_CLC, - SYSZ_INS_CLFDBR, - SYSZ_INS_CLFEBR, - SYSZ_INS_CLFHSI, - SYSZ_INS_CLFI, - SYSZ_INS_CLFXBR, - SYSZ_INS_CLG, - SYSZ_INS_CLGDBR, - SYSZ_INS_CLGEBR, - SYSZ_INS_CLGF, - SYSZ_INS_CLGFI, - SYSZ_INS_CLGFR, - SYSZ_INS_CLGFRL, - SYSZ_INS_CLGHRL, - SYSZ_INS_CLGHSI, - SYSZ_INS_CLGR, - SYSZ_INS_CLGRL, - SYSZ_INS_CLGXBR, - SYSZ_INS_CLHF, - SYSZ_INS_CLHHSI, - SYSZ_INS_CLHRL, - SYSZ_INS_CLI, - SYSZ_INS_CLIH, - SYSZ_INS_CLIY, - SYSZ_INS_CLR, - SYSZ_INS_CLRL, - SYSZ_INS_CLST, - SYSZ_INS_CLY, - SYSZ_INS_CPSDR, - SYSZ_INS_CR, - SYSZ_INS_CRL, - SYSZ_INS_CS, - SYSZ_INS_CSG, - SYSZ_INS_CSY, - SYSZ_INS_CXBR, - SYSZ_INS_CXFBR, - SYSZ_INS_CXGBR, - SYSZ_INS_CXLFBR, - SYSZ_INS_CXLGBR, - SYSZ_INS_CY, - SYSZ_INS_DDB, - SYSZ_INS_DDBR, - SYSZ_INS_DEB, - SYSZ_INS_DEBR, - SYSZ_INS_DL, - SYSZ_INS_DLG, - SYSZ_INS_DLGR, - SYSZ_INS_DLR, - SYSZ_INS_DSG, - SYSZ_INS_DSGF, - SYSZ_INS_DSGFR, - SYSZ_INS_DSGR, - SYSZ_INS_DXBR, - SYSZ_INS_EAR, - SYSZ_INS_FIDBR, - SYSZ_INS_FIDBRA, - SYSZ_INS_FIEBR, - SYSZ_INS_FIEBRA, - SYSZ_INS_FIXBR, - SYSZ_INS_FIXBRA, - SYSZ_INS_FLOGR, - SYSZ_INS_IC, - SYSZ_INS_ICY, - SYSZ_INS_IIHF, - SYSZ_INS_IIHH, - SYSZ_INS_IIHL, - SYSZ_INS_IILF, - SYSZ_INS_IILH, - SYSZ_INS_IILL, - SYSZ_INS_IPM, - SYSZ_INS_L, - SYSZ_INS_LA, - SYSZ_INS_LAA, - SYSZ_INS_LAAG, - SYSZ_INS_LAAL, - SYSZ_INS_LAALG, - SYSZ_INS_LAN, - SYSZ_INS_LANG, - SYSZ_INS_LAO, - SYSZ_INS_LAOG, - SYSZ_INS_LARL, - SYSZ_INS_LAX, - SYSZ_INS_LAXG, - SYSZ_INS_LAY, - SYSZ_INS_LB, - SYSZ_INS_LBH, - SYSZ_INS_LBR, - SYSZ_INS_LCDBR, - SYSZ_INS_LCEBR, - SYSZ_INS_LCGFR, - SYSZ_INS_LCGR, - SYSZ_INS_LCR, - SYSZ_INS_LCXBR, - SYSZ_INS_LD, - SYSZ_INS_LDEB, - SYSZ_INS_LDEBR, - SYSZ_INS_LDGR, - SYSZ_INS_LDR, - SYSZ_INS_LDXBR, - SYSZ_INS_LDXBRA, - SYSZ_INS_LDY, - SYSZ_INS_LE, - SYSZ_INS_LEDBR, - SYSZ_INS_LEDBRA, - SYSZ_INS_LER, - SYSZ_INS_LEXBR, - SYSZ_INS_LEXBRA, - SYSZ_INS_LEY, - SYSZ_INS_LFH, - SYSZ_INS_LG, - SYSZ_INS_LGB, - SYSZ_INS_LGBR, - SYSZ_INS_LGDR, - SYSZ_INS_LGF, - SYSZ_INS_LGFI, - SYSZ_INS_LGFR, - SYSZ_INS_LGFRL, - SYSZ_INS_LGH, - SYSZ_INS_LGHI, - SYSZ_INS_LGHR, - SYSZ_INS_LGHRL, - SYSZ_INS_LGR, - SYSZ_INS_LGRL, - SYSZ_INS_LH, - SYSZ_INS_LHH, - SYSZ_INS_LHI, - SYSZ_INS_LHR, - SYSZ_INS_LHRL, - SYSZ_INS_LHY, - SYSZ_INS_LLC, - SYSZ_INS_LLCH, - SYSZ_INS_LLCR, - SYSZ_INS_LLGC, - SYSZ_INS_LLGCR, - SYSZ_INS_LLGF, - SYSZ_INS_LLGFR, - SYSZ_INS_LLGFRL, - SYSZ_INS_LLGH, - SYSZ_INS_LLGHR, - SYSZ_INS_LLGHRL, - SYSZ_INS_LLH, - SYSZ_INS_LLHH, - SYSZ_INS_LLHR, - SYSZ_INS_LLHRL, - SYSZ_INS_LLIHF, - SYSZ_INS_LLIHH, - SYSZ_INS_LLIHL, - SYSZ_INS_LLILF, - SYSZ_INS_LLILH, - SYSZ_INS_LLILL, - SYSZ_INS_LMG, - SYSZ_INS_LNDBR, - SYSZ_INS_LNEBR, - SYSZ_INS_LNGFR, - SYSZ_INS_LNGR, - SYSZ_INS_LNR, - SYSZ_INS_LNXBR, - SYSZ_INS_LPDBR, - SYSZ_INS_LPEBR, - SYSZ_INS_LPGFR, - SYSZ_INS_LPGR, - SYSZ_INS_LPR, - SYSZ_INS_LPXBR, - SYSZ_INS_LR, - SYSZ_INS_LRL, - SYSZ_INS_LRV, - SYSZ_INS_LRVG, - SYSZ_INS_LRVGR, - SYSZ_INS_LRVR, - SYSZ_INS_LT, - SYSZ_INS_LTDBR, - SYSZ_INS_LTEBR, - SYSZ_INS_LTG, - SYSZ_INS_LTGF, - SYSZ_INS_LTGFR, - SYSZ_INS_LTGR, - SYSZ_INS_LTR, - SYSZ_INS_LTXBR, - SYSZ_INS_LXDB, - SYSZ_INS_LXDBR, - SYSZ_INS_LXEB, - SYSZ_INS_LXEBR, - SYSZ_INS_LXR, - SYSZ_INS_LY, - SYSZ_INS_LZDR, - SYSZ_INS_LZER, - SYSZ_INS_LZXR, - SYSZ_INS_MADB, - SYSZ_INS_MADBR, - SYSZ_INS_MAEB, - SYSZ_INS_MAEBR, - SYSZ_INS_MDB, - SYSZ_INS_MDBR, - SYSZ_INS_MDEB, - SYSZ_INS_MDEBR, - SYSZ_INS_MEEB, - SYSZ_INS_MEEBR, - SYSZ_INS_MGHI, - SYSZ_INS_MH, - SYSZ_INS_MHI, - SYSZ_INS_MHY, - SYSZ_INS_MLG, - SYSZ_INS_MLGR, - SYSZ_INS_MS, - SYSZ_INS_MSDB, - SYSZ_INS_MSDBR, - SYSZ_INS_MSEB, - SYSZ_INS_MSEBR, - SYSZ_INS_MSFI, - SYSZ_INS_MSG, - SYSZ_INS_MSGF, - SYSZ_INS_MSGFI, - SYSZ_INS_MSGFR, - SYSZ_INS_MSGR, - SYSZ_INS_MSR, - SYSZ_INS_MSY, - SYSZ_INS_MVC, - SYSZ_INS_MVGHI, - SYSZ_INS_MVHHI, - SYSZ_INS_MVHI, - SYSZ_INS_MVI, - SYSZ_INS_MVIY, - SYSZ_INS_MVST, - SYSZ_INS_MXBR, - SYSZ_INS_MXDB, - SYSZ_INS_MXDBR, - SYSZ_INS_N, - SYSZ_INS_NC, - SYSZ_INS_NG, - SYSZ_INS_NGR, - SYSZ_INS_NGRK, - SYSZ_INS_NI, - SYSZ_INS_NIHF, - SYSZ_INS_NIHH, - SYSZ_INS_NIHL, - SYSZ_INS_NILF, - SYSZ_INS_NILH, - SYSZ_INS_NILL, - SYSZ_INS_NIY, - SYSZ_INS_NR, - SYSZ_INS_NRK, - SYSZ_INS_NY, - SYSZ_INS_O, - SYSZ_INS_OC, - SYSZ_INS_OG, - SYSZ_INS_OGR, - SYSZ_INS_OGRK, - SYSZ_INS_OI, - SYSZ_INS_OIHF, - SYSZ_INS_OIHH, - SYSZ_INS_OIHL, - SYSZ_INS_OILF, - SYSZ_INS_OILH, - SYSZ_INS_OILL, - SYSZ_INS_OIY, - SYSZ_INS_OR, - SYSZ_INS_ORK, - SYSZ_INS_OY, - SYSZ_INS_PFD, - SYSZ_INS_PFDRL, - SYSZ_INS_RISBG, - SYSZ_INS_RISBHG, - SYSZ_INS_RISBLG, - SYSZ_INS_RLL, - SYSZ_INS_RLLG, - SYSZ_INS_RNSBG, - SYSZ_INS_ROSBG, - SYSZ_INS_RXSBG, - SYSZ_INS_S, - SYSZ_INS_SDB, - SYSZ_INS_SDBR, - SYSZ_INS_SEB, - SYSZ_INS_SEBR, - SYSZ_INS_SG, - SYSZ_INS_SGF, - SYSZ_INS_SGFR, - SYSZ_INS_SGR, - SYSZ_INS_SGRK, - SYSZ_INS_SH, - SYSZ_INS_SHY, - SYSZ_INS_SL, - SYSZ_INS_SLB, - SYSZ_INS_SLBG, - SYSZ_INS_SLBR, - SYSZ_INS_SLFI, - SYSZ_INS_SLG, - SYSZ_INS_SLBGR, - SYSZ_INS_SLGF, - SYSZ_INS_SLGFI, - SYSZ_INS_SLGFR, - SYSZ_INS_SLGR, - SYSZ_INS_SLGRK, - SYSZ_INS_SLL, - SYSZ_INS_SLLG, - SYSZ_INS_SLLK, - SYSZ_INS_SLR, - SYSZ_INS_SLRK, - SYSZ_INS_SLY, - SYSZ_INS_SQDB, - SYSZ_INS_SQDBR, - SYSZ_INS_SQEB, - SYSZ_INS_SQEBR, - SYSZ_INS_SQXBR, - SYSZ_INS_SR, - SYSZ_INS_SRA, - SYSZ_INS_SRAG, - SYSZ_INS_SRAK, - SYSZ_INS_SRK, - SYSZ_INS_SRL, - SYSZ_INS_SRLG, - SYSZ_INS_SRLK, - SYSZ_INS_SRST, - SYSZ_INS_ST, - SYSZ_INS_STC, - SYSZ_INS_STCH, - SYSZ_INS_STCY, - SYSZ_INS_STD, - SYSZ_INS_STDY, - SYSZ_INS_STE, - SYSZ_INS_STEY, - SYSZ_INS_STFH, - SYSZ_INS_STG, - SYSZ_INS_STGRL, - SYSZ_INS_STH, - SYSZ_INS_STHH, - SYSZ_INS_STHRL, - SYSZ_INS_STHY, - SYSZ_INS_STMG, - SYSZ_INS_STRL, - SYSZ_INS_STRV, - SYSZ_INS_STRVG, - SYSZ_INS_STY, - SYSZ_INS_SXBR, - SYSZ_INS_SY, - SYSZ_INS_TM, - SYSZ_INS_TMHH, - SYSZ_INS_TMHL, - SYSZ_INS_TMLH, - SYSZ_INS_TMLL, - SYSZ_INS_TMY, - SYSZ_INS_X, - SYSZ_INS_XC, - SYSZ_INS_XG, - SYSZ_INS_XGR, - SYSZ_INS_XGRK, - SYSZ_INS_XI, - SYSZ_INS_XIHF, - SYSZ_INS_XILF, - SYSZ_INS_XIY, - SYSZ_INS_XR, - SYSZ_INS_XRK, - SYSZ_INS_XY, - - SYSZ_INS_ENDING, // <-- mark the end of the list of instructions -} sysz_insn; - -//> Group of SystemZ instructions -typedef enum sysz_insn_group -{ - SYSZ_GRP_INVALID = 0, // = CS_GRP_INVALID - - //> Generic groups - // all jump instructions (conditional+direct+indirect jumps) - SYSZ_GRP_JUMP, // = CS_GRP_JUMP - - //> Architecture-specific groups - SYSZ_GRP_DISTINCTOPS = 128, - SYSZ_GRP_FPEXTENSION, - SYSZ_GRP_HIGHWORD, - SYSZ_GRP_INTERLOCKEDACCESS1, - SYSZ_GRP_LOADSTOREONCOND, - - SYSZ_GRP_ENDING, // <-- mark the end of the list of groups -} sysz_insn_group; - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef CAPSTONE_SYSTEMZ_H +#define CAPSTONE_SYSTEMZ_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "platform.h" + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> Enums corresponding to SystemZ condition codes +typedef enum sysz_cc +{ + SYSZ_CC_INVALID = 0, // invalid CC (default) + + SYSZ_CC_O, + SYSZ_CC_H, + SYSZ_CC_NLE, + SYSZ_CC_L, + SYSZ_CC_NHE, + SYSZ_CC_LH, + SYSZ_CC_NE, + SYSZ_CC_E, + SYSZ_CC_NLH, + SYSZ_CC_HE, + SYSZ_CC_NL, + SYSZ_CC_LE, + SYSZ_CC_NH, + SYSZ_CC_NO, +} sysz_cc; + +//> Operand type for instruction's operands +typedef enum sysz_op_type +{ + SYSZ_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + SYSZ_OP_REG, // = CS_OP_REG (Register operand). + SYSZ_OP_IMM, // = CS_OP_IMM (Immediate operand). + SYSZ_OP_MEM, // = CS_OP_MEM (Memory operand). + SYSZ_OP_ACREG = 64, // Access register operand. +} sysz_op_type; + +// Instruction's operand referring to memory +// This is associated with SYSZ_OP_MEM operand type above +typedef struct sysz_op_mem +{ + uint8_t base; // base register + uint8_t index; // index register + uint64_t length; // BDLAddr operand + int64_t disp; // displacement/offset value +} sysz_op_mem; + +// Instruction operand +typedef struct cs_sysz_op +{ + sysz_op_type type; // operand type + union + { + unsigned int reg; // register value for REG operand + int64_t imm; // immediate value for IMM operand + sysz_op_mem mem; // base/disp value for MEM operand + }; +} cs_sysz_op; + +// Instruction structure +typedef struct cs_sysz +{ + sysz_cc cc; // Code condition + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + cs_sysz_op operands[6]; // operands for this instruction. +} cs_sysz; + +//> SystemZ registers +typedef enum sysz_reg +{ + SYSZ_REG_INVALID = 0, + + SYSZ_REG_0, + SYSZ_REG_1, + SYSZ_REG_2, + SYSZ_REG_3, + SYSZ_REG_4, + SYSZ_REG_5, + SYSZ_REG_6, + SYSZ_REG_7, + SYSZ_REG_8, + SYSZ_REG_9, + SYSZ_REG_10, + SYSZ_REG_11, + SYSZ_REG_12, + SYSZ_REG_13, + SYSZ_REG_14, + SYSZ_REG_15, + SYSZ_REG_CC, + SYSZ_REG_F0, + SYSZ_REG_F1, + SYSZ_REG_F2, + SYSZ_REG_F3, + SYSZ_REG_F4, + SYSZ_REG_F5, + SYSZ_REG_F6, + SYSZ_REG_F7, + SYSZ_REG_F8, + SYSZ_REG_F9, + SYSZ_REG_F10, + SYSZ_REG_F11, + SYSZ_REG_F12, + SYSZ_REG_F13, + SYSZ_REG_F14, + SYSZ_REG_F15, + + SYSZ_REG_R0L, + + SYSZ_REG_ENDING, +} sysz_reg; + +//> SystemZ instruction +typedef enum sysz_insn +{ + SYSZ_INS_INVALID = 0, + + SYSZ_INS_A, + SYSZ_INS_ADB, + SYSZ_INS_ADBR, + SYSZ_INS_AEB, + SYSZ_INS_AEBR, + SYSZ_INS_AFI, + SYSZ_INS_AG, + SYSZ_INS_AGF, + SYSZ_INS_AGFI, + SYSZ_INS_AGFR, + SYSZ_INS_AGHI, + SYSZ_INS_AGHIK, + SYSZ_INS_AGR, + SYSZ_INS_AGRK, + SYSZ_INS_AGSI, + SYSZ_INS_AH, + SYSZ_INS_AHI, + SYSZ_INS_AHIK, + SYSZ_INS_AHY, + SYSZ_INS_AIH, + SYSZ_INS_AL, + SYSZ_INS_ALC, + SYSZ_INS_ALCG, + SYSZ_INS_ALCGR, + SYSZ_INS_ALCR, + SYSZ_INS_ALFI, + SYSZ_INS_ALG, + SYSZ_INS_ALGF, + SYSZ_INS_ALGFI, + SYSZ_INS_ALGFR, + SYSZ_INS_ALGHSIK, + SYSZ_INS_ALGR, + SYSZ_INS_ALGRK, + SYSZ_INS_ALHSIK, + SYSZ_INS_ALR, + SYSZ_INS_ALRK, + SYSZ_INS_ALY, + SYSZ_INS_AR, + SYSZ_INS_ARK, + SYSZ_INS_ASI, + SYSZ_INS_AXBR, + SYSZ_INS_AY, + SYSZ_INS_BCR, + SYSZ_INS_BRC, + SYSZ_INS_BRCL, + SYSZ_INS_CGIJ, + SYSZ_INS_CGRJ, + SYSZ_INS_CIJ, + SYSZ_INS_CLGIJ, + SYSZ_INS_CLGRJ, + SYSZ_INS_CLIJ, + SYSZ_INS_CLRJ, + SYSZ_INS_CRJ, + SYSZ_INS_BER, + SYSZ_INS_JE, + SYSZ_INS_JGE, + SYSZ_INS_LOCE, + SYSZ_INS_LOCGE, + SYSZ_INS_LOCGRE, + SYSZ_INS_LOCRE, + SYSZ_INS_STOCE, + SYSZ_INS_STOCGE, + SYSZ_INS_BHR, + SYSZ_INS_BHER, + SYSZ_INS_JHE, + SYSZ_INS_JGHE, + SYSZ_INS_LOCHE, + SYSZ_INS_LOCGHE, + SYSZ_INS_LOCGRHE, + SYSZ_INS_LOCRHE, + SYSZ_INS_STOCHE, + SYSZ_INS_STOCGHE, + SYSZ_INS_JH, + SYSZ_INS_JGH, + SYSZ_INS_LOCH, + SYSZ_INS_LOCGH, + SYSZ_INS_LOCGRH, + SYSZ_INS_LOCRH, + SYSZ_INS_STOCH, + SYSZ_INS_STOCGH, + SYSZ_INS_CGIJNLH, + SYSZ_INS_CGRJNLH, + SYSZ_INS_CIJNLH, + SYSZ_INS_CLGIJNLH, + SYSZ_INS_CLGRJNLH, + SYSZ_INS_CLIJNLH, + SYSZ_INS_CLRJNLH, + SYSZ_INS_CRJNLH, + SYSZ_INS_CGIJE, + SYSZ_INS_CGRJE, + SYSZ_INS_CIJE, + SYSZ_INS_CLGIJE, + SYSZ_INS_CLGRJE, + SYSZ_INS_CLIJE, + SYSZ_INS_CLRJE, + SYSZ_INS_CRJE, + SYSZ_INS_CGIJNLE, + SYSZ_INS_CGRJNLE, + SYSZ_INS_CIJNLE, + SYSZ_INS_CLGIJNLE, + SYSZ_INS_CLGRJNLE, + SYSZ_INS_CLIJNLE, + SYSZ_INS_CLRJNLE, + SYSZ_INS_CRJNLE, + SYSZ_INS_CGIJH, + SYSZ_INS_CGRJH, + SYSZ_INS_CIJH, + SYSZ_INS_CLGIJH, + SYSZ_INS_CLGRJH, + SYSZ_INS_CLIJH, + SYSZ_INS_CLRJH, + SYSZ_INS_CRJH, + SYSZ_INS_CGIJNL, + SYSZ_INS_CGRJNL, + SYSZ_INS_CIJNL, + SYSZ_INS_CLGIJNL, + SYSZ_INS_CLGRJNL, + SYSZ_INS_CLIJNL, + SYSZ_INS_CLRJNL, + SYSZ_INS_CRJNL, + SYSZ_INS_CGIJHE, + SYSZ_INS_CGRJHE, + SYSZ_INS_CIJHE, + SYSZ_INS_CLGIJHE, + SYSZ_INS_CLGRJHE, + SYSZ_INS_CLIJHE, + SYSZ_INS_CLRJHE, + SYSZ_INS_CRJHE, + SYSZ_INS_CGIJNHE, + SYSZ_INS_CGRJNHE, + SYSZ_INS_CIJNHE, + SYSZ_INS_CLGIJNHE, + SYSZ_INS_CLGRJNHE, + SYSZ_INS_CLIJNHE, + SYSZ_INS_CLRJNHE, + SYSZ_INS_CRJNHE, + SYSZ_INS_CGIJL, + SYSZ_INS_CGRJL, + SYSZ_INS_CIJL, + SYSZ_INS_CLGIJL, + SYSZ_INS_CLGRJL, + SYSZ_INS_CLIJL, + SYSZ_INS_CLRJL, + SYSZ_INS_CRJL, + SYSZ_INS_CGIJNH, + SYSZ_INS_CGRJNH, + SYSZ_INS_CIJNH, + SYSZ_INS_CLGIJNH, + SYSZ_INS_CLGRJNH, + SYSZ_INS_CLIJNH, + SYSZ_INS_CLRJNH, + SYSZ_INS_CRJNH, + SYSZ_INS_CGIJLE, + SYSZ_INS_CGRJLE, + SYSZ_INS_CIJLE, + SYSZ_INS_CLGIJLE, + SYSZ_INS_CLGRJLE, + SYSZ_INS_CLIJLE, + SYSZ_INS_CLRJLE, + SYSZ_INS_CRJLE, + SYSZ_INS_CGIJNE, + SYSZ_INS_CGRJNE, + SYSZ_INS_CIJNE, + SYSZ_INS_CLGIJNE, + SYSZ_INS_CLGRJNE, + SYSZ_INS_CLIJNE, + SYSZ_INS_CLRJNE, + SYSZ_INS_CRJNE, + SYSZ_INS_CGIJLH, + SYSZ_INS_CGRJLH, + SYSZ_INS_CIJLH, + SYSZ_INS_CLGIJLH, + SYSZ_INS_CLGRJLH, + SYSZ_INS_CLIJLH, + SYSZ_INS_CLRJLH, + SYSZ_INS_CRJLH, + SYSZ_INS_BLR, + SYSZ_INS_BLER, + SYSZ_INS_JLE, + SYSZ_INS_JGLE, + SYSZ_INS_LOCLE, + SYSZ_INS_LOCGLE, + SYSZ_INS_LOCGRLE, + SYSZ_INS_LOCRLE, + SYSZ_INS_STOCLE, + SYSZ_INS_STOCGLE, + SYSZ_INS_BLHR, + SYSZ_INS_JLH, + SYSZ_INS_JGLH, + SYSZ_INS_LOCLH, + SYSZ_INS_LOCGLH, + SYSZ_INS_LOCGRLH, + SYSZ_INS_LOCRLH, + SYSZ_INS_STOCLH, + SYSZ_INS_STOCGLH, + SYSZ_INS_JL, + SYSZ_INS_JGL, + SYSZ_INS_LOCL, + SYSZ_INS_LOCGL, + SYSZ_INS_LOCGRL, + SYSZ_INS_LOCRL, + SYSZ_INS_LOC, + SYSZ_INS_LOCG, + SYSZ_INS_LOCGR, + SYSZ_INS_LOCR, + SYSZ_INS_STOCL, + SYSZ_INS_STOCGL, + SYSZ_INS_BNER, + SYSZ_INS_JNE, + SYSZ_INS_JGNE, + SYSZ_INS_LOCNE, + SYSZ_INS_LOCGNE, + SYSZ_INS_LOCGRNE, + SYSZ_INS_LOCRNE, + SYSZ_INS_STOCNE, + SYSZ_INS_STOCGNE, + SYSZ_INS_BNHR, + SYSZ_INS_BNHER, + SYSZ_INS_JNHE, + SYSZ_INS_JGNHE, + SYSZ_INS_LOCNHE, + SYSZ_INS_LOCGNHE, + SYSZ_INS_LOCGRNHE, + SYSZ_INS_LOCRNHE, + SYSZ_INS_STOCNHE, + SYSZ_INS_STOCGNHE, + SYSZ_INS_JNH, + SYSZ_INS_JGNH, + SYSZ_INS_LOCNH, + SYSZ_INS_LOCGNH, + SYSZ_INS_LOCGRNH, + SYSZ_INS_LOCRNH, + SYSZ_INS_STOCNH, + SYSZ_INS_STOCGNH, + SYSZ_INS_BNLR, + SYSZ_INS_BNLER, + SYSZ_INS_JNLE, + SYSZ_INS_JGNLE, + SYSZ_INS_LOCNLE, + SYSZ_INS_LOCGNLE, + SYSZ_INS_LOCGRNLE, + SYSZ_INS_LOCRNLE, + SYSZ_INS_STOCNLE, + SYSZ_INS_STOCGNLE, + SYSZ_INS_BNLHR, + SYSZ_INS_JNLH, + SYSZ_INS_JGNLH, + SYSZ_INS_LOCNLH, + SYSZ_INS_LOCGNLH, + SYSZ_INS_LOCGRNLH, + SYSZ_INS_LOCRNLH, + SYSZ_INS_STOCNLH, + SYSZ_INS_STOCGNLH, + SYSZ_INS_JNL, + SYSZ_INS_JGNL, + SYSZ_INS_LOCNL, + SYSZ_INS_LOCGNL, + SYSZ_INS_LOCGRNL, + SYSZ_INS_LOCRNL, + SYSZ_INS_STOCNL, + SYSZ_INS_STOCGNL, + SYSZ_INS_BNOR, + SYSZ_INS_JNO, + SYSZ_INS_JGNO, + SYSZ_INS_LOCNO, + SYSZ_INS_LOCGNO, + SYSZ_INS_LOCGRNO, + SYSZ_INS_LOCRNO, + SYSZ_INS_STOCNO, + SYSZ_INS_STOCGNO, + SYSZ_INS_BOR, + SYSZ_INS_JO, + SYSZ_INS_JGO, + SYSZ_INS_LOCO, + SYSZ_INS_LOCGO, + SYSZ_INS_LOCGRO, + SYSZ_INS_LOCRO, + SYSZ_INS_STOCO, + SYSZ_INS_STOCGO, + SYSZ_INS_STOC, + SYSZ_INS_STOCG, + SYSZ_INS_BASR, + SYSZ_INS_BR, + SYSZ_INS_BRAS, + SYSZ_INS_BRASL, + SYSZ_INS_J, + SYSZ_INS_JG, + SYSZ_INS_BRCT, + SYSZ_INS_BRCTG, + SYSZ_INS_C, + SYSZ_INS_CDB, + SYSZ_INS_CDBR, + SYSZ_INS_CDFBR, + SYSZ_INS_CDGBR, + SYSZ_INS_CDLFBR, + SYSZ_INS_CDLGBR, + SYSZ_INS_CEB, + SYSZ_INS_CEBR, + SYSZ_INS_CEFBR, + SYSZ_INS_CEGBR, + SYSZ_INS_CELFBR, + SYSZ_INS_CELGBR, + SYSZ_INS_CFDBR, + SYSZ_INS_CFEBR, + SYSZ_INS_CFI, + SYSZ_INS_CFXBR, + SYSZ_INS_CG, + SYSZ_INS_CGDBR, + SYSZ_INS_CGEBR, + SYSZ_INS_CGF, + SYSZ_INS_CGFI, + SYSZ_INS_CGFR, + SYSZ_INS_CGFRL, + SYSZ_INS_CGH, + SYSZ_INS_CGHI, + SYSZ_INS_CGHRL, + SYSZ_INS_CGHSI, + SYSZ_INS_CGR, + SYSZ_INS_CGRL, + SYSZ_INS_CGXBR, + SYSZ_INS_CH, + SYSZ_INS_CHF, + SYSZ_INS_CHHSI, + SYSZ_INS_CHI, + SYSZ_INS_CHRL, + SYSZ_INS_CHSI, + SYSZ_INS_CHY, + SYSZ_INS_CIH, + SYSZ_INS_CL, + SYSZ_INS_CLC, + SYSZ_INS_CLFDBR, + SYSZ_INS_CLFEBR, + SYSZ_INS_CLFHSI, + SYSZ_INS_CLFI, + SYSZ_INS_CLFXBR, + SYSZ_INS_CLG, + SYSZ_INS_CLGDBR, + SYSZ_INS_CLGEBR, + SYSZ_INS_CLGF, + SYSZ_INS_CLGFI, + SYSZ_INS_CLGFR, + SYSZ_INS_CLGFRL, + SYSZ_INS_CLGHRL, + SYSZ_INS_CLGHSI, + SYSZ_INS_CLGR, + SYSZ_INS_CLGRL, + SYSZ_INS_CLGXBR, + SYSZ_INS_CLHF, + SYSZ_INS_CLHHSI, + SYSZ_INS_CLHRL, + SYSZ_INS_CLI, + SYSZ_INS_CLIH, + SYSZ_INS_CLIY, + SYSZ_INS_CLR, + SYSZ_INS_CLRL, + SYSZ_INS_CLST, + SYSZ_INS_CLY, + SYSZ_INS_CPSDR, + SYSZ_INS_CR, + SYSZ_INS_CRL, + SYSZ_INS_CS, + SYSZ_INS_CSG, + SYSZ_INS_CSY, + SYSZ_INS_CXBR, + SYSZ_INS_CXFBR, + SYSZ_INS_CXGBR, + SYSZ_INS_CXLFBR, + SYSZ_INS_CXLGBR, + SYSZ_INS_CY, + SYSZ_INS_DDB, + SYSZ_INS_DDBR, + SYSZ_INS_DEB, + SYSZ_INS_DEBR, + SYSZ_INS_DL, + SYSZ_INS_DLG, + SYSZ_INS_DLGR, + SYSZ_INS_DLR, + SYSZ_INS_DSG, + SYSZ_INS_DSGF, + SYSZ_INS_DSGFR, + SYSZ_INS_DSGR, + SYSZ_INS_DXBR, + SYSZ_INS_EAR, + SYSZ_INS_FIDBR, + SYSZ_INS_FIDBRA, + SYSZ_INS_FIEBR, + SYSZ_INS_FIEBRA, + SYSZ_INS_FIXBR, + SYSZ_INS_FIXBRA, + SYSZ_INS_FLOGR, + SYSZ_INS_IC, + SYSZ_INS_ICY, + SYSZ_INS_IIHF, + SYSZ_INS_IIHH, + SYSZ_INS_IIHL, + SYSZ_INS_IILF, + SYSZ_INS_IILH, + SYSZ_INS_IILL, + SYSZ_INS_IPM, + SYSZ_INS_L, + SYSZ_INS_LA, + SYSZ_INS_LAA, + SYSZ_INS_LAAG, + SYSZ_INS_LAAL, + SYSZ_INS_LAALG, + SYSZ_INS_LAN, + SYSZ_INS_LANG, + SYSZ_INS_LAO, + SYSZ_INS_LAOG, + SYSZ_INS_LARL, + SYSZ_INS_LAX, + SYSZ_INS_LAXG, + SYSZ_INS_LAY, + SYSZ_INS_LB, + SYSZ_INS_LBH, + SYSZ_INS_LBR, + SYSZ_INS_LCDBR, + SYSZ_INS_LCEBR, + SYSZ_INS_LCGFR, + SYSZ_INS_LCGR, + SYSZ_INS_LCR, + SYSZ_INS_LCXBR, + SYSZ_INS_LD, + SYSZ_INS_LDEB, + SYSZ_INS_LDEBR, + SYSZ_INS_LDGR, + SYSZ_INS_LDR, + SYSZ_INS_LDXBR, + SYSZ_INS_LDXBRA, + SYSZ_INS_LDY, + SYSZ_INS_LE, + SYSZ_INS_LEDBR, + SYSZ_INS_LEDBRA, + SYSZ_INS_LER, + SYSZ_INS_LEXBR, + SYSZ_INS_LEXBRA, + SYSZ_INS_LEY, + SYSZ_INS_LFH, + SYSZ_INS_LG, + SYSZ_INS_LGB, + SYSZ_INS_LGBR, + SYSZ_INS_LGDR, + SYSZ_INS_LGF, + SYSZ_INS_LGFI, + SYSZ_INS_LGFR, + SYSZ_INS_LGFRL, + SYSZ_INS_LGH, + SYSZ_INS_LGHI, + SYSZ_INS_LGHR, + SYSZ_INS_LGHRL, + SYSZ_INS_LGR, + SYSZ_INS_LGRL, + SYSZ_INS_LH, + SYSZ_INS_LHH, + SYSZ_INS_LHI, + SYSZ_INS_LHR, + SYSZ_INS_LHRL, + SYSZ_INS_LHY, + SYSZ_INS_LLC, + SYSZ_INS_LLCH, + SYSZ_INS_LLCR, + SYSZ_INS_LLGC, + SYSZ_INS_LLGCR, + SYSZ_INS_LLGF, + SYSZ_INS_LLGFR, + SYSZ_INS_LLGFRL, + SYSZ_INS_LLGH, + SYSZ_INS_LLGHR, + SYSZ_INS_LLGHRL, + SYSZ_INS_LLH, + SYSZ_INS_LLHH, + SYSZ_INS_LLHR, + SYSZ_INS_LLHRL, + SYSZ_INS_LLIHF, + SYSZ_INS_LLIHH, + SYSZ_INS_LLIHL, + SYSZ_INS_LLILF, + SYSZ_INS_LLILH, + SYSZ_INS_LLILL, + SYSZ_INS_LMG, + SYSZ_INS_LNDBR, + SYSZ_INS_LNEBR, + SYSZ_INS_LNGFR, + SYSZ_INS_LNGR, + SYSZ_INS_LNR, + SYSZ_INS_LNXBR, + SYSZ_INS_LPDBR, + SYSZ_INS_LPEBR, + SYSZ_INS_LPGFR, + SYSZ_INS_LPGR, + SYSZ_INS_LPR, + SYSZ_INS_LPXBR, + SYSZ_INS_LR, + SYSZ_INS_LRL, + SYSZ_INS_LRV, + SYSZ_INS_LRVG, + SYSZ_INS_LRVGR, + SYSZ_INS_LRVR, + SYSZ_INS_LT, + SYSZ_INS_LTDBR, + SYSZ_INS_LTEBR, + SYSZ_INS_LTG, + SYSZ_INS_LTGF, + SYSZ_INS_LTGFR, + SYSZ_INS_LTGR, + SYSZ_INS_LTR, + SYSZ_INS_LTXBR, + SYSZ_INS_LXDB, + SYSZ_INS_LXDBR, + SYSZ_INS_LXEB, + SYSZ_INS_LXEBR, + SYSZ_INS_LXR, + SYSZ_INS_LY, + SYSZ_INS_LZDR, + SYSZ_INS_LZER, + SYSZ_INS_LZXR, + SYSZ_INS_MADB, + SYSZ_INS_MADBR, + SYSZ_INS_MAEB, + SYSZ_INS_MAEBR, + SYSZ_INS_MDB, + SYSZ_INS_MDBR, + SYSZ_INS_MDEB, + SYSZ_INS_MDEBR, + SYSZ_INS_MEEB, + SYSZ_INS_MEEBR, + SYSZ_INS_MGHI, + SYSZ_INS_MH, + SYSZ_INS_MHI, + SYSZ_INS_MHY, + SYSZ_INS_MLG, + SYSZ_INS_MLGR, + SYSZ_INS_MS, + SYSZ_INS_MSDB, + SYSZ_INS_MSDBR, + SYSZ_INS_MSEB, + SYSZ_INS_MSEBR, + SYSZ_INS_MSFI, + SYSZ_INS_MSG, + SYSZ_INS_MSGF, + SYSZ_INS_MSGFI, + SYSZ_INS_MSGFR, + SYSZ_INS_MSGR, + SYSZ_INS_MSR, + SYSZ_INS_MSY, + SYSZ_INS_MVC, + SYSZ_INS_MVGHI, + SYSZ_INS_MVHHI, + SYSZ_INS_MVHI, + SYSZ_INS_MVI, + SYSZ_INS_MVIY, + SYSZ_INS_MVST, + SYSZ_INS_MXBR, + SYSZ_INS_MXDB, + SYSZ_INS_MXDBR, + SYSZ_INS_N, + SYSZ_INS_NC, + SYSZ_INS_NG, + SYSZ_INS_NGR, + SYSZ_INS_NGRK, + SYSZ_INS_NI, + SYSZ_INS_NIHF, + SYSZ_INS_NIHH, + SYSZ_INS_NIHL, + SYSZ_INS_NILF, + SYSZ_INS_NILH, + SYSZ_INS_NILL, + SYSZ_INS_NIY, + SYSZ_INS_NR, + SYSZ_INS_NRK, + SYSZ_INS_NY, + SYSZ_INS_O, + SYSZ_INS_OC, + SYSZ_INS_OG, + SYSZ_INS_OGR, + SYSZ_INS_OGRK, + SYSZ_INS_OI, + SYSZ_INS_OIHF, + SYSZ_INS_OIHH, + SYSZ_INS_OIHL, + SYSZ_INS_OILF, + SYSZ_INS_OILH, + SYSZ_INS_OILL, + SYSZ_INS_OIY, + SYSZ_INS_OR, + SYSZ_INS_ORK, + SYSZ_INS_OY, + SYSZ_INS_PFD, + SYSZ_INS_PFDRL, + SYSZ_INS_RISBG, + SYSZ_INS_RISBHG, + SYSZ_INS_RISBLG, + SYSZ_INS_RLL, + SYSZ_INS_RLLG, + SYSZ_INS_RNSBG, + SYSZ_INS_ROSBG, + SYSZ_INS_RXSBG, + SYSZ_INS_S, + SYSZ_INS_SDB, + SYSZ_INS_SDBR, + SYSZ_INS_SEB, + SYSZ_INS_SEBR, + SYSZ_INS_SG, + SYSZ_INS_SGF, + SYSZ_INS_SGFR, + SYSZ_INS_SGR, + SYSZ_INS_SGRK, + SYSZ_INS_SH, + SYSZ_INS_SHY, + SYSZ_INS_SL, + SYSZ_INS_SLB, + SYSZ_INS_SLBG, + SYSZ_INS_SLBR, + SYSZ_INS_SLFI, + SYSZ_INS_SLG, + SYSZ_INS_SLBGR, + SYSZ_INS_SLGF, + SYSZ_INS_SLGFI, + SYSZ_INS_SLGFR, + SYSZ_INS_SLGR, + SYSZ_INS_SLGRK, + SYSZ_INS_SLL, + SYSZ_INS_SLLG, + SYSZ_INS_SLLK, + SYSZ_INS_SLR, + SYSZ_INS_SLRK, + SYSZ_INS_SLY, + SYSZ_INS_SQDB, + SYSZ_INS_SQDBR, + SYSZ_INS_SQEB, + SYSZ_INS_SQEBR, + SYSZ_INS_SQXBR, + SYSZ_INS_SR, + SYSZ_INS_SRA, + SYSZ_INS_SRAG, + SYSZ_INS_SRAK, + SYSZ_INS_SRK, + SYSZ_INS_SRL, + SYSZ_INS_SRLG, + SYSZ_INS_SRLK, + SYSZ_INS_SRST, + SYSZ_INS_ST, + SYSZ_INS_STC, + SYSZ_INS_STCH, + SYSZ_INS_STCY, + SYSZ_INS_STD, + SYSZ_INS_STDY, + SYSZ_INS_STE, + SYSZ_INS_STEY, + SYSZ_INS_STFH, + SYSZ_INS_STG, + SYSZ_INS_STGRL, + SYSZ_INS_STH, + SYSZ_INS_STHH, + SYSZ_INS_STHRL, + SYSZ_INS_STHY, + SYSZ_INS_STMG, + SYSZ_INS_STRL, + SYSZ_INS_STRV, + SYSZ_INS_STRVG, + SYSZ_INS_STY, + SYSZ_INS_SXBR, + SYSZ_INS_SY, + SYSZ_INS_TM, + SYSZ_INS_TMHH, + SYSZ_INS_TMHL, + SYSZ_INS_TMLH, + SYSZ_INS_TMLL, + SYSZ_INS_TMY, + SYSZ_INS_X, + SYSZ_INS_XC, + SYSZ_INS_XG, + SYSZ_INS_XGR, + SYSZ_INS_XGRK, + SYSZ_INS_XI, + SYSZ_INS_XIHF, + SYSZ_INS_XILF, + SYSZ_INS_XIY, + SYSZ_INS_XR, + SYSZ_INS_XRK, + SYSZ_INS_XY, + + SYSZ_INS_ENDING, // <-- mark the end of the list of instructions +} sysz_insn; + +//> Group of SystemZ instructions +typedef enum sysz_insn_group +{ + SYSZ_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + SYSZ_GRP_JUMP, // = CS_GRP_JUMP + + //> Architecture-specific groups + SYSZ_GRP_DISTINCTOPS = 128, + SYSZ_GRP_FPEXTENSION, + SYSZ_GRP_HIGHWORD, + SYSZ_GRP_INTERLOCKEDACCESS1, + SYSZ_GRP_LOADSTOREONCOND, + + SYSZ_GRP_ENDING, // <-- mark the end of the list of groups +} sysz_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dbg/capstone/x86.h b/src/dbg/capstone/x86.h index 20f0d98f..cb083b1a 100644 --- a/src/dbg/capstone/x86.h +++ b/src/dbg/capstone/x86.h @@ -1,1641 +1,1641 @@ -#ifndef CAPSTONE_X86_H -#define CAPSTONE_X86_H - -/* Capstone Disassembly Engine */ -/* By Nguyen Anh Quynh , 2013-2014 */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -// Calculate relative address for X86-64, given cs_insn structure -#define X86_REL_ADDR(insn) (insn.address + insn.size + insn.detail->x86.disp) - -//> X86 registers -typedef enum x86_reg -{ - X86_REG_INVALID = 0, - X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_BH, X86_REG_BL, - X86_REG_BP, X86_REG_BPL, X86_REG_BX, X86_REG_CH, X86_REG_CL, - X86_REG_CS, X86_REG_CX, X86_REG_DH, X86_REG_DI, X86_REG_DIL, - X86_REG_DL, X86_REG_DS, X86_REG_DX, X86_REG_EAX, X86_REG_EBP, - X86_REG_EBX, X86_REG_ECX, X86_REG_EDI, X86_REG_EDX, X86_REG_EFLAGS, - X86_REG_EIP, X86_REG_EIZ, X86_REG_ES, X86_REG_ESI, X86_REG_ESP, - X86_REG_FPSW, X86_REG_FS, X86_REG_GS, X86_REG_IP, X86_REG_RAX, - X86_REG_RBP, X86_REG_RBX, X86_REG_RCX, X86_REG_RDI, X86_REG_RDX, - X86_REG_RIP, X86_REG_RIZ, X86_REG_RSI, X86_REG_RSP, X86_REG_SI, - X86_REG_SIL, X86_REG_SP, X86_REG_SPL, X86_REG_SS, X86_REG_CR0, - X86_REG_CR1, X86_REG_CR2, X86_REG_CR3, X86_REG_CR4, X86_REG_CR5, - X86_REG_CR6, X86_REG_CR7, X86_REG_CR8, X86_REG_CR9, X86_REG_CR10, - X86_REG_CR11, X86_REG_CR12, X86_REG_CR13, X86_REG_CR14, X86_REG_CR15, - X86_REG_DR0, X86_REG_DR1, X86_REG_DR2, X86_REG_DR3, X86_REG_DR4, - X86_REG_DR5, X86_REG_DR6, X86_REG_DR7, X86_REG_FP0, X86_REG_FP1, - X86_REG_FP2, X86_REG_FP3, X86_REG_FP4, X86_REG_FP5, X86_REG_FP6, X86_REG_FP7, - X86_REG_K0, X86_REG_K1, X86_REG_K2, X86_REG_K3, X86_REG_K4, - X86_REG_K5, X86_REG_K6, X86_REG_K7, X86_REG_MM0, X86_REG_MM1, - X86_REG_MM2, X86_REG_MM3, X86_REG_MM4, X86_REG_MM5, X86_REG_MM6, - X86_REG_MM7, X86_REG_R8, X86_REG_R9, X86_REG_R10, X86_REG_R11, - X86_REG_R12, X86_REG_R13, X86_REG_R14, X86_REG_R15, - X86_REG_ST0, X86_REG_ST1, X86_REG_ST2, X86_REG_ST3, - X86_REG_ST4, X86_REG_ST5, X86_REG_ST6, X86_REG_ST7, - X86_REG_XMM0, X86_REG_XMM1, X86_REG_XMM2, X86_REG_XMM3, X86_REG_XMM4, - X86_REG_XMM5, X86_REG_XMM6, X86_REG_XMM7, X86_REG_XMM8, X86_REG_XMM9, - X86_REG_XMM10, X86_REG_XMM11, X86_REG_XMM12, X86_REG_XMM13, X86_REG_XMM14, - X86_REG_XMM15, X86_REG_XMM16, X86_REG_XMM17, X86_REG_XMM18, X86_REG_XMM19, - X86_REG_XMM20, X86_REG_XMM21, X86_REG_XMM22, X86_REG_XMM23, X86_REG_XMM24, - X86_REG_XMM25, X86_REG_XMM26, X86_REG_XMM27, X86_REG_XMM28, X86_REG_XMM29, - X86_REG_XMM30, X86_REG_XMM31, X86_REG_YMM0, X86_REG_YMM1, X86_REG_YMM2, - X86_REG_YMM3, X86_REG_YMM4, X86_REG_YMM5, X86_REG_YMM6, X86_REG_YMM7, - X86_REG_YMM8, X86_REG_YMM9, X86_REG_YMM10, X86_REG_YMM11, X86_REG_YMM12, - X86_REG_YMM13, X86_REG_YMM14, X86_REG_YMM15, X86_REG_YMM16, X86_REG_YMM17, - X86_REG_YMM18, X86_REG_YMM19, X86_REG_YMM20, X86_REG_YMM21, X86_REG_YMM22, - X86_REG_YMM23, X86_REG_YMM24, X86_REG_YMM25, X86_REG_YMM26, X86_REG_YMM27, - X86_REG_YMM28, X86_REG_YMM29, X86_REG_YMM30, X86_REG_YMM31, X86_REG_ZMM0, - X86_REG_ZMM1, X86_REG_ZMM2, X86_REG_ZMM3, X86_REG_ZMM4, X86_REG_ZMM5, - X86_REG_ZMM6, X86_REG_ZMM7, X86_REG_ZMM8, X86_REG_ZMM9, X86_REG_ZMM10, - X86_REG_ZMM11, X86_REG_ZMM12, X86_REG_ZMM13, X86_REG_ZMM14, X86_REG_ZMM15, - X86_REG_ZMM16, X86_REG_ZMM17, X86_REG_ZMM18, X86_REG_ZMM19, X86_REG_ZMM20, - X86_REG_ZMM21, X86_REG_ZMM22, X86_REG_ZMM23, X86_REG_ZMM24, X86_REG_ZMM25, - X86_REG_ZMM26, X86_REG_ZMM27, X86_REG_ZMM28, X86_REG_ZMM29, X86_REG_ZMM30, - X86_REG_ZMM31, X86_REG_R8B, X86_REG_R9B, X86_REG_R10B, X86_REG_R11B, - X86_REG_R12B, X86_REG_R13B, X86_REG_R14B, X86_REG_R15B, X86_REG_R8D, - X86_REG_R9D, X86_REG_R10D, X86_REG_R11D, X86_REG_R12D, X86_REG_R13D, - X86_REG_R14D, X86_REG_R15D, X86_REG_R8W, X86_REG_R9W, X86_REG_R10W, - X86_REG_R11W, X86_REG_R12W, X86_REG_R13W, X86_REG_R14W, X86_REG_R15W, - - X86_REG_ENDING // <-- mark the end of the list of registers -} x86_reg; - -//> Operand type for instruction's operands -typedef enum x86_op_type -{ - X86_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). - X86_OP_REG, // = CS_OP_REG (Register operand). - X86_OP_IMM, // = CS_OP_IMM (Immediate operand). - X86_OP_MEM, // = CS_OP_MEM (Memory operand). - X86_OP_FP, // = CS_OP_FP (Floating-Point operand). -} x86_op_type; - -//> AVX broadcast type -typedef enum x86_avx_bcast -{ - X86_AVX_BCAST_INVALID = 0, // Uninitialized. - X86_AVX_BCAST_2, // AVX512 broadcast type {1to2} - X86_AVX_BCAST_4, // AVX512 broadcast type {1to4} - X86_AVX_BCAST_8, // AVX512 broadcast type {1to8} - X86_AVX_BCAST_16, // AVX512 broadcast type {1to16} -} x86_avx_bcast; - -//> SSE Code Condition type -typedef enum x86_sse_cc -{ - X86_SSE_CC_INVALID = 0, // Uninitialized. - X86_SSE_CC_EQ, - X86_SSE_CC_LT, - X86_SSE_CC_LE, - X86_SSE_CC_UNORD, - X86_SSE_CC_NEQ, - X86_SSE_CC_NLT, - X86_SSE_CC_NLE, - X86_SSE_CC_ORD, - X86_SSE_CC_EQ_UQ, - X86_SSE_CC_NGE, - X86_SSE_CC_NGT, - X86_SSE_CC_FALSE, - X86_SSE_CC_NEQ_OQ, - X86_SSE_CC_GE, - X86_SSE_CC_GT, - X86_SSE_CC_TRUE, -} x86_sse_cc; - -//> AVX Code Condition type -typedef enum x86_avx_cc -{ - X86_AVX_CC_INVALID = 0, // Uninitialized. - X86_AVX_CC_EQ, - X86_AVX_CC_LT, - X86_AVX_CC_LE, - X86_AVX_CC_UNORD, - X86_AVX_CC_NEQ, - X86_AVX_CC_NLT, - X86_AVX_CC_NLE, - X86_AVX_CC_ORD, - X86_AVX_CC_EQ_UQ, - X86_AVX_CC_NGE, - X86_AVX_CC_NGT, - X86_AVX_CC_FALSE, - X86_AVX_CC_NEQ_OQ, - X86_AVX_CC_GE, - X86_AVX_CC_GT, - X86_AVX_CC_TRUE, - X86_AVX_CC_EQ_OS, - X86_AVX_CC_LT_OQ, - X86_AVX_CC_LE_OQ, - X86_AVX_CC_UNORD_S, - X86_AVX_CC_NEQ_US, - X86_AVX_CC_NLT_UQ, - X86_AVX_CC_NLE_UQ, - X86_AVX_CC_ORD_S, - X86_AVX_CC_EQ_US, - X86_AVX_CC_NGE_UQ, - X86_AVX_CC_NGT_UQ, - X86_AVX_CC_FALSE_OS, - X86_AVX_CC_NEQ_OS, - X86_AVX_CC_GE_OQ, - X86_AVX_CC_GT_OQ, - X86_AVX_CC_TRUE_US, -} x86_avx_cc; - -//> AVX static rounding mode type -typedef enum x86_avx_rm -{ - X86_AVX_RM_INVALID = 0, // Uninitialized. - X86_AVX_RM_RN, // Round to nearest - X86_AVX_RM_RD, // Round down - X86_AVX_RM_RU, // Round up - X86_AVX_RM_RZ, // Round toward zero -} x86_avx_rm; - -//> Instruction prefixes - to be used in cs_x86.prefix[] -typedef enum x86_prefix -{ - X86_PREFIX_LOCK = 0xf0, // lock (cs_x86.prefix[0] - X86_PREFIX_REP = 0xf3, // rep (cs_x86.prefix[0] - X86_PREFIX_REPNE = 0xf2, // repne (cs_x86.prefix[0] - - X86_PREFIX_CS = 0x2e, // segment override CS (cs_x86.prefix[1] - X86_PREFIX_SS = 0x36, // segment override SS (cs_x86.prefix[1] - X86_PREFIX_DS = 0x3e, // segment override DS (cs_x86.prefix[1] - X86_PREFIX_ES = 0x26, // segment override ES (cs_x86.prefix[1] - X86_PREFIX_FS = 0x64, // segment override FS (cs_x86.prefix[1] - X86_PREFIX_GS = 0x65, // segment override GS (cs_x86.prefix[1] - - X86_PREFIX_OPSIZE = 0x66, // operand-size override (cs_x86.prefix[2] - X86_PREFIX_ADDRSIZE = 0x67, // address-size override (cs_x86.prefix[3] -} x86_prefix; - -// Instruction's operand referring to memory -// This is associated with X86_OP_MEM operand type above -typedef struct x86_op_mem -{ - unsigned int segment; // segment register (or X86_REG_INVALID if irrelevant) - unsigned int base; // base register (or X86_REG_INVALID if irrelevant) - unsigned int index; // index register (or X86_REG_INVALID if irrelevant) - int scale; // scale for index register - int64_t disp; // displacement value -} x86_op_mem; - -// Instruction operand -typedef struct cs_x86_op -{ - x86_op_type type; // operand type - union - { - x86_reg reg; // register value for REG operand - int64_t imm; // immediate value for IMM operand - double fp; // floating point value for FP operand - x86_op_mem mem; // base/index/scale/disp value for MEM operand - }; - - // size of this operand (in bytes). - uint8_t size; - - // AVX broadcast type, or 0 if irrelevant - x86_avx_bcast avx_bcast; - - // AVX zero opmask {z} - bool avx_zero_opmask; -} cs_x86_op; - -// Instruction structure -typedef struct cs_x86 -{ - // Instruction prefix, which can be up to 4 bytes. - // A prefix byte gets value 0 when irrelevant. - // prefix[0] indicates REP/REPNE/LOCK prefix (See X86_PREFIX_REP/REPNE/LOCK above) - // prefix[1] indicates segment override (irrelevant for x86_64): - // See X86_PREFIX_CS/SS/DS/ES/FS/GS above. - // prefix[2] indicates operand-size override (X86_PREFIX_OPSIZE) - // prefix[3] indicates address-size override (X86_PREFIX_ADDRSIZE) - uint8_t prefix[4]; - - // Instruction opcode, wich can be from 1 to 4 bytes in size. - // This contains VEX opcode as well. - // An trailing opcode byte gets value 0 when irrelevant. - uint8_t opcode[4]; - - // REX prefix: only a non-zero value is relavant for x86_64 - uint8_t rex; - - // Address size, which can be overrided with above prefix[5]. - uint8_t addr_size; - - // ModR/M byte - uint8_t modrm; - - // SIB value, or 0 when irrelevant. - uint8_t sib; - - // Displacement value, or 0 when irrelevant. - int32_t disp; - - /* SIB state */ - // SIB index register, or X86_REG_INVALID when irrelevant. - x86_reg sib_index; - // SIB scale. only applicable if sib_index is relavant. - int8_t sib_scale; - // SIB base register, or X86_REG_INVALID when irrelevant. - x86_reg sib_base; - - // SSE Code Condition - x86_sse_cc sse_cc; - - // AVX Code Condition - x86_avx_cc avx_cc; - - // AVX Suppress all Exception - bool avx_sae; - - // AVX static rounding mode - x86_avx_rm avx_rm; - - // Number of operands of this instruction, - // or 0 when instruction has no operand. - uint8_t op_count; - - cs_x86_op operands[8]; // operands for this instruction. -} cs_x86; - -//> X86 instructions -typedef enum x86_insn -{ - X86_INS_INVALID = 0, - - X86_INS_AAA, - X86_INS_AAD, - X86_INS_AAM, - X86_INS_AAS, - X86_INS_FABS, - X86_INS_ADC, - X86_INS_ADCX, - X86_INS_ADD, - X86_INS_ADDPD, - X86_INS_ADDPS, - X86_INS_ADDSD, - X86_INS_ADDSS, - X86_INS_ADDSUBPD, - X86_INS_ADDSUBPS, - X86_INS_FADD, - X86_INS_FIADD, - X86_INS_FADDP, - X86_INS_ADOX, - X86_INS_AESDECLAST, - X86_INS_AESDEC, - X86_INS_AESENCLAST, - X86_INS_AESENC, - X86_INS_AESIMC, - X86_INS_AESKEYGENASSIST, - X86_INS_AND, - X86_INS_ANDN, - X86_INS_ANDNPD, - X86_INS_ANDNPS, - X86_INS_ANDPD, - X86_INS_ANDPS, - X86_INS_ARPL, - X86_INS_BEXTR, - X86_INS_BLCFILL, - X86_INS_BLCI, - X86_INS_BLCIC, - X86_INS_BLCMSK, - X86_INS_BLCS, - X86_INS_BLENDPD, - X86_INS_BLENDPS, - X86_INS_BLENDVPD, - X86_INS_BLENDVPS, - X86_INS_BLSFILL, - X86_INS_BLSI, - X86_INS_BLSIC, - X86_INS_BLSMSK, - X86_INS_BLSR, - X86_INS_BOUND, - X86_INS_BSF, - X86_INS_BSR, - X86_INS_BSWAP, - X86_INS_BT, - X86_INS_BTC, - X86_INS_BTR, - X86_INS_BTS, - X86_INS_BZHI, - X86_INS_CALL, - X86_INS_CBW, - X86_INS_CDQ, - X86_INS_CDQE, - X86_INS_FCHS, - X86_INS_CLAC, - X86_INS_CLC, - X86_INS_CLD, - X86_INS_CLFLUSH, - X86_INS_CLGI, - X86_INS_CLI, - X86_INS_CLTS, - X86_INS_CMC, - X86_INS_CMOVA, - X86_INS_CMOVAE, - X86_INS_CMOVB, - X86_INS_CMOVBE, - X86_INS_FCMOVBE, - X86_INS_FCMOVB, - X86_INS_CMOVE, - X86_INS_FCMOVE, - X86_INS_CMOVG, - X86_INS_CMOVGE, - X86_INS_CMOVL, - X86_INS_CMOVLE, - X86_INS_FCMOVNBE, - X86_INS_FCMOVNB, - X86_INS_CMOVNE, - X86_INS_FCMOVNE, - X86_INS_CMOVNO, - X86_INS_CMOVNP, - X86_INS_FCMOVNU, - X86_INS_CMOVNS, - X86_INS_CMOVO, - X86_INS_CMOVP, - X86_INS_FCMOVU, - X86_INS_CMOVS, - X86_INS_CMP, - X86_INS_CMPPD, - X86_INS_CMPPS, - X86_INS_CMPSB, - X86_INS_CMPSD, - X86_INS_CMPSQ, - X86_INS_CMPSS, - X86_INS_CMPSW, - X86_INS_CMPXCHG16B, - X86_INS_CMPXCHG, - X86_INS_CMPXCHG8B, - X86_INS_COMISD, - X86_INS_COMISS, - X86_INS_FCOMP, - X86_INS_FCOMPI, - X86_INS_FCOMI, - X86_INS_FCOM, - X86_INS_FCOS, - X86_INS_CPUID, - X86_INS_CQO, - X86_INS_CRC32, - X86_INS_CVTDQ2PD, - X86_INS_CVTDQ2PS, - X86_INS_CVTPD2DQ, - X86_INS_CVTPD2PS, - X86_INS_CVTPS2DQ, - X86_INS_CVTPS2PD, - X86_INS_CVTSD2SI, - X86_INS_CVTSD2SS, - X86_INS_CVTSI2SD, - X86_INS_CVTSI2SS, - X86_INS_CVTSS2SD, - X86_INS_CVTSS2SI, - X86_INS_CVTTPD2DQ, - X86_INS_CVTTPS2DQ, - X86_INS_CVTTSD2SI, - X86_INS_CVTTSS2SI, - X86_INS_CWD, - X86_INS_CWDE, - X86_INS_DAA, - X86_INS_DAS, - X86_INS_DATA16, - X86_INS_DEC, - X86_INS_DIV, - X86_INS_DIVPD, - X86_INS_DIVPS, - X86_INS_FDIVR, - X86_INS_FIDIVR, - X86_INS_FDIVRP, - X86_INS_DIVSD, - X86_INS_DIVSS, - X86_INS_FDIV, - X86_INS_FIDIV, - X86_INS_FDIVP, - X86_INS_DPPD, - X86_INS_DPPS, - X86_INS_RET, - X86_INS_ENCLS, - X86_INS_ENCLU, - X86_INS_ENTER, - X86_INS_EXTRACTPS, - X86_INS_EXTRQ, - X86_INS_F2XM1, - X86_INS_LCALL, - X86_INS_LJMP, - X86_INS_FBLD, - X86_INS_FBSTP, - X86_INS_FCOMPP, - X86_INS_FDECSTP, - X86_INS_FEMMS, - X86_INS_FFREE, - X86_INS_FICOM, - X86_INS_FICOMP, - X86_INS_FINCSTP, - X86_INS_FLDCW, - X86_INS_FLDENV, - X86_INS_FLDL2E, - X86_INS_FLDL2T, - X86_INS_FLDLG2, - X86_INS_FLDLN2, - X86_INS_FLDPI, - X86_INS_FNCLEX, - X86_INS_FNINIT, - X86_INS_FNOP, - X86_INS_FNSTCW, - X86_INS_FNSTSW, - X86_INS_FPATAN, - X86_INS_FPREM, - X86_INS_FPREM1, - X86_INS_FPTAN, - X86_INS_FRNDINT, - X86_INS_FRSTOR, - X86_INS_FNSAVE, - X86_INS_FSCALE, - X86_INS_FSETPM, - X86_INS_FSINCOS, - X86_INS_FNSTENV, - X86_INS_FXAM, - X86_INS_FXRSTOR, - X86_INS_FXRSTOR64, - X86_INS_FXSAVE, - X86_INS_FXSAVE64, - X86_INS_FXTRACT, - X86_INS_FYL2X, - X86_INS_FYL2XP1, - X86_INS_MOVAPD, - X86_INS_MOVAPS, - X86_INS_ORPD, - X86_INS_ORPS, - X86_INS_VMOVAPD, - X86_INS_VMOVAPS, - X86_INS_XORPD, - X86_INS_XORPS, - X86_INS_GETSEC, - X86_INS_HADDPD, - X86_INS_HADDPS, - X86_INS_HLT, - X86_INS_HSUBPD, - X86_INS_HSUBPS, - X86_INS_IDIV, - X86_INS_FILD, - X86_INS_IMUL, - X86_INS_IN, - X86_INS_INC, - X86_INS_INSB, - X86_INS_INSERTPS, - X86_INS_INSERTQ, - X86_INS_INSD, - X86_INS_INSW, - X86_INS_INT, - X86_INS_INT1, - X86_INS_INT3, - X86_INS_INTO, - X86_INS_INVD, - X86_INS_INVEPT, - X86_INS_INVLPG, - X86_INS_INVLPGA, - X86_INS_INVPCID, - X86_INS_INVVPID, - X86_INS_IRET, - X86_INS_IRETD, - X86_INS_IRETQ, - X86_INS_FISTTP, - X86_INS_FIST, - X86_INS_FISTP, - X86_INS_UCOMISD, - X86_INS_UCOMISS, - X86_INS_VCMP, - X86_INS_VCOMISD, - X86_INS_VCOMISS, - X86_INS_VCVTSD2SS, - X86_INS_VCVTSI2SD, - X86_INS_VCVTSI2SS, - X86_INS_VCVTSS2SD, - X86_INS_VCVTTSD2SI, - X86_INS_VCVTTSD2USI, - X86_INS_VCVTTSS2SI, - X86_INS_VCVTTSS2USI, - X86_INS_VCVTUSI2SD, - X86_INS_VCVTUSI2SS, - X86_INS_VUCOMISD, - X86_INS_VUCOMISS, - X86_INS_JAE, - X86_INS_JA, - X86_INS_JBE, - X86_INS_JB, - X86_INS_JCXZ, - X86_INS_JECXZ, - X86_INS_JE, - X86_INS_JGE, - X86_INS_JG, - X86_INS_JLE, - X86_INS_JL, - X86_INS_JMP, - X86_INS_JNE, - X86_INS_JNO, - X86_INS_JNP, - X86_INS_JNS, - X86_INS_JO, - X86_INS_JP, - X86_INS_JRCXZ, - X86_INS_JS, - X86_INS_KANDB, - X86_INS_KANDD, - X86_INS_KANDNB, - X86_INS_KANDND, - X86_INS_KANDNQ, - X86_INS_KANDNW, - X86_INS_KANDQ, - X86_INS_KANDW, - X86_INS_KMOVB, - X86_INS_KMOVD, - X86_INS_KMOVQ, - X86_INS_KMOVW, - X86_INS_KNOTB, - X86_INS_KNOTD, - X86_INS_KNOTQ, - X86_INS_KNOTW, - X86_INS_KORB, - X86_INS_KORD, - X86_INS_KORQ, - X86_INS_KORTESTW, - X86_INS_KORW, - X86_INS_KSHIFTLW, - X86_INS_KSHIFTRW, - X86_INS_KUNPCKBW, - X86_INS_KXNORB, - X86_INS_KXNORD, - X86_INS_KXNORQ, - X86_INS_KXNORW, - X86_INS_KXORB, - X86_INS_KXORD, - X86_INS_KXORQ, - X86_INS_KXORW, - X86_INS_LAHF, - X86_INS_LAR, - X86_INS_LDDQU, - X86_INS_LDMXCSR, - X86_INS_LDS, - X86_INS_FLDZ, - X86_INS_FLD1, - X86_INS_FLD, - X86_INS_LEA, - X86_INS_LEAVE, - X86_INS_LES, - X86_INS_LFENCE, - X86_INS_LFS, - X86_INS_LGDT, - X86_INS_LGS, - X86_INS_LIDT, - X86_INS_LLDT, - X86_INS_LMSW, - X86_INS_OR, - X86_INS_SUB, - X86_INS_XOR, - X86_INS_LODSB, - X86_INS_LODSD, - X86_INS_LODSQ, - X86_INS_LODSW, - X86_INS_LOOP, - X86_INS_LOOPE, - X86_INS_LOOPNE, - X86_INS_RETF, - X86_INS_RETFQ, - X86_INS_LSL, - X86_INS_LSS, - X86_INS_LTR, - X86_INS_XADD, - X86_INS_LZCNT, - X86_INS_MASKMOVDQU, - X86_INS_MAXPD, - X86_INS_MAXPS, - X86_INS_MAXSD, - X86_INS_MAXSS, - X86_INS_MFENCE, - X86_INS_MINPD, - X86_INS_MINPS, - X86_INS_MINSD, - X86_INS_MINSS, - X86_INS_CVTPD2PI, - X86_INS_CVTPI2PD, - X86_INS_CVTPI2PS, - X86_INS_CVTPS2PI, - X86_INS_CVTTPD2PI, - X86_INS_CVTTPS2PI, - X86_INS_EMMS, - X86_INS_MASKMOVQ, - X86_INS_MOVD, - X86_INS_MOVDQ2Q, - X86_INS_MOVNTQ, - X86_INS_MOVQ2DQ, - X86_INS_MOVQ, - X86_INS_PABSB, - X86_INS_PABSD, - X86_INS_PABSW, - X86_INS_PACKSSDW, - X86_INS_PACKSSWB, - X86_INS_PACKUSWB, - X86_INS_PADDB, - X86_INS_PADDD, - X86_INS_PADDQ, - X86_INS_PADDSB, - X86_INS_PADDSW, - X86_INS_PADDUSB, - X86_INS_PADDUSW, - X86_INS_PADDW, - X86_INS_PALIGNR, - X86_INS_PANDN, - X86_INS_PAND, - X86_INS_PAVGB, - X86_INS_PAVGW, - X86_INS_PCMPEQB, - X86_INS_PCMPEQD, - X86_INS_PCMPEQW, - X86_INS_PCMPGTB, - X86_INS_PCMPGTD, - X86_INS_PCMPGTW, - X86_INS_PEXTRW, - X86_INS_PHADDSW, - X86_INS_PHADDW, - X86_INS_PHADDD, - X86_INS_PHSUBD, - X86_INS_PHSUBSW, - X86_INS_PHSUBW, - X86_INS_PINSRW, - X86_INS_PMADDUBSW, - X86_INS_PMADDWD, - X86_INS_PMAXSW, - X86_INS_PMAXUB, - X86_INS_PMINSW, - X86_INS_PMINUB, - X86_INS_PMOVMSKB, - X86_INS_PMULHRSW, - X86_INS_PMULHUW, - X86_INS_PMULHW, - X86_INS_PMULLW, - X86_INS_PMULUDQ, - X86_INS_POR, - X86_INS_PSADBW, - X86_INS_PSHUFB, - X86_INS_PSHUFW, - X86_INS_PSIGNB, - X86_INS_PSIGND, - X86_INS_PSIGNW, - X86_INS_PSLLD, - X86_INS_PSLLQ, - X86_INS_PSLLW, - X86_INS_PSRAD, - X86_INS_PSRAW, - X86_INS_PSRLD, - X86_INS_PSRLQ, - X86_INS_PSRLW, - X86_INS_PSUBB, - X86_INS_PSUBD, - X86_INS_PSUBQ, - X86_INS_PSUBSB, - X86_INS_PSUBSW, - X86_INS_PSUBUSB, - X86_INS_PSUBUSW, - X86_INS_PSUBW, - X86_INS_PUNPCKHBW, - X86_INS_PUNPCKHDQ, - X86_INS_PUNPCKHWD, - X86_INS_PUNPCKLBW, - X86_INS_PUNPCKLDQ, - X86_INS_PUNPCKLWD, - X86_INS_PXOR, - X86_INS_MONITOR, - X86_INS_MONTMUL, - X86_INS_MOV, - X86_INS_MOVABS, - X86_INS_MOVBE, - X86_INS_MOVDDUP, - X86_INS_MOVDQA, - X86_INS_MOVDQU, - X86_INS_MOVHLPS, - X86_INS_MOVHPD, - X86_INS_MOVHPS, - X86_INS_MOVLHPS, - X86_INS_MOVLPD, - X86_INS_MOVLPS, - X86_INS_MOVMSKPD, - X86_INS_MOVMSKPS, - X86_INS_MOVNTDQA, - X86_INS_MOVNTDQ, - X86_INS_MOVNTI, - X86_INS_MOVNTPD, - X86_INS_MOVNTPS, - X86_INS_MOVNTSD, - X86_INS_MOVNTSS, - X86_INS_MOVSB, - X86_INS_MOVSD, - X86_INS_MOVSHDUP, - X86_INS_MOVSLDUP, - X86_INS_MOVSQ, - X86_INS_MOVSS, - X86_INS_MOVSW, - X86_INS_MOVSX, - X86_INS_MOVSXD, - X86_INS_MOVUPD, - X86_INS_MOVUPS, - X86_INS_MOVZX, - X86_INS_MPSADBW, - X86_INS_MUL, - X86_INS_MULPD, - X86_INS_MULPS, - X86_INS_MULSD, - X86_INS_MULSS, - X86_INS_MULX, - X86_INS_FMUL, - X86_INS_FIMUL, - X86_INS_FMULP, - X86_INS_MWAIT, - X86_INS_NEG, - X86_INS_NOP, - X86_INS_NOT, - X86_INS_OUT, - X86_INS_OUTSB, - X86_INS_OUTSD, - X86_INS_OUTSW, - X86_INS_PACKUSDW, - X86_INS_PAUSE, - X86_INS_PAVGUSB, - X86_INS_PBLENDVB, - X86_INS_PBLENDW, - X86_INS_PCLMULQDQ, - X86_INS_PCMPEQQ, - X86_INS_PCMPESTRI, - X86_INS_PCMPESTRM, - X86_INS_PCMPGTQ, - X86_INS_PCMPISTRI, - X86_INS_PCMPISTRM, - X86_INS_PDEP, - X86_INS_PEXT, - X86_INS_PEXTRB, - X86_INS_PEXTRD, - X86_INS_PEXTRQ, - X86_INS_PF2ID, - X86_INS_PF2IW, - X86_INS_PFACC, - X86_INS_PFADD, - X86_INS_PFCMPEQ, - X86_INS_PFCMPGE, - X86_INS_PFCMPGT, - X86_INS_PFMAX, - X86_INS_PFMIN, - X86_INS_PFMUL, - X86_INS_PFNACC, - X86_INS_PFPNACC, - X86_INS_PFRCPIT1, - X86_INS_PFRCPIT2, - X86_INS_PFRCP, - X86_INS_PFRSQIT1, - X86_INS_PFRSQRT, - X86_INS_PFSUBR, - X86_INS_PFSUB, - X86_INS_PHMINPOSUW, - X86_INS_PI2FD, - X86_INS_PI2FW, - X86_INS_PINSRB, - X86_INS_PINSRD, - X86_INS_PINSRQ, - X86_INS_PMAXSB, - X86_INS_PMAXSD, - X86_INS_PMAXUD, - X86_INS_PMAXUW, - X86_INS_PMINSB, - X86_INS_PMINSD, - X86_INS_PMINUD, - X86_INS_PMINUW, - X86_INS_PMOVSXBD, - X86_INS_PMOVSXBQ, - X86_INS_PMOVSXBW, - X86_INS_PMOVSXDQ, - X86_INS_PMOVSXWD, - X86_INS_PMOVSXWQ, - X86_INS_PMOVZXBD, - X86_INS_PMOVZXBQ, - X86_INS_PMOVZXBW, - X86_INS_PMOVZXDQ, - X86_INS_PMOVZXWD, - X86_INS_PMOVZXWQ, - X86_INS_PMULDQ, - X86_INS_PMULHRW, - X86_INS_PMULLD, - X86_INS_POP, - X86_INS_POPAW, - X86_INS_POPAL, - X86_INS_POPCNT, - X86_INS_POPF, - X86_INS_POPFD, - X86_INS_POPFQ, - X86_INS_PREFETCH, - X86_INS_PREFETCHNTA, - X86_INS_PREFETCHT0, - X86_INS_PREFETCHT1, - X86_INS_PREFETCHT2, - X86_INS_PREFETCHW, - X86_INS_PSHUFD, - X86_INS_PSHUFHW, - X86_INS_PSHUFLW, - X86_INS_PSLLDQ, - X86_INS_PSRLDQ, - X86_INS_PSWAPD, - X86_INS_PTEST, - X86_INS_PUNPCKHQDQ, - X86_INS_PUNPCKLQDQ, - X86_INS_PUSH, - X86_INS_PUSHAW, - X86_INS_PUSHAL, - X86_INS_PUSHF, - X86_INS_PUSHFD, - X86_INS_PUSHFQ, - X86_INS_RCL, - X86_INS_RCPPS, - X86_INS_RCPSS, - X86_INS_RCR, - X86_INS_RDFSBASE, - X86_INS_RDGSBASE, - X86_INS_RDMSR, - X86_INS_RDPMC, - X86_INS_RDRAND, - X86_INS_RDSEED, - X86_INS_RDTSC, - X86_INS_RDTSCP, - X86_INS_ROL, - X86_INS_ROR, - X86_INS_RORX, - X86_INS_ROUNDPD, - X86_INS_ROUNDPS, - X86_INS_ROUNDSD, - X86_INS_ROUNDSS, - X86_INS_RSM, - X86_INS_RSQRTPS, - X86_INS_RSQRTSS, - X86_INS_SAHF, - X86_INS_SAL, - X86_INS_SALC, - X86_INS_SAR, - X86_INS_SARX, - X86_INS_SBB, - X86_INS_SCASB, - X86_INS_SCASD, - X86_INS_SCASQ, - X86_INS_SCASW, - X86_INS_SETAE, - X86_INS_SETA, - X86_INS_SETBE, - X86_INS_SETB, - X86_INS_SETE, - X86_INS_SETGE, - X86_INS_SETG, - X86_INS_SETLE, - X86_INS_SETL, - X86_INS_SETNE, - X86_INS_SETNO, - X86_INS_SETNP, - X86_INS_SETNS, - X86_INS_SETO, - X86_INS_SETP, - X86_INS_SETS, - X86_INS_SFENCE, - X86_INS_SGDT, - X86_INS_SHA1MSG1, - X86_INS_SHA1MSG2, - X86_INS_SHA1NEXTE, - X86_INS_SHA1RNDS4, - X86_INS_SHA256MSG1, - X86_INS_SHA256MSG2, - X86_INS_SHA256RNDS2, - X86_INS_SHL, - X86_INS_SHLD, - X86_INS_SHLX, - X86_INS_SHR, - X86_INS_SHRD, - X86_INS_SHRX, - X86_INS_SHUFPD, - X86_INS_SHUFPS, - X86_INS_SIDT, - X86_INS_FSIN, - X86_INS_SKINIT, - X86_INS_SLDT, - X86_INS_SMSW, - X86_INS_SQRTPD, - X86_INS_SQRTPS, - X86_INS_SQRTSD, - X86_INS_SQRTSS, - X86_INS_FSQRT, - X86_INS_STAC, - X86_INS_STC, - X86_INS_STD, - X86_INS_STGI, - X86_INS_STI, - X86_INS_STMXCSR, - X86_INS_STOSB, - X86_INS_STOSD, - X86_INS_STOSQ, - X86_INS_STOSW, - X86_INS_STR, - X86_INS_FST, - X86_INS_FSTP, - X86_INS_FSTPNCE, - X86_INS_SUBPD, - X86_INS_SUBPS, - X86_INS_FSUBR, - X86_INS_FISUBR, - X86_INS_FSUBRP, - X86_INS_SUBSD, - X86_INS_SUBSS, - X86_INS_FSUB, - X86_INS_FISUB, - X86_INS_FSUBP, - X86_INS_SWAPGS, - X86_INS_SYSCALL, - X86_INS_SYSENTER, - X86_INS_SYSEXIT, - X86_INS_SYSRET, - X86_INS_T1MSKC, - X86_INS_TEST, - X86_INS_UD2, - X86_INS_FTST, - X86_INS_TZCNT, - X86_INS_TZMSK, - X86_INS_FUCOMPI, - X86_INS_FUCOMI, - X86_INS_FUCOMPP, - X86_INS_FUCOMP, - X86_INS_FUCOM, - X86_INS_UD2B, - X86_INS_UNPCKHPD, - X86_INS_UNPCKHPS, - X86_INS_UNPCKLPD, - X86_INS_UNPCKLPS, - X86_INS_VADDPD, - X86_INS_VADDPS, - X86_INS_VADDSD, - X86_INS_VADDSS, - X86_INS_VADDSUBPD, - X86_INS_VADDSUBPS, - X86_INS_VAESDECLAST, - X86_INS_VAESDEC, - X86_INS_VAESENCLAST, - X86_INS_VAESENC, - X86_INS_VAESIMC, - X86_INS_VAESKEYGENASSIST, - X86_INS_VALIGND, - X86_INS_VALIGNQ, - X86_INS_VANDNPD, - X86_INS_VANDNPS, - X86_INS_VANDPD, - X86_INS_VANDPS, - X86_INS_VBLENDMPD, - X86_INS_VBLENDMPS, - X86_INS_VBLENDPD, - X86_INS_VBLENDPS, - X86_INS_VBLENDVPD, - X86_INS_VBLENDVPS, - X86_INS_VBROADCASTF128, - X86_INS_VBROADCASTI128, - X86_INS_VBROADCASTI32X4, - X86_INS_VBROADCASTI64X4, - X86_INS_VBROADCASTSD, - X86_INS_VBROADCASTSS, - X86_INS_VCMPPD, - X86_INS_VCMPPS, - X86_INS_VCMPSD, - X86_INS_VCMPSS, - X86_INS_VCVTDQ2PD, - X86_INS_VCVTDQ2PS, - X86_INS_VCVTPD2DQX, - X86_INS_VCVTPD2DQ, - X86_INS_VCVTPD2PSX, - X86_INS_VCVTPD2PS, - X86_INS_VCVTPD2UDQ, - X86_INS_VCVTPH2PS, - X86_INS_VCVTPS2DQ, - X86_INS_VCVTPS2PD, - X86_INS_VCVTPS2PH, - X86_INS_VCVTPS2UDQ, - X86_INS_VCVTSD2SI, - X86_INS_VCVTSD2USI, - X86_INS_VCVTSS2SI, - X86_INS_VCVTSS2USI, - X86_INS_VCVTTPD2DQX, - X86_INS_VCVTTPD2DQ, - X86_INS_VCVTTPD2UDQ, - X86_INS_VCVTTPS2DQ, - X86_INS_VCVTTPS2UDQ, - X86_INS_VCVTUDQ2PD, - X86_INS_VCVTUDQ2PS, - X86_INS_VDIVPD, - X86_INS_VDIVPS, - X86_INS_VDIVSD, - X86_INS_VDIVSS, - X86_INS_VDPPD, - X86_INS_VDPPS, - X86_INS_VERR, - X86_INS_VERW, - X86_INS_VEXTRACTF128, - X86_INS_VEXTRACTF32X4, - X86_INS_VEXTRACTF64X4, - X86_INS_VEXTRACTI128, - X86_INS_VEXTRACTI32X4, - X86_INS_VEXTRACTI64X4, - X86_INS_VEXTRACTPS, - X86_INS_VFMADD132PD, - X86_INS_VFMADD132PS, - X86_INS_VFMADD213PD, - X86_INS_VFMADD213PS, - X86_INS_VFMADDPD, - X86_INS_VFMADD231PD, - X86_INS_VFMADDPS, - X86_INS_VFMADD231PS, - X86_INS_VFMADDSD, - X86_INS_VFMADD213SD, - X86_INS_VFMADD132SD, - X86_INS_VFMADD231SD, - X86_INS_VFMADDSS, - X86_INS_VFMADD213SS, - X86_INS_VFMADD132SS, - X86_INS_VFMADD231SS, - X86_INS_VFMADDSUB132PD, - X86_INS_VFMADDSUB132PS, - X86_INS_VFMADDSUB213PD, - X86_INS_VFMADDSUB213PS, - X86_INS_VFMADDSUBPD, - X86_INS_VFMADDSUB231PD, - X86_INS_VFMADDSUBPS, - X86_INS_VFMADDSUB231PS, - X86_INS_VFMSUB132PD, - X86_INS_VFMSUB132PS, - X86_INS_VFMSUB213PD, - X86_INS_VFMSUB213PS, - X86_INS_VFMSUBADD132PD, - X86_INS_VFMSUBADD132PS, - X86_INS_VFMSUBADD213PD, - X86_INS_VFMSUBADD213PS, - X86_INS_VFMSUBADDPD, - X86_INS_VFMSUBADD231PD, - X86_INS_VFMSUBADDPS, - X86_INS_VFMSUBADD231PS, - X86_INS_VFMSUBPD, - X86_INS_VFMSUB231PD, - X86_INS_VFMSUBPS, - X86_INS_VFMSUB231PS, - X86_INS_VFMSUBSD, - X86_INS_VFMSUB213SD, - X86_INS_VFMSUB132SD, - X86_INS_VFMSUB231SD, - X86_INS_VFMSUBSS, - X86_INS_VFMSUB213SS, - X86_INS_VFMSUB132SS, - X86_INS_VFMSUB231SS, - X86_INS_VFNMADD132PD, - X86_INS_VFNMADD132PS, - X86_INS_VFNMADD213PD, - X86_INS_VFNMADD213PS, - X86_INS_VFNMADDPD, - X86_INS_VFNMADD231PD, - X86_INS_VFNMADDPS, - X86_INS_VFNMADD231PS, - X86_INS_VFNMADDSD, - X86_INS_VFNMADD213SD, - X86_INS_VFNMADD132SD, - X86_INS_VFNMADD231SD, - X86_INS_VFNMADDSS, - X86_INS_VFNMADD213SS, - X86_INS_VFNMADD132SS, - X86_INS_VFNMADD231SS, - X86_INS_VFNMSUB132PD, - X86_INS_VFNMSUB132PS, - X86_INS_VFNMSUB213PD, - X86_INS_VFNMSUB213PS, - X86_INS_VFNMSUBPD, - X86_INS_VFNMSUB231PD, - X86_INS_VFNMSUBPS, - X86_INS_VFNMSUB231PS, - X86_INS_VFNMSUBSD, - X86_INS_VFNMSUB213SD, - X86_INS_VFNMSUB132SD, - X86_INS_VFNMSUB231SD, - X86_INS_VFNMSUBSS, - X86_INS_VFNMSUB213SS, - X86_INS_VFNMSUB132SS, - X86_INS_VFNMSUB231SS, - X86_INS_VFRCZPD, - X86_INS_VFRCZPS, - X86_INS_VFRCZSD, - X86_INS_VFRCZSS, - X86_INS_VORPD, - X86_INS_VORPS, - X86_INS_VXORPD, - X86_INS_VXORPS, - X86_INS_VGATHERDPD, - X86_INS_VGATHERDPS, - X86_INS_VGATHERPF0DPD, - X86_INS_VGATHERPF0DPS, - X86_INS_VGATHERPF0QPD, - X86_INS_VGATHERPF0QPS, - X86_INS_VGATHERPF1DPD, - X86_INS_VGATHERPF1DPS, - X86_INS_VGATHERPF1QPD, - X86_INS_VGATHERPF1QPS, - X86_INS_VGATHERQPD, - X86_INS_VGATHERQPS, - X86_INS_VHADDPD, - X86_INS_VHADDPS, - X86_INS_VHSUBPD, - X86_INS_VHSUBPS, - X86_INS_VINSERTF128, - X86_INS_VINSERTF32X4, - X86_INS_VINSERTF64X4, - X86_INS_VINSERTI128, - X86_INS_VINSERTI32X4, - X86_INS_VINSERTI64X4, - X86_INS_VINSERTPS, - X86_INS_VLDDQU, - X86_INS_VLDMXCSR, - X86_INS_VMASKMOVDQU, - X86_INS_VMASKMOVPD, - X86_INS_VMASKMOVPS, - X86_INS_VMAXPD, - X86_INS_VMAXPS, - X86_INS_VMAXSD, - X86_INS_VMAXSS, - X86_INS_VMCALL, - X86_INS_VMCLEAR, - X86_INS_VMFUNC, - X86_INS_VMINPD, - X86_INS_VMINPS, - X86_INS_VMINSD, - X86_INS_VMINSS, - X86_INS_VMLAUNCH, - X86_INS_VMLOAD, - X86_INS_VMMCALL, - X86_INS_VMOVQ, - X86_INS_VMOVDDUP, - X86_INS_VMOVD, - X86_INS_VMOVDQA32, - X86_INS_VMOVDQA64, - X86_INS_VMOVDQA, - X86_INS_VMOVDQU16, - X86_INS_VMOVDQU32, - X86_INS_VMOVDQU64, - X86_INS_VMOVDQU8, - X86_INS_VMOVDQU, - X86_INS_VMOVHLPS, - X86_INS_VMOVHPD, - X86_INS_VMOVHPS, - X86_INS_VMOVLHPS, - X86_INS_VMOVLPD, - X86_INS_VMOVLPS, - X86_INS_VMOVMSKPD, - X86_INS_VMOVMSKPS, - X86_INS_VMOVNTDQA, - X86_INS_VMOVNTDQ, - X86_INS_VMOVNTPD, - X86_INS_VMOVNTPS, - X86_INS_VMOVSD, - X86_INS_VMOVSHDUP, - X86_INS_VMOVSLDUP, - X86_INS_VMOVSS, - X86_INS_VMOVUPD, - X86_INS_VMOVUPS, - X86_INS_VMPSADBW, - X86_INS_VMPTRLD, - X86_INS_VMPTRST, - X86_INS_VMREAD, - X86_INS_VMRESUME, - X86_INS_VMRUN, - X86_INS_VMSAVE, - X86_INS_VMULPD, - X86_INS_VMULPS, - X86_INS_VMULSD, - X86_INS_VMULSS, - X86_INS_VMWRITE, - X86_INS_VMXOFF, - X86_INS_VMXON, - X86_INS_VPABSB, - X86_INS_VPABSD, - X86_INS_VPABSQ, - X86_INS_VPABSW, - X86_INS_VPACKSSDW, - X86_INS_VPACKSSWB, - X86_INS_VPACKUSDW, - X86_INS_VPACKUSWB, - X86_INS_VPADDB, - X86_INS_VPADDD, - X86_INS_VPADDQ, - X86_INS_VPADDSB, - X86_INS_VPADDSW, - X86_INS_VPADDUSB, - X86_INS_VPADDUSW, - X86_INS_VPADDW, - X86_INS_VPALIGNR, - X86_INS_VPANDD, - X86_INS_VPANDND, - X86_INS_VPANDNQ, - X86_INS_VPANDN, - X86_INS_VPANDQ, - X86_INS_VPAND, - X86_INS_VPAVGB, - X86_INS_VPAVGW, - X86_INS_VPBLENDD, - X86_INS_VPBLENDMD, - X86_INS_VPBLENDMQ, - X86_INS_VPBLENDVB, - X86_INS_VPBLENDW, - X86_INS_VPBROADCASTB, - X86_INS_VPBROADCASTD, - X86_INS_VPBROADCASTMB2Q, - X86_INS_VPBROADCASTMW2D, - X86_INS_VPBROADCASTQ, - X86_INS_VPBROADCASTW, - X86_INS_VPCLMULQDQ, - X86_INS_VPCMOV, - X86_INS_VPCMP, - X86_INS_VPCMPD, - X86_INS_VPCMPEQB, - X86_INS_VPCMPEQD, - X86_INS_VPCMPEQQ, - X86_INS_VPCMPEQW, - X86_INS_VPCMPESTRI, - X86_INS_VPCMPESTRM, - X86_INS_VPCMPGTB, - X86_INS_VPCMPGTD, - X86_INS_VPCMPGTQ, - X86_INS_VPCMPGTW, - X86_INS_VPCMPISTRI, - X86_INS_VPCMPISTRM, - X86_INS_VPCMPQ, - X86_INS_VPCMPUD, - X86_INS_VPCMPUQ, - X86_INS_VPCOMB, - X86_INS_VPCOMD, - X86_INS_VPCOMQ, - X86_INS_VPCOMUB, - X86_INS_VPCOMUD, - X86_INS_VPCOMUQ, - X86_INS_VPCOMUW, - X86_INS_VPCOMW, - X86_INS_VPCONFLICTD, - X86_INS_VPCONFLICTQ, - X86_INS_VPERM2F128, - X86_INS_VPERM2I128, - X86_INS_VPERMD, - X86_INS_VPERMI2D, - X86_INS_VPERMI2PD, - X86_INS_VPERMI2PS, - X86_INS_VPERMI2Q, - X86_INS_VPERMIL2PD, - X86_INS_VPERMIL2PS, - X86_INS_VPERMILPD, - X86_INS_VPERMILPS, - X86_INS_VPERMPD, - X86_INS_VPERMPS, - X86_INS_VPERMQ, - X86_INS_VPERMT2D, - X86_INS_VPERMT2PD, - X86_INS_VPERMT2PS, - X86_INS_VPERMT2Q, - X86_INS_VPEXTRB, - X86_INS_VPEXTRD, - X86_INS_VPEXTRQ, - X86_INS_VPEXTRW, - X86_INS_VPGATHERDD, - X86_INS_VPGATHERDQ, - X86_INS_VPGATHERQD, - X86_INS_VPGATHERQQ, - X86_INS_VPHADDBD, - X86_INS_VPHADDBQ, - X86_INS_VPHADDBW, - X86_INS_VPHADDDQ, - X86_INS_VPHADDD, - X86_INS_VPHADDSW, - X86_INS_VPHADDUBD, - X86_INS_VPHADDUBQ, - X86_INS_VPHADDUBW, - X86_INS_VPHADDUDQ, - X86_INS_VPHADDUWD, - X86_INS_VPHADDUWQ, - X86_INS_VPHADDWD, - X86_INS_VPHADDWQ, - X86_INS_VPHADDW, - X86_INS_VPHMINPOSUW, - X86_INS_VPHSUBBW, - X86_INS_VPHSUBDQ, - X86_INS_VPHSUBD, - X86_INS_VPHSUBSW, - X86_INS_VPHSUBWD, - X86_INS_VPHSUBW, - X86_INS_VPINSRB, - X86_INS_VPINSRD, - X86_INS_VPINSRQ, - X86_INS_VPINSRW, - X86_INS_VPLZCNTD, - X86_INS_VPLZCNTQ, - X86_INS_VPMACSDD, - X86_INS_VPMACSDQH, - X86_INS_VPMACSDQL, - X86_INS_VPMACSSDD, - X86_INS_VPMACSSDQH, - X86_INS_VPMACSSDQL, - X86_INS_VPMACSSWD, - X86_INS_VPMACSSWW, - X86_INS_VPMACSWD, - X86_INS_VPMACSWW, - X86_INS_VPMADCSSWD, - X86_INS_VPMADCSWD, - X86_INS_VPMADDUBSW, - X86_INS_VPMADDWD, - X86_INS_VPMASKMOVD, - X86_INS_VPMASKMOVQ, - X86_INS_VPMAXSB, - X86_INS_VPMAXSD, - X86_INS_VPMAXSQ, - X86_INS_VPMAXSW, - X86_INS_VPMAXUB, - X86_INS_VPMAXUD, - X86_INS_VPMAXUQ, - X86_INS_VPMAXUW, - X86_INS_VPMINSB, - X86_INS_VPMINSD, - X86_INS_VPMINSQ, - X86_INS_VPMINSW, - X86_INS_VPMINUB, - X86_INS_VPMINUD, - X86_INS_VPMINUQ, - X86_INS_VPMINUW, - X86_INS_VPMOVDB, - X86_INS_VPMOVDW, - X86_INS_VPMOVMSKB, - X86_INS_VPMOVQB, - X86_INS_VPMOVQD, - X86_INS_VPMOVQW, - X86_INS_VPMOVSDB, - X86_INS_VPMOVSDW, - X86_INS_VPMOVSQB, - X86_INS_VPMOVSQD, - X86_INS_VPMOVSQW, - X86_INS_VPMOVSXBD, - X86_INS_VPMOVSXBQ, - X86_INS_VPMOVSXBW, - X86_INS_VPMOVSXDQ, - X86_INS_VPMOVSXWD, - X86_INS_VPMOVSXWQ, - X86_INS_VPMOVUSDB, - X86_INS_VPMOVUSDW, - X86_INS_VPMOVUSQB, - X86_INS_VPMOVUSQD, - X86_INS_VPMOVUSQW, - X86_INS_VPMOVZXBD, - X86_INS_VPMOVZXBQ, - X86_INS_VPMOVZXBW, - X86_INS_VPMOVZXDQ, - X86_INS_VPMOVZXWD, - X86_INS_VPMOVZXWQ, - X86_INS_VPMULDQ, - X86_INS_VPMULHRSW, - X86_INS_VPMULHUW, - X86_INS_VPMULHW, - X86_INS_VPMULLD, - X86_INS_VPMULLW, - X86_INS_VPMULUDQ, - X86_INS_VPORD, - X86_INS_VPORQ, - X86_INS_VPOR, - X86_INS_VPPERM, - X86_INS_VPROTB, - X86_INS_VPROTD, - X86_INS_VPROTQ, - X86_INS_VPROTW, - X86_INS_VPSADBW, - X86_INS_VPSCATTERDD, - X86_INS_VPSCATTERDQ, - X86_INS_VPSCATTERQD, - X86_INS_VPSCATTERQQ, - X86_INS_VPSHAB, - X86_INS_VPSHAD, - X86_INS_VPSHAQ, - X86_INS_VPSHAW, - X86_INS_VPSHLB, - X86_INS_VPSHLD, - X86_INS_VPSHLQ, - X86_INS_VPSHLW, - X86_INS_VPSHUFB, - X86_INS_VPSHUFD, - X86_INS_VPSHUFHW, - X86_INS_VPSHUFLW, - X86_INS_VPSIGNB, - X86_INS_VPSIGND, - X86_INS_VPSIGNW, - X86_INS_VPSLLDQ, - X86_INS_VPSLLD, - X86_INS_VPSLLQ, - X86_INS_VPSLLVD, - X86_INS_VPSLLVQ, - X86_INS_VPSLLW, - X86_INS_VPSRAD, - X86_INS_VPSRAQ, - X86_INS_VPSRAVD, - X86_INS_VPSRAVQ, - X86_INS_VPSRAW, - X86_INS_VPSRLDQ, - X86_INS_VPSRLD, - X86_INS_VPSRLQ, - X86_INS_VPSRLVD, - X86_INS_VPSRLVQ, - X86_INS_VPSRLW, - X86_INS_VPSUBB, - X86_INS_VPSUBD, - X86_INS_VPSUBQ, - X86_INS_VPSUBSB, - X86_INS_VPSUBSW, - X86_INS_VPSUBUSB, - X86_INS_VPSUBUSW, - X86_INS_VPSUBW, - X86_INS_VPTESTMD, - X86_INS_VPTESTMQ, - X86_INS_VPTESTNMD, - X86_INS_VPTESTNMQ, - X86_INS_VPTEST, - X86_INS_VPUNPCKHBW, - X86_INS_VPUNPCKHDQ, - X86_INS_VPUNPCKHQDQ, - X86_INS_VPUNPCKHWD, - X86_INS_VPUNPCKLBW, - X86_INS_VPUNPCKLDQ, - X86_INS_VPUNPCKLQDQ, - X86_INS_VPUNPCKLWD, - X86_INS_VPXORD, - X86_INS_VPXORQ, - X86_INS_VPXOR, - X86_INS_VRCP14PD, - X86_INS_VRCP14PS, - X86_INS_VRCP14SD, - X86_INS_VRCP14SS, - X86_INS_VRCP28PD, - X86_INS_VRCP28PS, - X86_INS_VRCP28SD, - X86_INS_VRCP28SS, - X86_INS_VRCPPS, - X86_INS_VRCPSS, - X86_INS_VRNDSCALEPD, - X86_INS_VRNDSCALEPS, - X86_INS_VRNDSCALESD, - X86_INS_VRNDSCALESS, - X86_INS_VROUNDPD, - X86_INS_VROUNDPS, - X86_INS_VROUNDSD, - X86_INS_VROUNDSS, - X86_INS_VRSQRT14PD, - X86_INS_VRSQRT14PS, - X86_INS_VRSQRT14SD, - X86_INS_VRSQRT14SS, - X86_INS_VRSQRT28PD, - X86_INS_VRSQRT28PS, - X86_INS_VRSQRT28SD, - X86_INS_VRSQRT28SS, - X86_INS_VRSQRTPS, - X86_INS_VRSQRTSS, - X86_INS_VSCATTERDPD, - X86_INS_VSCATTERDPS, - X86_INS_VSCATTERPF0DPD, - X86_INS_VSCATTERPF0DPS, - X86_INS_VSCATTERPF0QPD, - X86_INS_VSCATTERPF0QPS, - X86_INS_VSCATTERPF1DPD, - X86_INS_VSCATTERPF1DPS, - X86_INS_VSCATTERPF1QPD, - X86_INS_VSCATTERPF1QPS, - X86_INS_VSCATTERQPD, - X86_INS_VSCATTERQPS, - X86_INS_VSHUFPD, - X86_INS_VSHUFPS, - X86_INS_VSQRTPD, - X86_INS_VSQRTPS, - X86_INS_VSQRTSD, - X86_INS_VSQRTSS, - X86_INS_VSTMXCSR, - X86_INS_VSUBPD, - X86_INS_VSUBPS, - X86_INS_VSUBSD, - X86_INS_VSUBSS, - X86_INS_VTESTPD, - X86_INS_VTESTPS, - X86_INS_VUNPCKHPD, - X86_INS_VUNPCKHPS, - X86_INS_VUNPCKLPD, - X86_INS_VUNPCKLPS, - X86_INS_VZEROALL, - X86_INS_VZEROUPPER, - X86_INS_WAIT, - X86_INS_WBINVD, - X86_INS_WRFSBASE, - X86_INS_WRGSBASE, - X86_INS_WRMSR, - X86_INS_XABORT, - X86_INS_XACQUIRE, - X86_INS_XBEGIN, - X86_INS_XCHG, - X86_INS_FXCH, - X86_INS_XCRYPTCBC, - X86_INS_XCRYPTCFB, - X86_INS_XCRYPTCTR, - X86_INS_XCRYPTECB, - X86_INS_XCRYPTOFB, - X86_INS_XEND, - X86_INS_XGETBV, - X86_INS_XLATB, - X86_INS_XRELEASE, - X86_INS_XRSTOR, - X86_INS_XRSTOR64, - X86_INS_XSAVE, - X86_INS_XSAVE64, - X86_INS_XSAVEOPT, - X86_INS_XSAVEOPT64, - X86_INS_XSETBV, - X86_INS_XSHA1, - X86_INS_XSHA256, - X86_INS_XSTORE, - X86_INS_XTEST, - - X86_INS_ENDING, // mark the end of the list of insn -} x86_insn; - -//> Group of X86 instructions -typedef enum x86_insn_group -{ - X86_GRP_INVALID = 0, // = CS_GRP_INVALID - - //> Generic groups - // all jump instructions (conditional+direct+indirect jumps) - X86_GRP_JUMP, // = CS_GRP_JUMP - // all call instructions - X86_GRP_CALL, // = CS_GRP_CALL - // all return instructions - X86_GRP_RET, // = CS_GRP_RET - // all interrupt instructions (int+syscall) - X86_GRP_INT, // = CS_GRP_INT - // all interrupt return instructions - X86_GRP_IRET, // = CS_GRP_IRET - - //> Architecture-specific groups - X86_GRP_VM = 128, // all virtualization instructions (VT-x + AMD-V) - X86_GRP_3DNOW, - X86_GRP_AES, - X86_GRP_ADX, - X86_GRP_AVX, - X86_GRP_AVX2, - X86_GRP_AVX512, - X86_GRP_BMI, - X86_GRP_BMI2, - X86_GRP_CMOV, - X86_GRP_F16C, - X86_GRP_FMA, - X86_GRP_FMA4, - X86_GRP_FSGSBASE, - X86_GRP_HLE, - X86_GRP_MMX, - X86_GRP_MODE32, - X86_GRP_MODE64, - X86_GRP_RTM, - X86_GRP_SHA, - X86_GRP_SSE1, - X86_GRP_SSE2, - X86_GRP_SSE3, - X86_GRP_SSE41, - X86_GRP_SSE42, - X86_GRP_SSE4A, - X86_GRP_SSSE3, - X86_GRP_PCLMUL, - X86_GRP_XOP, - X86_GRP_CDI, - X86_GRP_ERI, - X86_GRP_TBM, - X86_GRP_16BITMODE, - X86_GRP_NOT64BITMODE, - X86_GRP_SGX, - X86_GRP_DQI, - X86_GRP_BWI, - X86_GRP_PFI, - X86_GRP_VLX, - X86_GRP_SMAP, - X86_GRP_NOVLX, - - X86_GRP_ENDING -} x86_insn_group; - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef CAPSTONE_X86_H +#define CAPSTONE_X86_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2013-2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +// Calculate relative address for X86-64, given cs_insn structure +#define X86_REL_ADDR(insn) (insn.address + insn.size + insn.detail->x86.disp) + +//> X86 registers +typedef enum x86_reg +{ + X86_REG_INVALID = 0, + X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_BH, X86_REG_BL, + X86_REG_BP, X86_REG_BPL, X86_REG_BX, X86_REG_CH, X86_REG_CL, + X86_REG_CS, X86_REG_CX, X86_REG_DH, X86_REG_DI, X86_REG_DIL, + X86_REG_DL, X86_REG_DS, X86_REG_DX, X86_REG_EAX, X86_REG_EBP, + X86_REG_EBX, X86_REG_ECX, X86_REG_EDI, X86_REG_EDX, X86_REG_EFLAGS, + X86_REG_EIP, X86_REG_EIZ, X86_REG_ES, X86_REG_ESI, X86_REG_ESP, + X86_REG_FPSW, X86_REG_FS, X86_REG_GS, X86_REG_IP, X86_REG_RAX, + X86_REG_RBP, X86_REG_RBX, X86_REG_RCX, X86_REG_RDI, X86_REG_RDX, + X86_REG_RIP, X86_REG_RIZ, X86_REG_RSI, X86_REG_RSP, X86_REG_SI, + X86_REG_SIL, X86_REG_SP, X86_REG_SPL, X86_REG_SS, X86_REG_CR0, + X86_REG_CR1, X86_REG_CR2, X86_REG_CR3, X86_REG_CR4, X86_REG_CR5, + X86_REG_CR6, X86_REG_CR7, X86_REG_CR8, X86_REG_CR9, X86_REG_CR10, + X86_REG_CR11, X86_REG_CR12, X86_REG_CR13, X86_REG_CR14, X86_REG_CR15, + X86_REG_DR0, X86_REG_DR1, X86_REG_DR2, X86_REG_DR3, X86_REG_DR4, + X86_REG_DR5, X86_REG_DR6, X86_REG_DR7, X86_REG_FP0, X86_REG_FP1, + X86_REG_FP2, X86_REG_FP3, X86_REG_FP4, X86_REG_FP5, X86_REG_FP6, X86_REG_FP7, + X86_REG_K0, X86_REG_K1, X86_REG_K2, X86_REG_K3, X86_REG_K4, + X86_REG_K5, X86_REG_K6, X86_REG_K7, X86_REG_MM0, X86_REG_MM1, + X86_REG_MM2, X86_REG_MM3, X86_REG_MM4, X86_REG_MM5, X86_REG_MM6, + X86_REG_MM7, X86_REG_R8, X86_REG_R9, X86_REG_R10, X86_REG_R11, + X86_REG_R12, X86_REG_R13, X86_REG_R14, X86_REG_R15, + X86_REG_ST0, X86_REG_ST1, X86_REG_ST2, X86_REG_ST3, + X86_REG_ST4, X86_REG_ST5, X86_REG_ST6, X86_REG_ST7, + X86_REG_XMM0, X86_REG_XMM1, X86_REG_XMM2, X86_REG_XMM3, X86_REG_XMM4, + X86_REG_XMM5, X86_REG_XMM6, X86_REG_XMM7, X86_REG_XMM8, X86_REG_XMM9, + X86_REG_XMM10, X86_REG_XMM11, X86_REG_XMM12, X86_REG_XMM13, X86_REG_XMM14, + X86_REG_XMM15, X86_REG_XMM16, X86_REG_XMM17, X86_REG_XMM18, X86_REG_XMM19, + X86_REG_XMM20, X86_REG_XMM21, X86_REG_XMM22, X86_REG_XMM23, X86_REG_XMM24, + X86_REG_XMM25, X86_REG_XMM26, X86_REG_XMM27, X86_REG_XMM28, X86_REG_XMM29, + X86_REG_XMM30, X86_REG_XMM31, X86_REG_YMM0, X86_REG_YMM1, X86_REG_YMM2, + X86_REG_YMM3, X86_REG_YMM4, X86_REG_YMM5, X86_REG_YMM6, X86_REG_YMM7, + X86_REG_YMM8, X86_REG_YMM9, X86_REG_YMM10, X86_REG_YMM11, X86_REG_YMM12, + X86_REG_YMM13, X86_REG_YMM14, X86_REG_YMM15, X86_REG_YMM16, X86_REG_YMM17, + X86_REG_YMM18, X86_REG_YMM19, X86_REG_YMM20, X86_REG_YMM21, X86_REG_YMM22, + X86_REG_YMM23, X86_REG_YMM24, X86_REG_YMM25, X86_REG_YMM26, X86_REG_YMM27, + X86_REG_YMM28, X86_REG_YMM29, X86_REG_YMM30, X86_REG_YMM31, X86_REG_ZMM0, + X86_REG_ZMM1, X86_REG_ZMM2, X86_REG_ZMM3, X86_REG_ZMM4, X86_REG_ZMM5, + X86_REG_ZMM6, X86_REG_ZMM7, X86_REG_ZMM8, X86_REG_ZMM9, X86_REG_ZMM10, + X86_REG_ZMM11, X86_REG_ZMM12, X86_REG_ZMM13, X86_REG_ZMM14, X86_REG_ZMM15, + X86_REG_ZMM16, X86_REG_ZMM17, X86_REG_ZMM18, X86_REG_ZMM19, X86_REG_ZMM20, + X86_REG_ZMM21, X86_REG_ZMM22, X86_REG_ZMM23, X86_REG_ZMM24, X86_REG_ZMM25, + X86_REG_ZMM26, X86_REG_ZMM27, X86_REG_ZMM28, X86_REG_ZMM29, X86_REG_ZMM30, + X86_REG_ZMM31, X86_REG_R8B, X86_REG_R9B, X86_REG_R10B, X86_REG_R11B, + X86_REG_R12B, X86_REG_R13B, X86_REG_R14B, X86_REG_R15B, X86_REG_R8D, + X86_REG_R9D, X86_REG_R10D, X86_REG_R11D, X86_REG_R12D, X86_REG_R13D, + X86_REG_R14D, X86_REG_R15D, X86_REG_R8W, X86_REG_R9W, X86_REG_R10W, + X86_REG_R11W, X86_REG_R12W, X86_REG_R13W, X86_REG_R14W, X86_REG_R15W, + + X86_REG_ENDING // <-- mark the end of the list of registers +} x86_reg; + +//> Operand type for instruction's operands +typedef enum x86_op_type +{ + X86_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + X86_OP_REG, // = CS_OP_REG (Register operand). + X86_OP_IMM, // = CS_OP_IMM (Immediate operand). + X86_OP_MEM, // = CS_OP_MEM (Memory operand). + X86_OP_FP, // = CS_OP_FP (Floating-Point operand). +} x86_op_type; + +//> AVX broadcast type +typedef enum x86_avx_bcast +{ + X86_AVX_BCAST_INVALID = 0, // Uninitialized. + X86_AVX_BCAST_2, // AVX512 broadcast type {1to2} + X86_AVX_BCAST_4, // AVX512 broadcast type {1to4} + X86_AVX_BCAST_8, // AVX512 broadcast type {1to8} + X86_AVX_BCAST_16, // AVX512 broadcast type {1to16} +} x86_avx_bcast; + +//> SSE Code Condition type +typedef enum x86_sse_cc +{ + X86_SSE_CC_INVALID = 0, // Uninitialized. + X86_SSE_CC_EQ, + X86_SSE_CC_LT, + X86_SSE_CC_LE, + X86_SSE_CC_UNORD, + X86_SSE_CC_NEQ, + X86_SSE_CC_NLT, + X86_SSE_CC_NLE, + X86_SSE_CC_ORD, + X86_SSE_CC_EQ_UQ, + X86_SSE_CC_NGE, + X86_SSE_CC_NGT, + X86_SSE_CC_FALSE, + X86_SSE_CC_NEQ_OQ, + X86_SSE_CC_GE, + X86_SSE_CC_GT, + X86_SSE_CC_TRUE, +} x86_sse_cc; + +//> AVX Code Condition type +typedef enum x86_avx_cc +{ + X86_AVX_CC_INVALID = 0, // Uninitialized. + X86_AVX_CC_EQ, + X86_AVX_CC_LT, + X86_AVX_CC_LE, + X86_AVX_CC_UNORD, + X86_AVX_CC_NEQ, + X86_AVX_CC_NLT, + X86_AVX_CC_NLE, + X86_AVX_CC_ORD, + X86_AVX_CC_EQ_UQ, + X86_AVX_CC_NGE, + X86_AVX_CC_NGT, + X86_AVX_CC_FALSE, + X86_AVX_CC_NEQ_OQ, + X86_AVX_CC_GE, + X86_AVX_CC_GT, + X86_AVX_CC_TRUE, + X86_AVX_CC_EQ_OS, + X86_AVX_CC_LT_OQ, + X86_AVX_CC_LE_OQ, + X86_AVX_CC_UNORD_S, + X86_AVX_CC_NEQ_US, + X86_AVX_CC_NLT_UQ, + X86_AVX_CC_NLE_UQ, + X86_AVX_CC_ORD_S, + X86_AVX_CC_EQ_US, + X86_AVX_CC_NGE_UQ, + X86_AVX_CC_NGT_UQ, + X86_AVX_CC_FALSE_OS, + X86_AVX_CC_NEQ_OS, + X86_AVX_CC_GE_OQ, + X86_AVX_CC_GT_OQ, + X86_AVX_CC_TRUE_US, +} x86_avx_cc; + +//> AVX static rounding mode type +typedef enum x86_avx_rm +{ + X86_AVX_RM_INVALID = 0, // Uninitialized. + X86_AVX_RM_RN, // Round to nearest + X86_AVX_RM_RD, // Round down + X86_AVX_RM_RU, // Round up + X86_AVX_RM_RZ, // Round toward zero +} x86_avx_rm; + +//> Instruction prefixes - to be used in cs_x86.prefix[] +typedef enum x86_prefix +{ + X86_PREFIX_LOCK = 0xf0, // lock (cs_x86.prefix[0] + X86_PREFIX_REP = 0xf3, // rep (cs_x86.prefix[0] + X86_PREFIX_REPNE = 0xf2, // repne (cs_x86.prefix[0] + + X86_PREFIX_CS = 0x2e, // segment override CS (cs_x86.prefix[1] + X86_PREFIX_SS = 0x36, // segment override SS (cs_x86.prefix[1] + X86_PREFIX_DS = 0x3e, // segment override DS (cs_x86.prefix[1] + X86_PREFIX_ES = 0x26, // segment override ES (cs_x86.prefix[1] + X86_PREFIX_FS = 0x64, // segment override FS (cs_x86.prefix[1] + X86_PREFIX_GS = 0x65, // segment override GS (cs_x86.prefix[1] + + X86_PREFIX_OPSIZE = 0x66, // operand-size override (cs_x86.prefix[2] + X86_PREFIX_ADDRSIZE = 0x67, // address-size override (cs_x86.prefix[3] +} x86_prefix; + +// Instruction's operand referring to memory +// This is associated with X86_OP_MEM operand type above +typedef struct x86_op_mem +{ + unsigned int segment; // segment register (or X86_REG_INVALID if irrelevant) + unsigned int base; // base register (or X86_REG_INVALID if irrelevant) + unsigned int index; // index register (or X86_REG_INVALID if irrelevant) + int scale; // scale for index register + int64_t disp; // displacement value +} x86_op_mem; + +// Instruction operand +typedef struct cs_x86_op +{ + x86_op_type type; // operand type + union + { + x86_reg reg; // register value for REG operand + int64_t imm; // immediate value for IMM operand + double fp; // floating point value for FP operand + x86_op_mem mem; // base/index/scale/disp value for MEM operand + }; + + // size of this operand (in bytes). + uint8_t size; + + // AVX broadcast type, or 0 if irrelevant + x86_avx_bcast avx_bcast; + + // AVX zero opmask {z} + bool avx_zero_opmask; +} cs_x86_op; + +// Instruction structure +typedef struct cs_x86 +{ + // Instruction prefix, which can be up to 4 bytes. + // A prefix byte gets value 0 when irrelevant. + // prefix[0] indicates REP/REPNE/LOCK prefix (See X86_PREFIX_REP/REPNE/LOCK above) + // prefix[1] indicates segment override (irrelevant for x86_64): + // See X86_PREFIX_CS/SS/DS/ES/FS/GS above. + // prefix[2] indicates operand-size override (X86_PREFIX_OPSIZE) + // prefix[3] indicates address-size override (X86_PREFIX_ADDRSIZE) + uint8_t prefix[4]; + + // Instruction opcode, wich can be from 1 to 4 bytes in size. + // This contains VEX opcode as well. + // An trailing opcode byte gets value 0 when irrelevant. + uint8_t opcode[4]; + + // REX prefix: only a non-zero value is relavant for x86_64 + uint8_t rex; + + // Address size, which can be overrided with above prefix[5]. + uint8_t addr_size; + + // ModR/M byte + uint8_t modrm; + + // SIB value, or 0 when irrelevant. + uint8_t sib; + + // Displacement value, or 0 when irrelevant. + int32_t disp; + + /* SIB state */ + // SIB index register, or X86_REG_INVALID when irrelevant. + x86_reg sib_index; + // SIB scale. only applicable if sib_index is relavant. + int8_t sib_scale; + // SIB base register, or X86_REG_INVALID when irrelevant. + x86_reg sib_base; + + // SSE Code Condition + x86_sse_cc sse_cc; + + // AVX Code Condition + x86_avx_cc avx_cc; + + // AVX Suppress all Exception + bool avx_sae; + + // AVX static rounding mode + x86_avx_rm avx_rm; + + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + + cs_x86_op operands[8]; // operands for this instruction. +} cs_x86; + +//> X86 instructions +typedef enum x86_insn +{ + X86_INS_INVALID = 0, + + X86_INS_AAA, + X86_INS_AAD, + X86_INS_AAM, + X86_INS_AAS, + X86_INS_FABS, + X86_INS_ADC, + X86_INS_ADCX, + X86_INS_ADD, + X86_INS_ADDPD, + X86_INS_ADDPS, + X86_INS_ADDSD, + X86_INS_ADDSS, + X86_INS_ADDSUBPD, + X86_INS_ADDSUBPS, + X86_INS_FADD, + X86_INS_FIADD, + X86_INS_FADDP, + X86_INS_ADOX, + X86_INS_AESDECLAST, + X86_INS_AESDEC, + X86_INS_AESENCLAST, + X86_INS_AESENC, + X86_INS_AESIMC, + X86_INS_AESKEYGENASSIST, + X86_INS_AND, + X86_INS_ANDN, + X86_INS_ANDNPD, + X86_INS_ANDNPS, + X86_INS_ANDPD, + X86_INS_ANDPS, + X86_INS_ARPL, + X86_INS_BEXTR, + X86_INS_BLCFILL, + X86_INS_BLCI, + X86_INS_BLCIC, + X86_INS_BLCMSK, + X86_INS_BLCS, + X86_INS_BLENDPD, + X86_INS_BLENDPS, + X86_INS_BLENDVPD, + X86_INS_BLENDVPS, + X86_INS_BLSFILL, + X86_INS_BLSI, + X86_INS_BLSIC, + X86_INS_BLSMSK, + X86_INS_BLSR, + X86_INS_BOUND, + X86_INS_BSF, + X86_INS_BSR, + X86_INS_BSWAP, + X86_INS_BT, + X86_INS_BTC, + X86_INS_BTR, + X86_INS_BTS, + X86_INS_BZHI, + X86_INS_CALL, + X86_INS_CBW, + X86_INS_CDQ, + X86_INS_CDQE, + X86_INS_FCHS, + X86_INS_CLAC, + X86_INS_CLC, + X86_INS_CLD, + X86_INS_CLFLUSH, + X86_INS_CLGI, + X86_INS_CLI, + X86_INS_CLTS, + X86_INS_CMC, + X86_INS_CMOVA, + X86_INS_CMOVAE, + X86_INS_CMOVB, + X86_INS_CMOVBE, + X86_INS_FCMOVBE, + X86_INS_FCMOVB, + X86_INS_CMOVE, + X86_INS_FCMOVE, + X86_INS_CMOVG, + X86_INS_CMOVGE, + X86_INS_CMOVL, + X86_INS_CMOVLE, + X86_INS_FCMOVNBE, + X86_INS_FCMOVNB, + X86_INS_CMOVNE, + X86_INS_FCMOVNE, + X86_INS_CMOVNO, + X86_INS_CMOVNP, + X86_INS_FCMOVNU, + X86_INS_CMOVNS, + X86_INS_CMOVO, + X86_INS_CMOVP, + X86_INS_FCMOVU, + X86_INS_CMOVS, + X86_INS_CMP, + X86_INS_CMPPD, + X86_INS_CMPPS, + X86_INS_CMPSB, + X86_INS_CMPSD, + X86_INS_CMPSQ, + X86_INS_CMPSS, + X86_INS_CMPSW, + X86_INS_CMPXCHG16B, + X86_INS_CMPXCHG, + X86_INS_CMPXCHG8B, + X86_INS_COMISD, + X86_INS_COMISS, + X86_INS_FCOMP, + X86_INS_FCOMPI, + X86_INS_FCOMI, + X86_INS_FCOM, + X86_INS_FCOS, + X86_INS_CPUID, + X86_INS_CQO, + X86_INS_CRC32, + X86_INS_CVTDQ2PD, + X86_INS_CVTDQ2PS, + X86_INS_CVTPD2DQ, + X86_INS_CVTPD2PS, + X86_INS_CVTPS2DQ, + X86_INS_CVTPS2PD, + X86_INS_CVTSD2SI, + X86_INS_CVTSD2SS, + X86_INS_CVTSI2SD, + X86_INS_CVTSI2SS, + X86_INS_CVTSS2SD, + X86_INS_CVTSS2SI, + X86_INS_CVTTPD2DQ, + X86_INS_CVTTPS2DQ, + X86_INS_CVTTSD2SI, + X86_INS_CVTTSS2SI, + X86_INS_CWD, + X86_INS_CWDE, + X86_INS_DAA, + X86_INS_DAS, + X86_INS_DATA16, + X86_INS_DEC, + X86_INS_DIV, + X86_INS_DIVPD, + X86_INS_DIVPS, + X86_INS_FDIVR, + X86_INS_FIDIVR, + X86_INS_FDIVRP, + X86_INS_DIVSD, + X86_INS_DIVSS, + X86_INS_FDIV, + X86_INS_FIDIV, + X86_INS_FDIVP, + X86_INS_DPPD, + X86_INS_DPPS, + X86_INS_RET, + X86_INS_ENCLS, + X86_INS_ENCLU, + X86_INS_ENTER, + X86_INS_EXTRACTPS, + X86_INS_EXTRQ, + X86_INS_F2XM1, + X86_INS_LCALL, + X86_INS_LJMP, + X86_INS_FBLD, + X86_INS_FBSTP, + X86_INS_FCOMPP, + X86_INS_FDECSTP, + X86_INS_FEMMS, + X86_INS_FFREE, + X86_INS_FICOM, + X86_INS_FICOMP, + X86_INS_FINCSTP, + X86_INS_FLDCW, + X86_INS_FLDENV, + X86_INS_FLDL2E, + X86_INS_FLDL2T, + X86_INS_FLDLG2, + X86_INS_FLDLN2, + X86_INS_FLDPI, + X86_INS_FNCLEX, + X86_INS_FNINIT, + X86_INS_FNOP, + X86_INS_FNSTCW, + X86_INS_FNSTSW, + X86_INS_FPATAN, + X86_INS_FPREM, + X86_INS_FPREM1, + X86_INS_FPTAN, + X86_INS_FRNDINT, + X86_INS_FRSTOR, + X86_INS_FNSAVE, + X86_INS_FSCALE, + X86_INS_FSETPM, + X86_INS_FSINCOS, + X86_INS_FNSTENV, + X86_INS_FXAM, + X86_INS_FXRSTOR, + X86_INS_FXRSTOR64, + X86_INS_FXSAVE, + X86_INS_FXSAVE64, + X86_INS_FXTRACT, + X86_INS_FYL2X, + X86_INS_FYL2XP1, + X86_INS_MOVAPD, + X86_INS_MOVAPS, + X86_INS_ORPD, + X86_INS_ORPS, + X86_INS_VMOVAPD, + X86_INS_VMOVAPS, + X86_INS_XORPD, + X86_INS_XORPS, + X86_INS_GETSEC, + X86_INS_HADDPD, + X86_INS_HADDPS, + X86_INS_HLT, + X86_INS_HSUBPD, + X86_INS_HSUBPS, + X86_INS_IDIV, + X86_INS_FILD, + X86_INS_IMUL, + X86_INS_IN, + X86_INS_INC, + X86_INS_INSB, + X86_INS_INSERTPS, + X86_INS_INSERTQ, + X86_INS_INSD, + X86_INS_INSW, + X86_INS_INT, + X86_INS_INT1, + X86_INS_INT3, + X86_INS_INTO, + X86_INS_INVD, + X86_INS_INVEPT, + X86_INS_INVLPG, + X86_INS_INVLPGA, + X86_INS_INVPCID, + X86_INS_INVVPID, + X86_INS_IRET, + X86_INS_IRETD, + X86_INS_IRETQ, + X86_INS_FISTTP, + X86_INS_FIST, + X86_INS_FISTP, + X86_INS_UCOMISD, + X86_INS_UCOMISS, + X86_INS_VCMP, + X86_INS_VCOMISD, + X86_INS_VCOMISS, + X86_INS_VCVTSD2SS, + X86_INS_VCVTSI2SD, + X86_INS_VCVTSI2SS, + X86_INS_VCVTSS2SD, + X86_INS_VCVTTSD2SI, + X86_INS_VCVTTSD2USI, + X86_INS_VCVTTSS2SI, + X86_INS_VCVTTSS2USI, + X86_INS_VCVTUSI2SD, + X86_INS_VCVTUSI2SS, + X86_INS_VUCOMISD, + X86_INS_VUCOMISS, + X86_INS_JAE, + X86_INS_JA, + X86_INS_JBE, + X86_INS_JB, + X86_INS_JCXZ, + X86_INS_JECXZ, + X86_INS_JE, + X86_INS_JGE, + X86_INS_JG, + X86_INS_JLE, + X86_INS_JL, + X86_INS_JMP, + X86_INS_JNE, + X86_INS_JNO, + X86_INS_JNP, + X86_INS_JNS, + X86_INS_JO, + X86_INS_JP, + X86_INS_JRCXZ, + X86_INS_JS, + X86_INS_KANDB, + X86_INS_KANDD, + X86_INS_KANDNB, + X86_INS_KANDND, + X86_INS_KANDNQ, + X86_INS_KANDNW, + X86_INS_KANDQ, + X86_INS_KANDW, + X86_INS_KMOVB, + X86_INS_KMOVD, + X86_INS_KMOVQ, + X86_INS_KMOVW, + X86_INS_KNOTB, + X86_INS_KNOTD, + X86_INS_KNOTQ, + X86_INS_KNOTW, + X86_INS_KORB, + X86_INS_KORD, + X86_INS_KORQ, + X86_INS_KORTESTW, + X86_INS_KORW, + X86_INS_KSHIFTLW, + X86_INS_KSHIFTRW, + X86_INS_KUNPCKBW, + X86_INS_KXNORB, + X86_INS_KXNORD, + X86_INS_KXNORQ, + X86_INS_KXNORW, + X86_INS_KXORB, + X86_INS_KXORD, + X86_INS_KXORQ, + X86_INS_KXORW, + X86_INS_LAHF, + X86_INS_LAR, + X86_INS_LDDQU, + X86_INS_LDMXCSR, + X86_INS_LDS, + X86_INS_FLDZ, + X86_INS_FLD1, + X86_INS_FLD, + X86_INS_LEA, + X86_INS_LEAVE, + X86_INS_LES, + X86_INS_LFENCE, + X86_INS_LFS, + X86_INS_LGDT, + X86_INS_LGS, + X86_INS_LIDT, + X86_INS_LLDT, + X86_INS_LMSW, + X86_INS_OR, + X86_INS_SUB, + X86_INS_XOR, + X86_INS_LODSB, + X86_INS_LODSD, + X86_INS_LODSQ, + X86_INS_LODSW, + X86_INS_LOOP, + X86_INS_LOOPE, + X86_INS_LOOPNE, + X86_INS_RETF, + X86_INS_RETFQ, + X86_INS_LSL, + X86_INS_LSS, + X86_INS_LTR, + X86_INS_XADD, + X86_INS_LZCNT, + X86_INS_MASKMOVDQU, + X86_INS_MAXPD, + X86_INS_MAXPS, + X86_INS_MAXSD, + X86_INS_MAXSS, + X86_INS_MFENCE, + X86_INS_MINPD, + X86_INS_MINPS, + X86_INS_MINSD, + X86_INS_MINSS, + X86_INS_CVTPD2PI, + X86_INS_CVTPI2PD, + X86_INS_CVTPI2PS, + X86_INS_CVTPS2PI, + X86_INS_CVTTPD2PI, + X86_INS_CVTTPS2PI, + X86_INS_EMMS, + X86_INS_MASKMOVQ, + X86_INS_MOVD, + X86_INS_MOVDQ2Q, + X86_INS_MOVNTQ, + X86_INS_MOVQ2DQ, + X86_INS_MOVQ, + X86_INS_PABSB, + X86_INS_PABSD, + X86_INS_PABSW, + X86_INS_PACKSSDW, + X86_INS_PACKSSWB, + X86_INS_PACKUSWB, + X86_INS_PADDB, + X86_INS_PADDD, + X86_INS_PADDQ, + X86_INS_PADDSB, + X86_INS_PADDSW, + X86_INS_PADDUSB, + X86_INS_PADDUSW, + X86_INS_PADDW, + X86_INS_PALIGNR, + X86_INS_PANDN, + X86_INS_PAND, + X86_INS_PAVGB, + X86_INS_PAVGW, + X86_INS_PCMPEQB, + X86_INS_PCMPEQD, + X86_INS_PCMPEQW, + X86_INS_PCMPGTB, + X86_INS_PCMPGTD, + X86_INS_PCMPGTW, + X86_INS_PEXTRW, + X86_INS_PHADDSW, + X86_INS_PHADDW, + X86_INS_PHADDD, + X86_INS_PHSUBD, + X86_INS_PHSUBSW, + X86_INS_PHSUBW, + X86_INS_PINSRW, + X86_INS_PMADDUBSW, + X86_INS_PMADDWD, + X86_INS_PMAXSW, + X86_INS_PMAXUB, + X86_INS_PMINSW, + X86_INS_PMINUB, + X86_INS_PMOVMSKB, + X86_INS_PMULHRSW, + X86_INS_PMULHUW, + X86_INS_PMULHW, + X86_INS_PMULLW, + X86_INS_PMULUDQ, + X86_INS_POR, + X86_INS_PSADBW, + X86_INS_PSHUFB, + X86_INS_PSHUFW, + X86_INS_PSIGNB, + X86_INS_PSIGND, + X86_INS_PSIGNW, + X86_INS_PSLLD, + X86_INS_PSLLQ, + X86_INS_PSLLW, + X86_INS_PSRAD, + X86_INS_PSRAW, + X86_INS_PSRLD, + X86_INS_PSRLQ, + X86_INS_PSRLW, + X86_INS_PSUBB, + X86_INS_PSUBD, + X86_INS_PSUBQ, + X86_INS_PSUBSB, + X86_INS_PSUBSW, + X86_INS_PSUBUSB, + X86_INS_PSUBUSW, + X86_INS_PSUBW, + X86_INS_PUNPCKHBW, + X86_INS_PUNPCKHDQ, + X86_INS_PUNPCKHWD, + X86_INS_PUNPCKLBW, + X86_INS_PUNPCKLDQ, + X86_INS_PUNPCKLWD, + X86_INS_PXOR, + X86_INS_MONITOR, + X86_INS_MONTMUL, + X86_INS_MOV, + X86_INS_MOVABS, + X86_INS_MOVBE, + X86_INS_MOVDDUP, + X86_INS_MOVDQA, + X86_INS_MOVDQU, + X86_INS_MOVHLPS, + X86_INS_MOVHPD, + X86_INS_MOVHPS, + X86_INS_MOVLHPS, + X86_INS_MOVLPD, + X86_INS_MOVLPS, + X86_INS_MOVMSKPD, + X86_INS_MOVMSKPS, + X86_INS_MOVNTDQA, + X86_INS_MOVNTDQ, + X86_INS_MOVNTI, + X86_INS_MOVNTPD, + X86_INS_MOVNTPS, + X86_INS_MOVNTSD, + X86_INS_MOVNTSS, + X86_INS_MOVSB, + X86_INS_MOVSD, + X86_INS_MOVSHDUP, + X86_INS_MOVSLDUP, + X86_INS_MOVSQ, + X86_INS_MOVSS, + X86_INS_MOVSW, + X86_INS_MOVSX, + X86_INS_MOVSXD, + X86_INS_MOVUPD, + X86_INS_MOVUPS, + X86_INS_MOVZX, + X86_INS_MPSADBW, + X86_INS_MUL, + X86_INS_MULPD, + X86_INS_MULPS, + X86_INS_MULSD, + X86_INS_MULSS, + X86_INS_MULX, + X86_INS_FMUL, + X86_INS_FIMUL, + X86_INS_FMULP, + X86_INS_MWAIT, + X86_INS_NEG, + X86_INS_NOP, + X86_INS_NOT, + X86_INS_OUT, + X86_INS_OUTSB, + X86_INS_OUTSD, + X86_INS_OUTSW, + X86_INS_PACKUSDW, + X86_INS_PAUSE, + X86_INS_PAVGUSB, + X86_INS_PBLENDVB, + X86_INS_PBLENDW, + X86_INS_PCLMULQDQ, + X86_INS_PCMPEQQ, + X86_INS_PCMPESTRI, + X86_INS_PCMPESTRM, + X86_INS_PCMPGTQ, + X86_INS_PCMPISTRI, + X86_INS_PCMPISTRM, + X86_INS_PDEP, + X86_INS_PEXT, + X86_INS_PEXTRB, + X86_INS_PEXTRD, + X86_INS_PEXTRQ, + X86_INS_PF2ID, + X86_INS_PF2IW, + X86_INS_PFACC, + X86_INS_PFADD, + X86_INS_PFCMPEQ, + X86_INS_PFCMPGE, + X86_INS_PFCMPGT, + X86_INS_PFMAX, + X86_INS_PFMIN, + X86_INS_PFMUL, + X86_INS_PFNACC, + X86_INS_PFPNACC, + X86_INS_PFRCPIT1, + X86_INS_PFRCPIT2, + X86_INS_PFRCP, + X86_INS_PFRSQIT1, + X86_INS_PFRSQRT, + X86_INS_PFSUBR, + X86_INS_PFSUB, + X86_INS_PHMINPOSUW, + X86_INS_PI2FD, + X86_INS_PI2FW, + X86_INS_PINSRB, + X86_INS_PINSRD, + X86_INS_PINSRQ, + X86_INS_PMAXSB, + X86_INS_PMAXSD, + X86_INS_PMAXUD, + X86_INS_PMAXUW, + X86_INS_PMINSB, + X86_INS_PMINSD, + X86_INS_PMINUD, + X86_INS_PMINUW, + X86_INS_PMOVSXBD, + X86_INS_PMOVSXBQ, + X86_INS_PMOVSXBW, + X86_INS_PMOVSXDQ, + X86_INS_PMOVSXWD, + X86_INS_PMOVSXWQ, + X86_INS_PMOVZXBD, + X86_INS_PMOVZXBQ, + X86_INS_PMOVZXBW, + X86_INS_PMOVZXDQ, + X86_INS_PMOVZXWD, + X86_INS_PMOVZXWQ, + X86_INS_PMULDQ, + X86_INS_PMULHRW, + X86_INS_PMULLD, + X86_INS_POP, + X86_INS_POPAW, + X86_INS_POPAL, + X86_INS_POPCNT, + X86_INS_POPF, + X86_INS_POPFD, + X86_INS_POPFQ, + X86_INS_PREFETCH, + X86_INS_PREFETCHNTA, + X86_INS_PREFETCHT0, + X86_INS_PREFETCHT1, + X86_INS_PREFETCHT2, + X86_INS_PREFETCHW, + X86_INS_PSHUFD, + X86_INS_PSHUFHW, + X86_INS_PSHUFLW, + X86_INS_PSLLDQ, + X86_INS_PSRLDQ, + X86_INS_PSWAPD, + X86_INS_PTEST, + X86_INS_PUNPCKHQDQ, + X86_INS_PUNPCKLQDQ, + X86_INS_PUSH, + X86_INS_PUSHAW, + X86_INS_PUSHAL, + X86_INS_PUSHF, + X86_INS_PUSHFD, + X86_INS_PUSHFQ, + X86_INS_RCL, + X86_INS_RCPPS, + X86_INS_RCPSS, + X86_INS_RCR, + X86_INS_RDFSBASE, + X86_INS_RDGSBASE, + X86_INS_RDMSR, + X86_INS_RDPMC, + X86_INS_RDRAND, + X86_INS_RDSEED, + X86_INS_RDTSC, + X86_INS_RDTSCP, + X86_INS_ROL, + X86_INS_ROR, + X86_INS_RORX, + X86_INS_ROUNDPD, + X86_INS_ROUNDPS, + X86_INS_ROUNDSD, + X86_INS_ROUNDSS, + X86_INS_RSM, + X86_INS_RSQRTPS, + X86_INS_RSQRTSS, + X86_INS_SAHF, + X86_INS_SAL, + X86_INS_SALC, + X86_INS_SAR, + X86_INS_SARX, + X86_INS_SBB, + X86_INS_SCASB, + X86_INS_SCASD, + X86_INS_SCASQ, + X86_INS_SCASW, + X86_INS_SETAE, + X86_INS_SETA, + X86_INS_SETBE, + X86_INS_SETB, + X86_INS_SETE, + X86_INS_SETGE, + X86_INS_SETG, + X86_INS_SETLE, + X86_INS_SETL, + X86_INS_SETNE, + X86_INS_SETNO, + X86_INS_SETNP, + X86_INS_SETNS, + X86_INS_SETO, + X86_INS_SETP, + X86_INS_SETS, + X86_INS_SFENCE, + X86_INS_SGDT, + X86_INS_SHA1MSG1, + X86_INS_SHA1MSG2, + X86_INS_SHA1NEXTE, + X86_INS_SHA1RNDS4, + X86_INS_SHA256MSG1, + X86_INS_SHA256MSG2, + X86_INS_SHA256RNDS2, + X86_INS_SHL, + X86_INS_SHLD, + X86_INS_SHLX, + X86_INS_SHR, + X86_INS_SHRD, + X86_INS_SHRX, + X86_INS_SHUFPD, + X86_INS_SHUFPS, + X86_INS_SIDT, + X86_INS_FSIN, + X86_INS_SKINIT, + X86_INS_SLDT, + X86_INS_SMSW, + X86_INS_SQRTPD, + X86_INS_SQRTPS, + X86_INS_SQRTSD, + X86_INS_SQRTSS, + X86_INS_FSQRT, + X86_INS_STAC, + X86_INS_STC, + X86_INS_STD, + X86_INS_STGI, + X86_INS_STI, + X86_INS_STMXCSR, + X86_INS_STOSB, + X86_INS_STOSD, + X86_INS_STOSQ, + X86_INS_STOSW, + X86_INS_STR, + X86_INS_FST, + X86_INS_FSTP, + X86_INS_FSTPNCE, + X86_INS_SUBPD, + X86_INS_SUBPS, + X86_INS_FSUBR, + X86_INS_FISUBR, + X86_INS_FSUBRP, + X86_INS_SUBSD, + X86_INS_SUBSS, + X86_INS_FSUB, + X86_INS_FISUB, + X86_INS_FSUBP, + X86_INS_SWAPGS, + X86_INS_SYSCALL, + X86_INS_SYSENTER, + X86_INS_SYSEXIT, + X86_INS_SYSRET, + X86_INS_T1MSKC, + X86_INS_TEST, + X86_INS_UD2, + X86_INS_FTST, + X86_INS_TZCNT, + X86_INS_TZMSK, + X86_INS_FUCOMPI, + X86_INS_FUCOMI, + X86_INS_FUCOMPP, + X86_INS_FUCOMP, + X86_INS_FUCOM, + X86_INS_UD2B, + X86_INS_UNPCKHPD, + X86_INS_UNPCKHPS, + X86_INS_UNPCKLPD, + X86_INS_UNPCKLPS, + X86_INS_VADDPD, + X86_INS_VADDPS, + X86_INS_VADDSD, + X86_INS_VADDSS, + X86_INS_VADDSUBPD, + X86_INS_VADDSUBPS, + X86_INS_VAESDECLAST, + X86_INS_VAESDEC, + X86_INS_VAESENCLAST, + X86_INS_VAESENC, + X86_INS_VAESIMC, + X86_INS_VAESKEYGENASSIST, + X86_INS_VALIGND, + X86_INS_VALIGNQ, + X86_INS_VANDNPD, + X86_INS_VANDNPS, + X86_INS_VANDPD, + X86_INS_VANDPS, + X86_INS_VBLENDMPD, + X86_INS_VBLENDMPS, + X86_INS_VBLENDPD, + X86_INS_VBLENDPS, + X86_INS_VBLENDVPD, + X86_INS_VBLENDVPS, + X86_INS_VBROADCASTF128, + X86_INS_VBROADCASTI128, + X86_INS_VBROADCASTI32X4, + X86_INS_VBROADCASTI64X4, + X86_INS_VBROADCASTSD, + X86_INS_VBROADCASTSS, + X86_INS_VCMPPD, + X86_INS_VCMPPS, + X86_INS_VCMPSD, + X86_INS_VCMPSS, + X86_INS_VCVTDQ2PD, + X86_INS_VCVTDQ2PS, + X86_INS_VCVTPD2DQX, + X86_INS_VCVTPD2DQ, + X86_INS_VCVTPD2PSX, + X86_INS_VCVTPD2PS, + X86_INS_VCVTPD2UDQ, + X86_INS_VCVTPH2PS, + X86_INS_VCVTPS2DQ, + X86_INS_VCVTPS2PD, + X86_INS_VCVTPS2PH, + X86_INS_VCVTPS2UDQ, + X86_INS_VCVTSD2SI, + X86_INS_VCVTSD2USI, + X86_INS_VCVTSS2SI, + X86_INS_VCVTSS2USI, + X86_INS_VCVTTPD2DQX, + X86_INS_VCVTTPD2DQ, + X86_INS_VCVTTPD2UDQ, + X86_INS_VCVTTPS2DQ, + X86_INS_VCVTTPS2UDQ, + X86_INS_VCVTUDQ2PD, + X86_INS_VCVTUDQ2PS, + X86_INS_VDIVPD, + X86_INS_VDIVPS, + X86_INS_VDIVSD, + X86_INS_VDIVSS, + X86_INS_VDPPD, + X86_INS_VDPPS, + X86_INS_VERR, + X86_INS_VERW, + X86_INS_VEXTRACTF128, + X86_INS_VEXTRACTF32X4, + X86_INS_VEXTRACTF64X4, + X86_INS_VEXTRACTI128, + X86_INS_VEXTRACTI32X4, + X86_INS_VEXTRACTI64X4, + X86_INS_VEXTRACTPS, + X86_INS_VFMADD132PD, + X86_INS_VFMADD132PS, + X86_INS_VFMADD213PD, + X86_INS_VFMADD213PS, + X86_INS_VFMADDPD, + X86_INS_VFMADD231PD, + X86_INS_VFMADDPS, + X86_INS_VFMADD231PS, + X86_INS_VFMADDSD, + X86_INS_VFMADD213SD, + X86_INS_VFMADD132SD, + X86_INS_VFMADD231SD, + X86_INS_VFMADDSS, + X86_INS_VFMADD213SS, + X86_INS_VFMADD132SS, + X86_INS_VFMADD231SS, + X86_INS_VFMADDSUB132PD, + X86_INS_VFMADDSUB132PS, + X86_INS_VFMADDSUB213PD, + X86_INS_VFMADDSUB213PS, + X86_INS_VFMADDSUBPD, + X86_INS_VFMADDSUB231PD, + X86_INS_VFMADDSUBPS, + X86_INS_VFMADDSUB231PS, + X86_INS_VFMSUB132PD, + X86_INS_VFMSUB132PS, + X86_INS_VFMSUB213PD, + X86_INS_VFMSUB213PS, + X86_INS_VFMSUBADD132PD, + X86_INS_VFMSUBADD132PS, + X86_INS_VFMSUBADD213PD, + X86_INS_VFMSUBADD213PS, + X86_INS_VFMSUBADDPD, + X86_INS_VFMSUBADD231PD, + X86_INS_VFMSUBADDPS, + X86_INS_VFMSUBADD231PS, + X86_INS_VFMSUBPD, + X86_INS_VFMSUB231PD, + X86_INS_VFMSUBPS, + X86_INS_VFMSUB231PS, + X86_INS_VFMSUBSD, + X86_INS_VFMSUB213SD, + X86_INS_VFMSUB132SD, + X86_INS_VFMSUB231SD, + X86_INS_VFMSUBSS, + X86_INS_VFMSUB213SS, + X86_INS_VFMSUB132SS, + X86_INS_VFMSUB231SS, + X86_INS_VFNMADD132PD, + X86_INS_VFNMADD132PS, + X86_INS_VFNMADD213PD, + X86_INS_VFNMADD213PS, + X86_INS_VFNMADDPD, + X86_INS_VFNMADD231PD, + X86_INS_VFNMADDPS, + X86_INS_VFNMADD231PS, + X86_INS_VFNMADDSD, + X86_INS_VFNMADD213SD, + X86_INS_VFNMADD132SD, + X86_INS_VFNMADD231SD, + X86_INS_VFNMADDSS, + X86_INS_VFNMADD213SS, + X86_INS_VFNMADD132SS, + X86_INS_VFNMADD231SS, + X86_INS_VFNMSUB132PD, + X86_INS_VFNMSUB132PS, + X86_INS_VFNMSUB213PD, + X86_INS_VFNMSUB213PS, + X86_INS_VFNMSUBPD, + X86_INS_VFNMSUB231PD, + X86_INS_VFNMSUBPS, + X86_INS_VFNMSUB231PS, + X86_INS_VFNMSUBSD, + X86_INS_VFNMSUB213SD, + X86_INS_VFNMSUB132SD, + X86_INS_VFNMSUB231SD, + X86_INS_VFNMSUBSS, + X86_INS_VFNMSUB213SS, + X86_INS_VFNMSUB132SS, + X86_INS_VFNMSUB231SS, + X86_INS_VFRCZPD, + X86_INS_VFRCZPS, + X86_INS_VFRCZSD, + X86_INS_VFRCZSS, + X86_INS_VORPD, + X86_INS_VORPS, + X86_INS_VXORPD, + X86_INS_VXORPS, + X86_INS_VGATHERDPD, + X86_INS_VGATHERDPS, + X86_INS_VGATHERPF0DPD, + X86_INS_VGATHERPF0DPS, + X86_INS_VGATHERPF0QPD, + X86_INS_VGATHERPF0QPS, + X86_INS_VGATHERPF1DPD, + X86_INS_VGATHERPF1DPS, + X86_INS_VGATHERPF1QPD, + X86_INS_VGATHERPF1QPS, + X86_INS_VGATHERQPD, + X86_INS_VGATHERQPS, + X86_INS_VHADDPD, + X86_INS_VHADDPS, + X86_INS_VHSUBPD, + X86_INS_VHSUBPS, + X86_INS_VINSERTF128, + X86_INS_VINSERTF32X4, + X86_INS_VINSERTF64X4, + X86_INS_VINSERTI128, + X86_INS_VINSERTI32X4, + X86_INS_VINSERTI64X4, + X86_INS_VINSERTPS, + X86_INS_VLDDQU, + X86_INS_VLDMXCSR, + X86_INS_VMASKMOVDQU, + X86_INS_VMASKMOVPD, + X86_INS_VMASKMOVPS, + X86_INS_VMAXPD, + X86_INS_VMAXPS, + X86_INS_VMAXSD, + X86_INS_VMAXSS, + X86_INS_VMCALL, + X86_INS_VMCLEAR, + X86_INS_VMFUNC, + X86_INS_VMINPD, + X86_INS_VMINPS, + X86_INS_VMINSD, + X86_INS_VMINSS, + X86_INS_VMLAUNCH, + X86_INS_VMLOAD, + X86_INS_VMMCALL, + X86_INS_VMOVQ, + X86_INS_VMOVDDUP, + X86_INS_VMOVD, + X86_INS_VMOVDQA32, + X86_INS_VMOVDQA64, + X86_INS_VMOVDQA, + X86_INS_VMOVDQU16, + X86_INS_VMOVDQU32, + X86_INS_VMOVDQU64, + X86_INS_VMOVDQU8, + X86_INS_VMOVDQU, + X86_INS_VMOVHLPS, + X86_INS_VMOVHPD, + X86_INS_VMOVHPS, + X86_INS_VMOVLHPS, + X86_INS_VMOVLPD, + X86_INS_VMOVLPS, + X86_INS_VMOVMSKPD, + X86_INS_VMOVMSKPS, + X86_INS_VMOVNTDQA, + X86_INS_VMOVNTDQ, + X86_INS_VMOVNTPD, + X86_INS_VMOVNTPS, + X86_INS_VMOVSD, + X86_INS_VMOVSHDUP, + X86_INS_VMOVSLDUP, + X86_INS_VMOVSS, + X86_INS_VMOVUPD, + X86_INS_VMOVUPS, + X86_INS_VMPSADBW, + X86_INS_VMPTRLD, + X86_INS_VMPTRST, + X86_INS_VMREAD, + X86_INS_VMRESUME, + X86_INS_VMRUN, + X86_INS_VMSAVE, + X86_INS_VMULPD, + X86_INS_VMULPS, + X86_INS_VMULSD, + X86_INS_VMULSS, + X86_INS_VMWRITE, + X86_INS_VMXOFF, + X86_INS_VMXON, + X86_INS_VPABSB, + X86_INS_VPABSD, + X86_INS_VPABSQ, + X86_INS_VPABSW, + X86_INS_VPACKSSDW, + X86_INS_VPACKSSWB, + X86_INS_VPACKUSDW, + X86_INS_VPACKUSWB, + X86_INS_VPADDB, + X86_INS_VPADDD, + X86_INS_VPADDQ, + X86_INS_VPADDSB, + X86_INS_VPADDSW, + X86_INS_VPADDUSB, + X86_INS_VPADDUSW, + X86_INS_VPADDW, + X86_INS_VPALIGNR, + X86_INS_VPANDD, + X86_INS_VPANDND, + X86_INS_VPANDNQ, + X86_INS_VPANDN, + X86_INS_VPANDQ, + X86_INS_VPAND, + X86_INS_VPAVGB, + X86_INS_VPAVGW, + X86_INS_VPBLENDD, + X86_INS_VPBLENDMD, + X86_INS_VPBLENDMQ, + X86_INS_VPBLENDVB, + X86_INS_VPBLENDW, + X86_INS_VPBROADCASTB, + X86_INS_VPBROADCASTD, + X86_INS_VPBROADCASTMB2Q, + X86_INS_VPBROADCASTMW2D, + X86_INS_VPBROADCASTQ, + X86_INS_VPBROADCASTW, + X86_INS_VPCLMULQDQ, + X86_INS_VPCMOV, + X86_INS_VPCMP, + X86_INS_VPCMPD, + X86_INS_VPCMPEQB, + X86_INS_VPCMPEQD, + X86_INS_VPCMPEQQ, + X86_INS_VPCMPEQW, + X86_INS_VPCMPESTRI, + X86_INS_VPCMPESTRM, + X86_INS_VPCMPGTB, + X86_INS_VPCMPGTD, + X86_INS_VPCMPGTQ, + X86_INS_VPCMPGTW, + X86_INS_VPCMPISTRI, + X86_INS_VPCMPISTRM, + X86_INS_VPCMPQ, + X86_INS_VPCMPUD, + X86_INS_VPCMPUQ, + X86_INS_VPCOMB, + X86_INS_VPCOMD, + X86_INS_VPCOMQ, + X86_INS_VPCOMUB, + X86_INS_VPCOMUD, + X86_INS_VPCOMUQ, + X86_INS_VPCOMUW, + X86_INS_VPCOMW, + X86_INS_VPCONFLICTD, + X86_INS_VPCONFLICTQ, + X86_INS_VPERM2F128, + X86_INS_VPERM2I128, + X86_INS_VPERMD, + X86_INS_VPERMI2D, + X86_INS_VPERMI2PD, + X86_INS_VPERMI2PS, + X86_INS_VPERMI2Q, + X86_INS_VPERMIL2PD, + X86_INS_VPERMIL2PS, + X86_INS_VPERMILPD, + X86_INS_VPERMILPS, + X86_INS_VPERMPD, + X86_INS_VPERMPS, + X86_INS_VPERMQ, + X86_INS_VPERMT2D, + X86_INS_VPERMT2PD, + X86_INS_VPERMT2PS, + X86_INS_VPERMT2Q, + X86_INS_VPEXTRB, + X86_INS_VPEXTRD, + X86_INS_VPEXTRQ, + X86_INS_VPEXTRW, + X86_INS_VPGATHERDD, + X86_INS_VPGATHERDQ, + X86_INS_VPGATHERQD, + X86_INS_VPGATHERQQ, + X86_INS_VPHADDBD, + X86_INS_VPHADDBQ, + X86_INS_VPHADDBW, + X86_INS_VPHADDDQ, + X86_INS_VPHADDD, + X86_INS_VPHADDSW, + X86_INS_VPHADDUBD, + X86_INS_VPHADDUBQ, + X86_INS_VPHADDUBW, + X86_INS_VPHADDUDQ, + X86_INS_VPHADDUWD, + X86_INS_VPHADDUWQ, + X86_INS_VPHADDWD, + X86_INS_VPHADDWQ, + X86_INS_VPHADDW, + X86_INS_VPHMINPOSUW, + X86_INS_VPHSUBBW, + X86_INS_VPHSUBDQ, + X86_INS_VPHSUBD, + X86_INS_VPHSUBSW, + X86_INS_VPHSUBWD, + X86_INS_VPHSUBW, + X86_INS_VPINSRB, + X86_INS_VPINSRD, + X86_INS_VPINSRQ, + X86_INS_VPINSRW, + X86_INS_VPLZCNTD, + X86_INS_VPLZCNTQ, + X86_INS_VPMACSDD, + X86_INS_VPMACSDQH, + X86_INS_VPMACSDQL, + X86_INS_VPMACSSDD, + X86_INS_VPMACSSDQH, + X86_INS_VPMACSSDQL, + X86_INS_VPMACSSWD, + X86_INS_VPMACSSWW, + X86_INS_VPMACSWD, + X86_INS_VPMACSWW, + X86_INS_VPMADCSSWD, + X86_INS_VPMADCSWD, + X86_INS_VPMADDUBSW, + X86_INS_VPMADDWD, + X86_INS_VPMASKMOVD, + X86_INS_VPMASKMOVQ, + X86_INS_VPMAXSB, + X86_INS_VPMAXSD, + X86_INS_VPMAXSQ, + X86_INS_VPMAXSW, + X86_INS_VPMAXUB, + X86_INS_VPMAXUD, + X86_INS_VPMAXUQ, + X86_INS_VPMAXUW, + X86_INS_VPMINSB, + X86_INS_VPMINSD, + X86_INS_VPMINSQ, + X86_INS_VPMINSW, + X86_INS_VPMINUB, + X86_INS_VPMINUD, + X86_INS_VPMINUQ, + X86_INS_VPMINUW, + X86_INS_VPMOVDB, + X86_INS_VPMOVDW, + X86_INS_VPMOVMSKB, + X86_INS_VPMOVQB, + X86_INS_VPMOVQD, + X86_INS_VPMOVQW, + X86_INS_VPMOVSDB, + X86_INS_VPMOVSDW, + X86_INS_VPMOVSQB, + X86_INS_VPMOVSQD, + X86_INS_VPMOVSQW, + X86_INS_VPMOVSXBD, + X86_INS_VPMOVSXBQ, + X86_INS_VPMOVSXBW, + X86_INS_VPMOVSXDQ, + X86_INS_VPMOVSXWD, + X86_INS_VPMOVSXWQ, + X86_INS_VPMOVUSDB, + X86_INS_VPMOVUSDW, + X86_INS_VPMOVUSQB, + X86_INS_VPMOVUSQD, + X86_INS_VPMOVUSQW, + X86_INS_VPMOVZXBD, + X86_INS_VPMOVZXBQ, + X86_INS_VPMOVZXBW, + X86_INS_VPMOVZXDQ, + X86_INS_VPMOVZXWD, + X86_INS_VPMOVZXWQ, + X86_INS_VPMULDQ, + X86_INS_VPMULHRSW, + X86_INS_VPMULHUW, + X86_INS_VPMULHW, + X86_INS_VPMULLD, + X86_INS_VPMULLW, + X86_INS_VPMULUDQ, + X86_INS_VPORD, + X86_INS_VPORQ, + X86_INS_VPOR, + X86_INS_VPPERM, + X86_INS_VPROTB, + X86_INS_VPROTD, + X86_INS_VPROTQ, + X86_INS_VPROTW, + X86_INS_VPSADBW, + X86_INS_VPSCATTERDD, + X86_INS_VPSCATTERDQ, + X86_INS_VPSCATTERQD, + X86_INS_VPSCATTERQQ, + X86_INS_VPSHAB, + X86_INS_VPSHAD, + X86_INS_VPSHAQ, + X86_INS_VPSHAW, + X86_INS_VPSHLB, + X86_INS_VPSHLD, + X86_INS_VPSHLQ, + X86_INS_VPSHLW, + X86_INS_VPSHUFB, + X86_INS_VPSHUFD, + X86_INS_VPSHUFHW, + X86_INS_VPSHUFLW, + X86_INS_VPSIGNB, + X86_INS_VPSIGND, + X86_INS_VPSIGNW, + X86_INS_VPSLLDQ, + X86_INS_VPSLLD, + X86_INS_VPSLLQ, + X86_INS_VPSLLVD, + X86_INS_VPSLLVQ, + X86_INS_VPSLLW, + X86_INS_VPSRAD, + X86_INS_VPSRAQ, + X86_INS_VPSRAVD, + X86_INS_VPSRAVQ, + X86_INS_VPSRAW, + X86_INS_VPSRLDQ, + X86_INS_VPSRLD, + X86_INS_VPSRLQ, + X86_INS_VPSRLVD, + X86_INS_VPSRLVQ, + X86_INS_VPSRLW, + X86_INS_VPSUBB, + X86_INS_VPSUBD, + X86_INS_VPSUBQ, + X86_INS_VPSUBSB, + X86_INS_VPSUBSW, + X86_INS_VPSUBUSB, + X86_INS_VPSUBUSW, + X86_INS_VPSUBW, + X86_INS_VPTESTMD, + X86_INS_VPTESTMQ, + X86_INS_VPTESTNMD, + X86_INS_VPTESTNMQ, + X86_INS_VPTEST, + X86_INS_VPUNPCKHBW, + X86_INS_VPUNPCKHDQ, + X86_INS_VPUNPCKHQDQ, + X86_INS_VPUNPCKHWD, + X86_INS_VPUNPCKLBW, + X86_INS_VPUNPCKLDQ, + X86_INS_VPUNPCKLQDQ, + X86_INS_VPUNPCKLWD, + X86_INS_VPXORD, + X86_INS_VPXORQ, + X86_INS_VPXOR, + X86_INS_VRCP14PD, + X86_INS_VRCP14PS, + X86_INS_VRCP14SD, + X86_INS_VRCP14SS, + X86_INS_VRCP28PD, + X86_INS_VRCP28PS, + X86_INS_VRCP28SD, + X86_INS_VRCP28SS, + X86_INS_VRCPPS, + X86_INS_VRCPSS, + X86_INS_VRNDSCALEPD, + X86_INS_VRNDSCALEPS, + X86_INS_VRNDSCALESD, + X86_INS_VRNDSCALESS, + X86_INS_VROUNDPD, + X86_INS_VROUNDPS, + X86_INS_VROUNDSD, + X86_INS_VROUNDSS, + X86_INS_VRSQRT14PD, + X86_INS_VRSQRT14PS, + X86_INS_VRSQRT14SD, + X86_INS_VRSQRT14SS, + X86_INS_VRSQRT28PD, + X86_INS_VRSQRT28PS, + X86_INS_VRSQRT28SD, + X86_INS_VRSQRT28SS, + X86_INS_VRSQRTPS, + X86_INS_VRSQRTSS, + X86_INS_VSCATTERDPD, + X86_INS_VSCATTERDPS, + X86_INS_VSCATTERPF0DPD, + X86_INS_VSCATTERPF0DPS, + X86_INS_VSCATTERPF0QPD, + X86_INS_VSCATTERPF0QPS, + X86_INS_VSCATTERPF1DPD, + X86_INS_VSCATTERPF1DPS, + X86_INS_VSCATTERPF1QPD, + X86_INS_VSCATTERPF1QPS, + X86_INS_VSCATTERQPD, + X86_INS_VSCATTERQPS, + X86_INS_VSHUFPD, + X86_INS_VSHUFPS, + X86_INS_VSQRTPD, + X86_INS_VSQRTPS, + X86_INS_VSQRTSD, + X86_INS_VSQRTSS, + X86_INS_VSTMXCSR, + X86_INS_VSUBPD, + X86_INS_VSUBPS, + X86_INS_VSUBSD, + X86_INS_VSUBSS, + X86_INS_VTESTPD, + X86_INS_VTESTPS, + X86_INS_VUNPCKHPD, + X86_INS_VUNPCKHPS, + X86_INS_VUNPCKLPD, + X86_INS_VUNPCKLPS, + X86_INS_VZEROALL, + X86_INS_VZEROUPPER, + X86_INS_WAIT, + X86_INS_WBINVD, + X86_INS_WRFSBASE, + X86_INS_WRGSBASE, + X86_INS_WRMSR, + X86_INS_XABORT, + X86_INS_XACQUIRE, + X86_INS_XBEGIN, + X86_INS_XCHG, + X86_INS_FXCH, + X86_INS_XCRYPTCBC, + X86_INS_XCRYPTCFB, + X86_INS_XCRYPTCTR, + X86_INS_XCRYPTECB, + X86_INS_XCRYPTOFB, + X86_INS_XEND, + X86_INS_XGETBV, + X86_INS_XLATB, + X86_INS_XRELEASE, + X86_INS_XRSTOR, + X86_INS_XRSTOR64, + X86_INS_XSAVE, + X86_INS_XSAVE64, + X86_INS_XSAVEOPT, + X86_INS_XSAVEOPT64, + X86_INS_XSETBV, + X86_INS_XSHA1, + X86_INS_XSHA256, + X86_INS_XSTORE, + X86_INS_XTEST, + + X86_INS_ENDING, // mark the end of the list of insn +} x86_insn; + +//> Group of X86 instructions +typedef enum x86_insn_group +{ + X86_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + X86_GRP_JUMP, // = CS_GRP_JUMP + // all call instructions + X86_GRP_CALL, // = CS_GRP_CALL + // all return instructions + X86_GRP_RET, // = CS_GRP_RET + // all interrupt instructions (int+syscall) + X86_GRP_INT, // = CS_GRP_INT + // all interrupt return instructions + X86_GRP_IRET, // = CS_GRP_IRET + + //> Architecture-specific groups + X86_GRP_VM = 128, // all virtualization instructions (VT-x + AMD-V) + X86_GRP_3DNOW, + X86_GRP_AES, + X86_GRP_ADX, + X86_GRP_AVX, + X86_GRP_AVX2, + X86_GRP_AVX512, + X86_GRP_BMI, + X86_GRP_BMI2, + X86_GRP_CMOV, + X86_GRP_F16C, + X86_GRP_FMA, + X86_GRP_FMA4, + X86_GRP_FSGSBASE, + X86_GRP_HLE, + X86_GRP_MMX, + X86_GRP_MODE32, + X86_GRP_MODE64, + X86_GRP_RTM, + X86_GRP_SHA, + X86_GRP_SSE1, + X86_GRP_SSE2, + X86_GRP_SSE3, + X86_GRP_SSE41, + X86_GRP_SSE42, + X86_GRP_SSE4A, + X86_GRP_SSSE3, + X86_GRP_PCLMUL, + X86_GRP_XOP, + X86_GRP_CDI, + X86_GRP_ERI, + X86_GRP_TBM, + X86_GRP_16BITMODE, + X86_GRP_NOT64BITMODE, + X86_GRP_SGX, + X86_GRP_DQI, + X86_GRP_BWI, + X86_GRP_PFI, + X86_GRP_VLX, + X86_GRP_SMAP, + X86_GRP_NOVLX, + + X86_GRP_ENDING +} x86_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dbg/capstone/xcore.h b/src/dbg/capstone/xcore.h index f5a6470c..b1c718a5 100644 --- a/src/dbg/capstone/xcore.h +++ b/src/dbg/capstone/xcore.h @@ -1,242 +1,242 @@ -#ifndef CAPSTONE_XCORE_H -#define CAPSTONE_XCORE_H - -/* Capstone Disassembly Engine */ -/* By Nguyen Anh Quynh , 2014 */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "platform.h" - -#ifdef _MSC_VER -#pragma warning(disable:4201) -#endif - -//> Operand type for instruction's operands -typedef enum xcore_op_type -{ - XCORE_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). - XCORE_OP_REG, // = CS_OP_REG (Register operand). - XCORE_OP_IMM, // = CS_OP_IMM (Immediate operand). - XCORE_OP_MEM, // = CS_OP_MEM (Memory operand). -} xcore_op_type; - -// Instruction's operand referring to memory -// This is associated with XCORE_OP_MEM operand type above -typedef struct xcore_op_mem -{ - uint8_t base; // base register - uint8_t index; // index register - int32_t disp; // displacement/offset value - int direct; // +1: forward, -1: backward -} xcore_op_mem; - -// Instruction operand -typedef struct cs_xcore_op -{ - xcore_op_type type; // operand type - union - { - unsigned int reg; // register value for REG operand - int32_t imm; // immediate value for IMM operand - xcore_op_mem mem; // base/disp value for MEM operand - }; -} cs_xcore_op; - -// Instruction structure -typedef struct cs_xcore -{ - // Number of operands of this instruction, - // or 0 when instruction has no operand. - uint8_t op_count; - cs_xcore_op operands[8]; // operands for this instruction. -} cs_xcore; - -//> XCore registers -typedef enum xcore_reg -{ - XCORE_REG_INVALID = 0, - - XCORE_REG_CP, - XCORE_REG_DP, - XCORE_REG_LR, - XCORE_REG_SP, - XCORE_REG_R0, - XCORE_REG_R1, - XCORE_REG_R2, - XCORE_REG_R3, - XCORE_REG_R4, - XCORE_REG_R5, - XCORE_REG_R6, - XCORE_REG_R7, - XCORE_REG_R8, - XCORE_REG_R9, - XCORE_REG_R10, - XCORE_REG_R11, - - //> pseudo registers - XCORE_REG_PC, // pc - - // internal thread registers - // see The-XMOS-XS1-Architecture(X7879A).pdf - XCORE_REG_SCP, // save pc - XCORE_REG_SSR, // save status - XCORE_REG_ET, // exception type - XCORE_REG_ED, // exception data - XCORE_REG_SED, // save exception data - XCORE_REG_KEP, // kernel entry pointer - XCORE_REG_KSP, // kernel stack pointer - XCORE_REG_ID, // thread ID - - XCORE_REG_ENDING, // <-- mark the end of the list of registers -} xcore_reg; - -//> XCore instruction -typedef enum xcore_insn -{ - XCORE_INS_INVALID = 0, - - XCORE_INS_ADD, - XCORE_INS_ANDNOT, - XCORE_INS_AND, - XCORE_INS_ASHR, - XCORE_INS_BAU, - XCORE_INS_BITREV, - XCORE_INS_BLA, - XCORE_INS_BLAT, - XCORE_INS_BL, - XCORE_INS_BF, - XCORE_INS_BT, - XCORE_INS_BU, - XCORE_INS_BRU, - XCORE_INS_BYTEREV, - XCORE_INS_CHKCT, - XCORE_INS_CLRE, - XCORE_INS_CLRPT, - XCORE_INS_CLRSR, - XCORE_INS_CLZ, - XCORE_INS_CRC8, - XCORE_INS_CRC32, - XCORE_INS_DCALL, - XCORE_INS_DENTSP, - XCORE_INS_DGETREG, - XCORE_INS_DIVS, - XCORE_INS_DIVU, - XCORE_INS_DRESTSP, - XCORE_INS_DRET, - XCORE_INS_ECALLF, - XCORE_INS_ECALLT, - XCORE_INS_EDU, - XCORE_INS_EEF, - XCORE_INS_EET, - XCORE_INS_EEU, - XCORE_INS_ENDIN, - XCORE_INS_ENTSP, - XCORE_INS_EQ, - XCORE_INS_EXTDP, - XCORE_INS_EXTSP, - XCORE_INS_FREER, - XCORE_INS_FREET, - XCORE_INS_GETD, - XCORE_INS_GET, - XCORE_INS_GETN, - XCORE_INS_GETR, - XCORE_INS_GETSR, - XCORE_INS_GETST, - XCORE_INS_GETTS, - XCORE_INS_INCT, - XCORE_INS_INIT, - XCORE_INS_INPW, - XCORE_INS_INSHR, - XCORE_INS_INT, - XCORE_INS_IN, - XCORE_INS_KCALL, - XCORE_INS_KENTSP, - XCORE_INS_KRESTSP, - XCORE_INS_KRET, - XCORE_INS_LADD, - XCORE_INS_LD16S, - XCORE_INS_LD8U, - XCORE_INS_LDA16, - XCORE_INS_LDAP, - XCORE_INS_LDAW, - XCORE_INS_LDC, - XCORE_INS_LDW, - XCORE_INS_LDIVU, - XCORE_INS_LMUL, - XCORE_INS_LSS, - XCORE_INS_LSUB, - XCORE_INS_LSU, - XCORE_INS_MACCS, - XCORE_INS_MACCU, - XCORE_INS_MJOIN, - XCORE_INS_MKMSK, - XCORE_INS_MSYNC, - XCORE_INS_MUL, - XCORE_INS_NEG, - XCORE_INS_NOT, - XCORE_INS_OR, - XCORE_INS_OUTCT, - XCORE_INS_OUTPW, - XCORE_INS_OUTSHR, - XCORE_INS_OUTT, - XCORE_INS_OUT, - XCORE_INS_PEEK, - XCORE_INS_REMS, - XCORE_INS_REMU, - XCORE_INS_RETSP, - XCORE_INS_SETCLK, - XCORE_INS_SET, - XCORE_INS_SETC, - XCORE_INS_SETD, - XCORE_INS_SETEV, - XCORE_INS_SETN, - XCORE_INS_SETPSC, - XCORE_INS_SETPT, - XCORE_INS_SETRDY, - XCORE_INS_SETSR, - XCORE_INS_SETTW, - XCORE_INS_SETV, - XCORE_INS_SEXT, - XCORE_INS_SHL, - XCORE_INS_SHR, - XCORE_INS_SSYNC, - XCORE_INS_ST16, - XCORE_INS_ST8, - XCORE_INS_STW, - XCORE_INS_SUB, - XCORE_INS_SYNCR, - XCORE_INS_TESTCT, - XCORE_INS_TESTLCL, - XCORE_INS_TESTWCT, - XCORE_INS_TSETMR, - XCORE_INS_START, - XCORE_INS_WAITEF, - XCORE_INS_WAITET, - XCORE_INS_WAITEU, - XCORE_INS_XOR, - XCORE_INS_ZEXT, - - XCORE_INS_ENDING, // <-- mark the end of the list of instructions -} xcore_insn; - -//> Group of XCore instructions -typedef enum xcore_insn_group -{ - XCORE_GRP_INVALID = 0, // = CS_GRP_INVALID - - //> Generic groups - // all jump instructions (conditional+direct+indirect jumps) - XCORE_GRP_JUMP, // = CS_GRP_JUMP - - XCORE_GRP_ENDING, // <-- mark the end of the list of groups -} xcore_insn_group; - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef CAPSTONE_XCORE_H +#define CAPSTONE_XCORE_H + +/* Capstone Disassembly Engine */ +/* By Nguyen Anh Quynh , 2014 */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "platform.h" + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +//> Operand type for instruction's operands +typedef enum xcore_op_type +{ + XCORE_OP_INVALID = 0, // = CS_OP_INVALID (Uninitialized). + XCORE_OP_REG, // = CS_OP_REG (Register operand). + XCORE_OP_IMM, // = CS_OP_IMM (Immediate operand). + XCORE_OP_MEM, // = CS_OP_MEM (Memory operand). +} xcore_op_type; + +// Instruction's operand referring to memory +// This is associated with XCORE_OP_MEM operand type above +typedef struct xcore_op_mem +{ + uint8_t base; // base register + uint8_t index; // index register + int32_t disp; // displacement/offset value + int direct; // +1: forward, -1: backward +} xcore_op_mem; + +// Instruction operand +typedef struct cs_xcore_op +{ + xcore_op_type type; // operand type + union + { + unsigned int reg; // register value for REG operand + int32_t imm; // immediate value for IMM operand + xcore_op_mem mem; // base/disp value for MEM operand + }; +} cs_xcore_op; + +// Instruction structure +typedef struct cs_xcore +{ + // Number of operands of this instruction, + // or 0 when instruction has no operand. + uint8_t op_count; + cs_xcore_op operands[8]; // operands for this instruction. +} cs_xcore; + +//> XCore registers +typedef enum xcore_reg +{ + XCORE_REG_INVALID = 0, + + XCORE_REG_CP, + XCORE_REG_DP, + XCORE_REG_LR, + XCORE_REG_SP, + XCORE_REG_R0, + XCORE_REG_R1, + XCORE_REG_R2, + XCORE_REG_R3, + XCORE_REG_R4, + XCORE_REG_R5, + XCORE_REG_R6, + XCORE_REG_R7, + XCORE_REG_R8, + XCORE_REG_R9, + XCORE_REG_R10, + XCORE_REG_R11, + + //> pseudo registers + XCORE_REG_PC, // pc + + // internal thread registers + // see The-XMOS-XS1-Architecture(X7879A).pdf + XCORE_REG_SCP, // save pc + XCORE_REG_SSR, // save status + XCORE_REG_ET, // exception type + XCORE_REG_ED, // exception data + XCORE_REG_SED, // save exception data + XCORE_REG_KEP, // kernel entry pointer + XCORE_REG_KSP, // kernel stack pointer + XCORE_REG_ID, // thread ID + + XCORE_REG_ENDING, // <-- mark the end of the list of registers +} xcore_reg; + +//> XCore instruction +typedef enum xcore_insn +{ + XCORE_INS_INVALID = 0, + + XCORE_INS_ADD, + XCORE_INS_ANDNOT, + XCORE_INS_AND, + XCORE_INS_ASHR, + XCORE_INS_BAU, + XCORE_INS_BITREV, + XCORE_INS_BLA, + XCORE_INS_BLAT, + XCORE_INS_BL, + XCORE_INS_BF, + XCORE_INS_BT, + XCORE_INS_BU, + XCORE_INS_BRU, + XCORE_INS_BYTEREV, + XCORE_INS_CHKCT, + XCORE_INS_CLRE, + XCORE_INS_CLRPT, + XCORE_INS_CLRSR, + XCORE_INS_CLZ, + XCORE_INS_CRC8, + XCORE_INS_CRC32, + XCORE_INS_DCALL, + XCORE_INS_DENTSP, + XCORE_INS_DGETREG, + XCORE_INS_DIVS, + XCORE_INS_DIVU, + XCORE_INS_DRESTSP, + XCORE_INS_DRET, + XCORE_INS_ECALLF, + XCORE_INS_ECALLT, + XCORE_INS_EDU, + XCORE_INS_EEF, + XCORE_INS_EET, + XCORE_INS_EEU, + XCORE_INS_ENDIN, + XCORE_INS_ENTSP, + XCORE_INS_EQ, + XCORE_INS_EXTDP, + XCORE_INS_EXTSP, + XCORE_INS_FREER, + XCORE_INS_FREET, + XCORE_INS_GETD, + XCORE_INS_GET, + XCORE_INS_GETN, + XCORE_INS_GETR, + XCORE_INS_GETSR, + XCORE_INS_GETST, + XCORE_INS_GETTS, + XCORE_INS_INCT, + XCORE_INS_INIT, + XCORE_INS_INPW, + XCORE_INS_INSHR, + XCORE_INS_INT, + XCORE_INS_IN, + XCORE_INS_KCALL, + XCORE_INS_KENTSP, + XCORE_INS_KRESTSP, + XCORE_INS_KRET, + XCORE_INS_LADD, + XCORE_INS_LD16S, + XCORE_INS_LD8U, + XCORE_INS_LDA16, + XCORE_INS_LDAP, + XCORE_INS_LDAW, + XCORE_INS_LDC, + XCORE_INS_LDW, + XCORE_INS_LDIVU, + XCORE_INS_LMUL, + XCORE_INS_LSS, + XCORE_INS_LSUB, + XCORE_INS_LSU, + XCORE_INS_MACCS, + XCORE_INS_MACCU, + XCORE_INS_MJOIN, + XCORE_INS_MKMSK, + XCORE_INS_MSYNC, + XCORE_INS_MUL, + XCORE_INS_NEG, + XCORE_INS_NOT, + XCORE_INS_OR, + XCORE_INS_OUTCT, + XCORE_INS_OUTPW, + XCORE_INS_OUTSHR, + XCORE_INS_OUTT, + XCORE_INS_OUT, + XCORE_INS_PEEK, + XCORE_INS_REMS, + XCORE_INS_REMU, + XCORE_INS_RETSP, + XCORE_INS_SETCLK, + XCORE_INS_SET, + XCORE_INS_SETC, + XCORE_INS_SETD, + XCORE_INS_SETEV, + XCORE_INS_SETN, + XCORE_INS_SETPSC, + XCORE_INS_SETPT, + XCORE_INS_SETRDY, + XCORE_INS_SETSR, + XCORE_INS_SETTW, + XCORE_INS_SETV, + XCORE_INS_SEXT, + XCORE_INS_SHL, + XCORE_INS_SHR, + XCORE_INS_SSYNC, + XCORE_INS_ST16, + XCORE_INS_ST8, + XCORE_INS_STW, + XCORE_INS_SUB, + XCORE_INS_SYNCR, + XCORE_INS_TESTCT, + XCORE_INS_TESTLCL, + XCORE_INS_TESTWCT, + XCORE_INS_TSETMR, + XCORE_INS_START, + XCORE_INS_WAITEF, + XCORE_INS_WAITET, + XCORE_INS_WAITEU, + XCORE_INS_XOR, + XCORE_INS_ZEXT, + + XCORE_INS_ENDING, // <-- mark the end of the list of instructions +} xcore_insn; + +//> Group of XCore instructions +typedef enum xcore_insn_group +{ + XCORE_GRP_INVALID = 0, // = CS_GRP_INVALID + + //> Generic groups + // all jump instructions (conditional+direct+indirect jumps) + XCORE_GRP_JUMP, // = CS_GRP_JUMP + + XCORE_GRP_ENDING, // <-- mark the end of the list of groups +} xcore_insn_group; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dbg/command.cpp b/src/dbg/command.cpp index a488579e..98e79d2c 100644 --- a/src/dbg/command.cpp +++ b/src/dbg/command.cpp @@ -1,412 +1,412 @@ -/** - @file command.cpp - - @brief Implements the command class. - */ - -#include "command.h" -#include "value.h" -#include "console.h" -#include "commandparser.h" - -COMMAND* cmd_list = 0; - -/** -\brief Finds a ::COMMAND in a command list. -\param [in] command list. -\param name The name of the command to find. -\param [out] Link to the command. -\return null if it fails, else a ::COMMAND*. -*/ -COMMAND* cmdfind(const char* name, COMMAND** link) -{ - COMMAND* cur = cmd_list; - if(!cur->name) - return 0; - COMMAND* prev = 0; - while(cur) - { - if(arraycontains(cur->name, name)) - { - if(link) - *link = prev; - return cur; - } - prev = cur; - cur = cur->next; - } - return 0; -} - -/** -\brief Initialize a command list. -\return a ::COMMAND* -*/ -COMMAND* cmdinit() -{ - cmd_list = (COMMAND*)emalloc(sizeof(COMMAND), "cmdinit:cmd"); - memset(cmd_list, 0, sizeof(COMMAND)); - return cmd_list; -} - -/** -\brief Clear a command list. -\param [in] cmd_list Command list to clear. -*/ -void cmdfree() -{ - COMMAND* cur = cmd_list; - while(cur) - { - efree(cur->name, "cmdfree:cur->name"); - COMMAND* next = cur->next; - efree(cur, "cmdfree:cur"); - cur = next; - } -} - -/** -\brief Creates a new command and adds it to the list. -\param [in,out] command_list Command list. Cannot be null. -\param name The command name. -\param cbCommand The command callback. -\param debugonly true if the command can only be executed in a debugging context. -\return true if the command was successfully added to the list. -*/ -bool cmdnew(const char* name, CBCOMMAND cbCommand, bool debugonly) -{ - if (!cmd_list || !cbCommand || !name || !*name || cmdfind(name, 0)) - return false; - COMMAND* cmd; - bool nonext = false; - if (!cmd_list->name) - { - cmd = cmd_list; - nonext = true; - } - else - cmd = (COMMAND*)emalloc(sizeof(COMMAND), "cmdnew:cmd"); - memset(cmd, 0, sizeof(COMMAND)); - cmd->name = (char*)emalloc(strlen(name) + 1, "cmdnew:cmd->name"); - strcpy(cmd->name, name); - cmd->cbCommand = cbCommand; - cmd->debugonly = debugonly; - COMMAND* cur = cmd_list; - if(!nonext) - { - while(cur->next) - cur = cur->next; - cur->next = cmd; - } - return true; -} - -/** -\brief Gets a ::COMMAND from the command list. -\param [in] command_list Command list. -\param cmd The command to get from the list. -\return null if the command was not found. Otherwise a ::COMMAND*. -*/ -COMMAND* cmdget(const char* cmd) -{ - char new_cmd[deflen] = ""; - strcpy_s(new_cmd, deflen, cmd); - int len = (int)strlen(new_cmd); - int start = 0; - while(new_cmd[start] != ' ' && start < len) - start++; - new_cmd[start] = 0; - COMMAND* found = cmdfind(new_cmd, 0); - if(!found) - return 0; - return found; -} - -/** -\brief Sets a new command callback and debugonly property in a command list. -\param [in] command_list Command list. -\param name The name of the command to change. -\param cbCommand The new command callback. -\param debugonly The new debugonly value. -\return The old command callback. -*/ -CBCOMMAND cmdset(const char* name, CBCOMMAND cbCommand, bool debugonly) -{ - if(!cbCommand) - return 0; - COMMAND* found = cmdfind(name, 0); - if(!found) - return 0; - CBCOMMAND old = found->cbCommand; - found->cbCommand = cbCommand; - found->debugonly = debugonly; - return old; -} - -/** -\brief Deletes a command from a command list. -\param [in] command_list Command list. -\param name The name of the command to delete. -\return true if the command was deleted. -*/ -bool cmddel(const char* name) -{ - COMMAND* prev = 0; - COMMAND* found = cmdfind(name, &prev); - if(!found) - return false; - efree(found->name, "cmddel:found->name"); - if (found == cmd_list) - { - COMMAND* next = cmd_list->next; - if(next) - { - memcpy(cmd_list, cmd_list->next, sizeof(COMMAND)); - cmd_list->next = next->next; - efree(next, "cmddel:next"); - } - else - memset(cmd_list, 0, sizeof(COMMAND)); - } - else - { - prev->next = found->next; - efree(found, "cmddel:found"); - } - return true; -} - -/* -command_list: command list -cbUnknownCommand: function to execute when an unknown command was found -cbCommandProvider: function that provides commands (fgets for example), does not return until a command was found -cbCommandFinder: non-default command finder -error_is_fatal: error return of a command callback stops the command processing -*/ - -/** -\brief Initiates a command loop. This function will not return until a command returns ::STATUS_EXIT. -\param [in] command_list Command list to use for the command lookups. -\param cbUnknownCommand The unknown command callback. -\param cbCommandProvider The command provider callback. -\param cbCommandFinder The command finder callback. -\param error_is_fatal true if commands that return ::STATUS_ERROR terminate the command loop. -\return A CMDRESULT, will always be ::STATUS_EXIT. -*/ -CMDRESULT cmdloop(CBCOMMAND cbUnknownCommand, CBCOMMANDPROVIDER cbCommandProvider, CBCOMMANDFINDER cbCommandFinder, bool error_is_fatal) -{ - if(!cbUnknownCommand || !cbCommandProvider) - return STATUS_ERROR; - char command[deflen] = ""; - bool bLoop = true; - while(bLoop) - { - if(!cbCommandProvider(command, deflen)) - break; - if(strlen(command)) - { - strcpy_s(command, StringUtils::Trim(command).c_str()); - COMMAND* cmd; - if(!cbCommandFinder) //'clean' command processing - cmd = cmdget(command); - else //'dirty' command processing - cmd = cbCommandFinder(command); - - if(!cmd || !cmd->cbCommand) //unknown command - { - char* argv[1]; - *argv = command; - CMDRESULT res = cbUnknownCommand(1, argv); - if((error_is_fatal && res == STATUS_ERROR) || res == STATUS_EXIT) - bLoop = false; - } - else - { - if(cmd->debugonly && !DbgIsDebugging()) - { - dputs("this command is debug-only"); - if(error_is_fatal) - bLoop = false; - } - else - { - Command commandParsed(command); - int argcount = commandParsed.GetArgCount(); - char** argv = (char**)emalloc((argcount + 1) * sizeof(char*), "cmdloop:argv"); - argv[0] = command; - for(int i = 0; i < argcount; i++) - { - argv[i + 1] = (char*)emalloc(deflen, "cmdloop:argv[i+1]"); - *argv[i + 1] = 0; - strcpy_s(argv[i + 1], deflen, commandParsed.GetArg(i).c_str()); - } - CMDRESULT res = cmd->cbCommand(argcount + 1, argv); - for(int i = 0; i < argcount; i++) - efree(argv[i + 1], "cmdloop:argv[i+1]"); - efree(argv, "cmdloop:argv"); - if((error_is_fatal && res == STATUS_ERROR) || res == STATUS_EXIT) - bLoop = false; - } - } - } - } - return STATUS_EXIT; -} - -/* -- custom command formatting rules -*/ - -/** -\brief Query if a string is a valid expression. -\param expression The expression to check. -\return true if the string is a valid expression. -*/ -static bool isvalidexpression(const char* expression) -{ - duint value; - return valfromstring(expression, &value); -} - -/** -\brief Check if a character is a mathematical operator. Used to determine stuff like "a *= b" -\param ch The character to check. -\return true if the character is an operator, false otherwise. -*/ -static bool mathisoperator(const char ch) -{ - switch(ch) - { - case '*': - case '`': - case '/': - case '%': - case '+': - case '-': - case '<': - case '>': - case '&': - case '^': - case '|': - return true; - default: - return false; - } -} - -/** -\brief Special formats a given command. Used as a little hack to support stuff like 'x++' and 'x=y' -\param [in,out] string String to format. -*/ -static void specialformat(char* string) -{ - int len = (int)strlen(string); - char* found = strstr(string, "="); - char str[deflen] = ""; - char backup[deflen] = ""; - strcpy_s(backup, string); //create a backup of the string - if(found) //contains = - { - char* a = (found - 1); - *found = 0; - found++; - if(!*found) - { - *found = '='; - return; - } - - if(mathisoperator(*a)) //x*=3 -> x=x*3 - { - char op = *a; - *a = 0; - if(isvalidexpression(string)) - sprintf_s(str, "mov %s,%s%c%s", string, string, op, found); - else - strcpy_s(str, backup); - } - else //x=y - { - if(isvalidexpression(found)) - sprintf_s(str, "mov %s,%s", string, found); - else - strcpy_s(str, backup); - } - strcpy_s(string, deflen, str); - } - else if((string[len - 1] == '+' && string[len - 2] == '+') || (string[len - 1] == '-' && string[len - 2] == '-')) //eax++/eax-- - { - string[len - 2] = 0; - char op = string[len - 1]; - if(isvalidexpression(string)) - sprintf_s(str, "mov %s,%s%c1", string, string, op); - else - strcpy_s(str, backup); - strcpy_s(string, deflen, str); - } -} - -/* -- 'default' command finder, with some custom rules -*/ - -/** -\brief Default command finder. It uses specialformat() and mathformat() to make sure the command is optimally checked. -\param [in] cmd_list Command list. -\param [in] command Command name. -\return null if it fails, else a COMMAND*. -*/ -COMMAND* cmdfindmain(char* command) -{ - COMMAND* cmd = cmdfind(command, 0); - if(!cmd) - { - specialformat(command); - cmd = cmdget(command); - } - return cmd; -} - -/** -\brief Directly execute a command. -\param [in,out] cmd_list Command list. -\param cmd The command to execute. -\return A CMDRESULT. -*/ -CMDRESULT cmddirectexec(const char* cmd, ...) -{ - // Fail on null strings - ASSERT_NONNULL(cmd); - - // Don't allow anyone to send in empty strings - if(!cmd || strlen(cmd) <= 0) - return STATUS_ERROR; - - char command[deflen]; - va_list ap; - va_start(ap, cmd); - _vsnprintf_s(command, _TRUNCATE, cmd, ap); - va_end(ap); - - strcpy_s(command, StringUtils::Trim(cmd).c_str()); - COMMAND* found = cmdfindmain(command); - if(!found || !found->cbCommand) - return STATUS_ERROR; - if(found->debugonly && !DbgIsDebugging()) - return STATUS_ERROR; - Command cmdParsed(command); - int argcount = cmdParsed.GetArgCount(); - char** argv = (char**)emalloc((argcount + 1) * sizeof(char*), "cmddirectexec:argv"); - argv[0] = command; - for(int i = 0; i < argcount; i++) - { - argv[i + 1] = (char*)emalloc(deflen, "cmddirectexec:argv[i+1]"); - *argv[i + 1] = 0; - strcpy_s(argv[i + 1], deflen, cmdParsed.GetArg(i).c_str()); - } - CMDRESULT res = found->cbCommand(argcount + 1, argv); - for(int i = 0; i < argcount; i++) - efree(argv[i + 1], "cmddirectexec:argv[i+1]"); - efree(argv, "cmddirectexec:argv"); - return res; -} +/** + @file command.cpp + + @brief Implements the command class. + */ + +#include "command.h" +#include "value.h" +#include "console.h" +#include "commandparser.h" + +COMMAND* cmd_list = 0; + +/** +\brief Finds a ::COMMAND in a command list. +\param [in] command list. +\param name The name of the command to find. +\param [out] Link to the command. +\return null if it fails, else a ::COMMAND*. +*/ +COMMAND* cmdfind(const char* name, COMMAND** link) +{ + COMMAND* cur = cmd_list; + if(!cur->name) + return 0; + COMMAND* prev = 0; + while(cur) + { + if(arraycontains(cur->name, name)) + { + if(link) + *link = prev; + return cur; + } + prev = cur; + cur = cur->next; + } + return 0; +} + +/** +\brief Initialize a command list. +\return a ::COMMAND* +*/ +COMMAND* cmdinit() +{ + cmd_list = (COMMAND*)emalloc(sizeof(COMMAND), "cmdinit:cmd"); + memset(cmd_list, 0, sizeof(COMMAND)); + return cmd_list; +} + +/** +\brief Clear a command list. +\param [in] cmd_list Command list to clear. +*/ +void cmdfree() +{ + COMMAND* cur = cmd_list; + while(cur) + { + efree(cur->name, "cmdfree:cur->name"); + COMMAND* next = cur->next; + efree(cur, "cmdfree:cur"); + cur = next; + } +} + +/** +\brief Creates a new command and adds it to the list. +\param [in,out] command_list Command list. Cannot be null. +\param name The command name. +\param cbCommand The command callback. +\param debugonly true if the command can only be executed in a debugging context. +\return true if the command was successfully added to the list. +*/ +bool cmdnew(const char* name, CBCOMMAND cbCommand, bool debugonly) +{ + if (!cmd_list || !cbCommand || !name || !*name || cmdfind(name, 0)) + return false; + COMMAND* cmd; + bool nonext = false; + if (!cmd_list->name) + { + cmd = cmd_list; + nonext = true; + } + else + cmd = (COMMAND*)emalloc(sizeof(COMMAND), "cmdnew:cmd"); + memset(cmd, 0, sizeof(COMMAND)); + cmd->name = (char*)emalloc(strlen(name) + 1, "cmdnew:cmd->name"); + strcpy(cmd->name, name); + cmd->cbCommand = cbCommand; + cmd->debugonly = debugonly; + COMMAND* cur = cmd_list; + if(!nonext) + { + while(cur->next) + cur = cur->next; + cur->next = cmd; + } + return true; +} + +/** +\brief Gets a ::COMMAND from the command list. +\param [in] command_list Command list. +\param cmd The command to get from the list. +\return null if the command was not found. Otherwise a ::COMMAND*. +*/ +COMMAND* cmdget(const char* cmd) +{ + char new_cmd[deflen] = ""; + strcpy_s(new_cmd, deflen, cmd); + int len = (int)strlen(new_cmd); + int start = 0; + while(new_cmd[start] != ' ' && start < len) + start++; + new_cmd[start] = 0; + COMMAND* found = cmdfind(new_cmd, 0); + if(!found) + return 0; + return found; +} + +/** +\brief Sets a new command callback and debugonly property in a command list. +\param [in] command_list Command list. +\param name The name of the command to change. +\param cbCommand The new command callback. +\param debugonly The new debugonly value. +\return The old command callback. +*/ +CBCOMMAND cmdset(const char* name, CBCOMMAND cbCommand, bool debugonly) +{ + if(!cbCommand) + return 0; + COMMAND* found = cmdfind(name, 0); + if(!found) + return 0; + CBCOMMAND old = found->cbCommand; + found->cbCommand = cbCommand; + found->debugonly = debugonly; + return old; +} + +/** +\brief Deletes a command from a command list. +\param [in] command_list Command list. +\param name The name of the command to delete. +\return true if the command was deleted. +*/ +bool cmddel(const char* name) +{ + COMMAND* prev = 0; + COMMAND* found = cmdfind(name, &prev); + if(!found) + return false; + efree(found->name, "cmddel:found->name"); + if (found == cmd_list) + { + COMMAND* next = cmd_list->next; + if(next) + { + memcpy(cmd_list, cmd_list->next, sizeof(COMMAND)); + cmd_list->next = next->next; + efree(next, "cmddel:next"); + } + else + memset(cmd_list, 0, sizeof(COMMAND)); + } + else + { + prev->next = found->next; + efree(found, "cmddel:found"); + } + return true; +} + +/* +command_list: command list +cbUnknownCommand: function to execute when an unknown command was found +cbCommandProvider: function that provides commands (fgets for example), does not return until a command was found +cbCommandFinder: non-default command finder +error_is_fatal: error return of a command callback stops the command processing +*/ + +/** +\brief Initiates a command loop. This function will not return until a command returns ::STATUS_EXIT. +\param [in] command_list Command list to use for the command lookups. +\param cbUnknownCommand The unknown command callback. +\param cbCommandProvider The command provider callback. +\param cbCommandFinder The command finder callback. +\param error_is_fatal true if commands that return ::STATUS_ERROR terminate the command loop. +\return A CMDRESULT, will always be ::STATUS_EXIT. +*/ +CMDRESULT cmdloop(CBCOMMAND cbUnknownCommand, CBCOMMANDPROVIDER cbCommandProvider, CBCOMMANDFINDER cbCommandFinder, bool error_is_fatal) +{ + if(!cbUnknownCommand || !cbCommandProvider) + return STATUS_ERROR; + char command[deflen] = ""; + bool bLoop = true; + while(bLoop) + { + if(!cbCommandProvider(command, deflen)) + break; + if(strlen(command)) + { + strcpy_s(command, StringUtils::Trim(command).c_str()); + COMMAND* cmd; + if(!cbCommandFinder) //'clean' command processing + cmd = cmdget(command); + else //'dirty' command processing + cmd = cbCommandFinder(command); + + if(!cmd || !cmd->cbCommand) //unknown command + { + char* argv[1]; + *argv = command; + CMDRESULT res = cbUnknownCommand(1, argv); + if((error_is_fatal && res == STATUS_ERROR) || res == STATUS_EXIT) + bLoop = false; + } + else + { + if(cmd->debugonly && !DbgIsDebugging()) + { + dputs("this command is debug-only"); + if(error_is_fatal) + bLoop = false; + } + else + { + Command commandParsed(command); + int argcount = commandParsed.GetArgCount(); + char** argv = (char**)emalloc((argcount + 1) * sizeof(char*), "cmdloop:argv"); + argv[0] = command; + for(int i = 0; i < argcount; i++) + { + argv[i + 1] = (char*)emalloc(deflen, "cmdloop:argv[i+1]"); + *argv[i + 1] = 0; + strcpy_s(argv[i + 1], deflen, commandParsed.GetArg(i).c_str()); + } + CMDRESULT res = cmd->cbCommand(argcount + 1, argv); + for(int i = 0; i < argcount; i++) + efree(argv[i + 1], "cmdloop:argv[i+1]"); + efree(argv, "cmdloop:argv"); + if((error_is_fatal && res == STATUS_ERROR) || res == STATUS_EXIT) + bLoop = false; + } + } + } + } + return STATUS_EXIT; +} + +/* +- custom command formatting rules +*/ + +/** +\brief Query if a string is a valid expression. +\param expression The expression to check. +\return true if the string is a valid expression. +*/ +static bool isvalidexpression(const char* expression) +{ + duint value; + return valfromstring(expression, &value); +} + +/** +\brief Check if a character is a mathematical operator. Used to determine stuff like "a *= b" +\param ch The character to check. +\return true if the character is an operator, false otherwise. +*/ +static bool mathisoperator(const char ch) +{ + switch(ch) + { + case '*': + case '`': + case '/': + case '%': + case '+': + case '-': + case '<': + case '>': + case '&': + case '^': + case '|': + return true; + default: + return false; + } +} + +/** +\brief Special formats a given command. Used as a little hack to support stuff like 'x++' and 'x=y' +\param [in,out] string String to format. +*/ +static void specialformat(char* string) +{ + int len = (int)strlen(string); + char* found = strstr(string, "="); + char str[deflen] = ""; + char backup[deflen] = ""; + strcpy_s(backup, string); //create a backup of the string + if(found) //contains = + { + char* a = (found - 1); + *found = 0; + found++; + if(!*found) + { + *found = '='; + return; + } + + if(mathisoperator(*a)) //x*=3 -> x=x*3 + { + char op = *a; + *a = 0; + if(isvalidexpression(string)) + sprintf_s(str, "mov %s,%s%c%s", string, string, op, found); + else + strcpy_s(str, backup); + } + else //x=y + { + if(isvalidexpression(found)) + sprintf_s(str, "mov %s,%s", string, found); + else + strcpy_s(str, backup); + } + strcpy_s(string, deflen, str); + } + else if((string[len - 1] == '+' && string[len - 2] == '+') || (string[len - 1] == '-' && string[len - 2] == '-')) //eax++/eax-- + { + string[len - 2] = 0; + char op = string[len - 1]; + if(isvalidexpression(string)) + sprintf_s(str, "mov %s,%s%c1", string, string, op); + else + strcpy_s(str, backup); + strcpy_s(string, deflen, str); + } +} + +/* +- 'default' command finder, with some custom rules +*/ + +/** +\brief Default command finder. It uses specialformat() and mathformat() to make sure the command is optimally checked. +\param [in] cmd_list Command list. +\param [in] command Command name. +\return null if it fails, else a COMMAND*. +*/ +COMMAND* cmdfindmain(char* command) +{ + COMMAND* cmd = cmdfind(command, 0); + if(!cmd) + { + specialformat(command); + cmd = cmdget(command); + } + return cmd; +} + +/** +\brief Directly execute a command. +\param [in,out] cmd_list Command list. +\param cmd The command to execute. +\return A CMDRESULT. +*/ +CMDRESULT cmddirectexec(const char* cmd, ...) +{ + // Fail on null strings + ASSERT_NONNULL(cmd); + + // Don't allow anyone to send in empty strings + if(!cmd || strlen(cmd) <= 0) + return STATUS_ERROR; + + char command[deflen]; + va_list ap; + va_start(ap, cmd); + _vsnprintf_s(command, _TRUNCATE, cmd, ap); + va_end(ap); + + strcpy_s(command, StringUtils::Trim(cmd).c_str()); + COMMAND* found = cmdfindmain(command); + if(!found || !found->cbCommand) + return STATUS_ERROR; + if(found->debugonly && !DbgIsDebugging()) + return STATUS_ERROR; + Command cmdParsed(command); + int argcount = cmdParsed.GetArgCount(); + char** argv = (char**)emalloc((argcount + 1) * sizeof(char*), "cmddirectexec:argv"); + argv[0] = command; + for(int i = 0; i < argcount; i++) + { + argv[i + 1] = (char*)emalloc(deflen, "cmddirectexec:argv[i+1]"); + *argv[i + 1] = 0; + strcpy_s(argv[i + 1], deflen, cmdParsed.GetArg(i).c_str()); + } + CMDRESULT res = found->cbCommand(argcount + 1, argv); + for(int i = 0; i < argcount; i++) + efree(argv[i + 1], "cmddirectexec:argv[i+1]"); + efree(argv, "cmddirectexec:argv"); + return res; +} diff --git a/src/dbg/command.h b/src/dbg/command.h index 22f66fd5..0658103b 100644 --- a/src/dbg/command.h +++ b/src/dbg/command.h @@ -1,42 +1,42 @@ -#ifndef _COMMAND_H -#define _COMMAND_H - -#include "_global.h" - -//typedefs - -struct COMMAND; - -enum CMDRESULT -{ - STATUS_ERROR = false, - STATUS_CONTINUE = true, - STATUS_EXIT = 2, - STATUS_PAUSE = 3 -}; - -typedef CMDRESULT(*CBCOMMAND)(int, char**); -typedef bool (*CBCOMMANDPROVIDER)(char*, int); -typedef COMMAND* (*CBCOMMANDFINDER)(char*); - -struct COMMAND -{ - char* name; - CBCOMMAND cbCommand; - bool debugonly; - COMMAND* next; -}; - -//functions -COMMAND* cmdinit(); -void cmdfree(); -COMMAND* cmdfind(const char* name, COMMAND** link); -bool cmdnew(const char* name, CBCOMMAND cbCommand, bool debugonly); -COMMAND* cmdget(const char* cmd); -CBCOMMAND cmdset(const char* name, CBCOMMAND cbCommand, bool debugonly); -bool cmddel(const char* name); -CMDRESULT cmdloop(CBCOMMAND cbUnknownCommand, CBCOMMANDPROVIDER cbCommandProvider, CBCOMMANDFINDER cbCommandFinder, bool error_is_fatal); -COMMAND* cmdfindmain(char* command); -CMDRESULT cmddirectexec(const char* cmd, ...); - -#endif // _COMMAND_H +#ifndef _COMMAND_H +#define _COMMAND_H + +#include "_global.h" + +//typedefs + +struct COMMAND; + +enum CMDRESULT +{ + STATUS_ERROR = false, + STATUS_CONTINUE = true, + STATUS_EXIT = 2, + STATUS_PAUSE = 3 +}; + +typedef CMDRESULT(*CBCOMMAND)(int, char**); +typedef bool (*CBCOMMANDPROVIDER)(char*, int); +typedef COMMAND* (*CBCOMMANDFINDER)(char*); + +struct COMMAND +{ + char* name; + CBCOMMAND cbCommand; + bool debugonly; + COMMAND* next; +}; + +//functions +COMMAND* cmdinit(); +void cmdfree(); +COMMAND* cmdfind(const char* name, COMMAND** link); +bool cmdnew(const char* name, CBCOMMAND cbCommand, bool debugonly); +COMMAND* cmdget(const char* cmd); +CBCOMMAND cmdset(const char* name, CBCOMMAND cbCommand, bool debugonly); +bool cmddel(const char* name); +CMDRESULT cmdloop(CBCOMMAND cbUnknownCommand, CBCOMMANDPROVIDER cbCommandProvider, CBCOMMANDFINDER cbCommandFinder, bool error_is_fatal); +COMMAND* cmdfindmain(char* command); +CMDRESULT cmddirectexec(const char* cmd, ...); + +#endif // _COMMAND_H diff --git a/src/dbg/commandparser.cpp b/src/dbg/commandparser.cpp index 325dc836..0cf5745d 100644 --- a/src/dbg/commandparser.cpp +++ b/src/dbg/commandparser.cpp @@ -1,116 +1,116 @@ -#include "commandparser.h" - -Command::Command(const String & command) -{ - ParseState state = Default; - int len = (int)command.length(); - for(int i = 0; i < len; i++) - { - char ch = command[i]; - switch(state) - { - case Default: - switch(ch) - { - case '\t': - case ' ': - if(!_tokens.size()) - dataFinish(); - break; - case ',': - dataFinish(); - break; - case '\\': - state = Escaped; - break; - case '\"': - state = Text; - break; - default: - dataAppend(ch); - break; - } - break; - case Escaped: - switch(ch) - { - case '\t': - case ' ': - dataAppend(' '); - break; - case ',': - dataAppend(ch); - break; - case '\"': - dataAppend(ch); - break; - default: - dataAppend('\\'); - dataAppend(ch); - break; - } - state = Default; - break; - case Text: - switch(ch) - { - case '\\': - state = TextEscaped; - break; - case '\"': - dataFinish(); - state = Default; - break; - default: - dataAppend(ch); - break; - } - break; - case TextEscaped: - switch(ch) - { - case '\"': - dataAppend(ch); - break; - default: - dataAppend('\\'); - dataAppend(ch); - break; - } - state = Text; - break; - } - } - if(state == Escaped || state == TextEscaped) - dataAppend('\\'); - dataFinish(); -} - -const String Command::GetText() -{ - return _tokens.size() ? _tokens[0] : String(); -} - -const int Command::GetArgCount() -{ - return _tokens.size() ? (int)_tokens.size() - 1 : 0; -} - -const String Command::GetArg(int argnum) -{ - return (int)_tokens.size() < argnum + 1 ? String() : _tokens[argnum + 1]; -} - -void Command::dataAppend(const char ch) -{ - _data += ch; -} - -void Command::dataFinish() -{ - if(_data.length()) - { - _tokens.push_back(_data); - _data.clear(); - } -} +#include "commandparser.h" + +Command::Command(const String & command) +{ + ParseState state = Default; + int len = (int)command.length(); + for(int i = 0; i < len; i++) + { + char ch = command[i]; + switch(state) + { + case Default: + switch(ch) + { + case '\t': + case ' ': + if(!_tokens.size()) + dataFinish(); + break; + case ',': + dataFinish(); + break; + case '\\': + state = Escaped; + break; + case '\"': + state = Text; + break; + default: + dataAppend(ch); + break; + } + break; + case Escaped: + switch(ch) + { + case '\t': + case ' ': + dataAppend(' '); + break; + case ',': + dataAppend(ch); + break; + case '\"': + dataAppend(ch); + break; + default: + dataAppend('\\'); + dataAppend(ch); + break; + } + state = Default; + break; + case Text: + switch(ch) + { + case '\\': + state = TextEscaped; + break; + case '\"': + dataFinish(); + state = Default; + break; + default: + dataAppend(ch); + break; + } + break; + case TextEscaped: + switch(ch) + { + case '\"': + dataAppend(ch); + break; + default: + dataAppend('\\'); + dataAppend(ch); + break; + } + state = Text; + break; + } + } + if(state == Escaped || state == TextEscaped) + dataAppend('\\'); + dataFinish(); +} + +const String Command::GetText() +{ + return _tokens.size() ? _tokens[0] : String(); +} + +const int Command::GetArgCount() +{ + return _tokens.size() ? (int)_tokens.size() - 1 : 0; +} + +const String Command::GetArg(int argnum) +{ + return (int)_tokens.size() < argnum + 1 ? String() : _tokens[argnum + 1]; +} + +void Command::dataAppend(const char ch) +{ + _data += ch; +} + +void Command::dataFinish() +{ + if(_data.length()) + { + _tokens.push_back(_data); + _data.clear(); + } +} diff --git a/src/dbg/commandparser.h b/src/dbg/commandparser.h index 999c9df1..4c15a69b 100644 --- a/src/dbg/commandparser.h +++ b/src/dbg/commandparser.h @@ -1,30 +1,30 @@ -#ifndef _COMMANDPARSER_H -#define _COMMANDPARSER_H - -#include "_global.h" - -class Command -{ -public: - Command(const String & command); - const String GetText(); - const String GetArg(const int argnum); - const int GetArgCount(); - -private: - String _data; - std::vector _tokens; - - enum ParseState - { - Default, - Escaped, - Text, - TextEscaped - }; - - void dataFinish(); - void dataAppend(const char ch); -}; - -#endif // _COMMANDPARSER_H +#ifndef _COMMANDPARSER_H +#define _COMMANDPARSER_H + +#include "_global.h" + +class Command +{ +public: + Command(const String & command); + const String GetText(); + const String GetArg(const int argnum); + const int GetArgCount(); + +private: + String _data; + std::vector _tokens; + + enum ParseState + { + Default, + Escaped, + Text, + TextEscaped + }; + + void dataFinish(); + void dataAppend(const char ch); +}; + +#endif // _COMMANDPARSER_H diff --git a/src/dbg/comment.cpp b/src/dbg/comment.cpp index 7814200f..37059635 100644 --- a/src/dbg/comment.cpp +++ b/src/dbg/comment.cpp @@ -1,236 +1,236 @@ -#include "comment.h" -#include "threading.h" -#include "module.h" -#include "memory.h" - -std::unordered_map comments; - -bool CommentSet(duint Address, const char* Text, bool Manual) -{ - ASSERT_DEBUGGING("Export call"); - - // A valid memory address must be supplied - if(!MemIsValidReadPtr(Address)) - return false; - - // Make sure the string is supplied, within bounds, and not a special delimiter - if(!Text || Text[0] == '\1' || strlen(Text) >= MAX_COMMENT_SIZE - 1) - return false; - - // Delete the comment if no text was supplied - if(Text[0] == '\0') - return CommentDelete(Address); - - // Fill out the structure - COMMENTSINFO comment; - strcpy_s(comment.text, Text); - ModNameFromAddr(Address, comment.mod, true); - - comment.manual = Manual; - comment.addr = Address - ModBaseFromAddr(Address); - - // Key generated from module hash - const duint key = ModHashFromAddr(Address); - - EXCLUSIVE_ACQUIRE(LockComments); - - // Insert if possible, otherwise replace - if(!comments.insert(std::make_pair(key, comment)).second) - comments[key] = comment; - - return true; -} - -bool CommentGet(duint Address, char* Text) -{ - ASSERT_DEBUGGING("Export call"); - SHARED_ACQUIRE(LockComments); - - // Get an existing comment and copy the string buffer - auto found = comments.find(ModHashFromAddr(Address)); - - // Was it found? - if(found == comments.end()) - return false; - - if(found->second.manual) //autocomment - strcpy_s(Text, MAX_COMMENT_SIZE, found->second.text); - else - sprintf_s(Text, MAX_COMMENT_SIZE, "\1%s", found->second.text); - - return true; -} - -bool CommentDelete(duint Address) -{ - ASSERT_DEBUGGING("Export call"); - EXCLUSIVE_ACQUIRE(LockComments); - - return (comments.erase(ModHashFromAddr(Address)) > 0); -} - -void CommentDelRange(duint Start, duint End) -{ - ASSERT_DEBUGGING("Export call"); - - // Are all comments going to be deleted? - // 0x00000000 - 0xFFFFFFFF - if(Start == 0 && End == ~0) - { - CommentClear(); - } - else - { - // Make sure 'Start' and 'End' reference the same module - duint moduleBase = ModBaseFromAddr(Start); - - if(moduleBase != ModBaseFromAddr(End)) - return; - - // Virtual -> relative offset - Start -= moduleBase; - End -= moduleBase; - - EXCLUSIVE_ACQUIRE(LockComments); - for(auto itr = comments.begin(); itr != comments.end();) - { - const auto & currentComment = itr->second; - // Ignore manually set entries - if(currentComment.manual) - { - ++itr; - continue; - } - - // [Start, End) - if(currentComment.addr >= Start && currentComment.addr < End) - itr = comments.erase(itr); - else - ++itr; - } - } -} - -void CommentCacheSave(JSON Root) -{ - EXCLUSIVE_ACQUIRE(LockComments); - - const JSON jsonComments = json_array(); - const JSON jsonAutoComments = json_array(); - - // Build the JSON array - for(auto & itr : comments) - { - JSON currentComment = json_object(); - - json_object_set_new(currentComment, "module", json_string(itr.second.mod)); - json_object_set_new(currentComment, "address", json_hex(itr.second.addr)); - json_object_set_new(currentComment, "text", json_string(itr.second.text)); - - if(itr.second.manual) - json_array_append_new(jsonComments, currentComment); - else - json_array_append_new(jsonAutoComments, currentComment); - } - - // Save to the JSON root - if(json_array_size(jsonComments)) - json_object_set(Root, "comments", jsonComments); - - if(json_array_size(jsonAutoComments)) - json_object_set(Root, "autocomments", jsonAutoComments); - - json_decref(jsonComments); - json_decref(jsonAutoComments); -} - -void CommentCacheLoad(JSON Root) -{ - EXCLUSIVE_ACQUIRE(LockComments); - - // Inline lambda to parse each JSON entry - auto AddComments = [](const JSON Object, bool Manual) - { - size_t i; - JSON value; - - json_array_foreach(Object, i, value) - { - COMMENTSINFO commentInfo; - memset(&commentInfo, 0, sizeof(COMMENTSINFO)); - - // Module - const char* mod = json_string_value(json_object_get(value, "module")); - - if(mod && strlen(mod) < MAX_MODULE_SIZE) - strcpy_s(commentInfo.mod, mod); - - // Address/Manual - commentInfo.addr = (duint)json_hex_value(json_object_get(value, "address")); - commentInfo.manual = Manual; - - // String value - const char* text = json_string_value(json_object_get(value, "text")); - - if(text) - strcpy_s(commentInfo.text, text); - else - { - // Skip blank comments - continue; - } - - const duint key = ModHashFromName(commentInfo.mod) + commentInfo.addr; - comments.insert(std::make_pair(key, commentInfo)); - } - }; - - // Remove existing entries - comments.clear(); - - const JSON jsonComments = json_object_get(Root, "comments"); - const JSON jsonAutoComments = json_object_get(Root, "autocomments"); - - // Load user-set comments - if(jsonComments) - AddComments(jsonComments, true); - - // Load auto-set comments - if(jsonAutoComments) - AddComments(jsonAutoComments, false); -} - -bool CommentEnum(COMMENTSINFO* List, size_t* Size) -{ - ASSERT_DEBUGGING("Command function call"); - - // At least 1 parameter must be supplied - ASSERT_FALSE(!List && !Size); - SHARED_ACQUIRE(LockComments); - - // Check if the user requested size only - if(Size) - { - *Size = comments.size() * sizeof(COMMENTSINFO); - - if(!List) - return true; - } - - // Populate the returned array - for(auto & itr : comments) - { - *List = itr.second; - List->addr += ModBaseFromName(List->mod); - - List++; - } - - return true; -} - -void CommentClear() -{ - EXCLUSIVE_ACQUIRE(LockComments); - comments.clear(); +#include "comment.h" +#include "threading.h" +#include "module.h" +#include "memory.h" + +std::unordered_map comments; + +bool CommentSet(duint Address, const char* Text, bool Manual) +{ + ASSERT_DEBUGGING("Export call"); + + // A valid memory address must be supplied + if(!MemIsValidReadPtr(Address)) + return false; + + // Make sure the string is supplied, within bounds, and not a special delimiter + if(!Text || Text[0] == '\1' || strlen(Text) >= MAX_COMMENT_SIZE - 1) + return false; + + // Delete the comment if no text was supplied + if(Text[0] == '\0') + return CommentDelete(Address); + + // Fill out the structure + COMMENTSINFO comment; + strcpy_s(comment.text, Text); + ModNameFromAddr(Address, comment.mod, true); + + comment.manual = Manual; + comment.addr = Address - ModBaseFromAddr(Address); + + // Key generated from module hash + const duint key = ModHashFromAddr(Address); + + EXCLUSIVE_ACQUIRE(LockComments); + + // Insert if possible, otherwise replace + if(!comments.insert(std::make_pair(key, comment)).second) + comments[key] = comment; + + return true; +} + +bool CommentGet(duint Address, char* Text) +{ + ASSERT_DEBUGGING("Export call"); + SHARED_ACQUIRE(LockComments); + + // Get an existing comment and copy the string buffer + auto found = comments.find(ModHashFromAddr(Address)); + + // Was it found? + if(found == comments.end()) + return false; + + if(found->second.manual) //autocomment + strcpy_s(Text, MAX_COMMENT_SIZE, found->second.text); + else + sprintf_s(Text, MAX_COMMENT_SIZE, "\1%s", found->second.text); + + return true; +} + +bool CommentDelete(duint Address) +{ + ASSERT_DEBUGGING("Export call"); + EXCLUSIVE_ACQUIRE(LockComments); + + return (comments.erase(ModHashFromAddr(Address)) > 0); +} + +void CommentDelRange(duint Start, duint End) +{ + ASSERT_DEBUGGING("Export call"); + + // Are all comments going to be deleted? + // 0x00000000 - 0xFFFFFFFF + if(Start == 0 && End == ~0) + { + CommentClear(); + } + else + { + // Make sure 'Start' and 'End' reference the same module + duint moduleBase = ModBaseFromAddr(Start); + + if(moduleBase != ModBaseFromAddr(End)) + return; + + // Virtual -> relative offset + Start -= moduleBase; + End -= moduleBase; + + EXCLUSIVE_ACQUIRE(LockComments); + for(auto itr = comments.begin(); itr != comments.end();) + { + const auto & currentComment = itr->second; + // Ignore manually set entries + if(currentComment.manual) + { + ++itr; + continue; + } + + // [Start, End) + if(currentComment.addr >= Start && currentComment.addr < End) + itr = comments.erase(itr); + else + ++itr; + } + } +} + +void CommentCacheSave(JSON Root) +{ + EXCLUSIVE_ACQUIRE(LockComments); + + const JSON jsonComments = json_array(); + const JSON jsonAutoComments = json_array(); + + // Build the JSON array + for(auto & itr : comments) + { + JSON currentComment = json_object(); + + json_object_set_new(currentComment, "module", json_string(itr.second.mod)); + json_object_set_new(currentComment, "address", json_hex(itr.second.addr)); + json_object_set_new(currentComment, "text", json_string(itr.second.text)); + + if(itr.second.manual) + json_array_append_new(jsonComments, currentComment); + else + json_array_append_new(jsonAutoComments, currentComment); + } + + // Save to the JSON root + if(json_array_size(jsonComments)) + json_object_set(Root, "comments", jsonComments); + + if(json_array_size(jsonAutoComments)) + json_object_set(Root, "autocomments", jsonAutoComments); + + json_decref(jsonComments); + json_decref(jsonAutoComments); +} + +void CommentCacheLoad(JSON Root) +{ + EXCLUSIVE_ACQUIRE(LockComments); + + // Inline lambda to parse each JSON entry + auto AddComments = [](const JSON Object, bool Manual) + { + size_t i; + JSON value; + + json_array_foreach(Object, i, value) + { + COMMENTSINFO commentInfo; + memset(&commentInfo, 0, sizeof(COMMENTSINFO)); + + // Module + const char* mod = json_string_value(json_object_get(value, "module")); + + if(mod && strlen(mod) < MAX_MODULE_SIZE) + strcpy_s(commentInfo.mod, mod); + + // Address/Manual + commentInfo.addr = (duint)json_hex_value(json_object_get(value, "address")); + commentInfo.manual = Manual; + + // String value + const char* text = json_string_value(json_object_get(value, "text")); + + if(text) + strcpy_s(commentInfo.text, text); + else + { + // Skip blank comments + continue; + } + + const duint key = ModHashFromName(commentInfo.mod) + commentInfo.addr; + comments.insert(std::make_pair(key, commentInfo)); + } + }; + + // Remove existing entries + comments.clear(); + + const JSON jsonComments = json_object_get(Root, "comments"); + const JSON jsonAutoComments = json_object_get(Root, "autocomments"); + + // Load user-set comments + if(jsonComments) + AddComments(jsonComments, true); + + // Load auto-set comments + if(jsonAutoComments) + AddComments(jsonAutoComments, false); +} + +bool CommentEnum(COMMENTSINFO* List, size_t* Size) +{ + ASSERT_DEBUGGING("Command function call"); + + // At least 1 parameter must be supplied + ASSERT_FALSE(!List && !Size); + SHARED_ACQUIRE(LockComments); + + // Check if the user requested size only + if(Size) + { + *Size = comments.size() * sizeof(COMMENTSINFO); + + if(!List) + return true; + } + + // Populate the returned array + for(auto & itr : comments) + { + *List = itr.second; + List->addr += ModBaseFromName(List->mod); + + List++; + } + + return true; +} + +void CommentClear() +{ + EXCLUSIVE_ACQUIRE(LockComments); + comments.clear(); } \ No newline at end of file diff --git a/src/dbg/comment.h b/src/dbg/comment.h index 2a570342..779e27ca 100644 --- a/src/dbg/comment.h +++ b/src/dbg/comment.h @@ -1,20 +1,20 @@ -#pragma once - -#include "_global.h" - -struct COMMENTSINFO -{ - char mod[MAX_MODULE_SIZE]; - duint addr; - char text[MAX_COMMENT_SIZE]; - bool manual; -}; - -bool CommentSet(duint Address, const char* Text, bool Manual); -bool CommentGet(duint Address, char* Text); -bool CommentDelete(duint Address); -void CommentDelRange(duint Start, duint End); -void CommentCacheSave(JSON Root); -void CommentCacheLoad(JSON Root); -bool CommentEnum(COMMENTSINFO* List, size_t* Size); +#pragma once + +#include "_global.h" + +struct COMMENTSINFO +{ + char mod[MAX_MODULE_SIZE]; + duint addr; + char text[MAX_COMMENT_SIZE]; + bool manual; +}; + +bool CommentSet(duint Address, const char* Text, bool Manual); +bool CommentGet(duint Address, char* Text); +bool CommentDelete(duint Address); +void CommentDelRange(duint Start, duint End); +void CommentCacheSave(JSON Root); +void CommentCacheLoad(JSON Root); +bool CommentEnum(COMMENTSINFO* List, size_t* Size); void CommentClear(); \ No newline at end of file diff --git a/src/dbg/console.cpp b/src/dbg/console.cpp index 960f300b..521ed7f0 100644 --- a/src/dbg/console.cpp +++ b/src/dbg/console.cpp @@ -1,41 +1,41 @@ -/** -\file console.cpp -\brief Implements the console class. -*/ - -#include "console.h" - -/** -\brief Print a line with text, terminated with a newline to the console. -\param text The text to print. -*/ -void dputs(const char* Text) -{ - dprintf("%s\n", Text); -} - -/** -\brief Print a formatted string to the console. -\param format The printf format to use (see documentation of printf for more information). -*/ -void dprintf(const char* Format, ...) -{ - va_list args; - - va_start(args, Format); - dprintf_args(Format, args); - va_end(args); -} - -/** -\brief Print a formatted string to the console. -\param format The printf format to use (see documentation of printf for more information). -\param Args The argument buffer passed to the string parser. -*/ -void dprintf_args(const char* Format, va_list Args) -{ - char buffer[16384]; - vsnprintf_s(buffer, _TRUNCATE, Format, Args); - - GuiAddLogMessage(buffer); -} +/** +\file console.cpp +\brief Implements the console class. +*/ + +#include "console.h" + +/** +\brief Print a line with text, terminated with a newline to the console. +\param text The text to print. +*/ +void dputs(const char* Text) +{ + dprintf("%s\n", Text); +} + +/** +\brief Print a formatted string to the console. +\param format The printf format to use (see documentation of printf for more information). +*/ +void dprintf(const char* Format, ...) +{ + va_list args; + + va_start(args, Format); + dprintf_args(Format, args); + va_end(args); +} + +/** +\brief Print a formatted string to the console. +\param format The printf format to use (see documentation of printf for more information). +\param Args The argument buffer passed to the string parser. +*/ +void dprintf_args(const char* Format, va_list Args) +{ + char buffer[16384]; + vsnprintf_s(buffer, _TRUNCATE, Format, Args); + + GuiAddLogMessage(buffer); +} diff --git a/src/dbg/console.h b/src/dbg/console.h index 8339033f..67183dd8 100644 --- a/src/dbg/console.h +++ b/src/dbg/console.h @@ -1,7 +1,7 @@ -#pragma once - -#include "_global.h" - -void dputs(const char* Text); -void dprintf(const char* Format, ...); +#pragma once + +#include "_global.h" + +void dputs(const char* Text); +void dprintf(const char* Format, ...); void dprintf_args(const char* Format, va_list Args); \ No newline at end of file diff --git a/src/dbg/controlflowanalysis.cpp b/src/dbg/controlflowanalysis.cpp index 49cc664e..4d7e7b84 100644 --- a/src/dbg/controlflowanalysis.cpp +++ b/src/dbg/controlflowanalysis.cpp @@ -1,445 +1,445 @@ -#include "controlflowanalysis.h" -#include "console.h" -#include "module.h" -#include "TitanEngine/TitanEngine.h" -#include "memory.h" -#include "function.h" - -ControlFlowAnalysis::ControlFlowAnalysis(duint base, duint size, bool exceptionDirectory) : Analysis(base, size) -{ - _functionInfoData = nullptr; -#ifdef _WIN64 - // This will only be valid if the address range is within a loaded module - _moduleBase = ModBaseFromAddr(base); - - if(exceptionDirectory && _moduleBase != 0) - { - char modulePath[MAX_PATH]; - memset(modulePath, 0, sizeof(modulePath)); - - ModPathFromAddr(_moduleBase, modulePath, ARRAYSIZE(modulePath)); - - HANDLE fileHandle; - DWORD fileSize; - HANDLE fileMapHandle; - ULONG_PTR fileMapVa; - if(StaticFileLoadW( - StringUtils::Utf8ToUtf16(modulePath).c_str(), - UE_ACCESS_READ, - false, - &fileHandle, - &fileSize, - &fileMapHandle, - &fileMapVa)) - { - // Find a pointer to IMAGE_DIRECTORY_ENTRY_EXCEPTION for later use - ULONG_PTR virtualOffset = GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALOFFSET); - _functionInfoSize = (duint)GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALSIZE); - - // Unload the file - StaticFileUnloadW(nullptr, false, fileHandle, fileSize, fileMapHandle, fileMapVa); - - // Get a copy of the function table - if(virtualOffset) - { - // Read the table into a buffer - _functionInfoData = emalloc(_functionInfoSize); - - if(_functionInfoData) - MemRead(virtualOffset + _moduleBase, _functionInfoData, _functionInfoSize); - } - } - } -#endif //_WIN64 -} - -ControlFlowAnalysis::~ControlFlowAnalysis() -{ - if(_functionInfoData) - efree(_functionInfoData); -} - -void ControlFlowAnalysis::Analyse() -{ - dputs("Starting analysis..."); - DWORD ticks = GetTickCount(); - - BasicBlockStarts(); - dprintf("Basic block starts in %ums!\n", GetTickCount() - ticks); - ticks = GetTickCount(); - - BasicBlocks(); - dprintf("Basic blocks in %ums!\n", GetTickCount() - ticks); - ticks = GetTickCount(); - - Functions(); - dprintf("Functions in %ums!\n", GetTickCount() - ticks); - ticks = GetTickCount(); - - FunctionRanges(); - dprintf("Function ranges in %ums!\n", GetTickCount() - ticks); - ticks = GetTickCount(); - - dprintf("Analysis finished!\n"); -} - -void ControlFlowAnalysis::SetMarkers() -{ - FunctionDelRange(_base, _base + _size); - auto size = _functionRanges.size(); - for(size_t i = size - 1; i != -1; i--) - { - const auto & range = _functionRanges[i]; - FunctionAdd(range.first, range.second, false); - } - /*dprintf("digraph ControlFlow {\n"); - int i = 0; - std::map nodeMap; - for(const auto & it : _blocks) - { - const auto & block = it.second; - nodeMap.insert({ block.start, i }); - dprintf(" node%u [label=\"s=%p, e=%p, f=%p\"];\n", i, block.start, block.end, block.function); - i++; - } - for(auto it : _blocks) - { - const auto & block = it.second; - int startNode = nodeMap[block.start]; - if(block.left) - { - if(nodeMap.count(block.left)) - dprintf(" node%u -> node%u;\n", startNode, nodeMap[block.left]); - } - else - { - dprintf(" node%u [shape=point];\n", i); - dprintf(" node%u -> node%u;\n", startNode, i); - i++; - } - if(block.right) - { - if(nodeMap.count(block.right)) - dprintf(" node%u -> node%u;\n", startNode, nodeMap[block.right]); - } - else - { - dprintf(" node%u [shape=point];\n", i); - dprintf(" node%u -> node%u;\n", startNode, i); - i++; - } - } - dprintf("}\n");*/ -} - -void ControlFlowAnalysis::BasicBlockStarts() -{ - _blockStarts.insert(_base); - bool bSkipFilling = false; - for(duint i = 0; i < _size;) - { - duint addr = _base + i; - if(_cp.Disassemble(addr, TranslateAddress(addr), MAX_DISASM_BUFFER)) - { - if(bSkipFilling) //handle filling skip mode - { - if(!_cp.IsFilling()) //do nothing until the filling stopped - { - bSkipFilling = false; - _blockStarts.insert(addr); - } - } - else if(_cp.InGroup(CS_GRP_RET) || _cp.GetId() == X86_INS_INT3) //RET/INT3 break control flow - { - bSkipFilling = true; //skip INT3/NOP/whatever filling bytes (those are not part of the control flow) - } - else if(_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) //branches - { - duint dest1 = GetReferenceOperand(); - duint dest2 = 0; - if(_cp.GetId() != X86_INS_JMP) //unconditional jump - dest2 = addr + _cp.Size(); - - if(!dest1 && !dest2) //TODO: better code for this (make sure absolutely no filling is inserted) - bSkipFilling = true; - if(dest1) - _blockStarts.insert(dest1); - if(dest2) - _blockStarts.insert(dest2); - } - else if(_cp.InGroup(CS_GRP_CALL)) - { - duint dest1 = GetReferenceOperand(); - if(dest1) - { - _blockStarts.insert(dest1); - _functionStarts.insert(dest1); - } - } - else - { - duint dest1 = GetReferenceOperand(); - if(dest1) - _blockStarts.insert(dest1); - } - i += _cp.Size(); - } - else - i++; - } -} - -void ControlFlowAnalysis::BasicBlocks() -{ - for(auto i = _blockStarts.begin(); i != _blockStarts.end(); ++i) - { - duint start = *i; - if(!IsValidAddress(start)) - continue; - duint nextStart = _base + _size; - auto next = std::next(i); - if(next != _blockStarts.end()) - nextStart = *next; - for(duint addr = start, prevaddr = 0; addr < _base + _size;) - { - prevaddr = addr; - if(_cp.Disassemble(addr, TranslateAddress(addr), MAX_DISASM_BUFFER)) - { - if(_cp.InGroup(CS_GRP_RET) || _cp.GetId() == X86_INS_INT3) - { - insertBlock(BasicBlock(start, addr, 0, 0)); //leaf block - break; - } - else if(_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) - { - duint dest1 = GetReferenceOperand(); - duint dest2 = _cp.GetId() != X86_INS_JMP ? addr + _cp.Size() : 0; - insertBlock(BasicBlock(start, addr, dest1, dest2)); - insertParent(dest1, start); - insertParent(dest2, start); - break; - } - addr += _cp.Size(); - } - else - addr++; - if(addr == nextStart) //special case handling overlapping blocks - { - insertBlock(BasicBlock(start, prevaddr, 0, nextStart)); - insertParent(nextStart, start); - break; - } - } - } - _blockStarts.clear(); - -#ifdef _WIN64 - int count = 0; - EnumerateFunctionRuntimeEntries64([&](PRUNTIME_FUNCTION Function) - { - const duint funcAddr = _moduleBase + Function->BeginAddress; - const duint funcEnd = _moduleBase + Function->EndAddress; - - // If within limits... - if(funcAddr >= _base && funcAddr < _base + _size) - _functionStarts.insert(funcAddr); - count++; - return true; - }); - dprintf("%u functions from the exception directory...\n", count); -#endif // _WIN64 - - dprintf("%u basic blocks, %u function starts detected...\n", _blocks.size(), _functionStarts.size()); -} - -void ControlFlowAnalysis::Functions() -{ - typedef std::pair DelayedBlock; - std::vector delayedBlocks; - for(auto & it : _blocks) - { - BasicBlock* block = &it.second; - UintSet* parents = findParents(block->start); - if(!block->function) - { - if(!parents || _functionStarts.count(block->start)) //no parents = function start - { - duint functionStart = block->start; - block->function = functionStart; - UintSet functionBlocks; - functionBlocks.insert(functionStart); - _functions[functionStart] = functionBlocks; - } - else //in function - { - duint function = findFunctionStart(block, parents); - if(!function) //this happens with loops / unreferenced blocks sometimes - delayedBlocks.push_back(DelayedBlock(block, parents)); - else - block->function = function; - } - } - else - DebugBreak(); //this should not happen - } - int delayedCount = (int)delayedBlocks.size(); - dprintf("%u/%u delayed blocks...\n", delayedCount, _blocks.size()); - int resolved = 0; - for(auto & delayedBlock : delayedBlocks) - { - BasicBlock* block = delayedBlock.first; - UintSet* parents = delayedBlock.second; - duint function = findFunctionStart(block, parents); - if(!function) - { - continue; - /*dprintf("unresolved block %s\n", blockToString(block).c_str()); - if(parents) - { - dprintf("parents:\n"); - for(auto parent : *parents) - dprintf(" %s\n", blockToString(findBlock(parent)).c_str()); - } - else - dprintf("parents: null"); - dprintf("left: %s\n", blockToString(findBlock(block->left)).c_str()); - dprintf("right: %s\n", blockToString(findBlock(block->right)).c_str()); - return;*/ - } - block->function = function; - resolved++; - } - dprintf("%u/%u delayed blocks resolved (%u/%u still left, probably unreferenced functions)\n", resolved, delayedCount, delayedCount - resolved, _blocks.size()); - int unreferencedCount = 0; - for(const auto & block : _blocks) - { - auto found = _functions.find(block.second.function); - if(found == _functions.end()) //unreferenced block - { - unreferencedCount++; - continue; - } - found->second.insert(block.second.start); - } - dprintf("%u/%u unreferenced blocks\n", unreferencedCount, _blocks.size()); - dprintf("%u functions found!\n", _functions.size()); -} - -void ControlFlowAnalysis::FunctionRanges() -{ - //iterate over the functions and then find the deepest block = function end - for(const auto & function : _functions) - { - duint start = function.first; - duint end = start; - for(auto blockstart : function.second) - { - BasicBlock* block = this->findBlock(blockstart); - if(!block) - DebugBreak(); //this shouldn't happen - if(block->end > end) - end = block->end; - } - _functionRanges.push_back({ start, end }); - } -} - -void ControlFlowAnalysis::insertBlock(BasicBlock block) -{ - if(_blocks.find(block.start) != _blocks.end()) - DebugBreak(); - _blocks[block.start] = block; -} - -ControlFlowAnalysis::BasicBlock* ControlFlowAnalysis::findBlock(duint start) -{ - if(!start) - return nullptr; - auto found = _blocks.find(start); - return found != _blocks.end() ? &found->second : nullptr; -} - -void ControlFlowAnalysis::insertParent(duint child, duint parent) -{ - if(!child || !parent) - return; - auto found = _parentMap.find(child); - if(found == _parentMap.end()) - { - UintSet parents; - parents.insert(parent); - _parentMap[child] = parents; - } - else - found->second.insert(parent); -} - -ControlFlowAnalysis::UintSet* ControlFlowAnalysis::findParents(duint child) -{ - if(!child) - return nullptr; - auto found = _parentMap.find(child); - return found != _parentMap.end() ? &found->second : nullptr; -} - -duint ControlFlowAnalysis::findFunctionStart(BasicBlock* block, ControlFlowAnalysis::UintSet* parents) -{ - if(!block) - return 0; - if(block->function) - return block->function; - BasicBlock* left = findBlock(block->left); - if(left && left->function) - return left->function; - BasicBlock* right = findBlock(block->right); - if(right && right->function) - return right->function; - for(auto start : *parents) - { - BasicBlock* parent = findBlock(start); - if(parent->function) - return parent->function; - } - return 0; -} - -String ControlFlowAnalysis::blockToString(BasicBlock* block) -{ - if(!block) - return String("null"); - return block->toString(); -} - -duint ControlFlowAnalysis::GetReferenceOperand() -{ - for(int i = 0; i < _cp.x86().op_count; i++) - { - const cs_x86_op & operand = _cp.x86().operands[i]; - if(operand.type == X86_OP_IMM) - { - duint dest = (duint)operand.imm; - if(dest >= _base && dest < _base + _size) - return dest; - } - } - return 0; -} - -#ifdef _WIN64 -void ControlFlowAnalysis::EnumerateFunctionRuntimeEntries64(std::function Callback) -{ - if(!_functionInfoData) - return; - - // Get the table pointer and size - auto functionTable = (PRUNTIME_FUNCTION)_functionInfoData; - duint totalCount = (_functionInfoSize / sizeof(RUNTIME_FUNCTION)); - - // Enumerate each entry - for(ULONG i = 0; i < totalCount; i++) - { - if(!Callback(&functionTable[i])) - break; - } -} +#include "controlflowanalysis.h" +#include "console.h" +#include "module.h" +#include "TitanEngine/TitanEngine.h" +#include "memory.h" +#include "function.h" + +ControlFlowAnalysis::ControlFlowAnalysis(duint base, duint size, bool exceptionDirectory) : Analysis(base, size) +{ + _functionInfoData = nullptr; +#ifdef _WIN64 + // This will only be valid if the address range is within a loaded module + _moduleBase = ModBaseFromAddr(base); + + if(exceptionDirectory && _moduleBase != 0) + { + char modulePath[MAX_PATH]; + memset(modulePath, 0, sizeof(modulePath)); + + ModPathFromAddr(_moduleBase, modulePath, ARRAYSIZE(modulePath)); + + HANDLE fileHandle; + DWORD fileSize; + HANDLE fileMapHandle; + ULONG_PTR fileMapVa; + if(StaticFileLoadW( + StringUtils::Utf8ToUtf16(modulePath).c_str(), + UE_ACCESS_READ, + false, + &fileHandle, + &fileSize, + &fileMapHandle, + &fileMapVa)) + { + // Find a pointer to IMAGE_DIRECTORY_ENTRY_EXCEPTION for later use + ULONG_PTR virtualOffset = GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALOFFSET); + _functionInfoSize = (duint)GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALSIZE); + + // Unload the file + StaticFileUnloadW(nullptr, false, fileHandle, fileSize, fileMapHandle, fileMapVa); + + // Get a copy of the function table + if(virtualOffset) + { + // Read the table into a buffer + _functionInfoData = emalloc(_functionInfoSize); + + if(_functionInfoData) + MemRead(virtualOffset + _moduleBase, _functionInfoData, _functionInfoSize); + } + } + } +#endif //_WIN64 +} + +ControlFlowAnalysis::~ControlFlowAnalysis() +{ + if(_functionInfoData) + efree(_functionInfoData); +} + +void ControlFlowAnalysis::Analyse() +{ + dputs("Starting analysis..."); + DWORD ticks = GetTickCount(); + + BasicBlockStarts(); + dprintf("Basic block starts in %ums!\n", GetTickCount() - ticks); + ticks = GetTickCount(); + + BasicBlocks(); + dprintf("Basic blocks in %ums!\n", GetTickCount() - ticks); + ticks = GetTickCount(); + + Functions(); + dprintf("Functions in %ums!\n", GetTickCount() - ticks); + ticks = GetTickCount(); + + FunctionRanges(); + dprintf("Function ranges in %ums!\n", GetTickCount() - ticks); + ticks = GetTickCount(); + + dprintf("Analysis finished!\n"); +} + +void ControlFlowAnalysis::SetMarkers() +{ + FunctionDelRange(_base, _base + _size); + auto size = _functionRanges.size(); + for(size_t i = size - 1; i != -1; i--) + { + const auto & range = _functionRanges[i]; + FunctionAdd(range.first, range.second, false); + } + /*dprintf("digraph ControlFlow {\n"); + int i = 0; + std::map nodeMap; + for(const auto & it : _blocks) + { + const auto & block = it.second; + nodeMap.insert({ block.start, i }); + dprintf(" node%u [label=\"s=%p, e=%p, f=%p\"];\n", i, block.start, block.end, block.function); + i++; + } + for(auto it : _blocks) + { + const auto & block = it.second; + int startNode = nodeMap[block.start]; + if(block.left) + { + if(nodeMap.count(block.left)) + dprintf(" node%u -> node%u;\n", startNode, nodeMap[block.left]); + } + else + { + dprintf(" node%u [shape=point];\n", i); + dprintf(" node%u -> node%u;\n", startNode, i); + i++; + } + if(block.right) + { + if(nodeMap.count(block.right)) + dprintf(" node%u -> node%u;\n", startNode, nodeMap[block.right]); + } + else + { + dprintf(" node%u [shape=point];\n", i); + dprintf(" node%u -> node%u;\n", startNode, i); + i++; + } + } + dprintf("}\n");*/ +} + +void ControlFlowAnalysis::BasicBlockStarts() +{ + _blockStarts.insert(_base); + bool bSkipFilling = false; + for(duint i = 0; i < _size;) + { + duint addr = _base + i; + if(_cp.Disassemble(addr, TranslateAddress(addr), MAX_DISASM_BUFFER)) + { + if(bSkipFilling) //handle filling skip mode + { + if(!_cp.IsFilling()) //do nothing until the filling stopped + { + bSkipFilling = false; + _blockStarts.insert(addr); + } + } + else if(_cp.InGroup(CS_GRP_RET) || _cp.GetId() == X86_INS_INT3) //RET/INT3 break control flow + { + bSkipFilling = true; //skip INT3/NOP/whatever filling bytes (those are not part of the control flow) + } + else if(_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) //branches + { + duint dest1 = GetReferenceOperand(); + duint dest2 = 0; + if(_cp.GetId() != X86_INS_JMP) //unconditional jump + dest2 = addr + _cp.Size(); + + if(!dest1 && !dest2) //TODO: better code for this (make sure absolutely no filling is inserted) + bSkipFilling = true; + if(dest1) + _blockStarts.insert(dest1); + if(dest2) + _blockStarts.insert(dest2); + } + else if(_cp.InGroup(CS_GRP_CALL)) + { + duint dest1 = GetReferenceOperand(); + if(dest1) + { + _blockStarts.insert(dest1); + _functionStarts.insert(dest1); + } + } + else + { + duint dest1 = GetReferenceOperand(); + if(dest1) + _blockStarts.insert(dest1); + } + i += _cp.Size(); + } + else + i++; + } +} + +void ControlFlowAnalysis::BasicBlocks() +{ + for(auto i = _blockStarts.begin(); i != _blockStarts.end(); ++i) + { + duint start = *i; + if(!IsValidAddress(start)) + continue; + duint nextStart = _base + _size; + auto next = std::next(i); + if(next != _blockStarts.end()) + nextStart = *next; + for(duint addr = start, prevaddr = 0; addr < _base + _size;) + { + prevaddr = addr; + if(_cp.Disassemble(addr, TranslateAddress(addr), MAX_DISASM_BUFFER)) + { + if(_cp.InGroup(CS_GRP_RET) || _cp.GetId() == X86_INS_INT3) + { + insertBlock(BasicBlock(start, addr, 0, 0)); //leaf block + break; + } + else if(_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) + { + duint dest1 = GetReferenceOperand(); + duint dest2 = _cp.GetId() != X86_INS_JMP ? addr + _cp.Size() : 0; + insertBlock(BasicBlock(start, addr, dest1, dest2)); + insertParent(dest1, start); + insertParent(dest2, start); + break; + } + addr += _cp.Size(); + } + else + addr++; + if(addr == nextStart) //special case handling overlapping blocks + { + insertBlock(BasicBlock(start, prevaddr, 0, nextStart)); + insertParent(nextStart, start); + break; + } + } + } + _blockStarts.clear(); + +#ifdef _WIN64 + int count = 0; + EnumerateFunctionRuntimeEntries64([&](PRUNTIME_FUNCTION Function) + { + const duint funcAddr = _moduleBase + Function->BeginAddress; + const duint funcEnd = _moduleBase + Function->EndAddress; + + // If within limits... + if(funcAddr >= _base && funcAddr < _base + _size) + _functionStarts.insert(funcAddr); + count++; + return true; + }); + dprintf("%u functions from the exception directory...\n", count); +#endif // _WIN64 + + dprintf("%u basic blocks, %u function starts detected...\n", _blocks.size(), _functionStarts.size()); +} + +void ControlFlowAnalysis::Functions() +{ + typedef std::pair DelayedBlock; + std::vector delayedBlocks; + for(auto & it : _blocks) + { + BasicBlock* block = &it.second; + UintSet* parents = findParents(block->start); + if(!block->function) + { + if(!parents || _functionStarts.count(block->start)) //no parents = function start + { + duint functionStart = block->start; + block->function = functionStart; + UintSet functionBlocks; + functionBlocks.insert(functionStart); + _functions[functionStart] = functionBlocks; + } + else //in function + { + duint function = findFunctionStart(block, parents); + if(!function) //this happens with loops / unreferenced blocks sometimes + delayedBlocks.push_back(DelayedBlock(block, parents)); + else + block->function = function; + } + } + else + DebugBreak(); //this should not happen + } + int delayedCount = (int)delayedBlocks.size(); + dprintf("%u/%u delayed blocks...\n", delayedCount, _blocks.size()); + int resolved = 0; + for(auto & delayedBlock : delayedBlocks) + { + BasicBlock* block = delayedBlock.first; + UintSet* parents = delayedBlock.second; + duint function = findFunctionStart(block, parents); + if(!function) + { + continue; + /*dprintf("unresolved block %s\n", blockToString(block).c_str()); + if(parents) + { + dprintf("parents:\n"); + for(auto parent : *parents) + dprintf(" %s\n", blockToString(findBlock(parent)).c_str()); + } + else + dprintf("parents: null"); + dprintf("left: %s\n", blockToString(findBlock(block->left)).c_str()); + dprintf("right: %s\n", blockToString(findBlock(block->right)).c_str()); + return;*/ + } + block->function = function; + resolved++; + } + dprintf("%u/%u delayed blocks resolved (%u/%u still left, probably unreferenced functions)\n", resolved, delayedCount, delayedCount - resolved, _blocks.size()); + int unreferencedCount = 0; + for(const auto & block : _blocks) + { + auto found = _functions.find(block.second.function); + if(found == _functions.end()) //unreferenced block + { + unreferencedCount++; + continue; + } + found->second.insert(block.second.start); + } + dprintf("%u/%u unreferenced blocks\n", unreferencedCount, _blocks.size()); + dprintf("%u functions found!\n", _functions.size()); +} + +void ControlFlowAnalysis::FunctionRanges() +{ + //iterate over the functions and then find the deepest block = function end + for(const auto & function : _functions) + { + duint start = function.first; + duint end = start; + for(auto blockstart : function.second) + { + BasicBlock* block = this->findBlock(blockstart); + if(!block) + DebugBreak(); //this shouldn't happen + if(block->end > end) + end = block->end; + } + _functionRanges.push_back({ start, end }); + } +} + +void ControlFlowAnalysis::insertBlock(BasicBlock block) +{ + if(_blocks.find(block.start) != _blocks.end()) + DebugBreak(); + _blocks[block.start] = block; +} + +ControlFlowAnalysis::BasicBlock* ControlFlowAnalysis::findBlock(duint start) +{ + if(!start) + return nullptr; + auto found = _blocks.find(start); + return found != _blocks.end() ? &found->second : nullptr; +} + +void ControlFlowAnalysis::insertParent(duint child, duint parent) +{ + if(!child || !parent) + return; + auto found = _parentMap.find(child); + if(found == _parentMap.end()) + { + UintSet parents; + parents.insert(parent); + _parentMap[child] = parents; + } + else + found->second.insert(parent); +} + +ControlFlowAnalysis::UintSet* ControlFlowAnalysis::findParents(duint child) +{ + if(!child) + return nullptr; + auto found = _parentMap.find(child); + return found != _parentMap.end() ? &found->second : nullptr; +} + +duint ControlFlowAnalysis::findFunctionStart(BasicBlock* block, ControlFlowAnalysis::UintSet* parents) +{ + if(!block) + return 0; + if(block->function) + return block->function; + BasicBlock* left = findBlock(block->left); + if(left && left->function) + return left->function; + BasicBlock* right = findBlock(block->right); + if(right && right->function) + return right->function; + for(auto start : *parents) + { + BasicBlock* parent = findBlock(start); + if(parent->function) + return parent->function; + } + return 0; +} + +String ControlFlowAnalysis::blockToString(BasicBlock* block) +{ + if(!block) + return String("null"); + return block->toString(); +} + +duint ControlFlowAnalysis::GetReferenceOperand() +{ + for(int i = 0; i < _cp.x86().op_count; i++) + { + const cs_x86_op & operand = _cp.x86().operands[i]; + if(operand.type == X86_OP_IMM) + { + duint dest = (duint)operand.imm; + if(dest >= _base && dest < _base + _size) + return dest; + } + } + return 0; +} + +#ifdef _WIN64 +void ControlFlowAnalysis::EnumerateFunctionRuntimeEntries64(std::function Callback) +{ + if(!_functionInfoData) + return; + + // Get the table pointer and size + auto functionTable = (PRUNTIME_FUNCTION)_functionInfoData; + duint totalCount = (_functionInfoSize / sizeof(RUNTIME_FUNCTION)); + + // Enumerate each entry + for(ULONG i = 0; i < totalCount; i++) + { + if(!Callback(&functionTable[i])) + break; + } +} #endif // _WIN64 \ No newline at end of file diff --git a/src/dbg/controlflowanalysis.h b/src/dbg/controlflowanalysis.h index 783f2dfb..6a7b6529 100644 --- a/src/dbg/controlflowanalysis.h +++ b/src/dbg/controlflowanalysis.h @@ -1,79 +1,79 @@ -#ifndef _CONTROLFLOWANALYSIS_H -#define _CONTROLFLOWANALYSIS_H - -#include "_global.h" -#include "analysis.h" -#include "addrinfo.h" -#include - -class ControlFlowAnalysis : public Analysis -{ -public: - explicit ControlFlowAnalysis(duint base, duint size, bool exceptionDirectory); - ~ControlFlowAnalysis(); - void Analyse() override; - void SetMarkers() override; - -private: - struct BasicBlock - { - duint start; - duint end; - duint left; - duint right; - duint function; - - BasicBlock() - { - this->start = 0; - this->end = 0; - this->left = 0; - this->right = 0; - this->function = 0; - } - - BasicBlock(duint start, duint end, duint left, duint right) - { - this->start = start; - this->end = end; - this->left = min(left, right); - this->right = max(left, right); - this->function = 0; - } - - String toString() - { - return StringUtils::sprintf("start:%p,end:%p,left:%p,right:%p,func:%p", start, end, left, right, function); - } - }; - - typedef std::set UintSet; - - duint _moduleBase; - duint _functionInfoSize; - void* _functionInfoData; - - UintSet _blockStarts; - UintSet _functionStarts; - std::map _blocks; //start of block -> block - std::map _parentMap; //start child -> parents - std::map _functions; //function start -> function block starts - std::vector _functionRanges; //function start -> function range TODO: smarter stuff with overlapping ranges - - void BasicBlockStarts(); - void BasicBlocks(); - void Functions(); - void FunctionRanges(); - void insertBlock(BasicBlock block); - BasicBlock* findBlock(duint start); - void insertParent(duint child, duint parent); - UintSet* findParents(duint child); - duint findFunctionStart(BasicBlock* block, UintSet* parents); - String blockToString(BasicBlock* block); - duint GetReferenceOperand(); -#ifdef _WIN64 - void EnumerateFunctionRuntimeEntries64(std::function Callback); -#endif // _WIN64 -}; - +#ifndef _CONTROLFLOWANALYSIS_H +#define _CONTROLFLOWANALYSIS_H + +#include "_global.h" +#include "analysis.h" +#include "addrinfo.h" +#include + +class ControlFlowAnalysis : public Analysis +{ +public: + explicit ControlFlowAnalysis(duint base, duint size, bool exceptionDirectory); + ~ControlFlowAnalysis(); + void Analyse() override; + void SetMarkers() override; + +private: + struct BasicBlock + { + duint start; + duint end; + duint left; + duint right; + duint function; + + BasicBlock() + { + this->start = 0; + this->end = 0; + this->left = 0; + this->right = 0; + this->function = 0; + } + + BasicBlock(duint start, duint end, duint left, duint right) + { + this->start = start; + this->end = end; + this->left = min(left, right); + this->right = max(left, right); + this->function = 0; + } + + String toString() + { + return StringUtils::sprintf("start:%p,end:%p,left:%p,right:%p,func:%p", start, end, left, right, function); + } + }; + + typedef std::set UintSet; + + duint _moduleBase; + duint _functionInfoSize; + void* _functionInfoData; + + UintSet _blockStarts; + UintSet _functionStarts; + std::map _blocks; //start of block -> block + std::map _parentMap; //start child -> parents + std::map _functions; //function start -> function block starts + std::vector _functionRanges; //function start -> function range TODO: smarter stuff with overlapping ranges + + void BasicBlockStarts(); + void BasicBlocks(); + void Functions(); + void FunctionRanges(); + void insertBlock(BasicBlock block); + BasicBlock* findBlock(duint start); + void insertParent(duint child, duint parent); + UintSet* findParents(duint child); + duint findFunctionStart(BasicBlock* block, UintSet* parents); + String blockToString(BasicBlock* block); + duint GetReferenceOperand(); +#ifdef _WIN64 + void EnumerateFunctionRuntimeEntries64(std::function Callback); +#endif // _WIN64 +}; + #endif //_CONTROLFLOWANALYSIS_H \ No newline at end of file diff --git a/src/dbg/database.cpp b/src/dbg/database.cpp index 767cd882..294fbdf9 100644 --- a/src/dbg/database.cpp +++ b/src/dbg/database.cpp @@ -1,235 +1,235 @@ -/** -@file database.cpp - -@brief Implements runtime database saving and loading. -*/ - -#include "lz4\lz4file.h" -#include "console.h" -#include "breakpoint.h" -#include "patches.h" -#include "comment.h" -#include "label.h" -#include "bookmark.h" -#include "function.h" -#include "loop.h" - -/** -\brief Directory where program databases are stored (usually in \db). UTF-8 encoding. -*/ -char dbbasepath[deflen]; - -/** -\brief Path of the current program database. UTF-8 encoding. -*/ -char dbpath[deflen]; - -void DBSave() -{ - dprintf("Saving database..."); - DWORD ticks = GetTickCount(); - JSON root = json_object(); - CommentCacheSave(root); - LabelCacheSave(root); - BookmarkCacheSave(root); - FunctionCacheSave(root); - LoopCacheSave(root); - BpCacheSave(root); - //save notes - char* text = nullptr; - GuiGetDebuggeeNotes(&text); - if (text) - { - json_object_set_new(root, "notes", json_string(text)); - BridgeFree(text); - } - GuiSetDebuggeeNotes(""); - - WString wdbpath = StringUtils::Utf8ToUtf16(dbpath); - if (json_object_size(root)) - { - Handle hFile = CreateFileW(wdbpath.c_str(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); - if (!hFile) - { - dputs("\nFailed to open database for writing!"); - json_decref(root); //free root - return; - } - SetEndOfFile(hFile); - char* jsonText = json_dumps(root, JSON_INDENT(4)); - DWORD written = 0; - if (!WriteFile(hFile, jsonText, (DWORD)strlen(jsonText), &written, 0)) - { - json_free(jsonText); - dputs("\nFailed to write database file!"); - json_decref(root); //free root - return; - } - hFile.Close(); - json_free(jsonText); - if (!settingboolget("Engine", "DisableDatabaseCompression")) - LZ4_compress_fileW(wdbpath.c_str(), wdbpath.c_str()); - } - else //remove database when nothing is in there - DeleteFileW(wdbpath.c_str()); - dprintf("%ums\n", GetTickCount() - ticks); - json_decref(root); //free root -} - -void DBLoad() -{ - // If the file doesn't exist, there is no DB to load - if (!FileExists(dbpath)) - return; - - dprintf("Loading database..."); - DWORD ticks = GetTickCount(); - - // Multi-byte (UTF8) file path converted to UTF16 - WString databasePathW = StringUtils::Utf8ToUtf16(dbpath); - - // Decompress the file if compression was enabled - bool useCompression = !settingboolget("Engine", "DisableDatabaseCompression"); - LZ4_STATUS lzmaStatus = LZ4_INVALID_ARCHIVE; - { - lzmaStatus = LZ4_decompress_fileW(databasePathW.c_str(), databasePathW.c_str()); - - // Check return code - if (useCompression && lzmaStatus != LZ4_SUCCESS && lzmaStatus != LZ4_INVALID_ARCHIVE) - { - dputs("\nInvalid database file!"); - return; - } - } - - // Read the database file - Handle hFile = CreateFileW(databasePathW.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); - if (!hFile) - { - dputs("\nFailed to open database file!"); - return; - } - - unsigned int jsonFileSize = GetFileSize(hFile, 0); - if (!jsonFileSize) - { - dputs("\nEmpty database file!"); - return; - } - - Memory jsonText(jsonFileSize + 1); - DWORD read = 0; - if (!ReadFile(hFile, jsonText(), jsonFileSize, &read, 0)) - { - dputs("\nFailed to read database file!"); - return; - } - hFile.Close(); - - // Deserialize JSON - JSON root = json_loads(jsonText(), 0, 0); - - if (lzmaStatus != LZ4_INVALID_ARCHIVE && useCompression) - LZ4_compress_fileW(databasePathW.c_str(), databasePathW.c_str()); - - // Validate JSON load status - if (!root) - { - dputs("\nInvalid database file (JSON)!"); - return; - } - - // Finally load all structures - CommentCacheLoad(root); - LabelCacheLoad(root); - BookmarkCacheLoad(root); - FunctionCacheLoad(root); - LoopCacheLoad(root); - BpCacheLoad(root); - - // Load notes - const char* text = json_string_value(json_object_get(root, "notes")); - GuiSetDebuggeeNotes(text); - - // Free root - json_decref(root); - dprintf("%ums\n", GetTickCount() - ticks); -} - -void DBClose() -{ - DBSave(); - CommentClear(); - LabelClear(); - BookmarkClear(); - FunctionClear(); - LoopClear(); - BpClear(); - PatchClear(); -} - -void DBSetPath(const char *Directory, const char *ModulePath) -{ - // Initialize directory if it was only supplied - if (Directory) - { - ASSERT_TRUE(strlen(Directory) > 0); - - // Copy to global - strcpy_s(dbbasepath, Directory); - - // Create directory - if (!CreateDirectoryW(StringUtils::Utf8ToUtf16(Directory).c_str(), nullptr)) - { - if (GetLastError() != ERROR_ALREADY_EXISTS) - dprintf("Warning: Failed to create database folder '%s'. Path may be read only.\n", Directory); - } - } - - // The database file path may be relative (dbbasepath) or a full path - if (ModulePath) - { - ASSERT_TRUE(strlen(ModulePath) > 0); - -#ifdef _WIN64 - const char *dbType = "dd64"; -#else - const char *dbType = "dd32"; -#endif // _WIN64 - - // Get the module name and directory - char dbName[deflen]; - char fileDir[deflen]; - { - // Dir <- file path - strcpy_s(fileDir, ModulePath); - - // Find the last instance of a path delimiter (slash) - char* fileStart = strrchr(fileDir, '\\'); - - if (fileStart) - { - strcpy_s(dbName, fileStart + 1); - fileStart[0] = '\0'; - } - else - { - // Directory or file with no extension - strcpy_s(dbName, fileDir); - } - } - - if (settingboolget("Engine", "SaveDatabaseInProgramDirectory")) - { - // Absolute path in the program directory - sprintf_s(dbpath, "%s\\%s.%s", fileDir, dbName, dbType); - } - else - { - // Relative path in debugger directory - sprintf_s(dbpath, "%s\\%s.%s", dbbasepath, dbName, dbType); - } - - dprintf("Database file: %s\n", dbpath); - } +/** +@file database.cpp + +@brief Implements runtime database saving and loading. +*/ + +#include "lz4\lz4file.h" +#include "console.h" +#include "breakpoint.h" +#include "patches.h" +#include "comment.h" +#include "label.h" +#include "bookmark.h" +#include "function.h" +#include "loop.h" + +/** +\brief Directory where program databases are stored (usually in \db). UTF-8 encoding. +*/ +char dbbasepath[deflen]; + +/** +\brief Path of the current program database. UTF-8 encoding. +*/ +char dbpath[deflen]; + +void DBSave() +{ + dprintf("Saving database..."); + DWORD ticks = GetTickCount(); + JSON root = json_object(); + CommentCacheSave(root); + LabelCacheSave(root); + BookmarkCacheSave(root); + FunctionCacheSave(root); + LoopCacheSave(root); + BpCacheSave(root); + //save notes + char* text = nullptr; + GuiGetDebuggeeNotes(&text); + if (text) + { + json_object_set_new(root, "notes", json_string(text)); + BridgeFree(text); + } + GuiSetDebuggeeNotes(""); + + WString wdbpath = StringUtils::Utf8ToUtf16(dbpath); + if (json_object_size(root)) + { + Handle hFile = CreateFileW(wdbpath.c_str(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); + if (!hFile) + { + dputs("\nFailed to open database for writing!"); + json_decref(root); //free root + return; + } + SetEndOfFile(hFile); + char* jsonText = json_dumps(root, JSON_INDENT(4)); + DWORD written = 0; + if (!WriteFile(hFile, jsonText, (DWORD)strlen(jsonText), &written, 0)) + { + json_free(jsonText); + dputs("\nFailed to write database file!"); + json_decref(root); //free root + return; + } + hFile.Close(); + json_free(jsonText); + if (!settingboolget("Engine", "DisableDatabaseCompression")) + LZ4_compress_fileW(wdbpath.c_str(), wdbpath.c_str()); + } + else //remove database when nothing is in there + DeleteFileW(wdbpath.c_str()); + dprintf("%ums\n", GetTickCount() - ticks); + json_decref(root); //free root +} + +void DBLoad() +{ + // If the file doesn't exist, there is no DB to load + if (!FileExists(dbpath)) + return; + + dprintf("Loading database..."); + DWORD ticks = GetTickCount(); + + // Multi-byte (UTF8) file path converted to UTF16 + WString databasePathW = StringUtils::Utf8ToUtf16(dbpath); + + // Decompress the file if compression was enabled + bool useCompression = !settingboolget("Engine", "DisableDatabaseCompression"); + LZ4_STATUS lzmaStatus = LZ4_INVALID_ARCHIVE; + { + lzmaStatus = LZ4_decompress_fileW(databasePathW.c_str(), databasePathW.c_str()); + + // Check return code + if (useCompression && lzmaStatus != LZ4_SUCCESS && lzmaStatus != LZ4_INVALID_ARCHIVE) + { + dputs("\nInvalid database file!"); + return; + } + } + + // Read the database file + Handle hFile = CreateFileW(databasePathW.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + if (!hFile) + { + dputs("\nFailed to open database file!"); + return; + } + + unsigned int jsonFileSize = GetFileSize(hFile, 0); + if (!jsonFileSize) + { + dputs("\nEmpty database file!"); + return; + } + + Memory jsonText(jsonFileSize + 1); + DWORD read = 0; + if (!ReadFile(hFile, jsonText(), jsonFileSize, &read, 0)) + { + dputs("\nFailed to read database file!"); + return; + } + hFile.Close(); + + // Deserialize JSON + JSON root = json_loads(jsonText(), 0, 0); + + if (lzmaStatus != LZ4_INVALID_ARCHIVE && useCompression) + LZ4_compress_fileW(databasePathW.c_str(), databasePathW.c_str()); + + // Validate JSON load status + if (!root) + { + dputs("\nInvalid database file (JSON)!"); + return; + } + + // Finally load all structures + CommentCacheLoad(root); + LabelCacheLoad(root); + BookmarkCacheLoad(root); + FunctionCacheLoad(root); + LoopCacheLoad(root); + BpCacheLoad(root); + + // Load notes + const char* text = json_string_value(json_object_get(root, "notes")); + GuiSetDebuggeeNotes(text); + + // Free root + json_decref(root); + dprintf("%ums\n", GetTickCount() - ticks); +} + +void DBClose() +{ + DBSave(); + CommentClear(); + LabelClear(); + BookmarkClear(); + FunctionClear(); + LoopClear(); + BpClear(); + PatchClear(); +} + +void DBSetPath(const char *Directory, const char *ModulePath) +{ + // Initialize directory if it was only supplied + if (Directory) + { + ASSERT_TRUE(strlen(Directory) > 0); + + // Copy to global + strcpy_s(dbbasepath, Directory); + + // Create directory + if (!CreateDirectoryW(StringUtils::Utf8ToUtf16(Directory).c_str(), nullptr)) + { + if (GetLastError() != ERROR_ALREADY_EXISTS) + dprintf("Warning: Failed to create database folder '%s'. Path may be read only.\n", Directory); + } + } + + // The database file path may be relative (dbbasepath) or a full path + if (ModulePath) + { + ASSERT_TRUE(strlen(ModulePath) > 0); + +#ifdef _WIN64 + const char *dbType = "dd64"; +#else + const char *dbType = "dd32"; +#endif // _WIN64 + + // Get the module name and directory + char dbName[deflen]; + char fileDir[deflen]; + { + // Dir <- file path + strcpy_s(fileDir, ModulePath); + + // Find the last instance of a path delimiter (slash) + char* fileStart = strrchr(fileDir, '\\'); + + if (fileStart) + { + strcpy_s(dbName, fileStart + 1); + fileStart[0] = '\0'; + } + else + { + // Directory or file with no extension + strcpy_s(dbName, fileDir); + } + } + + if (settingboolget("Engine", "SaveDatabaseInProgramDirectory")) + { + // Absolute path in the program directory + sprintf_s(dbpath, "%s\\%s.%s", fileDir, dbName, dbType); + } + else + { + // Relative path in debugger directory + sprintf_s(dbpath, "%s\\%s.%s", dbbasepath, dbName, dbType); + } + + dprintf("Database file: %s\n", dbpath); + } } \ No newline at end of file diff --git a/src/dbg/database.h b/src/dbg/database.h index 38ed2be6..5baa99f5 100644 --- a/src/dbg/database.h +++ b/src/dbg/database.h @@ -1,8 +1,8 @@ -#pragma once - -#include "_global.h" - -void DBSave(); -void DBLoad(); -void DBClose(); +#pragma once + +#include "_global.h" + +void DBSave(); +void DBLoad(); +void DBClose(); void DBSetPath(const char *Directory, const char *ModulePath); \ No newline at end of file diff --git a/src/dbg/dbghelp/dbghelp.h b/src/dbg/dbghelp/dbghelp.h index 53c634a5..19eda7b4 100644 --- a/src/dbg/dbghelp/dbghelp.h +++ b/src/dbg/dbghelp/dbghelp.h @@ -1,4677 +1,4677 @@ -#ifndef _DBGHELP_ -#define _DBGHELP_ - - -// As a general principal always call the 64 bit version -// of every API, if a choice exists. The 64 bit version -// works great on 32 bit platforms, and is forward -// compatible to 64 bit platforms. - -#ifdef _WIN64 -#ifndef _IMAGEHLP64 -#define _IMAGEHLP64 -#endif -#endif - -#pragma pack(push,8) - -// For those without specstrings.h -// Since there are different versions of this header, I need to -// individually test each item and define it if it is not around. - -#ifndef __in -#define __in -#endif -#ifndef __out -#define __out -#endif -#ifndef __inout -#define __inout -#endif -#ifndef __in_opt -#define __in_opt -#endif -#ifndef __out_opt -#define __out_opt -#endif -#ifndef __inout_opt -#define __inout_opt -#endif -#ifndef __in_ecount -#define __in_ecount(x) -#endif -#ifndef __out_ecount -#define __out_ecount(x) -#endif -#ifndef __inout_ecount -#define __inout_ecount(x) -#endif -#ifndef __in_bcount -#define __in_bcount(x) -#endif -#ifndef __out_bcount -#define __out_bcount(x) -#endif -#ifndef __inout_bcount -#define __inout_bcount(x) -#endif -#ifndef __out_xcount -#define __out_xcount(x) -#endif -#ifndef __deref_opt_out -#define __deref_opt_out -#endif -#ifndef __deref_out -#define __deref_out -#endif -#ifndef __out_ecount_opt -#define __out_ecount_opt(x) -#endif -#ifndef __in_bcount_opt -#define __in_bcount_opt(x) -#endif -#ifndef __out_bcount_opt -#define __out_bcount_opt(x) -#endif -#ifndef __deref_out_opt -#define __deref_out_opt -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _IMAGEHLP_SOURCE_ -#define IMAGEAPI __stdcall -#define DBHLP_DEPRECIATED -#else -#define IMAGEAPI DECLSPEC_IMPORT __stdcall -#if (_MSC_VER >= 1300) && !defined(MIDL_PASS) -#define DBHLP_DEPRECIATED __declspec(deprecated) -#else -#define DBHLP_DEPRECIATED -#endif -#endif - -#define DBHLPAPI IMAGEAPI - -#define IMAGE_SEPARATION (64*1024) - -// Observant readers may notice that 2 new fields, -// 'fReadOnly' and 'Version' have been added to -// the LOADED_IMAGE structure after 'fDOSImage'. -// This does not change the size of the structure -// from previous headers. That is because while -// 'fDOSImage' is a byte, it is padded by the -// compiler to 4 bytes. So the 2 new fields are -// slipped into the extra space. - -typedef struct _LOADED_IMAGE -{ - PSTR ModuleName; - HANDLE hFile; - PUCHAR MappedAddress; -#ifdef _IMAGEHLP64 - PIMAGE_NT_HEADERS64 FileHeader; -#else - PIMAGE_NT_HEADERS32 FileHeader; -#endif - PIMAGE_SECTION_HEADER LastRvaSection; - ULONG NumberOfSections; - PIMAGE_SECTION_HEADER Sections; - ULONG Characteristics; - BOOLEAN fSystemImage; - BOOLEAN fDOSImage; - BOOLEAN fReadOnly; - UCHAR Version; - LIST_ENTRY Links; - ULONG SizeOfImage; -} LOADED_IMAGE, *PLOADED_IMAGE; - -#define MAX_SYM_NAME 2000 - - -// Error codes set by dbghelp functions. Call GetLastError -// to see them. -// Dbghelp also sets error codes found in winerror.h - -#define ERROR_IMAGE_NOT_STRIPPED 0x8800 // the image is not stripped. No dbg file available. -#define ERROR_NO_DBG_POINTER 0x8801 // image is stripped but there is no pointer to a dbg file -#define ERROR_NO_PDB_POINTER 0x8802 // image does not point to a pdb file - -typedef BOOL -(CALLBACK* PFIND_DEBUG_FILE_CALLBACK)( - __in HANDLE FileHandle, - __in PCSTR FileName, - __in PVOID CallerData -); - -HANDLE -IMAGEAPI -SymFindDebugInfoFile( - __in HANDLE hProcess, - __in PCSTR FileName, - __out_ecount(MAX_PATH + 1) PSTR DebugFilePath, - __in_opt PFIND_DEBUG_FILE_CALLBACK Callback, - __in_opt PVOID CallerData -); - -typedef BOOL -(CALLBACK* PFIND_DEBUG_FILE_CALLBACKW)( - __in HANDLE FileHandle, - __in PCWSTR FileName, - __in PVOID CallerData -); - -HANDLE -IMAGEAPI -SymFindDebugInfoFileW( - __in HANDLE hProcess, - __in PCWSTR FileName, - __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath, - __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback, - __in_opt PVOID CallerData -); - -HANDLE -IMAGEAPI -FindDebugInfoFile( - __in PCSTR FileName, - __in PCSTR SymbolPath, - __out_ecount(MAX_PATH + 1) PSTR DebugFilePath -); - -HANDLE -IMAGEAPI -FindDebugInfoFileEx( - __in PCSTR FileName, - __in PCSTR SymbolPath, - __out_ecount(MAX_PATH + 1) PSTR DebugFilePath, - __in_opt PFIND_DEBUG_FILE_CALLBACK Callback, - __in_opt PVOID CallerData -); - -HANDLE -IMAGEAPI -FindDebugInfoFileExW( - __in PCWSTR FileName, - __in PCWSTR SymbolPath, - __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath, - __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback, - __in_opt PVOID CallerData -); - -typedef BOOL -(CALLBACK* PFINDFILEINPATHCALLBACK)( - __in PCSTR filename, - __in PVOID context -); - -BOOL -IMAGEAPI -SymFindFileInPath( - __in HANDLE hprocess, - __in_opt PCSTR SearchPath, - __in PCSTR FileName, - __in_opt PVOID id, - __in DWORD two, - __in DWORD three, - __in DWORD flags, - __out_ecount(MAX_PATH + 1) PSTR FoundFile, - __in_opt PFINDFILEINPATHCALLBACK callback, - __in_opt PVOID context -); - -typedef BOOL -(CALLBACK* PFINDFILEINPATHCALLBACKW)( - __in PCWSTR filename, - __in PVOID context -); - -BOOL -IMAGEAPI -SymFindFileInPathW( - __in HANDLE hprocess, - __in_opt PCWSTR SearchPath, - __in PCWSTR FileName, - __in_opt PVOID id, - __in DWORD two, - __in DWORD three, - __in DWORD flags, - __out_ecount(MAX_PATH + 1) PWSTR FoundFile, - __in_opt PFINDFILEINPATHCALLBACKW callback, - __in_opt PVOID context -); - -typedef BOOL -(CALLBACK* PFIND_EXE_FILE_CALLBACK)( - __in HANDLE FileHandle, - __in PCSTR FileName, - __in_opt PVOID CallerData -); - -HANDLE -IMAGEAPI -SymFindExecutableImage( - __in HANDLE hProcess, - __in PCSTR FileName, - __out_ecount(MAX_PATH + 1) PSTR ImageFilePath, - __in PFIND_EXE_FILE_CALLBACK Callback, - __in PVOID CallerData -); - -typedef BOOL -(CALLBACK* PFIND_EXE_FILE_CALLBACKW)( - __in HANDLE FileHandle, - __in PCWSTR FileName, - __in_opt PVOID CallerData -); - -HANDLE -IMAGEAPI -SymFindExecutableImageW( - __in HANDLE hProcess, - __in PCWSTR FileName, - __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath, - __in PFIND_EXE_FILE_CALLBACKW Callback, - __in PVOID CallerData -); - -HANDLE -IMAGEAPI -FindExecutableImage( - __in PCSTR FileName, - __in PCSTR SymbolPath, - __out_ecount(MAX_PATH + 1) PSTR ImageFilePath -); - -HANDLE -IMAGEAPI -FindExecutableImageEx( - __in PCSTR FileName, - __in PCSTR SymbolPath, - __out_ecount(MAX_PATH + 1) PSTR ImageFilePath, - __in_opt PFIND_EXE_FILE_CALLBACK Callback, - __in_opt PVOID CallerData -); - -HANDLE -IMAGEAPI -FindExecutableImageExW( - __in PCWSTR FileName, - __in PCWSTR SymbolPath, - __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath, - __in_opt PFIND_EXE_FILE_CALLBACKW Callback, - __in PVOID CallerData -); - -PIMAGE_NT_HEADERS -IMAGEAPI -ImageNtHeader( - __in PVOID Base -); - -PVOID -IMAGEAPI -ImageDirectoryEntryToDataEx( - __in PVOID Base, - __in BOOLEAN MappedAsImage, - __in USHORT DirectoryEntry, - __out PULONG Size, - __out_opt PIMAGE_SECTION_HEADER* FoundHeader -); - -PVOID -IMAGEAPI -ImageDirectoryEntryToData( - __in PVOID Base, - __in BOOLEAN MappedAsImage, - __in USHORT DirectoryEntry, - __out PULONG Size -); - -PIMAGE_SECTION_HEADER -IMAGEAPI -ImageRvaToSection( - __in PIMAGE_NT_HEADERS NtHeaders, - __in PVOID Base, - __in ULONG Rva -); - -PVOID -IMAGEAPI -ImageRvaToVa( - __in PIMAGE_NT_HEADERS NtHeaders, - __in PVOID Base, - __in ULONG Rva, - __in_opt OUT PIMAGE_SECTION_HEADER* LastRvaSection -); - -#ifndef _WIN64 -// This api won't be ported to Win64 - Fix your code. - -typedef struct _IMAGE_DEBUG_INFORMATION -{ - LIST_ENTRY List; - DWORD ReservedSize; - PVOID ReservedMappedBase; - USHORT ReservedMachine; - USHORT ReservedCharacteristics; - DWORD ReservedCheckSum; - DWORD ImageBase; - DWORD SizeOfImage; - - DWORD ReservedNumberOfSections; - PIMAGE_SECTION_HEADER ReservedSections; - - DWORD ReservedExportedNamesSize; - PSTR ReservedExportedNames; - - DWORD ReservedNumberOfFunctionTableEntries; - PIMAGE_FUNCTION_ENTRY ReservedFunctionTableEntries; - DWORD ReservedLowestFunctionStartingAddress; - DWORD ReservedHighestFunctionEndingAddress; - - DWORD ReservedNumberOfFpoTableEntries; - PFPO_DATA ReservedFpoTableEntries; - - DWORD SizeOfCoffSymbols; - PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols; - - DWORD ReservedSizeOfCodeViewSymbols; - PVOID ReservedCodeViewSymbols; - - PSTR ImageFilePath; - PSTR ImageFileName; - PSTR ReservedDebugFilePath; - - DWORD ReservedTimeDateStamp; - - BOOL ReservedRomImage; - PIMAGE_DEBUG_DIRECTORY ReservedDebugDirectory; - DWORD ReservedNumberOfDebugDirectories; - - DWORD ReservedOriginalFunctionTableBaseAddress; - - DWORD Reserved[ 2 ]; - -} IMAGE_DEBUG_INFORMATION, *PIMAGE_DEBUG_INFORMATION; - - -PIMAGE_DEBUG_INFORMATION -IMAGEAPI -MapDebugInformation( - __in_opt HANDLE FileHandle, - __in PCSTR FileName, - __in_opt PCSTR SymbolPath, - __in ULONG ImageBase -); - -BOOL -IMAGEAPI -UnmapDebugInformation( - __out_xcount(unknown) PIMAGE_DEBUG_INFORMATION DebugInfo -); - -#endif - -BOOL -IMAGEAPI -SearchTreeForFile( - __in PCSTR RootPath, - __in PCSTR InputPathName, - __out_ecount(MAX_PATH + 1) PSTR OutputPathBuffer -); - -BOOL -IMAGEAPI -SearchTreeForFileW( - __in PCWSTR RootPath, - __in PCWSTR InputPathName, - __out_ecount(MAX_PATH + 1) PWSTR OutputPathBuffer -); - -typedef BOOL -(CALLBACK* PENUMDIRTREE_CALLBACK)( - __in PCSTR FilePath, - __in_opt PVOID CallerData -); - -BOOL -IMAGEAPI -EnumDirTree( - __in_opt HANDLE hProcess, - __in PCSTR RootPath, - __in PCSTR InputPathName, - __out_ecount_opt(MAX_PATH + 1) PSTR OutputPathBuffer, - __in_opt PENUMDIRTREE_CALLBACK cb, - __in_opt PVOID data -); - -typedef BOOL -(CALLBACK* PENUMDIRTREE_CALLBACKW)( - __in PCWSTR FilePath, - __in_opt PVOID CallerData -); - -BOOL -IMAGEAPI -EnumDirTreeW( - __in_opt HANDLE hProcess, - __in PCWSTR RootPath, - __in PCWSTR InputPathName, - __out_ecount_opt(MAX_PATH + 1) PWSTR OutputPathBuffer, - __in_opt PENUMDIRTREE_CALLBACKW cb, - __in_opt PVOID data -); - -BOOL -IMAGEAPI -MakeSureDirectoryPathExists( - __in PCSTR DirPath -); - -// -// UnDecorateSymbolName Flags -// - -#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration -#define UNDNAME_NO_LEADING_UNDERSCORES (0x0001) // Remove leading underscores from MS extended keywords -#define UNDNAME_NO_MS_KEYWORDS (0x0002) // Disable expansion of MS extended keywords -#define UNDNAME_NO_FUNCTION_RETURNS (0x0004) // Disable expansion of return type for primary declaration -#define UNDNAME_NO_ALLOCATION_MODEL (0x0008) // Disable expansion of the declaration model -#define UNDNAME_NO_ALLOCATION_LANGUAGE (0x0010) // Disable expansion of the declaration language specifier -#define UNDNAME_NO_MS_THISTYPE (0x0020) // NYI Disable expansion of MS keywords on the 'this' type for primary declaration -#define UNDNAME_NO_CV_THISTYPE (0x0040) // NYI Disable expansion of CV modifiers on the 'this' type for primary declaration -#define UNDNAME_NO_THISTYPE (0x0060) // Disable all modifiers on the 'this' type -#define UNDNAME_NO_ACCESS_SPECIFIERS (0x0080) // Disable expansion of access specifiers for members -#define UNDNAME_NO_THROW_SIGNATURES (0x0100) // Disable expansion of 'throw-signatures' for functions and pointers to functions -#define UNDNAME_NO_MEMBER_TYPE (0x0200) // Disable expansion of 'static' or 'virtual'ness of members -#define UNDNAME_NO_RETURN_UDT_MODEL (0x0400) // Disable expansion of MS model for UDT returns -#define UNDNAME_32_BIT_DECODE (0x0800) // Undecorate 32-bit decorated names -#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration; -// return just [scope::]name. Does expand template params -#define UNDNAME_NO_ARGUMENTS (0x2000) // Don't undecorate arguments to function -#define UNDNAME_NO_SPECIAL_SYMS (0x4000) // Don't undecorate special names (v-table, vcall, vector xxx, metatype, etc) - -DWORD -IMAGEAPI -WINAPI -UnDecorateSymbolName( - __in PCSTR name, - __out_ecount(maxStringLength) PSTR outputString, - __in DWORD maxStringLength, - __in DWORD flags -); - -DWORD -IMAGEAPI -WINAPI -UnDecorateSymbolNameW( - __in PCWSTR name, - __out_ecount(maxStringLength) PWSTR outputString, - __in DWORD maxStringLength, - __in DWORD flags -); - -// -// these values are used for synthesized file types -// that can be passed in as image headers instead of -// the standard ones from ntimage.h -// - -#define DBHHEADER_DEBUGDIRS 0x1 -#define DBHHEADER_CVMISC 0x2 -#define DBHHEADER_PDBGUID 0x3 -typedef struct _MODLOAD_DATA -{ - DWORD ssize; // size of this struct - DWORD ssig; // signature identifying the passed data - PVOID data; // pointer to passed data - DWORD size; // size of passed data - DWORD flags; // options -} MODLOAD_DATA, *PMODLOAD_DATA; - -typedef struct _MODLOAD_CVMISC -{ - DWORD oCV; // ofset to the codeview record - size_t cCV; // size of the codeview record - DWORD oMisc; // offset to the misc record - size_t cMisc; // size of the misc record - DWORD dtImage; // datetime stamp of the image - DWORD cImage; // size of the image -} MODLOAD_CVMISC, *PMODLOAD_CVMISC; - -typedef struct _MODLOAD_PDBGUID_PDBAGE -{ - GUID PdbGuid; // Pdb Guid - DWORD PdbAge; // Pdb Age -} MODLOAD_PDBGUID_PDBAGE, *PMODLOAD_PDBGUID_PDBAGE; - -// -// StackWalking API -// - -typedef enum -{ - AddrMode1616, - AddrMode1632, - AddrModeReal, - AddrModeFlat -} ADDRESS_MODE; - -typedef struct _tagADDRESS64 -{ - DWORD64 Offset; - WORD Segment; - ADDRESS_MODE Mode; -} ADDRESS64, *LPADDRESS64; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define ADDRESS ADDRESS64 -#define LPADDRESS LPADDRESS64 -#else -typedef struct _tagADDRESS -{ - DWORD Offset; - WORD Segment; - ADDRESS_MODE Mode; -} ADDRESS, *LPADDRESS; - -__inline -void -Address32To64( - __in LPADDRESS a32, - __out LPADDRESS64 a64 -) -{ - a64->Offset = (ULONG64)(LONG64)(LONG)a32->Offset; - a64->Segment = a32->Segment; - a64->Mode = a32->Mode; -} - -__inline -void -Address64To32( - __in LPADDRESS64 a64, - __out LPADDRESS a32 -) -{ - a32->Offset = (ULONG)a64->Offset; - a32->Segment = a64->Segment; - a32->Mode = a64->Mode; -} -#endif - -// -// This structure is included in the STACKFRAME structure, -// and is used to trace through usermode callbacks in a thread's -// kernel stack. The values must be copied by the kernel debugger -// from the DBGKD_GET_VERSION and WAIT_STATE_CHANGE packets. -// - -// -// New KDHELP structure for 64 bit system support. -// This structure is preferred in new code. -// -typedef struct _KDHELP64 -{ - - // - // address of kernel thread object, as provided in the - // WAIT_STATE_CHANGE packet. - // - DWORD64 Thread; - - // - // offset in thread object to pointer to the current callback frame - // in kernel stack. - // - DWORD ThCallbackStack; - - // - // offset in thread object to pointer to the current callback backing - // store frame in kernel stack. - // - DWORD ThCallbackBStore; - - // - // offsets to values in frame: - // - // address of next callback frame - DWORD NextCallback; - - // address of saved frame pointer (if applicable) - DWORD FramePointer; - - - // - // Address of the kernel function that calls out to user mode - // - DWORD64 KiCallUserMode; - - // - // Address of the user mode dispatcher function - // - DWORD64 KeUserCallbackDispatcher; - - // - // Lowest kernel mode address - // - DWORD64 SystemRangeStart; - - // - // Address of the user mode exception dispatcher function. - // Added in API version 10. - // - DWORD64 KiUserExceptionDispatcher; - - // - // Stack bounds, added in API version 11. - // - DWORD64 StackBase; - DWORD64 StackLimit; - - DWORD64 Reserved[5]; - -} KDHELP64, *PKDHELP64; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define KDHELP KDHELP64 -#define PKDHELP PKDHELP64 -#else -typedef struct _KDHELP -{ - - // - // address of kernel thread object, as provided in the - // WAIT_STATE_CHANGE packet. - // - DWORD Thread; - - // - // offset in thread object to pointer to the current callback frame - // in kernel stack. - // - DWORD ThCallbackStack; - - // - // offsets to values in frame: - // - // address of next callback frame - DWORD NextCallback; - - // address of saved frame pointer (if applicable) - DWORD FramePointer; - - // - // Address of the kernel function that calls out to user mode - // - DWORD KiCallUserMode; - - // - // Address of the user mode dispatcher function - // - DWORD KeUserCallbackDispatcher; - - // - // Lowest kernel mode address - // - DWORD SystemRangeStart; - - // - // offset in thread object to pointer to the current callback backing - // store frame in kernel stack. - // - DWORD ThCallbackBStore; - - // - // Address of the user mode exception dispatcher function. - // Added in API version 10. - // - DWORD KiUserExceptionDispatcher; - - // - // Stack bounds, added in API version 11. - // - DWORD StackBase; - DWORD StackLimit; - - DWORD Reserved[5]; - -} KDHELP, *PKDHELP; - -__inline -void -KdHelp32To64( - __in PKDHELP p32, - __out PKDHELP64 p64 -) -{ - p64->Thread = p32->Thread; - p64->ThCallbackStack = p32->ThCallbackStack; - p64->NextCallback = p32->NextCallback; - p64->FramePointer = p32->FramePointer; - p64->KiCallUserMode = p32->KiCallUserMode; - p64->KeUserCallbackDispatcher = p32->KeUserCallbackDispatcher; - p64->SystemRangeStart = p32->SystemRangeStart; - p64->KiUserExceptionDispatcher = p32->KiUserExceptionDispatcher; - p64->StackBase = p32->StackBase; - p64->StackLimit = p32->StackLimit; -} -#endif - -typedef struct _tagSTACKFRAME64 -{ - ADDRESS64 AddrPC; // program counter - ADDRESS64 AddrReturn; // return address - ADDRESS64 AddrFrame; // frame pointer - ADDRESS64 AddrStack; // stack pointer - ADDRESS64 AddrBStore; // backing store pointer - PVOID FuncTableEntry; // pointer to pdata/fpo or NULL - DWORD64 Params[4]; // possible arguments to the function - BOOL Far; // WOW far call - BOOL Virtual; // is this a virtual frame? - DWORD64 Reserved[3]; - KDHELP64 KdHelp; -} STACKFRAME64, *LPSTACKFRAME64; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define STACKFRAME STACKFRAME64 -#define LPSTACKFRAME LPSTACKFRAME64 -#else -typedef struct _tagSTACKFRAME -{ - ADDRESS AddrPC; // program counter - ADDRESS AddrReturn; // return address - ADDRESS AddrFrame; // frame pointer - ADDRESS AddrStack; // stack pointer - PVOID FuncTableEntry; // pointer to pdata/fpo or NULL - DWORD Params[4]; // possible arguments to the function - BOOL Far; // WOW far call - BOOL Virtual; // is this a virtual frame? - DWORD Reserved[3]; - KDHELP KdHelp; - ADDRESS AddrBStore; // backing store pointer -} STACKFRAME, *LPSTACKFRAME; -#endif - - -typedef -BOOL -(__stdcall* PREAD_PROCESS_MEMORY_ROUTINE64)( - __in HANDLE hProcess, - __in DWORD64 qwBaseAddress, - __out_bcount(nSize) PVOID lpBuffer, - __in DWORD nSize, - __out LPDWORD lpNumberOfBytesRead -); - -typedef -PVOID -(__stdcall* PFUNCTION_TABLE_ACCESS_ROUTINE64)( - __in HANDLE ahProcess, - __in DWORD64 AddrBase -); - -typedef -DWORD64 -(__stdcall* PGET_MODULE_BASE_ROUTINE64)( - __in HANDLE hProcess, - __in DWORD64 Address -); - -typedef -DWORD64 -(__stdcall* PTRANSLATE_ADDRESS_ROUTINE64)( - __in HANDLE hProcess, - __in HANDLE hThread, - __in LPADDRESS64 lpaddr -); - -BOOL -IMAGEAPI -StackWalk64( - __in DWORD MachineType, - __in HANDLE hProcess, - __in HANDLE hThread, - __inout LPSTACKFRAME64 StackFrame, - __inout PVOID ContextRecord, - __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, - __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, - __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, - __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) - -#define PREAD_PROCESS_MEMORY_ROUTINE PREAD_PROCESS_MEMORY_ROUTINE64 -#define PFUNCTION_TABLE_ACCESS_ROUTINE PFUNCTION_TABLE_ACCESS_ROUTINE64 -#define PGET_MODULE_BASE_ROUTINE PGET_MODULE_BASE_ROUTINE64 -#define PTRANSLATE_ADDRESS_ROUTINE PTRANSLATE_ADDRESS_ROUTINE64 - -#define StackWalk StackWalk64 - -#else - -typedef -BOOL -(__stdcall* PREAD_PROCESS_MEMORY_ROUTINE)( - __in HANDLE hProcess, - __in DWORD lpBaseAddress, - __out_bcount(nSize) PVOID lpBuffer, - __in DWORD nSize, - __out PDWORD lpNumberOfBytesRead -); - -typedef -PVOID -(__stdcall* PFUNCTION_TABLE_ACCESS_ROUTINE)( - __in HANDLE hProcess, - __in DWORD AddrBase -); - -typedef -DWORD -(__stdcall* PGET_MODULE_BASE_ROUTINE)( - __in HANDLE hProcess, - __in DWORD Address -); - -typedef -DWORD -(__stdcall* PTRANSLATE_ADDRESS_ROUTINE)( - __in HANDLE hProcess, - __in HANDLE hThread, - __out LPADDRESS lpaddr -); - -BOOL -IMAGEAPI -StackWalk( - DWORD MachineType, - __in HANDLE hProcess, - __in HANDLE hThread, - __inout LPSTACKFRAME StackFrame, - __inout PVOID ContextRecord, - __in_opt PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, - __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, - __in_opt PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, - __in_opt PTRANSLATE_ADDRESS_ROUTINE TranslateAddress -); - -#endif - - -#define API_VERSION_NUMBER 11 - -typedef struct API_VERSION -{ - USHORT MajorVersion; - USHORT MinorVersion; - USHORT Revision; - USHORT Reserved; -} API_VERSION, *LPAPI_VERSION; - -LPAPI_VERSION -IMAGEAPI -ImagehlpApiVersion( - VOID -); - -LPAPI_VERSION -IMAGEAPI -ImagehlpApiVersionEx( - __in LPAPI_VERSION AppVersion -); - -DWORD -IMAGEAPI -GetTimestampForLoadedLibrary( - __in HMODULE Module -); - -// -// typedefs for function pointers -// -typedef BOOL -(CALLBACK* PSYM_ENUMMODULES_CALLBACK64)( - __in PCSTR ModuleName, - __in DWORD64 BaseOfDll, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PSYM_ENUMMODULES_CALLBACKW64)( - __in PCWSTR ModuleName, - __in DWORD64 BaseOfDll, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PENUMLOADED_MODULES_CALLBACK64)( - __in PCSTR ModuleName, - __in DWORD64 ModuleBase, - __in ULONG ModuleSize, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PENUMLOADED_MODULES_CALLBACKW64)( - __in PCWSTR ModuleName, - __in DWORD64 ModuleBase, - __in ULONG ModuleSize, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PSYM_ENUMSYMBOLS_CALLBACK64)( - __in PCSTR SymbolName, - __in DWORD64 SymbolAddress, - __in ULONG SymbolSize, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PSYM_ENUMSYMBOLS_CALLBACK64W)( - __in PCWSTR SymbolName, - __in DWORD64 SymbolAddress, - __in ULONG SymbolSize, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PSYMBOL_REGISTERED_CALLBACK64)( - __in HANDLE hProcess, - __in ULONG ActionCode, - __in_opt ULONG64 CallbackData, - __in_opt ULONG64 UserContext -); - -typedef -PVOID -(CALLBACK* PSYMBOL_FUNCENTRY_CALLBACK)( - __in HANDLE hProcess, - __in DWORD AddrBase, - __in_opt PVOID UserContext -); - -typedef -PVOID -(CALLBACK* PSYMBOL_FUNCENTRY_CALLBACK64)( - __in HANDLE hProcess, - __in ULONG64 AddrBase, - __in ULONG64 UserContext -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) - -#define PSYM_ENUMMODULES_CALLBACK PSYM_ENUMMODULES_CALLBACK64 -#define PSYM_ENUMSYMBOLS_CALLBACK PSYM_ENUMSYMBOLS_CALLBACK64 -#define PSYM_ENUMSYMBOLS_CALLBACKW PSYM_ENUMSYMBOLS_CALLBACK64W -#define PENUMLOADED_MODULES_CALLBACK PENUMLOADED_MODULES_CALLBACK64 -#define PSYMBOL_REGISTERED_CALLBACK PSYMBOL_REGISTERED_CALLBACK64 -#define PSYMBOL_FUNCENTRY_CALLBACK PSYMBOL_FUNCENTRY_CALLBACK64 - -#else - -typedef BOOL -(CALLBACK* PSYM_ENUMMODULES_CALLBACK)( - __in PCSTR ModuleName, - __in ULONG BaseOfDll, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PSYM_ENUMSYMBOLS_CALLBACK)( - __in PCSTR SymbolName, - __in ULONG SymbolAddress, - __in ULONG SymbolSize, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PSYM_ENUMSYMBOLS_CALLBACKW)( - __in PCWSTR SymbolName, - __in ULONG SymbolAddress, - __in ULONG SymbolSize, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PENUMLOADED_MODULES_CALLBACK)( - __in PCSTR ModuleName, - __in ULONG ModuleBase, - __in ULONG ModuleSize, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PSYMBOL_REGISTERED_CALLBACK)( - __in HANDLE hProcess, - __in ULONG ActionCode, - __in_opt PVOID CallbackData, - __in_opt PVOID UserContext -); - -#endif - - -// values found in SYMBOL_INFO.Tag -// -// This was taken from cvconst.h and should -// not override any values found there. -// -// #define _NO_CVCONST_H_ if you don't -// have access to that file... - -#ifdef _NO_CVCONST_H - -// DIA enums - -enum SymTagEnum -{ - SymTagNull, - SymTagExe, - SymTagCompiland, - SymTagCompilandDetails, - SymTagCompilandEnv, - SymTagFunction, - SymTagBlock, - SymTagData, - SymTagAnnotation, - SymTagLabel, - SymTagPublicSymbol, - SymTagUDT, - SymTagEnum, - SymTagFunctionType, - SymTagPointerType, - SymTagArrayType, - SymTagBaseType, - SymTagTypedef, - SymTagBaseClass, - SymTagFriend, - SymTagFunctionArgType, - SymTagFuncDebugStart, - SymTagFuncDebugEnd, - SymTagUsingNamespace, - SymTagVTableShape, - SymTagVTable, - SymTagCustom, - SymTagThunk, - SymTagCustomType, - SymTagManagedType, - SymTagDimension, - SymTagMax -}; - -#endif - -// -// flags found in SYMBOL_INFO.Flags -// - -#define SYMFLAG_VALUEPRESENT 0x00000001 -#define SYMFLAG_REGISTER 0x00000008 -#define SYMFLAG_REGREL 0x00000010 -#define SYMFLAG_FRAMEREL 0x00000020 -#define SYMFLAG_PARAMETER 0x00000040 -#define SYMFLAG_LOCAL 0x00000080 -#define SYMFLAG_CONSTANT 0x00000100 -#define SYMFLAG_EXPORT 0x00000200 -#define SYMFLAG_FORWARDER 0x00000400 -#define SYMFLAG_FUNCTION 0x00000800 -#define SYMFLAG_VIRTUAL 0x00001000 -#define SYMFLAG_THUNK 0x00002000 -#define SYMFLAG_TLSREL 0x00004000 -#define SYMFLAG_SLOT 0x00008000 -#define SYMFLAG_ILREL 0x00010000 -#define SYMFLAG_METADATA 0x00020000 -#define SYMFLAG_CLR_TOKEN 0x00040000 - -// this resets SymNext/Prev to the beginning -// of the module passed in the address field - -#define SYMFLAG_RESET 0x80000000 - -// -// symbol type enumeration -// -typedef enum -{ - SymNone = 0, - SymCoff, - SymCv, - SymPdb, - SymExport, - SymDeferred, - SymSym, // .sym file - SymDia, - SymVirtual, - NumSymTypes -} SYM_TYPE; - -// -// symbol data structure -// - -typedef struct _IMAGEHLP_SYMBOL64 -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64) - DWORD64 Address; // virtual address including dll base address - DWORD Size; // estimated size of symbol, can be zero - DWORD Flags; // info about the symbols, see the SYMF defines - DWORD MaxNameLength; // maximum size of symbol name in 'Name' - CHAR Name[1]; // symbol name (null terminated string) -} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; - -typedef struct _IMAGEHLP_SYMBOL64_PACKAGE -{ - IMAGEHLP_SYMBOL64 sym; - CHAR name[MAX_SYM_NAME + 1]; -} IMAGEHLP_SYMBOL64_PACKAGE, *PIMAGEHLP_SYMBOL64_PACKAGE; - -typedef struct _IMAGEHLP_SYMBOLW64 -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOLW64) - DWORD64 Address; // virtual address including dll base address - DWORD Size; // estimated size of symbol, can be zero - DWORD Flags; // info about the symbols, see the SYMF defines - DWORD MaxNameLength; // maximum size of symbol name in 'Name' - WCHAR Name[1]; // symbol name (null terminated string) -} IMAGEHLP_SYMBOLW64, *PIMAGEHLP_SYMBOLW64; - -typedef struct _IMAGEHLP_SYMBOLW64_PACKAGE -{ - IMAGEHLP_SYMBOLW64 sym; - WCHAR name[MAX_SYM_NAME + 1]; -} IMAGEHLP_SYMBOLW64_PACKAGE, *PIMAGEHLP_SYMBOLW64_PACKAGE; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) - -#define IMAGEHLP_SYMBOL IMAGEHLP_SYMBOL64 -#define PIMAGEHLP_SYMBOL PIMAGEHLP_SYMBOL64 -#define IMAGEHLP_SYMBOL_PACKAGE IMAGEHLP_SYMBOL64_PACKAGE -#define PIMAGEHLP_SYMBOL_PACKAGE PIMAGEHLP_SYMBOL64_PACKAGE -#define IMAGEHLP_SYMBOLW IMAGEHLP_SYMBOLW64 -#define PIMAGEHLP_SYMBOLW PIMAGEHLP_SYMBOLW64 -#define IMAGEHLP_SYMBOLW_PACKAGE IMAGEHLP_SYMBOLW64_PACKAGE -#define PIMAGEHLP_SYMBOLW_PACKAGE PIMAGEHLP_SYMBOLW64_PACKAGE - -#else - -typedef struct _IMAGEHLP_SYMBOL -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL) - DWORD Address; // virtual address including dll base address - DWORD Size; // estimated size of symbol, can be zero - DWORD Flags; // info about the symbols, see the SYMF defines - DWORD MaxNameLength; // maximum size of symbol name in 'Name' - CHAR Name[1]; // symbol name (null terminated string) -} IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL; - -typedef struct _IMAGEHLP_SYMBOL_PACKAGE -{ - IMAGEHLP_SYMBOL sym; - CHAR name[MAX_SYM_NAME + 1]; -} IMAGEHLP_SYMBOL_PACKAGE, *PIMAGEHLP_SYMBOL_PACKAGE; - -typedef struct _IMAGEHLP_SYMBOLW -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOLW) - DWORD Address; // virtual address including dll base address - DWORD Size; // estimated size of symbol, can be zero - DWORD Flags; // info about the symbols, see the SYMF defines - DWORD MaxNameLength; // maximum size of symbol name in 'Name' - WCHAR Name[1]; // symbol name (null terminated string) -} IMAGEHLP_SYMBOLW, *PIMAGEHLP_SYMBOLW; - -typedef struct _IMAGEHLP_SYMBOLW_PACKAGE -{ - IMAGEHLP_SYMBOLW sym; - WCHAR name[MAX_SYM_NAME + 1]; -} IMAGEHLP_SYMBOLW_PACKAGE, *PIMAGEHLP_SYMBOLW_PACKAGE; - -#endif - -// -// module data structure -// - -typedef struct _IMAGEHLP_MODULE64 -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) - DWORD64 BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - CHAR ModuleName[32]; // module name - CHAR ImageName[256]; // image name - CHAR LoadedImageName[256]; // symbol file name - // new elements: 07-Jun-2002 - CHAR LoadedPdbName[256]; // pdb file name - DWORD CVSig; // Signature of the CV record in the debug directories - CHAR CVData[MAX_PATH * 3]; // Contents of the CV record - DWORD PdbSig; // Signature of PDB - GUID PdbSig70; // Signature of PDB (VC 7 and up) - DWORD PdbAge; // DBI age of pdb - BOOL PdbUnmatched; // loaded an unmatched pdb - BOOL DbgUnmatched; // loaded an unmatched dbg - BOOL LineNumbers; // we have line number information - BOOL GlobalSymbols; // we have internal symbol information - BOOL TypeInfo; // we have type information - // new elements: 17-Dec-2003 - BOOL SourceIndexed; // pdb supports source server - BOOL Publics; // contains public symbols -} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; - -typedef struct _IMAGEHLP_MODULEW64 -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) - DWORD64 BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - WCHAR ModuleName[32]; // module name - WCHAR ImageName[256]; // image name - // new elements: 07-Jun-2002 - WCHAR LoadedImageName[256]; // symbol file name - WCHAR LoadedPdbName[256]; // pdb file name - DWORD CVSig; // Signature of the CV record in the debug directories - WCHAR CVData[MAX_PATH * 3]; // Contents of the CV record - DWORD PdbSig; // Signature of PDB - GUID PdbSig70; // Signature of PDB (VC 7 and up) - DWORD PdbAge; // DBI age of pdb - BOOL PdbUnmatched; // loaded an unmatched pdb - BOOL DbgUnmatched; // loaded an unmatched dbg - BOOL LineNumbers; // we have line number information - BOOL GlobalSymbols; // we have internal symbol information - BOOL TypeInfo; // we have type information - // new elements: 17-Dec-2003 - BOOL SourceIndexed; // pdb supports source server - BOOL Publics; // contains public symbols -} IMAGEHLP_MODULEW64, *PIMAGEHLP_MODULEW64; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define IMAGEHLP_MODULE IMAGEHLP_MODULE64 -#define PIMAGEHLP_MODULE PIMAGEHLP_MODULE64 -#define IMAGEHLP_MODULEW IMAGEHLP_MODULEW64 -#define PIMAGEHLP_MODULEW PIMAGEHLP_MODULEW64 -#else -typedef struct _IMAGEHLP_MODULE -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE) - DWORD BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - CHAR ModuleName[32]; // module name - CHAR ImageName[256]; // image name - CHAR LoadedImageName[256]; // symbol file name -} IMAGEHLP_MODULE, *PIMAGEHLP_MODULE; - -typedef struct _IMAGEHLP_MODULEW -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE) - DWORD BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - WCHAR ModuleName[32]; // module name - WCHAR ImageName[256]; // image name - WCHAR LoadedImageName[256]; // symbol file name -} IMAGEHLP_MODULEW, *PIMAGEHLP_MODULEW; -#endif - -// -// source file line data structure -// - -typedef struct _IMAGEHLP_LINE64 -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) - PVOID Key; // internal - DWORD LineNumber; // line number in file - PCHAR FileName; // full filename - DWORD64 Address; // first instruction of line -} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; - -typedef struct _IMAGEHLP_LINEW64 -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) - PVOID Key; // internal - DWORD LineNumber; // line number in file - PWSTR FileName; // full filename - DWORD64 Address; // first instruction of line -} IMAGEHLP_LINEW64, *PIMAGEHLP_LINEW64; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define IMAGEHLP_LINE IMAGEHLP_LINE64 -#define PIMAGEHLP_LINE PIMAGEHLP_LINE64 -#else -typedef struct _IMAGEHLP_LINE -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE) - PVOID Key; // internal - DWORD LineNumber; // line number in file - PCHAR FileName; // full filename - DWORD Address; // first instruction of line -} IMAGEHLP_LINE, *PIMAGEHLP_LINE; - -typedef struct _IMAGEHLP_LINEW -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) - PVOID Key; // internal - DWORD LineNumber; // line number in file - PCHAR FileName; // full filename - DWORD64 Address; // first instruction of line -} IMAGEHLP_LINEW, *PIMAGEHLP_LINEW; -#endif - -// -// source file structure -// - -typedef struct _SOURCEFILE -{ - DWORD64 ModBase; // base address of loaded module - PCHAR FileName; // full filename of source -} SOURCEFILE, *PSOURCEFILE; - -typedef struct _SOURCEFILEW -{ - DWORD64 ModBase; // base address of loaded module - PWSTR FileName; // full filename of source -} SOURCEFILEW, *PSOURCEFILEW; - -// -// data structures used for registered symbol callbacks -// - -#define CBA_DEFERRED_SYMBOL_LOAD_START 0x00000001 -#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE 0x00000002 -#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE 0x00000003 -#define CBA_SYMBOLS_UNLOADED 0x00000004 -#define CBA_DUPLICATE_SYMBOL 0x00000005 -#define CBA_READ_MEMORY 0x00000006 -#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL 0x00000007 -#define CBA_SET_OPTIONS 0x00000008 -#define CBA_EVENT 0x00000010 -#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL 0x00000020 -#define CBA_DEBUG_INFO 0x10000000 -#define CBA_SRCSRV_INFO 0x20000000 -#define CBA_SRCSRV_EVENT 0x40000000 - -typedef struct _IMAGEHLP_CBA_READ_MEMORY -{ - DWORD64 addr; // address to read from - PVOID buf; // buffer to read to - DWORD bytes; // amount of bytes to read - DWORD* bytesread; // pointer to store amount of bytes read -} IMAGEHLP_CBA_READ_MEMORY, *PIMAGEHLP_CBA_READ_MEMORY; - -enum -{ - sevInfo = 0, - sevProblem, - sevAttn, - sevFatal, - sevMax // unused -}; - -#define EVENT_SRCSPEW_START 100 -#define EVENT_SRCSPEW 100 -#define EVENT_SRCSPEW_END 199 - -typedef struct _IMAGEHLP_CBA_EVENT -{ - DWORD severity; // values from sevInfo to sevFatal - DWORD code; // numerical code IDs the error - PCHAR desc; // may contain a text description of the error - PVOID object; // value dependant upon the error code -} IMAGEHLP_CBA_EVENT, *PIMAGEHLP_CBA_EVENT; - -typedef struct _IMAGEHLP_CBA_EVENTW -{ - DWORD severity; // values from sevInfo to sevFatal - DWORD code; // numerical code IDs the error - PCWSTR desc; // may contain a text description of the error - PVOID object; // value dependant upon the error code -} IMAGEHLP_CBA_EVENTW, *PIMAGEHLP_CBA_EVENTW; - -typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64) - DWORD64 BaseOfImage; // base load address of module - DWORD CheckSum; // checksum from the pe header - DWORD TimeDateStamp; // date/time stamp from pe header - CHAR FileName[MAX_PATH]; // symbols file or image name - BOOLEAN Reparse; // load failure reparse - HANDLE hFile; // file handle, if passed - DWORD Flags; // -} IMAGEHLP_DEFERRED_SYMBOL_LOAD64, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD64; - -typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOADW64 -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOADW64) - DWORD64 BaseOfImage; // base load address of module - DWORD CheckSum; // checksum from the pe header - DWORD TimeDateStamp; // date/time stamp from pe header - WCHAR FileName[MAX_PATH + 1]; // symbols file or image name - BOOLEAN Reparse; // load failure reparse - HANDLE hFile; // file handle, if passed - DWORD Flags; // -} IMAGEHLP_DEFERRED_SYMBOL_LOADW64, *PIMAGEHLP_DEFERRED_SYMBOL_LOADW64; - -#define DSLFLAG_MISMATCHED_PDB 0x1 -#define DSLFLAG_MISMATCHED_DBG 0x2 - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define IMAGEHLP_DEFERRED_SYMBOL_LOAD IMAGEHLP_DEFERRED_SYMBOL_LOAD64 -#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 -#else -typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD) - DWORD BaseOfImage; // base load address of module - DWORD CheckSum; // checksum from the pe header - DWORD TimeDateStamp; // date/time stamp from pe header - CHAR FileName[MAX_PATH]; // symbols file or image name - BOOLEAN Reparse; // load failure reparse - HANDLE hFile; // file handle, if passed -} IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD; -#endif - -typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL64) - DWORD NumberOfDups; // number of duplicates in the Symbol array - PIMAGEHLP_SYMBOL64 Symbol; // array of duplicate symbols - DWORD SelectedSymbol; // symbol selected (-1 to start) -} IMAGEHLP_DUPLICATE_SYMBOL64, *PIMAGEHLP_DUPLICATE_SYMBOL64; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define IMAGEHLP_DUPLICATE_SYMBOL IMAGEHLP_DUPLICATE_SYMBOL64 -#define PIMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_DUPLICATE_SYMBOL64 -#else -typedef struct _IMAGEHLP_DUPLICATE_SYMBOL -{ - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL) - DWORD NumberOfDups; // number of duplicates in the Symbol array - PIMAGEHLP_SYMBOL Symbol; // array of duplicate symbols - DWORD SelectedSymbol; // symbol selected (-1 to start) -} IMAGEHLP_DUPLICATE_SYMBOL, *PIMAGEHLP_DUPLICATE_SYMBOL; -#endif - -// If dbghelp ever needs to display graphical UI, it will use this as the parent window. - -BOOL -IMAGEAPI -SymSetParentWindow( - __in HWND hwnd -); - -PCHAR -IMAGEAPI -SymSetHomeDirectory( - __in_opt HANDLE hProcess, - __in_opt PCSTR dir -); - -PWSTR -IMAGEAPI -SymSetHomeDirectoryW( - __in_opt HANDLE hProcess, - __in_opt PCWSTR dir -); - -PCHAR -IMAGEAPI -SymGetHomeDirectory( - __in DWORD type, - __out_ecount(size) PSTR dir, - __in size_t size -); - -PWSTR -IMAGEAPI -SymGetHomeDirectoryW( - __in DWORD type, - __out_ecount(size) PWSTR dir, - __in size_t size -); - -enum -{ - hdBase = 0, // root directory for dbghelp - hdSym, // where symbols are stored - hdSrc, // where source is stored - hdMax // end marker -}; - -typedef struct _OMAP -{ - ULONG rva; - ULONG rvaTo; -} OMAP, *POMAP; - -BOOL -IMAGEAPI -SymGetOmaps( - __in HANDLE hProcess, - __in DWORD64 BaseOfDll, - __out POMAP* OmapTo, - __out PDWORD64 cOmapTo, - __out POMAP* OmapFrom, - __out PDWORD64 cOmapFrom -); - -// -// options that are set/returned by SymSetOptions() & SymGetOptions() -// these are used as a mask -// -#define SYMOPT_CASE_INSENSITIVE 0x00000001 -#define SYMOPT_UNDNAME 0x00000002 -#define SYMOPT_DEFERRED_LOADS 0x00000004 -#define SYMOPT_NO_CPP 0x00000008 -#define SYMOPT_LOAD_LINES 0x00000010 -#define SYMOPT_OMAP_FIND_NEAREST 0x00000020 -#define SYMOPT_LOAD_ANYTHING 0x00000040 -#define SYMOPT_IGNORE_CVREC 0x00000080 -#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 -#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 -#define SYMOPT_EXACT_SYMBOLS 0x00000400 -#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 -#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 -#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 -#define SYMOPT_PUBLICS_ONLY 0x00004000 -#define SYMOPT_NO_PUBLICS 0x00008000 -#define SYMOPT_AUTO_PUBLICS 0x00010000 -#define SYMOPT_NO_IMAGE_SEARCH 0x00020000 -#define SYMOPT_SECURE 0x00040000 -#define SYMOPT_NO_PROMPTS 0x00080000 -#define SYMOPT_OVERWRITE 0x00100000 -#define SYMOPT_IGNORE_IMAGEDIR 0x00200000 -#define SYMOPT_FLAT_DIRECTORY 0x00400000 -#define SYMOPT_FAVOR_COMPRESSED 0x00800000 -#define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 -#define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 - -#define SYMOPT_DEBUG 0x80000000 - -DWORD -IMAGEAPI -SymSetOptions( - __in DWORD SymOptions -); - -DWORD -IMAGEAPI -SymGetOptions( - VOID -); - -BOOL -IMAGEAPI -SymCleanup( - __in HANDLE hProcess -); - -BOOL -IMAGEAPI -SymMatchString( - __in PCSTR string, - __in PCSTR expression, - __in BOOL fCase -); - -BOOL -IMAGEAPI -SymMatchStringA( - __in PCSTR string, - __in PCSTR expression, - __in BOOL fCase -); - -BOOL -IMAGEAPI -SymMatchStringW( - __in PCWSTR string, - __in PCWSTR expression, - __in BOOL fCase -); - -typedef BOOL -(CALLBACK* PSYM_ENUMSOURCEFILES_CALLBACK)( - __in PSOURCEFILE pSourceFile, - __in_opt PVOID UserContext -); - -// for backwards compatibility - don't use this -#define PSYM_ENUMSOURCFILES_CALLBACK PSYM_ENUMSOURCEFILES_CALLBACK - -BOOL -IMAGEAPI -SymEnumSourceFiles( - __in HANDLE hProcess, - __in ULONG64 ModBase, - __in_opt PCSTR Mask, - __in PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PSYM_ENUMSOURCEFILES_CALLBACKW)( - __in PSOURCEFILEW pSourceFile, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumSourceFilesW( - __in HANDLE hProcess, - __in ULONG64 ModBase, - __in_opt PCWSTR Mask, - __in PSYM_ENUMSOURCEFILES_CALLBACKW cbSrcFiles, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumerateModules64( - __in HANDLE hProcess, - __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumerateModulesW64( - __in HANDLE hProcess, - __in PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback, - __in_opt PVOID UserContext -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymEnumerateModules SymEnumerateModules64 -#else -BOOL -IMAGEAPI -SymEnumerateModules( - __in HANDLE hProcess, - __in PSYM_ENUMMODULES_CALLBACK EnumModulesCallback, - __in_opt PVOID UserContext -); -#endif - -BOOL -IMAGEAPI -EnumerateLoadedModulesEx( - __in HANDLE hProcess, - __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -EnumerateLoadedModulesExW( - __in HANDLE hProcess, - __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -EnumerateLoadedModules64( - __in HANDLE hProcess, - __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -EnumerateLoadedModulesW64( - __in HANDLE hProcess, - __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, - __in_opt PVOID UserContext -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define EnumerateLoadedModules EnumerateLoadedModules64 -#else -BOOL -IMAGEAPI -EnumerateLoadedModules( - __in HANDLE hProcess, - __in PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback, - __in_opt PVOID UserContext -); -#endif - -PVOID -IMAGEAPI -SymFunctionTableAccess64( - __in HANDLE hProcess, - __in DWORD64 AddrBase -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymFunctionTableAccess SymFunctionTableAccess64 -#else -PVOID -IMAGEAPI -SymFunctionTableAccess( - __in HANDLE hProcess, - __in DWORD AddrBase -); -#endif - -BOOL -IMAGEAPI -SymGetUnwindInfo( - __in HANDLE hProcess, - __in DWORD64 Address, - __out_bcount_opt(*Size) PVOID Buffer, - __inout PULONG Size -); - -BOOL -IMAGEAPI -SymGetModuleInfo64( - __in HANDLE hProcess, - __in DWORD64 qwAddr, - __out PIMAGEHLP_MODULE64 ModuleInfo -); - -BOOL -IMAGEAPI -SymGetModuleInfoW64( - __in HANDLE hProcess, - __in DWORD64 qwAddr, - __out PIMAGEHLP_MODULEW64 ModuleInfo -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetModuleInfo SymGetModuleInfo64 -#define SymGetModuleInfoW SymGetModuleInfoW64 -#else -BOOL -IMAGEAPI -SymGetModuleInfo( - __in HANDLE hProcess, - __in DWORD dwAddr, - __out PIMAGEHLP_MODULE ModuleInfo -); - -BOOL -IMAGEAPI -SymGetModuleInfoW( - __in HANDLE hProcess, - __in DWORD dwAddr, - __out PIMAGEHLP_MODULEW ModuleInfo -); -#endif - -DWORD64 -IMAGEAPI -SymGetModuleBase64( - __in HANDLE hProcess, - __in DWORD64 qwAddr -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetModuleBase SymGetModuleBase64 -#else -DWORD -IMAGEAPI -SymGetModuleBase( - __in HANDLE hProcess, - __in DWORD dwAddr -); -#endif - -typedef struct _SRCCODEINFO -{ - DWORD SizeOfStruct; // set to sizeof(SRCCODEINFO) - PVOID Key; // not used - DWORD64 ModBase; // base address of module this applies to - CHAR Obj[MAX_PATH + 1]; // the object file within the module - CHAR FileName[MAX_PATH + 1]; // full filename - DWORD LineNumber; // line number in file - DWORD64 Address; // first instruction of line -} SRCCODEINFO, *PSRCCODEINFO; - -typedef struct _SRCCODEINFOW -{ - DWORD SizeOfStruct; // set to sizeof(SRCCODEINFO) - PVOID Key; // not used - DWORD64 ModBase; // base address of module this applies to - WCHAR Obj[MAX_PATH + 1]; // the object file within the module - WCHAR FileName[MAX_PATH + 1]; // full filename - DWORD LineNumber; // line number in file - DWORD64 Address; // first instruction of line -} SRCCODEINFOW, *PSRCCODEINFOW; - -typedef BOOL -(CALLBACK* PSYM_ENUMLINES_CALLBACK)( - __in PSRCCODEINFO LineInfo, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumLines( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCSTR Obj, - __in_opt PCSTR File, - __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PSYM_ENUMLINES_CALLBACKW)( - __in PSRCCODEINFOW LineInfo, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumLinesW( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCWSTR Obj, - __in_opt PCWSTR File, - __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymGetLineFromAddr64( - __in HANDLE hProcess, - __in DWORD64 qwAddr, - __out PDWORD pdwDisplacement, - __out PIMAGEHLP_LINE64 Line64 -); - -BOOL -IMAGEAPI -SymGetLineFromAddrW64( - __in HANDLE hProcess, - __in DWORD64 dwAddr, - __out PDWORD pdwDisplacement, - __out PIMAGEHLP_LINEW64 Line -); - -BOOL -IMAGEAPI -SymEnumSourceLines( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCSTR Obj, - __in_opt PCSTR File, - __in_opt DWORD Line, - __in DWORD Flags, - __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumSourceLinesW( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCWSTR Obj, - __in_opt PCWSTR File, - __in_opt DWORD Line, - __in DWORD Flags, - __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback, - __in_opt PVOID UserContext -); - -// flags for SymEnumSourceLines - -#define ESLFLAG_FULLPATH 0x1 -#define ESLFLAG_NEAREST 0x2 -#define ESLFLAG_PREV 0x4 -#define ESLFLAG_NEXT 0x8 - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetLineFromAddr SymGetLineFromAddr64 -#define SymGetLineFromAddrW SymGetLineFromAddrW64 -#else -BOOL -IMAGEAPI -SymGetLineFromAddr( - __in HANDLE hProcess, - __in DWORD dwAddr, - __out PDWORD pdwDisplacement, - __out PIMAGEHLP_LINE Line -); - -BOOL -IMAGEAPI -SymGetLineFromAddrW( - __in HANDLE hProcess, - __in DWORD dwAddr, - __out PDWORD pdwDisplacement, - __out PIMAGEHLP_LINEW Line -); -#endif - -BOOL -IMAGEAPI -SymGetLineFromName64( - __in HANDLE hProcess, - __in_opt PCSTR ModuleName, - __in_opt PCSTR FileName, - __in DWORD dwLineNumber, - __out PLONG plDisplacement, - __inout PIMAGEHLP_LINE64 Line -); - -BOOL -IMAGEAPI -SymGetLineFromNameW64( - __in HANDLE hProcess, - __in_opt PCWSTR ModuleName, - __in_opt PCWSTR FileName, - __in DWORD dwLineNumber, - __out PLONG plDisplacement, - __inout PIMAGEHLP_LINEW64 Line -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetLineFromName SymGetLineFromName64 -#else -BOOL -IMAGEAPI -SymGetLineFromName( - __in HANDLE hProcess, - __in_opt PCSTR ModuleName, - __in_opt PCSTR FileName, - __in DWORD dwLineNumber, - __out PLONG plDisplacement, - __inout PIMAGEHLP_LINE Line -); -#endif - -BOOL -IMAGEAPI -SymGetLineNext64( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINE64 Line -); - -BOOL -IMAGEAPI -SymGetLineNextW64( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINEW64 Line -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetLineNext SymGetLineNext64 -#else -BOOL -IMAGEAPI -SymGetLineNext( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINE Line -); - -BOOL -IMAGEAPI -SymGetLineNextW( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINEW Line -); -#endif - -BOOL -IMAGEAPI -SymGetLinePrev64( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINE64 Line -); - -BOOL -IMAGEAPI -SymGetLinePrevW64( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINEW64 Line -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetLinePrev SymGetLinePrev64 -#else -BOOL -IMAGEAPI -SymGetLinePrev( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINE Line -); - -BOOL -IMAGEAPI -SymGetLinePrevW( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINEW Line -); -#endif - -ULONG -IMAGEAPI -SymGetFileLineOffsets64( - __in HANDLE hProcess, - __in_opt PCSTR ModuleName, - __in PCSTR FileName, - __out_ecount(BufferLines) PDWORD64 Buffer, - __in ULONG BufferLines -); - -BOOL -IMAGEAPI -SymMatchFileName( - __in PCSTR FileName, - __in PCSTR Match, - __deref_opt_out PSTR* FileNameStop, - __deref_opt_out PSTR* MatchStop -); - -BOOL -IMAGEAPI -SymMatchFileNameW( - __in PCWSTR FileName, - __in PCWSTR Match, - __deref_opt_out PWSTR* FileNameStop, - __deref_opt_out PWSTR* MatchStop -); - -BOOL -IMAGEAPI -SymGetSourceFile( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCSTR Params, - __in PCSTR FileSpec, - __out_ecount(Size) PSTR FilePath, - __in DWORD Size -); - -BOOL -IMAGEAPI -SymGetSourceFileW( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCWSTR Params, - __in PCWSTR FileSpec, - __out_ecount(Size) PWSTR FilePath, - __in DWORD Size -); - -BOOL -IMAGEAPI -SymGetSourceFileToken( - __in HANDLE hProcess, - __in ULONG64 Base, - __in PCSTR FileSpec, - __deref_out PVOID* Token, - __out DWORD* Size -); - -BOOL -IMAGEAPI -SymGetSourceFileTokenW( - __in HANDLE hProcess, - __in ULONG64 Base, - __in PCWSTR FileSpec, - __deref_out PVOID* Token, - __out DWORD* Size -); - -BOOL -IMAGEAPI -SymGetSourceFileFromToken( - __in HANDLE hProcess, - __in PVOID Token, - __in_opt PCSTR Params, - __out_ecount(Size) PSTR FilePath, - __in DWORD Size -); - -BOOL -IMAGEAPI -SymGetSourceFileFromTokenW( - __in HANDLE hProcess, - __in PVOID Token, - __in_opt PCWSTR Params, - __out_ecount(Size) PWSTR FilePath, - __in DWORD Size -); - -BOOL -IMAGEAPI -SymGetSourceVarFromToken( - __in HANDLE hProcess, - __in PVOID Token, - __in_opt PCSTR Params, - __in PCSTR VarName, - __out_ecount(Size) PSTR Value, - __in DWORD Size -); - -BOOL -IMAGEAPI -SymGetSourceVarFromTokenW( - __in HANDLE hProcess, - __in PVOID Token, - __in_opt PCWSTR Params, - __in PCWSTR VarName, - __out_ecount(Size) PWSTR Value, - __in DWORD Size -); - -typedef BOOL (CALLBACK* PENUMSOURCEFILETOKENSCALLBACK)(__in PVOID token, __in size_t size); - -BOOL -IMAGEAPI -SymEnumSourceFileTokens( - __in HANDLE hProcess, - __in ULONG64 Base, - __in PENUMSOURCEFILETOKENSCALLBACK Callback -); - -BOOL -IMAGEAPI -SymInitialize( - __in HANDLE hProcess, - __in_opt PCSTR UserSearchPath, - __in BOOL fInvadeProcess -); - -BOOL -IMAGEAPI -SymInitializeW( - __in HANDLE hProcess, - __in_opt PCWSTR UserSearchPath, - __in BOOL fInvadeProcess -); - -BOOL -IMAGEAPI -SymGetSearchPath( - __in HANDLE hProcess, - __out_ecount(SearchPathLength) PSTR SearchPath, - __in DWORD SearchPathLength -); - -BOOL -IMAGEAPI -SymGetSearchPathW( - __in HANDLE hProcess, - __out_ecount(SearchPathLength) PWSTR SearchPath, - __in DWORD SearchPathLength -); - -BOOL -IMAGEAPI -SymSetSearchPath( - __in HANDLE hProcess, - __in_opt PCSTR SearchPath -); - -BOOL -IMAGEAPI -SymSetSearchPathW( - __in HANDLE hProcess, - __in_opt PCWSTR SearchPath -); - -#define SLMFLAG_VIRTUAL 0x1 -#define SLMFLAG_ALT_INDEX 0x2 -#define SLMFLAG_NO_SYMBOLS 0x4 - -DWORD64 -IMAGEAPI -SymLoadModuleEx( - __in HANDLE hProcess, - __in_opt HANDLE hFile, - __in_opt PCSTR ImageName, - __in_opt PCSTR ModuleName, - __in DWORD64 BaseOfDll, - __in DWORD DllSize, - __in_opt PMODLOAD_DATA Data, - __in_opt DWORD Flags -); - -DWORD64 -IMAGEAPI -SymLoadModuleExW( - __in HANDLE hProcess, - __in_opt HANDLE hFile, - __in_opt PCWSTR ImageName, - __in_opt PCWSTR ModuleName, - __in DWORD64 BaseOfDll, - __in DWORD DllSize, - __in_opt PMODLOAD_DATA Data, - __in_opt DWORD Flags -); - -BOOL -IMAGEAPI -SymUnloadModule64( - __in HANDLE hProcess, - __in DWORD64 BaseOfDll -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymUnloadModule SymUnloadModule64 -#else -BOOL -IMAGEAPI -SymUnloadModule( - __in HANDLE hProcess, - __in DWORD BaseOfDll -); -#endif - -BOOL -IMAGEAPI -SymUnDName64( - __in PIMAGEHLP_SYMBOL64 sym, // Symbol to undecorate - __out_ecount(UnDecNameLength) PSTR UnDecName, // Buffer to store undecorated name in - __in DWORD UnDecNameLength // Size of the buffer -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymUnDName SymUnDName64 -#else -BOOL -IMAGEAPI -SymUnDName( - __in PIMAGEHLP_SYMBOL sym, // Symbol to undecorate - __out_ecount(UnDecNameLength) PSTR UnDecName, // Buffer to store undecorated name in - __in DWORD UnDecNameLength // Size of the buffer -); -#endif - -BOOL -IMAGEAPI -SymRegisterCallback64( - __in HANDLE hProcess, - __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, - __in ULONG64 UserContext -); - -BOOL -IMAGEAPI -SymRegisterCallbackW64( - __in HANDLE hProcess, - __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, - __in ULONG64 UserContext -); - -BOOL -IMAGEAPI -SymRegisterFunctionEntryCallback64( - __in HANDLE hProcess, - __in PSYMBOL_FUNCENTRY_CALLBACK64 CallbackFunction, - __in ULONG64 UserContext -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymRegisterCallback SymRegisterCallback64 -#define SymRegisterFunctionEntryCallback SymRegisterFunctionEntryCallback64 -#else -BOOL -IMAGEAPI -SymRegisterCallback( - __in HANDLE hProcess, - __in PSYMBOL_REGISTERED_CALLBACK CallbackFunction, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymRegisterFunctionEntryCallback( - __in HANDLE hProcess, - __in PSYMBOL_FUNCENTRY_CALLBACK CallbackFunction, - __in_opt PVOID UserContext -); -#endif - - -typedef struct _IMAGEHLP_SYMBOL_SRC -{ - DWORD sizeofstruct; - DWORD type; - char file[MAX_PATH]; -} IMAGEHLP_SYMBOL_SRC, *PIMAGEHLP_SYMBOL_SRC; - -typedef struct _MODULE_TYPE_INFO // AKA TYPTYP -{ - USHORT dataLength; - USHORT leaf; - BYTE data[1]; -} MODULE_TYPE_INFO, *PMODULE_TYPE_INFO; - -typedef struct _SYMBOL_INFO -{ - ULONG SizeOfStruct; - ULONG TypeIndex; // Type Index of symbol - ULONG64 Reserved[2]; - ULONG Index; - ULONG Size; - ULONG64 ModBase; // Base Address of module comtaining this symbol - ULONG Flags; - ULONG64 Value; // Value of symbol, ValuePresent should be 1 - ULONG64 Address; // Address of symbol including base address of module - ULONG Register; // register holding value or pointer to value - ULONG Scope; // scope of the symbol - ULONG Tag; // pdb classification - ULONG NameLen; // Actual length of name - ULONG MaxNameLen; - CHAR Name[1]; // Name of symbol -} SYMBOL_INFO, *PSYMBOL_INFO; - -typedef struct _SYMBOL_INFO_PACKAGE -{ - SYMBOL_INFO si; - CHAR name[MAX_SYM_NAME + 1]; -} SYMBOL_INFO_PACKAGE, *PSYMBOL_INFO_PACKAGE; - -typedef struct _SYMBOL_INFOW -{ - ULONG SizeOfStruct; - ULONG TypeIndex; // Type Index of symbol - ULONG64 Reserved[2]; - ULONG Index; - ULONG Size; - ULONG64 ModBase; // Base Address of module comtaining this symbol - ULONG Flags; - ULONG64 Value; // Value of symbol, ValuePresent should be 1 - ULONG64 Address; // Address of symbol including base address of module - ULONG Register; // register holding value or pointer to value - ULONG Scope; // scope of the symbol - ULONG Tag; // pdb classification - ULONG NameLen; // Actual length of name - ULONG MaxNameLen; - WCHAR Name[1]; // Name of symbol -} SYMBOL_INFOW, *PSYMBOL_INFOW; - -typedef struct _SYMBOL_INFO_PACKAGEW -{ - SYMBOL_INFOW si; - WCHAR name[MAX_SYM_NAME + 1]; -} SYMBOL_INFO_PACKAGEW, *PSYMBOL_INFO_PACKAGEW; - -typedef struct _IMAGEHLP_STACK_FRAME -{ - ULONG64 InstructionOffset; - ULONG64 ReturnOffset; - ULONG64 FrameOffset; - ULONG64 StackOffset; - ULONG64 BackingStoreOffset; - ULONG64 FuncTableEntry; - ULONG64 Params[4]; - ULONG64 Reserved[5]; - BOOL Virtual; - ULONG Reserved2; -} IMAGEHLP_STACK_FRAME, *PIMAGEHLP_STACK_FRAME; - -typedef VOID IMAGEHLP_CONTEXT, *PIMAGEHLP_CONTEXT; - - -BOOL -IMAGEAPI -SymSetContext( - __in HANDLE hProcess, - __in PIMAGEHLP_STACK_FRAME StackFrame, - __in_opt PIMAGEHLP_CONTEXT Context -); - -BOOL -IMAGEAPI -SymSetScopeFromAddr( - __in HANDLE hProcess, - __in ULONG64 Address -); - -BOOL -IMAGEAPI -SymSetScopeFromIndex( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in DWORD Index -); - -typedef BOOL -(CALLBACK* PSYM_ENUMPROCESSES_CALLBACK)( - __in HANDLE hProcess, - __in PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumProcesses( - __in PSYM_ENUMPROCESSES_CALLBACK EnumProcessesCallback, - __in PVOID UserContext -); - -BOOL -IMAGEAPI -SymFromAddr( - __in HANDLE hProcess, - __in DWORD64 Address, - __out_opt PDWORD64 Displacement, - __inout PSYMBOL_INFO Symbol -); - -BOOL -IMAGEAPI -SymFromAddrW( - __in HANDLE hProcess, - __in DWORD64 Address, - __out_opt PDWORD64 Displacement, - __inout PSYMBOL_INFOW Symbol -); - -BOOL -IMAGEAPI -SymFromToken( - __in HANDLE hProcess, - __in DWORD64 Base, - __in DWORD Token, - __inout PSYMBOL_INFO Symbol -); - -BOOL -IMAGEAPI -SymFromTokenW( - __in HANDLE hProcess, - __in DWORD64 Base, - __in DWORD Token, - __inout PSYMBOL_INFOW Symbol -); - -BOOL -IMAGEAPI -SymNext( - __in HANDLE hProcess, - __inout PSYMBOL_INFO si -); - -BOOL -IMAGEAPI -SymNextW( - __in HANDLE hProcess, - __inout PSYMBOL_INFOW siw -); - -BOOL -IMAGEAPI -SymPrev( - __in HANDLE hProcess, - __inout PSYMBOL_INFO si -); - -BOOL -IMAGEAPI -SymPrevW( - __in HANDLE hProcess, - __inout PSYMBOL_INFOW siw -); - -// While SymFromName will provide a symbol from a name, -// SymEnumSymbols can provide the same matching information -// for ALL symbols with a matching name, even regular -// expressions. That way you can search across modules -// and differentiate between identically named symbols. - -BOOL -IMAGEAPI -SymFromName( - __in HANDLE hProcess, - __in PCSTR Name, - __inout PSYMBOL_INFO Symbol -); - -BOOL -IMAGEAPI -SymFromNameW( - __in HANDLE hProcess, - __in PCWSTR Name, - __inout PSYMBOL_INFOW Symbol -); - -typedef BOOL -(CALLBACK* PSYM_ENUMERATESYMBOLS_CALLBACK)( - __in PSYMBOL_INFO pSymInfo, - __in ULONG SymbolSize, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumSymbols( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCSTR Mask, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext -); - -typedef BOOL -(CALLBACK* PSYM_ENUMERATESYMBOLS_CALLBACKW)( - __in PSYMBOL_INFOW pSymInfo, - __in ULONG SymbolSize, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumSymbolsW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCWSTR Mask, - __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumSymbolsForAddr( - __in HANDLE hProcess, - __in DWORD64 Address, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumSymbolsForAddrW( - __in HANDLE hProcess, - __in DWORD64 Address, - __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, - __in_opt PVOID UserContext -); - -#define SYMSEARCH_MASKOBJS 0x01 // used internally to implement other APIs -#define SYMSEARCH_RECURSE 0X02 // recurse scopes -#define SYMSEARCH_GLOBALSONLY 0X04 // search only for global symbols -#define SYMSEARCH_ALLITEMS 0X08 // search for everything in the pdb, not just normal scoped symbols - -BOOL -IMAGEAPI -SymSearch( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt DWORD Index, - __in_opt DWORD SymTag, - __in_opt PCSTR Mask, - __in_opt DWORD64 Address, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext, - __in DWORD Options -); - -BOOL -IMAGEAPI -SymSearchW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt DWORD Index, - __in_opt DWORD SymTag, - __in_opt PCWSTR Mask, - __in_opt DWORD64 Address, - __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, - __in_opt PVOID UserContext, - __in DWORD Options -); - -BOOL -IMAGEAPI -SymGetScope( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in DWORD Index, - __inout PSYMBOL_INFO Symbol -); - -BOOL -IMAGEAPI -SymGetScopeW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in DWORD Index, - __inout PSYMBOL_INFOW Symbol -); - -BOOL -IMAGEAPI -SymFromIndex( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in DWORD Index, - __inout PSYMBOL_INFO Symbol -); - -BOOL -IMAGEAPI -SymFromIndexW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in DWORD Index, - __inout PSYMBOL_INFOW Symbol -); - -typedef enum _IMAGEHLP_SYMBOL_TYPE_INFO -{ - TI_GET_SYMTAG, - TI_GET_SYMNAME, - TI_GET_LENGTH, - TI_GET_TYPE, - TI_GET_TYPEID, - TI_GET_BASETYPE, - TI_GET_ARRAYINDEXTYPEID, - TI_FINDCHILDREN, - TI_GET_DATAKIND, - TI_GET_ADDRESSOFFSET, - TI_GET_OFFSET, - TI_GET_VALUE, - TI_GET_COUNT, - TI_GET_CHILDRENCOUNT, - TI_GET_BITPOSITION, - TI_GET_VIRTUALBASECLASS, - TI_GET_VIRTUALTABLESHAPEID, - TI_GET_VIRTUALBASEPOINTEROFFSET, - TI_GET_CLASSPARENTID, - TI_GET_NESTED, - TI_GET_SYMINDEX, - TI_GET_LEXICALPARENT, - TI_GET_ADDRESS, - TI_GET_THISADJUST, - TI_GET_UDTKIND, - TI_IS_EQUIV_TO, - TI_GET_CALLING_CONVENTION, - TI_IS_CLOSE_EQUIV_TO, - TI_GTIEX_REQS_VALID, - TI_GET_VIRTUALBASEOFFSET, - TI_GET_VIRTUALBASEDISPINDEX, - TI_GET_IS_REFERENCE, - TI_GET_INDIRECTVIRTUALBASECLASS, - IMAGEHLP_SYMBOL_TYPE_INFO_MAX, -} IMAGEHLP_SYMBOL_TYPE_INFO; - -typedef struct _TI_FINDCHILDREN_PARAMS -{ - ULONG Count; - ULONG Start; - ULONG ChildId[1]; -} TI_FINDCHILDREN_PARAMS; - -BOOL -IMAGEAPI -SymGetTypeInfo( - __in HANDLE hProcess, - __in DWORD64 ModBase, - __in ULONG TypeId, - __in IMAGEHLP_SYMBOL_TYPE_INFO GetType, - __out PVOID pInfo -); - -#define IMAGEHLP_GET_TYPE_INFO_UNCACHED 0x00000001 -#define IMAGEHLP_GET_TYPE_INFO_CHILDREN 0x00000002 - -typedef struct _IMAGEHLP_GET_TYPE_INFO_PARAMS -{ - IN ULONG SizeOfStruct; - IN ULONG Flags; - IN ULONG NumIds; - IN PULONG TypeIds; - IN ULONG64 TagFilter; - IN ULONG NumReqs; - IN IMAGEHLP_SYMBOL_TYPE_INFO* ReqKinds; - IN PULONG_PTR ReqOffsets; - IN PULONG ReqSizes; - IN ULONG_PTR ReqStride; - IN ULONG_PTR BufferSize; - OUT PVOID Buffer; - OUT ULONG EntriesMatched; - OUT ULONG EntriesFilled; - OUT ULONG64 TagsFound; - OUT ULONG64 AllReqsValid; - IN ULONG NumReqsValid; - OUT PULONG64 ReqsValid OPTIONAL; -} IMAGEHLP_GET_TYPE_INFO_PARAMS, *PIMAGEHLP_GET_TYPE_INFO_PARAMS; - -BOOL -IMAGEAPI -SymGetTypeInfoEx( - __in HANDLE hProcess, - __in DWORD64 ModBase, - __inout PIMAGEHLP_GET_TYPE_INFO_PARAMS Params -); - -BOOL -IMAGEAPI -SymEnumTypes( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumTypesW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumTypesByName( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCSTR mask, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymEnumTypesByNameW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCWSTR mask, - __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, - __in_opt PVOID UserContext -); - -BOOL -IMAGEAPI -SymGetTypeFromName( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PCSTR Name, - __inout PSYMBOL_INFO Symbol -); - -BOOL -IMAGEAPI -SymGetTypeFromNameW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PCWSTR Name, - __inout PSYMBOL_INFOW Symbol -); - -BOOL -IMAGEAPI -SymAddSymbol( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PCSTR Name, - __in DWORD64 Address, - __in DWORD Size, - __in DWORD Flags -); - -BOOL -IMAGEAPI -SymAddSymbolW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PCWSTR Name, - __in DWORD64 Address, - __in DWORD Size, - __in DWORD Flags -); - -BOOL -IMAGEAPI -SymDeleteSymbol( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCSTR Name, - __in DWORD64 Address, - __in DWORD Flags -); - -BOOL -IMAGEAPI -SymDeleteSymbolW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCWSTR Name, - __in DWORD64 Address, - __in DWORD Flags -); - -BOOL -IMAGEAPI -SymRefreshModuleList( - __in HANDLE hProcess -); - -BOOL -IMAGEAPI -SymAddSourceStream( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCSTR StreamFile, - __in_bcount_opt(Size) PBYTE Buffer, - __in size_t Size -); - -typedef BOOL (WINAPI* SYMADDSOURCESTREAM)(HANDLE, ULONG64, PCSTR, PBYTE, size_t); - -BOOL -IMAGEAPI -SymAddSourceStreamA( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCSTR StreamFile, - __in_bcount_opt(Size) PBYTE Buffer, - __in size_t Size -); - -typedef BOOL (WINAPI* SYMADDSOURCESTREAMA)(HANDLE, ULONG64, PCSTR, PBYTE, size_t); - -BOOL -IMAGEAPI -SymAddSourceStreamW( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCWSTR FileSpec, - __in_bcount_opt(Size) PBYTE Buffer, - __in size_t Size -); - -BOOL -IMAGEAPI -SymSrvIsStoreW( - __in_opt HANDLE hProcess, - __in PCWSTR path -); - -BOOL -IMAGEAPI -SymSrvIsStore( - __in_opt HANDLE hProcess, - __in PCSTR path -); - -PCSTR -IMAGEAPI -SymSrvDeltaName( - __in HANDLE hProcess, - __in_opt PCSTR SymPath, - __in PCSTR Type, - __in PCSTR File1, - __in PCSTR File2 -); - -PCWSTR -IMAGEAPI -SymSrvDeltaNameW( - __in HANDLE hProcess, - __in_opt PCWSTR SymPath, - __in PCWSTR Type, - __in PCWSTR File1, - __in PCWSTR File2 -); - -PCSTR -IMAGEAPI -SymSrvGetSupplement( - __in HANDLE hProcess, - __in_opt PCSTR SymPath, - __in PCSTR Node, - __in PCSTR File -); - -PCWSTR -IMAGEAPI -SymSrvGetSupplementW( - __in HANDLE hProcess, - __in_opt PCWSTR SymPath, - __in PCWSTR Node, - __in PCWSTR File -); - -BOOL -IMAGEAPI -SymSrvGetFileIndexes( - __in PCSTR File, - __out GUID* Id, - __out PDWORD Val1, - __out_opt PDWORD Val2, - __in DWORD Flags -); - -BOOL -IMAGEAPI -SymSrvGetFileIndexesW( - __in PCWSTR File, - __out GUID* Id, - __out PDWORD Val1, - __out_opt PDWORD Val2, - __in DWORD Flags -); - -BOOL -IMAGEAPI -SymSrvGetFileIndexStringW( - __in HANDLE hProcess, - __in_opt PCWSTR SrvPath, - __in PCWSTR File, - __out_ecount(Size) PWSTR Index, - __in size_t Size, - __in DWORD Flags -); - -BOOL -IMAGEAPI -SymSrvGetFileIndexString( - __in HANDLE hProcess, - __in_opt PCSTR SrvPath, - __in PCSTR File, - __out_ecount(Size) PSTR Index, - __in size_t Size, - __in DWORD Flags -); - -typedef struct -{ - DWORD sizeofstruct; - char file[MAX_PATH + 1]; - BOOL stripped; - DWORD timestamp; - DWORD size; - char dbgfile[MAX_PATH + 1]; - char pdbfile[MAX_PATH + 1]; - GUID guid; - DWORD sig; - DWORD age; -} SYMSRV_INDEX_INFO, *PSYMSRV_INDEX_INFO; - -typedef struct -{ - DWORD sizeofstruct; - WCHAR file[MAX_PATH + 1]; - BOOL stripped; - DWORD timestamp; - DWORD size; - WCHAR dbgfile[MAX_PATH + 1]; - WCHAR pdbfile[MAX_PATH + 1]; - GUID guid; - DWORD sig; - DWORD age; -} SYMSRV_INDEX_INFOW, *PSYMSRV_INDEX_INFOW; - -BOOL -IMAGEAPI -SymSrvGetFileIndexInfo( - __in PCSTR File, - __out PSYMSRV_INDEX_INFO Info, - __in DWORD Flags -); - -BOOL -IMAGEAPI -SymSrvGetFileIndexInfoW( - __in PCWSTR File, - __out PSYMSRV_INDEX_INFOW Info, - __in DWORD Flags -); - -PCSTR -IMAGEAPI -SymSrvStoreSupplement( - __in HANDLE hProcess, - __in_opt PCSTR SrvPath, - __in PCSTR Node, - __in PCSTR File, - __in DWORD Flags -); - -PCWSTR -IMAGEAPI -SymSrvStoreSupplementW( - __in HANDLE hProcess, - __in_opt PCWSTR SymPath, - __in PCWSTR Node, - __in PCWSTR File, - __in DWORD Flags -); - -PCSTR -IMAGEAPI -SymSrvStoreFile( - __in HANDLE hProcess, - __in_opt PCSTR SrvPath, - __in PCSTR File, - __in DWORD Flags -); - -PCWSTR -IMAGEAPI -SymSrvStoreFileW( - __in HANDLE hProcess, - __in_opt PCWSTR SrvPath, - __in PCWSTR File, - __in DWORD Flags -); - -// used by SymGetSymbolFile's "Type" parameter - -enum -{ - sfImage = 0, - sfDbg, - sfPdb, - sfMpd, - sfMax -}; - -BOOL -IMAGEAPI -SymGetSymbolFile( - __in_opt HANDLE hProcess, - __in_opt PCSTR SymPath, - __in PCSTR ImageFile, - __in DWORD Type, - __out_ecount(cSymbolFile) PSTR SymbolFile, - __in size_t cSymbolFile, - __out_ecount(cDbgFile) PSTR DbgFile, - __in size_t cDbgFile -); - -BOOL -IMAGEAPI -SymGetSymbolFileW( - __in_opt HANDLE hProcess, - __in_opt PCWSTR SymPath, - __in PCWSTR ImageFile, - __in DWORD Type, - __out_ecount(cSymbolFile) PWSTR SymbolFile, - __in size_t cSymbolFile, - __out_ecount(cDbgFile) PWSTR DbgFile, - __in size_t cDbgFile -); - -// -// Full user-mode dump creation. -// - -typedef BOOL (WINAPI* PDBGHELP_CREATE_USER_DUMP_CALLBACK)( - __in DWORD DataType, - __in PVOID* Data, - __out LPDWORD DataLength, - __in_opt PVOID UserData -); - -BOOL -WINAPI -DbgHelpCreateUserDump( - __in_opt LPCSTR FileName, - __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback, - __in_opt PVOID UserData -); - -BOOL -WINAPI -DbgHelpCreateUserDumpW( - __in_opt LPCWSTR FileName, - __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback, - __in_opt PVOID UserData -); - -// ----------------------------------------------------------------- -// The following 4 legacy APIs are fully supported, but newer -// ones are recommended. SymFromName and SymFromAddr provide -// much more detailed info on the returned symbol. - -BOOL -IMAGEAPI -SymGetSymFromAddr64( - __in HANDLE hProcess, - __in DWORD64 qwAddr, - __out_opt PDWORD64 pdwDisplacement, - __inout PIMAGEHLP_SYMBOL64 Symbol -); - - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetSymFromAddr SymGetSymFromAddr64 -#else -BOOL -IMAGEAPI -SymGetSymFromAddr( - __in HANDLE hProcess, - __in DWORD dwAddr, - __out_opt PDWORD pdwDisplacement, - __inout PIMAGEHLP_SYMBOL Symbol -); -#endif - -// While following two APIs will provide a symbol from a name, -// SymEnumSymbols can provide the same matching information -// for ALL symbols with a matching name, even regular -// expressions. That way you can search across modules -// and differentiate between identically named symbols. - -BOOL -IMAGEAPI -SymGetSymFromName64( - __in HANDLE hProcess, - __in PCSTR Name, - __inout PIMAGEHLP_SYMBOL64 Symbol -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetSymFromName SymGetSymFromName64 -#else -BOOL -IMAGEAPI -SymGetSymFromName( - __in HANDLE hProcess, - __in PCSTR Name, - __inout PIMAGEHLP_SYMBOL Symbol -); -#endif - - -// Symbol server exports - -typedef BOOL (WINAPI* PSYMBOLSERVERPROC)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR); -typedef BOOL (WINAPI* PSYMBOLSERVERPROCA)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR); -typedef BOOL (WINAPI* PSYMBOLSERVERPROCW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR); -typedef BOOL (WINAPI* PSYMBOLSERVERBYINDEXPROC)(PCSTR, PCSTR, PCSTR, PSTR); -typedef BOOL (WINAPI* PSYMBOLSERVERBYINDEXPROCA)(PCSTR, PCSTR, PCSTR, PSTR); -typedef BOOL (WINAPI* PSYMBOLSERVERBYINDEXPROCW)(PCWSTR, PCWSTR, PCWSTR, PWSTR); -typedef BOOL (WINAPI* PSYMBOLSERVEROPENPROC)(VOID); -typedef BOOL (WINAPI* PSYMBOLSERVERCLOSEPROC)(VOID); -typedef BOOL (WINAPI* PSYMBOLSERVERSETOPTIONSPROC)(UINT_PTR, ULONG64); -typedef BOOL (WINAPI* PSYMBOLSERVERSETOPTIONSWPROC)(UINT_PTR, ULONG64); -typedef BOOL (CALLBACK WINAPI* PSYMBOLSERVERCALLBACKPROC)(UINT_PTR action, ULONG64 data, ULONG64 context); -typedef UINT_PTR(WINAPI* PSYMBOLSERVERGETOPTIONSPROC)(); -typedef BOOL (WINAPI* PSYMBOLSERVERPINGPROC)(PCSTR); -typedef BOOL (WINAPI* PSYMBOLSERVERPINGPROCA)(PCSTR); -typedef BOOL (WINAPI* PSYMBOLSERVERPINGPROCW)(PCWSTR); -typedef BOOL (WINAPI* PSYMBOLSERVERGETVERSION)(LPAPI_VERSION); -typedef BOOL (WINAPI* PSYMBOLSERVERDELTANAME)(PCSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PSTR, size_t); -typedef BOOL (WINAPI* PSYMBOLSERVERDELTANAMEW)(PCWSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PWSTR, size_t); -typedef BOOL (WINAPI* PSYMBOLSERVERGETSUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t); -typedef BOOL (WINAPI* PSYMBOLSERVERGETSUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t); -typedef BOOL (WINAPI* PSYMBOLSERVERSTORESUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t, DWORD); -typedef BOOL (WINAPI* PSYMBOLSERVERSTORESUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t, DWORD); -typedef BOOL (WINAPI* PSYMBOLSERVERGETINDEXSTRING)(PVOID, DWORD, DWORD, PSTR, size_t); -typedef BOOL (WINAPI* PSYMBOLSERVERGETINDEXSTRINGW)(PVOID, DWORD, DWORD, PWSTR, size_t); -typedef BOOL (WINAPI* PSYMBOLSERVERSTOREFILE)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR, size_t, DWORD); -typedef BOOL (WINAPI* PSYMBOLSERVERSTOREFILEW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR, size_t, DWORD); -typedef BOOL (WINAPI* PSYMBOLSERVERISSTORE)(PCSTR); -typedef BOOL (WINAPI* PSYMBOLSERVERISSTOREW)(PCWSTR); -typedef DWORD (WINAPI* PSYMBOLSERVERVERSION)(); -typedef BOOL (CALLBACK WINAPI* PSYMBOLSERVERMESSAGEPROC)(UINT_PTR action, ULONG64 data, ULONG64 context); - -#define SYMSRV_VERSION 2 - -#define SSRVOPT_CALLBACK 0x00000001 -#define SSRVOPT_DWORD 0x00000002 -#define SSRVOPT_DWORDPTR 0x00000004 -#define SSRVOPT_GUIDPTR 0x00000008 -#define SSRVOPT_OLDGUIDPTR 0x00000010 -#define SSRVOPT_UNATTENDED 0x00000020 -#define SSRVOPT_NOCOPY 0x00000040 -#define SSRVOPT_GETPATH 0x00000040 -#define SSRVOPT_PARENTWIN 0x00000080 -#define SSRVOPT_PARAMTYPE 0x00000100 -#define SSRVOPT_SECURE 0x00000200 -#define SSRVOPT_TRACE 0x00000400 -#define SSRVOPT_SETCONTEXT 0x00000800 -#define SSRVOPT_PROXY 0x00001000 -#define SSRVOPT_DOWNSTREAM_STORE 0x00002000 -#define SSRVOPT_OVERWRITE 0x00004000 -#define SSRVOPT_RESETTOU 0x00008000 -#define SSRVOPT_CALLBACKW 0x00010000 -#define SSRVOPT_FLAT_DEFAULT_STORE 0x00020000 -#define SSRVOPT_PROXYW 0x00040000 -#define SSRVOPT_MESSAGE 0x00080000 -#define SSRVOPT_SERVICE 0x00100000 // deprecated -#define SSRVOPT_FAVOR_COMPRESSED 0x00200000 -#define SSRVOPT_STRING 0x00400000 -#define SSRVOPT_WINHTTP 0x00800000 -#define SSRVOPT_WININET 0x01000000 - -#define SSRVOPT_MAX 0x0100000 - -#define SSRVOPT_RESET ((ULONG_PTR)-1) - - -#define NUM_SSRVOPTS 30 - -#define SSRVACTION_TRACE 1 -#define SSRVACTION_QUERYCANCEL 2 -#define SSRVACTION_EVENT 3 -#define SSRVACTION_EVENTW 4 -#define SSRVACTION_SIZE 5 - -#define SYMSTOREOPT_COMPRESS 0x01 -#define SYMSTOREOPT_OVERWRITE 0x02 -#define SYMSTOREOPT_RETURNINDEX 0x04 -#define SYMSTOREOPT_POINTER 0x08 -#define SYMSTOREOPT_ALT_INDEX 0x10 -#define SYMSTOREOPT_UNICODE 0x20 -#define SYMSTOREOPT_PASS_IF_EXISTS 0x40 - -#ifdef DBGHELP_TRANSLATE_TCHAR -#define SymInitialize SymInitializeW -#define SymAddSymbol SymAddSymbolW -#define SymDeleteSymbol SymDeleteSymbolW -#define SearchTreeForFile SearchTreeForFileW -#define UnDecorateSymbolName UnDecorateSymbolNameW -#define SymGetLineFromName64 SymGetLineFromNameW64 -#define SymGetLineFromAddr64 SymGetLineFromAddrW64 -#define SymGetLineNext64 SymGetLineNextW64 -#define SymGetLinePrev64 SymGetLinePrevW64 -#define SymFromName SymFromNameW -#define SymFindExecutableImage SymFindExecutableImageW -#define FindExecutableImageEx FindExecutableImageExW -#define SymSearch SymSearchW -#define SymEnumLines SymEnumLinesW -#define SymEnumSourceLines SymEnumSourceLinesW -#define SymGetTypeFromName SymGetTypeFromNameW -#define SymEnumSymbolsForAddr SymEnumSymbolsForAddrW -#define SymFromAddr SymFromAddrW -#define SymMatchString SymMatchStringW -#define SymEnumSourceFiles SymEnumSourceFilesW -#define SymEnumSymbols SymEnumSymbolsW -#define SymLoadModuleEx SymLoadModuleExW -#define SymSetSearchPath SymSetSearchPathW -#define SymGetSearchPath SymGetSearchPathW -#define EnumDirTree EnumDirTreeW -#define SymFromToken SymFromTokenW -#define SymFromIndex SymFromIndexW -#define SymGetScope SymGetScopeW -#define SymNext SymNextW -#define SymPrev SymPrevW -#define SymEnumTypes SymEnumTypesW -#define SymEnumTypesByName SymEnumTypesByNameW -#define SymRegisterCallback64 SymRegisterCallbackW64 -#define SymFindDebugInfoFile SymFindDebugInfoFileW -#define FindDebugInfoFileEx FindDebugInfoFileExW -#define SymFindFileInPath SymFindFileInPathW -#define SymEnumerateModules64 SymEnumerateModulesW64 -#define SymSetHomeDirectory SymSetHomeDirectoryW -#define SymGetHomeDirectory SymGetHomeDirectoryW -#define SymGetSourceFile SymGetSourceFileW -#define SymGetSourceFileToken SymGetSourceFileTokenW -#define SymGetSourceFileFromToken SymGetSourceFileFromTokenW -#define SymGetSourceVarFromToken SymGetSourceVarFromTokenW -#define SymGetSourceFileToken SymGetSourceFileTokenW -#define SymGetFileLineOffsets64 SymGetFileLineOffsetsW64 -#define SymFindFileInPath SymFindFileInPathW -#define SymMatchFileName SymMatchFileNameW -#define SymGetSourceFileFromToken SymGetSourceFileFromTokenW -#define SymGetSourceVarFromToken SymGetSourceVarFromTokenW -#define SymGetModuleInfo64 SymGetModuleInfoW64 -#define SymSrvIsStore SymSrvIsStoreW -#define SymSrvDeltaName SymSrvDeltaNameW -#define SymSrvGetSupplement SymSrvGetSupplementW -#define SymSrvStoreSupplement SymSrvStoreSupplementW -#define SymSrvGetFileIndexes SymSrvGetFileIndexes -#define SymSrvGetFileIndexString SymSrvGetFileIndexStringW -#define SymSrvStoreFile SymSrvStoreFileW -#define SymGetSymbolFile SymGetSymbolFileW -#define EnumerateLoadedModules64 EnumerateLoadedModulesW64 -#define EnumerateLoadedModulesEx EnumerateLoadedModulesExW -#define SymSrvGetFileIndexInfo SymSrvGetFileIndexInfoW - -#define IMAGEHLP_LINE64 IMAGEHLP_LINEW64 -#define PIMAGEHLP_LINE64 PIMAGEHLP_LINEW64 -#define SYMBOL_INFO SYMBOL_INFOW -#define PSYMBOL_INFO PSYMBOL_INFOW -#define SYMBOL_INFO_PACKAGE SYMBOL_INFO_PACKAGEW -#define PSYMBOL_INFO_PACKAGE PSYMBOL_INFO_PACKAGEW -#define FIND_EXE_FILE_CALLBACK FIND_EXE_FILE_CALLBACKW -#define PFIND_EXE_FILE_CALLBACK PFIND_EXE_FILE_CALLBACKW -#define SYM_ENUMERATESYMBOLS_CALLBACK SYM_ENUMERATESYMBOLS_CALLBACKW -#define PSYM_ENUMERATESYMBOLS_CALLBACK PSYM_ENUMERATESYMBOLS_CALLBACKW -#define SRCCODEINFO SRCCODEINFOW -#define PSRCCODEINFO PSRCCODEINFOW -#define SOURCEFILE SOURCEFILEW -#define PSOURCEFILE PSOURCEFILEW -#define SYM_ENUMSOURECFILES_CALLBACK SYM_ENUMSOURCEFILES_CALLBACKW -#define PSYM_ENUMSOURCEFILES_CALLBACK PSYM_ENUMSOURECFILES_CALLBACKW -#define IMAGEHLP_CBA_EVENT IMAGEHLP_CBA_EVENTW -#define PIMAGEHLP_CBA_EVENT PIMAGEHLP_CBA_EVENTW -#define PENUMDIRTREE_CALLBACK PENUMDIRTREE_CALLBACKW -#define IMAGEHLP_DEFERRED_SYMBOL_LOAD64 IMAGEHLP_DEFERRED_SYMBOL_LOADW64 -#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 PIMAGEHLP_DEFERRED_SYMBOL_LOADW64 -#define PFIND_DEBUG_FILE_CALLBACK PFIND_DEBUG_FILE_CALLBACKW -#define PFINDFILEINPATHCALLBACK PFINDFILEINPATHCALLBACKW -#define IMAGEHLP_MODULE64 IMAGEHLP_MODULEW64 -#define PIMAGEHLP_MODULE64 PIMAGEHLP_MODULEW64 -#define SYMSRV_INDEX_INFO SYMSRV_INDEX_INFOW -#define PSYMSRV_INDEX_INFO PSYMSRV_INDEX_INFOW - -#define PSYMBOLSERVERPROC PSYMBOLSERVERPROCW -#define PSYMBOLSERVERPINGPROC PSYMBOLSERVERPINGPROCW -#endif - -// ----------------------------------------------------------------- -// The following APIs exist only for backwards compatibility -// with a pre-release version documented in an MSDN release. - -// You should use SymFindFileInPath if you want to maintain -// future compatibility. - -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -FindFileInPath( - __in HANDLE hprocess, - __in PCSTR SearchPath, - __in PCSTR FileName, - __in PVOID id, - __in DWORD two, - __in DWORD three, - __in DWORD flags, - __out_ecount(MAX_PATH + 1) PSTR FilePath -); - -// You should use SymFindFileInPath if you want to maintain -// future compatibility. - -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -FindFileInSearchPath( - __in HANDLE hprocess, - __in PCSTR SearchPath, - __in PCSTR FileName, - __in DWORD one, - __in DWORD two, - __in DWORD three, - __out_ecount(MAX_PATH + 1) PSTR FilePath -); - -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -SymEnumSym( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext -); - -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -SymEnumerateSymbols64( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback, - __in_opt PVOID UserContext -); - -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -SymEnumerateSymbolsW64( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PSYM_ENUMSYMBOLS_CALLBACK64W EnumSymbolsCallback, - __in_opt PVOID UserContext -); - - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymEnumerateSymbols SymEnumerateSymbols64 -#define SymEnumerateSymbolsW SymEnumerateSymbolsW64 -#else -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -SymEnumerateSymbols( - __in HANDLE hProcess, - __in ULONG BaseOfDll, - __in PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext -); - -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -SymEnumerateSymbolsW( - __in HANDLE hProcess, - __in ULONG BaseOfDll, - __in PSYM_ENUMSYMBOLS_CALLBACKW EnumSymbolsCallback, - __in_opt PVOID UserContext -); -#endif - -// use SymLoadModuleEx - -DWORD64 -IMAGEAPI -SymLoadModule64( - __in HANDLE hProcess, - __in_opt HANDLE hFile, - __in_opt PCSTR ImageName, - __in_opt PCSTR ModuleName, - __in DWORD64 BaseOfDll, - __in DWORD SizeOfDll -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymLoadModule SymLoadModule64 -#else -DWORD -IMAGEAPI -SymLoadModule( - __in HANDLE hProcess, - __in_opt HANDLE hFile, - __in_opt PCSTR ImageName, - __in_opt PCSTR ModuleName, - __in DWORD BaseOfDll, - __in DWORD SizeOfDll -); -#endif - -BOOL -IMAGEAPI -SymGetSymNext64( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOL64 Symbol -); - -BOOL -IMAGEAPI -SymGetSymNextW64( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOLW64 Symbol -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetSymNext SymGetSymNext64 -#define SymGetSymNextW SymGetSymNextW64 -#else -BOOL -IMAGEAPI -SymGetSymNext( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOL Symbol -); - -BOOL -IMAGEAPI -SymGetSymNextW( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOLW Symbol -); -#endif - -BOOL -IMAGEAPI -SymGetSymPrev64( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOL64 Symbol -); - -BOOL -IMAGEAPI -SymGetSymPrevW64( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOLW64 Symbol -); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetSymPrev SymGetSymPrev64 -#define SymGetSymPrevW SymGetSymPrevW64 -#else -BOOL -IMAGEAPI -SymGetSymPrev( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOL Symbol -); - -BOOL -IMAGEAPI -SymGetSymPrevW( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOLW Symbol -); -#endif - - -// These values should not be used. -// They have been replaced by SYMFLAG_ values. - -#define SYMF_OMAP_GENERATED 0x00000001 -#define SYMF_OMAP_MODIFIED 0x00000002 -#define SYMF_REGISTER 0x00000008 -#define SYMF_REGREL 0x00000010 -#define SYMF_FRAMEREL 0x00000020 -#define SYMF_PARAMETER 0x00000040 -#define SYMF_LOCAL 0x00000080 -#define SYMF_CONSTANT 0x00000100 -#define SYMF_EXPORT 0x00000200 -#define SYMF_FORWARDER 0x00000400 -#define SYMF_FUNCTION 0x00000800 -#define SYMF_VIRTUAL 0x00001000 -#define SYMF_THUNK 0x00002000 -#define SYMF_TLSREL 0x00004000 - -// These values should also not be used. -// They have been replaced by SYMFLAG_ values. - -#define IMAGEHLP_SYMBOL_INFO_VALUEPRESENT 1 -#define IMAGEHLP_SYMBOL_INFO_REGISTER SYMF_REGISTER // 0x0008 -#define IMAGEHLP_SYMBOL_INFO_REGRELATIVE SYMF_REGREL // 0x0010 -#define IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE SYMF_FRAMEREL // 0x0020 -#define IMAGEHLP_SYMBOL_INFO_PARAMETER SYMF_PARAMETER // 0x0040 -#define IMAGEHLP_SYMBOL_INFO_LOCAL SYMF_LOCAL // 0x0080 -#define IMAGEHLP_SYMBOL_INFO_CONSTANT SYMF_CONSTANT // 0x0100 -#define IMAGEHLP_SYMBOL_FUNCTION SYMF_FUNCTION // 0x0800 -#define IMAGEHLP_SYMBOL_VIRTUAL SYMF_VIRTUAL // 0x1000 -#define IMAGEHLP_SYMBOL_THUNK SYMF_THUNK // 0x2000 -#define IMAGEHLP_SYMBOL_INFO_TLSRELATIVE SYMF_TLSREL // 0x4000 - -#pragma pack(pop) - - -#pragma pack(push,4) - -#define MINIDUMP_SIGNATURE ('PMDM') -#define MINIDUMP_VERSION (42899) -typedef DWORD RVA; -typedef ULONG64 RVA64; - -typedef struct _MINIDUMP_LOCATION_DESCRIPTOR -{ - ULONG32 DataSize; - RVA Rva; -} MINIDUMP_LOCATION_DESCRIPTOR; - -typedef struct _MINIDUMP_LOCATION_DESCRIPTOR64 -{ - ULONG64 DataSize; - RVA64 Rva; -} MINIDUMP_LOCATION_DESCRIPTOR64; - - -typedef struct _MINIDUMP_MEMORY_DESCRIPTOR -{ - ULONG64 StartOfMemoryRange; - MINIDUMP_LOCATION_DESCRIPTOR Memory; -} MINIDUMP_MEMORY_DESCRIPTOR, *PMINIDUMP_MEMORY_DESCRIPTOR; - -// DESCRIPTOR64 is used for full-memory minidumps where -// all of the raw memory is laid out sequentially at the -// end of the dump. There is no need for individual RVAs -// as the RVA is the base RVA plus the sum of the preceeding -// data blocks. -typedef struct _MINIDUMP_MEMORY_DESCRIPTOR64 -{ - ULONG64 StartOfMemoryRange; - ULONG64 DataSize; -} MINIDUMP_MEMORY_DESCRIPTOR64, *PMINIDUMP_MEMORY_DESCRIPTOR64; - - -typedef struct _MINIDUMP_HEADER -{ - ULONG32 Signature; - ULONG32 Version; - ULONG32 NumberOfStreams; - RVA StreamDirectoryRva; - ULONG32 CheckSum; - union - { - ULONG32 Reserved; - ULONG32 TimeDateStamp; - }; - ULONG64 Flags; -} MINIDUMP_HEADER, *PMINIDUMP_HEADER; - -// -// The MINIDUMP_HEADER field StreamDirectoryRva points to -// an array of MINIDUMP_DIRECTORY structures. -// - -typedef struct _MINIDUMP_DIRECTORY -{ - ULONG32 StreamType; - MINIDUMP_LOCATION_DESCRIPTOR Location; -} MINIDUMP_DIRECTORY, *PMINIDUMP_DIRECTORY; - - -typedef struct _MINIDUMP_STRING -{ - ULONG32 Length; // Length in bytes of the string - WCHAR Buffer [0]; // Variable size buffer -} MINIDUMP_STRING, *PMINIDUMP_STRING; - - - -// -// The MINIDUMP_DIRECTORY field StreamType may be one of the following types. -// Types will be added in the future, so if a program reading the minidump -// header encounters a stream type it does not understand it should ignore -// the data altogether. Any tag above LastReservedStream will not be used by -// the system and is reserved for program-specific information. -// - -typedef enum _MINIDUMP_STREAM_TYPE -{ - - UnusedStream = 0, - ReservedStream0 = 1, - ReservedStream1 = 2, - ThreadListStream = 3, - ModuleListStream = 4, - MemoryListStream = 5, - ExceptionStream = 6, - SystemInfoStream = 7, - ThreadExListStream = 8, - Memory64ListStream = 9, - CommentStreamA = 10, - CommentStreamW = 11, - HandleDataStream = 12, - FunctionTableStream = 13, - UnloadedModuleListStream = 14, - MiscInfoStream = 15, - MemoryInfoListStream = 16, - ThreadInfoListStream = 17, - HandleOperationListStream = 18, - TokenStream = 19, - - ceStreamNull = 0x8000, - ceStreamSystemInfo = 0x8001, - ceStreamException = 0x8002, - ceStreamModuleList = 0x8003, - ceStreamProcessList = 0x8004, - ceStreamThreadList = 0x8005, - ceStreamThreadContextList = 0x8006, - ceStreamThreadCallStackList = 0x8007, - ceStreamMemoryVirtualList = 0x8008, - ceStreamMemoryPhysicalList = 0x8009, - ceStreamBucketParameters = 0x800A, - ceStreamProcessModuleMap = 0x800B, - ceStreamDiagnosisList = 0x800C, - - LastReservedStream = 0xffff - -} MINIDUMP_STREAM_TYPE; - - -// -// The minidump system information contains processor and -// Operating System specific information. -// - -// -// CPU information is obtained from one of two places. -// -// 1) On x86 computers, CPU_INFORMATION is obtained from the CPUID -// instruction. You must use the X86 portion of the union for X86 -// computers. -// -// 2) On non-x86 architectures, CPU_INFORMATION is obtained by calling -// IsProcessorFeatureSupported(). -// - -typedef union _CPU_INFORMATION -{ - - // - // X86 platforms use CPUID function to obtain processor information. - // - - struct - { - - // - // CPUID Subfunction 0, register EAX (VendorId [0]), - // EBX (VendorId [1]) and ECX (VendorId [2]). - // - - ULONG32 VendorId [ 3 ]; - - // - // CPUID Subfunction 1, register EAX - // - - ULONG32 VersionInformation; - - // - // CPUID Subfunction 1, register EDX - // - - ULONG32 FeatureInformation; - - - // - // CPUID, Subfunction 80000001, register EBX. This will only - // be obtained if the vendor id is "AuthenticAMD". - // - - ULONG32 AMDExtendedCpuFeatures; - - } X86CpuInfo; - - // - // Non-x86 platforms use processor feature flags. - // - - struct - { - - ULONG64 ProcessorFeatures [ 2 ]; - - } OtherCpuInfo; - -} CPU_INFORMATION, *PCPU_INFORMATION; - -typedef struct _MINIDUMP_SYSTEM_INFO -{ - - // - // ProcessorArchitecture, ProcessorLevel and ProcessorRevision are all - // taken from the SYSTEM_INFO structure obtained by GetSystemInfo( ). - // - - USHORT ProcessorArchitecture; - USHORT ProcessorLevel; - USHORT ProcessorRevision; - - union - { - USHORT Reserved0; - struct - { - UCHAR NumberOfProcessors; - UCHAR ProductType; - }; - }; - - // - // MajorVersion, MinorVersion, BuildNumber, PlatformId and - // CSDVersion are all taken from the OSVERSIONINFO structure - // returned by GetVersionEx( ). - // - - ULONG32 MajorVersion; - ULONG32 MinorVersion; - ULONG32 BuildNumber; - ULONG32 PlatformId; - - // - // RVA to a CSDVersion string in the string table. - // - - RVA CSDVersionRva; - - union - { - ULONG32 Reserved1; - struct - { - USHORT SuiteMask; - USHORT Reserved2; - }; - }; - - CPU_INFORMATION Cpu; - -} MINIDUMP_SYSTEM_INFO, *PMINIDUMP_SYSTEM_INFO; - - -// -// The minidump thread contains standard thread -// information plus an RVA to the memory for this -// thread and an RVA to the CONTEXT structure for -// this thread. -// - - -// -// ThreadId must be 4 bytes on all architectures. -// - -C_ASSERT(sizeof(((PPROCESS_INFORMATION)0)->dwThreadId) == 4); - -typedef struct _MINIDUMP_THREAD -{ - ULONG32 ThreadId; - ULONG32 SuspendCount; - ULONG32 PriorityClass; - ULONG32 Priority; - ULONG64 Teb; - MINIDUMP_MEMORY_DESCRIPTOR Stack; - MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; -} MINIDUMP_THREAD, *PMINIDUMP_THREAD; - -// -// The thread list is a container of threads. -// - -typedef struct _MINIDUMP_THREAD_LIST -{ - ULONG32 NumberOfThreads; - MINIDUMP_THREAD Threads [0]; -} MINIDUMP_THREAD_LIST, *PMINIDUMP_THREAD_LIST; - - -typedef struct _MINIDUMP_THREAD_EX -{ - ULONG32 ThreadId; - ULONG32 SuspendCount; - ULONG32 PriorityClass; - ULONG32 Priority; - ULONG64 Teb; - MINIDUMP_MEMORY_DESCRIPTOR Stack; - MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; - MINIDUMP_MEMORY_DESCRIPTOR BackingStore; -} MINIDUMP_THREAD_EX, *PMINIDUMP_THREAD_EX; - -// -// The thread list is a container of threads. -// - -typedef struct _MINIDUMP_THREAD_EX_LIST -{ - ULONG32 NumberOfThreads; - MINIDUMP_THREAD_EX Threads [0]; -} MINIDUMP_THREAD_EX_LIST, *PMINIDUMP_THREAD_EX_LIST; - - -// -// The MINIDUMP_EXCEPTION is the same as EXCEPTION on Win64. -// - -typedef struct _MINIDUMP_EXCEPTION -{ - ULONG32 ExceptionCode; - ULONG32 ExceptionFlags; - ULONG64 ExceptionRecord; - ULONG64 ExceptionAddress; - ULONG32 NumberParameters; - ULONG32 __unusedAlignment; - ULONG64 ExceptionInformation [ EXCEPTION_MAXIMUM_PARAMETERS ]; -} MINIDUMP_EXCEPTION, *PMINIDUMP_EXCEPTION; - - -// -// The exception information stream contains the id of the thread that caused -// the exception (ThreadId), the exception record for the exception -// (ExceptionRecord) and an RVA to the thread context where the exception -// occured. -// - -typedef struct MINIDUMP_EXCEPTION_STREAM -{ - ULONG32 ThreadId; - ULONG32 __alignment; - MINIDUMP_EXCEPTION ExceptionRecord; - MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; -} MINIDUMP_EXCEPTION_STREAM, *PMINIDUMP_EXCEPTION_STREAM; - - -// -// The MINIDUMP_MODULE contains information about a -// a specific module. It includes the CheckSum and -// the TimeDateStamp for the module so the module -// can be reloaded during the analysis phase. -// - -typedef struct _MINIDUMP_MODULE -{ - ULONG64 BaseOfImage; - ULONG32 SizeOfImage; - ULONG32 CheckSum; - ULONG32 TimeDateStamp; - RVA ModuleNameRva; - VS_FIXEDFILEINFO VersionInfo; - MINIDUMP_LOCATION_DESCRIPTOR CvRecord; - MINIDUMP_LOCATION_DESCRIPTOR MiscRecord; - ULONG64 Reserved0; // Reserved for future use. - ULONG64 Reserved1; // Reserved for future use. -} MINIDUMP_MODULE, *PMINIDUMP_MODULE; - - -// -// The minidump module list is a container for modules. -// - -typedef struct _MINIDUMP_MODULE_LIST -{ - ULONG32 NumberOfModules; - MINIDUMP_MODULE Modules [ 0 ]; -} MINIDUMP_MODULE_LIST, *PMINIDUMP_MODULE_LIST; - - -// -// Memory Ranges -// - -typedef struct _MINIDUMP_MEMORY_LIST -{ - ULONG32 NumberOfMemoryRanges; - MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges [0]; -} MINIDUMP_MEMORY_LIST, *PMINIDUMP_MEMORY_LIST; - -typedef struct _MINIDUMP_MEMORY64_LIST -{ - ULONG64 NumberOfMemoryRanges; - RVA64 BaseRva; - MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges [0]; -} MINIDUMP_MEMORY64_LIST, *PMINIDUMP_MEMORY64_LIST; - - -// -// Support for user supplied exception information. -// - -typedef struct _MINIDUMP_EXCEPTION_INFORMATION -{ - DWORD ThreadId; - PEXCEPTION_POINTERS ExceptionPointers; - BOOL ClientPointers; -} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; - -typedef struct _MINIDUMP_EXCEPTION_INFORMATION64 -{ - DWORD ThreadId; - ULONG64 ExceptionRecord; - ULONG64 ContextRecord; - BOOL ClientPointers; -} MINIDUMP_EXCEPTION_INFORMATION64, *PMINIDUMP_EXCEPTION_INFORMATION64; - - -// -// Support for capturing system handle state at the time of the dump. -// - -// Per-handle object information varies according to -// the OS, the OS version, the processor type and -// so on. The minidump gives a minidump identifier -// to each possible data format for identification -// purposes but does not control nor describe the actual data. -typedef enum _MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE -{ - MiniHandleObjectInformationNone, - MiniThreadInformation1, - MiniMutantInformation1, - MiniMutantInformation2, - MiniProcessInformation1, - MiniProcessInformation2, - MiniHandleObjectInformationTypeMax -} MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE; - -typedef struct _MINIDUMP_HANDLE_OBJECT_INFORMATION -{ - RVA NextInfoRva; - ULONG32 InfoType; - ULONG32 SizeOfInfo; - // Raw information follows. -} MINIDUMP_HANDLE_OBJECT_INFORMATION; - -typedef struct _MINIDUMP_HANDLE_DESCRIPTOR -{ - ULONG64 Handle; - RVA TypeNameRva; - RVA ObjectNameRva; - ULONG32 Attributes; - ULONG32 GrantedAccess; - ULONG32 HandleCount; - ULONG32 PointerCount; -} MINIDUMP_HANDLE_DESCRIPTOR, *PMINIDUMP_HANDLE_DESCRIPTOR; - -typedef struct _MINIDUMP_HANDLE_DESCRIPTOR_2 -{ - ULONG64 Handle; - RVA TypeNameRva; - RVA ObjectNameRva; - ULONG32 Attributes; - ULONG32 GrantedAccess; - ULONG32 HandleCount; - ULONG32 PointerCount; - RVA ObjectInfoRva; - ULONG32 Reserved0; -} MINIDUMP_HANDLE_DESCRIPTOR_2, *PMINIDUMP_HANDLE_DESCRIPTOR_2; - -// The latest MINIDUMP_HANDLE_DESCRIPTOR definition. -typedef MINIDUMP_HANDLE_DESCRIPTOR_2 MINIDUMP_HANDLE_DESCRIPTOR_N; -typedef MINIDUMP_HANDLE_DESCRIPTOR_N* PMINIDUMP_HANDLE_DESCRIPTOR_N; - -typedef struct _MINIDUMP_HANDLE_DATA_STREAM -{ - ULONG32 SizeOfHeader; - ULONG32 SizeOfDescriptor; - ULONG32 NumberOfDescriptors; - ULONG32 Reserved; -} MINIDUMP_HANDLE_DATA_STREAM, *PMINIDUMP_HANDLE_DATA_STREAM; - -// Some operating systems can track the last operations -// performed on a handle. For example, Application Verifier -// can enable this for some versions of Windows. The -// handle operation list collects handle operations -// known for the dump target. -// Each entry is an AVRF_HANDLE_OPERATION. -typedef struct _MINIDUMP_HANDLE_OPERATION_LIST -{ - ULONG32 SizeOfHeader; - ULONG32 SizeOfEntry; - ULONG32 NumberOfEntries; - ULONG32 Reserved; -} MINIDUMP_HANDLE_OPERATION_LIST, *PMINIDUMP_HANDLE_OPERATION_LIST; - - -// -// Support for capturing dynamic function table state at the time of the dump. -// - -typedef struct _MINIDUMP_FUNCTION_TABLE_DESCRIPTOR -{ - ULONG64 MinimumAddress; - ULONG64 MaximumAddress; - ULONG64 BaseAddress; - ULONG32 EntryCount; - ULONG32 SizeOfAlignPad; -} MINIDUMP_FUNCTION_TABLE_DESCRIPTOR, *PMINIDUMP_FUNCTION_TABLE_DESCRIPTOR; - -typedef struct _MINIDUMP_FUNCTION_TABLE_STREAM -{ - ULONG32 SizeOfHeader; - ULONG32 SizeOfDescriptor; - ULONG32 SizeOfNativeDescriptor; - ULONG32 SizeOfFunctionEntry; - ULONG32 NumberOfDescriptors; - ULONG32 SizeOfAlignPad; -} MINIDUMP_FUNCTION_TABLE_STREAM, *PMINIDUMP_FUNCTION_TABLE_STREAM; - - -// -// The MINIDUMP_UNLOADED_MODULE contains information about a -// a specific module that was previously loaded but no -// longer is. This can help with diagnosing problems where -// callers attempt to call code that is no longer loaded. -// - -typedef struct _MINIDUMP_UNLOADED_MODULE -{ - ULONG64 BaseOfImage; - ULONG32 SizeOfImage; - ULONG32 CheckSum; - ULONG32 TimeDateStamp; - RVA ModuleNameRva; -} MINIDUMP_UNLOADED_MODULE, *PMINIDUMP_UNLOADED_MODULE; - - -// -// The minidump unloaded module list is a container for unloaded modules. -// - -typedef struct _MINIDUMP_UNLOADED_MODULE_LIST -{ - ULONG32 SizeOfHeader; - ULONG32 SizeOfEntry; - ULONG32 NumberOfEntries; -} MINIDUMP_UNLOADED_MODULE_LIST, *PMINIDUMP_UNLOADED_MODULE_LIST; - - -// -// The miscellaneous information stream contains a variety -// of small pieces of information. A member is valid if -// it's within the available size and its corresponding -// bit is set. -// - -#define MINIDUMP_MISC1_PROCESS_ID 0x00000001 -#define MINIDUMP_MISC1_PROCESS_TIMES 0x00000002 -#define MINIDUMP_MISC1_PROCESSOR_POWER_INFO 0x00000004 -#define MINIDUMP_MISC3_PROCESS_INTEGRITY 0x00000010 -#define MINIDUMP_MISC3_PROCESS_EXECUTE_FLAGS 0x00000020 -#define MINIDUMP_MISC3_TIMEZONE 0x00000040 -#define MINIDUMP_MISC3_PROTECTED_PROCESS 0x00000080 - -typedef struct _MINIDUMP_MISC_INFO -{ - ULONG32 SizeOfInfo; - ULONG32 Flags1; - ULONG32 ProcessId; - ULONG32 ProcessCreateTime; - ULONG32 ProcessUserTime; - ULONG32 ProcessKernelTime; -} MINIDUMP_MISC_INFO, *PMINIDUMP_MISC_INFO; - -typedef struct _MINIDUMP_MISC_INFO_2 -{ - ULONG32 SizeOfInfo; - ULONG32 Flags1; - ULONG32 ProcessId; - ULONG32 ProcessCreateTime; - ULONG32 ProcessUserTime; - ULONG32 ProcessKernelTime; - ULONG32 ProcessorMaxMhz; - ULONG32 ProcessorCurrentMhz; - ULONG32 ProcessorMhzLimit; - ULONG32 ProcessorMaxIdleState; - ULONG32 ProcessorCurrentIdleState; -} MINIDUMP_MISC_INFO_2, *PMINIDUMP_MISC_INFO_2; - -typedef struct _MINIDUMP_MISC_INFO_3 -{ - ULONG32 SizeOfInfo; - ULONG32 Flags1; - ULONG32 ProcessId; - ULONG32 ProcessCreateTime; - ULONG32 ProcessUserTime; - ULONG32 ProcessKernelTime; - ULONG32 ProcessorMaxMhz; - ULONG32 ProcessorCurrentMhz; - ULONG32 ProcessorMhzLimit; - ULONG32 ProcessorMaxIdleState; - ULONG32 ProcessorCurrentIdleState; - ULONG32 ProcessIntegrityLevel; - ULONG32 ProcessExecuteFlags; - ULONG32 ProtectedProcess; - ULONG32 TimeZoneId; - TIME_ZONE_INFORMATION TimeZone; -} MINIDUMP_MISC_INFO_3, *PMINIDUMP_MISC_INFO_3; - -// The latest MINIDUMP_MISC_INFO definition. -typedef MINIDUMP_MISC_INFO_3 MINIDUMP_MISC_INFO_N; -typedef MINIDUMP_MISC_INFO_N* PMINIDUMP_MISC_INFO_N; - - -// -// The memory information stream contains memory region -// description information. This stream corresponds to -// what VirtualQuery would return for the process the -// dump was created for. -// - -typedef struct _MINIDUMP_MEMORY_INFO -{ - ULONG64 BaseAddress; - ULONG64 AllocationBase; - ULONG32 AllocationProtect; - ULONG32 __alignment1; - ULONG64 RegionSize; - ULONG32 State; - ULONG32 Protect; - ULONG32 Type; - ULONG32 __alignment2; -} MINIDUMP_MEMORY_INFO, *PMINIDUMP_MEMORY_INFO; - -typedef struct _MINIDUMP_MEMORY_INFO_LIST -{ - ULONG SizeOfHeader; - ULONG SizeOfEntry; - ULONG64 NumberOfEntries; -} MINIDUMP_MEMORY_INFO_LIST, *PMINIDUMP_MEMORY_INFO_LIST; - - -// -// The memory information stream contains memory region -// description information. This stream corresponds to -// what VirtualQuery would return for the process the -// dump was created for. -// - -// Thread dump writer status flags. -#define MINIDUMP_THREAD_INFO_ERROR_THREAD 0x00000001 -#define MINIDUMP_THREAD_INFO_WRITING_THREAD 0x00000002 -#define MINIDUMP_THREAD_INFO_EXITED_THREAD 0x00000004 -#define MINIDUMP_THREAD_INFO_INVALID_INFO 0x00000008 -#define MINIDUMP_THREAD_INFO_INVALID_CONTEXT 0x00000010 -#define MINIDUMP_THREAD_INFO_INVALID_TEB 0x00000020 - -typedef struct _MINIDUMP_THREAD_INFO -{ - ULONG32 ThreadId; - ULONG32 DumpFlags; - ULONG32 DumpError; - ULONG32 ExitStatus; - ULONG64 CreateTime; - ULONG64 ExitTime; - ULONG64 KernelTime; - ULONG64 UserTime; - ULONG64 StartAddress; - ULONG64 Affinity; -} MINIDUMP_THREAD_INFO, *PMINIDUMP_THREAD_INFO; - -typedef struct _MINIDUMP_THREAD_INFO_LIST -{ - ULONG SizeOfHeader; - ULONG SizeOfEntry; - ULONG NumberOfEntries; -} MINIDUMP_THREAD_INFO_LIST, *PMINIDUMP_THREAD_INFO_LIST; - -// -// Support for token information. -// -typedef struct _MINIDUMP_TOKEN_INFO_HEADER -{ - ULONG TokenSize; // The size of the token structure. - ULONG TokenId; // The PID in NtOpenProcessToken() call or TID in NtOpenThreadToken() call. - ULONG64 TokenHandle; // The handle value returned. -} MINIDUMP_TOKEN_INFO_HEADER, *PMINIDUMP_TOKEN_INFO_HEADER; - -typedef struct _MINIDUMP_TOKEN_INFO_LIST -{ - ULONG TokenListSize; - ULONG TokenListEntries; - ULONG ListHeaderSize; - ULONG ElementHeaderSize; -} MINIDUMP_TOKEN_INFO_LIST, *PMINIDUMP_TOKEN_INFO_LIST; - -// -// Support for arbitrary user-defined information. -// - -typedef struct _MINIDUMP_USER_RECORD -{ - ULONG32 Type; - MINIDUMP_LOCATION_DESCRIPTOR Memory; -} MINIDUMP_USER_RECORD, *PMINIDUMP_USER_RECORD; - - -typedef struct _MINIDUMP_USER_STREAM -{ - ULONG32 Type; - ULONG BufferSize; - PVOID Buffer; - -} MINIDUMP_USER_STREAM, *PMINIDUMP_USER_STREAM; - - -typedef struct _MINIDUMP_USER_STREAM_INFORMATION -{ - ULONG UserStreamCount; - PMINIDUMP_USER_STREAM UserStreamArray; -} MINIDUMP_USER_STREAM_INFORMATION, *PMINIDUMP_USER_STREAM_INFORMATION; - -// -// Callback support. -// - -typedef enum _MINIDUMP_CALLBACK_TYPE -{ - ModuleCallback, - ThreadCallback, - ThreadExCallback, - IncludeThreadCallback, - IncludeModuleCallback, - MemoryCallback, - CancelCallback, - WriteKernelMinidumpCallback, - KernelMinidumpStatusCallback, - RemoveMemoryCallback, - IncludeVmRegionCallback, - IoStartCallback, - IoWriteAllCallback, - IoFinishCallback, - ReadMemoryFailureCallback, - SecondaryFlagsCallback, -} MINIDUMP_CALLBACK_TYPE; - - -typedef struct _MINIDUMP_THREAD_CALLBACK -{ - ULONG ThreadId; - HANDLE ThreadHandle; - CONTEXT Context; - ULONG SizeOfContext; - ULONG64 StackBase; - ULONG64 StackEnd; -} MINIDUMP_THREAD_CALLBACK, *PMINIDUMP_THREAD_CALLBACK; - - -typedef struct _MINIDUMP_THREAD_EX_CALLBACK -{ - ULONG ThreadId; - HANDLE ThreadHandle; - CONTEXT Context; - ULONG SizeOfContext; - ULONG64 StackBase; - ULONG64 StackEnd; - ULONG64 BackingStoreBase; - ULONG64 BackingStoreEnd; -} MINIDUMP_THREAD_EX_CALLBACK, *PMINIDUMP_THREAD_EX_CALLBACK; - - -typedef struct _MINIDUMP_INCLUDE_THREAD_CALLBACK -{ - ULONG ThreadId; -} MINIDUMP_INCLUDE_THREAD_CALLBACK, *PMINIDUMP_INCLUDE_THREAD_CALLBACK; - - -typedef enum _THREAD_WRITE_FLAGS -{ - ThreadWriteThread = 0x0001, - ThreadWriteStack = 0x0002, - ThreadWriteContext = 0x0004, - ThreadWriteBackingStore = 0x0008, - ThreadWriteInstructionWindow = 0x0010, - ThreadWriteThreadData = 0x0020, - ThreadWriteThreadInfo = 0x0040, -} THREAD_WRITE_FLAGS; - -typedef struct _MINIDUMP_MODULE_CALLBACK -{ - PWCHAR FullPath; - ULONG64 BaseOfImage; - ULONG SizeOfImage; - ULONG CheckSum; - ULONG TimeDateStamp; - VS_FIXEDFILEINFO VersionInfo; - PVOID CvRecord; - ULONG SizeOfCvRecord; - PVOID MiscRecord; - ULONG SizeOfMiscRecord; -} MINIDUMP_MODULE_CALLBACK, *PMINIDUMP_MODULE_CALLBACK; - - -typedef struct _MINIDUMP_INCLUDE_MODULE_CALLBACK -{ - ULONG64 BaseOfImage; -} MINIDUMP_INCLUDE_MODULE_CALLBACK, *PMINIDUMP_INCLUDE_MODULE_CALLBACK; - - -typedef enum _MODULE_WRITE_FLAGS -{ - ModuleWriteModule = 0x0001, - ModuleWriteDataSeg = 0x0002, - ModuleWriteMiscRecord = 0x0004, - ModuleWriteCvRecord = 0x0008, - ModuleReferencedByMemory = 0x0010, - ModuleWriteTlsData = 0x0020, - ModuleWriteCodeSegs = 0x0040, -} MODULE_WRITE_FLAGS; - - -typedef struct _MINIDUMP_IO_CALLBACK -{ - HANDLE Handle; - ULONG64 Offset; - PVOID Buffer; - ULONG BufferBytes; -} MINIDUMP_IO_CALLBACK, *PMINIDUMP_IO_CALLBACK; - - -typedef struct _MINIDUMP_READ_MEMORY_FAILURE_CALLBACK -{ - ULONG64 Offset; - ULONG Bytes; - HRESULT FailureStatus; -} MINIDUMP_READ_MEMORY_FAILURE_CALLBACK, -*PMINIDUMP_READ_MEMORY_FAILURE_CALLBACK; - - -typedef struct _MINIDUMP_CALLBACK_INPUT -{ - ULONG ProcessId; - HANDLE ProcessHandle; - ULONG CallbackType; - union - { - HRESULT Status; - MINIDUMP_THREAD_CALLBACK Thread; - MINIDUMP_THREAD_EX_CALLBACK ThreadEx; - MINIDUMP_MODULE_CALLBACK Module; - MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread; - MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule; - MINIDUMP_IO_CALLBACK Io; - MINIDUMP_READ_MEMORY_FAILURE_CALLBACK ReadMemoryFailure; - ULONG SecondaryFlags; - }; -} MINIDUMP_CALLBACK_INPUT, *PMINIDUMP_CALLBACK_INPUT; - -typedef struct _MINIDUMP_CALLBACK_OUTPUT -{ - union - { - ULONG ModuleWriteFlags; - ULONG ThreadWriteFlags; - ULONG SecondaryFlags; - struct - { - ULONG64 MemoryBase; - ULONG MemorySize; - }; - struct - { - BOOL CheckCancel; - BOOL Cancel; - }; - HANDLE Handle; - struct - { - MINIDUMP_MEMORY_INFO VmRegion; - BOOL Continue; - }; - HRESULT Status; - }; -} MINIDUMP_CALLBACK_OUTPUT, *PMINIDUMP_CALLBACK_OUTPUT; - - -// -// A normal minidump contains just the information -// necessary to capture stack traces for all of the -// existing threads in a process. -// -// A minidump with data segments includes all of the data -// sections from loaded modules in order to capture -// global variable contents. This can make the dump much -// larger if many modules have global data. -// -// A minidump with full memory includes all of the accessible -// memory in the process and can be very large. A minidump -// with full memory always has the raw memory data at the end -// of the dump so that the initial structures in the dump can -// be mapped directly without having to include the raw -// memory information. -// -// Stack and backing store memory can be filtered to remove -// data unnecessary for stack walking. This can improve -// compression of stacks and also deletes data that may -// be private and should not be stored in a dump. -// Memory can also be scanned to see what modules are -// referenced by stack and backing store memory to allow -// omission of other modules to reduce dump size. -// In either of these modes the ModuleReferencedByMemory flag -// is set for all modules referenced before the base -// module callbacks occur. -// -// On some operating systems a list of modules that were -// recently unloaded is kept in addition to the currently -// loaded module list. This information can be saved in -// the dump if desired. -// -// Stack and backing store memory can be scanned for referenced -// pages in order to pick up data referenced by locals or other -// stack memory. This can increase the size of a dump significantly. -// -// Module paths may contain undesired information such as user names -// or other important directory names so they can be stripped. This -// option reduces the ability to locate the proper image later -// and should only be used in certain situations. -// -// Complete operating system per-process and per-thread information can -// be gathered and stored in the dump. -// -// The virtual address space can be scanned for various types -// of memory to be included in the dump. -// -// Code which is concerned with potentially private information -// getting into the minidump can set a flag that automatically -// modifies all existing and future flags to avoid placing -// unnecessary data in the dump. Basic data, such as stack -// information, will still be included but optional data, such -// as indirect memory, will not. -// -// When doing a full memory dump it's possible to store all -// of the enumerated memory region descriptive information -// in a memory information stream. -// -// Additional thread information beyond the basic thread -// structure can be collected if desired. -// -// A minidump with code segments includes all of the code -// and code-related sections from loaded modules in order -// to capture executable content. -// -// MiniDumpWithoutAuxiliaryState turns off any secondary, -// auxiliary-supported memory gathering. -// -// MiniDumpWithFullAuxiliaryState asks any present auxiliary -// data providers to include all of their state in the dump. -// The exact set of what is provided depends on the auxiliary. -// This can be quite large. -// - -typedef enum _MINIDUMP_TYPE -{ - MiniDumpNormal = 0x00000000, - MiniDumpWithDataSegs = 0x00000001, - MiniDumpWithFullMemory = 0x00000002, - MiniDumpWithHandleData = 0x00000004, - MiniDumpFilterMemory = 0x00000008, - MiniDumpScanMemory = 0x00000010, - MiniDumpWithUnloadedModules = 0x00000020, - MiniDumpWithIndirectlyReferencedMemory = 0x00000040, - MiniDumpFilterModulePaths = 0x00000080, - MiniDumpWithProcessThreadData = 0x00000100, - MiniDumpWithPrivateReadWriteMemory = 0x00000200, - MiniDumpWithoutOptionalData = 0x00000400, - MiniDumpWithFullMemoryInfo = 0x00000800, - MiniDumpWithThreadInfo = 0x00001000, - MiniDumpWithCodeSegs = 0x00002000, - MiniDumpWithoutAuxiliaryState = 0x00004000, - MiniDumpWithFullAuxiliaryState = 0x00008000, - MiniDumpWithPrivateWriteCopyMemory = 0x00010000, - MiniDumpIgnoreInaccessibleMemory = 0x00020000, - MiniDumpWithTokenInformation = 0x00040000, - MiniDumpValidTypeFlags = 0x0007ffff, -} MINIDUMP_TYPE; - -// -// In addition to the primary flags provided to -// MiniDumpWriteDump there are additional, less -// frequently used options queried via the secondary -// flags callback. -// -// MiniSecondaryWithoutPowerInfo suppresses the minidump -// query that retrieves processor power information for -// MINIDUMP_MISC_INFO. -// - -typedef enum _MINIDUMP_SECONDARY_FLAGS -{ - MiniSecondaryWithoutPowerInfo = 0x00000001, - - MiniSecondaryValidFlags = 0x00000001, -} MINIDUMP_SECONDARY_FLAGS; - - -// -// The minidump callback should modify the FieldsToWrite parameter to reflect -// what portions of the specified thread or module should be written to the -// file. -// - -typedef -BOOL -(WINAPI* MINIDUMP_CALLBACK_ROUTINE)( - __inout PVOID CallbackParam, - __in PMINIDUMP_CALLBACK_INPUT CallbackInput, - __inout PMINIDUMP_CALLBACK_OUTPUT CallbackOutput -); - -typedef struct _MINIDUMP_CALLBACK_INFORMATION -{ - MINIDUMP_CALLBACK_ROUTINE CallbackRoutine; - PVOID CallbackParam; -} MINIDUMP_CALLBACK_INFORMATION, *PMINIDUMP_CALLBACK_INFORMATION; - - - -//++ -// -// PVOID -// RVA_TO_ADDR( -// PVOID Mapping, -// ULONG Rva -// ) -// -// Routine Description: -// -// Map an RVA that is contained within a mapped file to it's associated -// flat address. -// -// Arguments: -// -// Mapping - Base address of mapped file containing the RVA. -// -// Rva - An Rva to fixup. -// -// Return Values: -// -// A pointer to the desired data. -// -//-- - -#define RVA_TO_ADDR(Mapping,Rva) ((PVOID)(((ULONG_PTR) (Mapping)) + (Rva))) - -BOOL -WINAPI -MiniDumpWriteDump( - __in HANDLE hProcess, - __in DWORD ProcessId, - __in HANDLE hFile, - __in MINIDUMP_TYPE DumpType, - __in_opt PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, - __in_opt PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, - __in_opt PMINIDUMP_CALLBACK_INFORMATION CallbackParam -); - -BOOL -WINAPI -MiniDumpReadDumpStream( - __in PVOID BaseOfDump, - __in ULONG StreamNumber, - __deref_out_opt PMINIDUMP_DIRECTORY* Dir, - __deref_out_opt PVOID* StreamPointer, - __out_opt ULONG* StreamSize -); - -#pragma pack(pop) - -#ifdef __cplusplus -} -#endif - - -#endif // _DBGHELP_ - +#ifndef _DBGHELP_ +#define _DBGHELP_ + + +// As a general principal always call the 64 bit version +// of every API, if a choice exists. The 64 bit version +// works great on 32 bit platforms, and is forward +// compatible to 64 bit platforms. + +#ifdef _WIN64 +#ifndef _IMAGEHLP64 +#define _IMAGEHLP64 +#endif +#endif + +#pragma pack(push,8) + +// For those without specstrings.h +// Since there are different versions of this header, I need to +// individually test each item and define it if it is not around. + +#ifndef __in +#define __in +#endif +#ifndef __out +#define __out +#endif +#ifndef __inout +#define __inout +#endif +#ifndef __in_opt +#define __in_opt +#endif +#ifndef __out_opt +#define __out_opt +#endif +#ifndef __inout_opt +#define __inout_opt +#endif +#ifndef __in_ecount +#define __in_ecount(x) +#endif +#ifndef __out_ecount +#define __out_ecount(x) +#endif +#ifndef __inout_ecount +#define __inout_ecount(x) +#endif +#ifndef __in_bcount +#define __in_bcount(x) +#endif +#ifndef __out_bcount +#define __out_bcount(x) +#endif +#ifndef __inout_bcount +#define __inout_bcount(x) +#endif +#ifndef __out_xcount +#define __out_xcount(x) +#endif +#ifndef __deref_opt_out +#define __deref_opt_out +#endif +#ifndef __deref_out +#define __deref_out +#endif +#ifndef __out_ecount_opt +#define __out_ecount_opt(x) +#endif +#ifndef __in_bcount_opt +#define __in_bcount_opt(x) +#endif +#ifndef __out_bcount_opt +#define __out_bcount_opt(x) +#endif +#ifndef __deref_out_opt +#define __deref_out_opt +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _IMAGEHLP_SOURCE_ +#define IMAGEAPI __stdcall +#define DBHLP_DEPRECIATED +#else +#define IMAGEAPI DECLSPEC_IMPORT __stdcall +#if (_MSC_VER >= 1300) && !defined(MIDL_PASS) +#define DBHLP_DEPRECIATED __declspec(deprecated) +#else +#define DBHLP_DEPRECIATED +#endif +#endif + +#define DBHLPAPI IMAGEAPI + +#define IMAGE_SEPARATION (64*1024) + +// Observant readers may notice that 2 new fields, +// 'fReadOnly' and 'Version' have been added to +// the LOADED_IMAGE structure after 'fDOSImage'. +// This does not change the size of the structure +// from previous headers. That is because while +// 'fDOSImage' is a byte, it is padded by the +// compiler to 4 bytes. So the 2 new fields are +// slipped into the extra space. + +typedef struct _LOADED_IMAGE +{ + PSTR ModuleName; + HANDLE hFile; + PUCHAR MappedAddress; +#ifdef _IMAGEHLP64 + PIMAGE_NT_HEADERS64 FileHeader; +#else + PIMAGE_NT_HEADERS32 FileHeader; +#endif + PIMAGE_SECTION_HEADER LastRvaSection; + ULONG NumberOfSections; + PIMAGE_SECTION_HEADER Sections; + ULONG Characteristics; + BOOLEAN fSystemImage; + BOOLEAN fDOSImage; + BOOLEAN fReadOnly; + UCHAR Version; + LIST_ENTRY Links; + ULONG SizeOfImage; +} LOADED_IMAGE, *PLOADED_IMAGE; + +#define MAX_SYM_NAME 2000 + + +// Error codes set by dbghelp functions. Call GetLastError +// to see them. +// Dbghelp also sets error codes found in winerror.h + +#define ERROR_IMAGE_NOT_STRIPPED 0x8800 // the image is not stripped. No dbg file available. +#define ERROR_NO_DBG_POINTER 0x8801 // image is stripped but there is no pointer to a dbg file +#define ERROR_NO_PDB_POINTER 0x8802 // image does not point to a pdb file + +typedef BOOL +(CALLBACK* PFIND_DEBUG_FILE_CALLBACK)( + __in HANDLE FileHandle, + __in PCSTR FileName, + __in PVOID CallerData +); + +HANDLE +IMAGEAPI +SymFindDebugInfoFile( + __in HANDLE hProcess, + __in PCSTR FileName, + __out_ecount(MAX_PATH + 1) PSTR DebugFilePath, + __in_opt PFIND_DEBUG_FILE_CALLBACK Callback, + __in_opt PVOID CallerData +); + +typedef BOOL +(CALLBACK* PFIND_DEBUG_FILE_CALLBACKW)( + __in HANDLE FileHandle, + __in PCWSTR FileName, + __in PVOID CallerData +); + +HANDLE +IMAGEAPI +SymFindDebugInfoFileW( + __in HANDLE hProcess, + __in PCWSTR FileName, + __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath, + __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback, + __in_opt PVOID CallerData +); + +HANDLE +IMAGEAPI +FindDebugInfoFile( + __in PCSTR FileName, + __in PCSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PSTR DebugFilePath +); + +HANDLE +IMAGEAPI +FindDebugInfoFileEx( + __in PCSTR FileName, + __in PCSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PSTR DebugFilePath, + __in_opt PFIND_DEBUG_FILE_CALLBACK Callback, + __in_opt PVOID CallerData +); + +HANDLE +IMAGEAPI +FindDebugInfoFileExW( + __in PCWSTR FileName, + __in PCWSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath, + __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback, + __in_opt PVOID CallerData +); + +typedef BOOL +(CALLBACK* PFINDFILEINPATHCALLBACK)( + __in PCSTR filename, + __in PVOID context +); + +BOOL +IMAGEAPI +SymFindFileInPath( + __in HANDLE hprocess, + __in_opt PCSTR SearchPath, + __in PCSTR FileName, + __in_opt PVOID id, + __in DWORD two, + __in DWORD three, + __in DWORD flags, + __out_ecount(MAX_PATH + 1) PSTR FoundFile, + __in_opt PFINDFILEINPATHCALLBACK callback, + __in_opt PVOID context +); + +typedef BOOL +(CALLBACK* PFINDFILEINPATHCALLBACKW)( + __in PCWSTR filename, + __in PVOID context +); + +BOOL +IMAGEAPI +SymFindFileInPathW( + __in HANDLE hprocess, + __in_opt PCWSTR SearchPath, + __in PCWSTR FileName, + __in_opt PVOID id, + __in DWORD two, + __in DWORD three, + __in DWORD flags, + __out_ecount(MAX_PATH + 1) PWSTR FoundFile, + __in_opt PFINDFILEINPATHCALLBACKW callback, + __in_opt PVOID context +); + +typedef BOOL +(CALLBACK* PFIND_EXE_FILE_CALLBACK)( + __in HANDLE FileHandle, + __in PCSTR FileName, + __in_opt PVOID CallerData +); + +HANDLE +IMAGEAPI +SymFindExecutableImage( + __in HANDLE hProcess, + __in PCSTR FileName, + __out_ecount(MAX_PATH + 1) PSTR ImageFilePath, + __in PFIND_EXE_FILE_CALLBACK Callback, + __in PVOID CallerData +); + +typedef BOOL +(CALLBACK* PFIND_EXE_FILE_CALLBACKW)( + __in HANDLE FileHandle, + __in PCWSTR FileName, + __in_opt PVOID CallerData +); + +HANDLE +IMAGEAPI +SymFindExecutableImageW( + __in HANDLE hProcess, + __in PCWSTR FileName, + __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath, + __in PFIND_EXE_FILE_CALLBACKW Callback, + __in PVOID CallerData +); + +HANDLE +IMAGEAPI +FindExecutableImage( + __in PCSTR FileName, + __in PCSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PSTR ImageFilePath +); + +HANDLE +IMAGEAPI +FindExecutableImageEx( + __in PCSTR FileName, + __in PCSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PSTR ImageFilePath, + __in_opt PFIND_EXE_FILE_CALLBACK Callback, + __in_opt PVOID CallerData +); + +HANDLE +IMAGEAPI +FindExecutableImageExW( + __in PCWSTR FileName, + __in PCWSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath, + __in_opt PFIND_EXE_FILE_CALLBACKW Callback, + __in PVOID CallerData +); + +PIMAGE_NT_HEADERS +IMAGEAPI +ImageNtHeader( + __in PVOID Base +); + +PVOID +IMAGEAPI +ImageDirectoryEntryToDataEx( + __in PVOID Base, + __in BOOLEAN MappedAsImage, + __in USHORT DirectoryEntry, + __out PULONG Size, + __out_opt PIMAGE_SECTION_HEADER* FoundHeader +); + +PVOID +IMAGEAPI +ImageDirectoryEntryToData( + __in PVOID Base, + __in BOOLEAN MappedAsImage, + __in USHORT DirectoryEntry, + __out PULONG Size +); + +PIMAGE_SECTION_HEADER +IMAGEAPI +ImageRvaToSection( + __in PIMAGE_NT_HEADERS NtHeaders, + __in PVOID Base, + __in ULONG Rva +); + +PVOID +IMAGEAPI +ImageRvaToVa( + __in PIMAGE_NT_HEADERS NtHeaders, + __in PVOID Base, + __in ULONG Rva, + __in_opt OUT PIMAGE_SECTION_HEADER* LastRvaSection +); + +#ifndef _WIN64 +// This api won't be ported to Win64 - Fix your code. + +typedef struct _IMAGE_DEBUG_INFORMATION +{ + LIST_ENTRY List; + DWORD ReservedSize; + PVOID ReservedMappedBase; + USHORT ReservedMachine; + USHORT ReservedCharacteristics; + DWORD ReservedCheckSum; + DWORD ImageBase; + DWORD SizeOfImage; + + DWORD ReservedNumberOfSections; + PIMAGE_SECTION_HEADER ReservedSections; + + DWORD ReservedExportedNamesSize; + PSTR ReservedExportedNames; + + DWORD ReservedNumberOfFunctionTableEntries; + PIMAGE_FUNCTION_ENTRY ReservedFunctionTableEntries; + DWORD ReservedLowestFunctionStartingAddress; + DWORD ReservedHighestFunctionEndingAddress; + + DWORD ReservedNumberOfFpoTableEntries; + PFPO_DATA ReservedFpoTableEntries; + + DWORD SizeOfCoffSymbols; + PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols; + + DWORD ReservedSizeOfCodeViewSymbols; + PVOID ReservedCodeViewSymbols; + + PSTR ImageFilePath; + PSTR ImageFileName; + PSTR ReservedDebugFilePath; + + DWORD ReservedTimeDateStamp; + + BOOL ReservedRomImage; + PIMAGE_DEBUG_DIRECTORY ReservedDebugDirectory; + DWORD ReservedNumberOfDebugDirectories; + + DWORD ReservedOriginalFunctionTableBaseAddress; + + DWORD Reserved[ 2 ]; + +} IMAGE_DEBUG_INFORMATION, *PIMAGE_DEBUG_INFORMATION; + + +PIMAGE_DEBUG_INFORMATION +IMAGEAPI +MapDebugInformation( + __in_opt HANDLE FileHandle, + __in PCSTR FileName, + __in_opt PCSTR SymbolPath, + __in ULONG ImageBase +); + +BOOL +IMAGEAPI +UnmapDebugInformation( + __out_xcount(unknown) PIMAGE_DEBUG_INFORMATION DebugInfo +); + +#endif + +BOOL +IMAGEAPI +SearchTreeForFile( + __in PCSTR RootPath, + __in PCSTR InputPathName, + __out_ecount(MAX_PATH + 1) PSTR OutputPathBuffer +); + +BOOL +IMAGEAPI +SearchTreeForFileW( + __in PCWSTR RootPath, + __in PCWSTR InputPathName, + __out_ecount(MAX_PATH + 1) PWSTR OutputPathBuffer +); + +typedef BOOL +(CALLBACK* PENUMDIRTREE_CALLBACK)( + __in PCSTR FilePath, + __in_opt PVOID CallerData +); + +BOOL +IMAGEAPI +EnumDirTree( + __in_opt HANDLE hProcess, + __in PCSTR RootPath, + __in PCSTR InputPathName, + __out_ecount_opt(MAX_PATH + 1) PSTR OutputPathBuffer, + __in_opt PENUMDIRTREE_CALLBACK cb, + __in_opt PVOID data +); + +typedef BOOL +(CALLBACK* PENUMDIRTREE_CALLBACKW)( + __in PCWSTR FilePath, + __in_opt PVOID CallerData +); + +BOOL +IMAGEAPI +EnumDirTreeW( + __in_opt HANDLE hProcess, + __in PCWSTR RootPath, + __in PCWSTR InputPathName, + __out_ecount_opt(MAX_PATH + 1) PWSTR OutputPathBuffer, + __in_opt PENUMDIRTREE_CALLBACKW cb, + __in_opt PVOID data +); + +BOOL +IMAGEAPI +MakeSureDirectoryPathExists( + __in PCSTR DirPath +); + +// +// UnDecorateSymbolName Flags +// + +#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration +#define UNDNAME_NO_LEADING_UNDERSCORES (0x0001) // Remove leading underscores from MS extended keywords +#define UNDNAME_NO_MS_KEYWORDS (0x0002) // Disable expansion of MS extended keywords +#define UNDNAME_NO_FUNCTION_RETURNS (0x0004) // Disable expansion of return type for primary declaration +#define UNDNAME_NO_ALLOCATION_MODEL (0x0008) // Disable expansion of the declaration model +#define UNDNAME_NO_ALLOCATION_LANGUAGE (0x0010) // Disable expansion of the declaration language specifier +#define UNDNAME_NO_MS_THISTYPE (0x0020) // NYI Disable expansion of MS keywords on the 'this' type for primary declaration +#define UNDNAME_NO_CV_THISTYPE (0x0040) // NYI Disable expansion of CV modifiers on the 'this' type for primary declaration +#define UNDNAME_NO_THISTYPE (0x0060) // Disable all modifiers on the 'this' type +#define UNDNAME_NO_ACCESS_SPECIFIERS (0x0080) // Disable expansion of access specifiers for members +#define UNDNAME_NO_THROW_SIGNATURES (0x0100) // Disable expansion of 'throw-signatures' for functions and pointers to functions +#define UNDNAME_NO_MEMBER_TYPE (0x0200) // Disable expansion of 'static' or 'virtual'ness of members +#define UNDNAME_NO_RETURN_UDT_MODEL (0x0400) // Disable expansion of MS model for UDT returns +#define UNDNAME_32_BIT_DECODE (0x0800) // Undecorate 32-bit decorated names +#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration; +// return just [scope::]name. Does expand template params +#define UNDNAME_NO_ARGUMENTS (0x2000) // Don't undecorate arguments to function +#define UNDNAME_NO_SPECIAL_SYMS (0x4000) // Don't undecorate special names (v-table, vcall, vector xxx, metatype, etc) + +DWORD +IMAGEAPI +WINAPI +UnDecorateSymbolName( + __in PCSTR name, + __out_ecount(maxStringLength) PSTR outputString, + __in DWORD maxStringLength, + __in DWORD flags +); + +DWORD +IMAGEAPI +WINAPI +UnDecorateSymbolNameW( + __in PCWSTR name, + __out_ecount(maxStringLength) PWSTR outputString, + __in DWORD maxStringLength, + __in DWORD flags +); + +// +// these values are used for synthesized file types +// that can be passed in as image headers instead of +// the standard ones from ntimage.h +// + +#define DBHHEADER_DEBUGDIRS 0x1 +#define DBHHEADER_CVMISC 0x2 +#define DBHHEADER_PDBGUID 0x3 +typedef struct _MODLOAD_DATA +{ + DWORD ssize; // size of this struct + DWORD ssig; // signature identifying the passed data + PVOID data; // pointer to passed data + DWORD size; // size of passed data + DWORD flags; // options +} MODLOAD_DATA, *PMODLOAD_DATA; + +typedef struct _MODLOAD_CVMISC +{ + DWORD oCV; // ofset to the codeview record + size_t cCV; // size of the codeview record + DWORD oMisc; // offset to the misc record + size_t cMisc; // size of the misc record + DWORD dtImage; // datetime stamp of the image + DWORD cImage; // size of the image +} MODLOAD_CVMISC, *PMODLOAD_CVMISC; + +typedef struct _MODLOAD_PDBGUID_PDBAGE +{ + GUID PdbGuid; // Pdb Guid + DWORD PdbAge; // Pdb Age +} MODLOAD_PDBGUID_PDBAGE, *PMODLOAD_PDBGUID_PDBAGE; + +// +// StackWalking API +// + +typedef enum +{ + AddrMode1616, + AddrMode1632, + AddrModeReal, + AddrModeFlat +} ADDRESS_MODE; + +typedef struct _tagADDRESS64 +{ + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; +} ADDRESS64, *LPADDRESS64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define ADDRESS ADDRESS64 +#define LPADDRESS LPADDRESS64 +#else +typedef struct _tagADDRESS +{ + DWORD Offset; + WORD Segment; + ADDRESS_MODE Mode; +} ADDRESS, *LPADDRESS; + +__inline +void +Address32To64( + __in LPADDRESS a32, + __out LPADDRESS64 a64 +) +{ + a64->Offset = (ULONG64)(LONG64)(LONG)a32->Offset; + a64->Segment = a32->Segment; + a64->Mode = a32->Mode; +} + +__inline +void +Address64To32( + __in LPADDRESS64 a64, + __out LPADDRESS a32 +) +{ + a32->Offset = (ULONG)a64->Offset; + a32->Segment = a64->Segment; + a32->Mode = a64->Mode; +} +#endif + +// +// This structure is included in the STACKFRAME structure, +// and is used to trace through usermode callbacks in a thread's +// kernel stack. The values must be copied by the kernel debugger +// from the DBGKD_GET_VERSION and WAIT_STATE_CHANGE packets. +// + +// +// New KDHELP structure for 64 bit system support. +// This structure is preferred in new code. +// +typedef struct _KDHELP64 +{ + + // + // address of kernel thread object, as provided in the + // WAIT_STATE_CHANGE packet. + // + DWORD64 Thread; + + // + // offset in thread object to pointer to the current callback frame + // in kernel stack. + // + DWORD ThCallbackStack; + + // + // offset in thread object to pointer to the current callback backing + // store frame in kernel stack. + // + DWORD ThCallbackBStore; + + // + // offsets to values in frame: + // + // address of next callback frame + DWORD NextCallback; + + // address of saved frame pointer (if applicable) + DWORD FramePointer; + + + // + // Address of the kernel function that calls out to user mode + // + DWORD64 KiCallUserMode; + + // + // Address of the user mode dispatcher function + // + DWORD64 KeUserCallbackDispatcher; + + // + // Lowest kernel mode address + // + DWORD64 SystemRangeStart; + + // + // Address of the user mode exception dispatcher function. + // Added in API version 10. + // + DWORD64 KiUserExceptionDispatcher; + + // + // Stack bounds, added in API version 11. + // + DWORD64 StackBase; + DWORD64 StackLimit; + + DWORD64 Reserved[5]; + +} KDHELP64, *PKDHELP64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define KDHELP KDHELP64 +#define PKDHELP PKDHELP64 +#else +typedef struct _KDHELP +{ + + // + // address of kernel thread object, as provided in the + // WAIT_STATE_CHANGE packet. + // + DWORD Thread; + + // + // offset in thread object to pointer to the current callback frame + // in kernel stack. + // + DWORD ThCallbackStack; + + // + // offsets to values in frame: + // + // address of next callback frame + DWORD NextCallback; + + // address of saved frame pointer (if applicable) + DWORD FramePointer; + + // + // Address of the kernel function that calls out to user mode + // + DWORD KiCallUserMode; + + // + // Address of the user mode dispatcher function + // + DWORD KeUserCallbackDispatcher; + + // + // Lowest kernel mode address + // + DWORD SystemRangeStart; + + // + // offset in thread object to pointer to the current callback backing + // store frame in kernel stack. + // + DWORD ThCallbackBStore; + + // + // Address of the user mode exception dispatcher function. + // Added in API version 10. + // + DWORD KiUserExceptionDispatcher; + + // + // Stack bounds, added in API version 11. + // + DWORD StackBase; + DWORD StackLimit; + + DWORD Reserved[5]; + +} KDHELP, *PKDHELP; + +__inline +void +KdHelp32To64( + __in PKDHELP p32, + __out PKDHELP64 p64 +) +{ + p64->Thread = p32->Thread; + p64->ThCallbackStack = p32->ThCallbackStack; + p64->NextCallback = p32->NextCallback; + p64->FramePointer = p32->FramePointer; + p64->KiCallUserMode = p32->KiCallUserMode; + p64->KeUserCallbackDispatcher = p32->KeUserCallbackDispatcher; + p64->SystemRangeStart = p32->SystemRangeStart; + p64->KiUserExceptionDispatcher = p32->KiUserExceptionDispatcher; + p64->StackBase = p32->StackBase; + p64->StackLimit = p32->StackLimit; +} +#endif + +typedef struct _tagSTACKFRAME64 +{ + ADDRESS64 AddrPC; // program counter + ADDRESS64 AddrReturn; // return address + ADDRESS64 AddrFrame; // frame pointer + ADDRESS64 AddrStack; // stack pointer + ADDRESS64 AddrBStore; // backing store pointer + PVOID FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD64 Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD64 Reserved[3]; + KDHELP64 KdHelp; +} STACKFRAME64, *LPSTACKFRAME64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define STACKFRAME STACKFRAME64 +#define LPSTACKFRAME LPSTACKFRAME64 +#else +typedef struct _tagSTACKFRAME +{ + ADDRESS AddrPC; // program counter + ADDRESS AddrReturn; // return address + ADDRESS AddrFrame; // frame pointer + ADDRESS AddrStack; // stack pointer + PVOID FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD Reserved[3]; + KDHELP KdHelp; + ADDRESS AddrBStore; // backing store pointer +} STACKFRAME, *LPSTACKFRAME; +#endif + + +typedef +BOOL +(__stdcall* PREAD_PROCESS_MEMORY_ROUTINE64)( + __in HANDLE hProcess, + __in DWORD64 qwBaseAddress, + __out_bcount(nSize) PVOID lpBuffer, + __in DWORD nSize, + __out LPDWORD lpNumberOfBytesRead +); + +typedef +PVOID +(__stdcall* PFUNCTION_TABLE_ACCESS_ROUTINE64)( + __in HANDLE ahProcess, + __in DWORD64 AddrBase +); + +typedef +DWORD64 +(__stdcall* PGET_MODULE_BASE_ROUTINE64)( + __in HANDLE hProcess, + __in DWORD64 Address +); + +typedef +DWORD64 +(__stdcall* PTRANSLATE_ADDRESS_ROUTINE64)( + __in HANDLE hProcess, + __in HANDLE hThread, + __in LPADDRESS64 lpaddr +); + +BOOL +IMAGEAPI +StackWalk64( + __in DWORD MachineType, + __in HANDLE hProcess, + __in HANDLE hThread, + __inout LPSTACKFRAME64 StackFrame, + __inout PVOID ContextRecord, + __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) + +#define PREAD_PROCESS_MEMORY_ROUTINE PREAD_PROCESS_MEMORY_ROUTINE64 +#define PFUNCTION_TABLE_ACCESS_ROUTINE PFUNCTION_TABLE_ACCESS_ROUTINE64 +#define PGET_MODULE_BASE_ROUTINE PGET_MODULE_BASE_ROUTINE64 +#define PTRANSLATE_ADDRESS_ROUTINE PTRANSLATE_ADDRESS_ROUTINE64 + +#define StackWalk StackWalk64 + +#else + +typedef +BOOL +(__stdcall* PREAD_PROCESS_MEMORY_ROUTINE)( + __in HANDLE hProcess, + __in DWORD lpBaseAddress, + __out_bcount(nSize) PVOID lpBuffer, + __in DWORD nSize, + __out PDWORD lpNumberOfBytesRead +); + +typedef +PVOID +(__stdcall* PFUNCTION_TABLE_ACCESS_ROUTINE)( + __in HANDLE hProcess, + __in DWORD AddrBase +); + +typedef +DWORD +(__stdcall* PGET_MODULE_BASE_ROUTINE)( + __in HANDLE hProcess, + __in DWORD Address +); + +typedef +DWORD +(__stdcall* PTRANSLATE_ADDRESS_ROUTINE)( + __in HANDLE hProcess, + __in HANDLE hThread, + __out LPADDRESS lpaddr +); + +BOOL +IMAGEAPI +StackWalk( + DWORD MachineType, + __in HANDLE hProcess, + __in HANDLE hThread, + __inout LPSTACKFRAME StackFrame, + __inout PVOID ContextRecord, + __in_opt PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, + __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, + __in_opt PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, + __in_opt PTRANSLATE_ADDRESS_ROUTINE TranslateAddress +); + +#endif + + +#define API_VERSION_NUMBER 11 + +typedef struct API_VERSION +{ + USHORT MajorVersion; + USHORT MinorVersion; + USHORT Revision; + USHORT Reserved; +} API_VERSION, *LPAPI_VERSION; + +LPAPI_VERSION +IMAGEAPI +ImagehlpApiVersion( + VOID +); + +LPAPI_VERSION +IMAGEAPI +ImagehlpApiVersionEx( + __in LPAPI_VERSION AppVersion +); + +DWORD +IMAGEAPI +GetTimestampForLoadedLibrary( + __in HMODULE Module +); + +// +// typedefs for function pointers +// +typedef BOOL +(CALLBACK* PSYM_ENUMMODULES_CALLBACK64)( + __in PCSTR ModuleName, + __in DWORD64 BaseOfDll, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PSYM_ENUMMODULES_CALLBACKW64)( + __in PCWSTR ModuleName, + __in DWORD64 BaseOfDll, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PENUMLOADED_MODULES_CALLBACK64)( + __in PCSTR ModuleName, + __in DWORD64 ModuleBase, + __in ULONG ModuleSize, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PENUMLOADED_MODULES_CALLBACKW64)( + __in PCWSTR ModuleName, + __in DWORD64 ModuleBase, + __in ULONG ModuleSize, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PSYM_ENUMSYMBOLS_CALLBACK64)( + __in PCSTR SymbolName, + __in DWORD64 SymbolAddress, + __in ULONG SymbolSize, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PSYM_ENUMSYMBOLS_CALLBACK64W)( + __in PCWSTR SymbolName, + __in DWORD64 SymbolAddress, + __in ULONG SymbolSize, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PSYMBOL_REGISTERED_CALLBACK64)( + __in HANDLE hProcess, + __in ULONG ActionCode, + __in_opt ULONG64 CallbackData, + __in_opt ULONG64 UserContext +); + +typedef +PVOID +(CALLBACK* PSYMBOL_FUNCENTRY_CALLBACK)( + __in HANDLE hProcess, + __in DWORD AddrBase, + __in_opt PVOID UserContext +); + +typedef +PVOID +(CALLBACK* PSYMBOL_FUNCENTRY_CALLBACK64)( + __in HANDLE hProcess, + __in ULONG64 AddrBase, + __in ULONG64 UserContext +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) + +#define PSYM_ENUMMODULES_CALLBACK PSYM_ENUMMODULES_CALLBACK64 +#define PSYM_ENUMSYMBOLS_CALLBACK PSYM_ENUMSYMBOLS_CALLBACK64 +#define PSYM_ENUMSYMBOLS_CALLBACKW PSYM_ENUMSYMBOLS_CALLBACK64W +#define PENUMLOADED_MODULES_CALLBACK PENUMLOADED_MODULES_CALLBACK64 +#define PSYMBOL_REGISTERED_CALLBACK PSYMBOL_REGISTERED_CALLBACK64 +#define PSYMBOL_FUNCENTRY_CALLBACK PSYMBOL_FUNCENTRY_CALLBACK64 + +#else + +typedef BOOL +(CALLBACK* PSYM_ENUMMODULES_CALLBACK)( + __in PCSTR ModuleName, + __in ULONG BaseOfDll, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PSYM_ENUMSYMBOLS_CALLBACK)( + __in PCSTR SymbolName, + __in ULONG SymbolAddress, + __in ULONG SymbolSize, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PSYM_ENUMSYMBOLS_CALLBACKW)( + __in PCWSTR SymbolName, + __in ULONG SymbolAddress, + __in ULONG SymbolSize, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PENUMLOADED_MODULES_CALLBACK)( + __in PCSTR ModuleName, + __in ULONG ModuleBase, + __in ULONG ModuleSize, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PSYMBOL_REGISTERED_CALLBACK)( + __in HANDLE hProcess, + __in ULONG ActionCode, + __in_opt PVOID CallbackData, + __in_opt PVOID UserContext +); + +#endif + + +// values found in SYMBOL_INFO.Tag +// +// This was taken from cvconst.h and should +// not override any values found there. +// +// #define _NO_CVCONST_H_ if you don't +// have access to that file... + +#ifdef _NO_CVCONST_H + +// DIA enums + +enum SymTagEnum +{ + SymTagNull, + SymTagExe, + SymTagCompiland, + SymTagCompilandDetails, + SymTagCompilandEnv, + SymTagFunction, + SymTagBlock, + SymTagData, + SymTagAnnotation, + SymTagLabel, + SymTagPublicSymbol, + SymTagUDT, + SymTagEnum, + SymTagFunctionType, + SymTagPointerType, + SymTagArrayType, + SymTagBaseType, + SymTagTypedef, + SymTagBaseClass, + SymTagFriend, + SymTagFunctionArgType, + SymTagFuncDebugStart, + SymTagFuncDebugEnd, + SymTagUsingNamespace, + SymTagVTableShape, + SymTagVTable, + SymTagCustom, + SymTagThunk, + SymTagCustomType, + SymTagManagedType, + SymTagDimension, + SymTagMax +}; + +#endif + +// +// flags found in SYMBOL_INFO.Flags +// + +#define SYMFLAG_VALUEPRESENT 0x00000001 +#define SYMFLAG_REGISTER 0x00000008 +#define SYMFLAG_REGREL 0x00000010 +#define SYMFLAG_FRAMEREL 0x00000020 +#define SYMFLAG_PARAMETER 0x00000040 +#define SYMFLAG_LOCAL 0x00000080 +#define SYMFLAG_CONSTANT 0x00000100 +#define SYMFLAG_EXPORT 0x00000200 +#define SYMFLAG_FORWARDER 0x00000400 +#define SYMFLAG_FUNCTION 0x00000800 +#define SYMFLAG_VIRTUAL 0x00001000 +#define SYMFLAG_THUNK 0x00002000 +#define SYMFLAG_TLSREL 0x00004000 +#define SYMFLAG_SLOT 0x00008000 +#define SYMFLAG_ILREL 0x00010000 +#define SYMFLAG_METADATA 0x00020000 +#define SYMFLAG_CLR_TOKEN 0x00040000 + +// this resets SymNext/Prev to the beginning +// of the module passed in the address field + +#define SYMFLAG_RESET 0x80000000 + +// +// symbol type enumeration +// +typedef enum +{ + SymNone = 0, + SymCoff, + SymCv, + SymPdb, + SymExport, + SymDeferred, + SymSym, // .sym file + SymDia, + SymVirtual, + NumSymTypes +} SYM_TYPE; + +// +// symbol data structure +// + +typedef struct _IMAGEHLP_SYMBOL64 +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64) + DWORD64 Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + CHAR Name[1]; // symbol name (null terminated string) +} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; + +typedef struct _IMAGEHLP_SYMBOL64_PACKAGE +{ + IMAGEHLP_SYMBOL64 sym; + CHAR name[MAX_SYM_NAME + 1]; +} IMAGEHLP_SYMBOL64_PACKAGE, *PIMAGEHLP_SYMBOL64_PACKAGE; + +typedef struct _IMAGEHLP_SYMBOLW64 +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOLW64) + DWORD64 Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + WCHAR Name[1]; // symbol name (null terminated string) +} IMAGEHLP_SYMBOLW64, *PIMAGEHLP_SYMBOLW64; + +typedef struct _IMAGEHLP_SYMBOLW64_PACKAGE +{ + IMAGEHLP_SYMBOLW64 sym; + WCHAR name[MAX_SYM_NAME + 1]; +} IMAGEHLP_SYMBOLW64_PACKAGE, *PIMAGEHLP_SYMBOLW64_PACKAGE; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) + +#define IMAGEHLP_SYMBOL IMAGEHLP_SYMBOL64 +#define PIMAGEHLP_SYMBOL PIMAGEHLP_SYMBOL64 +#define IMAGEHLP_SYMBOL_PACKAGE IMAGEHLP_SYMBOL64_PACKAGE +#define PIMAGEHLP_SYMBOL_PACKAGE PIMAGEHLP_SYMBOL64_PACKAGE +#define IMAGEHLP_SYMBOLW IMAGEHLP_SYMBOLW64 +#define PIMAGEHLP_SYMBOLW PIMAGEHLP_SYMBOLW64 +#define IMAGEHLP_SYMBOLW_PACKAGE IMAGEHLP_SYMBOLW64_PACKAGE +#define PIMAGEHLP_SYMBOLW_PACKAGE PIMAGEHLP_SYMBOLW64_PACKAGE + +#else + +typedef struct _IMAGEHLP_SYMBOL +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL) + DWORD Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + CHAR Name[1]; // symbol name (null terminated string) +} IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL; + +typedef struct _IMAGEHLP_SYMBOL_PACKAGE +{ + IMAGEHLP_SYMBOL sym; + CHAR name[MAX_SYM_NAME + 1]; +} IMAGEHLP_SYMBOL_PACKAGE, *PIMAGEHLP_SYMBOL_PACKAGE; + +typedef struct _IMAGEHLP_SYMBOLW +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOLW) + DWORD Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + WCHAR Name[1]; // symbol name (null terminated string) +} IMAGEHLP_SYMBOLW, *PIMAGEHLP_SYMBOLW; + +typedef struct _IMAGEHLP_SYMBOLW_PACKAGE +{ + IMAGEHLP_SYMBOLW sym; + WCHAR name[MAX_SYM_NAME + 1]; +} IMAGEHLP_SYMBOLW_PACKAGE, *PIMAGEHLP_SYMBOLW_PACKAGE; + +#endif + +// +// module data structure +// + +typedef struct _IMAGEHLP_MODULE64 +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name + // new elements: 07-Jun-2002 + CHAR LoadedPdbName[256]; // pdb file name + DWORD CVSig; // Signature of the CV record in the debug directories + CHAR CVData[MAX_PATH * 3]; // Contents of the CV record + DWORD PdbSig; // Signature of PDB + GUID PdbSig70; // Signature of PDB (VC 7 and up) + DWORD PdbAge; // DBI age of pdb + BOOL PdbUnmatched; // loaded an unmatched pdb + BOOL DbgUnmatched; // loaded an unmatched dbg + BOOL LineNumbers; // we have line number information + BOOL GlobalSymbols; // we have internal symbol information + BOOL TypeInfo; // we have type information + // new elements: 17-Dec-2003 + BOOL SourceIndexed; // pdb supports source server + BOOL Publics; // contains public symbols +} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; + +typedef struct _IMAGEHLP_MODULEW64 +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + WCHAR ModuleName[32]; // module name + WCHAR ImageName[256]; // image name + // new elements: 07-Jun-2002 + WCHAR LoadedImageName[256]; // symbol file name + WCHAR LoadedPdbName[256]; // pdb file name + DWORD CVSig; // Signature of the CV record in the debug directories + WCHAR CVData[MAX_PATH * 3]; // Contents of the CV record + DWORD PdbSig; // Signature of PDB + GUID PdbSig70; // Signature of PDB (VC 7 and up) + DWORD PdbAge; // DBI age of pdb + BOOL PdbUnmatched; // loaded an unmatched pdb + BOOL DbgUnmatched; // loaded an unmatched dbg + BOOL LineNumbers; // we have line number information + BOOL GlobalSymbols; // we have internal symbol information + BOOL TypeInfo; // we have type information + // new elements: 17-Dec-2003 + BOOL SourceIndexed; // pdb supports source server + BOOL Publics; // contains public symbols +} IMAGEHLP_MODULEW64, *PIMAGEHLP_MODULEW64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_MODULE IMAGEHLP_MODULE64 +#define PIMAGEHLP_MODULE PIMAGEHLP_MODULE64 +#define IMAGEHLP_MODULEW IMAGEHLP_MODULEW64 +#define PIMAGEHLP_MODULEW PIMAGEHLP_MODULEW64 +#else +typedef struct _IMAGEHLP_MODULE +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE) + DWORD BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name +} IMAGEHLP_MODULE, *PIMAGEHLP_MODULE; + +typedef struct _IMAGEHLP_MODULEW +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE) + DWORD BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + WCHAR ModuleName[32]; // module name + WCHAR ImageName[256]; // image name + WCHAR LoadedImageName[256]; // symbol file name +} IMAGEHLP_MODULEW, *PIMAGEHLP_MODULEW; +#endif + +// +// source file line data structure +// + +typedef struct _IMAGEHLP_LINE64 +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; + +typedef struct _IMAGEHLP_LINEW64 +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PWSTR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINEW64, *PIMAGEHLP_LINEW64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_LINE IMAGEHLP_LINE64 +#define PIMAGEHLP_LINE PIMAGEHLP_LINE64 +#else +typedef struct _IMAGEHLP_LINE +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD Address; // first instruction of line +} IMAGEHLP_LINE, *PIMAGEHLP_LINE; + +typedef struct _IMAGEHLP_LINEW +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINEW, *PIMAGEHLP_LINEW; +#endif + +// +// source file structure +// + +typedef struct _SOURCEFILE +{ + DWORD64 ModBase; // base address of loaded module + PCHAR FileName; // full filename of source +} SOURCEFILE, *PSOURCEFILE; + +typedef struct _SOURCEFILEW +{ + DWORD64 ModBase; // base address of loaded module + PWSTR FileName; // full filename of source +} SOURCEFILEW, *PSOURCEFILEW; + +// +// data structures used for registered symbol callbacks +// + +#define CBA_DEFERRED_SYMBOL_LOAD_START 0x00000001 +#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE 0x00000002 +#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE 0x00000003 +#define CBA_SYMBOLS_UNLOADED 0x00000004 +#define CBA_DUPLICATE_SYMBOL 0x00000005 +#define CBA_READ_MEMORY 0x00000006 +#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL 0x00000007 +#define CBA_SET_OPTIONS 0x00000008 +#define CBA_EVENT 0x00000010 +#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL 0x00000020 +#define CBA_DEBUG_INFO 0x10000000 +#define CBA_SRCSRV_INFO 0x20000000 +#define CBA_SRCSRV_EVENT 0x40000000 + +typedef struct _IMAGEHLP_CBA_READ_MEMORY +{ + DWORD64 addr; // address to read from + PVOID buf; // buffer to read to + DWORD bytes; // amount of bytes to read + DWORD* bytesread; // pointer to store amount of bytes read +} IMAGEHLP_CBA_READ_MEMORY, *PIMAGEHLP_CBA_READ_MEMORY; + +enum +{ + sevInfo = 0, + sevProblem, + sevAttn, + sevFatal, + sevMax // unused +}; + +#define EVENT_SRCSPEW_START 100 +#define EVENT_SRCSPEW 100 +#define EVENT_SRCSPEW_END 199 + +typedef struct _IMAGEHLP_CBA_EVENT +{ + DWORD severity; // values from sevInfo to sevFatal + DWORD code; // numerical code IDs the error + PCHAR desc; // may contain a text description of the error + PVOID object; // value dependant upon the error code +} IMAGEHLP_CBA_EVENT, *PIMAGEHLP_CBA_EVENT; + +typedef struct _IMAGEHLP_CBA_EVENTW +{ + DWORD severity; // values from sevInfo to sevFatal + DWORD code; // numerical code IDs the error + PCWSTR desc; // may contain a text description of the error + PVOID object; // value dependant upon the error code +} IMAGEHLP_CBA_EVENTW, *PIMAGEHLP_CBA_EVENTW; + +typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64) + DWORD64 BaseOfImage; // base load address of module + DWORD CheckSum; // checksum from the pe header + DWORD TimeDateStamp; // date/time stamp from pe header + CHAR FileName[MAX_PATH]; // symbols file or image name + BOOLEAN Reparse; // load failure reparse + HANDLE hFile; // file handle, if passed + DWORD Flags; // +} IMAGEHLP_DEFERRED_SYMBOL_LOAD64, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD64; + +typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOADW64 +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOADW64) + DWORD64 BaseOfImage; // base load address of module + DWORD CheckSum; // checksum from the pe header + DWORD TimeDateStamp; // date/time stamp from pe header + WCHAR FileName[MAX_PATH + 1]; // symbols file or image name + BOOLEAN Reparse; // load failure reparse + HANDLE hFile; // file handle, if passed + DWORD Flags; // +} IMAGEHLP_DEFERRED_SYMBOL_LOADW64, *PIMAGEHLP_DEFERRED_SYMBOL_LOADW64; + +#define DSLFLAG_MISMATCHED_PDB 0x1 +#define DSLFLAG_MISMATCHED_DBG 0x2 + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_DEFERRED_SYMBOL_LOAD IMAGEHLP_DEFERRED_SYMBOL_LOAD64 +#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 +#else +typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD) + DWORD BaseOfImage; // base load address of module + DWORD CheckSum; // checksum from the pe header + DWORD TimeDateStamp; // date/time stamp from pe header + CHAR FileName[MAX_PATH]; // symbols file or image name + BOOLEAN Reparse; // load failure reparse + HANDLE hFile; // file handle, if passed +} IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD; +#endif + +typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL64) + DWORD NumberOfDups; // number of duplicates in the Symbol array + PIMAGEHLP_SYMBOL64 Symbol; // array of duplicate symbols + DWORD SelectedSymbol; // symbol selected (-1 to start) +} IMAGEHLP_DUPLICATE_SYMBOL64, *PIMAGEHLP_DUPLICATE_SYMBOL64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_DUPLICATE_SYMBOL IMAGEHLP_DUPLICATE_SYMBOL64 +#define PIMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_DUPLICATE_SYMBOL64 +#else +typedef struct _IMAGEHLP_DUPLICATE_SYMBOL +{ + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL) + DWORD NumberOfDups; // number of duplicates in the Symbol array + PIMAGEHLP_SYMBOL Symbol; // array of duplicate symbols + DWORD SelectedSymbol; // symbol selected (-1 to start) +} IMAGEHLP_DUPLICATE_SYMBOL, *PIMAGEHLP_DUPLICATE_SYMBOL; +#endif + +// If dbghelp ever needs to display graphical UI, it will use this as the parent window. + +BOOL +IMAGEAPI +SymSetParentWindow( + __in HWND hwnd +); + +PCHAR +IMAGEAPI +SymSetHomeDirectory( + __in_opt HANDLE hProcess, + __in_opt PCSTR dir +); + +PWSTR +IMAGEAPI +SymSetHomeDirectoryW( + __in_opt HANDLE hProcess, + __in_opt PCWSTR dir +); + +PCHAR +IMAGEAPI +SymGetHomeDirectory( + __in DWORD type, + __out_ecount(size) PSTR dir, + __in size_t size +); + +PWSTR +IMAGEAPI +SymGetHomeDirectoryW( + __in DWORD type, + __out_ecount(size) PWSTR dir, + __in size_t size +); + +enum +{ + hdBase = 0, // root directory for dbghelp + hdSym, // where symbols are stored + hdSrc, // where source is stored + hdMax // end marker +}; + +typedef struct _OMAP +{ + ULONG rva; + ULONG rvaTo; +} OMAP, *POMAP; + +BOOL +IMAGEAPI +SymGetOmaps( + __in HANDLE hProcess, + __in DWORD64 BaseOfDll, + __out POMAP* OmapTo, + __out PDWORD64 cOmapTo, + __out POMAP* OmapFrom, + __out PDWORD64 cOmapFrom +); + +// +// options that are set/returned by SymSetOptions() & SymGetOptions() +// these are used as a mask +// +#define SYMOPT_CASE_INSENSITIVE 0x00000001 +#define SYMOPT_UNDNAME 0x00000002 +#define SYMOPT_DEFERRED_LOADS 0x00000004 +#define SYMOPT_NO_CPP 0x00000008 +#define SYMOPT_LOAD_LINES 0x00000010 +#define SYMOPT_OMAP_FIND_NEAREST 0x00000020 +#define SYMOPT_LOAD_ANYTHING 0x00000040 +#define SYMOPT_IGNORE_CVREC 0x00000080 +#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 +#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 +#define SYMOPT_EXACT_SYMBOLS 0x00000400 +#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 +#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 +#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 +#define SYMOPT_PUBLICS_ONLY 0x00004000 +#define SYMOPT_NO_PUBLICS 0x00008000 +#define SYMOPT_AUTO_PUBLICS 0x00010000 +#define SYMOPT_NO_IMAGE_SEARCH 0x00020000 +#define SYMOPT_SECURE 0x00040000 +#define SYMOPT_NO_PROMPTS 0x00080000 +#define SYMOPT_OVERWRITE 0x00100000 +#define SYMOPT_IGNORE_IMAGEDIR 0x00200000 +#define SYMOPT_FLAT_DIRECTORY 0x00400000 +#define SYMOPT_FAVOR_COMPRESSED 0x00800000 +#define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 +#define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 + +#define SYMOPT_DEBUG 0x80000000 + +DWORD +IMAGEAPI +SymSetOptions( + __in DWORD SymOptions +); + +DWORD +IMAGEAPI +SymGetOptions( + VOID +); + +BOOL +IMAGEAPI +SymCleanup( + __in HANDLE hProcess +); + +BOOL +IMAGEAPI +SymMatchString( + __in PCSTR string, + __in PCSTR expression, + __in BOOL fCase +); + +BOOL +IMAGEAPI +SymMatchStringA( + __in PCSTR string, + __in PCSTR expression, + __in BOOL fCase +); + +BOOL +IMAGEAPI +SymMatchStringW( + __in PCWSTR string, + __in PCWSTR expression, + __in BOOL fCase +); + +typedef BOOL +(CALLBACK* PSYM_ENUMSOURCEFILES_CALLBACK)( + __in PSOURCEFILE pSourceFile, + __in_opt PVOID UserContext +); + +// for backwards compatibility - don't use this +#define PSYM_ENUMSOURCFILES_CALLBACK PSYM_ENUMSOURCEFILES_CALLBACK + +BOOL +IMAGEAPI +SymEnumSourceFiles( + __in HANDLE hProcess, + __in ULONG64 ModBase, + __in_opt PCSTR Mask, + __in PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PSYM_ENUMSOURCEFILES_CALLBACKW)( + __in PSOURCEFILEW pSourceFile, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumSourceFilesW( + __in HANDLE hProcess, + __in ULONG64 ModBase, + __in_opt PCWSTR Mask, + __in PSYM_ENUMSOURCEFILES_CALLBACKW cbSrcFiles, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumerateModules64( + __in HANDLE hProcess, + __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumerateModulesW64( + __in HANDLE hProcess, + __in PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback, + __in_opt PVOID UserContext +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymEnumerateModules SymEnumerateModules64 +#else +BOOL +IMAGEAPI +SymEnumerateModules( + __in HANDLE hProcess, + __in PSYM_ENUMMODULES_CALLBACK EnumModulesCallback, + __in_opt PVOID UserContext +); +#endif + +BOOL +IMAGEAPI +EnumerateLoadedModulesEx( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +EnumerateLoadedModulesExW( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +EnumerateLoadedModules64( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +EnumerateLoadedModulesW64( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, + __in_opt PVOID UserContext +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define EnumerateLoadedModules EnumerateLoadedModules64 +#else +BOOL +IMAGEAPI +EnumerateLoadedModules( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback, + __in_opt PVOID UserContext +); +#endif + +PVOID +IMAGEAPI +SymFunctionTableAccess64( + __in HANDLE hProcess, + __in DWORD64 AddrBase +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymFunctionTableAccess SymFunctionTableAccess64 +#else +PVOID +IMAGEAPI +SymFunctionTableAccess( + __in HANDLE hProcess, + __in DWORD AddrBase +); +#endif + +BOOL +IMAGEAPI +SymGetUnwindInfo( + __in HANDLE hProcess, + __in DWORD64 Address, + __out_bcount_opt(*Size) PVOID Buffer, + __inout PULONG Size +); + +BOOL +IMAGEAPI +SymGetModuleInfo64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PIMAGEHLP_MODULE64 ModuleInfo +); + +BOOL +IMAGEAPI +SymGetModuleInfoW64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PIMAGEHLP_MODULEW64 ModuleInfo +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetModuleInfo SymGetModuleInfo64 +#define SymGetModuleInfoW SymGetModuleInfoW64 +#else +BOOL +IMAGEAPI +SymGetModuleInfo( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out PIMAGEHLP_MODULE ModuleInfo +); + +BOOL +IMAGEAPI +SymGetModuleInfoW( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out PIMAGEHLP_MODULEW ModuleInfo +); +#endif + +DWORD64 +IMAGEAPI +SymGetModuleBase64( + __in HANDLE hProcess, + __in DWORD64 qwAddr +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetModuleBase SymGetModuleBase64 +#else +DWORD +IMAGEAPI +SymGetModuleBase( + __in HANDLE hProcess, + __in DWORD dwAddr +); +#endif + +typedef struct _SRCCODEINFO +{ + DWORD SizeOfStruct; // set to sizeof(SRCCODEINFO) + PVOID Key; // not used + DWORD64 ModBase; // base address of module this applies to + CHAR Obj[MAX_PATH + 1]; // the object file within the module + CHAR FileName[MAX_PATH + 1]; // full filename + DWORD LineNumber; // line number in file + DWORD64 Address; // first instruction of line +} SRCCODEINFO, *PSRCCODEINFO; + +typedef struct _SRCCODEINFOW +{ + DWORD SizeOfStruct; // set to sizeof(SRCCODEINFO) + PVOID Key; // not used + DWORD64 ModBase; // base address of module this applies to + WCHAR Obj[MAX_PATH + 1]; // the object file within the module + WCHAR FileName[MAX_PATH + 1]; // full filename + DWORD LineNumber; // line number in file + DWORD64 Address; // first instruction of line +} SRCCODEINFOW, *PSRCCODEINFOW; + +typedef BOOL +(CALLBACK* PSYM_ENUMLINES_CALLBACK)( + __in PSRCCODEINFO LineInfo, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumLines( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR Obj, + __in_opt PCSTR File, + __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PSYM_ENUMLINES_CALLBACKW)( + __in PSRCCODEINFOW LineInfo, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumLinesW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCWSTR Obj, + __in_opt PCWSTR File, + __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymGetLineFromAddr64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINE64 Line64 +); + +BOOL +IMAGEAPI +SymGetLineFromAddrW64( + __in HANDLE hProcess, + __in DWORD64 dwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINEW64 Line +); + +BOOL +IMAGEAPI +SymEnumSourceLines( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR Obj, + __in_opt PCSTR File, + __in_opt DWORD Line, + __in DWORD Flags, + __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumSourceLinesW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCWSTR Obj, + __in_opt PCWSTR File, + __in_opt DWORD Line, + __in DWORD Flags, + __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback, + __in_opt PVOID UserContext +); + +// flags for SymEnumSourceLines + +#define ESLFLAG_FULLPATH 0x1 +#define ESLFLAG_NEAREST 0x2 +#define ESLFLAG_PREV 0x4 +#define ESLFLAG_NEXT 0x8 + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetLineFromAddr SymGetLineFromAddr64 +#define SymGetLineFromAddrW SymGetLineFromAddrW64 +#else +BOOL +IMAGEAPI +SymGetLineFromAddr( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINE Line +); + +BOOL +IMAGEAPI +SymGetLineFromAddrW( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINEW Line +); +#endif + +BOOL +IMAGEAPI +SymGetLineFromName64( + __in HANDLE hProcess, + __in_opt PCSTR ModuleName, + __in_opt PCSTR FileName, + __in DWORD dwLineNumber, + __out PLONG plDisplacement, + __inout PIMAGEHLP_LINE64 Line +); + +BOOL +IMAGEAPI +SymGetLineFromNameW64( + __in HANDLE hProcess, + __in_opt PCWSTR ModuleName, + __in_opt PCWSTR FileName, + __in DWORD dwLineNumber, + __out PLONG plDisplacement, + __inout PIMAGEHLP_LINEW64 Line +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetLineFromName SymGetLineFromName64 +#else +BOOL +IMAGEAPI +SymGetLineFromName( + __in HANDLE hProcess, + __in_opt PCSTR ModuleName, + __in_opt PCSTR FileName, + __in DWORD dwLineNumber, + __out PLONG plDisplacement, + __inout PIMAGEHLP_LINE Line +); +#endif + +BOOL +IMAGEAPI +SymGetLineNext64( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINE64 Line +); + +BOOL +IMAGEAPI +SymGetLineNextW64( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINEW64 Line +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetLineNext SymGetLineNext64 +#else +BOOL +IMAGEAPI +SymGetLineNext( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINE Line +); + +BOOL +IMAGEAPI +SymGetLineNextW( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINEW Line +); +#endif + +BOOL +IMAGEAPI +SymGetLinePrev64( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINE64 Line +); + +BOOL +IMAGEAPI +SymGetLinePrevW64( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINEW64 Line +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetLinePrev SymGetLinePrev64 +#else +BOOL +IMAGEAPI +SymGetLinePrev( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINE Line +); + +BOOL +IMAGEAPI +SymGetLinePrevW( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINEW Line +); +#endif + +ULONG +IMAGEAPI +SymGetFileLineOffsets64( + __in HANDLE hProcess, + __in_opt PCSTR ModuleName, + __in PCSTR FileName, + __out_ecount(BufferLines) PDWORD64 Buffer, + __in ULONG BufferLines +); + +BOOL +IMAGEAPI +SymMatchFileName( + __in PCSTR FileName, + __in PCSTR Match, + __deref_opt_out PSTR* FileNameStop, + __deref_opt_out PSTR* MatchStop +); + +BOOL +IMAGEAPI +SymMatchFileNameW( + __in PCWSTR FileName, + __in PCWSTR Match, + __deref_opt_out PWSTR* FileNameStop, + __deref_opt_out PWSTR* MatchStop +); + +BOOL +IMAGEAPI +SymGetSourceFile( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR Params, + __in PCSTR FileSpec, + __out_ecount(Size) PSTR FilePath, + __in DWORD Size +); + +BOOL +IMAGEAPI +SymGetSourceFileW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCWSTR Params, + __in PCWSTR FileSpec, + __out_ecount(Size) PWSTR FilePath, + __in DWORD Size +); + +BOOL +IMAGEAPI +SymGetSourceFileToken( + __in HANDLE hProcess, + __in ULONG64 Base, + __in PCSTR FileSpec, + __deref_out PVOID* Token, + __out DWORD* Size +); + +BOOL +IMAGEAPI +SymGetSourceFileTokenW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in PCWSTR FileSpec, + __deref_out PVOID* Token, + __out DWORD* Size +); + +BOOL +IMAGEAPI +SymGetSourceFileFromToken( + __in HANDLE hProcess, + __in PVOID Token, + __in_opt PCSTR Params, + __out_ecount(Size) PSTR FilePath, + __in DWORD Size +); + +BOOL +IMAGEAPI +SymGetSourceFileFromTokenW( + __in HANDLE hProcess, + __in PVOID Token, + __in_opt PCWSTR Params, + __out_ecount(Size) PWSTR FilePath, + __in DWORD Size +); + +BOOL +IMAGEAPI +SymGetSourceVarFromToken( + __in HANDLE hProcess, + __in PVOID Token, + __in_opt PCSTR Params, + __in PCSTR VarName, + __out_ecount(Size) PSTR Value, + __in DWORD Size +); + +BOOL +IMAGEAPI +SymGetSourceVarFromTokenW( + __in HANDLE hProcess, + __in PVOID Token, + __in_opt PCWSTR Params, + __in PCWSTR VarName, + __out_ecount(Size) PWSTR Value, + __in DWORD Size +); + +typedef BOOL (CALLBACK* PENUMSOURCEFILETOKENSCALLBACK)(__in PVOID token, __in size_t size); + +BOOL +IMAGEAPI +SymEnumSourceFileTokens( + __in HANDLE hProcess, + __in ULONG64 Base, + __in PENUMSOURCEFILETOKENSCALLBACK Callback +); + +BOOL +IMAGEAPI +SymInitialize( + __in HANDLE hProcess, + __in_opt PCSTR UserSearchPath, + __in BOOL fInvadeProcess +); + +BOOL +IMAGEAPI +SymInitializeW( + __in HANDLE hProcess, + __in_opt PCWSTR UserSearchPath, + __in BOOL fInvadeProcess +); + +BOOL +IMAGEAPI +SymGetSearchPath( + __in HANDLE hProcess, + __out_ecount(SearchPathLength) PSTR SearchPath, + __in DWORD SearchPathLength +); + +BOOL +IMAGEAPI +SymGetSearchPathW( + __in HANDLE hProcess, + __out_ecount(SearchPathLength) PWSTR SearchPath, + __in DWORD SearchPathLength +); + +BOOL +IMAGEAPI +SymSetSearchPath( + __in HANDLE hProcess, + __in_opt PCSTR SearchPath +); + +BOOL +IMAGEAPI +SymSetSearchPathW( + __in HANDLE hProcess, + __in_opt PCWSTR SearchPath +); + +#define SLMFLAG_VIRTUAL 0x1 +#define SLMFLAG_ALT_INDEX 0x2 +#define SLMFLAG_NO_SYMBOLS 0x4 + +DWORD64 +IMAGEAPI +SymLoadModuleEx( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCSTR ImageName, + __in_opt PCSTR ModuleName, + __in DWORD64 BaseOfDll, + __in DWORD DllSize, + __in_opt PMODLOAD_DATA Data, + __in_opt DWORD Flags +); + +DWORD64 +IMAGEAPI +SymLoadModuleExW( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCWSTR ImageName, + __in_opt PCWSTR ModuleName, + __in DWORD64 BaseOfDll, + __in DWORD DllSize, + __in_opt PMODLOAD_DATA Data, + __in_opt DWORD Flags +); + +BOOL +IMAGEAPI +SymUnloadModule64( + __in HANDLE hProcess, + __in DWORD64 BaseOfDll +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymUnloadModule SymUnloadModule64 +#else +BOOL +IMAGEAPI +SymUnloadModule( + __in HANDLE hProcess, + __in DWORD BaseOfDll +); +#endif + +BOOL +IMAGEAPI +SymUnDName64( + __in PIMAGEHLP_SYMBOL64 sym, // Symbol to undecorate + __out_ecount(UnDecNameLength) PSTR UnDecName, // Buffer to store undecorated name in + __in DWORD UnDecNameLength // Size of the buffer +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymUnDName SymUnDName64 +#else +BOOL +IMAGEAPI +SymUnDName( + __in PIMAGEHLP_SYMBOL sym, // Symbol to undecorate + __out_ecount(UnDecNameLength) PSTR UnDecName, // Buffer to store undecorated name in + __in DWORD UnDecNameLength // Size of the buffer +); +#endif + +BOOL +IMAGEAPI +SymRegisterCallback64( + __in HANDLE hProcess, + __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, + __in ULONG64 UserContext +); + +BOOL +IMAGEAPI +SymRegisterCallbackW64( + __in HANDLE hProcess, + __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, + __in ULONG64 UserContext +); + +BOOL +IMAGEAPI +SymRegisterFunctionEntryCallback64( + __in HANDLE hProcess, + __in PSYMBOL_FUNCENTRY_CALLBACK64 CallbackFunction, + __in ULONG64 UserContext +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymRegisterCallback SymRegisterCallback64 +#define SymRegisterFunctionEntryCallback SymRegisterFunctionEntryCallback64 +#else +BOOL +IMAGEAPI +SymRegisterCallback( + __in HANDLE hProcess, + __in PSYMBOL_REGISTERED_CALLBACK CallbackFunction, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymRegisterFunctionEntryCallback( + __in HANDLE hProcess, + __in PSYMBOL_FUNCENTRY_CALLBACK CallbackFunction, + __in_opt PVOID UserContext +); +#endif + + +typedef struct _IMAGEHLP_SYMBOL_SRC +{ + DWORD sizeofstruct; + DWORD type; + char file[MAX_PATH]; +} IMAGEHLP_SYMBOL_SRC, *PIMAGEHLP_SYMBOL_SRC; + +typedef struct _MODULE_TYPE_INFO // AKA TYPTYP +{ + USHORT dataLength; + USHORT leaf; + BYTE data[1]; +} MODULE_TYPE_INFO, *PMODULE_TYPE_INFO; + +typedef struct _SYMBOL_INFO +{ + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG Index; + ULONG Size; + ULONG64 ModBase; // Base Address of module comtaining this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + CHAR Name[1]; // Name of symbol +} SYMBOL_INFO, *PSYMBOL_INFO; + +typedef struct _SYMBOL_INFO_PACKAGE +{ + SYMBOL_INFO si; + CHAR name[MAX_SYM_NAME + 1]; +} SYMBOL_INFO_PACKAGE, *PSYMBOL_INFO_PACKAGE; + +typedef struct _SYMBOL_INFOW +{ + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG Index; + ULONG Size; + ULONG64 ModBase; // Base Address of module comtaining this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + WCHAR Name[1]; // Name of symbol +} SYMBOL_INFOW, *PSYMBOL_INFOW; + +typedef struct _SYMBOL_INFO_PACKAGEW +{ + SYMBOL_INFOW si; + WCHAR name[MAX_SYM_NAME + 1]; +} SYMBOL_INFO_PACKAGEW, *PSYMBOL_INFO_PACKAGEW; + +typedef struct _IMAGEHLP_STACK_FRAME +{ + ULONG64 InstructionOffset; + ULONG64 ReturnOffset; + ULONG64 FrameOffset; + ULONG64 StackOffset; + ULONG64 BackingStoreOffset; + ULONG64 FuncTableEntry; + ULONG64 Params[4]; + ULONG64 Reserved[5]; + BOOL Virtual; + ULONG Reserved2; +} IMAGEHLP_STACK_FRAME, *PIMAGEHLP_STACK_FRAME; + +typedef VOID IMAGEHLP_CONTEXT, *PIMAGEHLP_CONTEXT; + + +BOOL +IMAGEAPI +SymSetContext( + __in HANDLE hProcess, + __in PIMAGEHLP_STACK_FRAME StackFrame, + __in_opt PIMAGEHLP_CONTEXT Context +); + +BOOL +IMAGEAPI +SymSetScopeFromAddr( + __in HANDLE hProcess, + __in ULONG64 Address +); + +BOOL +IMAGEAPI +SymSetScopeFromIndex( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index +); + +typedef BOOL +(CALLBACK* PSYM_ENUMPROCESSES_CALLBACK)( + __in HANDLE hProcess, + __in PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumProcesses( + __in PSYM_ENUMPROCESSES_CALLBACK EnumProcessesCallback, + __in PVOID UserContext +); + +BOOL +IMAGEAPI +SymFromAddr( + __in HANDLE hProcess, + __in DWORD64 Address, + __out_opt PDWORD64 Displacement, + __inout PSYMBOL_INFO Symbol +); + +BOOL +IMAGEAPI +SymFromAddrW( + __in HANDLE hProcess, + __in DWORD64 Address, + __out_opt PDWORD64 Displacement, + __inout PSYMBOL_INFOW Symbol +); + +BOOL +IMAGEAPI +SymFromToken( + __in HANDLE hProcess, + __in DWORD64 Base, + __in DWORD Token, + __inout PSYMBOL_INFO Symbol +); + +BOOL +IMAGEAPI +SymFromTokenW( + __in HANDLE hProcess, + __in DWORD64 Base, + __in DWORD Token, + __inout PSYMBOL_INFOW Symbol +); + +BOOL +IMAGEAPI +SymNext( + __in HANDLE hProcess, + __inout PSYMBOL_INFO si +); + +BOOL +IMAGEAPI +SymNextW( + __in HANDLE hProcess, + __inout PSYMBOL_INFOW siw +); + +BOOL +IMAGEAPI +SymPrev( + __in HANDLE hProcess, + __inout PSYMBOL_INFO si +); + +BOOL +IMAGEAPI +SymPrevW( + __in HANDLE hProcess, + __inout PSYMBOL_INFOW siw +); + +// While SymFromName will provide a symbol from a name, +// SymEnumSymbols can provide the same matching information +// for ALL symbols with a matching name, even regular +// expressions. That way you can search across modules +// and differentiate between identically named symbols. + +BOOL +IMAGEAPI +SymFromName( + __in HANDLE hProcess, + __in PCSTR Name, + __inout PSYMBOL_INFO Symbol +); + +BOOL +IMAGEAPI +SymFromNameW( + __in HANDLE hProcess, + __in PCWSTR Name, + __inout PSYMBOL_INFOW Symbol +); + +typedef BOOL +(CALLBACK* PSYM_ENUMERATESYMBOLS_CALLBACK)( + __in PSYMBOL_INFO pSymInfo, + __in ULONG SymbolSize, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumSymbols( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCSTR Mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext +); + +typedef BOOL +(CALLBACK* PSYM_ENUMERATESYMBOLS_CALLBACKW)( + __in PSYMBOL_INFOW pSymInfo, + __in ULONG SymbolSize, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumSymbolsW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCWSTR Mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumSymbolsForAddr( + __in HANDLE hProcess, + __in DWORD64 Address, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumSymbolsForAddrW( + __in HANDLE hProcess, + __in DWORD64 Address, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext +); + +#define SYMSEARCH_MASKOBJS 0x01 // used internally to implement other APIs +#define SYMSEARCH_RECURSE 0X02 // recurse scopes +#define SYMSEARCH_GLOBALSONLY 0X04 // search only for global symbols +#define SYMSEARCH_ALLITEMS 0X08 // search for everything in the pdb, not just normal scoped symbols + +BOOL +IMAGEAPI +SymSearch( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt DWORD Index, + __in_opt DWORD SymTag, + __in_opt PCSTR Mask, + __in_opt DWORD64 Address, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext, + __in DWORD Options +); + +BOOL +IMAGEAPI +SymSearchW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt DWORD Index, + __in_opt DWORD SymTag, + __in_opt PCWSTR Mask, + __in_opt DWORD64 Address, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext, + __in DWORD Options +); + +BOOL +IMAGEAPI +SymGetScope( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index, + __inout PSYMBOL_INFO Symbol +); + +BOOL +IMAGEAPI +SymGetScopeW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index, + __inout PSYMBOL_INFOW Symbol +); + +BOOL +IMAGEAPI +SymFromIndex( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index, + __inout PSYMBOL_INFO Symbol +); + +BOOL +IMAGEAPI +SymFromIndexW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index, + __inout PSYMBOL_INFOW Symbol +); + +typedef enum _IMAGEHLP_SYMBOL_TYPE_INFO +{ + TI_GET_SYMTAG, + TI_GET_SYMNAME, + TI_GET_LENGTH, + TI_GET_TYPE, + TI_GET_TYPEID, + TI_GET_BASETYPE, + TI_GET_ARRAYINDEXTYPEID, + TI_FINDCHILDREN, + TI_GET_DATAKIND, + TI_GET_ADDRESSOFFSET, + TI_GET_OFFSET, + TI_GET_VALUE, + TI_GET_COUNT, + TI_GET_CHILDRENCOUNT, + TI_GET_BITPOSITION, + TI_GET_VIRTUALBASECLASS, + TI_GET_VIRTUALTABLESHAPEID, + TI_GET_VIRTUALBASEPOINTEROFFSET, + TI_GET_CLASSPARENTID, + TI_GET_NESTED, + TI_GET_SYMINDEX, + TI_GET_LEXICALPARENT, + TI_GET_ADDRESS, + TI_GET_THISADJUST, + TI_GET_UDTKIND, + TI_IS_EQUIV_TO, + TI_GET_CALLING_CONVENTION, + TI_IS_CLOSE_EQUIV_TO, + TI_GTIEX_REQS_VALID, + TI_GET_VIRTUALBASEOFFSET, + TI_GET_VIRTUALBASEDISPINDEX, + TI_GET_IS_REFERENCE, + TI_GET_INDIRECTVIRTUALBASECLASS, + IMAGEHLP_SYMBOL_TYPE_INFO_MAX, +} IMAGEHLP_SYMBOL_TYPE_INFO; + +typedef struct _TI_FINDCHILDREN_PARAMS +{ + ULONG Count; + ULONG Start; + ULONG ChildId[1]; +} TI_FINDCHILDREN_PARAMS; + +BOOL +IMAGEAPI +SymGetTypeInfo( + __in HANDLE hProcess, + __in DWORD64 ModBase, + __in ULONG TypeId, + __in IMAGEHLP_SYMBOL_TYPE_INFO GetType, + __out PVOID pInfo +); + +#define IMAGEHLP_GET_TYPE_INFO_UNCACHED 0x00000001 +#define IMAGEHLP_GET_TYPE_INFO_CHILDREN 0x00000002 + +typedef struct _IMAGEHLP_GET_TYPE_INFO_PARAMS +{ + IN ULONG SizeOfStruct; + IN ULONG Flags; + IN ULONG NumIds; + IN PULONG TypeIds; + IN ULONG64 TagFilter; + IN ULONG NumReqs; + IN IMAGEHLP_SYMBOL_TYPE_INFO* ReqKinds; + IN PULONG_PTR ReqOffsets; + IN PULONG ReqSizes; + IN ULONG_PTR ReqStride; + IN ULONG_PTR BufferSize; + OUT PVOID Buffer; + OUT ULONG EntriesMatched; + OUT ULONG EntriesFilled; + OUT ULONG64 TagsFound; + OUT ULONG64 AllReqsValid; + IN ULONG NumReqsValid; + OUT PULONG64 ReqsValid OPTIONAL; +} IMAGEHLP_GET_TYPE_INFO_PARAMS, *PIMAGEHLP_GET_TYPE_INFO_PARAMS; + +BOOL +IMAGEAPI +SymGetTypeInfoEx( + __in HANDLE hProcess, + __in DWORD64 ModBase, + __inout PIMAGEHLP_GET_TYPE_INFO_PARAMS Params +); + +BOOL +IMAGEAPI +SymEnumTypes( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumTypesW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumTypesByName( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCSTR mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymEnumTypesByNameW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCWSTR mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext +); + +BOOL +IMAGEAPI +SymGetTypeFromName( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PCSTR Name, + __inout PSYMBOL_INFO Symbol +); + +BOOL +IMAGEAPI +SymGetTypeFromNameW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PCWSTR Name, + __inout PSYMBOL_INFOW Symbol +); + +BOOL +IMAGEAPI +SymAddSymbol( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PCSTR Name, + __in DWORD64 Address, + __in DWORD Size, + __in DWORD Flags +); + +BOOL +IMAGEAPI +SymAddSymbolW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PCWSTR Name, + __in DWORD64 Address, + __in DWORD Size, + __in DWORD Flags +); + +BOOL +IMAGEAPI +SymDeleteSymbol( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCSTR Name, + __in DWORD64 Address, + __in DWORD Flags +); + +BOOL +IMAGEAPI +SymDeleteSymbolW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCWSTR Name, + __in DWORD64 Address, + __in DWORD Flags +); + +BOOL +IMAGEAPI +SymRefreshModuleList( + __in HANDLE hProcess +); + +BOOL +IMAGEAPI +SymAddSourceStream( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR StreamFile, + __in_bcount_opt(Size) PBYTE Buffer, + __in size_t Size +); + +typedef BOOL (WINAPI* SYMADDSOURCESTREAM)(HANDLE, ULONG64, PCSTR, PBYTE, size_t); + +BOOL +IMAGEAPI +SymAddSourceStreamA( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR StreamFile, + __in_bcount_opt(Size) PBYTE Buffer, + __in size_t Size +); + +typedef BOOL (WINAPI* SYMADDSOURCESTREAMA)(HANDLE, ULONG64, PCSTR, PBYTE, size_t); + +BOOL +IMAGEAPI +SymAddSourceStreamW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCWSTR FileSpec, + __in_bcount_opt(Size) PBYTE Buffer, + __in size_t Size +); + +BOOL +IMAGEAPI +SymSrvIsStoreW( + __in_opt HANDLE hProcess, + __in PCWSTR path +); + +BOOL +IMAGEAPI +SymSrvIsStore( + __in_opt HANDLE hProcess, + __in PCSTR path +); + +PCSTR +IMAGEAPI +SymSrvDeltaName( + __in HANDLE hProcess, + __in_opt PCSTR SymPath, + __in PCSTR Type, + __in PCSTR File1, + __in PCSTR File2 +); + +PCWSTR +IMAGEAPI +SymSrvDeltaNameW( + __in HANDLE hProcess, + __in_opt PCWSTR SymPath, + __in PCWSTR Type, + __in PCWSTR File1, + __in PCWSTR File2 +); + +PCSTR +IMAGEAPI +SymSrvGetSupplement( + __in HANDLE hProcess, + __in_opt PCSTR SymPath, + __in PCSTR Node, + __in PCSTR File +); + +PCWSTR +IMAGEAPI +SymSrvGetSupplementW( + __in HANDLE hProcess, + __in_opt PCWSTR SymPath, + __in PCWSTR Node, + __in PCWSTR File +); + +BOOL +IMAGEAPI +SymSrvGetFileIndexes( + __in PCSTR File, + __out GUID* Id, + __out PDWORD Val1, + __out_opt PDWORD Val2, + __in DWORD Flags +); + +BOOL +IMAGEAPI +SymSrvGetFileIndexesW( + __in PCWSTR File, + __out GUID* Id, + __out PDWORD Val1, + __out_opt PDWORD Val2, + __in DWORD Flags +); + +BOOL +IMAGEAPI +SymSrvGetFileIndexStringW( + __in HANDLE hProcess, + __in_opt PCWSTR SrvPath, + __in PCWSTR File, + __out_ecount(Size) PWSTR Index, + __in size_t Size, + __in DWORD Flags +); + +BOOL +IMAGEAPI +SymSrvGetFileIndexString( + __in HANDLE hProcess, + __in_opt PCSTR SrvPath, + __in PCSTR File, + __out_ecount(Size) PSTR Index, + __in size_t Size, + __in DWORD Flags +); + +typedef struct +{ + DWORD sizeofstruct; + char file[MAX_PATH + 1]; + BOOL stripped; + DWORD timestamp; + DWORD size; + char dbgfile[MAX_PATH + 1]; + char pdbfile[MAX_PATH + 1]; + GUID guid; + DWORD sig; + DWORD age; +} SYMSRV_INDEX_INFO, *PSYMSRV_INDEX_INFO; + +typedef struct +{ + DWORD sizeofstruct; + WCHAR file[MAX_PATH + 1]; + BOOL stripped; + DWORD timestamp; + DWORD size; + WCHAR dbgfile[MAX_PATH + 1]; + WCHAR pdbfile[MAX_PATH + 1]; + GUID guid; + DWORD sig; + DWORD age; +} SYMSRV_INDEX_INFOW, *PSYMSRV_INDEX_INFOW; + +BOOL +IMAGEAPI +SymSrvGetFileIndexInfo( + __in PCSTR File, + __out PSYMSRV_INDEX_INFO Info, + __in DWORD Flags +); + +BOOL +IMAGEAPI +SymSrvGetFileIndexInfoW( + __in PCWSTR File, + __out PSYMSRV_INDEX_INFOW Info, + __in DWORD Flags +); + +PCSTR +IMAGEAPI +SymSrvStoreSupplement( + __in HANDLE hProcess, + __in_opt PCSTR SrvPath, + __in PCSTR Node, + __in PCSTR File, + __in DWORD Flags +); + +PCWSTR +IMAGEAPI +SymSrvStoreSupplementW( + __in HANDLE hProcess, + __in_opt PCWSTR SymPath, + __in PCWSTR Node, + __in PCWSTR File, + __in DWORD Flags +); + +PCSTR +IMAGEAPI +SymSrvStoreFile( + __in HANDLE hProcess, + __in_opt PCSTR SrvPath, + __in PCSTR File, + __in DWORD Flags +); + +PCWSTR +IMAGEAPI +SymSrvStoreFileW( + __in HANDLE hProcess, + __in_opt PCWSTR SrvPath, + __in PCWSTR File, + __in DWORD Flags +); + +// used by SymGetSymbolFile's "Type" parameter + +enum +{ + sfImage = 0, + sfDbg, + sfPdb, + sfMpd, + sfMax +}; + +BOOL +IMAGEAPI +SymGetSymbolFile( + __in_opt HANDLE hProcess, + __in_opt PCSTR SymPath, + __in PCSTR ImageFile, + __in DWORD Type, + __out_ecount(cSymbolFile) PSTR SymbolFile, + __in size_t cSymbolFile, + __out_ecount(cDbgFile) PSTR DbgFile, + __in size_t cDbgFile +); + +BOOL +IMAGEAPI +SymGetSymbolFileW( + __in_opt HANDLE hProcess, + __in_opt PCWSTR SymPath, + __in PCWSTR ImageFile, + __in DWORD Type, + __out_ecount(cSymbolFile) PWSTR SymbolFile, + __in size_t cSymbolFile, + __out_ecount(cDbgFile) PWSTR DbgFile, + __in size_t cDbgFile +); + +// +// Full user-mode dump creation. +// + +typedef BOOL (WINAPI* PDBGHELP_CREATE_USER_DUMP_CALLBACK)( + __in DWORD DataType, + __in PVOID* Data, + __out LPDWORD DataLength, + __in_opt PVOID UserData +); + +BOOL +WINAPI +DbgHelpCreateUserDump( + __in_opt LPCSTR FileName, + __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback, + __in_opt PVOID UserData +); + +BOOL +WINAPI +DbgHelpCreateUserDumpW( + __in_opt LPCWSTR FileName, + __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback, + __in_opt PVOID UserData +); + +// ----------------------------------------------------------------- +// The following 4 legacy APIs are fully supported, but newer +// ones are recommended. SymFromName and SymFromAddr provide +// much more detailed info on the returned symbol. + +BOOL +IMAGEAPI +SymGetSymFromAddr64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out_opt PDWORD64 pdwDisplacement, + __inout PIMAGEHLP_SYMBOL64 Symbol +); + + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetSymFromAddr SymGetSymFromAddr64 +#else +BOOL +IMAGEAPI +SymGetSymFromAddr( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out_opt PDWORD pdwDisplacement, + __inout PIMAGEHLP_SYMBOL Symbol +); +#endif + +// While following two APIs will provide a symbol from a name, +// SymEnumSymbols can provide the same matching information +// for ALL symbols with a matching name, even regular +// expressions. That way you can search across modules +// and differentiate between identically named symbols. + +BOOL +IMAGEAPI +SymGetSymFromName64( + __in HANDLE hProcess, + __in PCSTR Name, + __inout PIMAGEHLP_SYMBOL64 Symbol +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetSymFromName SymGetSymFromName64 +#else +BOOL +IMAGEAPI +SymGetSymFromName( + __in HANDLE hProcess, + __in PCSTR Name, + __inout PIMAGEHLP_SYMBOL Symbol +); +#endif + + +// Symbol server exports + +typedef BOOL (WINAPI* PSYMBOLSERVERPROC)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR); +typedef BOOL (WINAPI* PSYMBOLSERVERPROCA)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR); +typedef BOOL (WINAPI* PSYMBOLSERVERPROCW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR); +typedef BOOL (WINAPI* PSYMBOLSERVERBYINDEXPROC)(PCSTR, PCSTR, PCSTR, PSTR); +typedef BOOL (WINAPI* PSYMBOLSERVERBYINDEXPROCA)(PCSTR, PCSTR, PCSTR, PSTR); +typedef BOOL (WINAPI* PSYMBOLSERVERBYINDEXPROCW)(PCWSTR, PCWSTR, PCWSTR, PWSTR); +typedef BOOL (WINAPI* PSYMBOLSERVEROPENPROC)(VOID); +typedef BOOL (WINAPI* PSYMBOLSERVERCLOSEPROC)(VOID); +typedef BOOL (WINAPI* PSYMBOLSERVERSETOPTIONSPROC)(UINT_PTR, ULONG64); +typedef BOOL (WINAPI* PSYMBOLSERVERSETOPTIONSWPROC)(UINT_PTR, ULONG64); +typedef BOOL (CALLBACK WINAPI* PSYMBOLSERVERCALLBACKPROC)(UINT_PTR action, ULONG64 data, ULONG64 context); +typedef UINT_PTR(WINAPI* PSYMBOLSERVERGETOPTIONSPROC)(); +typedef BOOL (WINAPI* PSYMBOLSERVERPINGPROC)(PCSTR); +typedef BOOL (WINAPI* PSYMBOLSERVERPINGPROCA)(PCSTR); +typedef BOOL (WINAPI* PSYMBOLSERVERPINGPROCW)(PCWSTR); +typedef BOOL (WINAPI* PSYMBOLSERVERGETVERSION)(LPAPI_VERSION); +typedef BOOL (WINAPI* PSYMBOLSERVERDELTANAME)(PCSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PSTR, size_t); +typedef BOOL (WINAPI* PSYMBOLSERVERDELTANAMEW)(PCWSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PWSTR, size_t); +typedef BOOL (WINAPI* PSYMBOLSERVERGETSUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t); +typedef BOOL (WINAPI* PSYMBOLSERVERGETSUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t); +typedef BOOL (WINAPI* PSYMBOLSERVERSTORESUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t, DWORD); +typedef BOOL (WINAPI* PSYMBOLSERVERSTORESUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t, DWORD); +typedef BOOL (WINAPI* PSYMBOLSERVERGETINDEXSTRING)(PVOID, DWORD, DWORD, PSTR, size_t); +typedef BOOL (WINAPI* PSYMBOLSERVERGETINDEXSTRINGW)(PVOID, DWORD, DWORD, PWSTR, size_t); +typedef BOOL (WINAPI* PSYMBOLSERVERSTOREFILE)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR, size_t, DWORD); +typedef BOOL (WINAPI* PSYMBOLSERVERSTOREFILEW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR, size_t, DWORD); +typedef BOOL (WINAPI* PSYMBOLSERVERISSTORE)(PCSTR); +typedef BOOL (WINAPI* PSYMBOLSERVERISSTOREW)(PCWSTR); +typedef DWORD (WINAPI* PSYMBOLSERVERVERSION)(); +typedef BOOL (CALLBACK WINAPI* PSYMBOLSERVERMESSAGEPROC)(UINT_PTR action, ULONG64 data, ULONG64 context); + +#define SYMSRV_VERSION 2 + +#define SSRVOPT_CALLBACK 0x00000001 +#define SSRVOPT_DWORD 0x00000002 +#define SSRVOPT_DWORDPTR 0x00000004 +#define SSRVOPT_GUIDPTR 0x00000008 +#define SSRVOPT_OLDGUIDPTR 0x00000010 +#define SSRVOPT_UNATTENDED 0x00000020 +#define SSRVOPT_NOCOPY 0x00000040 +#define SSRVOPT_GETPATH 0x00000040 +#define SSRVOPT_PARENTWIN 0x00000080 +#define SSRVOPT_PARAMTYPE 0x00000100 +#define SSRVOPT_SECURE 0x00000200 +#define SSRVOPT_TRACE 0x00000400 +#define SSRVOPT_SETCONTEXT 0x00000800 +#define SSRVOPT_PROXY 0x00001000 +#define SSRVOPT_DOWNSTREAM_STORE 0x00002000 +#define SSRVOPT_OVERWRITE 0x00004000 +#define SSRVOPT_RESETTOU 0x00008000 +#define SSRVOPT_CALLBACKW 0x00010000 +#define SSRVOPT_FLAT_DEFAULT_STORE 0x00020000 +#define SSRVOPT_PROXYW 0x00040000 +#define SSRVOPT_MESSAGE 0x00080000 +#define SSRVOPT_SERVICE 0x00100000 // deprecated +#define SSRVOPT_FAVOR_COMPRESSED 0x00200000 +#define SSRVOPT_STRING 0x00400000 +#define SSRVOPT_WINHTTP 0x00800000 +#define SSRVOPT_WININET 0x01000000 + +#define SSRVOPT_MAX 0x0100000 + +#define SSRVOPT_RESET ((ULONG_PTR)-1) + + +#define NUM_SSRVOPTS 30 + +#define SSRVACTION_TRACE 1 +#define SSRVACTION_QUERYCANCEL 2 +#define SSRVACTION_EVENT 3 +#define SSRVACTION_EVENTW 4 +#define SSRVACTION_SIZE 5 + +#define SYMSTOREOPT_COMPRESS 0x01 +#define SYMSTOREOPT_OVERWRITE 0x02 +#define SYMSTOREOPT_RETURNINDEX 0x04 +#define SYMSTOREOPT_POINTER 0x08 +#define SYMSTOREOPT_ALT_INDEX 0x10 +#define SYMSTOREOPT_UNICODE 0x20 +#define SYMSTOREOPT_PASS_IF_EXISTS 0x40 + +#ifdef DBGHELP_TRANSLATE_TCHAR +#define SymInitialize SymInitializeW +#define SymAddSymbol SymAddSymbolW +#define SymDeleteSymbol SymDeleteSymbolW +#define SearchTreeForFile SearchTreeForFileW +#define UnDecorateSymbolName UnDecorateSymbolNameW +#define SymGetLineFromName64 SymGetLineFromNameW64 +#define SymGetLineFromAddr64 SymGetLineFromAddrW64 +#define SymGetLineNext64 SymGetLineNextW64 +#define SymGetLinePrev64 SymGetLinePrevW64 +#define SymFromName SymFromNameW +#define SymFindExecutableImage SymFindExecutableImageW +#define FindExecutableImageEx FindExecutableImageExW +#define SymSearch SymSearchW +#define SymEnumLines SymEnumLinesW +#define SymEnumSourceLines SymEnumSourceLinesW +#define SymGetTypeFromName SymGetTypeFromNameW +#define SymEnumSymbolsForAddr SymEnumSymbolsForAddrW +#define SymFromAddr SymFromAddrW +#define SymMatchString SymMatchStringW +#define SymEnumSourceFiles SymEnumSourceFilesW +#define SymEnumSymbols SymEnumSymbolsW +#define SymLoadModuleEx SymLoadModuleExW +#define SymSetSearchPath SymSetSearchPathW +#define SymGetSearchPath SymGetSearchPathW +#define EnumDirTree EnumDirTreeW +#define SymFromToken SymFromTokenW +#define SymFromIndex SymFromIndexW +#define SymGetScope SymGetScopeW +#define SymNext SymNextW +#define SymPrev SymPrevW +#define SymEnumTypes SymEnumTypesW +#define SymEnumTypesByName SymEnumTypesByNameW +#define SymRegisterCallback64 SymRegisterCallbackW64 +#define SymFindDebugInfoFile SymFindDebugInfoFileW +#define FindDebugInfoFileEx FindDebugInfoFileExW +#define SymFindFileInPath SymFindFileInPathW +#define SymEnumerateModules64 SymEnumerateModulesW64 +#define SymSetHomeDirectory SymSetHomeDirectoryW +#define SymGetHomeDirectory SymGetHomeDirectoryW +#define SymGetSourceFile SymGetSourceFileW +#define SymGetSourceFileToken SymGetSourceFileTokenW +#define SymGetSourceFileFromToken SymGetSourceFileFromTokenW +#define SymGetSourceVarFromToken SymGetSourceVarFromTokenW +#define SymGetSourceFileToken SymGetSourceFileTokenW +#define SymGetFileLineOffsets64 SymGetFileLineOffsetsW64 +#define SymFindFileInPath SymFindFileInPathW +#define SymMatchFileName SymMatchFileNameW +#define SymGetSourceFileFromToken SymGetSourceFileFromTokenW +#define SymGetSourceVarFromToken SymGetSourceVarFromTokenW +#define SymGetModuleInfo64 SymGetModuleInfoW64 +#define SymSrvIsStore SymSrvIsStoreW +#define SymSrvDeltaName SymSrvDeltaNameW +#define SymSrvGetSupplement SymSrvGetSupplementW +#define SymSrvStoreSupplement SymSrvStoreSupplementW +#define SymSrvGetFileIndexes SymSrvGetFileIndexes +#define SymSrvGetFileIndexString SymSrvGetFileIndexStringW +#define SymSrvStoreFile SymSrvStoreFileW +#define SymGetSymbolFile SymGetSymbolFileW +#define EnumerateLoadedModules64 EnumerateLoadedModulesW64 +#define EnumerateLoadedModulesEx EnumerateLoadedModulesExW +#define SymSrvGetFileIndexInfo SymSrvGetFileIndexInfoW + +#define IMAGEHLP_LINE64 IMAGEHLP_LINEW64 +#define PIMAGEHLP_LINE64 PIMAGEHLP_LINEW64 +#define SYMBOL_INFO SYMBOL_INFOW +#define PSYMBOL_INFO PSYMBOL_INFOW +#define SYMBOL_INFO_PACKAGE SYMBOL_INFO_PACKAGEW +#define PSYMBOL_INFO_PACKAGE PSYMBOL_INFO_PACKAGEW +#define FIND_EXE_FILE_CALLBACK FIND_EXE_FILE_CALLBACKW +#define PFIND_EXE_FILE_CALLBACK PFIND_EXE_FILE_CALLBACKW +#define SYM_ENUMERATESYMBOLS_CALLBACK SYM_ENUMERATESYMBOLS_CALLBACKW +#define PSYM_ENUMERATESYMBOLS_CALLBACK PSYM_ENUMERATESYMBOLS_CALLBACKW +#define SRCCODEINFO SRCCODEINFOW +#define PSRCCODEINFO PSRCCODEINFOW +#define SOURCEFILE SOURCEFILEW +#define PSOURCEFILE PSOURCEFILEW +#define SYM_ENUMSOURECFILES_CALLBACK SYM_ENUMSOURCEFILES_CALLBACKW +#define PSYM_ENUMSOURCEFILES_CALLBACK PSYM_ENUMSOURECFILES_CALLBACKW +#define IMAGEHLP_CBA_EVENT IMAGEHLP_CBA_EVENTW +#define PIMAGEHLP_CBA_EVENT PIMAGEHLP_CBA_EVENTW +#define PENUMDIRTREE_CALLBACK PENUMDIRTREE_CALLBACKW +#define IMAGEHLP_DEFERRED_SYMBOL_LOAD64 IMAGEHLP_DEFERRED_SYMBOL_LOADW64 +#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 PIMAGEHLP_DEFERRED_SYMBOL_LOADW64 +#define PFIND_DEBUG_FILE_CALLBACK PFIND_DEBUG_FILE_CALLBACKW +#define PFINDFILEINPATHCALLBACK PFINDFILEINPATHCALLBACKW +#define IMAGEHLP_MODULE64 IMAGEHLP_MODULEW64 +#define PIMAGEHLP_MODULE64 PIMAGEHLP_MODULEW64 +#define SYMSRV_INDEX_INFO SYMSRV_INDEX_INFOW +#define PSYMSRV_INDEX_INFO PSYMSRV_INDEX_INFOW + +#define PSYMBOLSERVERPROC PSYMBOLSERVERPROCW +#define PSYMBOLSERVERPINGPROC PSYMBOLSERVERPINGPROCW +#endif + +// ----------------------------------------------------------------- +// The following APIs exist only for backwards compatibility +// with a pre-release version documented in an MSDN release. + +// You should use SymFindFileInPath if you want to maintain +// future compatibility. + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +FindFileInPath( + __in HANDLE hprocess, + __in PCSTR SearchPath, + __in PCSTR FileName, + __in PVOID id, + __in DWORD two, + __in DWORD three, + __in DWORD flags, + __out_ecount(MAX_PATH + 1) PSTR FilePath +); + +// You should use SymFindFileInPath if you want to maintain +// future compatibility. + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +FindFileInSearchPath( + __in HANDLE hprocess, + __in PCSTR SearchPath, + __in PCSTR FileName, + __in DWORD one, + __in DWORD two, + __in DWORD three, + __out_ecount(MAX_PATH + 1) PSTR FilePath +); + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumSym( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext +); + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumerateSymbols64( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback, + __in_opt PVOID UserContext +); + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumerateSymbolsW64( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMSYMBOLS_CALLBACK64W EnumSymbolsCallback, + __in_opt PVOID UserContext +); + + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymEnumerateSymbols SymEnumerateSymbols64 +#define SymEnumerateSymbolsW SymEnumerateSymbolsW64 +#else +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumerateSymbols( + __in HANDLE hProcess, + __in ULONG BaseOfDll, + __in PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext +); + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumerateSymbolsW( + __in HANDLE hProcess, + __in ULONG BaseOfDll, + __in PSYM_ENUMSYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext +); +#endif + +// use SymLoadModuleEx + +DWORD64 +IMAGEAPI +SymLoadModule64( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCSTR ImageName, + __in_opt PCSTR ModuleName, + __in DWORD64 BaseOfDll, + __in DWORD SizeOfDll +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymLoadModule SymLoadModule64 +#else +DWORD +IMAGEAPI +SymLoadModule( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCSTR ImageName, + __in_opt PCSTR ModuleName, + __in DWORD BaseOfDll, + __in DWORD SizeOfDll +); +#endif + +BOOL +IMAGEAPI +SymGetSymNext64( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOL64 Symbol +); + +BOOL +IMAGEAPI +SymGetSymNextW64( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOLW64 Symbol +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetSymNext SymGetSymNext64 +#define SymGetSymNextW SymGetSymNextW64 +#else +BOOL +IMAGEAPI +SymGetSymNext( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOL Symbol +); + +BOOL +IMAGEAPI +SymGetSymNextW( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOLW Symbol +); +#endif + +BOOL +IMAGEAPI +SymGetSymPrev64( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOL64 Symbol +); + +BOOL +IMAGEAPI +SymGetSymPrevW64( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOLW64 Symbol +); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetSymPrev SymGetSymPrev64 +#define SymGetSymPrevW SymGetSymPrevW64 +#else +BOOL +IMAGEAPI +SymGetSymPrev( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOL Symbol +); + +BOOL +IMAGEAPI +SymGetSymPrevW( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOLW Symbol +); +#endif + + +// These values should not be used. +// They have been replaced by SYMFLAG_ values. + +#define SYMF_OMAP_GENERATED 0x00000001 +#define SYMF_OMAP_MODIFIED 0x00000002 +#define SYMF_REGISTER 0x00000008 +#define SYMF_REGREL 0x00000010 +#define SYMF_FRAMEREL 0x00000020 +#define SYMF_PARAMETER 0x00000040 +#define SYMF_LOCAL 0x00000080 +#define SYMF_CONSTANT 0x00000100 +#define SYMF_EXPORT 0x00000200 +#define SYMF_FORWARDER 0x00000400 +#define SYMF_FUNCTION 0x00000800 +#define SYMF_VIRTUAL 0x00001000 +#define SYMF_THUNK 0x00002000 +#define SYMF_TLSREL 0x00004000 + +// These values should also not be used. +// They have been replaced by SYMFLAG_ values. + +#define IMAGEHLP_SYMBOL_INFO_VALUEPRESENT 1 +#define IMAGEHLP_SYMBOL_INFO_REGISTER SYMF_REGISTER // 0x0008 +#define IMAGEHLP_SYMBOL_INFO_REGRELATIVE SYMF_REGREL // 0x0010 +#define IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE SYMF_FRAMEREL // 0x0020 +#define IMAGEHLP_SYMBOL_INFO_PARAMETER SYMF_PARAMETER // 0x0040 +#define IMAGEHLP_SYMBOL_INFO_LOCAL SYMF_LOCAL // 0x0080 +#define IMAGEHLP_SYMBOL_INFO_CONSTANT SYMF_CONSTANT // 0x0100 +#define IMAGEHLP_SYMBOL_FUNCTION SYMF_FUNCTION // 0x0800 +#define IMAGEHLP_SYMBOL_VIRTUAL SYMF_VIRTUAL // 0x1000 +#define IMAGEHLP_SYMBOL_THUNK SYMF_THUNK // 0x2000 +#define IMAGEHLP_SYMBOL_INFO_TLSRELATIVE SYMF_TLSREL // 0x4000 + +#pragma pack(pop) + + +#pragma pack(push,4) + +#define MINIDUMP_SIGNATURE ('PMDM') +#define MINIDUMP_VERSION (42899) +typedef DWORD RVA; +typedef ULONG64 RVA64; + +typedef struct _MINIDUMP_LOCATION_DESCRIPTOR +{ + ULONG32 DataSize; + RVA Rva; +} MINIDUMP_LOCATION_DESCRIPTOR; + +typedef struct _MINIDUMP_LOCATION_DESCRIPTOR64 +{ + ULONG64 DataSize; + RVA64 Rva; +} MINIDUMP_LOCATION_DESCRIPTOR64; + + +typedef struct _MINIDUMP_MEMORY_DESCRIPTOR +{ + ULONG64 StartOfMemoryRange; + MINIDUMP_LOCATION_DESCRIPTOR Memory; +} MINIDUMP_MEMORY_DESCRIPTOR, *PMINIDUMP_MEMORY_DESCRIPTOR; + +// DESCRIPTOR64 is used for full-memory minidumps where +// all of the raw memory is laid out sequentially at the +// end of the dump. There is no need for individual RVAs +// as the RVA is the base RVA plus the sum of the preceeding +// data blocks. +typedef struct _MINIDUMP_MEMORY_DESCRIPTOR64 +{ + ULONG64 StartOfMemoryRange; + ULONG64 DataSize; +} MINIDUMP_MEMORY_DESCRIPTOR64, *PMINIDUMP_MEMORY_DESCRIPTOR64; + + +typedef struct _MINIDUMP_HEADER +{ + ULONG32 Signature; + ULONG32 Version; + ULONG32 NumberOfStreams; + RVA StreamDirectoryRva; + ULONG32 CheckSum; + union + { + ULONG32 Reserved; + ULONG32 TimeDateStamp; + }; + ULONG64 Flags; +} MINIDUMP_HEADER, *PMINIDUMP_HEADER; + +// +// The MINIDUMP_HEADER field StreamDirectoryRva points to +// an array of MINIDUMP_DIRECTORY structures. +// + +typedef struct _MINIDUMP_DIRECTORY +{ + ULONG32 StreamType; + MINIDUMP_LOCATION_DESCRIPTOR Location; +} MINIDUMP_DIRECTORY, *PMINIDUMP_DIRECTORY; + + +typedef struct _MINIDUMP_STRING +{ + ULONG32 Length; // Length in bytes of the string + WCHAR Buffer [0]; // Variable size buffer +} MINIDUMP_STRING, *PMINIDUMP_STRING; + + + +// +// The MINIDUMP_DIRECTORY field StreamType may be one of the following types. +// Types will be added in the future, so if a program reading the minidump +// header encounters a stream type it does not understand it should ignore +// the data altogether. Any tag above LastReservedStream will not be used by +// the system and is reserved for program-specific information. +// + +typedef enum _MINIDUMP_STREAM_TYPE +{ + + UnusedStream = 0, + ReservedStream0 = 1, + ReservedStream1 = 2, + ThreadListStream = 3, + ModuleListStream = 4, + MemoryListStream = 5, + ExceptionStream = 6, + SystemInfoStream = 7, + ThreadExListStream = 8, + Memory64ListStream = 9, + CommentStreamA = 10, + CommentStreamW = 11, + HandleDataStream = 12, + FunctionTableStream = 13, + UnloadedModuleListStream = 14, + MiscInfoStream = 15, + MemoryInfoListStream = 16, + ThreadInfoListStream = 17, + HandleOperationListStream = 18, + TokenStream = 19, + + ceStreamNull = 0x8000, + ceStreamSystemInfo = 0x8001, + ceStreamException = 0x8002, + ceStreamModuleList = 0x8003, + ceStreamProcessList = 0x8004, + ceStreamThreadList = 0x8005, + ceStreamThreadContextList = 0x8006, + ceStreamThreadCallStackList = 0x8007, + ceStreamMemoryVirtualList = 0x8008, + ceStreamMemoryPhysicalList = 0x8009, + ceStreamBucketParameters = 0x800A, + ceStreamProcessModuleMap = 0x800B, + ceStreamDiagnosisList = 0x800C, + + LastReservedStream = 0xffff + +} MINIDUMP_STREAM_TYPE; + + +// +// The minidump system information contains processor and +// Operating System specific information. +// + +// +// CPU information is obtained from one of two places. +// +// 1) On x86 computers, CPU_INFORMATION is obtained from the CPUID +// instruction. You must use the X86 portion of the union for X86 +// computers. +// +// 2) On non-x86 architectures, CPU_INFORMATION is obtained by calling +// IsProcessorFeatureSupported(). +// + +typedef union _CPU_INFORMATION +{ + + // + // X86 platforms use CPUID function to obtain processor information. + // + + struct + { + + // + // CPUID Subfunction 0, register EAX (VendorId [0]), + // EBX (VendorId [1]) and ECX (VendorId [2]). + // + + ULONG32 VendorId [ 3 ]; + + // + // CPUID Subfunction 1, register EAX + // + + ULONG32 VersionInformation; + + // + // CPUID Subfunction 1, register EDX + // + + ULONG32 FeatureInformation; + + + // + // CPUID, Subfunction 80000001, register EBX. This will only + // be obtained if the vendor id is "AuthenticAMD". + // + + ULONG32 AMDExtendedCpuFeatures; + + } X86CpuInfo; + + // + // Non-x86 platforms use processor feature flags. + // + + struct + { + + ULONG64 ProcessorFeatures [ 2 ]; + + } OtherCpuInfo; + +} CPU_INFORMATION, *PCPU_INFORMATION; + +typedef struct _MINIDUMP_SYSTEM_INFO +{ + + // + // ProcessorArchitecture, ProcessorLevel and ProcessorRevision are all + // taken from the SYSTEM_INFO structure obtained by GetSystemInfo( ). + // + + USHORT ProcessorArchitecture; + USHORT ProcessorLevel; + USHORT ProcessorRevision; + + union + { + USHORT Reserved0; + struct + { + UCHAR NumberOfProcessors; + UCHAR ProductType; + }; + }; + + // + // MajorVersion, MinorVersion, BuildNumber, PlatformId and + // CSDVersion are all taken from the OSVERSIONINFO structure + // returned by GetVersionEx( ). + // + + ULONG32 MajorVersion; + ULONG32 MinorVersion; + ULONG32 BuildNumber; + ULONG32 PlatformId; + + // + // RVA to a CSDVersion string in the string table. + // + + RVA CSDVersionRva; + + union + { + ULONG32 Reserved1; + struct + { + USHORT SuiteMask; + USHORT Reserved2; + }; + }; + + CPU_INFORMATION Cpu; + +} MINIDUMP_SYSTEM_INFO, *PMINIDUMP_SYSTEM_INFO; + + +// +// The minidump thread contains standard thread +// information plus an RVA to the memory for this +// thread and an RVA to the CONTEXT structure for +// this thread. +// + + +// +// ThreadId must be 4 bytes on all architectures. +// + +C_ASSERT(sizeof(((PPROCESS_INFORMATION)0)->dwThreadId) == 4); + +typedef struct _MINIDUMP_THREAD +{ + ULONG32 ThreadId; + ULONG32 SuspendCount; + ULONG32 PriorityClass; + ULONG32 Priority; + ULONG64 Teb; + MINIDUMP_MEMORY_DESCRIPTOR Stack; + MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; +} MINIDUMP_THREAD, *PMINIDUMP_THREAD; + +// +// The thread list is a container of threads. +// + +typedef struct _MINIDUMP_THREAD_LIST +{ + ULONG32 NumberOfThreads; + MINIDUMP_THREAD Threads [0]; +} MINIDUMP_THREAD_LIST, *PMINIDUMP_THREAD_LIST; + + +typedef struct _MINIDUMP_THREAD_EX +{ + ULONG32 ThreadId; + ULONG32 SuspendCount; + ULONG32 PriorityClass; + ULONG32 Priority; + ULONG64 Teb; + MINIDUMP_MEMORY_DESCRIPTOR Stack; + MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; + MINIDUMP_MEMORY_DESCRIPTOR BackingStore; +} MINIDUMP_THREAD_EX, *PMINIDUMP_THREAD_EX; + +// +// The thread list is a container of threads. +// + +typedef struct _MINIDUMP_THREAD_EX_LIST +{ + ULONG32 NumberOfThreads; + MINIDUMP_THREAD_EX Threads [0]; +} MINIDUMP_THREAD_EX_LIST, *PMINIDUMP_THREAD_EX_LIST; + + +// +// The MINIDUMP_EXCEPTION is the same as EXCEPTION on Win64. +// + +typedef struct _MINIDUMP_EXCEPTION +{ + ULONG32 ExceptionCode; + ULONG32 ExceptionFlags; + ULONG64 ExceptionRecord; + ULONG64 ExceptionAddress; + ULONG32 NumberParameters; + ULONG32 __unusedAlignment; + ULONG64 ExceptionInformation [ EXCEPTION_MAXIMUM_PARAMETERS ]; +} MINIDUMP_EXCEPTION, *PMINIDUMP_EXCEPTION; + + +// +// The exception information stream contains the id of the thread that caused +// the exception (ThreadId), the exception record for the exception +// (ExceptionRecord) and an RVA to the thread context where the exception +// occured. +// + +typedef struct MINIDUMP_EXCEPTION_STREAM +{ + ULONG32 ThreadId; + ULONG32 __alignment; + MINIDUMP_EXCEPTION ExceptionRecord; + MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; +} MINIDUMP_EXCEPTION_STREAM, *PMINIDUMP_EXCEPTION_STREAM; + + +// +// The MINIDUMP_MODULE contains information about a +// a specific module. It includes the CheckSum and +// the TimeDateStamp for the module so the module +// can be reloaded during the analysis phase. +// + +typedef struct _MINIDUMP_MODULE +{ + ULONG64 BaseOfImage; + ULONG32 SizeOfImage; + ULONG32 CheckSum; + ULONG32 TimeDateStamp; + RVA ModuleNameRva; + VS_FIXEDFILEINFO VersionInfo; + MINIDUMP_LOCATION_DESCRIPTOR CvRecord; + MINIDUMP_LOCATION_DESCRIPTOR MiscRecord; + ULONG64 Reserved0; // Reserved for future use. + ULONG64 Reserved1; // Reserved for future use. +} MINIDUMP_MODULE, *PMINIDUMP_MODULE; + + +// +// The minidump module list is a container for modules. +// + +typedef struct _MINIDUMP_MODULE_LIST +{ + ULONG32 NumberOfModules; + MINIDUMP_MODULE Modules [ 0 ]; +} MINIDUMP_MODULE_LIST, *PMINIDUMP_MODULE_LIST; + + +// +// Memory Ranges +// + +typedef struct _MINIDUMP_MEMORY_LIST +{ + ULONG32 NumberOfMemoryRanges; + MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges [0]; +} MINIDUMP_MEMORY_LIST, *PMINIDUMP_MEMORY_LIST; + +typedef struct _MINIDUMP_MEMORY64_LIST +{ + ULONG64 NumberOfMemoryRanges; + RVA64 BaseRva; + MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges [0]; +} MINIDUMP_MEMORY64_LIST, *PMINIDUMP_MEMORY64_LIST; + + +// +// Support for user supplied exception information. +// + +typedef struct _MINIDUMP_EXCEPTION_INFORMATION +{ + DWORD ThreadId; + PEXCEPTION_POINTERS ExceptionPointers; + BOOL ClientPointers; +} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; + +typedef struct _MINIDUMP_EXCEPTION_INFORMATION64 +{ + DWORD ThreadId; + ULONG64 ExceptionRecord; + ULONG64 ContextRecord; + BOOL ClientPointers; +} MINIDUMP_EXCEPTION_INFORMATION64, *PMINIDUMP_EXCEPTION_INFORMATION64; + + +// +// Support for capturing system handle state at the time of the dump. +// + +// Per-handle object information varies according to +// the OS, the OS version, the processor type and +// so on. The minidump gives a minidump identifier +// to each possible data format for identification +// purposes but does not control nor describe the actual data. +typedef enum _MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE +{ + MiniHandleObjectInformationNone, + MiniThreadInformation1, + MiniMutantInformation1, + MiniMutantInformation2, + MiniProcessInformation1, + MiniProcessInformation2, + MiniHandleObjectInformationTypeMax +} MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE; + +typedef struct _MINIDUMP_HANDLE_OBJECT_INFORMATION +{ + RVA NextInfoRva; + ULONG32 InfoType; + ULONG32 SizeOfInfo; + // Raw information follows. +} MINIDUMP_HANDLE_OBJECT_INFORMATION; + +typedef struct _MINIDUMP_HANDLE_DESCRIPTOR +{ + ULONG64 Handle; + RVA TypeNameRva; + RVA ObjectNameRva; + ULONG32 Attributes; + ULONG32 GrantedAccess; + ULONG32 HandleCount; + ULONG32 PointerCount; +} MINIDUMP_HANDLE_DESCRIPTOR, *PMINIDUMP_HANDLE_DESCRIPTOR; + +typedef struct _MINIDUMP_HANDLE_DESCRIPTOR_2 +{ + ULONG64 Handle; + RVA TypeNameRva; + RVA ObjectNameRva; + ULONG32 Attributes; + ULONG32 GrantedAccess; + ULONG32 HandleCount; + ULONG32 PointerCount; + RVA ObjectInfoRva; + ULONG32 Reserved0; +} MINIDUMP_HANDLE_DESCRIPTOR_2, *PMINIDUMP_HANDLE_DESCRIPTOR_2; + +// The latest MINIDUMP_HANDLE_DESCRIPTOR definition. +typedef MINIDUMP_HANDLE_DESCRIPTOR_2 MINIDUMP_HANDLE_DESCRIPTOR_N; +typedef MINIDUMP_HANDLE_DESCRIPTOR_N* PMINIDUMP_HANDLE_DESCRIPTOR_N; + +typedef struct _MINIDUMP_HANDLE_DATA_STREAM +{ + ULONG32 SizeOfHeader; + ULONG32 SizeOfDescriptor; + ULONG32 NumberOfDescriptors; + ULONG32 Reserved; +} MINIDUMP_HANDLE_DATA_STREAM, *PMINIDUMP_HANDLE_DATA_STREAM; + +// Some operating systems can track the last operations +// performed on a handle. For example, Application Verifier +// can enable this for some versions of Windows. The +// handle operation list collects handle operations +// known for the dump target. +// Each entry is an AVRF_HANDLE_OPERATION. +typedef struct _MINIDUMP_HANDLE_OPERATION_LIST +{ + ULONG32 SizeOfHeader; + ULONG32 SizeOfEntry; + ULONG32 NumberOfEntries; + ULONG32 Reserved; +} MINIDUMP_HANDLE_OPERATION_LIST, *PMINIDUMP_HANDLE_OPERATION_LIST; + + +// +// Support for capturing dynamic function table state at the time of the dump. +// + +typedef struct _MINIDUMP_FUNCTION_TABLE_DESCRIPTOR +{ + ULONG64 MinimumAddress; + ULONG64 MaximumAddress; + ULONG64 BaseAddress; + ULONG32 EntryCount; + ULONG32 SizeOfAlignPad; +} MINIDUMP_FUNCTION_TABLE_DESCRIPTOR, *PMINIDUMP_FUNCTION_TABLE_DESCRIPTOR; + +typedef struct _MINIDUMP_FUNCTION_TABLE_STREAM +{ + ULONG32 SizeOfHeader; + ULONG32 SizeOfDescriptor; + ULONG32 SizeOfNativeDescriptor; + ULONG32 SizeOfFunctionEntry; + ULONG32 NumberOfDescriptors; + ULONG32 SizeOfAlignPad; +} MINIDUMP_FUNCTION_TABLE_STREAM, *PMINIDUMP_FUNCTION_TABLE_STREAM; + + +// +// The MINIDUMP_UNLOADED_MODULE contains information about a +// a specific module that was previously loaded but no +// longer is. This can help with diagnosing problems where +// callers attempt to call code that is no longer loaded. +// + +typedef struct _MINIDUMP_UNLOADED_MODULE +{ + ULONG64 BaseOfImage; + ULONG32 SizeOfImage; + ULONG32 CheckSum; + ULONG32 TimeDateStamp; + RVA ModuleNameRva; +} MINIDUMP_UNLOADED_MODULE, *PMINIDUMP_UNLOADED_MODULE; + + +// +// The minidump unloaded module list is a container for unloaded modules. +// + +typedef struct _MINIDUMP_UNLOADED_MODULE_LIST +{ + ULONG32 SizeOfHeader; + ULONG32 SizeOfEntry; + ULONG32 NumberOfEntries; +} MINIDUMP_UNLOADED_MODULE_LIST, *PMINIDUMP_UNLOADED_MODULE_LIST; + + +// +// The miscellaneous information stream contains a variety +// of small pieces of information. A member is valid if +// it's within the available size and its corresponding +// bit is set. +// + +#define MINIDUMP_MISC1_PROCESS_ID 0x00000001 +#define MINIDUMP_MISC1_PROCESS_TIMES 0x00000002 +#define MINIDUMP_MISC1_PROCESSOR_POWER_INFO 0x00000004 +#define MINIDUMP_MISC3_PROCESS_INTEGRITY 0x00000010 +#define MINIDUMP_MISC3_PROCESS_EXECUTE_FLAGS 0x00000020 +#define MINIDUMP_MISC3_TIMEZONE 0x00000040 +#define MINIDUMP_MISC3_PROTECTED_PROCESS 0x00000080 + +typedef struct _MINIDUMP_MISC_INFO +{ + ULONG32 SizeOfInfo; + ULONG32 Flags1; + ULONG32 ProcessId; + ULONG32 ProcessCreateTime; + ULONG32 ProcessUserTime; + ULONG32 ProcessKernelTime; +} MINIDUMP_MISC_INFO, *PMINIDUMP_MISC_INFO; + +typedef struct _MINIDUMP_MISC_INFO_2 +{ + ULONG32 SizeOfInfo; + ULONG32 Flags1; + ULONG32 ProcessId; + ULONG32 ProcessCreateTime; + ULONG32 ProcessUserTime; + ULONG32 ProcessKernelTime; + ULONG32 ProcessorMaxMhz; + ULONG32 ProcessorCurrentMhz; + ULONG32 ProcessorMhzLimit; + ULONG32 ProcessorMaxIdleState; + ULONG32 ProcessorCurrentIdleState; +} MINIDUMP_MISC_INFO_2, *PMINIDUMP_MISC_INFO_2; + +typedef struct _MINIDUMP_MISC_INFO_3 +{ + ULONG32 SizeOfInfo; + ULONG32 Flags1; + ULONG32 ProcessId; + ULONG32 ProcessCreateTime; + ULONG32 ProcessUserTime; + ULONG32 ProcessKernelTime; + ULONG32 ProcessorMaxMhz; + ULONG32 ProcessorCurrentMhz; + ULONG32 ProcessorMhzLimit; + ULONG32 ProcessorMaxIdleState; + ULONG32 ProcessorCurrentIdleState; + ULONG32 ProcessIntegrityLevel; + ULONG32 ProcessExecuteFlags; + ULONG32 ProtectedProcess; + ULONG32 TimeZoneId; + TIME_ZONE_INFORMATION TimeZone; +} MINIDUMP_MISC_INFO_3, *PMINIDUMP_MISC_INFO_3; + +// The latest MINIDUMP_MISC_INFO definition. +typedef MINIDUMP_MISC_INFO_3 MINIDUMP_MISC_INFO_N; +typedef MINIDUMP_MISC_INFO_N* PMINIDUMP_MISC_INFO_N; + + +// +// The memory information stream contains memory region +// description information. This stream corresponds to +// what VirtualQuery would return for the process the +// dump was created for. +// + +typedef struct _MINIDUMP_MEMORY_INFO +{ + ULONG64 BaseAddress; + ULONG64 AllocationBase; + ULONG32 AllocationProtect; + ULONG32 __alignment1; + ULONG64 RegionSize; + ULONG32 State; + ULONG32 Protect; + ULONG32 Type; + ULONG32 __alignment2; +} MINIDUMP_MEMORY_INFO, *PMINIDUMP_MEMORY_INFO; + +typedef struct _MINIDUMP_MEMORY_INFO_LIST +{ + ULONG SizeOfHeader; + ULONG SizeOfEntry; + ULONG64 NumberOfEntries; +} MINIDUMP_MEMORY_INFO_LIST, *PMINIDUMP_MEMORY_INFO_LIST; + + +// +// The memory information stream contains memory region +// description information. This stream corresponds to +// what VirtualQuery would return for the process the +// dump was created for. +// + +// Thread dump writer status flags. +#define MINIDUMP_THREAD_INFO_ERROR_THREAD 0x00000001 +#define MINIDUMP_THREAD_INFO_WRITING_THREAD 0x00000002 +#define MINIDUMP_THREAD_INFO_EXITED_THREAD 0x00000004 +#define MINIDUMP_THREAD_INFO_INVALID_INFO 0x00000008 +#define MINIDUMP_THREAD_INFO_INVALID_CONTEXT 0x00000010 +#define MINIDUMP_THREAD_INFO_INVALID_TEB 0x00000020 + +typedef struct _MINIDUMP_THREAD_INFO +{ + ULONG32 ThreadId; + ULONG32 DumpFlags; + ULONG32 DumpError; + ULONG32 ExitStatus; + ULONG64 CreateTime; + ULONG64 ExitTime; + ULONG64 KernelTime; + ULONG64 UserTime; + ULONG64 StartAddress; + ULONG64 Affinity; +} MINIDUMP_THREAD_INFO, *PMINIDUMP_THREAD_INFO; + +typedef struct _MINIDUMP_THREAD_INFO_LIST +{ + ULONG SizeOfHeader; + ULONG SizeOfEntry; + ULONG NumberOfEntries; +} MINIDUMP_THREAD_INFO_LIST, *PMINIDUMP_THREAD_INFO_LIST; + +// +// Support for token information. +// +typedef struct _MINIDUMP_TOKEN_INFO_HEADER +{ + ULONG TokenSize; // The size of the token structure. + ULONG TokenId; // The PID in NtOpenProcessToken() call or TID in NtOpenThreadToken() call. + ULONG64 TokenHandle; // The handle value returned. +} MINIDUMP_TOKEN_INFO_HEADER, *PMINIDUMP_TOKEN_INFO_HEADER; + +typedef struct _MINIDUMP_TOKEN_INFO_LIST +{ + ULONG TokenListSize; + ULONG TokenListEntries; + ULONG ListHeaderSize; + ULONG ElementHeaderSize; +} MINIDUMP_TOKEN_INFO_LIST, *PMINIDUMP_TOKEN_INFO_LIST; + +// +// Support for arbitrary user-defined information. +// + +typedef struct _MINIDUMP_USER_RECORD +{ + ULONG32 Type; + MINIDUMP_LOCATION_DESCRIPTOR Memory; +} MINIDUMP_USER_RECORD, *PMINIDUMP_USER_RECORD; + + +typedef struct _MINIDUMP_USER_STREAM +{ + ULONG32 Type; + ULONG BufferSize; + PVOID Buffer; + +} MINIDUMP_USER_STREAM, *PMINIDUMP_USER_STREAM; + + +typedef struct _MINIDUMP_USER_STREAM_INFORMATION +{ + ULONG UserStreamCount; + PMINIDUMP_USER_STREAM UserStreamArray; +} MINIDUMP_USER_STREAM_INFORMATION, *PMINIDUMP_USER_STREAM_INFORMATION; + +// +// Callback support. +// + +typedef enum _MINIDUMP_CALLBACK_TYPE +{ + ModuleCallback, + ThreadCallback, + ThreadExCallback, + IncludeThreadCallback, + IncludeModuleCallback, + MemoryCallback, + CancelCallback, + WriteKernelMinidumpCallback, + KernelMinidumpStatusCallback, + RemoveMemoryCallback, + IncludeVmRegionCallback, + IoStartCallback, + IoWriteAllCallback, + IoFinishCallback, + ReadMemoryFailureCallback, + SecondaryFlagsCallback, +} MINIDUMP_CALLBACK_TYPE; + + +typedef struct _MINIDUMP_THREAD_CALLBACK +{ + ULONG ThreadId; + HANDLE ThreadHandle; + CONTEXT Context; + ULONG SizeOfContext; + ULONG64 StackBase; + ULONG64 StackEnd; +} MINIDUMP_THREAD_CALLBACK, *PMINIDUMP_THREAD_CALLBACK; + + +typedef struct _MINIDUMP_THREAD_EX_CALLBACK +{ + ULONG ThreadId; + HANDLE ThreadHandle; + CONTEXT Context; + ULONG SizeOfContext; + ULONG64 StackBase; + ULONG64 StackEnd; + ULONG64 BackingStoreBase; + ULONG64 BackingStoreEnd; +} MINIDUMP_THREAD_EX_CALLBACK, *PMINIDUMP_THREAD_EX_CALLBACK; + + +typedef struct _MINIDUMP_INCLUDE_THREAD_CALLBACK +{ + ULONG ThreadId; +} MINIDUMP_INCLUDE_THREAD_CALLBACK, *PMINIDUMP_INCLUDE_THREAD_CALLBACK; + + +typedef enum _THREAD_WRITE_FLAGS +{ + ThreadWriteThread = 0x0001, + ThreadWriteStack = 0x0002, + ThreadWriteContext = 0x0004, + ThreadWriteBackingStore = 0x0008, + ThreadWriteInstructionWindow = 0x0010, + ThreadWriteThreadData = 0x0020, + ThreadWriteThreadInfo = 0x0040, +} THREAD_WRITE_FLAGS; + +typedef struct _MINIDUMP_MODULE_CALLBACK +{ + PWCHAR FullPath; + ULONG64 BaseOfImage; + ULONG SizeOfImage; + ULONG CheckSum; + ULONG TimeDateStamp; + VS_FIXEDFILEINFO VersionInfo; + PVOID CvRecord; + ULONG SizeOfCvRecord; + PVOID MiscRecord; + ULONG SizeOfMiscRecord; +} MINIDUMP_MODULE_CALLBACK, *PMINIDUMP_MODULE_CALLBACK; + + +typedef struct _MINIDUMP_INCLUDE_MODULE_CALLBACK +{ + ULONG64 BaseOfImage; +} MINIDUMP_INCLUDE_MODULE_CALLBACK, *PMINIDUMP_INCLUDE_MODULE_CALLBACK; + + +typedef enum _MODULE_WRITE_FLAGS +{ + ModuleWriteModule = 0x0001, + ModuleWriteDataSeg = 0x0002, + ModuleWriteMiscRecord = 0x0004, + ModuleWriteCvRecord = 0x0008, + ModuleReferencedByMemory = 0x0010, + ModuleWriteTlsData = 0x0020, + ModuleWriteCodeSegs = 0x0040, +} MODULE_WRITE_FLAGS; + + +typedef struct _MINIDUMP_IO_CALLBACK +{ + HANDLE Handle; + ULONG64 Offset; + PVOID Buffer; + ULONG BufferBytes; +} MINIDUMP_IO_CALLBACK, *PMINIDUMP_IO_CALLBACK; + + +typedef struct _MINIDUMP_READ_MEMORY_FAILURE_CALLBACK +{ + ULONG64 Offset; + ULONG Bytes; + HRESULT FailureStatus; +} MINIDUMP_READ_MEMORY_FAILURE_CALLBACK, +*PMINIDUMP_READ_MEMORY_FAILURE_CALLBACK; + + +typedef struct _MINIDUMP_CALLBACK_INPUT +{ + ULONG ProcessId; + HANDLE ProcessHandle; + ULONG CallbackType; + union + { + HRESULT Status; + MINIDUMP_THREAD_CALLBACK Thread; + MINIDUMP_THREAD_EX_CALLBACK ThreadEx; + MINIDUMP_MODULE_CALLBACK Module; + MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread; + MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule; + MINIDUMP_IO_CALLBACK Io; + MINIDUMP_READ_MEMORY_FAILURE_CALLBACK ReadMemoryFailure; + ULONG SecondaryFlags; + }; +} MINIDUMP_CALLBACK_INPUT, *PMINIDUMP_CALLBACK_INPUT; + +typedef struct _MINIDUMP_CALLBACK_OUTPUT +{ + union + { + ULONG ModuleWriteFlags; + ULONG ThreadWriteFlags; + ULONG SecondaryFlags; + struct + { + ULONG64 MemoryBase; + ULONG MemorySize; + }; + struct + { + BOOL CheckCancel; + BOOL Cancel; + }; + HANDLE Handle; + struct + { + MINIDUMP_MEMORY_INFO VmRegion; + BOOL Continue; + }; + HRESULT Status; + }; +} MINIDUMP_CALLBACK_OUTPUT, *PMINIDUMP_CALLBACK_OUTPUT; + + +// +// A normal minidump contains just the information +// necessary to capture stack traces for all of the +// existing threads in a process. +// +// A minidump with data segments includes all of the data +// sections from loaded modules in order to capture +// global variable contents. This can make the dump much +// larger if many modules have global data. +// +// A minidump with full memory includes all of the accessible +// memory in the process and can be very large. A minidump +// with full memory always has the raw memory data at the end +// of the dump so that the initial structures in the dump can +// be mapped directly without having to include the raw +// memory information. +// +// Stack and backing store memory can be filtered to remove +// data unnecessary for stack walking. This can improve +// compression of stacks and also deletes data that may +// be private and should not be stored in a dump. +// Memory can also be scanned to see what modules are +// referenced by stack and backing store memory to allow +// omission of other modules to reduce dump size. +// In either of these modes the ModuleReferencedByMemory flag +// is set for all modules referenced before the base +// module callbacks occur. +// +// On some operating systems a list of modules that were +// recently unloaded is kept in addition to the currently +// loaded module list. This information can be saved in +// the dump if desired. +// +// Stack and backing store memory can be scanned for referenced +// pages in order to pick up data referenced by locals or other +// stack memory. This can increase the size of a dump significantly. +// +// Module paths may contain undesired information such as user names +// or other important directory names so they can be stripped. This +// option reduces the ability to locate the proper image later +// and should only be used in certain situations. +// +// Complete operating system per-process and per-thread information can +// be gathered and stored in the dump. +// +// The virtual address space can be scanned for various types +// of memory to be included in the dump. +// +// Code which is concerned with potentially private information +// getting into the minidump can set a flag that automatically +// modifies all existing and future flags to avoid placing +// unnecessary data in the dump. Basic data, such as stack +// information, will still be included but optional data, such +// as indirect memory, will not. +// +// When doing a full memory dump it's possible to store all +// of the enumerated memory region descriptive information +// in a memory information stream. +// +// Additional thread information beyond the basic thread +// structure can be collected if desired. +// +// A minidump with code segments includes all of the code +// and code-related sections from loaded modules in order +// to capture executable content. +// +// MiniDumpWithoutAuxiliaryState turns off any secondary, +// auxiliary-supported memory gathering. +// +// MiniDumpWithFullAuxiliaryState asks any present auxiliary +// data providers to include all of their state in the dump. +// The exact set of what is provided depends on the auxiliary. +// This can be quite large. +// + +typedef enum _MINIDUMP_TYPE +{ + MiniDumpNormal = 0x00000000, + MiniDumpWithDataSegs = 0x00000001, + MiniDumpWithFullMemory = 0x00000002, + MiniDumpWithHandleData = 0x00000004, + MiniDumpFilterMemory = 0x00000008, + MiniDumpScanMemory = 0x00000010, + MiniDumpWithUnloadedModules = 0x00000020, + MiniDumpWithIndirectlyReferencedMemory = 0x00000040, + MiniDumpFilterModulePaths = 0x00000080, + MiniDumpWithProcessThreadData = 0x00000100, + MiniDumpWithPrivateReadWriteMemory = 0x00000200, + MiniDumpWithoutOptionalData = 0x00000400, + MiniDumpWithFullMemoryInfo = 0x00000800, + MiniDumpWithThreadInfo = 0x00001000, + MiniDumpWithCodeSegs = 0x00002000, + MiniDumpWithoutAuxiliaryState = 0x00004000, + MiniDumpWithFullAuxiliaryState = 0x00008000, + MiniDumpWithPrivateWriteCopyMemory = 0x00010000, + MiniDumpIgnoreInaccessibleMemory = 0x00020000, + MiniDumpWithTokenInformation = 0x00040000, + MiniDumpValidTypeFlags = 0x0007ffff, +} MINIDUMP_TYPE; + +// +// In addition to the primary flags provided to +// MiniDumpWriteDump there are additional, less +// frequently used options queried via the secondary +// flags callback. +// +// MiniSecondaryWithoutPowerInfo suppresses the minidump +// query that retrieves processor power information for +// MINIDUMP_MISC_INFO. +// + +typedef enum _MINIDUMP_SECONDARY_FLAGS +{ + MiniSecondaryWithoutPowerInfo = 0x00000001, + + MiniSecondaryValidFlags = 0x00000001, +} MINIDUMP_SECONDARY_FLAGS; + + +// +// The minidump callback should modify the FieldsToWrite parameter to reflect +// what portions of the specified thread or module should be written to the +// file. +// + +typedef +BOOL +(WINAPI* MINIDUMP_CALLBACK_ROUTINE)( + __inout PVOID CallbackParam, + __in PMINIDUMP_CALLBACK_INPUT CallbackInput, + __inout PMINIDUMP_CALLBACK_OUTPUT CallbackOutput +); + +typedef struct _MINIDUMP_CALLBACK_INFORMATION +{ + MINIDUMP_CALLBACK_ROUTINE CallbackRoutine; + PVOID CallbackParam; +} MINIDUMP_CALLBACK_INFORMATION, *PMINIDUMP_CALLBACK_INFORMATION; + + + +//++ +// +// PVOID +// RVA_TO_ADDR( +// PVOID Mapping, +// ULONG Rva +// ) +// +// Routine Description: +// +// Map an RVA that is contained within a mapped file to it's associated +// flat address. +// +// Arguments: +// +// Mapping - Base address of mapped file containing the RVA. +// +// Rva - An Rva to fixup. +// +// Return Values: +// +// A pointer to the desired data. +// +//-- + +#define RVA_TO_ADDR(Mapping,Rva) ((PVOID)(((ULONG_PTR) (Mapping)) + (Rva))) + +BOOL +WINAPI +MiniDumpWriteDump( + __in HANDLE hProcess, + __in DWORD ProcessId, + __in HANDLE hFile, + __in MINIDUMP_TYPE DumpType, + __in_opt PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + __in_opt PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + __in_opt PMINIDUMP_CALLBACK_INFORMATION CallbackParam +); + +BOOL +WINAPI +MiniDumpReadDumpStream( + __in PVOID BaseOfDump, + __in ULONG StreamNumber, + __deref_out_opt PMINIDUMP_DIRECTORY* Dir, + __deref_out_opt PVOID* StreamPointer, + __out_opt ULONG* StreamSize +); + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif + + +#endif // _DBGHELP_ + diff --git a/src/dbg/dbghelp_safe.cpp b/src/dbg/dbghelp_safe.cpp index d81da09d..0680f3f6 100644 --- a/src/dbg/dbghelp_safe.cpp +++ b/src/dbg/dbghelp_safe.cpp @@ -1,159 +1,159 @@ -#include "_global.h" -#include "dbghelp_safe.h" -#include "threading.h" - -DWORD -SafeUnDecorateSymbolName( - __in PCSTR name, - __out_ecount(maxStringLength) PSTR outputString, - __in DWORD maxStringLength, - __in DWORD flags -) -{ - // NOTE: Disabled because of potential recursive deadlocks - // EXCLUSIVE_ACQUIRE(LockSym); - return UnDecorateSymbolName(name, outputString, maxStringLength, flags); -} -BOOL -SafeSymUnloadModule64( - __in HANDLE hProcess, - __in DWORD64 BaseOfDll -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymUnloadModule64(hProcess, BaseOfDll); -} -BOOL -SafeSymSetSearchPathW( - __in HANDLE hProcess, - __in_opt PCWSTR SearchPath -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymSetSearchPathW(hProcess, SearchPath); -} -DWORD -SafeSymSetOptions( - __in DWORD SymOptions -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymSetOptions(SymOptions); -} -BOOL -SafeSymInitializeW( - __in HANDLE hProcess, - __in_opt PCWSTR UserSearchPath, - __in BOOL fInvadeProcess -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymInitializeW(hProcess, UserSearchPath, fInvadeProcess); -} -BOOL -SafeSymRegisterCallback64( - __in HANDLE hProcess, - __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, - __in ULONG64 UserContext -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymRegisterCallback64(hProcess, CallbackFunction, UserContext); -} -DWORD64 -SafeSymLoadModuleEx( - __in HANDLE hProcess, - __in_opt HANDLE hFile, - __in_opt PCSTR ImageName, - __in_opt PCSTR ModuleName, - __in DWORD64 BaseOfDll, - __in DWORD DllSize, - __in_opt PMODLOAD_DATA Data, - __in_opt DWORD Flags -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymLoadModuleEx(hProcess, hFile, ImageName, ModuleName, BaseOfDll, DllSize, Data, Flags); -} -BOOL -SafeSymGetModuleInfo64( - __in HANDLE hProcess, - __in DWORD64 qwAddr, - __out PIMAGEHLP_MODULE64 ModuleInfo -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymGetModuleInfo64(hProcess, qwAddr, ModuleInfo); -} -BOOL -SafeSymGetSearchPathW( - __in HANDLE hProcess, - __out_ecount(SearchPathLength) PWSTR SearchPath, - __in DWORD SearchPathLength -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymGetSearchPathW(hProcess, SearchPath, SearchPathLength); -} -BOOL -SafeSymEnumSymbols( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCSTR Mask, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymEnumSymbols(hProcess, BaseOfDll, Mask, EnumSymbolsCallback, UserContext); -} -BOOL -SafeSymEnumerateModules64( - __in HANDLE hProcess, - __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, - __in_opt PVOID UserContext -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymEnumerateModules64(hProcess, EnumModulesCallback, UserContext); -} -BOOL -SafeSymGetLineFromAddr64( - __in HANDLE hProcess, - __in DWORD64 qwAddr, - __out PDWORD pdwDisplacement, - __out PIMAGEHLP_LINE64 Line64 -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymGetLineFromAddr64(hProcess, qwAddr, pdwDisplacement, Line64); -} -BOOL -SafeSymFromName( - __in HANDLE hProcess, - __in PCSTR Name, - __inout PSYMBOL_INFO Symbol -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymFromName(hProcess, Name, Symbol); -} -BOOL -SafeSymFromAddr( - __in HANDLE hProcess, - __in DWORD64 Address, - __out_opt PDWORD64 Displacement, - __inout PSYMBOL_INFO Symbol -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymFromAddr(hProcess, Address, Displacement, Symbol); -} -BOOL -SafeSymCleanup( - __in HANDLE hProcess -) -{ - EXCLUSIVE_ACQUIRE(LockSym); - return SymCleanup(hProcess); +#include "_global.h" +#include "dbghelp_safe.h" +#include "threading.h" + +DWORD +SafeUnDecorateSymbolName( + __in PCSTR name, + __out_ecount(maxStringLength) PSTR outputString, + __in DWORD maxStringLength, + __in DWORD flags +) +{ + // NOTE: Disabled because of potential recursive deadlocks + // EXCLUSIVE_ACQUIRE(LockSym); + return UnDecorateSymbolName(name, outputString, maxStringLength, flags); +} +BOOL +SafeSymUnloadModule64( + __in HANDLE hProcess, + __in DWORD64 BaseOfDll +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymUnloadModule64(hProcess, BaseOfDll); +} +BOOL +SafeSymSetSearchPathW( + __in HANDLE hProcess, + __in_opt PCWSTR SearchPath +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymSetSearchPathW(hProcess, SearchPath); +} +DWORD +SafeSymSetOptions( + __in DWORD SymOptions +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymSetOptions(SymOptions); +} +BOOL +SafeSymInitializeW( + __in HANDLE hProcess, + __in_opt PCWSTR UserSearchPath, + __in BOOL fInvadeProcess +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymInitializeW(hProcess, UserSearchPath, fInvadeProcess); +} +BOOL +SafeSymRegisterCallback64( + __in HANDLE hProcess, + __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, + __in ULONG64 UserContext +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymRegisterCallback64(hProcess, CallbackFunction, UserContext); +} +DWORD64 +SafeSymLoadModuleEx( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCSTR ImageName, + __in_opt PCSTR ModuleName, + __in DWORD64 BaseOfDll, + __in DWORD DllSize, + __in_opt PMODLOAD_DATA Data, + __in_opt DWORD Flags +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymLoadModuleEx(hProcess, hFile, ImageName, ModuleName, BaseOfDll, DllSize, Data, Flags); +} +BOOL +SafeSymGetModuleInfo64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PIMAGEHLP_MODULE64 ModuleInfo +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymGetModuleInfo64(hProcess, qwAddr, ModuleInfo); +} +BOOL +SafeSymGetSearchPathW( + __in HANDLE hProcess, + __out_ecount(SearchPathLength) PWSTR SearchPath, + __in DWORD SearchPathLength +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymGetSearchPathW(hProcess, SearchPath, SearchPathLength); +} +BOOL +SafeSymEnumSymbols( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCSTR Mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymEnumSymbols(hProcess, BaseOfDll, Mask, EnumSymbolsCallback, UserContext); +} +BOOL +SafeSymEnumerateModules64( + __in HANDLE hProcess, + __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, + __in_opt PVOID UserContext +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymEnumerateModules64(hProcess, EnumModulesCallback, UserContext); +} +BOOL +SafeSymGetLineFromAddr64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINE64 Line64 +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymGetLineFromAddr64(hProcess, qwAddr, pdwDisplacement, Line64); +} +BOOL +SafeSymFromName( + __in HANDLE hProcess, + __in PCSTR Name, + __inout PSYMBOL_INFO Symbol +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymFromName(hProcess, Name, Symbol); +} +BOOL +SafeSymFromAddr( + __in HANDLE hProcess, + __in DWORD64 Address, + __out_opt PDWORD64 Displacement, + __inout PSYMBOL_INFO Symbol +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymFromAddr(hProcess, Address, Displacement, Symbol); +} +BOOL +SafeSymCleanup( + __in HANDLE hProcess +) +{ + EXCLUSIVE_ACQUIRE(LockSym); + return SymCleanup(hProcess); } \ No newline at end of file diff --git a/src/dbg/dbghelp_safe.h b/src/dbg/dbghelp_safe.h index eb0767e0..091f3956 100644 --- a/src/dbg/dbghelp_safe.h +++ b/src/dbg/dbghelp_safe.h @@ -1,105 +1,105 @@ -#ifndef _DBGHELP_SAFE_H -#define _DBGHELP_SAFE_H - -#ifdef __GNUC__ -#include "dbghelp\dbghelp.h" -#else -#include -#endif //__GNUC__ - -DWORD -SafeUnDecorateSymbolName( - __in PCSTR name, - __out_ecount(maxStringLength) PSTR outputString, - __in DWORD maxStringLength, - __in DWORD flags -); -BOOL -SafeSymUnloadModule64( - __in HANDLE hProcess, - __in DWORD64 BaseOfDll -); -BOOL -SafeSymSetSearchPathW( - __in HANDLE hProcess, - __in_opt PCWSTR SearchPath -); -DWORD -SafeSymSetOptions( - __in DWORD SymOptions -); -BOOL -SafeSymInitializeW( - __in HANDLE hProcess, - __in_opt PCWSTR UserSearchPath, - __in BOOL fInvadeProcess -); -BOOL -SafeSymRegisterCallback64( - __in HANDLE hProcess, - __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, - __in ULONG64 UserContext -); -DWORD64 -SafeSymLoadModuleEx( - __in HANDLE hProcess, - __in_opt HANDLE hFile, - __in_opt PCSTR ImageName, - __in_opt PCSTR ModuleName, - __in DWORD64 BaseOfDll, - __in DWORD DllSize, - __in_opt PMODLOAD_DATA Data, - __in_opt DWORD Flags -); -BOOL -SafeSymGetModuleInfo64( - __in HANDLE hProcess, - __in DWORD64 qwAddr, - __out PIMAGEHLP_MODULE64 ModuleInfo -); -BOOL -SafeSymGetSearchPathW( - __in HANDLE hProcess, - __out_ecount(SearchPathLength) PWSTR SearchPath, - __in DWORD SearchPathLength -); -BOOL -SafeSymEnumSymbols( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCSTR Mask, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext -); -BOOL -SafeSymEnumerateModules64( - __in HANDLE hProcess, - __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, - __in_opt PVOID UserContext -); -BOOL -SafeSymGetLineFromAddr64( - __in HANDLE hProcess, - __in DWORD64 qwAddr, - __out PDWORD pdwDisplacement, - __out PIMAGEHLP_LINE64 Line64 -); -BOOL -SafeSymFromName( - __in HANDLE hProcess, - __in PCSTR Name, - __inout PSYMBOL_INFO Symbol -); -BOOL -SafeSymFromAddr( - __in HANDLE hProcess, - __in DWORD64 Address, - __out_opt PDWORD64 Displacement, - __inout PSYMBOL_INFO Symbol -); -BOOL -SafeSymCleanup( - __in HANDLE hProcess -); - +#ifndef _DBGHELP_SAFE_H +#define _DBGHELP_SAFE_H + +#ifdef __GNUC__ +#include "dbghelp\dbghelp.h" +#else +#include +#endif //__GNUC__ + +DWORD +SafeUnDecorateSymbolName( + __in PCSTR name, + __out_ecount(maxStringLength) PSTR outputString, + __in DWORD maxStringLength, + __in DWORD flags +); +BOOL +SafeSymUnloadModule64( + __in HANDLE hProcess, + __in DWORD64 BaseOfDll +); +BOOL +SafeSymSetSearchPathW( + __in HANDLE hProcess, + __in_opt PCWSTR SearchPath +); +DWORD +SafeSymSetOptions( + __in DWORD SymOptions +); +BOOL +SafeSymInitializeW( + __in HANDLE hProcess, + __in_opt PCWSTR UserSearchPath, + __in BOOL fInvadeProcess +); +BOOL +SafeSymRegisterCallback64( + __in HANDLE hProcess, + __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, + __in ULONG64 UserContext +); +DWORD64 +SafeSymLoadModuleEx( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCSTR ImageName, + __in_opt PCSTR ModuleName, + __in DWORD64 BaseOfDll, + __in DWORD DllSize, + __in_opt PMODLOAD_DATA Data, + __in_opt DWORD Flags +); +BOOL +SafeSymGetModuleInfo64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PIMAGEHLP_MODULE64 ModuleInfo +); +BOOL +SafeSymGetSearchPathW( + __in HANDLE hProcess, + __out_ecount(SearchPathLength) PWSTR SearchPath, + __in DWORD SearchPathLength +); +BOOL +SafeSymEnumSymbols( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCSTR Mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext +); +BOOL +SafeSymEnumerateModules64( + __in HANDLE hProcess, + __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, + __in_opt PVOID UserContext +); +BOOL +SafeSymGetLineFromAddr64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINE64 Line64 +); +BOOL +SafeSymFromName( + __in HANDLE hProcess, + __in PCSTR Name, + __inout PSYMBOL_INFO Symbol +); +BOOL +SafeSymFromAddr( + __in HANDLE hProcess, + __in DWORD64 Address, + __out_opt PDWORD64 Displacement, + __inout PSYMBOL_INFO Symbol +); +BOOL +SafeSymCleanup( + __in HANDLE hProcess +); + #endif //_DBGHELP_SAFE_H \ No newline at end of file diff --git a/src/dbg/debugger.cpp b/src/dbg/debugger.cpp index df38bedf..d19a6fa1 100644 --- a/src/dbg/debugger.cpp +++ b/src/dbg/debugger.cpp @@ -1,1763 +1,1763 @@ -/** - @file debugger.cpp - - @brief Implements the debugger class. - */ - -#include "debugger.h" -#include "console.h" -#include "memory.h" -#include "threading.h" -#include "command.h" -#include "database.h" -#include "addrinfo.h" -#include "thread.h" -#include "plugin_loader.h" -#include "breakpoint.h" -#include "symbolinfo.h" -#include "variable.h" -#include "x64_dbg.h" -#include "exception.h" -#include "error.h" -#include "module.h" - -static PROCESS_INFORMATION g_pi = {0, 0, 0, 0}; -static char szBaseFileName[MAX_PATH] = ""; -static bool bFileIsDll = false; -static duint pDebuggedBase = 0; -static duint pCreateProcessBase = 0; -static duint pDebuggedEntry = 0; -static bool isStepping = false; -static bool isPausedByUser = false; -static bool isDetachedByUser = false; -static bool bIsAttached = false; -static bool bSkipExceptions = false; -static bool bBreakOnNextDll = false; -static bool bFreezeStack = false; -static int ecount = 0; -static std::vector ignoredExceptionRange; -static HANDLE hEvent = 0; -static HANDLE hProcess = 0; -static HANDLE hMemMapThread = 0; -static bool bStopMemMapThread = false; -static HANDLE hTimeWastedCounterThread = 0; -static bool bStopTimeWastedCounterThread = false; -static String lastDebugText; -static duint timeWastedDebugging = 0; -char szFileName[MAX_PATH] = ""; -char szSymbolCachePath[MAX_PATH] = ""; -char sqlitedb[deflen] = ""; -PROCESS_INFORMATION* fdProcessInfo = &g_pi; -HANDLE hActiveThread; -bool bUndecorateSymbolNames = true; -bool bEnableSourceDebugging = true; - -static DWORD WINAPI memMapThread(void* ptr) -{ - while(!bStopMemMapThread) - { - while(!DbgIsDebugging()) - { - if(bStopMemMapThread) - break; - Sleep(1); - } - if(bStopMemMapThread) - break; - MemUpdateMap(); - GuiUpdateMemoryView(); - Sleep(1000); - } - return 0; -} - -static DWORD WINAPI timeWastedCounterThread(void* ptr) -{ - if(!BridgeSettingGetUint("Engine", "TimeWastedDebugging", &timeWastedDebugging)) - timeWastedDebugging = 0; - GuiUpdateTimeWastedCounter(); - while(!bStopTimeWastedCounterThread) - { - while(!DbgIsDebugging()) - { - if(bStopTimeWastedCounterThread) - break; - Sleep(1); - } - if(bStopTimeWastedCounterThread) - break; - timeWastedDebugging++; - GuiUpdateTimeWastedCounter(); - Sleep(1000); - } - BridgeSettingSetUint("Engine", "TimeWastedDebugging", timeWastedDebugging); - return 0; -} - -void dbginit() -{ - ExceptionCodeInit(); - ErrorCodeInit(); - hMemMapThread = CreateThread(nullptr, 0, memMapThread, nullptr, 0, nullptr); - hTimeWastedCounterThread = CreateThread(nullptr, 0, timeWastedCounterThread, nullptr, 0, nullptr); -} - -void dbgstop() -{ - bStopMemMapThread = true; - bStopTimeWastedCounterThread = true; - WaitForThreadTermination(hMemMapThread); - WaitForThreadTermination(hTimeWastedCounterThread); -} - -duint dbgdebuggedbase() -{ - return pDebuggedBase; -} - -duint dbggettimewastedcounter() -{ - return timeWastedDebugging; -} - -bool dbgisrunning() -{ - return !waitislocked(WAITID_RUN); -} - -bool dbgisdll() -{ - return bFileIsDll; -} - -void dbgsetattachevent(HANDLE handle) -{ - hEvent = handle; -} - -void dbgsetskipexceptions(bool skip) -{ - bSkipExceptions = skip; -} - -void dbgsetstepping(bool stepping) -{ - isStepping = stepping; -} - -void dbgsetispausedbyuser(bool b) -{ - isPausedByUser = b; -} - -void dbgsetisdetachedbyuser(bool b) -{ - isDetachedByUser = b; -} - -void dbgsetfreezestack(bool freeze) -{ - bFreezeStack = freeze; -} - -void dbgclearignoredexceptions() -{ - ignoredExceptionRange.clear(); -} - -void dbgaddignoredexception(ExceptionRange range) -{ - ignoredExceptionRange.push_back(range); -} - -bool dbgisignoredexception(unsigned int exception) -{ - for(unsigned int i = 0; i < ignoredExceptionRange.size(); i++) - { - unsigned int curStart = ignoredExceptionRange.at(i).start; - unsigned int curEnd = ignoredExceptionRange.at(i).end; - if(exception >= curStart && exception <= curEnd) - return true; - } - return false; -} - -bool dbgcmdnew(const char* name, CBCOMMAND cbCommand, bool debugonly) -{ - if(!cmdnew(name, cbCommand, debugonly)) - return false; - GuiAutoCompleteAddCmd(name); - return true; -} - -bool dbgcmddel(const char* name) -{ - if(!cmddel(name)) - return false; - GuiAutoCompleteDelCmd(name); - return true; -} - -DWORD WINAPI updateCallStackThread(void* ptr) -{ - GuiUpdateCallStack(); - return 0; -} - -void DebugUpdateGui(duint disasm_addr, bool stack) -{ - duint cip = GetContextDataEx(hActiveThread, UE_CIP); - if(MemIsValidReadPtr(disasm_addr)) - { - if(bEnableSourceDebugging) - { - char szSourceFile[MAX_STRING_SIZE] = ""; - int line = 0; - if(SymGetSourceLine(cip, szSourceFile, &line)) - GuiLoadSourceFile(szSourceFile, line); - } - GuiDisasmAt(disasm_addr, cip); - } - duint csp = GetContextDataEx(hActiveThread, UE_CSP); - if(stack) - DebugUpdateStack(csp, csp); - static duint cacheCsp = 0; - if(csp != cacheCsp) - { - cacheCsp = csp; - CloseHandle(CreateThread(0, 0, updateCallStackThread, 0, 0, 0)); - } - char modname[MAX_MODULE_SIZE] = ""; - char modtext[MAX_MODULE_SIZE * 2] = ""; - if(!ModNameFromAddr(disasm_addr, modname, true)) - *modname = 0; - else - sprintf(modtext, "Module: %s - ", modname); - char title[1024] = ""; - sprintf(title, "File: %s - PID: %X - %sThread: %X", szBaseFileName, fdProcessInfo->dwProcessId, modtext, ThreadGetId(hActiveThread)); - GuiUpdateWindowTitle(title); - GuiUpdateAllViews(); -} - -void DebugUpdateStack(duint dumpAddr, duint csp, bool forceDump) -{ - if (!forceDump && bFreezeStack) - { - SELECTIONDATA selection; - if (GuiSelectionGet(GUI_STACK, &selection)) - dumpAddr = selection.view; - } - GuiStackDumpAt(dumpAddr, csp); -} - -void cbUserBreakpoint() -{ - hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); - BREAKPOINT bp; - BRIDGEBP pluginBp; - PLUG_CB_BREAKPOINT bpInfo; - bpInfo.breakpoint = 0; - if(!BpGet(GetContextDataEx(hActiveThread, UE_CIP), BPNORMAL, 0, &bp) && bp.enabled) - dputs("Breakpoint reached not in list!"); - else - { - const char* bptype = "INT3"; - int titantype = bp.titantype; - if((titantype & UE_BREAKPOINT_TYPE_UD2) == UE_BREAKPOINT_TYPE_UD2) - bptype = "UD2"; - else if((titantype & UE_BREAKPOINT_TYPE_LONG_INT3) == UE_BREAKPOINT_TYPE_LONG_INT3) - bptype = "LONG INT3"; - const char* symbolicname = SymGetSymbolicName(bp.addr); - if(symbolicname) - { - if(*bp.name) - dprintf("%s breakpoint \"%s\" at %s (" fhex ")!\n", bptype, bp.name, symbolicname, bp.addr); - else - dprintf("%s breakpoint at %s (" fhex ")!\n", bptype, symbolicname, bp.addr); - } - else - { - if(*bp.name) - dprintf("%s breakpoint \"%s\" at " fhex "!\n", bptype, bp.name, bp.addr); - else - dprintf("%s breakpoint at " fhex "!\n", bptype, bp.addr); - } - if(bp.singleshoot) - BpDelete(bp.addr, BPNORMAL); - BpToBridge(&bp, &pluginBp); - bpInfo.breakpoint = &pluginBp; - } - GuiSetDebugState(paused); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - bSkipExceptions = false; - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - plugincbcall(CB_BREAKPOINT, &bpInfo); - wait(WAITID_RUN); -} - -void cbHardwareBreakpoint(void* ExceptionAddress) -{ - hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); - duint cip = GetContextDataEx(hActiveThread, UE_CIP); - BREAKPOINT bp; - BRIDGEBP pluginBp; - PLUG_CB_BREAKPOINT bpInfo; - bpInfo.breakpoint = 0; - if(!BpGet((duint)ExceptionAddress, BPHARDWARE, 0, &bp)) - dputs("Hardware breakpoint reached not in list!"); - else - { - const char* bpsize = ""; - switch(TITANGETSIZE(bp.titantype)) //size - { - case UE_HARDWARE_SIZE_1: - bpsize = "byte, "; - break; - case UE_HARDWARE_SIZE_2: - bpsize = "word, "; - break; - case UE_HARDWARE_SIZE_4: - bpsize = "dword, "; - break; -#ifdef _WIN64 - case UE_HARDWARE_SIZE_8: - bpsize = "qword, "; - break; -#endif //_WIN64 - } - const char* bptype = ""; - switch(TITANGETTYPE(bp.titantype)) //type - { - case UE_HARDWARE_EXECUTE: - bptype = "execute"; - bpsize = ""; - break; - case UE_HARDWARE_READWRITE: - bptype = "read/write"; - break; - case UE_HARDWARE_WRITE: - bptype = "write"; - break; - } - const char* symbolicname = SymGetSymbolicName(bp.addr); - if(symbolicname) - { - if(*bp.name) - dprintf("Hardware breakpoint (%s%s) \"%s\" at %s (" fhex ")!\n", bpsize, bptype, bp.name, symbolicname, bp.addr); - else - dprintf("Hardware breakpoint (%s%s) at %s (" fhex ")!\n", bpsize, bptype, symbolicname, bp.addr); - } - else - { - if(*bp.name) - dprintf("Hardware breakpoint (%s%s) \"%s\" at " fhex "!\n", bpsize, bptype, bp.name, bp.addr); - else - dprintf("Hardware breakpoint (%s%s) at " fhex "!\n", bpsize, bptype, bp.addr); - } - BpToBridge(&bp, &pluginBp); - bpInfo.breakpoint = &pluginBp; - } - GuiSetDebugState(paused); - DebugUpdateGui(cip, true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - bSkipExceptions = false; - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - plugincbcall(CB_BREAKPOINT, &bpInfo); - wait(WAITID_RUN); -} - -void cbMemoryBreakpoint(void* ExceptionAddress) -{ - hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); - duint cip = GetContextDataEx(hActiveThread, UE_CIP); - duint size; - duint base = MemFindBaseAddr((duint)ExceptionAddress, &size, true); - BREAKPOINT bp; - BRIDGEBP pluginBp; - PLUG_CB_BREAKPOINT bpInfo; - bpInfo.breakpoint = 0; - if(!BpGet(base, BPMEMORY, 0, &bp)) - dputs("Memory breakpoint reached not in list!"); - else - { - const char* bptype = ""; - switch(bp.titantype) - { - case UE_MEMORY_READ: - bptype = " (read)"; - break; - case UE_MEMORY_WRITE: - bptype = " (write)"; - break; - case UE_MEMORY_EXECUTE: - bptype = " (execute)"; - break; - case UE_MEMORY: - bptype = " (read/write/execute)"; - break; - } - const char* symbolicname = SymGetSymbolicName(bp.addr); - if(symbolicname) - { - if(*bp.name) - dprintf("Memory breakpoint%s \"%s\" at %s (" fhex ", " fhex ")!\n", bptype, bp.name, symbolicname, bp.addr, ExceptionAddress); - else - dprintf("Memory breakpoint%s at %s (" fhex ", " fhex ")!\n", bptype, symbolicname, bp.addr, ExceptionAddress); - } - else - { - if(*bp.name) - dprintf("Memory breakpoint%s \"%s\" at " fhex " (" fhex ")!\n", bptype, bp.name, bp.addr, ExceptionAddress); - else - dprintf("Memory breakpoint%s at " fhex " (" fhex ")!\n", bptype, bp.addr, ExceptionAddress); - } - BpToBridge(&bp, &pluginBp); - bpInfo.breakpoint = &pluginBp; - } - if(bp.singleshoot) - BpDelete(bp.addr, BPMEMORY); //delete from breakpoint list - GuiSetDebugState(paused); - DebugUpdateGui(cip, true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - bSkipExceptions = false; - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - plugincbcall(CB_BREAKPOINT, &bpInfo); - wait(WAITID_RUN); -} - -void cbLibrarianBreakpoint(void* lpData) -{ - bBreakOnNextDll = true; -} - -static BOOL CALLBACK SymRegisterCallbackProc64(HANDLE hProcess, ULONG ActionCode, ULONG64 CallbackData, ULONG64 UserContext) -{ - UNREFERENCED_PARAMETER(hProcess); - UNREFERENCED_PARAMETER(UserContext); - PIMAGEHLP_CBA_EVENT evt; - switch(ActionCode) - { - case CBA_EVENT: - { - evt = (PIMAGEHLP_CBA_EVENT)CallbackData; - const char* text = (const char*)evt->desc; - if(strstr(text, "Successfully received a response from the server.")) - break; - if(strstr(text, "Waiting for the server to respond to a request.")) - break; - int len = (int)strlen(text); - bool suspress = false; - for(int i = 0; i < len; i++) - if(text[i] == 0x08) - { - suspress = true; - break; - } - int percent = 0; - static bool zerobar = false; - if(zerobar) - { - zerobar = false; - GuiSymbolSetProgress(0); - } - if(strstr(text, " bytes - ")) - { - Memory newtext(len + 1, "SymRegisterCallbackProc64:newtext"); - strcpy_s(newtext(), len + 1, text); - strstr(newtext(), " bytes - ")[8] = 0; - GuiSymbolLogAdd(newtext()); - suspress = true; - } - else if(strstr(text, " copied ")) - { - GuiSymbolSetProgress(100); - GuiSymbolLogAdd(" downloaded!\n"); - suspress = true; - zerobar = true; - } - else if(sscanf(text, "%*s %d percent", &percent) == 1 || sscanf(text, "%d percent", &percent) == 1) - { - GuiSymbolSetProgress(percent); - suspress = true; - } - - if(!suspress) - GuiSymbolLogAdd(text); - } - break; - - case CBA_DEBUG_INFO: - { - GuiSymbolLogAdd((const char*)CallbackData); - } - break; - - default: - { - return FALSE; - } - } - return TRUE; -} - -bool cbSetModuleBreakpoints(const BREAKPOINT* bp) -{ - if(!bp->enabled) - return true; - switch(bp->type) - { - case BPNORMAL: - { - if(!SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint)) - dprintf("Could not set breakpoint " fhex "! (SetBPX)\n", bp->addr); - } - break; - - case BPMEMORY: - { - duint size = 0; - MemFindBaseAddr(bp->addr, &size); - if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, (void*)cbMemoryBreakpoint)) - dprintf("Could not set memory breakpoint " fhex "! (SetMemoryBPXEx)\n", bp->addr); - } - break; - - case BPHARDWARE: - { - DWORD drx = 0; - if(!GetUnusedHardwareBreakPointRegister(&drx)) - { - dputs("You can only set 4 hardware breakpoints"); - return false; - } - int titantype = bp->titantype; - TITANSETDRX(titantype, drx); - BpSetTitanType(bp->addr, BPHARDWARE, titantype); - if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), (void*)cbHardwareBreakpoint)) - dprintf("Could not set hardware breakpoint " fhex "! (SetHardwareBreakPoint)\n", bp->addr); - } - break; - - default: - break; - } - return true; -} - -static bool cbRemoveModuleBreakpoints(const BREAKPOINT* bp) -{ - if(!bp->enabled) - return true; - switch(bp->type) - { - case BPNORMAL: - if(!DeleteBPX(bp->addr)) - dprintf("Could not delete breakpoint " fhex "! (DeleteBPX)\n", bp->addr); - break; - case BPMEMORY: - if(!RemoveMemoryBPX(bp->addr, 0)) - dprintf("Could not delete memory breakpoint " fhex "! (RemoveMemoryBPX)\n", bp->addr); - break; - case BPHARDWARE: - if(!DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype))) - dprintf("Could not delete hardware breakpoint " fhex "! (DeleteHardwareBreakPoint)\n", bp->addr); - break; - default: - break; - } - return true; -} - -void cbStep() -{ - hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); - isStepping = false; - GuiSetDebugState(paused); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - PLUG_CB_STEPPED stepInfo; - stepInfo.reserved = 0; - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - bSkipExceptions = false; - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - plugincbcall(CB_STEPPED, &stepInfo); - wait(WAITID_RUN); -} - -static void cbRtrFinalStep() -{ - hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); - GuiSetDebugState(paused); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - bSkipExceptions = false; - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - wait(WAITID_RUN); -} - -static unsigned char getCIPch() -{ - unsigned char ch = 0x90; - duint cip = GetContextDataEx(hActiveThread, UE_CIP); - MemRead(cip, &ch, 1); - return ch; -} - -void cbRtrStep() -{ - unsigned int cipch = getCIPch(); - if(cipch == 0xC3 || cipch == 0xC2) - cbRtrFinalStep(); - else - StepOver((void*)cbRtrStep); -} - -static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo) -{ - void* base = CreateProcessInfo->lpBaseOfImage; - - char DebugFileName[deflen] = ""; - if(!GetFileNameFromHandle(CreateProcessInfo->hFile, DebugFileName)) - strcpy_s(DebugFileName, "??? (GetFileNameFromHandle failed!)"); - dprintf("Process Started: " fhex " %s\n", base, DebugFileName); - - //update memory map - MemUpdateMap(); - GuiUpdateMemoryView(); - - GuiDumpAt(MemFindBaseAddr(GetContextData(UE_CIP), 0) + PAGE_SIZE); //dump somewhere - - // Init program database - DBSetPath(nullptr, szFileName); - DBLoad(); - - SafeSymSetOptions(SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS | SYMOPT_FAVOR_COMPRESSED | SYMOPT_IGNORE_NT_SYMPATH); - GuiSymbolLogClear(); - char szServerSearchPath[MAX_PATH * 2] = ""; - sprintf_s(szServerSearchPath, "SRV*%s", szSymbolCachePath); - SafeSymInitializeW(fdProcessInfo->hProcess, StringUtils::Utf8ToUtf16(szServerSearchPath).c_str(), false); //initialize symbols - SafeSymRegisterCallback64(fdProcessInfo->hProcess, SymRegisterCallbackProc64, 0); - SafeSymLoadModuleEx(fdProcessInfo->hProcess, CreateProcessInfo->hFile, DebugFileName, 0, (DWORD64)base, 0, 0, 0); - - IMAGEHLP_MODULE64 modInfo; - memset(&modInfo, 0, sizeof(modInfo)); - modInfo.SizeOfStruct = sizeof(modInfo); - if(SafeSymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo)) - ModLoad((duint)base, modInfo.ImageSize, modInfo.ImageName); - - char modname[256] = ""; - if(ModNameFromAddr((duint)base, modname, true)) - BpEnumAll(cbSetModuleBreakpoints, modname); - GuiUpdateBreakpointsView(); - pCreateProcessBase = (duint)CreateProcessInfo->lpBaseOfImage; - if(!bFileIsDll && !bIsAttached) //Set entry breakpoint - { - pDebuggedBase = pCreateProcessBase; //debugged base = executable - char command[256] = ""; - - if(settingboolget("Events", "TlsCallbacks")) - { - DWORD NumberOfCallBacks = 0; - TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, &NumberOfCallBacks); - if(NumberOfCallBacks) - { - dprintf("TLS Callbacks: %d\n", NumberOfCallBacks); - Memory TLSCallBacks(NumberOfCallBacks * sizeof(duint), "cbCreateProcess:TLSCallBacks"); - if(!TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), TLSCallBacks(), &NumberOfCallBacks)) - dputs("Failed to get TLS callback addresses!"); - else - { - duint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, UE_IMAGEBASE); - int invalidCount = 0; - for(unsigned int i = 0; i < NumberOfCallBacks; i++) - { - duint callbackVA = TLSCallBacks()[i] - ImageBase + pDebuggedBase; - if(MemIsValidReadPtr(callbackVA)) - { - sprintf(command, "bp " fhex ",\"TLS Callback %d\",ss", callbackVA, i + 1); - cmddirectexec(command); - } - else - invalidCount++; - } - if(invalidCount) - dprintf("%d invalid TLS callback addresses...\n", invalidCount); - } - } - } - - if(settingboolget("Events", "EntryBreakpoint")) - { - sprintf(command, "bp " fhex ",\"entry breakpoint\",ss", (duint)CreateProcessInfo->lpStartAddress); - cmddirectexec(command); - } - } - GuiUpdateBreakpointsView(); - - //call plugin callback - PLUG_CB_CREATEPROCESS callbackInfo; - callbackInfo.CreateProcessInfo = CreateProcessInfo; - callbackInfo.modInfo = &modInfo; - callbackInfo.DebugFileName = DebugFileName; - callbackInfo.fdProcessInfo = fdProcessInfo; - plugincbcall(CB_CREATEPROCESS, &callbackInfo); - - //update thread list - CREATE_THREAD_DEBUG_INFO threadInfo; - threadInfo.hThread = CreateProcessInfo->hThread; - threadInfo.lpStartAddress = CreateProcessInfo->lpStartAddress; - threadInfo.lpThreadLocalBase = CreateProcessInfo->lpThreadLocalBase; - ThreadCreate(&threadInfo); -} - -static void cbExitProcess(EXIT_PROCESS_DEBUG_INFO* ExitProcess) -{ - dprintf("Process stopped with exit code 0x%X\n", ExitProcess->dwExitCode); - PLUG_CB_EXITPROCESS callbackInfo; - callbackInfo.ExitProcess = ExitProcess; - plugincbcall(CB_EXITPROCESS, &callbackInfo); - //unload main module - SafeSymUnloadModule64(fdProcessInfo->hProcess, pCreateProcessBase); -} - -static void cbCreateThread(CREATE_THREAD_DEBUG_INFO* CreateThread) -{ - ThreadCreate(CreateThread); //update thread list - DWORD dwThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId; - hActiveThread = ThreadGetHandle(dwThreadId); - - if(settingboolget("Events", "ThreadEntry")) - { - char command[256] = ""; - sprintf(command, "bp " fhex ",\"Thread %X\",ss", (duint)CreateThread->lpStartAddress, dwThreadId); - cmddirectexec(command); - } - - PLUG_CB_CREATETHREAD callbackInfo; - callbackInfo.CreateThread = CreateThread; - callbackInfo.dwThreadId = dwThreadId; - plugincbcall(CB_CREATETHREAD, &callbackInfo); - - dprintf("Thread %X created\n", dwThreadId); - - if(settingboolget("Events", "ThreadStart")) - { - //update memory map - MemUpdateMap(); - //update GUI - GuiSetDebugState(paused); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - wait(WAITID_RUN); - } -} - -static void cbExitThread(EXIT_THREAD_DEBUG_INFO* ExitThread) -{ - hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); - DWORD dwThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId; - PLUG_CB_EXITTHREAD callbackInfo; - callbackInfo.ExitThread = ExitThread; - callbackInfo.dwThreadId = dwThreadId; - plugincbcall(CB_EXITTHREAD, &callbackInfo); - ThreadExit(dwThreadId); - dprintf("Thread %X exit\n", dwThreadId); - - if(settingboolget("Events", "ThreadEnd")) - { - //update GUI - GuiSetDebugState(paused); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - wait(WAITID_RUN); - } -} - -static void cbSystemBreakpoint(void* ExceptionData) -{ - hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); - - duint cip = GetContextDataEx(hActiveThread, UE_CIP); - GuiDumpAt(MemFindBaseAddr(cip, 0, true)); //dump somewhere - - //log message - if(bIsAttached) - dputs("Attach breakpoint reached!"); - else - dputs("System breakpoint reached!"); - bSkipExceptions = false; //we are not skipping first-chance exceptions - - //plugin callbacks - PLUG_CB_SYSTEMBREAKPOINT callbackInfo; - callbackInfo.reserved = 0; - plugincbcall(CB_SYSTEMBREAKPOINT, &callbackInfo); - - if(bIsAttached ? settingboolget("Events", "AttachBreakpoint") : settingboolget("Events", "SystemBreakpoint")) - { - //update GUI - GuiSetDebugState(paused); - DebugUpdateGui(cip, true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - wait(WAITID_RUN); - } -} - -static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll) -{ - hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); - void* base = LoadDll->lpBaseOfDll; - - char DLLDebugFileName[deflen] = ""; - if(!GetFileNameFromHandle(LoadDll->hFile, DLLDebugFileName)) - strcpy_s(DLLDebugFileName, "??? (GetFileNameFromHandle failed!)"); - - SafeSymLoadModuleEx(fdProcessInfo->hProcess, LoadDll->hFile, DLLDebugFileName, 0, (DWORD64)base, 0, 0, 0); - IMAGEHLP_MODULE64 modInfo; - memset(&modInfo, 0, sizeof(modInfo)); - modInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); - if(SafeSymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo)) - ModLoad((duint)base, modInfo.ImageSize, modInfo.ImageName); - - //update memory map - MemUpdateMap(); - GuiUpdateMemoryView(); - - char modname[256] = ""; - if(ModNameFromAddr((duint)base, modname, true)) - BpEnumAll(cbSetModuleBreakpoints, modname); - GuiUpdateBreakpointsView(); - bool bAlreadySetEntry = false; - - char command[256] = ""; - bool bIsDebuggingThis = false; - if(bFileIsDll && !_stricmp(DLLDebugFileName, szFileName) && !bIsAttached) //Set entry breakpoint - { - bIsDebuggingThis = true; - pDebuggedBase = (duint)base; - if(settingboolget("Events", "EntryBreakpoint")) - { - bAlreadySetEntry = true; - sprintf(command, "bp " fhex ",\"entry breakpoint\",ss", pDebuggedBase + pDebuggedEntry); - cmddirectexec(command); - } - } - GuiUpdateBreakpointsView(); - - if(settingboolget("Events", "TlsCallbacks")) - { - DWORD NumberOfCallBacks = 0; - TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), 0, &NumberOfCallBacks); - if(NumberOfCallBacks) - { - dprintf("TLS Callbacks: %d\n", NumberOfCallBacks); - Memory TLSCallBacks(NumberOfCallBacks * sizeof(duint), "cbLoadDll:TLSCallBacks"); - if(!TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), TLSCallBacks(), &NumberOfCallBacks)) - dputs("Failed to get TLS callback addresses!"); - else - { - duint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), 0, UE_IMAGEBASE); - int invalidCount = 0; - for(unsigned int i = 0; i < NumberOfCallBacks; i++) - { - duint callbackVA = TLSCallBacks()[i] - ImageBase + (duint)base; - if(MemIsValidReadPtr(callbackVA)) - { - if(bIsDebuggingThis) - sprintf(command, "bp " fhex ",\"TLS Callback %d\",ss", callbackVA, i + 1); - else - sprintf(command, "bp " fhex ",\"TLS Callback %d (%s)\",ss", callbackVA, i + 1, modname); - cmddirectexec(command); - } - else - invalidCount++; - } - if(invalidCount) - dprintf("%s invalid TLS callback addresses...\n", invalidCount); - } - } - } - - if((bBreakOnNextDll || settingboolget("Events", "DllEntry")) && !bAlreadySetEntry) - { - duint oep = GetPE32Data(DLLDebugFileName, 0, UE_OEP); - if(oep) - { - char command[256] = ""; - sprintf(command, "bp " fhex ",\"DllMain (%s)\",ss", oep + (duint)base, modname); - cmddirectexec(command); - } - } - - dprintf("DLL Loaded: " fhex " %s\n", base, DLLDebugFileName); - - //plugin callback - PLUG_CB_LOADDLL callbackInfo; - callbackInfo.LoadDll = LoadDll; - callbackInfo.modInfo = &modInfo; - callbackInfo.modname = modname; - plugincbcall(CB_LOADDLL, &callbackInfo); - - if(bBreakOnNextDll || settingboolget("Events", "DllLoad")) - { - bBreakOnNextDll = false; - //update GUI - GuiSetDebugState(paused); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - wait(WAITID_RUN); - } -} - -static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll) -{ - hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); - PLUG_CB_UNLOADDLL callbackInfo; - callbackInfo.UnloadDll = UnloadDll; - plugincbcall(CB_UNLOADDLL, &callbackInfo); - - void* base = UnloadDll->lpBaseOfDll; - char modname[256] = "???"; - if(ModNameFromAddr((duint)base, modname, true)) - BpEnumAll(cbRemoveModuleBreakpoints, modname); - GuiUpdateBreakpointsView(); - SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)base); - dprintf("DLL Unloaded: " fhex " %s\n", base, modname); - - if(bBreakOnNextDll || settingboolget("Events", "DllUnload")) - { - bBreakOnNextDll = false; - //update GUI - GuiSetDebugState(paused); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - wait(WAITID_RUN); - } - - ModUnload((duint)base); - - //update memory map - MemUpdateMap(); - GuiUpdateMemoryView(); -} - -static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString) -{ - - hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); - PLUG_CB_OUTPUTDEBUGSTRING callbackInfo; - callbackInfo.DebugString = DebugString; - plugincbcall(CB_OUTPUTDEBUGSTRING, &callbackInfo); - - if(!DebugString->fUnicode) //ASCII - { - Memory DebugText(DebugString->nDebugStringLength + 1, "cbOutputDebugString:DebugText"); - if(MemRead((duint)DebugString->lpDebugStringData, DebugText(), DebugString->nDebugStringLength)) - { - String str = String(DebugText()); - if(str != lastDebugText) //fix for every string being printed twice - { - if(str != "\n") - dprintf("DebugString: \"%s\"\n", StringUtils::Escape(str).c_str()); - lastDebugText = str; - } - else - lastDebugText.clear(); - } - } - - if(settingboolget("Events", "DebugStrings")) - { - //update GUI - GuiSetDebugState(paused); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - wait(WAITID_RUN); - } -} - -static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData) -{ - hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); - PLUG_CB_EXCEPTION callbackInfo; - callbackInfo.Exception = ExceptionData; - unsigned int ExceptionCode = ExceptionData->ExceptionRecord.ExceptionCode; - GuiSetLastException(ExceptionCode); - - duint addr = (duint)ExceptionData->ExceptionRecord.ExceptionAddress; - if(ExceptionData->ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) - { - if(isDetachedByUser) - { - PLUG_CB_DETACH detachInfo; - detachInfo.fdProcessInfo = fdProcessInfo; - plugincbcall(CB_DETACH, &detachInfo); - if(!DetachDebuggerEx(fdProcessInfo->dwProcessId)) - dputs("DetachDebuggerEx failed..."); - else - dputs("Detached!"); - isDetachedByUser = false; - return; - } - else if(isPausedByUser) - { - dputs("paused!"); - SetNextDbgContinueStatus(DBG_CONTINUE); - GuiSetDebugState(paused); - //update memory map - MemUpdateMap(); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - bSkipExceptions = false; - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - plugincbcall(CB_EXCEPTION, &callbackInfo); - wait(WAITID_RUN); - return; - } - SetContextDataEx(hActiveThread, UE_CIP, (duint)ExceptionData->ExceptionRecord.ExceptionAddress); - } - else if(ExceptionData->ExceptionRecord.ExceptionCode == MS_VC_EXCEPTION) //SetThreadName exception - { - THREADNAME_INFO nameInfo; //has no valid local pointers - memcpy(&nameInfo, ExceptionData->ExceptionRecord.ExceptionInformation, sizeof(THREADNAME_INFO)); - if(nameInfo.dwThreadID == -1) //current thread - nameInfo.dwThreadID = ((DEBUG_EVENT*)GetDebugData())->dwThreadId; - if(nameInfo.dwType == 0x1000 && nameInfo.dwFlags == 0 && ThreadIsValid(nameInfo.dwThreadID)) //passed basic checks - { - Memory ThreadName(MAX_THREAD_NAME_SIZE, "cbException:ThreadName"); - if(MemRead((duint)nameInfo.szName, ThreadName(), MAX_THREAD_NAME_SIZE - 1)) - { - String ThreadNameEscaped = StringUtils::Escape(ThreadName()); - dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped.c_str()); - ThreadSetName(nameInfo.dwThreadID, ThreadNameEscaped.c_str()); - } - } - } - const char* exceptionName = ExceptionCodeToName(ExceptionCode); - if(ExceptionData->dwFirstChance) //first chance exception - { - if(exceptionName) - dprintf("First chance exception on " fhex " (%.8X, %s)!\n", addr, ExceptionCode, exceptionName); - else - dprintf("First chance exception on " fhex " (%.8X)!\n", addr, ExceptionCode); - SetNextDbgContinueStatus(DBG_EXCEPTION_NOT_HANDLED); - if(bSkipExceptions || dbgisignoredexception(ExceptionCode)) - return; - } - else //lock the exception - { - if(exceptionName) - dprintf("Last chance exception on " fhex " (%.8X, %s)!\n", addr, ExceptionCode, exceptionName); - else - dprintf("Last chance exception on " fhex " (%.8X)!\n", addr, ExceptionCode); - SetNextDbgContinueStatus(DBG_CONTINUE); - } - - GuiSetDebugState(paused); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - bSkipExceptions = false; - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - plugincbcall(CB_EXCEPTION, &callbackInfo); - wait(WAITID_RUN); -} - -static void cbDebugEvent(DEBUG_EVENT* DebugEvent) -{ - PLUG_CB_DEBUGEVENT debugEventInfo; - debugEventInfo.DebugEvent = DebugEvent; - plugincbcall(CB_DEBUGEVENT, &debugEventInfo); -} - -DWORD WINAPI threadDebugLoop(void* lpParameter) -{ - lock(WAITID_STOP); //we are running - //initialize - bIsAttached = false; - bSkipExceptions = false; - bBreakOnNextDll = false; - bFreezeStack = false; - INIT_STRUCT* init = (INIT_STRUCT*)lpParameter; - bFileIsDll = IsFileDLLW(StringUtils::Utf8ToUtf16(init->exe).c_str(), 0); - pDebuggedEntry = GetPE32DataW(StringUtils::Utf8ToUtf16(init->exe).c_str(), 0, UE_OEP); - strcpy_s(szFileName, init->exe); - if(bFileIsDll) - fdProcessInfo = (PROCESS_INFORMATION*)InitDLLDebugW(StringUtils::Utf8ToUtf16(init->exe).c_str(), false, StringUtils::Utf8ToUtf16(init->commandline).c_str(), StringUtils::Utf8ToUtf16(init->currentfolder).c_str(), 0); - else - fdProcessInfo = (PROCESS_INFORMATION*)InitDebugW(StringUtils::Utf8ToUtf16(init->exe).c_str(), StringUtils::Utf8ToUtf16(init->commandline).c_str(), StringUtils::Utf8ToUtf16(init->currentfolder).c_str()); - if(!fdProcessInfo) - { - fdProcessInfo = &g_pi; - dputs("Error starting process (invalid pe?)!"); - unlock(WAITID_STOP); - return 0; - } - BOOL wow64 = false, mewow64 = false; - if(!IsWow64Process(fdProcessInfo->hProcess, &wow64) || !IsWow64Process(GetCurrentProcess(), &mewow64)) - { - dputs("IsWow64Process failed!"); - StopDebug(); - unlock(WAITID_STOP); - return 0; - } - if((mewow64 && !wow64) || (!mewow64 && wow64)) - { -#ifdef _WIN64 - dputs("Use x32dbg to debug this process!"); -#else - dputs("Use x64dbg to debug this process!"); -#endif // _WIN64 - unlock(WAITID_STOP); - return 0; - } - GuiAddRecentFile(szFileName); - varset("$hp", (duint)fdProcessInfo->hProcess, true); - varset("$pid", fdProcessInfo->dwProcessId, true); - ecount = 0; - //NOTE: set custom handlers - SetCustomHandler(UE_CH_CREATEPROCESS, (void*)cbCreateProcess); - SetCustomHandler(UE_CH_EXITPROCESS, (void*)cbExitProcess); - SetCustomHandler(UE_CH_CREATETHREAD, (void*)cbCreateThread); - SetCustomHandler(UE_CH_EXITTHREAD, (void*)cbExitThread); - SetCustomHandler(UE_CH_SYSTEMBREAKPOINT, (void*)cbSystemBreakpoint); - SetCustomHandler(UE_CH_LOADDLL, (void*)cbLoadDll); - SetCustomHandler(UE_CH_UNLOADDLL, (void*)cbUnloadDll); - SetCustomHandler(UE_CH_OUTPUTDEBUGSTRING, (void*)cbOutputDebugString); - SetCustomHandler(UE_CH_UNHANDLEDEXCEPTION, (void*)cbException); - SetCustomHandler(UE_CH_DEBUGEVENT, (void*)cbDebugEvent); - //inform GUI we started without problems - GuiSetDebugState(initialized); - //set GUI title - strcpy_s(szBaseFileName, szFileName); - int len = (int)strlen(szBaseFileName); - while(szBaseFileName[len] != '\\' && len) - len--; - if(len) - strcpy_s(szBaseFileName, szBaseFileName + len + 1); - GuiUpdateWindowTitle(szBaseFileName); - //call plugin callback - PLUG_CB_INITDEBUG initInfo; - initInfo.szFileName = szFileName; - plugincbcall(CB_INITDEBUG, &initInfo); - //run debug loop (returns when process debugging is stopped) - hProcess = fdProcessInfo->hProcess; - DebugLoop(); - isDetachedByUser = false; - //call plugin callback - PLUG_CB_STOPDEBUG stopInfo; - stopInfo.reserved = 0; - plugincbcall(CB_STOPDEBUG, &stopInfo); - //cleanup dbghelp - SafeSymRegisterCallback64(hProcess, nullptr, 0); - SafeSymCleanup(hProcess); - //message the user/do final stuff - RemoveAllBreakPoints(UE_OPTION_REMOVEALL); //remove all breakpoints - //cleanup - DBClose(); - ModClear(); - ThreadClear(); - GuiSetDebugState(stopped); - dputs("Debugging stopped!"); - varset("$hp", (duint)0, true); - varset("$pid", (duint)0, true); - unlock(WAITID_STOP); //we are done - pDebuggedEntry = 0; - pDebuggedBase = 0; - pCreateProcessBase = 0; - return 0; -} - -bool cbDeleteAllBreakpoints(const BREAKPOINT* bp) -{ - if(!BpDelete(bp->addr, BPNORMAL)) - { - dprintf("Delete breakpoint failed (BpDelete): " fhex "\n", bp->addr); - return false; - } - if(!bp->enabled || DeleteBPX(bp->addr)) - return true; - dprintf("Delete breakpoint failed (DeleteBPX): " fhex "\n", bp->addr); - return false; -} - -bool cbEnableAllBreakpoints(const BREAKPOINT* bp) -{ - if(bp->type != BPNORMAL || bp->enabled) - return true; - - if(!BpEnable(bp->addr, BPNORMAL, true)) - { - dprintf("Could not enable breakpoint " fhex " (BpEnable)\n", bp->addr); - return false; - } - if(!SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint)) - { - dprintf("Could not enable breakpoint " fhex " (SetBPX)\n", bp->addr); - return false; - } - return true; -} - -bool cbDisableAllBreakpoints(const BREAKPOINT* bp) -{ - if(bp->type != BPNORMAL || !bp->enabled) - return true; - - if(!BpEnable(bp->addr, BPNORMAL, false)) - { - dprintf("Could not disable breakpoint " fhex " (BpEnable)\n", bp->addr); - return false; - } - if(!DeleteBPX(bp->addr)) - { - dprintf("Could not disable breakpoint " fhex " (DeleteBPX)\n", bp->addr); - return false; - } - return true; -} - -bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp) -{ - if(bp->type != BPHARDWARE || bp->enabled) - return true; - DWORD drx = 0; - if(!GetUnusedHardwareBreakPointRegister(&drx)) - { - dprintf("Did not enable hardware breakpoint " fhex " (all slots full)\n", bp->addr); - return true; - } - int titantype = bp->titantype; - TITANSETDRX(titantype, drx); - BpSetTitanType(bp->addr, BPHARDWARE, titantype); - if(!BpEnable(bp->addr, BPHARDWARE, true)) - { - dprintf("Could not enable hardware breakpoint " fhex " (BpEnable)\n", bp->addr); - return false; - } - if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), (void*)cbHardwareBreakpoint)) - { - dprintf("Could not enable hardware breakpoint " fhex " (SetHardwareBreakPoint)\n", bp->addr); - return false; - } - return true; -} - -bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp) -{ - if(bp->type != BPHARDWARE || !bp->enabled) - return true; - if(!BpEnable(bp->addr, BPHARDWARE, false)) - { - dprintf("Could not disable hardware breakpoint " fhex " (BpEnable)\n", bp->addr); - return false; - } - if(!DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype))) - { - dprintf("Could not disable hardware breakpoint " fhex " (DeleteHardwareBreakPoint)\n", bp->addr); - return false; - } - return true; -} - -bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp) -{ - if(bp->type != BPMEMORY || bp->enabled) - return true; - duint size = 0; - MemFindBaseAddr(bp->addr, &size); - if(!BpEnable(bp->addr, BPMEMORY, true)) - { - dprintf("Could not enable memory breakpoint " fhex " (BpEnable)\n", bp->addr); - return false; - } - if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, (void*)cbMemoryBreakpoint)) - { - dprintf("Could not enable memory breakpoint " fhex " (SetMemoryBPXEx)\n", bp->addr); - return false; - } - return true; -} - -bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp) -{ - if(bp->type != BPMEMORY || !bp->enabled) - return true; - if(!BpEnable(bp->addr, BPMEMORY, false)) - { - dprintf("Could not disable memory breakpoint " fhex " (BpEnable)\n", bp->addr); - return false; - } - if(!RemoveMemoryBPX(bp->addr, 0)) - { - dprintf("Could not disable memory breakpoint " fhex " (RemoveMemoryBPX)\n", bp->addr); - return false; - } - return true; -} - -bool cbBreakpointList(const BREAKPOINT* bp) -{ - const char* type = 0; - if(bp->type == BPNORMAL) - { - if(bp->singleshoot) - type = "SS"; - else - type = "BP"; - } - else if(bp->type == BPHARDWARE) - type = "HW"; - else if(bp->type == BPMEMORY) - type = "GP"; - bool enabled = bp->enabled; - if(*bp->name) - dprintf("%d:%s:" fhex ":\"%s\"\n", enabled, type, bp->addr, bp->name); - else - dprintf("%d:%s:" fhex "\n", enabled, type, bp->addr); - return true; -} - -bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp) -{ - if(!bp->enabled) - return true; - duint size; - MemFindBaseAddr(bp->addr, &size); - if(!BpDelete(bp->addr, BPMEMORY)) - { - dprintf("Delete memory breakpoint failed (BpDelete): " fhex "\n", bp->addr); - return false; - } - if(!RemoveMemoryBPX(bp->addr, size)) - { - dprintf("Delete memory breakpoint failed (RemoveMemoryBPX): " fhex "\n", bp->addr); - return false; - } - return true; -} - -bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp) -{ - if(!bp->enabled) - return true; - if(!BpDelete(bp->addr, BPHARDWARE)) - { - dprintf("Delete hardware breakpoint failed (BpDelete): " fhex "\n", bp->addr); - return false; - } - if(!DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype))) - { - dprintf("Delete hardware breakpoint failed (DeleteHardwareBreakPoint): " fhex "\n", bp->addr); - return false; - } - return true; -} - -static void cbAttachDebugger() -{ - if(hEvent) //Signal the AeDebug event - { - SetEvent(hEvent); - hEvent = 0; - } - hProcess = fdProcessInfo->hProcess; - varset("$hp", (duint)fdProcessInfo->hProcess, true); - varset("$pid", fdProcessInfo->dwProcessId, true); -} - -DWORD WINAPI threadAttachLoop(void* lpParameter) -{ - lock(WAITID_STOP); - bIsAttached = true; - bSkipExceptions = false; - bFreezeStack = false; - DWORD pid = (DWORD)lpParameter; - static PROCESS_INFORMATION pi_attached; - fdProcessInfo = &pi_attached; - //do some init stuff - bFileIsDll = IsFileDLL(szFileName, 0); - GuiAddRecentFile(szFileName); - ecount = 0; - //NOTE: set custom handlers - SetCustomHandler(UE_CH_CREATEPROCESS, (void*)cbCreateProcess); - SetCustomHandler(UE_CH_EXITPROCESS, (void*)cbExitProcess); - SetCustomHandler(UE_CH_CREATETHREAD, (void*)cbCreateThread); - SetCustomHandler(UE_CH_EXITTHREAD, (void*)cbExitThread); - SetCustomHandler(UE_CH_SYSTEMBREAKPOINT, (void*)cbSystemBreakpoint); - SetCustomHandler(UE_CH_LOADDLL, (void*)cbLoadDll); - SetCustomHandler(UE_CH_UNLOADDLL, (void*)cbUnloadDll); - SetCustomHandler(UE_CH_OUTPUTDEBUGSTRING, (void*)cbOutputDebugString); - SetCustomHandler(UE_CH_UNHANDLEDEXCEPTION, (void*)cbException); - SetCustomHandler(UE_CH_DEBUGEVENT, (void*)cbDebugEvent); - //inform GUI start we started without problems - GuiSetDebugState(initialized); - //set GUI title - strcpy_s(szBaseFileName, szFileName); - int len = (int)strlen(szBaseFileName); - while(szBaseFileName[len] != '\\' && len) - len--; - if(len) - strcpy_s(szBaseFileName, szBaseFileName + len + 1); - GuiUpdateWindowTitle(szBaseFileName); - //call plugin callback (init) - PLUG_CB_INITDEBUG initInfo; - initInfo.szFileName = szFileName; - plugincbcall(CB_INITDEBUG, &initInfo); - //call plugin callback (attach) - PLUG_CB_ATTACH attachInfo; - attachInfo.dwProcessId = (DWORD)pid; - plugincbcall(CB_ATTACH, &attachInfo); - //run debug loop (returns when process debugging is stopped) - AttachDebugger(pid, true, fdProcessInfo, (void*)cbAttachDebugger); - isDetachedByUser = false; - //call plugin callback - PLUG_CB_STOPDEBUG stopInfo; - stopInfo.reserved = 0; - plugincbcall(CB_STOPDEBUG, &stopInfo); - //cleanup dbghelp - SafeSymRegisterCallback64(hProcess, nullptr, 0); - SafeSymCleanup(hProcess); - //message the user/do final stuff - RemoveAllBreakPoints(UE_OPTION_REMOVEALL); //remove all breakpoints - //cleanup - DBClose(); - ModClear(); - ThreadClear(); - GuiSetDebugState(stopped); - dputs("debugging stopped!"); - varset("$hp", (duint)0, true); - varset("$pid", (duint)0, true); - unlock(WAITID_STOP); - return 0; -} - -void cbDetach() -{ - if(!isDetachedByUser) - return; - PLUG_CB_DETACH detachInfo; - detachInfo.fdProcessInfo = fdProcessInfo; - plugincbcall(CB_DETACH, &detachInfo); - if(!DetachDebuggerEx(fdProcessInfo->dwProcessId)) - dputs("DetachDebuggerEx failed..."); - else - dputs("Detached!"); - return; -} - -bool dbglistprocesses(std::vector* list) -{ - list->clear(); - Handle hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if(!hProcessSnap) - return false; - PROCESSENTRY32 pe32; - pe32.dwSize = sizeof(PROCESSENTRY32); - if(!Process32First(hProcessSnap, &pe32)) - return false; - do - { - if(pe32.th32ProcessID == GetCurrentProcessId()) - continue; - if(!_stricmp(pe32.szExeFile, "System")) - continue; - if(!_stricmp(pe32.szExeFile, "[System Process]")) - continue; - Handle hProcess = TitanOpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pe32.th32ProcessID); - if(!hProcess) - continue; - BOOL wow64 = false, mewow64 = false; - if(!IsWow64Process(hProcess, &wow64) || !IsWow64Process(GetCurrentProcess(), &mewow64)) - continue; - if((mewow64 && !wow64) || (!mewow64 && wow64)) - continue; - wchar_t szExePath[MAX_PATH] = L""; - if(GetModuleFileNameExW(hProcess, 0, szExePath, MAX_PATH)) - strcpy_s(pe32.szExeFile, StringUtils::Utf16ToUtf8(szExePath).c_str()); - list->push_back(pe32); - } - while(Process32Next(hProcessSnap, &pe32)); - return true; -} - -static bool getcommandlineaddr(duint* addr, cmdline_error_t* cmd_line_error) -{ - duint pprocess_parameters; - - cmd_line_error->addr = (duint)GetPEBLocation(fdProcessInfo->hProcess); - - if(cmd_line_error->addr == 0) - { - cmd_line_error->type = CMDL_ERR_GET_PEB; - return false; - } - - //cast-trick to calculate the address of the remote peb field ProcessParameters - cmd_line_error->addr = (duint) & (((PPEB) cmd_line_error->addr)->ProcessParameters); - if(!MemRead(cmd_line_error->addr, &pprocess_parameters, sizeof(pprocess_parameters))) - { - cmd_line_error->type = CMDL_ERR_READ_PEBBASE; - return false; - } - - *addr = (duint) & (((RTL_USER_PROCESS_PARAMETERS*) pprocess_parameters)->CommandLine); - return true; -} - -static bool patchcmdline(duint getcommandline, duint new_command_line, cmdline_error_t* cmd_line_error) -{ - duint command_line_stored = 0; - unsigned char data[100]; - - cmd_line_error->addr = getcommandline; - if(!MemRead(cmd_line_error->addr, & data, sizeof(data))) - { - cmd_line_error->type = CMDL_ERR_READ_GETCOMMANDLINEBASE; - return false; - } - -#ifdef _WIN64 - /* - 00007FFC5B91E3C8 | 48 8B 05 19 1D 0E 00 | mov rax,qword ptr ds:[7FFC5BA000E8] - 00007FFC5B91E3CF | C3 | ret | - This is a relative offset then to get the symbol: next instruction of getmodulehandle (+7 bytes) + offset to symbol - (the last 4 bytes of the instruction) - */ - if(data[0] != 0x48 || data[1] != 0x8B || data[2] != 0x05 || data[7] != 0xC3) - { - cmd_line_error->type = CMDL_ERR_CHECK_GETCOMMANDLINESTORED; - return false; - } - DWORD offset = * ((DWORD*) & data[3]); - command_line_stored = getcommandline + 7 + offset; -#else //x86 - /* - 750FE9CA | A1 CC DB 1A 75 | mov eax,dword ptr ds:[751ADBCC] | - 750FE9CF | C3 | ret | - */ - if(data[0] != 0xA1 || data[5] != 0xC3) - { - cmd_line_error->type = CMDL_ERR_CHECK_GETCOMMANDLINESTORED; - return false; - } - command_line_stored = * ((duint*) & data[1]); -#endif - - //update the pointer in the debuggee - if(!MemWrite(command_line_stored, &new_command_line, sizeof(new_command_line))) - { - cmd_line_error->addr = command_line_stored; - cmd_line_error->type = CMDL_ERR_WRITE_GETCOMMANDLINESTORED; - return false; - } - - return true; -} - -static bool fixgetcommandlinesbase(duint new_command_line_unicode, duint new_command_line_ascii, cmdline_error_t* cmd_line_error) -{ - duint getcommandline; - - if(!valfromstring("kernelbase:GetCommandLineA", &getcommandline)) - { - if(!valfromstring("kernel32:GetCommandLineA", &getcommandline)) - { - cmd_line_error->type = CMDL_ERR_GET_GETCOMMANDLINE; - return false; - } - } - if(!patchcmdline(getcommandline, new_command_line_ascii, cmd_line_error)) - return false; - - if(!valfromstring("kernelbase:GetCommandLineW", &getcommandline)) - { - if(!valfromstring("kernel32:GetCommandLineW", &getcommandline)) - { - cmd_line_error->type = CMDL_ERR_GET_GETCOMMANDLINE; - return false; - } - } - if(!patchcmdline(getcommandline, new_command_line_unicode, cmd_line_error)) - return false; - - return true; -} - -bool dbgsetcmdline(const char* cmd_line, cmdline_error_t* cmd_line_error) -{ - cmdline_error_t cmd_line_error_aux; - UNICODE_STRING new_command_line; - duint command_line_addr; - - if(cmd_line_error == NULL) - cmd_line_error = &cmd_line_error_aux; - - if(!getcommandlineaddr(&cmd_line_error->addr, cmd_line_error)) - return false; - - command_line_addr = cmd_line_error->addr; - - SIZE_T cmd_line_size = strlen(cmd_line); - new_command_line.Length = (USHORT)(strlen(cmd_line) + 1) * sizeof(WCHAR); - new_command_line.MaximumLength = new_command_line.Length; - - Memory command_linewstr(new_command_line.Length); - - // Covert to Unicode. - if(!MultiByteToWideChar(CP_UTF8, 0, cmd_line, (int)cmd_line_size + 1, command_linewstr(), (int)cmd_line_size + 1)) - { - cmd_line_error->type = CMDL_ERR_CONVERTUNICODE; - return false; - } - - new_command_line.Buffer = command_linewstr(); - - duint mem = (duint)MemAllocRemote(0, new_command_line.Length * 2); - if(!mem) - { - cmd_line_error->type = CMDL_ERR_ALLOC_UNICODEANSI_COMMANDLINE; - return false; - } - - if(!MemWrite(mem, new_command_line.Buffer, new_command_line.Length)) - { - cmd_line_error->addr = mem; - cmd_line_error->type = CMDL_ERR_WRITE_UNICODE_COMMANDLINE; - return false; - } - - if(!MemWrite((mem + new_command_line.Length), (void*)cmd_line, strlen(cmd_line) + 1)) - { - cmd_line_error->addr = mem + new_command_line.Length; - cmd_line_error->type = CMDL_ERR_WRITE_ANSI_COMMANDLINE; - return false; - } - - if(!fixgetcommandlinesbase(mem, mem + new_command_line.Length, cmd_line_error)) - return false; - - new_command_line.Buffer = (PWSTR) mem; - if(!MemWrite(command_line_addr, &new_command_line, sizeof(new_command_line))) - { - cmd_line_error->addr = command_line_addr; - cmd_line_error->type = CMDL_ERR_WRITE_PEBUNICODE_COMMANDLINE; - return false; - } - - return true; -} - -bool dbggetcmdline(char** cmd_line, cmdline_error_t* cmd_line_error) -{ - UNICODE_STRING CommandLine; - cmdline_error_t cmd_line_error_aux; - - if(!cmd_line_error) - cmd_line_error = &cmd_line_error_aux; - - if(!getcommandlineaddr(&cmd_line_error->addr, cmd_line_error)) - return false; - - if(!MemRead(cmd_line_error->addr, &CommandLine, sizeof(CommandLine))) - { - cmd_line_error->type = CMDL_ERR_READ_PROCPARM_PTR; - return false; - } - - Memory wstr_cmd(CommandLine.Length + sizeof(wchar_t)); - - cmd_line_error->addr = (duint) CommandLine.Buffer; - if(!MemRead(cmd_line_error->addr, wstr_cmd(), CommandLine.Length)) - { - cmd_line_error->type = CMDL_ERR_READ_PROCPARM_CMDLINE; - return false; - } - - SIZE_T wstr_cmd_size = wcslen(wstr_cmd()) + 1; - SIZE_T cmd_line_size = wstr_cmd_size * 2; - - *cmd_line = (char*)emalloc(cmd_line_size, "dbggetcmdline:cmd_line"); - - //Convert TO UTF-8 - if(!WideCharToMultiByte(CP_UTF8, 0, wstr_cmd(), (int)wstr_cmd_size, * cmd_line, (int)cmd_line_size, NULL, NULL)) - { - efree(*cmd_line); - cmd_line_error->type = CMDL_ERR_CONVERTUNICODE; - return false; - } - return true; -} - -static DWORD WINAPI scriptThread(void* data) -{ - CBPLUGINSCRIPT cbScript = (CBPLUGINSCRIPT)data; - cbScript(); - return 0; -} - -void dbgstartscriptthread(CBPLUGINSCRIPT cbScript) -{ - CloseHandle(CreateThread(0, 0, scriptThread, cbScript, 0, 0)); -} - -duint dbggetdebuggedbase() -{ - return pDebuggedBase; +/** + @file debugger.cpp + + @brief Implements the debugger class. + */ + +#include "debugger.h" +#include "console.h" +#include "memory.h" +#include "threading.h" +#include "command.h" +#include "database.h" +#include "addrinfo.h" +#include "thread.h" +#include "plugin_loader.h" +#include "breakpoint.h" +#include "symbolinfo.h" +#include "variable.h" +#include "x64_dbg.h" +#include "exception.h" +#include "error.h" +#include "module.h" + +static PROCESS_INFORMATION g_pi = {0, 0, 0, 0}; +static char szBaseFileName[MAX_PATH] = ""; +static bool bFileIsDll = false; +static duint pDebuggedBase = 0; +static duint pCreateProcessBase = 0; +static duint pDebuggedEntry = 0; +static bool isStepping = false; +static bool isPausedByUser = false; +static bool isDetachedByUser = false; +static bool bIsAttached = false; +static bool bSkipExceptions = false; +static bool bBreakOnNextDll = false; +static bool bFreezeStack = false; +static int ecount = 0; +static std::vector ignoredExceptionRange; +static HANDLE hEvent = 0; +static HANDLE hProcess = 0; +static HANDLE hMemMapThread = 0; +static bool bStopMemMapThread = false; +static HANDLE hTimeWastedCounterThread = 0; +static bool bStopTimeWastedCounterThread = false; +static String lastDebugText; +static duint timeWastedDebugging = 0; +char szFileName[MAX_PATH] = ""; +char szSymbolCachePath[MAX_PATH] = ""; +char sqlitedb[deflen] = ""; +PROCESS_INFORMATION* fdProcessInfo = &g_pi; +HANDLE hActiveThread; +bool bUndecorateSymbolNames = true; +bool bEnableSourceDebugging = true; + +static DWORD WINAPI memMapThread(void* ptr) +{ + while(!bStopMemMapThread) + { + while(!DbgIsDebugging()) + { + if(bStopMemMapThread) + break; + Sleep(1); + } + if(bStopMemMapThread) + break; + MemUpdateMap(); + GuiUpdateMemoryView(); + Sleep(1000); + } + return 0; +} + +static DWORD WINAPI timeWastedCounterThread(void* ptr) +{ + if(!BridgeSettingGetUint("Engine", "TimeWastedDebugging", &timeWastedDebugging)) + timeWastedDebugging = 0; + GuiUpdateTimeWastedCounter(); + while(!bStopTimeWastedCounterThread) + { + while(!DbgIsDebugging()) + { + if(bStopTimeWastedCounterThread) + break; + Sleep(1); + } + if(bStopTimeWastedCounterThread) + break; + timeWastedDebugging++; + GuiUpdateTimeWastedCounter(); + Sleep(1000); + } + BridgeSettingSetUint("Engine", "TimeWastedDebugging", timeWastedDebugging); + return 0; +} + +void dbginit() +{ + ExceptionCodeInit(); + ErrorCodeInit(); + hMemMapThread = CreateThread(nullptr, 0, memMapThread, nullptr, 0, nullptr); + hTimeWastedCounterThread = CreateThread(nullptr, 0, timeWastedCounterThread, nullptr, 0, nullptr); +} + +void dbgstop() +{ + bStopMemMapThread = true; + bStopTimeWastedCounterThread = true; + WaitForThreadTermination(hMemMapThread); + WaitForThreadTermination(hTimeWastedCounterThread); +} + +duint dbgdebuggedbase() +{ + return pDebuggedBase; +} + +duint dbggettimewastedcounter() +{ + return timeWastedDebugging; +} + +bool dbgisrunning() +{ + return !waitislocked(WAITID_RUN); +} + +bool dbgisdll() +{ + return bFileIsDll; +} + +void dbgsetattachevent(HANDLE handle) +{ + hEvent = handle; +} + +void dbgsetskipexceptions(bool skip) +{ + bSkipExceptions = skip; +} + +void dbgsetstepping(bool stepping) +{ + isStepping = stepping; +} + +void dbgsetispausedbyuser(bool b) +{ + isPausedByUser = b; +} + +void dbgsetisdetachedbyuser(bool b) +{ + isDetachedByUser = b; +} + +void dbgsetfreezestack(bool freeze) +{ + bFreezeStack = freeze; +} + +void dbgclearignoredexceptions() +{ + ignoredExceptionRange.clear(); +} + +void dbgaddignoredexception(ExceptionRange range) +{ + ignoredExceptionRange.push_back(range); +} + +bool dbgisignoredexception(unsigned int exception) +{ + for(unsigned int i = 0; i < ignoredExceptionRange.size(); i++) + { + unsigned int curStart = ignoredExceptionRange.at(i).start; + unsigned int curEnd = ignoredExceptionRange.at(i).end; + if(exception >= curStart && exception <= curEnd) + return true; + } + return false; +} + +bool dbgcmdnew(const char* name, CBCOMMAND cbCommand, bool debugonly) +{ + if(!cmdnew(name, cbCommand, debugonly)) + return false; + GuiAutoCompleteAddCmd(name); + return true; +} + +bool dbgcmddel(const char* name) +{ + if(!cmddel(name)) + return false; + GuiAutoCompleteDelCmd(name); + return true; +} + +DWORD WINAPI updateCallStackThread(void* ptr) +{ + GuiUpdateCallStack(); + return 0; +} + +void DebugUpdateGui(duint disasm_addr, bool stack) +{ + duint cip = GetContextDataEx(hActiveThread, UE_CIP); + if(MemIsValidReadPtr(disasm_addr)) + { + if(bEnableSourceDebugging) + { + char szSourceFile[MAX_STRING_SIZE] = ""; + int line = 0; + if(SymGetSourceLine(cip, szSourceFile, &line)) + GuiLoadSourceFile(szSourceFile, line); + } + GuiDisasmAt(disasm_addr, cip); + } + duint csp = GetContextDataEx(hActiveThread, UE_CSP); + if(stack) + DebugUpdateStack(csp, csp); + static duint cacheCsp = 0; + if(csp != cacheCsp) + { + cacheCsp = csp; + CloseHandle(CreateThread(0, 0, updateCallStackThread, 0, 0, 0)); + } + char modname[MAX_MODULE_SIZE] = ""; + char modtext[MAX_MODULE_SIZE * 2] = ""; + if(!ModNameFromAddr(disasm_addr, modname, true)) + *modname = 0; + else + sprintf(modtext, "Module: %s - ", modname); + char title[1024] = ""; + sprintf(title, "File: %s - PID: %X - %sThread: %X", szBaseFileName, fdProcessInfo->dwProcessId, modtext, ThreadGetId(hActiveThread)); + GuiUpdateWindowTitle(title); + GuiUpdateAllViews(); +} + +void DebugUpdateStack(duint dumpAddr, duint csp, bool forceDump) +{ + if (!forceDump && bFreezeStack) + { + SELECTIONDATA selection; + if (GuiSelectionGet(GUI_STACK, &selection)) + dumpAddr = selection.view; + } + GuiStackDumpAt(dumpAddr, csp); +} + +void cbUserBreakpoint() +{ + hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); + BREAKPOINT bp; + BRIDGEBP pluginBp; + PLUG_CB_BREAKPOINT bpInfo; + bpInfo.breakpoint = 0; + if(!BpGet(GetContextDataEx(hActiveThread, UE_CIP), BPNORMAL, 0, &bp) && bp.enabled) + dputs("Breakpoint reached not in list!"); + else + { + const char* bptype = "INT3"; + int titantype = bp.titantype; + if((titantype & UE_BREAKPOINT_TYPE_UD2) == UE_BREAKPOINT_TYPE_UD2) + bptype = "UD2"; + else if((titantype & UE_BREAKPOINT_TYPE_LONG_INT3) == UE_BREAKPOINT_TYPE_LONG_INT3) + bptype = "LONG INT3"; + const char* symbolicname = SymGetSymbolicName(bp.addr); + if(symbolicname) + { + if(*bp.name) + dprintf("%s breakpoint \"%s\" at %s (" fhex ")!\n", bptype, bp.name, symbolicname, bp.addr); + else + dprintf("%s breakpoint at %s (" fhex ")!\n", bptype, symbolicname, bp.addr); + } + else + { + if(*bp.name) + dprintf("%s breakpoint \"%s\" at " fhex "!\n", bptype, bp.name, bp.addr); + else + dprintf("%s breakpoint at " fhex "!\n", bptype, bp.addr); + } + if(bp.singleshoot) + BpDelete(bp.addr, BPNORMAL); + BpToBridge(&bp, &pluginBp); + bpInfo.breakpoint = &pluginBp; + } + GuiSetDebugState(paused); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + bSkipExceptions = false; + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + plugincbcall(CB_BREAKPOINT, &bpInfo); + wait(WAITID_RUN); +} + +void cbHardwareBreakpoint(void* ExceptionAddress) +{ + hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); + duint cip = GetContextDataEx(hActiveThread, UE_CIP); + BREAKPOINT bp; + BRIDGEBP pluginBp; + PLUG_CB_BREAKPOINT bpInfo; + bpInfo.breakpoint = 0; + if(!BpGet((duint)ExceptionAddress, BPHARDWARE, 0, &bp)) + dputs("Hardware breakpoint reached not in list!"); + else + { + const char* bpsize = ""; + switch(TITANGETSIZE(bp.titantype)) //size + { + case UE_HARDWARE_SIZE_1: + bpsize = "byte, "; + break; + case UE_HARDWARE_SIZE_2: + bpsize = "word, "; + break; + case UE_HARDWARE_SIZE_4: + bpsize = "dword, "; + break; +#ifdef _WIN64 + case UE_HARDWARE_SIZE_8: + bpsize = "qword, "; + break; +#endif //_WIN64 + } + const char* bptype = ""; + switch(TITANGETTYPE(bp.titantype)) //type + { + case UE_HARDWARE_EXECUTE: + bptype = "execute"; + bpsize = ""; + break; + case UE_HARDWARE_READWRITE: + bptype = "read/write"; + break; + case UE_HARDWARE_WRITE: + bptype = "write"; + break; + } + const char* symbolicname = SymGetSymbolicName(bp.addr); + if(symbolicname) + { + if(*bp.name) + dprintf("Hardware breakpoint (%s%s) \"%s\" at %s (" fhex ")!\n", bpsize, bptype, bp.name, symbolicname, bp.addr); + else + dprintf("Hardware breakpoint (%s%s) at %s (" fhex ")!\n", bpsize, bptype, symbolicname, bp.addr); + } + else + { + if(*bp.name) + dprintf("Hardware breakpoint (%s%s) \"%s\" at " fhex "!\n", bpsize, bptype, bp.name, bp.addr); + else + dprintf("Hardware breakpoint (%s%s) at " fhex "!\n", bpsize, bptype, bp.addr); + } + BpToBridge(&bp, &pluginBp); + bpInfo.breakpoint = &pluginBp; + } + GuiSetDebugState(paused); + DebugUpdateGui(cip, true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + bSkipExceptions = false; + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + plugincbcall(CB_BREAKPOINT, &bpInfo); + wait(WAITID_RUN); +} + +void cbMemoryBreakpoint(void* ExceptionAddress) +{ + hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); + duint cip = GetContextDataEx(hActiveThread, UE_CIP); + duint size; + duint base = MemFindBaseAddr((duint)ExceptionAddress, &size, true); + BREAKPOINT bp; + BRIDGEBP pluginBp; + PLUG_CB_BREAKPOINT bpInfo; + bpInfo.breakpoint = 0; + if(!BpGet(base, BPMEMORY, 0, &bp)) + dputs("Memory breakpoint reached not in list!"); + else + { + const char* bptype = ""; + switch(bp.titantype) + { + case UE_MEMORY_READ: + bptype = " (read)"; + break; + case UE_MEMORY_WRITE: + bptype = " (write)"; + break; + case UE_MEMORY_EXECUTE: + bptype = " (execute)"; + break; + case UE_MEMORY: + bptype = " (read/write/execute)"; + break; + } + const char* symbolicname = SymGetSymbolicName(bp.addr); + if(symbolicname) + { + if(*bp.name) + dprintf("Memory breakpoint%s \"%s\" at %s (" fhex ", " fhex ")!\n", bptype, bp.name, symbolicname, bp.addr, ExceptionAddress); + else + dprintf("Memory breakpoint%s at %s (" fhex ", " fhex ")!\n", bptype, symbolicname, bp.addr, ExceptionAddress); + } + else + { + if(*bp.name) + dprintf("Memory breakpoint%s \"%s\" at " fhex " (" fhex ")!\n", bptype, bp.name, bp.addr, ExceptionAddress); + else + dprintf("Memory breakpoint%s at " fhex " (" fhex ")!\n", bptype, bp.addr, ExceptionAddress); + } + BpToBridge(&bp, &pluginBp); + bpInfo.breakpoint = &pluginBp; + } + if(bp.singleshoot) + BpDelete(bp.addr, BPMEMORY); //delete from breakpoint list + GuiSetDebugState(paused); + DebugUpdateGui(cip, true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + bSkipExceptions = false; + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + plugincbcall(CB_BREAKPOINT, &bpInfo); + wait(WAITID_RUN); +} + +void cbLibrarianBreakpoint(void* lpData) +{ + bBreakOnNextDll = true; +} + +static BOOL CALLBACK SymRegisterCallbackProc64(HANDLE hProcess, ULONG ActionCode, ULONG64 CallbackData, ULONG64 UserContext) +{ + UNREFERENCED_PARAMETER(hProcess); + UNREFERENCED_PARAMETER(UserContext); + PIMAGEHLP_CBA_EVENT evt; + switch(ActionCode) + { + case CBA_EVENT: + { + evt = (PIMAGEHLP_CBA_EVENT)CallbackData; + const char* text = (const char*)evt->desc; + if(strstr(text, "Successfully received a response from the server.")) + break; + if(strstr(text, "Waiting for the server to respond to a request.")) + break; + int len = (int)strlen(text); + bool suspress = false; + for(int i = 0; i < len; i++) + if(text[i] == 0x08) + { + suspress = true; + break; + } + int percent = 0; + static bool zerobar = false; + if(zerobar) + { + zerobar = false; + GuiSymbolSetProgress(0); + } + if(strstr(text, " bytes - ")) + { + Memory newtext(len + 1, "SymRegisterCallbackProc64:newtext"); + strcpy_s(newtext(), len + 1, text); + strstr(newtext(), " bytes - ")[8] = 0; + GuiSymbolLogAdd(newtext()); + suspress = true; + } + else if(strstr(text, " copied ")) + { + GuiSymbolSetProgress(100); + GuiSymbolLogAdd(" downloaded!\n"); + suspress = true; + zerobar = true; + } + else if(sscanf(text, "%*s %d percent", &percent) == 1 || sscanf(text, "%d percent", &percent) == 1) + { + GuiSymbolSetProgress(percent); + suspress = true; + } + + if(!suspress) + GuiSymbolLogAdd(text); + } + break; + + case CBA_DEBUG_INFO: + { + GuiSymbolLogAdd((const char*)CallbackData); + } + break; + + default: + { + return FALSE; + } + } + return TRUE; +} + +bool cbSetModuleBreakpoints(const BREAKPOINT* bp) +{ + if(!bp->enabled) + return true; + switch(bp->type) + { + case BPNORMAL: + { + if(!SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint)) + dprintf("Could not set breakpoint " fhex "! (SetBPX)\n", bp->addr); + } + break; + + case BPMEMORY: + { + duint size = 0; + MemFindBaseAddr(bp->addr, &size); + if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, (void*)cbMemoryBreakpoint)) + dprintf("Could not set memory breakpoint " fhex "! (SetMemoryBPXEx)\n", bp->addr); + } + break; + + case BPHARDWARE: + { + DWORD drx = 0; + if(!GetUnusedHardwareBreakPointRegister(&drx)) + { + dputs("You can only set 4 hardware breakpoints"); + return false; + } + int titantype = bp->titantype; + TITANSETDRX(titantype, drx); + BpSetTitanType(bp->addr, BPHARDWARE, titantype); + if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), (void*)cbHardwareBreakpoint)) + dprintf("Could not set hardware breakpoint " fhex "! (SetHardwareBreakPoint)\n", bp->addr); + } + break; + + default: + break; + } + return true; +} + +static bool cbRemoveModuleBreakpoints(const BREAKPOINT* bp) +{ + if(!bp->enabled) + return true; + switch(bp->type) + { + case BPNORMAL: + if(!DeleteBPX(bp->addr)) + dprintf("Could not delete breakpoint " fhex "! (DeleteBPX)\n", bp->addr); + break; + case BPMEMORY: + if(!RemoveMemoryBPX(bp->addr, 0)) + dprintf("Could not delete memory breakpoint " fhex "! (RemoveMemoryBPX)\n", bp->addr); + break; + case BPHARDWARE: + if(!DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype))) + dprintf("Could not delete hardware breakpoint " fhex "! (DeleteHardwareBreakPoint)\n", bp->addr); + break; + default: + break; + } + return true; +} + +void cbStep() +{ + hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); + isStepping = false; + GuiSetDebugState(paused); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + PLUG_CB_STEPPED stepInfo; + stepInfo.reserved = 0; + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + bSkipExceptions = false; + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + plugincbcall(CB_STEPPED, &stepInfo); + wait(WAITID_RUN); +} + +static void cbRtrFinalStep() +{ + hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); + GuiSetDebugState(paused); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + bSkipExceptions = false; + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + wait(WAITID_RUN); +} + +static unsigned char getCIPch() +{ + unsigned char ch = 0x90; + duint cip = GetContextDataEx(hActiveThread, UE_CIP); + MemRead(cip, &ch, 1); + return ch; +} + +void cbRtrStep() +{ + unsigned int cipch = getCIPch(); + if(cipch == 0xC3 || cipch == 0xC2) + cbRtrFinalStep(); + else + StepOver((void*)cbRtrStep); +} + +static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo) +{ + void* base = CreateProcessInfo->lpBaseOfImage; + + char DebugFileName[deflen] = ""; + if(!GetFileNameFromHandle(CreateProcessInfo->hFile, DebugFileName)) + strcpy_s(DebugFileName, "??? (GetFileNameFromHandle failed!)"); + dprintf("Process Started: " fhex " %s\n", base, DebugFileName); + + //update memory map + MemUpdateMap(); + GuiUpdateMemoryView(); + + GuiDumpAt(MemFindBaseAddr(GetContextData(UE_CIP), 0) + PAGE_SIZE); //dump somewhere + + // Init program database + DBSetPath(nullptr, szFileName); + DBLoad(); + + SafeSymSetOptions(SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS | SYMOPT_FAVOR_COMPRESSED | SYMOPT_IGNORE_NT_SYMPATH); + GuiSymbolLogClear(); + char szServerSearchPath[MAX_PATH * 2] = ""; + sprintf_s(szServerSearchPath, "SRV*%s", szSymbolCachePath); + SafeSymInitializeW(fdProcessInfo->hProcess, StringUtils::Utf8ToUtf16(szServerSearchPath).c_str(), false); //initialize symbols + SafeSymRegisterCallback64(fdProcessInfo->hProcess, SymRegisterCallbackProc64, 0); + SafeSymLoadModuleEx(fdProcessInfo->hProcess, CreateProcessInfo->hFile, DebugFileName, 0, (DWORD64)base, 0, 0, 0); + + IMAGEHLP_MODULE64 modInfo; + memset(&modInfo, 0, sizeof(modInfo)); + modInfo.SizeOfStruct = sizeof(modInfo); + if(SafeSymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo)) + ModLoad((duint)base, modInfo.ImageSize, modInfo.ImageName); + + char modname[256] = ""; + if(ModNameFromAddr((duint)base, modname, true)) + BpEnumAll(cbSetModuleBreakpoints, modname); + GuiUpdateBreakpointsView(); + pCreateProcessBase = (duint)CreateProcessInfo->lpBaseOfImage; + if(!bFileIsDll && !bIsAttached) //Set entry breakpoint + { + pDebuggedBase = pCreateProcessBase; //debugged base = executable + char command[256] = ""; + + if(settingboolget("Events", "TlsCallbacks")) + { + DWORD NumberOfCallBacks = 0; + TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, &NumberOfCallBacks); + if(NumberOfCallBacks) + { + dprintf("TLS Callbacks: %d\n", NumberOfCallBacks); + Memory TLSCallBacks(NumberOfCallBacks * sizeof(duint), "cbCreateProcess:TLSCallBacks"); + if(!TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), TLSCallBacks(), &NumberOfCallBacks)) + dputs("Failed to get TLS callback addresses!"); + else + { + duint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, UE_IMAGEBASE); + int invalidCount = 0; + for(unsigned int i = 0; i < NumberOfCallBacks; i++) + { + duint callbackVA = TLSCallBacks()[i] - ImageBase + pDebuggedBase; + if(MemIsValidReadPtr(callbackVA)) + { + sprintf(command, "bp " fhex ",\"TLS Callback %d\",ss", callbackVA, i + 1); + cmddirectexec(command); + } + else + invalidCount++; + } + if(invalidCount) + dprintf("%d invalid TLS callback addresses...\n", invalidCount); + } + } + } + + if(settingboolget("Events", "EntryBreakpoint")) + { + sprintf(command, "bp " fhex ",\"entry breakpoint\",ss", (duint)CreateProcessInfo->lpStartAddress); + cmddirectexec(command); + } + } + GuiUpdateBreakpointsView(); + + //call plugin callback + PLUG_CB_CREATEPROCESS callbackInfo; + callbackInfo.CreateProcessInfo = CreateProcessInfo; + callbackInfo.modInfo = &modInfo; + callbackInfo.DebugFileName = DebugFileName; + callbackInfo.fdProcessInfo = fdProcessInfo; + plugincbcall(CB_CREATEPROCESS, &callbackInfo); + + //update thread list + CREATE_THREAD_DEBUG_INFO threadInfo; + threadInfo.hThread = CreateProcessInfo->hThread; + threadInfo.lpStartAddress = CreateProcessInfo->lpStartAddress; + threadInfo.lpThreadLocalBase = CreateProcessInfo->lpThreadLocalBase; + ThreadCreate(&threadInfo); +} + +static void cbExitProcess(EXIT_PROCESS_DEBUG_INFO* ExitProcess) +{ + dprintf("Process stopped with exit code 0x%X\n", ExitProcess->dwExitCode); + PLUG_CB_EXITPROCESS callbackInfo; + callbackInfo.ExitProcess = ExitProcess; + plugincbcall(CB_EXITPROCESS, &callbackInfo); + //unload main module + SafeSymUnloadModule64(fdProcessInfo->hProcess, pCreateProcessBase); +} + +static void cbCreateThread(CREATE_THREAD_DEBUG_INFO* CreateThread) +{ + ThreadCreate(CreateThread); //update thread list + DWORD dwThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId; + hActiveThread = ThreadGetHandle(dwThreadId); + + if(settingboolget("Events", "ThreadEntry")) + { + char command[256] = ""; + sprintf(command, "bp " fhex ",\"Thread %X\",ss", (duint)CreateThread->lpStartAddress, dwThreadId); + cmddirectexec(command); + } + + PLUG_CB_CREATETHREAD callbackInfo; + callbackInfo.CreateThread = CreateThread; + callbackInfo.dwThreadId = dwThreadId; + plugincbcall(CB_CREATETHREAD, &callbackInfo); + + dprintf("Thread %X created\n", dwThreadId); + + if(settingboolget("Events", "ThreadStart")) + { + //update memory map + MemUpdateMap(); + //update GUI + GuiSetDebugState(paused); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + wait(WAITID_RUN); + } +} + +static void cbExitThread(EXIT_THREAD_DEBUG_INFO* ExitThread) +{ + hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); + DWORD dwThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId; + PLUG_CB_EXITTHREAD callbackInfo; + callbackInfo.ExitThread = ExitThread; + callbackInfo.dwThreadId = dwThreadId; + plugincbcall(CB_EXITTHREAD, &callbackInfo); + ThreadExit(dwThreadId); + dprintf("Thread %X exit\n", dwThreadId); + + if(settingboolget("Events", "ThreadEnd")) + { + //update GUI + GuiSetDebugState(paused); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + wait(WAITID_RUN); + } +} + +static void cbSystemBreakpoint(void* ExceptionData) +{ + hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); + + duint cip = GetContextDataEx(hActiveThread, UE_CIP); + GuiDumpAt(MemFindBaseAddr(cip, 0, true)); //dump somewhere + + //log message + if(bIsAttached) + dputs("Attach breakpoint reached!"); + else + dputs("System breakpoint reached!"); + bSkipExceptions = false; //we are not skipping first-chance exceptions + + //plugin callbacks + PLUG_CB_SYSTEMBREAKPOINT callbackInfo; + callbackInfo.reserved = 0; + plugincbcall(CB_SYSTEMBREAKPOINT, &callbackInfo); + + if(bIsAttached ? settingboolget("Events", "AttachBreakpoint") : settingboolget("Events", "SystemBreakpoint")) + { + //update GUI + GuiSetDebugState(paused); + DebugUpdateGui(cip, true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + wait(WAITID_RUN); + } +} + +static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll) +{ + hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); + void* base = LoadDll->lpBaseOfDll; + + char DLLDebugFileName[deflen] = ""; + if(!GetFileNameFromHandle(LoadDll->hFile, DLLDebugFileName)) + strcpy_s(DLLDebugFileName, "??? (GetFileNameFromHandle failed!)"); + + SafeSymLoadModuleEx(fdProcessInfo->hProcess, LoadDll->hFile, DLLDebugFileName, 0, (DWORD64)base, 0, 0, 0); + IMAGEHLP_MODULE64 modInfo; + memset(&modInfo, 0, sizeof(modInfo)); + modInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); + if(SafeSymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo)) + ModLoad((duint)base, modInfo.ImageSize, modInfo.ImageName); + + //update memory map + MemUpdateMap(); + GuiUpdateMemoryView(); + + char modname[256] = ""; + if(ModNameFromAddr((duint)base, modname, true)) + BpEnumAll(cbSetModuleBreakpoints, modname); + GuiUpdateBreakpointsView(); + bool bAlreadySetEntry = false; + + char command[256] = ""; + bool bIsDebuggingThis = false; + if(bFileIsDll && !_stricmp(DLLDebugFileName, szFileName) && !bIsAttached) //Set entry breakpoint + { + bIsDebuggingThis = true; + pDebuggedBase = (duint)base; + if(settingboolget("Events", "EntryBreakpoint")) + { + bAlreadySetEntry = true; + sprintf(command, "bp " fhex ",\"entry breakpoint\",ss", pDebuggedBase + pDebuggedEntry); + cmddirectexec(command); + } + } + GuiUpdateBreakpointsView(); + + if(settingboolget("Events", "TlsCallbacks")) + { + DWORD NumberOfCallBacks = 0; + TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), 0, &NumberOfCallBacks); + if(NumberOfCallBacks) + { + dprintf("TLS Callbacks: %d\n", NumberOfCallBacks); + Memory TLSCallBacks(NumberOfCallBacks * sizeof(duint), "cbLoadDll:TLSCallBacks"); + if(!TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), TLSCallBacks(), &NumberOfCallBacks)) + dputs("Failed to get TLS callback addresses!"); + else + { + duint ImageBase = GetPE32DataW(StringUtils::Utf8ToUtf16(DLLDebugFileName).c_str(), 0, UE_IMAGEBASE); + int invalidCount = 0; + for(unsigned int i = 0; i < NumberOfCallBacks; i++) + { + duint callbackVA = TLSCallBacks()[i] - ImageBase + (duint)base; + if(MemIsValidReadPtr(callbackVA)) + { + if(bIsDebuggingThis) + sprintf(command, "bp " fhex ",\"TLS Callback %d\",ss", callbackVA, i + 1); + else + sprintf(command, "bp " fhex ",\"TLS Callback %d (%s)\",ss", callbackVA, i + 1, modname); + cmddirectexec(command); + } + else + invalidCount++; + } + if(invalidCount) + dprintf("%s invalid TLS callback addresses...\n", invalidCount); + } + } + } + + if((bBreakOnNextDll || settingboolget("Events", "DllEntry")) && !bAlreadySetEntry) + { + duint oep = GetPE32Data(DLLDebugFileName, 0, UE_OEP); + if(oep) + { + char command[256] = ""; + sprintf(command, "bp " fhex ",\"DllMain (%s)\",ss", oep + (duint)base, modname); + cmddirectexec(command); + } + } + + dprintf("DLL Loaded: " fhex " %s\n", base, DLLDebugFileName); + + //plugin callback + PLUG_CB_LOADDLL callbackInfo; + callbackInfo.LoadDll = LoadDll; + callbackInfo.modInfo = &modInfo; + callbackInfo.modname = modname; + plugincbcall(CB_LOADDLL, &callbackInfo); + + if(bBreakOnNextDll || settingboolget("Events", "DllLoad")) + { + bBreakOnNextDll = false; + //update GUI + GuiSetDebugState(paused); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + wait(WAITID_RUN); + } +} + +static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll) +{ + hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); + PLUG_CB_UNLOADDLL callbackInfo; + callbackInfo.UnloadDll = UnloadDll; + plugincbcall(CB_UNLOADDLL, &callbackInfo); + + void* base = UnloadDll->lpBaseOfDll; + char modname[256] = "???"; + if(ModNameFromAddr((duint)base, modname, true)) + BpEnumAll(cbRemoveModuleBreakpoints, modname); + GuiUpdateBreakpointsView(); + SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)base); + dprintf("DLL Unloaded: " fhex " %s\n", base, modname); + + if(bBreakOnNextDll || settingboolget("Events", "DllUnload")) + { + bBreakOnNextDll = false; + //update GUI + GuiSetDebugState(paused); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + wait(WAITID_RUN); + } + + ModUnload((duint)base); + + //update memory map + MemUpdateMap(); + GuiUpdateMemoryView(); +} + +static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString) +{ + + hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); + PLUG_CB_OUTPUTDEBUGSTRING callbackInfo; + callbackInfo.DebugString = DebugString; + plugincbcall(CB_OUTPUTDEBUGSTRING, &callbackInfo); + + if(!DebugString->fUnicode) //ASCII + { + Memory DebugText(DebugString->nDebugStringLength + 1, "cbOutputDebugString:DebugText"); + if(MemRead((duint)DebugString->lpDebugStringData, DebugText(), DebugString->nDebugStringLength)) + { + String str = String(DebugText()); + if(str != lastDebugText) //fix for every string being printed twice + { + if(str != "\n") + dprintf("DebugString: \"%s\"\n", StringUtils::Escape(str).c_str()); + lastDebugText = str; + } + else + lastDebugText.clear(); + } + } + + if(settingboolget("Events", "DebugStrings")) + { + //update GUI + GuiSetDebugState(paused); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + wait(WAITID_RUN); + } +} + +static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData) +{ + hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId); + PLUG_CB_EXCEPTION callbackInfo; + callbackInfo.Exception = ExceptionData; + unsigned int ExceptionCode = ExceptionData->ExceptionRecord.ExceptionCode; + GuiSetLastException(ExceptionCode); + + duint addr = (duint)ExceptionData->ExceptionRecord.ExceptionAddress; + if(ExceptionData->ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) + { + if(isDetachedByUser) + { + PLUG_CB_DETACH detachInfo; + detachInfo.fdProcessInfo = fdProcessInfo; + plugincbcall(CB_DETACH, &detachInfo); + if(!DetachDebuggerEx(fdProcessInfo->dwProcessId)) + dputs("DetachDebuggerEx failed..."); + else + dputs("Detached!"); + isDetachedByUser = false; + return; + } + else if(isPausedByUser) + { + dputs("paused!"); + SetNextDbgContinueStatus(DBG_CONTINUE); + GuiSetDebugState(paused); + //update memory map + MemUpdateMap(); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + bSkipExceptions = false; + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + plugincbcall(CB_EXCEPTION, &callbackInfo); + wait(WAITID_RUN); + return; + } + SetContextDataEx(hActiveThread, UE_CIP, (duint)ExceptionData->ExceptionRecord.ExceptionAddress); + } + else if(ExceptionData->ExceptionRecord.ExceptionCode == MS_VC_EXCEPTION) //SetThreadName exception + { + THREADNAME_INFO nameInfo; //has no valid local pointers + memcpy(&nameInfo, ExceptionData->ExceptionRecord.ExceptionInformation, sizeof(THREADNAME_INFO)); + if(nameInfo.dwThreadID == -1) //current thread + nameInfo.dwThreadID = ((DEBUG_EVENT*)GetDebugData())->dwThreadId; + if(nameInfo.dwType == 0x1000 && nameInfo.dwFlags == 0 && ThreadIsValid(nameInfo.dwThreadID)) //passed basic checks + { + Memory ThreadName(MAX_THREAD_NAME_SIZE, "cbException:ThreadName"); + if(MemRead((duint)nameInfo.szName, ThreadName(), MAX_THREAD_NAME_SIZE - 1)) + { + String ThreadNameEscaped = StringUtils::Escape(ThreadName()); + dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped.c_str()); + ThreadSetName(nameInfo.dwThreadID, ThreadNameEscaped.c_str()); + } + } + } + const char* exceptionName = ExceptionCodeToName(ExceptionCode); + if(ExceptionData->dwFirstChance) //first chance exception + { + if(exceptionName) + dprintf("First chance exception on " fhex " (%.8X, %s)!\n", addr, ExceptionCode, exceptionName); + else + dprintf("First chance exception on " fhex " (%.8X)!\n", addr, ExceptionCode); + SetNextDbgContinueStatus(DBG_EXCEPTION_NOT_HANDLED); + if(bSkipExceptions || dbgisignoredexception(ExceptionCode)) + return; + } + else //lock the exception + { + if(exceptionName) + dprintf("Last chance exception on " fhex " (%.8X, %s)!\n", addr, ExceptionCode, exceptionName); + else + dprintf("Last chance exception on " fhex " (%.8X)!\n", addr, ExceptionCode); + SetNextDbgContinueStatus(DBG_CONTINUE); + } + + GuiSetDebugState(paused); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + bSkipExceptions = false; + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + plugincbcall(CB_EXCEPTION, &callbackInfo); + wait(WAITID_RUN); +} + +static void cbDebugEvent(DEBUG_EVENT* DebugEvent) +{ + PLUG_CB_DEBUGEVENT debugEventInfo; + debugEventInfo.DebugEvent = DebugEvent; + plugincbcall(CB_DEBUGEVENT, &debugEventInfo); +} + +DWORD WINAPI threadDebugLoop(void* lpParameter) +{ + lock(WAITID_STOP); //we are running + //initialize + bIsAttached = false; + bSkipExceptions = false; + bBreakOnNextDll = false; + bFreezeStack = false; + INIT_STRUCT* init = (INIT_STRUCT*)lpParameter; + bFileIsDll = IsFileDLLW(StringUtils::Utf8ToUtf16(init->exe).c_str(), 0); + pDebuggedEntry = GetPE32DataW(StringUtils::Utf8ToUtf16(init->exe).c_str(), 0, UE_OEP); + strcpy_s(szFileName, init->exe); + if(bFileIsDll) + fdProcessInfo = (PROCESS_INFORMATION*)InitDLLDebugW(StringUtils::Utf8ToUtf16(init->exe).c_str(), false, StringUtils::Utf8ToUtf16(init->commandline).c_str(), StringUtils::Utf8ToUtf16(init->currentfolder).c_str(), 0); + else + fdProcessInfo = (PROCESS_INFORMATION*)InitDebugW(StringUtils::Utf8ToUtf16(init->exe).c_str(), StringUtils::Utf8ToUtf16(init->commandline).c_str(), StringUtils::Utf8ToUtf16(init->currentfolder).c_str()); + if(!fdProcessInfo) + { + fdProcessInfo = &g_pi; + dputs("Error starting process (invalid pe?)!"); + unlock(WAITID_STOP); + return 0; + } + BOOL wow64 = false, mewow64 = false; + if(!IsWow64Process(fdProcessInfo->hProcess, &wow64) || !IsWow64Process(GetCurrentProcess(), &mewow64)) + { + dputs("IsWow64Process failed!"); + StopDebug(); + unlock(WAITID_STOP); + return 0; + } + if((mewow64 && !wow64) || (!mewow64 && wow64)) + { +#ifdef _WIN64 + dputs("Use x32dbg to debug this process!"); +#else + dputs("Use x64dbg to debug this process!"); +#endif // _WIN64 + unlock(WAITID_STOP); + return 0; + } + GuiAddRecentFile(szFileName); + varset("$hp", (duint)fdProcessInfo->hProcess, true); + varset("$pid", fdProcessInfo->dwProcessId, true); + ecount = 0; + //NOTE: set custom handlers + SetCustomHandler(UE_CH_CREATEPROCESS, (void*)cbCreateProcess); + SetCustomHandler(UE_CH_EXITPROCESS, (void*)cbExitProcess); + SetCustomHandler(UE_CH_CREATETHREAD, (void*)cbCreateThread); + SetCustomHandler(UE_CH_EXITTHREAD, (void*)cbExitThread); + SetCustomHandler(UE_CH_SYSTEMBREAKPOINT, (void*)cbSystemBreakpoint); + SetCustomHandler(UE_CH_LOADDLL, (void*)cbLoadDll); + SetCustomHandler(UE_CH_UNLOADDLL, (void*)cbUnloadDll); + SetCustomHandler(UE_CH_OUTPUTDEBUGSTRING, (void*)cbOutputDebugString); + SetCustomHandler(UE_CH_UNHANDLEDEXCEPTION, (void*)cbException); + SetCustomHandler(UE_CH_DEBUGEVENT, (void*)cbDebugEvent); + //inform GUI we started without problems + GuiSetDebugState(initialized); + //set GUI title + strcpy_s(szBaseFileName, szFileName); + int len = (int)strlen(szBaseFileName); + while(szBaseFileName[len] != '\\' && len) + len--; + if(len) + strcpy_s(szBaseFileName, szBaseFileName + len + 1); + GuiUpdateWindowTitle(szBaseFileName); + //call plugin callback + PLUG_CB_INITDEBUG initInfo; + initInfo.szFileName = szFileName; + plugincbcall(CB_INITDEBUG, &initInfo); + //run debug loop (returns when process debugging is stopped) + hProcess = fdProcessInfo->hProcess; + DebugLoop(); + isDetachedByUser = false; + //call plugin callback + PLUG_CB_STOPDEBUG stopInfo; + stopInfo.reserved = 0; + plugincbcall(CB_STOPDEBUG, &stopInfo); + //cleanup dbghelp + SafeSymRegisterCallback64(hProcess, nullptr, 0); + SafeSymCleanup(hProcess); + //message the user/do final stuff + RemoveAllBreakPoints(UE_OPTION_REMOVEALL); //remove all breakpoints + //cleanup + DBClose(); + ModClear(); + ThreadClear(); + GuiSetDebugState(stopped); + dputs("Debugging stopped!"); + varset("$hp", (duint)0, true); + varset("$pid", (duint)0, true); + unlock(WAITID_STOP); //we are done + pDebuggedEntry = 0; + pDebuggedBase = 0; + pCreateProcessBase = 0; + return 0; +} + +bool cbDeleteAllBreakpoints(const BREAKPOINT* bp) +{ + if(!BpDelete(bp->addr, BPNORMAL)) + { + dprintf("Delete breakpoint failed (BpDelete): " fhex "\n", bp->addr); + return false; + } + if(!bp->enabled || DeleteBPX(bp->addr)) + return true; + dprintf("Delete breakpoint failed (DeleteBPX): " fhex "\n", bp->addr); + return false; +} + +bool cbEnableAllBreakpoints(const BREAKPOINT* bp) +{ + if(bp->type != BPNORMAL || bp->enabled) + return true; + + if(!BpEnable(bp->addr, BPNORMAL, true)) + { + dprintf("Could not enable breakpoint " fhex " (BpEnable)\n", bp->addr); + return false; + } + if(!SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint)) + { + dprintf("Could not enable breakpoint " fhex " (SetBPX)\n", bp->addr); + return false; + } + return true; +} + +bool cbDisableAllBreakpoints(const BREAKPOINT* bp) +{ + if(bp->type != BPNORMAL || !bp->enabled) + return true; + + if(!BpEnable(bp->addr, BPNORMAL, false)) + { + dprintf("Could not disable breakpoint " fhex " (BpEnable)\n", bp->addr); + return false; + } + if(!DeleteBPX(bp->addr)) + { + dprintf("Could not disable breakpoint " fhex " (DeleteBPX)\n", bp->addr); + return false; + } + return true; +} + +bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp) +{ + if(bp->type != BPHARDWARE || bp->enabled) + return true; + DWORD drx = 0; + if(!GetUnusedHardwareBreakPointRegister(&drx)) + { + dprintf("Did not enable hardware breakpoint " fhex " (all slots full)\n", bp->addr); + return true; + } + int titantype = bp->titantype; + TITANSETDRX(titantype, drx); + BpSetTitanType(bp->addr, BPHARDWARE, titantype); + if(!BpEnable(bp->addr, BPHARDWARE, true)) + { + dprintf("Could not enable hardware breakpoint " fhex " (BpEnable)\n", bp->addr); + return false; + } + if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), (void*)cbHardwareBreakpoint)) + { + dprintf("Could not enable hardware breakpoint " fhex " (SetHardwareBreakPoint)\n", bp->addr); + return false; + } + return true; +} + +bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp) +{ + if(bp->type != BPHARDWARE || !bp->enabled) + return true; + if(!BpEnable(bp->addr, BPHARDWARE, false)) + { + dprintf("Could not disable hardware breakpoint " fhex " (BpEnable)\n", bp->addr); + return false; + } + if(!DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype))) + { + dprintf("Could not disable hardware breakpoint " fhex " (DeleteHardwareBreakPoint)\n", bp->addr); + return false; + } + return true; +} + +bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp) +{ + if(bp->type != BPMEMORY || bp->enabled) + return true; + duint size = 0; + MemFindBaseAddr(bp->addr, &size); + if(!BpEnable(bp->addr, BPMEMORY, true)) + { + dprintf("Could not enable memory breakpoint " fhex " (BpEnable)\n", bp->addr); + return false; + } + if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, (void*)cbMemoryBreakpoint)) + { + dprintf("Could not enable memory breakpoint " fhex " (SetMemoryBPXEx)\n", bp->addr); + return false; + } + return true; +} + +bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp) +{ + if(bp->type != BPMEMORY || !bp->enabled) + return true; + if(!BpEnable(bp->addr, BPMEMORY, false)) + { + dprintf("Could not disable memory breakpoint " fhex " (BpEnable)\n", bp->addr); + return false; + } + if(!RemoveMemoryBPX(bp->addr, 0)) + { + dprintf("Could not disable memory breakpoint " fhex " (RemoveMemoryBPX)\n", bp->addr); + return false; + } + return true; +} + +bool cbBreakpointList(const BREAKPOINT* bp) +{ + const char* type = 0; + if(bp->type == BPNORMAL) + { + if(bp->singleshoot) + type = "SS"; + else + type = "BP"; + } + else if(bp->type == BPHARDWARE) + type = "HW"; + else if(bp->type == BPMEMORY) + type = "GP"; + bool enabled = bp->enabled; + if(*bp->name) + dprintf("%d:%s:" fhex ":\"%s\"\n", enabled, type, bp->addr, bp->name); + else + dprintf("%d:%s:" fhex "\n", enabled, type, bp->addr); + return true; +} + +bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp) +{ + if(!bp->enabled) + return true; + duint size; + MemFindBaseAddr(bp->addr, &size); + if(!BpDelete(bp->addr, BPMEMORY)) + { + dprintf("Delete memory breakpoint failed (BpDelete): " fhex "\n", bp->addr); + return false; + } + if(!RemoveMemoryBPX(bp->addr, size)) + { + dprintf("Delete memory breakpoint failed (RemoveMemoryBPX): " fhex "\n", bp->addr); + return false; + } + return true; +} + +bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp) +{ + if(!bp->enabled) + return true; + if(!BpDelete(bp->addr, BPHARDWARE)) + { + dprintf("Delete hardware breakpoint failed (BpDelete): " fhex "\n", bp->addr); + return false; + } + if(!DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype))) + { + dprintf("Delete hardware breakpoint failed (DeleteHardwareBreakPoint): " fhex "\n", bp->addr); + return false; + } + return true; +} + +static void cbAttachDebugger() +{ + if(hEvent) //Signal the AeDebug event + { + SetEvent(hEvent); + hEvent = 0; + } + hProcess = fdProcessInfo->hProcess; + varset("$hp", (duint)fdProcessInfo->hProcess, true); + varset("$pid", fdProcessInfo->dwProcessId, true); +} + +DWORD WINAPI threadAttachLoop(void* lpParameter) +{ + lock(WAITID_STOP); + bIsAttached = true; + bSkipExceptions = false; + bFreezeStack = false; + DWORD pid = (DWORD)lpParameter; + static PROCESS_INFORMATION pi_attached; + fdProcessInfo = &pi_attached; + //do some init stuff + bFileIsDll = IsFileDLL(szFileName, 0); + GuiAddRecentFile(szFileName); + ecount = 0; + //NOTE: set custom handlers + SetCustomHandler(UE_CH_CREATEPROCESS, (void*)cbCreateProcess); + SetCustomHandler(UE_CH_EXITPROCESS, (void*)cbExitProcess); + SetCustomHandler(UE_CH_CREATETHREAD, (void*)cbCreateThread); + SetCustomHandler(UE_CH_EXITTHREAD, (void*)cbExitThread); + SetCustomHandler(UE_CH_SYSTEMBREAKPOINT, (void*)cbSystemBreakpoint); + SetCustomHandler(UE_CH_LOADDLL, (void*)cbLoadDll); + SetCustomHandler(UE_CH_UNLOADDLL, (void*)cbUnloadDll); + SetCustomHandler(UE_CH_OUTPUTDEBUGSTRING, (void*)cbOutputDebugString); + SetCustomHandler(UE_CH_UNHANDLEDEXCEPTION, (void*)cbException); + SetCustomHandler(UE_CH_DEBUGEVENT, (void*)cbDebugEvent); + //inform GUI start we started without problems + GuiSetDebugState(initialized); + //set GUI title + strcpy_s(szBaseFileName, szFileName); + int len = (int)strlen(szBaseFileName); + while(szBaseFileName[len] != '\\' && len) + len--; + if(len) + strcpy_s(szBaseFileName, szBaseFileName + len + 1); + GuiUpdateWindowTitle(szBaseFileName); + //call plugin callback (init) + PLUG_CB_INITDEBUG initInfo; + initInfo.szFileName = szFileName; + plugincbcall(CB_INITDEBUG, &initInfo); + //call plugin callback (attach) + PLUG_CB_ATTACH attachInfo; + attachInfo.dwProcessId = (DWORD)pid; + plugincbcall(CB_ATTACH, &attachInfo); + //run debug loop (returns when process debugging is stopped) + AttachDebugger(pid, true, fdProcessInfo, (void*)cbAttachDebugger); + isDetachedByUser = false; + //call plugin callback + PLUG_CB_STOPDEBUG stopInfo; + stopInfo.reserved = 0; + plugincbcall(CB_STOPDEBUG, &stopInfo); + //cleanup dbghelp + SafeSymRegisterCallback64(hProcess, nullptr, 0); + SafeSymCleanup(hProcess); + //message the user/do final stuff + RemoveAllBreakPoints(UE_OPTION_REMOVEALL); //remove all breakpoints + //cleanup + DBClose(); + ModClear(); + ThreadClear(); + GuiSetDebugState(stopped); + dputs("debugging stopped!"); + varset("$hp", (duint)0, true); + varset("$pid", (duint)0, true); + unlock(WAITID_STOP); + return 0; +} + +void cbDetach() +{ + if(!isDetachedByUser) + return; + PLUG_CB_DETACH detachInfo; + detachInfo.fdProcessInfo = fdProcessInfo; + plugincbcall(CB_DETACH, &detachInfo); + if(!DetachDebuggerEx(fdProcessInfo->dwProcessId)) + dputs("DetachDebuggerEx failed..."); + else + dputs("Detached!"); + return; +} + +bool dbglistprocesses(std::vector* list) +{ + list->clear(); + Handle hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if(!hProcessSnap) + return false; + PROCESSENTRY32 pe32; + pe32.dwSize = sizeof(PROCESSENTRY32); + if(!Process32First(hProcessSnap, &pe32)) + return false; + do + { + if(pe32.th32ProcessID == GetCurrentProcessId()) + continue; + if(!_stricmp(pe32.szExeFile, "System")) + continue; + if(!_stricmp(pe32.szExeFile, "[System Process]")) + continue; + Handle hProcess = TitanOpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pe32.th32ProcessID); + if(!hProcess) + continue; + BOOL wow64 = false, mewow64 = false; + if(!IsWow64Process(hProcess, &wow64) || !IsWow64Process(GetCurrentProcess(), &mewow64)) + continue; + if((mewow64 && !wow64) || (!mewow64 && wow64)) + continue; + wchar_t szExePath[MAX_PATH] = L""; + if(GetModuleFileNameExW(hProcess, 0, szExePath, MAX_PATH)) + strcpy_s(pe32.szExeFile, StringUtils::Utf16ToUtf8(szExePath).c_str()); + list->push_back(pe32); + } + while(Process32Next(hProcessSnap, &pe32)); + return true; +} + +static bool getcommandlineaddr(duint* addr, cmdline_error_t* cmd_line_error) +{ + duint pprocess_parameters; + + cmd_line_error->addr = (duint)GetPEBLocation(fdProcessInfo->hProcess); + + if(cmd_line_error->addr == 0) + { + cmd_line_error->type = CMDL_ERR_GET_PEB; + return false; + } + + //cast-trick to calculate the address of the remote peb field ProcessParameters + cmd_line_error->addr = (duint) & (((PPEB) cmd_line_error->addr)->ProcessParameters); + if(!MemRead(cmd_line_error->addr, &pprocess_parameters, sizeof(pprocess_parameters))) + { + cmd_line_error->type = CMDL_ERR_READ_PEBBASE; + return false; + } + + *addr = (duint) & (((RTL_USER_PROCESS_PARAMETERS*) pprocess_parameters)->CommandLine); + return true; +} + +static bool patchcmdline(duint getcommandline, duint new_command_line, cmdline_error_t* cmd_line_error) +{ + duint command_line_stored = 0; + unsigned char data[100]; + + cmd_line_error->addr = getcommandline; + if(!MemRead(cmd_line_error->addr, & data, sizeof(data))) + { + cmd_line_error->type = CMDL_ERR_READ_GETCOMMANDLINEBASE; + return false; + } + +#ifdef _WIN64 + /* + 00007FFC5B91E3C8 | 48 8B 05 19 1D 0E 00 | mov rax,qword ptr ds:[7FFC5BA000E8] + 00007FFC5B91E3CF | C3 | ret | + This is a relative offset then to get the symbol: next instruction of getmodulehandle (+7 bytes) + offset to symbol + (the last 4 bytes of the instruction) + */ + if(data[0] != 0x48 || data[1] != 0x8B || data[2] != 0x05 || data[7] != 0xC3) + { + cmd_line_error->type = CMDL_ERR_CHECK_GETCOMMANDLINESTORED; + return false; + } + DWORD offset = * ((DWORD*) & data[3]); + command_line_stored = getcommandline + 7 + offset; +#else //x86 + /* + 750FE9CA | A1 CC DB 1A 75 | mov eax,dword ptr ds:[751ADBCC] | + 750FE9CF | C3 | ret | + */ + if(data[0] != 0xA1 || data[5] != 0xC3) + { + cmd_line_error->type = CMDL_ERR_CHECK_GETCOMMANDLINESTORED; + return false; + } + command_line_stored = * ((duint*) & data[1]); +#endif + + //update the pointer in the debuggee + if(!MemWrite(command_line_stored, &new_command_line, sizeof(new_command_line))) + { + cmd_line_error->addr = command_line_stored; + cmd_line_error->type = CMDL_ERR_WRITE_GETCOMMANDLINESTORED; + return false; + } + + return true; +} + +static bool fixgetcommandlinesbase(duint new_command_line_unicode, duint new_command_line_ascii, cmdline_error_t* cmd_line_error) +{ + duint getcommandline; + + if(!valfromstring("kernelbase:GetCommandLineA", &getcommandline)) + { + if(!valfromstring("kernel32:GetCommandLineA", &getcommandline)) + { + cmd_line_error->type = CMDL_ERR_GET_GETCOMMANDLINE; + return false; + } + } + if(!patchcmdline(getcommandline, new_command_line_ascii, cmd_line_error)) + return false; + + if(!valfromstring("kernelbase:GetCommandLineW", &getcommandline)) + { + if(!valfromstring("kernel32:GetCommandLineW", &getcommandline)) + { + cmd_line_error->type = CMDL_ERR_GET_GETCOMMANDLINE; + return false; + } + } + if(!patchcmdline(getcommandline, new_command_line_unicode, cmd_line_error)) + return false; + + return true; +} + +bool dbgsetcmdline(const char* cmd_line, cmdline_error_t* cmd_line_error) +{ + cmdline_error_t cmd_line_error_aux; + UNICODE_STRING new_command_line; + duint command_line_addr; + + if(cmd_line_error == NULL) + cmd_line_error = &cmd_line_error_aux; + + if(!getcommandlineaddr(&cmd_line_error->addr, cmd_line_error)) + return false; + + command_line_addr = cmd_line_error->addr; + + SIZE_T cmd_line_size = strlen(cmd_line); + new_command_line.Length = (USHORT)(strlen(cmd_line) + 1) * sizeof(WCHAR); + new_command_line.MaximumLength = new_command_line.Length; + + Memory command_linewstr(new_command_line.Length); + + // Covert to Unicode. + if(!MultiByteToWideChar(CP_UTF8, 0, cmd_line, (int)cmd_line_size + 1, command_linewstr(), (int)cmd_line_size + 1)) + { + cmd_line_error->type = CMDL_ERR_CONVERTUNICODE; + return false; + } + + new_command_line.Buffer = command_linewstr(); + + duint mem = (duint)MemAllocRemote(0, new_command_line.Length * 2); + if(!mem) + { + cmd_line_error->type = CMDL_ERR_ALLOC_UNICODEANSI_COMMANDLINE; + return false; + } + + if(!MemWrite(mem, new_command_line.Buffer, new_command_line.Length)) + { + cmd_line_error->addr = mem; + cmd_line_error->type = CMDL_ERR_WRITE_UNICODE_COMMANDLINE; + return false; + } + + if(!MemWrite((mem + new_command_line.Length), (void*)cmd_line, strlen(cmd_line) + 1)) + { + cmd_line_error->addr = mem + new_command_line.Length; + cmd_line_error->type = CMDL_ERR_WRITE_ANSI_COMMANDLINE; + return false; + } + + if(!fixgetcommandlinesbase(mem, mem + new_command_line.Length, cmd_line_error)) + return false; + + new_command_line.Buffer = (PWSTR) mem; + if(!MemWrite(command_line_addr, &new_command_line, sizeof(new_command_line))) + { + cmd_line_error->addr = command_line_addr; + cmd_line_error->type = CMDL_ERR_WRITE_PEBUNICODE_COMMANDLINE; + return false; + } + + return true; +} + +bool dbggetcmdline(char** cmd_line, cmdline_error_t* cmd_line_error) +{ + UNICODE_STRING CommandLine; + cmdline_error_t cmd_line_error_aux; + + if(!cmd_line_error) + cmd_line_error = &cmd_line_error_aux; + + if(!getcommandlineaddr(&cmd_line_error->addr, cmd_line_error)) + return false; + + if(!MemRead(cmd_line_error->addr, &CommandLine, sizeof(CommandLine))) + { + cmd_line_error->type = CMDL_ERR_READ_PROCPARM_PTR; + return false; + } + + Memory wstr_cmd(CommandLine.Length + sizeof(wchar_t)); + + cmd_line_error->addr = (duint) CommandLine.Buffer; + if(!MemRead(cmd_line_error->addr, wstr_cmd(), CommandLine.Length)) + { + cmd_line_error->type = CMDL_ERR_READ_PROCPARM_CMDLINE; + return false; + } + + SIZE_T wstr_cmd_size = wcslen(wstr_cmd()) + 1; + SIZE_T cmd_line_size = wstr_cmd_size * 2; + + *cmd_line = (char*)emalloc(cmd_line_size, "dbggetcmdline:cmd_line"); + + //Convert TO UTF-8 + if(!WideCharToMultiByte(CP_UTF8, 0, wstr_cmd(), (int)wstr_cmd_size, * cmd_line, (int)cmd_line_size, NULL, NULL)) + { + efree(*cmd_line); + cmd_line_error->type = CMDL_ERR_CONVERTUNICODE; + return false; + } + return true; +} + +static DWORD WINAPI scriptThread(void* data) +{ + CBPLUGINSCRIPT cbScript = (CBPLUGINSCRIPT)data; + cbScript(); + return 0; +} + +void dbgstartscriptthread(CBPLUGINSCRIPT cbScript) +{ + CloseHandle(CreateThread(0, 0, scriptThread, cbScript, 0, 0)); +} + +duint dbggetdebuggedbase() +{ + return pDebuggedBase; } \ No newline at end of file diff --git a/src/dbg/debugger.h b/src/dbg/debugger.h index ad6bd02b..3f5294e1 100644 --- a/src/dbg/debugger.h +++ b/src/dbg/debugger.h @@ -1,120 +1,120 @@ -#ifndef _DEBUGGER_H -#define _DEBUGGER_H - -#include "_global.h" -#include "TitanEngine\TitanEngine.h" -#include "command.h" -#include "breakpoint.h" -#include "undocumented.h" -#include "value.h" -#include "_plugins.h" - -#define MS_VC_EXCEPTION 0x406D1388 - -//structures -struct INIT_STRUCT -{ - char* exe; - char* commandline; - char* currentfolder; -}; - -typedef enum -{ - CMDL_ERR_READ_PEBBASE = 0, - CMDL_ERR_READ_PROCPARM_PTR, - CMDL_ERR_READ_PROCPARM_CMDLINE, - CMDL_ERR_CONVERTUNICODE, - CMDL_ERR_ALLOC, - CMDL_ERR_GET_PEB, - CMDL_ERR_READ_GETCOMMANDLINEBASE, - CMDL_ERR_CHECK_GETCOMMANDLINESTORED, - CMDL_ERR_WRITE_GETCOMMANDLINESTORED, - CMDL_ERR_GET_GETCOMMANDLINE, - CMDL_ERR_ALLOC_UNICODEANSI_COMMANDLINE, - CMDL_ERR_WRITE_ANSI_COMMANDLINE, - CMDL_ERR_WRITE_UNICODE_COMMANDLINE, - CMDL_ERR_WRITE_PEBUNICODE_COMMANDLINE - -} cmdline_error_type_t; - -typedef struct -{ - cmdline_error_type_t type; - duint addr; -} cmdline_error_t; - -struct ExceptionRange -{ - unsigned int start; - unsigned int end; -}; - -#pragma pack(push,8) -typedef struct _THREADNAME_INFO -{ - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -} THREADNAME_INFO; -#pragma pack(pop) - -//functions -void dbginit(); -void dbgstop(); -duint dbgdebuggedbase(); -duint dbggettimewastedcounter(); -bool dbgisrunning(); -bool dbgisdll(); -void dbgsetattachevent(HANDLE handle); -void DebugUpdateGui(duint disasm_addr, bool stack); -void DebugUpdateStack(duint dumpAddr, duint csp, bool forceDump = false); -void dbgsetskipexceptions(bool skip); -void dbgsetstepping(bool stepping); -void dbgsetispausedbyuser(bool b); -void dbgsetisdetachedbyuser(bool b); -void dbgsetfreezestack(bool freeze); -void dbgclearignoredexceptions(); -void dbgaddignoredexception(ExceptionRange range); -bool dbgisignoredexception(unsigned int exception); -bool dbgcmdnew(const char* name, CBCOMMAND cbCommand, bool debugonly); -bool dbgcmddel(const char* name); -bool dbglistprocesses(std::vector* list); -bool dbgsetcmdline(const char* cmd_line, cmdline_error_t* cmd_line_error); -bool dbggetcmdline(char** cmd_line, cmdline_error_t* cmd_line_error); -void dbgstartscriptthread(CBPLUGINSCRIPT cbScript); -duint dbggetdebuggedbase(); - -void cbStep(); -void cbRtrStep(); -void cbSystemBreakpoint(void* ExceptionData); -void cbMemoryBreakpoint(void* ExceptionAddress); -void cbHardwareBreakpoint(void* ExceptionAddress); -void cbUserBreakpoint(); -void cbDebugLoadLibBPX(); -void cbLibrarianBreakpoint(void* lpData); -DWORD WINAPI threadDebugLoop(void* lpParameter); -bool cbDeleteAllBreakpoints(const BREAKPOINT* bp); -bool cbEnableAllBreakpoints(const BREAKPOINT* bp); -bool cbDisableAllBreakpoints(const BREAKPOINT* bp); -bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp); -bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp); -bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp); -bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp); -bool cbBreakpointList(const BREAKPOINT* bp); -bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp); -bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp); -DWORD WINAPI threadAttachLoop(void* lpParameter); -void cbDetach(); -bool cbSetModuleBreakpoints(const BREAKPOINT* bp); - -//variables -extern PROCESS_INFORMATION* fdProcessInfo; -extern HANDLE hActiveThread; -extern char szFileName[MAX_PATH]; -extern char szSymbolCachePath[MAX_PATH]; -extern bool bUndecorateSymbolNames; -extern bool bEnableSourceDebugging; - -#endif // _DEBUGGER_H +#ifndef _DEBUGGER_H +#define _DEBUGGER_H + +#include "_global.h" +#include "TitanEngine\TitanEngine.h" +#include "command.h" +#include "breakpoint.h" +#include "undocumented.h" +#include "value.h" +#include "_plugins.h" + +#define MS_VC_EXCEPTION 0x406D1388 + +//structures +struct INIT_STRUCT +{ + char* exe; + char* commandline; + char* currentfolder; +}; + +typedef enum +{ + CMDL_ERR_READ_PEBBASE = 0, + CMDL_ERR_READ_PROCPARM_PTR, + CMDL_ERR_READ_PROCPARM_CMDLINE, + CMDL_ERR_CONVERTUNICODE, + CMDL_ERR_ALLOC, + CMDL_ERR_GET_PEB, + CMDL_ERR_READ_GETCOMMANDLINEBASE, + CMDL_ERR_CHECK_GETCOMMANDLINESTORED, + CMDL_ERR_WRITE_GETCOMMANDLINESTORED, + CMDL_ERR_GET_GETCOMMANDLINE, + CMDL_ERR_ALLOC_UNICODEANSI_COMMANDLINE, + CMDL_ERR_WRITE_ANSI_COMMANDLINE, + CMDL_ERR_WRITE_UNICODE_COMMANDLINE, + CMDL_ERR_WRITE_PEBUNICODE_COMMANDLINE + +} cmdline_error_type_t; + +typedef struct +{ + cmdline_error_type_t type; + duint addr; +} cmdline_error_t; + +struct ExceptionRange +{ + unsigned int start; + unsigned int end; +}; + +#pragma pack(push,8) +typedef struct _THREADNAME_INFO +{ + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) + +//functions +void dbginit(); +void dbgstop(); +duint dbgdebuggedbase(); +duint dbggettimewastedcounter(); +bool dbgisrunning(); +bool dbgisdll(); +void dbgsetattachevent(HANDLE handle); +void DebugUpdateGui(duint disasm_addr, bool stack); +void DebugUpdateStack(duint dumpAddr, duint csp, bool forceDump = false); +void dbgsetskipexceptions(bool skip); +void dbgsetstepping(bool stepping); +void dbgsetispausedbyuser(bool b); +void dbgsetisdetachedbyuser(bool b); +void dbgsetfreezestack(bool freeze); +void dbgclearignoredexceptions(); +void dbgaddignoredexception(ExceptionRange range); +bool dbgisignoredexception(unsigned int exception); +bool dbgcmdnew(const char* name, CBCOMMAND cbCommand, bool debugonly); +bool dbgcmddel(const char* name); +bool dbglistprocesses(std::vector* list); +bool dbgsetcmdline(const char* cmd_line, cmdline_error_t* cmd_line_error); +bool dbggetcmdline(char** cmd_line, cmdline_error_t* cmd_line_error); +void dbgstartscriptthread(CBPLUGINSCRIPT cbScript); +duint dbggetdebuggedbase(); + +void cbStep(); +void cbRtrStep(); +void cbSystemBreakpoint(void* ExceptionData); +void cbMemoryBreakpoint(void* ExceptionAddress); +void cbHardwareBreakpoint(void* ExceptionAddress); +void cbUserBreakpoint(); +void cbDebugLoadLibBPX(); +void cbLibrarianBreakpoint(void* lpData); +DWORD WINAPI threadDebugLoop(void* lpParameter); +bool cbDeleteAllBreakpoints(const BREAKPOINT* bp); +bool cbEnableAllBreakpoints(const BREAKPOINT* bp); +bool cbDisableAllBreakpoints(const BREAKPOINT* bp); +bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp); +bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp); +bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp); +bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp); +bool cbBreakpointList(const BREAKPOINT* bp); +bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp); +bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp); +DWORD WINAPI threadAttachLoop(void* lpParameter); +void cbDetach(); +bool cbSetModuleBreakpoints(const BREAKPOINT* bp); + +//variables +extern PROCESS_INFORMATION* fdProcessInfo; +extern HANDLE hActiveThread; +extern char szFileName[MAX_PATH]; +extern char szSymbolCachePath[MAX_PATH]; +extern bool bUndecorateSymbolNames; +extern bool bEnableSourceDebugging; + +#endif // _DEBUGGER_H diff --git a/src/dbg/debugger_commands.cpp b/src/dbg/debugger_commands.cpp index c74245f9..a580a99d 100644 --- a/src/dbg/debugger_commands.cpp +++ b/src/dbg/debugger_commands.cpp @@ -1,2106 +1,2106 @@ -/** - @file debugger_commands.cpp - - @brief Implements the debugger commands class. - */ - -#include "debugger_commands.h" -#include "jit.h" -#include "console.h" -#include "value.h" -#include "thread.h" -#include "memory.h" -#include "threading.h" -#include "variable.h" -#include "plugin_loader.h" -#include "simplescript.h" -#include "symbolinfo.h" -#include "assemble.h" -#include "disasm_fast.h" -#include "module.h" -#include "comment.h" -#include "label.h" -#include "bookmark.h" -#include "function.h" - -static bool bScyllaLoaded = false; -duint LoadLibThreadID; -duint DLLNameMem; -duint ASMAddr; -TITAN_ENGINE_CONTEXT_t backupctx = { 0 }; - -CMDRESULT cbDebugInit(int argc, char* argv[]) -{ - cbDebugStop(argc, argv); - - static char arg1[deflen] = ""; - if(argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - strcpy_s(arg1, argv[1]); - char szResolvedPath[MAX_PATH] = ""; - if(ResolveShortcut(GuiGetWindowHandle(), StringUtils::Utf8ToUtf16(arg1).c_str(), szResolvedPath, _countof(szResolvedPath))) - { - dprintf("Resolved shortcut \"%s\"->\"%s\"\n", arg1, szResolvedPath); - strcpy_s(arg1, szResolvedPath); - } - if(!FileExists(arg1)) - { - dputs("File does not exist!"); - return STATUS_ERROR; - } - Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(arg1).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); - if(hFile == INVALID_HANDLE_VALUE) - { - dputs("Could not open file!"); - return STATUS_ERROR; - } - GetFileNameFromHandle(hFile, arg1); //get full path of the file - hFile.Close(); - - //do some basic checks - switch(GetFileArchitecture(arg1)) - { - case invalid: - dputs("Invalid PE file!"); - return STATUS_ERROR; -#ifdef _WIN64 - case x32: - dputs("Use x32dbg to debug this file!"); -#else //x86 - case x64: - dputs("Use x64dbg to debug this file!"); -#endif //_WIN64 - return STATUS_ERROR; - default: - break; - } - - static char arg2[deflen] = ""; - if(argc > 2) - strcpy_s(arg2, argv[2]); - char* commandline = 0; - if(strlen(arg2)) - commandline = arg2; - - char arg3[deflen] = ""; - if(argc > 3) - strcpy_s(arg3, argv[3]); - - static char currentfolder[deflen] = ""; - strcpy_s(currentfolder, arg1); - int len = (int)strlen(currentfolder); - while(currentfolder[len] != '\\' && len != 0) - len--; - currentfolder[len] = 0; - - if(DirExists(arg3)) - strcpy_s(currentfolder, arg3); - - static INIT_STRUCT init; - memset(&init, 0, sizeof(INIT_STRUCT)); - init.exe = arg1; - init.commandline = commandline; - if(*currentfolder) - init.currentfolder = currentfolder; - CloseHandle(CreateThread(0, 0, threadDebugLoop, &init, 0, 0)); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugStop(int argc, char* argv[]) -{ - // HACK: TODO: Don't kill script on debugger ending a process - //scriptreset(); //reset the currently-loaded script - StopDebug(); - while(waitislocked(WAITID_STOP)) //custom waiting - { - unlock(WAITID_RUN); - Sleep(1); - } - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugRun(int argc, char* argv[]) -{ - if(dbgisrunning()) - { - dputs("Program is already running"); - return STATUS_ERROR; - } - GuiSetDebugState(running); - unlock(WAITID_RUN); - PLUG_CB_RESUMEDEBUG callbackInfo; - callbackInfo.reserved = 0; - plugincbcall(CB_RESUMEDEBUG, &callbackInfo); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugErun(int argc, char* argv[]) -{ - if(!dbgisrunning()) - dbgsetskipexceptions(true); - return cbDebugRun(argc, argv); -} - -CMDRESULT cbDebugSetBPXOptions(int argc, char* argv[]) -{ - if(argc < 2) - { - dputs("Not enough arguments!"); - return STATUS_ERROR; - } - DWORD type = 0; - const char* strType = 0; - duint setting_type; - if(strstr(argv[1], "long")) - { - setting_type = 1; //break_int3long - strType = "TYPE_LONG_INT3"; - type = UE_BREAKPOINT_LONG_INT3; - } - else if(strstr(argv[1], "ud2")) - { - setting_type = 2; //break_ud2 - strType = "TYPE_UD2"; - type = UE_BREAKPOINT_UD2; - } - else if(strstr(argv[1], "short")) - { - setting_type = 0; //break_int3short - strType = "TYPE_INT3"; - type = UE_BREAKPOINT_INT3; - } - else - { - dputs("Invalid type specified!"); - return STATUS_ERROR; - } - SetBPXOptions(type); - BridgeSettingSetUint("Engine", "BreakpointType", setting_type); - dprintf("Default breakpoint type set to: %s\n", strType); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugSetBPX(int argc, char* argv[]) //bp addr [,name [,type]] -{ - if(argc < 2) - { - dputs("Not enough arguments!"); - return STATUS_ERROR; - } - char argaddr[deflen] = ""; - strcpy_s(argaddr, argv[1]); - char argname[deflen] = ""; - if(argc > 2) - strcpy_s(argname, argv[2]); - char argtype[deflen] = ""; - bool has_arg2 = argc > 3; - if(has_arg2) - strcpy_s(argtype, argv[3]); - if(!has_arg2 && (scmp(argname, "ss") || scmp(argname, "long") || scmp(argname, "ud2"))) - { - strcpy_s(argtype, argname); - *argname = 0; - } - _strlwr(argtype); - duint addr = 0; - if(!valfromstring(argaddr, &addr)) - { - dprintf("Invalid addr: \"%s\"\n", argaddr); - return STATUS_ERROR; - } - int type = 0; - bool singleshoot = false; - if(strstr(argtype, "ss")) - { - type |= UE_SINGLESHOOT; - singleshoot = true; - } - else - type |= UE_BREAKPOINT; - if(strstr(argtype, "long")) - type |= UE_BREAKPOINT_TYPE_LONG_INT3; - else if(strstr(argtype, "ud2")) - type |= UE_BREAKPOINT_TYPE_UD2; - else if(strstr(argtype, "short")) - type |= UE_BREAKPOINT_TYPE_INT3; - short oldbytes; - const char* bpname = 0; - if(*argname) - bpname = argname; - if(BpGet(addr, BPNORMAL, bpname, 0)) - { - dputs("Breakpoint already set!"); - return STATUS_CONTINUE; - } - if(IsBPXEnabled(addr)) - { - dprintf("Error setting breakpoint at " fhex "! (IsBPXEnabled)\n", addr); - return STATUS_ERROR; - } - else if(!MemRead(addr, &oldbytes, sizeof(short))) - { - dprintf("Error setting breakpoint at " fhex "! (memread)\n", addr); - return STATUS_ERROR; - } - else if(!BpNew(addr, true, singleshoot, oldbytes, BPNORMAL, type, bpname)) - { - dprintf("Error setting breakpoint at " fhex "! (bpnew)\n", addr); - return STATUS_ERROR; - } - else if(!SetBPX(addr, type, (void*)cbUserBreakpoint)) - { - dprintf("Error setting breakpoint at " fhex "! (SetBPX)\n", addr); - return STATUS_ERROR; - } - dprintf("Breakpoint at " fhex " set!\n", addr); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugDeleteBPX(int argc, char* argv[]) -{ - if(argc < 2) //delete all breakpoints - { - if(!BpGetCount(BPNORMAL)) - { - dputs("No breakpoints to delete!"); - return STATUS_CONTINUE; - } - if(!BpEnumAll(cbDeleteAllBreakpoints)) //at least one deletion failed - { - GuiUpdateAllViews(); - return STATUS_ERROR; - } - dputs("All breakpoints deleted!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - BREAKPOINT found; - if(BpGet(0, BPNORMAL, argv[1], &found)) //found a breakpoint with name - { - if(!BpDelete(found.addr, BPNORMAL)) - { - dprintf("Delete breakpoint failed (bpdel): " fhex "\n", found.addr); - return STATUS_ERROR; - } - else if(found.enabled && !DeleteBPX(found.addr)) - { - dprintf("Delete breakpoint failed (DeleteBPX): " fhex "\n", found.addr); - GuiUpdateAllViews(); - return STATUS_ERROR; - } - return STATUS_CONTINUE; - } - duint addr = 0; - if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint - { - dprintf("No such breakpoint \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - if(!BpDelete(found.addr, BPNORMAL)) - { - dprintf("Delete breakpoint failed (bpdel): " fhex "\n", found.addr); - return STATUS_ERROR; - } - else if(found.enabled && !DeleteBPX(found.addr)) - { - dprintf("Delete breakpoint failed (DeleteBPX): " fhex "\n", found.addr); - GuiUpdateAllViews(); - return STATUS_ERROR; - } - dputs("Breakpoint deleted!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugEnableBPX(int argc, char* argv[]) -{ - if(argc < 2) //enable all breakpoints - { - if(!BpGetCount(BPNORMAL)) - { - dputs("No breakpoints to enable!"); - return STATUS_CONTINUE; - } - if(!BpEnumAll(cbEnableAllBreakpoints)) //at least one enable failed - return STATUS_ERROR; - dputs("All breakpoints enabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - BREAKPOINT found; - if(BpGet(0, BPNORMAL, argv[1], &found)) //found a breakpoint with name - { - if(!BpEnable(found.addr, BPNORMAL, true)) - { - dprintf("Could not enable breakpoint " fhex " (BpEnable)\n", found.addr); - return STATUS_ERROR; - } - if(!SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint)) - { - dprintf("Could not enable breakpoint " fhex " (SetBPX)\n", found.addr); - return STATUS_ERROR; - } - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - duint addr = 0; - if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint - { - dprintf("No such breakpoint \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - if(found.enabled) - { - dputs("Breakpoint already enabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - if(!BpEnable(found.addr, BPNORMAL, true)) - { - dprintf("Could not enable breakpoint " fhex " (BpEnable)\n", found.addr); - return STATUS_ERROR; - } - if(!SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint)) - { - dprintf("Could not enable breakpoint " fhex " (SetBPX)\n", found.addr); - return STATUS_ERROR; - } - dputs("Breakpoint enabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugDisableBPX(int argc, char* argv[]) -{ - if(argc < 2) //delete all breakpoints - { - if(!BpGetCount(BPNORMAL)) - { - dputs("No breakpoints to disable!"); - return STATUS_CONTINUE; - } - if(!BpEnumAll(cbDisableAllBreakpoints)) //at least one deletion failed - return STATUS_ERROR; - dputs("All breakpoints disabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - BREAKPOINT found; - if(BpGet(0, BPNORMAL, argv[1], &found)) //found a breakpoint with name - { - if(!BpEnable(found.addr, BPNORMAL, false)) - { - dprintf("Could not disable breakpoint " fhex " (BpEnable)\n", found.addr); - return STATUS_ERROR; - } - if(!DeleteBPX(found.addr)) - { - dprintf("Could not disable breakpoint " fhex " (DeleteBPX)\n", found.addr); - return STATUS_ERROR; - } - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - duint addr = 0; - if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint - { - dprintf("No such breakpoint \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - if(!found.enabled) - { - dputs("Breakpoint already disabled!"); - return STATUS_CONTINUE; - } - if(!BpEnable(found.addr, BPNORMAL, false)) - { - dprintf("Could not disable breakpoint " fhex " (BpEnable)\n", found.addr); - return STATUS_ERROR; - } - if(!DeleteBPX(found.addr)) - { - dprintf("Could not disable breakpoint " fhex " (DeleteBPX)\n", found.addr); - return STATUS_ERROR; - } - dputs("Breakpoint disabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugBplist(int argc, char* argv[]) -{ - if(!BpEnumAll(cbBreakpointList)) - { - dputs("Something went wrong..."); - return STATUS_ERROR; - } - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugStepInto(int argc, char* argv[]) -{ - StepInto((void*)cbStep); - dbgsetstepping(true); - return cbDebugRun(argc, argv); -} - -CMDRESULT cbDebugeStepInto(int argc, char* argv[]) -{ - dbgsetskipexceptions(true); - return cbDebugStepInto(argc, argv); -} - -CMDRESULT cbDebugStepOver(int argc, char* argv[]) -{ - StepOver((void*)cbStep); - dbgsetstepping(true); - return cbDebugRun(argc, argv); -} - -CMDRESULT cbDebugeStepOver(int argc, char* argv[]) -{ - dbgsetskipexceptions(true); - return cbDebugStepOver(argc, argv); -} - -CMDRESULT cbDebugSingleStep(int argc, char* argv[]) -{ - duint stepcount = 1; - if(argc > 1) - if(!valfromstring(argv[1], &stepcount)) - stepcount = 1; - SingleStep((DWORD)stepcount, (void*)cbStep); - dbgsetstepping(true); - return cbDebugRun(argc, argv); -} - -CMDRESULT cbDebugeSingleStep(int argc, char* argv[]) -{ - dbgsetskipexceptions(true); - return cbDebugSingleStep(argc, argv); -} - -CMDRESULT cbDebugHide(int argc, char* argv[]) -{ - if(HideDebugger(fdProcessInfo->hProcess, UE_HIDE_PEBONLY)) - dputs("Debugger hidden"); - else - dputs("Something went wrong"); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugDisasm(int argc, char* argv[]) -{ - duint addr = 0; - if(argc > 1) - { - if(!valfromstring(argv[1], &addr)) - addr = GetContextDataEx(hActiveThread, UE_CIP); - } - if(!MemIsValidReadPtr(addr)) - return STATUS_CONTINUE; - DebugUpdateGui(addr, false); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugSetMemoryBpx(int argc, char* argv[]) -{ - if(argc < 2) - { - dputs("Not enough arguments!"); - return STATUS_ERROR; - } - duint addr; - if(!valfromstring(argv[1], &addr)) - return STATUS_ERROR; - bool restore = false; - char arg3[deflen] = ""; - if(argc > 3) - strcpy_s(arg3, argv[3]); - if(argc > 2) - { - if(*argv[2] == '1') - restore = true; - else if(*argv[2] == '0') - restore = false; - else - strcpy_s(arg3, argv[2]); - } - DWORD type = UE_MEMORY; - if(*arg3) - { - switch(*arg3) - { - case 'r': - type = UE_MEMORY_READ; - break; - case 'w': - type = UE_MEMORY_WRITE; - break; - case 'x': - type = UE_MEMORY_EXECUTE; //EXECUTE - break; - default: - dputs("Invalid type (argument ignored)"); - break; - } - } - duint size = 0; - duint base = MemFindBaseAddr(addr, &size, true); - bool singleshoot = false; - if(!restore) - singleshoot = true; - if(BpGet(base, BPMEMORY, 0, 0)) - { - dputs("Hardware breakpoint already set!"); - return STATUS_CONTINUE; - } - if(!BpNew(base, true, singleshoot, 0, BPMEMORY, type, 0)) - { - dputs("Error setting memory breakpoint! (BpNew)"); - return STATUS_ERROR; - } - if(!SetMemoryBPXEx(base, size, type, restore, (void*)cbMemoryBreakpoint)) - { - dputs("Error setting memory breakpoint! (SetMemoryBPXEx)"); - return STATUS_ERROR; - } - dprintf("Memory breakpoint at " fhex " set!\n", addr); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugDeleteMemoryBreakpoint(int argc, char* argv[]) -{ - if(argc < 2) //delete all breakpoints - { - if(!BpGetCount(BPMEMORY)) - { - dputs("no memory breakpoints to delete!"); - return STATUS_CONTINUE; - } - if(!BpEnumAll(cbDeleteAllMemoryBreakpoints)) //at least one deletion failed - return STATUS_ERROR; - dputs("All memory breakpoints deleted!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - BREAKPOINT found; - if(BpGet(0, BPMEMORY, argv[1], &found)) //found a breakpoint with name - { - duint size; - MemFindBaseAddr(found.addr, &size); - if(!BpDelete(found.addr, BPMEMORY)) - { - dprintf("Delete memory breakpoint failed: " fhex " (BpDelete)\n", found.addr); - return STATUS_ERROR; - } - if(!RemoveMemoryBPX(found.addr, size)) - { - dprintf("Delete memory breakpoint failed: " fhex " (RemoveMemoryBPX)\n", found.addr); - return STATUS_ERROR; - } - return STATUS_CONTINUE; - } - duint addr = 0; - if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPMEMORY, 0, &found)) //invalid breakpoint - { - dprintf("No such memory breakpoint \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - duint size; - MemFindBaseAddr(found.addr, &size); - if(!BpDelete(found.addr, BPMEMORY)) - { - dprintf("Delete memory breakpoint failed: " fhex " (BpDelete)\n", found.addr); - return STATUS_ERROR; - } - if(!RemoveMemoryBPX(found.addr, size)) - { - dprintf("Delete memory breakpoint failed: " fhex " (RemoveMemoryBPX)\n", found.addr); - return STATUS_ERROR; - } - dputs("Memory breakpoint deleted!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugRtr(int argc, char* argv[]) -{ - StepOver((void*)cbRtrStep); - cbDebugRun(argc, argv); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugeRtr(int argc, char* argv[]) -{ - dbgsetskipexceptions(true); - return cbDebugRtr(argc, argv); -} - -CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[]) -{ - if(argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr; - if(!valfromstring(argv[1], &addr)) - return STATUS_ERROR; - DWORD type = UE_HARDWARE_EXECUTE; - if(argc > 2) - { - switch(*argv[2]) - { - case 'r': - type = UE_HARDWARE_READWRITE; - break; - case 'w': - type = UE_HARDWARE_WRITE; - break; - case 'x': - break; - default: - dputs("Invalid type, assuming 'x'"); - break; - } - } - DWORD titsize = UE_HARDWARE_SIZE_1; - if(argc > 3) - { - duint size; - if(!valfromstring(argv[3], &size)) - return STATUS_ERROR; - switch(size) - { - case 1: - titsize = UE_HARDWARE_SIZE_1; - break; - case 2: - titsize = UE_HARDWARE_SIZE_2; - break; - case 4: - titsize = UE_HARDWARE_SIZE_4; - break; -#ifdef _WIN64 - case 8: - titsize = UE_HARDWARE_SIZE_8; - break; -#endif // _WIN64 - default: - titsize = UE_HARDWARE_SIZE_1; - dputs("Invalid size, using 1"); - break; - } - if((addr % size) != 0) - { - dprintf("Address not aligned to %d\n", size); - return STATUS_ERROR; - } - } - DWORD drx = 0; - if(!GetUnusedHardwareBreakPointRegister(&drx)) - { - dputs("You can only set 4 hardware breakpoints"); - return STATUS_ERROR; - } - int titantype = 0; - TITANSETDRX(titantype, drx); - TITANSETTYPE(titantype, type); - TITANSETSIZE(titantype, titsize); - //TODO: hwbp in multiple threads TEST - if(BpGet(addr, BPHARDWARE, 0, 0)) - { - dputs("Hardware breakpoint already set!"); - return STATUS_CONTINUE; - } - if(!BpNew(addr, true, false, 0, BPHARDWARE, titantype, 0)) - { - dputs("Error setting hardware breakpoint (bpnew)!"); - return STATUS_ERROR; - } - if(!SetHardwareBreakPoint(addr, drx, type, titsize, (void*)cbHardwareBreakpoint)) - { - dputs("Error setting hardware breakpoint (TitanEngine)!"); - return STATUS_ERROR; - } - dprintf("Hardware breakpoint at " fhex " set!\n", addr); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[]) -{ - if(argc < 2) //delete all breakpoints - { - if(!BpGetCount(BPHARDWARE)) - { - dputs("No hardware breakpoints to delete!"); - return STATUS_CONTINUE; - } - if(!BpEnumAll(cbDeleteAllHardwareBreakpoints)) //at least one deletion failed - return STATUS_ERROR; - dputs("All hardware breakpoints deleted!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - BREAKPOINT found; - if(BpGet(0, BPHARDWARE, argv[1], &found)) //found a breakpoint with name - { - if(!BpDelete(found.addr, BPHARDWARE)) - { - dprintf("Delete hardware breakpoint failed: " fhex " (BpDelete)\n", found.addr); - return STATUS_ERROR; - } - if(!DeleteHardwareBreakPoint(TITANGETDRX(found.titantype))) - { - dprintf("Delete hardware breakpoint failed: " fhex " (DeleteHardwareBreakPoint)\n", found.addr); - return STATUS_ERROR; - } - return STATUS_CONTINUE; - } - duint addr = 0; - if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPHARDWARE, 0, &found)) //invalid breakpoint - { - dprintf("No such hardware breakpoint \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - if(!BpDelete(found.addr, BPHARDWARE)) - { - dprintf("Delete hardware breakpoint failed: " fhex " (BpDelete)\n", found.addr); - return STATUS_ERROR; - } - if(!DeleteHardwareBreakPoint(TITANGETDRX(found.titantype))) - { - dprintf("Delete hardware breakpoint failed: " fhex " (DeleteHardwareBreakPoint)\n", found.addr); - return STATUS_ERROR; - } - dputs("Hardware breakpoint deleted!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugAlloc(int argc, char* argv[]) -{ - duint size = 0x1000; - if(argc > 1) - if(!valfromstring(argv[1], &size, false)) - return STATUS_ERROR; - duint mem = (duint)MemAllocRemote(0, size); - if(!mem) - dputs("VirtualAllocEx failed"); - else - dprintf(fhex"\n", mem); - if(mem) - varset("$lastalloc", mem, true); - //update memory map - MemUpdateMap(); - GuiUpdateMemoryView(); - - varset("$res", mem, false); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugFree(int argc, char* argv[]) -{ - duint lastalloc; - varget("$lastalloc", &lastalloc, 0, 0); - duint addr = lastalloc; - if(argc > 1) - { - if(!valfromstring(argv[1], &addr, false)) - return STATUS_ERROR; - } - else if(!lastalloc) - { - dputs("$lastalloc is zero, provide a page address"); - return STATUS_ERROR; - } - if(addr == lastalloc) - varset("$lastalloc", (duint)0, true); - bool ok = !!VirtualFreeEx(fdProcessInfo->hProcess, (void*)addr, 0, MEM_RELEASE); - if(!ok) - dputs("VirtualFreeEx failed"); - //update memory map - MemUpdateMap(); - GuiUpdateMemoryView(); - - varset("$res", ok, false); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugMemset(int argc, char* argv[]) -{ - duint addr; - duint value; - duint size; - if(argc < 3) - { - dputs("Not enough arguments"); - return STATUS_ERROR; - } - if(!valfromstring(argv[1], &addr, false) || !valfromstring(argv[2], &value, false)) - return STATUS_ERROR; - if(argc > 3) - { - if(!valfromstring(argv[3], &size, false)) - return STATUS_ERROR; - } - else - { - duint base = MemFindBaseAddr(addr, &size, true); - if(!base) - { - dputs("Invalid address specified"); - return STATUS_ERROR; - } - duint diff = addr - base; - addr = base + diff; - size -= diff; - } - BYTE fi = value & 0xFF; - if(!Fill((void*)addr, size & 0xFFFFFFFF, &fi)) - dputs("Memset failed"); - else - dprintf("Memory " fhex " (size: %.8X) set to %.2X\n", addr, size & 0xFFFFFFFF, value & 0xFF); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugBenchmark(int argc, char* argv[]) -{ - duint addr = MemFindBaseAddr(GetContextDataEx(hActiveThread, UE_CIP), 0); - DWORD ticks = GetTickCount(); - for(duint i = addr; i < addr + 100000; i++) - { - CommentSet(i, "test", false); - LabelSet(i, "test", false); - BookmarkSet(i, false); - FunctionAdd(i, i, false); - } - dprintf("%ums\n", GetTickCount() - ticks); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugPause(int argc, char* argv[]) -{ - if(!dbgisrunning()) - { - dputs("Program is not running"); - return STATUS_ERROR; - } - duint debugBreakAddr; - if(!valfromstring("DebugBreak", &debugBreakAddr)) - { - dputs("Could not find DebugBreak!"); - return STATUS_ERROR; - } - DWORD dwThreadId = 0; - HANDLE hThread = CreateRemoteThread(fdProcessInfo->hProcess, 0, 0, (LPTHREAD_START_ROUTINE)debugBreakAddr, 0, CREATE_SUSPENDED, &dwThreadId); - if(!hThread) - { - dputs("Failed to create thread in debuggee"); - return STATUS_ERROR; - } - dprintf("Created thread with ThreadId %X\n", dwThreadId); - dbgsetispausedbyuser(true); - ResumeThread(hThread); - CloseHandle(hThread); - return STATUS_CONTINUE; -} - -static DWORD WINAPI scyllaThread(void* lpParam) -{ - typedef INT (WINAPI * SCYLLASTARTGUI)(DWORD pid, HINSTANCE mod); - SCYLLASTARTGUI ScyllaStartGui = 0; - HINSTANCE hScylla = LoadLibraryW(L"Scylla.dll"); - if(!hScylla) - { - dputs("Error loading Scylla.dll!"); - bScyllaLoaded = false; - FreeLibrary(hScylla); - return 0; - } - ScyllaStartGui = (SCYLLASTARTGUI)GetProcAddress(hScylla, "ScyllaStartGui"); - if(!ScyllaStartGui) - { - dputs("Could not find export 'ScyllaStartGui' inside Scylla.dll"); - bScyllaLoaded = false; - FreeLibrary(hScylla); - return 0; - } - if(dbgisdll()) - ScyllaStartGui(fdProcessInfo->dwProcessId, (HINSTANCE)dbgdebuggedbase()); - else - ScyllaStartGui(fdProcessInfo->dwProcessId, 0); - FreeLibrary(hScylla); - bScyllaLoaded = false; - return 0; -} - -CMDRESULT cbDebugStartScylla(int argc, char* argv[]) -{ - if(bScyllaLoaded) - { - dputs("Scylla is already loaded"); - return STATUS_ERROR; - } - bScyllaLoaded = true; - CloseHandle(CreateThread(0, 0, scyllaThread, 0, 0, 0)); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugAttach(int argc, char* argv[]) -{ - if(argc < 2) - { - dputs("Not enough arguments!"); - return STATUS_ERROR; - } - duint pid = 0; - if(!valfromstring(argv[1], &pid, false)) - return STATUS_ERROR; - if(argc > 2) - { - duint eventHandle = 0; - if(!valfromstring(argv[2], &eventHandle, false)) - return STATUS_ERROR; - dbgsetattachevent((HANDLE)eventHandle); - } - if(DbgIsDebugging()) - DbgCmdExecDirect("stop"); - Handle hProcess = TitanOpenProcess(PROCESS_ALL_ACCESS, false, (DWORD)pid); - if(!hProcess) - { - dprintf("Could not open process %X!\n", pid); - return STATUS_ERROR; - } - BOOL wow64 = false, mewow64 = false; - if(!IsWow64Process(hProcess, &wow64) || !IsWow64Process(GetCurrentProcess(), &mewow64)) - { - dputs("IsWow64Process failed!"); - return STATUS_ERROR; - } - if((mewow64 && !wow64) || (!mewow64 && wow64)) - { -#ifdef _WIN64 - dputs("Use x32dbg to debug this process!"); -#else - dputs("Use x64dbg to debug this process!"); -#endif // _WIN64 - return STATUS_ERROR; - } - wchar_t wszFileName[MAX_PATH] = L""; - if(!GetModuleFileNameExW(hProcess, 0, wszFileName, MAX_PATH)) - { - dprintf("Could not get module filename %X!\n", pid); - return STATUS_ERROR; - } - strcpy_s(szFileName, StringUtils::Utf16ToUtf8(wszFileName).c_str()); - CloseHandle(CreateThread(0, 0, threadAttachLoop, (void*)pid, 0, 0)); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugDetach(int argc, char* argv[]) -{ - unlock(WAITID_RUN); //run - dbgsetisdetachedbyuser(true); //detach when paused - StepInto((void*)cbDetach); - DebugBreakProcess(fdProcessInfo->hProcess); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugDump(int argc, char* argv[]) -{ - if(argc < 2) - { - dputs("Not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if(!valfromstring(argv[1], &addr)) - { - dprintf("Invalid address \"%s\"!\n", argv[1]); - return STATUS_ERROR; - } - GuiDumpAt(addr); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugStackDump(int argc, char* argv[]) -{ - duint addr = 0; - if(argc < 2) - addr = GetContextDataEx(hActiveThread, UE_CSP); - else if(!valfromstring(argv[1], &addr)) - { - dprintf("Invalid address \"%s\"!\n", argv[1]); - return STATUS_ERROR; - } - duint csp = GetContextDataEx(hActiveThread, UE_CSP); - duint size = 0; - duint base = MemFindBaseAddr(csp, &size); - if(base && addr >= base && addr < (base + size)) - DebugUpdateStack(addr, csp, true); - else - dputs("Invalid stack address!"); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugContinue(int argc, char* argv[]) -{ - if(argc < 2) - { - SetNextDbgContinueStatus(DBG_CONTINUE); - dputs("Exception will be swallowed"); - } - else - { - SetNextDbgContinueStatus(DBG_EXCEPTION_NOT_HANDLED); - dputs("Exception will be thrown in the program"); - } - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugBpDll(int argc, char* argv[]) -{ - if(argc < 2) - { - dputs("Not enough arguments!"); - return STATUS_ERROR; - } - DWORD type = UE_ON_LIB_ALL; - if(argc > 2) - { - switch(*argv[2]) - { - case 'l': - type = UE_ON_LIB_LOAD; - break; - case 'u': - type = UE_ON_LIB_UNLOAD; - break; - } - } - bool singleshoot = true; - if(argc > 3) - singleshoot = false; - LibrarianSetBreakPoint(argv[1], type, singleshoot, (void*)cbLibrarianBreakpoint); - dprintf("Dll breakpoint set on \"%s\"!\n", argv[1]); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugBcDll(int argc, char* argv[]) -{ - if(argc < 2) - { - dputs("Not enough arguments"); - return STATUS_ERROR; - } - if(!LibrarianRemoveBreakPoint(argv[1], UE_ON_LIB_ALL)) - { - dputs("Failed to remove DLL breakpoint..."); - return STATUS_ERROR; - } - dputs("DLL breakpoint removed!"); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugSwitchthread(int argc, char* argv[]) -{ - duint threadid = fdProcessInfo->dwThreadId; //main thread - if(argc > 1) - if(!valfromstring(argv[1], &threadid, false)) - return STATUS_ERROR; - if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid - { - dprintf("Invalid thread %X\n", threadid); - return STATUS_ERROR; - } - //switch thread - hActiveThread = ThreadGetHandle((DWORD)threadid); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - dputs("Thread switched!"); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugSuspendthread(int argc, char* argv[]) -{ - duint threadid = fdProcessInfo->dwThreadId; - if(argc > 1) - if(!valfromstring(argv[1], &threadid, false)) - return STATUS_ERROR; - if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid - { - dprintf("Invalid thread %X\n", threadid); - return STATUS_ERROR; - } - //suspend thread - if(SuspendThread(ThreadGetHandle((DWORD)threadid)) == -1) - { - dputs("Error suspending thread"); - return STATUS_ERROR; - } - dputs("Thread suspended"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugResumethread(int argc, char* argv[]) -{ - duint threadid = fdProcessInfo->dwThreadId; - if(argc > 1) - if(!valfromstring(argv[1], &threadid, false)) - return STATUS_ERROR; - if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid - { - dprintf("Invalid thread %X\n", threadid); - return STATUS_ERROR; - } - //resume thread - if(ResumeThread(ThreadGetHandle((DWORD)threadid)) == -1) - { - dputs("Error resuming thread"); - return STATUS_ERROR; - } - dputs("Thread resumed!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugKillthread(int argc, char* argv[]) -{ - duint threadid = fdProcessInfo->dwThreadId; - if(argc > 1) - if(!valfromstring(argv[1], &threadid, false)) - return STATUS_ERROR; - duint exitcode = 0; - if(argc > 2) - if(!valfromstring(argv[2], &exitcode, false)) - return STATUS_ERROR; - if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid - { - dprintf("Invalid thread %X\n", threadid); - return STATUS_ERROR; - } - //terminate thread - if(TerminateThread(ThreadGetHandle((DWORD)threadid), (DWORD)exitcode) != 0) - { - GuiUpdateAllViews(); - dputs("Thread terminated"); - return STATUS_CONTINUE; - } - dputs("Error terminating thread!"); - return STATUS_ERROR; -} - -CMDRESULT cbDebugSuspendAllThreads(int argc, char* argv[]) -{ - dprintf("%d/%d thread(s) suspended\n", ThreadSuspendAll(), ThreadGetCount()); - - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugResumeAllThreads(int argc, char* argv[]) -{ - dprintf("%d/%d thread(s) resumed\n", ThreadResumeAll(), ThreadGetCount()); - - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugSetPriority(int argc, char* argv[]) -{ - if(argc < 3) - { - dputs("Not enough arguments!"); - return STATUS_ERROR; - } - duint threadid; - if(!valfromstring(argv[1], &threadid, false)) - return STATUS_ERROR; - duint priority; - if(!valfromstring(argv[2], &priority)) - { - if(_strcmpi(argv[2], "Normal") == 0) - priority = THREAD_PRIORITY_NORMAL; - else if(_strcmpi(argv[2], "AboveNormal") == 0) - priority = THREAD_PRIORITY_ABOVE_NORMAL; - else if(_strcmpi(argv[2], "TimeCritical") == 0) - priority = THREAD_PRIORITY_TIME_CRITICAL; - else if(_strcmpi(argv[2], "Idle") == 0) - priority = THREAD_PRIORITY_IDLE; - else if(_strcmpi(argv[2], "BelowNormal") == 0) - priority = THREAD_PRIORITY_BELOW_NORMAL; - else if(_strcmpi(argv[2], "Highest") == 0) - priority = THREAD_PRIORITY_HIGHEST; - else if(_strcmpi(argv[2], "Lowest") == 0) - priority = THREAD_PRIORITY_LOWEST; - else - { - dputs("Unknown priority value, read the help!"); - return STATUS_ERROR; - } - } - else - { - switch(priority) //check if the priority value is valid - { - case THREAD_PRIORITY_NORMAL: - case THREAD_PRIORITY_ABOVE_NORMAL: - case THREAD_PRIORITY_TIME_CRITICAL: - case THREAD_PRIORITY_IDLE: - case THREAD_PRIORITY_BELOW_NORMAL: - case THREAD_PRIORITY_HIGHEST: - case THREAD_PRIORITY_LOWEST: - break; - default: - dputs("Unknown priority value, read the help!"); - return STATUS_ERROR; - } - } - if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid - { - dprintf("Invalid thread %X\n", threadid); - return STATUS_ERROR; - } - //set thread priority - if(SetThreadPriority(ThreadGetHandle((DWORD)threadid), (int)priority) == 0) - { - dputs("Error setting thread priority"); - return STATUS_ERROR; - } - dputs("Thread priority changed!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[]) -{ - DWORD drx = 0; - if(!GetUnusedHardwareBreakPointRegister(&drx)) - { - dputs("You can only set 4 hardware breakpoints"); - return STATUS_ERROR; - } - if(argc < 2) //enable all hardware breakpoints - { - if(!BpGetCount(BPHARDWARE)) - { - dputs("No hardware breakpoints to enable!"); - return STATUS_CONTINUE; - } - if(!BpEnumAll(cbEnableAllHardwareBreakpoints)) //at least one enable failed - return STATUS_ERROR; - dputs("All hardware breakpoints enabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - BREAKPOINT found; - duint addr = 0; - if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint - { - dprintf("No such hardware breakpoint \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - if(found.enabled) - { - dputs("Hardware breakpoint already enabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - TITANSETDRX(found.titantype, drx); - BpSetTitanType(found.addr, BPHARDWARE, found.titantype); - if(!BpEnable(found.addr, BPHARDWARE, true) || !SetHardwareBreakPoint(found.addr, drx, TITANGETTYPE(found.titantype), TITANGETSIZE(found.titantype), (void*)cbHardwareBreakpoint)) - { - dprintf("Could not enable hardware breakpoint " fhex "\n", found.addr); - return STATUS_ERROR; - } - dputs("Hardware breakpoint enabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[]) -{ - if(argc < 2) //delete all hardware breakpoints - { - if(!BpGetCount(BPHARDWARE)) - { - dputs("No hardware breakpoints to disable!"); - return STATUS_CONTINUE; - } - if(!BpEnumAll(cbDisableAllHardwareBreakpoints)) //at least one deletion failed - return STATUS_ERROR; - dputs("All hardware breakpoints disabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - BREAKPOINT found; - duint addr = 0; - if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint - { - dprintf("No such hardware breakpoint \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - if(!found.enabled) - { - dputs("Hardware breakpoint already disabled!"); - return STATUS_CONTINUE; - } - if(!BpEnable(found.addr, BPHARDWARE, false) || !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype))) - { - dprintf("Could not disable hardware breakpoint " fhex "\n", found.addr); - return STATUS_ERROR; - } - dputs("Hardware breakpoint disabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[]) -{ - if(argc < 2) //enable all memory breakpoints - { - if(!BpGetCount(BPMEMORY)) - { - dputs("No memory breakpoints to enable!"); - return STATUS_CONTINUE; - } - if(!BpEnumAll(cbEnableAllMemoryBreakpoints)) //at least one enable failed - return STATUS_ERROR; - dputs("All memory breakpoints enabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - BREAKPOINT found; - duint addr = 0; - if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint - { - dprintf("No such memory breakpoint \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - if(found.enabled) - { - dputs("Memory memory already enabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - duint size = 0; - MemFindBaseAddr(found.addr, &size); - if(!BpEnable(found.addr, BPMEMORY, true) || !SetMemoryBPXEx(found.addr, size, found.titantype, !found.singleshoot, (void*)cbMemoryBreakpoint)) - { - dprintf("Could not enable memory breakpoint " fhex "\n", found.addr); - return STATUS_ERROR; - } - dputs("Memory breakpoint enabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[]) -{ - if(argc < 2) //delete all memory breakpoints - { - if(!BpGetCount(BPMEMORY)) - { - dputs("No memory breakpoints to disable!"); - return STATUS_CONTINUE; - } - if(!BpEnumAll(cbDisableAllMemoryBreakpoints)) //at least one deletion failed - return STATUS_ERROR; - dputs("All memory breakpoints disabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; - } - BREAKPOINT found; - duint addr = 0; - if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint - { - dprintf("No such memory breakpoint \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - if(!found.enabled) - { - dputs("Memory breakpoint already disabled!"); - return STATUS_CONTINUE; - } - duint size = 0; - MemFindBaseAddr(found.addr, &size); - if(!BpEnable(found.addr, BPMEMORY, false) || !RemoveMemoryBPX(found.addr, size)) - { - dprintf("Could not disable memory breakpoint " fhex "\n", found.addr); - return STATUS_ERROR; - } - dputs("Memory breakpoint disabled!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[]) -{ - char szDefaultStore[MAX_SETTING_SIZE] = ""; - const char* szSymbolStore = szDefaultStore; - if(!BridgeSettingGet("Symbols", "DefaultStore", szDefaultStore)) //get default symbol store from settings - { - strcpy_s(szDefaultStore, "http://msdl.microsoft.com/download/symbols"); - BridgeSettingSet("Symbols", "DefaultStore", szDefaultStore); - } - if(argc < 2) //no arguments - { - SymDownloadAllSymbols(szSymbolStore); //download symbols for all modules - GuiSymbolRefreshCurrent(); - dputs("Done! See symbol log for more information"); - return STATUS_CONTINUE; - } - //get some module information - duint modbase = ModBaseFromName(argv[1]); - if(!modbase) - { - dprintf("Invalid module \"%s\"!\n", argv[1]); - return STATUS_ERROR; - } - wchar_t wszModulePath[MAX_PATH] = L""; - if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbase, wszModulePath, MAX_PATH)) - { - dputs("GetModuleFileNameExA failed!"); - return STATUS_ERROR; - } - char szModulePath[MAX_PATH] = ""; - strcpy_s(szModulePath, StringUtils::Utf16ToUtf8(wszModulePath).c_str()); - wchar_t szOldSearchPath[MAX_PATH] = L""; - if(!SafeSymGetSearchPathW(fdProcessInfo->hProcess, szOldSearchPath, MAX_PATH)) //backup current search path - { - dputs("SymGetSearchPath failed!"); - return STATUS_ERROR; - } - char szServerSearchPath[MAX_PATH * 2] = ""; - if(argc > 2) - szSymbolStore = argv[2]; - sprintf_s(szServerSearchPath, "SRV*%s*%s", szSymbolCachePath, szSymbolStore); - if(!SafeSymSetSearchPathW(fdProcessInfo->hProcess, StringUtils::Utf8ToUtf16(szServerSearchPath).c_str())) //set new search path - { - dputs("SymSetSearchPath (1) failed!"); - return STATUS_ERROR; - } - if(!SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)modbase)) //unload module - { - SafeSymSetSearchPathW(fdProcessInfo->hProcess, szOldSearchPath); - dputs("SymUnloadModule64 failed!"); - return STATUS_ERROR; - } - if(!SafeSymLoadModuleEx(fdProcessInfo->hProcess, 0, szModulePath, 0, (DWORD64)modbase, 0, 0, 0)) //load module - { - dputs("SymLoadModuleEx failed!"); - SafeSymSetSearchPathW(fdProcessInfo->hProcess, szOldSearchPath); - return STATUS_ERROR; - } - if(!SafeSymSetSearchPathW(fdProcessInfo->hProcess, szOldSearchPath)) - { - dputs("SymSetSearchPathW (2) failed!"); - return STATUS_ERROR; - } - GuiSymbolRefreshCurrent(); - dputs("Done! See symbol log for more information"); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugGetJITAuto(int argc, char* argv[]) -{ - bool jit_auto = false; - arch actual_arch = invalid; - - if(argc == 1) - { - if(!dbggetjitauto(&jit_auto, notfound, & actual_arch, NULL)) - { - dprintf("Error getting JIT auto %s\n", (actual_arch == x64) ? "x64" : "x32"); - return STATUS_ERROR; - } - } - else if(argc == 2) - { - readwritejitkey_error_t rw_error; - if(_strcmpi(argv[1], "x64") == 0) - actual_arch = x64; - else if(_strcmpi(argv[1], "x32") == 0) - actual_arch = x32; - else - { - dputs("Unknown JIT auto entry type. Use x64 or x32 as parameter."); - return STATUS_ERROR; - } - - if(!dbggetjitauto(& jit_auto, actual_arch, NULL, & rw_error)) - { - if(rw_error == ERROR_RW_NOTWOW64) - dprintf("Error using x64 arg the debugger is not a WOW64 process\n"); - else - dprintf("Error getting JIT auto %s\n", argv[1]); - return STATUS_ERROR; - } - } - else - { - dputs("Unknown JIT auto entry type. Use x64 or x32 as parameter"); - } - - dprintf("JIT auto %s: %s\n", (actual_arch == x64) ? "x64" : "x32", jit_auto ? "ON" : "OFF"); - - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugSetJITAuto(int argc, char* argv[]) -{ - arch actual_arch; - bool set_jit_auto; - if(!IsProcessElevated()) - { - dprintf("Error run the debugger as Admin to setjitauto\n"); - return STATUS_ERROR; - } - if(argc < 2) - { - dprintf("Error setting JIT Auto. Use ON:1 or OFF:0 arg or x64/x32, ON:1 or OFF:0.\n"); - return STATUS_ERROR; - } - else if(argc == 2) - { - if(_strcmpi(argv[1], "1") == 0 || _strcmpi(argv[1], "ON") == 0) - set_jit_auto = true; - else if(_strcmpi(argv[1], "0") == 0 || _strcmpi(argv[1], "OFF") == 0) - set_jit_auto = false; - else - { - dputs("Error unknown parameters. Use ON:1 or OFF:0"); - return STATUS_ERROR; - } - - if(!dbgsetjitauto(set_jit_auto, notfound, & actual_arch, NULL)) - { - dprintf("Error setting JIT auto %s\n", (actual_arch == x64) ? "x64" : "x32"); - return STATUS_ERROR; - } - } - else if(argc == 3) - { - readwritejitkey_error_t rw_error; - actual_arch = x64; - - if(_strcmpi(argv[1], "x64") == 0) - actual_arch = x64; - else if(_strcmpi(argv[1], "x32") == 0) - actual_arch = x32; - else - { - dputs("Unknown JIT auto entry type. Use x64 or x32 as parameter"); - return STATUS_ERROR; - } - - if(_strcmpi(argv[2], "1") == 0 || _strcmpi(argv[2], "ON") == 0) - set_jit_auto = true; - else if(_strcmpi(argv[2], "0") == 0 || _strcmpi(argv[2], "OFF") == 0) - set_jit_auto = false; - else - { - dputs("Error unknown parameters. Use x86 or x64 and ON:1 or OFF:0\n"); - return STATUS_ERROR; - } - - if(!dbgsetjitauto(set_jit_auto, actual_arch, NULL, & rw_error)) - { - if(rw_error == ERROR_RW_NOTWOW64) - dprintf("Error using x64 arg the debugger is not a WOW64 process\n"); - else - - dprintf("Error getting JIT auto %s\n", (actual_arch == x64) ? "x64" : "x32"); - return STATUS_ERROR; - } - } - else - { - dputs("Error unknown parameters use x86 or x64, ON/1 or OFF/0\n"); - return STATUS_ERROR; - } - - dprintf("New JIT auto %s: %s\n", (actual_arch == x64) ? "x64" : "x32", set_jit_auto ? "ON" : "OFF"); - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugSetJIT(int argc, char* argv[]) -{ - arch actual_arch = invalid; - char* jit_debugger_cmd = ""; - char oldjit[MAX_SETTING_SIZE] = ""; - char path[JIT_ENTRY_DEF_SIZE]; - if(!IsProcessElevated()) - { - dprintf("Error run the debugger as Admin to setjit\n"); - return STATUS_ERROR; - } - if(argc < 2) - { - dbggetdefjit(path); - - jit_debugger_cmd = path; - if(!dbgsetjit(jit_debugger_cmd, notfound, & actual_arch, NULL)) - { - dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); - return STATUS_ERROR; - } - } - else if(argc == 2) - { - if(!_strcmpi(argv[1], "old")) - { - jit_debugger_cmd = oldjit; - if(!BridgeSettingGet("JIT", "Old", jit_debugger_cmd)) - { - dputs("Error there is no old JIT entry stored."); - return STATUS_ERROR; - } - - if(!dbgsetjit(jit_debugger_cmd, notfound, & actual_arch, NULL)) - { - dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); - return STATUS_ERROR; - } - } - else if(!_strcmpi(argv[1], "oldsave")) - { - char path[JIT_ENTRY_DEF_SIZE]; - dbggetdefjit(path); - char get_entry[JIT_ENTRY_MAX_SIZE] = ""; - bool get_last_jit = true; - - if(!dbggetjit(get_entry, notfound, & actual_arch, NULL)) - get_last_jit = false; - else - strcpy_s(oldjit, get_entry); - - jit_debugger_cmd = path; - if(!dbgsetjit(jit_debugger_cmd, notfound, & actual_arch, NULL)) - { - dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); - return STATUS_ERROR; - } - if(get_last_jit) - { - if(_stricmp(oldjit, path)) - BridgeSettingSet("JIT", "Old", oldjit); - } - } - else if(!_strcmpi(argv[1], "restore")) - { - jit_debugger_cmd = oldjit; - - if(!BridgeSettingGet("JIT", "Old", jit_debugger_cmd)) - { - dputs("Error there is no old JIT entry stored."); - return STATUS_ERROR; - } - - if(!dbgsetjit(jit_debugger_cmd, notfound, & actual_arch, NULL)) - { - dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); - return STATUS_ERROR; - } - BridgeSettingSet("JIT", 0, 0); - } - else - { - jit_debugger_cmd = argv[1]; - if(!dbgsetjit(jit_debugger_cmd, notfound, & actual_arch, NULL)) - { - dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); - return STATUS_ERROR; - } - } - } - else if(argc == 3) - { - readwritejitkey_error_t rw_error; - - if(!_strcmpi(argv[1], "old")) - { - BridgeSettingSet("JIT", "Old", argv[2]); - - dprintf("New OLD JIT stored: %s\n", argv[2]); - - return STATUS_CONTINUE; - } - - else if(_strcmpi(argv[1], "x64") == 0) - actual_arch = x64; - else if(_strcmpi(argv[1], "x32") == 0) - actual_arch = x32; - else - { - dputs("Unknown JIT entry type. Use OLD, x64 or x32 as parameter."); - return STATUS_ERROR; - } - - jit_debugger_cmd = argv[2]; - if(!dbgsetjit(jit_debugger_cmd, actual_arch, NULL, & rw_error)) - { - if(rw_error == ERROR_RW_NOTWOW64) - dprintf("Error using x64 arg. The debugger is not a WOW64 process\n"); - else - dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); - return STATUS_ERROR; - } - } - else - { - dputs("Error unknown parameters. Use old, oldsave, restore, x86 or x64 as parameter."); - return STATUS_ERROR; - } - - dprintf("New JIT %s: %s\n", (actual_arch == x64) ? "x64" : "x32", jit_debugger_cmd); - - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugGetJIT(int argc, char* argv[]) -{ - char get_entry[JIT_ENTRY_MAX_SIZE] = ""; - arch actual_arch; - - if(argc < 2) - { - if(!dbggetjit(get_entry, notfound, & actual_arch, NULL)) - { - dprintf("Error getting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); - return STATUS_ERROR; - } - } - else - { - readwritejitkey_error_t rw_error; - char oldjit[MAX_SETTING_SIZE] = ""; - if(_strcmpi(argv[1], "OLD") == 0) - { - if(!BridgeSettingGet("JIT", "Old", (char*) & oldjit)) - { - dputs("Error: there is not an OLD JIT entry stored yet."); - return STATUS_ERROR; - } - else - { - dprintf("OLD JIT entry stored: %s\n", oldjit); - return STATUS_CONTINUE; - } - } - else if(_strcmpi(argv[1], "x64") == 0) - actual_arch = x64; - else if(_strcmpi(argv[1], "x32") == 0) - actual_arch = x32; - else - { - dputs("Unknown JIT entry type. Use OLD, x64 or x32 as parameter."); - return STATUS_ERROR; - } - - if(!dbggetjit(get_entry, actual_arch, NULL, & rw_error)) - { - if(rw_error == ERROR_RW_NOTWOW64) - dprintf("Error using x64 arg. The debugger is not a WOW64 process\n"); - else - dprintf("Error getting JIT %s\n", argv[1]); - return STATUS_ERROR; - } - } - - dprintf("JIT %s: %s\n", (actual_arch == x64) ? "x64" : "x32", get_entry); - - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugGetPageRights(int argc, char* argv[]) -{ - duint addr = 0; - char rights[RIGHTS_STRING_SIZE]; - - if(argc != 2 || !valfromstring(argv[1], &addr)) - { - dprintf("Error: using an address as arg1\n"); - return STATUS_ERROR; - } - - if(!MemGetPageRights(addr, rights)) - { - dprintf("Error getting rights of page: %s\n", argv[1]); - return STATUS_ERROR; - } - - dprintf("Page: " fhex ", Rights: %s\n", addr, rights); - - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugSetPageRights(int argc, char* argv[]) -{ - duint addr = 0; - char rights[RIGHTS_STRING_SIZE]; - - if(argc < 3 || !valfromstring(argv[1], &addr)) - { - dprintf("Error: Using an address as arg1 and as arg2: Execute, ExecuteRead, ExecuteReadWrite, ExecuteWriteCopy, NoAccess, ReadOnly, ReadWrite, WriteCopy. You can add a G at first for add PAGE GUARD, example: GReadOnly\n"); - return STATUS_ERROR; - } - - if(!MemSetPageRights(addr, argv[2])) - { - dprintf("Error: Set rights of " fhex " with Rights: %s\n", addr, argv[2]); - return STATUS_ERROR; - } - - if(!MemGetPageRights(addr, rights)) - { - dprintf("Error getting rights of page: %s\n", argv[1]); - return STATUS_ERROR; - } - - //update the memory map - MemUpdateMap(); - GuiUpdateMemoryView(); - - dprintf("New rights of " fhex ": %s\n", addr, rights); - - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugLoadLib(int argc, char* argv[]) -{ - if(argc < 2) - { - dprintf("Error: you must specify the name of the DLL to load\n"); - return STATUS_ERROR; - } - - LoadLibThreadID = fdProcessInfo->dwThreadId; - HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID); - - DLLNameMem = MemAllocRemote(0, strlen(argv[1]) + 1); - ASMAddr = MemAllocRemote(0, 0x1000); - - if(!DLLNameMem || !ASMAddr) - { - dprintf("Error: couldn't allocate memory in debuggee"); - return STATUS_ERROR; - } - - if(!MemWrite(DLLNameMem, argv[1], strlen(argv[1]))) - { - dprintf("Error: couldn't write process memory"); - return STATUS_ERROR; - } - - int size = 0; - int counter = 0; - duint LoadLibraryA = 0; - char command[50] = ""; - char error[MAX_ERROR_SIZE] = ""; - - GetFullContextDataEx(LoadLibThread, &backupctx); - - if(!valfromstring("kernel32:LoadLibraryA", &LoadLibraryA, false)) - { - dprintf("Error: couldn't get kernel32:LoadLibraryA"); - return STATUS_ERROR; - } - - // Arch specific asm code -#ifdef _WIN64 - sprintf(command, "mov rcx, " fhex, (duint)DLLNameMem); -#else - sprintf(command, "push " fhex, DLLNameMem); -#endif // _WIN64 - - assembleat((duint)ASMAddr, command, &size, error, true); - counter += size; - -#ifdef _WIN64 - sprintf(command, "mov rax, " fhex, LoadLibraryA); - assembleat((duint)ASMAddr + counter, command, &size, error, true); - counter += size; - sprintf(command, "call rax"); -#else - sprintf(command, "call " fhex, LoadLibraryA); -#endif // _WIN64 - - assembleat((duint)ASMAddr + counter, command, &size, error, true); - counter += size; - - SetContextDataEx(LoadLibThread, UE_CIP, (duint)ASMAddr); - SetBPX((duint)ASMAddr + counter, UE_SINGLESHOOT | UE_BREAKPOINT_TYPE_INT3, (void*)cbDebugLoadLibBPX); - - ThreadSuspendAll(); - ResumeThread(LoadLibThread); - - unlock(WAITID_RUN); - - return STATUS_CONTINUE; -} - -void cbDebugLoadLibBPX() -{ - HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID); -#ifdef _WIN64 - duint LibAddr = GetContextDataEx(LoadLibThread, UE_RAX); -#else - duint LibAddr = GetContextDataEx(LoadLibThread, UE_EAX); -#endif //_WIN64 - varset("$result", LibAddr, false); - backupctx.eflags &= ~0x100; - SetFullContextDataEx(LoadLibThread, &backupctx); - MemFreeRemote(DLLNameMem); - MemFreeRemote(ASMAddr); - ThreadResumeAll(); - //update GUI - GuiSetDebugState(paused); - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); - //lock - lock(WAITID_RUN); - SetForegroundWindow(GuiGetWindowHandle()); - PLUG_CB_PAUSEDEBUG pauseInfo; - pauseInfo.reserved = 0; - plugincbcall(CB_PAUSEDEBUG, &pauseInfo); - wait(WAITID_RUN); -} - -void showcommandlineerror(cmdline_error_t* cmdline_error) -{ - bool unkown = false; - - switch(cmdline_error->type) - { - case CMDL_ERR_ALLOC: - dprintf("Error allocating memory for cmdline"); - break; - case CMDL_ERR_CONVERTUNICODE: - dprintf("Error converting UNICODE cmdline"); - break; - case CMDL_ERR_READ_PEBBASE: - dprintf("Error reading PEB base addres"); - break; - case CMDL_ERR_READ_PROCPARM_CMDLINE: - dprintf("Error reading PEB -> ProcessParameters -> CommandLine UNICODE_STRING"); - break; - case CMDL_ERR_READ_PROCPARM_PTR: - dprintf("Error reading PEB -> ProcessParameters pointer address"); - break; - case CMDL_ERR_GET_PEB: - dprintf("Error Getting remote PEB address"); - break; - case CMDL_ERR_READ_GETCOMMANDLINEBASE: - dprintf("Error Getting command line base address"); - break; - case CMDL_ERR_CHECK_GETCOMMANDLINESTORED: - dprintf("Error checking the pattern of the commandline stored"); - break; - case CMDL_ERR_WRITE_GETCOMMANDLINESTORED: - dprintf("Error writing the new command line stored"); - break; - case CMDL_ERR_GET_GETCOMMANDLINE: - dprintf("Error getting getcommandline"); - break; - case CMDL_ERR_ALLOC_UNICODEANSI_COMMANDLINE: - dprintf("Error allocating the page with UNICODE and ANSI command lines"); - break; - case CMDL_ERR_WRITE_ANSI_COMMANDLINE: - dprintf("Error writing the ANSI command line in the page"); - break; - case CMDL_ERR_WRITE_UNICODE_COMMANDLINE: - dprintf("Error writing the UNICODE command line in the page"); - break; - case CMDL_ERR_WRITE_PEBUNICODE_COMMANDLINE: - dprintf("Error writing command line UNICODE in PEB"); - break; - default: - unkown = true; - dputs("Error getting cmdline"); - break; - } - - if(!unkown) - { - if(cmdline_error->addr != 0) - dprintf(" (Address: " fhex ")", cmdline_error->addr); - dputs(""); - } -} - -CMDRESULT cbDebugGetCmdline(int argc, char* argv[]) -{ - char* cmd_line; - cmdline_error_t cmdline_error = {(cmdline_error_type_t) 0, 0}; - - if(!dbggetcmdline(& cmd_line, & cmdline_error)) - { - showcommandlineerror(& cmdline_error); - return STATUS_ERROR; - } - - dprintf("Command line: %s\n", cmd_line); - - efree(cmd_line); - - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugSetCmdline(int argc, char* argv[]) -{ - cmdline_error_t cmdline_error = {(cmdline_error_type_t) 0, 0}; - - if(argc != 2) - { - dputs("Error: write the arg1 with the new command line of the process debugged"); - return STATUS_ERROR; - } - - if(!dbgsetcmdline(argv[1], &cmdline_error)) - { - showcommandlineerror(&cmdline_error); - return STATUS_ERROR; - } - - //update the memory map - MemUpdateMap(); - GuiUpdateMemoryView(); - - dprintf("New command line: %s\n", argv[1]); - - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugSkip(int argc, char* argv[]) -{ - SetNextDbgContinueStatus(DBG_CONTINUE); //swallow the exception - duint cip = GetContextDataEx(hActiveThread, UE_CIP); - BASIC_INSTRUCTION_INFO basicinfo; - memset(&basicinfo, 0, sizeof(basicinfo)); - disasmfast(cip, &basicinfo); - cip += basicinfo.size; - SetContextDataEx(hActiveThread, UE_CIP, cip); - DebugUpdateGui(cip, false); //update GUI - return STATUS_CONTINUE; -} - -CMDRESULT cbDebugSetfreezestack(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("Not enough arguments!"); - return STATUS_ERROR; - } - bool freeze = *argv[1] != '0'; - dbgsetfreezestack(freeze); - dprintf("Stack is now %s\n", freeze ? "freezed" : "unfreezed"); - return STATUS_CONTINUE; -} +/** + @file debugger_commands.cpp + + @brief Implements the debugger commands class. + */ + +#include "debugger_commands.h" +#include "jit.h" +#include "console.h" +#include "value.h" +#include "thread.h" +#include "memory.h" +#include "threading.h" +#include "variable.h" +#include "plugin_loader.h" +#include "simplescript.h" +#include "symbolinfo.h" +#include "assemble.h" +#include "disasm_fast.h" +#include "module.h" +#include "comment.h" +#include "label.h" +#include "bookmark.h" +#include "function.h" + +static bool bScyllaLoaded = false; +duint LoadLibThreadID; +duint DLLNameMem; +duint ASMAddr; +TITAN_ENGINE_CONTEXT_t backupctx = { 0 }; + +CMDRESULT cbDebugInit(int argc, char* argv[]) +{ + cbDebugStop(argc, argv); + + static char arg1[deflen] = ""; + if(argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + strcpy_s(arg1, argv[1]); + char szResolvedPath[MAX_PATH] = ""; + if(ResolveShortcut(GuiGetWindowHandle(), StringUtils::Utf8ToUtf16(arg1).c_str(), szResolvedPath, _countof(szResolvedPath))) + { + dprintf("Resolved shortcut \"%s\"->\"%s\"\n", arg1, szResolvedPath); + strcpy_s(arg1, szResolvedPath); + } + if(!FileExists(arg1)) + { + dputs("File does not exist!"); + return STATUS_ERROR; + } + Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(arg1).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + if(hFile == INVALID_HANDLE_VALUE) + { + dputs("Could not open file!"); + return STATUS_ERROR; + } + GetFileNameFromHandle(hFile, arg1); //get full path of the file + hFile.Close(); + + //do some basic checks + switch(GetFileArchitecture(arg1)) + { + case invalid: + dputs("Invalid PE file!"); + return STATUS_ERROR; +#ifdef _WIN64 + case x32: + dputs("Use x32dbg to debug this file!"); +#else //x86 + case x64: + dputs("Use x64dbg to debug this file!"); +#endif //_WIN64 + return STATUS_ERROR; + default: + break; + } + + static char arg2[deflen] = ""; + if(argc > 2) + strcpy_s(arg2, argv[2]); + char* commandline = 0; + if(strlen(arg2)) + commandline = arg2; + + char arg3[deflen] = ""; + if(argc > 3) + strcpy_s(arg3, argv[3]); + + static char currentfolder[deflen] = ""; + strcpy_s(currentfolder, arg1); + int len = (int)strlen(currentfolder); + while(currentfolder[len] != '\\' && len != 0) + len--; + currentfolder[len] = 0; + + if(DirExists(arg3)) + strcpy_s(currentfolder, arg3); + + static INIT_STRUCT init; + memset(&init, 0, sizeof(INIT_STRUCT)); + init.exe = arg1; + init.commandline = commandline; + if(*currentfolder) + init.currentfolder = currentfolder; + CloseHandle(CreateThread(0, 0, threadDebugLoop, &init, 0, 0)); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugStop(int argc, char* argv[]) +{ + // HACK: TODO: Don't kill script on debugger ending a process + //scriptreset(); //reset the currently-loaded script + StopDebug(); + while(waitislocked(WAITID_STOP)) //custom waiting + { + unlock(WAITID_RUN); + Sleep(1); + } + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugRun(int argc, char* argv[]) +{ + if(dbgisrunning()) + { + dputs("Program is already running"); + return STATUS_ERROR; + } + GuiSetDebugState(running); + unlock(WAITID_RUN); + PLUG_CB_RESUMEDEBUG callbackInfo; + callbackInfo.reserved = 0; + plugincbcall(CB_RESUMEDEBUG, &callbackInfo); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugErun(int argc, char* argv[]) +{ + if(!dbgisrunning()) + dbgsetskipexceptions(true); + return cbDebugRun(argc, argv); +} + +CMDRESULT cbDebugSetBPXOptions(int argc, char* argv[]) +{ + if(argc < 2) + { + dputs("Not enough arguments!"); + return STATUS_ERROR; + } + DWORD type = 0; + const char* strType = 0; + duint setting_type; + if(strstr(argv[1], "long")) + { + setting_type = 1; //break_int3long + strType = "TYPE_LONG_INT3"; + type = UE_BREAKPOINT_LONG_INT3; + } + else if(strstr(argv[1], "ud2")) + { + setting_type = 2; //break_ud2 + strType = "TYPE_UD2"; + type = UE_BREAKPOINT_UD2; + } + else if(strstr(argv[1], "short")) + { + setting_type = 0; //break_int3short + strType = "TYPE_INT3"; + type = UE_BREAKPOINT_INT3; + } + else + { + dputs("Invalid type specified!"); + return STATUS_ERROR; + } + SetBPXOptions(type); + BridgeSettingSetUint("Engine", "BreakpointType", setting_type); + dprintf("Default breakpoint type set to: %s\n", strType); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugSetBPX(int argc, char* argv[]) //bp addr [,name [,type]] +{ + if(argc < 2) + { + dputs("Not enough arguments!"); + return STATUS_ERROR; + } + char argaddr[deflen] = ""; + strcpy_s(argaddr, argv[1]); + char argname[deflen] = ""; + if(argc > 2) + strcpy_s(argname, argv[2]); + char argtype[deflen] = ""; + bool has_arg2 = argc > 3; + if(has_arg2) + strcpy_s(argtype, argv[3]); + if(!has_arg2 && (scmp(argname, "ss") || scmp(argname, "long") || scmp(argname, "ud2"))) + { + strcpy_s(argtype, argname); + *argname = 0; + } + _strlwr(argtype); + duint addr = 0; + if(!valfromstring(argaddr, &addr)) + { + dprintf("Invalid addr: \"%s\"\n", argaddr); + return STATUS_ERROR; + } + int type = 0; + bool singleshoot = false; + if(strstr(argtype, "ss")) + { + type |= UE_SINGLESHOOT; + singleshoot = true; + } + else + type |= UE_BREAKPOINT; + if(strstr(argtype, "long")) + type |= UE_BREAKPOINT_TYPE_LONG_INT3; + else if(strstr(argtype, "ud2")) + type |= UE_BREAKPOINT_TYPE_UD2; + else if(strstr(argtype, "short")) + type |= UE_BREAKPOINT_TYPE_INT3; + short oldbytes; + const char* bpname = 0; + if(*argname) + bpname = argname; + if(BpGet(addr, BPNORMAL, bpname, 0)) + { + dputs("Breakpoint already set!"); + return STATUS_CONTINUE; + } + if(IsBPXEnabled(addr)) + { + dprintf("Error setting breakpoint at " fhex "! (IsBPXEnabled)\n", addr); + return STATUS_ERROR; + } + else if(!MemRead(addr, &oldbytes, sizeof(short))) + { + dprintf("Error setting breakpoint at " fhex "! (memread)\n", addr); + return STATUS_ERROR; + } + else if(!BpNew(addr, true, singleshoot, oldbytes, BPNORMAL, type, bpname)) + { + dprintf("Error setting breakpoint at " fhex "! (bpnew)\n", addr); + return STATUS_ERROR; + } + else if(!SetBPX(addr, type, (void*)cbUserBreakpoint)) + { + dprintf("Error setting breakpoint at " fhex "! (SetBPX)\n", addr); + return STATUS_ERROR; + } + dprintf("Breakpoint at " fhex " set!\n", addr); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugDeleteBPX(int argc, char* argv[]) +{ + if(argc < 2) //delete all breakpoints + { + if(!BpGetCount(BPNORMAL)) + { + dputs("No breakpoints to delete!"); + return STATUS_CONTINUE; + } + if(!BpEnumAll(cbDeleteAllBreakpoints)) //at least one deletion failed + { + GuiUpdateAllViews(); + return STATUS_ERROR; + } + dputs("All breakpoints deleted!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + BREAKPOINT found; + if(BpGet(0, BPNORMAL, argv[1], &found)) //found a breakpoint with name + { + if(!BpDelete(found.addr, BPNORMAL)) + { + dprintf("Delete breakpoint failed (bpdel): " fhex "\n", found.addr); + return STATUS_ERROR; + } + else if(found.enabled && !DeleteBPX(found.addr)) + { + dprintf("Delete breakpoint failed (DeleteBPX): " fhex "\n", found.addr); + GuiUpdateAllViews(); + return STATUS_ERROR; + } + return STATUS_CONTINUE; + } + duint addr = 0; + if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint + { + dprintf("No such breakpoint \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + if(!BpDelete(found.addr, BPNORMAL)) + { + dprintf("Delete breakpoint failed (bpdel): " fhex "\n", found.addr); + return STATUS_ERROR; + } + else if(found.enabled && !DeleteBPX(found.addr)) + { + dprintf("Delete breakpoint failed (DeleteBPX): " fhex "\n", found.addr); + GuiUpdateAllViews(); + return STATUS_ERROR; + } + dputs("Breakpoint deleted!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugEnableBPX(int argc, char* argv[]) +{ + if(argc < 2) //enable all breakpoints + { + if(!BpGetCount(BPNORMAL)) + { + dputs("No breakpoints to enable!"); + return STATUS_CONTINUE; + } + if(!BpEnumAll(cbEnableAllBreakpoints)) //at least one enable failed + return STATUS_ERROR; + dputs("All breakpoints enabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + BREAKPOINT found; + if(BpGet(0, BPNORMAL, argv[1], &found)) //found a breakpoint with name + { + if(!BpEnable(found.addr, BPNORMAL, true)) + { + dprintf("Could not enable breakpoint " fhex " (BpEnable)\n", found.addr); + return STATUS_ERROR; + } + if(!SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint)) + { + dprintf("Could not enable breakpoint " fhex " (SetBPX)\n", found.addr); + return STATUS_ERROR; + } + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + duint addr = 0; + if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint + { + dprintf("No such breakpoint \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + if(found.enabled) + { + dputs("Breakpoint already enabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + if(!BpEnable(found.addr, BPNORMAL, true)) + { + dprintf("Could not enable breakpoint " fhex " (BpEnable)\n", found.addr); + return STATUS_ERROR; + } + if(!SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint)) + { + dprintf("Could not enable breakpoint " fhex " (SetBPX)\n", found.addr); + return STATUS_ERROR; + } + dputs("Breakpoint enabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugDisableBPX(int argc, char* argv[]) +{ + if(argc < 2) //delete all breakpoints + { + if(!BpGetCount(BPNORMAL)) + { + dputs("No breakpoints to disable!"); + return STATUS_CONTINUE; + } + if(!BpEnumAll(cbDisableAllBreakpoints)) //at least one deletion failed + return STATUS_ERROR; + dputs("All breakpoints disabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + BREAKPOINT found; + if(BpGet(0, BPNORMAL, argv[1], &found)) //found a breakpoint with name + { + if(!BpEnable(found.addr, BPNORMAL, false)) + { + dprintf("Could not disable breakpoint " fhex " (BpEnable)\n", found.addr); + return STATUS_ERROR; + } + if(!DeleteBPX(found.addr)) + { + dprintf("Could not disable breakpoint " fhex " (DeleteBPX)\n", found.addr); + return STATUS_ERROR; + } + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + duint addr = 0; + if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint + { + dprintf("No such breakpoint \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + if(!found.enabled) + { + dputs("Breakpoint already disabled!"); + return STATUS_CONTINUE; + } + if(!BpEnable(found.addr, BPNORMAL, false)) + { + dprintf("Could not disable breakpoint " fhex " (BpEnable)\n", found.addr); + return STATUS_ERROR; + } + if(!DeleteBPX(found.addr)) + { + dprintf("Could not disable breakpoint " fhex " (DeleteBPX)\n", found.addr); + return STATUS_ERROR; + } + dputs("Breakpoint disabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugBplist(int argc, char* argv[]) +{ + if(!BpEnumAll(cbBreakpointList)) + { + dputs("Something went wrong..."); + return STATUS_ERROR; + } + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugStepInto(int argc, char* argv[]) +{ + StepInto((void*)cbStep); + dbgsetstepping(true); + return cbDebugRun(argc, argv); +} + +CMDRESULT cbDebugeStepInto(int argc, char* argv[]) +{ + dbgsetskipexceptions(true); + return cbDebugStepInto(argc, argv); +} + +CMDRESULT cbDebugStepOver(int argc, char* argv[]) +{ + StepOver((void*)cbStep); + dbgsetstepping(true); + return cbDebugRun(argc, argv); +} + +CMDRESULT cbDebugeStepOver(int argc, char* argv[]) +{ + dbgsetskipexceptions(true); + return cbDebugStepOver(argc, argv); +} + +CMDRESULT cbDebugSingleStep(int argc, char* argv[]) +{ + duint stepcount = 1; + if(argc > 1) + if(!valfromstring(argv[1], &stepcount)) + stepcount = 1; + SingleStep((DWORD)stepcount, (void*)cbStep); + dbgsetstepping(true); + return cbDebugRun(argc, argv); +} + +CMDRESULT cbDebugeSingleStep(int argc, char* argv[]) +{ + dbgsetskipexceptions(true); + return cbDebugSingleStep(argc, argv); +} + +CMDRESULT cbDebugHide(int argc, char* argv[]) +{ + if(HideDebugger(fdProcessInfo->hProcess, UE_HIDE_PEBONLY)) + dputs("Debugger hidden"); + else + dputs("Something went wrong"); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugDisasm(int argc, char* argv[]) +{ + duint addr = 0; + if(argc > 1) + { + if(!valfromstring(argv[1], &addr)) + addr = GetContextDataEx(hActiveThread, UE_CIP); + } + if(!MemIsValidReadPtr(addr)) + return STATUS_CONTINUE; + DebugUpdateGui(addr, false); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugSetMemoryBpx(int argc, char* argv[]) +{ + if(argc < 2) + { + dputs("Not enough arguments!"); + return STATUS_ERROR; + } + duint addr; + if(!valfromstring(argv[1], &addr)) + return STATUS_ERROR; + bool restore = false; + char arg3[deflen] = ""; + if(argc > 3) + strcpy_s(arg3, argv[3]); + if(argc > 2) + { + if(*argv[2] == '1') + restore = true; + else if(*argv[2] == '0') + restore = false; + else + strcpy_s(arg3, argv[2]); + } + DWORD type = UE_MEMORY; + if(*arg3) + { + switch(*arg3) + { + case 'r': + type = UE_MEMORY_READ; + break; + case 'w': + type = UE_MEMORY_WRITE; + break; + case 'x': + type = UE_MEMORY_EXECUTE; //EXECUTE + break; + default: + dputs("Invalid type (argument ignored)"); + break; + } + } + duint size = 0; + duint base = MemFindBaseAddr(addr, &size, true); + bool singleshoot = false; + if(!restore) + singleshoot = true; + if(BpGet(base, BPMEMORY, 0, 0)) + { + dputs("Hardware breakpoint already set!"); + return STATUS_CONTINUE; + } + if(!BpNew(base, true, singleshoot, 0, BPMEMORY, type, 0)) + { + dputs("Error setting memory breakpoint! (BpNew)"); + return STATUS_ERROR; + } + if(!SetMemoryBPXEx(base, size, type, restore, (void*)cbMemoryBreakpoint)) + { + dputs("Error setting memory breakpoint! (SetMemoryBPXEx)"); + return STATUS_ERROR; + } + dprintf("Memory breakpoint at " fhex " set!\n", addr); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugDeleteMemoryBreakpoint(int argc, char* argv[]) +{ + if(argc < 2) //delete all breakpoints + { + if(!BpGetCount(BPMEMORY)) + { + dputs("no memory breakpoints to delete!"); + return STATUS_CONTINUE; + } + if(!BpEnumAll(cbDeleteAllMemoryBreakpoints)) //at least one deletion failed + return STATUS_ERROR; + dputs("All memory breakpoints deleted!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + BREAKPOINT found; + if(BpGet(0, BPMEMORY, argv[1], &found)) //found a breakpoint with name + { + duint size; + MemFindBaseAddr(found.addr, &size); + if(!BpDelete(found.addr, BPMEMORY)) + { + dprintf("Delete memory breakpoint failed: " fhex " (BpDelete)\n", found.addr); + return STATUS_ERROR; + } + if(!RemoveMemoryBPX(found.addr, size)) + { + dprintf("Delete memory breakpoint failed: " fhex " (RemoveMemoryBPX)\n", found.addr); + return STATUS_ERROR; + } + return STATUS_CONTINUE; + } + duint addr = 0; + if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPMEMORY, 0, &found)) //invalid breakpoint + { + dprintf("No such memory breakpoint \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + duint size; + MemFindBaseAddr(found.addr, &size); + if(!BpDelete(found.addr, BPMEMORY)) + { + dprintf("Delete memory breakpoint failed: " fhex " (BpDelete)\n", found.addr); + return STATUS_ERROR; + } + if(!RemoveMemoryBPX(found.addr, size)) + { + dprintf("Delete memory breakpoint failed: " fhex " (RemoveMemoryBPX)\n", found.addr); + return STATUS_ERROR; + } + dputs("Memory breakpoint deleted!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugRtr(int argc, char* argv[]) +{ + StepOver((void*)cbRtrStep); + cbDebugRun(argc, argv); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugeRtr(int argc, char* argv[]) +{ + dbgsetskipexceptions(true); + return cbDebugRtr(argc, argv); +} + +CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[]) +{ + if(argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr; + if(!valfromstring(argv[1], &addr)) + return STATUS_ERROR; + DWORD type = UE_HARDWARE_EXECUTE; + if(argc > 2) + { + switch(*argv[2]) + { + case 'r': + type = UE_HARDWARE_READWRITE; + break; + case 'w': + type = UE_HARDWARE_WRITE; + break; + case 'x': + break; + default: + dputs("Invalid type, assuming 'x'"); + break; + } + } + DWORD titsize = UE_HARDWARE_SIZE_1; + if(argc > 3) + { + duint size; + if(!valfromstring(argv[3], &size)) + return STATUS_ERROR; + switch(size) + { + case 1: + titsize = UE_HARDWARE_SIZE_1; + break; + case 2: + titsize = UE_HARDWARE_SIZE_2; + break; + case 4: + titsize = UE_HARDWARE_SIZE_4; + break; +#ifdef _WIN64 + case 8: + titsize = UE_HARDWARE_SIZE_8; + break; +#endif // _WIN64 + default: + titsize = UE_HARDWARE_SIZE_1; + dputs("Invalid size, using 1"); + break; + } + if((addr % size) != 0) + { + dprintf("Address not aligned to %d\n", size); + return STATUS_ERROR; + } + } + DWORD drx = 0; + if(!GetUnusedHardwareBreakPointRegister(&drx)) + { + dputs("You can only set 4 hardware breakpoints"); + return STATUS_ERROR; + } + int titantype = 0; + TITANSETDRX(titantype, drx); + TITANSETTYPE(titantype, type); + TITANSETSIZE(titantype, titsize); + //TODO: hwbp in multiple threads TEST + if(BpGet(addr, BPHARDWARE, 0, 0)) + { + dputs("Hardware breakpoint already set!"); + return STATUS_CONTINUE; + } + if(!BpNew(addr, true, false, 0, BPHARDWARE, titantype, 0)) + { + dputs("Error setting hardware breakpoint (bpnew)!"); + return STATUS_ERROR; + } + if(!SetHardwareBreakPoint(addr, drx, type, titsize, (void*)cbHardwareBreakpoint)) + { + dputs("Error setting hardware breakpoint (TitanEngine)!"); + return STATUS_ERROR; + } + dprintf("Hardware breakpoint at " fhex " set!\n", addr); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[]) +{ + if(argc < 2) //delete all breakpoints + { + if(!BpGetCount(BPHARDWARE)) + { + dputs("No hardware breakpoints to delete!"); + return STATUS_CONTINUE; + } + if(!BpEnumAll(cbDeleteAllHardwareBreakpoints)) //at least one deletion failed + return STATUS_ERROR; + dputs("All hardware breakpoints deleted!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + BREAKPOINT found; + if(BpGet(0, BPHARDWARE, argv[1], &found)) //found a breakpoint with name + { + if(!BpDelete(found.addr, BPHARDWARE)) + { + dprintf("Delete hardware breakpoint failed: " fhex " (BpDelete)\n", found.addr); + return STATUS_ERROR; + } + if(!DeleteHardwareBreakPoint(TITANGETDRX(found.titantype))) + { + dprintf("Delete hardware breakpoint failed: " fhex " (DeleteHardwareBreakPoint)\n", found.addr); + return STATUS_ERROR; + } + return STATUS_CONTINUE; + } + duint addr = 0; + if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPHARDWARE, 0, &found)) //invalid breakpoint + { + dprintf("No such hardware breakpoint \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + if(!BpDelete(found.addr, BPHARDWARE)) + { + dprintf("Delete hardware breakpoint failed: " fhex " (BpDelete)\n", found.addr); + return STATUS_ERROR; + } + if(!DeleteHardwareBreakPoint(TITANGETDRX(found.titantype))) + { + dprintf("Delete hardware breakpoint failed: " fhex " (DeleteHardwareBreakPoint)\n", found.addr); + return STATUS_ERROR; + } + dputs("Hardware breakpoint deleted!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugAlloc(int argc, char* argv[]) +{ + duint size = 0x1000; + if(argc > 1) + if(!valfromstring(argv[1], &size, false)) + return STATUS_ERROR; + duint mem = (duint)MemAllocRemote(0, size); + if(!mem) + dputs("VirtualAllocEx failed"); + else + dprintf(fhex"\n", mem); + if(mem) + varset("$lastalloc", mem, true); + //update memory map + MemUpdateMap(); + GuiUpdateMemoryView(); + + varset("$res", mem, false); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugFree(int argc, char* argv[]) +{ + duint lastalloc; + varget("$lastalloc", &lastalloc, 0, 0); + duint addr = lastalloc; + if(argc > 1) + { + if(!valfromstring(argv[1], &addr, false)) + return STATUS_ERROR; + } + else if(!lastalloc) + { + dputs("$lastalloc is zero, provide a page address"); + return STATUS_ERROR; + } + if(addr == lastalloc) + varset("$lastalloc", (duint)0, true); + bool ok = !!VirtualFreeEx(fdProcessInfo->hProcess, (void*)addr, 0, MEM_RELEASE); + if(!ok) + dputs("VirtualFreeEx failed"); + //update memory map + MemUpdateMap(); + GuiUpdateMemoryView(); + + varset("$res", ok, false); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugMemset(int argc, char* argv[]) +{ + duint addr; + duint value; + duint size; + if(argc < 3) + { + dputs("Not enough arguments"); + return STATUS_ERROR; + } + if(!valfromstring(argv[1], &addr, false) || !valfromstring(argv[2], &value, false)) + return STATUS_ERROR; + if(argc > 3) + { + if(!valfromstring(argv[3], &size, false)) + return STATUS_ERROR; + } + else + { + duint base = MemFindBaseAddr(addr, &size, true); + if(!base) + { + dputs("Invalid address specified"); + return STATUS_ERROR; + } + duint diff = addr - base; + addr = base + diff; + size -= diff; + } + BYTE fi = value & 0xFF; + if(!Fill((void*)addr, size & 0xFFFFFFFF, &fi)) + dputs("Memset failed"); + else + dprintf("Memory " fhex " (size: %.8X) set to %.2X\n", addr, size & 0xFFFFFFFF, value & 0xFF); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugBenchmark(int argc, char* argv[]) +{ + duint addr = MemFindBaseAddr(GetContextDataEx(hActiveThread, UE_CIP), 0); + DWORD ticks = GetTickCount(); + for(duint i = addr; i < addr + 100000; i++) + { + CommentSet(i, "test", false); + LabelSet(i, "test", false); + BookmarkSet(i, false); + FunctionAdd(i, i, false); + } + dprintf("%ums\n", GetTickCount() - ticks); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugPause(int argc, char* argv[]) +{ + if(!dbgisrunning()) + { + dputs("Program is not running"); + return STATUS_ERROR; + } + duint debugBreakAddr; + if(!valfromstring("DebugBreak", &debugBreakAddr)) + { + dputs("Could not find DebugBreak!"); + return STATUS_ERROR; + } + DWORD dwThreadId = 0; + HANDLE hThread = CreateRemoteThread(fdProcessInfo->hProcess, 0, 0, (LPTHREAD_START_ROUTINE)debugBreakAddr, 0, CREATE_SUSPENDED, &dwThreadId); + if(!hThread) + { + dputs("Failed to create thread in debuggee"); + return STATUS_ERROR; + } + dprintf("Created thread with ThreadId %X\n", dwThreadId); + dbgsetispausedbyuser(true); + ResumeThread(hThread); + CloseHandle(hThread); + return STATUS_CONTINUE; +} + +static DWORD WINAPI scyllaThread(void* lpParam) +{ + typedef INT (WINAPI * SCYLLASTARTGUI)(DWORD pid, HINSTANCE mod); + SCYLLASTARTGUI ScyllaStartGui = 0; + HINSTANCE hScylla = LoadLibraryW(L"Scylla.dll"); + if(!hScylla) + { + dputs("Error loading Scylla.dll!"); + bScyllaLoaded = false; + FreeLibrary(hScylla); + return 0; + } + ScyllaStartGui = (SCYLLASTARTGUI)GetProcAddress(hScylla, "ScyllaStartGui"); + if(!ScyllaStartGui) + { + dputs("Could not find export 'ScyllaStartGui' inside Scylla.dll"); + bScyllaLoaded = false; + FreeLibrary(hScylla); + return 0; + } + if(dbgisdll()) + ScyllaStartGui(fdProcessInfo->dwProcessId, (HINSTANCE)dbgdebuggedbase()); + else + ScyllaStartGui(fdProcessInfo->dwProcessId, 0); + FreeLibrary(hScylla); + bScyllaLoaded = false; + return 0; +} + +CMDRESULT cbDebugStartScylla(int argc, char* argv[]) +{ + if(bScyllaLoaded) + { + dputs("Scylla is already loaded"); + return STATUS_ERROR; + } + bScyllaLoaded = true; + CloseHandle(CreateThread(0, 0, scyllaThread, 0, 0, 0)); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugAttach(int argc, char* argv[]) +{ + if(argc < 2) + { + dputs("Not enough arguments!"); + return STATUS_ERROR; + } + duint pid = 0; + if(!valfromstring(argv[1], &pid, false)) + return STATUS_ERROR; + if(argc > 2) + { + duint eventHandle = 0; + if(!valfromstring(argv[2], &eventHandle, false)) + return STATUS_ERROR; + dbgsetattachevent((HANDLE)eventHandle); + } + if(DbgIsDebugging()) + DbgCmdExecDirect("stop"); + Handle hProcess = TitanOpenProcess(PROCESS_ALL_ACCESS, false, (DWORD)pid); + if(!hProcess) + { + dprintf("Could not open process %X!\n", pid); + return STATUS_ERROR; + } + BOOL wow64 = false, mewow64 = false; + if(!IsWow64Process(hProcess, &wow64) || !IsWow64Process(GetCurrentProcess(), &mewow64)) + { + dputs("IsWow64Process failed!"); + return STATUS_ERROR; + } + if((mewow64 && !wow64) || (!mewow64 && wow64)) + { +#ifdef _WIN64 + dputs("Use x32dbg to debug this process!"); +#else + dputs("Use x64dbg to debug this process!"); +#endif // _WIN64 + return STATUS_ERROR; + } + wchar_t wszFileName[MAX_PATH] = L""; + if(!GetModuleFileNameExW(hProcess, 0, wszFileName, MAX_PATH)) + { + dprintf("Could not get module filename %X!\n", pid); + return STATUS_ERROR; + } + strcpy_s(szFileName, StringUtils::Utf16ToUtf8(wszFileName).c_str()); + CloseHandle(CreateThread(0, 0, threadAttachLoop, (void*)pid, 0, 0)); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugDetach(int argc, char* argv[]) +{ + unlock(WAITID_RUN); //run + dbgsetisdetachedbyuser(true); //detach when paused + StepInto((void*)cbDetach); + DebugBreakProcess(fdProcessInfo->hProcess); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugDump(int argc, char* argv[]) +{ + if(argc < 2) + { + dputs("Not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if(!valfromstring(argv[1], &addr)) + { + dprintf("Invalid address \"%s\"!\n", argv[1]); + return STATUS_ERROR; + } + GuiDumpAt(addr); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugStackDump(int argc, char* argv[]) +{ + duint addr = 0; + if(argc < 2) + addr = GetContextDataEx(hActiveThread, UE_CSP); + else if(!valfromstring(argv[1], &addr)) + { + dprintf("Invalid address \"%s\"!\n", argv[1]); + return STATUS_ERROR; + } + duint csp = GetContextDataEx(hActiveThread, UE_CSP); + duint size = 0; + duint base = MemFindBaseAddr(csp, &size); + if(base && addr >= base && addr < (base + size)) + DebugUpdateStack(addr, csp, true); + else + dputs("Invalid stack address!"); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugContinue(int argc, char* argv[]) +{ + if(argc < 2) + { + SetNextDbgContinueStatus(DBG_CONTINUE); + dputs("Exception will be swallowed"); + } + else + { + SetNextDbgContinueStatus(DBG_EXCEPTION_NOT_HANDLED); + dputs("Exception will be thrown in the program"); + } + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugBpDll(int argc, char* argv[]) +{ + if(argc < 2) + { + dputs("Not enough arguments!"); + return STATUS_ERROR; + } + DWORD type = UE_ON_LIB_ALL; + if(argc > 2) + { + switch(*argv[2]) + { + case 'l': + type = UE_ON_LIB_LOAD; + break; + case 'u': + type = UE_ON_LIB_UNLOAD; + break; + } + } + bool singleshoot = true; + if(argc > 3) + singleshoot = false; + LibrarianSetBreakPoint(argv[1], type, singleshoot, (void*)cbLibrarianBreakpoint); + dprintf("Dll breakpoint set on \"%s\"!\n", argv[1]); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugBcDll(int argc, char* argv[]) +{ + if(argc < 2) + { + dputs("Not enough arguments"); + return STATUS_ERROR; + } + if(!LibrarianRemoveBreakPoint(argv[1], UE_ON_LIB_ALL)) + { + dputs("Failed to remove DLL breakpoint..."); + return STATUS_ERROR; + } + dputs("DLL breakpoint removed!"); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugSwitchthread(int argc, char* argv[]) +{ + duint threadid = fdProcessInfo->dwThreadId; //main thread + if(argc > 1) + if(!valfromstring(argv[1], &threadid, false)) + return STATUS_ERROR; + if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid + { + dprintf("Invalid thread %X\n", threadid); + return STATUS_ERROR; + } + //switch thread + hActiveThread = ThreadGetHandle((DWORD)threadid); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + dputs("Thread switched!"); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugSuspendthread(int argc, char* argv[]) +{ + duint threadid = fdProcessInfo->dwThreadId; + if(argc > 1) + if(!valfromstring(argv[1], &threadid, false)) + return STATUS_ERROR; + if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid + { + dprintf("Invalid thread %X\n", threadid); + return STATUS_ERROR; + } + //suspend thread + if(SuspendThread(ThreadGetHandle((DWORD)threadid)) == -1) + { + dputs("Error suspending thread"); + return STATUS_ERROR; + } + dputs("Thread suspended"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugResumethread(int argc, char* argv[]) +{ + duint threadid = fdProcessInfo->dwThreadId; + if(argc > 1) + if(!valfromstring(argv[1], &threadid, false)) + return STATUS_ERROR; + if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid + { + dprintf("Invalid thread %X\n", threadid); + return STATUS_ERROR; + } + //resume thread + if(ResumeThread(ThreadGetHandle((DWORD)threadid)) == -1) + { + dputs("Error resuming thread"); + return STATUS_ERROR; + } + dputs("Thread resumed!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugKillthread(int argc, char* argv[]) +{ + duint threadid = fdProcessInfo->dwThreadId; + if(argc > 1) + if(!valfromstring(argv[1], &threadid, false)) + return STATUS_ERROR; + duint exitcode = 0; + if(argc > 2) + if(!valfromstring(argv[2], &exitcode, false)) + return STATUS_ERROR; + if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid + { + dprintf("Invalid thread %X\n", threadid); + return STATUS_ERROR; + } + //terminate thread + if(TerminateThread(ThreadGetHandle((DWORD)threadid), (DWORD)exitcode) != 0) + { + GuiUpdateAllViews(); + dputs("Thread terminated"); + return STATUS_CONTINUE; + } + dputs("Error terminating thread!"); + return STATUS_ERROR; +} + +CMDRESULT cbDebugSuspendAllThreads(int argc, char* argv[]) +{ + dprintf("%d/%d thread(s) suspended\n", ThreadSuspendAll(), ThreadGetCount()); + + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugResumeAllThreads(int argc, char* argv[]) +{ + dprintf("%d/%d thread(s) resumed\n", ThreadResumeAll(), ThreadGetCount()); + + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugSetPriority(int argc, char* argv[]) +{ + if(argc < 3) + { + dputs("Not enough arguments!"); + return STATUS_ERROR; + } + duint threadid; + if(!valfromstring(argv[1], &threadid, false)) + return STATUS_ERROR; + duint priority; + if(!valfromstring(argv[2], &priority)) + { + if(_strcmpi(argv[2], "Normal") == 0) + priority = THREAD_PRIORITY_NORMAL; + else if(_strcmpi(argv[2], "AboveNormal") == 0) + priority = THREAD_PRIORITY_ABOVE_NORMAL; + else if(_strcmpi(argv[2], "TimeCritical") == 0) + priority = THREAD_PRIORITY_TIME_CRITICAL; + else if(_strcmpi(argv[2], "Idle") == 0) + priority = THREAD_PRIORITY_IDLE; + else if(_strcmpi(argv[2], "BelowNormal") == 0) + priority = THREAD_PRIORITY_BELOW_NORMAL; + else if(_strcmpi(argv[2], "Highest") == 0) + priority = THREAD_PRIORITY_HIGHEST; + else if(_strcmpi(argv[2], "Lowest") == 0) + priority = THREAD_PRIORITY_LOWEST; + else + { + dputs("Unknown priority value, read the help!"); + return STATUS_ERROR; + } + } + else + { + switch(priority) //check if the priority value is valid + { + case THREAD_PRIORITY_NORMAL: + case THREAD_PRIORITY_ABOVE_NORMAL: + case THREAD_PRIORITY_TIME_CRITICAL: + case THREAD_PRIORITY_IDLE: + case THREAD_PRIORITY_BELOW_NORMAL: + case THREAD_PRIORITY_HIGHEST: + case THREAD_PRIORITY_LOWEST: + break; + default: + dputs("Unknown priority value, read the help!"); + return STATUS_ERROR; + } + } + if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid + { + dprintf("Invalid thread %X\n", threadid); + return STATUS_ERROR; + } + //set thread priority + if(SetThreadPriority(ThreadGetHandle((DWORD)threadid), (int)priority) == 0) + { + dputs("Error setting thread priority"); + return STATUS_ERROR; + } + dputs("Thread priority changed!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[]) +{ + DWORD drx = 0; + if(!GetUnusedHardwareBreakPointRegister(&drx)) + { + dputs("You can only set 4 hardware breakpoints"); + return STATUS_ERROR; + } + if(argc < 2) //enable all hardware breakpoints + { + if(!BpGetCount(BPHARDWARE)) + { + dputs("No hardware breakpoints to enable!"); + return STATUS_CONTINUE; + } + if(!BpEnumAll(cbEnableAllHardwareBreakpoints)) //at least one enable failed + return STATUS_ERROR; + dputs("All hardware breakpoints enabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + BREAKPOINT found; + duint addr = 0; + if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint + { + dprintf("No such hardware breakpoint \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + if(found.enabled) + { + dputs("Hardware breakpoint already enabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + TITANSETDRX(found.titantype, drx); + BpSetTitanType(found.addr, BPHARDWARE, found.titantype); + if(!BpEnable(found.addr, BPHARDWARE, true) || !SetHardwareBreakPoint(found.addr, drx, TITANGETTYPE(found.titantype), TITANGETSIZE(found.titantype), (void*)cbHardwareBreakpoint)) + { + dprintf("Could not enable hardware breakpoint " fhex "\n", found.addr); + return STATUS_ERROR; + } + dputs("Hardware breakpoint enabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[]) +{ + if(argc < 2) //delete all hardware breakpoints + { + if(!BpGetCount(BPHARDWARE)) + { + dputs("No hardware breakpoints to disable!"); + return STATUS_CONTINUE; + } + if(!BpEnumAll(cbDisableAllHardwareBreakpoints)) //at least one deletion failed + return STATUS_ERROR; + dputs("All hardware breakpoints disabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + BREAKPOINT found; + duint addr = 0; + if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint + { + dprintf("No such hardware breakpoint \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + if(!found.enabled) + { + dputs("Hardware breakpoint already disabled!"); + return STATUS_CONTINUE; + } + if(!BpEnable(found.addr, BPHARDWARE, false) || !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype))) + { + dprintf("Could not disable hardware breakpoint " fhex "\n", found.addr); + return STATUS_ERROR; + } + dputs("Hardware breakpoint disabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[]) +{ + if(argc < 2) //enable all memory breakpoints + { + if(!BpGetCount(BPMEMORY)) + { + dputs("No memory breakpoints to enable!"); + return STATUS_CONTINUE; + } + if(!BpEnumAll(cbEnableAllMemoryBreakpoints)) //at least one enable failed + return STATUS_ERROR; + dputs("All memory breakpoints enabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + BREAKPOINT found; + duint addr = 0; + if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint + { + dprintf("No such memory breakpoint \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + if(found.enabled) + { + dputs("Memory memory already enabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + duint size = 0; + MemFindBaseAddr(found.addr, &size); + if(!BpEnable(found.addr, BPMEMORY, true) || !SetMemoryBPXEx(found.addr, size, found.titantype, !found.singleshoot, (void*)cbMemoryBreakpoint)) + { + dprintf("Could not enable memory breakpoint " fhex "\n", found.addr); + return STATUS_ERROR; + } + dputs("Memory breakpoint enabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[]) +{ + if(argc < 2) //delete all memory breakpoints + { + if(!BpGetCount(BPMEMORY)) + { + dputs("No memory breakpoints to disable!"); + return STATUS_CONTINUE; + } + if(!BpEnumAll(cbDisableAllMemoryBreakpoints)) //at least one deletion failed + return STATUS_ERROR; + dputs("All memory breakpoints disabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; + } + BREAKPOINT found; + duint addr = 0; + if(!valfromstring(argv[1], &addr) || !BpGet(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint + { + dprintf("No such memory breakpoint \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + if(!found.enabled) + { + dputs("Memory breakpoint already disabled!"); + return STATUS_CONTINUE; + } + duint size = 0; + MemFindBaseAddr(found.addr, &size); + if(!BpEnable(found.addr, BPMEMORY, false) || !RemoveMemoryBPX(found.addr, size)) + { + dprintf("Could not disable memory breakpoint " fhex "\n", found.addr); + return STATUS_ERROR; + } + dputs("Memory breakpoint disabled!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[]) +{ + char szDefaultStore[MAX_SETTING_SIZE] = ""; + const char* szSymbolStore = szDefaultStore; + if(!BridgeSettingGet("Symbols", "DefaultStore", szDefaultStore)) //get default symbol store from settings + { + strcpy_s(szDefaultStore, "http://msdl.microsoft.com/download/symbols"); + BridgeSettingSet("Symbols", "DefaultStore", szDefaultStore); + } + if(argc < 2) //no arguments + { + SymDownloadAllSymbols(szSymbolStore); //download symbols for all modules + GuiSymbolRefreshCurrent(); + dputs("Done! See symbol log for more information"); + return STATUS_CONTINUE; + } + //get some module information + duint modbase = ModBaseFromName(argv[1]); + if(!modbase) + { + dprintf("Invalid module \"%s\"!\n", argv[1]); + return STATUS_ERROR; + } + wchar_t wszModulePath[MAX_PATH] = L""; + if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbase, wszModulePath, MAX_PATH)) + { + dputs("GetModuleFileNameExA failed!"); + return STATUS_ERROR; + } + char szModulePath[MAX_PATH] = ""; + strcpy_s(szModulePath, StringUtils::Utf16ToUtf8(wszModulePath).c_str()); + wchar_t szOldSearchPath[MAX_PATH] = L""; + if(!SafeSymGetSearchPathW(fdProcessInfo->hProcess, szOldSearchPath, MAX_PATH)) //backup current search path + { + dputs("SymGetSearchPath failed!"); + return STATUS_ERROR; + } + char szServerSearchPath[MAX_PATH * 2] = ""; + if(argc > 2) + szSymbolStore = argv[2]; + sprintf_s(szServerSearchPath, "SRV*%s*%s", szSymbolCachePath, szSymbolStore); + if(!SafeSymSetSearchPathW(fdProcessInfo->hProcess, StringUtils::Utf8ToUtf16(szServerSearchPath).c_str())) //set new search path + { + dputs("SymSetSearchPath (1) failed!"); + return STATUS_ERROR; + } + if(!SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)modbase)) //unload module + { + SafeSymSetSearchPathW(fdProcessInfo->hProcess, szOldSearchPath); + dputs("SymUnloadModule64 failed!"); + return STATUS_ERROR; + } + if(!SafeSymLoadModuleEx(fdProcessInfo->hProcess, 0, szModulePath, 0, (DWORD64)modbase, 0, 0, 0)) //load module + { + dputs("SymLoadModuleEx failed!"); + SafeSymSetSearchPathW(fdProcessInfo->hProcess, szOldSearchPath); + return STATUS_ERROR; + } + if(!SafeSymSetSearchPathW(fdProcessInfo->hProcess, szOldSearchPath)) + { + dputs("SymSetSearchPathW (2) failed!"); + return STATUS_ERROR; + } + GuiSymbolRefreshCurrent(); + dputs("Done! See symbol log for more information"); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugGetJITAuto(int argc, char* argv[]) +{ + bool jit_auto = false; + arch actual_arch = invalid; + + if(argc == 1) + { + if(!dbggetjitauto(&jit_auto, notfound, & actual_arch, NULL)) + { + dprintf("Error getting JIT auto %s\n", (actual_arch == x64) ? "x64" : "x32"); + return STATUS_ERROR; + } + } + else if(argc == 2) + { + readwritejitkey_error_t rw_error; + if(_strcmpi(argv[1], "x64") == 0) + actual_arch = x64; + else if(_strcmpi(argv[1], "x32") == 0) + actual_arch = x32; + else + { + dputs("Unknown JIT auto entry type. Use x64 or x32 as parameter."); + return STATUS_ERROR; + } + + if(!dbggetjitauto(& jit_auto, actual_arch, NULL, & rw_error)) + { + if(rw_error == ERROR_RW_NOTWOW64) + dprintf("Error using x64 arg the debugger is not a WOW64 process\n"); + else + dprintf("Error getting JIT auto %s\n", argv[1]); + return STATUS_ERROR; + } + } + else + { + dputs("Unknown JIT auto entry type. Use x64 or x32 as parameter"); + } + + dprintf("JIT auto %s: %s\n", (actual_arch == x64) ? "x64" : "x32", jit_auto ? "ON" : "OFF"); + + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugSetJITAuto(int argc, char* argv[]) +{ + arch actual_arch; + bool set_jit_auto; + if(!IsProcessElevated()) + { + dprintf("Error run the debugger as Admin to setjitauto\n"); + return STATUS_ERROR; + } + if(argc < 2) + { + dprintf("Error setting JIT Auto. Use ON:1 or OFF:0 arg or x64/x32, ON:1 or OFF:0.\n"); + return STATUS_ERROR; + } + else if(argc == 2) + { + if(_strcmpi(argv[1], "1") == 0 || _strcmpi(argv[1], "ON") == 0) + set_jit_auto = true; + else if(_strcmpi(argv[1], "0") == 0 || _strcmpi(argv[1], "OFF") == 0) + set_jit_auto = false; + else + { + dputs("Error unknown parameters. Use ON:1 or OFF:0"); + return STATUS_ERROR; + } + + if(!dbgsetjitauto(set_jit_auto, notfound, & actual_arch, NULL)) + { + dprintf("Error setting JIT auto %s\n", (actual_arch == x64) ? "x64" : "x32"); + return STATUS_ERROR; + } + } + else if(argc == 3) + { + readwritejitkey_error_t rw_error; + actual_arch = x64; + + if(_strcmpi(argv[1], "x64") == 0) + actual_arch = x64; + else if(_strcmpi(argv[1], "x32") == 0) + actual_arch = x32; + else + { + dputs("Unknown JIT auto entry type. Use x64 or x32 as parameter"); + return STATUS_ERROR; + } + + if(_strcmpi(argv[2], "1") == 0 || _strcmpi(argv[2], "ON") == 0) + set_jit_auto = true; + else if(_strcmpi(argv[2], "0") == 0 || _strcmpi(argv[2], "OFF") == 0) + set_jit_auto = false; + else + { + dputs("Error unknown parameters. Use x86 or x64 and ON:1 or OFF:0\n"); + return STATUS_ERROR; + } + + if(!dbgsetjitauto(set_jit_auto, actual_arch, NULL, & rw_error)) + { + if(rw_error == ERROR_RW_NOTWOW64) + dprintf("Error using x64 arg the debugger is not a WOW64 process\n"); + else + + dprintf("Error getting JIT auto %s\n", (actual_arch == x64) ? "x64" : "x32"); + return STATUS_ERROR; + } + } + else + { + dputs("Error unknown parameters use x86 or x64, ON/1 or OFF/0\n"); + return STATUS_ERROR; + } + + dprintf("New JIT auto %s: %s\n", (actual_arch == x64) ? "x64" : "x32", set_jit_auto ? "ON" : "OFF"); + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugSetJIT(int argc, char* argv[]) +{ + arch actual_arch = invalid; + char* jit_debugger_cmd = ""; + char oldjit[MAX_SETTING_SIZE] = ""; + char path[JIT_ENTRY_DEF_SIZE]; + if(!IsProcessElevated()) + { + dprintf("Error run the debugger as Admin to setjit\n"); + return STATUS_ERROR; + } + if(argc < 2) + { + dbggetdefjit(path); + + jit_debugger_cmd = path; + if(!dbgsetjit(jit_debugger_cmd, notfound, & actual_arch, NULL)) + { + dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); + return STATUS_ERROR; + } + } + else if(argc == 2) + { + if(!_strcmpi(argv[1], "old")) + { + jit_debugger_cmd = oldjit; + if(!BridgeSettingGet("JIT", "Old", jit_debugger_cmd)) + { + dputs("Error there is no old JIT entry stored."); + return STATUS_ERROR; + } + + if(!dbgsetjit(jit_debugger_cmd, notfound, & actual_arch, NULL)) + { + dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); + return STATUS_ERROR; + } + } + else if(!_strcmpi(argv[1], "oldsave")) + { + char path[JIT_ENTRY_DEF_SIZE]; + dbggetdefjit(path); + char get_entry[JIT_ENTRY_MAX_SIZE] = ""; + bool get_last_jit = true; + + if(!dbggetjit(get_entry, notfound, & actual_arch, NULL)) + get_last_jit = false; + else + strcpy_s(oldjit, get_entry); + + jit_debugger_cmd = path; + if(!dbgsetjit(jit_debugger_cmd, notfound, & actual_arch, NULL)) + { + dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); + return STATUS_ERROR; + } + if(get_last_jit) + { + if(_stricmp(oldjit, path)) + BridgeSettingSet("JIT", "Old", oldjit); + } + } + else if(!_strcmpi(argv[1], "restore")) + { + jit_debugger_cmd = oldjit; + + if(!BridgeSettingGet("JIT", "Old", jit_debugger_cmd)) + { + dputs("Error there is no old JIT entry stored."); + return STATUS_ERROR; + } + + if(!dbgsetjit(jit_debugger_cmd, notfound, & actual_arch, NULL)) + { + dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); + return STATUS_ERROR; + } + BridgeSettingSet("JIT", 0, 0); + } + else + { + jit_debugger_cmd = argv[1]; + if(!dbgsetjit(jit_debugger_cmd, notfound, & actual_arch, NULL)) + { + dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); + return STATUS_ERROR; + } + } + } + else if(argc == 3) + { + readwritejitkey_error_t rw_error; + + if(!_strcmpi(argv[1], "old")) + { + BridgeSettingSet("JIT", "Old", argv[2]); + + dprintf("New OLD JIT stored: %s\n", argv[2]); + + return STATUS_CONTINUE; + } + + else if(_strcmpi(argv[1], "x64") == 0) + actual_arch = x64; + else if(_strcmpi(argv[1], "x32") == 0) + actual_arch = x32; + else + { + dputs("Unknown JIT entry type. Use OLD, x64 or x32 as parameter."); + return STATUS_ERROR; + } + + jit_debugger_cmd = argv[2]; + if(!dbgsetjit(jit_debugger_cmd, actual_arch, NULL, & rw_error)) + { + if(rw_error == ERROR_RW_NOTWOW64) + dprintf("Error using x64 arg. The debugger is not a WOW64 process\n"); + else + dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); + return STATUS_ERROR; + } + } + else + { + dputs("Error unknown parameters. Use old, oldsave, restore, x86 or x64 as parameter."); + return STATUS_ERROR; + } + + dprintf("New JIT %s: %s\n", (actual_arch == x64) ? "x64" : "x32", jit_debugger_cmd); + + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugGetJIT(int argc, char* argv[]) +{ + char get_entry[JIT_ENTRY_MAX_SIZE] = ""; + arch actual_arch; + + if(argc < 2) + { + if(!dbggetjit(get_entry, notfound, & actual_arch, NULL)) + { + dprintf("Error getting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); + return STATUS_ERROR; + } + } + else + { + readwritejitkey_error_t rw_error; + char oldjit[MAX_SETTING_SIZE] = ""; + if(_strcmpi(argv[1], "OLD") == 0) + { + if(!BridgeSettingGet("JIT", "Old", (char*) & oldjit)) + { + dputs("Error: there is not an OLD JIT entry stored yet."); + return STATUS_ERROR; + } + else + { + dprintf("OLD JIT entry stored: %s\n", oldjit); + return STATUS_CONTINUE; + } + } + else if(_strcmpi(argv[1], "x64") == 0) + actual_arch = x64; + else if(_strcmpi(argv[1], "x32") == 0) + actual_arch = x32; + else + { + dputs("Unknown JIT entry type. Use OLD, x64 or x32 as parameter."); + return STATUS_ERROR; + } + + if(!dbggetjit(get_entry, actual_arch, NULL, & rw_error)) + { + if(rw_error == ERROR_RW_NOTWOW64) + dprintf("Error using x64 arg. The debugger is not a WOW64 process\n"); + else + dprintf("Error getting JIT %s\n", argv[1]); + return STATUS_ERROR; + } + } + + dprintf("JIT %s: %s\n", (actual_arch == x64) ? "x64" : "x32", get_entry); + + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugGetPageRights(int argc, char* argv[]) +{ + duint addr = 0; + char rights[RIGHTS_STRING_SIZE]; + + if(argc != 2 || !valfromstring(argv[1], &addr)) + { + dprintf("Error: using an address as arg1\n"); + return STATUS_ERROR; + } + + if(!MemGetPageRights(addr, rights)) + { + dprintf("Error getting rights of page: %s\n", argv[1]); + return STATUS_ERROR; + } + + dprintf("Page: " fhex ", Rights: %s\n", addr, rights); + + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugSetPageRights(int argc, char* argv[]) +{ + duint addr = 0; + char rights[RIGHTS_STRING_SIZE]; + + if(argc < 3 || !valfromstring(argv[1], &addr)) + { + dprintf("Error: Using an address as arg1 and as arg2: Execute, ExecuteRead, ExecuteReadWrite, ExecuteWriteCopy, NoAccess, ReadOnly, ReadWrite, WriteCopy. You can add a G at first for add PAGE GUARD, example: GReadOnly\n"); + return STATUS_ERROR; + } + + if(!MemSetPageRights(addr, argv[2])) + { + dprintf("Error: Set rights of " fhex " with Rights: %s\n", addr, argv[2]); + return STATUS_ERROR; + } + + if(!MemGetPageRights(addr, rights)) + { + dprintf("Error getting rights of page: %s\n", argv[1]); + return STATUS_ERROR; + } + + //update the memory map + MemUpdateMap(); + GuiUpdateMemoryView(); + + dprintf("New rights of " fhex ": %s\n", addr, rights); + + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugLoadLib(int argc, char* argv[]) +{ + if(argc < 2) + { + dprintf("Error: you must specify the name of the DLL to load\n"); + return STATUS_ERROR; + } + + LoadLibThreadID = fdProcessInfo->dwThreadId; + HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID); + + DLLNameMem = MemAllocRemote(0, strlen(argv[1]) + 1); + ASMAddr = MemAllocRemote(0, 0x1000); + + if(!DLLNameMem || !ASMAddr) + { + dprintf("Error: couldn't allocate memory in debuggee"); + return STATUS_ERROR; + } + + if(!MemWrite(DLLNameMem, argv[1], strlen(argv[1]))) + { + dprintf("Error: couldn't write process memory"); + return STATUS_ERROR; + } + + int size = 0; + int counter = 0; + duint LoadLibraryA = 0; + char command[50] = ""; + char error[MAX_ERROR_SIZE] = ""; + + GetFullContextDataEx(LoadLibThread, &backupctx); + + if(!valfromstring("kernel32:LoadLibraryA", &LoadLibraryA, false)) + { + dprintf("Error: couldn't get kernel32:LoadLibraryA"); + return STATUS_ERROR; + } + + // Arch specific asm code +#ifdef _WIN64 + sprintf(command, "mov rcx, " fhex, (duint)DLLNameMem); +#else + sprintf(command, "push " fhex, DLLNameMem); +#endif // _WIN64 + + assembleat((duint)ASMAddr, command, &size, error, true); + counter += size; + +#ifdef _WIN64 + sprintf(command, "mov rax, " fhex, LoadLibraryA); + assembleat((duint)ASMAddr + counter, command, &size, error, true); + counter += size; + sprintf(command, "call rax"); +#else + sprintf(command, "call " fhex, LoadLibraryA); +#endif // _WIN64 + + assembleat((duint)ASMAddr + counter, command, &size, error, true); + counter += size; + + SetContextDataEx(LoadLibThread, UE_CIP, (duint)ASMAddr); + SetBPX((duint)ASMAddr + counter, UE_SINGLESHOOT | UE_BREAKPOINT_TYPE_INT3, (void*)cbDebugLoadLibBPX); + + ThreadSuspendAll(); + ResumeThread(LoadLibThread); + + unlock(WAITID_RUN); + + return STATUS_CONTINUE; +} + +void cbDebugLoadLibBPX() +{ + HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID); +#ifdef _WIN64 + duint LibAddr = GetContextDataEx(LoadLibThread, UE_RAX); +#else + duint LibAddr = GetContextDataEx(LoadLibThread, UE_EAX); +#endif //_WIN64 + varset("$result", LibAddr, false); + backupctx.eflags &= ~0x100; + SetFullContextDataEx(LoadLibThread, &backupctx); + MemFreeRemote(DLLNameMem); + MemFreeRemote(ASMAddr); + ThreadResumeAll(); + //update GUI + GuiSetDebugState(paused); + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true); + //lock + lock(WAITID_RUN); + SetForegroundWindow(GuiGetWindowHandle()); + PLUG_CB_PAUSEDEBUG pauseInfo; + pauseInfo.reserved = 0; + plugincbcall(CB_PAUSEDEBUG, &pauseInfo); + wait(WAITID_RUN); +} + +void showcommandlineerror(cmdline_error_t* cmdline_error) +{ + bool unkown = false; + + switch(cmdline_error->type) + { + case CMDL_ERR_ALLOC: + dprintf("Error allocating memory for cmdline"); + break; + case CMDL_ERR_CONVERTUNICODE: + dprintf("Error converting UNICODE cmdline"); + break; + case CMDL_ERR_READ_PEBBASE: + dprintf("Error reading PEB base addres"); + break; + case CMDL_ERR_READ_PROCPARM_CMDLINE: + dprintf("Error reading PEB -> ProcessParameters -> CommandLine UNICODE_STRING"); + break; + case CMDL_ERR_READ_PROCPARM_PTR: + dprintf("Error reading PEB -> ProcessParameters pointer address"); + break; + case CMDL_ERR_GET_PEB: + dprintf("Error Getting remote PEB address"); + break; + case CMDL_ERR_READ_GETCOMMANDLINEBASE: + dprintf("Error Getting command line base address"); + break; + case CMDL_ERR_CHECK_GETCOMMANDLINESTORED: + dprintf("Error checking the pattern of the commandline stored"); + break; + case CMDL_ERR_WRITE_GETCOMMANDLINESTORED: + dprintf("Error writing the new command line stored"); + break; + case CMDL_ERR_GET_GETCOMMANDLINE: + dprintf("Error getting getcommandline"); + break; + case CMDL_ERR_ALLOC_UNICODEANSI_COMMANDLINE: + dprintf("Error allocating the page with UNICODE and ANSI command lines"); + break; + case CMDL_ERR_WRITE_ANSI_COMMANDLINE: + dprintf("Error writing the ANSI command line in the page"); + break; + case CMDL_ERR_WRITE_UNICODE_COMMANDLINE: + dprintf("Error writing the UNICODE command line in the page"); + break; + case CMDL_ERR_WRITE_PEBUNICODE_COMMANDLINE: + dprintf("Error writing command line UNICODE in PEB"); + break; + default: + unkown = true; + dputs("Error getting cmdline"); + break; + } + + if(!unkown) + { + if(cmdline_error->addr != 0) + dprintf(" (Address: " fhex ")", cmdline_error->addr); + dputs(""); + } +} + +CMDRESULT cbDebugGetCmdline(int argc, char* argv[]) +{ + char* cmd_line; + cmdline_error_t cmdline_error = {(cmdline_error_type_t) 0, 0}; + + if(!dbggetcmdline(& cmd_line, & cmdline_error)) + { + showcommandlineerror(& cmdline_error); + return STATUS_ERROR; + } + + dprintf("Command line: %s\n", cmd_line); + + efree(cmd_line); + + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugSetCmdline(int argc, char* argv[]) +{ + cmdline_error_t cmdline_error = {(cmdline_error_type_t) 0, 0}; + + if(argc != 2) + { + dputs("Error: write the arg1 with the new command line of the process debugged"); + return STATUS_ERROR; + } + + if(!dbgsetcmdline(argv[1], &cmdline_error)) + { + showcommandlineerror(&cmdline_error); + return STATUS_ERROR; + } + + //update the memory map + MemUpdateMap(); + GuiUpdateMemoryView(); + + dprintf("New command line: %s\n", argv[1]); + + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugSkip(int argc, char* argv[]) +{ + SetNextDbgContinueStatus(DBG_CONTINUE); //swallow the exception + duint cip = GetContextDataEx(hActiveThread, UE_CIP); + BASIC_INSTRUCTION_INFO basicinfo; + memset(&basicinfo, 0, sizeof(basicinfo)); + disasmfast(cip, &basicinfo); + cip += basicinfo.size; + SetContextDataEx(hActiveThread, UE_CIP, cip); + DebugUpdateGui(cip, false); //update GUI + return STATUS_CONTINUE; +} + +CMDRESULT cbDebugSetfreezestack(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("Not enough arguments!"); + return STATUS_ERROR; + } + bool freeze = *argv[1] != '0'; + dbgsetfreezestack(freeze); + dprintf("Stack is now %s\n", freeze ? "freezed" : "unfreezed"); + return STATUS_CONTINUE; +} diff --git a/src/dbg/debugger_commands.h b/src/dbg/debugger_commands.h index daa03aff..51f3979f 100644 --- a/src/dbg/debugger_commands.h +++ b/src/dbg/debugger_commands.h @@ -1,72 +1,72 @@ -#ifndef _DEBUGGER_COMMANDS_H -#define _DEBUGGER_COMMANDS_H - -#include "command.h" -#include "debugger.h" - -//command callbacks -CMDRESULT cbDebugInit(int argc, char* argv[]); -CMDRESULT cbDebugStop(int argc, char* argv[]); -CMDRESULT cbDebugRun(int argc, char* argv[]); -CMDRESULT cbDebugErun(int argc, char* argv[]); -CMDRESULT cbDebugSetBPXOptions(int argc, char* argv[]); -CMDRESULT cbDebugSetBPX(int argc, char* argv[]); -CMDRESULT cbDebugDeleteBPX(int argc, char* argv[]); -CMDRESULT cbDebugEnableBPX(int argc, char* argv[]); -CMDRESULT cbDebugDisableBPX(int argc, char* argv[]); -CMDRESULT cbDebugBplist(int argc, char* argv[]); -CMDRESULT cbDebugStepInto(int argc, char* argv[]); -CMDRESULT cbDebugeStepInto(int argc, char* argv[]); -CMDRESULT cbDebugStepOver(int argc, char* argv[]); -CMDRESULT cbDebugeStepOver(int argc, char* argv[]); -CMDRESULT cbDebugSingleStep(int argc, char* argv[]); -CMDRESULT cbDebugeSingleStep(int argc, char* argv[]); -CMDRESULT cbDebugHide(int argc, char* argv[]); -CMDRESULT cbDebugDisasm(int argc, char* argv[]); -CMDRESULT cbDebugSetMemoryBpx(int argc, char* argv[]); -CMDRESULT cbDebugRtr(int argc, char* argv[]); -CMDRESULT cbDebugeRtr(int argc, char* argv[]); -CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[]); -CMDRESULT cbDebugAlloc(int argc, char* argv[]); -CMDRESULT cbDebugFree(int argc, char* argv[]); -CMDRESULT cbDebugMemset(int argc, char* argv[]); -CMDRESULT cbDebugBenchmark(int argc, char* argv[]); -CMDRESULT cbDebugPause(int argc, char* argv[]); -CMDRESULT cbDebugStartScylla(int argc, char* argv[]); -CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[]); -CMDRESULT cbDebugDeleteMemoryBreakpoint(int argc, char* argv[]); -CMDRESULT cbDebugAttach(int argc, char* argv[]); -CMDRESULT cbDebugDetach(int argc, char* argv[]); -CMDRESULT cbDebugDump(int argc, char* argv[]); -CMDRESULT cbDebugStackDump(int argc, char* argv[]); -CMDRESULT cbDebugContinue(int argc, char* argv[]); -CMDRESULT cbDebugBpDll(int argc, char* argv[]); -CMDRESULT cbDebugBcDll(int argc, char* argv[]); -CMDRESULT cbDebugSwitchthread(int argc, char* argv[]); -CMDRESULT cbDebugResumethread(int argc, char* argv[]); -CMDRESULT cbDebugSetJIT(int argc, char* argv[]); -CMDRESULT cbDebugGetJIT(int argc, char* argv[]); -CMDRESULT cbDebugGetJITAuto(int argc, char* argv[]); -CMDRESULT cbDebugSetJITAuto(int argc, char* argv[]); -CMDRESULT cbDebugSuspendthread(int argc, char* argv[]); -CMDRESULT cbDebugKillthread(int argc, char* argv[]); -CMDRESULT cbDebugSuspendAllThreads(int argc, char* argv[]); -CMDRESULT cbDebugResumeAllThreads(int argc, char* argv[]); -CMDRESULT cbDebugSetPriority(int argc, char* argv[]); -CMDRESULT cbDebugGetCmdline(int argc, char* argv[]); -CMDRESULT cbDebugSetCmdline(int argc, char* argv[]); -CMDRESULT cbDebugLoadLib(int argc, char* argv[]); -CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[]); -CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[]); -CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[]); -CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[]); -CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[]); -CMDRESULT cbDebugGetPageRights(int argc, char* argv[]); -CMDRESULT cbDebugSetPageRights(int argc, char* argv[]); -CMDRESULT cbDebugSkip(int argc, char* argv[]); -CMDRESULT cbDebugSetfreezestack(int argc, char* argv[]); - -//misc -void showcommandlineerror(cmdline_error_t* cmdline_error); - +#ifndef _DEBUGGER_COMMANDS_H +#define _DEBUGGER_COMMANDS_H + +#include "command.h" +#include "debugger.h" + +//command callbacks +CMDRESULT cbDebugInit(int argc, char* argv[]); +CMDRESULT cbDebugStop(int argc, char* argv[]); +CMDRESULT cbDebugRun(int argc, char* argv[]); +CMDRESULT cbDebugErun(int argc, char* argv[]); +CMDRESULT cbDebugSetBPXOptions(int argc, char* argv[]); +CMDRESULT cbDebugSetBPX(int argc, char* argv[]); +CMDRESULT cbDebugDeleteBPX(int argc, char* argv[]); +CMDRESULT cbDebugEnableBPX(int argc, char* argv[]); +CMDRESULT cbDebugDisableBPX(int argc, char* argv[]); +CMDRESULT cbDebugBplist(int argc, char* argv[]); +CMDRESULT cbDebugStepInto(int argc, char* argv[]); +CMDRESULT cbDebugeStepInto(int argc, char* argv[]); +CMDRESULT cbDebugStepOver(int argc, char* argv[]); +CMDRESULT cbDebugeStepOver(int argc, char* argv[]); +CMDRESULT cbDebugSingleStep(int argc, char* argv[]); +CMDRESULT cbDebugeSingleStep(int argc, char* argv[]); +CMDRESULT cbDebugHide(int argc, char* argv[]); +CMDRESULT cbDebugDisasm(int argc, char* argv[]); +CMDRESULT cbDebugSetMemoryBpx(int argc, char* argv[]); +CMDRESULT cbDebugRtr(int argc, char* argv[]); +CMDRESULT cbDebugeRtr(int argc, char* argv[]); +CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[]); +CMDRESULT cbDebugAlloc(int argc, char* argv[]); +CMDRESULT cbDebugFree(int argc, char* argv[]); +CMDRESULT cbDebugMemset(int argc, char* argv[]); +CMDRESULT cbDebugBenchmark(int argc, char* argv[]); +CMDRESULT cbDebugPause(int argc, char* argv[]); +CMDRESULT cbDebugStartScylla(int argc, char* argv[]); +CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[]); +CMDRESULT cbDebugDeleteMemoryBreakpoint(int argc, char* argv[]); +CMDRESULT cbDebugAttach(int argc, char* argv[]); +CMDRESULT cbDebugDetach(int argc, char* argv[]); +CMDRESULT cbDebugDump(int argc, char* argv[]); +CMDRESULT cbDebugStackDump(int argc, char* argv[]); +CMDRESULT cbDebugContinue(int argc, char* argv[]); +CMDRESULT cbDebugBpDll(int argc, char* argv[]); +CMDRESULT cbDebugBcDll(int argc, char* argv[]); +CMDRESULT cbDebugSwitchthread(int argc, char* argv[]); +CMDRESULT cbDebugResumethread(int argc, char* argv[]); +CMDRESULT cbDebugSetJIT(int argc, char* argv[]); +CMDRESULT cbDebugGetJIT(int argc, char* argv[]); +CMDRESULT cbDebugGetJITAuto(int argc, char* argv[]); +CMDRESULT cbDebugSetJITAuto(int argc, char* argv[]); +CMDRESULT cbDebugSuspendthread(int argc, char* argv[]); +CMDRESULT cbDebugKillthread(int argc, char* argv[]); +CMDRESULT cbDebugSuspendAllThreads(int argc, char* argv[]); +CMDRESULT cbDebugResumeAllThreads(int argc, char* argv[]); +CMDRESULT cbDebugSetPriority(int argc, char* argv[]); +CMDRESULT cbDebugGetCmdline(int argc, char* argv[]); +CMDRESULT cbDebugSetCmdline(int argc, char* argv[]); +CMDRESULT cbDebugLoadLib(int argc, char* argv[]); +CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[]); +CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[]); +CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[]); +CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[]); +CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[]); +CMDRESULT cbDebugGetPageRights(int argc, char* argv[]); +CMDRESULT cbDebugSetPageRights(int argc, char* argv[]); +CMDRESULT cbDebugSkip(int argc, char* argv[]); +CMDRESULT cbDebugSetfreezestack(int argc, char* argv[]); + +//misc +void showcommandlineerror(cmdline_error_t* cmdline_error); + #endif //_DEBUGGER_COMMANDS_H \ No newline at end of file diff --git a/src/dbg/disasm_fast.cpp b/src/dbg/disasm_fast.cpp index 90ce4885..d0191777 100644 --- a/src/dbg/disasm_fast.cpp +++ b/src/dbg/disasm_fast.cpp @@ -1,109 +1,109 @@ -/** - @file disasm_fast.cpp - - @brief Implements the disasm fast class. - */ - -#include "disasm_fast.h" -#include "memory.h" - -static MEMORY_SIZE argsize2memsize(int argsize) -{ - switch(argsize) - { - case 8: - return size_byte; - case 16: - return size_word; - case 32: - return size_dword; - case 64: - return size_qword; - } - return size_byte; -} - -void fillbasicinfo(Capstone* cp, BASIC_INSTRUCTION_INFO* basicinfo) -{ - //zero basicinfo - memset(basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO)); - //copy instruction text - strcpy_s(basicinfo->instruction, cp->InstructionText().c_str()); - //instruction size - basicinfo->size = cp->Size(); - //branch/call info - if(cp->InGroup(CS_GRP_CALL)) - { - basicinfo->branch = true; - basicinfo->call = true; - } - else if(cp->InGroup(CS_GRP_JUMP) || cp->IsLoop()) - { - basicinfo->branch = true; - } - //handle operands - for(int i = 0; i < cp->x86().op_count; i++) - { - const cs_x86_op & op = cp->x86().operands[i]; - switch(op.type) - { - case CS_OP_IMM: - { - if(basicinfo->branch) - { - basicinfo->type |= TYPE_ADDR; - basicinfo->addr = (duint)op.imm; - basicinfo->value.value = (duint)op.imm + basicinfo->size; - } - else - { - basicinfo->type |= TYPE_VALUE; - basicinfo->value.size = (VALUE_SIZE)op.size; - basicinfo->value.value = (duint)op.imm; - } - } - break; - - case CS_OP_MEM: - { - const x86_op_mem & mem = op.mem; - strcpy_s(basicinfo->memory.mnemonic, cp->OperandText(i).c_str()); - basicinfo->memory.size = (MEMORY_SIZE)op.size; - if(op.mem.base == X86_REG_RIP) //rip-relative - { - basicinfo->memory.value = (ULONG_PTR)(cp->GetInstr()->address + op.mem.disp + basicinfo->size); - basicinfo->type |= TYPE_MEMORY; - } - else if(mem.disp) - { - basicinfo->type |= TYPE_MEMORY; - basicinfo->memory.value = (ULONG_PTR)mem.disp; - } - } - break; - } - } -} - -bool disasmfast(unsigned char* data, duint addr, BASIC_INSTRUCTION_INFO* basicinfo) -{ - if(!data || !basicinfo) - return false; - Capstone cp; - if(!cp.Disassemble(addr, data, MAX_DISASM_BUFFER)) - { - strcpy_s(basicinfo->instruction, "???"); - basicinfo->size = 1; - return false; - } - fillbasicinfo(&cp, basicinfo); - return true; -} - -bool disasmfast(duint addr, BASIC_INSTRUCTION_INFO* basicinfo) -{ - unsigned int data[16]; - if(!MemRead(addr, data, sizeof(data))) - return false; - return disasmfast((unsigned char*)data, addr, basicinfo); +/** + @file disasm_fast.cpp + + @brief Implements the disasm fast class. + */ + +#include "disasm_fast.h" +#include "memory.h" + +static MEMORY_SIZE argsize2memsize(int argsize) +{ + switch(argsize) + { + case 8: + return size_byte; + case 16: + return size_word; + case 32: + return size_dword; + case 64: + return size_qword; + } + return size_byte; +} + +void fillbasicinfo(Capstone* cp, BASIC_INSTRUCTION_INFO* basicinfo) +{ + //zero basicinfo + memset(basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO)); + //copy instruction text + strcpy_s(basicinfo->instruction, cp->InstructionText().c_str()); + //instruction size + basicinfo->size = cp->Size(); + //branch/call info + if(cp->InGroup(CS_GRP_CALL)) + { + basicinfo->branch = true; + basicinfo->call = true; + } + else if(cp->InGroup(CS_GRP_JUMP) || cp->IsLoop()) + { + basicinfo->branch = true; + } + //handle operands + for(int i = 0; i < cp->x86().op_count; i++) + { + const cs_x86_op & op = cp->x86().operands[i]; + switch(op.type) + { + case CS_OP_IMM: + { + if(basicinfo->branch) + { + basicinfo->type |= TYPE_ADDR; + basicinfo->addr = (duint)op.imm; + basicinfo->value.value = (duint)op.imm + basicinfo->size; + } + else + { + basicinfo->type |= TYPE_VALUE; + basicinfo->value.size = (VALUE_SIZE)op.size; + basicinfo->value.value = (duint)op.imm; + } + } + break; + + case CS_OP_MEM: + { + const x86_op_mem & mem = op.mem; + strcpy_s(basicinfo->memory.mnemonic, cp->OperandText(i).c_str()); + basicinfo->memory.size = (MEMORY_SIZE)op.size; + if(op.mem.base == X86_REG_RIP) //rip-relative + { + basicinfo->memory.value = (ULONG_PTR)(cp->GetInstr()->address + op.mem.disp + basicinfo->size); + basicinfo->type |= TYPE_MEMORY; + } + else if(mem.disp) + { + basicinfo->type |= TYPE_MEMORY; + basicinfo->memory.value = (ULONG_PTR)mem.disp; + } + } + break; + } + } +} + +bool disasmfast(unsigned char* data, duint addr, BASIC_INSTRUCTION_INFO* basicinfo) +{ + if(!data || !basicinfo) + return false; + Capstone cp; + if(!cp.Disassemble(addr, data, MAX_DISASM_BUFFER)) + { + strcpy_s(basicinfo->instruction, "???"); + basicinfo->size = 1; + return false; + } + fillbasicinfo(&cp, basicinfo); + return true; +} + +bool disasmfast(duint addr, BASIC_INSTRUCTION_INFO* basicinfo) +{ + unsigned int data[16]; + if(!MemRead(addr, data, sizeof(data))) + return false; + return disasmfast((unsigned char*)data, addr, basicinfo); } \ No newline at end of file diff --git a/src/dbg/disasm_fast.h b/src/dbg/disasm_fast.h index 9a62d0cd..ef62c319 100644 --- a/src/dbg/disasm_fast.h +++ b/src/dbg/disasm_fast.h @@ -1,11 +1,11 @@ -#ifndef _DISASM_FAST_H -#define _DISASM_FAST_H - -#include "_global.h" -#include - -void fillbasicinfo(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo); -bool disasmfast(duint addr, BASIC_INSTRUCTION_INFO* basicinfo); -bool disasmfast(unsigned char* data, duint addr, BASIC_INSTRUCTION_INFO* basicinfo); - -#endif //_DISASM_FAST_H +#ifndef _DISASM_FAST_H +#define _DISASM_FAST_H + +#include "_global.h" +#include + +void fillbasicinfo(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo); +bool disasmfast(duint addr, BASIC_INSTRUCTION_INFO* basicinfo); +bool disasmfast(unsigned char* data, duint addr, BASIC_INSTRUCTION_INFO* basicinfo); + +#endif //_DISASM_FAST_H diff --git a/src/dbg/disasm_helper.cpp b/src/dbg/disasm_helper.cpp index 71ef0cf9..ac4c0716 100644 --- a/src/dbg/disasm_helper.cpp +++ b/src/dbg/disasm_helper.cpp @@ -1,357 +1,357 @@ -/** - @file disasm_helper.cpp - - @brief Implements the disasm helper class. - */ - -#include "disasm_helper.h" -#include "value.h" -#include "console.h" -#include "memory.h" -#include - -duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n) -{ - int i; - duint abuf[131], addr, back, cmdsize; - unsigned char* pdata; - - // Reset Disasm Structure - Capstone cp; - - // Check if the pointer is not null - if(data == NULL) - return 0; - - // Round the number of back instructions to 127 - if(n < 0) - n = 0; - else if(n > 127) - n = 127; - - // Check if the instruction pointer ip is not outside the memory range - if(ip >= size) - ip = size - 1; - - // Obvious answer - if(n == 0) - return ip; - - if(ip < (duint)n) - return ip; - - back = MAX_DISASM_BUFFER * (n + 3); // Instruction length limited to 16 - - if(ip < back) - back = ip; - - addr = ip - back; - - pdata = data + addr; - - for(i = 0; addr < ip; i++) - { - abuf[i % 128] = addr; - - if(!cp.Disassemble(0, pdata, (int)size)) - cmdsize = 1; - else - cmdsize = cp.Size(); - - pdata += cmdsize; - addr += cmdsize; - back -= cmdsize; - size -= cmdsize; - } - - if(i < n) - return abuf[0]; - else - return abuf[(i - n + 128) % 128]; -} - -duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n) -{ - int i; - duint cmdsize; - unsigned char* pdata; - - // Reset Disasm Structure - Capstone cp; - - if(data == NULL) - return 0; - - if(ip >= size) - ip = size - 1; - - if(n <= 0) - return ip; - - pdata = data + ip; - size -= ip; - - for(i = 0; i < n && size > 0; i++) - { - if(!cp.Disassemble(0, pdata, (int)size)) - cmdsize = 1; - else - cmdsize = cp.Size(); - - pdata += cmdsize; - ip += cmdsize; - size -= cmdsize; - } - - return ip; -} - -const char* disasmtext(duint addr) -{ - unsigned char buffer[MAX_DISASM_BUFFER] = ""; - DbgMemRead(addr, buffer, sizeof(buffer)); - Capstone cp; - static char instruction[64] = ""; - if(!cp.Disassemble(addr, buffer)) - strcpy_s(instruction, "???"); - else - sprintf_s(instruction, "%s %s", cp.GetInstr()->mnemonic, cp.GetInstr()->op_str); - return instruction; -} - -static void HandleCapstoneOperand(Capstone & cp, int opindex, DISASM_ARG* arg) -{ - const cs_x86 & x86 = cp.x86(); - const cs_x86_op & op = x86.operands[opindex]; - arg->segment = SEG_DEFAULT; - strcpy_s(arg->mnemonic, cp.OperandText(opindex).c_str()); - switch(op.type) - { - case X86_OP_REG: - { - const char* regname = cp.RegName((x86_reg)op.reg); - arg->type = arg_normal; - duint value; - if(!valfromstring(regname, &value, true, true)) - value = 0; - arg->constant = arg->value = value; - } - break; - - case X86_OP_IMM: - { - arg->type = arg_normal; - arg->constant = arg->value = (duint)op.imm; - } - break; - - case X86_OP_MEM: - { - arg->type = arg_memory; - const x86_op_mem & mem = op.mem; - if(mem.base == X86_REG_RIP) //rip-relative - arg->constant = cp.Address() + (duint)mem.disp + cp.Size(); - else - arg->constant = (duint)mem.disp; - duint value; - if(!valfromstring(arg->mnemonic, &value, true, true)) - return; - arg->value = value; - if(DbgMemIsValidReadPtr(value)) - { - switch(op.size) - { - case 1: - DbgMemRead(value, (unsigned char*)&arg->memvalue, 1); - break; - case 2: - DbgMemRead(value, (unsigned char*)&arg->memvalue, 2); - break; - case 4: - DbgMemRead(value, (unsigned char*)&arg->memvalue, 4); - break; - case 8: - DbgMemRead(value, (unsigned char*)&arg->memvalue, 8); - break; - } - } - } - break; - } -} - -void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr) -{ - if(!DbgIsDebugging()) - { - if(instr) - instr->argcount = 0; - return; - } - memset(instr, 0, sizeof(DISASM_INSTR)); - Capstone cp; - if(!cp.Disassemble(addr, buffer, MAX_DISASM_BUFFER)) - { - strcpy_s(instr->instruction, "???"); - instr->instr_size = 1; - instr->type = instr_normal; - instr->argcount = 0; - return; - } - const cs_insn* cpInstr = cp.GetInstr(); - sprintf_s(instr->instruction, "%s %s", cpInstr->mnemonic, cpInstr->op_str); - instr->instr_size = cpInstr->size; - if(cp.InGroup(CS_GRP_JUMP) || cp.IsLoop() || cp.InGroup(CS_GRP_RET) || cp.InGroup(CS_GRP_CALL)) - instr->type = instr_branch; - else if(strstr(cpInstr->op_str, "sp") || strstr(cpInstr->op_str, "bp")) - instr->type = instr_stack; - else - instr->type = instr_normal; - instr->argcount = cp.x86().op_count <= 3 ? cp.x86().op_count : 3; - for(int i = 0; i < instr->argcount; i++) - HandleCapstoneOperand(cp, i, &instr->arg[i]); -} - -void disasmget(duint addr, DISASM_INSTR* instr) -{ - if(!DbgIsDebugging()) - { - if(instr) - instr->argcount = 0; - return; - } - unsigned char buffer[MAX_DISASM_BUFFER] = ""; - DbgMemRead(addr, buffer, sizeof(buffer)); - disasmget(buffer, addr, instr); -} - -void disasmprint(duint addr) -{ - DISASM_INSTR instr; - memset(&instr, 0, sizeof(instr)); - disasmget(addr, &instr); - dprintf(">%d:\"%s\":\n", instr.type, instr.instruction); - for(int i = 0; i < instr.argcount; i++) - dprintf(" %d:%d:%" fext "X:%" fext "X:%" fext "X\n", i, instr.arg[i].type, instr.arg[i].constant, instr.arg[i].value, instr.arg[i].memvalue); -} - -static bool isasciistring(const unsigned char* data, int maxlen) -{ - int len = 0; - for(char* p = (char*)data; *p; len++, p++) - { - if(len >= maxlen) - break; - } - - if(len < 2 || len + 1 >= maxlen) - return false; - for(int i = 0; i < len; i++) - if(!isprint(data[i]) && !isspace(data[i])) - return false; - return true; -} - -static bool isunicodestring(const unsigned char* data, int maxlen) -{ - int len = 0; - for(wchar_t* p = (wchar_t*)data; *p; len++, p++) - { - if(len >= maxlen) - break; - } - - if(len < 2 || len + 1 >= maxlen) - return false; - for(int i = 0; i < len * 2; i += 2) - { - if(data[i + 1]) //Extended ASCII only - return false; - if(!isprint(data[i]) && !isspace(data[i])) - return false; - } - return true; -} - -bool disasmispossiblestring(duint addr) -{ - unsigned char data[11]; - memset(data, 0, sizeof(data)); - if(!MemRead(addr, data, sizeof(data) - 3)) - return false; - duint test = 0; - memcpy(&test, data, sizeof(duint)); - if(isasciistring(data, sizeof(data)) || isunicodestring(data, _countof(data))) - return true; - return false; -} - -bool disasmgetstringat(duint addr, STRING_TYPE* type, char* ascii, char* unicode, int maxlen) -{ - if(type) - *type = str_none; - if(!disasmispossiblestring(addr)) - return false; - Memory data((maxlen + 1) * 2, "disasmgetstringat:data"); - if(!MemRead(addr, data(), (maxlen + 1) * 2)) - return false; - - // Save a few pointer casts - auto asciiData = (char*)data(); - auto unicodeData = (wchar_t*)data(); - - // First check if this was an ASCII only string - if(isasciistring(data(), maxlen)) - { - if(type) - *type = str_ascii; - - // Escape the string - String escaped = StringUtils::Escape(asciiData); - - // Copy data back to outgoing parameter - strncpy_s(ascii, min(int(escaped.length()) + 1, maxlen), escaped.c_str(), _TRUNCATE); - return true; - } - - if(isunicodestring(data(), maxlen)) - { - if(type) - *type = str_unicode; - - // Determine string length only once, limited to output buffer size - int unicodeLength = min(int(wcslen(unicodeData)), maxlen); - - // Truncate each wchar_t to char - for(int i = 0; i < unicodeLength; i++) - asciiData[i] = char(unicodeData[i] & 0xFF); - - // Fix the null terminator (data len = maxlen + 1) - asciiData[unicodeLength] = '\0'; - - // Escape the string - String escaped = StringUtils::Escape(asciiData); - - // Copy data back to outgoing parameter - strncpy_s(unicode, min(int(escaped.length()) + 1, maxlen), escaped.c_str(), _TRUNCATE); - return true; - } - - return false; -} - -int disasmgetsize(duint addr, unsigned char* data) -{ - Capstone cp; - if(!cp.Disassemble(addr, data, MAX_DISASM_BUFFER)) - return 1; - return cp.Size(); -} - -int disasmgetsize(duint addr) -{ - char data[MAX_DISASM_BUFFER]; - if(!MemRead(addr, data, sizeof(data))) - return 1; - return disasmgetsize(addr, (unsigned char*)data); +/** + @file disasm_helper.cpp + + @brief Implements the disasm helper class. + */ + +#include "disasm_helper.h" +#include "value.h" +#include "console.h" +#include "memory.h" +#include + +duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n) +{ + int i; + duint abuf[131], addr, back, cmdsize; + unsigned char* pdata; + + // Reset Disasm Structure + Capstone cp; + + // Check if the pointer is not null + if(data == NULL) + return 0; + + // Round the number of back instructions to 127 + if(n < 0) + n = 0; + else if(n > 127) + n = 127; + + // Check if the instruction pointer ip is not outside the memory range + if(ip >= size) + ip = size - 1; + + // Obvious answer + if(n == 0) + return ip; + + if(ip < (duint)n) + return ip; + + back = MAX_DISASM_BUFFER * (n + 3); // Instruction length limited to 16 + + if(ip < back) + back = ip; + + addr = ip - back; + + pdata = data + addr; + + for(i = 0; addr < ip; i++) + { + abuf[i % 128] = addr; + + if(!cp.Disassemble(0, pdata, (int)size)) + cmdsize = 1; + else + cmdsize = cp.Size(); + + pdata += cmdsize; + addr += cmdsize; + back -= cmdsize; + size -= cmdsize; + } + + if(i < n) + return abuf[0]; + else + return abuf[(i - n + 128) % 128]; +} + +duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n) +{ + int i; + duint cmdsize; + unsigned char* pdata; + + // Reset Disasm Structure + Capstone cp; + + if(data == NULL) + return 0; + + if(ip >= size) + ip = size - 1; + + if(n <= 0) + return ip; + + pdata = data + ip; + size -= ip; + + for(i = 0; i < n && size > 0; i++) + { + if(!cp.Disassemble(0, pdata, (int)size)) + cmdsize = 1; + else + cmdsize = cp.Size(); + + pdata += cmdsize; + ip += cmdsize; + size -= cmdsize; + } + + return ip; +} + +const char* disasmtext(duint addr) +{ + unsigned char buffer[MAX_DISASM_BUFFER] = ""; + DbgMemRead(addr, buffer, sizeof(buffer)); + Capstone cp; + static char instruction[64] = ""; + if(!cp.Disassemble(addr, buffer)) + strcpy_s(instruction, "???"); + else + sprintf_s(instruction, "%s %s", cp.GetInstr()->mnemonic, cp.GetInstr()->op_str); + return instruction; +} + +static void HandleCapstoneOperand(Capstone & cp, int opindex, DISASM_ARG* arg) +{ + const cs_x86 & x86 = cp.x86(); + const cs_x86_op & op = x86.operands[opindex]; + arg->segment = SEG_DEFAULT; + strcpy_s(arg->mnemonic, cp.OperandText(opindex).c_str()); + switch(op.type) + { + case X86_OP_REG: + { + const char* regname = cp.RegName((x86_reg)op.reg); + arg->type = arg_normal; + duint value; + if(!valfromstring(regname, &value, true, true)) + value = 0; + arg->constant = arg->value = value; + } + break; + + case X86_OP_IMM: + { + arg->type = arg_normal; + arg->constant = arg->value = (duint)op.imm; + } + break; + + case X86_OP_MEM: + { + arg->type = arg_memory; + const x86_op_mem & mem = op.mem; + if(mem.base == X86_REG_RIP) //rip-relative + arg->constant = cp.Address() + (duint)mem.disp + cp.Size(); + else + arg->constant = (duint)mem.disp; + duint value; + if(!valfromstring(arg->mnemonic, &value, true, true)) + return; + arg->value = value; + if(DbgMemIsValidReadPtr(value)) + { + switch(op.size) + { + case 1: + DbgMemRead(value, (unsigned char*)&arg->memvalue, 1); + break; + case 2: + DbgMemRead(value, (unsigned char*)&arg->memvalue, 2); + break; + case 4: + DbgMemRead(value, (unsigned char*)&arg->memvalue, 4); + break; + case 8: + DbgMemRead(value, (unsigned char*)&arg->memvalue, 8); + break; + } + } + } + break; + } +} + +void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr) +{ + if(!DbgIsDebugging()) + { + if(instr) + instr->argcount = 0; + return; + } + memset(instr, 0, sizeof(DISASM_INSTR)); + Capstone cp; + if(!cp.Disassemble(addr, buffer, MAX_DISASM_BUFFER)) + { + strcpy_s(instr->instruction, "???"); + instr->instr_size = 1; + instr->type = instr_normal; + instr->argcount = 0; + return; + } + const cs_insn* cpInstr = cp.GetInstr(); + sprintf_s(instr->instruction, "%s %s", cpInstr->mnemonic, cpInstr->op_str); + instr->instr_size = cpInstr->size; + if(cp.InGroup(CS_GRP_JUMP) || cp.IsLoop() || cp.InGroup(CS_GRP_RET) || cp.InGroup(CS_GRP_CALL)) + instr->type = instr_branch; + else if(strstr(cpInstr->op_str, "sp") || strstr(cpInstr->op_str, "bp")) + instr->type = instr_stack; + else + instr->type = instr_normal; + instr->argcount = cp.x86().op_count <= 3 ? cp.x86().op_count : 3; + for(int i = 0; i < instr->argcount; i++) + HandleCapstoneOperand(cp, i, &instr->arg[i]); +} + +void disasmget(duint addr, DISASM_INSTR* instr) +{ + if(!DbgIsDebugging()) + { + if(instr) + instr->argcount = 0; + return; + } + unsigned char buffer[MAX_DISASM_BUFFER] = ""; + DbgMemRead(addr, buffer, sizeof(buffer)); + disasmget(buffer, addr, instr); +} + +void disasmprint(duint addr) +{ + DISASM_INSTR instr; + memset(&instr, 0, sizeof(instr)); + disasmget(addr, &instr); + dprintf(">%d:\"%s\":\n", instr.type, instr.instruction); + for(int i = 0; i < instr.argcount; i++) + dprintf(" %d:%d:%" fext "X:%" fext "X:%" fext "X\n", i, instr.arg[i].type, instr.arg[i].constant, instr.arg[i].value, instr.arg[i].memvalue); +} + +static bool isasciistring(const unsigned char* data, int maxlen) +{ + int len = 0; + for(char* p = (char*)data; *p; len++, p++) + { + if(len >= maxlen) + break; + } + + if(len < 2 || len + 1 >= maxlen) + return false; + for(int i = 0; i < len; i++) + if(!isprint(data[i]) && !isspace(data[i])) + return false; + return true; +} + +static bool isunicodestring(const unsigned char* data, int maxlen) +{ + int len = 0; + for(wchar_t* p = (wchar_t*)data; *p; len++, p++) + { + if(len >= maxlen) + break; + } + + if(len < 2 || len + 1 >= maxlen) + return false; + for(int i = 0; i < len * 2; i += 2) + { + if(data[i + 1]) //Extended ASCII only + return false; + if(!isprint(data[i]) && !isspace(data[i])) + return false; + } + return true; +} + +bool disasmispossiblestring(duint addr) +{ + unsigned char data[11]; + memset(data, 0, sizeof(data)); + if(!MemRead(addr, data, sizeof(data) - 3)) + return false; + duint test = 0; + memcpy(&test, data, sizeof(duint)); + if(isasciistring(data, sizeof(data)) || isunicodestring(data, _countof(data))) + return true; + return false; +} + +bool disasmgetstringat(duint addr, STRING_TYPE* type, char* ascii, char* unicode, int maxlen) +{ + if(type) + *type = str_none; + if(!disasmispossiblestring(addr)) + return false; + Memory data((maxlen + 1) * 2, "disasmgetstringat:data"); + if(!MemRead(addr, data(), (maxlen + 1) * 2)) + return false; + + // Save a few pointer casts + auto asciiData = (char*)data(); + auto unicodeData = (wchar_t*)data(); + + // First check if this was an ASCII only string + if(isasciistring(data(), maxlen)) + { + if(type) + *type = str_ascii; + + // Escape the string + String escaped = StringUtils::Escape(asciiData); + + // Copy data back to outgoing parameter + strncpy_s(ascii, min(int(escaped.length()) + 1, maxlen), escaped.c_str(), _TRUNCATE); + return true; + } + + if(isunicodestring(data(), maxlen)) + { + if(type) + *type = str_unicode; + + // Determine string length only once, limited to output buffer size + int unicodeLength = min(int(wcslen(unicodeData)), maxlen); + + // Truncate each wchar_t to char + for(int i = 0; i < unicodeLength; i++) + asciiData[i] = char(unicodeData[i] & 0xFF); + + // Fix the null terminator (data len = maxlen + 1) + asciiData[unicodeLength] = '\0'; + + // Escape the string + String escaped = StringUtils::Escape(asciiData); + + // Copy data back to outgoing parameter + strncpy_s(unicode, min(int(escaped.length()) + 1, maxlen), escaped.c_str(), _TRUNCATE); + return true; + } + + return false; +} + +int disasmgetsize(duint addr, unsigned char* data) +{ + Capstone cp; + if(!cp.Disassemble(addr, data, MAX_DISASM_BUFFER)) + return 1; + return cp.Size(); +} + +int disasmgetsize(duint addr) +{ + char data[MAX_DISASM_BUFFER]; + if(!MemRead(addr, data, sizeof(data))) + return 1; + return disasmgetsize(addr, (unsigned char*)data); } \ No newline at end of file diff --git a/src/dbg/disasm_helper.h b/src/dbg/disasm_helper.h index f60cb6bc..c206af5b 100644 --- a/src/dbg/disasm_helper.h +++ b/src/dbg/disasm_helper.h @@ -1,18 +1,18 @@ -#ifndef _DISASM_HELPER_H -#define _DISASM_HELPER_H - -#include "_global.h" - -//functions -duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n); -duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n); -const char* disasmtext(duint addr); -void disasmprint(duint addr); -void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr); -void disasmget(duint addr, DISASM_INSTR* instr); -bool disasmispossiblestring(duint addr); -bool disasmgetstringat(duint addr, STRING_TYPE* type, char* ascii, char* unicode, int maxlen); -int disasmgetsize(duint addr, unsigned char* data); -int disasmgetsize(duint addr); - -#endif // _DISASM_HELPER_H +#ifndef _DISASM_HELPER_H +#define _DISASM_HELPER_H + +#include "_global.h" + +//functions +duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n); +duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n); +const char* disasmtext(duint addr); +void disasmprint(duint addr); +void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr); +void disasmget(duint addr, DISASM_INSTR* instr); +bool disasmispossiblestring(duint addr); +bool disasmgetstringat(duint addr, STRING_TYPE* type, char* ascii, char* unicode, int maxlen); +int disasmgetsize(duint addr, unsigned char* data); +int disasmgetsize(duint addr); + +#endif // _DISASM_HELPER_H diff --git a/src/dbg/dynamicmem.h b/src/dbg/dynamicmem.h index 3c428285..a9fdc800 100644 --- a/src/dbg/dynamicmem.h +++ b/src/dbg/dynamicmem.h @@ -1,56 +1,56 @@ -#pragma once - -template -class Memory -{ -public: - // - // This class guarantees that the returned allocated memory - // will always be zeroed - // - explicit Memory(const char* Reason = "Memory:???") - { - m_Ptr = nullptr; - m_Size = 0; - m_Reason = Reason; - } - - explicit Memory(size_t Size, const char* Reason = "Memory:???") - { - m_Ptr = reinterpret_cast(emalloc(Size)); - m_Size = Size; - m_Reason = Reason; - - memset(m_Ptr, 0, Size); - } - - ~Memory() - { - if(m_Ptr) - efree(m_Ptr); - } - - T realloc(size_t Size, const char* Reason = "Memory:???") - { - m_Ptr = reinterpret_cast(erealloc(m_Ptr, Size)); - m_Size = Size; - m_Reason = Reason; - - return (T)memset(m_Ptr, 0, m_Size); - } - - size_t size() - { - return m_Size; - } - - T operator()() - { - return m_Ptr; - } - -private: - T m_Ptr; - size_t m_Size; - const char* m_Reason; +#pragma once + +template +class Memory +{ +public: + // + // This class guarantees that the returned allocated memory + // will always be zeroed + // + explicit Memory(const char* Reason = "Memory:???") + { + m_Ptr = nullptr; + m_Size = 0; + m_Reason = Reason; + } + + explicit Memory(size_t Size, const char* Reason = "Memory:???") + { + m_Ptr = reinterpret_cast(emalloc(Size)); + m_Size = Size; + m_Reason = Reason; + + memset(m_Ptr, 0, Size); + } + + ~Memory() + { + if(m_Ptr) + efree(m_Ptr); + } + + T realloc(size_t Size, const char* Reason = "Memory:???") + { + m_Ptr = reinterpret_cast(erealloc(m_Ptr, Size)); + m_Size = Size; + m_Reason = Reason; + + return (T)memset(m_Ptr, 0, m_Size); + } + + size_t size() + { + return m_Size; + } + + T operator()() + { + return m_Ptr; + } + +private: + T m_Ptr; + size_t m_Size; + const char* m_Reason; }; \ No newline at end of file diff --git a/src/dbg/dynamicptr.h b/src/dbg/dynamicptr.h index bc086a4e..2013f218 100644 --- a/src/dbg/dynamicptr.h +++ b/src/dbg/dynamicptr.h @@ -1,149 +1,149 @@ -#pragma once - -#include "memory.h" - -template -class RemotePtr; - -template -RemotePtr RemoteMemberPtr(duint Address, U T::*Member) -{ - // Calculate the offset from the member to the class base - duint offset = ((char*) & ((T*)nullptr->*Member) - (char*)nullptr); - - return RemotePtr(Address + offset); -} - -template -class RemotePtr -{ - // Special template part of this class, everything here - // should not be touched - template - using enableIf = typename std::enable_if::type; - - template - using makePtrRemote = RemotePtr; - - template - struct isClass : std::integral_constant < bool, std::is_class>::value || - std::is_class>::value > {}; - - template - struct isPtrClass : std::integral_constant < bool, !std::is_arithmetic::value && - isClass::value > {}; - -public: - explicit RemotePtr(duint Address) - { - Init(Address); - } - - explicit RemotePtr(PVOID Address) - { - Init((duint)Address); - } - - ~RemotePtr() - { - if(!ReadOnly && m_Modified) - Sync(); - } - - T get() - { - // Read the external program data; no user edits - Update(); - return m_InternalData; - } - - template::type> - enableIf::value, makePtrRemote> next(A B::*Member) - { - // First the pointer is read - auto ptr = RemotePtr(m_InternalAddr + memberOffset(Member)); - - // Now return the real data structure - return makePtrRemote(ptr.get()); - } - - template - enableIf::value, makePtrRemote> next(A B::*Member) - { - // Return direct value with adjusted offset - return makePtrRemote(m_InternalAddr + memberOffset(Member)); - } - - template - enableIf::value, duint> memberOffset(A B::*Member) - { - return (char*) & ((typename std::remove_pointer::type*)nullptr->*Member) - (char*)nullptr; - } - - T* operator->() - { - // The user could modify our internal structure after - // return - m_Modified = true; - - // Read the external program data; return a pointer - Update(); - return &m_InternalData; - } - - T operator=(const T & rhs) - { - // This operation is only allowed with ReadOnly==false - if(!ReadOnly) - { - // Otherwise sync it with the external program. - // The external program can be messing with data at the same time. - m_InternalData = rhs; - Sync(); - - // Re-read data and then send it to the user - return get(); - } - - if(BreakOnFail) - __debugbreak(); - - return rhs; - } - - T operator()() - { - return get(); - } - -private: - inline void Update() - { - MemRead(m_InternalAddr, &m_InternalData, sizeof(T)); - } - - inline void Sync() - { - if(BreakOnFail) - { - if(ReadOnly) - __debugbreak(); - - if(!MemWrite(m_InternalAddr, &m_InternalData, sizeof(T))) - __debugbreak(); - } - - m_Modified = false; - } - - inline void Init(duint Address) - { - m_Modified = false; - m_InternalAddr = Address; - memset(&m_InternalData, 0, sizeof(T)); - } - - bool m_Modified; - duint m_InternalAddr; - T m_InternalData; +#pragma once + +#include "memory.h" + +template +class RemotePtr; + +template +RemotePtr RemoteMemberPtr(duint Address, U T::*Member) +{ + // Calculate the offset from the member to the class base + duint offset = ((char*) & ((T*)nullptr->*Member) - (char*)nullptr); + + return RemotePtr(Address + offset); +} + +template +class RemotePtr +{ + // Special template part of this class, everything here + // should not be touched + template + using enableIf = typename std::enable_if::type; + + template + using makePtrRemote = RemotePtr; + + template + struct isClass : std::integral_constant < bool, std::is_class>::value || + std::is_class>::value > {}; + + template + struct isPtrClass : std::integral_constant < bool, !std::is_arithmetic::value && + isClass::value > {}; + +public: + explicit RemotePtr(duint Address) + { + Init(Address); + } + + explicit RemotePtr(PVOID Address) + { + Init((duint)Address); + } + + ~RemotePtr() + { + if(!ReadOnly && m_Modified) + Sync(); + } + + T get() + { + // Read the external program data; no user edits + Update(); + return m_InternalData; + } + + template::type> + enableIf::value, makePtrRemote> next(A B::*Member) + { + // First the pointer is read + auto ptr = RemotePtr(m_InternalAddr + memberOffset(Member)); + + // Now return the real data structure + return makePtrRemote(ptr.get()); + } + + template + enableIf::value, makePtrRemote> next(A B::*Member) + { + // Return direct value with adjusted offset + return makePtrRemote(m_InternalAddr + memberOffset(Member)); + } + + template + enableIf::value, duint> memberOffset(A B::*Member) + { + return (char*) & ((typename std::remove_pointer::type*)nullptr->*Member) - (char*)nullptr; + } + + T* operator->() + { + // The user could modify our internal structure after + // return + m_Modified = true; + + // Read the external program data; return a pointer + Update(); + return &m_InternalData; + } + + T operator=(const T & rhs) + { + // This operation is only allowed with ReadOnly==false + if(!ReadOnly) + { + // Otherwise sync it with the external program. + // The external program can be messing with data at the same time. + m_InternalData = rhs; + Sync(); + + // Re-read data and then send it to the user + return get(); + } + + if(BreakOnFail) + __debugbreak(); + + return rhs; + } + + T operator()() + { + return get(); + } + +private: + inline void Update() + { + MemRead(m_InternalAddr, &m_InternalData, sizeof(T)); + } + + inline void Sync() + { + if(BreakOnFail) + { + if(ReadOnly) + __debugbreak(); + + if(!MemWrite(m_InternalAddr, &m_InternalData, sizeof(T))) + __debugbreak(); + } + + m_Modified = false; + } + + inline void Init(duint Address) + { + m_Modified = false; + m_InternalAddr = Address; + memset(&m_InternalData, 0, sizeof(T)); + } + + bool m_Modified; + duint m_InternalAddr; + T m_InternalData; }; \ No newline at end of file diff --git a/src/dbg/error.cpp b/src/dbg/error.cpp index b64c9605..1a83c3f2 100644 --- a/src/dbg/error.cpp +++ b/src/dbg/error.cpp @@ -1,2204 +1,2204 @@ -#include -#include "error.h" - -std::unordered_map ErrorNames; - -void ErrorCodeInit() -{ - ErrorNames.clear(); - ErrorNames.insert(std::make_pair(0, "ERROR_SUCCESS")); - ErrorNames.insert(std::make_pair(1, "ERROR_INVALID_FUNCTION")); - ErrorNames.insert(std::make_pair(2, "ERROR_FILE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(3, "ERROR_PATH_NOT_FOUND")); - ErrorNames.insert(std::make_pair(4, "ERROR_TOO_MANY_OPEN_FILES")); - ErrorNames.insert(std::make_pair(5, "ERROR_ACCESS_DENIED")); - ErrorNames.insert(std::make_pair(6, "ERROR_INVALID_HANDLE")); - ErrorNames.insert(std::make_pair(7, "ERROR_ARENA_TRASHED")); - ErrorNames.insert(std::make_pair(8, "ERROR_NOT_ENOUGH_MEMORY")); - ErrorNames.insert(std::make_pair(9, "ERROR_INVALID_BLOCK")); - ErrorNames.insert(std::make_pair(10, "ERROR_BAD_ENVIRONMENT")); - ErrorNames.insert(std::make_pair(11, "ERROR_BAD_FORMAT")); - ErrorNames.insert(std::make_pair(12, "ERROR_INVALID_ACCESS")); - ErrorNames.insert(std::make_pair(13, "ERROR_INVALID_DATA")); - ErrorNames.insert(std::make_pair(14, "ERROR_OUTOFMEMORY")); - ErrorNames.insert(std::make_pair(15, "ERROR_INVALID_DRIVE")); - ErrorNames.insert(std::make_pair(16, "ERROR_CURRENT_DIRECTORY")); - ErrorNames.insert(std::make_pair(17, "ERROR_NOT_SAME_DEVICE")); - ErrorNames.insert(std::make_pair(18, "ERROR_NO_MORE_FILES")); - ErrorNames.insert(std::make_pair(19, "ERROR_WRITE_PROTECT")); - ErrorNames.insert(std::make_pair(20, "ERROR_BAD_UNIT")); - ErrorNames.insert(std::make_pair(21, "ERROR_NOT_READY")); - ErrorNames.insert(std::make_pair(22, "ERROR_BAD_COMMAND")); - ErrorNames.insert(std::make_pair(23, "ERROR_CRC")); - ErrorNames.insert(std::make_pair(24, "ERROR_BAD_LENGTH")); - ErrorNames.insert(std::make_pair(25, "ERROR_SEEK")); - ErrorNames.insert(std::make_pair(26, "ERROR_NOT_DOS_DISK")); - ErrorNames.insert(std::make_pair(27, "ERROR_SECTOR_NOT_FOUND")); - ErrorNames.insert(std::make_pair(28, "ERROR_OUT_OF_PAPER")); - ErrorNames.insert(std::make_pair(29, "ERROR_WRITE_FAULT")); - ErrorNames.insert(std::make_pair(30, "ERROR_READ_FAULT")); - ErrorNames.insert(std::make_pair(31, "ERROR_GEN_FAILURE")); - ErrorNames.insert(std::make_pair(32, "ERROR_SHARING_VIOLATION")); - ErrorNames.insert(std::make_pair(33, "ERROR_LOCK_VIOLATION")); - ErrorNames.insert(std::make_pair(34, "ERROR_WRONG_DISK")); - ErrorNames.insert(std::make_pair(36, "ERROR_SHARING_BUFFER_EXCEEDED")); - ErrorNames.insert(std::make_pair(38, "ERROR_HANDLE_EOF")); - ErrorNames.insert(std::make_pair(39, "ERROR_HANDLE_DISK_FULL")); - ErrorNames.insert(std::make_pair(50, "ERROR_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(51, "ERROR_REM_NOT_LIST")); - ErrorNames.insert(std::make_pair(52, "ERROR_DUP_NAME")); - ErrorNames.insert(std::make_pair(53, "ERROR_BAD_NETPATH")); - ErrorNames.insert(std::make_pair(54, "ERROR_NETWORK_BUSY")); - ErrorNames.insert(std::make_pair(55, "ERROR_DEV_NOT_EXIST")); - ErrorNames.insert(std::make_pair(56, "ERROR_TOO_MANY_CMDS")); - ErrorNames.insert(std::make_pair(57, "ERROR_ADAP_HDW_ERR")); - ErrorNames.insert(std::make_pair(58, "ERROR_BAD_NET_RESP")); - ErrorNames.insert(std::make_pair(59, "ERROR_UNEXP_NET_ERR")); - ErrorNames.insert(std::make_pair(60, "ERROR_BAD_REM_ADAP")); - ErrorNames.insert(std::make_pair(61, "ERROR_PRINTQ_FULL")); - ErrorNames.insert(std::make_pair(62, "ERROR_NO_SPOOL_SPACE")); - ErrorNames.insert(std::make_pair(63, "ERROR_PRINT_CANCELLED")); - ErrorNames.insert(std::make_pair(64, "ERROR_NETNAME_DELETED")); - ErrorNames.insert(std::make_pair(65, "ERROR_NETWORK_ACCESS_DENIED")); - ErrorNames.insert(std::make_pair(66, "ERROR_BAD_DEV_TYPE")); - ErrorNames.insert(std::make_pair(67, "ERROR_BAD_NET_NAME")); - ErrorNames.insert(std::make_pair(68, "ERROR_TOO_MANY_NAMES")); - ErrorNames.insert(std::make_pair(69, "ERROR_TOO_MANY_SESS")); - ErrorNames.insert(std::make_pair(70, "ERROR_SHARING_PAUSED")); - ErrorNames.insert(std::make_pair(71, "ERROR_REQ_NOT_ACCEP")); - ErrorNames.insert(std::make_pair(72, "ERROR_REDIR_PAUSED")); - ErrorNames.insert(std::make_pair(80, "ERROR_FILE_EXISTS")); - ErrorNames.insert(std::make_pair(82, "ERROR_CANNOT_MAKE")); - ErrorNames.insert(std::make_pair(83, "ERROR_FAIL_I24")); - ErrorNames.insert(std::make_pair(84, "ERROR_OUT_OF_STRUCTURES")); - ErrorNames.insert(std::make_pair(85, "ERROR_ALREADY_ASSIGNED")); - ErrorNames.insert(std::make_pair(86, "ERROR_INVALID_PASSWORD")); - ErrorNames.insert(std::make_pair(87, "ERROR_INVALID_PARAMETER")); - ErrorNames.insert(std::make_pair(88, "ERROR_NET_WRITE_FAULT")); - ErrorNames.insert(std::make_pair(89, "ERROR_NO_PROC_SLOTS")); - ErrorNames.insert(std::make_pair(100, "ERROR_TOO_MANY_SEMAPHORES")); - ErrorNames.insert(std::make_pair(101, "ERROR_EXCL_SEM_ALREADY_OWNED")); - ErrorNames.insert(std::make_pair(102, "ERROR_SEM_IS_SET")); - ErrorNames.insert(std::make_pair(103, "ERROR_TOO_MANY_SEM_REQUESTS")); - ErrorNames.insert(std::make_pair(104, "ERROR_INVALID_AT_INTERRUPT_TIME")); - ErrorNames.insert(std::make_pair(105, "ERROR_SEM_OWNER_DIED")); - ErrorNames.insert(std::make_pair(106, "ERROR_SEM_USER_LIMIT")); - ErrorNames.insert(std::make_pair(107, "ERROR_DISK_CHANGE")); - ErrorNames.insert(std::make_pair(108, "ERROR_DRIVE_LOCKED")); - ErrorNames.insert(std::make_pair(109, "ERROR_BROKEN_PIPE")); - ErrorNames.insert(std::make_pair(110, "ERROR_OPEN_FAILED")); - ErrorNames.insert(std::make_pair(111, "ERROR_BUFFER_OVERFLOW")); - ErrorNames.insert(std::make_pair(112, "ERROR_DISK_FULL")); - ErrorNames.insert(std::make_pair(113, "ERROR_NO_MORE_SEARCH_HANDLES")); - ErrorNames.insert(std::make_pair(114, "ERROR_INVALID_TARGET_HANDLE")); - ErrorNames.insert(std::make_pair(117, "ERROR_INVALID_CATEGORY")); - ErrorNames.insert(std::make_pair(118, "ERROR_INVALID_VERIFY_SWITCH")); - ErrorNames.insert(std::make_pair(119, "ERROR_BAD_DRIVER_LEVEL")); - ErrorNames.insert(std::make_pair(120, "ERROR_CALL_NOT_IMPLEMENTED")); - ErrorNames.insert(std::make_pair(121, "ERROR_SEM_TIMEOUT")); - ErrorNames.insert(std::make_pair(122, "ERROR_INSUFFICIENT_BUFFER")); - ErrorNames.insert(std::make_pair(123, "ERROR_INVALID_NAME")); - ErrorNames.insert(std::make_pair(124, "ERROR_INVALID_LEVEL")); - ErrorNames.insert(std::make_pair(125, "ERROR_NO_VOLUME_LABEL")); - ErrorNames.insert(std::make_pair(126, "ERROR_MOD_NOT_FOUND")); - ErrorNames.insert(std::make_pair(127, "ERROR_PROC_NOT_FOUND")); - ErrorNames.insert(std::make_pair(128, "ERROR_WAIT_NO_CHILDREN")); - ErrorNames.insert(std::make_pair(129, "ERROR_CHILD_NOT_COMPLETE")); - ErrorNames.insert(std::make_pair(130, "ERROR_DIRECT_ACCESS_HANDLE")); - ErrorNames.insert(std::make_pair(131, "ERROR_NEGATIVE_SEEK")); - ErrorNames.insert(std::make_pair(132, "ERROR_SEEK_ON_DEVICE")); - ErrorNames.insert(std::make_pair(133, "ERROR_IS_JOIN_TARGET")); - ErrorNames.insert(std::make_pair(134, "ERROR_IS_JOINED")); - ErrorNames.insert(std::make_pair(135, "ERROR_IS_SUBSTED")); - ErrorNames.insert(std::make_pair(136, "ERROR_NOT_JOINED")); - ErrorNames.insert(std::make_pair(137, "ERROR_NOT_SUBSTED")); - ErrorNames.insert(std::make_pair(138, "ERROR_JOIN_TO_JOIN")); - ErrorNames.insert(std::make_pair(139, "ERROR_SUBST_TO_SUBST")); - ErrorNames.insert(std::make_pair(140, "ERROR_JOIN_TO_SUBST")); - ErrorNames.insert(std::make_pair(141, "ERROR_SUBST_TO_JOIN")); - ErrorNames.insert(std::make_pair(142, "ERROR_BUSY_DRIVE")); - ErrorNames.insert(std::make_pair(143, "ERROR_SAME_DRIVE")); - ErrorNames.insert(std::make_pair(144, "ERROR_DIR_NOT_ROOT")); - ErrorNames.insert(std::make_pair(145, "ERROR_DIR_NOT_EMPTY")); - ErrorNames.insert(std::make_pair(146, "ERROR_IS_SUBST_PATH")); - ErrorNames.insert(std::make_pair(147, "ERROR_IS_JOIN_PATH")); - ErrorNames.insert(std::make_pair(148, "ERROR_PATH_BUSY")); - ErrorNames.insert(std::make_pair(149, "ERROR_IS_SUBST_TARGET")); - ErrorNames.insert(std::make_pair(150, "ERROR_SYSTEM_TRACE")); - ErrorNames.insert(std::make_pair(151, "ERROR_INVALID_EVENT_COUNT")); - ErrorNames.insert(std::make_pair(152, "ERROR_TOO_MANY_MUXWAITERS")); - ErrorNames.insert(std::make_pair(153, "ERROR_INVALID_LIST_FORMAT")); - ErrorNames.insert(std::make_pair(154, "ERROR_LABEL_TOO_LONG")); - ErrorNames.insert(std::make_pair(155, "ERROR_TOO_MANY_TCBS")); - ErrorNames.insert(std::make_pair(156, "ERROR_SIGNAL_REFUSED")); - ErrorNames.insert(std::make_pair(157, "ERROR_DISCARDED")); - ErrorNames.insert(std::make_pair(158, "ERROR_NOT_LOCKED")); - ErrorNames.insert(std::make_pair(159, "ERROR_BAD_THREADID_ADDR")); - ErrorNames.insert(std::make_pair(160, "ERROR_BAD_ARGUMENTS")); - ErrorNames.insert(std::make_pair(161, "ERROR_BAD_PATHNAME")); - ErrorNames.insert(std::make_pair(162, "ERROR_SIGNAL_PENDING")); - ErrorNames.insert(std::make_pair(164, "ERROR_MAX_THRDS_REACHED")); - ErrorNames.insert(std::make_pair(167, "ERROR_LOCK_FAILED")); - ErrorNames.insert(std::make_pair(170, "ERROR_BUSY")); - ErrorNames.insert(std::make_pair(173, "ERROR_CANCEL_VIOLATION")); - ErrorNames.insert(std::make_pair(174, "ERROR_ATOMIC_LOCKS_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(180, "ERROR_INVALID_SEGMENT_NUMBER")); - ErrorNames.insert(std::make_pair(182, "ERROR_INVALID_ORDINAL")); - ErrorNames.insert(std::make_pair(183, "ERROR_ALREADY_EXISTS")); - ErrorNames.insert(std::make_pair(186, "ERROR_INVALID_FLAG_NUMBER")); - ErrorNames.insert(std::make_pair(187, "ERROR_SEM_NOT_FOUND")); - ErrorNames.insert(std::make_pair(188, "ERROR_INVALID_STARTING_CODESEG")); - ErrorNames.insert(std::make_pair(189, "ERROR_INVALID_STACKSEG")); - ErrorNames.insert(std::make_pair(190, "ERROR_INVALID_MODULETYPE")); - ErrorNames.insert(std::make_pair(191, "ERROR_INVALID_EXE_SIGNATURE")); - ErrorNames.insert(std::make_pair(192, "ERROR_EXE_MARKED_INVALID")); - ErrorNames.insert(std::make_pair(193, "ERROR_BAD_EXE_FORMAT")); - ErrorNames.insert(std::make_pair(194, "ERROR_ITERATED_DATA_EXCEEDS_64k")); - ErrorNames.insert(std::make_pair(195, "ERROR_INVALID_MINALLOCSIZE")); - ErrorNames.insert(std::make_pair(196, "ERROR_DYNLINK_FROM_INVALID_RING")); - ErrorNames.insert(std::make_pair(197, "ERROR_IOPL_NOT_ENABLED")); - ErrorNames.insert(std::make_pair(198, "ERROR_INVALID_SEGDPL")); - ErrorNames.insert(std::make_pair(199, "ERROR_AUTODATASEG_EXCEEDS_64k")); - ErrorNames.insert(std::make_pair(200, "ERROR_RING2SEG_MUST_BE_MOVABLE")); - ErrorNames.insert(std::make_pair(201, "ERROR_RELOC_CHAIN_XEEDS_SEGLIM")); - ErrorNames.insert(std::make_pair(202, "ERROR_INFLOOP_IN_RELOC_CHAIN")); - ErrorNames.insert(std::make_pair(203, "ERROR_ENVVAR_NOT_FOUND")); - ErrorNames.insert(std::make_pair(205, "ERROR_NO_SIGNAL_SENT")); - ErrorNames.insert(std::make_pair(206, "ERROR_FILENAME_EXCED_RANGE")); - ErrorNames.insert(std::make_pair(207, "ERROR_RING2_STACK_IN_USE")); - ErrorNames.insert(std::make_pair(208, "ERROR_META_EXPANSION_TOO_LONG")); - ErrorNames.insert(std::make_pair(209, "ERROR_INVALID_SIGNAL_NUMBER")); - ErrorNames.insert(std::make_pair(210, "ERROR_THREAD_1_INACTIVE")); - ErrorNames.insert(std::make_pair(212, "ERROR_LOCKED")); - ErrorNames.insert(std::make_pair(214, "ERROR_TOO_MANY_MODULES")); - ErrorNames.insert(std::make_pair(215, "ERROR_NESTING_NOT_ALLOWED")); - ErrorNames.insert(std::make_pair(216, "ERROR_EXE_MACHINE_TYPE_MISMATCH")); - ErrorNames.insert(std::make_pair(217, "ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY")); - ErrorNames.insert(std::make_pair(218, "ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY")); - ErrorNames.insert(std::make_pair(220, "ERROR_FILE_CHECKED_OUT")); - ErrorNames.insert(std::make_pair(221, "ERROR_CHECKOUT_REQUIRED")); - ErrorNames.insert(std::make_pair(222, "ERROR_BAD_FILE_TYPE")); - ErrorNames.insert(std::make_pair(223, "ERROR_FILE_TOO_LARGE")); - ErrorNames.insert(std::make_pair(224, "ERROR_FORMS_AUTH_REQUIRED")); - ErrorNames.insert(std::make_pair(225, "ERROR_VIRUS_INFECTED")); - ErrorNames.insert(std::make_pair(226, "ERROR_VIRUS_DELETED")); - ErrorNames.insert(std::make_pair(229, "ERROR_PIPE_LOCAL")); - ErrorNames.insert(std::make_pair(230, "ERROR_BAD_PIPE")); - ErrorNames.insert(std::make_pair(231, "ERROR_PIPE_BUSY")); - ErrorNames.insert(std::make_pair(232, "ERROR_NO_DATA")); - ErrorNames.insert(std::make_pair(233, "ERROR_PIPE_NOT_CONNECTED")); - ErrorNames.insert(std::make_pair(234, "ERROR_MORE_DATA")); - ErrorNames.insert(std::make_pair(240, "ERROR_VC_DISCONNECTED")); - ErrorNames.insert(std::make_pair(254, "ERROR_INVALID_EA_NAME")); - ErrorNames.insert(std::make_pair(255, "ERROR_EA_LIST_INCONSISTENT")); - ErrorNames.insert(std::make_pair(259, "ERROR_NO_MORE_ITEMS")); - ErrorNames.insert(std::make_pair(266, "ERROR_CANNOT_COPY")); - ErrorNames.insert(std::make_pair(267, "ERROR_DIRECTORY")); - ErrorNames.insert(std::make_pair(275, "ERROR_EAS_DIDNT_FIT")); - ErrorNames.insert(std::make_pair(276, "ERROR_EA_FILE_CORRUPT")); - ErrorNames.insert(std::make_pair(277, "ERROR_EA_TABLE_FULL")); - ErrorNames.insert(std::make_pair(278, "ERROR_INVALID_EA_HANDLE")); - ErrorNames.insert(std::make_pair(282, "ERROR_EAS_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(288, "ERROR_NOT_OWNER")); - ErrorNames.insert(std::make_pair(298, "ERROR_TOO_MANY_POSTS")); - ErrorNames.insert(std::make_pair(299, "ERROR_PARTIAL_COPY")); - ErrorNames.insert(std::make_pair(300, "ERROR_OPLOCK_NOT_GRANTED")); - ErrorNames.insert(std::make_pair(301, "ERROR_INVALID_OPLOCK_PROTOCOL")); - ErrorNames.insert(std::make_pair(302, "ERROR_DISK_TOO_FRAGMENTED")); - ErrorNames.insert(std::make_pair(303, "ERROR_DELETE_PENDING")); - ErrorNames.insert(std::make_pair(304, "ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING")); - ErrorNames.insert(std::make_pair(305, "ERROR_SHORT_NAMES_NOT_ENABLED_ON_VOLUME")); - ErrorNames.insert(std::make_pair(306, "ERROR_SECURITY_STREAM_IS_INCONSISTENT")); - ErrorNames.insert(std::make_pair(307, "ERROR_INVALID_LOCK_RANGE")); - ErrorNames.insert(std::make_pair(308, "ERROR_IMAGE_SUBSYSTEM_NOT_PRESENT")); - ErrorNames.insert(std::make_pair(309, "ERROR_NOTIFICATION_GUID_ALREADY_DEFINED")); - ErrorNames.insert(std::make_pair(317, "ERROR_MR_MID_NOT_FOUND")); - ErrorNames.insert(std::make_pair(318, "ERROR_SCOPE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(350, "ERROR_FAIL_NOACTION_REBOOT")); - ErrorNames.insert(std::make_pair(351, "ERROR_FAIL_SHUTDOWN")); - ErrorNames.insert(std::make_pair(352, "ERROR_FAIL_RESTART")); - ErrorNames.insert(std::make_pair(353, "ERROR_MAX_SESSIONS_REACHED")); - ErrorNames.insert(std::make_pair(400, "ERROR_THREAD_MODE_ALREADY_BACKGROUND")); - ErrorNames.insert(std::make_pair(401, "ERROR_THREAD_MODE_NOT_BACKGROUND")); - ErrorNames.insert(std::make_pair(402, "ERROR_PROCESS_MODE_ALREADY_BACKGROUND")); - ErrorNames.insert(std::make_pair(403, "ERROR_PROCESS_MODE_NOT_BACKGROUND")); - ErrorNames.insert(std::make_pair(487, "ERROR_INVALID_ADDRESS")); - ErrorNames.insert(std::make_pair(500, "ERROR_USER_PROFILE_LOAD")); - ErrorNames.insert(std::make_pair(534, "ERROR_ARITHMETIC_OVERFLOW")); - ErrorNames.insert(std::make_pair(535, "ERROR_PIPE_CONNECTED")); - ErrorNames.insert(std::make_pair(536, "ERROR_PIPE_LISTENING")); - ErrorNames.insert(std::make_pair(537, "ERROR_VERIFIER_STOP")); - ErrorNames.insert(std::make_pair(538, "ERROR_ABIOS_ERROR")); - ErrorNames.insert(std::make_pair(539, "ERROR_WX86_WARNING")); - ErrorNames.insert(std::make_pair(540, "ERROR_WX86_ERROR")); - ErrorNames.insert(std::make_pair(541, "ERROR_TIMER_NOT_CANCELED")); - ErrorNames.insert(std::make_pair(542, "ERROR_UNWIND")); - ErrorNames.insert(std::make_pair(543, "ERROR_BAD_STACK")); - ErrorNames.insert(std::make_pair(544, "ERROR_INVALID_UNWIND_TARGET")); - ErrorNames.insert(std::make_pair(545, "ERROR_INVALID_PORT_ATTRIBUTES")); - ErrorNames.insert(std::make_pair(546, "ERROR_PORT_MESSAGE_TOO_LONG")); - ErrorNames.insert(std::make_pair(547, "ERROR_INVALID_QUOTA_LOWER")); - ErrorNames.insert(std::make_pair(548, "ERROR_DEVICE_ALREADY_ATTACHED")); - ErrorNames.insert(std::make_pair(549, "ERROR_INSTRUCTION_MISALIGNMENT")); - ErrorNames.insert(std::make_pair(550, "ERROR_PROFILING_NOT_STARTED")); - ErrorNames.insert(std::make_pair(551, "ERROR_PROFILING_NOT_STOPPED")); - ErrorNames.insert(std::make_pair(552, "ERROR_COULD_NOT_INTERPRET")); - ErrorNames.insert(std::make_pair(553, "ERROR_PROFILING_AT_LIMIT")); - ErrorNames.insert(std::make_pair(554, "ERROR_CANT_WAIT")); - ErrorNames.insert(std::make_pair(555, "ERROR_CANT_TERMINATE_SELF")); - ErrorNames.insert(std::make_pair(556, "ERROR_UNEXPECTED_MM_CREATE_ERR")); - ErrorNames.insert(std::make_pair(557, "ERROR_UNEXPECTED_MM_MAP_ERROR")); - ErrorNames.insert(std::make_pair(558, "ERROR_UNEXPECTED_MM_EXTEND_ERR")); - ErrorNames.insert(std::make_pair(559, "ERROR_BAD_FUNCTION_TABLE")); - ErrorNames.insert(std::make_pair(560, "ERROR_NO_GUID_TRANSLATION")); - ErrorNames.insert(std::make_pair(561, "ERROR_INVALID_LDT_SIZE")); - ErrorNames.insert(std::make_pair(563, "ERROR_INVALID_LDT_OFFSET")); - ErrorNames.insert(std::make_pair(564, "ERROR_INVALID_LDT_DESCRIPTOR")); - ErrorNames.insert(std::make_pair(565, "ERROR_TOO_MANY_THREADS")); - ErrorNames.insert(std::make_pair(566, "ERROR_THREAD_NOT_IN_PROCESS")); - ErrorNames.insert(std::make_pair(567, "ERROR_PAGEFILE_QUOTA_EXCEEDED")); - ErrorNames.insert(std::make_pair(568, "ERROR_LOGON_SERVER_CONFLICT")); - ErrorNames.insert(std::make_pair(569, "ERROR_SYNCHRONIZATION_REQUIRED")); - ErrorNames.insert(std::make_pair(570, "ERROR_NET_OPEN_FAILED")); - ErrorNames.insert(std::make_pair(571, "ERROR_IO_PRIVILEGE_FAILED")); - ErrorNames.insert(std::make_pair(572, "ERROR_CONTROL_C_EXIT")); - ErrorNames.insert(std::make_pair(573, "ERROR_MISSING_SYSTEMFILE")); - ErrorNames.insert(std::make_pair(574, "ERROR_UNHANDLED_EXCEPTION")); - ErrorNames.insert(std::make_pair(575, "ERROR_APP_INIT_FAILURE")); - ErrorNames.insert(std::make_pair(576, "ERROR_PAGEFILE_CREATE_FAILED")); - ErrorNames.insert(std::make_pair(577, "ERROR_INVALID_IMAGE_HASH")); - ErrorNames.insert(std::make_pair(578, "ERROR_NO_PAGEFILE")); - ErrorNames.insert(std::make_pair(579, "ERROR_ILLEGAL_FLOAT_CONTEXT")); - ErrorNames.insert(std::make_pair(580, "ERROR_NO_EVENT_PAIR")); - ErrorNames.insert(std::make_pair(581, "ERROR_DOMAIN_CTRLR_CONFIG_ERROR")); - ErrorNames.insert(std::make_pair(582, "ERROR_ILLEGAL_CHARACTER")); - ErrorNames.insert(std::make_pair(583, "ERROR_UNDEFINED_CHARACTER")); - ErrorNames.insert(std::make_pair(584, "ERROR_FLOPPY_VOLUME")); - ErrorNames.insert(std::make_pair(585, "ERROR_BIOS_FAILED_TO_CONNECT_INTERRUPT")); - ErrorNames.insert(std::make_pair(586, "ERROR_BACKUP_CONTROLLER")); - ErrorNames.insert(std::make_pair(587, "ERROR_MUTANT_LIMIT_EXCEEDED")); - ErrorNames.insert(std::make_pair(588, "ERROR_FS_DRIVER_REQUIRED")); - ErrorNames.insert(std::make_pair(589, "ERROR_CANNOT_LOAD_REGISTRY_FILE")); - ErrorNames.insert(std::make_pair(590, "ERROR_DEBUG_ATTACH_FAILED")); - ErrorNames.insert(std::make_pair(591, "ERROR_SYSTEM_PROCESS_TERMINATED")); - ErrorNames.insert(std::make_pair(592, "ERROR_DATA_NOT_ACCEPTED")); - ErrorNames.insert(std::make_pair(593, "ERROR_VDM_HARD_ERROR")); - ErrorNames.insert(std::make_pair(594, "ERROR_DRIVER_CANCEL_TIMEOUT")); - ErrorNames.insert(std::make_pair(595, "ERROR_REPLY_MESSAGE_MISMATCH")); - ErrorNames.insert(std::make_pair(596, "ERROR_LOST_WRITEBEHIND_DATA")); - ErrorNames.insert(std::make_pair(597, "ERROR_CLIENT_SERVER_PARAMETERS_INVALID")); - ErrorNames.insert(std::make_pair(598, "ERROR_NOT_TINY_STREAM")); - ErrorNames.insert(std::make_pair(599, "ERROR_STACK_OVERFLOW_READ")); - ErrorNames.insert(std::make_pair(600, "ERROR_CONVERT_TO_LARGE")); - ErrorNames.insert(std::make_pair(601, "ERROR_FOUND_OUT_OF_SCOPE")); - ErrorNames.insert(std::make_pair(602, "ERROR_ALLOCATE_BUCKET")); - ErrorNames.insert(std::make_pair(603, "ERROR_MARSHALL_OVERFLOW")); - ErrorNames.insert(std::make_pair(604, "ERROR_INVALID_VARIANT")); - ErrorNames.insert(std::make_pair(605, "ERROR_BAD_COMPRESSION_BUFFER")); - ErrorNames.insert(std::make_pair(606, "ERROR_AUDIT_FAILED")); - ErrorNames.insert(std::make_pair(607, "ERROR_TIMER_RESOLUTION_NOT_SET")); - ErrorNames.insert(std::make_pair(608, "ERROR_INSUFFICIENT_LOGON_INFO")); - ErrorNames.insert(std::make_pair(609, "ERROR_BAD_DLL_ENTRYPOINT")); - ErrorNames.insert(std::make_pair(610, "ERROR_BAD_SERVICE_ENTRYPOINT")); - ErrorNames.insert(std::make_pair(611, "ERROR_IP_ADDRESS_CONFLICT1")); - ErrorNames.insert(std::make_pair(612, "ERROR_IP_ADDRESS_CONFLICT2")); - ErrorNames.insert(std::make_pair(613, "ERROR_REGISTRY_QUOTA_LIMIT")); - ErrorNames.insert(std::make_pair(614, "ERROR_NO_CALLBACK_ACTIVE")); - ErrorNames.insert(std::make_pair(615, "ERROR_PWD_TOO_SHORT")); - ErrorNames.insert(std::make_pair(616, "ERROR_PWD_TOO_RECENT")); - ErrorNames.insert(std::make_pair(617, "ERROR_PWD_HISTORY_CONFLICT")); - ErrorNames.insert(std::make_pair(618, "ERROR_UNSUPPORTED_COMPRESSION")); - ErrorNames.insert(std::make_pair(619, "ERROR_INVALID_HW_PROFILE")); - ErrorNames.insert(std::make_pair(620, "ERROR_INVALID_PLUGPLAY_DEVICE_PATH")); - ErrorNames.insert(std::make_pair(621, "ERROR_QUOTA_LIST_INCONSISTENT")); - ErrorNames.insert(std::make_pair(622, "ERROR_EVALUATION_EXPIRATION")); - ErrorNames.insert(std::make_pair(623, "ERROR_ILLEGAL_DLL_RELOCATION")); - ErrorNames.insert(std::make_pair(624, "ERROR_DLL_INIT_FAILED_LOGOFF")); - ErrorNames.insert(std::make_pair(625, "ERROR_VALIDATE_CONTINUE")); - ErrorNames.insert(std::make_pair(626, "ERROR_NO_MORE_MATCHES")); - ErrorNames.insert(std::make_pair(627, "ERROR_RANGE_LIST_CONFLICT")); - ErrorNames.insert(std::make_pair(628, "ERROR_SERVER_SID_MISMATCH")); - ErrorNames.insert(std::make_pair(629, "ERROR_CANT_ENABLE_DENY_ONLY")); - ErrorNames.insert(std::make_pair(630, "ERROR_FLOAT_MULTIPLE_FAULTS")); - ErrorNames.insert(std::make_pair(631, "ERROR_FLOAT_MULTIPLE_TRAPS")); - ErrorNames.insert(std::make_pair(632, "ERROR_NOINTERFACE")); - ErrorNames.insert(std::make_pair(633, "ERROR_DRIVER_FAILED_SLEEP")); - ErrorNames.insert(std::make_pair(634, "ERROR_CORRUPT_SYSTEM_FILE")); - ErrorNames.insert(std::make_pair(635, "ERROR_COMMITMENT_MINIMUM")); - ErrorNames.insert(std::make_pair(636, "ERROR_PNP_RESTART_ENUMERATION")); - ErrorNames.insert(std::make_pair(637, "ERROR_SYSTEM_IMAGE_BAD_SIGNATURE")); - ErrorNames.insert(std::make_pair(638, "ERROR_PNP_REBOOT_REQUIRED")); - ErrorNames.insert(std::make_pair(639, "ERROR_INSUFFICIENT_POWER")); - ErrorNames.insert(std::make_pair(640, "ERROR_MULTIPLE_FAULT_VIOLATION")); - ErrorNames.insert(std::make_pair(641, "ERROR_SYSTEM_SHUTDOWN")); - ErrorNames.insert(std::make_pair(642, "ERROR_PORT_NOT_SET")); - ErrorNames.insert(std::make_pair(643, "ERROR_DS_VERSION_CHECK_FAILURE")); - ErrorNames.insert(std::make_pair(644, "ERROR_RANGE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(646, "ERROR_NOT_SAFE_MODE_DRIVER")); - ErrorNames.insert(std::make_pair(647, "ERROR_FAILED_DRIVER_ENTRY")); - ErrorNames.insert(std::make_pair(648, "ERROR_DEVICE_ENUMERATION_ERROR")); - ErrorNames.insert(std::make_pair(649, "ERROR_MOUNT_POINT_NOT_RESOLVED")); - ErrorNames.insert(std::make_pair(650, "ERROR_INVALID_DEVICE_OBJECT_PARAMETER")); - ErrorNames.insert(std::make_pair(651, "ERROR_MCA_OCCURED")); - ErrorNames.insert(std::make_pair(652, "ERROR_DRIVER_DATABASE_ERROR")); - ErrorNames.insert(std::make_pair(653, "ERROR_SYSTEM_HIVE_TOO_LARGE")); - ErrorNames.insert(std::make_pair(654, "ERROR_DRIVER_FAILED_PRIOR_UNLOAD")); - ErrorNames.insert(std::make_pair(655, "ERROR_VOLSNAP_PREPARE_HIBERNATE")); - ErrorNames.insert(std::make_pair(656, "ERROR_HIBERNATION_FAILURE")); - ErrorNames.insert(std::make_pair(665, "ERROR_FILE_SYSTEM_LIMITATION")); - ErrorNames.insert(std::make_pair(668, "ERROR_ASSERTION_FAILURE")); - ErrorNames.insert(std::make_pair(669, "ERROR_ACPI_ERROR")); - ErrorNames.insert(std::make_pair(670, "ERROR_WOW_ASSERTION")); - ErrorNames.insert(std::make_pair(671, "ERROR_PNP_BAD_MPS_TABLE")); - ErrorNames.insert(std::make_pair(672, "ERROR_PNP_TRANSLATION_FAILED")); - ErrorNames.insert(std::make_pair(673, "ERROR_PNP_IRQ_TRANSLATION_FAILED")); - ErrorNames.insert(std::make_pair(674, "ERROR_PNP_INVALID_ID")); - ErrorNames.insert(std::make_pair(675, "ERROR_WAKE_SYSTEM_DEBUGGER")); - ErrorNames.insert(std::make_pair(676, "ERROR_HANDLES_CLOSED")); - ErrorNames.insert(std::make_pair(677, "ERROR_EXTRANEOUS_INFORMATION")); - ErrorNames.insert(std::make_pair(678, "ERROR_RXACT_COMMIT_NECESSARY")); - ErrorNames.insert(std::make_pair(679, "ERROR_MEDIA_CHECK")); - ErrorNames.insert(std::make_pair(680, "ERROR_GUID_SUBSTITUTION_MADE")); - ErrorNames.insert(std::make_pair(681, "ERROR_STOPPED_ON_SYMLINK")); - ErrorNames.insert(std::make_pair(682, "ERROR_LONGJUMP")); - ErrorNames.insert(std::make_pair(683, "ERROR_PLUGPLAY_QUERY_VETOED")); - ErrorNames.insert(std::make_pair(684, "ERROR_UNWIND_CONSOLIDATE")); - ErrorNames.insert(std::make_pair(685, "ERROR_REGISTRY_HIVE_RECOVERED")); - ErrorNames.insert(std::make_pair(686, "ERROR_DLL_MIGHT_BE_INSECURE")); - ErrorNames.insert(std::make_pair(687, "ERROR_DLL_MIGHT_BE_INCOMPATIBLE")); - ErrorNames.insert(std::make_pair(688, "ERROR_DBG_EXCEPTION_NOT_HANDLED")); - ErrorNames.insert(std::make_pair(689, "ERROR_DBG_REPLY_LATER")); - ErrorNames.insert(std::make_pair(690, "ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE")); - ErrorNames.insert(std::make_pair(691, "ERROR_DBG_TERMINATE_THREAD")); - ErrorNames.insert(std::make_pair(692, "ERROR_DBG_TERMINATE_PROCESS")); - ErrorNames.insert(std::make_pair(693, "ERROR_DBG_CONTROL_C")); - ErrorNames.insert(std::make_pair(694, "ERROR_DBG_PRINTEXCEPTION_C")); - ErrorNames.insert(std::make_pair(695, "ERROR_DBG_RIPEXCEPTION")); - ErrorNames.insert(std::make_pair(696, "ERROR_DBG_CONTROL_BREAK")); - ErrorNames.insert(std::make_pair(697, "ERROR_DBG_COMMAND_EXCEPTION")); - ErrorNames.insert(std::make_pair(698, "ERROR_OBJECT_NAME_EXISTS")); - ErrorNames.insert(std::make_pair(699, "ERROR_THREAD_WAS_SUSPENDED")); - ErrorNames.insert(std::make_pair(700, "ERROR_IMAGE_NOT_AT_BASE")); - ErrorNames.insert(std::make_pair(701, "ERROR_RXACT_STATE_CREATED")); - ErrorNames.insert(std::make_pair(702, "ERROR_SEGMENT_NOTIFICATION")); - ErrorNames.insert(std::make_pair(703, "ERROR_BAD_CURRENT_DIRECTORY")); - ErrorNames.insert(std::make_pair(704, "ERROR_FT_READ_RECOVERY_FROM_BACKUP")); - ErrorNames.insert(std::make_pair(705, "ERROR_FT_WRITE_RECOVERY")); - ErrorNames.insert(std::make_pair(706, "ERROR_IMAGE_MACHINE_TYPE_MISMATCH")); - ErrorNames.insert(std::make_pair(707, "ERROR_RECEIVE_PARTIAL")); - ErrorNames.insert(std::make_pair(708, "ERROR_RECEIVE_EXPEDITED")); - ErrorNames.insert(std::make_pair(709, "ERROR_RECEIVE_PARTIAL_EXPEDITED")); - ErrorNames.insert(std::make_pair(710, "ERROR_EVENT_DONE")); - ErrorNames.insert(std::make_pair(711, "ERROR_EVENT_PENDING")); - ErrorNames.insert(std::make_pair(712, "ERROR_CHECKING_FILE_SYSTEM")); - ErrorNames.insert(std::make_pair(713, "ERROR_FATAL_APP_EXIT")); - ErrorNames.insert(std::make_pair(714, "ERROR_PREDEFINED_HANDLE")); - ErrorNames.insert(std::make_pair(715, "ERROR_WAS_UNLOCKED")); - ErrorNames.insert(std::make_pair(716, "ERROR_SERVICE_NOTIFICATION")); - ErrorNames.insert(std::make_pair(717, "ERROR_WAS_LOCKED")); - ErrorNames.insert(std::make_pair(718, "ERROR_LOG_HARD_ERROR")); - ErrorNames.insert(std::make_pair(719, "ERROR_ALREADY_WIN32")); - ErrorNames.insert(std::make_pair(720, "ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE")); - ErrorNames.insert(std::make_pair(721, "ERROR_NO_YIELD_PERFORMED")); - ErrorNames.insert(std::make_pair(722, "ERROR_TIMER_RESUME_IGNORED")); - ErrorNames.insert(std::make_pair(723, "ERROR_ARBITRATION_UNHANDLED")); - ErrorNames.insert(std::make_pair(724, "ERROR_CARDBUS_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(725, "ERROR_MP_PROCESSOR_MISMATCH")); - ErrorNames.insert(std::make_pair(726, "ERROR_HIBERNATED")); - ErrorNames.insert(std::make_pair(727, "ERROR_RESUME_HIBERNATION")); - ErrorNames.insert(std::make_pair(728, "ERROR_FIRMWARE_UPDATED")); - ErrorNames.insert(std::make_pair(729, "ERROR_DRIVERS_LEAKING_LOCKED_PAGES")); - ErrorNames.insert(std::make_pair(730, "ERROR_WAKE_SYSTEM")); - ErrorNames.insert(std::make_pair(731, "ERROR_WAIT_1")); - ErrorNames.insert(std::make_pair(732, "ERROR_WAIT_2")); - ErrorNames.insert(std::make_pair(733, "ERROR_WAIT_3")); - ErrorNames.insert(std::make_pair(734, "ERROR_WAIT_63")); - ErrorNames.insert(std::make_pair(735, "ERROR_ABANDONED_WAIT_0")); - ErrorNames.insert(std::make_pair(736, "ERROR_ABANDONED_WAIT_63")); - ErrorNames.insert(std::make_pair(737, "ERROR_USER_APC")); - ErrorNames.insert(std::make_pair(738, "ERROR_KERNEL_APC")); - ErrorNames.insert(std::make_pair(739, "ERROR_ALERTED")); - ErrorNames.insert(std::make_pair(740, "ERROR_ELEVATION_REQUIRED")); - ErrorNames.insert(std::make_pair(741, "ERROR_REPARSE")); - ErrorNames.insert(std::make_pair(742, "ERROR_OPLOCK_BREAK_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(743, "ERROR_VOLUME_MOUNTED")); - ErrorNames.insert(std::make_pair(744, "ERROR_RXACT_COMMITTED")); - ErrorNames.insert(std::make_pair(745, "ERROR_NOTIFY_CLEANUP")); - ErrorNames.insert(std::make_pair(746, "ERROR_PRIMARY_TRANSPORT_CONNECT_FAILED")); - ErrorNames.insert(std::make_pair(747, "ERROR_PAGE_FAULT_TRANSITION")); - ErrorNames.insert(std::make_pair(748, "ERROR_PAGE_FAULT_DEMAND_ZERO")); - ErrorNames.insert(std::make_pair(749, "ERROR_PAGE_FAULT_COPY_ON_WRITE")); - ErrorNames.insert(std::make_pair(750, "ERROR_PAGE_FAULT_GUARD_PAGE")); - ErrorNames.insert(std::make_pair(751, "ERROR_PAGE_FAULT_PAGING_FILE")); - ErrorNames.insert(std::make_pair(752, "ERROR_CACHE_PAGE_LOCKED")); - ErrorNames.insert(std::make_pair(753, "ERROR_CRASH_DUMP")); - ErrorNames.insert(std::make_pair(754, "ERROR_BUFFER_ALL_ZEROS")); - ErrorNames.insert(std::make_pair(755, "ERROR_REPARSE_OBJECT")); - ErrorNames.insert(std::make_pair(756, "ERROR_RESOURCE_REQUIREMENTS_CHANGED")); - ErrorNames.insert(std::make_pair(757, "ERROR_TRANSLATION_COMPLETE")); - ErrorNames.insert(std::make_pair(758, "ERROR_NOTHING_TO_TERMINATE")); - ErrorNames.insert(std::make_pair(759, "ERROR_PROCESS_NOT_IN_JOB")); - ErrorNames.insert(std::make_pair(760, "ERROR_PROCESS_IN_JOB")); - ErrorNames.insert(std::make_pair(761, "ERROR_VOLSNAP_HIBERNATE_READY")); - ErrorNames.insert(std::make_pair(762, "ERROR_FSFILTER_OP_COMPLETED_SUCCESSFULLY")); - ErrorNames.insert(std::make_pair(763, "ERROR_INTERRUPT_VECTOR_ALREADY_CONNECTED")); - ErrorNames.insert(std::make_pair(764, "ERROR_INTERRUPT_STILL_CONNECTED")); - ErrorNames.insert(std::make_pair(765, "ERROR_WAIT_FOR_OPLOCK")); - ErrorNames.insert(std::make_pair(766, "ERROR_DBG_EXCEPTION_HANDLED")); - ErrorNames.insert(std::make_pair(767, "ERROR_DBG_CONTINUE")); - ErrorNames.insert(std::make_pair(768, "ERROR_CALLBACK_POP_STACK")); - ErrorNames.insert(std::make_pair(769, "ERROR_COMPRESSION_DISABLED")); - ErrorNames.insert(std::make_pair(770, "ERROR_CANTFETCHBACKWARDS")); - ErrorNames.insert(std::make_pair(771, "ERROR_CANTSCROLLBACKWARDS")); - ErrorNames.insert(std::make_pair(772, "ERROR_ROWSNOTRELEASED")); - ErrorNames.insert(std::make_pair(773, "ERROR_BAD_ACCESSOR_FLAGS")); - ErrorNames.insert(std::make_pair(774, "ERROR_ERRORS_ENCOUNTERED")); - ErrorNames.insert(std::make_pair(775, "ERROR_NOT_CAPABLE")); - ErrorNames.insert(std::make_pair(776, "ERROR_REQUEST_OUT_OF_SEQUENCE")); - ErrorNames.insert(std::make_pair(777, "ERROR_VERSION_PARSE_ERROR")); - ErrorNames.insert(std::make_pair(778, "ERROR_BADSTARTPOSITION")); - ErrorNames.insert(std::make_pair(779, "ERROR_MEMORY_HARDWARE")); - ErrorNames.insert(std::make_pair(780, "ERROR_DISK_REPAIR_DISABLED")); - ErrorNames.insert(std::make_pair(781, "ERROR_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE")); - ErrorNames.insert(std::make_pair(782, "ERROR_SYSTEM_POWERSTATE_TRANSITION")); - ErrorNames.insert(std::make_pair(783, "ERROR_SYSTEM_POWERSTATE_COMPLEX_TRANSITION")); - ErrorNames.insert(std::make_pair(784, "ERROR_MCA_EXCEPTION")); - ErrorNames.insert(std::make_pair(785, "ERROR_ACCESS_AUDIT_BY_POLICY")); - ErrorNames.insert(std::make_pair(786, "ERROR_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY")); - ErrorNames.insert(std::make_pair(787, "ERROR_ABANDON_HIBERFILE")); - ErrorNames.insert(std::make_pair(788, "ERROR_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED")); - ErrorNames.insert(std::make_pair(789, "ERROR_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR")); - ErrorNames.insert(std::make_pair(790, "ERROR_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR")); - ErrorNames.insert(std::make_pair(791, "ERROR_BAD_MCFG_TABLE")); - ErrorNames.insert(std::make_pair(800, "ERROR_OPLOCK_SWITCHED_TO_NEW_HANDLE")); - ErrorNames.insert(std::make_pair(801, "ERROR_CANNOT_GRANT_REQUESTED_OPLOCK")); - ErrorNames.insert(std::make_pair(802, "ERROR_CANNOT_BREAK_OPLOCK")); - ErrorNames.insert(std::make_pair(803, "ERROR_OPLOCK_HANDLE_CLOSED")); - ErrorNames.insert(std::make_pair(804, "ERROR_NO_ACE_CONDITION")); - ErrorNames.insert(std::make_pair(805, "ERROR_INVALID_ACE_CONDITION")); - ErrorNames.insert(std::make_pair(994, "ERROR_EA_ACCESS_DENIED")); - ErrorNames.insert(std::make_pair(995, "ERROR_OPERATION_ABORTED")); - ErrorNames.insert(std::make_pair(996, "ERROR_IO_INCOMPLETE")); - ErrorNames.insert(std::make_pair(997, "ERROR_IO_PENDING")); - ErrorNames.insert(std::make_pair(998, "ERROR_NOACCESS")); - ErrorNames.insert(std::make_pair(999, "ERROR_SWAPERROR")); - ErrorNames.insert(std::make_pair(1001, "ERROR_STACK_OVERFLOW")); - ErrorNames.insert(std::make_pair(1002, "ERROR_INVALID_MESSAGE")); - ErrorNames.insert(std::make_pair(1003, "ERROR_CAN_NOT_COMPLETE")); - ErrorNames.insert(std::make_pair(1004, "ERROR_INVALID_FLAGS")); - ErrorNames.insert(std::make_pair(1005, "ERROR_UNRECOGNIZED_VOLUME")); - ErrorNames.insert(std::make_pair(1006, "ERROR_FILE_INVALID")); - ErrorNames.insert(std::make_pair(1007, "ERROR_FULLSCREEN_MODE")); - ErrorNames.insert(std::make_pair(1008, "ERROR_NO_TOKEN")); - ErrorNames.insert(std::make_pair(1009, "ERROR_BADDB")); - ErrorNames.insert(std::make_pair(1010, "ERROR_BADKEY")); - ErrorNames.insert(std::make_pair(1011, "ERROR_CANTOPEN")); - ErrorNames.insert(std::make_pair(1012, "ERROR_CANTREAD")); - ErrorNames.insert(std::make_pair(1013, "ERROR_CANTWRITE")); - ErrorNames.insert(std::make_pair(1014, "ERROR_REGISTRY_RECOVERED")); - ErrorNames.insert(std::make_pair(1015, "ERROR_REGISTRY_CORRUPT")); - ErrorNames.insert(std::make_pair(1016, "ERROR_REGISTRY_IO_FAILED")); - ErrorNames.insert(std::make_pair(1017, "ERROR_NOT_REGISTRY_FILE")); - ErrorNames.insert(std::make_pair(1018, "ERROR_KEY_DELETED")); - ErrorNames.insert(std::make_pair(1019, "ERROR_NO_LOG_SPACE")); - ErrorNames.insert(std::make_pair(1020, "ERROR_KEY_HAS_CHILDREN")); - ErrorNames.insert(std::make_pair(1021, "ERROR_CHILD_MUST_BE_VOLATILE")); - ErrorNames.insert(std::make_pair(1022, "ERROR_NOTIFY_ENUM_DIR")); - ErrorNames.insert(std::make_pair(1051, "ERROR_DEPENDENT_SERVICES_RUNNING")); - ErrorNames.insert(std::make_pair(1052, "ERROR_INVALID_SERVICE_CONTROL")); - ErrorNames.insert(std::make_pair(1053, "ERROR_SERVICE_REQUEST_TIMEOUT")); - ErrorNames.insert(std::make_pair(1054, "ERROR_SERVICE_NO_THREAD")); - ErrorNames.insert(std::make_pair(1055, "ERROR_SERVICE_DATABASE_LOCKED")); - ErrorNames.insert(std::make_pair(1056, "ERROR_SERVICE_ALREADY_RUNNING")); - ErrorNames.insert(std::make_pair(1057, "ERROR_INVALID_SERVICE_ACCOUNT")); - ErrorNames.insert(std::make_pair(1058, "ERROR_SERVICE_DISABLED")); - ErrorNames.insert(std::make_pair(1059, "ERROR_CIRCULAR_DEPENDENCY")); - ErrorNames.insert(std::make_pair(1060, "ERROR_SERVICE_DOES_NOT_EXIST")); - ErrorNames.insert(std::make_pair(1061, "ERROR_SERVICE_CANNOT_ACCEPT_CTRL")); - ErrorNames.insert(std::make_pair(1062, "ERROR_SERVICE_NOT_ACTIVE")); - ErrorNames.insert(std::make_pair(1063, "ERROR_FAILED_SERVICE_CONTROLLER_CONNECT")); - ErrorNames.insert(std::make_pair(1064, "ERROR_EXCEPTION_IN_SERVICE")); - ErrorNames.insert(std::make_pair(1065, "ERROR_DATABASE_DOES_NOT_EXIST")); - ErrorNames.insert(std::make_pair(1066, "ERROR_SERVICE_SPECIFIC_ERROR")); - ErrorNames.insert(std::make_pair(1067, "ERROR_PROCESS_ABORTED")); - ErrorNames.insert(std::make_pair(1068, "ERROR_SERVICE_DEPENDENCY_FAIL")); - ErrorNames.insert(std::make_pair(1069, "ERROR_SERVICE_LOGON_FAILED")); - ErrorNames.insert(std::make_pair(1070, "ERROR_SERVICE_START_HANG")); - ErrorNames.insert(std::make_pair(1071, "ERROR_INVALID_SERVICE_LOCK")); - ErrorNames.insert(std::make_pair(1072, "ERROR_SERVICE_MARKED_FOR_DELETE")); - ErrorNames.insert(std::make_pair(1073, "ERROR_SERVICE_EXISTS")); - ErrorNames.insert(std::make_pair(1074, "ERROR_ALREADY_RUNNING_LKG")); - ErrorNames.insert(std::make_pair(1075, "ERROR_SERVICE_DEPENDENCY_DELETED")); - ErrorNames.insert(std::make_pair(1076, "ERROR_BOOT_ALREADY_ACCEPTED")); - ErrorNames.insert(std::make_pair(1077, "ERROR_SERVICE_NEVER_STARTED")); - ErrorNames.insert(std::make_pair(1078, "ERROR_DUPLICATE_SERVICE_NAME")); - ErrorNames.insert(std::make_pair(1079, "ERROR_DIFFERENT_SERVICE_ACCOUNT")); - ErrorNames.insert(std::make_pair(1080, "ERROR_CANNOT_DETECT_DRIVER_FAILURE")); - ErrorNames.insert(std::make_pair(1081, "ERROR_CANNOT_DETECT_PROCESS_ABORT")); - ErrorNames.insert(std::make_pair(1082, "ERROR_NO_RECOVERY_PROGRAM")); - ErrorNames.insert(std::make_pair(1083, "ERROR_SERVICE_NOT_IN_EXE")); - ErrorNames.insert(std::make_pair(1084, "ERROR_NOT_SAFEBOOT_SERVICE")); - ErrorNames.insert(std::make_pair(1100, "ERROR_END_OF_MEDIA")); - ErrorNames.insert(std::make_pair(1101, "ERROR_FILEMARK_DETECTED")); - ErrorNames.insert(std::make_pair(1102, "ERROR_BEGINNING_OF_MEDIA")); - ErrorNames.insert(std::make_pair(1103, "ERROR_SETMARK_DETECTED")); - ErrorNames.insert(std::make_pair(1104, "ERROR_NO_DATA_DETECTED")); - ErrorNames.insert(std::make_pair(1105, "ERROR_PARTITION_FAILURE")); - ErrorNames.insert(std::make_pair(1106, "ERROR_INVALID_BLOCK_LENGTH")); - ErrorNames.insert(std::make_pair(1107, "ERROR_DEVICE_NOT_PARTITIONED")); - ErrorNames.insert(std::make_pair(1108, "ERROR_UNABLE_TO_LOCK_MEDIA")); - ErrorNames.insert(std::make_pair(1109, "ERROR_UNABLE_TO_UNLOAD_MEDIA")); - ErrorNames.insert(std::make_pair(1110, "ERROR_MEDIA_CHANGED")); - ErrorNames.insert(std::make_pair(1111, "ERROR_BUS_RESET")); - ErrorNames.insert(std::make_pair(1112, "ERROR_NO_MEDIA_IN_DRIVE")); - ErrorNames.insert(std::make_pair(1113, "ERROR_NO_UNICODE_TRANSLATION")); - ErrorNames.insert(std::make_pair(1114, "ERROR_DLL_INIT_FAILED")); - ErrorNames.insert(std::make_pair(1115, "ERROR_SHUTDOWN_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(1116, "ERROR_NO_SHUTDOWN_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(1117, "ERROR_IO_DEVICE")); - ErrorNames.insert(std::make_pair(1118, "ERROR_SERIAL_NO_DEVICE")); - ErrorNames.insert(std::make_pair(1119, "ERROR_IRQ_BUSY")); - ErrorNames.insert(std::make_pair(1120, "ERROR_MORE_WRITES")); - ErrorNames.insert(std::make_pair(1121, "ERROR_COUNTER_TIMEOUT")); - ErrorNames.insert(std::make_pair(1122, "ERROR_FLOPPY_ID_MARK_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1123, "ERROR_FLOPPY_WRONG_CYLINDER")); - ErrorNames.insert(std::make_pair(1124, "ERROR_FLOPPY_UNKNOWN_ERROR")); - ErrorNames.insert(std::make_pair(1125, "ERROR_FLOPPY_BAD_REGISTERS")); - ErrorNames.insert(std::make_pair(1126, "ERROR_DISK_RECALIBRATE_FAILED")); - ErrorNames.insert(std::make_pair(1127, "ERROR_DISK_OPERATION_FAILED")); - ErrorNames.insert(std::make_pair(1128, "ERROR_DISK_RESET_FAILED")); - ErrorNames.insert(std::make_pair(1129, "ERROR_EOM_OVERFLOW")); - ErrorNames.insert(std::make_pair(1130, "ERROR_NOT_ENOUGH_SERVER_MEMORY")); - ErrorNames.insert(std::make_pair(1131, "ERROR_POSSIBLE_DEADLOCK")); - ErrorNames.insert(std::make_pair(1132, "ERROR_MAPPED_ALIGNMENT")); - ErrorNames.insert(std::make_pair(1140, "ERROR_SET_POWER_STATE_VETOED")); - ErrorNames.insert(std::make_pair(1141, "ERROR_SET_POWER_STATE_FAILED")); - ErrorNames.insert(std::make_pair(1142, "ERROR_TOO_MANY_LINKS")); - ErrorNames.insert(std::make_pair(1150, "ERROR_OLD_WIN_VERSION")); - ErrorNames.insert(std::make_pair(1151, "ERROR_APP_WRONG_OS")); - ErrorNames.insert(std::make_pair(1152, "ERROR_SINGLE_INSTANCE_APP")); - ErrorNames.insert(std::make_pair(1153, "ERROR_RMODE_APP")); - ErrorNames.insert(std::make_pair(1154, "ERROR_INVALID_DLL")); - ErrorNames.insert(std::make_pair(1155, "ERROR_NO_ASSOCIATION")); - ErrorNames.insert(std::make_pair(1156, "ERROR_DDE_FAIL")); - ErrorNames.insert(std::make_pair(1157, "ERROR_DLL_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1158, "ERROR_NO_MORE_USER_HANDLES")); - ErrorNames.insert(std::make_pair(1159, "ERROR_MESSAGE_SYNC_ONLY")); - ErrorNames.insert(std::make_pair(1160, "ERROR_SOURCE_ELEMENT_EMPTY")); - ErrorNames.insert(std::make_pair(1161, "ERROR_DESTINATION_ELEMENT_FULL")); - ErrorNames.insert(std::make_pair(1162, "ERROR_ILLEGAL_ELEMENT_ADDRESS")); - ErrorNames.insert(std::make_pair(1163, "ERROR_MAGAZINE_NOT_PRESENT")); - ErrorNames.insert(std::make_pair(1164, "ERROR_DEVICE_REINITIALIZATION_NEEDED")); - ErrorNames.insert(std::make_pair(1165, "ERROR_DEVICE_REQUIRES_CLEANING")); - ErrorNames.insert(std::make_pair(1166, "ERROR_DEVICE_DOOR_OPEN")); - ErrorNames.insert(std::make_pair(1167, "ERROR_DEVICE_NOT_CONNECTED")); - ErrorNames.insert(std::make_pair(1168, "ERROR_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1169, "ERROR_NO_MATCH")); - ErrorNames.insert(std::make_pair(1170, "ERROR_SET_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1171, "ERROR_POINT_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1172, "ERROR_NO_TRACKING_SERVICE")); - ErrorNames.insert(std::make_pair(1173, "ERROR_NO_VOLUME_ID")); - ErrorNames.insert(std::make_pair(1175, "ERROR_UNABLE_TO_REMOVE_REPLACED")); - ErrorNames.insert(std::make_pair(1176, "ERROR_UNABLE_TO_MOVE_REPLACEMENT")); - ErrorNames.insert(std::make_pair(1177, "ERROR_UNABLE_TO_MOVE_REPLACEMENT_2")); - ErrorNames.insert(std::make_pair(1178, "ERROR_JOURNAL_DELETE_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(1179, "ERROR_JOURNAL_NOT_ACTIVE")); - ErrorNames.insert(std::make_pair(1180, "ERROR_POTENTIAL_FILE_FOUND")); - ErrorNames.insert(std::make_pair(1181, "ERROR_JOURNAL_ENTRY_DELETED")); - ErrorNames.insert(std::make_pair(1190, "ERROR_SHUTDOWN_IS_SCHEDULED")); - ErrorNames.insert(std::make_pair(1191, "ERROR_SHUTDOWN_USERS_LOGGED_ON")); - ErrorNames.insert(std::make_pair(1200, "ERROR_BAD_DEVICE")); - ErrorNames.insert(std::make_pair(1201, "ERROR_CONNECTION_UNAVAIL")); - ErrorNames.insert(std::make_pair(1202, "ERROR_DEVICE_ALREADY_REMEMBERED")); - ErrorNames.insert(std::make_pair(1203, "ERROR_NO_NET_OR_BAD_PATH")); - ErrorNames.insert(std::make_pair(1204, "ERROR_BAD_PROVIDER")); - ErrorNames.insert(std::make_pair(1205, "ERROR_CANNOT_OPEN_PROFILE")); - ErrorNames.insert(std::make_pair(1206, "ERROR_BAD_PROFILE")); - ErrorNames.insert(std::make_pair(1207, "ERROR_NOT_CONTAINER")); - ErrorNames.insert(std::make_pair(1208, "ERROR_EXTENDED_ERROR")); - ErrorNames.insert(std::make_pair(1209, "ERROR_INVALID_GROUPNAME")); - ErrorNames.insert(std::make_pair(1210, "ERROR_INVALID_COMPUTERNAME")); - ErrorNames.insert(std::make_pair(1211, "ERROR_INVALID_EVENTNAME")); - ErrorNames.insert(std::make_pair(1212, "ERROR_INVALID_DOMAINNAME")); - ErrorNames.insert(std::make_pair(1213, "ERROR_INVALID_SERVICENAME")); - ErrorNames.insert(std::make_pair(1214, "ERROR_INVALID_NETNAME")); - ErrorNames.insert(std::make_pair(1215, "ERROR_INVALID_SHARENAME")); - ErrorNames.insert(std::make_pair(1216, "ERROR_INVALID_PASSWORDNAME")); - ErrorNames.insert(std::make_pair(1217, "ERROR_INVALID_MESSAGENAME")); - ErrorNames.insert(std::make_pair(1218, "ERROR_INVALID_MESSAGEDEST")); - ErrorNames.insert(std::make_pair(1219, "ERROR_SESSION_CREDENTIAL_CONFLICT")); - ErrorNames.insert(std::make_pair(1220, "ERROR_REMOTE_SESSION_LIMIT_EXCEEDED")); - ErrorNames.insert(std::make_pair(1221, "ERROR_DUP_DOMAINNAME")); - ErrorNames.insert(std::make_pair(1222, "ERROR_NO_NETWORK")); - ErrorNames.insert(std::make_pair(1223, "ERROR_CANCELLED")); - ErrorNames.insert(std::make_pair(1224, "ERROR_USER_MAPPED_FILE")); - ErrorNames.insert(std::make_pair(1225, "ERROR_CONNECTION_REFUSED")); - ErrorNames.insert(std::make_pair(1226, "ERROR_GRACEFUL_DISCONNECT")); - ErrorNames.insert(std::make_pair(1227, "ERROR_ADDRESS_ALREADY_ASSOCIATED")); - ErrorNames.insert(std::make_pair(1228, "ERROR_ADDRESS_NOT_ASSOCIATED")); - ErrorNames.insert(std::make_pair(1229, "ERROR_CONNECTION_INVALID")); - ErrorNames.insert(std::make_pair(1230, "ERROR_CONNECTION_ACTIVE")); - ErrorNames.insert(std::make_pair(1231, "ERROR_NETWORK_UNREACHABLE")); - ErrorNames.insert(std::make_pair(1232, "ERROR_HOST_UNREACHABLE")); - ErrorNames.insert(std::make_pair(1233, "ERROR_PROTOCOL_UNREACHABLE")); - ErrorNames.insert(std::make_pair(1234, "ERROR_PORT_UNREACHABLE")); - ErrorNames.insert(std::make_pair(1235, "ERROR_REQUEST_ABORTED")); - ErrorNames.insert(std::make_pair(1236, "ERROR_CONNECTION_ABORTED")); - ErrorNames.insert(std::make_pair(1237, "ERROR_RETRY")); - ErrorNames.insert(std::make_pair(1238, "ERROR_CONNECTION_COUNT_LIMIT")); - ErrorNames.insert(std::make_pair(1239, "ERROR_LOGIN_TIME_RESTRICTION")); - ErrorNames.insert(std::make_pair(1240, "ERROR_LOGIN_WKSTA_RESTRICTION")); - ErrorNames.insert(std::make_pair(1241, "ERROR_INCORRECT_ADDRESS")); - ErrorNames.insert(std::make_pair(1242, "ERROR_ALREADY_REGISTERED")); - ErrorNames.insert(std::make_pair(1243, "ERROR_SERVICE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1244, "ERROR_NOT_AUTHENTICATED")); - ErrorNames.insert(std::make_pair(1245, "ERROR_NOT_LOGGED_ON")); - ErrorNames.insert(std::make_pair(1246, "ERROR_CONTINUE")); - ErrorNames.insert(std::make_pair(1247, "ERROR_ALREADY_INITIALIZED")); - ErrorNames.insert(std::make_pair(1248, "ERROR_NO_MORE_DEVICES")); - ErrorNames.insert(std::make_pair(1249, "ERROR_NO_SUCH_SITE")); - ErrorNames.insert(std::make_pair(1250, "ERROR_DOMAIN_CONTROLLER_EXISTS")); - ErrorNames.insert(std::make_pair(1251, "ERROR_ONLY_IF_CONNECTED")); - ErrorNames.insert(std::make_pair(1252, "ERROR_OVERRIDE_NOCHANGES")); - ErrorNames.insert(std::make_pair(1253, "ERROR_BAD_USER_PROFILE")); - ErrorNames.insert(std::make_pair(1254, "ERROR_NOT_SUPPORTED_ON_SBS")); - ErrorNames.insert(std::make_pair(1255, "ERROR_SERVER_SHUTDOWN_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(1256, "ERROR_HOST_DOWN")); - ErrorNames.insert(std::make_pair(1257, "ERROR_NON_ACCOUNT_SID")); - ErrorNames.insert(std::make_pair(1258, "ERROR_NON_DOMAIN_SID")); - ErrorNames.insert(std::make_pair(1259, "ERROR_APPHELP_BLOCK")); - ErrorNames.insert(std::make_pair(1260, "ERROR_ACCESS_DISABLED_BY_POLICY")); - ErrorNames.insert(std::make_pair(1261, "ERROR_REG_NAT_CONSUMPTION")); - ErrorNames.insert(std::make_pair(1262, "ERROR_CSCSHARE_OFFLINE")); - ErrorNames.insert(std::make_pair(1263, "ERROR_PKINIT_FAILURE")); - ErrorNames.insert(std::make_pair(1264, "ERROR_SMARTCARD_SUBSYSTEM_FAILURE")); - ErrorNames.insert(std::make_pair(1265, "ERROR_DOWNGRADE_DETECTED")); - ErrorNames.insert(std::make_pair(1271, "ERROR_MACHINE_LOCKED")); - ErrorNames.insert(std::make_pair(1273, "ERROR_CALLBACK_SUPPLIED_INVALID_DATA")); - ErrorNames.insert(std::make_pair(1274, "ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED")); - ErrorNames.insert(std::make_pair(1275, "ERROR_DRIVER_BLOCKED")); - ErrorNames.insert(std::make_pair(1276, "ERROR_INVALID_IMPORT_OF_NON_DLL")); - ErrorNames.insert(std::make_pair(1277, "ERROR_ACCESS_DISABLED_WEBBLADE")); - ErrorNames.insert(std::make_pair(1278, "ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER")); - ErrorNames.insert(std::make_pair(1279, "ERROR_RECOVERY_FAILURE")); - ErrorNames.insert(std::make_pair(1280, "ERROR_ALREADY_FIBER")); - ErrorNames.insert(std::make_pair(1281, "ERROR_ALREADY_THREAD")); - ErrorNames.insert(std::make_pair(1282, "ERROR_STACK_BUFFER_OVERRUN")); - ErrorNames.insert(std::make_pair(1283, "ERROR_PARAMETER_QUOTA_EXCEEDED")); - ErrorNames.insert(std::make_pair(1284, "ERROR_DEBUGGER_INACTIVE")); - ErrorNames.insert(std::make_pair(1285, "ERROR_DELAY_LOAD_FAILED")); - ErrorNames.insert(std::make_pair(1286, "ERROR_VDM_DISALLOWED")); - ErrorNames.insert(std::make_pair(1287, "ERROR_UNIDENTIFIED_ERROR")); - ErrorNames.insert(std::make_pair(1288, "ERROR_INVALID_CRUNTIME_PARAMETER")); - ErrorNames.insert(std::make_pair(1289, "ERROR_BEYOND_VDL")); - ErrorNames.insert(std::make_pair(1290, "ERROR_INCOMPATIBLE_SERVICE_SID_TYPE")); - ErrorNames.insert(std::make_pair(1291, "ERROR_DRIVER_PROCESS_TERMINATED")); - ErrorNames.insert(std::make_pair(1292, "ERROR_IMPLEMENTATION_LIMIT")); - ErrorNames.insert(std::make_pair(1293, "ERROR_PROCESS_IS_PROTECTED")); - ErrorNames.insert(std::make_pair(1294, "ERROR_SERVICE_NOTIFY_CLIENT_LAGGING")); - ErrorNames.insert(std::make_pair(1295, "ERROR_DISK_QUOTA_EXCEEDED")); - ErrorNames.insert(std::make_pair(1296, "ERROR_CONTENT_BLOCKED")); - ErrorNames.insert(std::make_pair(1297, "ERROR_INCOMPATIBLE_SERVICE_PRIVILEGE")); - ErrorNames.insert(std::make_pair(1298, "ERROR_APP_HANG")); - ErrorNames.insert(std::make_pair(1299, "ERROR_INVALID_LABEL")); - ErrorNames.insert(std::make_pair(1300, "ERROR_NOT_ALL_ASSIGNED")); - ErrorNames.insert(std::make_pair(1301, "ERROR_SOME_NOT_MAPPED")); - ErrorNames.insert(std::make_pair(1302, "ERROR_NO_QUOTAS_FOR_ACCOUNT")); - ErrorNames.insert(std::make_pair(1303, "ERROR_LOCAL_USER_SESSION_KEY")); - ErrorNames.insert(std::make_pair(1304, "ERROR_NULL_LM_PASSWORD")); - ErrorNames.insert(std::make_pair(1305, "ERROR_UNKNOWN_REVISION")); - ErrorNames.insert(std::make_pair(1306, "ERROR_REVISION_MISMATCH")); - ErrorNames.insert(std::make_pair(1307, "ERROR_INVALID_OWNER")); - ErrorNames.insert(std::make_pair(1308, "ERROR_INVALID_PRIMARY_GROUP")); - ErrorNames.insert(std::make_pair(1309, "ERROR_NO_IMPERSONATION_TOKEN")); - ErrorNames.insert(std::make_pair(1310, "ERROR_CANT_DISABLE_MANDATORY")); - ErrorNames.insert(std::make_pair(1311, "ERROR_NO_LOGON_SERVERS")); - ErrorNames.insert(std::make_pair(1312, "ERROR_NO_SUCH_LOGON_SESSION")); - ErrorNames.insert(std::make_pair(1313, "ERROR_NO_SUCH_PRIVILEGE")); - ErrorNames.insert(std::make_pair(1314, "ERROR_PRIVILEGE_NOT_HELD")); - ErrorNames.insert(std::make_pair(1315, "ERROR_INVALID_ACCOUNT_NAME")); - ErrorNames.insert(std::make_pair(1316, "ERROR_USER_EXISTS")); - ErrorNames.insert(std::make_pair(1317, "ERROR_NO_SUCH_USER")); - ErrorNames.insert(std::make_pair(1318, "ERROR_GROUP_EXISTS")); - ErrorNames.insert(std::make_pair(1319, "ERROR_NO_SUCH_GROUP")); - ErrorNames.insert(std::make_pair(1320, "ERROR_MEMBER_IN_GROUP")); - ErrorNames.insert(std::make_pair(1321, "ERROR_MEMBER_NOT_IN_GROUP")); - ErrorNames.insert(std::make_pair(1322, "ERROR_LAST_ADMIN")); - ErrorNames.insert(std::make_pair(1323, "ERROR_WRONG_PASSWORD")); - ErrorNames.insert(std::make_pair(1324, "ERROR_ILL_FORMED_PASSWORD")); - ErrorNames.insert(std::make_pair(1325, "ERROR_PASSWORD_RESTRICTION")); - ErrorNames.insert(std::make_pair(1326, "ERROR_LOGON_FAILURE")); - ErrorNames.insert(std::make_pair(1327, "ERROR_ACCOUNT_RESTRICTION")); - ErrorNames.insert(std::make_pair(1328, "ERROR_INVALID_LOGON_HOURS")); - ErrorNames.insert(std::make_pair(1329, "ERROR_INVALID_WORKSTATION")); - ErrorNames.insert(std::make_pair(1330, "ERROR_PASSWORD_EXPIRED")); - ErrorNames.insert(std::make_pair(1331, "ERROR_ACCOUNT_DISABLED")); - ErrorNames.insert(std::make_pair(1332, "ERROR_NONE_MAPPED")); - ErrorNames.insert(std::make_pair(1333, "ERROR_TOO_MANY_LUIDS_REQUESTED")); - ErrorNames.insert(std::make_pair(1334, "ERROR_LUIDS_EXHAUSTED")); - ErrorNames.insert(std::make_pair(1335, "ERROR_INVALID_SUB_AUTHORITY")); - ErrorNames.insert(std::make_pair(1336, "ERROR_INVALID_ACL")); - ErrorNames.insert(std::make_pair(1337, "ERROR_INVALID_SID")); - ErrorNames.insert(std::make_pair(1338, "ERROR_INVALID_SECURITY_DESCR")); - ErrorNames.insert(std::make_pair(1340, "ERROR_BAD_INHERITANCE_ACL")); - ErrorNames.insert(std::make_pair(1341, "ERROR_SERVER_DISABLED")); - ErrorNames.insert(std::make_pair(1342, "ERROR_SERVER_NOT_DISABLED")); - ErrorNames.insert(std::make_pair(1343, "ERROR_INVALID_ID_AUTHORITY")); - ErrorNames.insert(std::make_pair(1344, "ERROR_ALLOTTED_SPACE_EXCEEDED")); - ErrorNames.insert(std::make_pair(1345, "ERROR_INVALID_GROUP_ATTRIBUTES")); - ErrorNames.insert(std::make_pair(1346, "ERROR_BAD_IMPERSONATION_LEVEL")); - ErrorNames.insert(std::make_pair(1347, "ERROR_CANT_OPEN_ANONYMOUS")); - ErrorNames.insert(std::make_pair(1348, "ERROR_BAD_VALIDATION_CLASS")); - ErrorNames.insert(std::make_pair(1349, "ERROR_BAD_TOKEN_TYPE")); - ErrorNames.insert(std::make_pair(1350, "ERROR_NO_SECURITY_ON_OBJECT")); - ErrorNames.insert(std::make_pair(1351, "ERROR_CANT_ACCESS_DOMAIN_INFO")); - ErrorNames.insert(std::make_pair(1352, "ERROR_INVALID_SERVER_STATE")); - ErrorNames.insert(std::make_pair(1353, "ERROR_INVALID_DOMAIN_STATE")); - ErrorNames.insert(std::make_pair(1354, "ERROR_INVALID_DOMAIN_ROLE")); - ErrorNames.insert(std::make_pair(1355, "ERROR_NO_SUCH_DOMAIN")); - ErrorNames.insert(std::make_pair(1356, "ERROR_DOMAIN_EXISTS")); - ErrorNames.insert(std::make_pair(1357, "ERROR_DOMAIN_LIMIT_EXCEEDED")); - ErrorNames.insert(std::make_pair(1358, "ERROR_INTERNAL_DB_CORRUPTION")); - ErrorNames.insert(std::make_pair(1359, "ERROR_INTERNAL_ERROR")); - ErrorNames.insert(std::make_pair(1360, "ERROR_GENERIC_NOT_MAPPED")); - ErrorNames.insert(std::make_pair(1361, "ERROR_BAD_DESCRIPTOR_FORMAT")); - ErrorNames.insert(std::make_pair(1362, "ERROR_NOT_LOGON_PROCESS")); - ErrorNames.insert(std::make_pair(1363, "ERROR_LOGON_SESSION_EXISTS")); - ErrorNames.insert(std::make_pair(1364, "ERROR_NO_SUCH_PACKAGE")); - ErrorNames.insert(std::make_pair(1365, "ERROR_BAD_LOGON_SESSION_STATE")); - ErrorNames.insert(std::make_pair(1366, "ERROR_LOGON_SESSION_COLLISION")); - ErrorNames.insert(std::make_pair(1367, "ERROR_INVALID_LOGON_TYPE")); - ErrorNames.insert(std::make_pair(1368, "ERROR_CANNOT_IMPERSONATE")); - ErrorNames.insert(std::make_pair(1369, "ERROR_RXACT_INVALID_STATE")); - ErrorNames.insert(std::make_pair(1370, "ERROR_RXACT_COMMIT_FAILURE")); - ErrorNames.insert(std::make_pair(1371, "ERROR_SPECIAL_ACCOUNT")); - ErrorNames.insert(std::make_pair(1372, "ERROR_SPECIAL_GROUP")); - ErrorNames.insert(std::make_pair(1373, "ERROR_SPECIAL_USER")); - ErrorNames.insert(std::make_pair(1374, "ERROR_MEMBERS_PRIMARY_GROUP")); - ErrorNames.insert(std::make_pair(1375, "ERROR_TOKEN_ALREADY_IN_USE")); - ErrorNames.insert(std::make_pair(1376, "ERROR_NO_SUCH_ALIAS")); - ErrorNames.insert(std::make_pair(1377, "ERROR_MEMBER_NOT_IN_ALIAS")); - ErrorNames.insert(std::make_pair(1378, "ERROR_MEMBER_IN_ALIAS")); - ErrorNames.insert(std::make_pair(1379, "ERROR_ALIAS_EXISTS")); - ErrorNames.insert(std::make_pair(1380, "ERROR_LOGON_NOT_GRANTED")); - ErrorNames.insert(std::make_pair(1381, "ERROR_TOO_MANY_SECRETS")); - ErrorNames.insert(std::make_pair(1382, "ERROR_SECRET_TOO_LONG")); - ErrorNames.insert(std::make_pair(1383, "ERROR_INTERNAL_DB_ERROR")); - ErrorNames.insert(std::make_pair(1384, "ERROR_TOO_MANY_CONTEXT_IDS")); - ErrorNames.insert(std::make_pair(1385, "ERROR_LOGON_TYPE_NOT_GRANTED")); - ErrorNames.insert(std::make_pair(1386, "ERROR_NT_CROSS_ENCRYPTION_REQUIRED")); - ErrorNames.insert(std::make_pair(1387, "ERROR_NO_SUCH_MEMBER")); - ErrorNames.insert(std::make_pair(1388, "ERROR_INVALID_MEMBER")); - ErrorNames.insert(std::make_pair(1389, "ERROR_TOO_MANY_SIDS")); - ErrorNames.insert(std::make_pair(1390, "ERROR_LM_CROSS_ENCRYPTION_REQUIRED")); - ErrorNames.insert(std::make_pair(1391, "ERROR_NO_INHERITANCE")); - ErrorNames.insert(std::make_pair(1392, "ERROR_FILE_CORRUPT")); - ErrorNames.insert(std::make_pair(1393, "ERROR_DISK_CORRUPT")); - ErrorNames.insert(std::make_pair(1394, "ERROR_NO_USER_SESSION_KEY")); - ErrorNames.insert(std::make_pair(1395, "ERROR_LICENSE_QUOTA_EXCEEDED")); - ErrorNames.insert(std::make_pair(1396, "ERROR_WRONG_TARGET_NAME")); - ErrorNames.insert(std::make_pair(1397, "ERROR_MUTUAL_AUTH_FAILED")); - ErrorNames.insert(std::make_pair(1398, "ERROR_TIME_SKEW")); - ErrorNames.insert(std::make_pair(1399, "ERROR_CURRENT_DOMAIN_NOT_ALLOWED")); - ErrorNames.insert(std::make_pair(1400, "ERROR_INVALID_WINDOW_HANDLE")); - ErrorNames.insert(std::make_pair(1401, "ERROR_INVALID_MENU_HANDLE")); - ErrorNames.insert(std::make_pair(1402, "ERROR_INVALID_CURSOR_HANDLE")); - ErrorNames.insert(std::make_pair(1403, "ERROR_INVALID_ACCEL_HANDLE")); - ErrorNames.insert(std::make_pair(1404, "ERROR_INVALID_HOOK_HANDLE")); - ErrorNames.insert(std::make_pair(1405, "ERROR_INVALID_DWP_HANDLE")); - ErrorNames.insert(std::make_pair(1406, "ERROR_TLW_WITH_WSCHILD")); - ErrorNames.insert(std::make_pair(1407, "ERROR_CANNOT_FIND_WND_CLASS")); - ErrorNames.insert(std::make_pair(1408, "ERROR_WINDOW_OF_OTHER_THREAD")); - ErrorNames.insert(std::make_pair(1409, "ERROR_HOTKEY_ALREADY_REGISTERED")); - ErrorNames.insert(std::make_pair(1410, "ERROR_CLASS_ALREADY_EXISTS")); - ErrorNames.insert(std::make_pair(1411, "ERROR_CLASS_DOES_NOT_EXIST")); - ErrorNames.insert(std::make_pair(1412, "ERROR_CLASS_HAS_WINDOWS")); - ErrorNames.insert(std::make_pair(1413, "ERROR_INVALID_INDEX")); - ErrorNames.insert(std::make_pair(1414, "ERROR_INVALID_ICON_HANDLE")); - ErrorNames.insert(std::make_pair(1415, "ERROR_PRIVATE_DIALOG_INDEX")); - ErrorNames.insert(std::make_pair(1416, "ERROR_LISTBOX_ID_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1417, "ERROR_NO_WILDCARD_CHARACTERS")); - ErrorNames.insert(std::make_pair(1418, "ERROR_CLIPBOARD_NOT_OPEN")); - ErrorNames.insert(std::make_pair(1419, "ERROR_HOTKEY_NOT_REGISTERED")); - ErrorNames.insert(std::make_pair(1420, "ERROR_WINDOW_NOT_DIALOG")); - ErrorNames.insert(std::make_pair(1421, "ERROR_CONTROL_ID_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1422, "ERROR_INVALID_COMBOBOX_MESSAGE")); - ErrorNames.insert(std::make_pair(1423, "ERROR_WINDOW_NOT_COMBOBOX")); - ErrorNames.insert(std::make_pair(1424, "ERROR_INVALID_EDIT_HEIGHT")); - ErrorNames.insert(std::make_pair(1425, "ERROR_DC_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1426, "ERROR_INVALID_HOOK_FILTER")); - ErrorNames.insert(std::make_pair(1427, "ERROR_INVALID_FILTER_PROC")); - ErrorNames.insert(std::make_pair(1428, "ERROR_HOOK_NEEDS_HMOD")); - ErrorNames.insert(std::make_pair(1429, "ERROR_GLOBAL_ONLY_HOOK")); - ErrorNames.insert(std::make_pair(1430, "ERROR_JOURNAL_HOOK_SET")); - ErrorNames.insert(std::make_pair(1431, "ERROR_HOOK_NOT_INSTALLED")); - ErrorNames.insert(std::make_pair(1432, "ERROR_INVALID_LB_MESSAGE")); - ErrorNames.insert(std::make_pair(1433, "ERROR_SETCOUNT_ON_BAD_LB")); - ErrorNames.insert(std::make_pair(1434, "ERROR_LB_WITHOUT_TABSTOPS")); - ErrorNames.insert(std::make_pair(1435, "ERROR_DESTROY_OBJECT_OF_OTHER_THREAD")); - ErrorNames.insert(std::make_pair(1436, "ERROR_CHILD_WINDOW_MENU")); - ErrorNames.insert(std::make_pair(1437, "ERROR_NO_SYSTEM_MENU")); - ErrorNames.insert(std::make_pair(1438, "ERROR_INVALID_MSGBOX_STYLE")); - ErrorNames.insert(std::make_pair(1439, "ERROR_INVALID_SPI_VALUE")); - ErrorNames.insert(std::make_pair(1440, "ERROR_SCREEN_ALREADY_LOCKED")); - ErrorNames.insert(std::make_pair(1441, "ERROR_HWNDS_HAVE_DIFF_PARENT")); - ErrorNames.insert(std::make_pair(1442, "ERROR_NOT_CHILD_WINDOW")); - ErrorNames.insert(std::make_pair(1443, "ERROR_INVALID_GW_COMMAND")); - ErrorNames.insert(std::make_pair(1444, "ERROR_INVALID_THREAD_ID")); - ErrorNames.insert(std::make_pair(1445, "ERROR_NON_MDICHILD_WINDOW")); - ErrorNames.insert(std::make_pair(1446, "ERROR_POPUP_ALREADY_ACTIVE")); - ErrorNames.insert(std::make_pair(1447, "ERROR_NO_SCROLLBARS")); - ErrorNames.insert(std::make_pair(1448, "ERROR_INVALID_SCROLLBAR_RANGE")); - ErrorNames.insert(std::make_pair(1449, "ERROR_INVALID_SHOWWIN_COMMAND")); - ErrorNames.insert(std::make_pair(1450, "ERROR_NO_SYSTEM_RESOURCES")); - ErrorNames.insert(std::make_pair(1451, "ERROR_NONPAGED_SYSTEM_RESOURCES")); - ErrorNames.insert(std::make_pair(1452, "ERROR_PAGED_SYSTEM_RESOURCES")); - ErrorNames.insert(std::make_pair(1453, "ERROR_WORKING_SET_QUOTA")); - ErrorNames.insert(std::make_pair(1454, "ERROR_PAGEFILE_QUOTA")); - ErrorNames.insert(std::make_pair(1455, "ERROR_COMMITMENT_LIMIT")); - ErrorNames.insert(std::make_pair(1456, "ERROR_MENU_ITEM_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1457, "ERROR_INVALID_KEYBOARD_HANDLE")); - ErrorNames.insert(std::make_pair(1458, "ERROR_HOOK_TYPE_NOT_ALLOWED")); - ErrorNames.insert(std::make_pair(1459, "ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION")); - ErrorNames.insert(std::make_pair(1460, "ERROR_TIMEOUT")); - ErrorNames.insert(std::make_pair(1461, "ERROR_INVALID_MONITOR_HANDLE")); - ErrorNames.insert(std::make_pair(1462, "ERROR_INCORRECT_SIZE")); - ErrorNames.insert(std::make_pair(1463, "ERROR_SYMLINK_CLASS_DISABLED")); - ErrorNames.insert(std::make_pair(1464, "ERROR_SYMLINK_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(1465, "ERROR_XML_PARSE_ERROR")); - ErrorNames.insert(std::make_pair(1466, "ERROR_XMLDSIG_ERROR")); - ErrorNames.insert(std::make_pair(1467, "ERROR_RESTART_APPLICATION")); - ErrorNames.insert(std::make_pair(1468, "ERROR_WRONG_COMPARTMENT")); - ErrorNames.insert(std::make_pair(1469, "ERROR_AUTHIP_FAILURE")); - ErrorNames.insert(std::make_pair(1470, "ERROR_NO_NVRAM_RESOURCES")); - ErrorNames.insert(std::make_pair(1500, "ERROR_EVENTLOG_FILE_CORRUPT")); - ErrorNames.insert(std::make_pair(1501, "ERROR_EVENTLOG_CANT_START")); - ErrorNames.insert(std::make_pair(1502, "ERROR_LOG_FILE_FULL")); - ErrorNames.insert(std::make_pair(1503, "ERROR_EVENTLOG_FILE_CHANGED")); - ErrorNames.insert(std::make_pair(1550, "ERROR_INVALID_TASK_NAME")); - ErrorNames.insert(std::make_pair(1551, "ERROR_INVALID_TASK_INDEX")); - ErrorNames.insert(std::make_pair(1552, "ERROR_THREAD_ALREADY_IN_TASK")); - ErrorNames.insert(std::make_pair(1601, "ERROR_INSTALL_SERVICE_FAILURE")); - ErrorNames.insert(std::make_pair(1602, "ERROR_INSTALL_USEREXIT")); - ErrorNames.insert(std::make_pair(1603, "ERROR_INSTALL_FAILURE")); - ErrorNames.insert(std::make_pair(1604, "ERROR_INSTALL_SUSPEND")); - ErrorNames.insert(std::make_pair(1605, "ERROR_UNKNOWN_PRODUCT")); - ErrorNames.insert(std::make_pair(1606, "ERROR_UNKNOWN_FEATURE")); - ErrorNames.insert(std::make_pair(1607, "ERROR_UNKNOWN_COMPONENT")); - ErrorNames.insert(std::make_pair(1608, "ERROR_UNKNOWN_PROPERTY")); - ErrorNames.insert(std::make_pair(1609, "ERROR_INVALID_HANDLE_STATE")); - ErrorNames.insert(std::make_pair(1610, "ERROR_BAD_CONFIGURATION")); - ErrorNames.insert(std::make_pair(1611, "ERROR_INDEX_ABSENT")); - ErrorNames.insert(std::make_pair(1612, "ERROR_INSTALL_SOURCE_ABSENT")); - ErrorNames.insert(std::make_pair(1613, "ERROR_INSTALL_PACKAGE_VERSION")); - ErrorNames.insert(std::make_pair(1614, "ERROR_PRODUCT_UNINSTALLED")); - ErrorNames.insert(std::make_pair(1615, "ERROR_BAD_QUERY_SYNTAX")); - ErrorNames.insert(std::make_pair(1616, "ERROR_INVALID_FIELD")); - ErrorNames.insert(std::make_pair(1617, "ERROR_DEVICE_REMOVED")); - ErrorNames.insert(std::make_pair(1618, "ERROR_INSTALL_ALREADY_RUNNING")); - ErrorNames.insert(std::make_pair(1619, "ERROR_INSTALL_PACKAGE_OPEN_FAILED")); - ErrorNames.insert(std::make_pair(1620, "ERROR_INSTALL_PACKAGE_INVALID")); - ErrorNames.insert(std::make_pair(1621, "ERROR_INSTALL_UI_FAILURE")); - ErrorNames.insert(std::make_pair(1622, "ERROR_INSTALL_LOG_FAILURE")); - ErrorNames.insert(std::make_pair(1623, "ERROR_INSTALL_LANGUAGE_UNSUPPORTED")); - ErrorNames.insert(std::make_pair(1624, "ERROR_INSTALL_TRANSFORM_FAILURE")); - ErrorNames.insert(std::make_pair(1625, "ERROR_INSTALL_PACKAGE_REJECTED")); - ErrorNames.insert(std::make_pair(1626, "ERROR_FUNCTION_NOT_CALLED")); - ErrorNames.insert(std::make_pair(1627, "ERROR_FUNCTION_FAILED")); - ErrorNames.insert(std::make_pair(1628, "ERROR_INVALID_TABLE")); - ErrorNames.insert(std::make_pair(1629, "ERROR_DATATYPE_MISMATCH")); - ErrorNames.insert(std::make_pair(1630, "ERROR_UNSUPPORTED_TYPE")); - ErrorNames.insert(std::make_pair(1631, "ERROR_CREATE_FAILED")); - ErrorNames.insert(std::make_pair(1632, "ERROR_INSTALL_TEMP_UNWRITABLE")); - ErrorNames.insert(std::make_pair(1633, "ERROR_INSTALL_PLATFORM_UNSUPPORTED")); - ErrorNames.insert(std::make_pair(1634, "ERROR_INSTALL_NOTUSED")); - ErrorNames.insert(std::make_pair(1635, "ERROR_PATCH_PACKAGE_OPEN_FAILED")); - ErrorNames.insert(std::make_pair(1636, "ERROR_PATCH_PACKAGE_INVALID")); - ErrorNames.insert(std::make_pair(1637, "ERROR_PATCH_PACKAGE_UNSUPPORTED")); - ErrorNames.insert(std::make_pair(1638, "ERROR_PRODUCT_VERSION")); - ErrorNames.insert(std::make_pair(1639, "ERROR_INVALID_COMMAND_LINE")); - ErrorNames.insert(std::make_pair(1640, "ERROR_INSTALL_REMOTE_DISALLOWED")); - ErrorNames.insert(std::make_pair(1641, "ERROR_SUCCESS_REBOOT_INITIATED")); - ErrorNames.insert(std::make_pair(1642, "ERROR_PATCH_TARGET_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1643, "ERROR_PATCH_PACKAGE_REJECTED")); - ErrorNames.insert(std::make_pair(1644, "ERROR_INSTALL_TRANSFORM_REJECTED")); - ErrorNames.insert(std::make_pair(1645, "ERROR_INSTALL_REMOTE_PROHIBITED")); - ErrorNames.insert(std::make_pair(1646, "ERROR_PATCH_REMOVAL_UNSUPPORTED")); - ErrorNames.insert(std::make_pair(1647, "ERROR_UNKNOWN_PATCH")); - ErrorNames.insert(std::make_pair(1648, "ERROR_PATCH_NO_SEQUENCE")); - ErrorNames.insert(std::make_pair(1649, "ERROR_PATCH_REMOVAL_DISALLOWED")); - ErrorNames.insert(std::make_pair(1650, "ERROR_INVALID_PATCH_XML")); - ErrorNames.insert(std::make_pair(1651, "ERROR_PATCH_MANAGED_ADVERTISED_PRODUCT")); - ErrorNames.insert(std::make_pair(1652, "ERROR_INSTALL_SERVICE_SAFEBOOT")); - ErrorNames.insert(std::make_pair(1653, "ERROR_FAIL_FAST_EXCEPTION")); - ErrorNames.insert(std::make_pair(1784, "ERROR_INVALID_USER_BUFFER")); - ErrorNames.insert(std::make_pair(1785, "ERROR_UNRECOGNIZED_MEDIA")); - ErrorNames.insert(std::make_pair(1786, "ERROR_NO_TRUST_LSA_SECRET")); - ErrorNames.insert(std::make_pair(1787, "ERROR_NO_TRUST_SAM_ACCOUNT")); - ErrorNames.insert(std::make_pair(1788, "ERROR_TRUSTED_DOMAIN_FAILURE")); - ErrorNames.insert(std::make_pair(1789, "ERROR_TRUSTED_RELATIONSHIP_FAILURE")); - ErrorNames.insert(std::make_pair(1790, "ERROR_TRUST_FAILURE")); - ErrorNames.insert(std::make_pair(1792, "ERROR_NETLOGON_NOT_STARTED")); - ErrorNames.insert(std::make_pair(1793, "ERROR_ACCOUNT_EXPIRED")); - ErrorNames.insert(std::make_pair(1794, "ERROR_REDIRECTOR_HAS_OPEN_HANDLES")); - ErrorNames.insert(std::make_pair(1795, "ERROR_PRINTER_DRIVER_ALREADY_INSTALLED")); - ErrorNames.insert(std::make_pair(1796, "ERROR_UNKNOWN_PORT")); - ErrorNames.insert(std::make_pair(1797, "ERROR_UNKNOWN_PRINTER_DRIVER")); - ErrorNames.insert(std::make_pair(1798, "ERROR_UNKNOWN_PRINTPROCESSOR")); - ErrorNames.insert(std::make_pair(1799, "ERROR_INVALID_SEPARATOR_FILE")); - ErrorNames.insert(std::make_pair(1800, "ERROR_INVALID_PRIORITY")); - ErrorNames.insert(std::make_pair(1801, "ERROR_INVALID_PRINTER_NAME")); - ErrorNames.insert(std::make_pair(1802, "ERROR_PRINTER_ALREADY_EXISTS")); - ErrorNames.insert(std::make_pair(1803, "ERROR_INVALID_PRINTER_COMMAND")); - ErrorNames.insert(std::make_pair(1804, "ERROR_INVALID_DATATYPE")); - ErrorNames.insert(std::make_pair(1805, "ERROR_INVALID_ENVIRONMENT")); - ErrorNames.insert(std::make_pair(1807, "ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT")); - ErrorNames.insert(std::make_pair(1808, "ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT")); - ErrorNames.insert(std::make_pair(1809, "ERROR_NOLOGON_SERVER_TRUST_ACCOUNT")); - ErrorNames.insert(std::make_pair(1810, "ERROR_DOMAIN_TRUST_INCONSISTENT")); - ErrorNames.insert(std::make_pair(1811, "ERROR_SERVER_HAS_OPEN_HANDLES")); - ErrorNames.insert(std::make_pair(1812, "ERROR_RESOURCE_DATA_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1813, "ERROR_RESOURCE_TYPE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1814, "ERROR_RESOURCE_NAME_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1815, "ERROR_RESOURCE_LANG_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1816, "ERROR_NOT_ENOUGH_QUOTA")); - ErrorNames.insert(std::make_pair(1901, "ERROR_INVALID_TIME")); - ErrorNames.insert(std::make_pair(1902, "ERROR_INVALID_FORM_NAME")); - ErrorNames.insert(std::make_pair(1903, "ERROR_INVALID_FORM_SIZE")); - ErrorNames.insert(std::make_pair(1904, "ERROR_ALREADY_WAITING")); - ErrorNames.insert(std::make_pair(1905, "ERROR_PRINTER_DELETED")); - ErrorNames.insert(std::make_pair(1906, "ERROR_INVALID_PRINTER_STATE")); - ErrorNames.insert(std::make_pair(1907, "ERROR_PASSWORD_MUST_CHANGE")); - ErrorNames.insert(std::make_pair(1908, "ERROR_DOMAIN_CONTROLLER_NOT_FOUND")); - ErrorNames.insert(std::make_pair(1909, "ERROR_ACCOUNT_LOCKED_OUT")); - ErrorNames.insert(std::make_pair(1919, "ERROR_NO_SITENAME")); - ErrorNames.insert(std::make_pair(1920, "ERROR_CANT_ACCESS_FILE")); - ErrorNames.insert(std::make_pair(1921, "ERROR_CANT_RESOLVE_FILENAME")); - ErrorNames.insert(std::make_pair(1930, "ERROR_KM_DRIVER_BLOCKED")); - ErrorNames.insert(std::make_pair(1931, "ERROR_CONTEXT_EXPIRED")); - ErrorNames.insert(std::make_pair(1932, "ERROR_PER_USER_TRUST_QUOTA_EXCEEDED")); - ErrorNames.insert(std::make_pair(1933, "ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED")); - ErrorNames.insert(std::make_pair(1934, "ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED")); - ErrorNames.insert(std::make_pair(1935, "ERROR_AUTHENTICATION_FIREWALL_FAILED")); - ErrorNames.insert(std::make_pair(1936, "ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED")); - ErrorNames.insert(std::make_pair(1937, "ERROR_NTLM_BLOCKED")); - ErrorNames.insert(std::make_pair(2000, "ERROR_INVALID_PIXEL_FORMAT")); - ErrorNames.insert(std::make_pair(2001, "ERROR_BAD_DRIVER")); - ErrorNames.insert(std::make_pair(2002, "ERROR_INVALID_WINDOW_STYLE")); - ErrorNames.insert(std::make_pair(2003, "ERROR_METAFILE_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(2004, "ERROR_TRANSFORM_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(2005, "ERROR_CLIPPING_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(2010, "ERROR_INVALID_CMM")); - ErrorNames.insert(std::make_pair(2011, "ERROR_INVALID_PROFILE")); - ErrorNames.insert(std::make_pair(2012, "ERROR_TAG_NOT_FOUND")); - ErrorNames.insert(std::make_pair(2013, "ERROR_TAG_NOT_PRESENT")); - ErrorNames.insert(std::make_pair(2014, "ERROR_DUPLICATE_TAG")); - ErrorNames.insert(std::make_pair(2015, "ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE")); - ErrorNames.insert(std::make_pair(2016, "ERROR_PROFILE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(2017, "ERROR_INVALID_COLORSPACE")); - ErrorNames.insert(std::make_pair(2018, "ERROR_ICM_NOT_ENABLED")); - ErrorNames.insert(std::make_pair(2019, "ERROR_DELETING_ICM_XFORM")); - ErrorNames.insert(std::make_pair(2020, "ERROR_INVALID_TRANSFORM")); - ErrorNames.insert(std::make_pair(2021, "ERROR_COLORSPACE_MISMATCH")); - ErrorNames.insert(std::make_pair(2022, "ERROR_INVALID_COLORINDEX")); - ErrorNames.insert(std::make_pair(2023, "ERROR_PROFILE_DOES_NOT_MATCH_DEVICE")); - ErrorNames.insert(std::make_pair(2108, "ERROR_CONNECTED_OTHER_PASSWORD")); - ErrorNames.insert(std::make_pair(2109, "ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT")); - ErrorNames.insert(std::make_pair(2202, "ERROR_BAD_USERNAME")); - ErrorNames.insert(std::make_pair(2250, "ERROR_NOT_CONNECTED")); - ErrorNames.insert(std::make_pair(2401, "ERROR_OPEN_FILES")); - ErrorNames.insert(std::make_pair(2402, "ERROR_ACTIVE_CONNECTIONS")); - ErrorNames.insert(std::make_pair(2404, "ERROR_DEVICE_IN_USE")); - ErrorNames.insert(std::make_pair(3000, "ERROR_UNKNOWN_PRINT_MONITOR")); - ErrorNames.insert(std::make_pair(3001, "ERROR_PRINTER_DRIVER_IN_USE")); - ErrorNames.insert(std::make_pair(3002, "ERROR_SPOOL_FILE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(3003, "ERROR_SPL_NO_STARTDOC")); - ErrorNames.insert(std::make_pair(3004, "ERROR_SPL_NO_ADDJOB")); - ErrorNames.insert(std::make_pair(3005, "ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED")); - ErrorNames.insert(std::make_pair(3006, "ERROR_PRINT_MONITOR_ALREADY_INSTALLED")); - ErrorNames.insert(std::make_pair(3007, "ERROR_INVALID_PRINT_MONITOR")); - ErrorNames.insert(std::make_pair(3008, "ERROR_PRINT_MONITOR_IN_USE")); - ErrorNames.insert(std::make_pair(3009, "ERROR_PRINTER_HAS_JOBS_QUEUED")); - ErrorNames.insert(std::make_pair(3010, "ERROR_SUCCESS_REBOOT_REQUIRED")); - ErrorNames.insert(std::make_pair(3011, "ERROR_SUCCESS_RESTART_REQUIRED")); - ErrorNames.insert(std::make_pair(3012, "ERROR_PRINTER_NOT_FOUND")); - ErrorNames.insert(std::make_pair(3013, "ERROR_PRINTER_DRIVER_WARNED")); - ErrorNames.insert(std::make_pair(3014, "ERROR_PRINTER_DRIVER_BLOCKED")); - ErrorNames.insert(std::make_pair(3015, "ERROR_PRINTER_DRIVER_PACKAGE_IN_USE")); - ErrorNames.insert(std::make_pair(3016, "ERROR_CORE_DRIVER_PACKAGE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(3017, "ERROR_FAIL_REBOOT_REQUIRED")); - ErrorNames.insert(std::make_pair(3018, "ERROR_FAIL_REBOOT_INITIATED")); - ErrorNames.insert(std::make_pair(3019, "ERROR_PRINTER_DRIVER_DOWNLOAD_NEEDED")); - ErrorNames.insert(std::make_pair(3020, "ERROR_PRINT_JOB_RESTART_REQUIRED")); - ErrorNames.insert(std::make_pair(3950, "ERROR_IO_REISSUE_AS_CACHED")); - ErrorNames.insert(std::make_pair(4000, "ERROR_WINS_INTERNAL")); - ErrorNames.insert(std::make_pair(4001, "ERROR_CAN_NOT_DEL_LOCAL_WINS")); - ErrorNames.insert(std::make_pair(4002, "ERROR_STATIC_INIT")); - ErrorNames.insert(std::make_pair(4003, "ERROR_INC_BACKUP")); - ErrorNames.insert(std::make_pair(4004, "ERROR_FULL_BACKUP")); - ErrorNames.insert(std::make_pair(4005, "ERROR_REC_NON_EXISTENT")); - ErrorNames.insert(std::make_pair(4006, "ERROR_RPL_NOT_ALLOWED")); - ErrorNames.insert(std::make_pair(4100, "ERROR_DHCP_ADDRESS_CONFLICT")); - ErrorNames.insert(std::make_pair(4200, "ERROR_WMI_GUID_NOT_FOUND")); - ErrorNames.insert(std::make_pair(4201, "ERROR_WMI_INSTANCE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(4202, "ERROR_WMI_ITEMID_NOT_FOUND")); - ErrorNames.insert(std::make_pair(4203, "ERROR_WMI_TRY_AGAIN")); - ErrorNames.insert(std::make_pair(4204, "ERROR_WMI_DP_NOT_FOUND")); - ErrorNames.insert(std::make_pair(4205, "ERROR_WMI_UNRESOLVED_INSTANCE_REF")); - ErrorNames.insert(std::make_pair(4206, "ERROR_WMI_ALREADY_ENABLED")); - ErrorNames.insert(std::make_pair(4207, "ERROR_WMI_GUID_DISCONNECTED")); - ErrorNames.insert(std::make_pair(4208, "ERROR_WMI_SERVER_UNAVAILABLE")); - ErrorNames.insert(std::make_pair(4209, "ERROR_WMI_DP_FAILED")); - ErrorNames.insert(std::make_pair(4210, "ERROR_WMI_INVALID_MOF")); - ErrorNames.insert(std::make_pair(4211, "ERROR_WMI_INVALID_REGINFO")); - ErrorNames.insert(std::make_pair(4212, "ERROR_WMI_ALREADY_DISABLED")); - ErrorNames.insert(std::make_pair(4213, "ERROR_WMI_READ_ONLY")); - ErrorNames.insert(std::make_pair(4214, "ERROR_WMI_SET_FAILURE")); - ErrorNames.insert(std::make_pair(4300, "ERROR_INVALID_MEDIA")); - ErrorNames.insert(std::make_pair(4301, "ERROR_INVALID_LIBRARY")); - ErrorNames.insert(std::make_pair(4302, "ERROR_INVALID_MEDIA_POOL")); - ErrorNames.insert(std::make_pair(4303, "ERROR_DRIVE_MEDIA_MISMATCH")); - ErrorNames.insert(std::make_pair(4304, "ERROR_MEDIA_OFFLINE")); - ErrorNames.insert(std::make_pair(4305, "ERROR_LIBRARY_OFFLINE")); - ErrorNames.insert(std::make_pair(4306, "ERROR_EMPTY")); - ErrorNames.insert(std::make_pair(4307, "ERROR_NOT_EMPTY")); - ErrorNames.insert(std::make_pair(4308, "ERROR_MEDIA_UNAVAILABLE")); - ErrorNames.insert(std::make_pair(4309, "ERROR_RESOURCE_DISABLED")); - ErrorNames.insert(std::make_pair(4310, "ERROR_INVALID_CLEANER")); - ErrorNames.insert(std::make_pair(4311, "ERROR_UNABLE_TO_CLEAN")); - ErrorNames.insert(std::make_pair(4312, "ERROR_OBJECT_NOT_FOUND")); - ErrorNames.insert(std::make_pair(4313, "ERROR_DATABASE_FAILURE")); - ErrorNames.insert(std::make_pair(4314, "ERROR_DATABASE_FULL")); - ErrorNames.insert(std::make_pair(4315, "ERROR_MEDIA_INCOMPATIBLE")); - ErrorNames.insert(std::make_pair(4316, "ERROR_RESOURCE_NOT_PRESENT")); - ErrorNames.insert(std::make_pair(4317, "ERROR_INVALID_OPERATION")); - ErrorNames.insert(std::make_pair(4318, "ERROR_MEDIA_NOT_AVAILABLE")); - ErrorNames.insert(std::make_pair(4319, "ERROR_DEVICE_NOT_AVAILABLE")); - ErrorNames.insert(std::make_pair(4320, "ERROR_REQUEST_REFUSED")); - ErrorNames.insert(std::make_pair(4321, "ERROR_INVALID_DRIVE_OBJECT")); - ErrorNames.insert(std::make_pair(4322, "ERROR_LIBRARY_FULL")); - ErrorNames.insert(std::make_pair(4323, "ERROR_MEDIUM_NOT_ACCESSIBLE")); - ErrorNames.insert(std::make_pair(4324, "ERROR_UNABLE_TO_LOAD_MEDIUM")); - ErrorNames.insert(std::make_pair(4325, "ERROR_UNABLE_TO_INVENTORY_DRIVE")); - ErrorNames.insert(std::make_pair(4326, "ERROR_UNABLE_TO_INVENTORY_SLOT")); - ErrorNames.insert(std::make_pair(4327, "ERROR_UNABLE_TO_INVENTORY_TRANSPORT")); - ErrorNames.insert(std::make_pair(4328, "ERROR_TRANSPORT_FULL")); - ErrorNames.insert(std::make_pair(4329, "ERROR_CONTROLLING_IEPORT")); - ErrorNames.insert(std::make_pair(4330, "ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA")); - ErrorNames.insert(std::make_pair(4331, "ERROR_CLEANER_SLOT_SET")); - ErrorNames.insert(std::make_pair(4332, "ERROR_CLEANER_SLOT_NOT_SET")); - ErrorNames.insert(std::make_pair(4333, "ERROR_CLEANER_CARTRIDGE_SPENT")); - ErrorNames.insert(std::make_pair(4334, "ERROR_UNEXPECTED_OMID")); - ErrorNames.insert(std::make_pair(4335, "ERROR_CANT_DELETE_LAST_ITEM")); - ErrorNames.insert(std::make_pair(4336, "ERROR_MESSAGE_EXCEEDS_MAX_SIZE")); - ErrorNames.insert(std::make_pair(4337, "ERROR_VOLUME_CONTAINS_SYS_FILES")); - ErrorNames.insert(std::make_pair(4338, "ERROR_INDIGENOUS_TYPE")); - ErrorNames.insert(std::make_pair(4339, "ERROR_NO_SUPPORTING_DRIVES")); - ErrorNames.insert(std::make_pair(4340, "ERROR_CLEANER_CARTRIDGE_INSTALLED")); - ErrorNames.insert(std::make_pair(4341, "ERROR_IEPORT_FULL")); - ErrorNames.insert(std::make_pair(4350, "ERROR_FILE_OFFLINE")); - ErrorNames.insert(std::make_pair(4351, "ERROR_REMOTE_STORAGE_NOT_ACTIVE")); - ErrorNames.insert(std::make_pair(4352, "ERROR_REMOTE_STORAGE_MEDIA_ERROR")); - ErrorNames.insert(std::make_pair(4390, "ERROR_NOT_A_REPARSE_POINT")); - ErrorNames.insert(std::make_pair(4391, "ERROR_REPARSE_ATTRIBUTE_CONFLICT")); - ErrorNames.insert(std::make_pair(4392, "ERROR_INVALID_REPARSE_DATA")); - ErrorNames.insert(std::make_pair(4393, "ERROR_REPARSE_TAG_INVALID")); - ErrorNames.insert(std::make_pair(4394, "ERROR_REPARSE_TAG_MISMATCH")); - ErrorNames.insert(std::make_pair(4500, "ERROR_VOLUME_NOT_SIS_ENABLED")); - ErrorNames.insert(std::make_pair(5001, "ERROR_DEPENDENT_RESOURCE_EXISTS")); - ErrorNames.insert(std::make_pair(5002, "ERROR_DEPENDENCY_NOT_FOUND")); - ErrorNames.insert(std::make_pair(5003, "ERROR_DEPENDENCY_ALREADY_EXISTS")); - ErrorNames.insert(std::make_pair(5004, "ERROR_RESOURCE_NOT_ONLINE")); - ErrorNames.insert(std::make_pair(5005, "ERROR_HOST_NODE_NOT_AVAILABLE")); - ErrorNames.insert(std::make_pair(5006, "ERROR_RESOURCE_NOT_AVAILABLE")); - ErrorNames.insert(std::make_pair(5007, "ERROR_RESOURCE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(5008, "ERROR_SHUTDOWN_CLUSTER")); - ErrorNames.insert(std::make_pair(5009, "ERROR_CANT_EVICT_ACTIVE_NODE")); - ErrorNames.insert(std::make_pair(5010, "ERROR_OBJECT_ALREADY_EXISTS")); - ErrorNames.insert(std::make_pair(5011, "ERROR_OBJECT_IN_LIST")); - ErrorNames.insert(std::make_pair(5012, "ERROR_GROUP_NOT_AVAILABLE")); - ErrorNames.insert(std::make_pair(5013, "ERROR_GROUP_NOT_FOUND")); - ErrorNames.insert(std::make_pair(5014, "ERROR_GROUP_NOT_ONLINE")); - ErrorNames.insert(std::make_pair(5015, "ERROR_HOST_NODE_NOT_RESOURCE_OWNER")); - ErrorNames.insert(std::make_pair(5016, "ERROR_HOST_NODE_NOT_GROUP_OWNER")); - ErrorNames.insert(std::make_pair(5017, "ERROR_RESMON_CREATE_FAILED")); - ErrorNames.insert(std::make_pair(5018, "ERROR_RESMON_ONLINE_FAILED")); - ErrorNames.insert(std::make_pair(5019, "ERROR_RESOURCE_ONLINE")); - ErrorNames.insert(std::make_pair(5020, "ERROR_QUORUM_RESOURCE")); - ErrorNames.insert(std::make_pair(5021, "ERROR_NOT_QUORUM_CAPABLE")); - ErrorNames.insert(std::make_pair(5022, "ERROR_CLUSTER_SHUTTING_DOWN")); - ErrorNames.insert(std::make_pair(5023, "ERROR_INVALID_STATE")); - ErrorNames.insert(std::make_pair(5024, "ERROR_RESOURCE_PROPERTIES_STORED")); - ErrorNames.insert(std::make_pair(5025, "ERROR_NOT_QUORUM_CLASS")); - ErrorNames.insert(std::make_pair(5026, "ERROR_CORE_RESOURCE")); - ErrorNames.insert(std::make_pair(5027, "ERROR_QUORUM_RESOURCE_ONLINE_FAILED")); - ErrorNames.insert(std::make_pair(5028, "ERROR_QUORUMLOG_OPEN_FAILED")); - ErrorNames.insert(std::make_pair(5029, "ERROR_CLUSTERLOG_CORRUPT")); - ErrorNames.insert(std::make_pair(5030, "ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE")); - ErrorNames.insert(std::make_pair(5031, "ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE")); - ErrorNames.insert(std::make_pair(5032, "ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND")); - ErrorNames.insert(std::make_pair(5033, "ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE")); - ErrorNames.insert(std::make_pair(5034, "ERROR_QUORUM_OWNER_ALIVE")); - ErrorNames.insert(std::make_pair(5035, "ERROR_NETWORK_NOT_AVAILABLE")); - ErrorNames.insert(std::make_pair(5036, "ERROR_NODE_NOT_AVAILABLE")); - ErrorNames.insert(std::make_pair(5037, "ERROR_ALL_NODES_NOT_AVAILABLE")); - ErrorNames.insert(std::make_pair(5038, "ERROR_RESOURCE_FAILED")); - ErrorNames.insert(std::make_pair(5039, "ERROR_CLUSTER_INVALID_NODE")); - ErrorNames.insert(std::make_pair(5040, "ERROR_CLUSTER_NODE_EXISTS")); - ErrorNames.insert(std::make_pair(5041, "ERROR_CLUSTER_JOIN_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(5042, "ERROR_CLUSTER_NODE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(5043, "ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(5044, "ERROR_CLUSTER_NETWORK_EXISTS")); - ErrorNames.insert(std::make_pair(5045, "ERROR_CLUSTER_NETWORK_NOT_FOUND")); - ErrorNames.insert(std::make_pair(5046, "ERROR_CLUSTER_NETINTERFACE_EXISTS")); - ErrorNames.insert(std::make_pair(5047, "ERROR_CLUSTER_NETINTERFACE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(5048, "ERROR_CLUSTER_INVALID_REQUEST")); - ErrorNames.insert(std::make_pair(5049, "ERROR_CLUSTER_INVALID_NETWORK_PROVIDER")); - ErrorNames.insert(std::make_pair(5050, "ERROR_CLUSTER_NODE_DOWN")); - ErrorNames.insert(std::make_pair(5051, "ERROR_CLUSTER_NODE_UNREACHABLE")); - ErrorNames.insert(std::make_pair(5052, "ERROR_CLUSTER_NODE_NOT_MEMBER")); - ErrorNames.insert(std::make_pair(5053, "ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(5054, "ERROR_CLUSTER_INVALID_NETWORK")); - ErrorNames.insert(std::make_pair(5056, "ERROR_CLUSTER_NODE_UP")); - ErrorNames.insert(std::make_pair(5057, "ERROR_CLUSTER_IPADDR_IN_USE")); - ErrorNames.insert(std::make_pair(5058, "ERROR_CLUSTER_NODE_NOT_PAUSED")); - ErrorNames.insert(std::make_pair(5059, "ERROR_CLUSTER_NO_SECURITY_CONTEXT")); - ErrorNames.insert(std::make_pair(5060, "ERROR_CLUSTER_NETWORK_NOT_INTERNAL")); - ErrorNames.insert(std::make_pair(5061, "ERROR_CLUSTER_NODE_ALREADY_UP")); - ErrorNames.insert(std::make_pair(5062, "ERROR_CLUSTER_NODE_ALREADY_DOWN")); - ErrorNames.insert(std::make_pair(5063, "ERROR_CLUSTER_NETWORK_ALREADY_ONLINE")); - ErrorNames.insert(std::make_pair(5064, "ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE")); - ErrorNames.insert(std::make_pair(5065, "ERROR_CLUSTER_NODE_ALREADY_MEMBER")); - ErrorNames.insert(std::make_pair(5066, "ERROR_CLUSTER_LAST_INTERNAL_NETWORK")); - ErrorNames.insert(std::make_pair(5067, "ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS")); - ErrorNames.insert(std::make_pair(5068, "ERROR_INVALID_OPERATION_ON_QUORUM")); - ErrorNames.insert(std::make_pair(5069, "ERROR_DEPENDENCY_NOT_ALLOWED")); - ErrorNames.insert(std::make_pair(5070, "ERROR_CLUSTER_NODE_PAUSED")); - ErrorNames.insert(std::make_pair(5071, "ERROR_NODE_CANT_HOST_RESOURCE")); - ErrorNames.insert(std::make_pair(5072, "ERROR_CLUSTER_NODE_NOT_READY")); - ErrorNames.insert(std::make_pair(5073, "ERROR_CLUSTER_NODE_SHUTTING_DOWN")); - ErrorNames.insert(std::make_pair(5074, "ERROR_CLUSTER_JOIN_ABORTED")); - ErrorNames.insert(std::make_pair(5075, "ERROR_CLUSTER_INCOMPATIBLE_VERSIONS")); - ErrorNames.insert(std::make_pair(5076, "ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED")); - ErrorNames.insert(std::make_pair(5077, "ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED")); - ErrorNames.insert(std::make_pair(5078, "ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(5079, "ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(5080, "ERROR_CLUSTER_RESNAME_NOT_FOUND")); - ErrorNames.insert(std::make_pair(5081, "ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED")); - ErrorNames.insert(std::make_pair(5082, "ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST")); - ErrorNames.insert(std::make_pair(5083, "ERROR_CLUSTER_DATABASE_SEQMISMATCH")); - ErrorNames.insert(std::make_pair(5084, "ERROR_RESMON_INVALID_STATE")); - ErrorNames.insert(std::make_pair(5085, "ERROR_CLUSTER_GUM_NOT_LOCKER")); - ErrorNames.insert(std::make_pair(5086, "ERROR_QUORUM_DISK_NOT_FOUND")); - ErrorNames.insert(std::make_pair(5087, "ERROR_DATABASE_BACKUP_CORRUPT")); - ErrorNames.insert(std::make_pair(5088, "ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT")); - ErrorNames.insert(std::make_pair(5089, "ERROR_RESOURCE_PROPERTY_UNCHANGEABLE")); - ErrorNames.insert(std::make_pair(5890, "ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE")); - ErrorNames.insert(std::make_pair(5891, "ERROR_CLUSTER_QUORUMLOG_NOT_FOUND")); - ErrorNames.insert(std::make_pair(5892, "ERROR_CLUSTER_MEMBERSHIP_HALT")); - ErrorNames.insert(std::make_pair(5893, "ERROR_CLUSTER_INSTANCE_ID_MISMATCH")); - ErrorNames.insert(std::make_pair(5894, "ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP")); - ErrorNames.insert(std::make_pair(5895, "ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH")); - ErrorNames.insert(std::make_pair(5896, "ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP")); - ErrorNames.insert(std::make_pair(5897, "ERROR_CLUSTER_PARAMETER_MISMATCH")); - ErrorNames.insert(std::make_pair(5898, "ERROR_NODE_CANNOT_BE_CLUSTERED")); - ErrorNames.insert(std::make_pair(5899, "ERROR_CLUSTER_WRONG_OS_VERSION")); - ErrorNames.insert(std::make_pair(5900, "ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME")); - ErrorNames.insert(std::make_pair(5901, "ERROR_CLUSCFG_ALREADY_COMMITTED")); - ErrorNames.insert(std::make_pair(5902, "ERROR_CLUSCFG_ROLLBACK_FAILED")); - ErrorNames.insert(std::make_pair(5903, "ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT")); - ErrorNames.insert(std::make_pair(5904, "ERROR_CLUSTER_OLD_VERSION")); - ErrorNames.insert(std::make_pair(5905, "ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME")); - ErrorNames.insert(std::make_pair(5906, "ERROR_CLUSTER_NO_NET_ADAPTERS")); - ErrorNames.insert(std::make_pair(5907, "ERROR_CLUSTER_POISONED")); - ErrorNames.insert(std::make_pair(5908, "ERROR_CLUSTER_GROUP_MOVING")); - ErrorNames.insert(std::make_pair(5909, "ERROR_CLUSTER_RESOURCE_TYPE_BUSY")); - ErrorNames.insert(std::make_pair(5910, "ERROR_RESOURCE_CALL_TIMED_OUT")); - ErrorNames.insert(std::make_pair(5911, "ERROR_INVALID_CLUSTER_IPV6_ADDRESS")); - ErrorNames.insert(std::make_pair(5912, "ERROR_CLUSTER_INTERNAL_INVALID_FUNCTION")); - ErrorNames.insert(std::make_pair(5913, "ERROR_CLUSTER_PARAMETER_OUT_OF_BOUNDS")); - ErrorNames.insert(std::make_pair(5914, "ERROR_CLUSTER_PARTIAL_SEND")); - ErrorNames.insert(std::make_pair(5915, "ERROR_CLUSTER_REGISTRY_INVALID_FUNCTION")); - ErrorNames.insert(std::make_pair(5916, "ERROR_CLUSTER_INVALID_STRING_TERMINATION")); - ErrorNames.insert(std::make_pair(5917, "ERROR_CLUSTER_INVALID_STRING_FORMAT")); - ErrorNames.insert(std::make_pair(5918, "ERROR_CLUSTER_DATABASE_TRANSACTION_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(5919, "ERROR_CLUSTER_DATABASE_TRANSACTION_NOT_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(5920, "ERROR_CLUSTER_NULL_DATA")); - ErrorNames.insert(std::make_pair(5921, "ERROR_CLUSTER_PARTIAL_READ")); - ErrorNames.insert(std::make_pair(5922, "ERROR_CLUSTER_PARTIAL_WRITE")); - ErrorNames.insert(std::make_pair(5923, "ERROR_CLUSTER_CANT_DESERIALIZE_DATA")); - ErrorNames.insert(std::make_pair(5924, "ERROR_DEPENDENT_RESOURCE_PROPERTY_CONFLICT")); - ErrorNames.insert(std::make_pair(5925, "ERROR_CLUSTER_NO_QUORUM")); - ErrorNames.insert(std::make_pair(5926, "ERROR_CLUSTER_INVALID_IPV6_NETWORK")); - ErrorNames.insert(std::make_pair(5927, "ERROR_CLUSTER_INVALID_IPV6_TUNNEL_NETWORK")); - ErrorNames.insert(std::make_pair(5928, "ERROR_QUORUM_NOT_ALLOWED_IN_THIS_GROUP")); - ErrorNames.insert(std::make_pair(5929, "ERROR_DEPENDENCY_TREE_TOO_COMPLEX")); - ErrorNames.insert(std::make_pair(5930, "ERROR_EXCEPTION_IN_RESOURCE_CALL")); - ErrorNames.insert(std::make_pair(5931, "ERROR_CLUSTER_RHS_FAILED_INITIALIZATION")); - ErrorNames.insert(std::make_pair(5932, "ERROR_CLUSTER_NOT_INSTALLED")); - ErrorNames.insert(std::make_pair(5933, "ERROR_CLUSTER_RESOURCES_MUST_BE_ONLINE_ON_THE_SAME_NODE")); - ErrorNames.insert(std::make_pair(5934, "ERROR_CLUSTER_MAX_NODES_IN_CLUSTER")); - ErrorNames.insert(std::make_pair(5935, "ERROR_CLUSTER_TOO_MANY_NODES")); - ErrorNames.insert(std::make_pair(5936, "ERROR_CLUSTER_OBJECT_ALREADY_USED")); - ErrorNames.insert(std::make_pair(5937, "ERROR_NONCORE_GROUPS_FOUND")); - ErrorNames.insert(std::make_pair(5938, "ERROR_FILE_SHARE_RESOURCE_CONFLICT")); - ErrorNames.insert(std::make_pair(5939, "ERROR_CLUSTER_EVICT_INVALID_REQUEST")); - ErrorNames.insert(std::make_pair(5940, "ERROR_CLUSTER_SINGLETON_RESOURCE")); - ErrorNames.insert(std::make_pair(5941, "ERROR_CLUSTER_GROUP_SINGLETON_RESOURCE")); - ErrorNames.insert(std::make_pair(5942, "ERROR_CLUSTER_RESOURCE_PROVIDER_FAILED")); - ErrorNames.insert(std::make_pair(5943, "ERROR_CLUSTER_RESOURCE_CONFIGURATION_ERROR")); - ErrorNames.insert(std::make_pair(5944, "ERROR_CLUSTER_GROUP_BUSY")); - ErrorNames.insert(std::make_pair(5945, "ERROR_CLUSTER_NOT_SHARED_VOLUME")); - ErrorNames.insert(std::make_pair(5946, "ERROR_CLUSTER_INVALID_SECURITY_DESCRIPTOR")); - ErrorNames.insert(std::make_pair(5947, "ERROR_CLUSTER_SHARED_VOLUMES_IN_USE")); - ErrorNames.insert(std::make_pair(5948, "ERROR_CLUSTER_USE_SHARED_VOLUMES_API")); - ErrorNames.insert(std::make_pair(5949, "ERROR_CLUSTER_BACKUP_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(5950, "ERROR_NON_CSV_PATH")); - ErrorNames.insert(std::make_pair(5951, "ERROR_CSV_VOLUME_NOT_LOCAL")); - ErrorNames.insert(std::make_pair(5952, "ERROR_CLUSTER_WATCHDOG_TERMINATING")); - ErrorNames.insert(std::make_pair(6000, "ERROR_ENCRYPTION_FAILED")); - ErrorNames.insert(std::make_pair(6001, "ERROR_DECRYPTION_FAILED")); - ErrorNames.insert(std::make_pair(6002, "ERROR_FILE_ENCRYPTED")); - ErrorNames.insert(std::make_pair(6003, "ERROR_NO_RECOVERY_POLICY")); - ErrorNames.insert(std::make_pair(6004, "ERROR_NO_EFS")); - ErrorNames.insert(std::make_pair(6005, "ERROR_WRONG_EFS")); - ErrorNames.insert(std::make_pair(6006, "ERROR_NO_USER_KEYS")); - ErrorNames.insert(std::make_pair(6007, "ERROR_FILE_NOT_ENCRYPTED")); - ErrorNames.insert(std::make_pair(6008, "ERROR_NOT_EXPORT_FORMAT")); - ErrorNames.insert(std::make_pair(6009, "ERROR_FILE_READ_ONLY")); - ErrorNames.insert(std::make_pair(6010, "ERROR_DIR_EFS_DISALLOWED")); - ErrorNames.insert(std::make_pair(6011, "ERROR_EFS_SERVER_NOT_TRUSTED")); - ErrorNames.insert(std::make_pair(6012, "ERROR_BAD_RECOVERY_POLICY")); - ErrorNames.insert(std::make_pair(6013, "ERROR_EFS_ALG_BLOB_TOO_BIG")); - ErrorNames.insert(std::make_pair(6014, "ERROR_VOLUME_NOT_SUPPORT_EFS")); - ErrorNames.insert(std::make_pair(6015, "ERROR_EFS_DISABLED")); - ErrorNames.insert(std::make_pair(6016, "ERROR_EFS_VERSION_NOT_SUPPORT")); - ErrorNames.insert(std::make_pair(6017, "ERROR_CS_ENCRYPTION_INVALID_SERVER_RESPONSE")); - ErrorNames.insert(std::make_pair(6018, "ERROR_CS_ENCRYPTION_UNSUPPORTED_SERVER")); - ErrorNames.insert(std::make_pair(6019, "ERROR_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE")); - ErrorNames.insert(std::make_pair(6020, "ERROR_CS_ENCRYPTION_NEW_ENCRYPTED_FILE")); - ErrorNames.insert(std::make_pair(6021, "ERROR_CS_ENCRYPTION_FILE_NOT_CSE")); - ErrorNames.insert(std::make_pair(6022, "ERROR_ENCRYPTION_POLICY_DENIES_OPERATION")); - ErrorNames.insert(std::make_pair(6118, "ERROR_NO_BROWSER_SERVERS_FOUND")); - ErrorNames.insert(std::make_pair(6600, "ERROR_LOG_SECTOR_INVALID")); - ErrorNames.insert(std::make_pair(6601, "ERROR_LOG_SECTOR_PARITY_INVALID")); - ErrorNames.insert(std::make_pair(6602, "ERROR_LOG_SECTOR_REMAPPED")); - ErrorNames.insert(std::make_pair(6603, "ERROR_LOG_BLOCK_INCOMPLETE")); - ErrorNames.insert(std::make_pair(6604, "ERROR_LOG_INVALID_RANGE")); - ErrorNames.insert(std::make_pair(6605, "ERROR_LOG_BLOCKS_EXHAUSTED")); - ErrorNames.insert(std::make_pair(6606, "ERROR_LOG_READ_CONTEXT_INVALID")); - ErrorNames.insert(std::make_pair(6607, "ERROR_LOG_RESTART_INVALID")); - ErrorNames.insert(std::make_pair(6608, "ERROR_LOG_BLOCK_VERSION")); - ErrorNames.insert(std::make_pair(6609, "ERROR_LOG_BLOCK_INVALID")); - ErrorNames.insert(std::make_pair(6610, "ERROR_LOG_READ_MODE_INVALID")); - ErrorNames.insert(std::make_pair(6611, "ERROR_LOG_NO_RESTART")); - ErrorNames.insert(std::make_pair(6612, "ERROR_LOG_METADATA_CORRUPT")); - ErrorNames.insert(std::make_pair(6613, "ERROR_LOG_METADATA_INVALID")); - ErrorNames.insert(std::make_pair(6614, "ERROR_LOG_METADATA_INCONSISTENT")); - ErrorNames.insert(std::make_pair(6615, "ERROR_LOG_RESERVATION_INVALID")); - ErrorNames.insert(std::make_pair(6616, "ERROR_LOG_CANT_DELETE")); - ErrorNames.insert(std::make_pair(6617, "ERROR_LOG_CONTAINER_LIMIT_EXCEEDED")); - ErrorNames.insert(std::make_pair(6618, "ERROR_LOG_START_OF_LOG")); - ErrorNames.insert(std::make_pair(6619, "ERROR_LOG_POLICY_ALREADY_INSTALLED")); - ErrorNames.insert(std::make_pair(6620, "ERROR_LOG_POLICY_NOT_INSTALLED")); - ErrorNames.insert(std::make_pair(6621, "ERROR_LOG_POLICY_INVALID")); - ErrorNames.insert(std::make_pair(6622, "ERROR_LOG_POLICY_CONFLICT")); - ErrorNames.insert(std::make_pair(6623, "ERROR_LOG_PINNED_ARCHIVE_TAIL")); - ErrorNames.insert(std::make_pair(6624, "ERROR_LOG_RECORD_NONEXISTENT")); - ErrorNames.insert(std::make_pair(6625, "ERROR_LOG_RECORDS_RESERVED_INVALID")); - ErrorNames.insert(std::make_pair(6626, "ERROR_LOG_SPACE_RESERVED_INVALID")); - ErrorNames.insert(std::make_pair(6627, "ERROR_LOG_TAIL_INVALID")); - ErrorNames.insert(std::make_pair(6628, "ERROR_LOG_FULL")); - ErrorNames.insert(std::make_pair(6629, "ERROR_COULD_NOT_RESIZE_LOG")); - ErrorNames.insert(std::make_pair(6630, "ERROR_LOG_MULTIPLEXED")); - ErrorNames.insert(std::make_pair(6631, "ERROR_LOG_DEDICATED")); - ErrorNames.insert(std::make_pair(6632, "ERROR_LOG_ARCHIVE_NOT_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(6633, "ERROR_LOG_ARCHIVE_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(6634, "ERROR_LOG_EPHEMERAL")); - ErrorNames.insert(std::make_pair(6635, "ERROR_LOG_NOT_ENOUGH_CONTAINERS")); - ErrorNames.insert(std::make_pair(6636, "ERROR_LOG_CLIENT_ALREADY_REGISTERED")); - ErrorNames.insert(std::make_pair(6637, "ERROR_LOG_CLIENT_NOT_REGISTERED")); - ErrorNames.insert(std::make_pair(6638, "ERROR_LOG_FULL_HANDLER_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(6639, "ERROR_LOG_CONTAINER_READ_FAILED")); - ErrorNames.insert(std::make_pair(6640, "ERROR_LOG_CONTAINER_WRITE_FAILED")); - ErrorNames.insert(std::make_pair(6641, "ERROR_LOG_CONTAINER_OPEN_FAILED")); - ErrorNames.insert(std::make_pair(6642, "ERROR_LOG_CONTAINER_STATE_INVALID")); - ErrorNames.insert(std::make_pair(6643, "ERROR_LOG_STATE_INVALID")); - ErrorNames.insert(std::make_pair(6644, "ERROR_LOG_PINNED")); - ErrorNames.insert(std::make_pair(6645, "ERROR_LOG_METADATA_FLUSH_FAILED")); - ErrorNames.insert(std::make_pair(6646, "ERROR_LOG_INCONSISTENT_SECURITY")); - ErrorNames.insert(std::make_pair(6647, "ERROR_LOG_APPENDED_FLUSH_FAILED")); - ErrorNames.insert(std::make_pair(6648, "ERROR_LOG_PINNED_RESERVATION")); - ErrorNames.insert(std::make_pair(6700, "ERROR_INVALID_TRANSACTION")); - ErrorNames.insert(std::make_pair(6701, "ERROR_TRANSACTION_NOT_ACTIVE")); - ErrorNames.insert(std::make_pair(6702, "ERROR_TRANSACTION_REQUEST_NOT_VALID")); - ErrorNames.insert(std::make_pair(6703, "ERROR_TRANSACTION_NOT_REQUESTED")); - ErrorNames.insert(std::make_pair(6704, "ERROR_TRANSACTION_ALREADY_ABORTED")); - ErrorNames.insert(std::make_pair(6705, "ERROR_TRANSACTION_ALREADY_COMMITTED")); - ErrorNames.insert(std::make_pair(6706, "ERROR_TM_INITIALIZATION_FAILED")); - ErrorNames.insert(std::make_pair(6707, "ERROR_RESOURCEMANAGER_READ_ONLY")); - ErrorNames.insert(std::make_pair(6708, "ERROR_TRANSACTION_NOT_JOINED")); - ErrorNames.insert(std::make_pair(6709, "ERROR_TRANSACTION_SUPERIOR_EXISTS")); - ErrorNames.insert(std::make_pair(6710, "ERROR_CRM_PROTOCOL_ALREADY_EXISTS")); - ErrorNames.insert(std::make_pair(6711, "ERROR_TRANSACTION_PROPAGATION_FAILED")); - ErrorNames.insert(std::make_pair(6712, "ERROR_CRM_PROTOCOL_NOT_FOUND")); - ErrorNames.insert(std::make_pair(6713, "ERROR_TRANSACTION_INVALID_MARSHALL_BUFFER")); - ErrorNames.insert(std::make_pair(6714, "ERROR_CURRENT_TRANSACTION_NOT_VALID")); - ErrorNames.insert(std::make_pair(6715, "ERROR_TRANSACTION_NOT_FOUND")); - ErrorNames.insert(std::make_pair(6716, "ERROR_RESOURCEMANAGER_NOT_FOUND")); - ErrorNames.insert(std::make_pair(6717, "ERROR_ENLISTMENT_NOT_FOUND")); - ErrorNames.insert(std::make_pair(6718, "ERROR_TRANSACTIONMANAGER_NOT_FOUND")); - ErrorNames.insert(std::make_pair(6719, "ERROR_TRANSACTIONMANAGER_NOT_ONLINE")); - ErrorNames.insert(std::make_pair(6720, "ERROR_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION")); - ErrorNames.insert(std::make_pair(6721, "ERROR_TRANSACTION_NOT_ROOT")); - ErrorNames.insert(std::make_pair(6722, "ERROR_TRANSACTION_OBJECT_EXPIRED")); - ErrorNames.insert(std::make_pair(6723, "ERROR_TRANSACTION_RESPONSE_NOT_ENLISTED")); - ErrorNames.insert(std::make_pair(6724, "ERROR_TRANSACTION_RECORD_TOO_LONG")); - ErrorNames.insert(std::make_pair(6725, "ERROR_IMPLICIT_TRANSACTION_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(6726, "ERROR_TRANSACTION_INTEGRITY_VIOLATED")); - ErrorNames.insert(std::make_pair(6727, "ERROR_TRANSACTIONMANAGER_IDENTITY_MISMATCH")); - ErrorNames.insert(std::make_pair(6728, "ERROR_RM_CANNOT_BE_FROZEN_FOR_SNAPSHOT")); - ErrorNames.insert(std::make_pair(6729, "ERROR_TRANSACTION_MUST_WRITETHROUGH")); - ErrorNames.insert(std::make_pair(6730, "ERROR_TRANSACTION_NO_SUPERIOR")); - ErrorNames.insert(std::make_pair(6731, "ERROR_HEURISTIC_DAMAGE_POSSIBLE")); - ErrorNames.insert(std::make_pair(6800, "ERROR_TRANSACTIONAL_CONFLICT")); - ErrorNames.insert(std::make_pair(6801, "ERROR_RM_NOT_ACTIVE")); - ErrorNames.insert(std::make_pair(6802, "ERROR_RM_METADATA_CORRUPT")); - ErrorNames.insert(std::make_pair(6803, "ERROR_DIRECTORY_NOT_RM")); - ErrorNames.insert(std::make_pair(6805, "ERROR_TRANSACTIONS_UNSUPPORTED_REMOTE")); - ErrorNames.insert(std::make_pair(6806, "ERROR_LOG_RESIZE_INVALID_SIZE")); - ErrorNames.insert(std::make_pair(6807, "ERROR_OBJECT_NO_LONGER_EXISTS")); - ErrorNames.insert(std::make_pair(6808, "ERROR_STREAM_MINIVERSION_NOT_FOUND")); - ErrorNames.insert(std::make_pair(6809, "ERROR_STREAM_MINIVERSION_NOT_VALID")); - ErrorNames.insert(std::make_pair(6810, "ERROR_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION")); - ErrorNames.insert(std::make_pair(6811, "ERROR_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT")); - ErrorNames.insert(std::make_pair(6812, "ERROR_CANT_CREATE_MORE_STREAM_MINIVERSIONS")); - ErrorNames.insert(std::make_pair(6814, "ERROR_REMOTE_FILE_VERSION_MISMATCH")); - ErrorNames.insert(std::make_pair(6815, "ERROR_HANDLE_NO_LONGER_VALID")); - ErrorNames.insert(std::make_pair(6816, "ERROR_NO_TXF_METADATA")); - ErrorNames.insert(std::make_pair(6817, "ERROR_LOG_CORRUPTION_DETECTED")); - ErrorNames.insert(std::make_pair(6818, "ERROR_CANT_RECOVER_WITH_HANDLE_OPEN")); - ErrorNames.insert(std::make_pair(6819, "ERROR_RM_DISCONNECTED")); - ErrorNames.insert(std::make_pair(6820, "ERROR_ENLISTMENT_NOT_SUPERIOR")); - ErrorNames.insert(std::make_pair(6821, "ERROR_RECOVERY_NOT_NEEDED")); - ErrorNames.insert(std::make_pair(6822, "ERROR_RM_ALREADY_STARTED")); - ErrorNames.insert(std::make_pair(6823, "ERROR_FILE_IDENTITY_NOT_PERSISTENT")); - ErrorNames.insert(std::make_pair(6824, "ERROR_CANT_BREAK_TRANSACTIONAL_DEPENDENCY")); - ErrorNames.insert(std::make_pair(6825, "ERROR_CANT_CROSS_RM_BOUNDARY")); - ErrorNames.insert(std::make_pair(6826, "ERROR_TXF_DIR_NOT_EMPTY")); - ErrorNames.insert(std::make_pair(6827, "ERROR_INDOUBT_TRANSACTIONS_EXIST")); - ErrorNames.insert(std::make_pair(6828, "ERROR_TM_VOLATILE")); - ErrorNames.insert(std::make_pair(6829, "ERROR_ROLLBACK_TIMER_EXPIRED")); - ErrorNames.insert(std::make_pair(6830, "ERROR_TXF_ATTRIBUTE_CORRUPT")); - ErrorNames.insert(std::make_pair(6831, "ERROR_EFS_NOT_ALLOWED_IN_TRANSACTION")); - ErrorNames.insert(std::make_pair(6832, "ERROR_TRANSACTIONAL_OPEN_NOT_ALLOWED")); - ErrorNames.insert(std::make_pair(6833, "ERROR_LOG_GROWTH_FAILED")); - ErrorNames.insert(std::make_pair(6834, "ERROR_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE")); - ErrorNames.insert(std::make_pair(6835, "ERROR_TXF_METADATA_ALREADY_PRESENT")); - ErrorNames.insert(std::make_pair(6836, "ERROR_TRANSACTION_SCOPE_CALLBACKS_NOT_SET")); - ErrorNames.insert(std::make_pair(6837, "ERROR_TRANSACTION_REQUIRED_PROMOTION")); - ErrorNames.insert(std::make_pair(6838, "ERROR_CANNOT_EXECUTE_FILE_IN_TRANSACTION")); - ErrorNames.insert(std::make_pair(6839, "ERROR_TRANSACTIONS_NOT_FROZEN")); - ErrorNames.insert(std::make_pair(6840, "ERROR_TRANSACTION_FREEZE_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(6841, "ERROR_NOT_SNAPSHOT_VOLUME")); - ErrorNames.insert(std::make_pair(6842, "ERROR_NO_SAVEPOINT_WITH_OPEN_FILES")); - ErrorNames.insert(std::make_pair(6843, "ERROR_DATA_LOST_REPAIR")); - ErrorNames.insert(std::make_pair(6844, "ERROR_SPARSE_NOT_ALLOWED_IN_TRANSACTION")); - ErrorNames.insert(std::make_pair(6845, "ERROR_TM_IDENTITY_MISMATCH")); - ErrorNames.insert(std::make_pair(6846, "ERROR_FLOATED_SECTION")); - ErrorNames.insert(std::make_pair(6847, "ERROR_CANNOT_ACCEPT_TRANSACTED_WORK")); - ErrorNames.insert(std::make_pair(6848, "ERROR_CANNOT_ABORT_TRANSACTIONS")); - ErrorNames.insert(std::make_pair(6849, "ERROR_BAD_CLUSTERS")); - ErrorNames.insert(std::make_pair(6850, "ERROR_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION")); - ErrorNames.insert(std::make_pair(6851, "ERROR_VOLUME_DIRTY")); - ErrorNames.insert(std::make_pair(6852, "ERROR_NO_LINK_TRACKING_IN_TRANSACTION")); - ErrorNames.insert(std::make_pair(6853, "ERROR_OPERATION_NOT_SUPPORTED_IN_TRANSACTION")); - ErrorNames.insert(std::make_pair(6854, "ERROR_EXPIRED_HANDLE")); - ErrorNames.insert(std::make_pair(6855, "ERROR_TRANSACTION_NOT_ENLISTED")); - ErrorNames.insert(std::make_pair(7001, "ERROR_CTX_WINSTATION_NAME_INVALID")); - ErrorNames.insert(std::make_pair(7002, "ERROR_CTX_INVALID_PD")); - ErrorNames.insert(std::make_pair(7003, "ERROR_CTX_PD_NOT_FOUND")); - ErrorNames.insert(std::make_pair(7004, "ERROR_CTX_WD_NOT_FOUND")); - ErrorNames.insert(std::make_pair(7005, "ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY")); - ErrorNames.insert(std::make_pair(7006, "ERROR_CTX_SERVICE_NAME_COLLISION")); - ErrorNames.insert(std::make_pair(7007, "ERROR_CTX_CLOSE_PENDING")); - ErrorNames.insert(std::make_pair(7008, "ERROR_CTX_NO_OUTBUF")); - ErrorNames.insert(std::make_pair(7009, "ERROR_CTX_MODEM_INF_NOT_FOUND")); - ErrorNames.insert(std::make_pair(7010, "ERROR_CTX_INVALID_MODEMNAME")); - ErrorNames.insert(std::make_pair(7011, "ERROR_CTX_MODEM_RESPONSE_ERROR")); - ErrorNames.insert(std::make_pair(7012, "ERROR_CTX_MODEM_RESPONSE_TIMEOUT")); - ErrorNames.insert(std::make_pair(7013, "ERROR_CTX_MODEM_RESPONSE_NO_CARRIER")); - ErrorNames.insert(std::make_pair(7014, "ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE")); - ErrorNames.insert(std::make_pair(7015, "ERROR_CTX_MODEM_RESPONSE_BUSY")); - ErrorNames.insert(std::make_pair(7016, "ERROR_CTX_MODEM_RESPONSE_VOICE")); - ErrorNames.insert(std::make_pair(7017, "ERROR_CTX_TD_ERROR")); - ErrorNames.insert(std::make_pair(7022, "ERROR_CTX_WINSTATION_NOT_FOUND")); - ErrorNames.insert(std::make_pair(7023, "ERROR_CTX_WINSTATION_ALREADY_EXISTS")); - ErrorNames.insert(std::make_pair(7024, "ERROR_CTX_WINSTATION_BUSY")); - ErrorNames.insert(std::make_pair(7025, "ERROR_CTX_BAD_VIDEO_MODE")); - ErrorNames.insert(std::make_pair(7035, "ERROR_CTX_GRAPHICS_INVALID")); - ErrorNames.insert(std::make_pair(7037, "ERROR_CTX_LOGON_DISABLED")); - ErrorNames.insert(std::make_pair(7038, "ERROR_CTX_NOT_CONSOLE")); - ErrorNames.insert(std::make_pair(7040, "ERROR_CTX_CLIENT_QUERY_TIMEOUT")); - ErrorNames.insert(std::make_pair(7041, "ERROR_CTX_CONSOLE_DISCONNECT")); - ErrorNames.insert(std::make_pair(7042, "ERROR_CTX_CONSOLE_CONNECT")); - ErrorNames.insert(std::make_pair(7044, "ERROR_CTX_SHADOW_DENIED")); - ErrorNames.insert(std::make_pair(7045, "ERROR_CTX_WINSTATION_ACCESS_DENIED")); - ErrorNames.insert(std::make_pair(7049, "ERROR_CTX_INVALID_WD")); - ErrorNames.insert(std::make_pair(7050, "ERROR_CTX_SHADOW_INVALID")); - ErrorNames.insert(std::make_pair(7051, "ERROR_CTX_SHADOW_DISABLED")); - ErrorNames.insert(std::make_pair(7052, "ERROR_CTX_CLIENT_LICENSE_IN_USE")); - ErrorNames.insert(std::make_pair(7053, "ERROR_CTX_CLIENT_LICENSE_NOT_SET")); - ErrorNames.insert(std::make_pair(7054, "ERROR_CTX_LICENSE_NOT_AVAILABLE")); - ErrorNames.insert(std::make_pair(7055, "ERROR_CTX_LICENSE_CLIENT_INVALID")); - ErrorNames.insert(std::make_pair(7056, "ERROR_CTX_LICENSE_EXPIRED")); - ErrorNames.insert(std::make_pair(7057, "ERROR_CTX_SHADOW_NOT_RUNNING")); - ErrorNames.insert(std::make_pair(7058, "ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE")); - ErrorNames.insert(std::make_pair(7059, "ERROR_ACTIVATION_COUNT_EXCEEDED")); - ErrorNames.insert(std::make_pair(7060, "ERROR_CTX_WINSTATIONS_DISABLED")); - ErrorNames.insert(std::make_pair(7061, "ERROR_CTX_ENCRYPTION_LEVEL_REQUIRED")); - ErrorNames.insert(std::make_pair(7062, "ERROR_CTX_SESSION_IN_USE")); - ErrorNames.insert(std::make_pair(7063, "ERROR_CTX_NO_FORCE_LOGOFF")); - ErrorNames.insert(std::make_pair(7064, "ERROR_CTX_ACCOUNT_RESTRICTION")); - ErrorNames.insert(std::make_pair(7065, "ERROR_RDP_PROTOCOL_ERROR")); - ErrorNames.insert(std::make_pair(7066, "ERROR_CTX_CDM_CONNECT")); - ErrorNames.insert(std::make_pair(7067, "ERROR_CTX_CDM_DISCONNECT")); - ErrorNames.insert(std::make_pair(7068, "ERROR_CTX_SECURITY_LAYER_ERROR")); - ErrorNames.insert(std::make_pair(7069, "ERROR_TS_INCOMPATIBLE_SESSIONS")); - ErrorNames.insert(std::make_pair(7070, "ERROR_TS_VIDEO_SUBSYSTEM_ERROR")); - ErrorNames.insert(std::make_pair(8200, "ERROR_DS_NOT_INSTALLED")); - ErrorNames.insert(std::make_pair(8201, "ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY")); - ErrorNames.insert(std::make_pair(8202, "ERROR_DS_NO_ATTRIBUTE_OR_VALUE")); - ErrorNames.insert(std::make_pair(8203, "ERROR_DS_INVALID_ATTRIBUTE_SYNTAX")); - ErrorNames.insert(std::make_pair(8204, "ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED")); - ErrorNames.insert(std::make_pair(8205, "ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS")); - ErrorNames.insert(std::make_pair(8206, "ERROR_DS_BUSY")); - ErrorNames.insert(std::make_pair(8207, "ERROR_DS_UNAVAILABLE")); - ErrorNames.insert(std::make_pair(8208, "ERROR_DS_NO_RIDS_ALLOCATED")); - ErrorNames.insert(std::make_pair(8209, "ERROR_DS_NO_MORE_RIDS")); - ErrorNames.insert(std::make_pair(8210, "ERROR_DS_INCORRECT_ROLE_OWNER")); - ErrorNames.insert(std::make_pair(8211, "ERROR_DS_RIDMGR_INIT_ERROR")); - ErrorNames.insert(std::make_pair(8212, "ERROR_DS_OBJ_CLASS_VIOLATION")); - ErrorNames.insert(std::make_pair(8213, "ERROR_DS_CANT_ON_NON_LEAF")); - ErrorNames.insert(std::make_pair(8214, "ERROR_DS_CANT_ON_RDN")); - ErrorNames.insert(std::make_pair(8215, "ERROR_DS_CANT_MOD_OBJ_CLASS")); - ErrorNames.insert(std::make_pair(8216, "ERROR_DS_CROSS_DOM_MOVE_ERROR")); - ErrorNames.insert(std::make_pair(8217, "ERROR_DS_GC_NOT_AVAILABLE")); - ErrorNames.insert(std::make_pair(8218, "ERROR_SHARED_POLICY")); - ErrorNames.insert(std::make_pair(8219, "ERROR_POLICY_OBJECT_NOT_FOUND")); - ErrorNames.insert(std::make_pair(8220, "ERROR_POLICY_ONLY_IN_DS")); - ErrorNames.insert(std::make_pair(8221, "ERROR_PROMOTION_ACTIVE")); - ErrorNames.insert(std::make_pair(8222, "ERROR_NO_PROMOTION_ACTIVE")); - ErrorNames.insert(std::make_pair(8224, "ERROR_DS_OPERATIONS_ERROR")); - ErrorNames.insert(std::make_pair(8225, "ERROR_DS_PROTOCOL_ERROR")); - ErrorNames.insert(std::make_pair(8226, "ERROR_DS_TIMELIMIT_EXCEEDED")); - ErrorNames.insert(std::make_pair(8227, "ERROR_DS_SIZELIMIT_EXCEEDED")); - ErrorNames.insert(std::make_pair(8228, "ERROR_DS_ADMIN_LIMIT_EXCEEDED")); - ErrorNames.insert(std::make_pair(8229, "ERROR_DS_COMPARE_FALSE")); - ErrorNames.insert(std::make_pair(8230, "ERROR_DS_COMPARE_TRUE")); - ErrorNames.insert(std::make_pair(8231, "ERROR_DS_AUTH_METHOD_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(8232, "ERROR_DS_STRONG_AUTH_REQUIRED")); - ErrorNames.insert(std::make_pair(8233, "ERROR_DS_INAPPROPRIATE_AUTH")); - ErrorNames.insert(std::make_pair(8234, "ERROR_DS_AUTH_UNKNOWN")); - ErrorNames.insert(std::make_pair(8235, "ERROR_DS_REFERRAL")); - ErrorNames.insert(std::make_pair(8236, "ERROR_DS_UNAVAILABLE_CRIT_EXTENSION")); - ErrorNames.insert(std::make_pair(8237, "ERROR_DS_CONFIDENTIALITY_REQUIRED")); - ErrorNames.insert(std::make_pair(8238, "ERROR_DS_INAPPROPRIATE_MATCHING")); - ErrorNames.insert(std::make_pair(8239, "ERROR_DS_CONSTRAINT_VIOLATION")); - ErrorNames.insert(std::make_pair(8240, "ERROR_DS_NO_SUCH_OBJECT")); - ErrorNames.insert(std::make_pair(8241, "ERROR_DS_ALIAS_PROBLEM")); - ErrorNames.insert(std::make_pair(8242, "ERROR_DS_INVALID_DN_SYNTAX")); - ErrorNames.insert(std::make_pair(8243, "ERROR_DS_IS_LEAF")); - ErrorNames.insert(std::make_pair(8244, "ERROR_DS_ALIAS_DEREF_PROBLEM")); - ErrorNames.insert(std::make_pair(8245, "ERROR_DS_UNWILLING_TO_PERFORM")); - ErrorNames.insert(std::make_pair(8246, "ERROR_DS_LOOP_DETECT")); - ErrorNames.insert(std::make_pair(8247, "ERROR_DS_NAMING_VIOLATION")); - ErrorNames.insert(std::make_pair(8248, "ERROR_DS_OBJECT_RESULTS_TOO_LARGE")); - ErrorNames.insert(std::make_pair(8249, "ERROR_DS_AFFECTS_MULTIPLE_DSAS")); - ErrorNames.insert(std::make_pair(8250, "ERROR_DS_SERVER_DOWN")); - ErrorNames.insert(std::make_pair(8251, "ERROR_DS_LOCAL_ERROR")); - ErrorNames.insert(std::make_pair(8252, "ERROR_DS_ENCODING_ERROR")); - ErrorNames.insert(std::make_pair(8253, "ERROR_DS_DECODING_ERROR")); - ErrorNames.insert(std::make_pair(8254, "ERROR_DS_FILTER_UNKNOWN")); - ErrorNames.insert(std::make_pair(8255, "ERROR_DS_PARAM_ERROR")); - ErrorNames.insert(std::make_pair(8256, "ERROR_DS_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(8257, "ERROR_DS_NO_RESULTS_RETURNED")); - ErrorNames.insert(std::make_pair(8258, "ERROR_DS_CONTROL_NOT_FOUND")); - ErrorNames.insert(std::make_pair(8259, "ERROR_DS_CLIENT_LOOP")); - ErrorNames.insert(std::make_pair(8260, "ERROR_DS_REFERRAL_LIMIT_EXCEEDED")); - ErrorNames.insert(std::make_pair(8261, "ERROR_DS_SORT_CONTROL_MISSING")); - ErrorNames.insert(std::make_pair(8262, "ERROR_DS_OFFSET_RANGE_ERROR")); - ErrorNames.insert(std::make_pair(8301, "ERROR_DS_ROOT_MUST_BE_NC")); - ErrorNames.insert(std::make_pair(8302, "ERROR_DS_ADD_REPLICA_INHIBITED")); - ErrorNames.insert(std::make_pair(8303, "ERROR_DS_ATT_NOT_DEF_IN_SCHEMA")); - ErrorNames.insert(std::make_pair(8304, "ERROR_DS_MAX_OBJ_SIZE_EXCEEDED")); - ErrorNames.insert(std::make_pair(8305, "ERROR_DS_OBJ_STRING_NAME_EXISTS")); - ErrorNames.insert(std::make_pair(8306, "ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA")); - ErrorNames.insert(std::make_pair(8307, "ERROR_DS_RDN_DOESNT_MATCH_SCHEMA")); - ErrorNames.insert(std::make_pair(8308, "ERROR_DS_NO_REQUESTED_ATTS_FOUND")); - ErrorNames.insert(std::make_pair(8309, "ERROR_DS_USER_BUFFER_TO_SMALL")); - ErrorNames.insert(std::make_pair(8310, "ERROR_DS_ATT_IS_NOT_ON_OBJ")); - ErrorNames.insert(std::make_pair(8311, "ERROR_DS_ILLEGAL_MOD_OPERATION")); - ErrorNames.insert(std::make_pair(8312, "ERROR_DS_OBJ_TOO_LARGE")); - ErrorNames.insert(std::make_pair(8313, "ERROR_DS_BAD_INSTANCE_TYPE")); - ErrorNames.insert(std::make_pair(8314, "ERROR_DS_MASTERDSA_REQUIRED")); - ErrorNames.insert(std::make_pair(8315, "ERROR_DS_OBJECT_CLASS_REQUIRED")); - ErrorNames.insert(std::make_pair(8316, "ERROR_DS_MISSING_REQUIRED_ATT")); - ErrorNames.insert(std::make_pair(8317, "ERROR_DS_ATT_NOT_DEF_FOR_CLASS")); - ErrorNames.insert(std::make_pair(8318, "ERROR_DS_ATT_ALREADY_EXISTS")); - ErrorNames.insert(std::make_pair(8320, "ERROR_DS_CANT_ADD_ATT_VALUES")); - ErrorNames.insert(std::make_pair(8321, "ERROR_DS_SINGLE_VALUE_CONSTRAINT")); - ErrorNames.insert(std::make_pair(8322, "ERROR_DS_RANGE_CONSTRAINT")); - ErrorNames.insert(std::make_pair(8323, "ERROR_DS_ATT_VAL_ALREADY_EXISTS")); - ErrorNames.insert(std::make_pair(8324, "ERROR_DS_CANT_REM_MISSING_ATT")); - ErrorNames.insert(std::make_pair(8325, "ERROR_DS_CANT_REM_MISSING_ATT_VAL")); - ErrorNames.insert(std::make_pair(8326, "ERROR_DS_ROOT_CANT_BE_SUBREF")); - ErrorNames.insert(std::make_pair(8327, "ERROR_DS_NO_CHAINING")); - ErrorNames.insert(std::make_pair(8328, "ERROR_DS_NO_CHAINED_EVAL")); - ErrorNames.insert(std::make_pair(8329, "ERROR_DS_NO_PARENT_OBJECT")); - ErrorNames.insert(std::make_pair(8330, "ERROR_DS_PARENT_IS_AN_ALIAS")); - ErrorNames.insert(std::make_pair(8331, "ERROR_DS_CANT_MIX_MASTER_AND_REPS")); - ErrorNames.insert(std::make_pair(8332, "ERROR_DS_CHILDREN_EXIST")); - ErrorNames.insert(std::make_pair(8333, "ERROR_DS_OBJ_NOT_FOUND")); - ErrorNames.insert(std::make_pair(8334, "ERROR_DS_ALIASED_OBJ_MISSING")); - ErrorNames.insert(std::make_pair(8335, "ERROR_DS_BAD_NAME_SYNTAX")); - ErrorNames.insert(std::make_pair(8336, "ERROR_DS_ALIAS_POINTS_TO_ALIAS")); - ErrorNames.insert(std::make_pair(8337, "ERROR_DS_CANT_DEREF_ALIAS")); - ErrorNames.insert(std::make_pair(8338, "ERROR_DS_OUT_OF_SCOPE")); - ErrorNames.insert(std::make_pair(8339, "ERROR_DS_OBJECT_BEING_REMOVED")); - ErrorNames.insert(std::make_pair(8340, "ERROR_DS_CANT_DELETE_DSA_OBJ")); - ErrorNames.insert(std::make_pair(8341, "ERROR_DS_GENERIC_ERROR")); - ErrorNames.insert(std::make_pair(8342, "ERROR_DS_DSA_MUST_BE_INT_MASTER")); - ErrorNames.insert(std::make_pair(8343, "ERROR_DS_CLASS_NOT_DSA")); - ErrorNames.insert(std::make_pair(8344, "ERROR_DS_INSUFF_ACCESS_RIGHTS")); - ErrorNames.insert(std::make_pair(8345, "ERROR_DS_ILLEGAL_SUPERIOR")); - ErrorNames.insert(std::make_pair(8346, "ERROR_DS_ATTRIBUTE_OWNED_BY_SAM")); - ErrorNames.insert(std::make_pair(8347, "ERROR_DS_NAME_TOO_MANY_PARTS")); - ErrorNames.insert(std::make_pair(8348, "ERROR_DS_NAME_TOO_LONG")); - ErrorNames.insert(std::make_pair(8349, "ERROR_DS_NAME_VALUE_TOO_LONG")); - ErrorNames.insert(std::make_pair(8350, "ERROR_DS_NAME_UNPARSEABLE")); - ErrorNames.insert(std::make_pair(8351, "ERROR_DS_NAME_TYPE_UNKNOWN")); - ErrorNames.insert(std::make_pair(8352, "ERROR_DS_NOT_AN_OBJECT")); - ErrorNames.insert(std::make_pair(8353, "ERROR_DS_SEC_DESC_TOO_SHORT")); - ErrorNames.insert(std::make_pair(8354, "ERROR_DS_SEC_DESC_INVALID")); - ErrorNames.insert(std::make_pair(8355, "ERROR_DS_NO_DELETED_NAME")); - ErrorNames.insert(std::make_pair(8356, "ERROR_DS_SUBREF_MUST_HAVE_PARENT")); - ErrorNames.insert(std::make_pair(8357, "ERROR_DS_NCNAME_MUST_BE_NC")); - ErrorNames.insert(std::make_pair(8358, "ERROR_DS_CANT_ADD_SYSTEM_ONLY")); - ErrorNames.insert(std::make_pair(8359, "ERROR_DS_CLASS_MUST_BE_CONCRETE")); - ErrorNames.insert(std::make_pair(8360, "ERROR_DS_INVALID_DMD")); - ErrorNames.insert(std::make_pair(8361, "ERROR_DS_OBJ_GUID_EXISTS")); - ErrorNames.insert(std::make_pair(8362, "ERROR_DS_NOT_ON_BACKLINK")); - ErrorNames.insert(std::make_pair(8363, "ERROR_DS_NO_CROSSREF_FOR_NC")); - ErrorNames.insert(std::make_pair(8364, "ERROR_DS_SHUTTING_DOWN")); - ErrorNames.insert(std::make_pair(8365, "ERROR_DS_UNKNOWN_OPERATION")); - ErrorNames.insert(std::make_pair(8366, "ERROR_DS_INVALID_ROLE_OWNER")); - ErrorNames.insert(std::make_pair(8367, "ERROR_DS_COULDNT_CONTACT_FSMO")); - ErrorNames.insert(std::make_pair(8368, "ERROR_DS_CROSS_NC_DN_RENAME")); - ErrorNames.insert(std::make_pair(8369, "ERROR_DS_CANT_MOD_SYSTEM_ONLY")); - ErrorNames.insert(std::make_pair(8370, "ERROR_DS_REPLICATOR_ONLY")); - ErrorNames.insert(std::make_pair(8371, "ERROR_DS_OBJ_CLASS_NOT_DEFINED")); - ErrorNames.insert(std::make_pair(8372, "ERROR_DS_OBJ_CLASS_NOT_SUBCLASS")); - ErrorNames.insert(std::make_pair(8373, "ERROR_DS_NAME_REFERENCE_INVALID")); - ErrorNames.insert(std::make_pair(8374, "ERROR_DS_CROSS_REF_EXISTS")); - ErrorNames.insert(std::make_pair(8375, "ERROR_DS_CANT_DEL_MASTER_CROSSREF")); - ErrorNames.insert(std::make_pair(8376, "ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD")); - ErrorNames.insert(std::make_pair(8377, "ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX")); - ErrorNames.insert(std::make_pair(8378, "ERROR_DS_DUP_RDN")); - ErrorNames.insert(std::make_pair(8379, "ERROR_DS_DUP_OID")); - ErrorNames.insert(std::make_pair(8380, "ERROR_DS_DUP_MAPI_ID")); - ErrorNames.insert(std::make_pair(8381, "ERROR_DS_DUP_SCHEMA_ID_GUID")); - ErrorNames.insert(std::make_pair(8382, "ERROR_DS_DUP_LDAP_DISPLAY_NAME")); - ErrorNames.insert(std::make_pair(8383, "ERROR_DS_SEMANTIC_ATT_TEST")); - ErrorNames.insert(std::make_pair(8384, "ERROR_DS_SYNTAX_MISMATCH")); - ErrorNames.insert(std::make_pair(8385, "ERROR_DS_EXISTS_IN_MUST_HAVE")); - ErrorNames.insert(std::make_pair(8386, "ERROR_DS_EXISTS_IN_MAY_HAVE")); - ErrorNames.insert(std::make_pair(8387, "ERROR_DS_NONEXISTENT_MAY_HAVE")); - ErrorNames.insert(std::make_pair(8388, "ERROR_DS_NONEXISTENT_MUST_HAVE")); - ErrorNames.insert(std::make_pair(8389, "ERROR_DS_AUX_CLS_TEST_FAIL")); - ErrorNames.insert(std::make_pair(8390, "ERROR_DS_NONEXISTENT_POSS_SUP")); - ErrorNames.insert(std::make_pair(8391, "ERROR_DS_SUB_CLS_TEST_FAIL")); - ErrorNames.insert(std::make_pair(8392, "ERROR_DS_BAD_RDN_ATT_ID_SYNTAX")); - ErrorNames.insert(std::make_pair(8393, "ERROR_DS_EXISTS_IN_AUX_CLS")); - ErrorNames.insert(std::make_pair(8394, "ERROR_DS_EXISTS_IN_SUB_CLS")); - ErrorNames.insert(std::make_pair(8395, "ERROR_DS_EXISTS_IN_POSS_SUP")); - ErrorNames.insert(std::make_pair(8396, "ERROR_DS_RECALCSCHEMA_FAILED")); - ErrorNames.insert(std::make_pair(8397, "ERROR_DS_TREE_DELETE_NOT_FINISHED")); - ErrorNames.insert(std::make_pair(8398, "ERROR_DS_CANT_DELETE")); - ErrorNames.insert(std::make_pair(8399, "ERROR_DS_ATT_SCHEMA_REQ_ID")); - ErrorNames.insert(std::make_pair(8400, "ERROR_DS_BAD_ATT_SCHEMA_SYNTAX")); - ErrorNames.insert(std::make_pair(8401, "ERROR_DS_CANT_CACHE_ATT")); - ErrorNames.insert(std::make_pair(8402, "ERROR_DS_CANT_CACHE_CLASS")); - ErrorNames.insert(std::make_pair(8403, "ERROR_DS_CANT_REMOVE_ATT_CACHE")); - ErrorNames.insert(std::make_pair(8404, "ERROR_DS_CANT_REMOVE_CLASS_CACHE")); - ErrorNames.insert(std::make_pair(8405, "ERROR_DS_CANT_RETRIEVE_DN")); - ErrorNames.insert(std::make_pair(8406, "ERROR_DS_MISSING_SUPREF")); - ErrorNames.insert(std::make_pair(8407, "ERROR_DS_CANT_RETRIEVE_INSTANCE")); - ErrorNames.insert(std::make_pair(8408, "ERROR_DS_CODE_INCONSISTENCY")); - ErrorNames.insert(std::make_pair(8409, "ERROR_DS_DATABASE_ERROR")); - ErrorNames.insert(std::make_pair(8410, "ERROR_DS_GOVERNSID_MISSING")); - ErrorNames.insert(std::make_pair(8411, "ERROR_DS_MISSING_EXPECTED_ATT")); - ErrorNames.insert(std::make_pair(8412, "ERROR_DS_NCNAME_MISSING_CR_REF")); - ErrorNames.insert(std::make_pair(8413, "ERROR_DS_SECURITY_CHECKING_ERROR")); - ErrorNames.insert(std::make_pair(8414, "ERROR_DS_SCHEMA_NOT_LOADED")); - ErrorNames.insert(std::make_pair(8415, "ERROR_DS_SCHEMA_ALLOC_FAILED")); - ErrorNames.insert(std::make_pair(8416, "ERROR_DS_ATT_SCHEMA_REQ_SYNTAX")); - ErrorNames.insert(std::make_pair(8417, "ERROR_DS_GCVERIFY_ERROR")); - ErrorNames.insert(std::make_pair(8418, "ERROR_DS_DRA_SCHEMA_MISMATCH")); - ErrorNames.insert(std::make_pair(8419, "ERROR_DS_CANT_FIND_DSA_OBJ")); - ErrorNames.insert(std::make_pair(8420, "ERROR_DS_CANT_FIND_EXPECTED_NC")); - ErrorNames.insert(std::make_pair(8421, "ERROR_DS_CANT_FIND_NC_IN_CACHE")); - ErrorNames.insert(std::make_pair(8422, "ERROR_DS_CANT_RETRIEVE_CHILD")); - ErrorNames.insert(std::make_pair(8423, "ERROR_DS_SECURITY_ILLEGAL_MODIFY")); - ErrorNames.insert(std::make_pair(8424, "ERROR_DS_CANT_REPLACE_HIDDEN_REC")); - ErrorNames.insert(std::make_pair(8425, "ERROR_DS_BAD_HIERARCHY_FILE")); - ErrorNames.insert(std::make_pair(8426, "ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED")); - ErrorNames.insert(std::make_pair(8427, "ERROR_DS_CONFIG_PARAM_MISSING")); - ErrorNames.insert(std::make_pair(8428, "ERROR_DS_COUNTING_AB_INDICES_FAILED")); - ErrorNames.insert(std::make_pair(8429, "ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED")); - ErrorNames.insert(std::make_pair(8430, "ERROR_DS_INTERNAL_FAILURE")); - ErrorNames.insert(std::make_pair(8431, "ERROR_DS_UNKNOWN_ERROR")); - ErrorNames.insert(std::make_pair(8432, "ERROR_DS_ROOT_REQUIRES_CLASS_TOP")); - ErrorNames.insert(std::make_pair(8433, "ERROR_DS_REFUSING_FSMO_ROLES")); - ErrorNames.insert(std::make_pair(8434, "ERROR_DS_MISSING_FSMO_SETTINGS")); - ErrorNames.insert(std::make_pair(8435, "ERROR_DS_UNABLE_TO_SURRENDER_ROLES")); - ErrorNames.insert(std::make_pair(8436, "ERROR_DS_DRA_GENERIC")); - ErrorNames.insert(std::make_pair(8437, "ERROR_DS_DRA_INVALID_PARAMETER")); - ErrorNames.insert(std::make_pair(8438, "ERROR_DS_DRA_BUSY")); - ErrorNames.insert(std::make_pair(8439, "ERROR_DS_DRA_BAD_DN")); - ErrorNames.insert(std::make_pair(8440, "ERROR_DS_DRA_BAD_NC")); - ErrorNames.insert(std::make_pair(8441, "ERROR_DS_DRA_DN_EXISTS")); - ErrorNames.insert(std::make_pair(8442, "ERROR_DS_DRA_INTERNAL_ERROR")); - ErrorNames.insert(std::make_pair(8443, "ERROR_DS_DRA_INCONSISTENT_DIT")); - ErrorNames.insert(std::make_pair(8444, "ERROR_DS_DRA_CONNECTION_FAILED")); - ErrorNames.insert(std::make_pair(8445, "ERROR_DS_DRA_BAD_INSTANCE_TYPE")); - ErrorNames.insert(std::make_pair(8446, "ERROR_DS_DRA_OUT_OF_MEM")); - ErrorNames.insert(std::make_pair(8447, "ERROR_DS_DRA_MAIL_PROBLEM")); - ErrorNames.insert(std::make_pair(8448, "ERROR_DS_DRA_REF_ALREADY_EXISTS")); - ErrorNames.insert(std::make_pair(8449, "ERROR_DS_DRA_REF_NOT_FOUND")); - ErrorNames.insert(std::make_pair(8450, "ERROR_DS_DRA_OBJ_IS_REP_SOURCE")); - ErrorNames.insert(std::make_pair(8451, "ERROR_DS_DRA_DB_ERROR")); - ErrorNames.insert(std::make_pair(8452, "ERROR_DS_DRA_NO_REPLICA")); - ErrorNames.insert(std::make_pair(8453, "ERROR_DS_DRA_ACCESS_DENIED")); - ErrorNames.insert(std::make_pair(8454, "ERROR_DS_DRA_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(8455, "ERROR_DS_DRA_RPC_CANCELLED")); - ErrorNames.insert(std::make_pair(8456, "ERROR_DS_DRA_SOURCE_DISABLED")); - ErrorNames.insert(std::make_pair(8457, "ERROR_DS_DRA_SINK_DISABLED")); - ErrorNames.insert(std::make_pair(8458, "ERROR_DS_DRA_NAME_COLLISION")); - ErrorNames.insert(std::make_pair(8459, "ERROR_DS_DRA_SOURCE_REINSTALLED")); - ErrorNames.insert(std::make_pair(8460, "ERROR_DS_DRA_MISSING_PARENT")); - ErrorNames.insert(std::make_pair(8461, "ERROR_DS_DRA_PREEMPTED")); - ErrorNames.insert(std::make_pair(8462, "ERROR_DS_DRA_ABANDON_SYNC")); - ErrorNames.insert(std::make_pair(8463, "ERROR_DS_DRA_SHUTDOWN")); - ErrorNames.insert(std::make_pair(8464, "ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET")); - ErrorNames.insert(std::make_pair(8465, "ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA")); - ErrorNames.insert(std::make_pair(8466, "ERROR_DS_DRA_EXTN_CONNECTION_FAILED")); - ErrorNames.insert(std::make_pair(8467, "ERROR_DS_INSTALL_SCHEMA_MISMATCH")); - ErrorNames.insert(std::make_pair(8468, "ERROR_DS_DUP_LINK_ID")); - ErrorNames.insert(std::make_pair(8469, "ERROR_DS_NAME_ERROR_RESOLVING")); - ErrorNames.insert(std::make_pair(8470, "ERROR_DS_NAME_ERROR_NOT_FOUND")); - ErrorNames.insert(std::make_pair(8471, "ERROR_DS_NAME_ERROR_NOT_UNIQUE")); - ErrorNames.insert(std::make_pair(8472, "ERROR_DS_NAME_ERROR_NO_MAPPING")); - ErrorNames.insert(std::make_pair(8473, "ERROR_DS_NAME_ERROR_DOMAIN_ONLY")); - ErrorNames.insert(std::make_pair(8474, "ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING")); - ErrorNames.insert(std::make_pair(8475, "ERROR_DS_CONSTRUCTED_ATT_MOD")); - ErrorNames.insert(std::make_pair(8476, "ERROR_DS_WRONG_OM_OBJ_CLASS")); - ErrorNames.insert(std::make_pair(8477, "ERROR_DS_DRA_REPL_PENDING")); - ErrorNames.insert(std::make_pair(8478, "ERROR_DS_DS_REQUIRED")); - ErrorNames.insert(std::make_pair(8479, "ERROR_DS_INVALID_LDAP_DISPLAY_NAME")); - ErrorNames.insert(std::make_pair(8480, "ERROR_DS_NON_BASE_SEARCH")); - ErrorNames.insert(std::make_pair(8481, "ERROR_DS_CANT_RETRIEVE_ATTS")); - ErrorNames.insert(std::make_pair(8482, "ERROR_DS_BACKLINK_WITHOUT_LINK")); - ErrorNames.insert(std::make_pair(8483, "ERROR_DS_EPOCH_MISMATCH")); - ErrorNames.insert(std::make_pair(8484, "ERROR_DS_SRC_NAME_MISMATCH")); - ErrorNames.insert(std::make_pair(8485, "ERROR_DS_SRC_AND_DST_NC_IDENTICAL")); - ErrorNames.insert(std::make_pair(8486, "ERROR_DS_DST_NC_MISMATCH")); - ErrorNames.insert(std::make_pair(8487, "ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC")); - ErrorNames.insert(std::make_pair(8488, "ERROR_DS_SRC_GUID_MISMATCH")); - ErrorNames.insert(std::make_pair(8489, "ERROR_DS_CANT_MOVE_DELETED_OBJECT")); - ErrorNames.insert(std::make_pair(8490, "ERROR_DS_PDC_OPERATION_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(8491, "ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD")); - ErrorNames.insert(std::make_pair(8492, "ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION")); - ErrorNames.insert(std::make_pair(8493, "ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS")); - ErrorNames.insert(std::make_pair(8494, "ERROR_DS_NC_MUST_HAVE_NC_PARENT")); - ErrorNames.insert(std::make_pair(8495, "ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE")); - ErrorNames.insert(std::make_pair(8496, "ERROR_DS_DST_DOMAIN_NOT_NATIVE")); - ErrorNames.insert(std::make_pair(8497, "ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER")); - ErrorNames.insert(std::make_pair(8498, "ERROR_DS_CANT_MOVE_ACCOUNT_GROUP")); - ErrorNames.insert(std::make_pair(8499, "ERROR_DS_CANT_MOVE_RESOURCE_GROUP")); - ErrorNames.insert(std::make_pair(8500, "ERROR_DS_INVALID_SEARCH_FLAG")); - ErrorNames.insert(std::make_pair(8501, "ERROR_DS_NO_TREE_DELETE_ABOVE_NC")); - ErrorNames.insert(std::make_pair(8502, "ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE")); - ErrorNames.insert(std::make_pair(8503, "ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE")); - ErrorNames.insert(std::make_pair(8504, "ERROR_DS_SAM_INIT_FAILURE")); - ErrorNames.insert(std::make_pair(8505, "ERROR_DS_SENSITIVE_GROUP_VIOLATION")); - ErrorNames.insert(std::make_pair(8506, "ERROR_DS_CANT_MOD_PRIMARYGROUPID")); - ErrorNames.insert(std::make_pair(8507, "ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD")); - ErrorNames.insert(std::make_pair(8508, "ERROR_DS_NONSAFE_SCHEMA_CHANGE")); - ErrorNames.insert(std::make_pair(8509, "ERROR_DS_SCHEMA_UPDATE_DISALLOWED")); - ErrorNames.insert(std::make_pair(8510, "ERROR_DS_CANT_CREATE_UNDER_SCHEMA")); - ErrorNames.insert(std::make_pair(8511, "ERROR_DS_INSTALL_NO_SRC_SCH_VERSION")); - ErrorNames.insert(std::make_pair(8512, "ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE")); - ErrorNames.insert(std::make_pair(8513, "ERROR_DS_INVALID_GROUP_TYPE")); - ErrorNames.insert(std::make_pair(8514, "ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN")); - ErrorNames.insert(std::make_pair(8515, "ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN")); - ErrorNames.insert(std::make_pair(8516, "ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER")); - ErrorNames.insert(std::make_pair(8517, "ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER")); - ErrorNames.insert(std::make_pair(8518, "ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER")); - ErrorNames.insert(std::make_pair(8519, "ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER")); - ErrorNames.insert(std::make_pair(8520, "ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER")); - ErrorNames.insert(std::make_pair(8521, "ERROR_DS_HAVE_PRIMARY_MEMBERS")); - ErrorNames.insert(std::make_pair(8522, "ERROR_DS_STRING_SD_CONVERSION_FAILED")); - ErrorNames.insert(std::make_pair(8523, "ERROR_DS_NAMING_MASTER_GC")); - ErrorNames.insert(std::make_pair(8524, "ERROR_DS_DNS_LOOKUP_FAILURE")); - ErrorNames.insert(std::make_pair(8525, "ERROR_DS_COULDNT_UPDATE_SPNS")); - ErrorNames.insert(std::make_pair(8526, "ERROR_DS_CANT_RETRIEVE_SD")); - ErrorNames.insert(std::make_pair(8527, "ERROR_DS_KEY_NOT_UNIQUE")); - ErrorNames.insert(std::make_pair(8528, "ERROR_DS_WRONG_LINKED_ATT_SYNTAX")); - ErrorNames.insert(std::make_pair(8529, "ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD")); - ErrorNames.insert(std::make_pair(8530, "ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY")); - ErrorNames.insert(std::make_pair(8531, "ERROR_DS_CANT_START")); - ErrorNames.insert(std::make_pair(8532, "ERROR_DS_INIT_FAILURE")); - ErrorNames.insert(std::make_pair(8533, "ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION")); - ErrorNames.insert(std::make_pair(8534, "ERROR_DS_SOURCE_DOMAIN_IN_FOREST")); - ErrorNames.insert(std::make_pair(8535, "ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST")); - ErrorNames.insert(std::make_pair(8536, "ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED")); - ErrorNames.insert(std::make_pair(8537, "ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN")); - ErrorNames.insert(std::make_pair(8538, "ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER")); - ErrorNames.insert(std::make_pair(8539, "ERROR_DS_SRC_SID_EXISTS_IN_FOREST")); - ErrorNames.insert(std::make_pair(8540, "ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH")); - ErrorNames.insert(std::make_pair(8541, "ERROR_SAM_INIT_FAILURE")); - ErrorNames.insert(std::make_pair(8542, "ERROR_DS_DRA_SCHEMA_INFO_SHIP")); - ErrorNames.insert(std::make_pair(8543, "ERROR_DS_DRA_SCHEMA_CONFLICT")); - ErrorNames.insert(std::make_pair(8544, "ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT")); - ErrorNames.insert(std::make_pair(8545, "ERROR_DS_DRA_OBJ_NC_MISMATCH")); - ErrorNames.insert(std::make_pair(8546, "ERROR_DS_NC_STILL_HAS_DSAS")); - ErrorNames.insert(std::make_pair(8547, "ERROR_DS_GC_REQUIRED")); - ErrorNames.insert(std::make_pair(8548, "ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY")); - ErrorNames.insert(std::make_pair(8549, "ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS")); - ErrorNames.insert(std::make_pair(8550, "ERROR_DS_CANT_ADD_TO_GC")); - ErrorNames.insert(std::make_pair(8551, "ERROR_DS_NO_CHECKPOINT_WITH_PDC")); - ErrorNames.insert(std::make_pair(8552, "ERROR_DS_SOURCE_AUDITING_NOT_ENABLED")); - ErrorNames.insert(std::make_pair(8553, "ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC")); - ErrorNames.insert(std::make_pair(8554, "ERROR_DS_INVALID_NAME_FOR_SPN")); - ErrorNames.insert(std::make_pair(8555, "ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS")); - ErrorNames.insert(std::make_pair(8556, "ERROR_DS_UNICODEPWD_NOT_IN_QUOTES")); - ErrorNames.insert(std::make_pair(8557, "ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED")); - ErrorNames.insert(std::make_pair(8558, "ERROR_DS_MUST_BE_RUN_ON_DST_DC")); - ErrorNames.insert(std::make_pair(8559, "ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER")); - ErrorNames.insert(std::make_pair(8560, "ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ")); - ErrorNames.insert(std::make_pair(8561, "ERROR_DS_INIT_FAILURE_CONSOLE")); - ErrorNames.insert(std::make_pair(8562, "ERROR_DS_SAM_INIT_FAILURE_CONSOLE")); - ErrorNames.insert(std::make_pair(8563, "ERROR_DS_FOREST_VERSION_TOO_HIGH")); - ErrorNames.insert(std::make_pair(8564, "ERROR_DS_DOMAIN_VERSION_TOO_HIGH")); - ErrorNames.insert(std::make_pair(8565, "ERROR_DS_FOREST_VERSION_TOO_LOW")); - ErrorNames.insert(std::make_pair(8566, "ERROR_DS_DOMAIN_VERSION_TOO_LOW")); - ErrorNames.insert(std::make_pair(8567, "ERROR_DS_INCOMPATIBLE_VERSION")); - ErrorNames.insert(std::make_pair(8568, "ERROR_DS_LOW_DSA_VERSION")); - ErrorNames.insert(std::make_pair(8569, "ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN")); - ErrorNames.insert(std::make_pair(8570, "ERROR_DS_NOT_SUPPORTED_SORT_ORDER")); - ErrorNames.insert(std::make_pair(8571, "ERROR_DS_NAME_NOT_UNIQUE")); - ErrorNames.insert(std::make_pair(8572, "ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4")); - ErrorNames.insert(std::make_pair(8573, "ERROR_DS_OUT_OF_VERSION_STORE")); - ErrorNames.insert(std::make_pair(8574, "ERROR_DS_INCOMPATIBLE_CONTROLS_USED")); - ErrorNames.insert(std::make_pair(8575, "ERROR_DS_NO_REF_DOMAIN")); - ErrorNames.insert(std::make_pair(8576, "ERROR_DS_RESERVED_LINK_ID")); - ErrorNames.insert(std::make_pair(8577, "ERROR_DS_LINK_ID_NOT_AVAILABLE")); - ErrorNames.insert(std::make_pair(8578, "ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER")); - ErrorNames.insert(std::make_pair(8579, "ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE")); - ErrorNames.insert(std::make_pair(8580, "ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC")); - ErrorNames.insert(std::make_pair(8581, "ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG")); - ErrorNames.insert(std::make_pair(8582, "ERROR_DS_MODIFYDN_WRONG_GRANDPARENT")); - ErrorNames.insert(std::make_pair(8583, "ERROR_DS_NAME_ERROR_TRUST_REFERRAL")); - ErrorNames.insert(std::make_pair(8584, "ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER")); - ErrorNames.insert(std::make_pair(8585, "ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD")); - ErrorNames.insert(std::make_pair(8586, "ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2")); - ErrorNames.insert(std::make_pair(8587, "ERROR_DS_THREAD_LIMIT_EXCEEDED")); - ErrorNames.insert(std::make_pair(8588, "ERROR_DS_NOT_CLOSEST")); - ErrorNames.insert(std::make_pair(8589, "ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF")); - ErrorNames.insert(std::make_pair(8590, "ERROR_DS_SINGLE_USER_MODE_FAILED")); - ErrorNames.insert(std::make_pair(8591, "ERROR_DS_NTDSCRIPT_SYNTAX_ERROR")); - ErrorNames.insert(std::make_pair(8592, "ERROR_DS_NTDSCRIPT_PROCESS_ERROR")); - ErrorNames.insert(std::make_pair(8593, "ERROR_DS_DIFFERENT_REPL_EPOCHS")); - ErrorNames.insert(std::make_pair(8594, "ERROR_DS_DRS_EXTENSIONS_CHANGED")); - ErrorNames.insert(std::make_pair(8595, "ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR")); - ErrorNames.insert(std::make_pair(8596, "ERROR_DS_NO_MSDS_INTID")); - ErrorNames.insert(std::make_pair(8597, "ERROR_DS_DUP_MSDS_INTID")); - ErrorNames.insert(std::make_pair(8598, "ERROR_DS_EXISTS_IN_RDNATTID")); - ErrorNames.insert(std::make_pair(8599, "ERROR_DS_AUTHORIZATION_FAILED")); - ErrorNames.insert(std::make_pair(8600, "ERROR_DS_INVALID_SCRIPT")); - ErrorNames.insert(std::make_pair(8601, "ERROR_DS_REMOTE_CROSSREF_OP_FAILED")); - ErrorNames.insert(std::make_pair(8602, "ERROR_DS_CROSS_REF_BUSY")); - ErrorNames.insert(std::make_pair(8603, "ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN")); - ErrorNames.insert(std::make_pair(8604, "ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC")); - ErrorNames.insert(std::make_pair(8605, "ERROR_DS_DUPLICATE_ID_FOUND")); - ErrorNames.insert(std::make_pair(8606, "ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT")); - ErrorNames.insert(std::make_pair(8607, "ERROR_DS_GROUP_CONVERSION_ERROR")); - ErrorNames.insert(std::make_pair(8608, "ERROR_DS_CANT_MOVE_APP_BASIC_GROUP")); - ErrorNames.insert(std::make_pair(8609, "ERROR_DS_CANT_MOVE_APP_QUERY_GROUP")); - ErrorNames.insert(std::make_pair(8610, "ERROR_DS_ROLE_NOT_VERIFIED")); - ErrorNames.insert(std::make_pair(8611, "ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL")); - ErrorNames.insert(std::make_pair(8612, "ERROR_DS_DOMAIN_RENAME_IN_PROGRESS")); - ErrorNames.insert(std::make_pair(8613, "ERROR_DS_EXISTING_AD_CHILD_NC")); - ErrorNames.insert(std::make_pair(8614, "ERROR_DS_REPL_LIFETIME_EXCEEDED")); - ErrorNames.insert(std::make_pair(8615, "ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER")); - ErrorNames.insert(std::make_pair(8616, "ERROR_DS_LDAP_SEND_QUEUE_FULL")); - ErrorNames.insert(std::make_pair(8617, "ERROR_DS_DRA_OUT_SCHEDULE_WINDOW")); - ErrorNames.insert(std::make_pair(8618, "ERROR_DS_POLICY_NOT_KNOWN")); - ErrorNames.insert(std::make_pair(8619, "ERROR_NO_SITE_SETTINGS_OBJECT")); - ErrorNames.insert(std::make_pair(8620, "ERROR_NO_SECRETS")); - ErrorNames.insert(std::make_pair(8621, "ERROR_NO_WRITABLE_DC_FOUND")); - ErrorNames.insert(std::make_pair(8622, "ERROR_DS_NO_SERVER_OBJECT")); - ErrorNames.insert(std::make_pair(8623, "ERROR_DS_NO_NTDSA_OBJECT")); - ErrorNames.insert(std::make_pair(8624, "ERROR_DS_NON_ASQ_SEARCH")); - ErrorNames.insert(std::make_pair(8625, "ERROR_DS_AUDIT_FAILURE")); - ErrorNames.insert(std::make_pair(8626, "ERROR_DS_INVALID_SEARCH_FLAG_SUBTREE")); - ErrorNames.insert(std::make_pair(8627, "ERROR_DS_INVALID_SEARCH_FLAG_TUPLE")); - ErrorNames.insert(std::make_pair(8628, "ERROR_DS_HIERARCHY_TABLE_TOO_DEEP")); - ErrorNames.insert(std::make_pair(8629, "ERROR_DS_DRA_CORRUPT_UTD_VECTOR")); - ErrorNames.insert(std::make_pair(8630, "ERROR_DS_DRA_SECRETS_DENIED")); - ErrorNames.insert(std::make_pair(8631, "ERROR_DS_RESERVED_MAPI_ID")); - ErrorNames.insert(std::make_pair(8632, "ERROR_DS_MAPI_ID_NOT_AVAILABLE")); - ErrorNames.insert(std::make_pair(8633, "ERROR_DS_DRA_MISSING_KRBTGT_SECRET")); - ErrorNames.insert(std::make_pair(8634, "ERROR_DS_DOMAIN_NAME_EXISTS_IN_FOREST")); - ErrorNames.insert(std::make_pair(8635, "ERROR_DS_FLAT_NAME_EXISTS_IN_FOREST")); - ErrorNames.insert(std::make_pair(8636, "ERROR_INVALID_USER_PRINCIPAL_NAME")); - ErrorNames.insert(std::make_pair(8637, "ERROR_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS")); - ErrorNames.insert(std::make_pair(8638, "ERROR_DS_OID_NOT_FOUND")); - ErrorNames.insert(std::make_pair(8639, "ERROR_DS_DRA_RECYCLED_TARGET")); - ErrorNames.insert(std::make_pair(13000, "ERROR_IPSEC_QM_POLICY_EXISTS")); - ErrorNames.insert(std::make_pair(13001, "ERROR_IPSEC_QM_POLICY_NOT_FOUND")); - ErrorNames.insert(std::make_pair(13002, "ERROR_IPSEC_QM_POLICY_IN_USE")); - ErrorNames.insert(std::make_pair(13003, "ERROR_IPSEC_MM_POLICY_EXISTS")); - ErrorNames.insert(std::make_pair(13004, "ERROR_IPSEC_MM_POLICY_NOT_FOUND")); - ErrorNames.insert(std::make_pair(13005, "ERROR_IPSEC_MM_POLICY_IN_USE")); - ErrorNames.insert(std::make_pair(13006, "ERROR_IPSEC_MM_FILTER_EXISTS")); - ErrorNames.insert(std::make_pair(13007, "ERROR_IPSEC_MM_FILTER_NOT_FOUND")); - ErrorNames.insert(std::make_pair(13008, "ERROR_IPSEC_TRANSPORT_FILTER_EXISTS")); - ErrorNames.insert(std::make_pair(13009, "ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND")); - ErrorNames.insert(std::make_pair(13010, "ERROR_IPSEC_MM_AUTH_EXISTS")); - ErrorNames.insert(std::make_pair(13011, "ERROR_IPSEC_MM_AUTH_NOT_FOUND")); - ErrorNames.insert(std::make_pair(13012, "ERROR_IPSEC_MM_AUTH_IN_USE")); - ErrorNames.insert(std::make_pair(13013, "ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND")); - ErrorNames.insert(std::make_pair(13014, "ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND")); - ErrorNames.insert(std::make_pair(13015, "ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND")); - ErrorNames.insert(std::make_pair(13016, "ERROR_IPSEC_TUNNEL_FILTER_EXISTS")); - ErrorNames.insert(std::make_pair(13017, "ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND")); - ErrorNames.insert(std::make_pair(13018, "ERROR_IPSEC_MM_FILTER_PENDING_DELETION")); - ErrorNames.insert(std::make_pair(13019, "ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION")); - ErrorNames.insert(std::make_pair(13020, "ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION")); - ErrorNames.insert(std::make_pair(13021, "ERROR_IPSEC_MM_POLICY_PENDING_DELETION")); - ErrorNames.insert(std::make_pair(13022, "ERROR_IPSEC_MM_AUTH_PENDING_DELETION")); - ErrorNames.insert(std::make_pair(13023, "ERROR_IPSEC_QM_POLICY_PENDING_DELETION")); - ErrorNames.insert(std::make_pair(13800, "ERROR_IPSEC_IKE_NEG_STATUS_BEGIN")); - ErrorNames.insert(std::make_pair(13801, "ERROR_IPSEC_IKE_AUTH_FAIL")); - ErrorNames.insert(std::make_pair(13802, "ERROR_IPSEC_IKE_ATTRIB_FAIL")); - ErrorNames.insert(std::make_pair(13803, "ERROR_IPSEC_IKE_NEGOTIATION_PENDING")); - ErrorNames.insert(std::make_pair(13804, "ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR")); - ErrorNames.insert(std::make_pair(13805, "ERROR_IPSEC_IKE_TIMED_OUT")); - ErrorNames.insert(std::make_pair(13806, "ERROR_IPSEC_IKE_NO_CERT")); - ErrorNames.insert(std::make_pair(13807, "ERROR_IPSEC_IKE_SA_DELETED")); - ErrorNames.insert(std::make_pair(13808, "ERROR_IPSEC_IKE_SA_REAPED")); - ErrorNames.insert(std::make_pair(13809, "ERROR_IPSEC_IKE_MM_ACQUIRE_DROP")); - ErrorNames.insert(std::make_pair(13810, "ERROR_IPSEC_IKE_QM_ACQUIRE_DROP")); - ErrorNames.insert(std::make_pair(13811, "ERROR_IPSEC_IKE_QUEUE_DROP_MM")); - ErrorNames.insert(std::make_pair(13812, "ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM")); - ErrorNames.insert(std::make_pair(13813, "ERROR_IPSEC_IKE_DROP_NO_RESPONSE")); - ErrorNames.insert(std::make_pair(13814, "ERROR_IPSEC_IKE_MM_DELAY_DROP")); - ErrorNames.insert(std::make_pair(13815, "ERROR_IPSEC_IKE_QM_DELAY_DROP")); - ErrorNames.insert(std::make_pair(13816, "ERROR_IPSEC_IKE_ERROR")); - ErrorNames.insert(std::make_pair(13817, "ERROR_IPSEC_IKE_CRL_FAILED")); - ErrorNames.insert(std::make_pair(13818, "ERROR_IPSEC_IKE_INVALID_KEY_USAGE")); - ErrorNames.insert(std::make_pair(13819, "ERROR_IPSEC_IKE_INVALID_CERT_TYPE")); - ErrorNames.insert(std::make_pair(13820, "ERROR_IPSEC_IKE_NO_PRIVATE_KEY")); - ErrorNames.insert(std::make_pair(13821, "ERROR_IPSEC_IKE_SIMULTANEOUS_REKEY")); - ErrorNames.insert(std::make_pair(13822, "ERROR_IPSEC_IKE_DH_FAIL")); - ErrorNames.insert(std::make_pair(13823, "ERROR_IPSEC_IKE_CRITICAL_PAYLOAD_NOT_RECOGNIZED")); - ErrorNames.insert(std::make_pair(13824, "ERROR_IPSEC_IKE_INVALID_HEADER")); - ErrorNames.insert(std::make_pair(13825, "ERROR_IPSEC_IKE_NO_POLICY")); - ErrorNames.insert(std::make_pair(13826, "ERROR_IPSEC_IKE_INVALID_SIGNATURE")); - ErrorNames.insert(std::make_pair(13827, "ERROR_IPSEC_IKE_KERBEROS_ERROR")); - ErrorNames.insert(std::make_pair(13828, "ERROR_IPSEC_IKE_NO_PUBLIC_KEY")); - ErrorNames.insert(std::make_pair(13829, "ERROR_IPSEC_IKE_PROCESS_ERR")); - ErrorNames.insert(std::make_pair(13830, "ERROR_IPSEC_IKE_PROCESS_ERR_SA")); - ErrorNames.insert(std::make_pair(13831, "ERROR_IPSEC_IKE_PROCESS_ERR_PROP")); - ErrorNames.insert(std::make_pair(13832, "ERROR_IPSEC_IKE_PROCESS_ERR_TRANS")); - ErrorNames.insert(std::make_pair(13833, "ERROR_IPSEC_IKE_PROCESS_ERR_KE")); - ErrorNames.insert(std::make_pair(13834, "ERROR_IPSEC_IKE_PROCESS_ERR_ID")); - ErrorNames.insert(std::make_pair(13835, "ERROR_IPSEC_IKE_PROCESS_ERR_CERT")); - ErrorNames.insert(std::make_pair(13836, "ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ")); - ErrorNames.insert(std::make_pair(13837, "ERROR_IPSEC_IKE_PROCESS_ERR_HASH")); - ErrorNames.insert(std::make_pair(13838, "ERROR_IPSEC_IKE_PROCESS_ERR_SIG")); - ErrorNames.insert(std::make_pair(13839, "ERROR_IPSEC_IKE_PROCESS_ERR_NONCE")); - ErrorNames.insert(std::make_pair(13840, "ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY")); - ErrorNames.insert(std::make_pair(13841, "ERROR_IPSEC_IKE_PROCESS_ERR_DELETE")); - ErrorNames.insert(std::make_pair(13842, "ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR")); - ErrorNames.insert(std::make_pair(13843, "ERROR_IPSEC_IKE_INVALID_PAYLOAD")); - ErrorNames.insert(std::make_pair(13844, "ERROR_IPSEC_IKE_LOAD_SOFT_SA")); - ErrorNames.insert(std::make_pair(13845, "ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN")); - ErrorNames.insert(std::make_pair(13846, "ERROR_IPSEC_IKE_INVALID_COOKIE")); - ErrorNames.insert(std::make_pair(13847, "ERROR_IPSEC_IKE_NO_PEER_CERT")); - ErrorNames.insert(std::make_pair(13848, "ERROR_IPSEC_IKE_PEER_CRL_FAILED")); - ErrorNames.insert(std::make_pair(13849, "ERROR_IPSEC_IKE_POLICY_CHANGE")); - ErrorNames.insert(std::make_pair(13850, "ERROR_IPSEC_IKE_NO_MM_POLICY")); - ErrorNames.insert(std::make_pair(13851, "ERROR_IPSEC_IKE_NOTCBPRIV")); - ErrorNames.insert(std::make_pair(13852, "ERROR_IPSEC_IKE_SECLOADFAIL")); - ErrorNames.insert(std::make_pair(13853, "ERROR_IPSEC_IKE_FAILSSPINIT")); - ErrorNames.insert(std::make_pair(13854, "ERROR_IPSEC_IKE_FAILQUERYSSP")); - ErrorNames.insert(std::make_pair(13855, "ERROR_IPSEC_IKE_SRVACQFAIL")); - ErrorNames.insert(std::make_pair(13856, "ERROR_IPSEC_IKE_SRVQUERYCRED")); - ErrorNames.insert(std::make_pair(13857, "ERROR_IPSEC_IKE_GETSPIFAIL")); - ErrorNames.insert(std::make_pair(13858, "ERROR_IPSEC_IKE_INVALID_FILTER")); - ErrorNames.insert(std::make_pair(13859, "ERROR_IPSEC_IKE_OUT_OF_MEMORY")); - ErrorNames.insert(std::make_pair(13860, "ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED")); - ErrorNames.insert(std::make_pair(13861, "ERROR_IPSEC_IKE_INVALID_POLICY")); - ErrorNames.insert(std::make_pair(13862, "ERROR_IPSEC_IKE_UNKNOWN_DOI")); - ErrorNames.insert(std::make_pair(13863, "ERROR_IPSEC_IKE_INVALID_SITUATION")); - ErrorNames.insert(std::make_pair(13864, "ERROR_IPSEC_IKE_DH_FAILURE")); - ErrorNames.insert(std::make_pair(13865, "ERROR_IPSEC_IKE_INVALID_GROUP")); - ErrorNames.insert(std::make_pair(13866, "ERROR_IPSEC_IKE_ENCRYPT")); - ErrorNames.insert(std::make_pair(13867, "ERROR_IPSEC_IKE_DECRYPT")); - ErrorNames.insert(std::make_pair(13868, "ERROR_IPSEC_IKE_POLICY_MATCH")); - ErrorNames.insert(std::make_pair(13869, "ERROR_IPSEC_IKE_UNSUPPORTED_ID")); - ErrorNames.insert(std::make_pair(13870, "ERROR_IPSEC_IKE_INVALID_HASH")); - ErrorNames.insert(std::make_pair(13871, "ERROR_IPSEC_IKE_INVALID_HASH_ALG")); - ErrorNames.insert(std::make_pair(13872, "ERROR_IPSEC_IKE_INVALID_HASH_SIZE")); - ErrorNames.insert(std::make_pair(13873, "ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG")); - ErrorNames.insert(std::make_pair(13874, "ERROR_IPSEC_IKE_INVALID_AUTH_ALG")); - ErrorNames.insert(std::make_pair(13875, "ERROR_IPSEC_IKE_INVALID_SIG")); - ErrorNames.insert(std::make_pair(13876, "ERROR_IPSEC_IKE_LOAD_FAILED")); - ErrorNames.insert(std::make_pair(13877, "ERROR_IPSEC_IKE_RPC_DELETE")); - ErrorNames.insert(std::make_pair(13878, "ERROR_IPSEC_IKE_BENIGN_REINIT")); - ErrorNames.insert(std::make_pair(13879, "ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY")); - ErrorNames.insert(std::make_pair(13880, "ERROR_IPSEC_IKE_INVALID_MAJOR_VERSION")); - ErrorNames.insert(std::make_pair(13881, "ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN")); - ErrorNames.insert(std::make_pair(13882, "ERROR_IPSEC_IKE_MM_LIMIT")); - ErrorNames.insert(std::make_pair(13883, "ERROR_IPSEC_IKE_NEGOTIATION_DISABLED")); - ErrorNames.insert(std::make_pair(13884, "ERROR_IPSEC_IKE_QM_LIMIT")); - ErrorNames.insert(std::make_pair(13885, "ERROR_IPSEC_IKE_MM_EXPIRED")); - ErrorNames.insert(std::make_pair(13886, "ERROR_IPSEC_IKE_PEER_MM_ASSUMED_INVALID")); - ErrorNames.insert(std::make_pair(13887, "ERROR_IPSEC_IKE_CERT_CHAIN_POLICY_MISMATCH")); - ErrorNames.insert(std::make_pair(13888, "ERROR_IPSEC_IKE_UNEXPECTED_MESSAGE_ID")); - ErrorNames.insert(std::make_pair(13889, "ERROR_IPSEC_IKE_INVALID_AUTH_PAYLOAD")); - ErrorNames.insert(std::make_pair(13890, "ERROR_IPSEC_IKE_DOS_COOKIE_SENT")); - ErrorNames.insert(std::make_pair(13891, "ERROR_IPSEC_IKE_SHUTTING_DOWN")); - ErrorNames.insert(std::make_pair(13892, "ERROR_IPSEC_IKE_CGA_AUTH_FAILED")); - ErrorNames.insert(std::make_pair(13893, "ERROR_IPSEC_IKE_PROCESS_ERR_NATOA")); - ErrorNames.insert(std::make_pair(13894, "ERROR_IPSEC_IKE_INVALID_MM_FOR_QM")); - ErrorNames.insert(std::make_pair(13895, "ERROR_IPSEC_IKE_QM_EXPIRED")); - ErrorNames.insert(std::make_pair(13896, "ERROR_IPSEC_IKE_TOO_MANY_FILTERS")); - ErrorNames.insert(std::make_pair(13897, "ERROR_IPSEC_IKE_NEG_STATUS_END")); - ErrorNames.insert(std::make_pair(13898, "ERROR_IPSEC_IKE_KILL_DUMMY_NAP_TUNNEL")); - ErrorNames.insert(std::make_pair(13899, "ERROR_IPSEC_IKE_INNER_IP_ASSIGNMENT_FAILURE")); - ErrorNames.insert(std::make_pair(13900, "ERROR_IPSEC_IKE_REQUIRE_CP_PAYLOAD_MISSING")); - ErrorNames.insert(std::make_pair(13901, "ERROR_IPSEC_KEY_MODULE_IMPERSONATION_NEGOTIATION_PENDING")); - ErrorNames.insert(std::make_pair(13902, "ERROR_IPSEC_IKE_COEXISTENCE_SUPPRESS")); - ErrorNames.insert(std::make_pair(13903, "ERROR_IPSEC_IKE_RATELIMIT_DROP")); - ErrorNames.insert(std::make_pair(13904, "ERROR_IPSEC_IKE_PEER_DOESNT_SUPPORT_MOBIKE")); - ErrorNames.insert(std::make_pair(13905, "ERROR_IPSEC_IKE_AUTHORIZATION_FAILURE")); - ErrorNames.insert(std::make_pair(13906, "ERROR_IPSEC_IKE_STRONG_CRED_AUTHORIZATION_FAILURE")); - ErrorNames.insert(std::make_pair(13907, "ERROR_IPSEC_IKE_AUTHORIZATION_FAILURE_WITH_OPTIONAL_RETRY")); - ErrorNames.insert(std::make_pair(13908, "ERROR_IPSEC_IKE_STRONG_CRED_AUTHORIZATION_AND_CERTMAP_FAILURE")); - ErrorNames.insert(std::make_pair(13909, "ERROR_IPSEC_IKE_NEG_STATUS_EXTENDED_END")); - ErrorNames.insert(std::make_pair(13910, "ERROR_IPSEC_BAD_SPI")); - ErrorNames.insert(std::make_pair(13911, "ERROR_IPSEC_SA_LIFETIME_EXPIRED")); - ErrorNames.insert(std::make_pair(13912, "ERROR_IPSEC_WRONG_SA")); - ErrorNames.insert(std::make_pair(13913, "ERROR_IPSEC_REPLAY_CHECK_FAILED")); - ErrorNames.insert(std::make_pair(13914, "ERROR_IPSEC_INVALID_PACKET")); - ErrorNames.insert(std::make_pair(13915, "ERROR_IPSEC_INTEGRITY_CHECK_FAILED")); - ErrorNames.insert(std::make_pair(13916, "ERROR_IPSEC_CLEAR_TEXT_DROP")); - ErrorNames.insert(std::make_pair(13917, "ERROR_IPSEC_AUTH_FIREWALL_DROP")); - ErrorNames.insert(std::make_pair(13918, "ERROR_IPSEC_THROTTLE_DROP")); - ErrorNames.insert(std::make_pair(13925, "ERROR_IPSEC_DOSP_BLOCK")); - ErrorNames.insert(std::make_pair(13926, "ERROR_IPSEC_DOSP_RECEIVED_MULTICAST")); - ErrorNames.insert(std::make_pair(13927, "ERROR_IPSEC_DOSP_INVALID_PACKET")); - ErrorNames.insert(std::make_pair(13928, "ERROR_IPSEC_DOSP_STATE_LOOKUP_FAILED")); - ErrorNames.insert(std::make_pair(13929, "ERROR_IPSEC_DOSP_MAX_ENTRIES")); - ErrorNames.insert(std::make_pair(13930, "ERROR_IPSEC_DOSP_KEYMOD_NOT_ALLOWED")); - ErrorNames.insert(std::make_pair(13931, "ERROR_IPSEC_DOSP_NOT_INSTALLED")); - ErrorNames.insert(std::make_pair(13932, "ERROR_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES")); - ErrorNames.insert(std::make_pair(14000, "ERROR_SXS_SECTION_NOT_FOUND")); - ErrorNames.insert(std::make_pair(14001, "ERROR_SXS_CANT_GEN_ACTCTX")); - ErrorNames.insert(std::make_pair(14002, "ERROR_SXS_INVALID_ACTCTXDATA_FORMAT")); - ErrorNames.insert(std::make_pair(14003, "ERROR_SXS_ASSEMBLY_NOT_FOUND")); - ErrorNames.insert(std::make_pair(14004, "ERROR_SXS_MANIFEST_FORMAT_ERROR")); - ErrorNames.insert(std::make_pair(14005, "ERROR_SXS_MANIFEST_PARSE_ERROR")); - ErrorNames.insert(std::make_pair(14006, "ERROR_SXS_ACTIVATION_CONTEXT_DISABLED")); - ErrorNames.insert(std::make_pair(14007, "ERROR_SXS_KEY_NOT_FOUND")); - ErrorNames.insert(std::make_pair(14008, "ERROR_SXS_VERSION_CONFLICT")); - ErrorNames.insert(std::make_pair(14009, "ERROR_SXS_WRONG_SECTION_TYPE")); - ErrorNames.insert(std::make_pair(14010, "ERROR_SXS_THREAD_QUERIES_DISABLED")); - ErrorNames.insert(std::make_pair(14011, "ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET")); - ErrorNames.insert(std::make_pair(14012, "ERROR_SXS_UNKNOWN_ENCODING_GROUP")); - ErrorNames.insert(std::make_pair(14013, "ERROR_SXS_UNKNOWN_ENCODING")); - ErrorNames.insert(std::make_pair(14014, "ERROR_SXS_INVALID_XML_NAMESPACE_URI")); - ErrorNames.insert(std::make_pair(14015, "ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED")); - ErrorNames.insert(std::make_pair(14016, "ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED")); - ErrorNames.insert(std::make_pair(14017, "ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE")); - ErrorNames.insert(std::make_pair(14018, "ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE")); - ErrorNames.insert(std::make_pair(14019, "ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE")); - ErrorNames.insert(std::make_pair(14020, "ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT")); - ErrorNames.insert(std::make_pair(14021, "ERROR_SXS_DUPLICATE_DLL_NAME")); - ErrorNames.insert(std::make_pair(14022, "ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME")); - ErrorNames.insert(std::make_pair(14023, "ERROR_SXS_DUPLICATE_CLSID")); - ErrorNames.insert(std::make_pair(14024, "ERROR_SXS_DUPLICATE_IID")); - ErrorNames.insert(std::make_pair(14025, "ERROR_SXS_DUPLICATE_TLBID")); - ErrorNames.insert(std::make_pair(14026, "ERROR_SXS_DUPLICATE_PROGID")); - ErrorNames.insert(std::make_pair(14027, "ERROR_SXS_DUPLICATE_ASSEMBLY_NAME")); - ErrorNames.insert(std::make_pair(14028, "ERROR_SXS_FILE_HASH_MISMATCH")); - ErrorNames.insert(std::make_pair(14029, "ERROR_SXS_POLICY_PARSE_ERROR")); - ErrorNames.insert(std::make_pair(14030, "ERROR_SXS_XML_E_MISSINGQUOTE")); - ErrorNames.insert(std::make_pair(14031, "ERROR_SXS_XML_E_COMMENTSYNTAX")); - ErrorNames.insert(std::make_pair(14032, "ERROR_SXS_XML_E_BADSTARTNAMECHAR")); - ErrorNames.insert(std::make_pair(14033, "ERROR_SXS_XML_E_BADNAMECHAR")); - ErrorNames.insert(std::make_pair(14034, "ERROR_SXS_XML_E_BADCHARINSTRING")); - ErrorNames.insert(std::make_pair(14035, "ERROR_SXS_XML_E_XMLDECLSYNTAX")); - ErrorNames.insert(std::make_pair(14036, "ERROR_SXS_XML_E_BADCHARDATA")); - ErrorNames.insert(std::make_pair(14037, "ERROR_SXS_XML_E_MISSINGWHITESPACE")); - ErrorNames.insert(std::make_pair(14038, "ERROR_SXS_XML_E_EXPECTINGTAGEND")); - ErrorNames.insert(std::make_pair(14039, "ERROR_SXS_XML_E_MISSINGSEMICOLON")); - ErrorNames.insert(std::make_pair(14040, "ERROR_SXS_XML_E_UNBALANCEDPAREN")); - ErrorNames.insert(std::make_pair(14041, "ERROR_SXS_XML_E_INTERNALERROR")); - ErrorNames.insert(std::make_pair(14042, "ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE")); - ErrorNames.insert(std::make_pair(14043, "ERROR_SXS_XML_E_INCOMPLETE_ENCODING")); - ErrorNames.insert(std::make_pair(14044, "ERROR_SXS_XML_E_MISSING_PAREN")); - ErrorNames.insert(std::make_pair(14045, "ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE")); - ErrorNames.insert(std::make_pair(14046, "ERROR_SXS_XML_E_MULTIPLE_COLONS")); - ErrorNames.insert(std::make_pair(14047, "ERROR_SXS_XML_E_INVALID_DECIMAL")); - ErrorNames.insert(std::make_pair(14048, "ERROR_SXS_XML_E_INVALID_HEXIDECIMAL")); - ErrorNames.insert(std::make_pair(14049, "ERROR_SXS_XML_E_INVALID_UNICODE")); - ErrorNames.insert(std::make_pair(14050, "ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK")); - ErrorNames.insert(std::make_pair(14051, "ERROR_SXS_XML_E_UNEXPECTEDENDTAG")); - ErrorNames.insert(std::make_pair(14052, "ERROR_SXS_XML_E_UNCLOSEDTAG")); - ErrorNames.insert(std::make_pair(14053, "ERROR_SXS_XML_E_DUPLICATEATTRIBUTE")); - ErrorNames.insert(std::make_pair(14054, "ERROR_SXS_XML_E_MULTIPLEROOTS")); - ErrorNames.insert(std::make_pair(14055, "ERROR_SXS_XML_E_INVALIDATROOTLEVEL")); - ErrorNames.insert(std::make_pair(14056, "ERROR_SXS_XML_E_BADXMLDECL")); - ErrorNames.insert(std::make_pair(14057, "ERROR_SXS_XML_E_MISSINGROOT")); - ErrorNames.insert(std::make_pair(14058, "ERROR_SXS_XML_E_UNEXPECTEDEOF")); - ErrorNames.insert(std::make_pair(14059, "ERROR_SXS_XML_E_BADPEREFINSUBSET")); - ErrorNames.insert(std::make_pair(14060, "ERROR_SXS_XML_E_UNCLOSEDSTARTTAG")); - ErrorNames.insert(std::make_pair(14061, "ERROR_SXS_XML_E_UNCLOSEDENDTAG")); - ErrorNames.insert(std::make_pair(14062, "ERROR_SXS_XML_E_UNCLOSEDSTRING")); - ErrorNames.insert(std::make_pair(14063, "ERROR_SXS_XML_E_UNCLOSEDCOMMENT")); - ErrorNames.insert(std::make_pair(14064, "ERROR_SXS_XML_E_UNCLOSEDDECL")); - ErrorNames.insert(std::make_pair(14065, "ERROR_SXS_XML_E_UNCLOSEDCDATA")); - ErrorNames.insert(std::make_pair(14066, "ERROR_SXS_XML_E_RESERVEDNAMESPACE")); - ErrorNames.insert(std::make_pair(14067, "ERROR_SXS_XML_E_INVALIDENCODING")); - ErrorNames.insert(std::make_pair(14068, "ERROR_SXS_XML_E_INVALIDSWITCH")); - ErrorNames.insert(std::make_pair(14069, "ERROR_SXS_XML_E_BADXMLCASE")); - ErrorNames.insert(std::make_pair(14070, "ERROR_SXS_XML_E_INVALID_STANDALONE")); - ErrorNames.insert(std::make_pair(14071, "ERROR_SXS_XML_E_UNEXPECTED_STANDALONE")); - ErrorNames.insert(std::make_pair(14072, "ERROR_SXS_XML_E_INVALID_VERSION")); - ErrorNames.insert(std::make_pair(14073, "ERROR_SXS_XML_E_MISSINGEQUALS")); - ErrorNames.insert(std::make_pair(14074, "ERROR_SXS_PROTECTION_RECOVERY_FAILED")); - ErrorNames.insert(std::make_pair(14075, "ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT")); - ErrorNames.insert(std::make_pair(14076, "ERROR_SXS_PROTECTION_CATALOG_NOT_VALID")); - ErrorNames.insert(std::make_pair(14077, "ERROR_SXS_UNTRANSLATABLE_HRESULT")); - ErrorNames.insert(std::make_pair(14078, "ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING")); - ErrorNames.insert(std::make_pair(14079, "ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE")); - ErrorNames.insert(std::make_pair(14080, "ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME")); - ErrorNames.insert(std::make_pair(14081, "ERROR_SXS_ASSEMBLY_MISSING")); - ErrorNames.insert(std::make_pair(14082, "ERROR_SXS_CORRUPT_ACTIVATION_STACK")); - ErrorNames.insert(std::make_pair(14083, "ERROR_SXS_CORRUPTION")); - ErrorNames.insert(std::make_pair(14084, "ERROR_SXS_EARLY_DEACTIVATION")); - ErrorNames.insert(std::make_pair(14085, "ERROR_SXS_INVALID_DEACTIVATION")); - ErrorNames.insert(std::make_pair(14086, "ERROR_SXS_MULTIPLE_DEACTIVATION")); - ErrorNames.insert(std::make_pair(14087, "ERROR_SXS_PROCESS_TERMINATION_REQUESTED")); - ErrorNames.insert(std::make_pair(14088, "ERROR_SXS_RELEASE_ACTIVATION_CONTEXT")); - ErrorNames.insert(std::make_pair(14089, "ERROR_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY")); - ErrorNames.insert(std::make_pair(14090, "ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE")); - ErrorNames.insert(std::make_pair(14091, "ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME")); - ErrorNames.insert(std::make_pair(14092, "ERROR_SXS_IDENTITY_DUPLICATE_ATTRIBUTE")); - ErrorNames.insert(std::make_pair(14093, "ERROR_SXS_IDENTITY_PARSE_ERROR")); - ErrorNames.insert(std::make_pair(14094, "ERROR_MALFORMED_SUBSTITUTION_STRING")); - ErrorNames.insert(std::make_pair(14095, "ERROR_SXS_INCORRECT_PUBLIC_KEY_TOKEN")); - ErrorNames.insert(std::make_pair(14096, "ERROR_UNMAPPED_SUBSTITUTION_STRING")); - ErrorNames.insert(std::make_pair(14097, "ERROR_SXS_ASSEMBLY_NOT_LOCKED")); - ErrorNames.insert(std::make_pair(14098, "ERROR_SXS_COMPONENT_STORE_CORRUPT")); - ErrorNames.insert(std::make_pair(14099, "ERROR_ADVANCED_INSTALLER_FAILED")); - ErrorNames.insert(std::make_pair(14100, "ERROR_XML_ENCODING_MISMATCH")); - ErrorNames.insert(std::make_pair(14101, "ERROR_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT")); - ErrorNames.insert(std::make_pair(14102, "ERROR_SXS_IDENTITIES_DIFFERENT")); - ErrorNames.insert(std::make_pair(14103, "ERROR_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT")); - ErrorNames.insert(std::make_pair(14104, "ERROR_SXS_FILE_NOT_PART_OF_ASSEMBLY")); - ErrorNames.insert(std::make_pair(14105, "ERROR_SXS_MANIFEST_TOO_BIG")); - ErrorNames.insert(std::make_pair(14106, "ERROR_SXS_SETTING_NOT_REGISTERED")); - ErrorNames.insert(std::make_pair(14107, "ERROR_SXS_TRANSACTION_CLOSURE_INCOMPLETE")); - ErrorNames.insert(std::make_pair(14108, "ERROR_SMI_PRIMITIVE_INSTALLER_FAILED")); - ErrorNames.insert(std::make_pair(14109, "ERROR_GENERIC_COMMAND_FAILED")); - ErrorNames.insert(std::make_pair(14110, "ERROR_SXS_FILE_HASH_MISSING")); - ErrorNames.insert(std::make_pair(15000, "ERROR_EVT_INVALID_CHANNEL_PATH")); - ErrorNames.insert(std::make_pair(15001, "ERROR_EVT_INVALID_QUERY")); - ErrorNames.insert(std::make_pair(15002, "ERROR_EVT_PUBLISHER_METADATA_NOT_FOUND")); - ErrorNames.insert(std::make_pair(15003, "ERROR_EVT_EVENT_TEMPLATE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(15004, "ERROR_EVT_INVALID_PUBLISHER_NAME")); - ErrorNames.insert(std::make_pair(15005, "ERROR_EVT_INVALID_EVENT_DATA")); - ErrorNames.insert(std::make_pair(15007, "ERROR_EVT_CHANNEL_NOT_FOUND")); - ErrorNames.insert(std::make_pair(15008, "ERROR_EVT_MALFORMED_XML_TEXT")); - ErrorNames.insert(std::make_pair(15009, "ERROR_EVT_SUBSCRIPTION_TO_DIRECT_CHANNEL")); - ErrorNames.insert(std::make_pair(15010, "ERROR_EVT_CONFIGURATION_ERROR")); - ErrorNames.insert(std::make_pair(15011, "ERROR_EVT_QUERY_RESULT_STALE")); - ErrorNames.insert(std::make_pair(15012, "ERROR_EVT_QUERY_RESULT_INVALID_POSITION")); - ErrorNames.insert(std::make_pair(15013, "ERROR_EVT_NON_VALIDATING_MSXML")); - ErrorNames.insert(std::make_pair(15014, "ERROR_EVT_FILTER_ALREADYSCOPED")); - ErrorNames.insert(std::make_pair(15015, "ERROR_EVT_FILTER_NOTELTSET")); - ErrorNames.insert(std::make_pair(15016, "ERROR_EVT_FILTER_INVARG")); - ErrorNames.insert(std::make_pair(15017, "ERROR_EVT_FILTER_INVTEST")); - ErrorNames.insert(std::make_pair(15018, "ERROR_EVT_FILTER_INVTYPE")); - ErrorNames.insert(std::make_pair(15019, "ERROR_EVT_FILTER_PARSEERR")); - ErrorNames.insert(std::make_pair(15020, "ERROR_EVT_FILTER_UNSUPPORTEDOP")); - ErrorNames.insert(std::make_pair(15021, "ERROR_EVT_FILTER_UNEXPECTEDTOKEN")); - ErrorNames.insert(std::make_pair(15022, "ERROR_EVT_INVALID_OPERATION_OVER_ENABLED_DIRECT_CHANNEL")); - ErrorNames.insert(std::make_pair(15023, "ERROR_EVT_INVALID_CHANNEL_PROPERTY_VALUE")); - ErrorNames.insert(std::make_pair(15024, "ERROR_EVT_INVALID_PUBLISHER_PROPERTY_VALUE")); - ErrorNames.insert(std::make_pair(15025, "ERROR_EVT_CHANNEL_CANNOT_ACTIVATE")); - ErrorNames.insert(std::make_pair(15026, "ERROR_EVT_FILTER_TOO_COMPLEX")); - ErrorNames.insert(std::make_pair(15027, "ERROR_EVT_MESSAGE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(15028, "ERROR_EVT_MESSAGE_ID_NOT_FOUND")); - ErrorNames.insert(std::make_pair(15029, "ERROR_EVT_UNRESOLVED_VALUE_INSERT")); - ErrorNames.insert(std::make_pair(15030, "ERROR_EVT_UNRESOLVED_PARAMETER_INSERT")); - ErrorNames.insert(std::make_pair(15031, "ERROR_EVT_MAX_INSERTS_REACHED")); - ErrorNames.insert(std::make_pair(15032, "ERROR_EVT_EVENT_DEFINITION_NOT_FOUND")); - ErrorNames.insert(std::make_pair(15033, "ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(15034, "ERROR_EVT_VERSION_TOO_OLD")); - ErrorNames.insert(std::make_pair(15035, "ERROR_EVT_VERSION_TOO_NEW")); - ErrorNames.insert(std::make_pair(15036, "ERROR_EVT_CANNOT_OPEN_CHANNEL_OF_QUERY")); - ErrorNames.insert(std::make_pair(15037, "ERROR_EVT_PUBLISHER_DISABLED")); - ErrorNames.insert(std::make_pair(15038, "ERROR_EVT_FILTER_OUT_OF_RANGE")); - ErrorNames.insert(std::make_pair(15080, "ERROR_EC_SUBSCRIPTION_CANNOT_ACTIVATE")); - ErrorNames.insert(std::make_pair(15081, "ERROR_EC_LOG_DISABLED")); - ErrorNames.insert(std::make_pair(15082, "ERROR_EC_CIRCULAR_FORWARDING")); - ErrorNames.insert(std::make_pair(15083, "ERROR_EC_CREDSTORE_FULL")); - ErrorNames.insert(std::make_pair(15084, "ERROR_EC_CRED_NOT_FOUND")); - ErrorNames.insert(std::make_pair(15085, "ERROR_EC_NO_ACTIVE_CHANNEL")); - ErrorNames.insert(std::make_pair(15100, "ERROR_MUI_FILE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(15101, "ERROR_MUI_INVALID_FILE")); - ErrorNames.insert(std::make_pair(15102, "ERROR_MUI_INVALID_RC_CONFIG")); - ErrorNames.insert(std::make_pair(15103, "ERROR_MUI_INVALID_LOCALE_NAME")); - ErrorNames.insert(std::make_pair(15104, "ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME")); - ErrorNames.insert(std::make_pair(15105, "ERROR_MUI_FILE_NOT_LOADED")); - ErrorNames.insert(std::make_pair(15106, "ERROR_RESOURCE_ENUM_USER_STOP")); - ErrorNames.insert(std::make_pair(15107, "ERROR_MUI_INTLSETTINGS_UILANG_NOT_INSTALLED")); - ErrorNames.insert(std::make_pair(15108, "ERROR_MUI_INTLSETTINGS_INVALID_LOCALE_NAME")); - ErrorNames.insert(std::make_pair(15200, "ERROR_MCA_INVALID_CAPABILITIES_STRING")); - ErrorNames.insert(std::make_pair(15201, "ERROR_MCA_INVALID_VCP_VERSION")); - ErrorNames.insert(std::make_pair(15202, "ERROR_MCA_MONITOR_VIOLATES_MCCS_SPECIFICATION")); - ErrorNames.insert(std::make_pair(15203, "ERROR_MCA_MCCS_VERSION_MISMATCH")); - ErrorNames.insert(std::make_pair(15204, "ERROR_MCA_UNSUPPORTED_MCCS_VERSION")); - ErrorNames.insert(std::make_pair(15205, "ERROR_MCA_INTERNAL_ERROR")); - ErrorNames.insert(std::make_pair(15206, "ERROR_MCA_INVALID_TECHNOLOGY_TYPE_RETURNED")); - ErrorNames.insert(std::make_pair(15207, "ERROR_MCA_UNSUPPORTED_COLOR_TEMPERATURE")); - ErrorNames.insert(std::make_pair(15250, "ERROR_AMBIGUOUS_SYSTEM_DEVICE")); - ErrorNames.insert(std::make_pair(15299, "ERROR_SYSTEM_DEVICE_NOT_FOUND")); - ErrorNames.insert(std::make_pair(15300, "ERROR_HASH_NOT_SUPPORTED")); - ErrorNames.insert(std::make_pair(15301, "ERROR_HASH_NOT_PRESENT")); -} - -const char* ErrorCodeToName(unsigned int ErrorCode) -{ - if(ErrorNames.find(ErrorCode) == ErrorNames.end()) - return nullptr; - - return ErrorNames[ErrorCode]; +#include +#include "error.h" + +std::unordered_map ErrorNames; + +void ErrorCodeInit() +{ + ErrorNames.clear(); + ErrorNames.insert(std::make_pair(0, "ERROR_SUCCESS")); + ErrorNames.insert(std::make_pair(1, "ERROR_INVALID_FUNCTION")); + ErrorNames.insert(std::make_pair(2, "ERROR_FILE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(3, "ERROR_PATH_NOT_FOUND")); + ErrorNames.insert(std::make_pair(4, "ERROR_TOO_MANY_OPEN_FILES")); + ErrorNames.insert(std::make_pair(5, "ERROR_ACCESS_DENIED")); + ErrorNames.insert(std::make_pair(6, "ERROR_INVALID_HANDLE")); + ErrorNames.insert(std::make_pair(7, "ERROR_ARENA_TRASHED")); + ErrorNames.insert(std::make_pair(8, "ERROR_NOT_ENOUGH_MEMORY")); + ErrorNames.insert(std::make_pair(9, "ERROR_INVALID_BLOCK")); + ErrorNames.insert(std::make_pair(10, "ERROR_BAD_ENVIRONMENT")); + ErrorNames.insert(std::make_pair(11, "ERROR_BAD_FORMAT")); + ErrorNames.insert(std::make_pair(12, "ERROR_INVALID_ACCESS")); + ErrorNames.insert(std::make_pair(13, "ERROR_INVALID_DATA")); + ErrorNames.insert(std::make_pair(14, "ERROR_OUTOFMEMORY")); + ErrorNames.insert(std::make_pair(15, "ERROR_INVALID_DRIVE")); + ErrorNames.insert(std::make_pair(16, "ERROR_CURRENT_DIRECTORY")); + ErrorNames.insert(std::make_pair(17, "ERROR_NOT_SAME_DEVICE")); + ErrorNames.insert(std::make_pair(18, "ERROR_NO_MORE_FILES")); + ErrorNames.insert(std::make_pair(19, "ERROR_WRITE_PROTECT")); + ErrorNames.insert(std::make_pair(20, "ERROR_BAD_UNIT")); + ErrorNames.insert(std::make_pair(21, "ERROR_NOT_READY")); + ErrorNames.insert(std::make_pair(22, "ERROR_BAD_COMMAND")); + ErrorNames.insert(std::make_pair(23, "ERROR_CRC")); + ErrorNames.insert(std::make_pair(24, "ERROR_BAD_LENGTH")); + ErrorNames.insert(std::make_pair(25, "ERROR_SEEK")); + ErrorNames.insert(std::make_pair(26, "ERROR_NOT_DOS_DISK")); + ErrorNames.insert(std::make_pair(27, "ERROR_SECTOR_NOT_FOUND")); + ErrorNames.insert(std::make_pair(28, "ERROR_OUT_OF_PAPER")); + ErrorNames.insert(std::make_pair(29, "ERROR_WRITE_FAULT")); + ErrorNames.insert(std::make_pair(30, "ERROR_READ_FAULT")); + ErrorNames.insert(std::make_pair(31, "ERROR_GEN_FAILURE")); + ErrorNames.insert(std::make_pair(32, "ERROR_SHARING_VIOLATION")); + ErrorNames.insert(std::make_pair(33, "ERROR_LOCK_VIOLATION")); + ErrorNames.insert(std::make_pair(34, "ERROR_WRONG_DISK")); + ErrorNames.insert(std::make_pair(36, "ERROR_SHARING_BUFFER_EXCEEDED")); + ErrorNames.insert(std::make_pair(38, "ERROR_HANDLE_EOF")); + ErrorNames.insert(std::make_pair(39, "ERROR_HANDLE_DISK_FULL")); + ErrorNames.insert(std::make_pair(50, "ERROR_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(51, "ERROR_REM_NOT_LIST")); + ErrorNames.insert(std::make_pair(52, "ERROR_DUP_NAME")); + ErrorNames.insert(std::make_pair(53, "ERROR_BAD_NETPATH")); + ErrorNames.insert(std::make_pair(54, "ERROR_NETWORK_BUSY")); + ErrorNames.insert(std::make_pair(55, "ERROR_DEV_NOT_EXIST")); + ErrorNames.insert(std::make_pair(56, "ERROR_TOO_MANY_CMDS")); + ErrorNames.insert(std::make_pair(57, "ERROR_ADAP_HDW_ERR")); + ErrorNames.insert(std::make_pair(58, "ERROR_BAD_NET_RESP")); + ErrorNames.insert(std::make_pair(59, "ERROR_UNEXP_NET_ERR")); + ErrorNames.insert(std::make_pair(60, "ERROR_BAD_REM_ADAP")); + ErrorNames.insert(std::make_pair(61, "ERROR_PRINTQ_FULL")); + ErrorNames.insert(std::make_pair(62, "ERROR_NO_SPOOL_SPACE")); + ErrorNames.insert(std::make_pair(63, "ERROR_PRINT_CANCELLED")); + ErrorNames.insert(std::make_pair(64, "ERROR_NETNAME_DELETED")); + ErrorNames.insert(std::make_pair(65, "ERROR_NETWORK_ACCESS_DENIED")); + ErrorNames.insert(std::make_pair(66, "ERROR_BAD_DEV_TYPE")); + ErrorNames.insert(std::make_pair(67, "ERROR_BAD_NET_NAME")); + ErrorNames.insert(std::make_pair(68, "ERROR_TOO_MANY_NAMES")); + ErrorNames.insert(std::make_pair(69, "ERROR_TOO_MANY_SESS")); + ErrorNames.insert(std::make_pair(70, "ERROR_SHARING_PAUSED")); + ErrorNames.insert(std::make_pair(71, "ERROR_REQ_NOT_ACCEP")); + ErrorNames.insert(std::make_pair(72, "ERROR_REDIR_PAUSED")); + ErrorNames.insert(std::make_pair(80, "ERROR_FILE_EXISTS")); + ErrorNames.insert(std::make_pair(82, "ERROR_CANNOT_MAKE")); + ErrorNames.insert(std::make_pair(83, "ERROR_FAIL_I24")); + ErrorNames.insert(std::make_pair(84, "ERROR_OUT_OF_STRUCTURES")); + ErrorNames.insert(std::make_pair(85, "ERROR_ALREADY_ASSIGNED")); + ErrorNames.insert(std::make_pair(86, "ERROR_INVALID_PASSWORD")); + ErrorNames.insert(std::make_pair(87, "ERROR_INVALID_PARAMETER")); + ErrorNames.insert(std::make_pair(88, "ERROR_NET_WRITE_FAULT")); + ErrorNames.insert(std::make_pair(89, "ERROR_NO_PROC_SLOTS")); + ErrorNames.insert(std::make_pair(100, "ERROR_TOO_MANY_SEMAPHORES")); + ErrorNames.insert(std::make_pair(101, "ERROR_EXCL_SEM_ALREADY_OWNED")); + ErrorNames.insert(std::make_pair(102, "ERROR_SEM_IS_SET")); + ErrorNames.insert(std::make_pair(103, "ERROR_TOO_MANY_SEM_REQUESTS")); + ErrorNames.insert(std::make_pair(104, "ERROR_INVALID_AT_INTERRUPT_TIME")); + ErrorNames.insert(std::make_pair(105, "ERROR_SEM_OWNER_DIED")); + ErrorNames.insert(std::make_pair(106, "ERROR_SEM_USER_LIMIT")); + ErrorNames.insert(std::make_pair(107, "ERROR_DISK_CHANGE")); + ErrorNames.insert(std::make_pair(108, "ERROR_DRIVE_LOCKED")); + ErrorNames.insert(std::make_pair(109, "ERROR_BROKEN_PIPE")); + ErrorNames.insert(std::make_pair(110, "ERROR_OPEN_FAILED")); + ErrorNames.insert(std::make_pair(111, "ERROR_BUFFER_OVERFLOW")); + ErrorNames.insert(std::make_pair(112, "ERROR_DISK_FULL")); + ErrorNames.insert(std::make_pair(113, "ERROR_NO_MORE_SEARCH_HANDLES")); + ErrorNames.insert(std::make_pair(114, "ERROR_INVALID_TARGET_HANDLE")); + ErrorNames.insert(std::make_pair(117, "ERROR_INVALID_CATEGORY")); + ErrorNames.insert(std::make_pair(118, "ERROR_INVALID_VERIFY_SWITCH")); + ErrorNames.insert(std::make_pair(119, "ERROR_BAD_DRIVER_LEVEL")); + ErrorNames.insert(std::make_pair(120, "ERROR_CALL_NOT_IMPLEMENTED")); + ErrorNames.insert(std::make_pair(121, "ERROR_SEM_TIMEOUT")); + ErrorNames.insert(std::make_pair(122, "ERROR_INSUFFICIENT_BUFFER")); + ErrorNames.insert(std::make_pair(123, "ERROR_INVALID_NAME")); + ErrorNames.insert(std::make_pair(124, "ERROR_INVALID_LEVEL")); + ErrorNames.insert(std::make_pair(125, "ERROR_NO_VOLUME_LABEL")); + ErrorNames.insert(std::make_pair(126, "ERROR_MOD_NOT_FOUND")); + ErrorNames.insert(std::make_pair(127, "ERROR_PROC_NOT_FOUND")); + ErrorNames.insert(std::make_pair(128, "ERROR_WAIT_NO_CHILDREN")); + ErrorNames.insert(std::make_pair(129, "ERROR_CHILD_NOT_COMPLETE")); + ErrorNames.insert(std::make_pair(130, "ERROR_DIRECT_ACCESS_HANDLE")); + ErrorNames.insert(std::make_pair(131, "ERROR_NEGATIVE_SEEK")); + ErrorNames.insert(std::make_pair(132, "ERROR_SEEK_ON_DEVICE")); + ErrorNames.insert(std::make_pair(133, "ERROR_IS_JOIN_TARGET")); + ErrorNames.insert(std::make_pair(134, "ERROR_IS_JOINED")); + ErrorNames.insert(std::make_pair(135, "ERROR_IS_SUBSTED")); + ErrorNames.insert(std::make_pair(136, "ERROR_NOT_JOINED")); + ErrorNames.insert(std::make_pair(137, "ERROR_NOT_SUBSTED")); + ErrorNames.insert(std::make_pair(138, "ERROR_JOIN_TO_JOIN")); + ErrorNames.insert(std::make_pair(139, "ERROR_SUBST_TO_SUBST")); + ErrorNames.insert(std::make_pair(140, "ERROR_JOIN_TO_SUBST")); + ErrorNames.insert(std::make_pair(141, "ERROR_SUBST_TO_JOIN")); + ErrorNames.insert(std::make_pair(142, "ERROR_BUSY_DRIVE")); + ErrorNames.insert(std::make_pair(143, "ERROR_SAME_DRIVE")); + ErrorNames.insert(std::make_pair(144, "ERROR_DIR_NOT_ROOT")); + ErrorNames.insert(std::make_pair(145, "ERROR_DIR_NOT_EMPTY")); + ErrorNames.insert(std::make_pair(146, "ERROR_IS_SUBST_PATH")); + ErrorNames.insert(std::make_pair(147, "ERROR_IS_JOIN_PATH")); + ErrorNames.insert(std::make_pair(148, "ERROR_PATH_BUSY")); + ErrorNames.insert(std::make_pair(149, "ERROR_IS_SUBST_TARGET")); + ErrorNames.insert(std::make_pair(150, "ERROR_SYSTEM_TRACE")); + ErrorNames.insert(std::make_pair(151, "ERROR_INVALID_EVENT_COUNT")); + ErrorNames.insert(std::make_pair(152, "ERROR_TOO_MANY_MUXWAITERS")); + ErrorNames.insert(std::make_pair(153, "ERROR_INVALID_LIST_FORMAT")); + ErrorNames.insert(std::make_pair(154, "ERROR_LABEL_TOO_LONG")); + ErrorNames.insert(std::make_pair(155, "ERROR_TOO_MANY_TCBS")); + ErrorNames.insert(std::make_pair(156, "ERROR_SIGNAL_REFUSED")); + ErrorNames.insert(std::make_pair(157, "ERROR_DISCARDED")); + ErrorNames.insert(std::make_pair(158, "ERROR_NOT_LOCKED")); + ErrorNames.insert(std::make_pair(159, "ERROR_BAD_THREADID_ADDR")); + ErrorNames.insert(std::make_pair(160, "ERROR_BAD_ARGUMENTS")); + ErrorNames.insert(std::make_pair(161, "ERROR_BAD_PATHNAME")); + ErrorNames.insert(std::make_pair(162, "ERROR_SIGNAL_PENDING")); + ErrorNames.insert(std::make_pair(164, "ERROR_MAX_THRDS_REACHED")); + ErrorNames.insert(std::make_pair(167, "ERROR_LOCK_FAILED")); + ErrorNames.insert(std::make_pair(170, "ERROR_BUSY")); + ErrorNames.insert(std::make_pair(173, "ERROR_CANCEL_VIOLATION")); + ErrorNames.insert(std::make_pair(174, "ERROR_ATOMIC_LOCKS_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(180, "ERROR_INVALID_SEGMENT_NUMBER")); + ErrorNames.insert(std::make_pair(182, "ERROR_INVALID_ORDINAL")); + ErrorNames.insert(std::make_pair(183, "ERROR_ALREADY_EXISTS")); + ErrorNames.insert(std::make_pair(186, "ERROR_INVALID_FLAG_NUMBER")); + ErrorNames.insert(std::make_pair(187, "ERROR_SEM_NOT_FOUND")); + ErrorNames.insert(std::make_pair(188, "ERROR_INVALID_STARTING_CODESEG")); + ErrorNames.insert(std::make_pair(189, "ERROR_INVALID_STACKSEG")); + ErrorNames.insert(std::make_pair(190, "ERROR_INVALID_MODULETYPE")); + ErrorNames.insert(std::make_pair(191, "ERROR_INVALID_EXE_SIGNATURE")); + ErrorNames.insert(std::make_pair(192, "ERROR_EXE_MARKED_INVALID")); + ErrorNames.insert(std::make_pair(193, "ERROR_BAD_EXE_FORMAT")); + ErrorNames.insert(std::make_pair(194, "ERROR_ITERATED_DATA_EXCEEDS_64k")); + ErrorNames.insert(std::make_pair(195, "ERROR_INVALID_MINALLOCSIZE")); + ErrorNames.insert(std::make_pair(196, "ERROR_DYNLINK_FROM_INVALID_RING")); + ErrorNames.insert(std::make_pair(197, "ERROR_IOPL_NOT_ENABLED")); + ErrorNames.insert(std::make_pair(198, "ERROR_INVALID_SEGDPL")); + ErrorNames.insert(std::make_pair(199, "ERROR_AUTODATASEG_EXCEEDS_64k")); + ErrorNames.insert(std::make_pair(200, "ERROR_RING2SEG_MUST_BE_MOVABLE")); + ErrorNames.insert(std::make_pair(201, "ERROR_RELOC_CHAIN_XEEDS_SEGLIM")); + ErrorNames.insert(std::make_pair(202, "ERROR_INFLOOP_IN_RELOC_CHAIN")); + ErrorNames.insert(std::make_pair(203, "ERROR_ENVVAR_NOT_FOUND")); + ErrorNames.insert(std::make_pair(205, "ERROR_NO_SIGNAL_SENT")); + ErrorNames.insert(std::make_pair(206, "ERROR_FILENAME_EXCED_RANGE")); + ErrorNames.insert(std::make_pair(207, "ERROR_RING2_STACK_IN_USE")); + ErrorNames.insert(std::make_pair(208, "ERROR_META_EXPANSION_TOO_LONG")); + ErrorNames.insert(std::make_pair(209, "ERROR_INVALID_SIGNAL_NUMBER")); + ErrorNames.insert(std::make_pair(210, "ERROR_THREAD_1_INACTIVE")); + ErrorNames.insert(std::make_pair(212, "ERROR_LOCKED")); + ErrorNames.insert(std::make_pair(214, "ERROR_TOO_MANY_MODULES")); + ErrorNames.insert(std::make_pair(215, "ERROR_NESTING_NOT_ALLOWED")); + ErrorNames.insert(std::make_pair(216, "ERROR_EXE_MACHINE_TYPE_MISMATCH")); + ErrorNames.insert(std::make_pair(217, "ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY")); + ErrorNames.insert(std::make_pair(218, "ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY")); + ErrorNames.insert(std::make_pair(220, "ERROR_FILE_CHECKED_OUT")); + ErrorNames.insert(std::make_pair(221, "ERROR_CHECKOUT_REQUIRED")); + ErrorNames.insert(std::make_pair(222, "ERROR_BAD_FILE_TYPE")); + ErrorNames.insert(std::make_pair(223, "ERROR_FILE_TOO_LARGE")); + ErrorNames.insert(std::make_pair(224, "ERROR_FORMS_AUTH_REQUIRED")); + ErrorNames.insert(std::make_pair(225, "ERROR_VIRUS_INFECTED")); + ErrorNames.insert(std::make_pair(226, "ERROR_VIRUS_DELETED")); + ErrorNames.insert(std::make_pair(229, "ERROR_PIPE_LOCAL")); + ErrorNames.insert(std::make_pair(230, "ERROR_BAD_PIPE")); + ErrorNames.insert(std::make_pair(231, "ERROR_PIPE_BUSY")); + ErrorNames.insert(std::make_pair(232, "ERROR_NO_DATA")); + ErrorNames.insert(std::make_pair(233, "ERROR_PIPE_NOT_CONNECTED")); + ErrorNames.insert(std::make_pair(234, "ERROR_MORE_DATA")); + ErrorNames.insert(std::make_pair(240, "ERROR_VC_DISCONNECTED")); + ErrorNames.insert(std::make_pair(254, "ERROR_INVALID_EA_NAME")); + ErrorNames.insert(std::make_pair(255, "ERROR_EA_LIST_INCONSISTENT")); + ErrorNames.insert(std::make_pair(259, "ERROR_NO_MORE_ITEMS")); + ErrorNames.insert(std::make_pair(266, "ERROR_CANNOT_COPY")); + ErrorNames.insert(std::make_pair(267, "ERROR_DIRECTORY")); + ErrorNames.insert(std::make_pair(275, "ERROR_EAS_DIDNT_FIT")); + ErrorNames.insert(std::make_pair(276, "ERROR_EA_FILE_CORRUPT")); + ErrorNames.insert(std::make_pair(277, "ERROR_EA_TABLE_FULL")); + ErrorNames.insert(std::make_pair(278, "ERROR_INVALID_EA_HANDLE")); + ErrorNames.insert(std::make_pair(282, "ERROR_EAS_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(288, "ERROR_NOT_OWNER")); + ErrorNames.insert(std::make_pair(298, "ERROR_TOO_MANY_POSTS")); + ErrorNames.insert(std::make_pair(299, "ERROR_PARTIAL_COPY")); + ErrorNames.insert(std::make_pair(300, "ERROR_OPLOCK_NOT_GRANTED")); + ErrorNames.insert(std::make_pair(301, "ERROR_INVALID_OPLOCK_PROTOCOL")); + ErrorNames.insert(std::make_pair(302, "ERROR_DISK_TOO_FRAGMENTED")); + ErrorNames.insert(std::make_pair(303, "ERROR_DELETE_PENDING")); + ErrorNames.insert(std::make_pair(304, "ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING")); + ErrorNames.insert(std::make_pair(305, "ERROR_SHORT_NAMES_NOT_ENABLED_ON_VOLUME")); + ErrorNames.insert(std::make_pair(306, "ERROR_SECURITY_STREAM_IS_INCONSISTENT")); + ErrorNames.insert(std::make_pair(307, "ERROR_INVALID_LOCK_RANGE")); + ErrorNames.insert(std::make_pair(308, "ERROR_IMAGE_SUBSYSTEM_NOT_PRESENT")); + ErrorNames.insert(std::make_pair(309, "ERROR_NOTIFICATION_GUID_ALREADY_DEFINED")); + ErrorNames.insert(std::make_pair(317, "ERROR_MR_MID_NOT_FOUND")); + ErrorNames.insert(std::make_pair(318, "ERROR_SCOPE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(350, "ERROR_FAIL_NOACTION_REBOOT")); + ErrorNames.insert(std::make_pair(351, "ERROR_FAIL_SHUTDOWN")); + ErrorNames.insert(std::make_pair(352, "ERROR_FAIL_RESTART")); + ErrorNames.insert(std::make_pair(353, "ERROR_MAX_SESSIONS_REACHED")); + ErrorNames.insert(std::make_pair(400, "ERROR_THREAD_MODE_ALREADY_BACKGROUND")); + ErrorNames.insert(std::make_pair(401, "ERROR_THREAD_MODE_NOT_BACKGROUND")); + ErrorNames.insert(std::make_pair(402, "ERROR_PROCESS_MODE_ALREADY_BACKGROUND")); + ErrorNames.insert(std::make_pair(403, "ERROR_PROCESS_MODE_NOT_BACKGROUND")); + ErrorNames.insert(std::make_pair(487, "ERROR_INVALID_ADDRESS")); + ErrorNames.insert(std::make_pair(500, "ERROR_USER_PROFILE_LOAD")); + ErrorNames.insert(std::make_pair(534, "ERROR_ARITHMETIC_OVERFLOW")); + ErrorNames.insert(std::make_pair(535, "ERROR_PIPE_CONNECTED")); + ErrorNames.insert(std::make_pair(536, "ERROR_PIPE_LISTENING")); + ErrorNames.insert(std::make_pair(537, "ERROR_VERIFIER_STOP")); + ErrorNames.insert(std::make_pair(538, "ERROR_ABIOS_ERROR")); + ErrorNames.insert(std::make_pair(539, "ERROR_WX86_WARNING")); + ErrorNames.insert(std::make_pair(540, "ERROR_WX86_ERROR")); + ErrorNames.insert(std::make_pair(541, "ERROR_TIMER_NOT_CANCELED")); + ErrorNames.insert(std::make_pair(542, "ERROR_UNWIND")); + ErrorNames.insert(std::make_pair(543, "ERROR_BAD_STACK")); + ErrorNames.insert(std::make_pair(544, "ERROR_INVALID_UNWIND_TARGET")); + ErrorNames.insert(std::make_pair(545, "ERROR_INVALID_PORT_ATTRIBUTES")); + ErrorNames.insert(std::make_pair(546, "ERROR_PORT_MESSAGE_TOO_LONG")); + ErrorNames.insert(std::make_pair(547, "ERROR_INVALID_QUOTA_LOWER")); + ErrorNames.insert(std::make_pair(548, "ERROR_DEVICE_ALREADY_ATTACHED")); + ErrorNames.insert(std::make_pair(549, "ERROR_INSTRUCTION_MISALIGNMENT")); + ErrorNames.insert(std::make_pair(550, "ERROR_PROFILING_NOT_STARTED")); + ErrorNames.insert(std::make_pair(551, "ERROR_PROFILING_NOT_STOPPED")); + ErrorNames.insert(std::make_pair(552, "ERROR_COULD_NOT_INTERPRET")); + ErrorNames.insert(std::make_pair(553, "ERROR_PROFILING_AT_LIMIT")); + ErrorNames.insert(std::make_pair(554, "ERROR_CANT_WAIT")); + ErrorNames.insert(std::make_pair(555, "ERROR_CANT_TERMINATE_SELF")); + ErrorNames.insert(std::make_pair(556, "ERROR_UNEXPECTED_MM_CREATE_ERR")); + ErrorNames.insert(std::make_pair(557, "ERROR_UNEXPECTED_MM_MAP_ERROR")); + ErrorNames.insert(std::make_pair(558, "ERROR_UNEXPECTED_MM_EXTEND_ERR")); + ErrorNames.insert(std::make_pair(559, "ERROR_BAD_FUNCTION_TABLE")); + ErrorNames.insert(std::make_pair(560, "ERROR_NO_GUID_TRANSLATION")); + ErrorNames.insert(std::make_pair(561, "ERROR_INVALID_LDT_SIZE")); + ErrorNames.insert(std::make_pair(563, "ERROR_INVALID_LDT_OFFSET")); + ErrorNames.insert(std::make_pair(564, "ERROR_INVALID_LDT_DESCRIPTOR")); + ErrorNames.insert(std::make_pair(565, "ERROR_TOO_MANY_THREADS")); + ErrorNames.insert(std::make_pair(566, "ERROR_THREAD_NOT_IN_PROCESS")); + ErrorNames.insert(std::make_pair(567, "ERROR_PAGEFILE_QUOTA_EXCEEDED")); + ErrorNames.insert(std::make_pair(568, "ERROR_LOGON_SERVER_CONFLICT")); + ErrorNames.insert(std::make_pair(569, "ERROR_SYNCHRONIZATION_REQUIRED")); + ErrorNames.insert(std::make_pair(570, "ERROR_NET_OPEN_FAILED")); + ErrorNames.insert(std::make_pair(571, "ERROR_IO_PRIVILEGE_FAILED")); + ErrorNames.insert(std::make_pair(572, "ERROR_CONTROL_C_EXIT")); + ErrorNames.insert(std::make_pair(573, "ERROR_MISSING_SYSTEMFILE")); + ErrorNames.insert(std::make_pair(574, "ERROR_UNHANDLED_EXCEPTION")); + ErrorNames.insert(std::make_pair(575, "ERROR_APP_INIT_FAILURE")); + ErrorNames.insert(std::make_pair(576, "ERROR_PAGEFILE_CREATE_FAILED")); + ErrorNames.insert(std::make_pair(577, "ERROR_INVALID_IMAGE_HASH")); + ErrorNames.insert(std::make_pair(578, "ERROR_NO_PAGEFILE")); + ErrorNames.insert(std::make_pair(579, "ERROR_ILLEGAL_FLOAT_CONTEXT")); + ErrorNames.insert(std::make_pair(580, "ERROR_NO_EVENT_PAIR")); + ErrorNames.insert(std::make_pair(581, "ERROR_DOMAIN_CTRLR_CONFIG_ERROR")); + ErrorNames.insert(std::make_pair(582, "ERROR_ILLEGAL_CHARACTER")); + ErrorNames.insert(std::make_pair(583, "ERROR_UNDEFINED_CHARACTER")); + ErrorNames.insert(std::make_pair(584, "ERROR_FLOPPY_VOLUME")); + ErrorNames.insert(std::make_pair(585, "ERROR_BIOS_FAILED_TO_CONNECT_INTERRUPT")); + ErrorNames.insert(std::make_pair(586, "ERROR_BACKUP_CONTROLLER")); + ErrorNames.insert(std::make_pair(587, "ERROR_MUTANT_LIMIT_EXCEEDED")); + ErrorNames.insert(std::make_pair(588, "ERROR_FS_DRIVER_REQUIRED")); + ErrorNames.insert(std::make_pair(589, "ERROR_CANNOT_LOAD_REGISTRY_FILE")); + ErrorNames.insert(std::make_pair(590, "ERROR_DEBUG_ATTACH_FAILED")); + ErrorNames.insert(std::make_pair(591, "ERROR_SYSTEM_PROCESS_TERMINATED")); + ErrorNames.insert(std::make_pair(592, "ERROR_DATA_NOT_ACCEPTED")); + ErrorNames.insert(std::make_pair(593, "ERROR_VDM_HARD_ERROR")); + ErrorNames.insert(std::make_pair(594, "ERROR_DRIVER_CANCEL_TIMEOUT")); + ErrorNames.insert(std::make_pair(595, "ERROR_REPLY_MESSAGE_MISMATCH")); + ErrorNames.insert(std::make_pair(596, "ERROR_LOST_WRITEBEHIND_DATA")); + ErrorNames.insert(std::make_pair(597, "ERROR_CLIENT_SERVER_PARAMETERS_INVALID")); + ErrorNames.insert(std::make_pair(598, "ERROR_NOT_TINY_STREAM")); + ErrorNames.insert(std::make_pair(599, "ERROR_STACK_OVERFLOW_READ")); + ErrorNames.insert(std::make_pair(600, "ERROR_CONVERT_TO_LARGE")); + ErrorNames.insert(std::make_pair(601, "ERROR_FOUND_OUT_OF_SCOPE")); + ErrorNames.insert(std::make_pair(602, "ERROR_ALLOCATE_BUCKET")); + ErrorNames.insert(std::make_pair(603, "ERROR_MARSHALL_OVERFLOW")); + ErrorNames.insert(std::make_pair(604, "ERROR_INVALID_VARIANT")); + ErrorNames.insert(std::make_pair(605, "ERROR_BAD_COMPRESSION_BUFFER")); + ErrorNames.insert(std::make_pair(606, "ERROR_AUDIT_FAILED")); + ErrorNames.insert(std::make_pair(607, "ERROR_TIMER_RESOLUTION_NOT_SET")); + ErrorNames.insert(std::make_pair(608, "ERROR_INSUFFICIENT_LOGON_INFO")); + ErrorNames.insert(std::make_pair(609, "ERROR_BAD_DLL_ENTRYPOINT")); + ErrorNames.insert(std::make_pair(610, "ERROR_BAD_SERVICE_ENTRYPOINT")); + ErrorNames.insert(std::make_pair(611, "ERROR_IP_ADDRESS_CONFLICT1")); + ErrorNames.insert(std::make_pair(612, "ERROR_IP_ADDRESS_CONFLICT2")); + ErrorNames.insert(std::make_pair(613, "ERROR_REGISTRY_QUOTA_LIMIT")); + ErrorNames.insert(std::make_pair(614, "ERROR_NO_CALLBACK_ACTIVE")); + ErrorNames.insert(std::make_pair(615, "ERROR_PWD_TOO_SHORT")); + ErrorNames.insert(std::make_pair(616, "ERROR_PWD_TOO_RECENT")); + ErrorNames.insert(std::make_pair(617, "ERROR_PWD_HISTORY_CONFLICT")); + ErrorNames.insert(std::make_pair(618, "ERROR_UNSUPPORTED_COMPRESSION")); + ErrorNames.insert(std::make_pair(619, "ERROR_INVALID_HW_PROFILE")); + ErrorNames.insert(std::make_pair(620, "ERROR_INVALID_PLUGPLAY_DEVICE_PATH")); + ErrorNames.insert(std::make_pair(621, "ERROR_QUOTA_LIST_INCONSISTENT")); + ErrorNames.insert(std::make_pair(622, "ERROR_EVALUATION_EXPIRATION")); + ErrorNames.insert(std::make_pair(623, "ERROR_ILLEGAL_DLL_RELOCATION")); + ErrorNames.insert(std::make_pair(624, "ERROR_DLL_INIT_FAILED_LOGOFF")); + ErrorNames.insert(std::make_pair(625, "ERROR_VALIDATE_CONTINUE")); + ErrorNames.insert(std::make_pair(626, "ERROR_NO_MORE_MATCHES")); + ErrorNames.insert(std::make_pair(627, "ERROR_RANGE_LIST_CONFLICT")); + ErrorNames.insert(std::make_pair(628, "ERROR_SERVER_SID_MISMATCH")); + ErrorNames.insert(std::make_pair(629, "ERROR_CANT_ENABLE_DENY_ONLY")); + ErrorNames.insert(std::make_pair(630, "ERROR_FLOAT_MULTIPLE_FAULTS")); + ErrorNames.insert(std::make_pair(631, "ERROR_FLOAT_MULTIPLE_TRAPS")); + ErrorNames.insert(std::make_pair(632, "ERROR_NOINTERFACE")); + ErrorNames.insert(std::make_pair(633, "ERROR_DRIVER_FAILED_SLEEP")); + ErrorNames.insert(std::make_pair(634, "ERROR_CORRUPT_SYSTEM_FILE")); + ErrorNames.insert(std::make_pair(635, "ERROR_COMMITMENT_MINIMUM")); + ErrorNames.insert(std::make_pair(636, "ERROR_PNP_RESTART_ENUMERATION")); + ErrorNames.insert(std::make_pair(637, "ERROR_SYSTEM_IMAGE_BAD_SIGNATURE")); + ErrorNames.insert(std::make_pair(638, "ERROR_PNP_REBOOT_REQUIRED")); + ErrorNames.insert(std::make_pair(639, "ERROR_INSUFFICIENT_POWER")); + ErrorNames.insert(std::make_pair(640, "ERROR_MULTIPLE_FAULT_VIOLATION")); + ErrorNames.insert(std::make_pair(641, "ERROR_SYSTEM_SHUTDOWN")); + ErrorNames.insert(std::make_pair(642, "ERROR_PORT_NOT_SET")); + ErrorNames.insert(std::make_pair(643, "ERROR_DS_VERSION_CHECK_FAILURE")); + ErrorNames.insert(std::make_pair(644, "ERROR_RANGE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(646, "ERROR_NOT_SAFE_MODE_DRIVER")); + ErrorNames.insert(std::make_pair(647, "ERROR_FAILED_DRIVER_ENTRY")); + ErrorNames.insert(std::make_pair(648, "ERROR_DEVICE_ENUMERATION_ERROR")); + ErrorNames.insert(std::make_pair(649, "ERROR_MOUNT_POINT_NOT_RESOLVED")); + ErrorNames.insert(std::make_pair(650, "ERROR_INVALID_DEVICE_OBJECT_PARAMETER")); + ErrorNames.insert(std::make_pair(651, "ERROR_MCA_OCCURED")); + ErrorNames.insert(std::make_pair(652, "ERROR_DRIVER_DATABASE_ERROR")); + ErrorNames.insert(std::make_pair(653, "ERROR_SYSTEM_HIVE_TOO_LARGE")); + ErrorNames.insert(std::make_pair(654, "ERROR_DRIVER_FAILED_PRIOR_UNLOAD")); + ErrorNames.insert(std::make_pair(655, "ERROR_VOLSNAP_PREPARE_HIBERNATE")); + ErrorNames.insert(std::make_pair(656, "ERROR_HIBERNATION_FAILURE")); + ErrorNames.insert(std::make_pair(665, "ERROR_FILE_SYSTEM_LIMITATION")); + ErrorNames.insert(std::make_pair(668, "ERROR_ASSERTION_FAILURE")); + ErrorNames.insert(std::make_pair(669, "ERROR_ACPI_ERROR")); + ErrorNames.insert(std::make_pair(670, "ERROR_WOW_ASSERTION")); + ErrorNames.insert(std::make_pair(671, "ERROR_PNP_BAD_MPS_TABLE")); + ErrorNames.insert(std::make_pair(672, "ERROR_PNP_TRANSLATION_FAILED")); + ErrorNames.insert(std::make_pair(673, "ERROR_PNP_IRQ_TRANSLATION_FAILED")); + ErrorNames.insert(std::make_pair(674, "ERROR_PNP_INVALID_ID")); + ErrorNames.insert(std::make_pair(675, "ERROR_WAKE_SYSTEM_DEBUGGER")); + ErrorNames.insert(std::make_pair(676, "ERROR_HANDLES_CLOSED")); + ErrorNames.insert(std::make_pair(677, "ERROR_EXTRANEOUS_INFORMATION")); + ErrorNames.insert(std::make_pair(678, "ERROR_RXACT_COMMIT_NECESSARY")); + ErrorNames.insert(std::make_pair(679, "ERROR_MEDIA_CHECK")); + ErrorNames.insert(std::make_pair(680, "ERROR_GUID_SUBSTITUTION_MADE")); + ErrorNames.insert(std::make_pair(681, "ERROR_STOPPED_ON_SYMLINK")); + ErrorNames.insert(std::make_pair(682, "ERROR_LONGJUMP")); + ErrorNames.insert(std::make_pair(683, "ERROR_PLUGPLAY_QUERY_VETOED")); + ErrorNames.insert(std::make_pair(684, "ERROR_UNWIND_CONSOLIDATE")); + ErrorNames.insert(std::make_pair(685, "ERROR_REGISTRY_HIVE_RECOVERED")); + ErrorNames.insert(std::make_pair(686, "ERROR_DLL_MIGHT_BE_INSECURE")); + ErrorNames.insert(std::make_pair(687, "ERROR_DLL_MIGHT_BE_INCOMPATIBLE")); + ErrorNames.insert(std::make_pair(688, "ERROR_DBG_EXCEPTION_NOT_HANDLED")); + ErrorNames.insert(std::make_pair(689, "ERROR_DBG_REPLY_LATER")); + ErrorNames.insert(std::make_pair(690, "ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE")); + ErrorNames.insert(std::make_pair(691, "ERROR_DBG_TERMINATE_THREAD")); + ErrorNames.insert(std::make_pair(692, "ERROR_DBG_TERMINATE_PROCESS")); + ErrorNames.insert(std::make_pair(693, "ERROR_DBG_CONTROL_C")); + ErrorNames.insert(std::make_pair(694, "ERROR_DBG_PRINTEXCEPTION_C")); + ErrorNames.insert(std::make_pair(695, "ERROR_DBG_RIPEXCEPTION")); + ErrorNames.insert(std::make_pair(696, "ERROR_DBG_CONTROL_BREAK")); + ErrorNames.insert(std::make_pair(697, "ERROR_DBG_COMMAND_EXCEPTION")); + ErrorNames.insert(std::make_pair(698, "ERROR_OBJECT_NAME_EXISTS")); + ErrorNames.insert(std::make_pair(699, "ERROR_THREAD_WAS_SUSPENDED")); + ErrorNames.insert(std::make_pair(700, "ERROR_IMAGE_NOT_AT_BASE")); + ErrorNames.insert(std::make_pair(701, "ERROR_RXACT_STATE_CREATED")); + ErrorNames.insert(std::make_pair(702, "ERROR_SEGMENT_NOTIFICATION")); + ErrorNames.insert(std::make_pair(703, "ERROR_BAD_CURRENT_DIRECTORY")); + ErrorNames.insert(std::make_pair(704, "ERROR_FT_READ_RECOVERY_FROM_BACKUP")); + ErrorNames.insert(std::make_pair(705, "ERROR_FT_WRITE_RECOVERY")); + ErrorNames.insert(std::make_pair(706, "ERROR_IMAGE_MACHINE_TYPE_MISMATCH")); + ErrorNames.insert(std::make_pair(707, "ERROR_RECEIVE_PARTIAL")); + ErrorNames.insert(std::make_pair(708, "ERROR_RECEIVE_EXPEDITED")); + ErrorNames.insert(std::make_pair(709, "ERROR_RECEIVE_PARTIAL_EXPEDITED")); + ErrorNames.insert(std::make_pair(710, "ERROR_EVENT_DONE")); + ErrorNames.insert(std::make_pair(711, "ERROR_EVENT_PENDING")); + ErrorNames.insert(std::make_pair(712, "ERROR_CHECKING_FILE_SYSTEM")); + ErrorNames.insert(std::make_pair(713, "ERROR_FATAL_APP_EXIT")); + ErrorNames.insert(std::make_pair(714, "ERROR_PREDEFINED_HANDLE")); + ErrorNames.insert(std::make_pair(715, "ERROR_WAS_UNLOCKED")); + ErrorNames.insert(std::make_pair(716, "ERROR_SERVICE_NOTIFICATION")); + ErrorNames.insert(std::make_pair(717, "ERROR_WAS_LOCKED")); + ErrorNames.insert(std::make_pair(718, "ERROR_LOG_HARD_ERROR")); + ErrorNames.insert(std::make_pair(719, "ERROR_ALREADY_WIN32")); + ErrorNames.insert(std::make_pair(720, "ERROR_IMAGE_MACHINE_TYPE_MISMATCH_EXE")); + ErrorNames.insert(std::make_pair(721, "ERROR_NO_YIELD_PERFORMED")); + ErrorNames.insert(std::make_pair(722, "ERROR_TIMER_RESUME_IGNORED")); + ErrorNames.insert(std::make_pair(723, "ERROR_ARBITRATION_UNHANDLED")); + ErrorNames.insert(std::make_pair(724, "ERROR_CARDBUS_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(725, "ERROR_MP_PROCESSOR_MISMATCH")); + ErrorNames.insert(std::make_pair(726, "ERROR_HIBERNATED")); + ErrorNames.insert(std::make_pair(727, "ERROR_RESUME_HIBERNATION")); + ErrorNames.insert(std::make_pair(728, "ERROR_FIRMWARE_UPDATED")); + ErrorNames.insert(std::make_pair(729, "ERROR_DRIVERS_LEAKING_LOCKED_PAGES")); + ErrorNames.insert(std::make_pair(730, "ERROR_WAKE_SYSTEM")); + ErrorNames.insert(std::make_pair(731, "ERROR_WAIT_1")); + ErrorNames.insert(std::make_pair(732, "ERROR_WAIT_2")); + ErrorNames.insert(std::make_pair(733, "ERROR_WAIT_3")); + ErrorNames.insert(std::make_pair(734, "ERROR_WAIT_63")); + ErrorNames.insert(std::make_pair(735, "ERROR_ABANDONED_WAIT_0")); + ErrorNames.insert(std::make_pair(736, "ERROR_ABANDONED_WAIT_63")); + ErrorNames.insert(std::make_pair(737, "ERROR_USER_APC")); + ErrorNames.insert(std::make_pair(738, "ERROR_KERNEL_APC")); + ErrorNames.insert(std::make_pair(739, "ERROR_ALERTED")); + ErrorNames.insert(std::make_pair(740, "ERROR_ELEVATION_REQUIRED")); + ErrorNames.insert(std::make_pair(741, "ERROR_REPARSE")); + ErrorNames.insert(std::make_pair(742, "ERROR_OPLOCK_BREAK_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(743, "ERROR_VOLUME_MOUNTED")); + ErrorNames.insert(std::make_pair(744, "ERROR_RXACT_COMMITTED")); + ErrorNames.insert(std::make_pair(745, "ERROR_NOTIFY_CLEANUP")); + ErrorNames.insert(std::make_pair(746, "ERROR_PRIMARY_TRANSPORT_CONNECT_FAILED")); + ErrorNames.insert(std::make_pair(747, "ERROR_PAGE_FAULT_TRANSITION")); + ErrorNames.insert(std::make_pair(748, "ERROR_PAGE_FAULT_DEMAND_ZERO")); + ErrorNames.insert(std::make_pair(749, "ERROR_PAGE_FAULT_COPY_ON_WRITE")); + ErrorNames.insert(std::make_pair(750, "ERROR_PAGE_FAULT_GUARD_PAGE")); + ErrorNames.insert(std::make_pair(751, "ERROR_PAGE_FAULT_PAGING_FILE")); + ErrorNames.insert(std::make_pair(752, "ERROR_CACHE_PAGE_LOCKED")); + ErrorNames.insert(std::make_pair(753, "ERROR_CRASH_DUMP")); + ErrorNames.insert(std::make_pair(754, "ERROR_BUFFER_ALL_ZEROS")); + ErrorNames.insert(std::make_pair(755, "ERROR_REPARSE_OBJECT")); + ErrorNames.insert(std::make_pair(756, "ERROR_RESOURCE_REQUIREMENTS_CHANGED")); + ErrorNames.insert(std::make_pair(757, "ERROR_TRANSLATION_COMPLETE")); + ErrorNames.insert(std::make_pair(758, "ERROR_NOTHING_TO_TERMINATE")); + ErrorNames.insert(std::make_pair(759, "ERROR_PROCESS_NOT_IN_JOB")); + ErrorNames.insert(std::make_pair(760, "ERROR_PROCESS_IN_JOB")); + ErrorNames.insert(std::make_pair(761, "ERROR_VOLSNAP_HIBERNATE_READY")); + ErrorNames.insert(std::make_pair(762, "ERROR_FSFILTER_OP_COMPLETED_SUCCESSFULLY")); + ErrorNames.insert(std::make_pair(763, "ERROR_INTERRUPT_VECTOR_ALREADY_CONNECTED")); + ErrorNames.insert(std::make_pair(764, "ERROR_INTERRUPT_STILL_CONNECTED")); + ErrorNames.insert(std::make_pair(765, "ERROR_WAIT_FOR_OPLOCK")); + ErrorNames.insert(std::make_pair(766, "ERROR_DBG_EXCEPTION_HANDLED")); + ErrorNames.insert(std::make_pair(767, "ERROR_DBG_CONTINUE")); + ErrorNames.insert(std::make_pair(768, "ERROR_CALLBACK_POP_STACK")); + ErrorNames.insert(std::make_pair(769, "ERROR_COMPRESSION_DISABLED")); + ErrorNames.insert(std::make_pair(770, "ERROR_CANTFETCHBACKWARDS")); + ErrorNames.insert(std::make_pair(771, "ERROR_CANTSCROLLBACKWARDS")); + ErrorNames.insert(std::make_pair(772, "ERROR_ROWSNOTRELEASED")); + ErrorNames.insert(std::make_pair(773, "ERROR_BAD_ACCESSOR_FLAGS")); + ErrorNames.insert(std::make_pair(774, "ERROR_ERRORS_ENCOUNTERED")); + ErrorNames.insert(std::make_pair(775, "ERROR_NOT_CAPABLE")); + ErrorNames.insert(std::make_pair(776, "ERROR_REQUEST_OUT_OF_SEQUENCE")); + ErrorNames.insert(std::make_pair(777, "ERROR_VERSION_PARSE_ERROR")); + ErrorNames.insert(std::make_pair(778, "ERROR_BADSTARTPOSITION")); + ErrorNames.insert(std::make_pair(779, "ERROR_MEMORY_HARDWARE")); + ErrorNames.insert(std::make_pair(780, "ERROR_DISK_REPAIR_DISABLED")); + ErrorNames.insert(std::make_pair(781, "ERROR_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE")); + ErrorNames.insert(std::make_pair(782, "ERROR_SYSTEM_POWERSTATE_TRANSITION")); + ErrorNames.insert(std::make_pair(783, "ERROR_SYSTEM_POWERSTATE_COMPLEX_TRANSITION")); + ErrorNames.insert(std::make_pair(784, "ERROR_MCA_EXCEPTION")); + ErrorNames.insert(std::make_pair(785, "ERROR_ACCESS_AUDIT_BY_POLICY")); + ErrorNames.insert(std::make_pair(786, "ERROR_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY")); + ErrorNames.insert(std::make_pair(787, "ERROR_ABANDON_HIBERFILE")); + ErrorNames.insert(std::make_pair(788, "ERROR_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED")); + ErrorNames.insert(std::make_pair(789, "ERROR_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR")); + ErrorNames.insert(std::make_pair(790, "ERROR_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR")); + ErrorNames.insert(std::make_pair(791, "ERROR_BAD_MCFG_TABLE")); + ErrorNames.insert(std::make_pair(800, "ERROR_OPLOCK_SWITCHED_TO_NEW_HANDLE")); + ErrorNames.insert(std::make_pair(801, "ERROR_CANNOT_GRANT_REQUESTED_OPLOCK")); + ErrorNames.insert(std::make_pair(802, "ERROR_CANNOT_BREAK_OPLOCK")); + ErrorNames.insert(std::make_pair(803, "ERROR_OPLOCK_HANDLE_CLOSED")); + ErrorNames.insert(std::make_pair(804, "ERROR_NO_ACE_CONDITION")); + ErrorNames.insert(std::make_pair(805, "ERROR_INVALID_ACE_CONDITION")); + ErrorNames.insert(std::make_pair(994, "ERROR_EA_ACCESS_DENIED")); + ErrorNames.insert(std::make_pair(995, "ERROR_OPERATION_ABORTED")); + ErrorNames.insert(std::make_pair(996, "ERROR_IO_INCOMPLETE")); + ErrorNames.insert(std::make_pair(997, "ERROR_IO_PENDING")); + ErrorNames.insert(std::make_pair(998, "ERROR_NOACCESS")); + ErrorNames.insert(std::make_pair(999, "ERROR_SWAPERROR")); + ErrorNames.insert(std::make_pair(1001, "ERROR_STACK_OVERFLOW")); + ErrorNames.insert(std::make_pair(1002, "ERROR_INVALID_MESSAGE")); + ErrorNames.insert(std::make_pair(1003, "ERROR_CAN_NOT_COMPLETE")); + ErrorNames.insert(std::make_pair(1004, "ERROR_INVALID_FLAGS")); + ErrorNames.insert(std::make_pair(1005, "ERROR_UNRECOGNIZED_VOLUME")); + ErrorNames.insert(std::make_pair(1006, "ERROR_FILE_INVALID")); + ErrorNames.insert(std::make_pair(1007, "ERROR_FULLSCREEN_MODE")); + ErrorNames.insert(std::make_pair(1008, "ERROR_NO_TOKEN")); + ErrorNames.insert(std::make_pair(1009, "ERROR_BADDB")); + ErrorNames.insert(std::make_pair(1010, "ERROR_BADKEY")); + ErrorNames.insert(std::make_pair(1011, "ERROR_CANTOPEN")); + ErrorNames.insert(std::make_pair(1012, "ERROR_CANTREAD")); + ErrorNames.insert(std::make_pair(1013, "ERROR_CANTWRITE")); + ErrorNames.insert(std::make_pair(1014, "ERROR_REGISTRY_RECOVERED")); + ErrorNames.insert(std::make_pair(1015, "ERROR_REGISTRY_CORRUPT")); + ErrorNames.insert(std::make_pair(1016, "ERROR_REGISTRY_IO_FAILED")); + ErrorNames.insert(std::make_pair(1017, "ERROR_NOT_REGISTRY_FILE")); + ErrorNames.insert(std::make_pair(1018, "ERROR_KEY_DELETED")); + ErrorNames.insert(std::make_pair(1019, "ERROR_NO_LOG_SPACE")); + ErrorNames.insert(std::make_pair(1020, "ERROR_KEY_HAS_CHILDREN")); + ErrorNames.insert(std::make_pair(1021, "ERROR_CHILD_MUST_BE_VOLATILE")); + ErrorNames.insert(std::make_pair(1022, "ERROR_NOTIFY_ENUM_DIR")); + ErrorNames.insert(std::make_pair(1051, "ERROR_DEPENDENT_SERVICES_RUNNING")); + ErrorNames.insert(std::make_pair(1052, "ERROR_INVALID_SERVICE_CONTROL")); + ErrorNames.insert(std::make_pair(1053, "ERROR_SERVICE_REQUEST_TIMEOUT")); + ErrorNames.insert(std::make_pair(1054, "ERROR_SERVICE_NO_THREAD")); + ErrorNames.insert(std::make_pair(1055, "ERROR_SERVICE_DATABASE_LOCKED")); + ErrorNames.insert(std::make_pair(1056, "ERROR_SERVICE_ALREADY_RUNNING")); + ErrorNames.insert(std::make_pair(1057, "ERROR_INVALID_SERVICE_ACCOUNT")); + ErrorNames.insert(std::make_pair(1058, "ERROR_SERVICE_DISABLED")); + ErrorNames.insert(std::make_pair(1059, "ERROR_CIRCULAR_DEPENDENCY")); + ErrorNames.insert(std::make_pair(1060, "ERROR_SERVICE_DOES_NOT_EXIST")); + ErrorNames.insert(std::make_pair(1061, "ERROR_SERVICE_CANNOT_ACCEPT_CTRL")); + ErrorNames.insert(std::make_pair(1062, "ERROR_SERVICE_NOT_ACTIVE")); + ErrorNames.insert(std::make_pair(1063, "ERROR_FAILED_SERVICE_CONTROLLER_CONNECT")); + ErrorNames.insert(std::make_pair(1064, "ERROR_EXCEPTION_IN_SERVICE")); + ErrorNames.insert(std::make_pair(1065, "ERROR_DATABASE_DOES_NOT_EXIST")); + ErrorNames.insert(std::make_pair(1066, "ERROR_SERVICE_SPECIFIC_ERROR")); + ErrorNames.insert(std::make_pair(1067, "ERROR_PROCESS_ABORTED")); + ErrorNames.insert(std::make_pair(1068, "ERROR_SERVICE_DEPENDENCY_FAIL")); + ErrorNames.insert(std::make_pair(1069, "ERROR_SERVICE_LOGON_FAILED")); + ErrorNames.insert(std::make_pair(1070, "ERROR_SERVICE_START_HANG")); + ErrorNames.insert(std::make_pair(1071, "ERROR_INVALID_SERVICE_LOCK")); + ErrorNames.insert(std::make_pair(1072, "ERROR_SERVICE_MARKED_FOR_DELETE")); + ErrorNames.insert(std::make_pair(1073, "ERROR_SERVICE_EXISTS")); + ErrorNames.insert(std::make_pair(1074, "ERROR_ALREADY_RUNNING_LKG")); + ErrorNames.insert(std::make_pair(1075, "ERROR_SERVICE_DEPENDENCY_DELETED")); + ErrorNames.insert(std::make_pair(1076, "ERROR_BOOT_ALREADY_ACCEPTED")); + ErrorNames.insert(std::make_pair(1077, "ERROR_SERVICE_NEVER_STARTED")); + ErrorNames.insert(std::make_pair(1078, "ERROR_DUPLICATE_SERVICE_NAME")); + ErrorNames.insert(std::make_pair(1079, "ERROR_DIFFERENT_SERVICE_ACCOUNT")); + ErrorNames.insert(std::make_pair(1080, "ERROR_CANNOT_DETECT_DRIVER_FAILURE")); + ErrorNames.insert(std::make_pair(1081, "ERROR_CANNOT_DETECT_PROCESS_ABORT")); + ErrorNames.insert(std::make_pair(1082, "ERROR_NO_RECOVERY_PROGRAM")); + ErrorNames.insert(std::make_pair(1083, "ERROR_SERVICE_NOT_IN_EXE")); + ErrorNames.insert(std::make_pair(1084, "ERROR_NOT_SAFEBOOT_SERVICE")); + ErrorNames.insert(std::make_pair(1100, "ERROR_END_OF_MEDIA")); + ErrorNames.insert(std::make_pair(1101, "ERROR_FILEMARK_DETECTED")); + ErrorNames.insert(std::make_pair(1102, "ERROR_BEGINNING_OF_MEDIA")); + ErrorNames.insert(std::make_pair(1103, "ERROR_SETMARK_DETECTED")); + ErrorNames.insert(std::make_pair(1104, "ERROR_NO_DATA_DETECTED")); + ErrorNames.insert(std::make_pair(1105, "ERROR_PARTITION_FAILURE")); + ErrorNames.insert(std::make_pair(1106, "ERROR_INVALID_BLOCK_LENGTH")); + ErrorNames.insert(std::make_pair(1107, "ERROR_DEVICE_NOT_PARTITIONED")); + ErrorNames.insert(std::make_pair(1108, "ERROR_UNABLE_TO_LOCK_MEDIA")); + ErrorNames.insert(std::make_pair(1109, "ERROR_UNABLE_TO_UNLOAD_MEDIA")); + ErrorNames.insert(std::make_pair(1110, "ERROR_MEDIA_CHANGED")); + ErrorNames.insert(std::make_pair(1111, "ERROR_BUS_RESET")); + ErrorNames.insert(std::make_pair(1112, "ERROR_NO_MEDIA_IN_DRIVE")); + ErrorNames.insert(std::make_pair(1113, "ERROR_NO_UNICODE_TRANSLATION")); + ErrorNames.insert(std::make_pair(1114, "ERROR_DLL_INIT_FAILED")); + ErrorNames.insert(std::make_pair(1115, "ERROR_SHUTDOWN_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(1116, "ERROR_NO_SHUTDOWN_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(1117, "ERROR_IO_DEVICE")); + ErrorNames.insert(std::make_pair(1118, "ERROR_SERIAL_NO_DEVICE")); + ErrorNames.insert(std::make_pair(1119, "ERROR_IRQ_BUSY")); + ErrorNames.insert(std::make_pair(1120, "ERROR_MORE_WRITES")); + ErrorNames.insert(std::make_pair(1121, "ERROR_COUNTER_TIMEOUT")); + ErrorNames.insert(std::make_pair(1122, "ERROR_FLOPPY_ID_MARK_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1123, "ERROR_FLOPPY_WRONG_CYLINDER")); + ErrorNames.insert(std::make_pair(1124, "ERROR_FLOPPY_UNKNOWN_ERROR")); + ErrorNames.insert(std::make_pair(1125, "ERROR_FLOPPY_BAD_REGISTERS")); + ErrorNames.insert(std::make_pair(1126, "ERROR_DISK_RECALIBRATE_FAILED")); + ErrorNames.insert(std::make_pair(1127, "ERROR_DISK_OPERATION_FAILED")); + ErrorNames.insert(std::make_pair(1128, "ERROR_DISK_RESET_FAILED")); + ErrorNames.insert(std::make_pair(1129, "ERROR_EOM_OVERFLOW")); + ErrorNames.insert(std::make_pair(1130, "ERROR_NOT_ENOUGH_SERVER_MEMORY")); + ErrorNames.insert(std::make_pair(1131, "ERROR_POSSIBLE_DEADLOCK")); + ErrorNames.insert(std::make_pair(1132, "ERROR_MAPPED_ALIGNMENT")); + ErrorNames.insert(std::make_pair(1140, "ERROR_SET_POWER_STATE_VETOED")); + ErrorNames.insert(std::make_pair(1141, "ERROR_SET_POWER_STATE_FAILED")); + ErrorNames.insert(std::make_pair(1142, "ERROR_TOO_MANY_LINKS")); + ErrorNames.insert(std::make_pair(1150, "ERROR_OLD_WIN_VERSION")); + ErrorNames.insert(std::make_pair(1151, "ERROR_APP_WRONG_OS")); + ErrorNames.insert(std::make_pair(1152, "ERROR_SINGLE_INSTANCE_APP")); + ErrorNames.insert(std::make_pair(1153, "ERROR_RMODE_APP")); + ErrorNames.insert(std::make_pair(1154, "ERROR_INVALID_DLL")); + ErrorNames.insert(std::make_pair(1155, "ERROR_NO_ASSOCIATION")); + ErrorNames.insert(std::make_pair(1156, "ERROR_DDE_FAIL")); + ErrorNames.insert(std::make_pair(1157, "ERROR_DLL_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1158, "ERROR_NO_MORE_USER_HANDLES")); + ErrorNames.insert(std::make_pair(1159, "ERROR_MESSAGE_SYNC_ONLY")); + ErrorNames.insert(std::make_pair(1160, "ERROR_SOURCE_ELEMENT_EMPTY")); + ErrorNames.insert(std::make_pair(1161, "ERROR_DESTINATION_ELEMENT_FULL")); + ErrorNames.insert(std::make_pair(1162, "ERROR_ILLEGAL_ELEMENT_ADDRESS")); + ErrorNames.insert(std::make_pair(1163, "ERROR_MAGAZINE_NOT_PRESENT")); + ErrorNames.insert(std::make_pair(1164, "ERROR_DEVICE_REINITIALIZATION_NEEDED")); + ErrorNames.insert(std::make_pair(1165, "ERROR_DEVICE_REQUIRES_CLEANING")); + ErrorNames.insert(std::make_pair(1166, "ERROR_DEVICE_DOOR_OPEN")); + ErrorNames.insert(std::make_pair(1167, "ERROR_DEVICE_NOT_CONNECTED")); + ErrorNames.insert(std::make_pair(1168, "ERROR_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1169, "ERROR_NO_MATCH")); + ErrorNames.insert(std::make_pair(1170, "ERROR_SET_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1171, "ERROR_POINT_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1172, "ERROR_NO_TRACKING_SERVICE")); + ErrorNames.insert(std::make_pair(1173, "ERROR_NO_VOLUME_ID")); + ErrorNames.insert(std::make_pair(1175, "ERROR_UNABLE_TO_REMOVE_REPLACED")); + ErrorNames.insert(std::make_pair(1176, "ERROR_UNABLE_TO_MOVE_REPLACEMENT")); + ErrorNames.insert(std::make_pair(1177, "ERROR_UNABLE_TO_MOVE_REPLACEMENT_2")); + ErrorNames.insert(std::make_pair(1178, "ERROR_JOURNAL_DELETE_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(1179, "ERROR_JOURNAL_NOT_ACTIVE")); + ErrorNames.insert(std::make_pair(1180, "ERROR_POTENTIAL_FILE_FOUND")); + ErrorNames.insert(std::make_pair(1181, "ERROR_JOURNAL_ENTRY_DELETED")); + ErrorNames.insert(std::make_pair(1190, "ERROR_SHUTDOWN_IS_SCHEDULED")); + ErrorNames.insert(std::make_pair(1191, "ERROR_SHUTDOWN_USERS_LOGGED_ON")); + ErrorNames.insert(std::make_pair(1200, "ERROR_BAD_DEVICE")); + ErrorNames.insert(std::make_pair(1201, "ERROR_CONNECTION_UNAVAIL")); + ErrorNames.insert(std::make_pair(1202, "ERROR_DEVICE_ALREADY_REMEMBERED")); + ErrorNames.insert(std::make_pair(1203, "ERROR_NO_NET_OR_BAD_PATH")); + ErrorNames.insert(std::make_pair(1204, "ERROR_BAD_PROVIDER")); + ErrorNames.insert(std::make_pair(1205, "ERROR_CANNOT_OPEN_PROFILE")); + ErrorNames.insert(std::make_pair(1206, "ERROR_BAD_PROFILE")); + ErrorNames.insert(std::make_pair(1207, "ERROR_NOT_CONTAINER")); + ErrorNames.insert(std::make_pair(1208, "ERROR_EXTENDED_ERROR")); + ErrorNames.insert(std::make_pair(1209, "ERROR_INVALID_GROUPNAME")); + ErrorNames.insert(std::make_pair(1210, "ERROR_INVALID_COMPUTERNAME")); + ErrorNames.insert(std::make_pair(1211, "ERROR_INVALID_EVENTNAME")); + ErrorNames.insert(std::make_pair(1212, "ERROR_INVALID_DOMAINNAME")); + ErrorNames.insert(std::make_pair(1213, "ERROR_INVALID_SERVICENAME")); + ErrorNames.insert(std::make_pair(1214, "ERROR_INVALID_NETNAME")); + ErrorNames.insert(std::make_pair(1215, "ERROR_INVALID_SHARENAME")); + ErrorNames.insert(std::make_pair(1216, "ERROR_INVALID_PASSWORDNAME")); + ErrorNames.insert(std::make_pair(1217, "ERROR_INVALID_MESSAGENAME")); + ErrorNames.insert(std::make_pair(1218, "ERROR_INVALID_MESSAGEDEST")); + ErrorNames.insert(std::make_pair(1219, "ERROR_SESSION_CREDENTIAL_CONFLICT")); + ErrorNames.insert(std::make_pair(1220, "ERROR_REMOTE_SESSION_LIMIT_EXCEEDED")); + ErrorNames.insert(std::make_pair(1221, "ERROR_DUP_DOMAINNAME")); + ErrorNames.insert(std::make_pair(1222, "ERROR_NO_NETWORK")); + ErrorNames.insert(std::make_pair(1223, "ERROR_CANCELLED")); + ErrorNames.insert(std::make_pair(1224, "ERROR_USER_MAPPED_FILE")); + ErrorNames.insert(std::make_pair(1225, "ERROR_CONNECTION_REFUSED")); + ErrorNames.insert(std::make_pair(1226, "ERROR_GRACEFUL_DISCONNECT")); + ErrorNames.insert(std::make_pair(1227, "ERROR_ADDRESS_ALREADY_ASSOCIATED")); + ErrorNames.insert(std::make_pair(1228, "ERROR_ADDRESS_NOT_ASSOCIATED")); + ErrorNames.insert(std::make_pair(1229, "ERROR_CONNECTION_INVALID")); + ErrorNames.insert(std::make_pair(1230, "ERROR_CONNECTION_ACTIVE")); + ErrorNames.insert(std::make_pair(1231, "ERROR_NETWORK_UNREACHABLE")); + ErrorNames.insert(std::make_pair(1232, "ERROR_HOST_UNREACHABLE")); + ErrorNames.insert(std::make_pair(1233, "ERROR_PROTOCOL_UNREACHABLE")); + ErrorNames.insert(std::make_pair(1234, "ERROR_PORT_UNREACHABLE")); + ErrorNames.insert(std::make_pair(1235, "ERROR_REQUEST_ABORTED")); + ErrorNames.insert(std::make_pair(1236, "ERROR_CONNECTION_ABORTED")); + ErrorNames.insert(std::make_pair(1237, "ERROR_RETRY")); + ErrorNames.insert(std::make_pair(1238, "ERROR_CONNECTION_COUNT_LIMIT")); + ErrorNames.insert(std::make_pair(1239, "ERROR_LOGIN_TIME_RESTRICTION")); + ErrorNames.insert(std::make_pair(1240, "ERROR_LOGIN_WKSTA_RESTRICTION")); + ErrorNames.insert(std::make_pair(1241, "ERROR_INCORRECT_ADDRESS")); + ErrorNames.insert(std::make_pair(1242, "ERROR_ALREADY_REGISTERED")); + ErrorNames.insert(std::make_pair(1243, "ERROR_SERVICE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1244, "ERROR_NOT_AUTHENTICATED")); + ErrorNames.insert(std::make_pair(1245, "ERROR_NOT_LOGGED_ON")); + ErrorNames.insert(std::make_pair(1246, "ERROR_CONTINUE")); + ErrorNames.insert(std::make_pair(1247, "ERROR_ALREADY_INITIALIZED")); + ErrorNames.insert(std::make_pair(1248, "ERROR_NO_MORE_DEVICES")); + ErrorNames.insert(std::make_pair(1249, "ERROR_NO_SUCH_SITE")); + ErrorNames.insert(std::make_pair(1250, "ERROR_DOMAIN_CONTROLLER_EXISTS")); + ErrorNames.insert(std::make_pair(1251, "ERROR_ONLY_IF_CONNECTED")); + ErrorNames.insert(std::make_pair(1252, "ERROR_OVERRIDE_NOCHANGES")); + ErrorNames.insert(std::make_pair(1253, "ERROR_BAD_USER_PROFILE")); + ErrorNames.insert(std::make_pair(1254, "ERROR_NOT_SUPPORTED_ON_SBS")); + ErrorNames.insert(std::make_pair(1255, "ERROR_SERVER_SHUTDOWN_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(1256, "ERROR_HOST_DOWN")); + ErrorNames.insert(std::make_pair(1257, "ERROR_NON_ACCOUNT_SID")); + ErrorNames.insert(std::make_pair(1258, "ERROR_NON_DOMAIN_SID")); + ErrorNames.insert(std::make_pair(1259, "ERROR_APPHELP_BLOCK")); + ErrorNames.insert(std::make_pair(1260, "ERROR_ACCESS_DISABLED_BY_POLICY")); + ErrorNames.insert(std::make_pair(1261, "ERROR_REG_NAT_CONSUMPTION")); + ErrorNames.insert(std::make_pair(1262, "ERROR_CSCSHARE_OFFLINE")); + ErrorNames.insert(std::make_pair(1263, "ERROR_PKINIT_FAILURE")); + ErrorNames.insert(std::make_pair(1264, "ERROR_SMARTCARD_SUBSYSTEM_FAILURE")); + ErrorNames.insert(std::make_pair(1265, "ERROR_DOWNGRADE_DETECTED")); + ErrorNames.insert(std::make_pair(1271, "ERROR_MACHINE_LOCKED")); + ErrorNames.insert(std::make_pair(1273, "ERROR_CALLBACK_SUPPLIED_INVALID_DATA")); + ErrorNames.insert(std::make_pair(1274, "ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED")); + ErrorNames.insert(std::make_pair(1275, "ERROR_DRIVER_BLOCKED")); + ErrorNames.insert(std::make_pair(1276, "ERROR_INVALID_IMPORT_OF_NON_DLL")); + ErrorNames.insert(std::make_pair(1277, "ERROR_ACCESS_DISABLED_WEBBLADE")); + ErrorNames.insert(std::make_pair(1278, "ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER")); + ErrorNames.insert(std::make_pair(1279, "ERROR_RECOVERY_FAILURE")); + ErrorNames.insert(std::make_pair(1280, "ERROR_ALREADY_FIBER")); + ErrorNames.insert(std::make_pair(1281, "ERROR_ALREADY_THREAD")); + ErrorNames.insert(std::make_pair(1282, "ERROR_STACK_BUFFER_OVERRUN")); + ErrorNames.insert(std::make_pair(1283, "ERROR_PARAMETER_QUOTA_EXCEEDED")); + ErrorNames.insert(std::make_pair(1284, "ERROR_DEBUGGER_INACTIVE")); + ErrorNames.insert(std::make_pair(1285, "ERROR_DELAY_LOAD_FAILED")); + ErrorNames.insert(std::make_pair(1286, "ERROR_VDM_DISALLOWED")); + ErrorNames.insert(std::make_pair(1287, "ERROR_UNIDENTIFIED_ERROR")); + ErrorNames.insert(std::make_pair(1288, "ERROR_INVALID_CRUNTIME_PARAMETER")); + ErrorNames.insert(std::make_pair(1289, "ERROR_BEYOND_VDL")); + ErrorNames.insert(std::make_pair(1290, "ERROR_INCOMPATIBLE_SERVICE_SID_TYPE")); + ErrorNames.insert(std::make_pair(1291, "ERROR_DRIVER_PROCESS_TERMINATED")); + ErrorNames.insert(std::make_pair(1292, "ERROR_IMPLEMENTATION_LIMIT")); + ErrorNames.insert(std::make_pair(1293, "ERROR_PROCESS_IS_PROTECTED")); + ErrorNames.insert(std::make_pair(1294, "ERROR_SERVICE_NOTIFY_CLIENT_LAGGING")); + ErrorNames.insert(std::make_pair(1295, "ERROR_DISK_QUOTA_EXCEEDED")); + ErrorNames.insert(std::make_pair(1296, "ERROR_CONTENT_BLOCKED")); + ErrorNames.insert(std::make_pair(1297, "ERROR_INCOMPATIBLE_SERVICE_PRIVILEGE")); + ErrorNames.insert(std::make_pair(1298, "ERROR_APP_HANG")); + ErrorNames.insert(std::make_pair(1299, "ERROR_INVALID_LABEL")); + ErrorNames.insert(std::make_pair(1300, "ERROR_NOT_ALL_ASSIGNED")); + ErrorNames.insert(std::make_pair(1301, "ERROR_SOME_NOT_MAPPED")); + ErrorNames.insert(std::make_pair(1302, "ERROR_NO_QUOTAS_FOR_ACCOUNT")); + ErrorNames.insert(std::make_pair(1303, "ERROR_LOCAL_USER_SESSION_KEY")); + ErrorNames.insert(std::make_pair(1304, "ERROR_NULL_LM_PASSWORD")); + ErrorNames.insert(std::make_pair(1305, "ERROR_UNKNOWN_REVISION")); + ErrorNames.insert(std::make_pair(1306, "ERROR_REVISION_MISMATCH")); + ErrorNames.insert(std::make_pair(1307, "ERROR_INVALID_OWNER")); + ErrorNames.insert(std::make_pair(1308, "ERROR_INVALID_PRIMARY_GROUP")); + ErrorNames.insert(std::make_pair(1309, "ERROR_NO_IMPERSONATION_TOKEN")); + ErrorNames.insert(std::make_pair(1310, "ERROR_CANT_DISABLE_MANDATORY")); + ErrorNames.insert(std::make_pair(1311, "ERROR_NO_LOGON_SERVERS")); + ErrorNames.insert(std::make_pair(1312, "ERROR_NO_SUCH_LOGON_SESSION")); + ErrorNames.insert(std::make_pair(1313, "ERROR_NO_SUCH_PRIVILEGE")); + ErrorNames.insert(std::make_pair(1314, "ERROR_PRIVILEGE_NOT_HELD")); + ErrorNames.insert(std::make_pair(1315, "ERROR_INVALID_ACCOUNT_NAME")); + ErrorNames.insert(std::make_pair(1316, "ERROR_USER_EXISTS")); + ErrorNames.insert(std::make_pair(1317, "ERROR_NO_SUCH_USER")); + ErrorNames.insert(std::make_pair(1318, "ERROR_GROUP_EXISTS")); + ErrorNames.insert(std::make_pair(1319, "ERROR_NO_SUCH_GROUP")); + ErrorNames.insert(std::make_pair(1320, "ERROR_MEMBER_IN_GROUP")); + ErrorNames.insert(std::make_pair(1321, "ERROR_MEMBER_NOT_IN_GROUP")); + ErrorNames.insert(std::make_pair(1322, "ERROR_LAST_ADMIN")); + ErrorNames.insert(std::make_pair(1323, "ERROR_WRONG_PASSWORD")); + ErrorNames.insert(std::make_pair(1324, "ERROR_ILL_FORMED_PASSWORD")); + ErrorNames.insert(std::make_pair(1325, "ERROR_PASSWORD_RESTRICTION")); + ErrorNames.insert(std::make_pair(1326, "ERROR_LOGON_FAILURE")); + ErrorNames.insert(std::make_pair(1327, "ERROR_ACCOUNT_RESTRICTION")); + ErrorNames.insert(std::make_pair(1328, "ERROR_INVALID_LOGON_HOURS")); + ErrorNames.insert(std::make_pair(1329, "ERROR_INVALID_WORKSTATION")); + ErrorNames.insert(std::make_pair(1330, "ERROR_PASSWORD_EXPIRED")); + ErrorNames.insert(std::make_pair(1331, "ERROR_ACCOUNT_DISABLED")); + ErrorNames.insert(std::make_pair(1332, "ERROR_NONE_MAPPED")); + ErrorNames.insert(std::make_pair(1333, "ERROR_TOO_MANY_LUIDS_REQUESTED")); + ErrorNames.insert(std::make_pair(1334, "ERROR_LUIDS_EXHAUSTED")); + ErrorNames.insert(std::make_pair(1335, "ERROR_INVALID_SUB_AUTHORITY")); + ErrorNames.insert(std::make_pair(1336, "ERROR_INVALID_ACL")); + ErrorNames.insert(std::make_pair(1337, "ERROR_INVALID_SID")); + ErrorNames.insert(std::make_pair(1338, "ERROR_INVALID_SECURITY_DESCR")); + ErrorNames.insert(std::make_pair(1340, "ERROR_BAD_INHERITANCE_ACL")); + ErrorNames.insert(std::make_pair(1341, "ERROR_SERVER_DISABLED")); + ErrorNames.insert(std::make_pair(1342, "ERROR_SERVER_NOT_DISABLED")); + ErrorNames.insert(std::make_pair(1343, "ERROR_INVALID_ID_AUTHORITY")); + ErrorNames.insert(std::make_pair(1344, "ERROR_ALLOTTED_SPACE_EXCEEDED")); + ErrorNames.insert(std::make_pair(1345, "ERROR_INVALID_GROUP_ATTRIBUTES")); + ErrorNames.insert(std::make_pair(1346, "ERROR_BAD_IMPERSONATION_LEVEL")); + ErrorNames.insert(std::make_pair(1347, "ERROR_CANT_OPEN_ANONYMOUS")); + ErrorNames.insert(std::make_pair(1348, "ERROR_BAD_VALIDATION_CLASS")); + ErrorNames.insert(std::make_pair(1349, "ERROR_BAD_TOKEN_TYPE")); + ErrorNames.insert(std::make_pair(1350, "ERROR_NO_SECURITY_ON_OBJECT")); + ErrorNames.insert(std::make_pair(1351, "ERROR_CANT_ACCESS_DOMAIN_INFO")); + ErrorNames.insert(std::make_pair(1352, "ERROR_INVALID_SERVER_STATE")); + ErrorNames.insert(std::make_pair(1353, "ERROR_INVALID_DOMAIN_STATE")); + ErrorNames.insert(std::make_pair(1354, "ERROR_INVALID_DOMAIN_ROLE")); + ErrorNames.insert(std::make_pair(1355, "ERROR_NO_SUCH_DOMAIN")); + ErrorNames.insert(std::make_pair(1356, "ERROR_DOMAIN_EXISTS")); + ErrorNames.insert(std::make_pair(1357, "ERROR_DOMAIN_LIMIT_EXCEEDED")); + ErrorNames.insert(std::make_pair(1358, "ERROR_INTERNAL_DB_CORRUPTION")); + ErrorNames.insert(std::make_pair(1359, "ERROR_INTERNAL_ERROR")); + ErrorNames.insert(std::make_pair(1360, "ERROR_GENERIC_NOT_MAPPED")); + ErrorNames.insert(std::make_pair(1361, "ERROR_BAD_DESCRIPTOR_FORMAT")); + ErrorNames.insert(std::make_pair(1362, "ERROR_NOT_LOGON_PROCESS")); + ErrorNames.insert(std::make_pair(1363, "ERROR_LOGON_SESSION_EXISTS")); + ErrorNames.insert(std::make_pair(1364, "ERROR_NO_SUCH_PACKAGE")); + ErrorNames.insert(std::make_pair(1365, "ERROR_BAD_LOGON_SESSION_STATE")); + ErrorNames.insert(std::make_pair(1366, "ERROR_LOGON_SESSION_COLLISION")); + ErrorNames.insert(std::make_pair(1367, "ERROR_INVALID_LOGON_TYPE")); + ErrorNames.insert(std::make_pair(1368, "ERROR_CANNOT_IMPERSONATE")); + ErrorNames.insert(std::make_pair(1369, "ERROR_RXACT_INVALID_STATE")); + ErrorNames.insert(std::make_pair(1370, "ERROR_RXACT_COMMIT_FAILURE")); + ErrorNames.insert(std::make_pair(1371, "ERROR_SPECIAL_ACCOUNT")); + ErrorNames.insert(std::make_pair(1372, "ERROR_SPECIAL_GROUP")); + ErrorNames.insert(std::make_pair(1373, "ERROR_SPECIAL_USER")); + ErrorNames.insert(std::make_pair(1374, "ERROR_MEMBERS_PRIMARY_GROUP")); + ErrorNames.insert(std::make_pair(1375, "ERROR_TOKEN_ALREADY_IN_USE")); + ErrorNames.insert(std::make_pair(1376, "ERROR_NO_SUCH_ALIAS")); + ErrorNames.insert(std::make_pair(1377, "ERROR_MEMBER_NOT_IN_ALIAS")); + ErrorNames.insert(std::make_pair(1378, "ERROR_MEMBER_IN_ALIAS")); + ErrorNames.insert(std::make_pair(1379, "ERROR_ALIAS_EXISTS")); + ErrorNames.insert(std::make_pair(1380, "ERROR_LOGON_NOT_GRANTED")); + ErrorNames.insert(std::make_pair(1381, "ERROR_TOO_MANY_SECRETS")); + ErrorNames.insert(std::make_pair(1382, "ERROR_SECRET_TOO_LONG")); + ErrorNames.insert(std::make_pair(1383, "ERROR_INTERNAL_DB_ERROR")); + ErrorNames.insert(std::make_pair(1384, "ERROR_TOO_MANY_CONTEXT_IDS")); + ErrorNames.insert(std::make_pair(1385, "ERROR_LOGON_TYPE_NOT_GRANTED")); + ErrorNames.insert(std::make_pair(1386, "ERROR_NT_CROSS_ENCRYPTION_REQUIRED")); + ErrorNames.insert(std::make_pair(1387, "ERROR_NO_SUCH_MEMBER")); + ErrorNames.insert(std::make_pair(1388, "ERROR_INVALID_MEMBER")); + ErrorNames.insert(std::make_pair(1389, "ERROR_TOO_MANY_SIDS")); + ErrorNames.insert(std::make_pair(1390, "ERROR_LM_CROSS_ENCRYPTION_REQUIRED")); + ErrorNames.insert(std::make_pair(1391, "ERROR_NO_INHERITANCE")); + ErrorNames.insert(std::make_pair(1392, "ERROR_FILE_CORRUPT")); + ErrorNames.insert(std::make_pair(1393, "ERROR_DISK_CORRUPT")); + ErrorNames.insert(std::make_pair(1394, "ERROR_NO_USER_SESSION_KEY")); + ErrorNames.insert(std::make_pair(1395, "ERROR_LICENSE_QUOTA_EXCEEDED")); + ErrorNames.insert(std::make_pair(1396, "ERROR_WRONG_TARGET_NAME")); + ErrorNames.insert(std::make_pair(1397, "ERROR_MUTUAL_AUTH_FAILED")); + ErrorNames.insert(std::make_pair(1398, "ERROR_TIME_SKEW")); + ErrorNames.insert(std::make_pair(1399, "ERROR_CURRENT_DOMAIN_NOT_ALLOWED")); + ErrorNames.insert(std::make_pair(1400, "ERROR_INVALID_WINDOW_HANDLE")); + ErrorNames.insert(std::make_pair(1401, "ERROR_INVALID_MENU_HANDLE")); + ErrorNames.insert(std::make_pair(1402, "ERROR_INVALID_CURSOR_HANDLE")); + ErrorNames.insert(std::make_pair(1403, "ERROR_INVALID_ACCEL_HANDLE")); + ErrorNames.insert(std::make_pair(1404, "ERROR_INVALID_HOOK_HANDLE")); + ErrorNames.insert(std::make_pair(1405, "ERROR_INVALID_DWP_HANDLE")); + ErrorNames.insert(std::make_pair(1406, "ERROR_TLW_WITH_WSCHILD")); + ErrorNames.insert(std::make_pair(1407, "ERROR_CANNOT_FIND_WND_CLASS")); + ErrorNames.insert(std::make_pair(1408, "ERROR_WINDOW_OF_OTHER_THREAD")); + ErrorNames.insert(std::make_pair(1409, "ERROR_HOTKEY_ALREADY_REGISTERED")); + ErrorNames.insert(std::make_pair(1410, "ERROR_CLASS_ALREADY_EXISTS")); + ErrorNames.insert(std::make_pair(1411, "ERROR_CLASS_DOES_NOT_EXIST")); + ErrorNames.insert(std::make_pair(1412, "ERROR_CLASS_HAS_WINDOWS")); + ErrorNames.insert(std::make_pair(1413, "ERROR_INVALID_INDEX")); + ErrorNames.insert(std::make_pair(1414, "ERROR_INVALID_ICON_HANDLE")); + ErrorNames.insert(std::make_pair(1415, "ERROR_PRIVATE_DIALOG_INDEX")); + ErrorNames.insert(std::make_pair(1416, "ERROR_LISTBOX_ID_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1417, "ERROR_NO_WILDCARD_CHARACTERS")); + ErrorNames.insert(std::make_pair(1418, "ERROR_CLIPBOARD_NOT_OPEN")); + ErrorNames.insert(std::make_pair(1419, "ERROR_HOTKEY_NOT_REGISTERED")); + ErrorNames.insert(std::make_pair(1420, "ERROR_WINDOW_NOT_DIALOG")); + ErrorNames.insert(std::make_pair(1421, "ERROR_CONTROL_ID_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1422, "ERROR_INVALID_COMBOBOX_MESSAGE")); + ErrorNames.insert(std::make_pair(1423, "ERROR_WINDOW_NOT_COMBOBOX")); + ErrorNames.insert(std::make_pair(1424, "ERROR_INVALID_EDIT_HEIGHT")); + ErrorNames.insert(std::make_pair(1425, "ERROR_DC_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1426, "ERROR_INVALID_HOOK_FILTER")); + ErrorNames.insert(std::make_pair(1427, "ERROR_INVALID_FILTER_PROC")); + ErrorNames.insert(std::make_pair(1428, "ERROR_HOOK_NEEDS_HMOD")); + ErrorNames.insert(std::make_pair(1429, "ERROR_GLOBAL_ONLY_HOOK")); + ErrorNames.insert(std::make_pair(1430, "ERROR_JOURNAL_HOOK_SET")); + ErrorNames.insert(std::make_pair(1431, "ERROR_HOOK_NOT_INSTALLED")); + ErrorNames.insert(std::make_pair(1432, "ERROR_INVALID_LB_MESSAGE")); + ErrorNames.insert(std::make_pair(1433, "ERROR_SETCOUNT_ON_BAD_LB")); + ErrorNames.insert(std::make_pair(1434, "ERROR_LB_WITHOUT_TABSTOPS")); + ErrorNames.insert(std::make_pair(1435, "ERROR_DESTROY_OBJECT_OF_OTHER_THREAD")); + ErrorNames.insert(std::make_pair(1436, "ERROR_CHILD_WINDOW_MENU")); + ErrorNames.insert(std::make_pair(1437, "ERROR_NO_SYSTEM_MENU")); + ErrorNames.insert(std::make_pair(1438, "ERROR_INVALID_MSGBOX_STYLE")); + ErrorNames.insert(std::make_pair(1439, "ERROR_INVALID_SPI_VALUE")); + ErrorNames.insert(std::make_pair(1440, "ERROR_SCREEN_ALREADY_LOCKED")); + ErrorNames.insert(std::make_pair(1441, "ERROR_HWNDS_HAVE_DIFF_PARENT")); + ErrorNames.insert(std::make_pair(1442, "ERROR_NOT_CHILD_WINDOW")); + ErrorNames.insert(std::make_pair(1443, "ERROR_INVALID_GW_COMMAND")); + ErrorNames.insert(std::make_pair(1444, "ERROR_INVALID_THREAD_ID")); + ErrorNames.insert(std::make_pair(1445, "ERROR_NON_MDICHILD_WINDOW")); + ErrorNames.insert(std::make_pair(1446, "ERROR_POPUP_ALREADY_ACTIVE")); + ErrorNames.insert(std::make_pair(1447, "ERROR_NO_SCROLLBARS")); + ErrorNames.insert(std::make_pair(1448, "ERROR_INVALID_SCROLLBAR_RANGE")); + ErrorNames.insert(std::make_pair(1449, "ERROR_INVALID_SHOWWIN_COMMAND")); + ErrorNames.insert(std::make_pair(1450, "ERROR_NO_SYSTEM_RESOURCES")); + ErrorNames.insert(std::make_pair(1451, "ERROR_NONPAGED_SYSTEM_RESOURCES")); + ErrorNames.insert(std::make_pair(1452, "ERROR_PAGED_SYSTEM_RESOURCES")); + ErrorNames.insert(std::make_pair(1453, "ERROR_WORKING_SET_QUOTA")); + ErrorNames.insert(std::make_pair(1454, "ERROR_PAGEFILE_QUOTA")); + ErrorNames.insert(std::make_pair(1455, "ERROR_COMMITMENT_LIMIT")); + ErrorNames.insert(std::make_pair(1456, "ERROR_MENU_ITEM_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1457, "ERROR_INVALID_KEYBOARD_HANDLE")); + ErrorNames.insert(std::make_pair(1458, "ERROR_HOOK_TYPE_NOT_ALLOWED")); + ErrorNames.insert(std::make_pair(1459, "ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION")); + ErrorNames.insert(std::make_pair(1460, "ERROR_TIMEOUT")); + ErrorNames.insert(std::make_pair(1461, "ERROR_INVALID_MONITOR_HANDLE")); + ErrorNames.insert(std::make_pair(1462, "ERROR_INCORRECT_SIZE")); + ErrorNames.insert(std::make_pair(1463, "ERROR_SYMLINK_CLASS_DISABLED")); + ErrorNames.insert(std::make_pair(1464, "ERROR_SYMLINK_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(1465, "ERROR_XML_PARSE_ERROR")); + ErrorNames.insert(std::make_pair(1466, "ERROR_XMLDSIG_ERROR")); + ErrorNames.insert(std::make_pair(1467, "ERROR_RESTART_APPLICATION")); + ErrorNames.insert(std::make_pair(1468, "ERROR_WRONG_COMPARTMENT")); + ErrorNames.insert(std::make_pair(1469, "ERROR_AUTHIP_FAILURE")); + ErrorNames.insert(std::make_pair(1470, "ERROR_NO_NVRAM_RESOURCES")); + ErrorNames.insert(std::make_pair(1500, "ERROR_EVENTLOG_FILE_CORRUPT")); + ErrorNames.insert(std::make_pair(1501, "ERROR_EVENTLOG_CANT_START")); + ErrorNames.insert(std::make_pair(1502, "ERROR_LOG_FILE_FULL")); + ErrorNames.insert(std::make_pair(1503, "ERROR_EVENTLOG_FILE_CHANGED")); + ErrorNames.insert(std::make_pair(1550, "ERROR_INVALID_TASK_NAME")); + ErrorNames.insert(std::make_pair(1551, "ERROR_INVALID_TASK_INDEX")); + ErrorNames.insert(std::make_pair(1552, "ERROR_THREAD_ALREADY_IN_TASK")); + ErrorNames.insert(std::make_pair(1601, "ERROR_INSTALL_SERVICE_FAILURE")); + ErrorNames.insert(std::make_pair(1602, "ERROR_INSTALL_USEREXIT")); + ErrorNames.insert(std::make_pair(1603, "ERROR_INSTALL_FAILURE")); + ErrorNames.insert(std::make_pair(1604, "ERROR_INSTALL_SUSPEND")); + ErrorNames.insert(std::make_pair(1605, "ERROR_UNKNOWN_PRODUCT")); + ErrorNames.insert(std::make_pair(1606, "ERROR_UNKNOWN_FEATURE")); + ErrorNames.insert(std::make_pair(1607, "ERROR_UNKNOWN_COMPONENT")); + ErrorNames.insert(std::make_pair(1608, "ERROR_UNKNOWN_PROPERTY")); + ErrorNames.insert(std::make_pair(1609, "ERROR_INVALID_HANDLE_STATE")); + ErrorNames.insert(std::make_pair(1610, "ERROR_BAD_CONFIGURATION")); + ErrorNames.insert(std::make_pair(1611, "ERROR_INDEX_ABSENT")); + ErrorNames.insert(std::make_pair(1612, "ERROR_INSTALL_SOURCE_ABSENT")); + ErrorNames.insert(std::make_pair(1613, "ERROR_INSTALL_PACKAGE_VERSION")); + ErrorNames.insert(std::make_pair(1614, "ERROR_PRODUCT_UNINSTALLED")); + ErrorNames.insert(std::make_pair(1615, "ERROR_BAD_QUERY_SYNTAX")); + ErrorNames.insert(std::make_pair(1616, "ERROR_INVALID_FIELD")); + ErrorNames.insert(std::make_pair(1617, "ERROR_DEVICE_REMOVED")); + ErrorNames.insert(std::make_pair(1618, "ERROR_INSTALL_ALREADY_RUNNING")); + ErrorNames.insert(std::make_pair(1619, "ERROR_INSTALL_PACKAGE_OPEN_FAILED")); + ErrorNames.insert(std::make_pair(1620, "ERROR_INSTALL_PACKAGE_INVALID")); + ErrorNames.insert(std::make_pair(1621, "ERROR_INSTALL_UI_FAILURE")); + ErrorNames.insert(std::make_pair(1622, "ERROR_INSTALL_LOG_FAILURE")); + ErrorNames.insert(std::make_pair(1623, "ERROR_INSTALL_LANGUAGE_UNSUPPORTED")); + ErrorNames.insert(std::make_pair(1624, "ERROR_INSTALL_TRANSFORM_FAILURE")); + ErrorNames.insert(std::make_pair(1625, "ERROR_INSTALL_PACKAGE_REJECTED")); + ErrorNames.insert(std::make_pair(1626, "ERROR_FUNCTION_NOT_CALLED")); + ErrorNames.insert(std::make_pair(1627, "ERROR_FUNCTION_FAILED")); + ErrorNames.insert(std::make_pair(1628, "ERROR_INVALID_TABLE")); + ErrorNames.insert(std::make_pair(1629, "ERROR_DATATYPE_MISMATCH")); + ErrorNames.insert(std::make_pair(1630, "ERROR_UNSUPPORTED_TYPE")); + ErrorNames.insert(std::make_pair(1631, "ERROR_CREATE_FAILED")); + ErrorNames.insert(std::make_pair(1632, "ERROR_INSTALL_TEMP_UNWRITABLE")); + ErrorNames.insert(std::make_pair(1633, "ERROR_INSTALL_PLATFORM_UNSUPPORTED")); + ErrorNames.insert(std::make_pair(1634, "ERROR_INSTALL_NOTUSED")); + ErrorNames.insert(std::make_pair(1635, "ERROR_PATCH_PACKAGE_OPEN_FAILED")); + ErrorNames.insert(std::make_pair(1636, "ERROR_PATCH_PACKAGE_INVALID")); + ErrorNames.insert(std::make_pair(1637, "ERROR_PATCH_PACKAGE_UNSUPPORTED")); + ErrorNames.insert(std::make_pair(1638, "ERROR_PRODUCT_VERSION")); + ErrorNames.insert(std::make_pair(1639, "ERROR_INVALID_COMMAND_LINE")); + ErrorNames.insert(std::make_pair(1640, "ERROR_INSTALL_REMOTE_DISALLOWED")); + ErrorNames.insert(std::make_pair(1641, "ERROR_SUCCESS_REBOOT_INITIATED")); + ErrorNames.insert(std::make_pair(1642, "ERROR_PATCH_TARGET_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1643, "ERROR_PATCH_PACKAGE_REJECTED")); + ErrorNames.insert(std::make_pair(1644, "ERROR_INSTALL_TRANSFORM_REJECTED")); + ErrorNames.insert(std::make_pair(1645, "ERROR_INSTALL_REMOTE_PROHIBITED")); + ErrorNames.insert(std::make_pair(1646, "ERROR_PATCH_REMOVAL_UNSUPPORTED")); + ErrorNames.insert(std::make_pair(1647, "ERROR_UNKNOWN_PATCH")); + ErrorNames.insert(std::make_pair(1648, "ERROR_PATCH_NO_SEQUENCE")); + ErrorNames.insert(std::make_pair(1649, "ERROR_PATCH_REMOVAL_DISALLOWED")); + ErrorNames.insert(std::make_pair(1650, "ERROR_INVALID_PATCH_XML")); + ErrorNames.insert(std::make_pair(1651, "ERROR_PATCH_MANAGED_ADVERTISED_PRODUCT")); + ErrorNames.insert(std::make_pair(1652, "ERROR_INSTALL_SERVICE_SAFEBOOT")); + ErrorNames.insert(std::make_pair(1653, "ERROR_FAIL_FAST_EXCEPTION")); + ErrorNames.insert(std::make_pair(1784, "ERROR_INVALID_USER_BUFFER")); + ErrorNames.insert(std::make_pair(1785, "ERROR_UNRECOGNIZED_MEDIA")); + ErrorNames.insert(std::make_pair(1786, "ERROR_NO_TRUST_LSA_SECRET")); + ErrorNames.insert(std::make_pair(1787, "ERROR_NO_TRUST_SAM_ACCOUNT")); + ErrorNames.insert(std::make_pair(1788, "ERROR_TRUSTED_DOMAIN_FAILURE")); + ErrorNames.insert(std::make_pair(1789, "ERROR_TRUSTED_RELATIONSHIP_FAILURE")); + ErrorNames.insert(std::make_pair(1790, "ERROR_TRUST_FAILURE")); + ErrorNames.insert(std::make_pair(1792, "ERROR_NETLOGON_NOT_STARTED")); + ErrorNames.insert(std::make_pair(1793, "ERROR_ACCOUNT_EXPIRED")); + ErrorNames.insert(std::make_pair(1794, "ERROR_REDIRECTOR_HAS_OPEN_HANDLES")); + ErrorNames.insert(std::make_pair(1795, "ERROR_PRINTER_DRIVER_ALREADY_INSTALLED")); + ErrorNames.insert(std::make_pair(1796, "ERROR_UNKNOWN_PORT")); + ErrorNames.insert(std::make_pair(1797, "ERROR_UNKNOWN_PRINTER_DRIVER")); + ErrorNames.insert(std::make_pair(1798, "ERROR_UNKNOWN_PRINTPROCESSOR")); + ErrorNames.insert(std::make_pair(1799, "ERROR_INVALID_SEPARATOR_FILE")); + ErrorNames.insert(std::make_pair(1800, "ERROR_INVALID_PRIORITY")); + ErrorNames.insert(std::make_pair(1801, "ERROR_INVALID_PRINTER_NAME")); + ErrorNames.insert(std::make_pair(1802, "ERROR_PRINTER_ALREADY_EXISTS")); + ErrorNames.insert(std::make_pair(1803, "ERROR_INVALID_PRINTER_COMMAND")); + ErrorNames.insert(std::make_pair(1804, "ERROR_INVALID_DATATYPE")); + ErrorNames.insert(std::make_pair(1805, "ERROR_INVALID_ENVIRONMENT")); + ErrorNames.insert(std::make_pair(1807, "ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT")); + ErrorNames.insert(std::make_pair(1808, "ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT")); + ErrorNames.insert(std::make_pair(1809, "ERROR_NOLOGON_SERVER_TRUST_ACCOUNT")); + ErrorNames.insert(std::make_pair(1810, "ERROR_DOMAIN_TRUST_INCONSISTENT")); + ErrorNames.insert(std::make_pair(1811, "ERROR_SERVER_HAS_OPEN_HANDLES")); + ErrorNames.insert(std::make_pair(1812, "ERROR_RESOURCE_DATA_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1813, "ERROR_RESOURCE_TYPE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1814, "ERROR_RESOURCE_NAME_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1815, "ERROR_RESOURCE_LANG_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1816, "ERROR_NOT_ENOUGH_QUOTA")); + ErrorNames.insert(std::make_pair(1901, "ERROR_INVALID_TIME")); + ErrorNames.insert(std::make_pair(1902, "ERROR_INVALID_FORM_NAME")); + ErrorNames.insert(std::make_pair(1903, "ERROR_INVALID_FORM_SIZE")); + ErrorNames.insert(std::make_pair(1904, "ERROR_ALREADY_WAITING")); + ErrorNames.insert(std::make_pair(1905, "ERROR_PRINTER_DELETED")); + ErrorNames.insert(std::make_pair(1906, "ERROR_INVALID_PRINTER_STATE")); + ErrorNames.insert(std::make_pair(1907, "ERROR_PASSWORD_MUST_CHANGE")); + ErrorNames.insert(std::make_pair(1908, "ERROR_DOMAIN_CONTROLLER_NOT_FOUND")); + ErrorNames.insert(std::make_pair(1909, "ERROR_ACCOUNT_LOCKED_OUT")); + ErrorNames.insert(std::make_pair(1919, "ERROR_NO_SITENAME")); + ErrorNames.insert(std::make_pair(1920, "ERROR_CANT_ACCESS_FILE")); + ErrorNames.insert(std::make_pair(1921, "ERROR_CANT_RESOLVE_FILENAME")); + ErrorNames.insert(std::make_pair(1930, "ERROR_KM_DRIVER_BLOCKED")); + ErrorNames.insert(std::make_pair(1931, "ERROR_CONTEXT_EXPIRED")); + ErrorNames.insert(std::make_pair(1932, "ERROR_PER_USER_TRUST_QUOTA_EXCEEDED")); + ErrorNames.insert(std::make_pair(1933, "ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED")); + ErrorNames.insert(std::make_pair(1934, "ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED")); + ErrorNames.insert(std::make_pair(1935, "ERROR_AUTHENTICATION_FIREWALL_FAILED")); + ErrorNames.insert(std::make_pair(1936, "ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED")); + ErrorNames.insert(std::make_pair(1937, "ERROR_NTLM_BLOCKED")); + ErrorNames.insert(std::make_pair(2000, "ERROR_INVALID_PIXEL_FORMAT")); + ErrorNames.insert(std::make_pair(2001, "ERROR_BAD_DRIVER")); + ErrorNames.insert(std::make_pair(2002, "ERROR_INVALID_WINDOW_STYLE")); + ErrorNames.insert(std::make_pair(2003, "ERROR_METAFILE_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(2004, "ERROR_TRANSFORM_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(2005, "ERROR_CLIPPING_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(2010, "ERROR_INVALID_CMM")); + ErrorNames.insert(std::make_pair(2011, "ERROR_INVALID_PROFILE")); + ErrorNames.insert(std::make_pair(2012, "ERROR_TAG_NOT_FOUND")); + ErrorNames.insert(std::make_pair(2013, "ERROR_TAG_NOT_PRESENT")); + ErrorNames.insert(std::make_pair(2014, "ERROR_DUPLICATE_TAG")); + ErrorNames.insert(std::make_pair(2015, "ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE")); + ErrorNames.insert(std::make_pair(2016, "ERROR_PROFILE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(2017, "ERROR_INVALID_COLORSPACE")); + ErrorNames.insert(std::make_pair(2018, "ERROR_ICM_NOT_ENABLED")); + ErrorNames.insert(std::make_pair(2019, "ERROR_DELETING_ICM_XFORM")); + ErrorNames.insert(std::make_pair(2020, "ERROR_INVALID_TRANSFORM")); + ErrorNames.insert(std::make_pair(2021, "ERROR_COLORSPACE_MISMATCH")); + ErrorNames.insert(std::make_pair(2022, "ERROR_INVALID_COLORINDEX")); + ErrorNames.insert(std::make_pair(2023, "ERROR_PROFILE_DOES_NOT_MATCH_DEVICE")); + ErrorNames.insert(std::make_pair(2108, "ERROR_CONNECTED_OTHER_PASSWORD")); + ErrorNames.insert(std::make_pair(2109, "ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT")); + ErrorNames.insert(std::make_pair(2202, "ERROR_BAD_USERNAME")); + ErrorNames.insert(std::make_pair(2250, "ERROR_NOT_CONNECTED")); + ErrorNames.insert(std::make_pair(2401, "ERROR_OPEN_FILES")); + ErrorNames.insert(std::make_pair(2402, "ERROR_ACTIVE_CONNECTIONS")); + ErrorNames.insert(std::make_pair(2404, "ERROR_DEVICE_IN_USE")); + ErrorNames.insert(std::make_pair(3000, "ERROR_UNKNOWN_PRINT_MONITOR")); + ErrorNames.insert(std::make_pair(3001, "ERROR_PRINTER_DRIVER_IN_USE")); + ErrorNames.insert(std::make_pair(3002, "ERROR_SPOOL_FILE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(3003, "ERROR_SPL_NO_STARTDOC")); + ErrorNames.insert(std::make_pair(3004, "ERROR_SPL_NO_ADDJOB")); + ErrorNames.insert(std::make_pair(3005, "ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED")); + ErrorNames.insert(std::make_pair(3006, "ERROR_PRINT_MONITOR_ALREADY_INSTALLED")); + ErrorNames.insert(std::make_pair(3007, "ERROR_INVALID_PRINT_MONITOR")); + ErrorNames.insert(std::make_pair(3008, "ERROR_PRINT_MONITOR_IN_USE")); + ErrorNames.insert(std::make_pair(3009, "ERROR_PRINTER_HAS_JOBS_QUEUED")); + ErrorNames.insert(std::make_pair(3010, "ERROR_SUCCESS_REBOOT_REQUIRED")); + ErrorNames.insert(std::make_pair(3011, "ERROR_SUCCESS_RESTART_REQUIRED")); + ErrorNames.insert(std::make_pair(3012, "ERROR_PRINTER_NOT_FOUND")); + ErrorNames.insert(std::make_pair(3013, "ERROR_PRINTER_DRIVER_WARNED")); + ErrorNames.insert(std::make_pair(3014, "ERROR_PRINTER_DRIVER_BLOCKED")); + ErrorNames.insert(std::make_pair(3015, "ERROR_PRINTER_DRIVER_PACKAGE_IN_USE")); + ErrorNames.insert(std::make_pair(3016, "ERROR_CORE_DRIVER_PACKAGE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(3017, "ERROR_FAIL_REBOOT_REQUIRED")); + ErrorNames.insert(std::make_pair(3018, "ERROR_FAIL_REBOOT_INITIATED")); + ErrorNames.insert(std::make_pair(3019, "ERROR_PRINTER_DRIVER_DOWNLOAD_NEEDED")); + ErrorNames.insert(std::make_pair(3020, "ERROR_PRINT_JOB_RESTART_REQUIRED")); + ErrorNames.insert(std::make_pair(3950, "ERROR_IO_REISSUE_AS_CACHED")); + ErrorNames.insert(std::make_pair(4000, "ERROR_WINS_INTERNAL")); + ErrorNames.insert(std::make_pair(4001, "ERROR_CAN_NOT_DEL_LOCAL_WINS")); + ErrorNames.insert(std::make_pair(4002, "ERROR_STATIC_INIT")); + ErrorNames.insert(std::make_pair(4003, "ERROR_INC_BACKUP")); + ErrorNames.insert(std::make_pair(4004, "ERROR_FULL_BACKUP")); + ErrorNames.insert(std::make_pair(4005, "ERROR_REC_NON_EXISTENT")); + ErrorNames.insert(std::make_pair(4006, "ERROR_RPL_NOT_ALLOWED")); + ErrorNames.insert(std::make_pair(4100, "ERROR_DHCP_ADDRESS_CONFLICT")); + ErrorNames.insert(std::make_pair(4200, "ERROR_WMI_GUID_NOT_FOUND")); + ErrorNames.insert(std::make_pair(4201, "ERROR_WMI_INSTANCE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(4202, "ERROR_WMI_ITEMID_NOT_FOUND")); + ErrorNames.insert(std::make_pair(4203, "ERROR_WMI_TRY_AGAIN")); + ErrorNames.insert(std::make_pair(4204, "ERROR_WMI_DP_NOT_FOUND")); + ErrorNames.insert(std::make_pair(4205, "ERROR_WMI_UNRESOLVED_INSTANCE_REF")); + ErrorNames.insert(std::make_pair(4206, "ERROR_WMI_ALREADY_ENABLED")); + ErrorNames.insert(std::make_pair(4207, "ERROR_WMI_GUID_DISCONNECTED")); + ErrorNames.insert(std::make_pair(4208, "ERROR_WMI_SERVER_UNAVAILABLE")); + ErrorNames.insert(std::make_pair(4209, "ERROR_WMI_DP_FAILED")); + ErrorNames.insert(std::make_pair(4210, "ERROR_WMI_INVALID_MOF")); + ErrorNames.insert(std::make_pair(4211, "ERROR_WMI_INVALID_REGINFO")); + ErrorNames.insert(std::make_pair(4212, "ERROR_WMI_ALREADY_DISABLED")); + ErrorNames.insert(std::make_pair(4213, "ERROR_WMI_READ_ONLY")); + ErrorNames.insert(std::make_pair(4214, "ERROR_WMI_SET_FAILURE")); + ErrorNames.insert(std::make_pair(4300, "ERROR_INVALID_MEDIA")); + ErrorNames.insert(std::make_pair(4301, "ERROR_INVALID_LIBRARY")); + ErrorNames.insert(std::make_pair(4302, "ERROR_INVALID_MEDIA_POOL")); + ErrorNames.insert(std::make_pair(4303, "ERROR_DRIVE_MEDIA_MISMATCH")); + ErrorNames.insert(std::make_pair(4304, "ERROR_MEDIA_OFFLINE")); + ErrorNames.insert(std::make_pair(4305, "ERROR_LIBRARY_OFFLINE")); + ErrorNames.insert(std::make_pair(4306, "ERROR_EMPTY")); + ErrorNames.insert(std::make_pair(4307, "ERROR_NOT_EMPTY")); + ErrorNames.insert(std::make_pair(4308, "ERROR_MEDIA_UNAVAILABLE")); + ErrorNames.insert(std::make_pair(4309, "ERROR_RESOURCE_DISABLED")); + ErrorNames.insert(std::make_pair(4310, "ERROR_INVALID_CLEANER")); + ErrorNames.insert(std::make_pair(4311, "ERROR_UNABLE_TO_CLEAN")); + ErrorNames.insert(std::make_pair(4312, "ERROR_OBJECT_NOT_FOUND")); + ErrorNames.insert(std::make_pair(4313, "ERROR_DATABASE_FAILURE")); + ErrorNames.insert(std::make_pair(4314, "ERROR_DATABASE_FULL")); + ErrorNames.insert(std::make_pair(4315, "ERROR_MEDIA_INCOMPATIBLE")); + ErrorNames.insert(std::make_pair(4316, "ERROR_RESOURCE_NOT_PRESENT")); + ErrorNames.insert(std::make_pair(4317, "ERROR_INVALID_OPERATION")); + ErrorNames.insert(std::make_pair(4318, "ERROR_MEDIA_NOT_AVAILABLE")); + ErrorNames.insert(std::make_pair(4319, "ERROR_DEVICE_NOT_AVAILABLE")); + ErrorNames.insert(std::make_pair(4320, "ERROR_REQUEST_REFUSED")); + ErrorNames.insert(std::make_pair(4321, "ERROR_INVALID_DRIVE_OBJECT")); + ErrorNames.insert(std::make_pair(4322, "ERROR_LIBRARY_FULL")); + ErrorNames.insert(std::make_pair(4323, "ERROR_MEDIUM_NOT_ACCESSIBLE")); + ErrorNames.insert(std::make_pair(4324, "ERROR_UNABLE_TO_LOAD_MEDIUM")); + ErrorNames.insert(std::make_pair(4325, "ERROR_UNABLE_TO_INVENTORY_DRIVE")); + ErrorNames.insert(std::make_pair(4326, "ERROR_UNABLE_TO_INVENTORY_SLOT")); + ErrorNames.insert(std::make_pair(4327, "ERROR_UNABLE_TO_INVENTORY_TRANSPORT")); + ErrorNames.insert(std::make_pair(4328, "ERROR_TRANSPORT_FULL")); + ErrorNames.insert(std::make_pair(4329, "ERROR_CONTROLLING_IEPORT")); + ErrorNames.insert(std::make_pair(4330, "ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA")); + ErrorNames.insert(std::make_pair(4331, "ERROR_CLEANER_SLOT_SET")); + ErrorNames.insert(std::make_pair(4332, "ERROR_CLEANER_SLOT_NOT_SET")); + ErrorNames.insert(std::make_pair(4333, "ERROR_CLEANER_CARTRIDGE_SPENT")); + ErrorNames.insert(std::make_pair(4334, "ERROR_UNEXPECTED_OMID")); + ErrorNames.insert(std::make_pair(4335, "ERROR_CANT_DELETE_LAST_ITEM")); + ErrorNames.insert(std::make_pair(4336, "ERROR_MESSAGE_EXCEEDS_MAX_SIZE")); + ErrorNames.insert(std::make_pair(4337, "ERROR_VOLUME_CONTAINS_SYS_FILES")); + ErrorNames.insert(std::make_pair(4338, "ERROR_INDIGENOUS_TYPE")); + ErrorNames.insert(std::make_pair(4339, "ERROR_NO_SUPPORTING_DRIVES")); + ErrorNames.insert(std::make_pair(4340, "ERROR_CLEANER_CARTRIDGE_INSTALLED")); + ErrorNames.insert(std::make_pair(4341, "ERROR_IEPORT_FULL")); + ErrorNames.insert(std::make_pair(4350, "ERROR_FILE_OFFLINE")); + ErrorNames.insert(std::make_pair(4351, "ERROR_REMOTE_STORAGE_NOT_ACTIVE")); + ErrorNames.insert(std::make_pair(4352, "ERROR_REMOTE_STORAGE_MEDIA_ERROR")); + ErrorNames.insert(std::make_pair(4390, "ERROR_NOT_A_REPARSE_POINT")); + ErrorNames.insert(std::make_pair(4391, "ERROR_REPARSE_ATTRIBUTE_CONFLICT")); + ErrorNames.insert(std::make_pair(4392, "ERROR_INVALID_REPARSE_DATA")); + ErrorNames.insert(std::make_pair(4393, "ERROR_REPARSE_TAG_INVALID")); + ErrorNames.insert(std::make_pair(4394, "ERROR_REPARSE_TAG_MISMATCH")); + ErrorNames.insert(std::make_pair(4500, "ERROR_VOLUME_NOT_SIS_ENABLED")); + ErrorNames.insert(std::make_pair(5001, "ERROR_DEPENDENT_RESOURCE_EXISTS")); + ErrorNames.insert(std::make_pair(5002, "ERROR_DEPENDENCY_NOT_FOUND")); + ErrorNames.insert(std::make_pair(5003, "ERROR_DEPENDENCY_ALREADY_EXISTS")); + ErrorNames.insert(std::make_pair(5004, "ERROR_RESOURCE_NOT_ONLINE")); + ErrorNames.insert(std::make_pair(5005, "ERROR_HOST_NODE_NOT_AVAILABLE")); + ErrorNames.insert(std::make_pair(5006, "ERROR_RESOURCE_NOT_AVAILABLE")); + ErrorNames.insert(std::make_pair(5007, "ERROR_RESOURCE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(5008, "ERROR_SHUTDOWN_CLUSTER")); + ErrorNames.insert(std::make_pair(5009, "ERROR_CANT_EVICT_ACTIVE_NODE")); + ErrorNames.insert(std::make_pair(5010, "ERROR_OBJECT_ALREADY_EXISTS")); + ErrorNames.insert(std::make_pair(5011, "ERROR_OBJECT_IN_LIST")); + ErrorNames.insert(std::make_pair(5012, "ERROR_GROUP_NOT_AVAILABLE")); + ErrorNames.insert(std::make_pair(5013, "ERROR_GROUP_NOT_FOUND")); + ErrorNames.insert(std::make_pair(5014, "ERROR_GROUP_NOT_ONLINE")); + ErrorNames.insert(std::make_pair(5015, "ERROR_HOST_NODE_NOT_RESOURCE_OWNER")); + ErrorNames.insert(std::make_pair(5016, "ERROR_HOST_NODE_NOT_GROUP_OWNER")); + ErrorNames.insert(std::make_pair(5017, "ERROR_RESMON_CREATE_FAILED")); + ErrorNames.insert(std::make_pair(5018, "ERROR_RESMON_ONLINE_FAILED")); + ErrorNames.insert(std::make_pair(5019, "ERROR_RESOURCE_ONLINE")); + ErrorNames.insert(std::make_pair(5020, "ERROR_QUORUM_RESOURCE")); + ErrorNames.insert(std::make_pair(5021, "ERROR_NOT_QUORUM_CAPABLE")); + ErrorNames.insert(std::make_pair(5022, "ERROR_CLUSTER_SHUTTING_DOWN")); + ErrorNames.insert(std::make_pair(5023, "ERROR_INVALID_STATE")); + ErrorNames.insert(std::make_pair(5024, "ERROR_RESOURCE_PROPERTIES_STORED")); + ErrorNames.insert(std::make_pair(5025, "ERROR_NOT_QUORUM_CLASS")); + ErrorNames.insert(std::make_pair(5026, "ERROR_CORE_RESOURCE")); + ErrorNames.insert(std::make_pair(5027, "ERROR_QUORUM_RESOURCE_ONLINE_FAILED")); + ErrorNames.insert(std::make_pair(5028, "ERROR_QUORUMLOG_OPEN_FAILED")); + ErrorNames.insert(std::make_pair(5029, "ERROR_CLUSTERLOG_CORRUPT")); + ErrorNames.insert(std::make_pair(5030, "ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE")); + ErrorNames.insert(std::make_pair(5031, "ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE")); + ErrorNames.insert(std::make_pair(5032, "ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND")); + ErrorNames.insert(std::make_pair(5033, "ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE")); + ErrorNames.insert(std::make_pair(5034, "ERROR_QUORUM_OWNER_ALIVE")); + ErrorNames.insert(std::make_pair(5035, "ERROR_NETWORK_NOT_AVAILABLE")); + ErrorNames.insert(std::make_pair(5036, "ERROR_NODE_NOT_AVAILABLE")); + ErrorNames.insert(std::make_pair(5037, "ERROR_ALL_NODES_NOT_AVAILABLE")); + ErrorNames.insert(std::make_pair(5038, "ERROR_RESOURCE_FAILED")); + ErrorNames.insert(std::make_pair(5039, "ERROR_CLUSTER_INVALID_NODE")); + ErrorNames.insert(std::make_pair(5040, "ERROR_CLUSTER_NODE_EXISTS")); + ErrorNames.insert(std::make_pair(5041, "ERROR_CLUSTER_JOIN_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(5042, "ERROR_CLUSTER_NODE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(5043, "ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(5044, "ERROR_CLUSTER_NETWORK_EXISTS")); + ErrorNames.insert(std::make_pair(5045, "ERROR_CLUSTER_NETWORK_NOT_FOUND")); + ErrorNames.insert(std::make_pair(5046, "ERROR_CLUSTER_NETINTERFACE_EXISTS")); + ErrorNames.insert(std::make_pair(5047, "ERROR_CLUSTER_NETINTERFACE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(5048, "ERROR_CLUSTER_INVALID_REQUEST")); + ErrorNames.insert(std::make_pair(5049, "ERROR_CLUSTER_INVALID_NETWORK_PROVIDER")); + ErrorNames.insert(std::make_pair(5050, "ERROR_CLUSTER_NODE_DOWN")); + ErrorNames.insert(std::make_pair(5051, "ERROR_CLUSTER_NODE_UNREACHABLE")); + ErrorNames.insert(std::make_pair(5052, "ERROR_CLUSTER_NODE_NOT_MEMBER")); + ErrorNames.insert(std::make_pair(5053, "ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(5054, "ERROR_CLUSTER_INVALID_NETWORK")); + ErrorNames.insert(std::make_pair(5056, "ERROR_CLUSTER_NODE_UP")); + ErrorNames.insert(std::make_pair(5057, "ERROR_CLUSTER_IPADDR_IN_USE")); + ErrorNames.insert(std::make_pair(5058, "ERROR_CLUSTER_NODE_NOT_PAUSED")); + ErrorNames.insert(std::make_pair(5059, "ERROR_CLUSTER_NO_SECURITY_CONTEXT")); + ErrorNames.insert(std::make_pair(5060, "ERROR_CLUSTER_NETWORK_NOT_INTERNAL")); + ErrorNames.insert(std::make_pair(5061, "ERROR_CLUSTER_NODE_ALREADY_UP")); + ErrorNames.insert(std::make_pair(5062, "ERROR_CLUSTER_NODE_ALREADY_DOWN")); + ErrorNames.insert(std::make_pair(5063, "ERROR_CLUSTER_NETWORK_ALREADY_ONLINE")); + ErrorNames.insert(std::make_pair(5064, "ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE")); + ErrorNames.insert(std::make_pair(5065, "ERROR_CLUSTER_NODE_ALREADY_MEMBER")); + ErrorNames.insert(std::make_pair(5066, "ERROR_CLUSTER_LAST_INTERNAL_NETWORK")); + ErrorNames.insert(std::make_pair(5067, "ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS")); + ErrorNames.insert(std::make_pair(5068, "ERROR_INVALID_OPERATION_ON_QUORUM")); + ErrorNames.insert(std::make_pair(5069, "ERROR_DEPENDENCY_NOT_ALLOWED")); + ErrorNames.insert(std::make_pair(5070, "ERROR_CLUSTER_NODE_PAUSED")); + ErrorNames.insert(std::make_pair(5071, "ERROR_NODE_CANT_HOST_RESOURCE")); + ErrorNames.insert(std::make_pair(5072, "ERROR_CLUSTER_NODE_NOT_READY")); + ErrorNames.insert(std::make_pair(5073, "ERROR_CLUSTER_NODE_SHUTTING_DOWN")); + ErrorNames.insert(std::make_pair(5074, "ERROR_CLUSTER_JOIN_ABORTED")); + ErrorNames.insert(std::make_pair(5075, "ERROR_CLUSTER_INCOMPATIBLE_VERSIONS")); + ErrorNames.insert(std::make_pair(5076, "ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED")); + ErrorNames.insert(std::make_pair(5077, "ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED")); + ErrorNames.insert(std::make_pair(5078, "ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(5079, "ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(5080, "ERROR_CLUSTER_RESNAME_NOT_FOUND")); + ErrorNames.insert(std::make_pair(5081, "ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED")); + ErrorNames.insert(std::make_pair(5082, "ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST")); + ErrorNames.insert(std::make_pair(5083, "ERROR_CLUSTER_DATABASE_SEQMISMATCH")); + ErrorNames.insert(std::make_pair(5084, "ERROR_RESMON_INVALID_STATE")); + ErrorNames.insert(std::make_pair(5085, "ERROR_CLUSTER_GUM_NOT_LOCKER")); + ErrorNames.insert(std::make_pair(5086, "ERROR_QUORUM_DISK_NOT_FOUND")); + ErrorNames.insert(std::make_pair(5087, "ERROR_DATABASE_BACKUP_CORRUPT")); + ErrorNames.insert(std::make_pair(5088, "ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT")); + ErrorNames.insert(std::make_pair(5089, "ERROR_RESOURCE_PROPERTY_UNCHANGEABLE")); + ErrorNames.insert(std::make_pair(5890, "ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE")); + ErrorNames.insert(std::make_pair(5891, "ERROR_CLUSTER_QUORUMLOG_NOT_FOUND")); + ErrorNames.insert(std::make_pair(5892, "ERROR_CLUSTER_MEMBERSHIP_HALT")); + ErrorNames.insert(std::make_pair(5893, "ERROR_CLUSTER_INSTANCE_ID_MISMATCH")); + ErrorNames.insert(std::make_pair(5894, "ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP")); + ErrorNames.insert(std::make_pair(5895, "ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH")); + ErrorNames.insert(std::make_pair(5896, "ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP")); + ErrorNames.insert(std::make_pair(5897, "ERROR_CLUSTER_PARAMETER_MISMATCH")); + ErrorNames.insert(std::make_pair(5898, "ERROR_NODE_CANNOT_BE_CLUSTERED")); + ErrorNames.insert(std::make_pair(5899, "ERROR_CLUSTER_WRONG_OS_VERSION")); + ErrorNames.insert(std::make_pair(5900, "ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME")); + ErrorNames.insert(std::make_pair(5901, "ERROR_CLUSCFG_ALREADY_COMMITTED")); + ErrorNames.insert(std::make_pair(5902, "ERROR_CLUSCFG_ROLLBACK_FAILED")); + ErrorNames.insert(std::make_pair(5903, "ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT")); + ErrorNames.insert(std::make_pair(5904, "ERROR_CLUSTER_OLD_VERSION")); + ErrorNames.insert(std::make_pair(5905, "ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME")); + ErrorNames.insert(std::make_pair(5906, "ERROR_CLUSTER_NO_NET_ADAPTERS")); + ErrorNames.insert(std::make_pair(5907, "ERROR_CLUSTER_POISONED")); + ErrorNames.insert(std::make_pair(5908, "ERROR_CLUSTER_GROUP_MOVING")); + ErrorNames.insert(std::make_pair(5909, "ERROR_CLUSTER_RESOURCE_TYPE_BUSY")); + ErrorNames.insert(std::make_pair(5910, "ERROR_RESOURCE_CALL_TIMED_OUT")); + ErrorNames.insert(std::make_pair(5911, "ERROR_INVALID_CLUSTER_IPV6_ADDRESS")); + ErrorNames.insert(std::make_pair(5912, "ERROR_CLUSTER_INTERNAL_INVALID_FUNCTION")); + ErrorNames.insert(std::make_pair(5913, "ERROR_CLUSTER_PARAMETER_OUT_OF_BOUNDS")); + ErrorNames.insert(std::make_pair(5914, "ERROR_CLUSTER_PARTIAL_SEND")); + ErrorNames.insert(std::make_pair(5915, "ERROR_CLUSTER_REGISTRY_INVALID_FUNCTION")); + ErrorNames.insert(std::make_pair(5916, "ERROR_CLUSTER_INVALID_STRING_TERMINATION")); + ErrorNames.insert(std::make_pair(5917, "ERROR_CLUSTER_INVALID_STRING_FORMAT")); + ErrorNames.insert(std::make_pair(5918, "ERROR_CLUSTER_DATABASE_TRANSACTION_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(5919, "ERROR_CLUSTER_DATABASE_TRANSACTION_NOT_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(5920, "ERROR_CLUSTER_NULL_DATA")); + ErrorNames.insert(std::make_pair(5921, "ERROR_CLUSTER_PARTIAL_READ")); + ErrorNames.insert(std::make_pair(5922, "ERROR_CLUSTER_PARTIAL_WRITE")); + ErrorNames.insert(std::make_pair(5923, "ERROR_CLUSTER_CANT_DESERIALIZE_DATA")); + ErrorNames.insert(std::make_pair(5924, "ERROR_DEPENDENT_RESOURCE_PROPERTY_CONFLICT")); + ErrorNames.insert(std::make_pair(5925, "ERROR_CLUSTER_NO_QUORUM")); + ErrorNames.insert(std::make_pair(5926, "ERROR_CLUSTER_INVALID_IPV6_NETWORK")); + ErrorNames.insert(std::make_pair(5927, "ERROR_CLUSTER_INVALID_IPV6_TUNNEL_NETWORK")); + ErrorNames.insert(std::make_pair(5928, "ERROR_QUORUM_NOT_ALLOWED_IN_THIS_GROUP")); + ErrorNames.insert(std::make_pair(5929, "ERROR_DEPENDENCY_TREE_TOO_COMPLEX")); + ErrorNames.insert(std::make_pair(5930, "ERROR_EXCEPTION_IN_RESOURCE_CALL")); + ErrorNames.insert(std::make_pair(5931, "ERROR_CLUSTER_RHS_FAILED_INITIALIZATION")); + ErrorNames.insert(std::make_pair(5932, "ERROR_CLUSTER_NOT_INSTALLED")); + ErrorNames.insert(std::make_pair(5933, "ERROR_CLUSTER_RESOURCES_MUST_BE_ONLINE_ON_THE_SAME_NODE")); + ErrorNames.insert(std::make_pair(5934, "ERROR_CLUSTER_MAX_NODES_IN_CLUSTER")); + ErrorNames.insert(std::make_pair(5935, "ERROR_CLUSTER_TOO_MANY_NODES")); + ErrorNames.insert(std::make_pair(5936, "ERROR_CLUSTER_OBJECT_ALREADY_USED")); + ErrorNames.insert(std::make_pair(5937, "ERROR_NONCORE_GROUPS_FOUND")); + ErrorNames.insert(std::make_pair(5938, "ERROR_FILE_SHARE_RESOURCE_CONFLICT")); + ErrorNames.insert(std::make_pair(5939, "ERROR_CLUSTER_EVICT_INVALID_REQUEST")); + ErrorNames.insert(std::make_pair(5940, "ERROR_CLUSTER_SINGLETON_RESOURCE")); + ErrorNames.insert(std::make_pair(5941, "ERROR_CLUSTER_GROUP_SINGLETON_RESOURCE")); + ErrorNames.insert(std::make_pair(5942, "ERROR_CLUSTER_RESOURCE_PROVIDER_FAILED")); + ErrorNames.insert(std::make_pair(5943, "ERROR_CLUSTER_RESOURCE_CONFIGURATION_ERROR")); + ErrorNames.insert(std::make_pair(5944, "ERROR_CLUSTER_GROUP_BUSY")); + ErrorNames.insert(std::make_pair(5945, "ERROR_CLUSTER_NOT_SHARED_VOLUME")); + ErrorNames.insert(std::make_pair(5946, "ERROR_CLUSTER_INVALID_SECURITY_DESCRIPTOR")); + ErrorNames.insert(std::make_pair(5947, "ERROR_CLUSTER_SHARED_VOLUMES_IN_USE")); + ErrorNames.insert(std::make_pair(5948, "ERROR_CLUSTER_USE_SHARED_VOLUMES_API")); + ErrorNames.insert(std::make_pair(5949, "ERROR_CLUSTER_BACKUP_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(5950, "ERROR_NON_CSV_PATH")); + ErrorNames.insert(std::make_pair(5951, "ERROR_CSV_VOLUME_NOT_LOCAL")); + ErrorNames.insert(std::make_pair(5952, "ERROR_CLUSTER_WATCHDOG_TERMINATING")); + ErrorNames.insert(std::make_pair(6000, "ERROR_ENCRYPTION_FAILED")); + ErrorNames.insert(std::make_pair(6001, "ERROR_DECRYPTION_FAILED")); + ErrorNames.insert(std::make_pair(6002, "ERROR_FILE_ENCRYPTED")); + ErrorNames.insert(std::make_pair(6003, "ERROR_NO_RECOVERY_POLICY")); + ErrorNames.insert(std::make_pair(6004, "ERROR_NO_EFS")); + ErrorNames.insert(std::make_pair(6005, "ERROR_WRONG_EFS")); + ErrorNames.insert(std::make_pair(6006, "ERROR_NO_USER_KEYS")); + ErrorNames.insert(std::make_pair(6007, "ERROR_FILE_NOT_ENCRYPTED")); + ErrorNames.insert(std::make_pair(6008, "ERROR_NOT_EXPORT_FORMAT")); + ErrorNames.insert(std::make_pair(6009, "ERROR_FILE_READ_ONLY")); + ErrorNames.insert(std::make_pair(6010, "ERROR_DIR_EFS_DISALLOWED")); + ErrorNames.insert(std::make_pair(6011, "ERROR_EFS_SERVER_NOT_TRUSTED")); + ErrorNames.insert(std::make_pair(6012, "ERROR_BAD_RECOVERY_POLICY")); + ErrorNames.insert(std::make_pair(6013, "ERROR_EFS_ALG_BLOB_TOO_BIG")); + ErrorNames.insert(std::make_pair(6014, "ERROR_VOLUME_NOT_SUPPORT_EFS")); + ErrorNames.insert(std::make_pair(6015, "ERROR_EFS_DISABLED")); + ErrorNames.insert(std::make_pair(6016, "ERROR_EFS_VERSION_NOT_SUPPORT")); + ErrorNames.insert(std::make_pair(6017, "ERROR_CS_ENCRYPTION_INVALID_SERVER_RESPONSE")); + ErrorNames.insert(std::make_pair(6018, "ERROR_CS_ENCRYPTION_UNSUPPORTED_SERVER")); + ErrorNames.insert(std::make_pair(6019, "ERROR_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE")); + ErrorNames.insert(std::make_pair(6020, "ERROR_CS_ENCRYPTION_NEW_ENCRYPTED_FILE")); + ErrorNames.insert(std::make_pair(6021, "ERROR_CS_ENCRYPTION_FILE_NOT_CSE")); + ErrorNames.insert(std::make_pair(6022, "ERROR_ENCRYPTION_POLICY_DENIES_OPERATION")); + ErrorNames.insert(std::make_pair(6118, "ERROR_NO_BROWSER_SERVERS_FOUND")); + ErrorNames.insert(std::make_pair(6600, "ERROR_LOG_SECTOR_INVALID")); + ErrorNames.insert(std::make_pair(6601, "ERROR_LOG_SECTOR_PARITY_INVALID")); + ErrorNames.insert(std::make_pair(6602, "ERROR_LOG_SECTOR_REMAPPED")); + ErrorNames.insert(std::make_pair(6603, "ERROR_LOG_BLOCK_INCOMPLETE")); + ErrorNames.insert(std::make_pair(6604, "ERROR_LOG_INVALID_RANGE")); + ErrorNames.insert(std::make_pair(6605, "ERROR_LOG_BLOCKS_EXHAUSTED")); + ErrorNames.insert(std::make_pair(6606, "ERROR_LOG_READ_CONTEXT_INVALID")); + ErrorNames.insert(std::make_pair(6607, "ERROR_LOG_RESTART_INVALID")); + ErrorNames.insert(std::make_pair(6608, "ERROR_LOG_BLOCK_VERSION")); + ErrorNames.insert(std::make_pair(6609, "ERROR_LOG_BLOCK_INVALID")); + ErrorNames.insert(std::make_pair(6610, "ERROR_LOG_READ_MODE_INVALID")); + ErrorNames.insert(std::make_pair(6611, "ERROR_LOG_NO_RESTART")); + ErrorNames.insert(std::make_pair(6612, "ERROR_LOG_METADATA_CORRUPT")); + ErrorNames.insert(std::make_pair(6613, "ERROR_LOG_METADATA_INVALID")); + ErrorNames.insert(std::make_pair(6614, "ERROR_LOG_METADATA_INCONSISTENT")); + ErrorNames.insert(std::make_pair(6615, "ERROR_LOG_RESERVATION_INVALID")); + ErrorNames.insert(std::make_pair(6616, "ERROR_LOG_CANT_DELETE")); + ErrorNames.insert(std::make_pair(6617, "ERROR_LOG_CONTAINER_LIMIT_EXCEEDED")); + ErrorNames.insert(std::make_pair(6618, "ERROR_LOG_START_OF_LOG")); + ErrorNames.insert(std::make_pair(6619, "ERROR_LOG_POLICY_ALREADY_INSTALLED")); + ErrorNames.insert(std::make_pair(6620, "ERROR_LOG_POLICY_NOT_INSTALLED")); + ErrorNames.insert(std::make_pair(6621, "ERROR_LOG_POLICY_INVALID")); + ErrorNames.insert(std::make_pair(6622, "ERROR_LOG_POLICY_CONFLICT")); + ErrorNames.insert(std::make_pair(6623, "ERROR_LOG_PINNED_ARCHIVE_TAIL")); + ErrorNames.insert(std::make_pair(6624, "ERROR_LOG_RECORD_NONEXISTENT")); + ErrorNames.insert(std::make_pair(6625, "ERROR_LOG_RECORDS_RESERVED_INVALID")); + ErrorNames.insert(std::make_pair(6626, "ERROR_LOG_SPACE_RESERVED_INVALID")); + ErrorNames.insert(std::make_pair(6627, "ERROR_LOG_TAIL_INVALID")); + ErrorNames.insert(std::make_pair(6628, "ERROR_LOG_FULL")); + ErrorNames.insert(std::make_pair(6629, "ERROR_COULD_NOT_RESIZE_LOG")); + ErrorNames.insert(std::make_pair(6630, "ERROR_LOG_MULTIPLEXED")); + ErrorNames.insert(std::make_pair(6631, "ERROR_LOG_DEDICATED")); + ErrorNames.insert(std::make_pair(6632, "ERROR_LOG_ARCHIVE_NOT_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(6633, "ERROR_LOG_ARCHIVE_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(6634, "ERROR_LOG_EPHEMERAL")); + ErrorNames.insert(std::make_pair(6635, "ERROR_LOG_NOT_ENOUGH_CONTAINERS")); + ErrorNames.insert(std::make_pair(6636, "ERROR_LOG_CLIENT_ALREADY_REGISTERED")); + ErrorNames.insert(std::make_pair(6637, "ERROR_LOG_CLIENT_NOT_REGISTERED")); + ErrorNames.insert(std::make_pair(6638, "ERROR_LOG_FULL_HANDLER_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(6639, "ERROR_LOG_CONTAINER_READ_FAILED")); + ErrorNames.insert(std::make_pair(6640, "ERROR_LOG_CONTAINER_WRITE_FAILED")); + ErrorNames.insert(std::make_pair(6641, "ERROR_LOG_CONTAINER_OPEN_FAILED")); + ErrorNames.insert(std::make_pair(6642, "ERROR_LOG_CONTAINER_STATE_INVALID")); + ErrorNames.insert(std::make_pair(6643, "ERROR_LOG_STATE_INVALID")); + ErrorNames.insert(std::make_pair(6644, "ERROR_LOG_PINNED")); + ErrorNames.insert(std::make_pair(6645, "ERROR_LOG_METADATA_FLUSH_FAILED")); + ErrorNames.insert(std::make_pair(6646, "ERROR_LOG_INCONSISTENT_SECURITY")); + ErrorNames.insert(std::make_pair(6647, "ERROR_LOG_APPENDED_FLUSH_FAILED")); + ErrorNames.insert(std::make_pair(6648, "ERROR_LOG_PINNED_RESERVATION")); + ErrorNames.insert(std::make_pair(6700, "ERROR_INVALID_TRANSACTION")); + ErrorNames.insert(std::make_pair(6701, "ERROR_TRANSACTION_NOT_ACTIVE")); + ErrorNames.insert(std::make_pair(6702, "ERROR_TRANSACTION_REQUEST_NOT_VALID")); + ErrorNames.insert(std::make_pair(6703, "ERROR_TRANSACTION_NOT_REQUESTED")); + ErrorNames.insert(std::make_pair(6704, "ERROR_TRANSACTION_ALREADY_ABORTED")); + ErrorNames.insert(std::make_pair(6705, "ERROR_TRANSACTION_ALREADY_COMMITTED")); + ErrorNames.insert(std::make_pair(6706, "ERROR_TM_INITIALIZATION_FAILED")); + ErrorNames.insert(std::make_pair(6707, "ERROR_RESOURCEMANAGER_READ_ONLY")); + ErrorNames.insert(std::make_pair(6708, "ERROR_TRANSACTION_NOT_JOINED")); + ErrorNames.insert(std::make_pair(6709, "ERROR_TRANSACTION_SUPERIOR_EXISTS")); + ErrorNames.insert(std::make_pair(6710, "ERROR_CRM_PROTOCOL_ALREADY_EXISTS")); + ErrorNames.insert(std::make_pair(6711, "ERROR_TRANSACTION_PROPAGATION_FAILED")); + ErrorNames.insert(std::make_pair(6712, "ERROR_CRM_PROTOCOL_NOT_FOUND")); + ErrorNames.insert(std::make_pair(6713, "ERROR_TRANSACTION_INVALID_MARSHALL_BUFFER")); + ErrorNames.insert(std::make_pair(6714, "ERROR_CURRENT_TRANSACTION_NOT_VALID")); + ErrorNames.insert(std::make_pair(6715, "ERROR_TRANSACTION_NOT_FOUND")); + ErrorNames.insert(std::make_pair(6716, "ERROR_RESOURCEMANAGER_NOT_FOUND")); + ErrorNames.insert(std::make_pair(6717, "ERROR_ENLISTMENT_NOT_FOUND")); + ErrorNames.insert(std::make_pair(6718, "ERROR_TRANSACTIONMANAGER_NOT_FOUND")); + ErrorNames.insert(std::make_pair(6719, "ERROR_TRANSACTIONMANAGER_NOT_ONLINE")); + ErrorNames.insert(std::make_pair(6720, "ERROR_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION")); + ErrorNames.insert(std::make_pair(6721, "ERROR_TRANSACTION_NOT_ROOT")); + ErrorNames.insert(std::make_pair(6722, "ERROR_TRANSACTION_OBJECT_EXPIRED")); + ErrorNames.insert(std::make_pair(6723, "ERROR_TRANSACTION_RESPONSE_NOT_ENLISTED")); + ErrorNames.insert(std::make_pair(6724, "ERROR_TRANSACTION_RECORD_TOO_LONG")); + ErrorNames.insert(std::make_pair(6725, "ERROR_IMPLICIT_TRANSACTION_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(6726, "ERROR_TRANSACTION_INTEGRITY_VIOLATED")); + ErrorNames.insert(std::make_pair(6727, "ERROR_TRANSACTIONMANAGER_IDENTITY_MISMATCH")); + ErrorNames.insert(std::make_pair(6728, "ERROR_RM_CANNOT_BE_FROZEN_FOR_SNAPSHOT")); + ErrorNames.insert(std::make_pair(6729, "ERROR_TRANSACTION_MUST_WRITETHROUGH")); + ErrorNames.insert(std::make_pair(6730, "ERROR_TRANSACTION_NO_SUPERIOR")); + ErrorNames.insert(std::make_pair(6731, "ERROR_HEURISTIC_DAMAGE_POSSIBLE")); + ErrorNames.insert(std::make_pair(6800, "ERROR_TRANSACTIONAL_CONFLICT")); + ErrorNames.insert(std::make_pair(6801, "ERROR_RM_NOT_ACTIVE")); + ErrorNames.insert(std::make_pair(6802, "ERROR_RM_METADATA_CORRUPT")); + ErrorNames.insert(std::make_pair(6803, "ERROR_DIRECTORY_NOT_RM")); + ErrorNames.insert(std::make_pair(6805, "ERROR_TRANSACTIONS_UNSUPPORTED_REMOTE")); + ErrorNames.insert(std::make_pair(6806, "ERROR_LOG_RESIZE_INVALID_SIZE")); + ErrorNames.insert(std::make_pair(6807, "ERROR_OBJECT_NO_LONGER_EXISTS")); + ErrorNames.insert(std::make_pair(6808, "ERROR_STREAM_MINIVERSION_NOT_FOUND")); + ErrorNames.insert(std::make_pair(6809, "ERROR_STREAM_MINIVERSION_NOT_VALID")); + ErrorNames.insert(std::make_pair(6810, "ERROR_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION")); + ErrorNames.insert(std::make_pair(6811, "ERROR_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT")); + ErrorNames.insert(std::make_pair(6812, "ERROR_CANT_CREATE_MORE_STREAM_MINIVERSIONS")); + ErrorNames.insert(std::make_pair(6814, "ERROR_REMOTE_FILE_VERSION_MISMATCH")); + ErrorNames.insert(std::make_pair(6815, "ERROR_HANDLE_NO_LONGER_VALID")); + ErrorNames.insert(std::make_pair(6816, "ERROR_NO_TXF_METADATA")); + ErrorNames.insert(std::make_pair(6817, "ERROR_LOG_CORRUPTION_DETECTED")); + ErrorNames.insert(std::make_pair(6818, "ERROR_CANT_RECOVER_WITH_HANDLE_OPEN")); + ErrorNames.insert(std::make_pair(6819, "ERROR_RM_DISCONNECTED")); + ErrorNames.insert(std::make_pair(6820, "ERROR_ENLISTMENT_NOT_SUPERIOR")); + ErrorNames.insert(std::make_pair(6821, "ERROR_RECOVERY_NOT_NEEDED")); + ErrorNames.insert(std::make_pair(6822, "ERROR_RM_ALREADY_STARTED")); + ErrorNames.insert(std::make_pair(6823, "ERROR_FILE_IDENTITY_NOT_PERSISTENT")); + ErrorNames.insert(std::make_pair(6824, "ERROR_CANT_BREAK_TRANSACTIONAL_DEPENDENCY")); + ErrorNames.insert(std::make_pair(6825, "ERROR_CANT_CROSS_RM_BOUNDARY")); + ErrorNames.insert(std::make_pair(6826, "ERROR_TXF_DIR_NOT_EMPTY")); + ErrorNames.insert(std::make_pair(6827, "ERROR_INDOUBT_TRANSACTIONS_EXIST")); + ErrorNames.insert(std::make_pair(6828, "ERROR_TM_VOLATILE")); + ErrorNames.insert(std::make_pair(6829, "ERROR_ROLLBACK_TIMER_EXPIRED")); + ErrorNames.insert(std::make_pair(6830, "ERROR_TXF_ATTRIBUTE_CORRUPT")); + ErrorNames.insert(std::make_pair(6831, "ERROR_EFS_NOT_ALLOWED_IN_TRANSACTION")); + ErrorNames.insert(std::make_pair(6832, "ERROR_TRANSACTIONAL_OPEN_NOT_ALLOWED")); + ErrorNames.insert(std::make_pair(6833, "ERROR_LOG_GROWTH_FAILED")); + ErrorNames.insert(std::make_pair(6834, "ERROR_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE")); + ErrorNames.insert(std::make_pair(6835, "ERROR_TXF_METADATA_ALREADY_PRESENT")); + ErrorNames.insert(std::make_pair(6836, "ERROR_TRANSACTION_SCOPE_CALLBACKS_NOT_SET")); + ErrorNames.insert(std::make_pair(6837, "ERROR_TRANSACTION_REQUIRED_PROMOTION")); + ErrorNames.insert(std::make_pair(6838, "ERROR_CANNOT_EXECUTE_FILE_IN_TRANSACTION")); + ErrorNames.insert(std::make_pair(6839, "ERROR_TRANSACTIONS_NOT_FROZEN")); + ErrorNames.insert(std::make_pair(6840, "ERROR_TRANSACTION_FREEZE_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(6841, "ERROR_NOT_SNAPSHOT_VOLUME")); + ErrorNames.insert(std::make_pair(6842, "ERROR_NO_SAVEPOINT_WITH_OPEN_FILES")); + ErrorNames.insert(std::make_pair(6843, "ERROR_DATA_LOST_REPAIR")); + ErrorNames.insert(std::make_pair(6844, "ERROR_SPARSE_NOT_ALLOWED_IN_TRANSACTION")); + ErrorNames.insert(std::make_pair(6845, "ERROR_TM_IDENTITY_MISMATCH")); + ErrorNames.insert(std::make_pair(6846, "ERROR_FLOATED_SECTION")); + ErrorNames.insert(std::make_pair(6847, "ERROR_CANNOT_ACCEPT_TRANSACTED_WORK")); + ErrorNames.insert(std::make_pair(6848, "ERROR_CANNOT_ABORT_TRANSACTIONS")); + ErrorNames.insert(std::make_pair(6849, "ERROR_BAD_CLUSTERS")); + ErrorNames.insert(std::make_pair(6850, "ERROR_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION")); + ErrorNames.insert(std::make_pair(6851, "ERROR_VOLUME_DIRTY")); + ErrorNames.insert(std::make_pair(6852, "ERROR_NO_LINK_TRACKING_IN_TRANSACTION")); + ErrorNames.insert(std::make_pair(6853, "ERROR_OPERATION_NOT_SUPPORTED_IN_TRANSACTION")); + ErrorNames.insert(std::make_pair(6854, "ERROR_EXPIRED_HANDLE")); + ErrorNames.insert(std::make_pair(6855, "ERROR_TRANSACTION_NOT_ENLISTED")); + ErrorNames.insert(std::make_pair(7001, "ERROR_CTX_WINSTATION_NAME_INVALID")); + ErrorNames.insert(std::make_pair(7002, "ERROR_CTX_INVALID_PD")); + ErrorNames.insert(std::make_pair(7003, "ERROR_CTX_PD_NOT_FOUND")); + ErrorNames.insert(std::make_pair(7004, "ERROR_CTX_WD_NOT_FOUND")); + ErrorNames.insert(std::make_pair(7005, "ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY")); + ErrorNames.insert(std::make_pair(7006, "ERROR_CTX_SERVICE_NAME_COLLISION")); + ErrorNames.insert(std::make_pair(7007, "ERROR_CTX_CLOSE_PENDING")); + ErrorNames.insert(std::make_pair(7008, "ERROR_CTX_NO_OUTBUF")); + ErrorNames.insert(std::make_pair(7009, "ERROR_CTX_MODEM_INF_NOT_FOUND")); + ErrorNames.insert(std::make_pair(7010, "ERROR_CTX_INVALID_MODEMNAME")); + ErrorNames.insert(std::make_pair(7011, "ERROR_CTX_MODEM_RESPONSE_ERROR")); + ErrorNames.insert(std::make_pair(7012, "ERROR_CTX_MODEM_RESPONSE_TIMEOUT")); + ErrorNames.insert(std::make_pair(7013, "ERROR_CTX_MODEM_RESPONSE_NO_CARRIER")); + ErrorNames.insert(std::make_pair(7014, "ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE")); + ErrorNames.insert(std::make_pair(7015, "ERROR_CTX_MODEM_RESPONSE_BUSY")); + ErrorNames.insert(std::make_pair(7016, "ERROR_CTX_MODEM_RESPONSE_VOICE")); + ErrorNames.insert(std::make_pair(7017, "ERROR_CTX_TD_ERROR")); + ErrorNames.insert(std::make_pair(7022, "ERROR_CTX_WINSTATION_NOT_FOUND")); + ErrorNames.insert(std::make_pair(7023, "ERROR_CTX_WINSTATION_ALREADY_EXISTS")); + ErrorNames.insert(std::make_pair(7024, "ERROR_CTX_WINSTATION_BUSY")); + ErrorNames.insert(std::make_pair(7025, "ERROR_CTX_BAD_VIDEO_MODE")); + ErrorNames.insert(std::make_pair(7035, "ERROR_CTX_GRAPHICS_INVALID")); + ErrorNames.insert(std::make_pair(7037, "ERROR_CTX_LOGON_DISABLED")); + ErrorNames.insert(std::make_pair(7038, "ERROR_CTX_NOT_CONSOLE")); + ErrorNames.insert(std::make_pair(7040, "ERROR_CTX_CLIENT_QUERY_TIMEOUT")); + ErrorNames.insert(std::make_pair(7041, "ERROR_CTX_CONSOLE_DISCONNECT")); + ErrorNames.insert(std::make_pair(7042, "ERROR_CTX_CONSOLE_CONNECT")); + ErrorNames.insert(std::make_pair(7044, "ERROR_CTX_SHADOW_DENIED")); + ErrorNames.insert(std::make_pair(7045, "ERROR_CTX_WINSTATION_ACCESS_DENIED")); + ErrorNames.insert(std::make_pair(7049, "ERROR_CTX_INVALID_WD")); + ErrorNames.insert(std::make_pair(7050, "ERROR_CTX_SHADOW_INVALID")); + ErrorNames.insert(std::make_pair(7051, "ERROR_CTX_SHADOW_DISABLED")); + ErrorNames.insert(std::make_pair(7052, "ERROR_CTX_CLIENT_LICENSE_IN_USE")); + ErrorNames.insert(std::make_pair(7053, "ERROR_CTX_CLIENT_LICENSE_NOT_SET")); + ErrorNames.insert(std::make_pair(7054, "ERROR_CTX_LICENSE_NOT_AVAILABLE")); + ErrorNames.insert(std::make_pair(7055, "ERROR_CTX_LICENSE_CLIENT_INVALID")); + ErrorNames.insert(std::make_pair(7056, "ERROR_CTX_LICENSE_EXPIRED")); + ErrorNames.insert(std::make_pair(7057, "ERROR_CTX_SHADOW_NOT_RUNNING")); + ErrorNames.insert(std::make_pair(7058, "ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE")); + ErrorNames.insert(std::make_pair(7059, "ERROR_ACTIVATION_COUNT_EXCEEDED")); + ErrorNames.insert(std::make_pair(7060, "ERROR_CTX_WINSTATIONS_DISABLED")); + ErrorNames.insert(std::make_pair(7061, "ERROR_CTX_ENCRYPTION_LEVEL_REQUIRED")); + ErrorNames.insert(std::make_pair(7062, "ERROR_CTX_SESSION_IN_USE")); + ErrorNames.insert(std::make_pair(7063, "ERROR_CTX_NO_FORCE_LOGOFF")); + ErrorNames.insert(std::make_pair(7064, "ERROR_CTX_ACCOUNT_RESTRICTION")); + ErrorNames.insert(std::make_pair(7065, "ERROR_RDP_PROTOCOL_ERROR")); + ErrorNames.insert(std::make_pair(7066, "ERROR_CTX_CDM_CONNECT")); + ErrorNames.insert(std::make_pair(7067, "ERROR_CTX_CDM_DISCONNECT")); + ErrorNames.insert(std::make_pair(7068, "ERROR_CTX_SECURITY_LAYER_ERROR")); + ErrorNames.insert(std::make_pair(7069, "ERROR_TS_INCOMPATIBLE_SESSIONS")); + ErrorNames.insert(std::make_pair(7070, "ERROR_TS_VIDEO_SUBSYSTEM_ERROR")); + ErrorNames.insert(std::make_pair(8200, "ERROR_DS_NOT_INSTALLED")); + ErrorNames.insert(std::make_pair(8201, "ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY")); + ErrorNames.insert(std::make_pair(8202, "ERROR_DS_NO_ATTRIBUTE_OR_VALUE")); + ErrorNames.insert(std::make_pair(8203, "ERROR_DS_INVALID_ATTRIBUTE_SYNTAX")); + ErrorNames.insert(std::make_pair(8204, "ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED")); + ErrorNames.insert(std::make_pair(8205, "ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS")); + ErrorNames.insert(std::make_pair(8206, "ERROR_DS_BUSY")); + ErrorNames.insert(std::make_pair(8207, "ERROR_DS_UNAVAILABLE")); + ErrorNames.insert(std::make_pair(8208, "ERROR_DS_NO_RIDS_ALLOCATED")); + ErrorNames.insert(std::make_pair(8209, "ERROR_DS_NO_MORE_RIDS")); + ErrorNames.insert(std::make_pair(8210, "ERROR_DS_INCORRECT_ROLE_OWNER")); + ErrorNames.insert(std::make_pair(8211, "ERROR_DS_RIDMGR_INIT_ERROR")); + ErrorNames.insert(std::make_pair(8212, "ERROR_DS_OBJ_CLASS_VIOLATION")); + ErrorNames.insert(std::make_pair(8213, "ERROR_DS_CANT_ON_NON_LEAF")); + ErrorNames.insert(std::make_pair(8214, "ERROR_DS_CANT_ON_RDN")); + ErrorNames.insert(std::make_pair(8215, "ERROR_DS_CANT_MOD_OBJ_CLASS")); + ErrorNames.insert(std::make_pair(8216, "ERROR_DS_CROSS_DOM_MOVE_ERROR")); + ErrorNames.insert(std::make_pair(8217, "ERROR_DS_GC_NOT_AVAILABLE")); + ErrorNames.insert(std::make_pair(8218, "ERROR_SHARED_POLICY")); + ErrorNames.insert(std::make_pair(8219, "ERROR_POLICY_OBJECT_NOT_FOUND")); + ErrorNames.insert(std::make_pair(8220, "ERROR_POLICY_ONLY_IN_DS")); + ErrorNames.insert(std::make_pair(8221, "ERROR_PROMOTION_ACTIVE")); + ErrorNames.insert(std::make_pair(8222, "ERROR_NO_PROMOTION_ACTIVE")); + ErrorNames.insert(std::make_pair(8224, "ERROR_DS_OPERATIONS_ERROR")); + ErrorNames.insert(std::make_pair(8225, "ERROR_DS_PROTOCOL_ERROR")); + ErrorNames.insert(std::make_pair(8226, "ERROR_DS_TIMELIMIT_EXCEEDED")); + ErrorNames.insert(std::make_pair(8227, "ERROR_DS_SIZELIMIT_EXCEEDED")); + ErrorNames.insert(std::make_pair(8228, "ERROR_DS_ADMIN_LIMIT_EXCEEDED")); + ErrorNames.insert(std::make_pair(8229, "ERROR_DS_COMPARE_FALSE")); + ErrorNames.insert(std::make_pair(8230, "ERROR_DS_COMPARE_TRUE")); + ErrorNames.insert(std::make_pair(8231, "ERROR_DS_AUTH_METHOD_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(8232, "ERROR_DS_STRONG_AUTH_REQUIRED")); + ErrorNames.insert(std::make_pair(8233, "ERROR_DS_INAPPROPRIATE_AUTH")); + ErrorNames.insert(std::make_pair(8234, "ERROR_DS_AUTH_UNKNOWN")); + ErrorNames.insert(std::make_pair(8235, "ERROR_DS_REFERRAL")); + ErrorNames.insert(std::make_pair(8236, "ERROR_DS_UNAVAILABLE_CRIT_EXTENSION")); + ErrorNames.insert(std::make_pair(8237, "ERROR_DS_CONFIDENTIALITY_REQUIRED")); + ErrorNames.insert(std::make_pair(8238, "ERROR_DS_INAPPROPRIATE_MATCHING")); + ErrorNames.insert(std::make_pair(8239, "ERROR_DS_CONSTRAINT_VIOLATION")); + ErrorNames.insert(std::make_pair(8240, "ERROR_DS_NO_SUCH_OBJECT")); + ErrorNames.insert(std::make_pair(8241, "ERROR_DS_ALIAS_PROBLEM")); + ErrorNames.insert(std::make_pair(8242, "ERROR_DS_INVALID_DN_SYNTAX")); + ErrorNames.insert(std::make_pair(8243, "ERROR_DS_IS_LEAF")); + ErrorNames.insert(std::make_pair(8244, "ERROR_DS_ALIAS_DEREF_PROBLEM")); + ErrorNames.insert(std::make_pair(8245, "ERROR_DS_UNWILLING_TO_PERFORM")); + ErrorNames.insert(std::make_pair(8246, "ERROR_DS_LOOP_DETECT")); + ErrorNames.insert(std::make_pair(8247, "ERROR_DS_NAMING_VIOLATION")); + ErrorNames.insert(std::make_pair(8248, "ERROR_DS_OBJECT_RESULTS_TOO_LARGE")); + ErrorNames.insert(std::make_pair(8249, "ERROR_DS_AFFECTS_MULTIPLE_DSAS")); + ErrorNames.insert(std::make_pair(8250, "ERROR_DS_SERVER_DOWN")); + ErrorNames.insert(std::make_pair(8251, "ERROR_DS_LOCAL_ERROR")); + ErrorNames.insert(std::make_pair(8252, "ERROR_DS_ENCODING_ERROR")); + ErrorNames.insert(std::make_pair(8253, "ERROR_DS_DECODING_ERROR")); + ErrorNames.insert(std::make_pair(8254, "ERROR_DS_FILTER_UNKNOWN")); + ErrorNames.insert(std::make_pair(8255, "ERROR_DS_PARAM_ERROR")); + ErrorNames.insert(std::make_pair(8256, "ERROR_DS_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(8257, "ERROR_DS_NO_RESULTS_RETURNED")); + ErrorNames.insert(std::make_pair(8258, "ERROR_DS_CONTROL_NOT_FOUND")); + ErrorNames.insert(std::make_pair(8259, "ERROR_DS_CLIENT_LOOP")); + ErrorNames.insert(std::make_pair(8260, "ERROR_DS_REFERRAL_LIMIT_EXCEEDED")); + ErrorNames.insert(std::make_pair(8261, "ERROR_DS_SORT_CONTROL_MISSING")); + ErrorNames.insert(std::make_pair(8262, "ERROR_DS_OFFSET_RANGE_ERROR")); + ErrorNames.insert(std::make_pair(8301, "ERROR_DS_ROOT_MUST_BE_NC")); + ErrorNames.insert(std::make_pair(8302, "ERROR_DS_ADD_REPLICA_INHIBITED")); + ErrorNames.insert(std::make_pair(8303, "ERROR_DS_ATT_NOT_DEF_IN_SCHEMA")); + ErrorNames.insert(std::make_pair(8304, "ERROR_DS_MAX_OBJ_SIZE_EXCEEDED")); + ErrorNames.insert(std::make_pair(8305, "ERROR_DS_OBJ_STRING_NAME_EXISTS")); + ErrorNames.insert(std::make_pair(8306, "ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA")); + ErrorNames.insert(std::make_pair(8307, "ERROR_DS_RDN_DOESNT_MATCH_SCHEMA")); + ErrorNames.insert(std::make_pair(8308, "ERROR_DS_NO_REQUESTED_ATTS_FOUND")); + ErrorNames.insert(std::make_pair(8309, "ERROR_DS_USER_BUFFER_TO_SMALL")); + ErrorNames.insert(std::make_pair(8310, "ERROR_DS_ATT_IS_NOT_ON_OBJ")); + ErrorNames.insert(std::make_pair(8311, "ERROR_DS_ILLEGAL_MOD_OPERATION")); + ErrorNames.insert(std::make_pair(8312, "ERROR_DS_OBJ_TOO_LARGE")); + ErrorNames.insert(std::make_pair(8313, "ERROR_DS_BAD_INSTANCE_TYPE")); + ErrorNames.insert(std::make_pair(8314, "ERROR_DS_MASTERDSA_REQUIRED")); + ErrorNames.insert(std::make_pair(8315, "ERROR_DS_OBJECT_CLASS_REQUIRED")); + ErrorNames.insert(std::make_pair(8316, "ERROR_DS_MISSING_REQUIRED_ATT")); + ErrorNames.insert(std::make_pair(8317, "ERROR_DS_ATT_NOT_DEF_FOR_CLASS")); + ErrorNames.insert(std::make_pair(8318, "ERROR_DS_ATT_ALREADY_EXISTS")); + ErrorNames.insert(std::make_pair(8320, "ERROR_DS_CANT_ADD_ATT_VALUES")); + ErrorNames.insert(std::make_pair(8321, "ERROR_DS_SINGLE_VALUE_CONSTRAINT")); + ErrorNames.insert(std::make_pair(8322, "ERROR_DS_RANGE_CONSTRAINT")); + ErrorNames.insert(std::make_pair(8323, "ERROR_DS_ATT_VAL_ALREADY_EXISTS")); + ErrorNames.insert(std::make_pair(8324, "ERROR_DS_CANT_REM_MISSING_ATT")); + ErrorNames.insert(std::make_pair(8325, "ERROR_DS_CANT_REM_MISSING_ATT_VAL")); + ErrorNames.insert(std::make_pair(8326, "ERROR_DS_ROOT_CANT_BE_SUBREF")); + ErrorNames.insert(std::make_pair(8327, "ERROR_DS_NO_CHAINING")); + ErrorNames.insert(std::make_pair(8328, "ERROR_DS_NO_CHAINED_EVAL")); + ErrorNames.insert(std::make_pair(8329, "ERROR_DS_NO_PARENT_OBJECT")); + ErrorNames.insert(std::make_pair(8330, "ERROR_DS_PARENT_IS_AN_ALIAS")); + ErrorNames.insert(std::make_pair(8331, "ERROR_DS_CANT_MIX_MASTER_AND_REPS")); + ErrorNames.insert(std::make_pair(8332, "ERROR_DS_CHILDREN_EXIST")); + ErrorNames.insert(std::make_pair(8333, "ERROR_DS_OBJ_NOT_FOUND")); + ErrorNames.insert(std::make_pair(8334, "ERROR_DS_ALIASED_OBJ_MISSING")); + ErrorNames.insert(std::make_pair(8335, "ERROR_DS_BAD_NAME_SYNTAX")); + ErrorNames.insert(std::make_pair(8336, "ERROR_DS_ALIAS_POINTS_TO_ALIAS")); + ErrorNames.insert(std::make_pair(8337, "ERROR_DS_CANT_DEREF_ALIAS")); + ErrorNames.insert(std::make_pair(8338, "ERROR_DS_OUT_OF_SCOPE")); + ErrorNames.insert(std::make_pair(8339, "ERROR_DS_OBJECT_BEING_REMOVED")); + ErrorNames.insert(std::make_pair(8340, "ERROR_DS_CANT_DELETE_DSA_OBJ")); + ErrorNames.insert(std::make_pair(8341, "ERROR_DS_GENERIC_ERROR")); + ErrorNames.insert(std::make_pair(8342, "ERROR_DS_DSA_MUST_BE_INT_MASTER")); + ErrorNames.insert(std::make_pair(8343, "ERROR_DS_CLASS_NOT_DSA")); + ErrorNames.insert(std::make_pair(8344, "ERROR_DS_INSUFF_ACCESS_RIGHTS")); + ErrorNames.insert(std::make_pair(8345, "ERROR_DS_ILLEGAL_SUPERIOR")); + ErrorNames.insert(std::make_pair(8346, "ERROR_DS_ATTRIBUTE_OWNED_BY_SAM")); + ErrorNames.insert(std::make_pair(8347, "ERROR_DS_NAME_TOO_MANY_PARTS")); + ErrorNames.insert(std::make_pair(8348, "ERROR_DS_NAME_TOO_LONG")); + ErrorNames.insert(std::make_pair(8349, "ERROR_DS_NAME_VALUE_TOO_LONG")); + ErrorNames.insert(std::make_pair(8350, "ERROR_DS_NAME_UNPARSEABLE")); + ErrorNames.insert(std::make_pair(8351, "ERROR_DS_NAME_TYPE_UNKNOWN")); + ErrorNames.insert(std::make_pair(8352, "ERROR_DS_NOT_AN_OBJECT")); + ErrorNames.insert(std::make_pair(8353, "ERROR_DS_SEC_DESC_TOO_SHORT")); + ErrorNames.insert(std::make_pair(8354, "ERROR_DS_SEC_DESC_INVALID")); + ErrorNames.insert(std::make_pair(8355, "ERROR_DS_NO_DELETED_NAME")); + ErrorNames.insert(std::make_pair(8356, "ERROR_DS_SUBREF_MUST_HAVE_PARENT")); + ErrorNames.insert(std::make_pair(8357, "ERROR_DS_NCNAME_MUST_BE_NC")); + ErrorNames.insert(std::make_pair(8358, "ERROR_DS_CANT_ADD_SYSTEM_ONLY")); + ErrorNames.insert(std::make_pair(8359, "ERROR_DS_CLASS_MUST_BE_CONCRETE")); + ErrorNames.insert(std::make_pair(8360, "ERROR_DS_INVALID_DMD")); + ErrorNames.insert(std::make_pair(8361, "ERROR_DS_OBJ_GUID_EXISTS")); + ErrorNames.insert(std::make_pair(8362, "ERROR_DS_NOT_ON_BACKLINK")); + ErrorNames.insert(std::make_pair(8363, "ERROR_DS_NO_CROSSREF_FOR_NC")); + ErrorNames.insert(std::make_pair(8364, "ERROR_DS_SHUTTING_DOWN")); + ErrorNames.insert(std::make_pair(8365, "ERROR_DS_UNKNOWN_OPERATION")); + ErrorNames.insert(std::make_pair(8366, "ERROR_DS_INVALID_ROLE_OWNER")); + ErrorNames.insert(std::make_pair(8367, "ERROR_DS_COULDNT_CONTACT_FSMO")); + ErrorNames.insert(std::make_pair(8368, "ERROR_DS_CROSS_NC_DN_RENAME")); + ErrorNames.insert(std::make_pair(8369, "ERROR_DS_CANT_MOD_SYSTEM_ONLY")); + ErrorNames.insert(std::make_pair(8370, "ERROR_DS_REPLICATOR_ONLY")); + ErrorNames.insert(std::make_pair(8371, "ERROR_DS_OBJ_CLASS_NOT_DEFINED")); + ErrorNames.insert(std::make_pair(8372, "ERROR_DS_OBJ_CLASS_NOT_SUBCLASS")); + ErrorNames.insert(std::make_pair(8373, "ERROR_DS_NAME_REFERENCE_INVALID")); + ErrorNames.insert(std::make_pair(8374, "ERROR_DS_CROSS_REF_EXISTS")); + ErrorNames.insert(std::make_pair(8375, "ERROR_DS_CANT_DEL_MASTER_CROSSREF")); + ErrorNames.insert(std::make_pair(8376, "ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD")); + ErrorNames.insert(std::make_pair(8377, "ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX")); + ErrorNames.insert(std::make_pair(8378, "ERROR_DS_DUP_RDN")); + ErrorNames.insert(std::make_pair(8379, "ERROR_DS_DUP_OID")); + ErrorNames.insert(std::make_pair(8380, "ERROR_DS_DUP_MAPI_ID")); + ErrorNames.insert(std::make_pair(8381, "ERROR_DS_DUP_SCHEMA_ID_GUID")); + ErrorNames.insert(std::make_pair(8382, "ERROR_DS_DUP_LDAP_DISPLAY_NAME")); + ErrorNames.insert(std::make_pair(8383, "ERROR_DS_SEMANTIC_ATT_TEST")); + ErrorNames.insert(std::make_pair(8384, "ERROR_DS_SYNTAX_MISMATCH")); + ErrorNames.insert(std::make_pair(8385, "ERROR_DS_EXISTS_IN_MUST_HAVE")); + ErrorNames.insert(std::make_pair(8386, "ERROR_DS_EXISTS_IN_MAY_HAVE")); + ErrorNames.insert(std::make_pair(8387, "ERROR_DS_NONEXISTENT_MAY_HAVE")); + ErrorNames.insert(std::make_pair(8388, "ERROR_DS_NONEXISTENT_MUST_HAVE")); + ErrorNames.insert(std::make_pair(8389, "ERROR_DS_AUX_CLS_TEST_FAIL")); + ErrorNames.insert(std::make_pair(8390, "ERROR_DS_NONEXISTENT_POSS_SUP")); + ErrorNames.insert(std::make_pair(8391, "ERROR_DS_SUB_CLS_TEST_FAIL")); + ErrorNames.insert(std::make_pair(8392, "ERROR_DS_BAD_RDN_ATT_ID_SYNTAX")); + ErrorNames.insert(std::make_pair(8393, "ERROR_DS_EXISTS_IN_AUX_CLS")); + ErrorNames.insert(std::make_pair(8394, "ERROR_DS_EXISTS_IN_SUB_CLS")); + ErrorNames.insert(std::make_pair(8395, "ERROR_DS_EXISTS_IN_POSS_SUP")); + ErrorNames.insert(std::make_pair(8396, "ERROR_DS_RECALCSCHEMA_FAILED")); + ErrorNames.insert(std::make_pair(8397, "ERROR_DS_TREE_DELETE_NOT_FINISHED")); + ErrorNames.insert(std::make_pair(8398, "ERROR_DS_CANT_DELETE")); + ErrorNames.insert(std::make_pair(8399, "ERROR_DS_ATT_SCHEMA_REQ_ID")); + ErrorNames.insert(std::make_pair(8400, "ERROR_DS_BAD_ATT_SCHEMA_SYNTAX")); + ErrorNames.insert(std::make_pair(8401, "ERROR_DS_CANT_CACHE_ATT")); + ErrorNames.insert(std::make_pair(8402, "ERROR_DS_CANT_CACHE_CLASS")); + ErrorNames.insert(std::make_pair(8403, "ERROR_DS_CANT_REMOVE_ATT_CACHE")); + ErrorNames.insert(std::make_pair(8404, "ERROR_DS_CANT_REMOVE_CLASS_CACHE")); + ErrorNames.insert(std::make_pair(8405, "ERROR_DS_CANT_RETRIEVE_DN")); + ErrorNames.insert(std::make_pair(8406, "ERROR_DS_MISSING_SUPREF")); + ErrorNames.insert(std::make_pair(8407, "ERROR_DS_CANT_RETRIEVE_INSTANCE")); + ErrorNames.insert(std::make_pair(8408, "ERROR_DS_CODE_INCONSISTENCY")); + ErrorNames.insert(std::make_pair(8409, "ERROR_DS_DATABASE_ERROR")); + ErrorNames.insert(std::make_pair(8410, "ERROR_DS_GOVERNSID_MISSING")); + ErrorNames.insert(std::make_pair(8411, "ERROR_DS_MISSING_EXPECTED_ATT")); + ErrorNames.insert(std::make_pair(8412, "ERROR_DS_NCNAME_MISSING_CR_REF")); + ErrorNames.insert(std::make_pair(8413, "ERROR_DS_SECURITY_CHECKING_ERROR")); + ErrorNames.insert(std::make_pair(8414, "ERROR_DS_SCHEMA_NOT_LOADED")); + ErrorNames.insert(std::make_pair(8415, "ERROR_DS_SCHEMA_ALLOC_FAILED")); + ErrorNames.insert(std::make_pair(8416, "ERROR_DS_ATT_SCHEMA_REQ_SYNTAX")); + ErrorNames.insert(std::make_pair(8417, "ERROR_DS_GCVERIFY_ERROR")); + ErrorNames.insert(std::make_pair(8418, "ERROR_DS_DRA_SCHEMA_MISMATCH")); + ErrorNames.insert(std::make_pair(8419, "ERROR_DS_CANT_FIND_DSA_OBJ")); + ErrorNames.insert(std::make_pair(8420, "ERROR_DS_CANT_FIND_EXPECTED_NC")); + ErrorNames.insert(std::make_pair(8421, "ERROR_DS_CANT_FIND_NC_IN_CACHE")); + ErrorNames.insert(std::make_pair(8422, "ERROR_DS_CANT_RETRIEVE_CHILD")); + ErrorNames.insert(std::make_pair(8423, "ERROR_DS_SECURITY_ILLEGAL_MODIFY")); + ErrorNames.insert(std::make_pair(8424, "ERROR_DS_CANT_REPLACE_HIDDEN_REC")); + ErrorNames.insert(std::make_pair(8425, "ERROR_DS_BAD_HIERARCHY_FILE")); + ErrorNames.insert(std::make_pair(8426, "ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED")); + ErrorNames.insert(std::make_pair(8427, "ERROR_DS_CONFIG_PARAM_MISSING")); + ErrorNames.insert(std::make_pair(8428, "ERROR_DS_COUNTING_AB_INDICES_FAILED")); + ErrorNames.insert(std::make_pair(8429, "ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED")); + ErrorNames.insert(std::make_pair(8430, "ERROR_DS_INTERNAL_FAILURE")); + ErrorNames.insert(std::make_pair(8431, "ERROR_DS_UNKNOWN_ERROR")); + ErrorNames.insert(std::make_pair(8432, "ERROR_DS_ROOT_REQUIRES_CLASS_TOP")); + ErrorNames.insert(std::make_pair(8433, "ERROR_DS_REFUSING_FSMO_ROLES")); + ErrorNames.insert(std::make_pair(8434, "ERROR_DS_MISSING_FSMO_SETTINGS")); + ErrorNames.insert(std::make_pair(8435, "ERROR_DS_UNABLE_TO_SURRENDER_ROLES")); + ErrorNames.insert(std::make_pair(8436, "ERROR_DS_DRA_GENERIC")); + ErrorNames.insert(std::make_pair(8437, "ERROR_DS_DRA_INVALID_PARAMETER")); + ErrorNames.insert(std::make_pair(8438, "ERROR_DS_DRA_BUSY")); + ErrorNames.insert(std::make_pair(8439, "ERROR_DS_DRA_BAD_DN")); + ErrorNames.insert(std::make_pair(8440, "ERROR_DS_DRA_BAD_NC")); + ErrorNames.insert(std::make_pair(8441, "ERROR_DS_DRA_DN_EXISTS")); + ErrorNames.insert(std::make_pair(8442, "ERROR_DS_DRA_INTERNAL_ERROR")); + ErrorNames.insert(std::make_pair(8443, "ERROR_DS_DRA_INCONSISTENT_DIT")); + ErrorNames.insert(std::make_pair(8444, "ERROR_DS_DRA_CONNECTION_FAILED")); + ErrorNames.insert(std::make_pair(8445, "ERROR_DS_DRA_BAD_INSTANCE_TYPE")); + ErrorNames.insert(std::make_pair(8446, "ERROR_DS_DRA_OUT_OF_MEM")); + ErrorNames.insert(std::make_pair(8447, "ERROR_DS_DRA_MAIL_PROBLEM")); + ErrorNames.insert(std::make_pair(8448, "ERROR_DS_DRA_REF_ALREADY_EXISTS")); + ErrorNames.insert(std::make_pair(8449, "ERROR_DS_DRA_REF_NOT_FOUND")); + ErrorNames.insert(std::make_pair(8450, "ERROR_DS_DRA_OBJ_IS_REP_SOURCE")); + ErrorNames.insert(std::make_pair(8451, "ERROR_DS_DRA_DB_ERROR")); + ErrorNames.insert(std::make_pair(8452, "ERROR_DS_DRA_NO_REPLICA")); + ErrorNames.insert(std::make_pair(8453, "ERROR_DS_DRA_ACCESS_DENIED")); + ErrorNames.insert(std::make_pair(8454, "ERROR_DS_DRA_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(8455, "ERROR_DS_DRA_RPC_CANCELLED")); + ErrorNames.insert(std::make_pair(8456, "ERROR_DS_DRA_SOURCE_DISABLED")); + ErrorNames.insert(std::make_pair(8457, "ERROR_DS_DRA_SINK_DISABLED")); + ErrorNames.insert(std::make_pair(8458, "ERROR_DS_DRA_NAME_COLLISION")); + ErrorNames.insert(std::make_pair(8459, "ERROR_DS_DRA_SOURCE_REINSTALLED")); + ErrorNames.insert(std::make_pair(8460, "ERROR_DS_DRA_MISSING_PARENT")); + ErrorNames.insert(std::make_pair(8461, "ERROR_DS_DRA_PREEMPTED")); + ErrorNames.insert(std::make_pair(8462, "ERROR_DS_DRA_ABANDON_SYNC")); + ErrorNames.insert(std::make_pair(8463, "ERROR_DS_DRA_SHUTDOWN")); + ErrorNames.insert(std::make_pair(8464, "ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET")); + ErrorNames.insert(std::make_pair(8465, "ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA")); + ErrorNames.insert(std::make_pair(8466, "ERROR_DS_DRA_EXTN_CONNECTION_FAILED")); + ErrorNames.insert(std::make_pair(8467, "ERROR_DS_INSTALL_SCHEMA_MISMATCH")); + ErrorNames.insert(std::make_pair(8468, "ERROR_DS_DUP_LINK_ID")); + ErrorNames.insert(std::make_pair(8469, "ERROR_DS_NAME_ERROR_RESOLVING")); + ErrorNames.insert(std::make_pair(8470, "ERROR_DS_NAME_ERROR_NOT_FOUND")); + ErrorNames.insert(std::make_pair(8471, "ERROR_DS_NAME_ERROR_NOT_UNIQUE")); + ErrorNames.insert(std::make_pair(8472, "ERROR_DS_NAME_ERROR_NO_MAPPING")); + ErrorNames.insert(std::make_pair(8473, "ERROR_DS_NAME_ERROR_DOMAIN_ONLY")); + ErrorNames.insert(std::make_pair(8474, "ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING")); + ErrorNames.insert(std::make_pair(8475, "ERROR_DS_CONSTRUCTED_ATT_MOD")); + ErrorNames.insert(std::make_pair(8476, "ERROR_DS_WRONG_OM_OBJ_CLASS")); + ErrorNames.insert(std::make_pair(8477, "ERROR_DS_DRA_REPL_PENDING")); + ErrorNames.insert(std::make_pair(8478, "ERROR_DS_DS_REQUIRED")); + ErrorNames.insert(std::make_pair(8479, "ERROR_DS_INVALID_LDAP_DISPLAY_NAME")); + ErrorNames.insert(std::make_pair(8480, "ERROR_DS_NON_BASE_SEARCH")); + ErrorNames.insert(std::make_pair(8481, "ERROR_DS_CANT_RETRIEVE_ATTS")); + ErrorNames.insert(std::make_pair(8482, "ERROR_DS_BACKLINK_WITHOUT_LINK")); + ErrorNames.insert(std::make_pair(8483, "ERROR_DS_EPOCH_MISMATCH")); + ErrorNames.insert(std::make_pair(8484, "ERROR_DS_SRC_NAME_MISMATCH")); + ErrorNames.insert(std::make_pair(8485, "ERROR_DS_SRC_AND_DST_NC_IDENTICAL")); + ErrorNames.insert(std::make_pair(8486, "ERROR_DS_DST_NC_MISMATCH")); + ErrorNames.insert(std::make_pair(8487, "ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC")); + ErrorNames.insert(std::make_pair(8488, "ERROR_DS_SRC_GUID_MISMATCH")); + ErrorNames.insert(std::make_pair(8489, "ERROR_DS_CANT_MOVE_DELETED_OBJECT")); + ErrorNames.insert(std::make_pair(8490, "ERROR_DS_PDC_OPERATION_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(8491, "ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD")); + ErrorNames.insert(std::make_pair(8492, "ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION")); + ErrorNames.insert(std::make_pair(8493, "ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS")); + ErrorNames.insert(std::make_pair(8494, "ERROR_DS_NC_MUST_HAVE_NC_PARENT")); + ErrorNames.insert(std::make_pair(8495, "ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE")); + ErrorNames.insert(std::make_pair(8496, "ERROR_DS_DST_DOMAIN_NOT_NATIVE")); + ErrorNames.insert(std::make_pair(8497, "ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER")); + ErrorNames.insert(std::make_pair(8498, "ERROR_DS_CANT_MOVE_ACCOUNT_GROUP")); + ErrorNames.insert(std::make_pair(8499, "ERROR_DS_CANT_MOVE_RESOURCE_GROUP")); + ErrorNames.insert(std::make_pair(8500, "ERROR_DS_INVALID_SEARCH_FLAG")); + ErrorNames.insert(std::make_pair(8501, "ERROR_DS_NO_TREE_DELETE_ABOVE_NC")); + ErrorNames.insert(std::make_pair(8502, "ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE")); + ErrorNames.insert(std::make_pair(8503, "ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE")); + ErrorNames.insert(std::make_pair(8504, "ERROR_DS_SAM_INIT_FAILURE")); + ErrorNames.insert(std::make_pair(8505, "ERROR_DS_SENSITIVE_GROUP_VIOLATION")); + ErrorNames.insert(std::make_pair(8506, "ERROR_DS_CANT_MOD_PRIMARYGROUPID")); + ErrorNames.insert(std::make_pair(8507, "ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD")); + ErrorNames.insert(std::make_pair(8508, "ERROR_DS_NONSAFE_SCHEMA_CHANGE")); + ErrorNames.insert(std::make_pair(8509, "ERROR_DS_SCHEMA_UPDATE_DISALLOWED")); + ErrorNames.insert(std::make_pair(8510, "ERROR_DS_CANT_CREATE_UNDER_SCHEMA")); + ErrorNames.insert(std::make_pair(8511, "ERROR_DS_INSTALL_NO_SRC_SCH_VERSION")); + ErrorNames.insert(std::make_pair(8512, "ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE")); + ErrorNames.insert(std::make_pair(8513, "ERROR_DS_INVALID_GROUP_TYPE")); + ErrorNames.insert(std::make_pair(8514, "ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN")); + ErrorNames.insert(std::make_pair(8515, "ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN")); + ErrorNames.insert(std::make_pair(8516, "ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER")); + ErrorNames.insert(std::make_pair(8517, "ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER")); + ErrorNames.insert(std::make_pair(8518, "ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER")); + ErrorNames.insert(std::make_pair(8519, "ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER")); + ErrorNames.insert(std::make_pair(8520, "ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER")); + ErrorNames.insert(std::make_pair(8521, "ERROR_DS_HAVE_PRIMARY_MEMBERS")); + ErrorNames.insert(std::make_pair(8522, "ERROR_DS_STRING_SD_CONVERSION_FAILED")); + ErrorNames.insert(std::make_pair(8523, "ERROR_DS_NAMING_MASTER_GC")); + ErrorNames.insert(std::make_pair(8524, "ERROR_DS_DNS_LOOKUP_FAILURE")); + ErrorNames.insert(std::make_pair(8525, "ERROR_DS_COULDNT_UPDATE_SPNS")); + ErrorNames.insert(std::make_pair(8526, "ERROR_DS_CANT_RETRIEVE_SD")); + ErrorNames.insert(std::make_pair(8527, "ERROR_DS_KEY_NOT_UNIQUE")); + ErrorNames.insert(std::make_pair(8528, "ERROR_DS_WRONG_LINKED_ATT_SYNTAX")); + ErrorNames.insert(std::make_pair(8529, "ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD")); + ErrorNames.insert(std::make_pair(8530, "ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY")); + ErrorNames.insert(std::make_pair(8531, "ERROR_DS_CANT_START")); + ErrorNames.insert(std::make_pair(8532, "ERROR_DS_INIT_FAILURE")); + ErrorNames.insert(std::make_pair(8533, "ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION")); + ErrorNames.insert(std::make_pair(8534, "ERROR_DS_SOURCE_DOMAIN_IN_FOREST")); + ErrorNames.insert(std::make_pair(8535, "ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST")); + ErrorNames.insert(std::make_pair(8536, "ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED")); + ErrorNames.insert(std::make_pair(8537, "ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN")); + ErrorNames.insert(std::make_pair(8538, "ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER")); + ErrorNames.insert(std::make_pair(8539, "ERROR_DS_SRC_SID_EXISTS_IN_FOREST")); + ErrorNames.insert(std::make_pair(8540, "ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH")); + ErrorNames.insert(std::make_pair(8541, "ERROR_SAM_INIT_FAILURE")); + ErrorNames.insert(std::make_pair(8542, "ERROR_DS_DRA_SCHEMA_INFO_SHIP")); + ErrorNames.insert(std::make_pair(8543, "ERROR_DS_DRA_SCHEMA_CONFLICT")); + ErrorNames.insert(std::make_pair(8544, "ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT")); + ErrorNames.insert(std::make_pair(8545, "ERROR_DS_DRA_OBJ_NC_MISMATCH")); + ErrorNames.insert(std::make_pair(8546, "ERROR_DS_NC_STILL_HAS_DSAS")); + ErrorNames.insert(std::make_pair(8547, "ERROR_DS_GC_REQUIRED")); + ErrorNames.insert(std::make_pair(8548, "ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY")); + ErrorNames.insert(std::make_pair(8549, "ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS")); + ErrorNames.insert(std::make_pair(8550, "ERROR_DS_CANT_ADD_TO_GC")); + ErrorNames.insert(std::make_pair(8551, "ERROR_DS_NO_CHECKPOINT_WITH_PDC")); + ErrorNames.insert(std::make_pair(8552, "ERROR_DS_SOURCE_AUDITING_NOT_ENABLED")); + ErrorNames.insert(std::make_pair(8553, "ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC")); + ErrorNames.insert(std::make_pair(8554, "ERROR_DS_INVALID_NAME_FOR_SPN")); + ErrorNames.insert(std::make_pair(8555, "ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS")); + ErrorNames.insert(std::make_pair(8556, "ERROR_DS_UNICODEPWD_NOT_IN_QUOTES")); + ErrorNames.insert(std::make_pair(8557, "ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED")); + ErrorNames.insert(std::make_pair(8558, "ERROR_DS_MUST_BE_RUN_ON_DST_DC")); + ErrorNames.insert(std::make_pair(8559, "ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER")); + ErrorNames.insert(std::make_pair(8560, "ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ")); + ErrorNames.insert(std::make_pair(8561, "ERROR_DS_INIT_FAILURE_CONSOLE")); + ErrorNames.insert(std::make_pair(8562, "ERROR_DS_SAM_INIT_FAILURE_CONSOLE")); + ErrorNames.insert(std::make_pair(8563, "ERROR_DS_FOREST_VERSION_TOO_HIGH")); + ErrorNames.insert(std::make_pair(8564, "ERROR_DS_DOMAIN_VERSION_TOO_HIGH")); + ErrorNames.insert(std::make_pair(8565, "ERROR_DS_FOREST_VERSION_TOO_LOW")); + ErrorNames.insert(std::make_pair(8566, "ERROR_DS_DOMAIN_VERSION_TOO_LOW")); + ErrorNames.insert(std::make_pair(8567, "ERROR_DS_INCOMPATIBLE_VERSION")); + ErrorNames.insert(std::make_pair(8568, "ERROR_DS_LOW_DSA_VERSION")); + ErrorNames.insert(std::make_pair(8569, "ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN")); + ErrorNames.insert(std::make_pair(8570, "ERROR_DS_NOT_SUPPORTED_SORT_ORDER")); + ErrorNames.insert(std::make_pair(8571, "ERROR_DS_NAME_NOT_UNIQUE")); + ErrorNames.insert(std::make_pair(8572, "ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4")); + ErrorNames.insert(std::make_pair(8573, "ERROR_DS_OUT_OF_VERSION_STORE")); + ErrorNames.insert(std::make_pair(8574, "ERROR_DS_INCOMPATIBLE_CONTROLS_USED")); + ErrorNames.insert(std::make_pair(8575, "ERROR_DS_NO_REF_DOMAIN")); + ErrorNames.insert(std::make_pair(8576, "ERROR_DS_RESERVED_LINK_ID")); + ErrorNames.insert(std::make_pair(8577, "ERROR_DS_LINK_ID_NOT_AVAILABLE")); + ErrorNames.insert(std::make_pair(8578, "ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER")); + ErrorNames.insert(std::make_pair(8579, "ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE")); + ErrorNames.insert(std::make_pair(8580, "ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC")); + ErrorNames.insert(std::make_pair(8581, "ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG")); + ErrorNames.insert(std::make_pair(8582, "ERROR_DS_MODIFYDN_WRONG_GRANDPARENT")); + ErrorNames.insert(std::make_pair(8583, "ERROR_DS_NAME_ERROR_TRUST_REFERRAL")); + ErrorNames.insert(std::make_pair(8584, "ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER")); + ErrorNames.insert(std::make_pair(8585, "ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD")); + ErrorNames.insert(std::make_pair(8586, "ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2")); + ErrorNames.insert(std::make_pair(8587, "ERROR_DS_THREAD_LIMIT_EXCEEDED")); + ErrorNames.insert(std::make_pair(8588, "ERROR_DS_NOT_CLOSEST")); + ErrorNames.insert(std::make_pair(8589, "ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF")); + ErrorNames.insert(std::make_pair(8590, "ERROR_DS_SINGLE_USER_MODE_FAILED")); + ErrorNames.insert(std::make_pair(8591, "ERROR_DS_NTDSCRIPT_SYNTAX_ERROR")); + ErrorNames.insert(std::make_pair(8592, "ERROR_DS_NTDSCRIPT_PROCESS_ERROR")); + ErrorNames.insert(std::make_pair(8593, "ERROR_DS_DIFFERENT_REPL_EPOCHS")); + ErrorNames.insert(std::make_pair(8594, "ERROR_DS_DRS_EXTENSIONS_CHANGED")); + ErrorNames.insert(std::make_pair(8595, "ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR")); + ErrorNames.insert(std::make_pair(8596, "ERROR_DS_NO_MSDS_INTID")); + ErrorNames.insert(std::make_pair(8597, "ERROR_DS_DUP_MSDS_INTID")); + ErrorNames.insert(std::make_pair(8598, "ERROR_DS_EXISTS_IN_RDNATTID")); + ErrorNames.insert(std::make_pair(8599, "ERROR_DS_AUTHORIZATION_FAILED")); + ErrorNames.insert(std::make_pair(8600, "ERROR_DS_INVALID_SCRIPT")); + ErrorNames.insert(std::make_pair(8601, "ERROR_DS_REMOTE_CROSSREF_OP_FAILED")); + ErrorNames.insert(std::make_pair(8602, "ERROR_DS_CROSS_REF_BUSY")); + ErrorNames.insert(std::make_pair(8603, "ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN")); + ErrorNames.insert(std::make_pair(8604, "ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC")); + ErrorNames.insert(std::make_pair(8605, "ERROR_DS_DUPLICATE_ID_FOUND")); + ErrorNames.insert(std::make_pair(8606, "ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT")); + ErrorNames.insert(std::make_pair(8607, "ERROR_DS_GROUP_CONVERSION_ERROR")); + ErrorNames.insert(std::make_pair(8608, "ERROR_DS_CANT_MOVE_APP_BASIC_GROUP")); + ErrorNames.insert(std::make_pair(8609, "ERROR_DS_CANT_MOVE_APP_QUERY_GROUP")); + ErrorNames.insert(std::make_pair(8610, "ERROR_DS_ROLE_NOT_VERIFIED")); + ErrorNames.insert(std::make_pair(8611, "ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL")); + ErrorNames.insert(std::make_pair(8612, "ERROR_DS_DOMAIN_RENAME_IN_PROGRESS")); + ErrorNames.insert(std::make_pair(8613, "ERROR_DS_EXISTING_AD_CHILD_NC")); + ErrorNames.insert(std::make_pair(8614, "ERROR_DS_REPL_LIFETIME_EXCEEDED")); + ErrorNames.insert(std::make_pair(8615, "ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER")); + ErrorNames.insert(std::make_pair(8616, "ERROR_DS_LDAP_SEND_QUEUE_FULL")); + ErrorNames.insert(std::make_pair(8617, "ERROR_DS_DRA_OUT_SCHEDULE_WINDOW")); + ErrorNames.insert(std::make_pair(8618, "ERROR_DS_POLICY_NOT_KNOWN")); + ErrorNames.insert(std::make_pair(8619, "ERROR_NO_SITE_SETTINGS_OBJECT")); + ErrorNames.insert(std::make_pair(8620, "ERROR_NO_SECRETS")); + ErrorNames.insert(std::make_pair(8621, "ERROR_NO_WRITABLE_DC_FOUND")); + ErrorNames.insert(std::make_pair(8622, "ERROR_DS_NO_SERVER_OBJECT")); + ErrorNames.insert(std::make_pair(8623, "ERROR_DS_NO_NTDSA_OBJECT")); + ErrorNames.insert(std::make_pair(8624, "ERROR_DS_NON_ASQ_SEARCH")); + ErrorNames.insert(std::make_pair(8625, "ERROR_DS_AUDIT_FAILURE")); + ErrorNames.insert(std::make_pair(8626, "ERROR_DS_INVALID_SEARCH_FLAG_SUBTREE")); + ErrorNames.insert(std::make_pair(8627, "ERROR_DS_INVALID_SEARCH_FLAG_TUPLE")); + ErrorNames.insert(std::make_pair(8628, "ERROR_DS_HIERARCHY_TABLE_TOO_DEEP")); + ErrorNames.insert(std::make_pair(8629, "ERROR_DS_DRA_CORRUPT_UTD_VECTOR")); + ErrorNames.insert(std::make_pair(8630, "ERROR_DS_DRA_SECRETS_DENIED")); + ErrorNames.insert(std::make_pair(8631, "ERROR_DS_RESERVED_MAPI_ID")); + ErrorNames.insert(std::make_pair(8632, "ERROR_DS_MAPI_ID_NOT_AVAILABLE")); + ErrorNames.insert(std::make_pair(8633, "ERROR_DS_DRA_MISSING_KRBTGT_SECRET")); + ErrorNames.insert(std::make_pair(8634, "ERROR_DS_DOMAIN_NAME_EXISTS_IN_FOREST")); + ErrorNames.insert(std::make_pair(8635, "ERROR_DS_FLAT_NAME_EXISTS_IN_FOREST")); + ErrorNames.insert(std::make_pair(8636, "ERROR_INVALID_USER_PRINCIPAL_NAME")); + ErrorNames.insert(std::make_pair(8637, "ERROR_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS")); + ErrorNames.insert(std::make_pair(8638, "ERROR_DS_OID_NOT_FOUND")); + ErrorNames.insert(std::make_pair(8639, "ERROR_DS_DRA_RECYCLED_TARGET")); + ErrorNames.insert(std::make_pair(13000, "ERROR_IPSEC_QM_POLICY_EXISTS")); + ErrorNames.insert(std::make_pair(13001, "ERROR_IPSEC_QM_POLICY_NOT_FOUND")); + ErrorNames.insert(std::make_pair(13002, "ERROR_IPSEC_QM_POLICY_IN_USE")); + ErrorNames.insert(std::make_pair(13003, "ERROR_IPSEC_MM_POLICY_EXISTS")); + ErrorNames.insert(std::make_pair(13004, "ERROR_IPSEC_MM_POLICY_NOT_FOUND")); + ErrorNames.insert(std::make_pair(13005, "ERROR_IPSEC_MM_POLICY_IN_USE")); + ErrorNames.insert(std::make_pair(13006, "ERROR_IPSEC_MM_FILTER_EXISTS")); + ErrorNames.insert(std::make_pair(13007, "ERROR_IPSEC_MM_FILTER_NOT_FOUND")); + ErrorNames.insert(std::make_pair(13008, "ERROR_IPSEC_TRANSPORT_FILTER_EXISTS")); + ErrorNames.insert(std::make_pair(13009, "ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND")); + ErrorNames.insert(std::make_pair(13010, "ERROR_IPSEC_MM_AUTH_EXISTS")); + ErrorNames.insert(std::make_pair(13011, "ERROR_IPSEC_MM_AUTH_NOT_FOUND")); + ErrorNames.insert(std::make_pair(13012, "ERROR_IPSEC_MM_AUTH_IN_USE")); + ErrorNames.insert(std::make_pair(13013, "ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND")); + ErrorNames.insert(std::make_pair(13014, "ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND")); + ErrorNames.insert(std::make_pair(13015, "ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND")); + ErrorNames.insert(std::make_pair(13016, "ERROR_IPSEC_TUNNEL_FILTER_EXISTS")); + ErrorNames.insert(std::make_pair(13017, "ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND")); + ErrorNames.insert(std::make_pair(13018, "ERROR_IPSEC_MM_FILTER_PENDING_DELETION")); + ErrorNames.insert(std::make_pair(13019, "ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION")); + ErrorNames.insert(std::make_pair(13020, "ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION")); + ErrorNames.insert(std::make_pair(13021, "ERROR_IPSEC_MM_POLICY_PENDING_DELETION")); + ErrorNames.insert(std::make_pair(13022, "ERROR_IPSEC_MM_AUTH_PENDING_DELETION")); + ErrorNames.insert(std::make_pair(13023, "ERROR_IPSEC_QM_POLICY_PENDING_DELETION")); + ErrorNames.insert(std::make_pair(13800, "ERROR_IPSEC_IKE_NEG_STATUS_BEGIN")); + ErrorNames.insert(std::make_pair(13801, "ERROR_IPSEC_IKE_AUTH_FAIL")); + ErrorNames.insert(std::make_pair(13802, "ERROR_IPSEC_IKE_ATTRIB_FAIL")); + ErrorNames.insert(std::make_pair(13803, "ERROR_IPSEC_IKE_NEGOTIATION_PENDING")); + ErrorNames.insert(std::make_pair(13804, "ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR")); + ErrorNames.insert(std::make_pair(13805, "ERROR_IPSEC_IKE_TIMED_OUT")); + ErrorNames.insert(std::make_pair(13806, "ERROR_IPSEC_IKE_NO_CERT")); + ErrorNames.insert(std::make_pair(13807, "ERROR_IPSEC_IKE_SA_DELETED")); + ErrorNames.insert(std::make_pair(13808, "ERROR_IPSEC_IKE_SA_REAPED")); + ErrorNames.insert(std::make_pair(13809, "ERROR_IPSEC_IKE_MM_ACQUIRE_DROP")); + ErrorNames.insert(std::make_pair(13810, "ERROR_IPSEC_IKE_QM_ACQUIRE_DROP")); + ErrorNames.insert(std::make_pair(13811, "ERROR_IPSEC_IKE_QUEUE_DROP_MM")); + ErrorNames.insert(std::make_pair(13812, "ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM")); + ErrorNames.insert(std::make_pair(13813, "ERROR_IPSEC_IKE_DROP_NO_RESPONSE")); + ErrorNames.insert(std::make_pair(13814, "ERROR_IPSEC_IKE_MM_DELAY_DROP")); + ErrorNames.insert(std::make_pair(13815, "ERROR_IPSEC_IKE_QM_DELAY_DROP")); + ErrorNames.insert(std::make_pair(13816, "ERROR_IPSEC_IKE_ERROR")); + ErrorNames.insert(std::make_pair(13817, "ERROR_IPSEC_IKE_CRL_FAILED")); + ErrorNames.insert(std::make_pair(13818, "ERROR_IPSEC_IKE_INVALID_KEY_USAGE")); + ErrorNames.insert(std::make_pair(13819, "ERROR_IPSEC_IKE_INVALID_CERT_TYPE")); + ErrorNames.insert(std::make_pair(13820, "ERROR_IPSEC_IKE_NO_PRIVATE_KEY")); + ErrorNames.insert(std::make_pair(13821, "ERROR_IPSEC_IKE_SIMULTANEOUS_REKEY")); + ErrorNames.insert(std::make_pair(13822, "ERROR_IPSEC_IKE_DH_FAIL")); + ErrorNames.insert(std::make_pair(13823, "ERROR_IPSEC_IKE_CRITICAL_PAYLOAD_NOT_RECOGNIZED")); + ErrorNames.insert(std::make_pair(13824, "ERROR_IPSEC_IKE_INVALID_HEADER")); + ErrorNames.insert(std::make_pair(13825, "ERROR_IPSEC_IKE_NO_POLICY")); + ErrorNames.insert(std::make_pair(13826, "ERROR_IPSEC_IKE_INVALID_SIGNATURE")); + ErrorNames.insert(std::make_pair(13827, "ERROR_IPSEC_IKE_KERBEROS_ERROR")); + ErrorNames.insert(std::make_pair(13828, "ERROR_IPSEC_IKE_NO_PUBLIC_KEY")); + ErrorNames.insert(std::make_pair(13829, "ERROR_IPSEC_IKE_PROCESS_ERR")); + ErrorNames.insert(std::make_pair(13830, "ERROR_IPSEC_IKE_PROCESS_ERR_SA")); + ErrorNames.insert(std::make_pair(13831, "ERROR_IPSEC_IKE_PROCESS_ERR_PROP")); + ErrorNames.insert(std::make_pair(13832, "ERROR_IPSEC_IKE_PROCESS_ERR_TRANS")); + ErrorNames.insert(std::make_pair(13833, "ERROR_IPSEC_IKE_PROCESS_ERR_KE")); + ErrorNames.insert(std::make_pair(13834, "ERROR_IPSEC_IKE_PROCESS_ERR_ID")); + ErrorNames.insert(std::make_pair(13835, "ERROR_IPSEC_IKE_PROCESS_ERR_CERT")); + ErrorNames.insert(std::make_pair(13836, "ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ")); + ErrorNames.insert(std::make_pair(13837, "ERROR_IPSEC_IKE_PROCESS_ERR_HASH")); + ErrorNames.insert(std::make_pair(13838, "ERROR_IPSEC_IKE_PROCESS_ERR_SIG")); + ErrorNames.insert(std::make_pair(13839, "ERROR_IPSEC_IKE_PROCESS_ERR_NONCE")); + ErrorNames.insert(std::make_pair(13840, "ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY")); + ErrorNames.insert(std::make_pair(13841, "ERROR_IPSEC_IKE_PROCESS_ERR_DELETE")); + ErrorNames.insert(std::make_pair(13842, "ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR")); + ErrorNames.insert(std::make_pair(13843, "ERROR_IPSEC_IKE_INVALID_PAYLOAD")); + ErrorNames.insert(std::make_pair(13844, "ERROR_IPSEC_IKE_LOAD_SOFT_SA")); + ErrorNames.insert(std::make_pair(13845, "ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN")); + ErrorNames.insert(std::make_pair(13846, "ERROR_IPSEC_IKE_INVALID_COOKIE")); + ErrorNames.insert(std::make_pair(13847, "ERROR_IPSEC_IKE_NO_PEER_CERT")); + ErrorNames.insert(std::make_pair(13848, "ERROR_IPSEC_IKE_PEER_CRL_FAILED")); + ErrorNames.insert(std::make_pair(13849, "ERROR_IPSEC_IKE_POLICY_CHANGE")); + ErrorNames.insert(std::make_pair(13850, "ERROR_IPSEC_IKE_NO_MM_POLICY")); + ErrorNames.insert(std::make_pair(13851, "ERROR_IPSEC_IKE_NOTCBPRIV")); + ErrorNames.insert(std::make_pair(13852, "ERROR_IPSEC_IKE_SECLOADFAIL")); + ErrorNames.insert(std::make_pair(13853, "ERROR_IPSEC_IKE_FAILSSPINIT")); + ErrorNames.insert(std::make_pair(13854, "ERROR_IPSEC_IKE_FAILQUERYSSP")); + ErrorNames.insert(std::make_pair(13855, "ERROR_IPSEC_IKE_SRVACQFAIL")); + ErrorNames.insert(std::make_pair(13856, "ERROR_IPSEC_IKE_SRVQUERYCRED")); + ErrorNames.insert(std::make_pair(13857, "ERROR_IPSEC_IKE_GETSPIFAIL")); + ErrorNames.insert(std::make_pair(13858, "ERROR_IPSEC_IKE_INVALID_FILTER")); + ErrorNames.insert(std::make_pair(13859, "ERROR_IPSEC_IKE_OUT_OF_MEMORY")); + ErrorNames.insert(std::make_pair(13860, "ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED")); + ErrorNames.insert(std::make_pair(13861, "ERROR_IPSEC_IKE_INVALID_POLICY")); + ErrorNames.insert(std::make_pair(13862, "ERROR_IPSEC_IKE_UNKNOWN_DOI")); + ErrorNames.insert(std::make_pair(13863, "ERROR_IPSEC_IKE_INVALID_SITUATION")); + ErrorNames.insert(std::make_pair(13864, "ERROR_IPSEC_IKE_DH_FAILURE")); + ErrorNames.insert(std::make_pair(13865, "ERROR_IPSEC_IKE_INVALID_GROUP")); + ErrorNames.insert(std::make_pair(13866, "ERROR_IPSEC_IKE_ENCRYPT")); + ErrorNames.insert(std::make_pair(13867, "ERROR_IPSEC_IKE_DECRYPT")); + ErrorNames.insert(std::make_pair(13868, "ERROR_IPSEC_IKE_POLICY_MATCH")); + ErrorNames.insert(std::make_pair(13869, "ERROR_IPSEC_IKE_UNSUPPORTED_ID")); + ErrorNames.insert(std::make_pair(13870, "ERROR_IPSEC_IKE_INVALID_HASH")); + ErrorNames.insert(std::make_pair(13871, "ERROR_IPSEC_IKE_INVALID_HASH_ALG")); + ErrorNames.insert(std::make_pair(13872, "ERROR_IPSEC_IKE_INVALID_HASH_SIZE")); + ErrorNames.insert(std::make_pair(13873, "ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG")); + ErrorNames.insert(std::make_pair(13874, "ERROR_IPSEC_IKE_INVALID_AUTH_ALG")); + ErrorNames.insert(std::make_pair(13875, "ERROR_IPSEC_IKE_INVALID_SIG")); + ErrorNames.insert(std::make_pair(13876, "ERROR_IPSEC_IKE_LOAD_FAILED")); + ErrorNames.insert(std::make_pair(13877, "ERROR_IPSEC_IKE_RPC_DELETE")); + ErrorNames.insert(std::make_pair(13878, "ERROR_IPSEC_IKE_BENIGN_REINIT")); + ErrorNames.insert(std::make_pair(13879, "ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY")); + ErrorNames.insert(std::make_pair(13880, "ERROR_IPSEC_IKE_INVALID_MAJOR_VERSION")); + ErrorNames.insert(std::make_pair(13881, "ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN")); + ErrorNames.insert(std::make_pair(13882, "ERROR_IPSEC_IKE_MM_LIMIT")); + ErrorNames.insert(std::make_pair(13883, "ERROR_IPSEC_IKE_NEGOTIATION_DISABLED")); + ErrorNames.insert(std::make_pair(13884, "ERROR_IPSEC_IKE_QM_LIMIT")); + ErrorNames.insert(std::make_pair(13885, "ERROR_IPSEC_IKE_MM_EXPIRED")); + ErrorNames.insert(std::make_pair(13886, "ERROR_IPSEC_IKE_PEER_MM_ASSUMED_INVALID")); + ErrorNames.insert(std::make_pair(13887, "ERROR_IPSEC_IKE_CERT_CHAIN_POLICY_MISMATCH")); + ErrorNames.insert(std::make_pair(13888, "ERROR_IPSEC_IKE_UNEXPECTED_MESSAGE_ID")); + ErrorNames.insert(std::make_pair(13889, "ERROR_IPSEC_IKE_INVALID_AUTH_PAYLOAD")); + ErrorNames.insert(std::make_pair(13890, "ERROR_IPSEC_IKE_DOS_COOKIE_SENT")); + ErrorNames.insert(std::make_pair(13891, "ERROR_IPSEC_IKE_SHUTTING_DOWN")); + ErrorNames.insert(std::make_pair(13892, "ERROR_IPSEC_IKE_CGA_AUTH_FAILED")); + ErrorNames.insert(std::make_pair(13893, "ERROR_IPSEC_IKE_PROCESS_ERR_NATOA")); + ErrorNames.insert(std::make_pair(13894, "ERROR_IPSEC_IKE_INVALID_MM_FOR_QM")); + ErrorNames.insert(std::make_pair(13895, "ERROR_IPSEC_IKE_QM_EXPIRED")); + ErrorNames.insert(std::make_pair(13896, "ERROR_IPSEC_IKE_TOO_MANY_FILTERS")); + ErrorNames.insert(std::make_pair(13897, "ERROR_IPSEC_IKE_NEG_STATUS_END")); + ErrorNames.insert(std::make_pair(13898, "ERROR_IPSEC_IKE_KILL_DUMMY_NAP_TUNNEL")); + ErrorNames.insert(std::make_pair(13899, "ERROR_IPSEC_IKE_INNER_IP_ASSIGNMENT_FAILURE")); + ErrorNames.insert(std::make_pair(13900, "ERROR_IPSEC_IKE_REQUIRE_CP_PAYLOAD_MISSING")); + ErrorNames.insert(std::make_pair(13901, "ERROR_IPSEC_KEY_MODULE_IMPERSONATION_NEGOTIATION_PENDING")); + ErrorNames.insert(std::make_pair(13902, "ERROR_IPSEC_IKE_COEXISTENCE_SUPPRESS")); + ErrorNames.insert(std::make_pair(13903, "ERROR_IPSEC_IKE_RATELIMIT_DROP")); + ErrorNames.insert(std::make_pair(13904, "ERROR_IPSEC_IKE_PEER_DOESNT_SUPPORT_MOBIKE")); + ErrorNames.insert(std::make_pair(13905, "ERROR_IPSEC_IKE_AUTHORIZATION_FAILURE")); + ErrorNames.insert(std::make_pair(13906, "ERROR_IPSEC_IKE_STRONG_CRED_AUTHORIZATION_FAILURE")); + ErrorNames.insert(std::make_pair(13907, "ERROR_IPSEC_IKE_AUTHORIZATION_FAILURE_WITH_OPTIONAL_RETRY")); + ErrorNames.insert(std::make_pair(13908, "ERROR_IPSEC_IKE_STRONG_CRED_AUTHORIZATION_AND_CERTMAP_FAILURE")); + ErrorNames.insert(std::make_pair(13909, "ERROR_IPSEC_IKE_NEG_STATUS_EXTENDED_END")); + ErrorNames.insert(std::make_pair(13910, "ERROR_IPSEC_BAD_SPI")); + ErrorNames.insert(std::make_pair(13911, "ERROR_IPSEC_SA_LIFETIME_EXPIRED")); + ErrorNames.insert(std::make_pair(13912, "ERROR_IPSEC_WRONG_SA")); + ErrorNames.insert(std::make_pair(13913, "ERROR_IPSEC_REPLAY_CHECK_FAILED")); + ErrorNames.insert(std::make_pair(13914, "ERROR_IPSEC_INVALID_PACKET")); + ErrorNames.insert(std::make_pair(13915, "ERROR_IPSEC_INTEGRITY_CHECK_FAILED")); + ErrorNames.insert(std::make_pair(13916, "ERROR_IPSEC_CLEAR_TEXT_DROP")); + ErrorNames.insert(std::make_pair(13917, "ERROR_IPSEC_AUTH_FIREWALL_DROP")); + ErrorNames.insert(std::make_pair(13918, "ERROR_IPSEC_THROTTLE_DROP")); + ErrorNames.insert(std::make_pair(13925, "ERROR_IPSEC_DOSP_BLOCK")); + ErrorNames.insert(std::make_pair(13926, "ERROR_IPSEC_DOSP_RECEIVED_MULTICAST")); + ErrorNames.insert(std::make_pair(13927, "ERROR_IPSEC_DOSP_INVALID_PACKET")); + ErrorNames.insert(std::make_pair(13928, "ERROR_IPSEC_DOSP_STATE_LOOKUP_FAILED")); + ErrorNames.insert(std::make_pair(13929, "ERROR_IPSEC_DOSP_MAX_ENTRIES")); + ErrorNames.insert(std::make_pair(13930, "ERROR_IPSEC_DOSP_KEYMOD_NOT_ALLOWED")); + ErrorNames.insert(std::make_pair(13931, "ERROR_IPSEC_DOSP_NOT_INSTALLED")); + ErrorNames.insert(std::make_pair(13932, "ERROR_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES")); + ErrorNames.insert(std::make_pair(14000, "ERROR_SXS_SECTION_NOT_FOUND")); + ErrorNames.insert(std::make_pair(14001, "ERROR_SXS_CANT_GEN_ACTCTX")); + ErrorNames.insert(std::make_pair(14002, "ERROR_SXS_INVALID_ACTCTXDATA_FORMAT")); + ErrorNames.insert(std::make_pair(14003, "ERROR_SXS_ASSEMBLY_NOT_FOUND")); + ErrorNames.insert(std::make_pair(14004, "ERROR_SXS_MANIFEST_FORMAT_ERROR")); + ErrorNames.insert(std::make_pair(14005, "ERROR_SXS_MANIFEST_PARSE_ERROR")); + ErrorNames.insert(std::make_pair(14006, "ERROR_SXS_ACTIVATION_CONTEXT_DISABLED")); + ErrorNames.insert(std::make_pair(14007, "ERROR_SXS_KEY_NOT_FOUND")); + ErrorNames.insert(std::make_pair(14008, "ERROR_SXS_VERSION_CONFLICT")); + ErrorNames.insert(std::make_pair(14009, "ERROR_SXS_WRONG_SECTION_TYPE")); + ErrorNames.insert(std::make_pair(14010, "ERROR_SXS_THREAD_QUERIES_DISABLED")); + ErrorNames.insert(std::make_pair(14011, "ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET")); + ErrorNames.insert(std::make_pair(14012, "ERROR_SXS_UNKNOWN_ENCODING_GROUP")); + ErrorNames.insert(std::make_pair(14013, "ERROR_SXS_UNKNOWN_ENCODING")); + ErrorNames.insert(std::make_pair(14014, "ERROR_SXS_INVALID_XML_NAMESPACE_URI")); + ErrorNames.insert(std::make_pair(14015, "ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED")); + ErrorNames.insert(std::make_pair(14016, "ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED")); + ErrorNames.insert(std::make_pair(14017, "ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE")); + ErrorNames.insert(std::make_pair(14018, "ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE")); + ErrorNames.insert(std::make_pair(14019, "ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE")); + ErrorNames.insert(std::make_pair(14020, "ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT")); + ErrorNames.insert(std::make_pair(14021, "ERROR_SXS_DUPLICATE_DLL_NAME")); + ErrorNames.insert(std::make_pair(14022, "ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME")); + ErrorNames.insert(std::make_pair(14023, "ERROR_SXS_DUPLICATE_CLSID")); + ErrorNames.insert(std::make_pair(14024, "ERROR_SXS_DUPLICATE_IID")); + ErrorNames.insert(std::make_pair(14025, "ERROR_SXS_DUPLICATE_TLBID")); + ErrorNames.insert(std::make_pair(14026, "ERROR_SXS_DUPLICATE_PROGID")); + ErrorNames.insert(std::make_pair(14027, "ERROR_SXS_DUPLICATE_ASSEMBLY_NAME")); + ErrorNames.insert(std::make_pair(14028, "ERROR_SXS_FILE_HASH_MISMATCH")); + ErrorNames.insert(std::make_pair(14029, "ERROR_SXS_POLICY_PARSE_ERROR")); + ErrorNames.insert(std::make_pair(14030, "ERROR_SXS_XML_E_MISSINGQUOTE")); + ErrorNames.insert(std::make_pair(14031, "ERROR_SXS_XML_E_COMMENTSYNTAX")); + ErrorNames.insert(std::make_pair(14032, "ERROR_SXS_XML_E_BADSTARTNAMECHAR")); + ErrorNames.insert(std::make_pair(14033, "ERROR_SXS_XML_E_BADNAMECHAR")); + ErrorNames.insert(std::make_pair(14034, "ERROR_SXS_XML_E_BADCHARINSTRING")); + ErrorNames.insert(std::make_pair(14035, "ERROR_SXS_XML_E_XMLDECLSYNTAX")); + ErrorNames.insert(std::make_pair(14036, "ERROR_SXS_XML_E_BADCHARDATA")); + ErrorNames.insert(std::make_pair(14037, "ERROR_SXS_XML_E_MISSINGWHITESPACE")); + ErrorNames.insert(std::make_pair(14038, "ERROR_SXS_XML_E_EXPECTINGTAGEND")); + ErrorNames.insert(std::make_pair(14039, "ERROR_SXS_XML_E_MISSINGSEMICOLON")); + ErrorNames.insert(std::make_pair(14040, "ERROR_SXS_XML_E_UNBALANCEDPAREN")); + ErrorNames.insert(std::make_pair(14041, "ERROR_SXS_XML_E_INTERNALERROR")); + ErrorNames.insert(std::make_pair(14042, "ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE")); + ErrorNames.insert(std::make_pair(14043, "ERROR_SXS_XML_E_INCOMPLETE_ENCODING")); + ErrorNames.insert(std::make_pair(14044, "ERROR_SXS_XML_E_MISSING_PAREN")); + ErrorNames.insert(std::make_pair(14045, "ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE")); + ErrorNames.insert(std::make_pair(14046, "ERROR_SXS_XML_E_MULTIPLE_COLONS")); + ErrorNames.insert(std::make_pair(14047, "ERROR_SXS_XML_E_INVALID_DECIMAL")); + ErrorNames.insert(std::make_pair(14048, "ERROR_SXS_XML_E_INVALID_HEXIDECIMAL")); + ErrorNames.insert(std::make_pair(14049, "ERROR_SXS_XML_E_INVALID_UNICODE")); + ErrorNames.insert(std::make_pair(14050, "ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK")); + ErrorNames.insert(std::make_pair(14051, "ERROR_SXS_XML_E_UNEXPECTEDENDTAG")); + ErrorNames.insert(std::make_pair(14052, "ERROR_SXS_XML_E_UNCLOSEDTAG")); + ErrorNames.insert(std::make_pair(14053, "ERROR_SXS_XML_E_DUPLICATEATTRIBUTE")); + ErrorNames.insert(std::make_pair(14054, "ERROR_SXS_XML_E_MULTIPLEROOTS")); + ErrorNames.insert(std::make_pair(14055, "ERROR_SXS_XML_E_INVALIDATROOTLEVEL")); + ErrorNames.insert(std::make_pair(14056, "ERROR_SXS_XML_E_BADXMLDECL")); + ErrorNames.insert(std::make_pair(14057, "ERROR_SXS_XML_E_MISSINGROOT")); + ErrorNames.insert(std::make_pair(14058, "ERROR_SXS_XML_E_UNEXPECTEDEOF")); + ErrorNames.insert(std::make_pair(14059, "ERROR_SXS_XML_E_BADPEREFINSUBSET")); + ErrorNames.insert(std::make_pair(14060, "ERROR_SXS_XML_E_UNCLOSEDSTARTTAG")); + ErrorNames.insert(std::make_pair(14061, "ERROR_SXS_XML_E_UNCLOSEDENDTAG")); + ErrorNames.insert(std::make_pair(14062, "ERROR_SXS_XML_E_UNCLOSEDSTRING")); + ErrorNames.insert(std::make_pair(14063, "ERROR_SXS_XML_E_UNCLOSEDCOMMENT")); + ErrorNames.insert(std::make_pair(14064, "ERROR_SXS_XML_E_UNCLOSEDDECL")); + ErrorNames.insert(std::make_pair(14065, "ERROR_SXS_XML_E_UNCLOSEDCDATA")); + ErrorNames.insert(std::make_pair(14066, "ERROR_SXS_XML_E_RESERVEDNAMESPACE")); + ErrorNames.insert(std::make_pair(14067, "ERROR_SXS_XML_E_INVALIDENCODING")); + ErrorNames.insert(std::make_pair(14068, "ERROR_SXS_XML_E_INVALIDSWITCH")); + ErrorNames.insert(std::make_pair(14069, "ERROR_SXS_XML_E_BADXMLCASE")); + ErrorNames.insert(std::make_pair(14070, "ERROR_SXS_XML_E_INVALID_STANDALONE")); + ErrorNames.insert(std::make_pair(14071, "ERROR_SXS_XML_E_UNEXPECTED_STANDALONE")); + ErrorNames.insert(std::make_pair(14072, "ERROR_SXS_XML_E_INVALID_VERSION")); + ErrorNames.insert(std::make_pair(14073, "ERROR_SXS_XML_E_MISSINGEQUALS")); + ErrorNames.insert(std::make_pair(14074, "ERROR_SXS_PROTECTION_RECOVERY_FAILED")); + ErrorNames.insert(std::make_pair(14075, "ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT")); + ErrorNames.insert(std::make_pair(14076, "ERROR_SXS_PROTECTION_CATALOG_NOT_VALID")); + ErrorNames.insert(std::make_pair(14077, "ERROR_SXS_UNTRANSLATABLE_HRESULT")); + ErrorNames.insert(std::make_pair(14078, "ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING")); + ErrorNames.insert(std::make_pair(14079, "ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE")); + ErrorNames.insert(std::make_pair(14080, "ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME")); + ErrorNames.insert(std::make_pair(14081, "ERROR_SXS_ASSEMBLY_MISSING")); + ErrorNames.insert(std::make_pair(14082, "ERROR_SXS_CORRUPT_ACTIVATION_STACK")); + ErrorNames.insert(std::make_pair(14083, "ERROR_SXS_CORRUPTION")); + ErrorNames.insert(std::make_pair(14084, "ERROR_SXS_EARLY_DEACTIVATION")); + ErrorNames.insert(std::make_pair(14085, "ERROR_SXS_INVALID_DEACTIVATION")); + ErrorNames.insert(std::make_pair(14086, "ERROR_SXS_MULTIPLE_DEACTIVATION")); + ErrorNames.insert(std::make_pair(14087, "ERROR_SXS_PROCESS_TERMINATION_REQUESTED")); + ErrorNames.insert(std::make_pair(14088, "ERROR_SXS_RELEASE_ACTIVATION_CONTEXT")); + ErrorNames.insert(std::make_pair(14089, "ERROR_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY")); + ErrorNames.insert(std::make_pair(14090, "ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE")); + ErrorNames.insert(std::make_pair(14091, "ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME")); + ErrorNames.insert(std::make_pair(14092, "ERROR_SXS_IDENTITY_DUPLICATE_ATTRIBUTE")); + ErrorNames.insert(std::make_pair(14093, "ERROR_SXS_IDENTITY_PARSE_ERROR")); + ErrorNames.insert(std::make_pair(14094, "ERROR_MALFORMED_SUBSTITUTION_STRING")); + ErrorNames.insert(std::make_pair(14095, "ERROR_SXS_INCORRECT_PUBLIC_KEY_TOKEN")); + ErrorNames.insert(std::make_pair(14096, "ERROR_UNMAPPED_SUBSTITUTION_STRING")); + ErrorNames.insert(std::make_pair(14097, "ERROR_SXS_ASSEMBLY_NOT_LOCKED")); + ErrorNames.insert(std::make_pair(14098, "ERROR_SXS_COMPONENT_STORE_CORRUPT")); + ErrorNames.insert(std::make_pair(14099, "ERROR_ADVANCED_INSTALLER_FAILED")); + ErrorNames.insert(std::make_pair(14100, "ERROR_XML_ENCODING_MISMATCH")); + ErrorNames.insert(std::make_pair(14101, "ERROR_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT")); + ErrorNames.insert(std::make_pair(14102, "ERROR_SXS_IDENTITIES_DIFFERENT")); + ErrorNames.insert(std::make_pair(14103, "ERROR_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT")); + ErrorNames.insert(std::make_pair(14104, "ERROR_SXS_FILE_NOT_PART_OF_ASSEMBLY")); + ErrorNames.insert(std::make_pair(14105, "ERROR_SXS_MANIFEST_TOO_BIG")); + ErrorNames.insert(std::make_pair(14106, "ERROR_SXS_SETTING_NOT_REGISTERED")); + ErrorNames.insert(std::make_pair(14107, "ERROR_SXS_TRANSACTION_CLOSURE_INCOMPLETE")); + ErrorNames.insert(std::make_pair(14108, "ERROR_SMI_PRIMITIVE_INSTALLER_FAILED")); + ErrorNames.insert(std::make_pair(14109, "ERROR_GENERIC_COMMAND_FAILED")); + ErrorNames.insert(std::make_pair(14110, "ERROR_SXS_FILE_HASH_MISSING")); + ErrorNames.insert(std::make_pair(15000, "ERROR_EVT_INVALID_CHANNEL_PATH")); + ErrorNames.insert(std::make_pair(15001, "ERROR_EVT_INVALID_QUERY")); + ErrorNames.insert(std::make_pair(15002, "ERROR_EVT_PUBLISHER_METADATA_NOT_FOUND")); + ErrorNames.insert(std::make_pair(15003, "ERROR_EVT_EVENT_TEMPLATE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(15004, "ERROR_EVT_INVALID_PUBLISHER_NAME")); + ErrorNames.insert(std::make_pair(15005, "ERROR_EVT_INVALID_EVENT_DATA")); + ErrorNames.insert(std::make_pair(15007, "ERROR_EVT_CHANNEL_NOT_FOUND")); + ErrorNames.insert(std::make_pair(15008, "ERROR_EVT_MALFORMED_XML_TEXT")); + ErrorNames.insert(std::make_pair(15009, "ERROR_EVT_SUBSCRIPTION_TO_DIRECT_CHANNEL")); + ErrorNames.insert(std::make_pair(15010, "ERROR_EVT_CONFIGURATION_ERROR")); + ErrorNames.insert(std::make_pair(15011, "ERROR_EVT_QUERY_RESULT_STALE")); + ErrorNames.insert(std::make_pair(15012, "ERROR_EVT_QUERY_RESULT_INVALID_POSITION")); + ErrorNames.insert(std::make_pair(15013, "ERROR_EVT_NON_VALIDATING_MSXML")); + ErrorNames.insert(std::make_pair(15014, "ERROR_EVT_FILTER_ALREADYSCOPED")); + ErrorNames.insert(std::make_pair(15015, "ERROR_EVT_FILTER_NOTELTSET")); + ErrorNames.insert(std::make_pair(15016, "ERROR_EVT_FILTER_INVARG")); + ErrorNames.insert(std::make_pair(15017, "ERROR_EVT_FILTER_INVTEST")); + ErrorNames.insert(std::make_pair(15018, "ERROR_EVT_FILTER_INVTYPE")); + ErrorNames.insert(std::make_pair(15019, "ERROR_EVT_FILTER_PARSEERR")); + ErrorNames.insert(std::make_pair(15020, "ERROR_EVT_FILTER_UNSUPPORTEDOP")); + ErrorNames.insert(std::make_pair(15021, "ERROR_EVT_FILTER_UNEXPECTEDTOKEN")); + ErrorNames.insert(std::make_pair(15022, "ERROR_EVT_INVALID_OPERATION_OVER_ENABLED_DIRECT_CHANNEL")); + ErrorNames.insert(std::make_pair(15023, "ERROR_EVT_INVALID_CHANNEL_PROPERTY_VALUE")); + ErrorNames.insert(std::make_pair(15024, "ERROR_EVT_INVALID_PUBLISHER_PROPERTY_VALUE")); + ErrorNames.insert(std::make_pair(15025, "ERROR_EVT_CHANNEL_CANNOT_ACTIVATE")); + ErrorNames.insert(std::make_pair(15026, "ERROR_EVT_FILTER_TOO_COMPLEX")); + ErrorNames.insert(std::make_pair(15027, "ERROR_EVT_MESSAGE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(15028, "ERROR_EVT_MESSAGE_ID_NOT_FOUND")); + ErrorNames.insert(std::make_pair(15029, "ERROR_EVT_UNRESOLVED_VALUE_INSERT")); + ErrorNames.insert(std::make_pair(15030, "ERROR_EVT_UNRESOLVED_PARAMETER_INSERT")); + ErrorNames.insert(std::make_pair(15031, "ERROR_EVT_MAX_INSERTS_REACHED")); + ErrorNames.insert(std::make_pair(15032, "ERROR_EVT_EVENT_DEFINITION_NOT_FOUND")); + ErrorNames.insert(std::make_pair(15033, "ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(15034, "ERROR_EVT_VERSION_TOO_OLD")); + ErrorNames.insert(std::make_pair(15035, "ERROR_EVT_VERSION_TOO_NEW")); + ErrorNames.insert(std::make_pair(15036, "ERROR_EVT_CANNOT_OPEN_CHANNEL_OF_QUERY")); + ErrorNames.insert(std::make_pair(15037, "ERROR_EVT_PUBLISHER_DISABLED")); + ErrorNames.insert(std::make_pair(15038, "ERROR_EVT_FILTER_OUT_OF_RANGE")); + ErrorNames.insert(std::make_pair(15080, "ERROR_EC_SUBSCRIPTION_CANNOT_ACTIVATE")); + ErrorNames.insert(std::make_pair(15081, "ERROR_EC_LOG_DISABLED")); + ErrorNames.insert(std::make_pair(15082, "ERROR_EC_CIRCULAR_FORWARDING")); + ErrorNames.insert(std::make_pair(15083, "ERROR_EC_CREDSTORE_FULL")); + ErrorNames.insert(std::make_pair(15084, "ERROR_EC_CRED_NOT_FOUND")); + ErrorNames.insert(std::make_pair(15085, "ERROR_EC_NO_ACTIVE_CHANNEL")); + ErrorNames.insert(std::make_pair(15100, "ERROR_MUI_FILE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(15101, "ERROR_MUI_INVALID_FILE")); + ErrorNames.insert(std::make_pair(15102, "ERROR_MUI_INVALID_RC_CONFIG")); + ErrorNames.insert(std::make_pair(15103, "ERROR_MUI_INVALID_LOCALE_NAME")); + ErrorNames.insert(std::make_pair(15104, "ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME")); + ErrorNames.insert(std::make_pair(15105, "ERROR_MUI_FILE_NOT_LOADED")); + ErrorNames.insert(std::make_pair(15106, "ERROR_RESOURCE_ENUM_USER_STOP")); + ErrorNames.insert(std::make_pair(15107, "ERROR_MUI_INTLSETTINGS_UILANG_NOT_INSTALLED")); + ErrorNames.insert(std::make_pair(15108, "ERROR_MUI_INTLSETTINGS_INVALID_LOCALE_NAME")); + ErrorNames.insert(std::make_pair(15200, "ERROR_MCA_INVALID_CAPABILITIES_STRING")); + ErrorNames.insert(std::make_pair(15201, "ERROR_MCA_INVALID_VCP_VERSION")); + ErrorNames.insert(std::make_pair(15202, "ERROR_MCA_MONITOR_VIOLATES_MCCS_SPECIFICATION")); + ErrorNames.insert(std::make_pair(15203, "ERROR_MCA_MCCS_VERSION_MISMATCH")); + ErrorNames.insert(std::make_pair(15204, "ERROR_MCA_UNSUPPORTED_MCCS_VERSION")); + ErrorNames.insert(std::make_pair(15205, "ERROR_MCA_INTERNAL_ERROR")); + ErrorNames.insert(std::make_pair(15206, "ERROR_MCA_INVALID_TECHNOLOGY_TYPE_RETURNED")); + ErrorNames.insert(std::make_pair(15207, "ERROR_MCA_UNSUPPORTED_COLOR_TEMPERATURE")); + ErrorNames.insert(std::make_pair(15250, "ERROR_AMBIGUOUS_SYSTEM_DEVICE")); + ErrorNames.insert(std::make_pair(15299, "ERROR_SYSTEM_DEVICE_NOT_FOUND")); + ErrorNames.insert(std::make_pair(15300, "ERROR_HASH_NOT_SUPPORTED")); + ErrorNames.insert(std::make_pair(15301, "ERROR_HASH_NOT_PRESENT")); +} + +const char* ErrorCodeToName(unsigned int ErrorCode) +{ + if(ErrorNames.find(ErrorCode) == ErrorNames.end()) + return nullptr; + + return ErrorNames[ErrorCode]; } \ No newline at end of file diff --git a/src/dbg/error.h b/src/dbg/error.h index 9f0ac834..65985171 100644 --- a/src/dbg/error.h +++ b/src/dbg/error.h @@ -1,4 +1,4 @@ -#pragma once - -void ErrorCodeInit(); +#pragma once + +void ErrorCodeInit(); const char* ErrorCodeToName(unsigned int ErrorCode); \ No newline at end of file diff --git a/src/dbg/exception.cpp b/src/dbg/exception.cpp index aaa8bac8..a8a39c62 100644 --- a/src/dbg/exception.cpp +++ b/src/dbg/exception.cpp @@ -1,83 +1,83 @@ -#include -#include "exception.h" - -std::unordered_map ExceptionNames; - -void ExceptionCodeInit() -{ - ExceptionNames.clear(); - ExceptionNames.insert(std::make_pair(0x000006BA, "RPC_S_SERVER_UNAVAILABLE")); - ExceptionNames.insert(std::make_pair(0x0000071A, "RPC_S_CALL_CANCELLED")); - ExceptionNames.insert(std::make_pair(0x04242420, "CLRDBG_NOTIFICATION_EXCEPTION_CODE")); - ExceptionNames.insert(std::make_pair(0x40000005, "STATUS_SEGMENT_NOTIFICATION")); - ExceptionNames.insert(std::make_pair(0x4000001C, "STATUS_WX86_UNSIMULATE")); - ExceptionNames.insert(std::make_pair(0x4000001D, "STATUS_WX86_CONTINUE")); - ExceptionNames.insert(std::make_pair(0x4000001E, "STATUS_WX86_SINGLE_STEP")); - ExceptionNames.insert(std::make_pair(0x4000001F, "STATUS_WX86_BREAKPOINT")); - ExceptionNames.insert(std::make_pair(0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE")); - ExceptionNames.insert(std::make_pair(0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE")); - ExceptionNames.insert(std::make_pair(0x40000022, "STATUS_WX86_EXCEPTION_CHAIN")); - ExceptionNames.insert(std::make_pair(0x40000028, "STATUS_WX86_CREATEWX86TIB")); - ExceptionNames.insert(std::make_pair(0x40010003, "DBG_TERMINATE_THREAD")); - ExceptionNames.insert(std::make_pair(0x40010004, "DBG_TERMINATE_PROCESS")); - ExceptionNames.insert(std::make_pair(0x40010005, "DBG_CONTROL_C")); - ExceptionNames.insert(std::make_pair(0x40010006, "DBG_PRINTEXCEPTION_C")); - ExceptionNames.insert(std::make_pair(0x40010007, "DBG_RIPEXCEPTION")); - ExceptionNames.insert(std::make_pair(0x40010008, "DBG_CONTROL_BREAK")); - ExceptionNames.insert(std::make_pair(0x40010009, "DBG_COMMAND_EXCEPTION")); - ExceptionNames.insert(std::make_pair(0x4001000A, "DBG_PRINTEXCEPTION_WIDE_C")); - ExceptionNames.insert(std::make_pair(0x406D1388, "MS_VC_EXCEPTION")); - ExceptionNames.insert(std::make_pair(0x80000001, "EXCEPTION_GUARD_PAGE")); - ExceptionNames.insert(std::make_pair(0x80000002, "EXCEPTION_DATATYPE_MISALIGNMENT")); - ExceptionNames.insert(std::make_pair(0x80000003, "EXCEPTION_BREAKPOINT")); - ExceptionNames.insert(std::make_pair(0x80000004, "EXCEPTION_SINGLE_STEP")); - ExceptionNames.insert(std::make_pair(0x80000026, "STATUS_LONGJUMP")); - ExceptionNames.insert(std::make_pair(0x80000029, "STATUS_UNWIND_CONSOLIDATE")); - ExceptionNames.insert(std::make_pair(0x80010001, "DBG_EXCEPTION_NOT_HANDLED")); - ExceptionNames.insert(std::make_pair(0xC0000005, "EXCEPTION_ACCESS_VIOLATION")); - ExceptionNames.insert(std::make_pair(0xC0000006, "EXCEPTION_IN_PAGE_ERROR")); - ExceptionNames.insert(std::make_pair(0xC0000008, "EXCEPTION_INVALID_HANDLE")); - ExceptionNames.insert(std::make_pair(0xC000000D, "STATUS_INVALID_PARAMETER")); - ExceptionNames.insert(std::make_pair(0xC0000017, "STATUS_NO_MEMORY")); - ExceptionNames.insert(std::make_pair(0xC000001D, "EXCEPTION_ILLEGAL_INSTRUCTION")); - ExceptionNames.insert(std::make_pair(0xC0000025, "EXCEPTION_NONCONTINUABLE_EXCEPTION")); - ExceptionNames.insert(std::make_pair(0xC0000026, "EXCEPTION_INVALID_DISPOSITION")); - ExceptionNames.insert(std::make_pair(0xC000008C, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED")); - ExceptionNames.insert(std::make_pair(0xC000008D, "EXCEPTION_FLT_DENORMAL_OPERAND")); - ExceptionNames.insert(std::make_pair(0xC000008E, "EXCEPTION_FLT_DIVIDE_BY_ZERO")); - ExceptionNames.insert(std::make_pair(0xC000008F, "EXCEPTION_FLT_INEXACT_RESULT")); - ExceptionNames.insert(std::make_pair(0xC0000090, "EXCEPTION_FLT_INVALID_OPERATION")); - ExceptionNames.insert(std::make_pair(0xC0000091, "EXCEPTION_FLT_OVERFLOW")); - ExceptionNames.insert(std::make_pair(0xC0000092, "EXCEPTION_FLT_STACK_CHECK")); - ExceptionNames.insert(std::make_pair(0xC0000093, "EXCEPTION_FLT_UNDERFLOW")); - ExceptionNames.insert(std::make_pair(0xC0000094, "EXCEPTION_INT_DIVIDE_BY_ZERO")); - ExceptionNames.insert(std::make_pair(0xC0000095, "EXCEPTION_INT_OVERFLOW")); - ExceptionNames.insert(std::make_pair(0xC0000096, "EXCEPTION_PRIV_INSTRUCTION")); - ExceptionNames.insert(std::make_pair(0xC00000FD, "EXCEPTION_STACK_OVERFLOW")); - ExceptionNames.insert(std::make_pair(0xC0000135, "STATUS_DLL_NOT_FOUND")); - ExceptionNames.insert(std::make_pair(0xC0000138, "STATUS_ORDINAL_NOT_FOUND")); - ExceptionNames.insert(std::make_pair(0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND")); - ExceptionNames.insert(std::make_pair(0xC000013A, "STATUS_CONTROL_C_EXIT")); - ExceptionNames.insert(std::make_pair(0xC0000142, "STATUS_DLL_INIT_FAILED")); - ExceptionNames.insert(std::make_pair(0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT")); - ExceptionNames.insert(std::make_pair(0xC0000194, "EXCEPTION_POSSIBLE_DEADLOCK")); - ExceptionNames.insert(std::make_pair(0xC00001A5, "STATUS_INVALID_EXCEPTION_HANDLER")); - ExceptionNames.insert(std::make_pair(0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS")); - ExceptionNames.insert(std::make_pair(0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS")); - ExceptionNames.insert(std::make_pair(0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR")); - ExceptionNames.insert(std::make_pair(0xC00002C9, "STATUS_REG_NAT_CONSUMPTION")); - ExceptionNames.insert(std::make_pair(0xC0000409, "STATUS_STACK_BUFFER_OVERRUN")); - ExceptionNames.insert(std::make_pair(0xC0000417, "STATUS_INVALID_CRUNTIME_PARAMETER")); - ExceptionNames.insert(std::make_pair(0xC000041D, "STATUS_USER_CALLBACK")); - ExceptionNames.insert(std::make_pair(0xC0000420, "STATUS_ASSERTION_FAILURE")); - ExceptionNames.insert(std::make_pair(0xE0434352, "CLR_EXCEPTION")); - ExceptionNames.insert(std::make_pair(0xE06D7363, "CPP_EH_EXCEPTION")); -} - -const char* ExceptionCodeToName(unsigned int ExceptionCode) -{ - if(ExceptionNames.find(ExceptionCode) == ExceptionNames.end()) - return nullptr; - - return ExceptionNames[ExceptionCode]; +#include +#include "exception.h" + +std::unordered_map ExceptionNames; + +void ExceptionCodeInit() +{ + ExceptionNames.clear(); + ExceptionNames.insert(std::make_pair(0x000006BA, "RPC_S_SERVER_UNAVAILABLE")); + ExceptionNames.insert(std::make_pair(0x0000071A, "RPC_S_CALL_CANCELLED")); + ExceptionNames.insert(std::make_pair(0x04242420, "CLRDBG_NOTIFICATION_EXCEPTION_CODE")); + ExceptionNames.insert(std::make_pair(0x40000005, "STATUS_SEGMENT_NOTIFICATION")); + ExceptionNames.insert(std::make_pair(0x4000001C, "STATUS_WX86_UNSIMULATE")); + ExceptionNames.insert(std::make_pair(0x4000001D, "STATUS_WX86_CONTINUE")); + ExceptionNames.insert(std::make_pair(0x4000001E, "STATUS_WX86_SINGLE_STEP")); + ExceptionNames.insert(std::make_pair(0x4000001F, "STATUS_WX86_BREAKPOINT")); + ExceptionNames.insert(std::make_pair(0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE")); + ExceptionNames.insert(std::make_pair(0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE")); + ExceptionNames.insert(std::make_pair(0x40000022, "STATUS_WX86_EXCEPTION_CHAIN")); + ExceptionNames.insert(std::make_pair(0x40000028, "STATUS_WX86_CREATEWX86TIB")); + ExceptionNames.insert(std::make_pair(0x40010003, "DBG_TERMINATE_THREAD")); + ExceptionNames.insert(std::make_pair(0x40010004, "DBG_TERMINATE_PROCESS")); + ExceptionNames.insert(std::make_pair(0x40010005, "DBG_CONTROL_C")); + ExceptionNames.insert(std::make_pair(0x40010006, "DBG_PRINTEXCEPTION_C")); + ExceptionNames.insert(std::make_pair(0x40010007, "DBG_RIPEXCEPTION")); + ExceptionNames.insert(std::make_pair(0x40010008, "DBG_CONTROL_BREAK")); + ExceptionNames.insert(std::make_pair(0x40010009, "DBG_COMMAND_EXCEPTION")); + ExceptionNames.insert(std::make_pair(0x4001000A, "DBG_PRINTEXCEPTION_WIDE_C")); + ExceptionNames.insert(std::make_pair(0x406D1388, "MS_VC_EXCEPTION")); + ExceptionNames.insert(std::make_pair(0x80000001, "EXCEPTION_GUARD_PAGE")); + ExceptionNames.insert(std::make_pair(0x80000002, "EXCEPTION_DATATYPE_MISALIGNMENT")); + ExceptionNames.insert(std::make_pair(0x80000003, "EXCEPTION_BREAKPOINT")); + ExceptionNames.insert(std::make_pair(0x80000004, "EXCEPTION_SINGLE_STEP")); + ExceptionNames.insert(std::make_pair(0x80000026, "STATUS_LONGJUMP")); + ExceptionNames.insert(std::make_pair(0x80000029, "STATUS_UNWIND_CONSOLIDATE")); + ExceptionNames.insert(std::make_pair(0x80010001, "DBG_EXCEPTION_NOT_HANDLED")); + ExceptionNames.insert(std::make_pair(0xC0000005, "EXCEPTION_ACCESS_VIOLATION")); + ExceptionNames.insert(std::make_pair(0xC0000006, "EXCEPTION_IN_PAGE_ERROR")); + ExceptionNames.insert(std::make_pair(0xC0000008, "EXCEPTION_INVALID_HANDLE")); + ExceptionNames.insert(std::make_pair(0xC000000D, "STATUS_INVALID_PARAMETER")); + ExceptionNames.insert(std::make_pair(0xC0000017, "STATUS_NO_MEMORY")); + ExceptionNames.insert(std::make_pair(0xC000001D, "EXCEPTION_ILLEGAL_INSTRUCTION")); + ExceptionNames.insert(std::make_pair(0xC0000025, "EXCEPTION_NONCONTINUABLE_EXCEPTION")); + ExceptionNames.insert(std::make_pair(0xC0000026, "EXCEPTION_INVALID_DISPOSITION")); + ExceptionNames.insert(std::make_pair(0xC000008C, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED")); + ExceptionNames.insert(std::make_pair(0xC000008D, "EXCEPTION_FLT_DENORMAL_OPERAND")); + ExceptionNames.insert(std::make_pair(0xC000008E, "EXCEPTION_FLT_DIVIDE_BY_ZERO")); + ExceptionNames.insert(std::make_pair(0xC000008F, "EXCEPTION_FLT_INEXACT_RESULT")); + ExceptionNames.insert(std::make_pair(0xC0000090, "EXCEPTION_FLT_INVALID_OPERATION")); + ExceptionNames.insert(std::make_pair(0xC0000091, "EXCEPTION_FLT_OVERFLOW")); + ExceptionNames.insert(std::make_pair(0xC0000092, "EXCEPTION_FLT_STACK_CHECK")); + ExceptionNames.insert(std::make_pair(0xC0000093, "EXCEPTION_FLT_UNDERFLOW")); + ExceptionNames.insert(std::make_pair(0xC0000094, "EXCEPTION_INT_DIVIDE_BY_ZERO")); + ExceptionNames.insert(std::make_pair(0xC0000095, "EXCEPTION_INT_OVERFLOW")); + ExceptionNames.insert(std::make_pair(0xC0000096, "EXCEPTION_PRIV_INSTRUCTION")); + ExceptionNames.insert(std::make_pair(0xC00000FD, "EXCEPTION_STACK_OVERFLOW")); + ExceptionNames.insert(std::make_pair(0xC0000135, "STATUS_DLL_NOT_FOUND")); + ExceptionNames.insert(std::make_pair(0xC0000138, "STATUS_ORDINAL_NOT_FOUND")); + ExceptionNames.insert(std::make_pair(0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND")); + ExceptionNames.insert(std::make_pair(0xC000013A, "STATUS_CONTROL_C_EXIT")); + ExceptionNames.insert(std::make_pair(0xC0000142, "STATUS_DLL_INIT_FAILED")); + ExceptionNames.insert(std::make_pair(0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT")); + ExceptionNames.insert(std::make_pair(0xC0000194, "EXCEPTION_POSSIBLE_DEADLOCK")); + ExceptionNames.insert(std::make_pair(0xC00001A5, "STATUS_INVALID_EXCEPTION_HANDLER")); + ExceptionNames.insert(std::make_pair(0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS")); + ExceptionNames.insert(std::make_pair(0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS")); + ExceptionNames.insert(std::make_pair(0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR")); + ExceptionNames.insert(std::make_pair(0xC00002C9, "STATUS_REG_NAT_CONSUMPTION")); + ExceptionNames.insert(std::make_pair(0xC0000409, "STATUS_STACK_BUFFER_OVERRUN")); + ExceptionNames.insert(std::make_pair(0xC0000417, "STATUS_INVALID_CRUNTIME_PARAMETER")); + ExceptionNames.insert(std::make_pair(0xC000041D, "STATUS_USER_CALLBACK")); + ExceptionNames.insert(std::make_pair(0xC0000420, "STATUS_ASSERTION_FAILURE")); + ExceptionNames.insert(std::make_pair(0xE0434352, "CLR_EXCEPTION")); + ExceptionNames.insert(std::make_pair(0xE06D7363, "CPP_EH_EXCEPTION")); +} + +const char* ExceptionCodeToName(unsigned int ExceptionCode) +{ + if(ExceptionNames.find(ExceptionCode) == ExceptionNames.end()) + return nullptr; + + return ExceptionNames[ExceptionCode]; } \ No newline at end of file diff --git a/src/dbg/exception.h b/src/dbg/exception.h index c63340eb..39043631 100644 --- a/src/dbg/exception.h +++ b/src/dbg/exception.h @@ -1,4 +1,4 @@ -#pragma once - -void ExceptionCodeInit(); +#pragma once + +void ExceptionCodeInit(); const char* ExceptionCodeToName(unsigned int ExceptionCode); \ No newline at end of file diff --git a/src/dbg/exceptiondirectoryanalysis.cpp b/src/dbg/exceptiondirectoryanalysis.cpp index cda058e0..fbd00f9e 100644 --- a/src/dbg/exceptiondirectoryanalysis.cpp +++ b/src/dbg/exceptiondirectoryanalysis.cpp @@ -1,106 +1,106 @@ -#include "exceptiondirectoryanalysis.h" -#include "module.h" -#include "TitanEngine/TitanEngine.h" -#include "memory.h" -#include "console.h" -#include "function.h" - -ExceptionDirectoryAnalysis::ExceptionDirectoryAnalysis(duint base, duint size) : Analysis(base, size) -{ - _functionInfoData = nullptr; -#ifdef _WIN64 - // This will only be valid if the address range is within a loaded module - _moduleBase = ModBaseFromAddr(base); - - if(_moduleBase != 0) - { - char modulePath[MAX_PATH]; - memset(modulePath, 0, sizeof(modulePath)); - - ModPathFromAddr(_moduleBase, modulePath, ARRAYSIZE(modulePath)); - - HANDLE fileHandle; - DWORD fileSize; - HANDLE fileMapHandle; - ULONG_PTR fileMapVa; - if(StaticFileLoadW( - StringUtils::Utf8ToUtf16(modulePath).c_str(), - UE_ACCESS_READ, - false, - &fileHandle, - &fileSize, - &fileMapHandle, - &fileMapVa)) - { - // Find a pointer to IMAGE_DIRECTORY_ENTRY_EXCEPTION for later use - ULONG_PTR virtualOffset = GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALOFFSET); - _functionInfoSize = (duint)GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALSIZE); - - // Unload the file - StaticFileUnloadW(nullptr, false, fileHandle, fileSize, fileMapHandle, fileMapVa); - - // Get a copy of the function table - if(virtualOffset) - { - // Read the table into a buffer - _functionInfoData = emalloc(_functionInfoSize); - - if(_functionInfoData) - MemRead(virtualOffset + _moduleBase, _functionInfoData, _functionInfoSize); - } - } - } -#endif //_WIN64 -} - -ExceptionDirectoryAnalysis::~ExceptionDirectoryAnalysis() -{ - if(_functionInfoData) - efree(_functionInfoData); -} - -void ExceptionDirectoryAnalysis::Analyse() -{ -#ifdef _WIN64 - EnumerateFunctionRuntimeEntries64([&](PRUNTIME_FUNCTION Function) - { - const duint funcAddr = _moduleBase + Function->BeginAddress; - const duint funcEnd = _moduleBase + Function->EndAddress; - - // If within limits... - if(funcAddr >= _base && funcAddr < _base + _size) - _functions.push_back({ funcAddr, funcEnd }); - - return true; - }); - dprintf("%u functions discovered!\n", _functions.size()); -#else //x32 - dprintf("This kind of analysis doesn't work on x32 executables...\n"); -#endif // _WIN64 -} - -void ExceptionDirectoryAnalysis::SetMarkers() -{ - FunctionDelRange(_base, _base + _size); - for(const auto & function : _functions) - FunctionAdd(function.first, function.second, false); -} - -#ifdef _WIN64 -void ExceptionDirectoryAnalysis::EnumerateFunctionRuntimeEntries64(std::function Callback) -{ - if(!_functionInfoData) - return; - - // Get the table pointer and size - auto functionTable = (PRUNTIME_FUNCTION)_functionInfoData; - duint totalCount = (_functionInfoSize / sizeof(RUNTIME_FUNCTION)); - - // Enumerate each entry - for(duint i = 0; i < totalCount; i++) - { - if(!Callback(&functionTable[i])) - break; - } -} +#include "exceptiondirectoryanalysis.h" +#include "module.h" +#include "TitanEngine/TitanEngine.h" +#include "memory.h" +#include "console.h" +#include "function.h" + +ExceptionDirectoryAnalysis::ExceptionDirectoryAnalysis(duint base, duint size) : Analysis(base, size) +{ + _functionInfoData = nullptr; +#ifdef _WIN64 + // This will only be valid if the address range is within a loaded module + _moduleBase = ModBaseFromAddr(base); + + if(_moduleBase != 0) + { + char modulePath[MAX_PATH]; + memset(modulePath, 0, sizeof(modulePath)); + + ModPathFromAddr(_moduleBase, modulePath, ARRAYSIZE(modulePath)); + + HANDLE fileHandle; + DWORD fileSize; + HANDLE fileMapHandle; + ULONG_PTR fileMapVa; + if(StaticFileLoadW( + StringUtils::Utf8ToUtf16(modulePath).c_str(), + UE_ACCESS_READ, + false, + &fileHandle, + &fileSize, + &fileMapHandle, + &fileMapVa)) + { + // Find a pointer to IMAGE_DIRECTORY_ENTRY_EXCEPTION for later use + ULONG_PTR virtualOffset = GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALOFFSET); + _functionInfoSize = (duint)GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALSIZE); + + // Unload the file + StaticFileUnloadW(nullptr, false, fileHandle, fileSize, fileMapHandle, fileMapVa); + + // Get a copy of the function table + if(virtualOffset) + { + // Read the table into a buffer + _functionInfoData = emalloc(_functionInfoSize); + + if(_functionInfoData) + MemRead(virtualOffset + _moduleBase, _functionInfoData, _functionInfoSize); + } + } + } +#endif //_WIN64 +} + +ExceptionDirectoryAnalysis::~ExceptionDirectoryAnalysis() +{ + if(_functionInfoData) + efree(_functionInfoData); +} + +void ExceptionDirectoryAnalysis::Analyse() +{ +#ifdef _WIN64 + EnumerateFunctionRuntimeEntries64([&](PRUNTIME_FUNCTION Function) + { + const duint funcAddr = _moduleBase + Function->BeginAddress; + const duint funcEnd = _moduleBase + Function->EndAddress; + + // If within limits... + if(funcAddr >= _base && funcAddr < _base + _size) + _functions.push_back({ funcAddr, funcEnd }); + + return true; + }); + dprintf("%u functions discovered!\n", _functions.size()); +#else //x32 + dprintf("This kind of analysis doesn't work on x32 executables...\n"); +#endif // _WIN64 +} + +void ExceptionDirectoryAnalysis::SetMarkers() +{ + FunctionDelRange(_base, _base + _size); + for(const auto & function : _functions) + FunctionAdd(function.first, function.second, false); +} + +#ifdef _WIN64 +void ExceptionDirectoryAnalysis::EnumerateFunctionRuntimeEntries64(std::function Callback) +{ + if(!_functionInfoData) + return; + + // Get the table pointer and size + auto functionTable = (PRUNTIME_FUNCTION)_functionInfoData; + duint totalCount = (_functionInfoSize / sizeof(RUNTIME_FUNCTION)); + + // Enumerate each entry + for(duint i = 0; i < totalCount; i++) + { + if(!Callback(&functionTable[i])) + break; + } +} #endif // _WIN64 \ No newline at end of file diff --git a/src/dbg/exceptiondirectoryanalysis.h b/src/dbg/exceptiondirectoryanalysis.h index 6ebc9ca6..bed5427a 100644 --- a/src/dbg/exceptiondirectoryanalysis.h +++ b/src/dbg/exceptiondirectoryanalysis.h @@ -1,26 +1,26 @@ -#ifndef _EXCEPTIONDIRECTORYANALYSIS_H -#define _EXCEPTIONDIRECTORYANALYSIS_H - -#include "analysis.h" -#include - -class ExceptionDirectoryAnalysis : public Analysis -{ -public: - explicit ExceptionDirectoryAnalysis(duint base, duint size); - ~ExceptionDirectoryAnalysis(); - void Analyse() override; - void SetMarkers() override; - -private: - duint _moduleBase; - duint _functionInfoSize; - void* _functionInfoData; - std::vector> _functions; - -#ifdef _WIN64 - void EnumerateFunctionRuntimeEntries64(std::function Callback); -#endif // _WIN64 -}; - +#ifndef _EXCEPTIONDIRECTORYANALYSIS_H +#define _EXCEPTIONDIRECTORYANALYSIS_H + +#include "analysis.h" +#include + +class ExceptionDirectoryAnalysis : public Analysis +{ +public: + explicit ExceptionDirectoryAnalysis(duint base, duint size); + ~ExceptionDirectoryAnalysis(); + void Analyse() override; + void SetMarkers() override; + +private: + duint _moduleBase; + duint _functionInfoSize; + void* _functionInfoData; + std::vector> _functions; + +#ifdef _WIN64 + void EnumerateFunctionRuntimeEntries64(std::function Callback); +#endif // _WIN64 +}; + #endif //_EXCEPTIONDIRECTORYANALYSIS_H \ No newline at end of file diff --git a/src/dbg/expressionparser.cpp b/src/dbg/expressionparser.cpp index 2cc06967..975780b6 100644 --- a/src/dbg/expressionparser.cpp +++ b/src/dbg/expressionparser.cpp @@ -1,453 +1,453 @@ -#include "expressionparser.h" -#include "value.h" - -ExpressionParser::Token::Token(const String & data, const Type type) -{ - _data = data; - _type = type; -} - -const String & ExpressionParser::Token::data() const -{ - return _data; -} - -ExpressionParser::Token::Type ExpressionParser::Token::type() const -{ - return _type; -} - -ExpressionParser::Token::Associativity ExpressionParser::Token::associativity() const -{ - switch(_type) - { - case Type::OperatorUnarySub: - case Type::OperatorNot: - return Associativity::RightToLeft; - case Type::OperatorMul: - case Type::OperatorHiMul: - case Type::OperatorDiv: - case Type::OperatorMod: - case Type::OperatorAdd: - case Type::OperatorSub: - case Type::OperatorShl: - case Type::OperatorShr: - case Type::OperatorAnd: - case Type::OperatorXor: - case Type::OperatorOr: - return Associativity::LeftToRight; - default: - return Associativity::Unspecified; - } -} - -int ExpressionParser::Token::precedence() const -{ - switch(_type) - { - case Type::OperatorUnarySub: - case Type::OperatorNot: - return 7; - case Type::OperatorMul: - case Type::OperatorHiMul: - case Type::OperatorDiv: - case Type::OperatorMod: - return 6; - case Type::OperatorAdd: - case Type::OperatorSub: - return 5; - case Type::OperatorShl: - case Type::OperatorShr: - return 4; - case Type::OperatorAnd: - return 3; - case Type::OperatorXor: - return 2; - case Type::OperatorOr: - return 1; - default: - return 0; - } -} - -bool ExpressionParser::Token::isOperator() const -{ - return _type != Type::Data && _type != Type::OpenBracket && _type != Type::CloseBracket; -} - -ExpressionParser::ExpressionParser(const String & expression) -{ - _tokens.clear(); - _prefixTokens.clear(); - tokenize(fixClosingBrackets(expression)); - shuntingYard(); -} - -String ExpressionParser::fixClosingBrackets(const String & expression) -{ - int open = 0; - int close = 0; - size_t len = expression.length(); - for(size_t i = 0; i < len; i++) - { - if(expression[i] == '(') - open++; - else if(expression[i] == ')') - close++; - } - String result = expression; - if(close < open) - { - for(int i = 0; i < open - close; i++) - result += ")"; - } - return result; -} - -void ExpressionParser::tokenize(const String & expression) -{ - bool stateMemory = false; - size_t len = expression.length(); - for(size_t i = 0; i < len; i++) - { - char ch = expression[i]; - switch(ch) - { - case '[': - { - stateMemory = true; - _curToken += ch; - } - break; - - case ']': - { - stateMemory = false; - _curToken += ch; - } - break; - - default: - { - if(stateMemory) - _curToken += ch; - else - { - switch(ch) - { - case '(': - addOperatorToken(ch, Token::Type::OpenBracket); - break; - case ')': - addOperatorToken(ch, Token::Type::CloseBracket); - break; - case '~': - addOperatorToken(ch, Token::Type::OperatorNot); - break; - case '*': - addOperatorToken(ch, Token::Type::OperatorMul); - break; - case '`': - addOperatorToken(ch, Token::Type::OperatorHiMul); - break; - case '/': - addOperatorToken(ch, Token::Type::OperatorDiv); - break; - case '%': - addOperatorToken(ch, Token::Type::OperatorMod); - break; - case '+': - if(!isUnaryOperator()) //skip all unary add operators - addOperatorToken(ch, Token::Type::OperatorAdd); - break; - case '-': - if(isUnaryOperator()) - addOperatorToken(ch, Token::Type::OperatorUnarySub); - else - addOperatorToken(ch, Token::Type::OperatorSub); - break; - case '<': - addOperatorToken(ch, Token::Type::OperatorShl); - break; - case '>': - addOperatorToken(ch, Token::Type::OperatorShr); - break; - case '&': - addOperatorToken(ch, Token::Type::OperatorAnd); - break; - case '^': - addOperatorToken(ch, Token::Type::OperatorXor); - break; - case '|': - addOperatorToken(ch, Token::Type::OperatorOr); - break; - case ' ': //ignore spaces - break; - default: - _curToken += ch; - break; - } - } - } - break; - } - } - if(_curToken.length() != 0) //make sure the last token is added - _tokens.push_back(Token(_curToken, Token::Type::Data)); -} - -void ExpressionParser::addOperatorToken(const char ch, const Token::Type type) -{ - if(_curToken.length()) //add a new data token when there is data in the buffer - { - _tokens.push_back(Token(_curToken, Token::Type::Data)); - _curToken.clear(); - } - String data; - data += ch; - _tokens.push_back(Token(data, type)); //add the operator token -} - -bool ExpressionParser::isUnaryOperator() -{ - if(_curToken.length()) //data before the operator means it is no unary operator - return false; - if(!_tokens.size()) //no tokens before the operator means it is an unary operator - return true; - Token lastToken = _tokens[_tokens.size() - 1]; - return lastToken.isOperator(); //if the previous operator is a token, the operator is an unary operator -} - -void ExpressionParser::shuntingYard() -{ - //Implementation of Dijkstra's Shunting-yard algorithm - std::vector queue; - std::stack stack; - size_t len = _tokens.size(); - //process the tokens - for(size_t i = 0; i < len; i++) - { - Token & token = _tokens[i]; - switch(token.type()) - { - case Token::Type::Data: - queue.push_back(token); - break; - case Token::Type::OpenBracket: - stack.push(token); - break; - case Token::Type::CloseBracket: - while(true) - { - if(stack.empty()) //empty stack = bracket mismatch - return; - Token curToken = stack.top(); - stack.pop(); - if(curToken.type() == Token::Type::OpenBracket) - break; - queue.push_back(curToken); - } - break; - default: //operator - Token & o1 = token; - while(!stack.empty()) - { - Token o2 = stack.top(); - if(o2.isOperator() && - (o1.associativity() == Token::Associativity::LeftToRight && o1.precedence() <= o2.precedence()) || - (o1.associativity() == Token::Associativity::RightToLeft && o1.precedence() < o2.precedence())) - { - queue.push_back(o2); - stack.pop(); - } - else - break; - } - stack.push(o1); - break; - } - } - //pop the remaining operators - while(!stack.empty()) - { - Token curToken = stack.top(); - stack.pop(); - if(curToken.type() == Token::Type::OpenBracket || curToken.type() == Token::Type::CloseBracket) //brackets on the stack means invalid expression - return; - queue.push_back(curToken); - } - _prefixTokens = queue; -} - -#ifdef _WIN64 -#include - -static inline unsigned long long umulhi(unsigned long long x, unsigned long long y) -{ - unsigned __int64 res; - _umul128(x, y, &res); - return res; -} - -static inline long long mulhi(long long x, long long y) -{ - __int64 res; - _mul128(x, y, &res); - return res; -} -#else -static inline unsigned int umulhi(unsigned int x, unsigned int y) -{ - return (unsigned int)(((unsigned long long)x * y) >> 32); -} - -static inline int mulhi(int x, int y) -{ - return (int)(((long long)x * y) >> 32); -} -#endif //__MINGW64__ - -template -static bool operation(const ExpressionParser::Token::Type type, const T op1, const T op2, T & result, const bool signedcalc) -{ - result = 0; - switch(type) - { - case ExpressionParser::Token::Type::OperatorUnarySub: - result = op1 * ~0; - return true; - case ExpressionParser::Token::Type::OperatorNot: - result = ~op1; - return true; - case ExpressionParser::Token::Type::OperatorMul: - result = op1 * op2; - return true; - case ExpressionParser::Token::Type::OperatorHiMul: - if(signedcalc) - result = mulhi(op1, op2); - else - result = umulhi(op1, op2); - return true; - case ExpressionParser::Token::Type::OperatorDiv: - if(op2 != 0) - { - result = op1 / op2; - return true; - } - return false; - case ExpressionParser::Token::Type::OperatorMod: - if(op2 != 0) - { - result = op1 % op2; - return true; - } - return false; - case ExpressionParser::Token::Type::OperatorAdd: - result = op1 + op2; - return true; - case ExpressionParser::Token::Type::OperatorSub: - result = op1 - op2; - return true; - case ExpressionParser::Token::Type::OperatorShl: - result = op1 << op2; - return true; - case ExpressionParser::Token::Type::OperatorShr: - result = op1 >> op2; - return true; - case ExpressionParser::Token::Type::OperatorAnd: - result = op1 & op2; - return true; - case ExpressionParser::Token::Type::OperatorXor: - result = op1 ^ op2; - return true; - case ExpressionParser::Token::Type::OperatorOr: - result = op1 | op2; - return true; - default: - return false; - } -} - -bool ExpressionParser::unsignedoperation(const Token::Type type, const duint op1, const duint op2, duint & result) -{ - return operation(type, op1, op2, result, false); -} - -bool ExpressionParser::signedoperation(const Token::Type type, const dsint op1, const dsint op2, duint & result) -{ - dsint signedResult; - if(!operation(type, op1, op2, signedResult, true)) - return false; - result = (duint)signedResult; - return true; -} - -bool ExpressionParser::calculate(duint & value, bool signedcalc, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly) -{ - value = 0; - if(!_prefixTokens.size()) - return false; - std::stack stack; - //calculate the result from the RPN queue - for(const auto & token : _prefixTokens) - { - if(token.isOperator()) - { - duint op1 = 0; - duint op2 = 0; - duint result = 0; - switch(token.type()) - { - case Token::Type::OperatorUnarySub: - case Token::Type::OperatorNot: - if(stack.size() < 1) - return false; - op1 = stack.top(); - stack.pop(); - if(signedcalc) - signedoperation(token.type(), op1, op2, result); - else - unsignedoperation(token.type(), op1, op2, result); - stack.push(result); - break; - case Token::Type::OperatorMul: - case Token::Type::OperatorHiMul: - case Token::Type::OperatorDiv: - case Token::Type::OperatorMod: - case Token::Type::OperatorAdd: - case Token::Type::OperatorSub: - case Token::Type::OperatorShl: - case Token::Type::OperatorShr: - case Token::Type::OperatorAnd: - case Token::Type::OperatorXor: - case Token::Type::OperatorOr: - if(stack.size() < 2) - return false; - op2 = stack.top(); - stack.pop(); - op1 = stack.top(); - stack.pop(); - if(signedcalc) - signedoperation(token.type(), op1, op2, result); - else - unsignedoperation(token.type(), op1, op2, result); - stack.push(result); - break; - default: //do nothing - break; - } - } - else - { - duint result; - if(!valfromstring_noexpr(token.data().c_str(), &result, silent, baseonly, value_size, isvar, hexonly)) - return false; - stack.push(result); - } - - } - if(stack.empty()) //empty result stack means error - return false; - value = stack.top(); - return true; +#include "expressionparser.h" +#include "value.h" + +ExpressionParser::Token::Token(const String & data, const Type type) +{ + _data = data; + _type = type; +} + +const String & ExpressionParser::Token::data() const +{ + return _data; +} + +ExpressionParser::Token::Type ExpressionParser::Token::type() const +{ + return _type; +} + +ExpressionParser::Token::Associativity ExpressionParser::Token::associativity() const +{ + switch(_type) + { + case Type::OperatorUnarySub: + case Type::OperatorNot: + return Associativity::RightToLeft; + case Type::OperatorMul: + case Type::OperatorHiMul: + case Type::OperatorDiv: + case Type::OperatorMod: + case Type::OperatorAdd: + case Type::OperatorSub: + case Type::OperatorShl: + case Type::OperatorShr: + case Type::OperatorAnd: + case Type::OperatorXor: + case Type::OperatorOr: + return Associativity::LeftToRight; + default: + return Associativity::Unspecified; + } +} + +int ExpressionParser::Token::precedence() const +{ + switch(_type) + { + case Type::OperatorUnarySub: + case Type::OperatorNot: + return 7; + case Type::OperatorMul: + case Type::OperatorHiMul: + case Type::OperatorDiv: + case Type::OperatorMod: + return 6; + case Type::OperatorAdd: + case Type::OperatorSub: + return 5; + case Type::OperatorShl: + case Type::OperatorShr: + return 4; + case Type::OperatorAnd: + return 3; + case Type::OperatorXor: + return 2; + case Type::OperatorOr: + return 1; + default: + return 0; + } +} + +bool ExpressionParser::Token::isOperator() const +{ + return _type != Type::Data && _type != Type::OpenBracket && _type != Type::CloseBracket; +} + +ExpressionParser::ExpressionParser(const String & expression) +{ + _tokens.clear(); + _prefixTokens.clear(); + tokenize(fixClosingBrackets(expression)); + shuntingYard(); +} + +String ExpressionParser::fixClosingBrackets(const String & expression) +{ + int open = 0; + int close = 0; + size_t len = expression.length(); + for(size_t i = 0; i < len; i++) + { + if(expression[i] == '(') + open++; + else if(expression[i] == ')') + close++; + } + String result = expression; + if(close < open) + { + for(int i = 0; i < open - close; i++) + result += ")"; + } + return result; +} + +void ExpressionParser::tokenize(const String & expression) +{ + bool stateMemory = false; + size_t len = expression.length(); + for(size_t i = 0; i < len; i++) + { + char ch = expression[i]; + switch(ch) + { + case '[': + { + stateMemory = true; + _curToken += ch; + } + break; + + case ']': + { + stateMemory = false; + _curToken += ch; + } + break; + + default: + { + if(stateMemory) + _curToken += ch; + else + { + switch(ch) + { + case '(': + addOperatorToken(ch, Token::Type::OpenBracket); + break; + case ')': + addOperatorToken(ch, Token::Type::CloseBracket); + break; + case '~': + addOperatorToken(ch, Token::Type::OperatorNot); + break; + case '*': + addOperatorToken(ch, Token::Type::OperatorMul); + break; + case '`': + addOperatorToken(ch, Token::Type::OperatorHiMul); + break; + case '/': + addOperatorToken(ch, Token::Type::OperatorDiv); + break; + case '%': + addOperatorToken(ch, Token::Type::OperatorMod); + break; + case '+': + if(!isUnaryOperator()) //skip all unary add operators + addOperatorToken(ch, Token::Type::OperatorAdd); + break; + case '-': + if(isUnaryOperator()) + addOperatorToken(ch, Token::Type::OperatorUnarySub); + else + addOperatorToken(ch, Token::Type::OperatorSub); + break; + case '<': + addOperatorToken(ch, Token::Type::OperatorShl); + break; + case '>': + addOperatorToken(ch, Token::Type::OperatorShr); + break; + case '&': + addOperatorToken(ch, Token::Type::OperatorAnd); + break; + case '^': + addOperatorToken(ch, Token::Type::OperatorXor); + break; + case '|': + addOperatorToken(ch, Token::Type::OperatorOr); + break; + case ' ': //ignore spaces + break; + default: + _curToken += ch; + break; + } + } + } + break; + } + } + if(_curToken.length() != 0) //make sure the last token is added + _tokens.push_back(Token(_curToken, Token::Type::Data)); +} + +void ExpressionParser::addOperatorToken(const char ch, const Token::Type type) +{ + if(_curToken.length()) //add a new data token when there is data in the buffer + { + _tokens.push_back(Token(_curToken, Token::Type::Data)); + _curToken.clear(); + } + String data; + data += ch; + _tokens.push_back(Token(data, type)); //add the operator token +} + +bool ExpressionParser::isUnaryOperator() +{ + if(_curToken.length()) //data before the operator means it is no unary operator + return false; + if(!_tokens.size()) //no tokens before the operator means it is an unary operator + return true; + Token lastToken = _tokens[_tokens.size() - 1]; + return lastToken.isOperator(); //if the previous operator is a token, the operator is an unary operator +} + +void ExpressionParser::shuntingYard() +{ + //Implementation of Dijkstra's Shunting-yard algorithm + std::vector queue; + std::stack stack; + size_t len = _tokens.size(); + //process the tokens + for(size_t i = 0; i < len; i++) + { + Token & token = _tokens[i]; + switch(token.type()) + { + case Token::Type::Data: + queue.push_back(token); + break; + case Token::Type::OpenBracket: + stack.push(token); + break; + case Token::Type::CloseBracket: + while(true) + { + if(stack.empty()) //empty stack = bracket mismatch + return; + Token curToken = stack.top(); + stack.pop(); + if(curToken.type() == Token::Type::OpenBracket) + break; + queue.push_back(curToken); + } + break; + default: //operator + Token & o1 = token; + while(!stack.empty()) + { + Token o2 = stack.top(); + if(o2.isOperator() && + (o1.associativity() == Token::Associativity::LeftToRight && o1.precedence() <= o2.precedence()) || + (o1.associativity() == Token::Associativity::RightToLeft && o1.precedence() < o2.precedence())) + { + queue.push_back(o2); + stack.pop(); + } + else + break; + } + stack.push(o1); + break; + } + } + //pop the remaining operators + while(!stack.empty()) + { + Token curToken = stack.top(); + stack.pop(); + if(curToken.type() == Token::Type::OpenBracket || curToken.type() == Token::Type::CloseBracket) //brackets on the stack means invalid expression + return; + queue.push_back(curToken); + } + _prefixTokens = queue; +} + +#ifdef _WIN64 +#include + +static inline unsigned long long umulhi(unsigned long long x, unsigned long long y) +{ + unsigned __int64 res; + _umul128(x, y, &res); + return res; +} + +static inline long long mulhi(long long x, long long y) +{ + __int64 res; + _mul128(x, y, &res); + return res; +} +#else +static inline unsigned int umulhi(unsigned int x, unsigned int y) +{ + return (unsigned int)(((unsigned long long)x * y) >> 32); +} + +static inline int mulhi(int x, int y) +{ + return (int)(((long long)x * y) >> 32); +} +#endif //__MINGW64__ + +template +static bool operation(const ExpressionParser::Token::Type type, const T op1, const T op2, T & result, const bool signedcalc) +{ + result = 0; + switch(type) + { + case ExpressionParser::Token::Type::OperatorUnarySub: + result = op1 * ~0; + return true; + case ExpressionParser::Token::Type::OperatorNot: + result = ~op1; + return true; + case ExpressionParser::Token::Type::OperatorMul: + result = op1 * op2; + return true; + case ExpressionParser::Token::Type::OperatorHiMul: + if(signedcalc) + result = mulhi(op1, op2); + else + result = umulhi(op1, op2); + return true; + case ExpressionParser::Token::Type::OperatorDiv: + if(op2 != 0) + { + result = op1 / op2; + return true; + } + return false; + case ExpressionParser::Token::Type::OperatorMod: + if(op2 != 0) + { + result = op1 % op2; + return true; + } + return false; + case ExpressionParser::Token::Type::OperatorAdd: + result = op1 + op2; + return true; + case ExpressionParser::Token::Type::OperatorSub: + result = op1 - op2; + return true; + case ExpressionParser::Token::Type::OperatorShl: + result = op1 << op2; + return true; + case ExpressionParser::Token::Type::OperatorShr: + result = op1 >> op2; + return true; + case ExpressionParser::Token::Type::OperatorAnd: + result = op1 & op2; + return true; + case ExpressionParser::Token::Type::OperatorXor: + result = op1 ^ op2; + return true; + case ExpressionParser::Token::Type::OperatorOr: + result = op1 | op2; + return true; + default: + return false; + } +} + +bool ExpressionParser::unsignedoperation(const Token::Type type, const duint op1, const duint op2, duint & result) +{ + return operation(type, op1, op2, result, false); +} + +bool ExpressionParser::signedoperation(const Token::Type type, const dsint op1, const dsint op2, duint & result) +{ + dsint signedResult; + if(!operation(type, op1, op2, signedResult, true)) + return false; + result = (duint)signedResult; + return true; +} + +bool ExpressionParser::calculate(duint & value, bool signedcalc, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly) +{ + value = 0; + if(!_prefixTokens.size()) + return false; + std::stack stack; + //calculate the result from the RPN queue + for(const auto & token : _prefixTokens) + { + if(token.isOperator()) + { + duint op1 = 0; + duint op2 = 0; + duint result = 0; + switch(token.type()) + { + case Token::Type::OperatorUnarySub: + case Token::Type::OperatorNot: + if(stack.size() < 1) + return false; + op1 = stack.top(); + stack.pop(); + if(signedcalc) + signedoperation(token.type(), op1, op2, result); + else + unsignedoperation(token.type(), op1, op2, result); + stack.push(result); + break; + case Token::Type::OperatorMul: + case Token::Type::OperatorHiMul: + case Token::Type::OperatorDiv: + case Token::Type::OperatorMod: + case Token::Type::OperatorAdd: + case Token::Type::OperatorSub: + case Token::Type::OperatorShl: + case Token::Type::OperatorShr: + case Token::Type::OperatorAnd: + case Token::Type::OperatorXor: + case Token::Type::OperatorOr: + if(stack.size() < 2) + return false; + op2 = stack.top(); + stack.pop(); + op1 = stack.top(); + stack.pop(); + if(signedcalc) + signedoperation(token.type(), op1, op2, result); + else + unsignedoperation(token.type(), op1, op2, result); + stack.push(result); + break; + default: //do nothing + break; + } + } + else + { + duint result; + if(!valfromstring_noexpr(token.data().c_str(), &result, silent, baseonly, value_size, isvar, hexonly)) + return false; + stack.push(result); + } + + } + if(stack.empty()) //empty result stack means error + return false; + value = stack.top(); + return true; } \ No newline at end of file diff --git a/src/dbg/expressionparser.h b/src/dbg/expressionparser.h index a94ea6d4..55ed0275 100644 --- a/src/dbg/expressionparser.h +++ b/src/dbg/expressionparser.h @@ -1,68 +1,68 @@ -#ifndef _EXPRESSION_PARSER_H -#define _EXPRESSION_PARSER_H - -#include "_global.h" - -class ExpressionParser -{ -public: - ExpressionParser(const String & expression); - bool calculate(duint & value, bool signedcalc, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly); - - class Token - { - public: - enum class Type - { - Data, - OpenBracket, - CloseBracket, - OperatorUnarySub, - OperatorNot, - OperatorMul, - OperatorHiMul, - OperatorDiv, - OperatorMod, - OperatorAdd, - OperatorSub, - OperatorShl, - OperatorShr, - OperatorAnd, - OperatorXor, - OperatorOr - }; - - enum class Associativity - { - LeftToRight, - RightToLeft, - Unspecified - }; - - Token(const String & data, const Type type); - const String & data() const; - Type type() const; - Associativity associativity() const; - int precedence() const; - bool isOperator() const; - - private: - String _data; - Type _type; - }; - -private: - String fixClosingBrackets(const String & expression); - bool isUnaryOperator(); - void tokenize(const String & expression); - void shuntingYard(); - void addOperatorToken(const char ch, const Token::Type type); - bool unsignedoperation(const Token::Type type, const duint op1, const duint op2, duint & result); - bool signedoperation(const Token::Type type, const dsint op1, const dsint op2, duint & result); - - std::vector _tokens; - std::vector _prefixTokens; - String _curToken; -}; - +#ifndef _EXPRESSION_PARSER_H +#define _EXPRESSION_PARSER_H + +#include "_global.h" + +class ExpressionParser +{ +public: + ExpressionParser(const String & expression); + bool calculate(duint & value, bool signedcalc, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly); + + class Token + { + public: + enum class Type + { + Data, + OpenBracket, + CloseBracket, + OperatorUnarySub, + OperatorNot, + OperatorMul, + OperatorHiMul, + OperatorDiv, + OperatorMod, + OperatorAdd, + OperatorSub, + OperatorShl, + OperatorShr, + OperatorAnd, + OperatorXor, + OperatorOr + }; + + enum class Associativity + { + LeftToRight, + RightToLeft, + Unspecified + }; + + Token(const String & data, const Type type); + const String & data() const; + Type type() const; + Associativity associativity() const; + int precedence() const; + bool isOperator() const; + + private: + String _data; + Type _type; + }; + +private: + String fixClosingBrackets(const String & expression); + bool isUnaryOperator(); + void tokenize(const String & expression); + void shuntingYard(); + void addOperatorToken(const char ch, const Token::Type type); + bool unsignedoperation(const Token::Type type, const duint op1, const duint op2, duint & result); + bool signedoperation(const Token::Type type, const dsint op1, const dsint op2, duint & result); + + std::vector _tokens; + std::vector _prefixTokens; + String _curToken; +}; + #endif //_EXPRESSION_PARSER_H \ No newline at end of file diff --git a/src/dbg/filehelper.cpp b/src/dbg/filehelper.cpp index 5e78ce27..bfd0aa7b 100644 --- a/src/dbg/filehelper.cpp +++ b/src/dbg/filehelper.cpp @@ -1,29 +1,29 @@ -#include "filehelper.h" - -bool FileHelper::ReadAllText(const String & fileName, String & content) -{ - Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(fileName).c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); - if(hFile == INVALID_HANDLE_VALUE) - return false; - unsigned int filesize = GetFileSize(hFile, 0); - if(!filesize) - { - content.clear(); - return true; - } - Memory filedata(filesize + 1, "FileReader::ReadAllText:filedata"); - DWORD read = 0; - if(!ReadFile(hFile, filedata(), filesize, &read, 0)) - return false; - content = String(filedata()); - return true; -} - -bool FileHelper::WriteAllText(const String & fileName, const String & content) -{ - Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(fileName).c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr); - if(hFile == INVALID_HANDLE_VALUE) - return false; - DWORD written = 0; - return !!WriteFile(hFile, content.c_str(), DWORD(content.length()), &written, nullptr); +#include "filehelper.h" + +bool FileHelper::ReadAllText(const String & fileName, String & content) +{ + Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(fileName).c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); + if(hFile == INVALID_HANDLE_VALUE) + return false; + unsigned int filesize = GetFileSize(hFile, 0); + if(!filesize) + { + content.clear(); + return true; + } + Memory filedata(filesize + 1, "FileReader::ReadAllText:filedata"); + DWORD read = 0; + if(!ReadFile(hFile, filedata(), filesize, &read, 0)) + return false; + content = String(filedata()); + return true; +} + +bool FileHelper::WriteAllText(const String & fileName, const String & content) +{ + Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(fileName).c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr); + if(hFile == INVALID_HANDLE_VALUE) + return false; + DWORD written = 0; + return !!WriteFile(hFile, content.c_str(), DWORD(content.length()), &written, nullptr); } \ No newline at end of file diff --git a/src/dbg/filehelper.h b/src/dbg/filehelper.h index a2459d04..e50fadf4 100644 --- a/src/dbg/filehelper.h +++ b/src/dbg/filehelper.h @@ -1,13 +1,13 @@ -#ifndef _FILEREADER_H -#define _FILEREADER_H - -#include "_global.h" - -class FileHelper -{ -public: - static bool ReadAllText(const String & fileName, String & content); - static bool WriteAllText(const String & fileName, const String & content); -}; - +#ifndef _FILEREADER_H +#define _FILEREADER_H + +#include "_global.h" + +class FileHelper +{ +public: + static bool ReadAllText(const String & fileName, String & content); + static bool WriteAllText(const String & fileName, const String & content); +}; + #endif //_FILEREADER_H \ No newline at end of file diff --git a/src/dbg/function.cpp b/src/dbg/function.cpp index 4d02fff6..cd0f8829 100644 --- a/src/dbg/function.cpp +++ b/src/dbg/function.cpp @@ -1,249 +1,249 @@ -#include "function.h" -#include "module.h" -#include "memory.h" -#include "threading.h" - -std::map functions; - -bool FunctionAdd(duint Start, duint End, bool Manual) -{ - ASSERT_DEBUGGING("Export call"); - - // Make sure memory is readable - if(!MemIsValidReadPtr(Start)) - return false; - - // Fail if boundary exceeds module size - const duint moduleBase = ModBaseFromAddr(Start); - - if(moduleBase != ModBaseFromAddr(End)) - return false; - - // Fail if 'Start' and 'End' are incompatible - if(Start > End || FunctionOverlaps(Start, End)) - return false; - - FUNCTIONSINFO function; - ModNameFromAddr(Start, function.mod, true); - function.start = Start - moduleBase; - function.end = End - moduleBase; - function.manual = Manual; - - // Insert to global table - EXCLUSIVE_ACQUIRE(LockFunctions); - - functions.insert(std::make_pair(ModuleRange(ModHashFromAddr(moduleBase), Range(function.start, function.end)), function)); - return true; -} - -bool FunctionGet(duint Address, duint* Start, duint* End) -{ - ASSERT_DEBUGGING("Export call"); - - const duint moduleBase = ModBaseFromAddr(Address); - - // Lookup by module hash, then function range - SHARED_ACQUIRE(LockFunctions); - - auto found = functions.find(ModuleRange(ModHashFromAddr(moduleBase), Range(Address - moduleBase, Address - moduleBase))); - - // Was this range found? - if(found == functions.end()) - return false; - - if(Start) - *Start = found->second.start + moduleBase; - - if(End) - *End = found->second.end + moduleBase; - - return true; -} - -bool FunctionOverlaps(duint Start, duint End) -{ - ASSERT_DEBUGGING("Export call"); - - // A function can't end before it begins - if(Start > End) - return false; - - const duint moduleBase = ModBaseFromAddr(Start); - - SHARED_ACQUIRE(LockFunctions); - return (functions.count(ModuleRange(ModHashFromAddr(moduleBase), Range(Start - moduleBase, End - moduleBase))) > 0); -} - -bool FunctionDelete(duint Address) -{ - ASSERT_DEBUGGING("Export call"); - - const duint moduleBase = ModBaseFromAddr(Address); - - EXCLUSIVE_ACQUIRE(LockFunctions); - return (functions.erase(ModuleRange(ModHashFromAddr(moduleBase), Range(Address - moduleBase, Address - moduleBase))) > 0); -} - -void FunctionDelRange(duint Start, duint End) -{ - ASSERT_DEBUGGING("Export call"); - - // Should all functions be deleted? - // 0x00000000 - 0xFFFFFFFF - if(Start == 0 && End == ~0) - { - FunctionClear(); - } - else - { - // The start and end address must be in the same module - duint moduleBase = ModBaseFromAddr(Start); - - if(moduleBase != ModBaseFromAddr(End)) - return; - - // Convert these to a relative offset - Start -= moduleBase; - End -= moduleBase; - - EXCLUSIVE_ACQUIRE(LockFunctions); - for(auto itr = functions.begin(); itr != functions.end();) - { - const auto & currentFunction = itr->second; - - // Ignore manually set entries - if(currentFunction.manual) - { - ++itr; - continue; - } - - // [Start, End] - if(currentFunction.end >= Start && currentFunction.start <= End) - itr = functions.erase(itr); - else - ++itr; - } - } -} - -void FunctionCacheSave(JSON Root) -{ - EXCLUSIVE_ACQUIRE(LockFunctions); - - // Allocate JSON object array - const JSON jsonFunctions = json_array(); - const JSON jsonAutoFunctions = json_array(); - - for(auto & i : functions) - { - JSON currentFunction = json_object(); - - json_object_set_new(currentFunction, "module", json_string(i.second.mod)); - json_object_set_new(currentFunction, "start", json_hex(i.second.start)); - json_object_set_new(currentFunction, "end", json_hex(i.second.end)); - - if(i.second.manual) - json_array_append_new(jsonFunctions, currentFunction); - else - json_array_append_new(jsonAutoFunctions, currentFunction); - } - - if(json_array_size(jsonFunctions)) - json_object_set(Root, "functions", jsonFunctions); - - if(json_array_size(jsonAutoFunctions)) - json_object_set(Root, "autofunctions", jsonAutoFunctions); - - // Decrease reference count to avoid leaking memory - json_decref(jsonFunctions); - json_decref(jsonAutoFunctions); -} - -void FunctionCacheLoad(JSON Root) -{ - EXCLUSIVE_ACQUIRE(LockFunctions); - - // Delete existing entries - functions.clear(); - - // Inline lambda to enumerate all JSON array indices - auto InsertFunctions = [](const JSON Object, bool Manual) - { - size_t i; - JSON value; - json_array_foreach(Object, i, value) - { - FUNCTIONSINFO functionInfo; - memset(&functionInfo, 0, sizeof(FUNCTIONSINFO)); - - // Copy module name - const char* mod = json_string_value(json_object_get(value, "module")); - - if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE) - strcpy_s(functionInfo.mod, mod); - - // Function address - functionInfo.start = (duint)json_hex_value(json_object_get(value, "start")); - functionInfo.end = (duint)json_hex_value(json_object_get(value, "end")); - functionInfo.manual = Manual; - - // Sanity check - if(functionInfo.end < functionInfo.start) - continue; - - const duint key = ModHashFromName(functionInfo.mod); - functions.insert(std::make_pair(ModuleRange(key, Range(functionInfo.start, functionInfo.end)), functionInfo)); - } - }; - - const JSON jsonFunctions = json_object_get(Root, "functions"); - const JSON jsonAutoFunctions = json_object_get(Root, "autofunctions"); - - // Manual - if(jsonFunctions) - InsertFunctions(jsonFunctions, true); - - // Auto - if(jsonAutoFunctions) - InsertFunctions(jsonAutoFunctions, false); -} - -bool FunctionEnum(FUNCTIONSINFO* List, size_t* Size) -{ - ASSERT_DEBUGGING("Export call"); - - // If a list isn't passed and the size not requested, fail - ASSERT_FALSE(!List && !Size); - SHARED_ACQUIRE(LockFunctions); - - // Did the caller request the buffer size needed? - if(Size) - { - *Size = functions.size() * sizeof(FUNCTIONSINFO); - - if(!List) - return true; - } - - // Fill out the buffer - for(auto & itr : functions) - { - // Adjust for relative to virtual addresses - duint moduleBase = ModBaseFromName(itr.second.mod); - - *List = itr.second; - List->start += moduleBase; - List->end += moduleBase; - - List++; - } - - return true; -} - -void FunctionClear() -{ - EXCLUSIVE_ACQUIRE(LockFunctions); - functions.clear(); +#include "function.h" +#include "module.h" +#include "memory.h" +#include "threading.h" + +std::map functions; + +bool FunctionAdd(duint Start, duint End, bool Manual) +{ + ASSERT_DEBUGGING("Export call"); + + // Make sure memory is readable + if(!MemIsValidReadPtr(Start)) + return false; + + // Fail if boundary exceeds module size + const duint moduleBase = ModBaseFromAddr(Start); + + if(moduleBase != ModBaseFromAddr(End)) + return false; + + // Fail if 'Start' and 'End' are incompatible + if(Start > End || FunctionOverlaps(Start, End)) + return false; + + FUNCTIONSINFO function; + ModNameFromAddr(Start, function.mod, true); + function.start = Start - moduleBase; + function.end = End - moduleBase; + function.manual = Manual; + + // Insert to global table + EXCLUSIVE_ACQUIRE(LockFunctions); + + functions.insert(std::make_pair(ModuleRange(ModHashFromAddr(moduleBase), Range(function.start, function.end)), function)); + return true; +} + +bool FunctionGet(duint Address, duint* Start, duint* End) +{ + ASSERT_DEBUGGING("Export call"); + + const duint moduleBase = ModBaseFromAddr(Address); + + // Lookup by module hash, then function range + SHARED_ACQUIRE(LockFunctions); + + auto found = functions.find(ModuleRange(ModHashFromAddr(moduleBase), Range(Address - moduleBase, Address - moduleBase))); + + // Was this range found? + if(found == functions.end()) + return false; + + if(Start) + *Start = found->second.start + moduleBase; + + if(End) + *End = found->second.end + moduleBase; + + return true; +} + +bool FunctionOverlaps(duint Start, duint End) +{ + ASSERT_DEBUGGING("Export call"); + + // A function can't end before it begins + if(Start > End) + return false; + + const duint moduleBase = ModBaseFromAddr(Start); + + SHARED_ACQUIRE(LockFunctions); + return (functions.count(ModuleRange(ModHashFromAddr(moduleBase), Range(Start - moduleBase, End - moduleBase))) > 0); +} + +bool FunctionDelete(duint Address) +{ + ASSERT_DEBUGGING("Export call"); + + const duint moduleBase = ModBaseFromAddr(Address); + + EXCLUSIVE_ACQUIRE(LockFunctions); + return (functions.erase(ModuleRange(ModHashFromAddr(moduleBase), Range(Address - moduleBase, Address - moduleBase))) > 0); +} + +void FunctionDelRange(duint Start, duint End) +{ + ASSERT_DEBUGGING("Export call"); + + // Should all functions be deleted? + // 0x00000000 - 0xFFFFFFFF + if(Start == 0 && End == ~0) + { + FunctionClear(); + } + else + { + // The start and end address must be in the same module + duint moduleBase = ModBaseFromAddr(Start); + + if(moduleBase != ModBaseFromAddr(End)) + return; + + // Convert these to a relative offset + Start -= moduleBase; + End -= moduleBase; + + EXCLUSIVE_ACQUIRE(LockFunctions); + for(auto itr = functions.begin(); itr != functions.end();) + { + const auto & currentFunction = itr->second; + + // Ignore manually set entries + if(currentFunction.manual) + { + ++itr; + continue; + } + + // [Start, End] + if(currentFunction.end >= Start && currentFunction.start <= End) + itr = functions.erase(itr); + else + ++itr; + } + } +} + +void FunctionCacheSave(JSON Root) +{ + EXCLUSIVE_ACQUIRE(LockFunctions); + + // Allocate JSON object array + const JSON jsonFunctions = json_array(); + const JSON jsonAutoFunctions = json_array(); + + for(auto & i : functions) + { + JSON currentFunction = json_object(); + + json_object_set_new(currentFunction, "module", json_string(i.second.mod)); + json_object_set_new(currentFunction, "start", json_hex(i.second.start)); + json_object_set_new(currentFunction, "end", json_hex(i.second.end)); + + if(i.second.manual) + json_array_append_new(jsonFunctions, currentFunction); + else + json_array_append_new(jsonAutoFunctions, currentFunction); + } + + if(json_array_size(jsonFunctions)) + json_object_set(Root, "functions", jsonFunctions); + + if(json_array_size(jsonAutoFunctions)) + json_object_set(Root, "autofunctions", jsonAutoFunctions); + + // Decrease reference count to avoid leaking memory + json_decref(jsonFunctions); + json_decref(jsonAutoFunctions); +} + +void FunctionCacheLoad(JSON Root) +{ + EXCLUSIVE_ACQUIRE(LockFunctions); + + // Delete existing entries + functions.clear(); + + // Inline lambda to enumerate all JSON array indices + auto InsertFunctions = [](const JSON Object, bool Manual) + { + size_t i; + JSON value; + json_array_foreach(Object, i, value) + { + FUNCTIONSINFO functionInfo; + memset(&functionInfo, 0, sizeof(FUNCTIONSINFO)); + + // Copy module name + const char* mod = json_string_value(json_object_get(value, "module")); + + if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE) + strcpy_s(functionInfo.mod, mod); + + // Function address + functionInfo.start = (duint)json_hex_value(json_object_get(value, "start")); + functionInfo.end = (duint)json_hex_value(json_object_get(value, "end")); + functionInfo.manual = Manual; + + // Sanity check + if(functionInfo.end < functionInfo.start) + continue; + + const duint key = ModHashFromName(functionInfo.mod); + functions.insert(std::make_pair(ModuleRange(key, Range(functionInfo.start, functionInfo.end)), functionInfo)); + } + }; + + const JSON jsonFunctions = json_object_get(Root, "functions"); + const JSON jsonAutoFunctions = json_object_get(Root, "autofunctions"); + + // Manual + if(jsonFunctions) + InsertFunctions(jsonFunctions, true); + + // Auto + if(jsonAutoFunctions) + InsertFunctions(jsonAutoFunctions, false); +} + +bool FunctionEnum(FUNCTIONSINFO* List, size_t* Size) +{ + ASSERT_DEBUGGING("Export call"); + + // If a list isn't passed and the size not requested, fail + ASSERT_FALSE(!List && !Size); + SHARED_ACQUIRE(LockFunctions); + + // Did the caller request the buffer size needed? + if(Size) + { + *Size = functions.size() * sizeof(FUNCTIONSINFO); + + if(!List) + return true; + } + + // Fill out the buffer + for(auto & itr : functions) + { + // Adjust for relative to virtual addresses + duint moduleBase = ModBaseFromName(itr.second.mod); + + *List = itr.second; + List->start += moduleBase; + List->end += moduleBase; + + List++; + } + + return true; +} + +void FunctionClear() +{ + EXCLUSIVE_ACQUIRE(LockFunctions); + functions.clear(); } \ No newline at end of file diff --git a/src/dbg/function.h b/src/dbg/function.h index 07a0c292..989f39b2 100644 --- a/src/dbg/function.h +++ b/src/dbg/function.h @@ -1,21 +1,21 @@ -#pragma once - -#include "addrinfo.h" - -struct FUNCTIONSINFO -{ - char mod[MAX_MODULE_SIZE]; - duint start; - duint end; - bool manual; -}; - -bool FunctionAdd(duint Start, duint End, bool Manual); -bool FunctionGet(duint Address, duint* Start, duint* End); -bool FunctionOverlaps(duint Start, duint End); -bool FunctionDelete(duint Address); -void FunctionDelRange(duint Start, duint End); -void FunctionCacheSave(JSON Root); -void FunctionCacheLoad(JSON Root); -bool FunctionEnum(FUNCTIONSINFO* List, size_t* Size); +#pragma once + +#include "addrinfo.h" + +struct FUNCTIONSINFO +{ + char mod[MAX_MODULE_SIZE]; + duint start; + duint end; + bool manual; +}; + +bool FunctionAdd(duint Start, duint End, bool Manual); +bool FunctionGet(duint Address, duint* Start, duint* End); +bool FunctionOverlaps(duint Start, duint End); +bool FunctionDelete(duint Address); +void FunctionDelRange(duint Start, duint End); +void FunctionCacheSave(JSON Root); +void FunctionCacheLoad(JSON Root); +bool FunctionEnum(FUNCTIONSINFO* List, size_t* Size); void FunctionClear(); \ No newline at end of file diff --git a/src/dbg/handle.h b/src/dbg/handle.h index 645acd01..f98b556d 100644 --- a/src/dbg/handle.h +++ b/src/dbg/handle.h @@ -1,51 +1,51 @@ -#ifndef _HANDLE_H -#define _HANDLE_H - -#include - -class Handle -{ -public: - Handle(HANDLE h = nullptr) - { - mHandle = h; - } - - ~Handle() - { - Close(); - } - - void Close() - { - DWORD dwFlags = 0; - if(GetHandleInformation(mHandle, &dwFlags) && !(dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE)) - CloseHandle(mHandle); - mHandle = INVALID_HANDLE_VALUE; - } - - const HANDLE & operator=(const HANDLE & h) - { - return mHandle = h; - } - - operator HANDLE & () - { - return mHandle; - } - - bool operator!() const - { - return (!mHandle || mHandle == INVALID_HANDLE_VALUE); - } - - operator bool() const - { - return !this; - } - -private: - HANDLE mHandle; -}; - +#ifndef _HANDLE_H +#define _HANDLE_H + +#include + +class Handle +{ +public: + Handle(HANDLE h = nullptr) + { + mHandle = h; + } + + ~Handle() + { + Close(); + } + + void Close() + { + DWORD dwFlags = 0; + if(GetHandleInformation(mHandle, &dwFlags) && !(dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE)) + CloseHandle(mHandle); + mHandle = INVALID_HANDLE_VALUE; + } + + const HANDLE & operator=(const HANDLE & h) + { + return mHandle = h; + } + + operator HANDLE & () + { + return mHandle; + } + + bool operator!() const + { + return (!mHandle || mHandle == INVALID_HANDLE_VALUE); + } + + operator bool() const + { + return !this; + } + +private: + HANDLE mHandle; +}; + #endif //_HANDLE_H \ No newline at end of file diff --git a/src/dbg/instruction.cpp b/src/dbg/instruction.cpp index 954e3c44..70eca16a 100644 --- a/src/dbg/instruction.cpp +++ b/src/dbg/instruction.cpp @@ -1,2250 +1,2250 @@ -/** -@file instruction.cpp - -@brief Implements the instruction class. -*/ - -#include "instruction.h" -#include "variable.h" -#include "console.h" -#include "value.h" -#include "command.h" -#include "database.h" -#include "addrinfo.h" -#include "assemble.h" -#include "debugger.h" -#include "memory.h" -#include "x64_dbg.h" -#include "disasm_fast.h" -#include "reference.h" -#include "disasm_helper.h" -#include "comment.h" -#include "label.h" -#include "bookmark.h" -#include "function.h" -#include "loop.h" -#include "patternfind.h" -#include "module.h" -#include "stringformat.h" -#include "filehelper.h" -#include "linearanalysis.h" -#include "controlflowanalysis.h" -#include "analysis_nukem.h" -#include "exceptiondirectoryanalysis.h" -#include "_scriptapi_stack.h" -#include "threading.h" - -static bool bRefinit = false; -static int maxFindResults = 5000; - -CMDRESULT cbBadCmd(int argc, char* argv[]) -{ - duint value = 0; - int valsize = 0; - bool isvar = false; - bool hexonly = false; - if (valfromstring(*argv, &value, false, false, &valsize, &isvar, &hexonly)) //dump variable/value/register/etc - { - //dprintf("[DEBUG] valsize: %d\n", valsize); - if (valsize) - valsize *= 2; - else - valsize = 1; - char format_str[deflen] = ""; - if (isvar)// and *cmd!='.' and *cmd!='x') //prevent stupid 0=0 stuff - { - if (value > 15 && !hexonly) - { - if (!valuesignedcalc()) //signed numbers - sprintf(format_str, "%%s=%%.%d" fext "X (%%" fext "ud)\n", valsize); - else - sprintf(format_str, "%%s=%%.%d" fext "X (%%" fext "d)\n", valsize); - dprintf(format_str, *argv, value, value); - } - else - { - sprintf(format_str, "%%s=%%.%d" fext "X\n", valsize); - dprintf(format_str, *argv, value); - } - } - else - { - if (value > 15 && !hexonly) - { - if (!valuesignedcalc()) //signed numbers - sprintf(format_str, "%%s=%%.%d" fext "X (%%" fext "ud)\n", valsize); - else - sprintf(format_str, "%%s=%%.%d" fext "X (%%" fext "d)\n", valsize); - sprintf(format_str, "%%.%d" fext "X (%%" fext "ud)\n", valsize); - dprintf(format_str, value, value); - } - else - { - sprintf(format_str, "%%.%d" fext "X\n", valsize); - dprintf(format_str, value); - } - } - } - else //unknown command - { - dprintf("unknown command/expression: \"%s\"\n", *argv); - return STATUS_ERROR; - } - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrVar(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - char arg2[deflen] = ""; //var value (optional) - if (argc > 2) - strcpy_s(arg2, argv[2]); - duint value = 0; - int add = 0; - if (*argv[1] == '$') - add++; - if (valfromstring(argv[1] + add, &value)) - { - dprintf("invalid variable name \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - if (!valfromstring(arg2, &value)) - { - dprintf("invalid value \"%s\"\n", arg2); - return STATUS_ERROR; - } - if (!varnew(argv[1], value, VAR_USER)) - { - dprintf("error creating variable \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - else - { - if (value > 15) - dprintf("%s=%" fext "X (%" fext "ud)\n", argv[1], value, value); - else - dprintf("%s=%" fext "X\n", argv[1], value); - } - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrVarDel(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - if (!vardel(argv[1], false)) - dprintf("could not delete variable \"%s\"\n", argv[1]); - else - dprintf("deleted variable \"%s\"\n", argv[1]); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrMov(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments"); - return STATUS_ERROR; - } - - String srcText = argv[2]; - if (srcText[0] == '#' && srcText[srcText.length() - 1] == '#') //handle mov addr, #DATA# - { - //do some checks on the data - String dataText = srcText.substr(1, srcText.length() - 2); - int len = (int)dataText.length(); - if (len % 2) - { - dprintf("invalid hex string \"%s\" (length not divisible by 2)\n"); - return STATUS_ERROR; - } - for (int i = 0; i < len; i++) - { - if (!isxdigit(dataText[i])) - { - dprintf("invalid hex string \"%s\" (contains invalid characters)\n", dataText.c_str()); - return STATUS_ERROR; - } - } - //Check the destination - duint dest; - if (!valfromstring(argv[1], &dest) || !MemIsValidReadPtr(dest)) - { - dprintf("invalid destination \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - //Convert text to byte array (very ugly) - Memory data(len / 2); - for (int i = 0, j = 0; i < len; i += 2, j++) - { - char b[3] = ""; - b[0] = dataText[i]; - b[1] = dataText[i + 1]; - int res = 0; - sscanf_s(b, "%X", &res); - data()[j] = res; - } - //Move data to destination - if (!MemWrite(dest, data(), data.size())) - { - dprintf("failed to write to " fhex "\n", dest); - return STATUS_ERROR; - } - GuiUpdateAllViews(); //refresh disassembly/dump/etc - return STATUS_CONTINUE; - } - else - { - duint set_value = 0; - if (!valfromstring(srcText.c_str(), &set_value)) - { - dprintf("invalid src \"%s\"\n", argv[2]); - return STATUS_ERROR; - } - bool isvar = false; - duint temp = 0; - valfromstring(argv[1], &temp, true, false, 0, &isvar, 0); - if (!isvar) - isvar = vargettype(argv[1], 0); - if (!isvar || !valtostring(argv[1], set_value, true)) - { - duint value; - if (valfromstring(argv[1], &value)) //if the var is a value already it's an invalid destination - { - dprintf("invalid dest \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - varnew(argv[1], set_value, VAR_USER); - } - } - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrVarList(int argc, char* argv[]) -{ - int filter = 0; - if (argc > 1) - { - if (!_stricmp(argv[1], "USER")) - filter = VAR_USER; - else if (!_stricmp(argv[1], "READONLY")) - filter = VAR_READONLY; - else if (!_stricmp(argv[1], "SYSTEM")) - filter = VAR_SYSTEM; - } - - size_t cbsize = 0; - if (!varenum(0, &cbsize)) - { - dputs("no variables!"); - return STATUS_CONTINUE; - } - Memory variables(cbsize, "cbInstrVarList:variables"); - if (!varenum(variables(), 0)) - { - dputs("error listing variables!"); - return STATUS_ERROR; - } - - int varcount = (int)cbsize / sizeof(VAR); - for (int i = 0; i < varcount; i++) - { - if (variables()[i].alias.length()) - continue; - char name[deflen] = ""; - strcpy_s(name, variables()[i].name.c_str()); - duint value = (duint)variables()[i].value.u.value; - if (variables()[i].type != VAR_HIDDEN) - { - if (filter) - { - if (variables()[i].type == filter) - { - if (value > 15) - dprintf("%s=%" fext "X (%" fext "ud)\n", name, value, value); - else - dprintf("%s=%" fext "X\n", name, value); - } - } - else - { - if (value > 15) - dprintf("%s=%" fext "X (%" fext "ud)\n", name, value, value); - else - dprintf("%s=%" fext "X\n", name, value); - } - } - } - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrChd(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - if (!DirExists(argv[1])) - { - dputs("directory doesn't exist"); - return STATUS_ERROR; - } - SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(argv[1]).c_str()); - dputs("current directory changed!"); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrCmt(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if (!valfromstring(argv[1], &addr, false)) - return STATUS_ERROR; - if (!CommentSet(addr, argv[2], true)) - { - dputs("error setting comment"); - return STATUS_ERROR; - } - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrCmtdel(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if (!valfromstring(argv[1], &addr, false)) - return STATUS_ERROR; - if (!CommentDelete(addr)) - { - dputs("error deleting comment"); - return STATUS_ERROR; - } - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrLbl(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if (!valfromstring(argv[1], &addr, false)) - return STATUS_ERROR; - if (!LabelSet(addr, argv[2], true)) - { - dputs("error setting label"); - return STATUS_ERROR; - } - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrLbldel(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if (!valfromstring(argv[1], &addr, false)) - return STATUS_ERROR; - if (!LabelDelete(addr)) - { - dputs("error deleting label"); - return STATUS_ERROR; - } - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrBookmarkSet(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if (!valfromstring(argv[1], &addr, false)) - return STATUS_ERROR; - if (!BookmarkSet(addr, true)) - { - dputs("failed to set bookmark!"); - return STATUS_ERROR; - } - dputs("bookmark set!"); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrBookmarkDel(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if (!valfromstring(argv[1], &addr, false)) - return STATUS_ERROR; - if (!BookmarkDelete(addr)) - { - dputs("failed to delete bookmark!"); - return STATUS_ERROR; - } - dputs("bookmark deleted!"); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrLoaddb(int argc, char* argv[]) -{ - DBLoad(); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrSavedb(int argc, char* argv[]) -{ - DBSave(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrAssemble(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if (!valfromstring(argv[1], &addr)) - { - dprintf("invalid expression: \"%s\"!\n", argv[1]); - return STATUS_ERROR; - } - if (!DbgMemIsValidReadPtr(addr)) - { - dprintf("invalid address: " fhex "!\n", addr); - return STATUS_ERROR; - } - bool fillnop = false; - if (argc > 3) - fillnop = true; - char error[MAX_ERROR_SIZE] = ""; - int size = 0; - if (!assembleat(addr, argv[2], &size, error, fillnop)) - { - varset("$result", size, false); - dprintf("failed to assemble \"%s\" (%s)\n", argv[2], error); - return STATUS_ERROR; - } - varset("$result", size, false); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrFunctionAdd(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint start = 0; - duint end = 0; - if (!valfromstring(argv[1], &start, false) || !valfromstring(argv[2], &end, false)) - return STATUS_ERROR; - if (!FunctionAdd(start, end, true)) - { - dputs("failed to add function"); - return STATUS_ERROR; - } - dputs("function added!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrFunctionDel(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if (!valfromstring(argv[1], &addr, false)) - return STATUS_ERROR; - if (!FunctionDelete(addr)) - { - dputs("failed to delete function"); - return STATUS_ERROR; - } - dputs("function deleted!"); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrCmp(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint arg1 = 0; - if (!valfromstring(argv[1], &arg1, false)) - return STATUS_ERROR; - duint arg2 = 0; - if (!valfromstring(argv[2], &arg2, false)) - return STATUS_ERROR; - duint ezflag; - duint bsflag; - if (arg1 == arg2) - ezflag = 1; - else - ezflag = 0; - if (valuesignedcalc()) //signed comparision - { - if ((dsint)arg1 < (dsint)arg2) - bsflag = 0; - else - bsflag = 1; - } - else //unsigned comparision - { - if (arg1 > arg2) - bsflag = 1; - else - bsflag = 0; - } - varset("$_EZ_FLAG", ezflag, true); - varset("$_BS_FLAG", bsflag, true); - //dprintf("$_EZ_FLAG=%d, $_BS_FLAG=%d\n", ezflag, bsflag); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrGpa(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - char newcmd[deflen] = ""; - if (argc >= 3) - sprintf(newcmd, "%s:%s", argv[2], argv[1]); - else - sprintf(newcmd, "%s", argv[1]); - duint result = 0; - if (!valfromstring(newcmd, &result, false)) - return STATUS_ERROR; - varset("$RESULT", result, false); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrAdd(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - return cmddirectexec("mov %s,%s+%s", argv[1], argv[1], argv[2]); -} - -CMDRESULT cbInstrAnd(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - return cmddirectexec("mov %s,%s&%s", argv[1], argv[1], argv[2]); -} - -CMDRESULT cbInstrDec(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - return cmddirectexec("mov %s,%s-1", argv[1], argv[1]); -} - -CMDRESULT cbInstrDiv(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - return cmddirectexec("mov %s,%s/%s", argv[1], argv[1], argv[2]); -} - -CMDRESULT cbInstrInc(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - return cmddirectexec("mov %s,%s+1", argv[1], argv[1]); -} - -CMDRESULT cbInstrMul(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - return cmddirectexec("mov %s,%s*%s", argv[1], argv[1], argv[2]); -} - -CMDRESULT cbInstrNeg(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - return cmddirectexec("mov %s,%s*-1", argv[1], argv[1]); -} - -CMDRESULT cbInstrNot(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - return cmddirectexec("mov %s,~%s", argv[1], argv[1]); -} - -CMDRESULT cbInstrOr(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - return cmddirectexec("mov %s,%s|%s", argv[1], argv[1], argv[2]); -} - -CMDRESULT cbInstrRol(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - bool signedcalc = valuesignedcalc(); - valuesetsignedcalc(true); //rol = signed - CMDRESULT res = cmddirectexec("mov %s,%s<%s", argv[1], argv[1], argv[2]); - valuesetsignedcalc(signedcalc); - return res; -} - -CMDRESULT cbInstrRor(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - bool signedcalc = valuesignedcalc(); - valuesetsignedcalc(true); //ror = signed - CMDRESULT res = cmddirectexec("mov %s,%s>%s", argv[1], argv[1], argv[2]); - valuesetsignedcalc(signedcalc); - return res; -} - -CMDRESULT cbInstrShl(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - bool signedcalc = valuesignedcalc(); - valuesetsignedcalc(false); //shl = unsigned - CMDRESULT res = cmddirectexec("mov %s,%s<%s", argv[1], argv[1], argv[2]); - valuesetsignedcalc(signedcalc); - return res; -} - -CMDRESULT cbInstrShr(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - bool signedcalc = valuesignedcalc(); - valuesetsignedcalc(false); //shr = unsigned - CMDRESULT res = cmddirectexec("mov %s,%s>%s", argv[1], argv[1], argv[2]); - valuesetsignedcalc(signedcalc); - return res; -} - -CMDRESULT cbInstrSub(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - return cmddirectexec("mov %s,%s-%s", argv[1], argv[1], argv[2]); -} - -CMDRESULT cbInstrTest(int argc, char* argv[]) -{ - //TODO: test - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint arg1 = 0; - if (!valfromstring(argv[1], &arg1, false)) - return STATUS_ERROR; - duint arg2 = 0; - if (!valfromstring(argv[2], &arg2, false)) - return STATUS_ERROR; - duint ezflag; - duint bsflag = 0; - if (!(arg1 & arg2)) - ezflag = 1; - else - ezflag = 0; - varset("$_EZ_FLAG", ezflag, true); - varset("$_BS_FLAG", bsflag, true); - //dprintf("$_EZ_FLAG=%d, $_BS_FLAG=%d\n", ezflag, bsflag); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrXor(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - return cmddirectexec("mov %s,%s^%s", argv[1], argv[1], argv[2]); -} - -CMDRESULT cbInstrPush(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint value; - if (!valfromstring(argv[1], &value)) - { - dprintf("invalid argument \"%s\"!\n", argv[1]); - return STATUS_ERROR; - } - Script::Stack::Push(value); - duint csp = GetContextDataEx(hActiveThread, UE_CSP); - DebugUpdateStack(csp, csp); - GuiUpdateRegisterView(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrPop(int argc, char* argv[]) -{ - duint value = Script::Stack::Pop(); - duint csp = GetContextDataEx(hActiveThread, UE_CSP); - DebugUpdateStack(csp, csp); - GuiUpdateRegisterView(); - if (argc > 1) - { - if (!valtostring(argv[1], value, false)) - return STATUS_ERROR; - } - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrRefinit(int argc, char* argv[]) -{ - GuiReferenceInitialize("Script"); - GuiReferenceAddColumn(sizeof(duint) * 2, "Address"); - GuiReferenceAddColumn(0, "Data"); - GuiReferenceSetRowCount(0); - GuiReferenceReloadData(); - bRefinit = true; - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrRefadd(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if (!valfromstring(argv[1], &addr, false)) - return STATUS_ERROR; - if (!bRefinit) - cbInstrRefinit(argc, argv); - int index = GuiReferenceGetRowCount(); - GuiReferenceSetRowCount(index + 1); - char addr_text[deflen] = ""; - sprintf(addr_text, fhex, addr); - GuiReferenceSetCellContent(index, 0, addr_text); - GuiReferenceSetCellContent(index, 1, argv[2]); - GuiReferenceReloadData(); - return STATUS_CONTINUE; -} - -struct VALUERANGE -{ - duint start; - duint end; -}; - -static bool cbRefFind(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo) -{ - if (!disasm || !basicinfo) //initialize - { - GuiReferenceInitialize(refinfo->name); - GuiReferenceAddColumn(2 * sizeof(duint), "Address"); - GuiReferenceAddColumn(0, "Disassembly"); - GuiReferenceSetRowCount(0); - GuiReferenceReloadData(); - return true; - } - bool found = false; - VALUERANGE* range = (VALUERANGE*)refinfo->userinfo; - duint start = range->start; - duint end = range->end; - if ((basicinfo->type & TYPE_VALUE) == TYPE_VALUE) - { - duint value = basicinfo->value.value; - if (value >= start && value <= end) - found = true; - } - if ((basicinfo->type & TYPE_MEMORY) == TYPE_MEMORY) - { - duint value = basicinfo->memory.value; - if (value >= start && value <= end) - found = true; - } - if ((basicinfo->type & TYPE_ADDR) == TYPE_ADDR) - { - duint value = basicinfo->addr; - if (value >= start && value <= end) - found = true; - } - if (found) - { - char addrText[20] = ""; - sprintf(addrText, "%p", disasm->Address()); - GuiReferenceSetRowCount(refinfo->refcount + 1); - GuiReferenceSetCellContent(refinfo->refcount, 0, addrText); - char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; - if (GuiGetDisassembly((duint)disasm->Address(), disassembly)) - GuiReferenceSetCellContent(refinfo->refcount, 1, disassembly); - else - GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->InstructionText().c_str()); - } - return found; -} - -CMDRESULT cbInstrRefFind(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - std::string newCommand = std::string("reffindrange ") + argv[1] + std::string(",") + argv[1]; - if (argc > 2) - newCommand += std::string(",") + argv[2]; - if (argc > 3) - newCommand += std::string(",") + argv[3]; - return cmddirectexec(newCommand.c_str()); -} - -CMDRESULT cbInstrRefFindRange(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - VALUERANGE range; - if (!valfromstring(argv[1], &range.start, false)) - return STATUS_ERROR; - if (argc < 3 || !valfromstring(argv[2], &range.end, false)) - range.end = range.start; - duint addr = 0; - if (argc < 4 || !valfromstring(argv[3], &addr)) - addr = GetContextDataEx(hActiveThread, UE_CIP); - duint size = 0; - if (argc >= 5) - if (!valfromstring(argv[4], &size)) - size = 0; - duint ticks = GetTickCount(); - char title[256] = ""; - if (range.start == range.end) - sprintf_s(title, "Constant: %" fext "X", range.start); - else - sprintf_s(title, "Range: %" fext "X-%" fext "X", range.start, range.end); - int found = RefFind(addr, size, cbRefFind, &range, false, title); - dprintf("%u reference(s) in %ums\n", found, GetTickCount() - ticks); - varset("$result", found, false); - return STATUS_CONTINUE; -} - -bool cbRefStr(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo) -{ - if (!disasm || !basicinfo) //initialize - { - GuiReferenceInitialize(refinfo->name); - GuiReferenceAddColumn(2 * sizeof(duint), "Address"); - GuiReferenceAddColumn(64, "Disassembly"); - GuiReferenceAddColumn(500, "String"); - GuiReferenceSetSearchStartCol(2); //only search the strings - GuiReferenceReloadData(); - return true; - } - bool found = false; - STRING_TYPE strtype; - char string[1024] = ""; - if (basicinfo->branch) //branches have no strings (jmp dword [401000]) - return false; - if ((basicinfo->type & TYPE_VALUE) == TYPE_VALUE) - { - if (disasmgetstringat(basicinfo->value.value, &strtype, string, string, 500)) - found = true; - } - if ((basicinfo->type & TYPE_MEMORY) == TYPE_MEMORY) - { - if (!found && disasmgetstringat(basicinfo->memory.value, &strtype, string, string, 500)) - found = true; - } - if (found) - { - char addrText[20] = ""; - sprintf(addrText, "%p", disasm->Address()); - GuiReferenceSetRowCount(refinfo->refcount + 1); - GuiReferenceSetCellContent(refinfo->refcount, 0, addrText); - char disassembly[4096] = ""; - if (GuiGetDisassembly((duint)disasm->Address(), disassembly)) - GuiReferenceSetCellContent(refinfo->refcount, 1, disassembly); - else - GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->InstructionText().c_str()); - char dispString[1024] = ""; - if (strtype == str_ascii) - sprintf(dispString, "\"%s\"", string); - else - sprintf(dispString, "L\"%s\"", string); - GuiReferenceSetCellContent(refinfo->refcount, 2, dispString); - } - return found; -} - -CMDRESULT cbInstrRefStr(int argc, char* argv[]) -{ - duint addr; - if (argc < 2 || !valfromstring(argv[1], &addr, true)) - addr = GetContextDataEx(hActiveThread, UE_CIP); - duint size = 0; - if (argc >= 3) - if (!valfromstring(argv[2], &size, true)) - size = 0; - duint ticks = GetTickCount(); - int found = RefFind(addr, size, cbRefStr, 0, false, "Strings"); - dprintf("%u string(s) in %ums\n", found, GetTickCount() - ticks); - varset("$result", found, false); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrSetstr(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - varnew(argv[1], 0, VAR_USER); - if (!vargettype(argv[1], 0)) - { - dprintf("no such variable \"%s\"!\n", argv[1]); - return STATUS_ERROR; - } - if (!varset(argv[1], argv[2], false)) - { - dprintf("failed to set variable \"%s\"!\n", argv[1]); - return STATUS_ERROR; - } - cmddirectexec("getstr \"%s\"", argv[1]); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrGetstr(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - VAR_VALUE_TYPE valtype; - if (!vargettype(argv[1], 0, &valtype)) - { - dprintf("no such variable \"%s\"!\n", argv[1]); - return STATUS_ERROR; - } - if (valtype != VAR_STRING) - { - dprintf("variable \"%s\" is not a string!\n", argv[1]); - return STATUS_ERROR; - } - int size; - if (!varget(argv[1], (char*)0, &size, 0) || !size) - { - dprintf("failed to get variable size \"%s\"!\n", argv[1]); - return STATUS_ERROR; - } - Memory string(size + 1, "cbInstrGetstr:string"); - if (!varget(argv[1], string(), &size, 0)) - { - dprintf("failed to get variable data \"%s\"!\n", argv[1]); - return STATUS_ERROR; - } - dprintf("%s=\"%s\"\n", argv[1], string()); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrCopystr(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - VAR_VALUE_TYPE valtype; - if (!vargettype(argv[2], 0, &valtype)) - { - dprintf("no such variable \"%s\"!\n", argv[2]); - return STATUS_ERROR; - } - if (valtype != VAR_STRING) - { - dprintf("variable \"%s\" is not a string!\n", argv[2]); - return STATUS_ERROR; - } - int size; - if (!varget(argv[2], (char*)0, &size, 0) || !size) - { - dprintf("failed to get variable size \"%s\"!\n", argv[2]); - return STATUS_ERROR; - } - Memory string(size + 1, "cbInstrGetstr:string"); - if (!varget(argv[2], string(), &size, 0)) - { - dprintf("failed to get variable data \"%s\"!\n", argv[2]); - return STATUS_ERROR; - } - duint addr; - if (!valfromstring(argv[1], &addr)) - { - dprintf("invalid address \"%s\"!\n", argv[1]); - return STATUS_ERROR; - } - if (!MemPatch(addr, string(), strlen(string()))) - { - dputs("memwrite failed!"); - return STATUS_ERROR; - } - dputs("string written!"); - GuiUpdateAllViews(); - GuiUpdatePatches(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrFind(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if (!valfromstring(argv[1], &addr, false)) - return STATUS_ERROR; - char pattern[deflen] = ""; - //remove # from the start and end of the pattern (ODBGScript support) - if (argv[2][0] == '#') - strcpy_s(pattern, argv[2] + 1); - else - strcpy_s(pattern, argv[2]); - int len = (int)strlen(pattern); - if (pattern[len - 1] == '#') - pattern[len - 1] = '\0'; - duint size = 0; - duint base = MemFindBaseAddr(addr, &size, true); - if (!base) - { - dprintf("invalid memory address " fhex "!\n", addr); - return STATUS_ERROR; - } - Memory data(size, "cbInstrFind:data"); - if (!MemRead(base, data(), size)) - { - dputs("failed to read memory!"); - return STATUS_ERROR; - } - duint start = addr - base; - duint find_size = 0; - if (argc >= 4) - { - if (!valfromstring(argv[3], &find_size)) - find_size = size - start; - if (find_size > (size - start)) - find_size = size - start; - } - else - find_size = size - start; - duint foundoffset = patternfind(data() + start, find_size, pattern); - duint result = 0; - if (foundoffset != -1) - result = addr + foundoffset; - varset("$result", result, false); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrFindAll(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if (!valfromstring(argv[1], &addr, false)) - return STATUS_ERROR; - - char pattern[deflen] = ""; - //remove # from the start and end of the pattern (ODBGScript support) - if (argv[2][0] == '#') - strcpy_s(pattern, argv[2] + 1); - else - strcpy_s(pattern, argv[2]); - int len = (int)strlen(pattern); - if (pattern[len - 1] == '#') - pattern[len - 1] = '\0'; - duint size = 0; - duint base = MemFindBaseAddr(addr, &size, true); - if (!base) - { - dprintf("invalid memory address " fhex "!\n", addr); - return STATUS_ERROR; - } - Memory data(size, "cbInstrFindAll:data"); - if (!MemRead(base, data(), size)) - { - dputs("failed to read memory!"); - return STATUS_ERROR; - } - duint start = addr - base; - duint find_size = 0; - bool findData = false; - if (argc >= 4) - { - if (!_stricmp(argv[3], "&data&")) - { - find_size = size - start; - findData = true; - } - else if (!valfromstring(argv[3], &find_size)) - find_size = size - start; - else if (find_size > (size - start)) - find_size = size - start; - } - else - find_size = size - start; - //setup reference view - char patternshort[256] = ""; - strncpy_s(patternshort, pattern, min(16, len)); - if (len > 16) - strcat_s(patternshort, "..."); - char patterntitle[256] = ""; - sprintf_s(patterntitle, "Pattern: %s", patternshort); - GuiReferenceInitialize(patterntitle); - GuiReferenceAddColumn(2 * sizeof(duint), "Address"); - if (findData) - GuiReferenceAddColumn(0, "&Data&"); - else - GuiReferenceAddColumn(0, "Disassembly"); - GuiReferenceReloadData(); - DWORD ticks = GetTickCount(); - int refCount = 0; - duint i = 0; - duint result = 0; - std::vector searchpattern; - if (!patterntransform(pattern, searchpattern)) - { - dputs("failed to transform pattern!"); - return STATUS_ERROR; - } - while (refCount < maxFindResults) - { - duint foundoffset = patternfind(data() + start + i, find_size - i, searchpattern); - if (foundoffset == -1) - break; - i += foundoffset + 1; - result = addr + i - 1; - char msg[deflen] = ""; - sprintf(msg, fhex, result); - GuiReferenceSetRowCount(refCount + 1); - GuiReferenceSetCellContent(refCount, 0, msg); - if (findData) - { - Memory printData(searchpattern.size(), "cbInstrFindAll:printData"); - MemRead(result, printData(), printData.size()); - for (size_t j = 0, k = 0; j < printData.size(); j++) - { - if (j) - k += sprintf(msg + k, " "); - k += sprintf(msg + k, "%.2X", printData()[j]); - } - } - else - { - if (!GuiGetDisassembly(result, msg)) - strcpy_s(msg, "[Error disassembling]"); - } - GuiReferenceSetCellContent(refCount, 1, msg); - result++; - refCount++; - } - GuiReferenceReloadData(); - dprintf("%d occurrences found in %ums\n", refCount, GetTickCount() - ticks); - varset("$result", refCount, false); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrFindMemAll(int argc, char* argv[]) -{ - dprintf("argc: %d\n", argc); - for (int i = 0; i < argc; i++) - { - dprintf("%d:\"%s\"\n", i, argv[i]); - } - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - if (!valfromstring(argv[1], &addr, false)) - return STATUS_ERROR; - - char pattern[deflen] = ""; - //remove # from the start and end of the pattern (ODBGScript support) - if (argv[2][0] == '#') - strcpy_s(pattern, argv[2] + 1); - else - strcpy_s(pattern, argv[2]); - int len = (int)strlen(pattern); - if (pattern[len - 1] == '#') - pattern[len - 1] = '\0'; - std::vector searchpattern; - if (!patterntransform(pattern, searchpattern)) - { - dputs("failed to transform pattern!"); - return STATUS_ERROR; - } - - duint endAddr = -1; - bool findData = false; - if (argc >= 4) - { - if (!_stricmp(argv[3], "&data&")) - findData = true; - else if (!valfromstring(argv[3], &endAddr)) - findData = false; - } - - SHARED_ACQUIRE(LockMemoryPages); - std::vector searchPages; - for (auto & itr : memoryPages) - { - SimplePage page(duint(itr.second.mbi.BaseAddress), itr.second.mbi.RegionSize); - if (page.address >= addr && page.address + page.size <= endAddr) - searchPages.push_back(page); - } - SHARED_RELEASE(); - - DWORD ticks = GetTickCount(); - - std::vector results; - if (!MemFindInMap(searchPages, searchpattern, results, maxFindResults)) - { - dputs("MemFindInMap failed!"); - return STATUS_ERROR; - } - - //setup reference view - char patternshort[256] = ""; - strncpy_s(patternshort, pattern, min(16, len)); - if (len > 16) - strcat_s(patternshort, "..."); - char patterntitle[256] = ""; - sprintf_s(patterntitle, "Pattern: %s", patternshort); - GuiReferenceInitialize(patterntitle); - GuiReferenceAddColumn(2 * sizeof(duint), "Address"); - if (findData) - GuiReferenceAddColumn(0, "&Data&"); - else - GuiReferenceAddColumn(0, "Disassembly"); - GuiReferenceReloadData(); - - int refCount = 0; - for (duint result : results) - { - char msg[deflen] = ""; - sprintf(msg, fhex, result); - GuiReferenceSetRowCount(refCount + 1); - GuiReferenceSetCellContent(refCount, 0, msg); - if (findData) - { - Memory printData(searchpattern.size(), "cbInstrFindAll:printData"); - MemRead(result, printData(), printData.size()); - for (size_t j = 0, k = 0; j < printData.size(); j++) - { - if (j) - k += sprintf(msg + k, " "); - k += sprintf(msg + k, "%.2X", printData()[j]); - } - } - else - { - if (!GuiGetDisassembly(result, msg)) - strcpy_s(msg, "[Error disassembling]"); - } - GuiReferenceSetCellContent(refCount, 1, msg); - refCount++; - } - - GuiReferenceReloadData(); - dprintf("%d occurrences found in %ums\n", refCount, GetTickCount() - ticks); - varset("$result", refCount, false); - - return STATUS_CONTINUE; -} - -static bool cbModCallFind(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo) -{ - if (!disasm || !basicinfo) //initialize - { - GuiReferenceInitialize(refinfo->name); - GuiReferenceAddColumn(2 * sizeof(duint), "Address"); - GuiReferenceAddColumn(0, "Disassembly"); - GuiReferenceReloadData(); - return true; - } - bool found = false; - if (basicinfo->call) //we are looking for calls - { - duint ptr = basicinfo->addr > 0 ? basicinfo->addr : basicinfo->memory.value; - char label[MAX_LABEL_SIZE] = ""; - found = DbgGetLabelAt(ptr, SEG_DEFAULT, label) && !LabelGet(ptr, label); //a non-user label - } - if (found) - { - char addrText[20] = ""; - sprintf(addrText, "%p", disasm->Address()); - GuiReferenceSetRowCount(refinfo->refcount + 1); - GuiReferenceSetCellContent(refinfo->refcount, 0, addrText); - char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; - if (GuiGetDisassembly((duint)disasm->Address(), disassembly)) - GuiReferenceSetCellContent(refinfo->refcount, 1, disassembly); - else - GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->InstructionText().c_str()); - } - return found; -} - -CMDRESULT cbInstrModCallFind(int argc, char* argv[]) -{ - duint addr; - if (argc < 2 || !valfromstring(argv[1], &addr, true)) - addr = GetContextDataEx(hActiveThread, UE_CIP); - duint size = 0; - if (argc >= 3) - if (!valfromstring(argv[2], &size, true)) - size = 0; - duint ticks = GetTickCount(); - int found = RefFind(addr, size, cbModCallFind, 0, false, "Calls"); - dprintf("%u call(s) in %ums\n", found, GetTickCount() - ticks); - varset("$result", found, false); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrCommentList(int argc, char* argv[]) -{ - //setup reference view - GuiReferenceInitialize("Comments"); - GuiReferenceAddColumn(2 * sizeof(duint), "Address"); - GuiReferenceAddColumn(64, "Disassembly"); - GuiReferenceAddColumn(0, "Comment"); - GuiReferenceReloadData(); - size_t cbsize; - CommentEnum(0, &cbsize); - if (!cbsize) - { - dputs("no comments"); - return STATUS_CONTINUE; - } - Memory comments(cbsize, "cbInstrCommentList:comments"); - CommentEnum(comments(), 0); - int count = (int)(cbsize / sizeof(COMMENTSINFO)); - for (int i = 0; i < count; i++) - { - GuiReferenceSetRowCount(i + 1); - char addrText[20] = ""; - sprintf(addrText, "%p", comments()[i].addr); - GuiReferenceSetCellContent(i, 0, addrText); - char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; - if (GuiGetDisassembly(comments()[i].addr, disassembly)) - GuiReferenceSetCellContent(i, 1, disassembly); - GuiReferenceSetCellContent(i, 2, comments()[i].text); - } - varset("$result", count, false); - dprintf("%d comment(s) listed in Reference View\n", count); - GuiReferenceReloadData(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrLabelList(int argc, char* argv[]) -{ - //setup reference view - GuiReferenceInitialize("Labels"); - GuiReferenceAddColumn(2 * sizeof(duint), "Address"); - GuiReferenceAddColumn(64, "Disassembly"); - GuiReferenceAddColumn(0, "Label"); - GuiReferenceReloadData(); - size_t cbsize; - LabelEnum(0, &cbsize); - if (!cbsize) - { - dputs("no labels"); - return STATUS_CONTINUE; - } - Memory labels(cbsize, "cbInstrLabelList:labels"); - LabelEnum(labels(), 0); - int count = (int)(cbsize / sizeof(LABELSINFO)); - for (int i = 0; i < count; i++) - { - GuiReferenceSetRowCount(i + 1); - char addrText[20] = ""; - sprintf(addrText, "%p", labels()[i].addr); - GuiReferenceSetCellContent(i, 0, addrText); - char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; - if (GuiGetDisassembly(labels()[i].addr, disassembly)) - GuiReferenceSetCellContent(i, 1, disassembly); - GuiReferenceSetCellContent(i, 2, labels()[i].text); - } - varset("$result", count, false); - dprintf("%d label(s) listed in Reference View\n", count); - GuiReferenceReloadData(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrBookmarkList(int argc, char* argv[]) -{ - //setup reference view - GuiReferenceInitialize("Bookmarks"); - GuiReferenceAddColumn(2 * sizeof(duint), "Address"); - GuiReferenceAddColumn(0, "Disassembly"); - GuiReferenceReloadData(); - size_t cbsize; - BookmarkEnum(0, &cbsize); - if (!cbsize) - { - dputs("No bookmarks found"); - return STATUS_CONTINUE; - } - Memory bookmarks(cbsize, "cbInstrBookmarkList:bookmarks"); - BookmarkEnum(bookmarks(), 0); - int count = (int)(cbsize / sizeof(BOOKMARKSINFO)); - for (int i = 0; i < count; i++) - { - GuiReferenceSetRowCount(i + 1); - char addrText[20] = ""; - sprintf(addrText, "%p", bookmarks()[i].addr); - GuiReferenceSetCellContent(i, 0, addrText); - char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; - if (GuiGetDisassembly(bookmarks()[i].addr, disassembly)) - GuiReferenceSetCellContent(i, 1, disassembly); - } - varset("$result", count, false); - dprintf("%d bookmark(s) listed\n", count); - GuiReferenceReloadData(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrFunctionList(int argc, char* argv[]) -{ - //setup reference view - GuiReferenceInitialize("Functions"); - GuiReferenceAddColumn(2 * sizeof(duint), "Start"); - GuiReferenceAddColumn(2 * sizeof(duint), "End"); - GuiReferenceAddColumn(64, "Disassembly (Start)"); - GuiReferenceAddColumn(0, "Label/Comment"); - GuiReferenceReloadData(); - size_t cbsize; - FunctionEnum(0, &cbsize); - if (!cbsize) - { - dputs("No functions"); - return STATUS_CONTINUE; - } - Memory functions(cbsize, "cbInstrFunctionList:functions"); - FunctionEnum(functions(), 0); - int count = (int)(cbsize / sizeof(FUNCTIONSINFO)); - for (int i = 0; i < count; i++) - { - GuiReferenceSetRowCount(i + 1); - char addrText[20] = ""; - sprintf(addrText, "%p", functions()[i].start); - GuiReferenceSetCellContent(i, 0, addrText); - sprintf(addrText, "%p", functions()[i].end); - GuiReferenceSetCellContent(i, 1, addrText); - char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; - if (GuiGetDisassembly(functions()[i].start, disassembly)) - GuiReferenceSetCellContent(i, 2, disassembly); - char label[MAX_LABEL_SIZE] = ""; - if (LabelGet(functions()[i].start, label)) - GuiReferenceSetCellContent(i, 3, label); - else - { - char comment[MAX_COMMENT_SIZE] = ""; - if (CommentGet(functions()[i].start, comment)) - GuiReferenceSetCellContent(i, 3, comment); - } - } - varset("$result", count, false); - dprintf("%d function(s) listed\n", count); - GuiReferenceReloadData(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrLoopList(int argc, char* argv[]) -{ - //setup reference view - GuiReferenceInitialize("Loops"); - GuiReferenceAddColumn(2 * sizeof(duint), "Start"); - GuiReferenceAddColumn(2 * sizeof(duint), "End"); - GuiReferenceAddColumn(64, "Disassembly (Start)"); - GuiReferenceAddColumn(0, "Label/Comment"); - GuiReferenceReloadData(); - size_t cbsize; - LoopEnum(0, &cbsize); - if (!cbsize) - { - dputs("no loops"); - return STATUS_CONTINUE; - } - Memory loops(cbsize, "cbInstrLoopList:loops"); - LoopEnum(loops(), 0); - int count = (int)(cbsize / sizeof(LOOPSINFO)); - for (int i = 0; i < count; i++) - { - GuiReferenceSetRowCount(i + 1); - char addrText[20] = ""; - sprintf(addrText, "%p", loops()[i].start); - GuiReferenceSetCellContent(i, 0, addrText); - sprintf(addrText, "%p", loops()[i].end); - GuiReferenceSetCellContent(i, 1, addrText); - char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; - if (GuiGetDisassembly(loops()[i].start, disassembly)) - GuiReferenceSetCellContent(i, 2, disassembly); - char label[MAX_LABEL_SIZE] = ""; - if (LabelGet(loops()[i].start, label)) - GuiReferenceSetCellContent(i, 3, label); - else - { - char comment[MAX_COMMENT_SIZE] = ""; - if (CommentGet(loops()[i].start, comment)) - GuiReferenceSetCellContent(i, 3, comment); - } - } - varset("$result", count, false); - dprintf("%d loop(s) listed\n", count); - GuiReferenceReloadData(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrSleep(int argc, char* argv[]) -{ - duint ms = 100; - if (argc > 1) - if (!valfromstring(argv[1], &ms, false)) - return STATUS_ERROR; - if (ms >= 0xFFFFFFFF) - ms = 100; - Sleep((DWORD)ms); - return STATUS_CONTINUE; -} - -static bool cbFindAsm(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo) -{ - if (!disasm || !basicinfo) //initialize - { - GuiReferenceInitialize(refinfo->name); - GuiReferenceAddColumn(2 * sizeof(duint), "Address"); - GuiReferenceAddColumn(0, "Disassembly"); - GuiReferenceReloadData(); - return true; - } - const char* instruction = (const char*)refinfo->userinfo; - bool found = !_stricmp(instruction, basicinfo->instruction); - if (found) - { - char addrText[20] = ""; - sprintf(addrText, fhex, disasm->Address()); - GuiReferenceSetRowCount(refinfo->refcount + 1); - GuiReferenceSetCellContent(refinfo->refcount, 0, addrText); - char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; - if (GuiGetDisassembly((duint)disasm->Address(), disassembly)) - GuiReferenceSetCellContent(refinfo->refcount, 1, disassembly); - else - GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->InstructionText().c_str()); - } - return found; -} - -CMDRESULT cbInstrFindAsm(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - - duint addr = 0; - if (argc < 3 || !valfromstring(argv[2], &addr)) - addr = GetContextDataEx(hActiveThread, UE_CIP); - duint size = 0; - if (argc >= 4) - if (!valfromstring(argv[3], &size)) - size = 0; - - unsigned char dest[16]; - int asmsize = 0; - char error[MAX_ERROR_SIZE] = ""; - if (!assemble(addr + size / 2, dest, &asmsize, argv[1], error)) - { - dprintf("failed to assemble \"%s\" (%s)!\n", argv[1], error); - return STATUS_ERROR; - } - BASIC_INSTRUCTION_INFO basicinfo; - memset(&basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO)); - disasmfast(dest, addr + size / 2, &basicinfo); - - duint ticks = GetTickCount(); - char title[256] = ""; - sprintf_s(title, "Command: \"%s\"", basicinfo.instruction); - int found = RefFind(addr, size, cbFindAsm, (void*)&basicinfo.instruction[0], false, title); - dprintf("%u result(s) in %ums\n", found, GetTickCount() - ticks); - varset("$result", found, false); - return STATUS_CONTINUE; -} - -static void yaraCompilerCallback(int error_level, const char* file_name, int line_number, const char* message, void* user_data) -{ - switch (error_level) - { - case YARA_ERROR_LEVEL_ERROR: - dprintf("[YARA ERROR] "); - break; - case YARA_ERROR_LEVEL_WARNING: - dprintf("[YARA WARNING] "); - break; - } - dprintf("File: \"%s\", Line: %d, Message: \"%s\"\n", file_name, line_number, message); -} - -static String yara_print_string(const uint8_t* data, int length) -{ - String result = "\""; - const char* str = (const char*)data; - for (int i = 0; i < length; i++) - { - char cur[16] = ""; - if (str[i] >= 32 && str[i] <= 126) - sprintf_s(cur, "%c", str[i]); - else - sprintf_s(cur, "\\x%02X", (uint8_t)str[i]); - result += cur; - } - result += "\""; - return result; -} - -static String yara_print_hex_string(const uint8_t* data, int length) -{ - String result = ""; - for (int i = 0; i < length; i++) - { - if (i) - result += " "; - char cur[16] = ""; - sprintf_s(cur, "%02X", (uint8_t)data[i]); - result += cur; - } - return result; -} - -struct YaraScanInfo -{ - duint base; - int index; -}; - -static int yaraScanCallback(int message, void* message_data, void* user_data) -{ - YaraScanInfo* scanInfo = (YaraScanInfo*)user_data; - switch (message) - { - case CALLBACK_MSG_RULE_MATCHING: - { - duint base = scanInfo->base; - YR_RULE* yrRule = (YR_RULE*)message_data; - dprintf("[YARA] Rule \"%s\" matched:\n", yrRule->identifier); - YR_STRING* string; - yr_rule_strings_foreach(yrRule, string) - { - YR_MATCH* match; - yr_string_matches_foreach(string, match) - { - String pattern; - if (STRING_IS_HEX(string)) - pattern = yara_print_hex_string(match->data, match->length); - else - pattern = yara_print_string(match->data, match->length); - duint addr = (duint)(base + match->base + match->offset); - //dprintf("[YARA] String \"%s\" : %s on 0x%" fext "X\n", string->identifier, pattern.c_str(), addr); - - //update references - int index = scanInfo->index; - GuiReferenceSetRowCount(index + 1); - scanInfo->index++; - char addr_text[deflen] = ""; - sprintf(addr_text, fhex, addr); - GuiReferenceSetCellContent(index, 0, addr_text); //Address - String ruleFullName = ""; - ruleFullName += yrRule->identifier; - ruleFullName += "."; - ruleFullName += string->identifier; - GuiReferenceSetCellContent(index, 1, ruleFullName.c_str()); //Rule - GuiReferenceSetCellContent(index, 2, pattern.c_str()); //Data - } - } - } - break; - - case CALLBACK_MSG_RULE_NOT_MATCHING: - { - YR_RULE* yrRule = (YR_RULE*)message_data; - dprintf("[YARA] Rule \"%s\" did not match!\n", yrRule->identifier); - } - break; - - case CALLBACK_MSG_SCAN_FINISHED: - { - dputs("[YARA] Scan finished!"); - } - break; - - case CALLBACK_MSG_IMPORT_MODULE: - { - YR_MODULE_IMPORT* yrModuleImport = (YR_MODULE_IMPORT*)message_data; - dprintf("[YARA] Imported module \"%s\"!\n", yrModuleImport->module_name); - } - break; - } - return ERROR_SUCCESS; //nicely undocumented what this should be -} - -CMDRESULT cbInstrYara(int argc, char* argv[]) -{ - if (argc < 2) //yara rulesFile, addr_of_mempage, size_of_scan - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint addr = 0; - SELECTIONDATA sel; - GuiSelectionGet(GUI_DISASSEMBLY, &sel); - addr = sel.start; - - duint base = 0; - duint size = 0; - duint mod = ModBaseFromName(argv[2]); - if (mod) - { - base = mod; - size = ModSizeFromAddr(base); - } - else - { - if (!valfromstring(argv[2], &addr)) - { - dprintf("invalid value \"%s\"!\n", argv[2]); - return STATUS_ERROR; - } - - size = 0; - if (argc >= 4) - if (!valfromstring(argv[3], &size)) - size = 0; - if (!size) - addr = MemFindBaseAddr(addr, &size); - base = addr; - } - Memory data(size); - if (!MemRead(base, data(), size)) - { - dprintf("failed to read memory page %p[%X]!\n", base, size); - return STATUS_ERROR; - } - - String rulesContent; - if (!FileHelper::ReadAllText(argv[1], rulesContent)) - { - dprintf("Failed to read the rules file \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - - bool bSuccess = false; - YR_COMPILER* yrCompiler; - if (yr_compiler_create(&yrCompiler) == ERROR_SUCCESS) - { - yr_compiler_set_callback(yrCompiler, yaraCompilerCallback, 0); - if (yr_compiler_add_string(yrCompiler, rulesContent.c_str(), nullptr) == 0) //no errors found - { - YR_RULES* yrRules; - if (yr_compiler_get_rules(yrCompiler, &yrRules) == ERROR_SUCCESS) - { - //initialize new reference tab - char modname[MAX_MODULE_SIZE] = ""; - if (!ModNameFromAddr(base, modname, true)) - sprintf_s(modname, "%p", base); - String fullName; - const char* fileName = strrchr(argv[1], '\\'); - if (fileName) - fullName = fileName + 1; - else - fullName = argv[1]; - fullName += " ("; - fullName += modname; - fullName += ")"; //nanana, very ugly code (long live open source) - GuiReferenceInitialize(fullName.c_str()); - GuiReferenceAddColumn(sizeof(duint) * 2, "Address"); - GuiReferenceAddColumn(48, "Rule"); - GuiReferenceAddColumn(0, "Data"); - GuiReferenceSetRowCount(0); - GuiReferenceReloadData(); - YaraScanInfo scanInfo; - scanInfo.base = base; - scanInfo.index = 0; - duint ticks = GetTickCount(); - dputs("[YARA] Scan started..."); - int err = yr_rules_scan_mem(yrRules, data(), size, 0, yaraScanCallback, &scanInfo, 0); - GuiReferenceReloadData(); - switch (err) - { - case ERROR_SUCCESS: - dprintf("%u scan results in %ums...\n", scanInfo.index, GetTickCount() - ticks); - bSuccess = true; - break; - case ERROR_TOO_MANY_MATCHES: - dputs("too many matches!"); - break; - default: - dputs("error while scanning memory!"); - break; - } - yr_rules_destroy(yrRules); - } - else - dputs("error while getting the rules!"); - } - else - dputs("errors in the rules file!"); - yr_compiler_destroy(yrCompiler); - } - else - dputs("yr_compiler_create failed!"); - return bSuccess ? STATUS_CONTINUE : STATUS_ERROR; -} - -CMDRESULT cbInstrYaramod(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint base = ModBaseFromName(argv[2]); - if (!base) - { - dprintf("invalid module \"%s\"!\n", argv[2]); - return STATUS_ERROR; - } - duint size = ModSizeFromAddr(base); - return cmddirectexec("yara \"%s\",%p,%p", argv[1], base, size); -} - -CMDRESULT cbInstrLog(int argc, char* argv[]) -{ - //log "format {0} string",arg1, arg2, argN - if (argc == 1) //just log newline - { - dputs(""); - return STATUS_CONTINUE; - } - FormatValueVector formatArgs; - for (int i = 2; i < argc; i++) - formatArgs.push_back(argv[i]); - String logString = stringformat(argv[1], formatArgs); - dputs(logString.c_str()); - return STATUS_CONTINUE; -} - -#include - -CMDRESULT cbInstrCapstone(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("not enough arguments..."); - return STATUS_ERROR; - } - - duint addr = 0; - if (!valfromstring(argv[1], &addr) || !MemIsValidReadPtr(addr)) - { - dprintf("invalid address \"%s\"\n", argv[1]); - return STATUS_ERROR; - } - - unsigned char data[16]; - if (!MemRead(addr, data, sizeof(data))) - { - dprintf("could not read memory at %p\n", addr); - return STATUS_ERROR; - } - - Capstone cp; - if (!cp.Disassemble(addr, data)) - { - dprintf("failed to disassemble!"); - return STATUS_ERROR; - } - - const cs_insn* instr = cp.GetInstr(); - const cs_x86 & x86 = cp.x86(); - int argcount = x86.op_count; - dprintf("%s %s\n", instr->mnemonic, instr->op_str); - dprintf("size: %d, id: %d, opcount: %d\n", cp.Size(), cp.GetId(), cp.OpCount()); - for (int i = 0; i < argcount; i++) - { - const cs_x86_op & op = x86.operands[i]; - dprintf("operand \"%s\" %d, ", cp.OperandText(i).c_str(), i + 1); - switch (op.type) - { - case X86_OP_REG: - dprintf("register: %s\n", cp.RegName((x86_reg)op.reg)); - break; - case X86_OP_IMM: - dprintf("immediate: 0x%p\n", op.imm); - break; - case X86_OP_MEM: - { - //[base + index * scale +/- disp] - const x86_op_mem & mem = op.mem; - dprintf("memory segment: %s, base: %s, index: %s, scale: %d, displacement: 0x%p\n", - cp.RegName((x86_reg)mem.segment), - cp.RegName((x86_reg)mem.base), - cp.RegName((x86_reg)mem.index), - mem.scale, - mem.disp); - } - break; - case X86_OP_FP: - dprintf("float: %f\n", op.fp); - break; - } - } - - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrAnalyseNukem(int argc, char* argv[]) -{ - SELECTIONDATA sel; - GuiSelectionGet(GUI_DISASSEMBLY, &sel); - duint size = 0; - duint base = MemFindBaseAddr(sel.start, &size); - Analyse_nukem(base, size); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrAnalyse(int argc, char* argv[]) -{ - SELECTIONDATA sel; - GuiSelectionGet(GUI_DISASSEMBLY, &sel); - duint size = 0; - duint base = MemFindBaseAddr(sel.start, &size); - LinearAnalysis anal(base, size); - anal.Analyse(); - anal.SetMarkers(); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrCfanalyse(int argc, char* argv[]) -{ - bool exceptionDirectory = false; - if (argc > 1) - exceptionDirectory = true; - SELECTIONDATA sel; - GuiSelectionGet(GUI_DISASSEMBLY, &sel); - duint size = 0; - duint base = MemFindBaseAddr(sel.start, &size); - ControlFlowAnalysis anal(base, size, exceptionDirectory); - anal.Analyse(); - anal.SetMarkers(); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrExanalyse(int argc, char* argv[]) -{ - SELECTIONDATA sel; - GuiSelectionGet(GUI_DISASSEMBLY, &sel); - duint size = 0; - duint base = MemFindBaseAddr(sel.start, &size); - ExceptionDirectoryAnalysis anal(base, size); - anal.Analyse(); - anal.SetMarkers(); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrVirtualmod(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("Not enough arguments!"); - return STATUS_ERROR; - } - duint base; - if (!valfromstring(argv[2], &base)) - { - dputs("Invalid parameter [base]!"); - return STATUS_ERROR; - } - if (!MemIsValidReadPtr(base)) - { - dputs("Invalid memory address!"); - return STATUS_ERROR; - } - duint size; - if (argc < 4) - base = MemFindBaseAddr(base, &size); - else if (!valfromstring(argv[3], &size)) - { - dputs("Invalid parameter [size]"); - return STATUS_ERROR; - } - auto name = String("virtual:\\") + (argv[1]); - if (!ModLoad(base, size, name.c_str())) - { - dputs("Failed to load module (ModLoad)..."); - return STATUS_ERROR; - } - - char modname[256] = ""; - if (ModNameFromAddr(base, modname, true)) - BpEnumAll(cbSetModuleBreakpoints, modname); - - dprintf("Virtual module \"%s\" loaded on %p[%p]!\n", argv[1], base, size); - GuiUpdateAllViews(); - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrVisualize(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - duint start; - duint maxaddr; - if (!valfromstring(argv[1], &start) || !valfromstring(argv[2], &maxaddr)) - { - dputs("invalid arguments!"); - return STATUS_ERROR; - } - //actual algorithm - //make sure to set these options in the INI (rest the default theme of x64dbg): - //DisassemblyBookmarkBackgroundColor = #00FFFF - //DisassemblyBookmarkColor = #000000 - //DisassemblyHardwareBreakpointBackgroundColor = #00FF00 - //DisassemblyHardwareBreakpointColor = #000000 - //DisassemblyBreakpointBackgroundColor = #FF0000 - //DisassemblyBreakpointColor = #000000 - { - //initialize - Capstone _cp; - duint _base = start; - duint _size = maxaddr - start; - Memory _data(_size); - MemRead(_base, _data(), _size); - FunctionClear(); - - //linear search with some trickery - duint end = 0; - duint jumpback = 0; - for (duint addr = start, fardest = 0; addr < maxaddr;) - { - //update GUI - BpClear(); - BookmarkClear(); - LabelClear(); - SetContextDataEx(fdProcessInfo->hThread, UE_CIP, addr); - if (end) - BpNew(end, true, false, 0, BPNORMAL, 0, nullptr); - if (jumpback) - BookmarkSet(jumpback, false); - if (fardest) - BpNew(fardest, true, false, 0, BPHARDWARE, 0, nullptr); - DebugUpdateGui(addr, false); - Sleep(300); - - //continue algorithm - const unsigned char* curData = (addr >= _base && addr < _base + _size) ? _data() + (addr - _base) : nullptr; - if (_cp.Disassemble(addr, curData, MAX_DISASM_BUFFER)) - { - if (addr + _cp.Size() > maxaddr) //we went past the maximum allowed address - break; - - const cs_x86_op & operand = _cp.x86().operands[0]; - if ((_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) && operand.type == X86_OP_IMM) //jump - { - duint dest = (duint)operand.imm; - - if (dest >= maxaddr) //jump across function boundaries - { - //currently unused - } - else if (dest > addr && dest > fardest) //save the farthest JXX destination forward - { - fardest = dest; - } - else if (end && dest < end && _cp.GetId() == X86_INS_JMP) //save the last JMP backwards - { - jumpback = addr; - } - } - else if (_cp.InGroup(CS_GRP_RET)) //possible function end? - { - end = addr; - if (fardest < addr) //we stop if the farthest JXX destination forward is before this RET - break; - } - - addr += _cp.Size(); - } - else - addr++; - } - end = end < jumpback ? jumpback : end; - - //update GUI - FunctionAdd(start, end, false); - BpClear(); - BookmarkClear(); - SetContextDataEx(fdProcessInfo->hThread, UE_CIP, start); - DebugUpdateGui(start, false); - } - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrMeminfo(int argc, char* argv[]) -{ - if (argc < 3) - { - dputs("usage: meminfo a/r, addr"); - return STATUS_ERROR; - } - duint addr; - if (!valfromstring(argv[2], &addr)) - { - dputs("invalid argument"); - return STATUS_ERROR; - } - if (argv[1][0] == 'a') - { - unsigned char buf = 0; - if (!ReadProcessMemory(fdProcessInfo->hProcess, (void*)addr, &buf, sizeof(buf), nullptr)) - dputs("ReadProcessMemory failed!"); - else - dprintf("data: %02X\n", buf); - } - else if (argv[1][0] == 'r') - { - MemUpdateMap(); - GuiUpdateMemoryView(); - dputs("memory map updated!"); - } - return STATUS_CONTINUE; -} - -CMDRESULT cbInstrSetMaxFindResult(int argc, char* argv[]) -{ - if (argc < 2) - { - dputs("Not enough arguments!"); - return STATUS_ERROR; - } - duint num; - if (!valfromstring(argv[1], &num)) - { - dprintf("Invalid expression: \"%s\"", argv[1]); - return STATUS_ERROR; - } - maxFindResults = int(num & 0x7FFFFFFF); - return STATUS_CONTINUE; +/** +@file instruction.cpp + +@brief Implements the instruction class. +*/ + +#include "instruction.h" +#include "variable.h" +#include "console.h" +#include "value.h" +#include "command.h" +#include "database.h" +#include "addrinfo.h" +#include "assemble.h" +#include "debugger.h" +#include "memory.h" +#include "x64_dbg.h" +#include "disasm_fast.h" +#include "reference.h" +#include "disasm_helper.h" +#include "comment.h" +#include "label.h" +#include "bookmark.h" +#include "function.h" +#include "loop.h" +#include "patternfind.h" +#include "module.h" +#include "stringformat.h" +#include "filehelper.h" +#include "linearanalysis.h" +#include "controlflowanalysis.h" +#include "analysis_nukem.h" +#include "exceptiondirectoryanalysis.h" +#include "_scriptapi_stack.h" +#include "threading.h" + +static bool bRefinit = false; +static int maxFindResults = 5000; + +CMDRESULT cbBadCmd(int argc, char* argv[]) +{ + duint value = 0; + int valsize = 0; + bool isvar = false; + bool hexonly = false; + if (valfromstring(*argv, &value, false, false, &valsize, &isvar, &hexonly)) //dump variable/value/register/etc + { + //dprintf("[DEBUG] valsize: %d\n", valsize); + if (valsize) + valsize *= 2; + else + valsize = 1; + char format_str[deflen] = ""; + if (isvar)// and *cmd!='.' and *cmd!='x') //prevent stupid 0=0 stuff + { + if (value > 15 && !hexonly) + { + if (!valuesignedcalc()) //signed numbers + sprintf(format_str, "%%s=%%.%d" fext "X (%%" fext "ud)\n", valsize); + else + sprintf(format_str, "%%s=%%.%d" fext "X (%%" fext "d)\n", valsize); + dprintf(format_str, *argv, value, value); + } + else + { + sprintf(format_str, "%%s=%%.%d" fext "X\n", valsize); + dprintf(format_str, *argv, value); + } + } + else + { + if (value > 15 && !hexonly) + { + if (!valuesignedcalc()) //signed numbers + sprintf(format_str, "%%s=%%.%d" fext "X (%%" fext "ud)\n", valsize); + else + sprintf(format_str, "%%s=%%.%d" fext "X (%%" fext "d)\n", valsize); + sprintf(format_str, "%%.%d" fext "X (%%" fext "ud)\n", valsize); + dprintf(format_str, value, value); + } + else + { + sprintf(format_str, "%%.%d" fext "X\n", valsize); + dprintf(format_str, value); + } + } + } + else //unknown command + { + dprintf("unknown command/expression: \"%s\"\n", *argv); + return STATUS_ERROR; + } + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrVar(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + char arg2[deflen] = ""; //var value (optional) + if (argc > 2) + strcpy_s(arg2, argv[2]); + duint value = 0; + int add = 0; + if (*argv[1] == '$') + add++; + if (valfromstring(argv[1] + add, &value)) + { + dprintf("invalid variable name \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + if (!valfromstring(arg2, &value)) + { + dprintf("invalid value \"%s\"\n", arg2); + return STATUS_ERROR; + } + if (!varnew(argv[1], value, VAR_USER)) + { + dprintf("error creating variable \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + else + { + if (value > 15) + dprintf("%s=%" fext "X (%" fext "ud)\n", argv[1], value, value); + else + dprintf("%s=%" fext "X\n", argv[1], value); + } + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrVarDel(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + if (!vardel(argv[1], false)) + dprintf("could not delete variable \"%s\"\n", argv[1]); + else + dprintf("deleted variable \"%s\"\n", argv[1]); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrMov(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments"); + return STATUS_ERROR; + } + + String srcText = argv[2]; + if (srcText[0] == '#' && srcText[srcText.length() - 1] == '#') //handle mov addr, #DATA# + { + //do some checks on the data + String dataText = srcText.substr(1, srcText.length() - 2); + int len = (int)dataText.length(); + if (len % 2) + { + dprintf("invalid hex string \"%s\" (length not divisible by 2)\n"); + return STATUS_ERROR; + } + for (int i = 0; i < len; i++) + { + if (!isxdigit(dataText[i])) + { + dprintf("invalid hex string \"%s\" (contains invalid characters)\n", dataText.c_str()); + return STATUS_ERROR; + } + } + //Check the destination + duint dest; + if (!valfromstring(argv[1], &dest) || !MemIsValidReadPtr(dest)) + { + dprintf("invalid destination \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + //Convert text to byte array (very ugly) + Memory data(len / 2); + for (int i = 0, j = 0; i < len; i += 2, j++) + { + char b[3] = ""; + b[0] = dataText[i]; + b[1] = dataText[i + 1]; + int res = 0; + sscanf_s(b, "%X", &res); + data()[j] = res; + } + //Move data to destination + if (!MemWrite(dest, data(), data.size())) + { + dprintf("failed to write to " fhex "\n", dest); + return STATUS_ERROR; + } + GuiUpdateAllViews(); //refresh disassembly/dump/etc + return STATUS_CONTINUE; + } + else + { + duint set_value = 0; + if (!valfromstring(srcText.c_str(), &set_value)) + { + dprintf("invalid src \"%s\"\n", argv[2]); + return STATUS_ERROR; + } + bool isvar = false; + duint temp = 0; + valfromstring(argv[1], &temp, true, false, 0, &isvar, 0); + if (!isvar) + isvar = vargettype(argv[1], 0); + if (!isvar || !valtostring(argv[1], set_value, true)) + { + duint value; + if (valfromstring(argv[1], &value)) //if the var is a value already it's an invalid destination + { + dprintf("invalid dest \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + varnew(argv[1], set_value, VAR_USER); + } + } + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrVarList(int argc, char* argv[]) +{ + int filter = 0; + if (argc > 1) + { + if (!_stricmp(argv[1], "USER")) + filter = VAR_USER; + else if (!_stricmp(argv[1], "READONLY")) + filter = VAR_READONLY; + else if (!_stricmp(argv[1], "SYSTEM")) + filter = VAR_SYSTEM; + } + + size_t cbsize = 0; + if (!varenum(0, &cbsize)) + { + dputs("no variables!"); + return STATUS_CONTINUE; + } + Memory variables(cbsize, "cbInstrVarList:variables"); + if (!varenum(variables(), 0)) + { + dputs("error listing variables!"); + return STATUS_ERROR; + } + + int varcount = (int)cbsize / sizeof(VAR); + for (int i = 0; i < varcount; i++) + { + if (variables()[i].alias.length()) + continue; + char name[deflen] = ""; + strcpy_s(name, variables()[i].name.c_str()); + duint value = (duint)variables()[i].value.u.value; + if (variables()[i].type != VAR_HIDDEN) + { + if (filter) + { + if (variables()[i].type == filter) + { + if (value > 15) + dprintf("%s=%" fext "X (%" fext "ud)\n", name, value, value); + else + dprintf("%s=%" fext "X\n", name, value); + } + } + else + { + if (value > 15) + dprintf("%s=%" fext "X (%" fext "ud)\n", name, value, value); + else + dprintf("%s=%" fext "X\n", name, value); + } + } + } + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrChd(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + if (!DirExists(argv[1])) + { + dputs("directory doesn't exist"); + return STATUS_ERROR; + } + SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(argv[1]).c_str()); + dputs("current directory changed!"); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrCmt(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if (!valfromstring(argv[1], &addr, false)) + return STATUS_ERROR; + if (!CommentSet(addr, argv[2], true)) + { + dputs("error setting comment"); + return STATUS_ERROR; + } + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrCmtdel(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if (!valfromstring(argv[1], &addr, false)) + return STATUS_ERROR; + if (!CommentDelete(addr)) + { + dputs("error deleting comment"); + return STATUS_ERROR; + } + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrLbl(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if (!valfromstring(argv[1], &addr, false)) + return STATUS_ERROR; + if (!LabelSet(addr, argv[2], true)) + { + dputs("error setting label"); + return STATUS_ERROR; + } + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrLbldel(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if (!valfromstring(argv[1], &addr, false)) + return STATUS_ERROR; + if (!LabelDelete(addr)) + { + dputs("error deleting label"); + return STATUS_ERROR; + } + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrBookmarkSet(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if (!valfromstring(argv[1], &addr, false)) + return STATUS_ERROR; + if (!BookmarkSet(addr, true)) + { + dputs("failed to set bookmark!"); + return STATUS_ERROR; + } + dputs("bookmark set!"); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrBookmarkDel(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if (!valfromstring(argv[1], &addr, false)) + return STATUS_ERROR; + if (!BookmarkDelete(addr)) + { + dputs("failed to delete bookmark!"); + return STATUS_ERROR; + } + dputs("bookmark deleted!"); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrLoaddb(int argc, char* argv[]) +{ + DBLoad(); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrSavedb(int argc, char* argv[]) +{ + DBSave(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrAssemble(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if (!valfromstring(argv[1], &addr)) + { + dprintf("invalid expression: \"%s\"!\n", argv[1]); + return STATUS_ERROR; + } + if (!DbgMemIsValidReadPtr(addr)) + { + dprintf("invalid address: " fhex "!\n", addr); + return STATUS_ERROR; + } + bool fillnop = false; + if (argc > 3) + fillnop = true; + char error[MAX_ERROR_SIZE] = ""; + int size = 0; + if (!assembleat(addr, argv[2], &size, error, fillnop)) + { + varset("$result", size, false); + dprintf("failed to assemble \"%s\" (%s)\n", argv[2], error); + return STATUS_ERROR; + } + varset("$result", size, false); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrFunctionAdd(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint start = 0; + duint end = 0; + if (!valfromstring(argv[1], &start, false) || !valfromstring(argv[2], &end, false)) + return STATUS_ERROR; + if (!FunctionAdd(start, end, true)) + { + dputs("failed to add function"); + return STATUS_ERROR; + } + dputs("function added!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrFunctionDel(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if (!valfromstring(argv[1], &addr, false)) + return STATUS_ERROR; + if (!FunctionDelete(addr)) + { + dputs("failed to delete function"); + return STATUS_ERROR; + } + dputs("function deleted!"); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrCmp(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint arg1 = 0; + if (!valfromstring(argv[1], &arg1, false)) + return STATUS_ERROR; + duint arg2 = 0; + if (!valfromstring(argv[2], &arg2, false)) + return STATUS_ERROR; + duint ezflag; + duint bsflag; + if (arg1 == arg2) + ezflag = 1; + else + ezflag = 0; + if (valuesignedcalc()) //signed comparision + { + if ((dsint)arg1 < (dsint)arg2) + bsflag = 0; + else + bsflag = 1; + } + else //unsigned comparision + { + if (arg1 > arg2) + bsflag = 1; + else + bsflag = 0; + } + varset("$_EZ_FLAG", ezflag, true); + varset("$_BS_FLAG", bsflag, true); + //dprintf("$_EZ_FLAG=%d, $_BS_FLAG=%d\n", ezflag, bsflag); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrGpa(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + char newcmd[deflen] = ""; + if (argc >= 3) + sprintf(newcmd, "%s:%s", argv[2], argv[1]); + else + sprintf(newcmd, "%s", argv[1]); + duint result = 0; + if (!valfromstring(newcmd, &result, false)) + return STATUS_ERROR; + varset("$RESULT", result, false); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrAdd(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + return cmddirectexec("mov %s,%s+%s", argv[1], argv[1], argv[2]); +} + +CMDRESULT cbInstrAnd(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + return cmddirectexec("mov %s,%s&%s", argv[1], argv[1], argv[2]); +} + +CMDRESULT cbInstrDec(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + return cmddirectexec("mov %s,%s-1", argv[1], argv[1]); +} + +CMDRESULT cbInstrDiv(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + return cmddirectexec("mov %s,%s/%s", argv[1], argv[1], argv[2]); +} + +CMDRESULT cbInstrInc(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + return cmddirectexec("mov %s,%s+1", argv[1], argv[1]); +} + +CMDRESULT cbInstrMul(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + return cmddirectexec("mov %s,%s*%s", argv[1], argv[1], argv[2]); +} + +CMDRESULT cbInstrNeg(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + return cmddirectexec("mov %s,%s*-1", argv[1], argv[1]); +} + +CMDRESULT cbInstrNot(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + return cmddirectexec("mov %s,~%s", argv[1], argv[1]); +} + +CMDRESULT cbInstrOr(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + return cmddirectexec("mov %s,%s|%s", argv[1], argv[1], argv[2]); +} + +CMDRESULT cbInstrRol(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + bool signedcalc = valuesignedcalc(); + valuesetsignedcalc(true); //rol = signed + CMDRESULT res = cmddirectexec("mov %s,%s<%s", argv[1], argv[1], argv[2]); + valuesetsignedcalc(signedcalc); + return res; +} + +CMDRESULT cbInstrRor(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + bool signedcalc = valuesignedcalc(); + valuesetsignedcalc(true); //ror = signed + CMDRESULT res = cmddirectexec("mov %s,%s>%s", argv[1], argv[1], argv[2]); + valuesetsignedcalc(signedcalc); + return res; +} + +CMDRESULT cbInstrShl(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + bool signedcalc = valuesignedcalc(); + valuesetsignedcalc(false); //shl = unsigned + CMDRESULT res = cmddirectexec("mov %s,%s<%s", argv[1], argv[1], argv[2]); + valuesetsignedcalc(signedcalc); + return res; +} + +CMDRESULT cbInstrShr(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + bool signedcalc = valuesignedcalc(); + valuesetsignedcalc(false); //shr = unsigned + CMDRESULT res = cmddirectexec("mov %s,%s>%s", argv[1], argv[1], argv[2]); + valuesetsignedcalc(signedcalc); + return res; +} + +CMDRESULT cbInstrSub(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + return cmddirectexec("mov %s,%s-%s", argv[1], argv[1], argv[2]); +} + +CMDRESULT cbInstrTest(int argc, char* argv[]) +{ + //TODO: test + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint arg1 = 0; + if (!valfromstring(argv[1], &arg1, false)) + return STATUS_ERROR; + duint arg2 = 0; + if (!valfromstring(argv[2], &arg2, false)) + return STATUS_ERROR; + duint ezflag; + duint bsflag = 0; + if (!(arg1 & arg2)) + ezflag = 1; + else + ezflag = 0; + varset("$_EZ_FLAG", ezflag, true); + varset("$_BS_FLAG", bsflag, true); + //dprintf("$_EZ_FLAG=%d, $_BS_FLAG=%d\n", ezflag, bsflag); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrXor(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + return cmddirectexec("mov %s,%s^%s", argv[1], argv[1], argv[2]); +} + +CMDRESULT cbInstrPush(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint value; + if (!valfromstring(argv[1], &value)) + { + dprintf("invalid argument \"%s\"!\n", argv[1]); + return STATUS_ERROR; + } + Script::Stack::Push(value); + duint csp = GetContextDataEx(hActiveThread, UE_CSP); + DebugUpdateStack(csp, csp); + GuiUpdateRegisterView(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrPop(int argc, char* argv[]) +{ + duint value = Script::Stack::Pop(); + duint csp = GetContextDataEx(hActiveThread, UE_CSP); + DebugUpdateStack(csp, csp); + GuiUpdateRegisterView(); + if (argc > 1) + { + if (!valtostring(argv[1], value, false)) + return STATUS_ERROR; + } + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrRefinit(int argc, char* argv[]) +{ + GuiReferenceInitialize("Script"); + GuiReferenceAddColumn(sizeof(duint) * 2, "Address"); + GuiReferenceAddColumn(0, "Data"); + GuiReferenceSetRowCount(0); + GuiReferenceReloadData(); + bRefinit = true; + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrRefadd(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if (!valfromstring(argv[1], &addr, false)) + return STATUS_ERROR; + if (!bRefinit) + cbInstrRefinit(argc, argv); + int index = GuiReferenceGetRowCount(); + GuiReferenceSetRowCount(index + 1); + char addr_text[deflen] = ""; + sprintf(addr_text, fhex, addr); + GuiReferenceSetCellContent(index, 0, addr_text); + GuiReferenceSetCellContent(index, 1, argv[2]); + GuiReferenceReloadData(); + return STATUS_CONTINUE; +} + +struct VALUERANGE +{ + duint start; + duint end; +}; + +static bool cbRefFind(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo) +{ + if (!disasm || !basicinfo) //initialize + { + GuiReferenceInitialize(refinfo->name); + GuiReferenceAddColumn(2 * sizeof(duint), "Address"); + GuiReferenceAddColumn(0, "Disassembly"); + GuiReferenceSetRowCount(0); + GuiReferenceReloadData(); + return true; + } + bool found = false; + VALUERANGE* range = (VALUERANGE*)refinfo->userinfo; + duint start = range->start; + duint end = range->end; + if ((basicinfo->type & TYPE_VALUE) == TYPE_VALUE) + { + duint value = basicinfo->value.value; + if (value >= start && value <= end) + found = true; + } + if ((basicinfo->type & TYPE_MEMORY) == TYPE_MEMORY) + { + duint value = basicinfo->memory.value; + if (value >= start && value <= end) + found = true; + } + if ((basicinfo->type & TYPE_ADDR) == TYPE_ADDR) + { + duint value = basicinfo->addr; + if (value >= start && value <= end) + found = true; + } + if (found) + { + char addrText[20] = ""; + sprintf(addrText, "%p", disasm->Address()); + GuiReferenceSetRowCount(refinfo->refcount + 1); + GuiReferenceSetCellContent(refinfo->refcount, 0, addrText); + char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; + if (GuiGetDisassembly((duint)disasm->Address(), disassembly)) + GuiReferenceSetCellContent(refinfo->refcount, 1, disassembly); + else + GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->InstructionText().c_str()); + } + return found; +} + +CMDRESULT cbInstrRefFind(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + std::string newCommand = std::string("reffindrange ") + argv[1] + std::string(",") + argv[1]; + if (argc > 2) + newCommand += std::string(",") + argv[2]; + if (argc > 3) + newCommand += std::string(",") + argv[3]; + return cmddirectexec(newCommand.c_str()); +} + +CMDRESULT cbInstrRefFindRange(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + VALUERANGE range; + if (!valfromstring(argv[1], &range.start, false)) + return STATUS_ERROR; + if (argc < 3 || !valfromstring(argv[2], &range.end, false)) + range.end = range.start; + duint addr = 0; + if (argc < 4 || !valfromstring(argv[3], &addr)) + addr = GetContextDataEx(hActiveThread, UE_CIP); + duint size = 0; + if (argc >= 5) + if (!valfromstring(argv[4], &size)) + size = 0; + duint ticks = GetTickCount(); + char title[256] = ""; + if (range.start == range.end) + sprintf_s(title, "Constant: %" fext "X", range.start); + else + sprintf_s(title, "Range: %" fext "X-%" fext "X", range.start, range.end); + int found = RefFind(addr, size, cbRefFind, &range, false, title); + dprintf("%u reference(s) in %ums\n", found, GetTickCount() - ticks); + varset("$result", found, false); + return STATUS_CONTINUE; +} + +bool cbRefStr(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo) +{ + if (!disasm || !basicinfo) //initialize + { + GuiReferenceInitialize(refinfo->name); + GuiReferenceAddColumn(2 * sizeof(duint), "Address"); + GuiReferenceAddColumn(64, "Disassembly"); + GuiReferenceAddColumn(500, "String"); + GuiReferenceSetSearchStartCol(2); //only search the strings + GuiReferenceReloadData(); + return true; + } + bool found = false; + STRING_TYPE strtype; + char string[1024] = ""; + if (basicinfo->branch) //branches have no strings (jmp dword [401000]) + return false; + if ((basicinfo->type & TYPE_VALUE) == TYPE_VALUE) + { + if (disasmgetstringat(basicinfo->value.value, &strtype, string, string, 500)) + found = true; + } + if ((basicinfo->type & TYPE_MEMORY) == TYPE_MEMORY) + { + if (!found && disasmgetstringat(basicinfo->memory.value, &strtype, string, string, 500)) + found = true; + } + if (found) + { + char addrText[20] = ""; + sprintf(addrText, "%p", disasm->Address()); + GuiReferenceSetRowCount(refinfo->refcount + 1); + GuiReferenceSetCellContent(refinfo->refcount, 0, addrText); + char disassembly[4096] = ""; + if (GuiGetDisassembly((duint)disasm->Address(), disassembly)) + GuiReferenceSetCellContent(refinfo->refcount, 1, disassembly); + else + GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->InstructionText().c_str()); + char dispString[1024] = ""; + if (strtype == str_ascii) + sprintf(dispString, "\"%s\"", string); + else + sprintf(dispString, "L\"%s\"", string); + GuiReferenceSetCellContent(refinfo->refcount, 2, dispString); + } + return found; +} + +CMDRESULT cbInstrRefStr(int argc, char* argv[]) +{ + duint addr; + if (argc < 2 || !valfromstring(argv[1], &addr, true)) + addr = GetContextDataEx(hActiveThread, UE_CIP); + duint size = 0; + if (argc >= 3) + if (!valfromstring(argv[2], &size, true)) + size = 0; + duint ticks = GetTickCount(); + int found = RefFind(addr, size, cbRefStr, 0, false, "Strings"); + dprintf("%u string(s) in %ums\n", found, GetTickCount() - ticks); + varset("$result", found, false); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrSetstr(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + varnew(argv[1], 0, VAR_USER); + if (!vargettype(argv[1], 0)) + { + dprintf("no such variable \"%s\"!\n", argv[1]); + return STATUS_ERROR; + } + if (!varset(argv[1], argv[2], false)) + { + dprintf("failed to set variable \"%s\"!\n", argv[1]); + return STATUS_ERROR; + } + cmddirectexec("getstr \"%s\"", argv[1]); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrGetstr(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + VAR_VALUE_TYPE valtype; + if (!vargettype(argv[1], 0, &valtype)) + { + dprintf("no such variable \"%s\"!\n", argv[1]); + return STATUS_ERROR; + } + if (valtype != VAR_STRING) + { + dprintf("variable \"%s\" is not a string!\n", argv[1]); + return STATUS_ERROR; + } + int size; + if (!varget(argv[1], (char*)0, &size, 0) || !size) + { + dprintf("failed to get variable size \"%s\"!\n", argv[1]); + return STATUS_ERROR; + } + Memory string(size + 1, "cbInstrGetstr:string"); + if (!varget(argv[1], string(), &size, 0)) + { + dprintf("failed to get variable data \"%s\"!\n", argv[1]); + return STATUS_ERROR; + } + dprintf("%s=\"%s\"\n", argv[1], string()); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrCopystr(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + VAR_VALUE_TYPE valtype; + if (!vargettype(argv[2], 0, &valtype)) + { + dprintf("no such variable \"%s\"!\n", argv[2]); + return STATUS_ERROR; + } + if (valtype != VAR_STRING) + { + dprintf("variable \"%s\" is not a string!\n", argv[2]); + return STATUS_ERROR; + } + int size; + if (!varget(argv[2], (char*)0, &size, 0) || !size) + { + dprintf("failed to get variable size \"%s\"!\n", argv[2]); + return STATUS_ERROR; + } + Memory string(size + 1, "cbInstrGetstr:string"); + if (!varget(argv[2], string(), &size, 0)) + { + dprintf("failed to get variable data \"%s\"!\n", argv[2]); + return STATUS_ERROR; + } + duint addr; + if (!valfromstring(argv[1], &addr)) + { + dprintf("invalid address \"%s\"!\n", argv[1]); + return STATUS_ERROR; + } + if (!MemPatch(addr, string(), strlen(string()))) + { + dputs("memwrite failed!"); + return STATUS_ERROR; + } + dputs("string written!"); + GuiUpdateAllViews(); + GuiUpdatePatches(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrFind(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if (!valfromstring(argv[1], &addr, false)) + return STATUS_ERROR; + char pattern[deflen] = ""; + //remove # from the start and end of the pattern (ODBGScript support) + if (argv[2][0] == '#') + strcpy_s(pattern, argv[2] + 1); + else + strcpy_s(pattern, argv[2]); + int len = (int)strlen(pattern); + if (pattern[len - 1] == '#') + pattern[len - 1] = '\0'; + duint size = 0; + duint base = MemFindBaseAddr(addr, &size, true); + if (!base) + { + dprintf("invalid memory address " fhex "!\n", addr); + return STATUS_ERROR; + } + Memory data(size, "cbInstrFind:data"); + if (!MemRead(base, data(), size)) + { + dputs("failed to read memory!"); + return STATUS_ERROR; + } + duint start = addr - base; + duint find_size = 0; + if (argc >= 4) + { + if (!valfromstring(argv[3], &find_size)) + find_size = size - start; + if (find_size > (size - start)) + find_size = size - start; + } + else + find_size = size - start; + duint foundoffset = patternfind(data() + start, find_size, pattern); + duint result = 0; + if (foundoffset != -1) + result = addr + foundoffset; + varset("$result", result, false); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrFindAll(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if (!valfromstring(argv[1], &addr, false)) + return STATUS_ERROR; + + char pattern[deflen] = ""; + //remove # from the start and end of the pattern (ODBGScript support) + if (argv[2][0] == '#') + strcpy_s(pattern, argv[2] + 1); + else + strcpy_s(pattern, argv[2]); + int len = (int)strlen(pattern); + if (pattern[len - 1] == '#') + pattern[len - 1] = '\0'; + duint size = 0; + duint base = MemFindBaseAddr(addr, &size, true); + if (!base) + { + dprintf("invalid memory address " fhex "!\n", addr); + return STATUS_ERROR; + } + Memory data(size, "cbInstrFindAll:data"); + if (!MemRead(base, data(), size)) + { + dputs("failed to read memory!"); + return STATUS_ERROR; + } + duint start = addr - base; + duint find_size = 0; + bool findData = false; + if (argc >= 4) + { + if (!_stricmp(argv[3], "&data&")) + { + find_size = size - start; + findData = true; + } + else if (!valfromstring(argv[3], &find_size)) + find_size = size - start; + else if (find_size > (size - start)) + find_size = size - start; + } + else + find_size = size - start; + //setup reference view + char patternshort[256] = ""; + strncpy_s(patternshort, pattern, min(16, len)); + if (len > 16) + strcat_s(patternshort, "..."); + char patterntitle[256] = ""; + sprintf_s(patterntitle, "Pattern: %s", patternshort); + GuiReferenceInitialize(patterntitle); + GuiReferenceAddColumn(2 * sizeof(duint), "Address"); + if (findData) + GuiReferenceAddColumn(0, "&Data&"); + else + GuiReferenceAddColumn(0, "Disassembly"); + GuiReferenceReloadData(); + DWORD ticks = GetTickCount(); + int refCount = 0; + duint i = 0; + duint result = 0; + std::vector searchpattern; + if (!patterntransform(pattern, searchpattern)) + { + dputs("failed to transform pattern!"); + return STATUS_ERROR; + } + while (refCount < maxFindResults) + { + duint foundoffset = patternfind(data() + start + i, find_size - i, searchpattern); + if (foundoffset == -1) + break; + i += foundoffset + 1; + result = addr + i - 1; + char msg[deflen] = ""; + sprintf(msg, fhex, result); + GuiReferenceSetRowCount(refCount + 1); + GuiReferenceSetCellContent(refCount, 0, msg); + if (findData) + { + Memory printData(searchpattern.size(), "cbInstrFindAll:printData"); + MemRead(result, printData(), printData.size()); + for (size_t j = 0, k = 0; j < printData.size(); j++) + { + if (j) + k += sprintf(msg + k, " "); + k += sprintf(msg + k, "%.2X", printData()[j]); + } + } + else + { + if (!GuiGetDisassembly(result, msg)) + strcpy_s(msg, "[Error disassembling]"); + } + GuiReferenceSetCellContent(refCount, 1, msg); + result++; + refCount++; + } + GuiReferenceReloadData(); + dprintf("%d occurrences found in %ums\n", refCount, GetTickCount() - ticks); + varset("$result", refCount, false); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrFindMemAll(int argc, char* argv[]) +{ + dprintf("argc: %d\n", argc); + for (int i = 0; i < argc; i++) + { + dprintf("%d:\"%s\"\n", i, argv[i]); + } + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + if (!valfromstring(argv[1], &addr, false)) + return STATUS_ERROR; + + char pattern[deflen] = ""; + //remove # from the start and end of the pattern (ODBGScript support) + if (argv[2][0] == '#') + strcpy_s(pattern, argv[2] + 1); + else + strcpy_s(pattern, argv[2]); + int len = (int)strlen(pattern); + if (pattern[len - 1] == '#') + pattern[len - 1] = '\0'; + std::vector searchpattern; + if (!patterntransform(pattern, searchpattern)) + { + dputs("failed to transform pattern!"); + return STATUS_ERROR; + } + + duint endAddr = -1; + bool findData = false; + if (argc >= 4) + { + if (!_stricmp(argv[3], "&data&")) + findData = true; + else if (!valfromstring(argv[3], &endAddr)) + findData = false; + } + + SHARED_ACQUIRE(LockMemoryPages); + std::vector searchPages; + for (auto & itr : memoryPages) + { + SimplePage page(duint(itr.second.mbi.BaseAddress), itr.second.mbi.RegionSize); + if (page.address >= addr && page.address + page.size <= endAddr) + searchPages.push_back(page); + } + SHARED_RELEASE(); + + DWORD ticks = GetTickCount(); + + std::vector results; + if (!MemFindInMap(searchPages, searchpattern, results, maxFindResults)) + { + dputs("MemFindInMap failed!"); + return STATUS_ERROR; + } + + //setup reference view + char patternshort[256] = ""; + strncpy_s(patternshort, pattern, min(16, len)); + if (len > 16) + strcat_s(patternshort, "..."); + char patterntitle[256] = ""; + sprintf_s(patterntitle, "Pattern: %s", patternshort); + GuiReferenceInitialize(patterntitle); + GuiReferenceAddColumn(2 * sizeof(duint), "Address"); + if (findData) + GuiReferenceAddColumn(0, "&Data&"); + else + GuiReferenceAddColumn(0, "Disassembly"); + GuiReferenceReloadData(); + + int refCount = 0; + for (duint result : results) + { + char msg[deflen] = ""; + sprintf(msg, fhex, result); + GuiReferenceSetRowCount(refCount + 1); + GuiReferenceSetCellContent(refCount, 0, msg); + if (findData) + { + Memory printData(searchpattern.size(), "cbInstrFindAll:printData"); + MemRead(result, printData(), printData.size()); + for (size_t j = 0, k = 0; j < printData.size(); j++) + { + if (j) + k += sprintf(msg + k, " "); + k += sprintf(msg + k, "%.2X", printData()[j]); + } + } + else + { + if (!GuiGetDisassembly(result, msg)) + strcpy_s(msg, "[Error disassembling]"); + } + GuiReferenceSetCellContent(refCount, 1, msg); + refCount++; + } + + GuiReferenceReloadData(); + dprintf("%d occurrences found in %ums\n", refCount, GetTickCount() - ticks); + varset("$result", refCount, false); + + return STATUS_CONTINUE; +} + +static bool cbModCallFind(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo) +{ + if (!disasm || !basicinfo) //initialize + { + GuiReferenceInitialize(refinfo->name); + GuiReferenceAddColumn(2 * sizeof(duint), "Address"); + GuiReferenceAddColumn(0, "Disassembly"); + GuiReferenceReloadData(); + return true; + } + bool found = false; + if (basicinfo->call) //we are looking for calls + { + duint ptr = basicinfo->addr > 0 ? basicinfo->addr : basicinfo->memory.value; + char label[MAX_LABEL_SIZE] = ""; + found = DbgGetLabelAt(ptr, SEG_DEFAULT, label) && !LabelGet(ptr, label); //a non-user label + } + if (found) + { + char addrText[20] = ""; + sprintf(addrText, "%p", disasm->Address()); + GuiReferenceSetRowCount(refinfo->refcount + 1); + GuiReferenceSetCellContent(refinfo->refcount, 0, addrText); + char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; + if (GuiGetDisassembly((duint)disasm->Address(), disassembly)) + GuiReferenceSetCellContent(refinfo->refcount, 1, disassembly); + else + GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->InstructionText().c_str()); + } + return found; +} + +CMDRESULT cbInstrModCallFind(int argc, char* argv[]) +{ + duint addr; + if (argc < 2 || !valfromstring(argv[1], &addr, true)) + addr = GetContextDataEx(hActiveThread, UE_CIP); + duint size = 0; + if (argc >= 3) + if (!valfromstring(argv[2], &size, true)) + size = 0; + duint ticks = GetTickCount(); + int found = RefFind(addr, size, cbModCallFind, 0, false, "Calls"); + dprintf("%u call(s) in %ums\n", found, GetTickCount() - ticks); + varset("$result", found, false); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrCommentList(int argc, char* argv[]) +{ + //setup reference view + GuiReferenceInitialize("Comments"); + GuiReferenceAddColumn(2 * sizeof(duint), "Address"); + GuiReferenceAddColumn(64, "Disassembly"); + GuiReferenceAddColumn(0, "Comment"); + GuiReferenceReloadData(); + size_t cbsize; + CommentEnum(0, &cbsize); + if (!cbsize) + { + dputs("no comments"); + return STATUS_CONTINUE; + } + Memory comments(cbsize, "cbInstrCommentList:comments"); + CommentEnum(comments(), 0); + int count = (int)(cbsize / sizeof(COMMENTSINFO)); + for (int i = 0; i < count; i++) + { + GuiReferenceSetRowCount(i + 1); + char addrText[20] = ""; + sprintf(addrText, "%p", comments()[i].addr); + GuiReferenceSetCellContent(i, 0, addrText); + char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; + if (GuiGetDisassembly(comments()[i].addr, disassembly)) + GuiReferenceSetCellContent(i, 1, disassembly); + GuiReferenceSetCellContent(i, 2, comments()[i].text); + } + varset("$result", count, false); + dprintf("%d comment(s) listed in Reference View\n", count); + GuiReferenceReloadData(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrLabelList(int argc, char* argv[]) +{ + //setup reference view + GuiReferenceInitialize("Labels"); + GuiReferenceAddColumn(2 * sizeof(duint), "Address"); + GuiReferenceAddColumn(64, "Disassembly"); + GuiReferenceAddColumn(0, "Label"); + GuiReferenceReloadData(); + size_t cbsize; + LabelEnum(0, &cbsize); + if (!cbsize) + { + dputs("no labels"); + return STATUS_CONTINUE; + } + Memory labels(cbsize, "cbInstrLabelList:labels"); + LabelEnum(labels(), 0); + int count = (int)(cbsize / sizeof(LABELSINFO)); + for (int i = 0; i < count; i++) + { + GuiReferenceSetRowCount(i + 1); + char addrText[20] = ""; + sprintf(addrText, "%p", labels()[i].addr); + GuiReferenceSetCellContent(i, 0, addrText); + char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; + if (GuiGetDisassembly(labels()[i].addr, disassembly)) + GuiReferenceSetCellContent(i, 1, disassembly); + GuiReferenceSetCellContent(i, 2, labels()[i].text); + } + varset("$result", count, false); + dprintf("%d label(s) listed in Reference View\n", count); + GuiReferenceReloadData(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrBookmarkList(int argc, char* argv[]) +{ + //setup reference view + GuiReferenceInitialize("Bookmarks"); + GuiReferenceAddColumn(2 * sizeof(duint), "Address"); + GuiReferenceAddColumn(0, "Disassembly"); + GuiReferenceReloadData(); + size_t cbsize; + BookmarkEnum(0, &cbsize); + if (!cbsize) + { + dputs("No bookmarks found"); + return STATUS_CONTINUE; + } + Memory bookmarks(cbsize, "cbInstrBookmarkList:bookmarks"); + BookmarkEnum(bookmarks(), 0); + int count = (int)(cbsize / sizeof(BOOKMARKSINFO)); + for (int i = 0; i < count; i++) + { + GuiReferenceSetRowCount(i + 1); + char addrText[20] = ""; + sprintf(addrText, "%p", bookmarks()[i].addr); + GuiReferenceSetCellContent(i, 0, addrText); + char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; + if (GuiGetDisassembly(bookmarks()[i].addr, disassembly)) + GuiReferenceSetCellContent(i, 1, disassembly); + } + varset("$result", count, false); + dprintf("%d bookmark(s) listed\n", count); + GuiReferenceReloadData(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrFunctionList(int argc, char* argv[]) +{ + //setup reference view + GuiReferenceInitialize("Functions"); + GuiReferenceAddColumn(2 * sizeof(duint), "Start"); + GuiReferenceAddColumn(2 * sizeof(duint), "End"); + GuiReferenceAddColumn(64, "Disassembly (Start)"); + GuiReferenceAddColumn(0, "Label/Comment"); + GuiReferenceReloadData(); + size_t cbsize; + FunctionEnum(0, &cbsize); + if (!cbsize) + { + dputs("No functions"); + return STATUS_CONTINUE; + } + Memory functions(cbsize, "cbInstrFunctionList:functions"); + FunctionEnum(functions(), 0); + int count = (int)(cbsize / sizeof(FUNCTIONSINFO)); + for (int i = 0; i < count; i++) + { + GuiReferenceSetRowCount(i + 1); + char addrText[20] = ""; + sprintf(addrText, "%p", functions()[i].start); + GuiReferenceSetCellContent(i, 0, addrText); + sprintf(addrText, "%p", functions()[i].end); + GuiReferenceSetCellContent(i, 1, addrText); + char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; + if (GuiGetDisassembly(functions()[i].start, disassembly)) + GuiReferenceSetCellContent(i, 2, disassembly); + char label[MAX_LABEL_SIZE] = ""; + if (LabelGet(functions()[i].start, label)) + GuiReferenceSetCellContent(i, 3, label); + else + { + char comment[MAX_COMMENT_SIZE] = ""; + if (CommentGet(functions()[i].start, comment)) + GuiReferenceSetCellContent(i, 3, comment); + } + } + varset("$result", count, false); + dprintf("%d function(s) listed\n", count); + GuiReferenceReloadData(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrLoopList(int argc, char* argv[]) +{ + //setup reference view + GuiReferenceInitialize("Loops"); + GuiReferenceAddColumn(2 * sizeof(duint), "Start"); + GuiReferenceAddColumn(2 * sizeof(duint), "End"); + GuiReferenceAddColumn(64, "Disassembly (Start)"); + GuiReferenceAddColumn(0, "Label/Comment"); + GuiReferenceReloadData(); + size_t cbsize; + LoopEnum(0, &cbsize); + if (!cbsize) + { + dputs("no loops"); + return STATUS_CONTINUE; + } + Memory loops(cbsize, "cbInstrLoopList:loops"); + LoopEnum(loops(), 0); + int count = (int)(cbsize / sizeof(LOOPSINFO)); + for (int i = 0; i < count; i++) + { + GuiReferenceSetRowCount(i + 1); + char addrText[20] = ""; + sprintf(addrText, "%p", loops()[i].start); + GuiReferenceSetCellContent(i, 0, addrText); + sprintf(addrText, "%p", loops()[i].end); + GuiReferenceSetCellContent(i, 1, addrText); + char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; + if (GuiGetDisassembly(loops()[i].start, disassembly)) + GuiReferenceSetCellContent(i, 2, disassembly); + char label[MAX_LABEL_SIZE] = ""; + if (LabelGet(loops()[i].start, label)) + GuiReferenceSetCellContent(i, 3, label); + else + { + char comment[MAX_COMMENT_SIZE] = ""; + if (CommentGet(loops()[i].start, comment)) + GuiReferenceSetCellContent(i, 3, comment); + } + } + varset("$result", count, false); + dprintf("%d loop(s) listed\n", count); + GuiReferenceReloadData(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrSleep(int argc, char* argv[]) +{ + duint ms = 100; + if (argc > 1) + if (!valfromstring(argv[1], &ms, false)) + return STATUS_ERROR; + if (ms >= 0xFFFFFFFF) + ms = 100; + Sleep((DWORD)ms); + return STATUS_CONTINUE; +} + +static bool cbFindAsm(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo) +{ + if (!disasm || !basicinfo) //initialize + { + GuiReferenceInitialize(refinfo->name); + GuiReferenceAddColumn(2 * sizeof(duint), "Address"); + GuiReferenceAddColumn(0, "Disassembly"); + GuiReferenceReloadData(); + return true; + } + const char* instruction = (const char*)refinfo->userinfo; + bool found = !_stricmp(instruction, basicinfo->instruction); + if (found) + { + char addrText[20] = ""; + sprintf(addrText, fhex, disasm->Address()); + GuiReferenceSetRowCount(refinfo->refcount + 1); + GuiReferenceSetCellContent(refinfo->refcount, 0, addrText); + char disassembly[GUI_MAX_DISASSEMBLY_SIZE] = ""; + if (GuiGetDisassembly((duint)disasm->Address(), disassembly)) + GuiReferenceSetCellContent(refinfo->refcount, 1, disassembly); + else + GuiReferenceSetCellContent(refinfo->refcount, 1, disasm->InstructionText().c_str()); + } + return found; +} + +CMDRESULT cbInstrFindAsm(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + + duint addr = 0; + if (argc < 3 || !valfromstring(argv[2], &addr)) + addr = GetContextDataEx(hActiveThread, UE_CIP); + duint size = 0; + if (argc >= 4) + if (!valfromstring(argv[3], &size)) + size = 0; + + unsigned char dest[16]; + int asmsize = 0; + char error[MAX_ERROR_SIZE] = ""; + if (!assemble(addr + size / 2, dest, &asmsize, argv[1], error)) + { + dprintf("failed to assemble \"%s\" (%s)!\n", argv[1], error); + return STATUS_ERROR; + } + BASIC_INSTRUCTION_INFO basicinfo; + memset(&basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO)); + disasmfast(dest, addr + size / 2, &basicinfo); + + duint ticks = GetTickCount(); + char title[256] = ""; + sprintf_s(title, "Command: \"%s\"", basicinfo.instruction); + int found = RefFind(addr, size, cbFindAsm, (void*)&basicinfo.instruction[0], false, title); + dprintf("%u result(s) in %ums\n", found, GetTickCount() - ticks); + varset("$result", found, false); + return STATUS_CONTINUE; +} + +static void yaraCompilerCallback(int error_level, const char* file_name, int line_number, const char* message, void* user_data) +{ + switch (error_level) + { + case YARA_ERROR_LEVEL_ERROR: + dprintf("[YARA ERROR] "); + break; + case YARA_ERROR_LEVEL_WARNING: + dprintf("[YARA WARNING] "); + break; + } + dprintf("File: \"%s\", Line: %d, Message: \"%s\"\n", file_name, line_number, message); +} + +static String yara_print_string(const uint8_t* data, int length) +{ + String result = "\""; + const char* str = (const char*)data; + for (int i = 0; i < length; i++) + { + char cur[16] = ""; + if (str[i] >= 32 && str[i] <= 126) + sprintf_s(cur, "%c", str[i]); + else + sprintf_s(cur, "\\x%02X", (uint8_t)str[i]); + result += cur; + } + result += "\""; + return result; +} + +static String yara_print_hex_string(const uint8_t* data, int length) +{ + String result = ""; + for (int i = 0; i < length; i++) + { + if (i) + result += " "; + char cur[16] = ""; + sprintf_s(cur, "%02X", (uint8_t)data[i]); + result += cur; + } + return result; +} + +struct YaraScanInfo +{ + duint base; + int index; +}; + +static int yaraScanCallback(int message, void* message_data, void* user_data) +{ + YaraScanInfo* scanInfo = (YaraScanInfo*)user_data; + switch (message) + { + case CALLBACK_MSG_RULE_MATCHING: + { + duint base = scanInfo->base; + YR_RULE* yrRule = (YR_RULE*)message_data; + dprintf("[YARA] Rule \"%s\" matched:\n", yrRule->identifier); + YR_STRING* string; + yr_rule_strings_foreach(yrRule, string) + { + YR_MATCH* match; + yr_string_matches_foreach(string, match) + { + String pattern; + if (STRING_IS_HEX(string)) + pattern = yara_print_hex_string(match->data, match->length); + else + pattern = yara_print_string(match->data, match->length); + duint addr = (duint)(base + match->base + match->offset); + //dprintf("[YARA] String \"%s\" : %s on 0x%" fext "X\n", string->identifier, pattern.c_str(), addr); + + //update references + int index = scanInfo->index; + GuiReferenceSetRowCount(index + 1); + scanInfo->index++; + char addr_text[deflen] = ""; + sprintf(addr_text, fhex, addr); + GuiReferenceSetCellContent(index, 0, addr_text); //Address + String ruleFullName = ""; + ruleFullName += yrRule->identifier; + ruleFullName += "."; + ruleFullName += string->identifier; + GuiReferenceSetCellContent(index, 1, ruleFullName.c_str()); //Rule + GuiReferenceSetCellContent(index, 2, pattern.c_str()); //Data + } + } + } + break; + + case CALLBACK_MSG_RULE_NOT_MATCHING: + { + YR_RULE* yrRule = (YR_RULE*)message_data; + dprintf("[YARA] Rule \"%s\" did not match!\n", yrRule->identifier); + } + break; + + case CALLBACK_MSG_SCAN_FINISHED: + { + dputs("[YARA] Scan finished!"); + } + break; + + case CALLBACK_MSG_IMPORT_MODULE: + { + YR_MODULE_IMPORT* yrModuleImport = (YR_MODULE_IMPORT*)message_data; + dprintf("[YARA] Imported module \"%s\"!\n", yrModuleImport->module_name); + } + break; + } + return ERROR_SUCCESS; //nicely undocumented what this should be +} + +CMDRESULT cbInstrYara(int argc, char* argv[]) +{ + if (argc < 2) //yara rulesFile, addr_of_mempage, size_of_scan + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint addr = 0; + SELECTIONDATA sel; + GuiSelectionGet(GUI_DISASSEMBLY, &sel); + addr = sel.start; + + duint base = 0; + duint size = 0; + duint mod = ModBaseFromName(argv[2]); + if (mod) + { + base = mod; + size = ModSizeFromAddr(base); + } + else + { + if (!valfromstring(argv[2], &addr)) + { + dprintf("invalid value \"%s\"!\n", argv[2]); + return STATUS_ERROR; + } + + size = 0; + if (argc >= 4) + if (!valfromstring(argv[3], &size)) + size = 0; + if (!size) + addr = MemFindBaseAddr(addr, &size); + base = addr; + } + Memory data(size); + if (!MemRead(base, data(), size)) + { + dprintf("failed to read memory page %p[%X]!\n", base, size); + return STATUS_ERROR; + } + + String rulesContent; + if (!FileHelper::ReadAllText(argv[1], rulesContent)) + { + dprintf("Failed to read the rules file \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + + bool bSuccess = false; + YR_COMPILER* yrCompiler; + if (yr_compiler_create(&yrCompiler) == ERROR_SUCCESS) + { + yr_compiler_set_callback(yrCompiler, yaraCompilerCallback, 0); + if (yr_compiler_add_string(yrCompiler, rulesContent.c_str(), nullptr) == 0) //no errors found + { + YR_RULES* yrRules; + if (yr_compiler_get_rules(yrCompiler, &yrRules) == ERROR_SUCCESS) + { + //initialize new reference tab + char modname[MAX_MODULE_SIZE] = ""; + if (!ModNameFromAddr(base, modname, true)) + sprintf_s(modname, "%p", base); + String fullName; + const char* fileName = strrchr(argv[1], '\\'); + if (fileName) + fullName = fileName + 1; + else + fullName = argv[1]; + fullName += " ("; + fullName += modname; + fullName += ")"; //nanana, very ugly code (long live open source) + GuiReferenceInitialize(fullName.c_str()); + GuiReferenceAddColumn(sizeof(duint) * 2, "Address"); + GuiReferenceAddColumn(48, "Rule"); + GuiReferenceAddColumn(0, "Data"); + GuiReferenceSetRowCount(0); + GuiReferenceReloadData(); + YaraScanInfo scanInfo; + scanInfo.base = base; + scanInfo.index = 0; + duint ticks = GetTickCount(); + dputs("[YARA] Scan started..."); + int err = yr_rules_scan_mem(yrRules, data(), size, 0, yaraScanCallback, &scanInfo, 0); + GuiReferenceReloadData(); + switch (err) + { + case ERROR_SUCCESS: + dprintf("%u scan results in %ums...\n", scanInfo.index, GetTickCount() - ticks); + bSuccess = true; + break; + case ERROR_TOO_MANY_MATCHES: + dputs("too many matches!"); + break; + default: + dputs("error while scanning memory!"); + break; + } + yr_rules_destroy(yrRules); + } + else + dputs("error while getting the rules!"); + } + else + dputs("errors in the rules file!"); + yr_compiler_destroy(yrCompiler); + } + else + dputs("yr_compiler_create failed!"); + return bSuccess ? STATUS_CONTINUE : STATUS_ERROR; +} + +CMDRESULT cbInstrYaramod(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint base = ModBaseFromName(argv[2]); + if (!base) + { + dprintf("invalid module \"%s\"!\n", argv[2]); + return STATUS_ERROR; + } + duint size = ModSizeFromAddr(base); + return cmddirectexec("yara \"%s\",%p,%p", argv[1], base, size); +} + +CMDRESULT cbInstrLog(int argc, char* argv[]) +{ + //log "format {0} string",arg1, arg2, argN + if (argc == 1) //just log newline + { + dputs(""); + return STATUS_CONTINUE; + } + FormatValueVector formatArgs; + for (int i = 2; i < argc; i++) + formatArgs.push_back(argv[i]); + String logString = stringformat(argv[1], formatArgs); + dputs(logString.c_str()); + return STATUS_CONTINUE; +} + +#include + +CMDRESULT cbInstrCapstone(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("not enough arguments..."); + return STATUS_ERROR; + } + + duint addr = 0; + if (!valfromstring(argv[1], &addr) || !MemIsValidReadPtr(addr)) + { + dprintf("invalid address \"%s\"\n", argv[1]); + return STATUS_ERROR; + } + + unsigned char data[16]; + if (!MemRead(addr, data, sizeof(data))) + { + dprintf("could not read memory at %p\n", addr); + return STATUS_ERROR; + } + + Capstone cp; + if (!cp.Disassemble(addr, data)) + { + dprintf("failed to disassemble!"); + return STATUS_ERROR; + } + + const cs_insn* instr = cp.GetInstr(); + const cs_x86 & x86 = cp.x86(); + int argcount = x86.op_count; + dprintf("%s %s\n", instr->mnemonic, instr->op_str); + dprintf("size: %d, id: %d, opcount: %d\n", cp.Size(), cp.GetId(), cp.OpCount()); + for (int i = 0; i < argcount; i++) + { + const cs_x86_op & op = x86.operands[i]; + dprintf("operand \"%s\" %d, ", cp.OperandText(i).c_str(), i + 1); + switch (op.type) + { + case X86_OP_REG: + dprintf("register: %s\n", cp.RegName((x86_reg)op.reg)); + break; + case X86_OP_IMM: + dprintf("immediate: 0x%p\n", op.imm); + break; + case X86_OP_MEM: + { + //[base + index * scale +/- disp] + const x86_op_mem & mem = op.mem; + dprintf("memory segment: %s, base: %s, index: %s, scale: %d, displacement: 0x%p\n", + cp.RegName((x86_reg)mem.segment), + cp.RegName((x86_reg)mem.base), + cp.RegName((x86_reg)mem.index), + mem.scale, + mem.disp); + } + break; + case X86_OP_FP: + dprintf("float: %f\n", op.fp); + break; + } + } + + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrAnalyseNukem(int argc, char* argv[]) +{ + SELECTIONDATA sel; + GuiSelectionGet(GUI_DISASSEMBLY, &sel); + duint size = 0; + duint base = MemFindBaseAddr(sel.start, &size); + Analyse_nukem(base, size); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrAnalyse(int argc, char* argv[]) +{ + SELECTIONDATA sel; + GuiSelectionGet(GUI_DISASSEMBLY, &sel); + duint size = 0; + duint base = MemFindBaseAddr(sel.start, &size); + LinearAnalysis anal(base, size); + anal.Analyse(); + anal.SetMarkers(); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrCfanalyse(int argc, char* argv[]) +{ + bool exceptionDirectory = false; + if (argc > 1) + exceptionDirectory = true; + SELECTIONDATA sel; + GuiSelectionGet(GUI_DISASSEMBLY, &sel); + duint size = 0; + duint base = MemFindBaseAddr(sel.start, &size); + ControlFlowAnalysis anal(base, size, exceptionDirectory); + anal.Analyse(); + anal.SetMarkers(); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrExanalyse(int argc, char* argv[]) +{ + SELECTIONDATA sel; + GuiSelectionGet(GUI_DISASSEMBLY, &sel); + duint size = 0; + duint base = MemFindBaseAddr(sel.start, &size); + ExceptionDirectoryAnalysis anal(base, size); + anal.Analyse(); + anal.SetMarkers(); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrVirtualmod(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("Not enough arguments!"); + return STATUS_ERROR; + } + duint base; + if (!valfromstring(argv[2], &base)) + { + dputs("Invalid parameter [base]!"); + return STATUS_ERROR; + } + if (!MemIsValidReadPtr(base)) + { + dputs("Invalid memory address!"); + return STATUS_ERROR; + } + duint size; + if (argc < 4) + base = MemFindBaseAddr(base, &size); + else if (!valfromstring(argv[3], &size)) + { + dputs("Invalid parameter [size]"); + return STATUS_ERROR; + } + auto name = String("virtual:\\") + (argv[1]); + if (!ModLoad(base, size, name.c_str())) + { + dputs("Failed to load module (ModLoad)..."); + return STATUS_ERROR; + } + + char modname[256] = ""; + if (ModNameFromAddr(base, modname, true)) + BpEnumAll(cbSetModuleBreakpoints, modname); + + dprintf("Virtual module \"%s\" loaded on %p[%p]!\n", argv[1], base, size); + GuiUpdateAllViews(); + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrVisualize(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + duint start; + duint maxaddr; + if (!valfromstring(argv[1], &start) || !valfromstring(argv[2], &maxaddr)) + { + dputs("invalid arguments!"); + return STATUS_ERROR; + } + //actual algorithm + //make sure to set these options in the INI (rest the default theme of x64dbg): + //DisassemblyBookmarkBackgroundColor = #00FFFF + //DisassemblyBookmarkColor = #000000 + //DisassemblyHardwareBreakpointBackgroundColor = #00FF00 + //DisassemblyHardwareBreakpointColor = #000000 + //DisassemblyBreakpointBackgroundColor = #FF0000 + //DisassemblyBreakpointColor = #000000 + { + //initialize + Capstone _cp; + duint _base = start; + duint _size = maxaddr - start; + Memory _data(_size); + MemRead(_base, _data(), _size); + FunctionClear(); + + //linear search with some trickery + duint end = 0; + duint jumpback = 0; + for (duint addr = start, fardest = 0; addr < maxaddr;) + { + //update GUI + BpClear(); + BookmarkClear(); + LabelClear(); + SetContextDataEx(fdProcessInfo->hThread, UE_CIP, addr); + if (end) + BpNew(end, true, false, 0, BPNORMAL, 0, nullptr); + if (jumpback) + BookmarkSet(jumpback, false); + if (fardest) + BpNew(fardest, true, false, 0, BPHARDWARE, 0, nullptr); + DebugUpdateGui(addr, false); + Sleep(300); + + //continue algorithm + const unsigned char* curData = (addr >= _base && addr < _base + _size) ? _data() + (addr - _base) : nullptr; + if (_cp.Disassemble(addr, curData, MAX_DISASM_BUFFER)) + { + if (addr + _cp.Size() > maxaddr) //we went past the maximum allowed address + break; + + const cs_x86_op & operand = _cp.x86().operands[0]; + if ((_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) && operand.type == X86_OP_IMM) //jump + { + duint dest = (duint)operand.imm; + + if (dest >= maxaddr) //jump across function boundaries + { + //currently unused + } + else if (dest > addr && dest > fardest) //save the farthest JXX destination forward + { + fardest = dest; + } + else if (end && dest < end && _cp.GetId() == X86_INS_JMP) //save the last JMP backwards + { + jumpback = addr; + } + } + else if (_cp.InGroup(CS_GRP_RET)) //possible function end? + { + end = addr; + if (fardest < addr) //we stop if the farthest JXX destination forward is before this RET + break; + } + + addr += _cp.Size(); + } + else + addr++; + } + end = end < jumpback ? jumpback : end; + + //update GUI + FunctionAdd(start, end, false); + BpClear(); + BookmarkClear(); + SetContextDataEx(fdProcessInfo->hThread, UE_CIP, start); + DebugUpdateGui(start, false); + } + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrMeminfo(int argc, char* argv[]) +{ + if (argc < 3) + { + dputs("usage: meminfo a/r, addr"); + return STATUS_ERROR; + } + duint addr; + if (!valfromstring(argv[2], &addr)) + { + dputs("invalid argument"); + return STATUS_ERROR; + } + if (argv[1][0] == 'a') + { + unsigned char buf = 0; + if (!ReadProcessMemory(fdProcessInfo->hProcess, (void*)addr, &buf, sizeof(buf), nullptr)) + dputs("ReadProcessMemory failed!"); + else + dprintf("data: %02X\n", buf); + } + else if (argv[1][0] == 'r') + { + MemUpdateMap(); + GuiUpdateMemoryView(); + dputs("memory map updated!"); + } + return STATUS_CONTINUE; +} + +CMDRESULT cbInstrSetMaxFindResult(int argc, char* argv[]) +{ + if (argc < 2) + { + dputs("Not enough arguments!"); + return STATUS_ERROR; + } + duint num; + if (!valfromstring(argv[1], &num)) + { + dprintf("Invalid expression: \"%s\"", argv[1]); + return STATUS_ERROR; + } + maxFindResults = int(num & 0x7FFFFFFF); + return STATUS_CONTINUE; } \ No newline at end of file diff --git a/src/dbg/instruction.h b/src/dbg/instruction.h index 6aec2249..48f69688 100644 --- a/src/dbg/instruction.h +++ b/src/dbg/instruction.h @@ -1,81 +1,81 @@ -#ifndef _INSTRUCTIONS_H -#define _INSTRUCTIONS_H - -#include "command.h" - -//functions -CMDRESULT cbBadCmd(int argc, char* argv[]); -CMDRESULT cbInstrVar(int argc, char* argv[]); -CMDRESULT cbInstrVarDel(int argc, char* argv[]); -CMDRESULT cbInstrMov(int argc, char* argv[]); -CMDRESULT cbInstrVarList(int argc, char* argv[]); -CMDRESULT cbInstrChd(int argc, char* argv[]); -CMDRESULT cbInstrCmt(int argc, char* argv[]); -CMDRESULT cbInstrCmtdel(int argc, char* argv[]); -CMDRESULT cbInstrLbl(int argc, char* argv[]); -CMDRESULT cbInstrLbldel(int argc, char* argv[]); -CMDRESULT cbInstrBookmarkSet(int argc, char* argv[]); -CMDRESULT cbInstrBookmarkDel(int argc, char* argv[]); -CMDRESULT cbInstrLoaddb(int argc, char* argv[]); -CMDRESULT cbInstrSavedb(int argc, char* argv[]); -CMDRESULT cbInstrAssemble(int argc, char* argv[]); -CMDRESULT cbInstrFunctionAdd(int argc, char* argv[]); -CMDRESULT cbInstrFunctionDel(int argc, char* argv[]); - -CMDRESULT cbInstrCmp(int argc, char* argv[]); -CMDRESULT cbInstrGpa(int argc, char* argv[]); -CMDRESULT cbInstrAdd(int argc, char* argv[]); -CMDRESULT cbInstrAnd(int argc, char* argv[]); -CMDRESULT cbInstrDec(int argc, char* argv[]); -CMDRESULT cbInstrDiv(int argc, char* argv[]); -CMDRESULT cbInstrInc(int argc, char* argv[]); -CMDRESULT cbInstrMul(int argc, char* argv[]); -CMDRESULT cbInstrNeg(int argc, char* argv[]); -CMDRESULT cbInstrNot(int argc, char* argv[]); -CMDRESULT cbInstrOr(int argc, char* argv[]); -CMDRESULT cbInstrRol(int argc, char* argv[]); -CMDRESULT cbInstrRor(int argc, char* argv[]); -CMDRESULT cbInstrShl(int argc, char* argv[]); -CMDRESULT cbInstrShr(int argc, char* argv[]); -CMDRESULT cbInstrSub(int argc, char* argv[]); -CMDRESULT cbInstrTest(int argc, char* argv[]); -CMDRESULT cbInstrXor(int argc, char* argv[]); -CMDRESULT cbInstrPush(int argc, char* argv[]); -CMDRESULT cbInstrPop(int argc, char* argv[]); - -CMDRESULT cbInstrRefinit(int argc, char* argv[]); -CMDRESULT cbInstrRefadd(int argc, char* argv[]); -CMDRESULT cbInstrRefFind(int argc, char* argv[]); -CMDRESULT cbInstrRefStr(int argc, char* argv[]); -CMDRESULT cbInstrRefFindRange(int argc, char* argv[]); - -CMDRESULT cbInstrSetstr(int argc, char* argv[]); -CMDRESULT cbInstrGetstr(int argc, char* argv[]); -CMDRESULT cbInstrCopystr(int argc, char* argv[]); - -CMDRESULT cbInstrFind(int argc, char* argv[]); -CMDRESULT cbInstrFindAll(int argc, char* argv[]); -CMDRESULT cbInstrFindMemAll(int argc, char* argv[]); -CMDRESULT cbInstrModCallFind(int argc, char* argv[]); -CMDRESULT cbInstrCommentList(int argc, char* argv[]); -CMDRESULT cbInstrLabelList(int argc, char* argv[]); -CMDRESULT cbInstrBookmarkList(int argc, char* argv[]); -CMDRESULT cbInstrFunctionList(int argc, char* argv[]); -CMDRESULT cbInstrLoopList(int argc, char* argv[]); -CMDRESULT cbInstrSleep(int argc, char* argv[]); -CMDRESULT cbInstrFindAsm(int argc, char* argv[]); -CMDRESULT cbInstrYara(int argc, char* argv[]); -CMDRESULT cbInstrYaramod(int argc, char* argv[]); -CMDRESULT cbInstrLog(int argc, char* argv[]); - -CMDRESULT cbInstrCapstone(int argc, char* argv[]); -CMDRESULT cbInstrAnalyseNukem(int argc, char* argv[]); -CMDRESULT cbInstrAnalyse(int argc, char* argv[]); -CMDRESULT cbInstrVisualize(int argc, char* argv[]); -CMDRESULT cbInstrMeminfo(int argc, char* argv[]); -CMDRESULT cbInstrCfanalyse(int argc, char* argv[]); -CMDRESULT cbInstrExanalyse(int argc, char* argv[]); -CMDRESULT cbInstrVirtualmod(int argc, char* argv[]); -CMDRESULT cbInstrSetMaxFindResult(int argc, char* argv[]); - -#endif // _INSTRUCTIONS_H +#ifndef _INSTRUCTIONS_H +#define _INSTRUCTIONS_H + +#include "command.h" + +//functions +CMDRESULT cbBadCmd(int argc, char* argv[]); +CMDRESULT cbInstrVar(int argc, char* argv[]); +CMDRESULT cbInstrVarDel(int argc, char* argv[]); +CMDRESULT cbInstrMov(int argc, char* argv[]); +CMDRESULT cbInstrVarList(int argc, char* argv[]); +CMDRESULT cbInstrChd(int argc, char* argv[]); +CMDRESULT cbInstrCmt(int argc, char* argv[]); +CMDRESULT cbInstrCmtdel(int argc, char* argv[]); +CMDRESULT cbInstrLbl(int argc, char* argv[]); +CMDRESULT cbInstrLbldel(int argc, char* argv[]); +CMDRESULT cbInstrBookmarkSet(int argc, char* argv[]); +CMDRESULT cbInstrBookmarkDel(int argc, char* argv[]); +CMDRESULT cbInstrLoaddb(int argc, char* argv[]); +CMDRESULT cbInstrSavedb(int argc, char* argv[]); +CMDRESULT cbInstrAssemble(int argc, char* argv[]); +CMDRESULT cbInstrFunctionAdd(int argc, char* argv[]); +CMDRESULT cbInstrFunctionDel(int argc, char* argv[]); + +CMDRESULT cbInstrCmp(int argc, char* argv[]); +CMDRESULT cbInstrGpa(int argc, char* argv[]); +CMDRESULT cbInstrAdd(int argc, char* argv[]); +CMDRESULT cbInstrAnd(int argc, char* argv[]); +CMDRESULT cbInstrDec(int argc, char* argv[]); +CMDRESULT cbInstrDiv(int argc, char* argv[]); +CMDRESULT cbInstrInc(int argc, char* argv[]); +CMDRESULT cbInstrMul(int argc, char* argv[]); +CMDRESULT cbInstrNeg(int argc, char* argv[]); +CMDRESULT cbInstrNot(int argc, char* argv[]); +CMDRESULT cbInstrOr(int argc, char* argv[]); +CMDRESULT cbInstrRol(int argc, char* argv[]); +CMDRESULT cbInstrRor(int argc, char* argv[]); +CMDRESULT cbInstrShl(int argc, char* argv[]); +CMDRESULT cbInstrShr(int argc, char* argv[]); +CMDRESULT cbInstrSub(int argc, char* argv[]); +CMDRESULT cbInstrTest(int argc, char* argv[]); +CMDRESULT cbInstrXor(int argc, char* argv[]); +CMDRESULT cbInstrPush(int argc, char* argv[]); +CMDRESULT cbInstrPop(int argc, char* argv[]); + +CMDRESULT cbInstrRefinit(int argc, char* argv[]); +CMDRESULT cbInstrRefadd(int argc, char* argv[]); +CMDRESULT cbInstrRefFind(int argc, char* argv[]); +CMDRESULT cbInstrRefStr(int argc, char* argv[]); +CMDRESULT cbInstrRefFindRange(int argc, char* argv[]); + +CMDRESULT cbInstrSetstr(int argc, char* argv[]); +CMDRESULT cbInstrGetstr(int argc, char* argv[]); +CMDRESULT cbInstrCopystr(int argc, char* argv[]); + +CMDRESULT cbInstrFind(int argc, char* argv[]); +CMDRESULT cbInstrFindAll(int argc, char* argv[]); +CMDRESULT cbInstrFindMemAll(int argc, char* argv[]); +CMDRESULT cbInstrModCallFind(int argc, char* argv[]); +CMDRESULT cbInstrCommentList(int argc, char* argv[]); +CMDRESULT cbInstrLabelList(int argc, char* argv[]); +CMDRESULT cbInstrBookmarkList(int argc, char* argv[]); +CMDRESULT cbInstrFunctionList(int argc, char* argv[]); +CMDRESULT cbInstrLoopList(int argc, char* argv[]); +CMDRESULT cbInstrSleep(int argc, char* argv[]); +CMDRESULT cbInstrFindAsm(int argc, char* argv[]); +CMDRESULT cbInstrYara(int argc, char* argv[]); +CMDRESULT cbInstrYaramod(int argc, char* argv[]); +CMDRESULT cbInstrLog(int argc, char* argv[]); + +CMDRESULT cbInstrCapstone(int argc, char* argv[]); +CMDRESULT cbInstrAnalyseNukem(int argc, char* argv[]); +CMDRESULT cbInstrAnalyse(int argc, char* argv[]); +CMDRESULT cbInstrVisualize(int argc, char* argv[]); +CMDRESULT cbInstrMeminfo(int argc, char* argv[]); +CMDRESULT cbInstrCfanalyse(int argc, char* argv[]); +CMDRESULT cbInstrExanalyse(int argc, char* argv[]); +CMDRESULT cbInstrVirtualmod(int argc, char* argv[]); +CMDRESULT cbInstrSetMaxFindResult(int argc, char* argv[]); + +#endif // _INSTRUCTIONS_H diff --git a/src/dbg/jansson/jansson.h b/src/dbg/jansson/jansson.h index 5c5d2ef2..060c065f 100644 --- a/src/dbg/jansson/jansson.h +++ b/src/dbg/jansson/jansson.h @@ -1,293 +1,293 @@ -/* - * Copyright (c) 2009-2014 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - */ - -#ifndef JANSSON_H -#define JANSSON_H - -#include -#include /* for size_t */ -#include - -#include "jansson_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* version */ - -#define JANSSON_MAJOR_VERSION 2 -#define JANSSON_MINOR_VERSION 7 -#define JANSSON_MICRO_VERSION 0 - -/* Micro version is omitted if it's 0 */ -#define JANSSON_VERSION "2.7" - -/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this - for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */ -#define JANSSON_VERSION_HEX ((JANSSON_MAJOR_VERSION << 16) | \ - (JANSSON_MINOR_VERSION << 8) | \ - (JANSSON_MICRO_VERSION << 0)) - - -/* types */ - -typedef enum -{ - JSON_OBJECT, - JSON_ARRAY, - JSON_STRING, - JSON_INTEGER, - JSON_REAL, - JSON_TRUE, - JSON_FALSE, - JSON_NULL -} json_type; - -typedef struct json_t -{ - json_type type; - size_t refcount; -} json_t; - -#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */ -#if JSON_INTEGER_IS_LONG_LONG -#ifdef _WIN32 -#define JSON_INTEGER_FORMAT "I64d" -#else -#define JSON_INTEGER_FORMAT "lld" -#endif -typedef long long json_int_t; -#else -#define JSON_INTEGER_FORMAT "ld" -typedef long json_int_t; -#endif /* JSON_INTEGER_IS_LONG_LONG */ -#endif - -#define json_typeof(json) ((json)->type) -#define json_is_object(json) ((json) && json_typeof(json) == JSON_OBJECT) -#define json_is_array(json) ((json) && json_typeof(json) == JSON_ARRAY) -#define json_is_string(json) ((json) && json_typeof(json) == JSON_STRING) -#define json_is_integer(json) ((json) && json_typeof(json) == JSON_INTEGER) -#define json_is_real(json) ((json) && json_typeof(json) == JSON_REAL) -#define json_is_number(json) (json_is_integer(json) || json_is_real(json)) -#define json_is_true(json) ((json) && json_typeof(json) == JSON_TRUE) -#define json_is_false(json) ((json) && json_typeof(json) == JSON_FALSE) -#define json_boolean_value json_is_true -#define json_is_boolean(json) (json_is_true(json) || json_is_false(json)) -#define json_is_null(json) ((json) && json_typeof(json) == JSON_NULL) - -/* construction, destruction, reference counting */ - -__declspec(dllimport) json_t* json_object(void); -__declspec(dllimport) json_t* json_array(void); -__declspec(dllimport) json_t* json_string(const char* value); -__declspec(dllimport) json_t* json_stringn(const char* value, size_t len); -__declspec(dllimport) json_t* json_string_nocheck(const char* value); -__declspec(dllimport) json_t* json_stringn_nocheck(const char* value, size_t len); -__declspec(dllimport) json_t* json_integer(json_int_t value); -__declspec(dllimport) json_t* json_real(double value); -__declspec(dllimport) json_t* json_true(void); -__declspec(dllimport) json_t* json_false(void); -#define json_boolean(val) ((val) ? json_true() : json_false()) -__declspec(dllimport) json_t* json_null(void); - -static JSON_INLINE -json_t* json_incref(json_t* json) -{ - if(json && json->refcount != (size_t) - 1) - ++json->refcount; - return json; -} - -/* do not call json_delete directly */ -__declspec(dllimport) void json_delete(json_t* json); - -static JSON_INLINE -void json_decref(json_t* json) -{ - if(json && json->refcount != (size_t) - 1 && --json->refcount == 0) - json_delete(json); -} - - -/* error reporting */ - -#define JSON_ERROR_TEXT_LENGTH 160 -#define JSON_ERROR_SOURCE_LENGTH 80 - -typedef struct -{ - int line; - int column; - int position; - char source[JSON_ERROR_SOURCE_LENGTH]; - char text[JSON_ERROR_TEXT_LENGTH]; -} json_error_t; - - -/* getters, setters, manipulation */ - -__declspec(dllimport) void json_object_seed(size_t seed); -__declspec(dllimport) size_t json_object_size(const json_t* object); -__declspec(dllimport) json_t* json_object_get(const json_t* object, const char* key); -__declspec(dllimport) int json_object_set_new(json_t* object, const char* key, json_t* value); -__declspec(dllimport) int json_object_set_new_nocheck(json_t* object, const char* key, json_t* value); -__declspec(dllimport) int json_object_del(json_t* object, const char* key); -__declspec(dllimport) int json_object_clear(json_t* object); -__declspec(dllimport) int json_object_update(json_t* object, json_t* other); -__declspec(dllimport) int json_object_update_existing(json_t* object, json_t* other); -__declspec(dllimport) int json_object_update_missing(json_t* object, json_t* other); -__declspec(dllimport) void* json_object_iter(json_t* object); -__declspec(dllimport) void* json_object_iter_at(json_t* object, const char* key); -__declspec(dllimport) void* json_object_key_to_iter(const char* key); -__declspec(dllimport) void* json_object_iter_next(json_t* object, void* iter); -__declspec(dllimport) const char* json_object_iter_key(void* iter); -__declspec(dllimport) json_t* json_object_iter_value(void* iter); -__declspec(dllimport) int json_object_iter_set_new(json_t* object, void* iter, json_t* value); - -#define json_object_foreach(object, key, value) \ - for(key = json_object_iter_key(json_object_iter(object)); \ - key && (value = json_object_iter_value(json_object_key_to_iter(key))); \ - key = json_object_iter_key(json_object_iter_next(object, json_object_key_to_iter(key)))) - -#define json_array_foreach(array, index, value) \ - for(index = 0; \ - index < json_array_size(array) && (value = json_array_get(array, index)); \ - index++) - -static JSON_INLINE -int json_object_set(json_t* object, const char* key, json_t* value) -{ - return json_object_set_new(object, key, json_incref(value)); -} - -static JSON_INLINE -int json_object_set_nocheck(json_t* object, const char* key, json_t* value) -{ - return json_object_set_new_nocheck(object, key, json_incref(value)); -} - -static JSON_INLINE -int json_object_iter_set(json_t* object, void* iter, json_t* value) -{ - return json_object_iter_set_new(object, iter, json_incref(value)); -} - -__declspec(dllimport) size_t json_array_size(const json_t* array); -__declspec(dllimport) json_t* json_array_get(const json_t* array, size_t index); -__declspec(dllimport) int json_array_set_new(json_t* array, size_t index, json_t* value); -__declspec(dllimport) int json_array_append_new(json_t* array, json_t* value); -__declspec(dllimport) int json_array_insert_new(json_t* array, size_t index, json_t* value); -__declspec(dllimport) int json_array_remove(json_t* array, size_t index); -__declspec(dllimport) int json_array_clear(json_t* array); -__declspec(dllimport) int json_array_extend(json_t* array, json_t* other); - -static JSON_INLINE -int json_array_set(json_t* array, size_t ind, json_t* value) -{ - return json_array_set_new(array, ind, json_incref(value)); -} - -static JSON_INLINE -int json_array_append(json_t* array, json_t* value) -{ - return json_array_append_new(array, json_incref(value)); -} - -static JSON_INLINE -int json_array_insert(json_t* array, size_t ind, json_t* value) -{ - return json_array_insert_new(array, ind, json_incref(value)); -} - -__declspec(dllimport) const char* json_string_value(const json_t* string); -__declspec(dllimport) size_t json_string_length(const json_t* string); -__declspec(dllimport) json_int_t json_integer_value(const json_t* integer); -__declspec(dllimport) double json_real_value(const json_t* real); -__declspec(dllimport) double json_number_value(const json_t* json); - -__declspec(dllimport) int json_string_set(json_t* string, const char* value); -__declspec(dllimport) int json_string_setn(json_t* string, const char* value, size_t len); -__declspec(dllimport) int json_string_set_nocheck(json_t* string, const char* value); -__declspec(dllimport) int json_string_setn_nocheck(json_t* string, const char* value, size_t len); -__declspec(dllimport) int json_integer_set(json_t* integer, json_int_t value); -__declspec(dllimport) int json_real_set(json_t* real, double value); - -/* pack, unpack */ - -__declspec(dllimport) json_t* json_pack(const char* fmt, ...); -__declspec(dllimport) json_t* json_pack_ex(json_error_t* error, size_t flags, const char* fmt, ...); -__declspec(dllimport) json_t* json_vpack_ex(json_error_t* error, size_t flags, const char* fmt, va_list ap); - -#define JSON_VALIDATE_ONLY 0x1 -#define JSON_STRICT 0x2 - -__declspec(dllimport) int json_unpack(json_t* root, const char* fmt, ...); -__declspec(dllimport) int json_unpack_ex(json_t* root, json_error_t* error, size_t flags, const char* fmt, ...); -__declspec(dllimport) int json_vunpack_ex(json_t* root, json_error_t* error, size_t flags, const char* fmt, va_list ap); - - -/* equality */ - -__declspec(dllimport) int json_equal(json_t* value1, json_t* value2); - - -/* copying */ - -__declspec(dllimport) json_t* json_copy(json_t* value); -__declspec(dllimport) json_t* json_deep_copy(const json_t* value); - - -/* decoding */ - -#define JSON_REJECT_DUPLICATES 0x1 -#define JSON_DISABLE_EOF_CHECK 0x2 -#define JSON_DECODE_ANY 0x4 -#define JSON_DECODE_INT_AS_REAL 0x8 -#define JSON_ALLOW_NUL 0x10 - -typedef size_t (*json_load_callback_t)(void* buffer, size_t buflen, void* data); - -__declspec(dllimport) json_t* json_loads(const char* input, size_t flags, json_error_t* error); -__declspec(dllimport) json_t* json_loadb(const char* buffer, size_t buflen, size_t flags, json_error_t* error); -__declspec(dllimport) json_t* json_loadf(FILE* input, size_t flags, json_error_t* error); -__declspec(dllimport) json_t* json_load_file(const char* path, size_t flags, json_error_t* error); -__declspec(dllimport) json_t* json_load_callback(json_load_callback_t callback, void* data, size_t flags, json_error_t* error); - - -/* encoding */ - -#define JSON_MAX_INDENT 0x1F -#define JSON_INDENT(n) ((n) & JSON_MAX_INDENT) -#define JSON_COMPACT 0x20 -#define JSON_ENSURE_ASCII 0x40 -#define JSON_SORT_KEYS 0x80 -#define JSON_PRESERVE_ORDER 0x100 -#define JSON_ENCODE_ANY 0x200 -#define JSON_ESCAPE_SLASH 0x400 -#define JSON_REAL_PRECISION(n) (((n) & 0x1F) << 11) - -typedef int (*json_dump_callback_t)(const char* buffer, size_t size, void* data); - -__declspec(dllimport) char* json_dumps(const json_t* json, size_t flags); -__declspec(dllimport) int json_dumpf(const json_t* json, FILE* output, size_t flags); -__declspec(dllimport) int json_dump_file(const json_t* json, const char* path, size_t flags); -__declspec(dllimport) int json_dump_callback(const json_t* json, json_dump_callback_t callback, void* data, size_t flags); - -/* custom memory allocation */ - -typedef void* (*json_malloc_t)(size_t); -typedef void (*json_free_t)(void*); - -__declspec(dllimport) void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn); - -#ifdef __cplusplus -} -#endif - -#endif +/* + * Copyright (c) 2009-2014 Petri Lehtinen + * + * Jansson is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +#ifndef JANSSON_H +#define JANSSON_H + +#include +#include /* for size_t */ +#include + +#include "jansson_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* version */ + +#define JANSSON_MAJOR_VERSION 2 +#define JANSSON_MINOR_VERSION 7 +#define JANSSON_MICRO_VERSION 0 + +/* Micro version is omitted if it's 0 */ +#define JANSSON_VERSION "2.7" + +/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this + for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */ +#define JANSSON_VERSION_HEX ((JANSSON_MAJOR_VERSION << 16) | \ + (JANSSON_MINOR_VERSION << 8) | \ + (JANSSON_MICRO_VERSION << 0)) + + +/* types */ + +typedef enum +{ + JSON_OBJECT, + JSON_ARRAY, + JSON_STRING, + JSON_INTEGER, + JSON_REAL, + JSON_TRUE, + JSON_FALSE, + JSON_NULL +} json_type; + +typedef struct json_t +{ + json_type type; + size_t refcount; +} json_t; + +#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */ +#if JSON_INTEGER_IS_LONG_LONG +#ifdef _WIN32 +#define JSON_INTEGER_FORMAT "I64d" +#else +#define JSON_INTEGER_FORMAT "lld" +#endif +typedef long long json_int_t; +#else +#define JSON_INTEGER_FORMAT "ld" +typedef long json_int_t; +#endif /* JSON_INTEGER_IS_LONG_LONG */ +#endif + +#define json_typeof(json) ((json)->type) +#define json_is_object(json) ((json) && json_typeof(json) == JSON_OBJECT) +#define json_is_array(json) ((json) && json_typeof(json) == JSON_ARRAY) +#define json_is_string(json) ((json) && json_typeof(json) == JSON_STRING) +#define json_is_integer(json) ((json) && json_typeof(json) == JSON_INTEGER) +#define json_is_real(json) ((json) && json_typeof(json) == JSON_REAL) +#define json_is_number(json) (json_is_integer(json) || json_is_real(json)) +#define json_is_true(json) ((json) && json_typeof(json) == JSON_TRUE) +#define json_is_false(json) ((json) && json_typeof(json) == JSON_FALSE) +#define json_boolean_value json_is_true +#define json_is_boolean(json) (json_is_true(json) || json_is_false(json)) +#define json_is_null(json) ((json) && json_typeof(json) == JSON_NULL) + +/* construction, destruction, reference counting */ + +__declspec(dllimport) json_t* json_object(void); +__declspec(dllimport) json_t* json_array(void); +__declspec(dllimport) json_t* json_string(const char* value); +__declspec(dllimport) json_t* json_stringn(const char* value, size_t len); +__declspec(dllimport) json_t* json_string_nocheck(const char* value); +__declspec(dllimport) json_t* json_stringn_nocheck(const char* value, size_t len); +__declspec(dllimport) json_t* json_integer(json_int_t value); +__declspec(dllimport) json_t* json_real(double value); +__declspec(dllimport) json_t* json_true(void); +__declspec(dllimport) json_t* json_false(void); +#define json_boolean(val) ((val) ? json_true() : json_false()) +__declspec(dllimport) json_t* json_null(void); + +static JSON_INLINE +json_t* json_incref(json_t* json) +{ + if(json && json->refcount != (size_t) - 1) + ++json->refcount; + return json; +} + +/* do not call json_delete directly */ +__declspec(dllimport) void json_delete(json_t* json); + +static JSON_INLINE +void json_decref(json_t* json) +{ + if(json && json->refcount != (size_t) - 1 && --json->refcount == 0) + json_delete(json); +} + + +/* error reporting */ + +#define JSON_ERROR_TEXT_LENGTH 160 +#define JSON_ERROR_SOURCE_LENGTH 80 + +typedef struct +{ + int line; + int column; + int position; + char source[JSON_ERROR_SOURCE_LENGTH]; + char text[JSON_ERROR_TEXT_LENGTH]; +} json_error_t; + + +/* getters, setters, manipulation */ + +__declspec(dllimport) void json_object_seed(size_t seed); +__declspec(dllimport) size_t json_object_size(const json_t* object); +__declspec(dllimport) json_t* json_object_get(const json_t* object, const char* key); +__declspec(dllimport) int json_object_set_new(json_t* object, const char* key, json_t* value); +__declspec(dllimport) int json_object_set_new_nocheck(json_t* object, const char* key, json_t* value); +__declspec(dllimport) int json_object_del(json_t* object, const char* key); +__declspec(dllimport) int json_object_clear(json_t* object); +__declspec(dllimport) int json_object_update(json_t* object, json_t* other); +__declspec(dllimport) int json_object_update_existing(json_t* object, json_t* other); +__declspec(dllimport) int json_object_update_missing(json_t* object, json_t* other); +__declspec(dllimport) void* json_object_iter(json_t* object); +__declspec(dllimport) void* json_object_iter_at(json_t* object, const char* key); +__declspec(dllimport) void* json_object_key_to_iter(const char* key); +__declspec(dllimport) void* json_object_iter_next(json_t* object, void* iter); +__declspec(dllimport) const char* json_object_iter_key(void* iter); +__declspec(dllimport) json_t* json_object_iter_value(void* iter); +__declspec(dllimport) int json_object_iter_set_new(json_t* object, void* iter, json_t* value); + +#define json_object_foreach(object, key, value) \ + for(key = json_object_iter_key(json_object_iter(object)); \ + key && (value = json_object_iter_value(json_object_key_to_iter(key))); \ + key = json_object_iter_key(json_object_iter_next(object, json_object_key_to_iter(key)))) + +#define json_array_foreach(array, index, value) \ + for(index = 0; \ + index < json_array_size(array) && (value = json_array_get(array, index)); \ + index++) + +static JSON_INLINE +int json_object_set(json_t* object, const char* key, json_t* value) +{ + return json_object_set_new(object, key, json_incref(value)); +} + +static JSON_INLINE +int json_object_set_nocheck(json_t* object, const char* key, json_t* value) +{ + return json_object_set_new_nocheck(object, key, json_incref(value)); +} + +static JSON_INLINE +int json_object_iter_set(json_t* object, void* iter, json_t* value) +{ + return json_object_iter_set_new(object, iter, json_incref(value)); +} + +__declspec(dllimport) size_t json_array_size(const json_t* array); +__declspec(dllimport) json_t* json_array_get(const json_t* array, size_t index); +__declspec(dllimport) int json_array_set_new(json_t* array, size_t index, json_t* value); +__declspec(dllimport) int json_array_append_new(json_t* array, json_t* value); +__declspec(dllimport) int json_array_insert_new(json_t* array, size_t index, json_t* value); +__declspec(dllimport) int json_array_remove(json_t* array, size_t index); +__declspec(dllimport) int json_array_clear(json_t* array); +__declspec(dllimport) int json_array_extend(json_t* array, json_t* other); + +static JSON_INLINE +int json_array_set(json_t* array, size_t ind, json_t* value) +{ + return json_array_set_new(array, ind, json_incref(value)); +} + +static JSON_INLINE +int json_array_append(json_t* array, json_t* value) +{ + return json_array_append_new(array, json_incref(value)); +} + +static JSON_INLINE +int json_array_insert(json_t* array, size_t ind, json_t* value) +{ + return json_array_insert_new(array, ind, json_incref(value)); +} + +__declspec(dllimport) const char* json_string_value(const json_t* string); +__declspec(dllimport) size_t json_string_length(const json_t* string); +__declspec(dllimport) json_int_t json_integer_value(const json_t* integer); +__declspec(dllimport) double json_real_value(const json_t* real); +__declspec(dllimport) double json_number_value(const json_t* json); + +__declspec(dllimport) int json_string_set(json_t* string, const char* value); +__declspec(dllimport) int json_string_setn(json_t* string, const char* value, size_t len); +__declspec(dllimport) int json_string_set_nocheck(json_t* string, const char* value); +__declspec(dllimport) int json_string_setn_nocheck(json_t* string, const char* value, size_t len); +__declspec(dllimport) int json_integer_set(json_t* integer, json_int_t value); +__declspec(dllimport) int json_real_set(json_t* real, double value); + +/* pack, unpack */ + +__declspec(dllimport) json_t* json_pack(const char* fmt, ...); +__declspec(dllimport) json_t* json_pack_ex(json_error_t* error, size_t flags, const char* fmt, ...); +__declspec(dllimport) json_t* json_vpack_ex(json_error_t* error, size_t flags, const char* fmt, va_list ap); + +#define JSON_VALIDATE_ONLY 0x1 +#define JSON_STRICT 0x2 + +__declspec(dllimport) int json_unpack(json_t* root, const char* fmt, ...); +__declspec(dllimport) int json_unpack_ex(json_t* root, json_error_t* error, size_t flags, const char* fmt, ...); +__declspec(dllimport) int json_vunpack_ex(json_t* root, json_error_t* error, size_t flags, const char* fmt, va_list ap); + + +/* equality */ + +__declspec(dllimport) int json_equal(json_t* value1, json_t* value2); + + +/* copying */ + +__declspec(dllimport) json_t* json_copy(json_t* value); +__declspec(dllimport) json_t* json_deep_copy(const json_t* value); + + +/* decoding */ + +#define JSON_REJECT_DUPLICATES 0x1 +#define JSON_DISABLE_EOF_CHECK 0x2 +#define JSON_DECODE_ANY 0x4 +#define JSON_DECODE_INT_AS_REAL 0x8 +#define JSON_ALLOW_NUL 0x10 + +typedef size_t (*json_load_callback_t)(void* buffer, size_t buflen, void* data); + +__declspec(dllimport) json_t* json_loads(const char* input, size_t flags, json_error_t* error); +__declspec(dllimport) json_t* json_loadb(const char* buffer, size_t buflen, size_t flags, json_error_t* error); +__declspec(dllimport) json_t* json_loadf(FILE* input, size_t flags, json_error_t* error); +__declspec(dllimport) json_t* json_load_file(const char* path, size_t flags, json_error_t* error); +__declspec(dllimport) json_t* json_load_callback(json_load_callback_t callback, void* data, size_t flags, json_error_t* error); + + +/* encoding */ + +#define JSON_MAX_INDENT 0x1F +#define JSON_INDENT(n) ((n) & JSON_MAX_INDENT) +#define JSON_COMPACT 0x20 +#define JSON_ENSURE_ASCII 0x40 +#define JSON_SORT_KEYS 0x80 +#define JSON_PRESERVE_ORDER 0x100 +#define JSON_ENCODE_ANY 0x200 +#define JSON_ESCAPE_SLASH 0x400 +#define JSON_REAL_PRECISION(n) (((n) & 0x1F) << 11) + +typedef int (*json_dump_callback_t)(const char* buffer, size_t size, void* data); + +__declspec(dllimport) char* json_dumps(const json_t* json, size_t flags); +__declspec(dllimport) int json_dumpf(const json_t* json, FILE* output, size_t flags); +__declspec(dllimport) int json_dump_file(const json_t* json, const char* path, size_t flags); +__declspec(dllimport) int json_dump_callback(const json_t* json, json_dump_callback_t callback, void* data, size_t flags); + +/* custom memory allocation */ + +typedef void* (*json_malloc_t)(size_t); +typedef void (*json_free_t)(void*); + +__declspec(dllimport) void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/dbg/jansson/jansson_config.h b/src/dbg/jansson/jansson_config.h index 85269998..b80a497a 100644 --- a/src/dbg/jansson/jansson_config.h +++ b/src/dbg/jansson/jansson_config.h @@ -1,64 +1,64 @@ -/* - * Copyright (c) 2010-2014 Petri Lehtinen - * - * Jansson is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See LICENSE for details. - * - * - * This file specifies a part of the site-specific configuration for - * Jansson, namely those things that affect the public API in - * jansson.h. - * - * The CMake system will generate the jansson_config.h file and - * copy it to the build and install directories. - */ - -#ifndef JANSSON_CONFIG_H -#define JANSSON_CONFIG_H - -/* Define this so that we can disable scattered automake configuration in source files */ -#ifndef JANSSON_USING_CMAKE -#define JANSSON_USING_CMAKE -#endif - -/* Note: when using cmake, JSON_INTEGER_IS_LONG_LONG is not defined nor used, - * as we will also check for __int64 etc types. - * (the definition was used in the automake system) */ - -/* Bring in the cmake-detected defines */ -#define HAVE_STDINT_H 1 -/* #undef HAVE_INTTYPES_H */ -/* #undef HAVE_SYS_TYPES_H */ - -/* Include our standard type header for the integer typedef */ - -#if defined(HAVE_STDINT_H) -# include -#elif defined(HAVE_INTTYPES_H) -# include -#elif defined(HAVE_SYS_TYPES_H) -# include -#endif - - -/* If your compiler supports the inline keyword in C, JSON_INLINE is - defined to `inline', otherwise empty. In C++, the inline is always - supported. */ -#ifdef __cplusplus -#define JSON_INLINE inline -#else -#define JSON_INLINE __inline -#endif - - -#define json_int_t long long -#define json_strtoint _strtoi64 -#define JSON_INTEGER_FORMAT "I64d" - - -/* If locale.h and localeconv() are available, define to 1, otherwise to 0. */ -#define JSON_HAVE_LOCALECONV 1 - - - -#endif +/* + * Copyright (c) 2010-2014 Petri Lehtinen + * + * Jansson is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + * + * + * This file specifies a part of the site-specific configuration for + * Jansson, namely those things that affect the public API in + * jansson.h. + * + * The CMake system will generate the jansson_config.h file and + * copy it to the build and install directories. + */ + +#ifndef JANSSON_CONFIG_H +#define JANSSON_CONFIG_H + +/* Define this so that we can disable scattered automake configuration in source files */ +#ifndef JANSSON_USING_CMAKE +#define JANSSON_USING_CMAKE +#endif + +/* Note: when using cmake, JSON_INTEGER_IS_LONG_LONG is not defined nor used, + * as we will also check for __int64 etc types. + * (the definition was used in the automake system) */ + +/* Bring in the cmake-detected defines */ +#define HAVE_STDINT_H 1 +/* #undef HAVE_INTTYPES_H */ +/* #undef HAVE_SYS_TYPES_H */ + +/* Include our standard type header for the integer typedef */ + +#if defined(HAVE_STDINT_H) +# include +#elif defined(HAVE_INTTYPES_H) +# include +#elif defined(HAVE_SYS_TYPES_H) +# include +#endif + + +/* If your compiler supports the inline keyword in C, JSON_INLINE is + defined to `inline', otherwise empty. In C++, the inline is always + supported. */ +#ifdef __cplusplus +#define JSON_INLINE inline +#else +#define JSON_INLINE __inline +#endif + + +#define json_int_t long long +#define json_strtoint _strtoi64 +#define JSON_INTEGER_FORMAT "I64d" + + +/* If locale.h and localeconv() are available, define to 1, otherwise to 0. */ +#define JSON_HAVE_LOCALECONV 1 + + + +#endif diff --git a/src/dbg/jansson/jansson_x64dbg.h b/src/dbg/jansson/jansson_x64dbg.h index d84890a7..7a5c4283 100644 --- a/src/dbg/jansson/jansson_x64dbg.h +++ b/src/dbg/jansson/jansson_x64dbg.h @@ -1,29 +1,29 @@ -typedef json_t* JSON; - -static JSON_INLINE -json_t* json_hex(unsigned json_int_t value) -{ - char hexvalue[20]; -#ifdef _WIN64 - sprintf(hexvalue, "0x%llX", value); -#else //x64 - sprintf(hexvalue, "0x%X", value); -#endif //_WIN64 - return json_string(hexvalue); -} - -static JSON_INLINE -unsigned json_int_t json_hex_value(const json_t* hex) -{ - unsigned json_int_t ret; - const char* hexvalue; - hexvalue = json_string_value(hex); - if(!hexvalue) - return 0; -#ifdef _WIN64 - sscanf(hexvalue, "0x%llX", &ret); -#else //x64 - sscanf(hexvalue, "0x%X", &ret); -#endif //_WIN64 - return ret; +typedef json_t* JSON; + +static JSON_INLINE +json_t* json_hex(unsigned json_int_t value) +{ + char hexvalue[20]; +#ifdef _WIN64 + sprintf(hexvalue, "0x%llX", value); +#else //x64 + sprintf(hexvalue, "0x%X", value); +#endif //_WIN64 + return json_string(hexvalue); +} + +static JSON_INLINE +unsigned json_int_t json_hex_value(const json_t* hex) +{ + unsigned json_int_t ret; + const char* hexvalue; + hexvalue = json_string_value(hex); + if(!hexvalue) + return 0; +#ifdef _WIN64 + sscanf(hexvalue, "0x%llX", &ret); +#else //x64 + sscanf(hexvalue, "0x%X", &ret); +#endif //_WIN64 + return ret; } \ No newline at end of file diff --git a/src/dbg/jit.cpp b/src/dbg/jit.cpp index 863ba41e..41981ca8 100644 --- a/src/dbg/jit.cpp +++ b/src/dbg/jit.cpp @@ -1,190 +1,190 @@ -#include "jit.h" - -bool IsProcessElevated() -{ - SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; - PSID SecurityIdentifier; - if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &SecurityIdentifier)) - return 0; - - BOOL IsAdminMember; - if (!CheckTokenMembership(NULL, SecurityIdentifier, &IsAdminMember)) - IsAdminMember = FALSE; - - FreeSid(SecurityIdentifier); - return !!IsAdminMember; -} - -static bool readwritejitkey(wchar_t* jit_key_value, DWORD* jit_key_vale_size, char* key, arch arch_in, arch* arch_out, readwritejitkey_error_t* error, bool write) -{ - DWORD key_flags; - DWORD lRv; - HKEY hKey; - DWORD dwDisposition; - - if (error != NULL) - *error = ERROR_RW; - - if (write) - { - if (!IsProcessElevated()) - { - if (error != NULL) - *error = ERROR_RW_NOTADMIN; - return false; - } - key_flags = KEY_WRITE; - } - else - key_flags = KEY_READ; - - if (arch_out != NULL) - { - if (arch_in != x64 && arch_in != x32) - { -#ifdef _WIN64 - *arch_out = x64; -#else //x86 - *arch_out = x32; -#endif //_WIN64 - } - else - *arch_out = arch_in; - } - - if (arch_in == x64) - { -#ifndef _WIN64 - if (!IsWow64()) - { - if (error != NULL) - *error = ERROR_RW_NOTWOW64; - return false; - } - key_flags |= KEY_WOW64_64KEY; -#endif //_WIN64 - } - else if (arch_in == x32) - { -#ifdef _WIN64 - key_flags |= KEY_WOW64_32KEY; -#endif - } - - if (write) - { - lRv = RegCreateKeyEx(HKEY_LOCAL_MACHINE, JIT_REG_KEY, 0, NULL, REG_OPTION_NON_VOLATILE, key_flags, NULL, &hKey, &dwDisposition); - if (lRv != ERROR_SUCCESS) - return false; - - lRv = RegSetValueExW(hKey, StringUtils::Utf8ToUtf16(key).c_str(), 0, REG_SZ, (BYTE*)jit_key_value, (DWORD)(*jit_key_vale_size) + 1); - } - else - { - lRv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, JIT_REG_KEY, 0, key_flags, &hKey); - if (lRv != ERROR_SUCCESS) - { - if (error != NULL) - *error = ERROR_RW_FILE_NOT_FOUND; - return false; - } - - lRv = RegQueryValueExW(hKey, StringUtils::Utf8ToUtf16(key).c_str(), 0, NULL, (LPBYTE)jit_key_value, jit_key_vale_size); - if (lRv != ERROR_SUCCESS) - { - if (error != NULL) - *error = ERROR_RW_FILE_NOT_FOUND; - } - } - - RegCloseKey(hKey); - return (lRv == ERROR_SUCCESS); -} - -bool dbggetjitauto(bool* auto_on, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out) -{ - wchar_t jit_entry[4] = L""; - DWORD jit_entry_size = sizeof(jit_entry) - 1; - readwritejitkey_error_t rw_error; - - if (!readwritejitkey(jit_entry, &jit_entry_size, "Auto", arch_in, arch_out, &rw_error, false)) - { - if (rw_error == ERROR_RW_FILE_NOT_FOUND) - { - if (rw_error_out != NULL) - *rw_error_out = rw_error; - return true; - } - return false; - } - if (_wcsicmp(jit_entry, L"1") == 0) - *auto_on = true; - else if (_wcsicmp(jit_entry, L"0") == 0) - *auto_on = false; - else - return false; - return true; -} - -bool dbgsetjitauto(bool auto_on, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out) -{ - DWORD auto_string_size = sizeof(L"1"); - readwritejitkey_error_t rw_error; - if (!auto_on) - { - wchar_t jit_entry[4] = L""; - DWORD jit_entry_size = sizeof(jit_entry) - 1; - if (!readwritejitkey(jit_entry, &jit_entry_size, "Auto", arch_in, arch_out, &rw_error, false)) - { - if (rw_error == ERROR_RW_FILE_NOT_FOUND) - return true; - } - } - if (!readwritejitkey(auto_on ? L"1" : L"0", &auto_string_size, "Auto", arch_in, arch_out, &rw_error, true)) - { - if (rw_error_out != NULL) - *rw_error_out = rw_error; - return false; - } - return true; -} - -bool dbggetjit(char jit_entry[JIT_ENTRY_MAX_SIZE], arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out) -{ - wchar_t wszJitEntry[JIT_ENTRY_MAX_SIZE] = L""; - DWORD jit_entry_size = JIT_ENTRY_MAX_SIZE * sizeof(wchar_t); - readwritejitkey_error_t rw_error; - if (!readwritejitkey(wszJitEntry, &jit_entry_size, "Debugger", arch_in, arch_out, &rw_error, false)) - { - if (rw_error_out != NULL) - *rw_error_out = rw_error; - return false; - } - strcpy_s(jit_entry, JIT_ENTRY_MAX_SIZE, StringUtils::Utf16ToUtf8(wszJitEntry).c_str()); - return true; -} - -bool dbggetdefjit(char* jit_entry) -{ - char path[JIT_ENTRY_DEF_SIZE]; - path[0] = '"'; - wchar_t wszPath[MAX_PATH] = L""; - GetModuleFileNameW(GetModuleHandleW(NULL), wszPath, MAX_PATH); - strcpy_s(&path[1], JIT_ENTRY_DEF_SIZE - 1, StringUtils::Utf16ToUtf8(wszPath).c_str()); - strcat(path, ATTACH_CMD_LINE); - strcpy_s(jit_entry, JIT_ENTRY_DEF_SIZE, path); - return true; -} - -bool dbgsetjit(char* jit_cmd, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out) -{ - DWORD jit_cmd_size = (DWORD)strlen(jit_cmd) * sizeof(wchar_t); - readwritejitkey_error_t rw_error; - if (!readwritejitkey((wchar_t*)StringUtils::Utf8ToUtf16(jit_cmd).c_str(), &jit_cmd_size, "Debugger", arch_in, arch_out, &rw_error, true)) - { - if (rw_error_out != NULL) - *rw_error_out = rw_error; - return false; - } - return true; +#include "jit.h" + +bool IsProcessElevated() +{ + SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; + PSID SecurityIdentifier; + if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &SecurityIdentifier)) + return 0; + + BOOL IsAdminMember; + if (!CheckTokenMembership(NULL, SecurityIdentifier, &IsAdminMember)) + IsAdminMember = FALSE; + + FreeSid(SecurityIdentifier); + return !!IsAdminMember; +} + +static bool readwritejitkey(wchar_t* jit_key_value, DWORD* jit_key_vale_size, char* key, arch arch_in, arch* arch_out, readwritejitkey_error_t* error, bool write) +{ + DWORD key_flags; + DWORD lRv; + HKEY hKey; + DWORD dwDisposition; + + if (error != NULL) + *error = ERROR_RW; + + if (write) + { + if (!IsProcessElevated()) + { + if (error != NULL) + *error = ERROR_RW_NOTADMIN; + return false; + } + key_flags = KEY_WRITE; + } + else + key_flags = KEY_READ; + + if (arch_out != NULL) + { + if (arch_in != x64 && arch_in != x32) + { +#ifdef _WIN64 + *arch_out = x64; +#else //x86 + *arch_out = x32; +#endif //_WIN64 + } + else + *arch_out = arch_in; + } + + if (arch_in == x64) + { +#ifndef _WIN64 + if (!IsWow64()) + { + if (error != NULL) + *error = ERROR_RW_NOTWOW64; + return false; + } + key_flags |= KEY_WOW64_64KEY; +#endif //_WIN64 + } + else if (arch_in == x32) + { +#ifdef _WIN64 + key_flags |= KEY_WOW64_32KEY; +#endif + } + + if (write) + { + lRv = RegCreateKeyEx(HKEY_LOCAL_MACHINE, JIT_REG_KEY, 0, NULL, REG_OPTION_NON_VOLATILE, key_flags, NULL, &hKey, &dwDisposition); + if (lRv != ERROR_SUCCESS) + return false; + + lRv = RegSetValueExW(hKey, StringUtils::Utf8ToUtf16(key).c_str(), 0, REG_SZ, (BYTE*)jit_key_value, (DWORD)(*jit_key_vale_size) + 1); + } + else + { + lRv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, JIT_REG_KEY, 0, key_flags, &hKey); + if (lRv != ERROR_SUCCESS) + { + if (error != NULL) + *error = ERROR_RW_FILE_NOT_FOUND; + return false; + } + + lRv = RegQueryValueExW(hKey, StringUtils::Utf8ToUtf16(key).c_str(), 0, NULL, (LPBYTE)jit_key_value, jit_key_vale_size); + if (lRv != ERROR_SUCCESS) + { + if (error != NULL) + *error = ERROR_RW_FILE_NOT_FOUND; + } + } + + RegCloseKey(hKey); + return (lRv == ERROR_SUCCESS); +} + +bool dbggetjitauto(bool* auto_on, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out) +{ + wchar_t jit_entry[4] = L""; + DWORD jit_entry_size = sizeof(jit_entry) - 1; + readwritejitkey_error_t rw_error; + + if (!readwritejitkey(jit_entry, &jit_entry_size, "Auto", arch_in, arch_out, &rw_error, false)) + { + if (rw_error == ERROR_RW_FILE_NOT_FOUND) + { + if (rw_error_out != NULL) + *rw_error_out = rw_error; + return true; + } + return false; + } + if (_wcsicmp(jit_entry, L"1") == 0) + *auto_on = true; + else if (_wcsicmp(jit_entry, L"0") == 0) + *auto_on = false; + else + return false; + return true; +} + +bool dbgsetjitauto(bool auto_on, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out) +{ + DWORD auto_string_size = sizeof(L"1"); + readwritejitkey_error_t rw_error; + if (!auto_on) + { + wchar_t jit_entry[4] = L""; + DWORD jit_entry_size = sizeof(jit_entry) - 1; + if (!readwritejitkey(jit_entry, &jit_entry_size, "Auto", arch_in, arch_out, &rw_error, false)) + { + if (rw_error == ERROR_RW_FILE_NOT_FOUND) + return true; + } + } + if (!readwritejitkey(auto_on ? L"1" : L"0", &auto_string_size, "Auto", arch_in, arch_out, &rw_error, true)) + { + if (rw_error_out != NULL) + *rw_error_out = rw_error; + return false; + } + return true; +} + +bool dbggetjit(char jit_entry[JIT_ENTRY_MAX_SIZE], arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out) +{ + wchar_t wszJitEntry[JIT_ENTRY_MAX_SIZE] = L""; + DWORD jit_entry_size = JIT_ENTRY_MAX_SIZE * sizeof(wchar_t); + readwritejitkey_error_t rw_error; + if (!readwritejitkey(wszJitEntry, &jit_entry_size, "Debugger", arch_in, arch_out, &rw_error, false)) + { + if (rw_error_out != NULL) + *rw_error_out = rw_error; + return false; + } + strcpy_s(jit_entry, JIT_ENTRY_MAX_SIZE, StringUtils::Utf16ToUtf8(wszJitEntry).c_str()); + return true; +} + +bool dbggetdefjit(char* jit_entry) +{ + char path[JIT_ENTRY_DEF_SIZE]; + path[0] = '"'; + wchar_t wszPath[MAX_PATH] = L""; + GetModuleFileNameW(GetModuleHandleW(NULL), wszPath, MAX_PATH); + strcpy_s(&path[1], JIT_ENTRY_DEF_SIZE - 1, StringUtils::Utf16ToUtf8(wszPath).c_str()); + strcat(path, ATTACH_CMD_LINE); + strcpy_s(jit_entry, JIT_ENTRY_DEF_SIZE, path); + return true; +} + +bool dbgsetjit(char* jit_cmd, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out) +{ + DWORD jit_cmd_size = (DWORD)strlen(jit_cmd) * sizeof(wchar_t); + readwritejitkey_error_t rw_error; + if (!readwritejitkey((wchar_t*)StringUtils::Utf8ToUtf16(jit_cmd).c_str(), &jit_cmd_size, "Debugger", arch_in, arch_out, &rw_error, true)) + { + if (rw_error_out != NULL) + *rw_error_out = rw_error; + return false; + } + return true; } \ No newline at end of file diff --git a/src/dbg/jit.h b/src/dbg/jit.h index 2a3678da..8527a927 100644 --- a/src/dbg/jit.h +++ b/src/dbg/jit.h @@ -1,24 +1,24 @@ -#pragma once - -#include "_global.h" - -#define ATTACH_CMD_LINE "\" -a %ld -e %ld" -#define JIT_REG_KEY TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug") - -#define JIT_ENTRY_MAX_SIZE 512 -#define JIT_ENTRY_DEF_SIZE (MAX_PATH + sizeof(ATTACH_CMD_LINE) + 2) - -typedef enum -{ - ERROR_RW = 0, - ERROR_RW_FILE_NOT_FOUND, - ERROR_RW_NOTWOW64, - ERROR_RW_NOTADMIN -} readwritejitkey_error_t; - -bool IsProcessElevated(); -bool dbggetjit(char *jit_entry, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out); -bool dbgsetjit(char* jit_cmd, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out); -bool dbggetjitauto(bool* auto_on, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out); -bool dbgsetjitauto(bool auto_on, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out); +#pragma once + +#include "_global.h" + +#define ATTACH_CMD_LINE "\" -a %ld -e %ld" +#define JIT_REG_KEY TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug") + +#define JIT_ENTRY_MAX_SIZE 512 +#define JIT_ENTRY_DEF_SIZE (MAX_PATH + sizeof(ATTACH_CMD_LINE) + 2) + +typedef enum +{ + ERROR_RW = 0, + ERROR_RW_FILE_NOT_FOUND, + ERROR_RW_NOTWOW64, + ERROR_RW_NOTADMIN +} readwritejitkey_error_t; + +bool IsProcessElevated(); +bool dbggetjit(char *jit_entry, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out); +bool dbgsetjit(char* jit_cmd, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out); +bool dbggetjitauto(bool* auto_on, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out); +bool dbgsetjitauto(bool auto_on, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out); bool dbggetdefjit(char* jit_entry); \ No newline at end of file diff --git a/src/dbg/label.cpp b/src/dbg/label.cpp index 656e6c94..0fac7cea 100644 --- a/src/dbg/label.cpp +++ b/src/dbg/label.cpp @@ -1,265 +1,265 @@ -#include "label.h" -#include "threading.h" -#include "module.h" -#include "memory.h" - -std::unordered_map labels; - -bool LabelSet(duint Address, const char* Text, bool Manual) -{ - ASSERT_DEBUGGING("Exported/Command function"); - - // A valid memory address must be supplied - if(!MemIsValidReadPtr(Address)) - return false; - - // Make sure the string is supplied, within bounds, and not a special delimiter - if(!Text || Text[0] == '\1' || strlen(Text) >= MAX_LABEL_SIZE - 1) - return false; - - // Labels cannot be "address" of actual variables - if(strstr(Text, "&")) - return false; - - // Delete the label if no text was supplied - if(Text[0] == '\0') - return LabelDelete(Address); - - // Fill out the structure data - LABELSINFO labelInfo; - labelInfo.manual = Manual; - labelInfo.addr = Address - ModBaseFromAddr(Address); - strcpy_s(labelInfo.text, Text); - ModNameFromAddr(Address, labelInfo.mod, true); - - EXCLUSIVE_ACQUIRE(LockLabels); - - // Insert label by key - const duint key = ModHashFromAddr(Address); - - if(!labels.insert(std::make_pair(ModHashFromAddr(key), labelInfo)).second) - labels[key] = labelInfo; - - return true; -} - -bool LabelFromString(const char* Text, duint* Address) -{ - ASSERT_DEBUGGING("Future(?): Currently not used"); - SHARED_ACQUIRE(LockLabels); - - for(auto & itr : labels) - { - // Check if the actual label name matches - if(strcmp(itr.second.text, Text)) - continue; - - if(Address) - *Address = itr.second.addr + ModBaseFromName(itr.second.mod); - - // Set status to indicate if label was ever found - return true; - } - - return false; -} - -bool LabelGet(duint Address, char* Text) -{ - ASSERT_DEBUGGING("Export call"); - SHARED_ACQUIRE(LockLabels); - - // Was the label at this address exist? - auto found = labels.find(ModHashFromAddr(Address)); - - if(found == labels.end()) - return false; - - // Copy to user buffer - if(Text) - strcpy_s(Text, MAX_LABEL_SIZE, found->second.text); - - return true; -} - -bool LabelDelete(duint Address) -{ - ASSERT_DEBUGGING("Export call"); - EXCLUSIVE_ACQUIRE(LockLabels); - - return (labels.erase(ModHashFromAddr(Address)) > 0); -} - -void LabelDelRange(duint Start, duint End) -{ - ASSERT_DEBUGGING("Export call"); - - // Are all comments going to be deleted? - // 0x00000000 - 0xFFFFFFFF - if(Start == 0 && End == ~0) - { - LabelClear(); - } - else - { - // Make sure 'Start' and 'End' reference the same module - duint moduleBase = ModBaseFromAddr(Start); - - if(moduleBase != ModBaseFromAddr(End)) - return; - - EXCLUSIVE_ACQUIRE(LockLabels); - for(auto itr = labels.begin(); itr != labels.end();) - { - const auto & currentLabel = itr->second; - // Ignore manually set entries - if(currentLabel.manual) - { - ++itr; - continue; - } - - // [Start, End) - if(currentLabel.addr >= Start && currentLabel.addr < End) - itr = labels.erase(itr); - else - ++itr; - } - } -} - -void LabelCacheSave(JSON Root) -{ - EXCLUSIVE_ACQUIRE(LockLabels); - - // Create the sub-root structures in memory - const JSON jsonLabels = json_array(); - const JSON jsonAutoLabels = json_array(); - - // Iterator each label - for(auto & itr : labels) - { - JSON jsonLabel = json_object(); - json_object_set_new(jsonLabel, "module", json_string(itr.second.mod)); - json_object_set_new(jsonLabel, "address", json_hex(itr.second.addr)); - json_object_set_new(jsonLabel, "text", json_string(itr.second.text)); - - // Was the label manually added? - if(itr.second.manual) - json_array_append_new(jsonLabels, jsonLabel); - else - json_array_append_new(jsonAutoLabels, jsonLabel); - } - - // Apply the object to the global root - if(json_array_size(jsonLabels)) - json_object_set(Root, "labels", jsonLabels); - - if(json_array_size(jsonAutoLabels)) - json_object_set(Root, "autolabels", jsonAutoLabels); - - json_decref(jsonLabels); - json_decref(jsonAutoLabels); -} - -void LabelCacheLoad(JSON Root) -{ - EXCLUSIVE_ACQUIRE(LockLabels); - - // Inline lambda to parse each JSON entry - auto AddLabels = [](const JSON Object, bool Manual) - { - size_t i; - JSON value; - - json_array_foreach(Object, i, value) - { - LABELSINFO labelInfo; - memset(&labelInfo, 0, sizeof(LABELSINFO)); - - // Module - const char* mod = json_string_value(json_object_get(value, "module")); - - if(mod && strlen(mod) < MAX_MODULE_SIZE) - strcpy_s(labelInfo.mod, mod); - - // Address/Manual - labelInfo.addr = (duint)json_hex_value(json_object_get(value, "address")); - labelInfo.manual = Manual; - - // Text string - const char* text = json_string_value(json_object_get(value, "text")); - - if(text) - strcpy_s(labelInfo.text, text); - else - { - // Skip empty strings - continue; - } - - // Go through the string replacing '&' with spaces - for(char* ptr = labelInfo.text; ptr[0] != '\0'; ptr++) - { - if(ptr[0] == '&') - ptr[0] = ' '; - } - - // Finally insert the data - const duint key = ModHashFromName(labelInfo.mod) + labelInfo.addr; - - labels.insert(std::make_pair(key, labelInfo)); - } - }; - - // Remove previous data - labels.clear(); - - const JSON jsonLabels = json_object_get(Root, "labels"); - const JSON jsonAutoLabels = json_object_get(Root, "autolabels"); - - // Load user-set labels - if(jsonLabels) - AddLabels(jsonLabels, true); - - // Load auto-set labels - if(jsonAutoLabels) - AddLabels(jsonAutoLabels, false); -} - -bool LabelEnum(LABELSINFO* List, size_t* Size) -{ - ASSERT_DEBUGGING("Export call"); - - // At least 1 parameter is required - if(!List && !Size) - return false; - - EXCLUSIVE_ACQUIRE(LockLabels); - - // See if the user requested a size - if(Size) - { - *Size = labels.size() * sizeof(LABELSINFO); - - if(!List) - return true; - } - - // Fill out the return list while converting the offset - // to a virtual address - for(auto & itr : labels) - { - *List = itr.second; - List->addr += ModBaseFromName(itr.second.mod); - List++; - } - - return true; -} - -void LabelClear() -{ - EXCLUSIVE_ACQUIRE(LockLabels); - labels.clear(); +#include "label.h" +#include "threading.h" +#include "module.h" +#include "memory.h" + +std::unordered_map labels; + +bool LabelSet(duint Address, const char* Text, bool Manual) +{ + ASSERT_DEBUGGING("Exported/Command function"); + + // A valid memory address must be supplied + if(!MemIsValidReadPtr(Address)) + return false; + + // Make sure the string is supplied, within bounds, and not a special delimiter + if(!Text || Text[0] == '\1' || strlen(Text) >= MAX_LABEL_SIZE - 1) + return false; + + // Labels cannot be "address" of actual variables + if(strstr(Text, "&")) + return false; + + // Delete the label if no text was supplied + if(Text[0] == '\0') + return LabelDelete(Address); + + // Fill out the structure data + LABELSINFO labelInfo; + labelInfo.manual = Manual; + labelInfo.addr = Address - ModBaseFromAddr(Address); + strcpy_s(labelInfo.text, Text); + ModNameFromAddr(Address, labelInfo.mod, true); + + EXCLUSIVE_ACQUIRE(LockLabels); + + // Insert label by key + const duint key = ModHashFromAddr(Address); + + if(!labels.insert(std::make_pair(ModHashFromAddr(key), labelInfo)).second) + labels[key] = labelInfo; + + return true; +} + +bool LabelFromString(const char* Text, duint* Address) +{ + ASSERT_DEBUGGING("Future(?): Currently not used"); + SHARED_ACQUIRE(LockLabels); + + for(auto & itr : labels) + { + // Check if the actual label name matches + if(strcmp(itr.second.text, Text)) + continue; + + if(Address) + *Address = itr.second.addr + ModBaseFromName(itr.second.mod); + + // Set status to indicate if label was ever found + return true; + } + + return false; +} + +bool LabelGet(duint Address, char* Text) +{ + ASSERT_DEBUGGING("Export call"); + SHARED_ACQUIRE(LockLabels); + + // Was the label at this address exist? + auto found = labels.find(ModHashFromAddr(Address)); + + if(found == labels.end()) + return false; + + // Copy to user buffer + if(Text) + strcpy_s(Text, MAX_LABEL_SIZE, found->second.text); + + return true; +} + +bool LabelDelete(duint Address) +{ + ASSERT_DEBUGGING("Export call"); + EXCLUSIVE_ACQUIRE(LockLabels); + + return (labels.erase(ModHashFromAddr(Address)) > 0); +} + +void LabelDelRange(duint Start, duint End) +{ + ASSERT_DEBUGGING("Export call"); + + // Are all comments going to be deleted? + // 0x00000000 - 0xFFFFFFFF + if(Start == 0 && End == ~0) + { + LabelClear(); + } + else + { + // Make sure 'Start' and 'End' reference the same module + duint moduleBase = ModBaseFromAddr(Start); + + if(moduleBase != ModBaseFromAddr(End)) + return; + + EXCLUSIVE_ACQUIRE(LockLabels); + for(auto itr = labels.begin(); itr != labels.end();) + { + const auto & currentLabel = itr->second; + // Ignore manually set entries + if(currentLabel.manual) + { + ++itr; + continue; + } + + // [Start, End) + if(currentLabel.addr >= Start && currentLabel.addr < End) + itr = labels.erase(itr); + else + ++itr; + } + } +} + +void LabelCacheSave(JSON Root) +{ + EXCLUSIVE_ACQUIRE(LockLabels); + + // Create the sub-root structures in memory + const JSON jsonLabels = json_array(); + const JSON jsonAutoLabels = json_array(); + + // Iterator each label + for(auto & itr : labels) + { + JSON jsonLabel = json_object(); + json_object_set_new(jsonLabel, "module", json_string(itr.second.mod)); + json_object_set_new(jsonLabel, "address", json_hex(itr.second.addr)); + json_object_set_new(jsonLabel, "text", json_string(itr.second.text)); + + // Was the label manually added? + if(itr.second.manual) + json_array_append_new(jsonLabels, jsonLabel); + else + json_array_append_new(jsonAutoLabels, jsonLabel); + } + + // Apply the object to the global root + if(json_array_size(jsonLabels)) + json_object_set(Root, "labels", jsonLabels); + + if(json_array_size(jsonAutoLabels)) + json_object_set(Root, "autolabels", jsonAutoLabels); + + json_decref(jsonLabels); + json_decref(jsonAutoLabels); +} + +void LabelCacheLoad(JSON Root) +{ + EXCLUSIVE_ACQUIRE(LockLabels); + + // Inline lambda to parse each JSON entry + auto AddLabels = [](const JSON Object, bool Manual) + { + size_t i; + JSON value; + + json_array_foreach(Object, i, value) + { + LABELSINFO labelInfo; + memset(&labelInfo, 0, sizeof(LABELSINFO)); + + // Module + const char* mod = json_string_value(json_object_get(value, "module")); + + if(mod && strlen(mod) < MAX_MODULE_SIZE) + strcpy_s(labelInfo.mod, mod); + + // Address/Manual + labelInfo.addr = (duint)json_hex_value(json_object_get(value, "address")); + labelInfo.manual = Manual; + + // Text string + const char* text = json_string_value(json_object_get(value, "text")); + + if(text) + strcpy_s(labelInfo.text, text); + else + { + // Skip empty strings + continue; + } + + // Go through the string replacing '&' with spaces + for(char* ptr = labelInfo.text; ptr[0] != '\0'; ptr++) + { + if(ptr[0] == '&') + ptr[0] = ' '; + } + + // Finally insert the data + const duint key = ModHashFromName(labelInfo.mod) + labelInfo.addr; + + labels.insert(std::make_pair(key, labelInfo)); + } + }; + + // Remove previous data + labels.clear(); + + const JSON jsonLabels = json_object_get(Root, "labels"); + const JSON jsonAutoLabels = json_object_get(Root, "autolabels"); + + // Load user-set labels + if(jsonLabels) + AddLabels(jsonLabels, true); + + // Load auto-set labels + if(jsonAutoLabels) + AddLabels(jsonAutoLabels, false); +} + +bool LabelEnum(LABELSINFO* List, size_t* Size) +{ + ASSERT_DEBUGGING("Export call"); + + // At least 1 parameter is required + if(!List && !Size) + return false; + + EXCLUSIVE_ACQUIRE(LockLabels); + + // See if the user requested a size + if(Size) + { + *Size = labels.size() * sizeof(LABELSINFO); + + if(!List) + return true; + } + + // Fill out the return list while converting the offset + // to a virtual address + for(auto & itr : labels) + { + *List = itr.second; + List->addr += ModBaseFromName(itr.second.mod); + List++; + } + + return true; +} + +void LabelClear() +{ + EXCLUSIVE_ACQUIRE(LockLabels); + labels.clear(); } \ No newline at end of file diff --git a/src/dbg/label.h b/src/dbg/label.h index 46812309..abdea403 100644 --- a/src/dbg/label.h +++ b/src/dbg/label.h @@ -1,21 +1,21 @@ -#pragma once - -#include "_global.h" - -struct LABELSINFO -{ - char mod[MAX_MODULE_SIZE]; - duint addr; - char text[MAX_LABEL_SIZE]; - bool manual; -}; - -bool LabelSet(duint Address, const char* Text, bool Manual); -bool LabelFromString(const char* Text, duint* Address); -bool LabelGet(duint Address, char* Text); -bool LabelDelete(duint Address); -void LabelDelRange(duint Start, duint End); -void LabelCacheSave(JSON root); -void LabelCacheLoad(JSON root); -bool LabelEnum(LABELSINFO* List, size_t* Size); +#pragma once + +#include "_global.h" + +struct LABELSINFO +{ + char mod[MAX_MODULE_SIZE]; + duint addr; + char text[MAX_LABEL_SIZE]; + bool manual; +}; + +bool LabelSet(duint Address, const char* Text, bool Manual); +bool LabelFromString(const char* Text, duint* Address); +bool LabelGet(duint Address, char* Text); +bool LabelDelete(duint Address); +void LabelDelRange(duint Start, duint End); +void LabelCacheSave(JSON root); +void LabelCacheLoad(JSON root); +bool LabelEnum(LABELSINFO* List, size_t* Size); void LabelClear(); \ No newline at end of file diff --git a/src/dbg/linearanalysis.cpp b/src/dbg/linearanalysis.cpp index 1a93d31d..292033ac 100644 --- a/src/dbg/linearanalysis.cpp +++ b/src/dbg/linearanalysis.cpp @@ -1,150 +1,150 @@ -#include "linearanalysis.h" -#include "console.h" -#include "memory.h" -#include "function.h" - -LinearAnalysis::LinearAnalysis(duint base, duint size) : Analysis(base, size) -{ -} - -void LinearAnalysis::Analyse() -{ - dputs("Starting analysis..."); - DWORD ticks = GetTickCount(); - - PopulateReferences(); - dprintf("%u called functions populated\n", _functions.size()); - AnalyseFunctions(); - - dprintf("Analysis finished in %ums!\n", GetTickCount() - ticks); -} - -void LinearAnalysis::SetMarkers() -{ - FunctionDelRange(_base, _base + _size); - for(auto & function : _functions) - { - if(!function.end) - continue; - FunctionAdd(function.start, function.end, false); - } -} - -void LinearAnalysis::SortCleanup() -{ - //sort & remove duplicates - std::sort(_functions.begin(), _functions.end()); - auto last = std::unique(_functions.begin(), _functions.end()); - _functions.erase(last, _functions.end()); -} - -void LinearAnalysis::PopulateReferences() -{ - //linear immediate reference scan (call , push , mov [somewhere], ) - for(duint i = 0; i < _size;) - { - duint addr = _base + i; - if(_cp.Disassemble(addr, TranslateAddress(addr), MAX_DISASM_BUFFER)) - { - duint ref = GetReferenceOperand(); - if(ref) - _functions.push_back({ ref, 0 }); - i += _cp.Size(); - } - else - i++; - } - SortCleanup(); -} - -void LinearAnalysis::AnalyseFunctions() -{ - for(size_t i = 0; i < _functions.size(); i++) - { - FunctionInfo & function = _functions[i]; - if(function.end) //skip already-analysed functions - continue; - duint maxaddr = _base + _size; - if(i < _functions.size() - 1) - maxaddr = _functions[i + 1].start; - - duint end = FindFunctionEnd(function.start, maxaddr); - if(end) - { - if(_cp.Disassemble(end, TranslateAddress(end), MAX_DISASM_BUFFER)) - function.end = end + _cp.Size() - 1; - else - function.end = end; - } - } -} - -duint LinearAnalysis::FindFunctionEnd(duint start, duint maxaddr) -{ - //disassemble first instruction for some heuristics - if(_cp.Disassemble(start, TranslateAddress(start), MAX_DISASM_BUFFER)) - { - //JMP [123456] ; import - if(_cp.InGroup(CS_GRP_JUMP) && _cp.x86().operands[0].type == X86_OP_MEM) - return 0; - } - - //linear search with some trickery - duint end = 0; - duint jumpback = 0; - for(duint addr = start, fardest = 0; addr < maxaddr;) - { - if(_cp.Disassemble(addr, TranslateAddress(addr), MAX_DISASM_BUFFER)) - { - if(addr + _cp.Size() > maxaddr) //we went past the maximum allowed address - break; - - const cs_x86_op & operand = _cp.x86().operands[0]; - if((_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) && operand.type == X86_OP_IMM) //jump - { - duint dest = (duint)operand.imm; - - if(dest >= maxaddr) //jump across function boundaries - { - //currently unused - } - else if(dest > addr && dest > fardest) //save the farthest JXX destination forward - { - fardest = dest; - } - else if(end && dest < end && (_cp.GetId() == X86_INS_JMP || _cp.GetId() == X86_INS_LOOP)) //save the last JMP backwards - { - jumpback = addr; - } - } - else if(_cp.InGroup(CS_GRP_RET)) //possible function end? - { - end = addr; - if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET - break; - } - - addr += _cp.Size(); - } - else - addr++; - } - return end < jumpback ? jumpback : end; -} - -duint LinearAnalysis::GetReferenceOperand() -{ - for(int i = 0; i < _cp.x86().op_count; i++) - { - const cs_x86_op & operand = _cp.x86().operands[i]; - if(_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) //skip jumps/loops - continue; - if(operand.type == X86_OP_IMM) //we are looking for immediate references - { - duint dest = (duint)operand.imm; - if(dest >= _base && dest < _base + _size) - return dest; - } - } - return 0; +#include "linearanalysis.h" +#include "console.h" +#include "memory.h" +#include "function.h" + +LinearAnalysis::LinearAnalysis(duint base, duint size) : Analysis(base, size) +{ +} + +void LinearAnalysis::Analyse() +{ + dputs("Starting analysis..."); + DWORD ticks = GetTickCount(); + + PopulateReferences(); + dprintf("%u called functions populated\n", _functions.size()); + AnalyseFunctions(); + + dprintf("Analysis finished in %ums!\n", GetTickCount() - ticks); +} + +void LinearAnalysis::SetMarkers() +{ + FunctionDelRange(_base, _base + _size); + for(auto & function : _functions) + { + if(!function.end) + continue; + FunctionAdd(function.start, function.end, false); + } +} + +void LinearAnalysis::SortCleanup() +{ + //sort & remove duplicates + std::sort(_functions.begin(), _functions.end()); + auto last = std::unique(_functions.begin(), _functions.end()); + _functions.erase(last, _functions.end()); +} + +void LinearAnalysis::PopulateReferences() +{ + //linear immediate reference scan (call , push , mov [somewhere], ) + for(duint i = 0; i < _size;) + { + duint addr = _base + i; + if(_cp.Disassemble(addr, TranslateAddress(addr), MAX_DISASM_BUFFER)) + { + duint ref = GetReferenceOperand(); + if(ref) + _functions.push_back({ ref, 0 }); + i += _cp.Size(); + } + else + i++; + } + SortCleanup(); +} + +void LinearAnalysis::AnalyseFunctions() +{ + for(size_t i = 0; i < _functions.size(); i++) + { + FunctionInfo & function = _functions[i]; + if(function.end) //skip already-analysed functions + continue; + duint maxaddr = _base + _size; + if(i < _functions.size() - 1) + maxaddr = _functions[i + 1].start; + + duint end = FindFunctionEnd(function.start, maxaddr); + if(end) + { + if(_cp.Disassemble(end, TranslateAddress(end), MAX_DISASM_BUFFER)) + function.end = end + _cp.Size() - 1; + else + function.end = end; + } + } +} + +duint LinearAnalysis::FindFunctionEnd(duint start, duint maxaddr) +{ + //disassemble first instruction for some heuristics + if(_cp.Disassemble(start, TranslateAddress(start), MAX_DISASM_BUFFER)) + { + //JMP [123456] ; import + if(_cp.InGroup(CS_GRP_JUMP) && _cp.x86().operands[0].type == X86_OP_MEM) + return 0; + } + + //linear search with some trickery + duint end = 0; + duint jumpback = 0; + for(duint addr = start, fardest = 0; addr < maxaddr;) + { + if(_cp.Disassemble(addr, TranslateAddress(addr), MAX_DISASM_BUFFER)) + { + if(addr + _cp.Size() > maxaddr) //we went past the maximum allowed address + break; + + const cs_x86_op & operand = _cp.x86().operands[0]; + if((_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) && operand.type == X86_OP_IMM) //jump + { + duint dest = (duint)operand.imm; + + if(dest >= maxaddr) //jump across function boundaries + { + //currently unused + } + else if(dest > addr && dest > fardest) //save the farthest JXX destination forward + { + fardest = dest; + } + else if(end && dest < end && (_cp.GetId() == X86_INS_JMP || _cp.GetId() == X86_INS_LOOP)) //save the last JMP backwards + { + jumpback = addr; + } + } + else if(_cp.InGroup(CS_GRP_RET)) //possible function end? + { + end = addr; + if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET + break; + } + + addr += _cp.Size(); + } + else + addr++; + } + return end < jumpback ? jumpback : end; +} + +duint LinearAnalysis::GetReferenceOperand() +{ + for(int i = 0; i < _cp.x86().op_count; i++) + { + const cs_x86_op & operand = _cp.x86().operands[i]; + if(_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) //skip jumps/loops + continue; + if(operand.type == X86_OP_IMM) //we are looking for immediate references + { + duint dest = (duint)operand.imm; + if(dest >= _base && dest < _base + _size) + return dest; + } + } + return 0; } \ No newline at end of file diff --git a/src/dbg/linearanalysis.h b/src/dbg/linearanalysis.h index c920cacd..22c057ad 100644 --- a/src/dbg/linearanalysis.h +++ b/src/dbg/linearanalysis.h @@ -1,40 +1,40 @@ -#ifndef _LINEARANALYSIS_H -#define _LINEARANALYSIS_H - -#include "_global.h" -#include "analysis.h" - -class LinearAnalysis : public Analysis -{ -public: - explicit LinearAnalysis(duint base, duint size); - void Analyse() override; - void SetMarkers() override; - -private: - struct FunctionInfo - { - duint start; - duint end; - - bool operator<(const FunctionInfo & b) const - { - return start < b.start; - } - - bool operator==(const FunctionInfo & b) const - { - return start == b.start; - } - }; - - std::vector _functions; - - void SortCleanup(); - void PopulateReferences(); - void AnalyseFunctions(); - duint FindFunctionEnd(duint start, duint maxaddr); - duint GetReferenceOperand(); -}; - +#ifndef _LINEARANALYSIS_H +#define _LINEARANALYSIS_H + +#include "_global.h" +#include "analysis.h" + +class LinearAnalysis : public Analysis +{ +public: + explicit LinearAnalysis(duint base, duint size); + void Analyse() override; + void SetMarkers() override; + +private: + struct FunctionInfo + { + duint start; + duint end; + + bool operator<(const FunctionInfo & b) const + { + return start < b.start; + } + + bool operator==(const FunctionInfo & b) const + { + return start == b.start; + } + }; + + std::vector _functions; + + void SortCleanup(); + void PopulateReferences(); + void AnalyseFunctions(); + duint FindFunctionEnd(duint start, duint maxaddr); + duint GetReferenceOperand(); +}; + #endif //_LINEARANALYSIS_H \ No newline at end of file diff --git a/src/dbg/log.cpp b/src/dbg/log.cpp index 409eb202..63dd6559 100644 --- a/src/dbg/log.cpp +++ b/src/dbg/log.cpp @@ -1,12 +1,12 @@ -#include "_global.h" -#include "log.h" - -log::log(void) -{ -} - -log::~log(void) -{ - GuiAddLogMessage(message.str().c_str()); -} - +#include "_global.h" +#include "log.h" + +log::log(void) +{ +} + +log::~log(void) +{ + GuiAddLogMessage(message.str().c_str()); +} + diff --git a/src/dbg/loop.cpp b/src/dbg/loop.cpp index 44ee3fe5..b7ff5e6e 100644 --- a/src/dbg/loop.cpp +++ b/src/dbg/loop.cpp @@ -1,264 +1,264 @@ -#include "loop.h" -#include "memory.h" -#include "threading.h" -#include "module.h" - -std::map loops; - -bool LoopAdd(duint Start, duint End, bool Manual) -{ - ASSERT_DEBUGGING("Export call"); - - // Loop must begin before it ends - if(Start > End) - return false; - - // Memory addresses must be valid - if(!MemIsValidReadPtr(Start) || !MemIsValidReadPtr(End)) - return false; - - // Check if loop boundaries are in the same module range - const duint moduleBase = ModBaseFromAddr(Start); - - if(moduleBase != ModBaseFromAddr(End)) - return false; - - // Loops cannot overlap other loops - int finalDepth = 0; - - if(LoopOverlaps(0, Start, End, &finalDepth)) - return false; - - // Fill out loop information structure - LOOPSINFO loopInfo; - loopInfo.start = Start - moduleBase; - loopInfo.end = End - moduleBase; - loopInfo.depth = finalDepth; - loopInfo.manual = Manual; - ModNameFromAddr(Start, loopInfo.mod, true); - - // Link this to a parent loop if one does exist - if(finalDepth) - LoopGet(finalDepth - 1, Start, &loopInfo.parent, 0); - else - loopInfo.parent = 0; - - EXCLUSIVE_ACQUIRE(LockLoops); - - // Insert into list - loops.insert(std::make_pair(DepthModuleRange(finalDepth, ModuleRange(ModHashFromAddr(moduleBase), Range(loopInfo.start, loopInfo.end))), loopInfo)); - return true; -} - -// Get the start/end of a loop at a certain depth and address -bool LoopGet(int Depth, duint Address, duint* Start, duint* End) -{ - ASSERT_DEBUGGING("Export call"); - - // Get the virtual address module - const duint moduleBase = ModBaseFromAddr(Address); - - // Virtual address to relative address - Address -= moduleBase; - - SHARED_ACQUIRE(LockLoops); - - // Search with this address range - auto found = loops.find(DepthModuleRange(Depth, ModuleRange(ModHashFromAddr(moduleBase), Range(Address, Address)))); - - if(found == loops.end()) - return false; - - // Return the loop start and end - if(Start) - *Start = found->second.start + moduleBase; - - if(End) - *End = found->second.end + moduleBase; - - return true; -} - -// Check if a loop overlaps a range, inside is not overlapping -bool LoopOverlaps(int Depth, duint Start, duint End, int* FinalDepth) -{ - ASSERT_DEBUGGING("Export call"); - - // Determine module addresses and lookup keys - const duint moduleBase = ModBaseFromAddr(Start); - const duint key = ModHashFromAddr(moduleBase); - - duint curStart = Start - moduleBase; - duint curEnd = End - moduleBase; - - SHARED_ACQUIRE(LockLoops); - - // Check if the new loop fits in the old loop - for(auto & itr : loops) - { - // Only look in the current module - if(itr.first.second.first != key) - continue; - - // Loop must be at this recursive depth - if(itr.second.depth != Depth) - continue; - - if(itr.second.start < curStart && itr.second.end > curEnd) - return LoopOverlaps(Depth + 1, curStart, curEnd, FinalDepth); - } - - // Did the user request t the loop depth? - if(FinalDepth) - *FinalDepth = Depth; - - // Check for loop overlaps - for(auto & itr : loops) - { - // Only look in the current module - if(itr.first.second.first != key) - continue; - - // Loop must be at this recursive depth - if(itr.second.depth != Depth) - continue; - - if(itr.second.start <= curEnd && itr.second.end >= curStart) - return true; - } - - return false; -} - -// This should delete a loop and all sub-loops that matches a certain addr -bool LoopDelete(int Depth, duint Address) -{ - ASSERT_ALWAYS("Function unimplemented"); - return false; -} - -void LoopCacheSave(JSON Root) -{ - EXCLUSIVE_ACQUIRE(LockLoops); - - // Create the root JSON objects - const JSON jsonLoops = json_array(); - const JSON jsonAutoLoops = json_array(); - - // Write all entries - for(auto & itr : loops) - { - const LOOPSINFO & currentLoop = itr.second; - JSON currentJson = json_object(); - - json_object_set_new(currentJson, "module", json_string(currentLoop.mod)); - json_object_set_new(currentJson, "start", json_hex(currentLoop.start)); - json_object_set_new(currentJson, "end", json_hex(currentLoop.end)); - json_object_set_new(currentJson, "depth", json_integer(currentLoop.depth)); - json_object_set_new(currentJson, "parent", json_hex(currentLoop.parent)); - - if(currentLoop.manual) - json_array_append_new(jsonLoops, currentJson); - else - json_array_append_new(jsonAutoLoops, currentJson); - } - - // Append a link to the global root - if(json_array_size(jsonLoops)) - json_object_set(Root, "loops", jsonLoops); - - if(json_array_size(jsonAutoLoops)) - json_object_set(Root, "autoloops", jsonAutoLoops); - - // Release memory/references - json_decref(jsonLoops); - json_decref(jsonAutoLoops); -} - -void LoopCacheLoad(JSON Root) -{ - EXCLUSIVE_ACQUIRE(LockLoops); - - // Inline lambda to parse each JSON entry - auto AddLoops = [](const JSON Object, bool Manual) - { - size_t i; - JSON value; - - json_array_foreach(Object, i, value) - { - LOOPSINFO loopInfo; - memset(&loopInfo, 0, sizeof(LOOPSINFO)); - - // Module name - const char* mod = json_string_value(json_object_get(value, "module")); - - if(mod && strlen(mod) < MAX_MODULE_SIZE) - strcpy_s(loopInfo.mod, mod); - - // All other variables - loopInfo.start = (duint)json_hex_value(json_object_get(value, "start")); - loopInfo.end = (duint)json_hex_value(json_object_get(value, "end")); - loopInfo.depth = (int)json_integer_value(json_object_get(value, "depth")); - loopInfo.parent = (duint)json_hex_value(json_object_get(value, "parent")); - loopInfo.manual = Manual; - - // Sanity check: Make sure the loop starts before it ends - if(loopInfo.end < loopInfo.start) - continue; - - // Insert into global list - loops.insert(std::make_pair(DepthModuleRange(loopInfo.depth, ModuleRange(ModHashFromName(loopInfo.mod), Range(loopInfo.start, loopInfo.end))), loopInfo)); - } - }; - - // Remove existing entries - loops.clear(); - - const JSON jsonLoops = json_object_get(Root, "loops"); - const JSON jsonAutoLoops = json_object_get(Root, "autoloops"); - - // Load user-set loops - if(jsonLoops) - AddLoops(jsonLoops, true); - - // Load auto-set loops - if(jsonAutoLoops) - AddLoops(jsonAutoLoops, false); -} - -bool LoopEnum(LOOPSINFO* List, size_t* Size) -{ - // If list or size is not requested, fail - ASSERT_FALSE(!List && !Size); - SHARED_ACQUIRE(LockLoops); - - // See if the caller requested an output size - if(Size) - { - *Size = loops.size() * sizeof(LOOPSINFO); - - if(!List) - return true; - } - - for(auto & itr : loops) - { - *List = itr.second; - - // Adjust the offset to a real virtual address - duint modbase = ModBaseFromName(List->mod); - List->start += modbase; - List->end += modbase; - - List++; - } - - return true; -} - -void LoopClear() -{ - EXCLUSIVE_ACQUIRE(LockLoops); - loops.clear(); +#include "loop.h" +#include "memory.h" +#include "threading.h" +#include "module.h" + +std::map loops; + +bool LoopAdd(duint Start, duint End, bool Manual) +{ + ASSERT_DEBUGGING("Export call"); + + // Loop must begin before it ends + if(Start > End) + return false; + + // Memory addresses must be valid + if(!MemIsValidReadPtr(Start) || !MemIsValidReadPtr(End)) + return false; + + // Check if loop boundaries are in the same module range + const duint moduleBase = ModBaseFromAddr(Start); + + if(moduleBase != ModBaseFromAddr(End)) + return false; + + // Loops cannot overlap other loops + int finalDepth = 0; + + if(LoopOverlaps(0, Start, End, &finalDepth)) + return false; + + // Fill out loop information structure + LOOPSINFO loopInfo; + loopInfo.start = Start - moduleBase; + loopInfo.end = End - moduleBase; + loopInfo.depth = finalDepth; + loopInfo.manual = Manual; + ModNameFromAddr(Start, loopInfo.mod, true); + + // Link this to a parent loop if one does exist + if(finalDepth) + LoopGet(finalDepth - 1, Start, &loopInfo.parent, 0); + else + loopInfo.parent = 0; + + EXCLUSIVE_ACQUIRE(LockLoops); + + // Insert into list + loops.insert(std::make_pair(DepthModuleRange(finalDepth, ModuleRange(ModHashFromAddr(moduleBase), Range(loopInfo.start, loopInfo.end))), loopInfo)); + return true; +} + +// Get the start/end of a loop at a certain depth and address +bool LoopGet(int Depth, duint Address, duint* Start, duint* End) +{ + ASSERT_DEBUGGING("Export call"); + + // Get the virtual address module + const duint moduleBase = ModBaseFromAddr(Address); + + // Virtual address to relative address + Address -= moduleBase; + + SHARED_ACQUIRE(LockLoops); + + // Search with this address range + auto found = loops.find(DepthModuleRange(Depth, ModuleRange(ModHashFromAddr(moduleBase), Range(Address, Address)))); + + if(found == loops.end()) + return false; + + // Return the loop start and end + if(Start) + *Start = found->second.start + moduleBase; + + if(End) + *End = found->second.end + moduleBase; + + return true; +} + +// Check if a loop overlaps a range, inside is not overlapping +bool LoopOverlaps(int Depth, duint Start, duint End, int* FinalDepth) +{ + ASSERT_DEBUGGING("Export call"); + + // Determine module addresses and lookup keys + const duint moduleBase = ModBaseFromAddr(Start); + const duint key = ModHashFromAddr(moduleBase); + + duint curStart = Start - moduleBase; + duint curEnd = End - moduleBase; + + SHARED_ACQUIRE(LockLoops); + + // Check if the new loop fits in the old loop + for(auto & itr : loops) + { + // Only look in the current module + if(itr.first.second.first != key) + continue; + + // Loop must be at this recursive depth + if(itr.second.depth != Depth) + continue; + + if(itr.second.start < curStart && itr.second.end > curEnd) + return LoopOverlaps(Depth + 1, curStart, curEnd, FinalDepth); + } + + // Did the user request t the loop depth? + if(FinalDepth) + *FinalDepth = Depth; + + // Check for loop overlaps + for(auto & itr : loops) + { + // Only look in the current module + if(itr.first.second.first != key) + continue; + + // Loop must be at this recursive depth + if(itr.second.depth != Depth) + continue; + + if(itr.second.start <= curEnd && itr.second.end >= curStart) + return true; + } + + return false; +} + +// This should delete a loop and all sub-loops that matches a certain addr +bool LoopDelete(int Depth, duint Address) +{ + ASSERT_ALWAYS("Function unimplemented"); + return false; +} + +void LoopCacheSave(JSON Root) +{ + EXCLUSIVE_ACQUIRE(LockLoops); + + // Create the root JSON objects + const JSON jsonLoops = json_array(); + const JSON jsonAutoLoops = json_array(); + + // Write all entries + for(auto & itr : loops) + { + const LOOPSINFO & currentLoop = itr.second; + JSON currentJson = json_object(); + + json_object_set_new(currentJson, "module", json_string(currentLoop.mod)); + json_object_set_new(currentJson, "start", json_hex(currentLoop.start)); + json_object_set_new(currentJson, "end", json_hex(currentLoop.end)); + json_object_set_new(currentJson, "depth", json_integer(currentLoop.depth)); + json_object_set_new(currentJson, "parent", json_hex(currentLoop.parent)); + + if(currentLoop.manual) + json_array_append_new(jsonLoops, currentJson); + else + json_array_append_new(jsonAutoLoops, currentJson); + } + + // Append a link to the global root + if(json_array_size(jsonLoops)) + json_object_set(Root, "loops", jsonLoops); + + if(json_array_size(jsonAutoLoops)) + json_object_set(Root, "autoloops", jsonAutoLoops); + + // Release memory/references + json_decref(jsonLoops); + json_decref(jsonAutoLoops); +} + +void LoopCacheLoad(JSON Root) +{ + EXCLUSIVE_ACQUIRE(LockLoops); + + // Inline lambda to parse each JSON entry + auto AddLoops = [](const JSON Object, bool Manual) + { + size_t i; + JSON value; + + json_array_foreach(Object, i, value) + { + LOOPSINFO loopInfo; + memset(&loopInfo, 0, sizeof(LOOPSINFO)); + + // Module name + const char* mod = json_string_value(json_object_get(value, "module")); + + if(mod && strlen(mod) < MAX_MODULE_SIZE) + strcpy_s(loopInfo.mod, mod); + + // All other variables + loopInfo.start = (duint)json_hex_value(json_object_get(value, "start")); + loopInfo.end = (duint)json_hex_value(json_object_get(value, "end")); + loopInfo.depth = (int)json_integer_value(json_object_get(value, "depth")); + loopInfo.parent = (duint)json_hex_value(json_object_get(value, "parent")); + loopInfo.manual = Manual; + + // Sanity check: Make sure the loop starts before it ends + if(loopInfo.end < loopInfo.start) + continue; + + // Insert into global list + loops.insert(std::make_pair(DepthModuleRange(loopInfo.depth, ModuleRange(ModHashFromName(loopInfo.mod), Range(loopInfo.start, loopInfo.end))), loopInfo)); + } + }; + + // Remove existing entries + loops.clear(); + + const JSON jsonLoops = json_object_get(Root, "loops"); + const JSON jsonAutoLoops = json_object_get(Root, "autoloops"); + + // Load user-set loops + if(jsonLoops) + AddLoops(jsonLoops, true); + + // Load auto-set loops + if(jsonAutoLoops) + AddLoops(jsonAutoLoops, false); +} + +bool LoopEnum(LOOPSINFO* List, size_t* Size) +{ + // If list or size is not requested, fail + ASSERT_FALSE(!List && !Size); + SHARED_ACQUIRE(LockLoops); + + // See if the caller requested an output size + if(Size) + { + *Size = loops.size() * sizeof(LOOPSINFO); + + if(!List) + return true; + } + + for(auto & itr : loops) + { + *List = itr.second; + + // Adjust the offset to a real virtual address + duint modbase = ModBaseFromName(List->mod); + List->start += modbase; + List->end += modbase; + + List++; + } + + return true; +} + +void LoopClear() +{ + EXCLUSIVE_ACQUIRE(LockLoops); + loops.clear(); } \ No newline at end of file diff --git a/src/dbg/loop.h b/src/dbg/loop.h index 48c0841d..dfc5a37e 100644 --- a/src/dbg/loop.h +++ b/src/dbg/loop.h @@ -1,25 +1,25 @@ -#ifndef _LOOP_H -#define _LOOP_H - -#include "addrinfo.h" - -struct LOOPSINFO -{ - char mod[MAX_MODULE_SIZE]; - duint start; - duint end; - duint parent; - int depth; - bool manual; -}; - -bool LoopAdd(duint Start, duint End, bool Manual); -bool LoopGet(int Depth, duint Address, duint* Start, duint* End); -bool LoopOverlaps(int Depth, duint Start, duint End, int* FinalDepth); -bool LoopDelete(int Depth, duint Address); -void LoopCacheSave(JSON Root); -void LoopCacheLoad(JSON Root); -bool LoopEnum(LOOPSINFO* List, size_t* Size); -void LoopClear(); - +#ifndef _LOOP_H +#define _LOOP_H + +#include "addrinfo.h" + +struct LOOPSINFO +{ + char mod[MAX_MODULE_SIZE]; + duint start; + duint end; + duint parent; + int depth; + bool manual; +}; + +bool LoopAdd(duint Start, duint End, bool Manual); +bool LoopGet(int Depth, duint Address, duint* Start, duint* End); +bool LoopOverlaps(int Depth, duint Start, duint End, int* FinalDepth); +bool LoopDelete(int Depth, duint Address); +void LoopCacheSave(JSON Root); +void LoopCacheLoad(JSON Root); +bool LoopEnum(LOOPSINFO* List, size_t* Size); +void LoopClear(); + #endif //_LOOP_H \ No newline at end of file diff --git a/src/dbg/lz4/lz4.h b/src/dbg/lz4/lz4.h index bf8aa8dd..766a6052 100644 --- a/src/dbg/lz4/lz4.h +++ b/src/dbg/lz4/lz4.h @@ -1,252 +1,252 @@ -/* - LZ4 - Fast LZ compression algorithm - Header File - Copyright (C) 2011-2014, Yann Collet. - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - You can contact the author at : - - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html - - LZ4 source repository : http://code.google.com/p/lz4/ -*/ -#ifndef _LZ4_H -#define _LZ4_H - -#if defined (__cplusplus) -extern "C" -{ -#endif - - -/************************************** - Version -**************************************/ -#define LZ4_VERSION_MAJOR 1 /* for major interface/format changes */ -#define LZ4_VERSION_MINOR 1 /* for minor interface/format changes */ -#define LZ4_VERSION_RELEASE 3 /* for tweaks, bug-fixes, or development */ - - -/************************************** - Compiler Options -**************************************/ -#if (defined(__GNUC__) && defined(__STRICT_ANSI__)) || (defined(_MSC_VER) && !defined(__cplusplus)) /* Visual Studio */ -# define inline __inline /* Visual C is not C99, but supports some kind of inline */ -#endif - - -/************************************** - Simple Functions -**************************************/ - -__declspec(dllimport) int LZ4_compress(const char* source, char* dest, int inputSize); -__declspec(dllimport) int LZ4_decompress_safe(const char* source, char* dest, int inputSize, int maxOutputSize); - -/* -LZ4_compress() : - Compresses 'inputSize' bytes from 'source' into 'dest'. - Destination buffer must be already allocated, - and must be sized to handle worst cases situations (input data not compressible) - Worst case size evaluation is provided by function LZ4_compressBound() - inputSize : Max supported value is LZ4_MAX_INPUT_VALUE - return : the number of bytes written in buffer dest - or 0 if the compression fails - -LZ4_decompress_safe() : - maxOutputSize : is the size of the destination buffer (which must be already allocated) - return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize) - If the source stream is detected malformed, the function will stop decoding and return a negative result. - This function is protected against buffer overflow exploits (never writes outside of output buffer, and never reads outside of input buffer). Therefore, it is protected against malicious data packets -*/ - - -/************************************** - Advanced Functions -**************************************/ -#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ -#define LZ4_COMPRESSBOUND(isize) ((unsigned int)(isize) > (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) - -/* -LZ4_compressBound() : - Provides the maximum size that LZ4 may output in a "worst case" scenario (input data not compressible) - primarily useful for memory allocation of output buffer. - inline function is recommended for the general case, - macro is also provided when result needs to be evaluated at compilation (such as stack memory allocation). - - isize : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE - return : maximum output size in a "worst case" scenario - or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) -*/ -__declspec(dllimport) int LZ4_compressBound(int isize); - - -/* -LZ4_compress_limitedOutput() : - Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. - If it cannot achieve it, compression will stop, and result of the function will be zero. - This function never writes outside of provided output buffer. - - inputSize : Max supported value is LZ4_MAX_INPUT_VALUE - maxOutputSize : is the size of the destination buffer (which must be already allocated) - return : the number of bytes written in buffer 'dest' - or 0 if the compression fails -*/ -__declspec(dllimport) int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize); - - -/* -LZ4_decompress_fast() : - originalSize : is the original and therefore uncompressed size - return : the number of bytes read from the source buffer (in other words, the compressed size) - If the source stream is malformed, the function will stop decoding and return a negative result. - note : This function is a bit faster than LZ4_decompress_safe() - This function never writes outside of output buffers, but may read beyond input buffer in case of malicious data packet. - Use this function preferably into a trusted environment (data to decode comes from a trusted source). - Destination buffer must be already allocated. Its size must be a minimum of 'outputSize' bytes. -*/ -__declspec(dllimport) int LZ4_decompress_fast(const char* source, char* dest, int originalSize); - - -/* -LZ4_decompress_safe_partial() : - This function decompress a compressed block of size 'inputSize' at position 'source' - into output buffer 'dest' of size 'maxOutputSize'. - The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, - reducing decompression time. - return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize) - Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. - Always control how many bytes were decoded. - If the source stream is detected malformed, the function will stop decoding and return a negative result. - This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets -*/ -__declspec(dllimport) int LZ4_decompress_safe_partial(const char* source, char* dest, int inputSize, int targetOutputSize, int maxOutputSize); - - -/* -These functions are provided should you prefer to allocate memory for compression tables with your own allocation methods. -To know how much memory must be allocated for the compression tables, use : -int LZ4_sizeofState(); - -Note that tables must be aligned on 4-bytes boundaries, otherwise compression will fail (return code 0). - -The allocated memory can be provided to the compressions functions using 'void* state' parameter. -LZ4_compress_withState() and LZ4_compress_limitedOutput_withState() are equivalent to previously described functions. -They just use the externally allocated memory area instead of allocating their own (on stack, or on heap). -*/ -__declspec(dllimport) int LZ4_sizeofState(void); -__declspec(dllimport) int LZ4_compress_withState(void* state, const char* source, char* dest, int inputSize); -__declspec(dllimport) int LZ4_compress_limitedOutput_withState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize); - - -/************************************** - Streaming Functions -**************************************/ -__declspec(dllimport) void* LZ4_create(const char* inputBuffer); -__declspec(dllimport) int LZ4_compress_continue(void* LZ4_Data, const char* source, char* dest, int inputSize); -__declspec(dllimport) int LZ4_compress_limitedOutput_continue(void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize); -__declspec(dllimport) char* LZ4_slideInputBuffer(void* LZ4_Data); -__declspec(dllimport) int LZ4_free(void* LZ4_Data); - -/* -These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks. -In order to achieve this, it is necessary to start creating the LZ4 Data Structure, thanks to the function : - -void* LZ4_create (const char* inputBuffer); -The result of the function is the (void*) pointer on the LZ4 Data Structure. -This pointer will be needed in all other functions. -If the pointer returned is NULL, then the allocation has failed, and compression must be aborted. -The only parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. -The input buffer must be already allocated, and size at least 192KB. -'inputBuffer' will also be the 'const char* source' of the first block. - -All blocks are expected to lay next to each other within the input buffer, starting from 'inputBuffer'. -To compress each block, use either LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(). -Their behavior are identical to LZ4_compress() or LZ4_compress_limitedOutput(), -but require the LZ4 Data Structure as their first argument, and check that each block starts right after the previous one. -If next block does not begin immediately after the previous one, the compression will fail (return 0). - -When it's no longer possible to lay the next block after the previous one (not enough space left into input buffer), a call to : -char* LZ4_slideInputBuffer(void* LZ4_Data); -must be performed. It will typically copy the latest 64KB of input at the beginning of input buffer. -Note that, for this function to work properly, minimum size of an input buffer must be 192KB. -==> The memory position where the next input data block must start is provided as the result of the function. - -Compression can then resume, using LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(), as usual. - -When compression is completed, a call to LZ4_free() will release the memory used by the LZ4 Data Structure. -*/ - - -__declspec(dllimport) int LZ4_sizeofStreamState(void); -__declspec(dllimport) int LZ4_resetStreamState(void* state, const char* inputBuffer); - -/* -These functions achieve the same result as : -void* LZ4_create (const char* inputBuffer); - -They are provided here to allow the user program to allocate memory using its own routines. - -To know how much space must be allocated, use LZ4_sizeofStreamState(); -Note also that space must be 4-bytes aligned. - -Once space is allocated, you must initialize it using : LZ4_resetStreamState(void* state, const char* inputBuffer); -void* state is a pointer to the space allocated. -It must be aligned on 4-bytes boundaries, and be large enough. -The parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. -The input buffer must be already allocated, and size at least 192KB. -'inputBuffer' will also be the 'const char* source' of the first block. - -The same space can be re-used multiple times, just by initializing it each time with LZ4_resetStreamState(). -return value of LZ4_resetStreamState() must be 0 is OK. -Any other value means there was an error (typically, pointer is not aligned on 4-bytes boundaries). -*/ - - -__declspec(dllimport) int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int inputSize, int maxOutputSize); -__declspec(dllimport) int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int outputSize); - -/* -*_withPrefix64k() : - These decoding functions work the same as their "normal name" versions, - but can use up to 64KB of data in front of 'char* dest'. - These functions are necessary to decode inter-dependant blocks. -*/ - - -/************************************** - Obsolete Functions -**************************************/ -/* -These functions are deprecated and should no longer be used. -They are provided here for compatibility with existing user programs. -*/ -__declspec(dllimport) int LZ4_uncompress(const char* source, char* dest, int outputSize); -__declspec(dllimport) int LZ4_uncompress_unknownOutputSize(const char* source, char* dest, int isize, int maxOutputSize); - - -#if defined (__cplusplus) -} -#endif - +/* + LZ4 - Fast LZ compression algorithm + Header File + Copyright (C) 2011-2014, Yann Collet. + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html + - LZ4 source repository : http://code.google.com/p/lz4/ +*/ +#ifndef _LZ4_H +#define _LZ4_H + +#if defined (__cplusplus) +extern "C" +{ +#endif + + +/************************************** + Version +**************************************/ +#define LZ4_VERSION_MAJOR 1 /* for major interface/format changes */ +#define LZ4_VERSION_MINOR 1 /* for minor interface/format changes */ +#define LZ4_VERSION_RELEASE 3 /* for tweaks, bug-fixes, or development */ + + +/************************************** + Compiler Options +**************************************/ +#if (defined(__GNUC__) && defined(__STRICT_ANSI__)) || (defined(_MSC_VER) && !defined(__cplusplus)) /* Visual Studio */ +# define inline __inline /* Visual C is not C99, but supports some kind of inline */ +#endif + + +/************************************** + Simple Functions +**************************************/ + +__declspec(dllimport) int LZ4_compress(const char* source, char* dest, int inputSize); +__declspec(dllimport) int LZ4_decompress_safe(const char* source, char* dest, int inputSize, int maxOutputSize); + +/* +LZ4_compress() : + Compresses 'inputSize' bytes from 'source' into 'dest'. + Destination buffer must be already allocated, + and must be sized to handle worst cases situations (input data not compressible) + Worst case size evaluation is provided by function LZ4_compressBound() + inputSize : Max supported value is LZ4_MAX_INPUT_VALUE + return : the number of bytes written in buffer dest + or 0 if the compression fails + +LZ4_decompress_safe() : + maxOutputSize : is the size of the destination buffer (which must be already allocated) + return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize) + If the source stream is detected malformed, the function will stop decoding and return a negative result. + This function is protected against buffer overflow exploits (never writes outside of output buffer, and never reads outside of input buffer). Therefore, it is protected against malicious data packets +*/ + + +/************************************** + Advanced Functions +**************************************/ +#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ +#define LZ4_COMPRESSBOUND(isize) ((unsigned int)(isize) > (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) + +/* +LZ4_compressBound() : + Provides the maximum size that LZ4 may output in a "worst case" scenario (input data not compressible) + primarily useful for memory allocation of output buffer. + inline function is recommended for the general case, + macro is also provided when result needs to be evaluated at compilation (such as stack memory allocation). + + isize : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE + return : maximum output size in a "worst case" scenario + or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) +*/ +__declspec(dllimport) int LZ4_compressBound(int isize); + + +/* +LZ4_compress_limitedOutput() : + Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. + If it cannot achieve it, compression will stop, and result of the function will be zero. + This function never writes outside of provided output buffer. + + inputSize : Max supported value is LZ4_MAX_INPUT_VALUE + maxOutputSize : is the size of the destination buffer (which must be already allocated) + return : the number of bytes written in buffer 'dest' + or 0 if the compression fails +*/ +__declspec(dllimport) int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize); + + +/* +LZ4_decompress_fast() : + originalSize : is the original and therefore uncompressed size + return : the number of bytes read from the source buffer (in other words, the compressed size) + If the source stream is malformed, the function will stop decoding and return a negative result. + note : This function is a bit faster than LZ4_decompress_safe() + This function never writes outside of output buffers, but may read beyond input buffer in case of malicious data packet. + Use this function preferably into a trusted environment (data to decode comes from a trusted source). + Destination buffer must be already allocated. Its size must be a minimum of 'outputSize' bytes. +*/ +__declspec(dllimport) int LZ4_decompress_fast(const char* source, char* dest, int originalSize); + + +/* +LZ4_decompress_safe_partial() : + This function decompress a compressed block of size 'inputSize' at position 'source' + into output buffer 'dest' of size 'maxOutputSize'. + The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, + reducing decompression time. + return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize) + Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. + Always control how many bytes were decoded. + If the source stream is detected malformed, the function will stop decoding and return a negative result. + This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets +*/ +__declspec(dllimport) int LZ4_decompress_safe_partial(const char* source, char* dest, int inputSize, int targetOutputSize, int maxOutputSize); + + +/* +These functions are provided should you prefer to allocate memory for compression tables with your own allocation methods. +To know how much memory must be allocated for the compression tables, use : +int LZ4_sizeofState(); + +Note that tables must be aligned on 4-bytes boundaries, otherwise compression will fail (return code 0). + +The allocated memory can be provided to the compressions functions using 'void* state' parameter. +LZ4_compress_withState() and LZ4_compress_limitedOutput_withState() are equivalent to previously described functions. +They just use the externally allocated memory area instead of allocating their own (on stack, or on heap). +*/ +__declspec(dllimport) int LZ4_sizeofState(void); +__declspec(dllimport) int LZ4_compress_withState(void* state, const char* source, char* dest, int inputSize); +__declspec(dllimport) int LZ4_compress_limitedOutput_withState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize); + + +/************************************** + Streaming Functions +**************************************/ +__declspec(dllimport) void* LZ4_create(const char* inputBuffer); +__declspec(dllimport) int LZ4_compress_continue(void* LZ4_Data, const char* source, char* dest, int inputSize); +__declspec(dllimport) int LZ4_compress_limitedOutput_continue(void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllimport) char* LZ4_slideInputBuffer(void* LZ4_Data); +__declspec(dllimport) int LZ4_free(void* LZ4_Data); + +/* +These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks. +In order to achieve this, it is necessary to start creating the LZ4 Data Structure, thanks to the function : + +void* LZ4_create (const char* inputBuffer); +The result of the function is the (void*) pointer on the LZ4 Data Structure. +This pointer will be needed in all other functions. +If the pointer returned is NULL, then the allocation has failed, and compression must be aborted. +The only parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. +The input buffer must be already allocated, and size at least 192KB. +'inputBuffer' will also be the 'const char* source' of the first block. + +All blocks are expected to lay next to each other within the input buffer, starting from 'inputBuffer'. +To compress each block, use either LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(). +Their behavior are identical to LZ4_compress() or LZ4_compress_limitedOutput(), +but require the LZ4 Data Structure as their first argument, and check that each block starts right after the previous one. +If next block does not begin immediately after the previous one, the compression will fail (return 0). + +When it's no longer possible to lay the next block after the previous one (not enough space left into input buffer), a call to : +char* LZ4_slideInputBuffer(void* LZ4_Data); +must be performed. It will typically copy the latest 64KB of input at the beginning of input buffer. +Note that, for this function to work properly, minimum size of an input buffer must be 192KB. +==> The memory position where the next input data block must start is provided as the result of the function. + +Compression can then resume, using LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(), as usual. + +When compression is completed, a call to LZ4_free() will release the memory used by the LZ4 Data Structure. +*/ + + +__declspec(dllimport) int LZ4_sizeofStreamState(void); +__declspec(dllimport) int LZ4_resetStreamState(void* state, const char* inputBuffer); + +/* +These functions achieve the same result as : +void* LZ4_create (const char* inputBuffer); + +They are provided here to allow the user program to allocate memory using its own routines. + +To know how much space must be allocated, use LZ4_sizeofStreamState(); +Note also that space must be 4-bytes aligned. + +Once space is allocated, you must initialize it using : LZ4_resetStreamState(void* state, const char* inputBuffer); +void* state is a pointer to the space allocated. +It must be aligned on 4-bytes boundaries, and be large enough. +The parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. +The input buffer must be already allocated, and size at least 192KB. +'inputBuffer' will also be the 'const char* source' of the first block. + +The same space can be re-used multiple times, just by initializing it each time with LZ4_resetStreamState(). +return value of LZ4_resetStreamState() must be 0 is OK. +Any other value means there was an error (typically, pointer is not aligned on 4-bytes boundaries). +*/ + + +__declspec(dllimport) int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllimport) int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int outputSize); + +/* +*_withPrefix64k() : + These decoding functions work the same as their "normal name" versions, + but can use up to 64KB of data in front of 'char* dest'. + These functions are necessary to decode inter-dependant blocks. +*/ + + +/************************************** + Obsolete Functions +**************************************/ +/* +These functions are deprecated and should no longer be used. +They are provided here for compatibility with existing user programs. +*/ +__declspec(dllimport) int LZ4_uncompress(const char* source, char* dest, int outputSize); +__declspec(dllimport) int LZ4_uncompress_unknownOutputSize(const char* source, char* dest, int isize, int maxOutputSize); + + +#if defined (__cplusplus) +} +#endif + #endif //_LZ4_H \ No newline at end of file diff --git a/src/dbg/lz4/lz4file.h b/src/dbg/lz4/lz4file.h index d2a06275..7f64b7f7 100644 --- a/src/dbg/lz4/lz4file.h +++ b/src/dbg/lz4/lz4file.h @@ -1,28 +1,28 @@ -#ifndef _LZ4FILE_H -#define _LZ4FILE_H - -typedef enum _LZ4_STATUS -{ - LZ4_SUCCESS, - LZ4_FAILED_OPEN_INPUT, - LZ4_FAILED_OPEN_OUTPUT, - LZ4_NOT_ENOUGH_MEMORY, - LZ4_INVALID_ARCHIVE, - LZ4_CORRUPTED_ARCHIVE -} LZ4_STATUS; - -#if defined (__cplusplus) -extern "C" -{ -#endif - -__declspec(dllimport) LZ4_STATUS LZ4_compress_file(const char* input_filename, const char* output_filename); -__declspec(dllimport) LZ4_STATUS LZ4_compress_fileW(const wchar_t* input_filename, const wchar_t* output_filename); -__declspec(dllimport) LZ4_STATUS LZ4_decompress_file(const char* input_filename, const char* output_filename); -__declspec(dllimport) LZ4_STATUS LZ4_decompress_fileW(const wchar_t* input_filename, const wchar_t* output_filename); - -#if defined (__cplusplus) -} -#endif - +#ifndef _LZ4FILE_H +#define _LZ4FILE_H + +typedef enum _LZ4_STATUS +{ + LZ4_SUCCESS, + LZ4_FAILED_OPEN_INPUT, + LZ4_FAILED_OPEN_OUTPUT, + LZ4_NOT_ENOUGH_MEMORY, + LZ4_INVALID_ARCHIVE, + LZ4_CORRUPTED_ARCHIVE +} LZ4_STATUS; + +#if defined (__cplusplus) +extern "C" +{ +#endif + +__declspec(dllimport) LZ4_STATUS LZ4_compress_file(const char* input_filename, const char* output_filename); +__declspec(dllimport) LZ4_STATUS LZ4_compress_fileW(const wchar_t* input_filename, const wchar_t* output_filename); +__declspec(dllimport) LZ4_STATUS LZ4_decompress_file(const char* input_filename, const char* output_filename); +__declspec(dllimport) LZ4_STATUS LZ4_decompress_fileW(const wchar_t* input_filename, const wchar_t* output_filename); + +#if defined (__cplusplus) +} +#endif + #endif //_LZ4FILE_H \ No newline at end of file diff --git a/src/dbg/lz4/lz4hc.h b/src/dbg/lz4/lz4hc.h index 08ddb3aa..bfed4b03 100644 --- a/src/dbg/lz4/lz4hc.h +++ b/src/dbg/lz4/lz4hc.h @@ -1,175 +1,175 @@ -/* - LZ4 HC - High Compression Mode of LZ4 - Header File - Copyright (C) 2011-2014, Yann Collet. - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - You can contact the author at : - - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html - - LZ4 source repository : http://code.google.com/p/lz4/ -*/ -#ifndef _LZ4HC_H -#define _LZ4HC_H - -#if defined (__cplusplus) -extern "C" -{ -#endif - - -__declspec(dllimport) int LZ4_compressHC(const char* source, char* dest, int inputSize); -/* -LZ4_compressHC : - return : the number of bytes in compressed buffer dest - or 0 if compression fails. - note : destination buffer must be already allocated. - To avoid any problem, size it to handle worst cases situations (input data not compressible) - Worst case size evaluation is provided by function LZ4_compressBound() (see "lz4.h") -*/ - -__declspec(dllimport) int LZ4_compressHC_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize); -/* -LZ4_compress_limitedOutput() : - Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. - If it cannot achieve it, compression will stop, and result of the function will be zero. - This function never writes outside of provided output buffer. - - inputSize : Max supported value is 1 GB - maxOutputSize : is maximum allowed size into the destination buffer (which must be already allocated) - return : the number of output bytes written in buffer 'dest' - or 0 if compression fails. -*/ - - -__declspec(dllimport) int LZ4_compressHC2(const char* source, char* dest, int inputSize, int compressionLevel); -__declspec(dllimport) int LZ4_compressHC2_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); -/* - Same functions as above, but with programmable 'compressionLevel'. - Recommended values are between 4 and 9, although any value between 0 and 16 will work. - 'compressionLevel'==0 means use default 'compressionLevel' value. - Values above 16 behave the same as 16. - Equivalent variants exist for all other compression functions below. -*/ - -/* Note : -Decompression functions are provided within LZ4 source code (see "lz4.h") (BSD license) -*/ - - -/************************************** - Using an external allocation -**************************************/ -__declspec(dllimport) int LZ4_sizeofStateHC(void); -__declspec(dllimport) int LZ4_compressHC_withStateHC(void* state, const char* source, char* dest, int inputSize); -__declspec(dllimport) int LZ4_compressHC_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize); - -__declspec(dllimport) int LZ4_compressHC2_withStateHC(void* state, const char* source, char* dest, int inputSize, int compressionLevel); -__declspec(dllimport) int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); - -/* -These functions are provided should you prefer to allocate memory for compression tables with your own allocation methods. -To know how much memory must be allocated for the compression tables, use : -int LZ4_sizeofStateHC(); - -Note that tables must be aligned for pointer (32 or 64 bits), otherwise compression will fail (return code 0). - -The allocated memory can be provided to the compressions functions using 'void* state' parameter. -LZ4_compress_withStateHC() and LZ4_compress_limitedOutput_withStateHC() are equivalent to previously described functions. -They just use the externally allocated memory area instead of allocating their own (on stack, or on heap). -*/ - - -/************************************** - Streaming Functions -**************************************/ -__declspec(dllimport) void* LZ4_createHC(const char* inputBuffer); -__declspec(dllimport) int LZ4_compressHC_continue(void* LZ4HC_Data, const char* source, char* dest, int inputSize); -__declspec(dllimport) int LZ4_compressHC_limitedOutput_continue(void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize); -__declspec(dllimport) char* LZ4_slideInputBufferHC(void* LZ4HC_Data); -__declspec(dllimport) int LZ4_freeHC(void* LZ4HC_Data); - -__declspec(dllimport) int LZ4_compressHC2_continue(void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel); -__declspec(dllimport) int LZ4_compressHC2_limitedOutput_continue(void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); - -/* -These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks. -In order to achieve this, it is necessary to start creating the LZ4HC Data Structure, thanks to the function : - -void* LZ4_createHC (const char* inputBuffer); -The result of the function is the (void*) pointer on the LZ4HC Data Structure. -This pointer will be needed in all other functions. -If the pointer returned is NULL, then the allocation has failed, and compression must be aborted. -The only parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. -The input buffer must be already allocated, and size at least 192KB. -'inputBuffer' will also be the 'const char* source' of the first block. - -All blocks are expected to lay next to each other within the input buffer, starting from 'inputBuffer'. -To compress each block, use either LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue(). -Their behavior are identical to LZ4_compressHC() or LZ4_compressHC_limitedOutput(), -but require the LZ4HC Data Structure as their first argument, and check that each block starts right after the previous one. -If next block does not begin immediately after the previous one, the compression will fail (return 0). - -When it's no longer possible to lay the next block after the previous one (not enough space left into input buffer), a call to : -char* LZ4_slideInputBufferHC(void* LZ4HC_Data); -must be performed. It will typically copy the latest 64KB of input at the beginning of input buffer. -Note that, for this function to work properly, minimum size of an input buffer must be 192KB. -==> The memory position where the next input data block must start is provided as the result of the function. - -Compression can then resume, using LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue(), as usual. - -When compression is completed, a call to LZ4_freeHC() will release the memory used by the LZ4HC Data Structure. -*/ - -__declspec(dllimport) int LZ4_sizeofStreamStateHC(void); -__declspec(dllimport) int LZ4_resetStreamStateHC(void* state, const char* inputBuffer); - -/* -These functions achieve the same result as : -void* LZ4_createHC (const char* inputBuffer); - -They are provided here to allow the user program to allocate memory using its own routines. - -To know how much space must be allocated, use LZ4_sizeofStreamStateHC(); -Note also that space must be aligned for pointers (32 or 64 bits). - -Once space is allocated, you must initialize it using : LZ4_resetStreamStateHC(void* state, const char* inputBuffer); -void* state is a pointer to the space allocated. -It must be aligned for pointers (32 or 64 bits), and be large enough. -The parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. -The input buffer must be already allocated, and size at least 192KB. -'inputBuffer' will also be the 'const char* source' of the first block. - -The same space can be re-used multiple times, just by initializing it each time with LZ4_resetStreamState(). -return value of LZ4_resetStreamStateHC() must be 0 is OK. -Any other value means there was an error (typically, state is not aligned for pointers (32 or 64 bits)). -*/ - - -#if defined (__cplusplus) -} -#endif - -#endif //_LZ4HC_H +/* + LZ4 HC - High Compression Mode of LZ4 + Header File + Copyright (C) 2011-2014, Yann Collet. + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html + - LZ4 source repository : http://code.google.com/p/lz4/ +*/ +#ifndef _LZ4HC_H +#define _LZ4HC_H + +#if defined (__cplusplus) +extern "C" +{ +#endif + + +__declspec(dllimport) int LZ4_compressHC(const char* source, char* dest, int inputSize); +/* +LZ4_compressHC : + return : the number of bytes in compressed buffer dest + or 0 if compression fails. + note : destination buffer must be already allocated. + To avoid any problem, size it to handle worst cases situations (input data not compressible) + Worst case size evaluation is provided by function LZ4_compressBound() (see "lz4.h") +*/ + +__declspec(dllimport) int LZ4_compressHC_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize); +/* +LZ4_compress_limitedOutput() : + Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. + If it cannot achieve it, compression will stop, and result of the function will be zero. + This function never writes outside of provided output buffer. + + inputSize : Max supported value is 1 GB + maxOutputSize : is maximum allowed size into the destination buffer (which must be already allocated) + return : the number of output bytes written in buffer 'dest' + or 0 if compression fails. +*/ + + +__declspec(dllimport) int LZ4_compressHC2(const char* source, char* dest, int inputSize, int compressionLevel); +__declspec(dllimport) int LZ4_compressHC2_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); +/* + Same functions as above, but with programmable 'compressionLevel'. + Recommended values are between 4 and 9, although any value between 0 and 16 will work. + 'compressionLevel'==0 means use default 'compressionLevel' value. + Values above 16 behave the same as 16. + Equivalent variants exist for all other compression functions below. +*/ + +/* Note : +Decompression functions are provided within LZ4 source code (see "lz4.h") (BSD license) +*/ + + +/************************************** + Using an external allocation +**************************************/ +__declspec(dllimport) int LZ4_sizeofStateHC(void); +__declspec(dllimport) int LZ4_compressHC_withStateHC(void* state, const char* source, char* dest, int inputSize); +__declspec(dllimport) int LZ4_compressHC_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize); + +__declspec(dllimport) int LZ4_compressHC2_withStateHC(void* state, const char* source, char* dest, int inputSize, int compressionLevel); +__declspec(dllimport) int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); + +/* +These functions are provided should you prefer to allocate memory for compression tables with your own allocation methods. +To know how much memory must be allocated for the compression tables, use : +int LZ4_sizeofStateHC(); + +Note that tables must be aligned for pointer (32 or 64 bits), otherwise compression will fail (return code 0). + +The allocated memory can be provided to the compressions functions using 'void* state' parameter. +LZ4_compress_withStateHC() and LZ4_compress_limitedOutput_withStateHC() are equivalent to previously described functions. +They just use the externally allocated memory area instead of allocating their own (on stack, or on heap). +*/ + + +/************************************** + Streaming Functions +**************************************/ +__declspec(dllimport) void* LZ4_createHC(const char* inputBuffer); +__declspec(dllimport) int LZ4_compressHC_continue(void* LZ4HC_Data, const char* source, char* dest, int inputSize); +__declspec(dllimport) int LZ4_compressHC_limitedOutput_continue(void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllimport) char* LZ4_slideInputBufferHC(void* LZ4HC_Data); +__declspec(dllimport) int LZ4_freeHC(void* LZ4HC_Data); + +__declspec(dllimport) int LZ4_compressHC2_continue(void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel); +__declspec(dllimport) int LZ4_compressHC2_limitedOutput_continue(void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); + +/* +These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks. +In order to achieve this, it is necessary to start creating the LZ4HC Data Structure, thanks to the function : + +void* LZ4_createHC (const char* inputBuffer); +The result of the function is the (void*) pointer on the LZ4HC Data Structure. +This pointer will be needed in all other functions. +If the pointer returned is NULL, then the allocation has failed, and compression must be aborted. +The only parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. +The input buffer must be already allocated, and size at least 192KB. +'inputBuffer' will also be the 'const char* source' of the first block. + +All blocks are expected to lay next to each other within the input buffer, starting from 'inputBuffer'. +To compress each block, use either LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue(). +Their behavior are identical to LZ4_compressHC() or LZ4_compressHC_limitedOutput(), +but require the LZ4HC Data Structure as their first argument, and check that each block starts right after the previous one. +If next block does not begin immediately after the previous one, the compression will fail (return 0). + +When it's no longer possible to lay the next block after the previous one (not enough space left into input buffer), a call to : +char* LZ4_slideInputBufferHC(void* LZ4HC_Data); +must be performed. It will typically copy the latest 64KB of input at the beginning of input buffer. +Note that, for this function to work properly, minimum size of an input buffer must be 192KB. +==> The memory position where the next input data block must start is provided as the result of the function. + +Compression can then resume, using LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue(), as usual. + +When compression is completed, a call to LZ4_freeHC() will release the memory used by the LZ4HC Data Structure. +*/ + +__declspec(dllimport) int LZ4_sizeofStreamStateHC(void); +__declspec(dllimport) int LZ4_resetStreamStateHC(void* state, const char* inputBuffer); + +/* +These functions achieve the same result as : +void* LZ4_createHC (const char* inputBuffer); + +They are provided here to allow the user program to allocate memory using its own routines. + +To know how much space must be allocated, use LZ4_sizeofStreamStateHC(); +Note also that space must be aligned for pointers (32 or 64 bits). + +Once space is allocated, you must initialize it using : LZ4_resetStreamStateHC(void* state, const char* inputBuffer); +void* state is a pointer to the space allocated. +It must be aligned for pointers (32 or 64 bits), and be large enough. +The parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. +The input buffer must be already allocated, and size at least 192KB. +'inputBuffer' will also be the 'const char* source' of the first block. + +The same space can be re-used multiple times, just by initializing it each time with LZ4_resetStreamState(). +return value of LZ4_resetStreamStateHC() must be 0 is OK. +Any other value means there was an error (typically, state is not aligned for pointers (32 or 64 bits)). +*/ + + +#if defined (__cplusplus) +} +#endif + +#endif //_LZ4HC_H diff --git a/src/dbg/main.cpp b/src/dbg/main.cpp index 90e65df9..66146624 100644 --- a/src/dbg/main.cpp +++ b/src/dbg/main.cpp @@ -1,14 +1,14 @@ -/** - @file main.cpp - - @brief Implements the main class. - */ - -#include "_global.h" - -extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - if(fdwReason == DLL_PROCESS_ATTACH) - hInst = hinstDLL; - return TRUE; -} +/** + @file main.cpp + + @brief Implements the main class. + */ + +#include "_global.h" + +extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + if(fdwReason == DLL_PROCESS_ATTACH) + hInst = hinstDLL; + return TRUE; +} diff --git a/src/dbg/memory.cpp b/src/dbg/memory.cpp index 40cc0d94..ae59e635 100644 --- a/src/dbg/memory.cpp +++ b/src/dbg/memory.cpp @@ -1,572 +1,572 @@ -/** - @file memory.cpp - - @brief Implements the memory class. - */ - -#include "memory.h" -#include "debugger.h" -#include "patches.h" -#include "threading.h" -#include "thread.h" -#include "module.h" - -#define PAGE_SHIFT (12) -//#define PAGE_SIZE (4096) -#define PAGE_ALIGN(Va) ((ULONG_PTR)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1))) -#define BYTES_TO_PAGES(Size) (((Size) >> PAGE_SHIFT) + (((Size) & (PAGE_SIZE - 1)) != 0)) -#define ROUND_TO_PAGES(Size) (((ULONG_PTR)(Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) - -std::map memoryPages; -bool bListAllPages = false; - -void MemUpdateMap() -{ - // First gather all possible pages in the memory range - std::vector pageVector; - { - SIZE_T numBytes = 0; - duint pageStart = 0; - duint allocationBase = 0; - - do - { - // Query memory attributes - MEMORY_BASIC_INFORMATION mbi; - memset(&mbi, 0, sizeof(mbi)); - - numBytes = VirtualQueryEx(fdProcessInfo->hProcess, (LPVOID)pageStart, &mbi, sizeof(mbi)); - - // Only allow pages that are committed to memory (exclude reserved/mapped) - if(mbi.State == MEM_COMMIT) - { - // Only list allocation bases, unless if forced to list all - if(bListAllPages || allocationBase != (duint)mbi.AllocationBase) - { - // Set the new allocation base page - allocationBase = (duint)mbi.AllocationBase; - - MEMPAGE curPage; - memset(&curPage, 0, sizeof(MEMPAGE)); - memcpy(&curPage.mbi, &mbi, sizeof(mbi)); - - ModNameFromAddr(pageStart, curPage.info, true); - pageVector.push_back(curPage); - } - else - { - // Otherwise append the page to the last created entry - pageVector.back().mbi.RegionSize += mbi.RegionSize; - } - } - - // Calculate the next page start - duint newAddress = (duint)mbi.BaseAddress + mbi.RegionSize; - - if(newAddress <= pageStart) - break; - - pageStart = newAddress; - } - while(numBytes); - } - - // Process file sections - int pagecount = (int)pageVector.size(); - char curMod[MAX_MODULE_SIZE] = ""; - for(int i = pagecount - 1; i > -1; i--) - { - auto & currentPage = pageVector.at(i); - if(!currentPage.info[0] || (scmp(curMod, currentPage.info) && !bListAllPages)) //there is a module - continue; //skip non-modules - strcpy(curMod, pageVector.at(i).info); - duint base = ModBaseFromName(currentPage.info); - if(!base) - continue; - std::vector sections; - if(!ModSectionsFromAddr(base, §ions)) - continue; - int SectionNumber = (int)sections.size(); - if(!SectionNumber) //no sections = skip - continue; - if(!bListAllPages) //normal view - { - MEMPAGE newPage; - //remove the current module page (page = size of module at this point) and insert the module sections - pageVector.erase(pageVector.begin() + i); //remove the SizeOfImage page - for(int j = SectionNumber - 1; j > -1; j--) - { - const auto & currentSection = sections.at(j); - memset(&newPage, 0, sizeof(MEMPAGE)); - VirtualQueryEx(fdProcessInfo->hProcess, (LPCVOID)currentSection.addr, &newPage.mbi, sizeof(MEMORY_BASIC_INFORMATION)); - duint SectionSize = currentSection.size; - if(SectionSize % PAGE_SIZE) //unaligned page size - SectionSize += PAGE_SIZE - (SectionSize % PAGE_SIZE); //fix this - if(SectionSize) - newPage.mbi.RegionSize = SectionSize; - sprintf_s(newPage.info, " \"%s\"", currentSection.name); - pageVector.insert(pageVector.begin() + i, newPage); - } - //insert the module itself (the module header) - memset(&newPage, 0, sizeof(MEMPAGE)); - VirtualQueryEx(fdProcessInfo->hProcess, (LPCVOID)base, &newPage.mbi, sizeof(MEMORY_BASIC_INFORMATION)); - strcpy_s(newPage.info, curMod); - pageVector.insert(pageVector.begin() + i, newPage); - } - else //list all pages - { - duint start = (duint)currentPage.mbi.BaseAddress; - duint end = start + currentPage.mbi.RegionSize; - for(int j = 0, k = 0; j < SectionNumber; j++) - { - const auto & currentSection = sections.at(j); - duint secStart = currentSection.addr; - duint SectionSize = currentSection.size; - if(SectionSize % PAGE_SIZE) //unaligned page size - SectionSize += PAGE_SIZE - (SectionSize % PAGE_SIZE); //fix this - duint secEnd = secStart + SectionSize; - if(secStart >= start && secEnd <= end) //section is inside the memory page - { - if(k) - k += sprintf_s(currentPage.info + k, MAX_MODULE_SIZE - k, ","); - k += sprintf_s(currentPage.info + k, MAX_MODULE_SIZE - k, " \"%s\"", currentSection.name); - } - else if(start >= secStart && end <= secEnd) //memory page is inside the section - { - if(k) - k += sprintf_s(currentPage.info + k, MAX_MODULE_SIZE - k, ","); - k += sprintf_s(currentPage.info + k, MAX_MODULE_SIZE - k, " \"%s\"", currentSection.name); - } - } - } - } - - // Get a list of threads for information about Kernel/PEB/TEB/Stack ranges - THREADLIST threadList; - ThreadGetList(&threadList); - - for (auto & page : pageVector) - { - const duint pageBase = (duint)page.mbi.BaseAddress; - const duint pageSize = (duint)page.mbi.RegionSize; - - // Check for windows specific data - if (pageBase == 0x7FFE0000) - { - strcpy_s(page.info, "KUSER_SHARED_DATA"); - continue; - } - - // Check in threads - for (int i = 0; i < threadList.count; i++) - { - duint tebBase = threadList.list[i].BasicInfo.ThreadLocalBase; - DWORD threadId = threadList.list[i].BasicInfo.ThreadId; - - // Mark TEB - if (pageBase == tebBase) - { - sprintf_s(page.info, "Thread %X TEB", threadId); - break; - } - - // Read the TEB to get stack information - TEB teb; - if (!ThreadGetTeb(tebBase, &teb)) - continue; - - // The stack will be a specific range only, not always the base address - duint stackAddr = (duint)teb.Tib.StackLimit; - - if (stackAddr >= pageBase && stackAddr < (pageBase + pageSize)) - sprintf_s(page.info, "Thread %X Stack", threadId); - } - } - - // Only free thread data if it was allocated - if (threadList.list) - BridgeFree(threadList.list); - - // Convert the vector to a map - EXCLUSIVE_ACQUIRE(LockMemoryPages); - memoryPages.clear(); - - for(auto & page : pageVector) - { - duint start = (duint)page.mbi.BaseAddress; - duint size = (duint)page.mbi.RegionSize; - memoryPages.insert(std::make_pair(std::make_pair(start, start + size - 1), page)); - } -} - -duint MemFindBaseAddr(duint Address, duint* Size, bool Refresh) -{ - // Update the memory map if needed - if(Refresh) - MemUpdateMap(); - - SHARED_ACQUIRE(LockMemoryPages); - - // Search for the memory page address - auto found = memoryPages.find(std::make_pair(Address, Address)); - - if(found == memoryPages.end()) - return 0; - - // Return the allocation region size when requested - if(Size) - *Size = found->second.mbi.RegionSize; - - return found->first.first; -} - -bool MemRead(duint BaseAddress, void* Buffer, duint Size, duint* NumberOfBytesRead) -{ - if(!MemIsCanonicalAddress(BaseAddress)) - return false; - - // Buffer must be supplied and size must be greater than 0 - if(!Buffer || Size <= 0) - return false; - - // If the 'bytes read' parameter is null, use a temp - SIZE_T bytesReadTemp = 0; - - if(!NumberOfBytesRead) - NumberOfBytesRead = &bytesReadTemp; - - // Normal single-call read - bool ret = MemoryReadSafe(fdProcessInfo->hProcess, (LPVOID)BaseAddress, Buffer, Size, NumberOfBytesRead); - - if(ret && *NumberOfBytesRead == Size) - return true; - - // Read page-by-page (Skip if only 1 page exists) - // If (SIZE > PAGE_SIZE) or (ADDRESS exceeds boundary), multiple reads will be needed - SIZE_T pageCount = BYTES_TO_PAGES(Size); - - if(pageCount > 1) - { - // Determine the number of bytes between ADDRESS and the next page - duint offset = 0; - duint readBase = BaseAddress; - duint readSize = ROUND_TO_PAGES(readBase) - readBase; - - // Reset the bytes read count - *NumberOfBytesRead = 0; - - for(SIZE_T i = 0; i < pageCount; i++) - { - SIZE_T bytesRead = 0; - - if(MemoryReadSafe(fdProcessInfo->hProcess, (PVOID)readBase, ((PBYTE)Buffer + offset), readSize, &bytesRead)) - *NumberOfBytesRead += bytesRead; - - offset += readSize; - readBase += readSize; - - Size -= readSize; - readSize = min(PAGE_SIZE, Size); - } - } - - SetLastError(ERROR_PARTIAL_COPY); - return (*NumberOfBytesRead > 0); -} - -bool MemWrite(duint BaseAddress, const void* Buffer, duint Size, duint* NumberOfBytesWritten) -{ - if(!MemIsCanonicalAddress(BaseAddress)) - return false; - - // Buffer must be supplied and size must be greater than 0 - if(!Buffer || Size <= 0) - return false; - - // If the 'bytes written' parameter is null, use a temp - SIZE_T bytesWrittenTemp = 0; - - if(!NumberOfBytesWritten) - NumberOfBytesWritten = &bytesWrittenTemp; - - // Try a regular WriteProcessMemory call - bool ret = MemoryWriteSafe(fdProcessInfo->hProcess, (LPVOID)BaseAddress, Buffer, Size, NumberOfBytesWritten); - - if(ret && *NumberOfBytesWritten == Size) - return true; - - // Write page-by-page (Skip if only 1 page exists) - // See: MemRead - SIZE_T pageCount = BYTES_TO_PAGES(Size); - - if(pageCount > 1) - { - // Determine the number of bytes between ADDRESS and the next page - duint offset = 0; - duint writeBase = BaseAddress; - duint writeSize = ROUND_TO_PAGES(writeBase) - writeBase; - - // Reset the bytes read count - *NumberOfBytesWritten = 0; - - for(SIZE_T i = 0; i < pageCount; i++) - { - SIZE_T bytesWritten = 0; - - if(MemoryWriteSafe(fdProcessInfo->hProcess, (PVOID)writeBase, ((PBYTE)Buffer + offset), writeSize, &bytesWritten)) - *NumberOfBytesWritten += bytesWritten; - - offset += writeSize; - writeBase += writeSize; - - Size -= writeSize; - writeSize = min(PAGE_SIZE, Size); - } - } - - SetLastError(ERROR_PARTIAL_COPY); - return (*NumberOfBytesWritten > 0); -} - -bool MemPatch(duint BaseAddress, const void* Buffer, duint Size, duint* NumberOfBytesWritten) -{ - // Buffer and size must be valid - if(!Buffer || Size <= 0) - return false; - - // Allocate the memory - Memory oldData(Size, "mempatch:oldData"); - - if(!MemRead(BaseAddress, oldData(), Size)) - { - // If no memory can be read, no memory can be written. Fail out - // of this function. - return false; - } - - // Are we able to write on this page? - if (MemWrite(BaseAddress, Buffer, Size, NumberOfBytesWritten)) - { - for (duint i = 0; i < Size; i++) - PatchSet(BaseAddress + i, oldData()[i], ((const unsigned char*)Buffer)[i]); - - // Done - return true; - } - - // Unable to write memory - return false; -} - -bool MemIsValidReadPtr(duint Address) -{ - unsigned char a = 0; - return MemRead(Address, &a, sizeof(unsigned char)); -} - -bool MemIsCanonicalAddress(duint Address) -{ -#ifndef _WIN64 - // 32-bit mode only supports 4GB max, so limits are - // not an issue - return true; -#else - // The most-significant 16 bits must be all 1 or all 0. - // (64 - 16) = 48bit linear address range. - // - // 0xFFFF800000000000 = Significant 16 bits set - // 0x0000800000000000 = 48th bit set - return (((Address & 0xFFFF800000000000) + 0x800000000000) & ~0x800000000000) == 0; -#endif // ndef _WIN64 -} - -bool MemIsCodePage(duint Address, bool Refresh) -{ - MEMPAGE pageInfo; - if(!MemGetPageInfo(Address, &pageInfo, Refresh)) - return false; - - return (pageInfo.mbi.Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0; -} - -duint MemAllocRemote(duint Address, duint Size, DWORD Type, DWORD Protect) -{ - return (duint)VirtualAllocEx(fdProcessInfo->hProcess, (LPVOID)Address, Size, Type, Protect); -} - -bool MemFreeRemote(duint Address) -{ - return VirtualFreeEx(fdProcessInfo->hProcess, (LPVOID)Address, 0, MEM_RELEASE) == TRUE; -} - -duint MemGetPageAligned(duint Address) -{ - return PAGE_ALIGN(Address); -} - -bool MemGetPageInfo(duint Address, MEMPAGE* PageInfo, bool Refresh) -{ - // Update the memory map if needed - if(Refresh) - MemUpdateMap(); - - SHARED_ACQUIRE(LockMemoryPages); - - // Search for the memory page address - auto found = memoryPages.find(std::make_pair(Address, Address)); - - if(found == memoryPages.end()) - return false; - - // Return the data when possible - if(PageInfo) - *PageInfo = found->second; - - return true; -} - -bool MemSetPageRights(duint Address, const char* Rights) -{ - // Align address to page base - Address = MemGetPageAligned(Address); - - // String -> bit mask - DWORD protect; - if(!MemPageRightsFromString(&protect, Rights)) - return false; - - DWORD oldProtect; - return VirtualProtectEx(fdProcessInfo->hProcess, (void*)Address, PAGE_SIZE, protect, &oldProtect) == TRUE; -} - -bool MemGetPageRights(duint Address, char* Rights) -{ - // Align address to page base - Address = MemGetPageAligned(Address); - - MEMORY_BASIC_INFORMATION mbi; - memset(&mbi, 0, sizeof(MEMORY_BASIC_INFORMATION)); - - if(!VirtualQueryEx(fdProcessInfo->hProcess, (void*)Address, &mbi, sizeof(mbi))) - return false; - - return MemPageRightsToString(mbi.Protect, Rights); -} - -bool MemPageRightsToString(DWORD Protect, char* Rights) -{ - switch(Protect & 0xFF) - { - case PAGE_NOACCESS: - strcpy_s(Rights, RIGHTS_STRING_SIZE, "----"); - break; - case PAGE_READONLY: - strcpy_s(Rights, RIGHTS_STRING_SIZE, "-R--"); - break; - case PAGE_READWRITE: - strcpy_s(Rights, RIGHTS_STRING_SIZE, "-RW-"); - break; - case PAGE_WRITECOPY: - strcpy_s(Rights, RIGHTS_STRING_SIZE, "-RWC"); - break; - case PAGE_EXECUTE: - strcpy_s(Rights, RIGHTS_STRING_SIZE, "E---"); - break; - case PAGE_EXECUTE_READ: - strcpy_s(Rights, RIGHTS_STRING_SIZE, "ER--"); - break; - case PAGE_EXECUTE_READWRITE: - strcpy_s(Rights, RIGHTS_STRING_SIZE, "ERW-"); - break; - case PAGE_EXECUTE_WRITECOPY: - strcpy_s(Rights, RIGHTS_STRING_SIZE, "ERWC"); - break; - } - - strcat_s(Rights, RIGHTS_STRING_SIZE, ((Protect & PAGE_GUARD) == PAGE_GUARD) ? "G" : "-"); - // Rights[5] = ((Protect & PAGE_NOCACHE) == PAGE_NOCACHE) ? '' : '-'; - // Rights[6] = ((Protect & PAGE_WRITECOMBINE) == PAGE_GUARD) ? '' : '-'; - - return true; -} - -bool MemPageRightsFromString(DWORD* Protect, const char* Rights) -{ - ASSERT_TRUE(strlen(Rights) >= 2); - *Protect = 0; - - // Check for the PAGE_GUARD flag - if(Rights[0] == 'G' || Rights[0] == 'g') - { - *Protect |= PAGE_GUARD; - Rights++; - } - - if(_strcmpi(Rights, "Execute") == 0) - *Protect |= PAGE_EXECUTE; - else if(_strcmpi(Rights, "ExecuteRead") == 0) - *Protect |= PAGE_EXECUTE_READ; - else if(_strcmpi(Rights, "ExecuteReadWrite") == 0) - *Protect |= PAGE_EXECUTE_READWRITE; - else if(_strcmpi(Rights, "ExecuteWriteCopy") == 0) - *Protect |= PAGE_EXECUTE_WRITECOPY; - else if(_strcmpi(Rights, "NoAccess") == 0) - *Protect |= PAGE_NOACCESS; - else if(_strcmpi(Rights, "ReadOnly") == 0) - *Protect |= PAGE_READONLY; - else if(_strcmpi(Rights, "ReadWrite") == 0) - *Protect |= PAGE_READWRITE; - else if(_strcmpi(Rights, "WriteCopy") == 0) - *Protect |= PAGE_WRITECOPY; - - return (*Protect != 0); -} - -bool MemFindInPage(SimplePage page, duint startoffset, const std::vector & pattern, std::vector & results, duint maxresults) -{ - if(startoffset >= page.size || results.size() >= maxresults) - return false; - - //TODO: memory read limit - Memory data(page.size); - if(!MemRead(page.address, data(), data.size())) - return false; - - duint maxFind = maxresults; - duint foundCount = results.size(); - duint i = 0; - duint findSize = data.size() - startoffset; - while(foundCount < maxFind) - { - duint foundoffset = patternfind(data() + startoffset + i, findSize - i, pattern); - if(foundoffset == -1) - break; - i += foundoffset + 1; - duint result = page.address + startoffset + i - 1; - results.push_back(result); - foundCount++; - } - return true; -} - -bool MemFindInMap(const std::vector & pages, const std::vector & pattern, std::vector & results, duint maxresults, bool progress) -{ - duint count = 0; - duint total = pages.size(); - for(const auto page : pages) - { - if(!MemFindInPage(page, 0, pattern, results, maxresults)) - return false; - if(progress) - GuiReferenceSetProgress(int(floor((float(count) / float(total)) * 100.0f))); - if(results.size() >= maxresults) - break; - count++; - } - if(progress) - { - GuiReferenceSetProgress(100); - GuiReferenceReloadData(); - } - return true; +/** + @file memory.cpp + + @brief Implements the memory class. + */ + +#include "memory.h" +#include "debugger.h" +#include "patches.h" +#include "threading.h" +#include "thread.h" +#include "module.h" + +#define PAGE_SHIFT (12) +//#define PAGE_SIZE (4096) +#define PAGE_ALIGN(Va) ((ULONG_PTR)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1))) +#define BYTES_TO_PAGES(Size) (((Size) >> PAGE_SHIFT) + (((Size) & (PAGE_SIZE - 1)) != 0)) +#define ROUND_TO_PAGES(Size) (((ULONG_PTR)(Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) + +std::map memoryPages; +bool bListAllPages = false; + +void MemUpdateMap() +{ + // First gather all possible pages in the memory range + std::vector pageVector; + { + SIZE_T numBytes = 0; + duint pageStart = 0; + duint allocationBase = 0; + + do + { + // Query memory attributes + MEMORY_BASIC_INFORMATION mbi; + memset(&mbi, 0, sizeof(mbi)); + + numBytes = VirtualQueryEx(fdProcessInfo->hProcess, (LPVOID)pageStart, &mbi, sizeof(mbi)); + + // Only allow pages that are committed to memory (exclude reserved/mapped) + if(mbi.State == MEM_COMMIT) + { + // Only list allocation bases, unless if forced to list all + if(bListAllPages || allocationBase != (duint)mbi.AllocationBase) + { + // Set the new allocation base page + allocationBase = (duint)mbi.AllocationBase; + + MEMPAGE curPage; + memset(&curPage, 0, sizeof(MEMPAGE)); + memcpy(&curPage.mbi, &mbi, sizeof(mbi)); + + ModNameFromAddr(pageStart, curPage.info, true); + pageVector.push_back(curPage); + } + else + { + // Otherwise append the page to the last created entry + pageVector.back().mbi.RegionSize += mbi.RegionSize; + } + } + + // Calculate the next page start + duint newAddress = (duint)mbi.BaseAddress + mbi.RegionSize; + + if(newAddress <= pageStart) + break; + + pageStart = newAddress; + } + while(numBytes); + } + + // Process file sections + int pagecount = (int)pageVector.size(); + char curMod[MAX_MODULE_SIZE] = ""; + for(int i = pagecount - 1; i > -1; i--) + { + auto & currentPage = pageVector.at(i); + if(!currentPage.info[0] || (scmp(curMod, currentPage.info) && !bListAllPages)) //there is a module + continue; //skip non-modules + strcpy(curMod, pageVector.at(i).info); + duint base = ModBaseFromName(currentPage.info); + if(!base) + continue; + std::vector sections; + if(!ModSectionsFromAddr(base, §ions)) + continue; + int SectionNumber = (int)sections.size(); + if(!SectionNumber) //no sections = skip + continue; + if(!bListAllPages) //normal view + { + MEMPAGE newPage; + //remove the current module page (page = size of module at this point) and insert the module sections + pageVector.erase(pageVector.begin() + i); //remove the SizeOfImage page + for(int j = SectionNumber - 1; j > -1; j--) + { + const auto & currentSection = sections.at(j); + memset(&newPage, 0, sizeof(MEMPAGE)); + VirtualQueryEx(fdProcessInfo->hProcess, (LPCVOID)currentSection.addr, &newPage.mbi, sizeof(MEMORY_BASIC_INFORMATION)); + duint SectionSize = currentSection.size; + if(SectionSize % PAGE_SIZE) //unaligned page size + SectionSize += PAGE_SIZE - (SectionSize % PAGE_SIZE); //fix this + if(SectionSize) + newPage.mbi.RegionSize = SectionSize; + sprintf_s(newPage.info, " \"%s\"", currentSection.name); + pageVector.insert(pageVector.begin() + i, newPage); + } + //insert the module itself (the module header) + memset(&newPage, 0, sizeof(MEMPAGE)); + VirtualQueryEx(fdProcessInfo->hProcess, (LPCVOID)base, &newPage.mbi, sizeof(MEMORY_BASIC_INFORMATION)); + strcpy_s(newPage.info, curMod); + pageVector.insert(pageVector.begin() + i, newPage); + } + else //list all pages + { + duint start = (duint)currentPage.mbi.BaseAddress; + duint end = start + currentPage.mbi.RegionSize; + for(int j = 0, k = 0; j < SectionNumber; j++) + { + const auto & currentSection = sections.at(j); + duint secStart = currentSection.addr; + duint SectionSize = currentSection.size; + if(SectionSize % PAGE_SIZE) //unaligned page size + SectionSize += PAGE_SIZE - (SectionSize % PAGE_SIZE); //fix this + duint secEnd = secStart + SectionSize; + if(secStart >= start && secEnd <= end) //section is inside the memory page + { + if(k) + k += sprintf_s(currentPage.info + k, MAX_MODULE_SIZE - k, ","); + k += sprintf_s(currentPage.info + k, MAX_MODULE_SIZE - k, " \"%s\"", currentSection.name); + } + else if(start >= secStart && end <= secEnd) //memory page is inside the section + { + if(k) + k += sprintf_s(currentPage.info + k, MAX_MODULE_SIZE - k, ","); + k += sprintf_s(currentPage.info + k, MAX_MODULE_SIZE - k, " \"%s\"", currentSection.name); + } + } + } + } + + // Get a list of threads for information about Kernel/PEB/TEB/Stack ranges + THREADLIST threadList; + ThreadGetList(&threadList); + + for (auto & page : pageVector) + { + const duint pageBase = (duint)page.mbi.BaseAddress; + const duint pageSize = (duint)page.mbi.RegionSize; + + // Check for windows specific data + if (pageBase == 0x7FFE0000) + { + strcpy_s(page.info, "KUSER_SHARED_DATA"); + continue; + } + + // Check in threads + for (int i = 0; i < threadList.count; i++) + { + duint tebBase = threadList.list[i].BasicInfo.ThreadLocalBase; + DWORD threadId = threadList.list[i].BasicInfo.ThreadId; + + // Mark TEB + if (pageBase == tebBase) + { + sprintf_s(page.info, "Thread %X TEB", threadId); + break; + } + + // Read the TEB to get stack information + TEB teb; + if (!ThreadGetTeb(tebBase, &teb)) + continue; + + // The stack will be a specific range only, not always the base address + duint stackAddr = (duint)teb.Tib.StackLimit; + + if (stackAddr >= pageBase && stackAddr < (pageBase + pageSize)) + sprintf_s(page.info, "Thread %X Stack", threadId); + } + } + + // Only free thread data if it was allocated + if (threadList.list) + BridgeFree(threadList.list); + + // Convert the vector to a map + EXCLUSIVE_ACQUIRE(LockMemoryPages); + memoryPages.clear(); + + for(auto & page : pageVector) + { + duint start = (duint)page.mbi.BaseAddress; + duint size = (duint)page.mbi.RegionSize; + memoryPages.insert(std::make_pair(std::make_pair(start, start + size - 1), page)); + } +} + +duint MemFindBaseAddr(duint Address, duint* Size, bool Refresh) +{ + // Update the memory map if needed + if(Refresh) + MemUpdateMap(); + + SHARED_ACQUIRE(LockMemoryPages); + + // Search for the memory page address + auto found = memoryPages.find(std::make_pair(Address, Address)); + + if(found == memoryPages.end()) + return 0; + + // Return the allocation region size when requested + if(Size) + *Size = found->second.mbi.RegionSize; + + return found->first.first; +} + +bool MemRead(duint BaseAddress, void* Buffer, duint Size, duint* NumberOfBytesRead) +{ + if(!MemIsCanonicalAddress(BaseAddress)) + return false; + + // Buffer must be supplied and size must be greater than 0 + if(!Buffer || Size <= 0) + return false; + + // If the 'bytes read' parameter is null, use a temp + SIZE_T bytesReadTemp = 0; + + if(!NumberOfBytesRead) + NumberOfBytesRead = &bytesReadTemp; + + // Normal single-call read + bool ret = MemoryReadSafe(fdProcessInfo->hProcess, (LPVOID)BaseAddress, Buffer, Size, NumberOfBytesRead); + + if(ret && *NumberOfBytesRead == Size) + return true; + + // Read page-by-page (Skip if only 1 page exists) + // If (SIZE > PAGE_SIZE) or (ADDRESS exceeds boundary), multiple reads will be needed + SIZE_T pageCount = BYTES_TO_PAGES(Size); + + if(pageCount > 1) + { + // Determine the number of bytes between ADDRESS and the next page + duint offset = 0; + duint readBase = BaseAddress; + duint readSize = ROUND_TO_PAGES(readBase) - readBase; + + // Reset the bytes read count + *NumberOfBytesRead = 0; + + for(SIZE_T i = 0; i < pageCount; i++) + { + SIZE_T bytesRead = 0; + + if(MemoryReadSafe(fdProcessInfo->hProcess, (PVOID)readBase, ((PBYTE)Buffer + offset), readSize, &bytesRead)) + *NumberOfBytesRead += bytesRead; + + offset += readSize; + readBase += readSize; + + Size -= readSize; + readSize = min(PAGE_SIZE, Size); + } + } + + SetLastError(ERROR_PARTIAL_COPY); + return (*NumberOfBytesRead > 0); +} + +bool MemWrite(duint BaseAddress, const void* Buffer, duint Size, duint* NumberOfBytesWritten) +{ + if(!MemIsCanonicalAddress(BaseAddress)) + return false; + + // Buffer must be supplied and size must be greater than 0 + if(!Buffer || Size <= 0) + return false; + + // If the 'bytes written' parameter is null, use a temp + SIZE_T bytesWrittenTemp = 0; + + if(!NumberOfBytesWritten) + NumberOfBytesWritten = &bytesWrittenTemp; + + // Try a regular WriteProcessMemory call + bool ret = MemoryWriteSafe(fdProcessInfo->hProcess, (LPVOID)BaseAddress, Buffer, Size, NumberOfBytesWritten); + + if(ret && *NumberOfBytesWritten == Size) + return true; + + // Write page-by-page (Skip if only 1 page exists) + // See: MemRead + SIZE_T pageCount = BYTES_TO_PAGES(Size); + + if(pageCount > 1) + { + // Determine the number of bytes between ADDRESS and the next page + duint offset = 0; + duint writeBase = BaseAddress; + duint writeSize = ROUND_TO_PAGES(writeBase) - writeBase; + + // Reset the bytes read count + *NumberOfBytesWritten = 0; + + for(SIZE_T i = 0; i < pageCount; i++) + { + SIZE_T bytesWritten = 0; + + if(MemoryWriteSafe(fdProcessInfo->hProcess, (PVOID)writeBase, ((PBYTE)Buffer + offset), writeSize, &bytesWritten)) + *NumberOfBytesWritten += bytesWritten; + + offset += writeSize; + writeBase += writeSize; + + Size -= writeSize; + writeSize = min(PAGE_SIZE, Size); + } + } + + SetLastError(ERROR_PARTIAL_COPY); + return (*NumberOfBytesWritten > 0); +} + +bool MemPatch(duint BaseAddress, const void* Buffer, duint Size, duint* NumberOfBytesWritten) +{ + // Buffer and size must be valid + if(!Buffer || Size <= 0) + return false; + + // Allocate the memory + Memory oldData(Size, "mempatch:oldData"); + + if(!MemRead(BaseAddress, oldData(), Size)) + { + // If no memory can be read, no memory can be written. Fail out + // of this function. + return false; + } + + // Are we able to write on this page? + if (MemWrite(BaseAddress, Buffer, Size, NumberOfBytesWritten)) + { + for (duint i = 0; i < Size; i++) + PatchSet(BaseAddress + i, oldData()[i], ((const unsigned char*)Buffer)[i]); + + // Done + return true; + } + + // Unable to write memory + return false; +} + +bool MemIsValidReadPtr(duint Address) +{ + unsigned char a = 0; + return MemRead(Address, &a, sizeof(unsigned char)); +} + +bool MemIsCanonicalAddress(duint Address) +{ +#ifndef _WIN64 + // 32-bit mode only supports 4GB max, so limits are + // not an issue + return true; +#else + // The most-significant 16 bits must be all 1 or all 0. + // (64 - 16) = 48bit linear address range. + // + // 0xFFFF800000000000 = Significant 16 bits set + // 0x0000800000000000 = 48th bit set + return (((Address & 0xFFFF800000000000) + 0x800000000000) & ~0x800000000000) == 0; +#endif // ndef _WIN64 +} + +bool MemIsCodePage(duint Address, bool Refresh) +{ + MEMPAGE pageInfo; + if(!MemGetPageInfo(Address, &pageInfo, Refresh)) + return false; + + return (pageInfo.mbi.Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) != 0; +} + +duint MemAllocRemote(duint Address, duint Size, DWORD Type, DWORD Protect) +{ + return (duint)VirtualAllocEx(fdProcessInfo->hProcess, (LPVOID)Address, Size, Type, Protect); +} + +bool MemFreeRemote(duint Address) +{ + return VirtualFreeEx(fdProcessInfo->hProcess, (LPVOID)Address, 0, MEM_RELEASE) == TRUE; +} + +duint MemGetPageAligned(duint Address) +{ + return PAGE_ALIGN(Address); +} + +bool MemGetPageInfo(duint Address, MEMPAGE* PageInfo, bool Refresh) +{ + // Update the memory map if needed + if(Refresh) + MemUpdateMap(); + + SHARED_ACQUIRE(LockMemoryPages); + + // Search for the memory page address + auto found = memoryPages.find(std::make_pair(Address, Address)); + + if(found == memoryPages.end()) + return false; + + // Return the data when possible + if(PageInfo) + *PageInfo = found->second; + + return true; +} + +bool MemSetPageRights(duint Address, const char* Rights) +{ + // Align address to page base + Address = MemGetPageAligned(Address); + + // String -> bit mask + DWORD protect; + if(!MemPageRightsFromString(&protect, Rights)) + return false; + + DWORD oldProtect; + return VirtualProtectEx(fdProcessInfo->hProcess, (void*)Address, PAGE_SIZE, protect, &oldProtect) == TRUE; +} + +bool MemGetPageRights(duint Address, char* Rights) +{ + // Align address to page base + Address = MemGetPageAligned(Address); + + MEMORY_BASIC_INFORMATION mbi; + memset(&mbi, 0, sizeof(MEMORY_BASIC_INFORMATION)); + + if(!VirtualQueryEx(fdProcessInfo->hProcess, (void*)Address, &mbi, sizeof(mbi))) + return false; + + return MemPageRightsToString(mbi.Protect, Rights); +} + +bool MemPageRightsToString(DWORD Protect, char* Rights) +{ + switch(Protect & 0xFF) + { + case PAGE_NOACCESS: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "----"); + break; + case PAGE_READONLY: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "-R--"); + break; + case PAGE_READWRITE: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "-RW-"); + break; + case PAGE_WRITECOPY: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "-RWC"); + break; + case PAGE_EXECUTE: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "E---"); + break; + case PAGE_EXECUTE_READ: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "ER--"); + break; + case PAGE_EXECUTE_READWRITE: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "ERW-"); + break; + case PAGE_EXECUTE_WRITECOPY: + strcpy_s(Rights, RIGHTS_STRING_SIZE, "ERWC"); + break; + } + + strcat_s(Rights, RIGHTS_STRING_SIZE, ((Protect & PAGE_GUARD) == PAGE_GUARD) ? "G" : "-"); + // Rights[5] = ((Protect & PAGE_NOCACHE) == PAGE_NOCACHE) ? '' : '-'; + // Rights[6] = ((Protect & PAGE_WRITECOMBINE) == PAGE_GUARD) ? '' : '-'; + + return true; +} + +bool MemPageRightsFromString(DWORD* Protect, const char* Rights) +{ + ASSERT_TRUE(strlen(Rights) >= 2); + *Protect = 0; + + // Check for the PAGE_GUARD flag + if(Rights[0] == 'G' || Rights[0] == 'g') + { + *Protect |= PAGE_GUARD; + Rights++; + } + + if(_strcmpi(Rights, "Execute") == 0) + *Protect |= PAGE_EXECUTE; + else if(_strcmpi(Rights, "ExecuteRead") == 0) + *Protect |= PAGE_EXECUTE_READ; + else if(_strcmpi(Rights, "ExecuteReadWrite") == 0) + *Protect |= PAGE_EXECUTE_READWRITE; + else if(_strcmpi(Rights, "ExecuteWriteCopy") == 0) + *Protect |= PAGE_EXECUTE_WRITECOPY; + else if(_strcmpi(Rights, "NoAccess") == 0) + *Protect |= PAGE_NOACCESS; + else if(_strcmpi(Rights, "ReadOnly") == 0) + *Protect |= PAGE_READONLY; + else if(_strcmpi(Rights, "ReadWrite") == 0) + *Protect |= PAGE_READWRITE; + else if(_strcmpi(Rights, "WriteCopy") == 0) + *Protect |= PAGE_WRITECOPY; + + return (*Protect != 0); +} + +bool MemFindInPage(SimplePage page, duint startoffset, const std::vector & pattern, std::vector & results, duint maxresults) +{ + if(startoffset >= page.size || results.size() >= maxresults) + return false; + + //TODO: memory read limit + Memory data(page.size); + if(!MemRead(page.address, data(), data.size())) + return false; + + duint maxFind = maxresults; + duint foundCount = results.size(); + duint i = 0; + duint findSize = data.size() - startoffset; + while(foundCount < maxFind) + { + duint foundoffset = patternfind(data() + startoffset + i, findSize - i, pattern); + if(foundoffset == -1) + break; + i += foundoffset + 1; + duint result = page.address + startoffset + i - 1; + results.push_back(result); + foundCount++; + } + return true; +} + +bool MemFindInMap(const std::vector & pages, const std::vector & pattern, std::vector & results, duint maxresults, bool progress) +{ + duint count = 0; + duint total = pages.size(); + for(const auto page : pages) + { + if(!MemFindInPage(page, 0, pattern, results, maxresults)) + return false; + if(progress) + GuiReferenceSetProgress(int(floor((float(count) / float(total)) * 100.0f))); + if(results.size() >= maxresults) + break; + count++; + } + if(progress) + { + GuiReferenceSetProgress(100); + GuiReferenceReloadData(); + } + return true; } \ No newline at end of file diff --git a/src/dbg/memory.h b/src/dbg/memory.h index f620f2d0..6ba9059d 100644 --- a/src/dbg/memory.h +++ b/src/dbg/memory.h @@ -1,39 +1,39 @@ -#pragma once - -#include "_global.h" -#include "addrinfo.h" -#include "patternfind.h" - -extern std::map memoryPages; -extern bool bListAllPages; - -struct SimplePage -{ - duint address; - duint size; - - SimplePage(duint address, duint size) - { - this->address = address; - this->size = size; - } -}; - -void MemUpdateMap(); -duint MemFindBaseAddr(duint Address, duint* Size, bool Refresh = false); -bool MemRead(duint BaseAddress, void* Buffer, duint Size, duint* NumberOfBytesRead = nullptr); -bool MemWrite(duint BaseAddress, const void* Buffer, duint Size, duint* NumberOfBytesWritten = nullptr); -bool MemPatch(duint BaseAddress, const void* Buffer, duint Size, duint* NumberOfBytesWritten = nullptr); -bool MemIsValidReadPtr(duint Address); -bool MemIsCanonicalAddress(duint Address); -bool MemIsCodePage(duint Address, bool Refresh); -duint MemAllocRemote(duint Address, duint Size, DWORD Type = MEM_RESERVE | MEM_COMMIT, DWORD Protect = PAGE_EXECUTE_READWRITE); -bool MemFreeRemote(duint Address); -duint MemGetPageAligned(duint Address); -bool MemGetPageInfo(duint Address, MEMPAGE* PageInfo, bool Refresh = false); -bool MemSetPageRights(duint Address, const char* Rights); -bool MemGetPageRights(duint Address, char* Rights); -bool MemPageRightsToString(DWORD Protect, char* Rights); -bool MemPageRightsFromString(DWORD* Protect, const char* Rights); -bool MemFindInPage(SimplePage page, duint startoffset, const std::vector & pattern, std::vector & results, duint maxresults); +#pragma once + +#include "_global.h" +#include "addrinfo.h" +#include "patternfind.h" + +extern std::map memoryPages; +extern bool bListAllPages; + +struct SimplePage +{ + duint address; + duint size; + + SimplePage(duint address, duint size) + { + this->address = address; + this->size = size; + } +}; + +void MemUpdateMap(); +duint MemFindBaseAddr(duint Address, duint* Size, bool Refresh = false); +bool MemRead(duint BaseAddress, void* Buffer, duint Size, duint* NumberOfBytesRead = nullptr); +bool MemWrite(duint BaseAddress, const void* Buffer, duint Size, duint* NumberOfBytesWritten = nullptr); +bool MemPatch(duint BaseAddress, const void* Buffer, duint Size, duint* NumberOfBytesWritten = nullptr); +bool MemIsValidReadPtr(duint Address); +bool MemIsCanonicalAddress(duint Address); +bool MemIsCodePage(duint Address, bool Refresh); +duint MemAllocRemote(duint Address, duint Size, DWORD Type = MEM_RESERVE | MEM_COMMIT, DWORD Protect = PAGE_EXECUTE_READWRITE); +bool MemFreeRemote(duint Address); +duint MemGetPageAligned(duint Address); +bool MemGetPageInfo(duint Address, MEMPAGE* PageInfo, bool Refresh = false); +bool MemSetPageRights(duint Address, const char* Rights); +bool MemGetPageRights(duint Address, char* Rights); +bool MemPageRightsToString(DWORD Protect, char* Rights); +bool MemPageRightsFromString(DWORD* Protect, const char* Rights); +bool MemFindInPage(SimplePage page, duint startoffset, const std::vector & pattern, std::vector & results, duint maxresults); bool MemFindInMap(const std::vector & pages, const std::vector & pattern, std::vector & results, duint maxresults, bool progress = true); \ No newline at end of file diff --git a/src/dbg/module.cpp b/src/dbg/module.cpp index c2111342..dc709f49 100644 --- a/src/dbg/module.cpp +++ b/src/dbg/module.cpp @@ -1,331 +1,331 @@ -#include "module.h" -#include "debugger.h" -#include "threading.h" -#include "symbolinfo.h" -#include "murmurhash.h" -#include "memory.h" -#include "label.h" - -std::map modinfo; - -void GetModuleInfo(MODINFO & Info, ULONG_PTR FileMapVA) -{ - // Get the entry point - duint moduleOEP = GetPE32DataFromMappedFile(FileMapVA, 0, UE_OEP); - - // Fix a problem where the OEP is set to zero (non-existent). - // OEP can't start at the PE header/offset 0 -- except if module is an EXE. - Info.entry = moduleOEP + Info.base; - - if(!moduleOEP) - { - WORD characteristics = (WORD)GetPE32DataFromMappedFile(FileMapVA, 0, UE_CHARACTERISTICS); - - // If this wasn't an exe, invalidate the entry point - if((characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL) - Info.entry = 0; - } - - // Enumerate all PE sections - Info.sections.clear(); - int sectionCount = (int)GetPE32DataFromMappedFile(FileMapVA, 0, UE_SECTIONNUMBER); - - for(int i = 0; i < sectionCount; i++) - { - MODSECTIONINFO curSection; - memset(&curSection, 0, sizeof(MODSECTIONINFO)); - - curSection.addr = GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALOFFSET) + Info.base; - curSection.size = GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALSIZE); - const char* sectionName = (const char*)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONNAME); - - // Escape section name when needed - strcpy_s(curSection.name, StringUtils::Escape(sectionName).c_str()); - - // Add entry to the vector - Info.sections.push_back(curSection); - } -} - -bool ModLoad(duint Base, duint Size, const char* FullPath) -{ - // Handle a new module being loaded - if(!Base || !Size || !FullPath) - return false; - - // Copy the module path in the struct - MODINFO info; - strcpy_s(info.path, FullPath); - - // Break the module path into a directory and file name - char file[MAX_MODULE_SIZE]; - { - char dir[MAX_PATH]; - memset(dir, 0, sizeof(dir)); - - // Dir <- lowercase(file path) - strcpy_s(dir, FullPath); - _strlwr(dir); - - // Find the last instance of a path delimiter (slash) - char* fileStart = strrchr(dir, '\\'); - - if(fileStart) - { - strcpy_s(file, fileStart + 1); - fileStart[0] = '\0'; - } - else - strcpy_s(file, FullPath); - } - - // Calculate module hash from full file name - info.hash = ModHashFromName(file); - - // Copy the extension into the module struct - { - char* extensionPos = strrchr(file, '.'); - - if(extensionPos) - { - strcpy_s(info.extension, extensionPos); - extensionPos[0] = '\0'; - } - } - - // Copy information to struct - strcpy_s(info.name, file); - info.base = Base; - info.size = Size; - - // Load module data - bool virtualModule = strstr(FullPath, "virtual:\\") == FullPath; - - if(!virtualModule) - { - HANDLE fileHandle; - DWORD loadedSize; - HANDLE fileMap; - ULONG_PTR fileMapVA; - WString wszFullPath = StringUtils::Utf8ToUtf16(FullPath); - - // Load the physical module from disk - if(StaticFileLoadW(wszFullPath.c_str(), UE_ACCESS_READ, false, &fileHandle, &loadedSize, &fileMap, &fileMapVA)) - { - GetModuleInfo(info, fileMapVA); - StaticFileUnloadW(wszFullPath.c_str(), false, fileHandle, loadedSize, fileMap, fileMapVA); - } - } - else - { - // This was a virtual module -> read it remotely - Memory data(Size); - MemRead(Base, data(), data.size()); - - // Get information from the local buffer - GetModuleInfo(info, (ULONG_PTR)data()); - } - - // Add module to list - EXCLUSIVE_ACQUIRE(LockModules); - modinfo.insert(std::make_pair(Range(Base, Base + Size - 1), info)); - EXCLUSIVE_RELEASE(); - - // Put labels for virtual module exports - if(virtualModule) - { - if(info.entry >= Base && info.entry < Base + Size) - LabelSet(info.entry, "EntryPoint", false); - - apienumexports(Base, [](duint base, const char* mod, const char* name, duint addr) - { - LabelSet(addr, name, false); - }); - } - - SymUpdateModuleList(); - return true; -} - -bool ModUnload(duint Base) -{ - EXCLUSIVE_ACQUIRE(LockModules); - - // Find the iterator index - const auto found = modinfo.find(Range(Base, Base)); - - if(found == modinfo.end()) - return false; - - // Remove it from the list - modinfo.erase(found); - EXCLUSIVE_RELEASE(); - - // Update symbols - SymUpdateModuleList(); - return true; -} - -void ModClear() -{ - // Clean up all the modules - EXCLUSIVE_ACQUIRE(LockModules); - modinfo.clear(); - EXCLUSIVE_RELEASE(); - - // Tell the symbol updater - GuiSymbolUpdateModuleList(0, nullptr); -} - -MODINFO* ModInfoFromAddr(duint Address) -{ - // - // NOTE: THIS DOES _NOT_ USE LOCKS - // - auto found = modinfo.find(Range(Address, Address)); - - // Was the module found with this address? - if(found == modinfo.end()) - return nullptr; - - return &found->second; -} - -bool ModNameFromAddr(duint Address, char* Name, bool Extension) -{ - ASSERT_NONNULL(Name); - SHARED_ACQUIRE(LockModules); - - // Get a pointer to module information - auto module = ModInfoFromAddr(Address); - - if(!module) - return false; - - // Copy initial module name - strcpy_s(Name, MAX_MODULE_SIZE, module->name); - - if(Extension) - strcat_s(Name, MAX_MODULE_SIZE, module->extension); - - return true; -} - -duint ModBaseFromAddr(duint Address) -{ - SHARED_ACQUIRE(LockModules); - - auto module = ModInfoFromAddr(Address); - - if(!module) - return 0; - - return module->base; -} - -duint ModHashFromAddr(duint Address) -{ - // Returns a unique hash from a virtual address - SHARED_ACQUIRE(LockModules); - - auto module = ModInfoFromAddr(Address); - - if(!module) - return Address; - - return module->hash + (Address - module->base); -} - -duint ModHashFromName(const char* Module) -{ - // return MODINFO.hash (based on the name) - ASSERT_NONNULL(Module); - ASSERT_FALSE(Module[0] == '\0'); - - return murmurhash(Module, (int)strlen(Module)); -} - -duint ModBaseFromName(const char* Module) -{ - ASSERT_NONNULL(Module); - ASSERT_TRUE(strlen(Module) < MAX_MODULE_SIZE); - SHARED_ACQUIRE(LockModules); - - for(const auto & i : modinfo) - { - const auto & currentModule = i.second; - char currentModuleName[MAX_MODULE_SIZE]; - strcpy_s(currentModuleName, currentModule.name); - strcat_s(currentModuleName, currentModule.extension); - - // Test with and without extension - if(!_stricmp(currentModuleName, Module) || !_stricmp(currentModule.name, Module)) - return currentModule.base; - } - - return 0; -} - -duint ModSizeFromAddr(duint Address) -{ - SHARED_ACQUIRE(LockModules); - - auto module = ModInfoFromAddr(Address); - - if(!module) - return 0; - - return module->size; -} - -bool ModSectionsFromAddr(duint Address, std::vector* Sections) -{ - SHARED_ACQUIRE(LockModules); - - auto module = ModInfoFromAddr(Address); - - if(!module) - return false; - - // Copy vector <-> vector - *Sections = module->sections; - return true; -} - -duint ModEntryFromAddr(duint Address) -{ - SHARED_ACQUIRE(LockModules); - - auto module = ModInfoFromAddr(Address); - - if(!module) - return 0; - - return module->entry; -} - -int ModPathFromAddr(duint Address, char* Path, int Size) -{ - SHARED_ACQUIRE(LockModules); - - auto module = ModInfoFromAddr(Address); - - if(!module) - return 0; - - strcpy_s(Path, Size, module->path); - return (int)strlen(Path); -} - -int ModPathFromName(const char* Module, char* Path, int Size) -{ - return ModPathFromAddr(ModBaseFromName(Module), Path, Size); -} - -void ModGetList(std::vector & list) -{ - SHARED_ACQUIRE(LockModules); - list.clear(); - for(const auto & mod : modinfo) - list.push_back(mod.second); +#include "module.h" +#include "debugger.h" +#include "threading.h" +#include "symbolinfo.h" +#include "murmurhash.h" +#include "memory.h" +#include "label.h" + +std::map modinfo; + +void GetModuleInfo(MODINFO & Info, ULONG_PTR FileMapVA) +{ + // Get the entry point + duint moduleOEP = GetPE32DataFromMappedFile(FileMapVA, 0, UE_OEP); + + // Fix a problem where the OEP is set to zero (non-existent). + // OEP can't start at the PE header/offset 0 -- except if module is an EXE. + Info.entry = moduleOEP + Info.base; + + if(!moduleOEP) + { + WORD characteristics = (WORD)GetPE32DataFromMappedFile(FileMapVA, 0, UE_CHARACTERISTICS); + + // If this wasn't an exe, invalidate the entry point + if((characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL) + Info.entry = 0; + } + + // Enumerate all PE sections + Info.sections.clear(); + int sectionCount = (int)GetPE32DataFromMappedFile(FileMapVA, 0, UE_SECTIONNUMBER); + + for(int i = 0; i < sectionCount; i++) + { + MODSECTIONINFO curSection; + memset(&curSection, 0, sizeof(MODSECTIONINFO)); + + curSection.addr = GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALOFFSET) + Info.base; + curSection.size = GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALSIZE); + const char* sectionName = (const char*)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONNAME); + + // Escape section name when needed + strcpy_s(curSection.name, StringUtils::Escape(sectionName).c_str()); + + // Add entry to the vector + Info.sections.push_back(curSection); + } +} + +bool ModLoad(duint Base, duint Size, const char* FullPath) +{ + // Handle a new module being loaded + if(!Base || !Size || !FullPath) + return false; + + // Copy the module path in the struct + MODINFO info; + strcpy_s(info.path, FullPath); + + // Break the module path into a directory and file name + char file[MAX_MODULE_SIZE]; + { + char dir[MAX_PATH]; + memset(dir, 0, sizeof(dir)); + + // Dir <- lowercase(file path) + strcpy_s(dir, FullPath); + _strlwr(dir); + + // Find the last instance of a path delimiter (slash) + char* fileStart = strrchr(dir, '\\'); + + if(fileStart) + { + strcpy_s(file, fileStart + 1); + fileStart[0] = '\0'; + } + else + strcpy_s(file, FullPath); + } + + // Calculate module hash from full file name + info.hash = ModHashFromName(file); + + // Copy the extension into the module struct + { + char* extensionPos = strrchr(file, '.'); + + if(extensionPos) + { + strcpy_s(info.extension, extensionPos); + extensionPos[0] = '\0'; + } + } + + // Copy information to struct + strcpy_s(info.name, file); + info.base = Base; + info.size = Size; + + // Load module data + bool virtualModule = strstr(FullPath, "virtual:\\") == FullPath; + + if(!virtualModule) + { + HANDLE fileHandle; + DWORD loadedSize; + HANDLE fileMap; + ULONG_PTR fileMapVA; + WString wszFullPath = StringUtils::Utf8ToUtf16(FullPath); + + // Load the physical module from disk + if(StaticFileLoadW(wszFullPath.c_str(), UE_ACCESS_READ, false, &fileHandle, &loadedSize, &fileMap, &fileMapVA)) + { + GetModuleInfo(info, fileMapVA); + StaticFileUnloadW(wszFullPath.c_str(), false, fileHandle, loadedSize, fileMap, fileMapVA); + } + } + else + { + // This was a virtual module -> read it remotely + Memory data(Size); + MemRead(Base, data(), data.size()); + + // Get information from the local buffer + GetModuleInfo(info, (ULONG_PTR)data()); + } + + // Add module to list + EXCLUSIVE_ACQUIRE(LockModules); + modinfo.insert(std::make_pair(Range(Base, Base + Size - 1), info)); + EXCLUSIVE_RELEASE(); + + // Put labels for virtual module exports + if(virtualModule) + { + if(info.entry >= Base && info.entry < Base + Size) + LabelSet(info.entry, "EntryPoint", false); + + apienumexports(Base, [](duint base, const char* mod, const char* name, duint addr) + { + LabelSet(addr, name, false); + }); + } + + SymUpdateModuleList(); + return true; +} + +bool ModUnload(duint Base) +{ + EXCLUSIVE_ACQUIRE(LockModules); + + // Find the iterator index + const auto found = modinfo.find(Range(Base, Base)); + + if(found == modinfo.end()) + return false; + + // Remove it from the list + modinfo.erase(found); + EXCLUSIVE_RELEASE(); + + // Update symbols + SymUpdateModuleList(); + return true; +} + +void ModClear() +{ + // Clean up all the modules + EXCLUSIVE_ACQUIRE(LockModules); + modinfo.clear(); + EXCLUSIVE_RELEASE(); + + // Tell the symbol updater + GuiSymbolUpdateModuleList(0, nullptr); +} + +MODINFO* ModInfoFromAddr(duint Address) +{ + // + // NOTE: THIS DOES _NOT_ USE LOCKS + // + auto found = modinfo.find(Range(Address, Address)); + + // Was the module found with this address? + if(found == modinfo.end()) + return nullptr; + + return &found->second; +} + +bool ModNameFromAddr(duint Address, char* Name, bool Extension) +{ + ASSERT_NONNULL(Name); + SHARED_ACQUIRE(LockModules); + + // Get a pointer to module information + auto module = ModInfoFromAddr(Address); + + if(!module) + return false; + + // Copy initial module name + strcpy_s(Name, MAX_MODULE_SIZE, module->name); + + if(Extension) + strcat_s(Name, MAX_MODULE_SIZE, module->extension); + + return true; +} + +duint ModBaseFromAddr(duint Address) +{ + SHARED_ACQUIRE(LockModules); + + auto module = ModInfoFromAddr(Address); + + if(!module) + return 0; + + return module->base; +} + +duint ModHashFromAddr(duint Address) +{ + // Returns a unique hash from a virtual address + SHARED_ACQUIRE(LockModules); + + auto module = ModInfoFromAddr(Address); + + if(!module) + return Address; + + return module->hash + (Address - module->base); +} + +duint ModHashFromName(const char* Module) +{ + // return MODINFO.hash (based on the name) + ASSERT_NONNULL(Module); + ASSERT_FALSE(Module[0] == '\0'); + + return murmurhash(Module, (int)strlen(Module)); +} + +duint ModBaseFromName(const char* Module) +{ + ASSERT_NONNULL(Module); + ASSERT_TRUE(strlen(Module) < MAX_MODULE_SIZE); + SHARED_ACQUIRE(LockModules); + + for(const auto & i : modinfo) + { + const auto & currentModule = i.second; + char currentModuleName[MAX_MODULE_SIZE]; + strcpy_s(currentModuleName, currentModule.name); + strcat_s(currentModuleName, currentModule.extension); + + // Test with and without extension + if(!_stricmp(currentModuleName, Module) || !_stricmp(currentModule.name, Module)) + return currentModule.base; + } + + return 0; +} + +duint ModSizeFromAddr(duint Address) +{ + SHARED_ACQUIRE(LockModules); + + auto module = ModInfoFromAddr(Address); + + if(!module) + return 0; + + return module->size; +} + +bool ModSectionsFromAddr(duint Address, std::vector* Sections) +{ + SHARED_ACQUIRE(LockModules); + + auto module = ModInfoFromAddr(Address); + + if(!module) + return false; + + // Copy vector <-> vector + *Sections = module->sections; + return true; +} + +duint ModEntryFromAddr(duint Address) +{ + SHARED_ACQUIRE(LockModules); + + auto module = ModInfoFromAddr(Address); + + if(!module) + return 0; + + return module->entry; +} + +int ModPathFromAddr(duint Address, char* Path, int Size) +{ + SHARED_ACQUIRE(LockModules); + + auto module = ModInfoFromAddr(Address); + + if(!module) + return 0; + + strcpy_s(Path, Size, module->path); + return (int)strlen(Path); +} + +int ModPathFromName(const char* Module, char* Path, int Size) +{ + return ModPathFromAddr(ModBaseFromName(Module), Path, Size); +} + +void ModGetList(std::vector & list) +{ + SHARED_ACQUIRE(LockModules); + list.clear(); + for(const auto & mod : modinfo) + list.push_back(mod.second); } \ No newline at end of file diff --git a/src/dbg/module.h b/src/dbg/module.h index 02d78220..6e5689f9 100644 --- a/src/dbg/module.h +++ b/src/dbg/module.h @@ -1,40 +1,40 @@ -#pragma once - -#include "_global.h" - -struct MODSECTIONINFO -{ - duint addr; // Virtual address - duint size; // Virtual size - char name[MAX_SECTION_SIZE * 5]; // Escaped section name -}; - -struct MODINFO -{ - duint base; // Module base - duint size; // Module size - duint hash; // Full module name hash - duint entry; // Entry point - - char name[MAX_MODULE_SIZE]; // Module name (without extension) - char extension[MAX_MODULE_SIZE]; // File extension - char path[MAX_PATH]; // File path (in UTF8) - - std::vector sections; -}; - -bool ModLoad(duint Base, duint Size, const char* FullPath); -bool ModUnload(duint Base); -void ModClear(); -MODINFO* ModInfoFromAddr(duint Address); -bool ModNameFromAddr(duint Address, char* Name, bool Extension); -duint ModBaseFromAddr(duint Address); -duint ModHashFromAddr(duint Address); -duint ModHashFromName(const char* Module); -duint ModBaseFromName(const char* Module); -duint ModSizeFromAddr(duint Address); -bool ModSectionsFromAddr(duint Address, std::vector* Sections); -duint ModEntryFromAddr(duint Address); -int ModPathFromAddr(duint Address, char* Path, int Size); -int ModPathFromName(const char* Module, char* Path, int Size); +#pragma once + +#include "_global.h" + +struct MODSECTIONINFO +{ + duint addr; // Virtual address + duint size; // Virtual size + char name[MAX_SECTION_SIZE * 5]; // Escaped section name +}; + +struct MODINFO +{ + duint base; // Module base + duint size; // Module size + duint hash; // Full module name hash + duint entry; // Entry point + + char name[MAX_MODULE_SIZE]; // Module name (without extension) + char extension[MAX_MODULE_SIZE]; // File extension + char path[MAX_PATH]; // File path (in UTF8) + + std::vector sections; +}; + +bool ModLoad(duint Base, duint Size, const char* FullPath); +bool ModUnload(duint Base); +void ModClear(); +MODINFO* ModInfoFromAddr(duint Address); +bool ModNameFromAddr(duint Address, char* Name, bool Extension); +duint ModBaseFromAddr(duint Address); +duint ModHashFromAddr(duint Address); +duint ModHashFromName(const char* Module); +duint ModBaseFromName(const char* Module); +duint ModSizeFromAddr(duint Address); +bool ModSectionsFromAddr(duint Address, std::vector* Sections); +duint ModEntryFromAddr(duint Address); +int ModPathFromAddr(duint Address, char* Path, int Size); +int ModPathFromName(const char* Module, char* Path, int Size); void ModGetList(std::vector & list); \ No newline at end of file diff --git a/src/dbg/msgqueue.cpp b/src/dbg/msgqueue.cpp index 7d254c0c..d9adc5eb 100644 --- a/src/dbg/msgqueue.cpp +++ b/src/dbg/msgqueue.cpp @@ -1,69 +1,69 @@ -#include "msgqueue.h" - -// Allocate a message stack -MESSAGE_STACK* MsgAllocStack() -{ - auto stack = new MESSAGE_STACK; - - stack->WaitingCalls = 0; - stack->Destroy = false; - - return stack; -} - -// Free a message stack -void MsgFreeStack(MESSAGE_STACK* Stack) -{ - ASSERT_NONNULL(Stack); - - // Update termination variable - Stack->Destroy = true; - - // Notify each thread - for(int i = 0; i < Stack->WaitingCalls + 1; i++) - { - MESSAGE newMessage; - Stack->msgs.enqueue(newMessage); - } - - // Delete allocated structure - delete Stack; -} - -// Add a message to the stack -bool MsgSend(MESSAGE_STACK* Stack, int Msg, duint Param1, duint Param2) -{ - if(Stack->Destroy) - return false; - - MESSAGE newMessage; - newMessage.msg = Msg; - newMessage.param1 = Param1; - newMessage.param2 = Param2; - - // Asynchronous send - asend(Stack->msgs, newMessage); - return true; -} - -// Get a message from the stack (will return false when there are no messages) -bool MsgGet(MESSAGE_STACK* Stack, MESSAGE* Msg) -{ - if(Stack->Destroy) - return false; - - // Don't increment the wait count because this does not wait - return try_receive(Stack->msgs, *Msg); -} - -// Wait for a message on the specified stack -void MsgWait(MESSAGE_STACK* Stack, MESSAGE* Msg) -{ - if(Stack->Destroy) - return; - - // Increment/decrement wait count - InterlockedIncrement((volatile long*)&Stack->WaitingCalls); - *Msg = Stack->msgs.dequeue(); - InterlockedDecrement((volatile long*)&Stack->WaitingCalls); -} +#include "msgqueue.h" + +// Allocate a message stack +MESSAGE_STACK* MsgAllocStack() +{ + auto stack = new MESSAGE_STACK; + + stack->WaitingCalls = 0; + stack->Destroy = false; + + return stack; +} + +// Free a message stack +void MsgFreeStack(MESSAGE_STACK* Stack) +{ + ASSERT_NONNULL(Stack); + + // Update termination variable + Stack->Destroy = true; + + // Notify each thread + for(int i = 0; i < Stack->WaitingCalls + 1; i++) + { + MESSAGE newMessage; + Stack->msgs.enqueue(newMessage); + } + + // Delete allocated structure + delete Stack; +} + +// Add a message to the stack +bool MsgSend(MESSAGE_STACK* Stack, int Msg, duint Param1, duint Param2) +{ + if(Stack->Destroy) + return false; + + MESSAGE newMessage; + newMessage.msg = Msg; + newMessage.param1 = Param1; + newMessage.param2 = Param2; + + // Asynchronous send + asend(Stack->msgs, newMessage); + return true; +} + +// Get a message from the stack (will return false when there are no messages) +bool MsgGet(MESSAGE_STACK* Stack, MESSAGE* Msg) +{ + if(Stack->Destroy) + return false; + + // Don't increment the wait count because this does not wait + return try_receive(Stack->msgs, *Msg); +} + +// Wait for a message on the specified stack +void MsgWait(MESSAGE_STACK* Stack, MESSAGE* Msg) +{ + if(Stack->Destroy) + return; + + // Increment/decrement wait count + InterlockedIncrement((volatile long*)&Stack->WaitingCalls); + *Msg = Stack->msgs.dequeue(); + InterlockedDecrement((volatile long*)&Stack->WaitingCalls); +} diff --git a/src/dbg/msgqueue.h b/src/dbg/msgqueue.h index fac907d2..c9ccb13b 100644 --- a/src/dbg/msgqueue.h +++ b/src/dbg/msgqueue.h @@ -1,35 +1,35 @@ -#ifndef _MSGQUEUE_H -#define _MSGQUEUE_H - -#include "_global.h" -#include -#include - -#define MAX_MESSAGES 256 - -// Message structure -struct MESSAGE -{ - int msg; - duint param1; - duint param2; -}; - -// Message stack structure -class MESSAGE_STACK -{ -public: - Concurrency::unbounded_buffer msgs; - - int WaitingCalls; // Number of threads waiting - bool Destroy; // Destroy stack as soon as possible -}; - -// Function definitions -MESSAGE_STACK* MsgAllocStack(); -void MsgFreeStack(MESSAGE_STACK* Stack); -bool MsgSend(MESSAGE_STACK* Stack, int Msg, duint Param1, duint Param2); -bool MsgGet(MESSAGE_STACK* Stack, MESSAGE* Msg); -void MsgWait(MESSAGE_STACK* Stack, MESSAGE* Msg); - -#endif // _MSGQUEUE_H +#ifndef _MSGQUEUE_H +#define _MSGQUEUE_H + +#include "_global.h" +#include +#include + +#define MAX_MESSAGES 256 + +// Message structure +struct MESSAGE +{ + int msg; + duint param1; + duint param2; +}; + +// Message stack structure +class MESSAGE_STACK +{ +public: + Concurrency::unbounded_buffer msgs; + + int WaitingCalls; // Number of threads waiting + bool Destroy; // Destroy stack as soon as possible +}; + +// Function definitions +MESSAGE_STACK* MsgAllocStack(); +void MsgFreeStack(MESSAGE_STACK* Stack); +bool MsgSend(MESSAGE_STACK* Stack, int Msg, duint Param1, duint Param2); +bool MsgGet(MESSAGE_STACK* Stack, MESSAGE* Msg); +void MsgWait(MESSAGE_STACK* Stack, MESSAGE* Msg); + +#endif // _MSGQUEUE_H diff --git a/src/dbg/murmurhash.cpp b/src/dbg/murmurhash.cpp index cb8ad875..a386fe27 100644 --- a/src/dbg/murmurhash.cpp +++ b/src/dbg/murmurhash.cpp @@ -1,566 +1,566 @@ -//----------------------------------------------------------------------------- -// MurmurHash3 was written by Austin Appleby, and is placed in the public -// domain. The author hereby disclaims copyright to this source code. - -// Note - The x86 and x64 versions do _not_ produce the same results, as the -// algorithms are optimized for their respective platforms. You can still -// compile and run any of them on any platform, but your performance with the -// non-native version will be less than optimal. - -#include "murmurhash.h" - -//----------------------------------------------------------------------------- -// Platform-specific functions and macros - -// Microsoft Visual Studio - -#if defined(_MSC_VER) - -/** - @def FORCE_INLINE - - @brief A macro that defines force inline. - */ - -#define FORCE_INLINE __forceinline - -#include - -/** - @def ROTL32(x,y) _rotl(x,y) - - @brief A macro that defines rotl 32. - - @param x The void to process. - @param y The void to process. - */ - -#define ROTL32(x,y) _rotl(x,y) - -/** - @def ROTL64(x,y) _rotl64(x,y) - - @brief A macro that defines rotl 64. - - @param x The void to process. - @param y The void to process. - */ - -#define ROTL64(x,y) _rotl64(x,y) - -/** - @def BIG_CONSTANT(x) (x) - - @brief A macro that defines big constant. - - @param x The void to process. - */ - -#define BIG_CONSTANT(x) (x) - -// Other compilers - -#else // defined(_MSC_VER) - -/** - @brief The force inline. - */ - -#define FORCE_INLINE inline __attribute__((always_inline)) - -inline uint32_t rotl32(uint32_t x, int8_t r) -{ - return (x << r) | (x >> (32 - r)); -} - -inline uint64_t rotl64(uint64_t x, int8_t r) -{ - return (x << r) | (x >> (64 - r)); -} - -/** - @def ROTL32(x,y) rotl32(x,y) - - @brief A macro that defines rotl 32. - - @param x The void to process. - @param y The void to process. - */ - -#define ROTL32(x,y) rotl32(x,y) - -/** - @def ROTL64(x,y) rotl64(x,y) - - @brief A macro that defines rotl 64. - - @param x The void to process. - @param y The void to process. - */ - -#define ROTL64(x,y) rotl64(x,y) - -/** - @def BIG_CONSTANT(x) (x##LLU) - - @brief A macro that defines big constant. - - @param x The void to process. - */ - -#define BIG_CONSTANT(x) (x##LLU) - -#endif // !defined(_MSC_VER) - -/** - @fn FORCE_INLINE uint32_t getblock32(const uint32_t* p, int i) - - @brief ----------------------------------------------------------------------------- - Block read - if your platform needs to do endian-swapping or can only handle aligned reads, do - the conversion here. - - @param p The const uint32_t* to process. - @param i Zero-based index of the. - - @return An uint32_t. - */ - -FORCE_INLINE uint32_t getblock32(const uint32_t* p, int i) -{ - return p[i]; -} - -/** - @fn FORCE_INLINE uint64_t getblock64(const uint64_t* p, int i) - - @brief Getblock 64. - - @param p The const uint64_t* to process. - @param i Zero-based index of the. - - @return An uint64_t. - */ - -FORCE_INLINE uint64_t getblock64(const uint64_t* p, int i) -{ - return p[i]; -} - -/** - @fn FORCE_INLINE uint32_t fmix32(uint32_t h) - - @brief ----------------------------------------------------------------------------- - Finalization mix - force all bits of a hash block to avalanche. - - @param h The uint32_t to process. - - @return An uint32_t. - */ - -FORCE_INLINE uint32_t fmix32(uint32_t h) -{ - h ^= h >> 16; - h *= 0x85ebca6b; - h ^= h >> 13; - h *= 0xc2b2ae35; - h ^= h >> 16; - - return h; -} - -//---------- - -/** - @fn FORCE_INLINE uint64_t fmix64(uint64_t k) - - @brief Fmix 64. - - @param k The uint64_t to process. - - @return An uint64_t. - */ - -FORCE_INLINE uint64_t fmix64(uint64_t k) -{ - k ^= k >> 33; - k *= BIG_CONSTANT(0xff51afd7ed558ccd); - k ^= k >> 33; - k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); - k ^= k >> 33; - - return k; -} - -//----------------------------------------------------------------------------- - -/** - @fn void MurmurHash3_x86_32(const void* key, int len, uint32_t seed, void* out) - - @brief Murmur hash 3 x coordinate 86 32. - - @param key The key. - @param len The length. - @param seed The seed. - @param [in,out] out If non-null, the out. - */ - -void MurmurHash3_x86_32(const void* key, int len, - uint32_t seed, void* out) -{ - const uint8_t* data = (const uint8_t*)key; - const int nblocks = len / 4; - - uint32_t h1 = seed; - - const uint32_t c1 = 0xcc9e2d51; - const uint32_t c2 = 0x1b873593; - - //---------- - // body - - const uint32_t* blocks = (const uint32_t*)(data + nblocks * 4); - - for(int i = -nblocks; i; i++) - { - uint32_t k1 = getblock32(blocks, i); - - k1 *= c1; - k1 = ROTL32(k1, 15); - k1 *= c2; - - h1 ^= k1; - h1 = ROTL32(h1, 13); - h1 = h1 * 5 + 0xe6546b64; - } - - //---------- - // tail - - const uint8_t* tail = (const uint8_t*)(data + nblocks * 4); - - uint32_t k1 = 0; - - switch(len & 3) - { - case 3: - k1 ^= tail[2] << 16; - case 2: - k1 ^= tail[1] << 8; - case 1: - k1 ^= tail[0]; - k1 *= c1; - k1 = ROTL32(k1, 15); - k1 *= c2; - h1 ^= k1; - }; - - //---------- - // finalization - - h1 ^= len; - - h1 = fmix32(h1); - - *(uint32_t*)out = h1; -} - -//----------------------------------------------------------------------------- - -/** - @fn void MurmurHash3_x86_128(const void* key, const int len, uint32_t seed, void* out) - - @brief Murmur hash 3 x coordinate 86 128. - - @param key The key. - @param len The length. - @param seed The seed. - @param [in,out] out If non-null, the out. - */ - -void MurmurHash3_x86_128(const void* key, const int len, - uint32_t seed, void* out) -{ - const uint8_t* data = (const uint8_t*)key; - const int nblocks = len / 16; - - uint32_t h1 = seed; - uint32_t h2 = seed; - uint32_t h3 = seed; - uint32_t h4 = seed; - - const uint32_t c1 = 0x239b961b; - const uint32_t c2 = 0xab0e9789; - const uint32_t c3 = 0x38b34ae5; - const uint32_t c4 = 0xa1e38b93; - - //---------- - // body - - const uint32_t* blocks = (const uint32_t*)(data + nblocks * 16); - - for(int i = -nblocks; i; i++) - { - uint32_t k1 = getblock32(blocks, i * 4 + 0); - uint32_t k2 = getblock32(blocks, i * 4 + 1); - uint32_t k3 = getblock32(blocks, i * 4 + 2); - uint32_t k4 = getblock32(blocks, i * 4 + 3); - - k1 *= c1; - k1 = ROTL32(k1, 15); - k1 *= c2; - h1 ^= k1; - - h1 = ROTL32(h1, 19); - h1 += h2; - h1 = h1 * 5 + 0x561ccd1b; - - k2 *= c2; - k2 = ROTL32(k2, 16); - k2 *= c3; - h2 ^= k2; - - h2 = ROTL32(h2, 17); - h2 += h3; - h2 = h2 * 5 + 0x0bcaa747; - - k3 *= c3; - k3 = ROTL32(k3, 17); - k3 *= c4; - h3 ^= k3; - - h3 = ROTL32(h3, 15); - h3 += h4; - h3 = h3 * 5 + 0x96cd1c35; - - k4 *= c4; - k4 = ROTL32(k4, 18); - k4 *= c1; - h4 ^= k4; - - h4 = ROTL32(h4, 13); - h4 += h1; - h4 = h4 * 5 + 0x32ac3b17; - } - - //---------- - // tail - - const uint8_t* tail = (const uint8_t*)(data + nblocks * 16); - - uint32_t k1 = 0; - uint32_t k2 = 0; - uint32_t k3 = 0; - uint32_t k4 = 0; - - switch(len & 15) - { - case 15: - k4 ^= tail[14] << 16; - case 14: - k4 ^= tail[13] << 8; - case 13: - k4 ^= tail[12] << 0; - k4 *= c4; - k4 = ROTL32(k4, 18); - k4 *= c1; - h4 ^= k4; - - case 12: - k3 ^= tail[11] << 24; - case 11: - k3 ^= tail[10] << 16; - case 10: - k3 ^= tail[ 9] << 8; - case 9: - k3 ^= tail[ 8] << 0; - k3 *= c3; - k3 = ROTL32(k3, 17); - k3 *= c4; - h3 ^= k3; - - case 8: - k2 ^= tail[ 7] << 24; - case 7: - k2 ^= tail[ 6] << 16; - case 6: - k2 ^= tail[ 5] << 8; - case 5: - k2 ^= tail[ 4] << 0; - k2 *= c2; - k2 = ROTL32(k2, 16); - k2 *= c3; - h2 ^= k2; - - case 4: - k1 ^= tail[ 3] << 24; - case 3: - k1 ^= tail[ 2] << 16; - case 2: - k1 ^= tail[ 1] << 8; - case 1: - k1 ^= tail[ 0] << 0; - k1 *= c1; - k1 = ROTL32(k1, 15); - k1 *= c2; - h1 ^= k1; - }; - - //---------- - // finalization - - h1 ^= len; - h2 ^= len; - h3 ^= len; - h4 ^= len; - - h1 += h2; - h1 += h3; - h1 += h4; - h2 += h1; - h3 += h1; - h4 += h1; - - h1 = fmix32(h1); - h2 = fmix32(h2); - h3 = fmix32(h3); - h4 = fmix32(h4); - - h1 += h2; - h1 += h3; - h1 += h4; - h2 += h1; - h3 += h1; - h4 += h1; - - ((uint32_t*)out)[0] = h1; - ((uint32_t*)out)[1] = h2; - ((uint32_t*)out)[2] = h3; - ((uint32_t*)out)[3] = h4; -} - -//----------------------------------------------------------------------------- - -/** - @fn void MurmurHash3_x64_128(const void* key, const int len, const uint32_t seed, void* out) - - @brief Murmur hash 3 x coordinate 64 128. - - @param key The key. - @param len The length. - @param seed The seed. - @param [in,out] out If non-null, the out. - */ - -void MurmurHash3_x64_128(const void* key, const int len, - const uint32_t seed, void* out) -{ - const uint8_t* data = (const uint8_t*)key; - const int nblocks = len / 16; - - uint64_t h1 = seed; - uint64_t h2 = seed; - - const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5); - const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f); - - //---------- - // body - - const uint64_t* blocks = (const uint64_t*)(data); - - for(int i = 0; i < nblocks; i++) - { - uint64_t k1 = getblock64(blocks, i * 2 + 0); - uint64_t k2 = getblock64(blocks, i * 2 + 1); - - k1 *= c1; - k1 = ROTL64(k1, 31); - k1 *= c2; - h1 ^= k1; - - h1 = ROTL64(h1, 27); - h1 += h2; - h1 = h1 * 5 + 0x52dce729; - - k2 *= c2; - k2 = ROTL64(k2, 33); - k2 *= c1; - h2 ^= k2; - - h2 = ROTL64(h2, 31); - h2 += h1; - h2 = h2 * 5 + 0x38495ab5; - } - - //---------- - // tail - - const uint8_t* tail = (const uint8_t*)(data + nblocks * 16); - - uint64_t k1 = 0; - uint64_t k2 = 0; - - switch(len & 15) - { - case 15: - k2 ^= ((uint64_t)tail[14]) << 48; - case 14: - k2 ^= ((uint64_t)tail[13]) << 40; - case 13: - k2 ^= ((uint64_t)tail[12]) << 32; - case 12: - k2 ^= ((uint64_t)tail[11]) << 24; - case 11: - k2 ^= ((uint64_t)tail[10]) << 16; - case 10: - k2 ^= ((uint64_t)tail[ 9]) << 8; - case 9: - k2 ^= ((uint64_t)tail[ 8]) << 0; - k2 *= c2; - k2 = ROTL64(k2, 33); - k2 *= c1; - h2 ^= k2; - - case 8: - k1 ^= ((uint64_t)tail[ 7]) << 56; - case 7: - k1 ^= ((uint64_t)tail[ 6]) << 48; - case 6: - k1 ^= ((uint64_t)tail[ 5]) << 40; - case 5: - k1 ^= ((uint64_t)tail[ 4]) << 32; - case 4: - k1 ^= ((uint64_t)tail[ 3]) << 24; - case 3: - k1 ^= ((uint64_t)tail[ 2]) << 16; - case 2: - k1 ^= ((uint64_t)tail[ 1]) << 8; - case 1: - k1 ^= ((uint64_t)tail[ 0]) << 0; - k1 *= c1; - k1 = ROTL64(k1, 31); - k1 *= c2; - h1 ^= k1; - }; - - //---------- - // finalization - - h1 ^= len; - h2 ^= len; - - h1 += h2; - h2 += h1; - - h1 = fmix64(h1); - h2 = fmix64(h2); - - h1 += h2; - h2 += h1; - - ((uint64_t*)out)[0] = h1; - ((uint64_t*)out)[1] = h2; -} - -//----------------------------------------------------------------------------- - +//----------------------------------------------------------------------------- +// MurmurHash3 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. + +// Note - The x86 and x64 versions do _not_ produce the same results, as the +// algorithms are optimized for their respective platforms. You can still +// compile and run any of them on any platform, but your performance with the +// non-native version will be less than optimal. + +#include "murmurhash.h" + +//----------------------------------------------------------------------------- +// Platform-specific functions and macros + +// Microsoft Visual Studio + +#if defined(_MSC_VER) + +/** + @def FORCE_INLINE + + @brief A macro that defines force inline. + */ + +#define FORCE_INLINE __forceinline + +#include + +/** + @def ROTL32(x,y) _rotl(x,y) + + @brief A macro that defines rotl 32. + + @param x The void to process. + @param y The void to process. + */ + +#define ROTL32(x,y) _rotl(x,y) + +/** + @def ROTL64(x,y) _rotl64(x,y) + + @brief A macro that defines rotl 64. + + @param x The void to process. + @param y The void to process. + */ + +#define ROTL64(x,y) _rotl64(x,y) + +/** + @def BIG_CONSTANT(x) (x) + + @brief A macro that defines big constant. + + @param x The void to process. + */ + +#define BIG_CONSTANT(x) (x) + +// Other compilers + +#else // defined(_MSC_VER) + +/** + @brief The force inline. + */ + +#define FORCE_INLINE inline __attribute__((always_inline)) + +inline uint32_t rotl32(uint32_t x, int8_t r) +{ + return (x << r) | (x >> (32 - r)); +} + +inline uint64_t rotl64(uint64_t x, int8_t r) +{ + return (x << r) | (x >> (64 - r)); +} + +/** + @def ROTL32(x,y) rotl32(x,y) + + @brief A macro that defines rotl 32. + + @param x The void to process. + @param y The void to process. + */ + +#define ROTL32(x,y) rotl32(x,y) + +/** + @def ROTL64(x,y) rotl64(x,y) + + @brief A macro that defines rotl 64. + + @param x The void to process. + @param y The void to process. + */ + +#define ROTL64(x,y) rotl64(x,y) + +/** + @def BIG_CONSTANT(x) (x##LLU) + + @brief A macro that defines big constant. + + @param x The void to process. + */ + +#define BIG_CONSTANT(x) (x##LLU) + +#endif // !defined(_MSC_VER) + +/** + @fn FORCE_INLINE uint32_t getblock32(const uint32_t* p, int i) + + @brief ----------------------------------------------------------------------------- + Block read - if your platform needs to do endian-swapping or can only handle aligned reads, do + the conversion here. + + @param p The const uint32_t* to process. + @param i Zero-based index of the. + + @return An uint32_t. + */ + +FORCE_INLINE uint32_t getblock32(const uint32_t* p, int i) +{ + return p[i]; +} + +/** + @fn FORCE_INLINE uint64_t getblock64(const uint64_t* p, int i) + + @brief Getblock 64. + + @param p The const uint64_t* to process. + @param i Zero-based index of the. + + @return An uint64_t. + */ + +FORCE_INLINE uint64_t getblock64(const uint64_t* p, int i) +{ + return p[i]; +} + +/** + @fn FORCE_INLINE uint32_t fmix32(uint32_t h) + + @brief ----------------------------------------------------------------------------- + Finalization mix - force all bits of a hash block to avalanche. + + @param h The uint32_t to process. + + @return An uint32_t. + */ + +FORCE_INLINE uint32_t fmix32(uint32_t h) +{ + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return h; +} + +//---------- + +/** + @fn FORCE_INLINE uint64_t fmix64(uint64_t k) + + @brief Fmix 64. + + @param k The uint64_t to process. + + @return An uint64_t. + */ + +FORCE_INLINE uint64_t fmix64(uint64_t k) +{ + k ^= k >> 33; + k *= BIG_CONSTANT(0xff51afd7ed558ccd); + k ^= k >> 33; + k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); + k ^= k >> 33; + + return k; +} + +//----------------------------------------------------------------------------- + +/** + @fn void MurmurHash3_x86_32(const void* key, int len, uint32_t seed, void* out) + + @brief Murmur hash 3 x coordinate 86 32. + + @param key The key. + @param len The length. + @param seed The seed. + @param [in,out] out If non-null, the out. + */ + +void MurmurHash3_x86_32(const void* key, int len, + uint32_t seed, void* out) +{ + const uint8_t* data = (const uint8_t*)key; + const int nblocks = len / 4; + + uint32_t h1 = seed; + + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + + //---------- + // body + + const uint32_t* blocks = (const uint32_t*)(data + nblocks * 4); + + for(int i = -nblocks; i; i++) + { + uint32_t k1 = getblock32(blocks, i); + + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + + h1 ^= k1; + h1 = ROTL32(h1, 13); + h1 = h1 * 5 + 0xe6546b64; + } + + //---------- + // tail + + const uint8_t* tail = (const uint8_t*)(data + nblocks * 4); + + uint32_t k1 = 0; + + switch(len & 3) + { + case 3: + k1 ^= tail[2] << 16; + case 2: + k1 ^= tail[1] << 8; + case 1: + k1 ^= tail[0]; + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + h1 ^= k1; + }; + + //---------- + // finalization + + h1 ^= len; + + h1 = fmix32(h1); + + *(uint32_t*)out = h1; +} + +//----------------------------------------------------------------------------- + +/** + @fn void MurmurHash3_x86_128(const void* key, const int len, uint32_t seed, void* out) + + @brief Murmur hash 3 x coordinate 86 128. + + @param key The key. + @param len The length. + @param seed The seed. + @param [in,out] out If non-null, the out. + */ + +void MurmurHash3_x86_128(const void* key, const int len, + uint32_t seed, void* out) +{ + const uint8_t* data = (const uint8_t*)key; + const int nblocks = len / 16; + + uint32_t h1 = seed; + uint32_t h2 = seed; + uint32_t h3 = seed; + uint32_t h4 = seed; + + const uint32_t c1 = 0x239b961b; + const uint32_t c2 = 0xab0e9789; + const uint32_t c3 = 0x38b34ae5; + const uint32_t c4 = 0xa1e38b93; + + //---------- + // body + + const uint32_t* blocks = (const uint32_t*)(data + nblocks * 16); + + for(int i = -nblocks; i; i++) + { + uint32_t k1 = getblock32(blocks, i * 4 + 0); + uint32_t k2 = getblock32(blocks, i * 4 + 1); + uint32_t k3 = getblock32(blocks, i * 4 + 2); + uint32_t k4 = getblock32(blocks, i * 4 + 3); + + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + h1 ^= k1; + + h1 = ROTL32(h1, 19); + h1 += h2; + h1 = h1 * 5 + 0x561ccd1b; + + k2 *= c2; + k2 = ROTL32(k2, 16); + k2 *= c3; + h2 ^= k2; + + h2 = ROTL32(h2, 17); + h2 += h3; + h2 = h2 * 5 + 0x0bcaa747; + + k3 *= c3; + k3 = ROTL32(k3, 17); + k3 *= c4; + h3 ^= k3; + + h3 = ROTL32(h3, 15); + h3 += h4; + h3 = h3 * 5 + 0x96cd1c35; + + k4 *= c4; + k4 = ROTL32(k4, 18); + k4 *= c1; + h4 ^= k4; + + h4 = ROTL32(h4, 13); + h4 += h1; + h4 = h4 * 5 + 0x32ac3b17; + } + + //---------- + // tail + + const uint8_t* tail = (const uint8_t*)(data + nblocks * 16); + + uint32_t k1 = 0; + uint32_t k2 = 0; + uint32_t k3 = 0; + uint32_t k4 = 0; + + switch(len & 15) + { + case 15: + k4 ^= tail[14] << 16; + case 14: + k4 ^= tail[13] << 8; + case 13: + k4 ^= tail[12] << 0; + k4 *= c4; + k4 = ROTL32(k4, 18); + k4 *= c1; + h4 ^= k4; + + case 12: + k3 ^= tail[11] << 24; + case 11: + k3 ^= tail[10] << 16; + case 10: + k3 ^= tail[ 9] << 8; + case 9: + k3 ^= tail[ 8] << 0; + k3 *= c3; + k3 = ROTL32(k3, 17); + k3 *= c4; + h3 ^= k3; + + case 8: + k2 ^= tail[ 7] << 24; + case 7: + k2 ^= tail[ 6] << 16; + case 6: + k2 ^= tail[ 5] << 8; + case 5: + k2 ^= tail[ 4] << 0; + k2 *= c2; + k2 = ROTL32(k2, 16); + k2 *= c3; + h2 ^= k2; + + case 4: + k1 ^= tail[ 3] << 24; + case 3: + k1 ^= tail[ 2] << 16; + case 2: + k1 ^= tail[ 1] << 8; + case 1: + k1 ^= tail[ 0] << 0; + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + h1 ^= k1; + }; + + //---------- + // finalization + + h1 ^= len; + h2 ^= len; + h3 ^= len; + h4 ^= len; + + h1 += h2; + h1 += h3; + h1 += h4; + h2 += h1; + h3 += h1; + h4 += h1; + + h1 = fmix32(h1); + h2 = fmix32(h2); + h3 = fmix32(h3); + h4 = fmix32(h4); + + h1 += h2; + h1 += h3; + h1 += h4; + h2 += h1; + h3 += h1; + h4 += h1; + + ((uint32_t*)out)[0] = h1; + ((uint32_t*)out)[1] = h2; + ((uint32_t*)out)[2] = h3; + ((uint32_t*)out)[3] = h4; +} + +//----------------------------------------------------------------------------- + +/** + @fn void MurmurHash3_x64_128(const void* key, const int len, const uint32_t seed, void* out) + + @brief Murmur hash 3 x coordinate 64 128. + + @param key The key. + @param len The length. + @param seed The seed. + @param [in,out] out If non-null, the out. + */ + +void MurmurHash3_x64_128(const void* key, const int len, + const uint32_t seed, void* out) +{ + const uint8_t* data = (const uint8_t*)key; + const int nblocks = len / 16; + + uint64_t h1 = seed; + uint64_t h2 = seed; + + const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5); + const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f); + + //---------- + // body + + const uint64_t* blocks = (const uint64_t*)(data); + + for(int i = 0; i < nblocks; i++) + { + uint64_t k1 = getblock64(blocks, i * 2 + 0); + uint64_t k2 = getblock64(blocks, i * 2 + 1); + + k1 *= c1; + k1 = ROTL64(k1, 31); + k1 *= c2; + h1 ^= k1; + + h1 = ROTL64(h1, 27); + h1 += h2; + h1 = h1 * 5 + 0x52dce729; + + k2 *= c2; + k2 = ROTL64(k2, 33); + k2 *= c1; + h2 ^= k2; + + h2 = ROTL64(h2, 31); + h2 += h1; + h2 = h2 * 5 + 0x38495ab5; + } + + //---------- + // tail + + const uint8_t* tail = (const uint8_t*)(data + nblocks * 16); + + uint64_t k1 = 0; + uint64_t k2 = 0; + + switch(len & 15) + { + case 15: + k2 ^= ((uint64_t)tail[14]) << 48; + case 14: + k2 ^= ((uint64_t)tail[13]) << 40; + case 13: + k2 ^= ((uint64_t)tail[12]) << 32; + case 12: + k2 ^= ((uint64_t)tail[11]) << 24; + case 11: + k2 ^= ((uint64_t)tail[10]) << 16; + case 10: + k2 ^= ((uint64_t)tail[ 9]) << 8; + case 9: + k2 ^= ((uint64_t)tail[ 8]) << 0; + k2 *= c2; + k2 = ROTL64(k2, 33); + k2 *= c1; + h2 ^= k2; + + case 8: + k1 ^= ((uint64_t)tail[ 7]) << 56; + case 7: + k1 ^= ((uint64_t)tail[ 6]) << 48; + case 6: + k1 ^= ((uint64_t)tail[ 5]) << 40; + case 5: + k1 ^= ((uint64_t)tail[ 4]) << 32; + case 4: + k1 ^= ((uint64_t)tail[ 3]) << 24; + case 3: + k1 ^= ((uint64_t)tail[ 2]) << 16; + case 2: + k1 ^= ((uint64_t)tail[ 1]) << 8; + case 1: + k1 ^= ((uint64_t)tail[ 0]) << 0; + k1 *= c1; + k1 = ROTL64(k1, 31); + k1 *= c2; + h1 ^= k1; + }; + + //---------- + // finalization + + h1 ^= len; + h2 ^= len; + + h1 += h2; + h2 += h1; + + h1 = fmix64(h1); + h2 = fmix64(h2); + + h1 += h2; + h2 += h1; + + ((uint64_t*)out)[0] = h1; + ((uint64_t*)out)[1] = h2; +} + +//----------------------------------------------------------------------------- + diff --git a/src/dbg/murmurhash.h b/src/dbg/murmurhash.h index b592c7ee..f0d55184 100644 --- a/src/dbg/murmurhash.h +++ b/src/dbg/murmurhash.h @@ -1,53 +1,53 @@ -//----------------------------------------------------------------------------- -// MurmurHash3 was written by Austin Appleby, and is placed in the public -// domain. The author hereby disclaims copyright to this source code. - -#ifndef _MURMURHASH3_H_ -#define _MURMURHASH3_H_ - -//----------------------------------------------------------------------------- -// Platform-specific functions and macros - -// Microsoft Visual Studio - -#if defined(_MSC_VER) && (_MSC_VER < 1600) - -typedef unsigned char uint8_t; -typedef unsigned int uint32_t; -typedef unsigned __int64 uint64_t; - -// Other compilers - -#else // defined(_MSC_VER) - -#include - -#endif // !defined(_MSC_VER) - -//----------------------------------------------------------------------------- - -void MurmurHash3_x86_32(const void* key, int len, uint32_t seed, void* out); - -void MurmurHash3_x86_128(const void* key, int len, uint32_t seed, void* out); - -void MurmurHash3_x64_128(const void* key, int len, uint32_t seed, void* out); - -//----------------------------------------------------------------------------- - -#ifdef _WIN64 -static inline -unsigned long long murmurhash(const void* data, int len) -{ - unsigned long long hash[2]; - MurmurHash3_x64_128(data, len, 0x1337, hash); -#else //x86 -static inline -unsigned long murmurhash(const void* data, int len) -{ - unsigned int hash[1]; - MurmurHash3_x86_32(data, len, 0x1337, hash); -#endif //_WIN64 - return hash[0]; -} - -#endif // _MURMURHASH3_H_ +//----------------------------------------------------------------------------- +// MurmurHash3 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. + +#ifndef _MURMURHASH3_H_ +#define _MURMURHASH3_H_ + +//----------------------------------------------------------------------------- +// Platform-specific functions and macros + +// Microsoft Visual Studio + +#if defined(_MSC_VER) && (_MSC_VER < 1600) + +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +typedef unsigned __int64 uint64_t; + +// Other compilers + +#else // defined(_MSC_VER) + +#include + +#endif // !defined(_MSC_VER) + +//----------------------------------------------------------------------------- + +void MurmurHash3_x86_32(const void* key, int len, uint32_t seed, void* out); + +void MurmurHash3_x86_128(const void* key, int len, uint32_t seed, void* out); + +void MurmurHash3_x64_128(const void* key, int len, uint32_t seed, void* out); + +//----------------------------------------------------------------------------- + +#ifdef _WIN64 +static inline +unsigned long long murmurhash(const void* data, int len) +{ + unsigned long long hash[2]; + MurmurHash3_x64_128(data, len, 0x1337, hash); +#else //x86 +static inline +unsigned long murmurhash(const void* data, int len) +{ + unsigned int hash[1]; + MurmurHash3_x86_32(data, len, 0x1337, hash); +#endif //_WIN64 + return hash[0]; +} + +#endif // _MURMURHASH3_H_ diff --git a/src/dbg/patches.cpp b/src/dbg/patches.cpp index 2a380c2f..ad1aa5a9 100644 --- a/src/dbg/patches.cpp +++ b/src/dbg/patches.cpp @@ -1,299 +1,299 @@ -/** - @file patches.cpp - - @brief Implements the patches class. - */ - -#include "patches.h" -#include "memory.h" -#include "debugger.h" -#include "threading.h" -#include "module.h" - -std::unordered_map patches; - -bool PatchSet(duint Address, unsigned char OldByte, unsigned char NewByte) -{ - ASSERT_DEBUGGING("Export call"); - - // Address must be valid - if(!MemIsValidReadPtr(Address)) - return false; - - // Don't patch anything if the new and old values are the same - if(OldByte == NewByte) - return true; - - PATCHINFO newPatch; - newPatch.addr = Address - ModBaseFromAddr(Address); - newPatch.oldbyte = OldByte; - newPatch.newbyte = NewByte; - ModNameFromAddr(Address, newPatch.mod, true); - - // Generate a key for this address - const duint key = ModHashFromAddr(Address); - - EXCLUSIVE_ACQUIRE(LockPatches); - - // Find any patch with this specific address - auto found = patches.find(key); - - if(found != patches.end()) - { - if(found->second.oldbyte == NewByte) - { - // The patch was undone here - patches.erase(found); - return true; - } - - // Keep the original byte from the previous patch - newPatch.oldbyte = found->second.oldbyte; - found->second = newPatch; - } - else - { - // The entry was never found, insert it - patches.insert(std::make_pair(key, newPatch)); - } - - return true; -} - -bool PatchGet(duint Address, PATCHINFO* Patch) -{ - ASSERT_DEBUGGING("Export call"); - SHARED_ACQUIRE(LockPatches); - - // Find this specific address in the list - auto found = patches.find(ModHashFromAddr(Address)); - - if(found == patches.end()) - return false; - - // Did the user request an output buffer? - if(Patch) - { - *Patch = found->second; - Patch->addr += ModBaseFromAddr(Address); - } - - // Return true because the patch was found - return true; -} - -bool PatchDelete(duint Address, bool Restore) -{ - ASSERT_DEBUGGING("Export call"); - EXCLUSIVE_ACQUIRE(LockPatches); - - // Do a list lookup with hash - auto found = patches.find(ModHashFromAddr(Address)); - - if(found == patches.end()) - return false; - - // Restore the original byte at this address - if(Restore) - MemWrite((found->second.addr + ModBaseFromAddr(Address)), &found->second.oldbyte, sizeof(char)); - - // Finally remove it from the list - patches.erase(found); - return true; -} - -void PatchDelRange(duint Start, duint End, bool Restore) -{ - ASSERT_DEBUGGING("Export call"); - - // Are all bookmarks going to be deleted? - // 0x00000000 - 0xFFFFFFFF - if(Start == 0 && End == ~0) - { - EXCLUSIVE_ACQUIRE(LockPatches); - patches.clear(); - } - else - { - // Make sure 'Start' and 'End' reference the same module - duint moduleBase = ModBaseFromAddr(Start); - - if(moduleBase != ModBaseFromAddr(End)) - return; - - // VA to RVA in module - Start -= moduleBase; - End -= moduleBase; - - EXCLUSIVE_ACQUIRE(LockPatches); - for(auto itr = patches.begin(); itr != patches.end();) - { - const auto & currentPatch = itr->second; - // [Start, End) - if(currentPatch.addr >= Start && currentPatch.addr < End) - { - // Restore the original byte if necessary - if(Restore) - MemWrite((currentPatch.addr + moduleBase), ¤tPatch.oldbyte, sizeof(char)); - - itr = patches.erase(itr); - } - else - ++itr; - } - } -} - -bool PatchEnum(PATCHINFO* List, size_t* Size) -{ - ASSERT_DEBUGGING("Export call"); - ASSERT_FALSE(!List && !Size); - SHARED_ACQUIRE(LockPatches); - - // Did the user request the size? - if(Size) - { - *Size = patches.size() * sizeof(PATCHINFO); - - if(!List) - return true; - } - - // Copy each vector entry to a C-style array - for(auto & itr : patches) - { - *List = itr.second; - List->addr += ModBaseFromName(itr.second.mod);; - List++; - } - - return true; -} - -int PatchFile(const PATCHINFO* List, int Count, const char* FileName, char* Error) -{ - // - // This function returns an int based on the number - // of patches applied. -1 indicates a failure. - // - if(Count <= 0) - { - // Notify the user of the error - if(Error) - strcpy_s(Error, MAX_ERROR_SIZE, "No patches to apply"); - - return -1; - } - - // Get a copy of the first module name in the array - char moduleName[MAX_MODULE_SIZE]; - strcpy_s(moduleName, List[0].mod); - - // Check if all patches are in the same module - for(int i = 0; i < Count; i++) - { - if(_stricmp(List[i].mod, moduleName)) - { - if(Error) - sprintf_s(Error, MAX_ERROR_SIZE, "Not all patches are in module %s", moduleName); - - return -1; - } - } - - // See if the module was loaded - duint moduleBase = ModBaseFromName(moduleName); - - if(!moduleBase) - { - if(Error) - sprintf_s(Error, MAX_ERROR_SIZE, "Failed to get base of module %s", moduleName); - - return -1; - } - - // Get the unicode version of the module's path - wchar_t originalName[MAX_PATH]; - - if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)moduleBase, originalName, ARRAYSIZE(originalName))) - { - if(Error) - sprintf_s(Error, MAX_ERROR_SIZE, "Failed to get module path of module %s", moduleName); - - return -1; - } - - // Create a temporary backup file - if(!CopyFileW(originalName, StringUtils::Utf8ToUtf16(FileName).c_str(), false)) - { - if(Error) - strcpy_s(Error, MAX_ERROR_SIZE, "Failed to make a copy of the original file (patch target is in use?)"); - - return -1; - } - - HANDLE fileHandle; - DWORD loadedSize; - HANDLE fileMap; - ULONG_PTR fileMapVa; - if(!StaticFileLoadW(StringUtils::Utf8ToUtf16(FileName).c_str(), UE_ACCESS_ALL, false, &fileHandle, &loadedSize, &fileMap, &fileMapVa)) - { - strcpy_s(Error, MAX_ERROR_SIZE, "StaticFileLoad failed"); - return -1; - } - - // Begin iterating all patches, applying them to a file - int patchCount = 0; - - for(int i = 0; i < Count; i++) - { - // Convert the virtual address to an offset within disk file data - unsigned char* ptr = (unsigned char*)ConvertVAtoFileOffsetEx(fileMapVa, loadedSize, moduleBase, List[i].addr, false, true); - - // Skip patches that do not have a raw address - if(!ptr) - continue; - - *ptr = List[i].newbyte; - patchCount++; - } - - // Unload the file from memory and commit changes to disk - if(!StaticFileUnloadW(StringUtils::Utf8ToUtf16(FileName).c_str(), true, fileHandle, loadedSize, fileMap, fileMapVa)) - { - if(Error) - strcpy_s(Error, MAX_ERROR_SIZE, "StaticFileUnload failed"); - - return -1; - } - - // Zero the error message and return count - if(Error) - memset(Error, 0, MAX_ERROR_SIZE * sizeof(char)); - - return patchCount; -} - -void PatchClear(const char* Module) -{ - EXCLUSIVE_ACQUIRE(LockPatches); - - // Was a module specified? - if(!Module || Module[0] == '\0') - { - // No specific entries to delete, so remove all of them - patches.clear(); - } - else - { - // Otherwise iterate over each patch and check the owner - // module for the address - for(auto itr = patches.begin(); itr != patches.end();) - { - if(!_stricmp(itr->second.mod, Module)) - itr = patches.erase(itr); - else - ++itr; - } - } +/** + @file patches.cpp + + @brief Implements the patches class. + */ + +#include "patches.h" +#include "memory.h" +#include "debugger.h" +#include "threading.h" +#include "module.h" + +std::unordered_map patches; + +bool PatchSet(duint Address, unsigned char OldByte, unsigned char NewByte) +{ + ASSERT_DEBUGGING("Export call"); + + // Address must be valid + if(!MemIsValidReadPtr(Address)) + return false; + + // Don't patch anything if the new and old values are the same + if(OldByte == NewByte) + return true; + + PATCHINFO newPatch; + newPatch.addr = Address - ModBaseFromAddr(Address); + newPatch.oldbyte = OldByte; + newPatch.newbyte = NewByte; + ModNameFromAddr(Address, newPatch.mod, true); + + // Generate a key for this address + const duint key = ModHashFromAddr(Address); + + EXCLUSIVE_ACQUIRE(LockPatches); + + // Find any patch with this specific address + auto found = patches.find(key); + + if(found != patches.end()) + { + if(found->second.oldbyte == NewByte) + { + // The patch was undone here + patches.erase(found); + return true; + } + + // Keep the original byte from the previous patch + newPatch.oldbyte = found->second.oldbyte; + found->second = newPatch; + } + else + { + // The entry was never found, insert it + patches.insert(std::make_pair(key, newPatch)); + } + + return true; +} + +bool PatchGet(duint Address, PATCHINFO* Patch) +{ + ASSERT_DEBUGGING("Export call"); + SHARED_ACQUIRE(LockPatches); + + // Find this specific address in the list + auto found = patches.find(ModHashFromAddr(Address)); + + if(found == patches.end()) + return false; + + // Did the user request an output buffer? + if(Patch) + { + *Patch = found->second; + Patch->addr += ModBaseFromAddr(Address); + } + + // Return true because the patch was found + return true; +} + +bool PatchDelete(duint Address, bool Restore) +{ + ASSERT_DEBUGGING("Export call"); + EXCLUSIVE_ACQUIRE(LockPatches); + + // Do a list lookup with hash + auto found = patches.find(ModHashFromAddr(Address)); + + if(found == patches.end()) + return false; + + // Restore the original byte at this address + if(Restore) + MemWrite((found->second.addr + ModBaseFromAddr(Address)), &found->second.oldbyte, sizeof(char)); + + // Finally remove it from the list + patches.erase(found); + return true; +} + +void PatchDelRange(duint Start, duint End, bool Restore) +{ + ASSERT_DEBUGGING("Export call"); + + // Are all bookmarks going to be deleted? + // 0x00000000 - 0xFFFFFFFF + if(Start == 0 && End == ~0) + { + EXCLUSIVE_ACQUIRE(LockPatches); + patches.clear(); + } + else + { + // Make sure 'Start' and 'End' reference the same module + duint moduleBase = ModBaseFromAddr(Start); + + if(moduleBase != ModBaseFromAddr(End)) + return; + + // VA to RVA in module + Start -= moduleBase; + End -= moduleBase; + + EXCLUSIVE_ACQUIRE(LockPatches); + for(auto itr = patches.begin(); itr != patches.end();) + { + const auto & currentPatch = itr->second; + // [Start, End) + if(currentPatch.addr >= Start && currentPatch.addr < End) + { + // Restore the original byte if necessary + if(Restore) + MemWrite((currentPatch.addr + moduleBase), ¤tPatch.oldbyte, sizeof(char)); + + itr = patches.erase(itr); + } + else + ++itr; + } + } +} + +bool PatchEnum(PATCHINFO* List, size_t* Size) +{ + ASSERT_DEBUGGING("Export call"); + ASSERT_FALSE(!List && !Size); + SHARED_ACQUIRE(LockPatches); + + // Did the user request the size? + if(Size) + { + *Size = patches.size() * sizeof(PATCHINFO); + + if(!List) + return true; + } + + // Copy each vector entry to a C-style array + for(auto & itr : patches) + { + *List = itr.second; + List->addr += ModBaseFromName(itr.second.mod);; + List++; + } + + return true; +} + +int PatchFile(const PATCHINFO* List, int Count, const char* FileName, char* Error) +{ + // + // This function returns an int based on the number + // of patches applied. -1 indicates a failure. + // + if(Count <= 0) + { + // Notify the user of the error + if(Error) + strcpy_s(Error, MAX_ERROR_SIZE, "No patches to apply"); + + return -1; + } + + // Get a copy of the first module name in the array + char moduleName[MAX_MODULE_SIZE]; + strcpy_s(moduleName, List[0].mod); + + // Check if all patches are in the same module + for(int i = 0; i < Count; i++) + { + if(_stricmp(List[i].mod, moduleName)) + { + if(Error) + sprintf_s(Error, MAX_ERROR_SIZE, "Not all patches are in module %s", moduleName); + + return -1; + } + } + + // See if the module was loaded + duint moduleBase = ModBaseFromName(moduleName); + + if(!moduleBase) + { + if(Error) + sprintf_s(Error, MAX_ERROR_SIZE, "Failed to get base of module %s", moduleName); + + return -1; + } + + // Get the unicode version of the module's path + wchar_t originalName[MAX_PATH]; + + if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)moduleBase, originalName, ARRAYSIZE(originalName))) + { + if(Error) + sprintf_s(Error, MAX_ERROR_SIZE, "Failed to get module path of module %s", moduleName); + + return -1; + } + + // Create a temporary backup file + if(!CopyFileW(originalName, StringUtils::Utf8ToUtf16(FileName).c_str(), false)) + { + if(Error) + strcpy_s(Error, MAX_ERROR_SIZE, "Failed to make a copy of the original file (patch target is in use?)"); + + return -1; + } + + HANDLE fileHandle; + DWORD loadedSize; + HANDLE fileMap; + ULONG_PTR fileMapVa; + if(!StaticFileLoadW(StringUtils::Utf8ToUtf16(FileName).c_str(), UE_ACCESS_ALL, false, &fileHandle, &loadedSize, &fileMap, &fileMapVa)) + { + strcpy_s(Error, MAX_ERROR_SIZE, "StaticFileLoad failed"); + return -1; + } + + // Begin iterating all patches, applying them to a file + int patchCount = 0; + + for(int i = 0; i < Count; i++) + { + // Convert the virtual address to an offset within disk file data + unsigned char* ptr = (unsigned char*)ConvertVAtoFileOffsetEx(fileMapVa, loadedSize, moduleBase, List[i].addr, false, true); + + // Skip patches that do not have a raw address + if(!ptr) + continue; + + *ptr = List[i].newbyte; + patchCount++; + } + + // Unload the file from memory and commit changes to disk + if(!StaticFileUnloadW(StringUtils::Utf8ToUtf16(FileName).c_str(), true, fileHandle, loadedSize, fileMap, fileMapVa)) + { + if(Error) + strcpy_s(Error, MAX_ERROR_SIZE, "StaticFileUnload failed"); + + return -1; + } + + // Zero the error message and return count + if(Error) + memset(Error, 0, MAX_ERROR_SIZE * sizeof(char)); + + return patchCount; +} + +void PatchClear(const char* Module) +{ + EXCLUSIVE_ACQUIRE(LockPatches); + + // Was a module specified? + if(!Module || Module[0] == '\0') + { + // No specific entries to delete, so remove all of them + patches.clear(); + } + else + { + // Otherwise iterate over each patch and check the owner + // module for the address + for(auto itr = patches.begin(); itr != patches.end();) + { + if(!_stricmp(itr->second.mod, Module)) + itr = patches.erase(itr); + else + ++itr; + } + } } \ No newline at end of file diff --git a/src/dbg/patches.h b/src/dbg/patches.h index 2ba26ee2..57169770 100644 --- a/src/dbg/patches.h +++ b/src/dbg/patches.h @@ -1,19 +1,19 @@ -#pragma once - -#include "_global.h" - -struct PATCHINFO -{ - char mod[MAX_MODULE_SIZE]; - duint addr; - unsigned char oldbyte; - unsigned char newbyte; -}; - -bool PatchSet(duint Address, unsigned char OldByte, unsigned char NewByte); -bool PatchGet(duint Address, PATCHINFO* Patch); -bool PatchDelete(duint Address, bool Restore); -void PatchDelRange(duint Start, duint End, bool Restore); -bool PatchEnum(PATCHINFO* List, size_t* Size); -int PatchFile(const PATCHINFO* List, int Count, const char* FileName, char* Error); +#pragma once + +#include "_global.h" + +struct PATCHINFO +{ + char mod[MAX_MODULE_SIZE]; + duint addr; + unsigned char oldbyte; + unsigned char newbyte; +}; + +bool PatchSet(duint Address, unsigned char OldByte, unsigned char NewByte); +bool PatchGet(duint Address, PATCHINFO* Patch); +bool PatchDelete(duint Address, bool Restore); +void PatchDelRange(duint Start, duint End, bool Restore); +bool PatchEnum(PATCHINFO* List, size_t* Size); +int PatchFile(const PATCHINFO* List, int Count, const char* FileName, char* Error); void PatchClear(const char* Module = nullptr); \ No newline at end of file diff --git a/src/dbg/patternfind.cpp b/src/dbg/patternfind.cpp index 9cd056b8..51c3638c 100644 --- a/src/dbg/patternfind.cpp +++ b/src/dbg/patternfind.cpp @@ -1,169 +1,169 @@ -#include "patternfind.h" -#include - -using namespace std; - -static inline bool isHex(char ch) -{ - return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'); -} - -static inline string formathexpattern(const string & patterntext) -{ - string result; - int len = (int)patterntext.length(); - for(int i = 0; i < len; i++) - if(patterntext[i] == '?' || isHex(patterntext[i])) - result += patterntext[i]; - return result; -} - -static inline int hexchtoint(char ch) -{ - if(ch >= '0' && ch <= '9') - return ch - '0'; - else if(ch >= 'A' && ch <= 'F') - return ch - 'A' + 10; - else if(ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - return -1; -} - -bool patterntransform(const string & patterntext, vector & pattern) -{ - pattern.clear(); - string formattext = formathexpattern(patterntext); - int len = (int)formattext.length(); - if(!len) - return false; - - if(len % 2) //not a multiple of 2 - { - formattext += '?'; - len++; - } - - PatternByte newByte; - for(int i = 0, j = 0; i < len; i++) - { - if(formattext[i] == '?') //wildcard - { - newByte.nibble[j].wildcard = true; //match anything - } - else //hex - { - newByte.nibble[j].wildcard = false; - newByte.nibble[j].data = hexchtoint(formattext[i]) & 0xF; - } - - j++; - if(j == 2) //two nibbles = one byte - { - j = 0; - pattern.push_back(newByte); - } - } - return true; -} - -static inline bool patternmatchbyte(unsigned char byte, const PatternByte & pbyte) -{ - int matched = 0; - - unsigned char n1 = (byte >> 4) & 0xF; - if(pbyte.nibble[0].wildcard) - matched++; - else if(pbyte.nibble[0].data == n1) - matched++; - - unsigned char n2 = byte & 0xF; - if(pbyte.nibble[1].wildcard) - matched++; - else if(pbyte.nibble[1].data == n2) - matched++; - - return (matched == 2); -} - -size_t patternfind(const unsigned char* data, size_t datasize, const char* pattern, int* patternsize) -{ - string patterntext(pattern); - vector searchpattern; - if(!patterntransform(patterntext, searchpattern)) - return -1; - return patternfind(data, datasize, searchpattern); -} - -size_t patternfind(const unsigned char* data, size_t datasize, unsigned char* pattern, size_t patternsize) -{ - if(patternsize > datasize) - patternsize = datasize; - for(size_t i = 0, pos = 0; i < datasize; i++) - { - if(data[i] == pattern[pos]) - { - pos++; - if(pos == patternsize) - return i - patternsize + 1; - } - else if(pos > 0) - { - i -= pos; - pos = 0; //reset current pattern position - } - } - return -1; -} - -static inline void patternwritebyte(unsigned char* byte, const PatternByte & pbyte) -{ - unsigned char n1 = (*byte >> 4) & 0xF; - unsigned char n2 = *byte & 0xF; - if(!pbyte.nibble[0].wildcard) - n1 = pbyte.nibble[0].data; - if(!pbyte.nibble[1].wildcard) - n2 = pbyte.nibble[1].data; - *byte = ((n1 << 4) & 0xF0) | (n2 & 0xF); -} - -void patternwrite(unsigned char* data, size_t datasize, const char* pattern) -{ - vector writepattern; - string patterntext(pattern); - if(!patterntransform(patterntext, writepattern)) - return; - size_t writepatternsize = writepattern.size(); - if(writepatternsize > datasize) - writepatternsize = datasize; - for(size_t i = 0; i < writepatternsize; i++) - patternwritebyte(&data[i], writepattern.at(i)); -} - -bool patternsnr(unsigned char* data, size_t datasize, const char* searchpattern, const char* replacepattern) -{ - size_t found = patternfind(data, datasize, searchpattern); - if(found == -1) - return false; - patternwrite(data + found, datasize - found, replacepattern); - return true; -} - -size_t patternfind(const unsigned char* data, size_t datasize, const std::vector & pattern) -{ - size_t searchpatternsize = pattern.size(); - for(size_t i = 0, pos = 0; i < datasize; i++) //search for the pattern - { - if(patternmatchbyte(data[i], pattern.at(pos))) //check if our pattern matches the current byte - { - pos++; - if(pos == searchpatternsize) //everything matched - return i - searchpatternsize + 1; - } - else if(pos > 0) //fix by Computer_Angel - { - i -= pos; - pos = 0; //reset current pattern position - } - } - return -1; +#include "patternfind.h" +#include + +using namespace std; + +static inline bool isHex(char ch) +{ + return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'); +} + +static inline string formathexpattern(const string & patterntext) +{ + string result; + int len = (int)patterntext.length(); + for(int i = 0; i < len; i++) + if(patterntext[i] == '?' || isHex(patterntext[i])) + result += patterntext[i]; + return result; +} + +static inline int hexchtoint(char ch) +{ + if(ch >= '0' && ch <= '9') + return ch - '0'; + else if(ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + else if(ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + return -1; +} + +bool patterntransform(const string & patterntext, vector & pattern) +{ + pattern.clear(); + string formattext = formathexpattern(patterntext); + int len = (int)formattext.length(); + if(!len) + return false; + + if(len % 2) //not a multiple of 2 + { + formattext += '?'; + len++; + } + + PatternByte newByte; + for(int i = 0, j = 0; i < len; i++) + { + if(formattext[i] == '?') //wildcard + { + newByte.nibble[j].wildcard = true; //match anything + } + else //hex + { + newByte.nibble[j].wildcard = false; + newByte.nibble[j].data = hexchtoint(formattext[i]) & 0xF; + } + + j++; + if(j == 2) //two nibbles = one byte + { + j = 0; + pattern.push_back(newByte); + } + } + return true; +} + +static inline bool patternmatchbyte(unsigned char byte, const PatternByte & pbyte) +{ + int matched = 0; + + unsigned char n1 = (byte >> 4) & 0xF; + if(pbyte.nibble[0].wildcard) + matched++; + else if(pbyte.nibble[0].data == n1) + matched++; + + unsigned char n2 = byte & 0xF; + if(pbyte.nibble[1].wildcard) + matched++; + else if(pbyte.nibble[1].data == n2) + matched++; + + return (matched == 2); +} + +size_t patternfind(const unsigned char* data, size_t datasize, const char* pattern, int* patternsize) +{ + string patterntext(pattern); + vector searchpattern; + if(!patterntransform(patterntext, searchpattern)) + return -1; + return patternfind(data, datasize, searchpattern); +} + +size_t patternfind(const unsigned char* data, size_t datasize, unsigned char* pattern, size_t patternsize) +{ + if(patternsize > datasize) + patternsize = datasize; + for(size_t i = 0, pos = 0; i < datasize; i++) + { + if(data[i] == pattern[pos]) + { + pos++; + if(pos == patternsize) + return i - patternsize + 1; + } + else if(pos > 0) + { + i -= pos; + pos = 0; //reset current pattern position + } + } + return -1; +} + +static inline void patternwritebyte(unsigned char* byte, const PatternByte & pbyte) +{ + unsigned char n1 = (*byte >> 4) & 0xF; + unsigned char n2 = *byte & 0xF; + if(!pbyte.nibble[0].wildcard) + n1 = pbyte.nibble[0].data; + if(!pbyte.nibble[1].wildcard) + n2 = pbyte.nibble[1].data; + *byte = ((n1 << 4) & 0xF0) | (n2 & 0xF); +} + +void patternwrite(unsigned char* data, size_t datasize, const char* pattern) +{ + vector writepattern; + string patterntext(pattern); + if(!patterntransform(patterntext, writepattern)) + return; + size_t writepatternsize = writepattern.size(); + if(writepatternsize > datasize) + writepatternsize = datasize; + for(size_t i = 0; i < writepatternsize; i++) + patternwritebyte(&data[i], writepattern.at(i)); +} + +bool patternsnr(unsigned char* data, size_t datasize, const char* searchpattern, const char* replacepattern) +{ + size_t found = patternfind(data, datasize, searchpattern); + if(found == -1) + return false; + patternwrite(data + found, datasize - found, replacepattern); + return true; +} + +size_t patternfind(const unsigned char* data, size_t datasize, const std::vector & pattern) +{ + size_t searchpatternsize = pattern.size(); + for(size_t i = 0, pos = 0; i < datasize; i++) //search for the pattern + { + if(patternmatchbyte(data[i], pattern.at(pos))) //check if our pattern matches the current byte + { + pos++; + if(pos == searchpatternsize) //everything matched + return i - searchpatternsize + 1; + } + else if(pos > 0) //fix by Computer_Angel + { + i -= pos; + pos = 0; //reset current pattern position + } + } + return -1; } \ No newline at end of file diff --git a/src/dbg/patternfind.h b/src/dbg/patternfind.h index 71d5a9bc..b338d3d3 100644 --- a/src/dbg/patternfind.h +++ b/src/dbg/patternfind.h @@ -1,58 +1,58 @@ -#ifndef _PATTERNFIND_H -#define _PATTERNFIND_H - -#include - -struct PatternByte -{ - struct PatternNibble - { - unsigned char data; - bool wildcard; - } nibble[2]; -}; - -//returns: offset to data when found, -1 when not found -size_t patternfind( - const unsigned char* data, //data - size_t datasize, //size of data - const char* pattern, //pattern to search - int* patternsize = 0 //outputs the number of bytes the pattern is -); - -//returns: offset to data when found, -1 when not found -size_t patternfind( - const unsigned char* data, //data - size_t datasize, //size of data - unsigned char* pattern, //bytes to search - size_t patternsize //size of bytes to search -); - -//returns: nothing -void patternwrite( - unsigned char* data, //data - size_t datasize, //size of data - const char* pattern //pattern to write -); - -//returns: true on success, false on failure -bool patternsnr( - unsigned char* data, //data - size_t datasize, //size of data - const char* searchpattern, //pattern to search - const char* replacepattern //pattern to write -); - -//returns: true on success, false on failure -bool patterntransform(const std::string & patterntext, //pattern string - std::vector & pattern //pattern to feed to patternfind - ); - -//returns: offset to data when found, -1 when not found -size_t patternfind( - const unsigned char* data, //data - size_t datasize, //size of data - const std::vector & pattern //pattern to search -); - -#endif // _PATTERNFIND_H +#ifndef _PATTERNFIND_H +#define _PATTERNFIND_H + +#include + +struct PatternByte +{ + struct PatternNibble + { + unsigned char data; + bool wildcard; + } nibble[2]; +}; + +//returns: offset to data when found, -1 when not found +size_t patternfind( + const unsigned char* data, //data + size_t datasize, //size of data + const char* pattern, //pattern to search + int* patternsize = 0 //outputs the number of bytes the pattern is +); + +//returns: offset to data when found, -1 when not found +size_t patternfind( + const unsigned char* data, //data + size_t datasize, //size of data + unsigned char* pattern, //bytes to search + size_t patternsize //size of bytes to search +); + +//returns: nothing +void patternwrite( + unsigned char* data, //data + size_t datasize, //size of data + const char* pattern //pattern to write +); + +//returns: true on success, false on failure +bool patternsnr( + unsigned char* data, //data + size_t datasize, //size of data + const char* searchpattern, //pattern to search + const char* replacepattern //pattern to write +); + +//returns: true on success, false on failure +bool patterntransform(const std::string & patterntext, //pattern string + std::vector & pattern //pattern to feed to patternfind + ); + +//returns: offset to data when found, -1 when not found +size_t patternfind( + const unsigned char* data, //data + size_t datasize, //size of data + const std::vector & pattern //pattern to search +); + +#endif // _PATTERNFIND_H diff --git a/src/dbg/plugin_loader.cpp b/src/dbg/plugin_loader.cpp index a81051cf..f54285f5 100644 --- a/src/dbg/plugin_loader.cpp +++ b/src/dbg/plugin_loader.cpp @@ -1,663 +1,663 @@ -/** - @file plugin_loader.cpp - - @brief Implements the plugin loader. - */ - -#include "plugin_loader.h" -#include "console.h" -#include "debugger.h" -#include "threading.h" - -/** -\brief List of plugins. -*/ -static std::vector pluginList; - -/** -\brief The current plugin handle. -*/ -static int curPluginHandle = 0; - -/** -\brief List of plugin callbacks. -*/ -static std::vector pluginCallbackList; - -/** -\brief List of plugin commands. -*/ -static std::vector pluginCommandList; - -/** -\brief List of plugin menus. -*/ -static std::vector pluginMenuList; - -/** -\brief Loads plugins from a specified directory. -\param pluginDir The directory to load plugins from. -*/ -void pluginload(const char* pluginDir) -{ - //load new plugins - wchar_t currentDir[deflen] = L""; - GetCurrentDirectoryW(deflen, currentDir); - SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(pluginDir).c_str()); - char searchName[deflen] = ""; -#ifdef _WIN64 - sprintf(searchName, "%s\\*.dp64", pluginDir); -#else - sprintf(searchName, "%s\\*.dp32", pluginDir); -#endif // _WIN64 - WIN32_FIND_DATAW foundData; - HANDLE hSearch = FindFirstFileW(StringUtils::Utf8ToUtf16(searchName).c_str(), &foundData); - if(hSearch == INVALID_HANDLE_VALUE) - { - SetCurrentDirectoryW(currentDir); - return; - } - PLUG_DATA pluginData; - do - { - //set plugin data - pluginData.initStruct.pluginHandle = curPluginHandle; - char szPluginPath[MAX_PATH] = ""; - sprintf_s(szPluginPath, "%s\\%s", pluginDir, StringUtils::Utf16ToUtf8(foundData.cFileName).c_str()); - pluginData.hPlugin = LoadLibraryW(StringUtils::Utf8ToUtf16(szPluginPath).c_str()); //load the plugin library - if(!pluginData.hPlugin) - { - dprintf("[PLUGIN] Failed to load plugin: %s\n", StringUtils::Utf16ToUtf8(foundData.cFileName).c_str()); - continue; - } - pluginData.pluginit = (PLUGINIT)GetProcAddress(pluginData.hPlugin, "pluginit"); - if(!pluginData.pluginit) - { - dprintf("[PLUGIN] Export \"pluginit\" not found in plugin: %s\n", StringUtils::Utf16ToUtf8(foundData.cFileName).c_str()); - FreeLibrary(pluginData.hPlugin); - continue; - } - pluginData.plugstop = (PLUGSTOP)GetProcAddress(pluginData.hPlugin, "plugstop"); - pluginData.plugsetup = (PLUGSETUP)GetProcAddress(pluginData.hPlugin, "plugsetup"); - - //auto-register callbacks for certain export names - CBPLUGIN cbPlugin; - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBALLEVENTS"); - if(cbPlugin) - { - pluginregistercallback(curPluginHandle, CB_INITDEBUG, cbPlugin); - pluginregistercallback(curPluginHandle, CB_STOPDEBUG, cbPlugin); - pluginregistercallback(curPluginHandle, CB_CREATEPROCESS, cbPlugin); - pluginregistercallback(curPluginHandle, CB_EXITPROCESS, cbPlugin); - pluginregistercallback(curPluginHandle, CB_CREATETHREAD, cbPlugin); - pluginregistercallback(curPluginHandle, CB_EXITTHREAD, cbPlugin); - pluginregistercallback(curPluginHandle, CB_SYSTEMBREAKPOINT, cbPlugin); - pluginregistercallback(curPluginHandle, CB_LOADDLL, cbPlugin); - pluginregistercallback(curPluginHandle, CB_UNLOADDLL, cbPlugin); - pluginregistercallback(curPluginHandle, CB_OUTPUTDEBUGSTRING, cbPlugin); - pluginregistercallback(curPluginHandle, CB_EXCEPTION, cbPlugin); - pluginregistercallback(curPluginHandle, CB_BREAKPOINT, cbPlugin); - pluginregistercallback(curPluginHandle, CB_PAUSEDEBUG, cbPlugin); - pluginregistercallback(curPluginHandle, CB_RESUMEDEBUG, cbPlugin); - pluginregistercallback(curPluginHandle, CB_STEPPED, cbPlugin); - pluginregistercallback(curPluginHandle, CB_ATTACH, cbPlugin); - pluginregistercallback(curPluginHandle, CB_DETACH, cbPlugin); - pluginregistercallback(curPluginHandle, CB_DEBUGEVENT, cbPlugin); - pluginregistercallback(curPluginHandle, CB_MENUENTRY, cbPlugin); - pluginregistercallback(curPluginHandle, CB_WINEVENT, cbPlugin); - pluginregistercallback(curPluginHandle, CB_WINEVENTGLOBAL, cbPlugin); - } - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBINITDEBUG"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_INITDEBUG, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBSTOPDEBUG"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_STOPDEBUG, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBCREATEPROCESS"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_CREATEPROCESS, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBEXITPROCESS"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_EXITPROCESS, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBCREATETHREAD"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_CREATETHREAD, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBEXITTHREAD"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_EXITTHREAD, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBSYSTEMBREAKPOINT"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_SYSTEMBREAKPOINT, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBLOADDLL"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_LOADDLL, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBUNLOADDLL"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_UNLOADDLL, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBOUTPUTDEBUGSTRING"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_OUTPUTDEBUGSTRING, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBEXCEPTION"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_EXCEPTION, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBBREAKPOINT"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_BREAKPOINT, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBPAUSEDEBUG"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_PAUSEDEBUG, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBRESUMEDEBUG"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_RESUMEDEBUG, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBSTEPPED"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_STEPPED, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBATTACH"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_ATTACH, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBDETACH"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_DETACH, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBDEBUGEVENT"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_DEBUGEVENT, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBMENUENTRY"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_MENUENTRY, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBWINEVENT"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_WINEVENT, cbPlugin); - cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBWINEVENTGLOBAL"); - if(cbPlugin) - pluginregistercallback(curPluginHandle, CB_WINEVENTGLOBAL, cbPlugin); - - //init plugin - if(!pluginData.pluginit(&pluginData.initStruct)) - { - dprintf("[PLUGIN] pluginit failed for plugin: %s\n", foundData.cFileName); - FreeLibrary(pluginData.hPlugin); - continue; - } - else if(pluginData.initStruct.sdkVersion < PLUG_SDKVERSION) //the plugin SDK is not compatible - { - dprintf("[PLUGIN] %s is incompatible with this SDK version\n", pluginData.initStruct.pluginName); - FreeLibrary(pluginData.hPlugin); - continue; - } - else - dprintf("[PLUGIN] %s v%d Loaded!\n", pluginData.initStruct.pluginName, pluginData.initStruct.pluginVersion); - - SectionLocker menuLock; //exclusive lock - - //add plugin menu - int hNewMenu = GuiMenuAdd(GUI_PLUGIN_MENU, pluginData.initStruct.pluginName); - if(hNewMenu == -1) - { - dprintf("[PLUGIN] GuiMenuAdd(GUI_PLUGIN_MENU) failed for plugin: %s\n", pluginData.initStruct.pluginName); - pluginData.hMenu = -1; - } - else - { - PLUG_MENU newMenu; - newMenu.hEntryMenu = hNewMenu; - newMenu.hEntryPlugin = -1; - newMenu.pluginHandle = pluginData.initStruct.pluginHandle; - pluginMenuList.push_back(newMenu); - pluginData.hMenu = newMenu.hEntryMenu; - } - - //add disasm plugin menu - hNewMenu = GuiMenuAdd(GUI_DISASM_MENU, pluginData.initStruct.pluginName); - if(hNewMenu == -1) - { - dprintf("[PLUGIN] GuiMenuAdd(GUI_DISASM_MENU) failed for plugin: %s\n", pluginData.initStruct.pluginName); - pluginData.hMenu = -1; - } - else - { - PLUG_MENU newMenu; - newMenu.hEntryMenu = hNewMenu; - newMenu.hEntryPlugin = -1; - newMenu.pluginHandle = pluginData.initStruct.pluginHandle; - pluginMenuList.push_back(newMenu); - pluginData.hMenuDisasm = newMenu.hEntryMenu; - } - - //add dump plugin menu - hNewMenu = GuiMenuAdd(GUI_DUMP_MENU, pluginData.initStruct.pluginName); - if(hNewMenu == -1) - { - dprintf("[PLUGIN] GuiMenuAdd(GUI_DUMP_MENU) failed for plugin: %s\n", pluginData.initStruct.pluginName); - pluginData.hMenu = -1; - } - else - { - PLUG_MENU newMenu; - newMenu.hEntryMenu = hNewMenu; - newMenu.hEntryPlugin = -1; - newMenu.pluginHandle = pluginData.initStruct.pluginHandle; - pluginMenuList.push_back(newMenu); - pluginData.hMenuDump = newMenu.hEntryMenu; - } - - //add stack plugin menu - hNewMenu = GuiMenuAdd(GUI_STACK_MENU, pluginData.initStruct.pluginName); - if(hNewMenu == -1) - { - dprintf("[PLUGIN] GuiMenuAdd(GUI_STACK_MENU) failed for plugin: %s\n", pluginData.initStruct.pluginName); - pluginData.hMenu = -1; - } - else - { - PLUG_MENU newMenu; - newMenu.hEntryMenu = hNewMenu; - newMenu.hEntryPlugin = -1; - newMenu.pluginHandle = pluginData.initStruct.pluginHandle; - pluginMenuList.push_back(newMenu); - pluginData.hMenuStack = newMenu.hEntryMenu; - } - menuLock.Unlock(); - - //add the plugin to the list - SectionLocker pluginLock; //exclusive lock - pluginList.push_back(pluginData); - pluginLock.Unlock(); - - //setup plugin - if(pluginData.plugsetup) - { - PLUG_SETUPSTRUCT setupStruct; - setupStruct.hwndDlg = GuiGetWindowHandle(); - setupStruct.hMenu = pluginData.hMenu; - setupStruct.hMenuDisasm = pluginData.hMenuDisasm; - setupStruct.hMenuDump = pluginData.hMenuDump; - setupStruct.hMenuStack = pluginData.hMenuStack; - pluginData.plugsetup(&setupStruct); - } - curPluginHandle++; - } - while(FindNextFileW(hSearch, &foundData)); - SetCurrentDirectoryW(currentDir); -} - -/** -\brief Unregister all plugin commands. -\param pluginHandle Handle of the plugin to remove the commands from. -*/ -static void plugincmdunregisterall(int pluginHandle) -{ - SHARED_ACQUIRE(LockPluginCommandList); - auto commandList = pluginCommandList; //copy for thread-safety reasons - SHARED_RELEASE(); - auto i = commandList.begin(); - while(i != commandList.end()) - { - auto currentCommand = *i; - if(currentCommand.pluginHandle == pluginHandle) - { - i = commandList.erase(i); - dbgcmddel(currentCommand.command); - } - else - ++i; - } -} - -/** -\brief Unloads all plugins. -*/ -void pluginunload() -{ - { - EXCLUSIVE_ACQUIRE(LockPluginList); - for(const auto & currentPlugin : pluginList) //call plugin stop & unregister all plugin commands - { - PLUGSTOP stop = currentPlugin.plugstop; - if(stop) - stop(); - plugincmdunregisterall(currentPlugin.initStruct.pluginHandle); - } - } - { - EXCLUSIVE_ACQUIRE(LockPluginCallbackList); - pluginCallbackList.clear(); //remove all callbacks - } - { - EXCLUSIVE_ACQUIRE(LockPluginMenuList); - pluginMenuList.clear(); //clear menu list - } - { - EXCLUSIVE_ACQUIRE(LockPluginList); - for(const auto & currentPlugin : pluginList) //free the libraries - FreeLibrary(currentPlugin.hPlugin); - } - GuiMenuClear(GUI_PLUGIN_MENU); //clear the plugin menu -} - -/** -\brief Register a plugin callback. -\param pluginHandle Handle of the plugin to register a callback for. -\param cbType The type of the callback to register. -\param cbPlugin The actual callback function. -*/ -void pluginregistercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin) -{ - pluginunregistercallback(pluginHandle, cbType); //remove previous callback - PLUG_CALLBACK cbStruct; - cbStruct.pluginHandle = pluginHandle; - cbStruct.cbType = cbType; - cbStruct.cbPlugin = cbPlugin; - EXCLUSIVE_ACQUIRE(LockPluginCallbackList); - pluginCallbackList.push_back(cbStruct); -} - -/** -\brief Unregister all plugin callbacks of a certain type. -\param pluginHandle Handle of the plugin to unregister a callback from. -\param cbType The type of the callback to unregister. -*/ -bool pluginunregistercallback(int pluginHandle, CBTYPE cbType) -{ - EXCLUSIVE_ACQUIRE(LockPluginCallbackList); - for(auto it = pluginCallbackList.begin(); it != pluginCallbackList.end(); ++it) - { - const auto & currentCallback = *it; - if(currentCallback.pluginHandle == pluginHandle && currentCallback.cbType == cbType) - { - pluginCallbackList.erase(it); - return true; - } - } - return false; -} - -/** -\brief Call all registered callbacks of a certain type. -\param cbType The type of callbacks to call. -\param [in,out] callbackInfo Information describing the callback. See plugin documentation for more information on this. -*/ -void plugincbcall(CBTYPE cbType, void* callbackInfo) -{ - SHARED_ACQUIRE(LockPluginCallbackList); - auto callbackList = pluginCallbackList; //copy for thread-safety reasons - SHARED_RELEASE(); - for(const auto & currentCallback : callbackList) - { - if(currentCallback.cbType == cbType) - { - CBPLUGIN cbPlugin = currentCallback.cbPlugin; - if(!IsBadReadPtr((const void*)cbPlugin, sizeof(duint))) - cbPlugin(cbType, callbackInfo); - } - } -} - -/** -\brief Register a plugin command. -\param pluginHandle Handle of the plugin to register a command for. -\param command The command text to register. This text cannot contain the '\1' character. This text is not case sensitive. -\param cbCommand The command callback. -\param debugonly true if the command can only be called during debugging. -\return true if it the registration succeeded, false otherwise. -*/ -bool plugincmdregister(int pluginHandle, const char* command, CBPLUGINCOMMAND cbCommand, bool debugonly) -{ - if(!command || strlen(command) >= deflen || strstr(command, "\1")) - return false; - PLUG_COMMAND plugCmd; - plugCmd.pluginHandle = pluginHandle; - strcpy_s(plugCmd.command, command); - if(!dbgcmdnew(command, (CBCOMMAND)cbCommand, debugonly)) - return false; - EXCLUSIVE_ACQUIRE(LockPluginCommandList); - pluginCommandList.push_back(plugCmd); - EXCLUSIVE_RELEASE(); - dprintf("[PLUGIN] command \"%s\" registered!\n", command); - return true; -} - -/** -\brief Unregister a plugin command. -\param pluginHandle Handle of the plugin to unregister the command from. -\param command The command text to unregister. This text is not case sensitive. -\return true if the command was found and removed, false otherwise. -*/ -bool plugincmdunregister(int pluginHandle, const char* command) -{ - if(!command || strlen(command) >= deflen || strstr(command, "\1")) - return false; - EXCLUSIVE_ACQUIRE(LockPluginCommandList); - for(auto it = pluginCommandList.begin(); it != pluginCommandList.end(); ++it) - { - const auto & currentCommand = *it; - if(currentCommand.pluginHandle == pluginHandle && !strcmp(currentCommand.command, command)) - { - pluginCommandList.erase(it); - EXCLUSIVE_RELEASE(); - if(!dbgcmddel(command)) - return false; - dprintf("[PLUGIN] command \"%s\" unregistered!\n", command); - return true; - } - } - return false; -} - -/** -\brief Add a new plugin (sub)menu. -\param hMenu The menu handle to add the (sub)menu to. -\param title The title of the (sub)menu. -\return The handle of the new (sub)menu. -*/ -int pluginmenuadd(int hMenu, const char* title) -{ - if(!title || !strlen(title)) - return -1; - EXCLUSIVE_ACQUIRE(LockPluginMenuList); - int nFound = -1; - for(unsigned int i = 0; i < pluginMenuList.size(); i++) - { - if(pluginMenuList.at(i).hEntryMenu == hMenu && pluginMenuList.at(i).hEntryPlugin == -1) - { - nFound = i; - break; - } - } - if(nFound == -1) //not a valid menu handle - return -1; - int hMenuNew = GuiMenuAdd(pluginMenuList.at(nFound).hEntryMenu, title); - PLUG_MENU newMenu; - newMenu.pluginHandle = pluginMenuList.at(nFound).pluginHandle; - newMenu.hEntryPlugin = -1; - newMenu.hEntryMenu = hMenuNew; - pluginMenuList.push_back(newMenu); - return hMenuNew; -} - -/** -\brief Add a plugin menu entry to a menu. -\param hMenu The menu to add the entry to. -\param hEntry The handle you like to have the entry. This should be a unique value in the scope of the plugin that registered the \p hMenu. -\param title The menu entry title. -\return true if the \p hEntry was unique and the entry was successfully added, false otherwise. -*/ -bool pluginmenuaddentry(int hMenu, int hEntry, const char* title) -{ - if(!title || !strlen(title) || hEntry == -1) - return false; - EXCLUSIVE_ACQUIRE(LockPluginMenuList); - int pluginHandle = -1; - //find plugin handle - for(const auto & currentMenu : pluginMenuList) - { - if(currentMenu.hEntryMenu == hMenu && currentMenu.hEntryPlugin == -1) - { - pluginHandle = currentMenu.pluginHandle; - break; - } - } - if(pluginHandle == -1) //not found - return false; - //search if hEntry was previously used - for(const auto & currentMenu : pluginMenuList) - if(currentMenu.pluginHandle == pluginHandle && currentMenu.hEntryPlugin == hEntry) - return false; - int hNewEntry = GuiMenuAddEntry(hMenu, title); - if(hNewEntry == -1) - return false; - PLUG_MENU newMenu; - newMenu.hEntryMenu = hNewEntry; - newMenu.hEntryPlugin = hEntry; - newMenu.pluginHandle = pluginHandle; - pluginMenuList.push_back(newMenu); - return true; -} - -/** -\brief Add a menu separator to a menu. -\param hMenu The menu to add the separator to. -\return true if it succeeds, false otherwise. -*/ -bool pluginmenuaddseparator(int hMenu) -{ - SHARED_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuList) - { - if(currentMenu.hEntryMenu == hMenu && currentMenu.hEntryPlugin == -1) - { - GuiMenuAddSeparator(hMenu); - return true; - } - } - return false; -} - -/** -\brief Clears a plugin menu. -\param hMenu The menu to clear. -\return true if it succeeds, false otherwise. -*/ -bool pluginmenuclear(int hMenu) -{ - EXCLUSIVE_ACQUIRE(LockPluginMenuList); - bool bFound = false; - for(auto it = pluginMenuList.begin(); it != pluginMenuList.end(); ++it) - { - const auto & currentMenu = *it; - if(currentMenu.hEntryMenu == hMenu && currentMenu.hEntryPlugin == -1) - { - it = pluginMenuList.erase(it); - bFound = true; - } - } - if(!bFound) - return false; - GuiMenuClear(hMenu); - return true; -} - -/** -\brief Call the registered CB_MENUENTRY callbacks for a menu entry. -\param hEntry The menu entry that triggered the event. -*/ -void pluginmenucall(int hEntry) -{ - if(hEntry == -1) - return; - - SectionLocker menuLock; //shared lock - auto i = pluginMenuList.begin(); - while(i != pluginMenuList.end()) - { - const auto currentMenu = *i; - ++i; - if(currentMenu.hEntryMenu == hEntry && currentMenu.hEntryPlugin != -1) - { - PLUG_CB_MENUENTRY menuEntryInfo; - menuEntryInfo.hEntry = currentMenu.hEntryPlugin; - SectionLocker callbackLock; //shared lock - auto j = pluginCallbackList.begin(); - while(j != pluginCallbackList.end()) - { - const auto currentCallback = *j; - ++j; - if(currentCallback.pluginHandle == currentMenu.pluginHandle && currentCallback.cbType == CB_MENUENTRY) - { - menuLock.Unlock(); - callbackLock.Unlock(); - currentCallback.cbPlugin(CB_MENUENTRY, &menuEntryInfo); - return; - } - } - } - } -} - -/** -\brief Calls the registered CB_WINEVENT callbacks. -\param [in,out] message the message that triggered the event. Cannot be null. -\param [out] result The result value. Cannot be null. -\return The value the plugin told it to return. See plugin documentation for more information. -*/ -bool pluginwinevent(MSG* message, long* result) -{ - PLUG_CB_WINEVENT winevent; - winevent.message = message; - winevent.result = result; - winevent.retval = false; - plugincbcall(CB_WINEVENT, &winevent); - return winevent.retval; -} - -/** -\brief Calls the registered CB_WINEVENTGLOBAL callbacks. -\param [in,out] message the message that triggered the event. Cannot be null. -\return The value the plugin told it to return. See plugin documentation for more information. -*/ -bool pluginwineventglobal(MSG* message) -{ - PLUG_CB_WINEVENTGLOBAL winevent; - winevent.message = message; - winevent.retval = false; - plugincbcall(CB_WINEVENTGLOBAL, &winevent); - return winevent.retval; -} - -/** -\brief Sets an icon for a menu. -\param hMenu The menu handle. -\param icon The icon (can be all kinds of formats). -*/ -void pluginmenuseticon(int hMenu, const ICONDATA* icon) -{ - SHARED_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuList) - { - if(currentMenu.hEntryMenu == hMenu && currentMenu.hEntryPlugin == -1) - { - GuiMenuSetIcon(hMenu, icon); - break; - } - } -} - -/** -\brief Sets an icon for a menu entry. -\param pluginHandle Plugin handle. -\param hEntry The menu entry handle (unique per plugin). -\param icon The icon (can be all kinds of formats). -*/ -void pluginmenuentryseticon(int pluginHandle, int hEntry, const ICONDATA* icon) -{ - if(hEntry == -1) - return; - SHARED_ACQUIRE(LockPluginMenuList); - for(const auto & currentMenu : pluginMenuList) - { - if(currentMenu.pluginHandle == pluginHandle && currentMenu.hEntryPlugin == hEntry) - { - GuiMenuSetEntryIcon(currentMenu.hEntryMenu, icon); - break; - } - } +/** + @file plugin_loader.cpp + + @brief Implements the plugin loader. + */ + +#include "plugin_loader.h" +#include "console.h" +#include "debugger.h" +#include "threading.h" + +/** +\brief List of plugins. +*/ +static std::vector pluginList; + +/** +\brief The current plugin handle. +*/ +static int curPluginHandle = 0; + +/** +\brief List of plugin callbacks. +*/ +static std::vector pluginCallbackList; + +/** +\brief List of plugin commands. +*/ +static std::vector pluginCommandList; + +/** +\brief List of plugin menus. +*/ +static std::vector pluginMenuList; + +/** +\brief Loads plugins from a specified directory. +\param pluginDir The directory to load plugins from. +*/ +void pluginload(const char* pluginDir) +{ + //load new plugins + wchar_t currentDir[deflen] = L""; + GetCurrentDirectoryW(deflen, currentDir); + SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(pluginDir).c_str()); + char searchName[deflen] = ""; +#ifdef _WIN64 + sprintf(searchName, "%s\\*.dp64", pluginDir); +#else + sprintf(searchName, "%s\\*.dp32", pluginDir); +#endif // _WIN64 + WIN32_FIND_DATAW foundData; + HANDLE hSearch = FindFirstFileW(StringUtils::Utf8ToUtf16(searchName).c_str(), &foundData); + if(hSearch == INVALID_HANDLE_VALUE) + { + SetCurrentDirectoryW(currentDir); + return; + } + PLUG_DATA pluginData; + do + { + //set plugin data + pluginData.initStruct.pluginHandle = curPluginHandle; + char szPluginPath[MAX_PATH] = ""; + sprintf_s(szPluginPath, "%s\\%s", pluginDir, StringUtils::Utf16ToUtf8(foundData.cFileName).c_str()); + pluginData.hPlugin = LoadLibraryW(StringUtils::Utf8ToUtf16(szPluginPath).c_str()); //load the plugin library + if(!pluginData.hPlugin) + { + dprintf("[PLUGIN] Failed to load plugin: %s\n", StringUtils::Utf16ToUtf8(foundData.cFileName).c_str()); + continue; + } + pluginData.pluginit = (PLUGINIT)GetProcAddress(pluginData.hPlugin, "pluginit"); + if(!pluginData.pluginit) + { + dprintf("[PLUGIN] Export \"pluginit\" not found in plugin: %s\n", StringUtils::Utf16ToUtf8(foundData.cFileName).c_str()); + FreeLibrary(pluginData.hPlugin); + continue; + } + pluginData.plugstop = (PLUGSTOP)GetProcAddress(pluginData.hPlugin, "plugstop"); + pluginData.plugsetup = (PLUGSETUP)GetProcAddress(pluginData.hPlugin, "plugsetup"); + + //auto-register callbacks for certain export names + CBPLUGIN cbPlugin; + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBALLEVENTS"); + if(cbPlugin) + { + pluginregistercallback(curPluginHandle, CB_INITDEBUG, cbPlugin); + pluginregistercallback(curPluginHandle, CB_STOPDEBUG, cbPlugin); + pluginregistercallback(curPluginHandle, CB_CREATEPROCESS, cbPlugin); + pluginregistercallback(curPluginHandle, CB_EXITPROCESS, cbPlugin); + pluginregistercallback(curPluginHandle, CB_CREATETHREAD, cbPlugin); + pluginregistercallback(curPluginHandle, CB_EXITTHREAD, cbPlugin); + pluginregistercallback(curPluginHandle, CB_SYSTEMBREAKPOINT, cbPlugin); + pluginregistercallback(curPluginHandle, CB_LOADDLL, cbPlugin); + pluginregistercallback(curPluginHandle, CB_UNLOADDLL, cbPlugin); + pluginregistercallback(curPluginHandle, CB_OUTPUTDEBUGSTRING, cbPlugin); + pluginregistercallback(curPluginHandle, CB_EXCEPTION, cbPlugin); + pluginregistercallback(curPluginHandle, CB_BREAKPOINT, cbPlugin); + pluginregistercallback(curPluginHandle, CB_PAUSEDEBUG, cbPlugin); + pluginregistercallback(curPluginHandle, CB_RESUMEDEBUG, cbPlugin); + pluginregistercallback(curPluginHandle, CB_STEPPED, cbPlugin); + pluginregistercallback(curPluginHandle, CB_ATTACH, cbPlugin); + pluginregistercallback(curPluginHandle, CB_DETACH, cbPlugin); + pluginregistercallback(curPluginHandle, CB_DEBUGEVENT, cbPlugin); + pluginregistercallback(curPluginHandle, CB_MENUENTRY, cbPlugin); + pluginregistercallback(curPluginHandle, CB_WINEVENT, cbPlugin); + pluginregistercallback(curPluginHandle, CB_WINEVENTGLOBAL, cbPlugin); + } + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBINITDEBUG"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_INITDEBUG, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBSTOPDEBUG"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_STOPDEBUG, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBCREATEPROCESS"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_CREATEPROCESS, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBEXITPROCESS"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_EXITPROCESS, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBCREATETHREAD"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_CREATETHREAD, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBEXITTHREAD"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_EXITTHREAD, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBSYSTEMBREAKPOINT"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_SYSTEMBREAKPOINT, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBLOADDLL"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_LOADDLL, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBUNLOADDLL"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_UNLOADDLL, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBOUTPUTDEBUGSTRING"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_OUTPUTDEBUGSTRING, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBEXCEPTION"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_EXCEPTION, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBBREAKPOINT"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_BREAKPOINT, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBPAUSEDEBUG"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_PAUSEDEBUG, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBRESUMEDEBUG"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_RESUMEDEBUG, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBSTEPPED"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_STEPPED, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBATTACH"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_ATTACH, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBDETACH"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_DETACH, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBDEBUGEVENT"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_DEBUGEVENT, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBMENUENTRY"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_MENUENTRY, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBWINEVENT"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_WINEVENT, cbPlugin); + cbPlugin = (CBPLUGIN)GetProcAddress(pluginData.hPlugin, "CBWINEVENTGLOBAL"); + if(cbPlugin) + pluginregistercallback(curPluginHandle, CB_WINEVENTGLOBAL, cbPlugin); + + //init plugin + if(!pluginData.pluginit(&pluginData.initStruct)) + { + dprintf("[PLUGIN] pluginit failed for plugin: %s\n", foundData.cFileName); + FreeLibrary(pluginData.hPlugin); + continue; + } + else if(pluginData.initStruct.sdkVersion < PLUG_SDKVERSION) //the plugin SDK is not compatible + { + dprintf("[PLUGIN] %s is incompatible with this SDK version\n", pluginData.initStruct.pluginName); + FreeLibrary(pluginData.hPlugin); + continue; + } + else + dprintf("[PLUGIN] %s v%d Loaded!\n", pluginData.initStruct.pluginName, pluginData.initStruct.pluginVersion); + + SectionLocker menuLock; //exclusive lock + + //add plugin menu + int hNewMenu = GuiMenuAdd(GUI_PLUGIN_MENU, pluginData.initStruct.pluginName); + if(hNewMenu == -1) + { + dprintf("[PLUGIN] GuiMenuAdd(GUI_PLUGIN_MENU) failed for plugin: %s\n", pluginData.initStruct.pluginName); + pluginData.hMenu = -1; + } + else + { + PLUG_MENU newMenu; + newMenu.hEntryMenu = hNewMenu; + newMenu.hEntryPlugin = -1; + newMenu.pluginHandle = pluginData.initStruct.pluginHandle; + pluginMenuList.push_back(newMenu); + pluginData.hMenu = newMenu.hEntryMenu; + } + + //add disasm plugin menu + hNewMenu = GuiMenuAdd(GUI_DISASM_MENU, pluginData.initStruct.pluginName); + if(hNewMenu == -1) + { + dprintf("[PLUGIN] GuiMenuAdd(GUI_DISASM_MENU) failed for plugin: %s\n", pluginData.initStruct.pluginName); + pluginData.hMenu = -1; + } + else + { + PLUG_MENU newMenu; + newMenu.hEntryMenu = hNewMenu; + newMenu.hEntryPlugin = -1; + newMenu.pluginHandle = pluginData.initStruct.pluginHandle; + pluginMenuList.push_back(newMenu); + pluginData.hMenuDisasm = newMenu.hEntryMenu; + } + + //add dump plugin menu + hNewMenu = GuiMenuAdd(GUI_DUMP_MENU, pluginData.initStruct.pluginName); + if(hNewMenu == -1) + { + dprintf("[PLUGIN] GuiMenuAdd(GUI_DUMP_MENU) failed for plugin: %s\n", pluginData.initStruct.pluginName); + pluginData.hMenu = -1; + } + else + { + PLUG_MENU newMenu; + newMenu.hEntryMenu = hNewMenu; + newMenu.hEntryPlugin = -1; + newMenu.pluginHandle = pluginData.initStruct.pluginHandle; + pluginMenuList.push_back(newMenu); + pluginData.hMenuDump = newMenu.hEntryMenu; + } + + //add stack plugin menu + hNewMenu = GuiMenuAdd(GUI_STACK_MENU, pluginData.initStruct.pluginName); + if(hNewMenu == -1) + { + dprintf("[PLUGIN] GuiMenuAdd(GUI_STACK_MENU) failed for plugin: %s\n", pluginData.initStruct.pluginName); + pluginData.hMenu = -1; + } + else + { + PLUG_MENU newMenu; + newMenu.hEntryMenu = hNewMenu; + newMenu.hEntryPlugin = -1; + newMenu.pluginHandle = pluginData.initStruct.pluginHandle; + pluginMenuList.push_back(newMenu); + pluginData.hMenuStack = newMenu.hEntryMenu; + } + menuLock.Unlock(); + + //add the plugin to the list + SectionLocker pluginLock; //exclusive lock + pluginList.push_back(pluginData); + pluginLock.Unlock(); + + //setup plugin + if(pluginData.plugsetup) + { + PLUG_SETUPSTRUCT setupStruct; + setupStruct.hwndDlg = GuiGetWindowHandle(); + setupStruct.hMenu = pluginData.hMenu; + setupStruct.hMenuDisasm = pluginData.hMenuDisasm; + setupStruct.hMenuDump = pluginData.hMenuDump; + setupStruct.hMenuStack = pluginData.hMenuStack; + pluginData.plugsetup(&setupStruct); + } + curPluginHandle++; + } + while(FindNextFileW(hSearch, &foundData)); + SetCurrentDirectoryW(currentDir); +} + +/** +\brief Unregister all plugin commands. +\param pluginHandle Handle of the plugin to remove the commands from. +*/ +static void plugincmdunregisterall(int pluginHandle) +{ + SHARED_ACQUIRE(LockPluginCommandList); + auto commandList = pluginCommandList; //copy for thread-safety reasons + SHARED_RELEASE(); + auto i = commandList.begin(); + while(i != commandList.end()) + { + auto currentCommand = *i; + if(currentCommand.pluginHandle == pluginHandle) + { + i = commandList.erase(i); + dbgcmddel(currentCommand.command); + } + else + ++i; + } +} + +/** +\brief Unloads all plugins. +*/ +void pluginunload() +{ + { + EXCLUSIVE_ACQUIRE(LockPluginList); + for(const auto & currentPlugin : pluginList) //call plugin stop & unregister all plugin commands + { + PLUGSTOP stop = currentPlugin.plugstop; + if(stop) + stop(); + plugincmdunregisterall(currentPlugin.initStruct.pluginHandle); + } + } + { + EXCLUSIVE_ACQUIRE(LockPluginCallbackList); + pluginCallbackList.clear(); //remove all callbacks + } + { + EXCLUSIVE_ACQUIRE(LockPluginMenuList); + pluginMenuList.clear(); //clear menu list + } + { + EXCLUSIVE_ACQUIRE(LockPluginList); + for(const auto & currentPlugin : pluginList) //free the libraries + FreeLibrary(currentPlugin.hPlugin); + } + GuiMenuClear(GUI_PLUGIN_MENU); //clear the plugin menu +} + +/** +\brief Register a plugin callback. +\param pluginHandle Handle of the plugin to register a callback for. +\param cbType The type of the callback to register. +\param cbPlugin The actual callback function. +*/ +void pluginregistercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin) +{ + pluginunregistercallback(pluginHandle, cbType); //remove previous callback + PLUG_CALLBACK cbStruct; + cbStruct.pluginHandle = pluginHandle; + cbStruct.cbType = cbType; + cbStruct.cbPlugin = cbPlugin; + EXCLUSIVE_ACQUIRE(LockPluginCallbackList); + pluginCallbackList.push_back(cbStruct); +} + +/** +\brief Unregister all plugin callbacks of a certain type. +\param pluginHandle Handle of the plugin to unregister a callback from. +\param cbType The type of the callback to unregister. +*/ +bool pluginunregistercallback(int pluginHandle, CBTYPE cbType) +{ + EXCLUSIVE_ACQUIRE(LockPluginCallbackList); + for(auto it = pluginCallbackList.begin(); it != pluginCallbackList.end(); ++it) + { + const auto & currentCallback = *it; + if(currentCallback.pluginHandle == pluginHandle && currentCallback.cbType == cbType) + { + pluginCallbackList.erase(it); + return true; + } + } + return false; +} + +/** +\brief Call all registered callbacks of a certain type. +\param cbType The type of callbacks to call. +\param [in,out] callbackInfo Information describing the callback. See plugin documentation for more information on this. +*/ +void plugincbcall(CBTYPE cbType, void* callbackInfo) +{ + SHARED_ACQUIRE(LockPluginCallbackList); + auto callbackList = pluginCallbackList; //copy for thread-safety reasons + SHARED_RELEASE(); + for(const auto & currentCallback : callbackList) + { + if(currentCallback.cbType == cbType) + { + CBPLUGIN cbPlugin = currentCallback.cbPlugin; + if(!IsBadReadPtr((const void*)cbPlugin, sizeof(duint))) + cbPlugin(cbType, callbackInfo); + } + } +} + +/** +\brief Register a plugin command. +\param pluginHandle Handle of the plugin to register a command for. +\param command The command text to register. This text cannot contain the '\1' character. This text is not case sensitive. +\param cbCommand The command callback. +\param debugonly true if the command can only be called during debugging. +\return true if it the registration succeeded, false otherwise. +*/ +bool plugincmdregister(int pluginHandle, const char* command, CBPLUGINCOMMAND cbCommand, bool debugonly) +{ + if(!command || strlen(command) >= deflen || strstr(command, "\1")) + return false; + PLUG_COMMAND plugCmd; + plugCmd.pluginHandle = pluginHandle; + strcpy_s(plugCmd.command, command); + if(!dbgcmdnew(command, (CBCOMMAND)cbCommand, debugonly)) + return false; + EXCLUSIVE_ACQUIRE(LockPluginCommandList); + pluginCommandList.push_back(plugCmd); + EXCLUSIVE_RELEASE(); + dprintf("[PLUGIN] command \"%s\" registered!\n", command); + return true; +} + +/** +\brief Unregister a plugin command. +\param pluginHandle Handle of the plugin to unregister the command from. +\param command The command text to unregister. This text is not case sensitive. +\return true if the command was found and removed, false otherwise. +*/ +bool plugincmdunregister(int pluginHandle, const char* command) +{ + if(!command || strlen(command) >= deflen || strstr(command, "\1")) + return false; + EXCLUSIVE_ACQUIRE(LockPluginCommandList); + for(auto it = pluginCommandList.begin(); it != pluginCommandList.end(); ++it) + { + const auto & currentCommand = *it; + if(currentCommand.pluginHandle == pluginHandle && !strcmp(currentCommand.command, command)) + { + pluginCommandList.erase(it); + EXCLUSIVE_RELEASE(); + if(!dbgcmddel(command)) + return false; + dprintf("[PLUGIN] command \"%s\" unregistered!\n", command); + return true; + } + } + return false; +} + +/** +\brief Add a new plugin (sub)menu. +\param hMenu The menu handle to add the (sub)menu to. +\param title The title of the (sub)menu. +\return The handle of the new (sub)menu. +*/ +int pluginmenuadd(int hMenu, const char* title) +{ + if(!title || !strlen(title)) + return -1; + EXCLUSIVE_ACQUIRE(LockPluginMenuList); + int nFound = -1; + for(unsigned int i = 0; i < pluginMenuList.size(); i++) + { + if(pluginMenuList.at(i).hEntryMenu == hMenu && pluginMenuList.at(i).hEntryPlugin == -1) + { + nFound = i; + break; + } + } + if(nFound == -1) //not a valid menu handle + return -1; + int hMenuNew = GuiMenuAdd(pluginMenuList.at(nFound).hEntryMenu, title); + PLUG_MENU newMenu; + newMenu.pluginHandle = pluginMenuList.at(nFound).pluginHandle; + newMenu.hEntryPlugin = -1; + newMenu.hEntryMenu = hMenuNew; + pluginMenuList.push_back(newMenu); + return hMenuNew; +} + +/** +\brief Add a plugin menu entry to a menu. +\param hMenu The menu to add the entry to. +\param hEntry The handle you like to have the entry. This should be a unique value in the scope of the plugin that registered the \p hMenu. +\param title The menu entry title. +\return true if the \p hEntry was unique and the entry was successfully added, false otherwise. +*/ +bool pluginmenuaddentry(int hMenu, int hEntry, const char* title) +{ + if(!title || !strlen(title) || hEntry == -1) + return false; + EXCLUSIVE_ACQUIRE(LockPluginMenuList); + int pluginHandle = -1; + //find plugin handle + for(const auto & currentMenu : pluginMenuList) + { + if(currentMenu.hEntryMenu == hMenu && currentMenu.hEntryPlugin == -1) + { + pluginHandle = currentMenu.pluginHandle; + break; + } + } + if(pluginHandle == -1) //not found + return false; + //search if hEntry was previously used + for(const auto & currentMenu : pluginMenuList) + if(currentMenu.pluginHandle == pluginHandle && currentMenu.hEntryPlugin == hEntry) + return false; + int hNewEntry = GuiMenuAddEntry(hMenu, title); + if(hNewEntry == -1) + return false; + PLUG_MENU newMenu; + newMenu.hEntryMenu = hNewEntry; + newMenu.hEntryPlugin = hEntry; + newMenu.pluginHandle = pluginHandle; + pluginMenuList.push_back(newMenu); + return true; +} + +/** +\brief Add a menu separator to a menu. +\param hMenu The menu to add the separator to. +\return true if it succeeds, false otherwise. +*/ +bool pluginmenuaddseparator(int hMenu) +{ + SHARED_ACQUIRE(LockPluginMenuList); + for(const auto & currentMenu : pluginMenuList) + { + if(currentMenu.hEntryMenu == hMenu && currentMenu.hEntryPlugin == -1) + { + GuiMenuAddSeparator(hMenu); + return true; + } + } + return false; +} + +/** +\brief Clears a plugin menu. +\param hMenu The menu to clear. +\return true if it succeeds, false otherwise. +*/ +bool pluginmenuclear(int hMenu) +{ + EXCLUSIVE_ACQUIRE(LockPluginMenuList); + bool bFound = false; + for(auto it = pluginMenuList.begin(); it != pluginMenuList.end(); ++it) + { + const auto & currentMenu = *it; + if(currentMenu.hEntryMenu == hMenu && currentMenu.hEntryPlugin == -1) + { + it = pluginMenuList.erase(it); + bFound = true; + } + } + if(!bFound) + return false; + GuiMenuClear(hMenu); + return true; +} + +/** +\brief Call the registered CB_MENUENTRY callbacks for a menu entry. +\param hEntry The menu entry that triggered the event. +*/ +void pluginmenucall(int hEntry) +{ + if(hEntry == -1) + return; + + SectionLocker menuLock; //shared lock + auto i = pluginMenuList.begin(); + while(i != pluginMenuList.end()) + { + const auto currentMenu = *i; + ++i; + if(currentMenu.hEntryMenu == hEntry && currentMenu.hEntryPlugin != -1) + { + PLUG_CB_MENUENTRY menuEntryInfo; + menuEntryInfo.hEntry = currentMenu.hEntryPlugin; + SectionLocker callbackLock; //shared lock + auto j = pluginCallbackList.begin(); + while(j != pluginCallbackList.end()) + { + const auto currentCallback = *j; + ++j; + if(currentCallback.pluginHandle == currentMenu.pluginHandle && currentCallback.cbType == CB_MENUENTRY) + { + menuLock.Unlock(); + callbackLock.Unlock(); + currentCallback.cbPlugin(CB_MENUENTRY, &menuEntryInfo); + return; + } + } + } + } +} + +/** +\brief Calls the registered CB_WINEVENT callbacks. +\param [in,out] message the message that triggered the event. Cannot be null. +\param [out] result The result value. Cannot be null. +\return The value the plugin told it to return. See plugin documentation for more information. +*/ +bool pluginwinevent(MSG* message, long* result) +{ + PLUG_CB_WINEVENT winevent; + winevent.message = message; + winevent.result = result; + winevent.retval = false; + plugincbcall(CB_WINEVENT, &winevent); + return winevent.retval; +} + +/** +\brief Calls the registered CB_WINEVENTGLOBAL callbacks. +\param [in,out] message the message that triggered the event. Cannot be null. +\return The value the plugin told it to return. See plugin documentation for more information. +*/ +bool pluginwineventglobal(MSG* message) +{ + PLUG_CB_WINEVENTGLOBAL winevent; + winevent.message = message; + winevent.retval = false; + plugincbcall(CB_WINEVENTGLOBAL, &winevent); + return winevent.retval; +} + +/** +\brief Sets an icon for a menu. +\param hMenu The menu handle. +\param icon The icon (can be all kinds of formats). +*/ +void pluginmenuseticon(int hMenu, const ICONDATA* icon) +{ + SHARED_ACQUIRE(LockPluginMenuList); + for(const auto & currentMenu : pluginMenuList) + { + if(currentMenu.hEntryMenu == hMenu && currentMenu.hEntryPlugin == -1) + { + GuiMenuSetIcon(hMenu, icon); + break; + } + } +} + +/** +\brief Sets an icon for a menu entry. +\param pluginHandle Plugin handle. +\param hEntry The menu entry handle (unique per plugin). +\param icon The icon (can be all kinds of formats). +*/ +void pluginmenuentryseticon(int pluginHandle, int hEntry, const ICONDATA* icon) +{ + if(hEntry == -1) + return; + SHARED_ACQUIRE(LockPluginMenuList); + for(const auto & currentMenu : pluginMenuList) + { + if(currentMenu.pluginHandle == pluginHandle && currentMenu.hEntryPlugin == hEntry) + { + GuiMenuSetEntryIcon(currentMenu.hEntryMenu, icon); + break; + } + } } \ No newline at end of file diff --git a/src/dbg/plugin_loader.h b/src/dbg/plugin_loader.h index 619ae2e6..31c28b58 100644 --- a/src/dbg/plugin_loader.h +++ b/src/dbg/plugin_loader.h @@ -1,65 +1,65 @@ -#ifndef _PLUGIN_LOADER_H -#define _PLUGIN_LOADER_H - -#include "_global.h" -#include "_plugins.h" - -//typedefs -typedef bool (*PLUGINIT)(PLUG_INITSTRUCT* initStruct); -typedef bool (*PLUGSTOP)(); -typedef void (*PLUGSETUP)(PLUG_SETUPSTRUCT* setupStruct); - -//structures -struct PLUG_MENU -{ - int pluginHandle; //plugin handle - int hEntryMenu; //GUI entry/menu handle (unique) - int hEntryPlugin; //plugin entry handle (unique per plugin) -}; - -struct PLUG_DATA -{ - HINSTANCE hPlugin; - PLUGINIT pluginit; - PLUGSTOP plugstop; - PLUGSETUP plugsetup; - int hMenu; - int hMenuDisasm; - int hMenuDump; - int hMenuStack; - PLUG_INITSTRUCT initStruct; -}; - -struct PLUG_CALLBACK -{ - int pluginHandle; - CBTYPE cbType; - CBPLUGIN cbPlugin; -}; - -struct PLUG_COMMAND -{ - int pluginHandle; - char command[deflen]; -}; - -//plugin management functions -void pluginload(const char* pluginDir); -void pluginunload(); -void pluginregistercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin); -bool pluginunregistercallback(int pluginHandle, CBTYPE cbType); -void plugincbcall(CBTYPE cbType, void* callbackInfo); -bool plugincmdregister(int pluginHandle, const char* command, CBPLUGINCOMMAND cbCommand, bool debugonly); -bool plugincmdunregister(int pluginHandle, const char* command); -int pluginmenuadd(int hMenu, const char* title); -bool pluginmenuaddentry(int hMenu, int hEntry, const char* title); -bool pluginmenuaddseparator(int hMenu); -bool pluginmenuclear(int hMenu); -void pluginmenucall(int hEntry); -bool pluginwinevent(MSG* message, long* result); -bool pluginwineventglobal(MSG* message); -void pluginmenuseticon(int hMenu, const ICONDATA* icon); -void pluginmenuentryseticon(int pluginHandle, int hEntry, const ICONDATA* icon); - - -#endif // _PLUGIN_LOADER_H +#ifndef _PLUGIN_LOADER_H +#define _PLUGIN_LOADER_H + +#include "_global.h" +#include "_plugins.h" + +//typedefs +typedef bool (*PLUGINIT)(PLUG_INITSTRUCT* initStruct); +typedef bool (*PLUGSTOP)(); +typedef void (*PLUGSETUP)(PLUG_SETUPSTRUCT* setupStruct); + +//structures +struct PLUG_MENU +{ + int pluginHandle; //plugin handle + int hEntryMenu; //GUI entry/menu handle (unique) + int hEntryPlugin; //plugin entry handle (unique per plugin) +}; + +struct PLUG_DATA +{ + HINSTANCE hPlugin; + PLUGINIT pluginit; + PLUGSTOP plugstop; + PLUGSETUP plugsetup; + int hMenu; + int hMenuDisasm; + int hMenuDump; + int hMenuStack; + PLUG_INITSTRUCT initStruct; +}; + +struct PLUG_CALLBACK +{ + int pluginHandle; + CBTYPE cbType; + CBPLUGIN cbPlugin; +}; + +struct PLUG_COMMAND +{ + int pluginHandle; + char command[deflen]; +}; + +//plugin management functions +void pluginload(const char* pluginDir); +void pluginunload(); +void pluginregistercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin); +bool pluginunregistercallback(int pluginHandle, CBTYPE cbType); +void plugincbcall(CBTYPE cbType, void* callbackInfo); +bool plugincmdregister(int pluginHandle, const char* command, CBPLUGINCOMMAND cbCommand, bool debugonly); +bool plugincmdunregister(int pluginHandle, const char* command); +int pluginmenuadd(int hMenu, const char* title); +bool pluginmenuaddentry(int hMenu, int hEntry, const char* title); +bool pluginmenuaddseparator(int hMenu); +bool pluginmenuclear(int hMenu); +void pluginmenucall(int hEntry); +bool pluginwinevent(MSG* message, long* result); +bool pluginwineventglobal(MSG* message); +void pluginmenuseticon(int hMenu, const ICONDATA* icon); +void pluginmenuentryseticon(int pluginHandle, int hEntry, const ICONDATA* icon); + + +#endif // _PLUGIN_LOADER_H diff --git a/src/dbg/reference.cpp b/src/dbg/reference.cpp index 8f8e4bb7..f586ca6b 100644 --- a/src/dbg/reference.cpp +++ b/src/dbg/reference.cpp @@ -1,110 +1,110 @@ -/** - @file reference.cpp - - @brief Implements the reference class. - */ - -#include "reference.h" -#include "memory.h" -#include "console.h" -#include "module.h" - -int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Silent, const char* Name) -{ - duint regionSize = 0; - duint regionBase = MemFindBaseAddr(Address, ®ionSize, true); - - // If the memory page wasn't found, fail - if(!regionBase || !regionSize) - { - if(!Silent) - dprintf("Invalid memory page 0x%p\n", Address); - - return 0; - } - - // Assume the entire range is used - duint scanStart = regionBase; - duint scanSize = regionSize; - - // Otherwise use custom boundaries if size was supplied - if(Size) - { - duint maxsize = Size - (Address - regionBase); - - // Make sure the size fits in one page - scanStart = Address; - scanSize = min(Size, maxsize); - } - - // Allocate and read a buffer from the remote process - Memory data(scanSize, "reffind:data"); - - if(!MemRead(scanStart, data(), scanSize)) - { - if(!Silent) - dprintf("Error reading memory in reference search\n"); - - return 0; - } - - // Determine the full module name - char fullName[deflen]; - char moduleName[MAX_MODULE_SIZE]; - - if(ModNameFromAddr(scanStart, moduleName, true)) - sprintf_s(fullName, "%s (%s)", Name, moduleName); - else - sprintf_s(fullName, "%s (%p)", Name, scanStart); - - // Initialize disassembler - Capstone cp; - - // Allow an "initialization" notice - REFINFO refInfo; - refInfo.refcount = 0; - refInfo.userinfo = UserData; - refInfo.name = fullName; - - Callback(0, 0, &refInfo); - - //concurrency::parallel_for(duint (0), scanSize, [&](duint i) - for(duint i = 0; i < scanSize;) - { - // Print the progress every 4096 bytes - if((i % 0x1000) == 0) - { - // Percent = (current / total) * 100 - // Integer = floor(percent) - int percent = (int)floor(((float)i / (float)scanSize) * 100.0f); - - GuiReferenceSetProgress(percent); - } - - // Disassemble the instruction - int disasmMaxSize = min(MAX_DISASM_BUFFER, (int)(scanSize - i)); // Prevent going past the boundary - int disasmLen = 1; - - if (cp.Disassemble(scanStart, data() + i, disasmMaxSize)) - { - BASIC_INSTRUCTION_INFO basicinfo; - fillbasicinfo(&cp, &basicinfo); - - if(Callback(&cp, &basicinfo, &refInfo)) - refInfo.refcount++; - - disasmLen = cp.Size(); - } - else - { - // Invalid instruction detected, so just skip the byte - } - - scanStart += disasmLen; - i += disasmLen; - } - - GuiReferenceSetProgress(100); - GuiReferenceReloadData(); - return refInfo.refcount; -} +/** + @file reference.cpp + + @brief Implements the reference class. + */ + +#include "reference.h" +#include "memory.h" +#include "console.h" +#include "module.h" + +int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Silent, const char* Name) +{ + duint regionSize = 0; + duint regionBase = MemFindBaseAddr(Address, ®ionSize, true); + + // If the memory page wasn't found, fail + if(!regionBase || !regionSize) + { + if(!Silent) + dprintf("Invalid memory page 0x%p\n", Address); + + return 0; + } + + // Assume the entire range is used + duint scanStart = regionBase; + duint scanSize = regionSize; + + // Otherwise use custom boundaries if size was supplied + if(Size) + { + duint maxsize = Size - (Address - regionBase); + + // Make sure the size fits in one page + scanStart = Address; + scanSize = min(Size, maxsize); + } + + // Allocate and read a buffer from the remote process + Memory data(scanSize, "reffind:data"); + + if(!MemRead(scanStart, data(), scanSize)) + { + if(!Silent) + dprintf("Error reading memory in reference search\n"); + + return 0; + } + + // Determine the full module name + char fullName[deflen]; + char moduleName[MAX_MODULE_SIZE]; + + if(ModNameFromAddr(scanStart, moduleName, true)) + sprintf_s(fullName, "%s (%s)", Name, moduleName); + else + sprintf_s(fullName, "%s (%p)", Name, scanStart); + + // Initialize disassembler + Capstone cp; + + // Allow an "initialization" notice + REFINFO refInfo; + refInfo.refcount = 0; + refInfo.userinfo = UserData; + refInfo.name = fullName; + + Callback(0, 0, &refInfo); + + //concurrency::parallel_for(duint (0), scanSize, [&](duint i) + for(duint i = 0; i < scanSize;) + { + // Print the progress every 4096 bytes + if((i % 0x1000) == 0) + { + // Percent = (current / total) * 100 + // Integer = floor(percent) + int percent = (int)floor(((float)i / (float)scanSize) * 100.0f); + + GuiReferenceSetProgress(percent); + } + + // Disassemble the instruction + int disasmMaxSize = min(MAX_DISASM_BUFFER, (int)(scanSize - i)); // Prevent going past the boundary + int disasmLen = 1; + + if (cp.Disassemble(scanStart, data() + i, disasmMaxSize)) + { + BASIC_INSTRUCTION_INFO basicinfo; + fillbasicinfo(&cp, &basicinfo); + + if(Callback(&cp, &basicinfo, &refInfo)) + refInfo.refcount++; + + disasmLen = cp.Size(); + } + else + { + // Invalid instruction detected, so just skip the byte + } + + scanStart += disasmLen; + i += disasmLen; + } + + GuiReferenceSetProgress(100); + GuiReferenceReloadData(); + return refInfo.refcount; +} diff --git a/src/dbg/reference.h b/src/dbg/reference.h index f565a082..58a3bd2a 100644 --- a/src/dbg/reference.h +++ b/src/dbg/reference.h @@ -1,16 +1,16 @@ -#pragma once - -#include "_global.h" -#include "disasm_fast.h" - -struct REFINFO -{ - int refcount; - void* userinfo; - const char* name; -}; - -// Reference callback typedef -typedef bool (*CBREF)(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo); - +#pragma once + +#include "_global.h" +#include "disasm_fast.h" + +struct REFINFO +{ + int refcount; + void* userinfo; + const char* name; +}; + +// Reference callback typedef +typedef bool (*CBREF)(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo); + int RefFind(duint Address, duint Size, CBREF Callback, void* UserData, bool Silent, const char* Name); \ No newline at end of file diff --git a/src/dbg/simplescript.cpp b/src/dbg/simplescript.cpp index 16e9a1ee..7d4fcd9d 100644 --- a/src/dbg/simplescript.cpp +++ b/src/dbg/simplescript.cpp @@ -1,656 +1,656 @@ -/** - @file simplescript.cpp - - @brief Implements the simplescript class. - */ - -#include "simplescript.h" -#include "console.h" -#include "variable.h" -#include "x64_dbg.h" -#include "debugger.h" - -static std::vector linemap; - -static std::vector scriptbplist; - -static std::vector scriptstack; - -static int scriptIp = 0; - -static bool volatile bAbort = false; - -static bool volatile bIsRunning = false; - -static SCRIPTBRANCHTYPE scriptgetbranchtype(const char* text) -{ - char newtext[MAX_SCRIPT_LINE_SIZE] = ""; - strcpy_s(newtext, StringUtils::Trim(text).c_str()); - if(!strstr(newtext, " ")) - strcat(newtext, " "); - if(!strncmp(newtext, "jmp ", 4) || !strncmp(newtext, "goto ", 5)) - return scriptjmp; - else if(!strncmp(newtext, "jbe ", 4) || !strncmp(newtext, "ifbe ", 5) || !strncmp(newtext, "ifbeq ", 6) || !strncmp(newtext, "jle ", 4) || !strncmp(newtext, "ifle ", 5) || !strncmp(newtext, "ifleq ", 6)) - return scriptjbejle; - else if(!strncmp(newtext, "jae ", 4) || !strncmp(newtext, "ifae ", 5) || !strncmp(newtext, "ifaeq ", 6) || !strncmp(newtext, "jge ", 4) || !strncmp(newtext, "ifge ", 5) || !strncmp(newtext, "ifgeq ", 6)) - return scriptjaejge; - else if(!strncmp(newtext, "jne ", 4) || !strncmp(newtext, "ifne ", 5) || !strncmp(newtext, "ifneq ", 6) || !strncmp(newtext, "jnz ", 4) || !strncmp(newtext, "ifnz ", 5)) - return scriptjnejnz; - else if(!strncmp(newtext, "je ", 3) || !strncmp(newtext, "ife ", 4) || !strncmp(newtext, "ifeq ", 5) || !strncmp(newtext, "jz ", 3) || !strncmp(newtext, "ifz ", 4)) - return scriptjejz; - else if(!strncmp(newtext, "jb ", 3) || !strncmp(newtext, "ifb ", 4) || !strncmp(newtext, "jl ", 3) || !strncmp(newtext, "ifl ", 4)) - return scriptjbjl; - else if(!strncmp(newtext, "ja ", 3) || !strncmp(newtext, "ifa ", 4) || !strncmp(newtext, "jg ", 3) || !strncmp(newtext, "ifg ", 4)) - return scriptjajg; - else if(!strncmp(newtext, "call ", 5)) - return scriptcall; - return scriptnobranch; -} - -static int scriptlabelfind(const char* labelname) -{ - int linecount = (int)linemap.size(); - for(int i = 0; i < linecount; i++) - if(linemap.at(i).type == linelabel && !strcmp(linemap.at(i).u.label, labelname)) - return i + 1; - return 0; -} - -static inline bool isEmptyLine(SCRIPTLINETYPE type) -{ - return type == lineempty || type == linecomment || type == linelabel; -} - -static int scriptinternalstep(int fromIp) //internal step routine -{ - int maxIp = (int)linemap.size(); //maximum ip - if(fromIp >= maxIp) //script end - return fromIp; - while(isEmptyLine(linemap.at(fromIp).type) && fromIp < maxIp) //skip empty lines - fromIp++; - fromIp++; - return fromIp; -} - -static bool scriptcreatelinemap(const char* filename) -{ - Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(filename).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); - if(hFile == INVALID_HANDLE_VALUE) - { - GuiScriptError(0, "CreateFile failed..."); - return false; - } - unsigned int filesize = GetFileSize(hFile, 0); - if(!filesize) - { - GuiScriptError(0, "Empty script..."); - return false; - } - Memory filedata(filesize + 1, "createlinemap:filedata"); - DWORD read = 0; - if(!ReadFile(hFile, filedata(), filesize, &read, 0)) - { - GuiScriptError(0, "ReadFile failed..."); - return false; - } - hFile.Close(); - int len = (int)strlen(filedata()); - char temp[256] = ""; - LINEMAPENTRY entry; - memset(&entry, 0, sizeof(entry)); - std::vector().swap(linemap); - for(int i = 0, j = 0; i < len; i++) //make raw line map - { - if(filedata()[i] == '\r' && filedata()[i + 1] == '\n') //windows file - { - memset(&entry, 0, sizeof(entry)); - int add = 0; - while(temp[add] == ' ') - add++; - strcpy_s(entry.raw, temp + add); - *temp = 0; - j = 0; - i++; - linemap.push_back(entry); - } - else if(filedata()[i] == '\n') //other file - { - memset(&entry, 0, sizeof(entry)); - int add = 0; - while(temp[add] == ' ') - add++; - strcpy_s(entry.raw, temp + add); - *temp = 0; - j = 0; - linemap.push_back(entry); - } - else if(j >= 254) - { - memset(&entry, 0, sizeof(entry)); - int add = 0; - while(temp[add] == ' ') - add++; - strcpy_s(entry.raw, temp + add); - *temp = 0; - j = 0; - linemap.push_back(entry); - } - else - j += sprintf(temp + j, "%c", filedata()[i]); - } - if(*temp) - { - memset(&entry, 0, sizeof(entry)); - strcpy_s(entry.raw, temp); - linemap.push_back(entry); - } - int linemapsize = (int)linemap.size(); - while(!*linemap.at(linemapsize - 1).raw) //remove empty lines from the end - { - linemapsize--; - linemap.pop_back(); - } - for(int i = 0; i < linemapsize; i++) - { - LINEMAPENTRY cur = linemap.at(i); - - //temp. remove comments from the raw line - char line_comment[256] = ""; - char* comment = strstr(&cur.raw[0], "//"); - if(comment && comment != cur.raw) //only when the line doesnt start with a comment - { - if(*(comment - 1) == ' ') //space before comment - { - strcpy_s(line_comment, comment); - *(comment - 1) = '\0'; - } - else //no space before comment - { - strcpy_s(line_comment, comment); - *comment = 0; - } - } - - int rawlen = (int)strlen(cur.raw); - if(!rawlen) //empty - { - cur.type = lineempty; - } - else if(!strncmp(cur.raw, "//", 2)) //comment - { - cur.type = linecomment; - strcpy_s(cur.u.comment, cur.raw); - } - else if(cur.raw[rawlen - 1] == ':') //label - { - cur.type = linelabel; - sprintf(cur.u.label, "l %.*s", rawlen - 1, cur.raw); //create a fake command for formatting - strcpy_s(cur.u.label, StringUtils::Trim(cur.u.label).c_str()); - char temp[256] = ""; - strcpy_s(temp, cur.u.label + 2); - strcpy_s(cur.u.label, temp); //remove fake command - if(!*cur.u.label || !strcmp(cur.u.label, "\"\"")) //no label text - { - char message[256] = ""; - sprintf(message, "Empty label detected on line %d!", i + 1); - GuiScriptError(0, message); - std::vector().swap(linemap); - return false; - } - int foundlabel = scriptlabelfind(cur.u.label); - if(foundlabel) //label defined twice - { - char message[256] = ""; - sprintf(message, "Duplicate label \"%s\" detected on lines %d and %d!", cur.u.label, foundlabel, i + 1); - GuiScriptError(0, message); - std::vector().swap(linemap); - return false; - } - } - else if(scriptgetbranchtype(cur.raw) != scriptnobranch) //branch - { - cur.type = linebranch; - cur.u.branch.type = scriptgetbranchtype(cur.raw); - char newraw[MAX_SCRIPT_LINE_SIZE] = ""; - strcpy_s(newraw, StringUtils::Trim(cur.raw).c_str()); - int len = (int)strlen(newraw); - for(int i = 0; i < len; i++) - if(newraw[i] == ' ') - { - strcpy_s(cur.u.branch.branchlabel, newraw + i + 1); - break; - } - } - else - { - cur.type = linecommand; - strcpy_s(cur.u.command, cur.raw); - } - - //append the comment to the raw line again - if(*line_comment) - sprintf(cur.raw + rawlen, " %s", line_comment); - linemap.at(i) = cur; - } - linemapsize = (int)linemap.size(); - for(int i = 0; i < linemapsize; i++) - { - auto & currentLine = linemap.at(i); - if(currentLine.type == linebranch) //invalid branch label - { - int labelline = scriptlabelfind(currentLine.u.branch.branchlabel); - if(!labelline) //invalid branch label - { - char message[256] = ""; - sprintf(message, "Invalid branch label \"%s\" detected on line %d!", currentLine.u.branch.branchlabel, i + 1); - GuiScriptError(0, message); - std::vector().swap(linemap); - return false; - } - else //set the branch destination line - currentLine.u.branch.dest = scriptinternalstep(labelline); - } - } - if(linemap.at(linemapsize - 1).type == linecomment || linemap.at(linemapsize - 1).type == linelabel) //label/comment on the end - { - memset(&entry, 0, sizeof(entry)); - entry.type = linecommand; - strcpy_s(entry.raw, "ret"); - strcpy_s(entry.u.command, "ret"); - linemap.push_back(entry); - } - return true; -} - -static bool scriptinternalbpget(int line) //internal bpget routine -{ - int bpcount = (int)scriptbplist.size(); - for(int i = 0; i < bpcount; i++) - if(scriptbplist.at(i).line == line) - return true; - return false; -} - -static bool scriptinternalbptoggle(int line) //internal breakpoint -{ - if(!line || line > (int)linemap.size()) //invalid line - return false; - line = scriptinternalstep(line - 1); //no breakpoints on non-executable locations - if(scriptinternalbpget(line)) //remove breakpoint - { - int bpcount = (int)scriptbplist.size(); - for(int i = 0; i < bpcount; i++) - if(scriptbplist.at(i).line == line) - { - scriptbplist.erase(scriptbplist.begin() + i); - break; - } - } - else //add breakpoint - { - SCRIPTBP newbp; - newbp.silent = true; - newbp.line = line; - scriptbplist.push_back(newbp); - } - return true; -} - -static bool scriptisinternalcommand(const char* text, const char* cmd) -{ - int len = (int)strlen(text); - int cmdlen = (int)strlen(cmd); - if(cmdlen > len) - return false; - else if(cmdlen == len) - return scmp(text, cmd); - else if(text[cmdlen] == ' ') - return (!_strnicmp(text, cmd, cmdlen)); - return false; -} - -static CMDRESULT scriptinternalcmdexec(const char* cmd) -{ - if(scriptisinternalcommand(cmd, "ret")) //script finished - { - if(!scriptstack.size()) //nothing on the stack - { - GuiScriptMessage("Script finished!"); - return STATUS_EXIT; - } - scriptIp = scriptstack.back(); //set scriptIp to the call address (scriptinternalstep will step over it) - scriptstack.pop_back(); //remove last stack entry - return STATUS_CONTINUE; - } - else if(scriptisinternalcommand(cmd, "invalid")) //invalid command for testing - return STATUS_ERROR; - else if(scriptisinternalcommand(cmd, "pause")) //pause the script - return STATUS_PAUSE; - else if(scriptisinternalcommand(cmd, "nop")) //do nothing - return STATUS_CONTINUE; - char command[deflen] = ""; - strcpy_s(command, StringUtils::Trim(cmd).c_str()); - COMMAND* found = cmdfindmain(command); - if(!found) //invalid command - return STATUS_ERROR; - if(arraycontains(found->name, "var")) //var - { - cmddirectexec(command); - return STATUS_CONTINUE; - } - CMDRESULT res = cmddirectexec(command); - while(DbgIsDebugging() && dbgisrunning()) //while not locked (NOTE: possible deadlock) - Sleep(10); - return res; -} - -static bool scriptinternalbranch(SCRIPTBRANCHTYPE type) //determine if we should jump -{ - duint ezflag = 0; - duint bsflag = 0; - varget("$_EZ_FLAG", &ezflag, 0, 0); - varget("$_BS_FLAG", &bsflag, 0, 0); - bool bJump = false; - switch(type) - { - case scriptcall: - case scriptjmp: - bJump = true; - break; - case scriptjnejnz: //$_EZ_FLAG=0 - if(!ezflag) - bJump = true; - break; - case scriptjejz: //$_EZ_FLAG=1 - if(ezflag) - bJump = true; - break; - case scriptjbjl: //$_BS_FLAG=0 and $_EZ_FLAG=0 //below, not equal - if(!bsflag && !ezflag) - bJump = true; - break; - case scriptjajg: //$_BS_FLAG=1 and $_EZ_FLAG=0 //above, not equal - if(bsflag && !ezflag) - bJump = true; - break; - case scriptjbejle: //$_BS_FLAG=0 or $_EZ_FLAG=1 - if(!bsflag || ezflag) - bJump = true; - break; - case scriptjaejge: //$_BS_FLAG=1 or $_EZ_FLAG=1 - if(bsflag || ezflag) - bJump = true; - break; - default: - bJump = false; - break; - } - return bJump; -} - -static bool scriptinternalcmd() -{ - bool bContinue = true; - LINEMAPENTRY cur = linemap.at(scriptIp - 1); - if(cur.type == linecommand) - { - switch(scriptinternalcmdexec(cur.u.command)) - { - case STATUS_CONTINUE: - break; - case STATUS_ERROR: - bContinue = false; - GuiScriptError(scriptIp, "Error executing command!"); - break; - case STATUS_EXIT: - bContinue = false; - scriptIp = scriptinternalstep(0); - GuiScriptSetIp(scriptIp); - break; - case STATUS_PAUSE: - bContinue = false; //stop running the script - scriptIp = scriptinternalstep(scriptIp); - GuiScriptSetIp(scriptIp); - break; - } - } - else if(cur.type == linebranch) - { - if(cur.u.branch.type == scriptcall) //calls have a special meaning - scriptstack.push_back(scriptIp); - if(scriptinternalbranch(cur.u.branch.type)) - scriptIp = scriptlabelfind(cur.u.branch.branchlabel); - } - return bContinue; -} - -static DWORD WINAPI scriptRunThread(void* arg) -{ - int destline = (int)(duint)arg; - if(!destline || destline > (int)linemap.size()) //invalid line - destline = 0; - if(destline) - { - destline = scriptinternalstep(destline - 1); //no breakpoints on non-executable locations - if(!scriptinternalbpget(destline)) //no breakpoint set - scriptinternalbptoggle(destline); - } - bAbort = false; - if(scriptIp) - scriptIp--; - scriptIp = scriptinternalstep(scriptIp); - bool bContinue = true; - while(bContinue && !bAbort) //run loop - { - bContinue = scriptinternalcmd(); - if(scriptIp == scriptinternalstep(scriptIp)) //end of script - { - bContinue = false; - scriptIp = scriptinternalstep(0); - } - if(bContinue) - scriptIp = scriptinternalstep(scriptIp); //this is the next ip - if(scriptinternalbpget(scriptIp)) //breakpoint=stop run loop - bContinue = false; - Sleep(1); //don't fry the processor - } - bIsRunning = false; //not running anymore - GuiScriptSetIp(scriptIp); - return 0; -} - -static DWORD WINAPI scriptLoadThread(void* filename) -{ - GuiScriptClear(); - GuiScriptEnableHighlighting(true); //enable default script syntax highlighting - scriptIp = 0; - std::vector().swap(scriptbplist); //clear breakpoints - std::vector().swap(scriptstack); //clear script stack - bAbort = false; - if(!scriptcreatelinemap((const char*)filename)) - return 0; - int lines = (int)linemap.size(); - const char** script = (const char**)BridgeAlloc(lines * sizeof(const char*)); - for(int i = 0; i < lines; i++) //add script lines - script[i] = linemap.at(i).raw; - GuiScriptAdd(lines, script); - scriptIp = scriptinternalstep(0); - GuiScriptSetIp(scriptIp); - return 0; -} - -void scriptload(const char* filename) -{ - static char filename_[MAX_PATH] = ""; - strcpy_s(filename_, filename); - CloseHandle(CreateThread(0, 0, scriptLoadThread, filename_, 0, 0)); -} - -void scriptunload() -{ - GuiScriptClear(); - scriptIp = 0; - std::vector().swap(scriptbplist); //clear breakpoints - bAbort = false; -} - -void scriptrun(int destline) -{ - if(DbgIsDebugging() && dbgisrunning()) - { - GuiScriptError(0, "Debugger must be paused to run a script!"); - return; - } - if(bIsRunning) //already running - return; - bIsRunning = true; - CloseHandle(CreateThread(0, 0, scriptRunThread, (void*)(duint)destline, 0, 0)); -} - -DWORD WINAPI scriptStepThread(void* param) -{ - if(bIsRunning) //already running - return 0; - scriptIp = scriptinternalstep(scriptIp - 1); //probably useless - if(!scriptinternalcmd()) - return 0; - if(scriptIp == scriptinternalstep(scriptIp)) //end of script - scriptIp = 0; - scriptIp = scriptinternalstep(scriptIp); - GuiScriptSetIp(scriptIp); - return 0; -} - -void scriptstep() -{ - CloseHandle(CreateThread(0, 0, scriptStepThread, 0, 0, 0)); -} - -bool scriptbptoggle(int line) -{ - if(!line || line > (int)linemap.size()) //invalid line - return false; - line = scriptinternalstep(line - 1); //no breakpoints on non-executable locations - if(scriptbpget(line)) //remove breakpoint - { - int bpcount = (int)scriptbplist.size(); - for(int i = 0; i < bpcount; i++) - if(scriptbplist.at(i).line == line && !scriptbplist.at(i).silent) - { - scriptbplist.erase(scriptbplist.begin() + i); - break; - } - } - else //add breakpoint - { - SCRIPTBP newbp; - newbp.silent = false; - newbp.line = line; - scriptbplist.push_back(newbp); - } - return true; -} - -bool scriptbpget(int line) -{ - int bpcount = (int)scriptbplist.size(); - for(int i = 0; i < bpcount; i++) - if(scriptbplist.at(i).line == line && !scriptbplist.at(i).silent) - return true; - return false; -} - -bool scriptcmdexec(const char* command) -{ - switch(scriptinternalcmdexec(command)) - { - case STATUS_ERROR: - return false; - case STATUS_EXIT: - scriptIp = scriptinternalstep(0); - GuiScriptSetIp(scriptIp); - break; - case STATUS_PAUSE: - case STATUS_CONTINUE: - break; - } - return true; -} - -void scriptabort() -{ - if(bIsRunning) - { - bAbort = true; - while(bIsRunning) - Sleep(1); - } - else //reset the script - scriptsetip(0); -} - -SCRIPTLINETYPE scriptgetlinetype(int line) -{ - if(line > (int)linemap.size()) - return lineempty; - return linemap.at(line - 1).type; -} - -void scriptsetip(int line) -{ - if(line) - line--; - scriptIp = scriptinternalstep(line); - GuiScriptSetIp(scriptIp); -} - -void scriptreset() -{ - while(bIsRunning) - { - bAbort = true; - Sleep(1); - } - Sleep(10); - scriptsetip(0); -} - -bool scriptgetbranchinfo(int line, SCRIPTBRANCH* info) -{ - if(!info || !line || line > (int)linemap.size()) //invalid line - return false; - if(linemap.at(line - 1).type != linebranch) //no branch - return false; - memcpy(info, &linemap.at(line - 1).u.branch, sizeof(SCRIPTBRANCH)); - return true; -} - -CMDRESULT cbScriptLoad(int argc, char* argv[]) -{ - if(argc < 2) - return STATUS_ERROR; - scriptload(argv[1]); - return STATUS_CONTINUE; -} - -CMDRESULT cbScriptMsg(int argc, char* argv[]) -{ - if(argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - GuiScriptMessage(argv[1]); - return STATUS_CONTINUE; -} - -CMDRESULT cbScriptMsgyn(int argc, char* argv[]) -{ - if(argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - varset("$RESULT", GuiScriptMsgyn(argv[1]), false); - return STATUS_CONTINUE; -} +/** + @file simplescript.cpp + + @brief Implements the simplescript class. + */ + +#include "simplescript.h" +#include "console.h" +#include "variable.h" +#include "x64_dbg.h" +#include "debugger.h" + +static std::vector linemap; + +static std::vector scriptbplist; + +static std::vector scriptstack; + +static int scriptIp = 0; + +static bool volatile bAbort = false; + +static bool volatile bIsRunning = false; + +static SCRIPTBRANCHTYPE scriptgetbranchtype(const char* text) +{ + char newtext[MAX_SCRIPT_LINE_SIZE] = ""; + strcpy_s(newtext, StringUtils::Trim(text).c_str()); + if(!strstr(newtext, " ")) + strcat(newtext, " "); + if(!strncmp(newtext, "jmp ", 4) || !strncmp(newtext, "goto ", 5)) + return scriptjmp; + else if(!strncmp(newtext, "jbe ", 4) || !strncmp(newtext, "ifbe ", 5) || !strncmp(newtext, "ifbeq ", 6) || !strncmp(newtext, "jle ", 4) || !strncmp(newtext, "ifle ", 5) || !strncmp(newtext, "ifleq ", 6)) + return scriptjbejle; + else if(!strncmp(newtext, "jae ", 4) || !strncmp(newtext, "ifae ", 5) || !strncmp(newtext, "ifaeq ", 6) || !strncmp(newtext, "jge ", 4) || !strncmp(newtext, "ifge ", 5) || !strncmp(newtext, "ifgeq ", 6)) + return scriptjaejge; + else if(!strncmp(newtext, "jne ", 4) || !strncmp(newtext, "ifne ", 5) || !strncmp(newtext, "ifneq ", 6) || !strncmp(newtext, "jnz ", 4) || !strncmp(newtext, "ifnz ", 5)) + return scriptjnejnz; + else if(!strncmp(newtext, "je ", 3) || !strncmp(newtext, "ife ", 4) || !strncmp(newtext, "ifeq ", 5) || !strncmp(newtext, "jz ", 3) || !strncmp(newtext, "ifz ", 4)) + return scriptjejz; + else if(!strncmp(newtext, "jb ", 3) || !strncmp(newtext, "ifb ", 4) || !strncmp(newtext, "jl ", 3) || !strncmp(newtext, "ifl ", 4)) + return scriptjbjl; + else if(!strncmp(newtext, "ja ", 3) || !strncmp(newtext, "ifa ", 4) || !strncmp(newtext, "jg ", 3) || !strncmp(newtext, "ifg ", 4)) + return scriptjajg; + else if(!strncmp(newtext, "call ", 5)) + return scriptcall; + return scriptnobranch; +} + +static int scriptlabelfind(const char* labelname) +{ + int linecount = (int)linemap.size(); + for(int i = 0; i < linecount; i++) + if(linemap.at(i).type == linelabel && !strcmp(linemap.at(i).u.label, labelname)) + return i + 1; + return 0; +} + +static inline bool isEmptyLine(SCRIPTLINETYPE type) +{ + return type == lineempty || type == linecomment || type == linelabel; +} + +static int scriptinternalstep(int fromIp) //internal step routine +{ + int maxIp = (int)linemap.size(); //maximum ip + if(fromIp >= maxIp) //script end + return fromIp; + while(isEmptyLine(linemap.at(fromIp).type) && fromIp < maxIp) //skip empty lines + fromIp++; + fromIp++; + return fromIp; +} + +static bool scriptcreatelinemap(const char* filename) +{ + Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(filename).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + if(hFile == INVALID_HANDLE_VALUE) + { + GuiScriptError(0, "CreateFile failed..."); + return false; + } + unsigned int filesize = GetFileSize(hFile, 0); + if(!filesize) + { + GuiScriptError(0, "Empty script..."); + return false; + } + Memory filedata(filesize + 1, "createlinemap:filedata"); + DWORD read = 0; + if(!ReadFile(hFile, filedata(), filesize, &read, 0)) + { + GuiScriptError(0, "ReadFile failed..."); + return false; + } + hFile.Close(); + int len = (int)strlen(filedata()); + char temp[256] = ""; + LINEMAPENTRY entry; + memset(&entry, 0, sizeof(entry)); + std::vector().swap(linemap); + for(int i = 0, j = 0; i < len; i++) //make raw line map + { + if(filedata()[i] == '\r' && filedata()[i + 1] == '\n') //windows file + { + memset(&entry, 0, sizeof(entry)); + int add = 0; + while(temp[add] == ' ') + add++; + strcpy_s(entry.raw, temp + add); + *temp = 0; + j = 0; + i++; + linemap.push_back(entry); + } + else if(filedata()[i] == '\n') //other file + { + memset(&entry, 0, sizeof(entry)); + int add = 0; + while(temp[add] == ' ') + add++; + strcpy_s(entry.raw, temp + add); + *temp = 0; + j = 0; + linemap.push_back(entry); + } + else if(j >= 254) + { + memset(&entry, 0, sizeof(entry)); + int add = 0; + while(temp[add] == ' ') + add++; + strcpy_s(entry.raw, temp + add); + *temp = 0; + j = 0; + linemap.push_back(entry); + } + else + j += sprintf(temp + j, "%c", filedata()[i]); + } + if(*temp) + { + memset(&entry, 0, sizeof(entry)); + strcpy_s(entry.raw, temp); + linemap.push_back(entry); + } + int linemapsize = (int)linemap.size(); + while(!*linemap.at(linemapsize - 1).raw) //remove empty lines from the end + { + linemapsize--; + linemap.pop_back(); + } + for(int i = 0; i < linemapsize; i++) + { + LINEMAPENTRY cur = linemap.at(i); + + //temp. remove comments from the raw line + char line_comment[256] = ""; + char* comment = strstr(&cur.raw[0], "//"); + if(comment && comment != cur.raw) //only when the line doesnt start with a comment + { + if(*(comment - 1) == ' ') //space before comment + { + strcpy_s(line_comment, comment); + *(comment - 1) = '\0'; + } + else //no space before comment + { + strcpy_s(line_comment, comment); + *comment = 0; + } + } + + int rawlen = (int)strlen(cur.raw); + if(!rawlen) //empty + { + cur.type = lineempty; + } + else if(!strncmp(cur.raw, "//", 2)) //comment + { + cur.type = linecomment; + strcpy_s(cur.u.comment, cur.raw); + } + else if(cur.raw[rawlen - 1] == ':') //label + { + cur.type = linelabel; + sprintf(cur.u.label, "l %.*s", rawlen - 1, cur.raw); //create a fake command for formatting + strcpy_s(cur.u.label, StringUtils::Trim(cur.u.label).c_str()); + char temp[256] = ""; + strcpy_s(temp, cur.u.label + 2); + strcpy_s(cur.u.label, temp); //remove fake command + if(!*cur.u.label || !strcmp(cur.u.label, "\"\"")) //no label text + { + char message[256] = ""; + sprintf(message, "Empty label detected on line %d!", i + 1); + GuiScriptError(0, message); + std::vector().swap(linemap); + return false; + } + int foundlabel = scriptlabelfind(cur.u.label); + if(foundlabel) //label defined twice + { + char message[256] = ""; + sprintf(message, "Duplicate label \"%s\" detected on lines %d and %d!", cur.u.label, foundlabel, i + 1); + GuiScriptError(0, message); + std::vector().swap(linemap); + return false; + } + } + else if(scriptgetbranchtype(cur.raw) != scriptnobranch) //branch + { + cur.type = linebranch; + cur.u.branch.type = scriptgetbranchtype(cur.raw); + char newraw[MAX_SCRIPT_LINE_SIZE] = ""; + strcpy_s(newraw, StringUtils::Trim(cur.raw).c_str()); + int len = (int)strlen(newraw); + for(int i = 0; i < len; i++) + if(newraw[i] == ' ') + { + strcpy_s(cur.u.branch.branchlabel, newraw + i + 1); + break; + } + } + else + { + cur.type = linecommand; + strcpy_s(cur.u.command, cur.raw); + } + + //append the comment to the raw line again + if(*line_comment) + sprintf(cur.raw + rawlen, " %s", line_comment); + linemap.at(i) = cur; + } + linemapsize = (int)linemap.size(); + for(int i = 0; i < linemapsize; i++) + { + auto & currentLine = linemap.at(i); + if(currentLine.type == linebranch) //invalid branch label + { + int labelline = scriptlabelfind(currentLine.u.branch.branchlabel); + if(!labelline) //invalid branch label + { + char message[256] = ""; + sprintf(message, "Invalid branch label \"%s\" detected on line %d!", currentLine.u.branch.branchlabel, i + 1); + GuiScriptError(0, message); + std::vector().swap(linemap); + return false; + } + else //set the branch destination line + currentLine.u.branch.dest = scriptinternalstep(labelline); + } + } + if(linemap.at(linemapsize - 1).type == linecomment || linemap.at(linemapsize - 1).type == linelabel) //label/comment on the end + { + memset(&entry, 0, sizeof(entry)); + entry.type = linecommand; + strcpy_s(entry.raw, "ret"); + strcpy_s(entry.u.command, "ret"); + linemap.push_back(entry); + } + return true; +} + +static bool scriptinternalbpget(int line) //internal bpget routine +{ + int bpcount = (int)scriptbplist.size(); + for(int i = 0; i < bpcount; i++) + if(scriptbplist.at(i).line == line) + return true; + return false; +} + +static bool scriptinternalbptoggle(int line) //internal breakpoint +{ + if(!line || line > (int)linemap.size()) //invalid line + return false; + line = scriptinternalstep(line - 1); //no breakpoints on non-executable locations + if(scriptinternalbpget(line)) //remove breakpoint + { + int bpcount = (int)scriptbplist.size(); + for(int i = 0; i < bpcount; i++) + if(scriptbplist.at(i).line == line) + { + scriptbplist.erase(scriptbplist.begin() + i); + break; + } + } + else //add breakpoint + { + SCRIPTBP newbp; + newbp.silent = true; + newbp.line = line; + scriptbplist.push_back(newbp); + } + return true; +} + +static bool scriptisinternalcommand(const char* text, const char* cmd) +{ + int len = (int)strlen(text); + int cmdlen = (int)strlen(cmd); + if(cmdlen > len) + return false; + else if(cmdlen == len) + return scmp(text, cmd); + else if(text[cmdlen] == ' ') + return (!_strnicmp(text, cmd, cmdlen)); + return false; +} + +static CMDRESULT scriptinternalcmdexec(const char* cmd) +{ + if(scriptisinternalcommand(cmd, "ret")) //script finished + { + if(!scriptstack.size()) //nothing on the stack + { + GuiScriptMessage("Script finished!"); + return STATUS_EXIT; + } + scriptIp = scriptstack.back(); //set scriptIp to the call address (scriptinternalstep will step over it) + scriptstack.pop_back(); //remove last stack entry + return STATUS_CONTINUE; + } + else if(scriptisinternalcommand(cmd, "invalid")) //invalid command for testing + return STATUS_ERROR; + else if(scriptisinternalcommand(cmd, "pause")) //pause the script + return STATUS_PAUSE; + else if(scriptisinternalcommand(cmd, "nop")) //do nothing + return STATUS_CONTINUE; + char command[deflen] = ""; + strcpy_s(command, StringUtils::Trim(cmd).c_str()); + COMMAND* found = cmdfindmain(command); + if(!found) //invalid command + return STATUS_ERROR; + if(arraycontains(found->name, "var")) //var + { + cmddirectexec(command); + return STATUS_CONTINUE; + } + CMDRESULT res = cmddirectexec(command); + while(DbgIsDebugging() && dbgisrunning()) //while not locked (NOTE: possible deadlock) + Sleep(10); + return res; +} + +static bool scriptinternalbranch(SCRIPTBRANCHTYPE type) //determine if we should jump +{ + duint ezflag = 0; + duint bsflag = 0; + varget("$_EZ_FLAG", &ezflag, 0, 0); + varget("$_BS_FLAG", &bsflag, 0, 0); + bool bJump = false; + switch(type) + { + case scriptcall: + case scriptjmp: + bJump = true; + break; + case scriptjnejnz: //$_EZ_FLAG=0 + if(!ezflag) + bJump = true; + break; + case scriptjejz: //$_EZ_FLAG=1 + if(ezflag) + bJump = true; + break; + case scriptjbjl: //$_BS_FLAG=0 and $_EZ_FLAG=0 //below, not equal + if(!bsflag && !ezflag) + bJump = true; + break; + case scriptjajg: //$_BS_FLAG=1 and $_EZ_FLAG=0 //above, not equal + if(bsflag && !ezflag) + bJump = true; + break; + case scriptjbejle: //$_BS_FLAG=0 or $_EZ_FLAG=1 + if(!bsflag || ezflag) + bJump = true; + break; + case scriptjaejge: //$_BS_FLAG=1 or $_EZ_FLAG=1 + if(bsflag || ezflag) + bJump = true; + break; + default: + bJump = false; + break; + } + return bJump; +} + +static bool scriptinternalcmd() +{ + bool bContinue = true; + LINEMAPENTRY cur = linemap.at(scriptIp - 1); + if(cur.type == linecommand) + { + switch(scriptinternalcmdexec(cur.u.command)) + { + case STATUS_CONTINUE: + break; + case STATUS_ERROR: + bContinue = false; + GuiScriptError(scriptIp, "Error executing command!"); + break; + case STATUS_EXIT: + bContinue = false; + scriptIp = scriptinternalstep(0); + GuiScriptSetIp(scriptIp); + break; + case STATUS_PAUSE: + bContinue = false; //stop running the script + scriptIp = scriptinternalstep(scriptIp); + GuiScriptSetIp(scriptIp); + break; + } + } + else if(cur.type == linebranch) + { + if(cur.u.branch.type == scriptcall) //calls have a special meaning + scriptstack.push_back(scriptIp); + if(scriptinternalbranch(cur.u.branch.type)) + scriptIp = scriptlabelfind(cur.u.branch.branchlabel); + } + return bContinue; +} + +static DWORD WINAPI scriptRunThread(void* arg) +{ + int destline = (int)(duint)arg; + if(!destline || destline > (int)linemap.size()) //invalid line + destline = 0; + if(destline) + { + destline = scriptinternalstep(destline - 1); //no breakpoints on non-executable locations + if(!scriptinternalbpget(destline)) //no breakpoint set + scriptinternalbptoggle(destline); + } + bAbort = false; + if(scriptIp) + scriptIp--; + scriptIp = scriptinternalstep(scriptIp); + bool bContinue = true; + while(bContinue && !bAbort) //run loop + { + bContinue = scriptinternalcmd(); + if(scriptIp == scriptinternalstep(scriptIp)) //end of script + { + bContinue = false; + scriptIp = scriptinternalstep(0); + } + if(bContinue) + scriptIp = scriptinternalstep(scriptIp); //this is the next ip + if(scriptinternalbpget(scriptIp)) //breakpoint=stop run loop + bContinue = false; + Sleep(1); //don't fry the processor + } + bIsRunning = false; //not running anymore + GuiScriptSetIp(scriptIp); + return 0; +} + +static DWORD WINAPI scriptLoadThread(void* filename) +{ + GuiScriptClear(); + GuiScriptEnableHighlighting(true); //enable default script syntax highlighting + scriptIp = 0; + std::vector().swap(scriptbplist); //clear breakpoints + std::vector().swap(scriptstack); //clear script stack + bAbort = false; + if(!scriptcreatelinemap((const char*)filename)) + return 0; + int lines = (int)linemap.size(); + const char** script = (const char**)BridgeAlloc(lines * sizeof(const char*)); + for(int i = 0; i < lines; i++) //add script lines + script[i] = linemap.at(i).raw; + GuiScriptAdd(lines, script); + scriptIp = scriptinternalstep(0); + GuiScriptSetIp(scriptIp); + return 0; +} + +void scriptload(const char* filename) +{ + static char filename_[MAX_PATH] = ""; + strcpy_s(filename_, filename); + CloseHandle(CreateThread(0, 0, scriptLoadThread, filename_, 0, 0)); +} + +void scriptunload() +{ + GuiScriptClear(); + scriptIp = 0; + std::vector().swap(scriptbplist); //clear breakpoints + bAbort = false; +} + +void scriptrun(int destline) +{ + if(DbgIsDebugging() && dbgisrunning()) + { + GuiScriptError(0, "Debugger must be paused to run a script!"); + return; + } + if(bIsRunning) //already running + return; + bIsRunning = true; + CloseHandle(CreateThread(0, 0, scriptRunThread, (void*)(duint)destline, 0, 0)); +} + +DWORD WINAPI scriptStepThread(void* param) +{ + if(bIsRunning) //already running + return 0; + scriptIp = scriptinternalstep(scriptIp - 1); //probably useless + if(!scriptinternalcmd()) + return 0; + if(scriptIp == scriptinternalstep(scriptIp)) //end of script + scriptIp = 0; + scriptIp = scriptinternalstep(scriptIp); + GuiScriptSetIp(scriptIp); + return 0; +} + +void scriptstep() +{ + CloseHandle(CreateThread(0, 0, scriptStepThread, 0, 0, 0)); +} + +bool scriptbptoggle(int line) +{ + if(!line || line > (int)linemap.size()) //invalid line + return false; + line = scriptinternalstep(line - 1); //no breakpoints on non-executable locations + if(scriptbpget(line)) //remove breakpoint + { + int bpcount = (int)scriptbplist.size(); + for(int i = 0; i < bpcount; i++) + if(scriptbplist.at(i).line == line && !scriptbplist.at(i).silent) + { + scriptbplist.erase(scriptbplist.begin() + i); + break; + } + } + else //add breakpoint + { + SCRIPTBP newbp; + newbp.silent = false; + newbp.line = line; + scriptbplist.push_back(newbp); + } + return true; +} + +bool scriptbpget(int line) +{ + int bpcount = (int)scriptbplist.size(); + for(int i = 0; i < bpcount; i++) + if(scriptbplist.at(i).line == line && !scriptbplist.at(i).silent) + return true; + return false; +} + +bool scriptcmdexec(const char* command) +{ + switch(scriptinternalcmdexec(command)) + { + case STATUS_ERROR: + return false; + case STATUS_EXIT: + scriptIp = scriptinternalstep(0); + GuiScriptSetIp(scriptIp); + break; + case STATUS_PAUSE: + case STATUS_CONTINUE: + break; + } + return true; +} + +void scriptabort() +{ + if(bIsRunning) + { + bAbort = true; + while(bIsRunning) + Sleep(1); + } + else //reset the script + scriptsetip(0); +} + +SCRIPTLINETYPE scriptgetlinetype(int line) +{ + if(line > (int)linemap.size()) + return lineempty; + return linemap.at(line - 1).type; +} + +void scriptsetip(int line) +{ + if(line) + line--; + scriptIp = scriptinternalstep(line); + GuiScriptSetIp(scriptIp); +} + +void scriptreset() +{ + while(bIsRunning) + { + bAbort = true; + Sleep(1); + } + Sleep(10); + scriptsetip(0); +} + +bool scriptgetbranchinfo(int line, SCRIPTBRANCH* info) +{ + if(!info || !line || line > (int)linemap.size()) //invalid line + return false; + if(linemap.at(line - 1).type != linebranch) //no branch + return false; + memcpy(info, &linemap.at(line - 1).u.branch, sizeof(SCRIPTBRANCH)); + return true; +} + +CMDRESULT cbScriptLoad(int argc, char* argv[]) +{ + if(argc < 2) + return STATUS_ERROR; + scriptload(argv[1]); + return STATUS_CONTINUE; +} + +CMDRESULT cbScriptMsg(int argc, char* argv[]) +{ + if(argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + GuiScriptMessage(argv[1]); + return STATUS_CONTINUE; +} + +CMDRESULT cbScriptMsgyn(int argc, char* argv[]) +{ + if(argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + varset("$RESULT", GuiScriptMsgyn(argv[1]), false); + return STATUS_CONTINUE; +} diff --git a/src/dbg/simplescript.h b/src/dbg/simplescript.h index fdec24a5..4b847d54 100644 --- a/src/dbg/simplescript.h +++ b/src/dbg/simplescript.h @@ -1,45 +1,45 @@ -#ifndef _SIMPLESCRIPT_H -#define _SIMPLESCRIPT_H - -#include "command.h" - -//structures -struct SCRIPTBP -{ - int line; - bool silent; //do not show in GUI -}; - -struct LINEMAPENTRY -{ - SCRIPTLINETYPE type; - char raw[256]; - union - { - char command[256]; - SCRIPTBRANCH branch; - char label[256]; - char comment[256]; - } u; -}; - -//functions -void scriptload(const char* filename); -void scriptunload(); -void scriptrun(int destline); -void scriptstep(); -bool scriptbptoggle(int line); -bool scriptbpget(int line); -bool scriptcmdexec(const char* command); -void scriptabort(); -SCRIPTLINETYPE scriptgetlinetype(int line); -void scriptsetip(int line); -void scriptreset(); -bool scriptgetbranchinfo(int line, SCRIPTBRANCH* info); - -//script commands -CMDRESULT cbScriptLoad(int argc, char* argv[]); -CMDRESULT cbScriptMsg(int argc, char* argv[]); -CMDRESULT cbScriptMsgyn(int argc, char* argv[]); - -#endif // _SIMPLESCRIPT_H +#ifndef _SIMPLESCRIPT_H +#define _SIMPLESCRIPT_H + +#include "command.h" + +//structures +struct SCRIPTBP +{ + int line; + bool silent; //do not show in GUI +}; + +struct LINEMAPENTRY +{ + SCRIPTLINETYPE type; + char raw[256]; + union + { + char command[256]; + SCRIPTBRANCH branch; + char label[256]; + char comment[256]; + } u; +}; + +//functions +void scriptload(const char* filename); +void scriptunload(); +void scriptrun(int destline); +void scriptstep(); +bool scriptbptoggle(int line); +bool scriptbpget(int line); +bool scriptcmdexec(const char* command); +void scriptabort(); +SCRIPTLINETYPE scriptgetlinetype(int line); +void scriptsetip(int line); +void scriptreset(); +bool scriptgetbranchinfo(int line, SCRIPTBRANCH* info); + +//script commands +CMDRESULT cbScriptLoad(int argc, char* argv[]); +CMDRESULT cbScriptMsg(int argc, char* argv[]); +CMDRESULT cbScriptMsgyn(int argc, char* argv[]); + +#endif // _SIMPLESCRIPT_H diff --git a/src/dbg/stackinfo.cpp b/src/dbg/stackinfo.cpp index 1848ec47..11930185 100644 --- a/src/dbg/stackinfo.cpp +++ b/src/dbg/stackinfo.cpp @@ -1,266 +1,266 @@ -/** - @file stackinfo.cpp - - @brief Implements the stackinfo class. - */ - -#include "stackinfo.h" -#include "memory.h" -#include "disasm_helper.h" -#include "disasm_fast.h" -#include "_exports.h" -#include "module.h" -#include "thread.h" - -bool stackcommentget(duint addr, STACK_COMMENT* comment) -{ - duint data = 0; - memset(comment, 0, sizeof(STACK_COMMENT)); - MemRead(addr, &data, sizeof(duint)); - if(!MemIsValidReadPtr(data)) //the stack value is no pointer - return false; - - duint size = 0; - duint base = MemFindBaseAddr(data, &size); - duint readStart = data - 16 * 4; - if(readStart < base) - readStart = base; - unsigned char disasmData[256]; - MemRead(readStart, disasmData, sizeof(disasmData)); - duint prev = disasmback(disasmData, 0, sizeof(disasmData), data - readStart, 1); - duint previousInstr = readStart + prev; - - BASIC_INSTRUCTION_INFO basicinfo; - bool valid = disasmfast(disasmData + prev, previousInstr, &basicinfo); - if(valid && basicinfo.call) //call - { - char label[MAX_LABEL_SIZE] = ""; - ADDRINFO addrinfo; - addrinfo.flags = flaglabel; - if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) - strcpy_s(label, addrinfo.label); - char module[MAX_MODULE_SIZE] = ""; - ModNameFromAddr(data, module, false); - char returnToAddr[MAX_COMMENT_SIZE] = ""; - if(*module) - sprintf(returnToAddr, "%s.", module); - if(!*label) - sprintf(label, fhex, data); - strcat(returnToAddr, label); - - data = basicinfo.addr; - if(data) - { - *label = 0; - addrinfo.flags = flaglabel; - if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) - strcpy_s(label, addrinfo.label); - *module = 0; - ModNameFromAddr(data, module, false); - char returnFromAddr[MAX_COMMENT_SIZE] = ""; - if(*module) - sprintf(returnFromAddr, "%s.", module); - if(!*label) - sprintf(label, fhex, data); - strcat_s(returnFromAddr, label); - sprintf_s(comment->comment, "return to %s from %s", returnToAddr, returnFromAddr); - } - else - sprintf_s(comment->comment, "return to %s from ???", returnToAddr); - strcpy_s(comment->color, "#ff0000"); - return true; - } - - //string - STRING_TYPE strtype; - char string[512] = ""; - if(disasmgetstringat(data, &strtype, string, string, 500)) - { - if(strtype == str_ascii) - sprintf(comment->comment, "\"%s\"", string); - else //unicode - sprintf(comment->comment, "L\"%s\"", string); - return true; - } - - //label - char label[MAX_LABEL_SIZE] = ""; - ADDRINFO addrinfo; - addrinfo.flags = flaglabel; - if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) - strcpy_s(label, addrinfo.label); - char module[MAX_MODULE_SIZE] = ""; - ModNameFromAddr(data, module, false); - - if(*module) //module - { - if(*label) //+label - sprintf(comment->comment, "%s.%s", module, label); - else //module only - sprintf(comment->comment, "%s." fhex, module, data); - return true; - } - else if(*label) //label only - { - sprintf(comment->comment, "<%s>", label); - return true; - } - - return false; -} - -BOOL CALLBACK StackReadProcessMemoryProc64(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) -{ - // Fix for 64-bit sizes - SIZE_T bytesRead = 0; - - if(MemRead((duint)lpBaseAddress, lpBuffer, nSize, &bytesRead)) - { - if(lpNumberOfBytesRead) - *lpNumberOfBytesRead = (DWORD)bytesRead; - - return true; - } - - return false; -} - -DWORD64 CALLBACK StackGetModuleBaseProc64(HANDLE hProcess, DWORD64 Address) -{ - return (DWORD64)ModBaseFromAddr((duint)Address); -} - -DWORD64 CALLBACK StackTranslateAddressProc64(HANDLE hProcess, HANDLE hThread, LPADDRESS64 lpaddr) -{ - ASSERT_ALWAYS("This function should never be called"); - return 0; -} - -void StackEntryFromFrame(CALLSTACKENTRY* Entry, duint Address, duint From, duint To) -{ - Entry->addr = Address; - Entry->from = From; - Entry->to = To; - - char label[MAX_LABEL_SIZE] = ""; - ADDRINFO addrinfo; - addrinfo.flags = flaglabel; - if(_dbg_addrinfoget(Entry->to, SEG_DEFAULT, &addrinfo)) - strcpy_s(label, addrinfo.label); - char module[MAX_MODULE_SIZE] = ""; - ModNameFromAddr(Entry->to, module, false); - char returnToAddr[MAX_COMMENT_SIZE] = ""; - if(*module) - sprintf(returnToAddr, "%s.", module); - if(!*label) - sprintf(label, fhex, Entry->to); - strcat(returnToAddr, label); - - if(Entry->from) - { - *label = 0; - addrinfo.flags = flaglabel; - if(_dbg_addrinfoget(Entry->from, SEG_DEFAULT, &addrinfo)) - strcpy_s(label, addrinfo.label); - *module = 0; - ModNameFromAddr(Entry->from, module, false); - char returnFromAddr[MAX_COMMENT_SIZE] = ""; - if(*module) - sprintf(returnFromAddr, "%s.", module); - if(!*label) - sprintf(label, fhex, Entry->from); - strcat(returnFromAddr, label); - - sprintf_s(Entry->comment, "return to %s from %s", returnToAddr, returnFromAddr); - } - else - sprintf_s(Entry->comment, "return to %s from ???", returnToAddr); -} - -void stackgetcallstack(duint csp, CALLSTACK* callstack) -{ - // Gather context data - CONTEXT context; - memset(&context, 0, sizeof(CONTEXT)); - - context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; - - if(SuspendThread(hActiveThread) == -1) - return; - - if(!GetThreadContext(hActiveThread, &context)) - return; - - if(ResumeThread(hActiveThread) == -1) - return; - - // Set up all frame data - STACKFRAME64 frame; - ZeroMemory(&frame, sizeof(STACKFRAME64)); - -#ifdef _M_IX86 - DWORD machineType = IMAGE_FILE_MACHINE_I386; - frame.AddrPC.Offset = context.Eip; - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrFrame.Offset = context.Ebp; - frame.AddrFrame.Mode = AddrModeFlat; - frame.AddrStack.Offset = csp; - frame.AddrStack.Mode = AddrModeFlat; -#elif _M_X64 - DWORD machineType = IMAGE_FILE_MACHINE_AMD64; - frame.AddrPC.Offset = context.Rip; - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrFrame.Offset = context.Rsp; - frame.AddrFrame.Mode = AddrModeFlat; - frame.AddrStack.Offset = csp; - frame.AddrStack.Mode = AddrModeFlat; -#endif - - // Container for each callstack entry (20 pre-allocated entries) - std::vector callstackVector; - callstackVector.reserve(20); - - while(true) - { - if(!StackWalk64( - machineType, - fdProcessInfo->hProcess, - hActiveThread, - &frame, - &context, - StackReadProcessMemoryProc64, - SymFunctionTableAccess64, - StackGetModuleBaseProc64, - StackTranslateAddressProc64)) - { - // Maybe it failed, maybe we have finished walking the stack - break; - } - - if(frame.AddrPC.Offset != 0) - { - // Valid frame - CALLSTACKENTRY entry; - memset(&entry, 0, sizeof(CALLSTACKENTRY)); - - StackEntryFromFrame(&entry, (duint)frame.AddrFrame.Offset, (duint)frame.AddrReturn.Offset, (duint)frame.AddrPC.Offset); - callstackVector.push_back(entry); - } - else - { - // Base reached - break; - } - } - - // Convert to a C data structure - callstack->total = (int)callstackVector.size(); - - if(callstack->total > 0) - { - callstack->entries = (CALLSTACKENTRY*)BridgeAlloc(callstack->total * sizeof(CALLSTACKENTRY)); - - // Copy data directly from the vector - memcpy(callstack->entries, callstackVector.data(), callstack->total * sizeof(CALLSTACKENTRY)); - } +/** + @file stackinfo.cpp + + @brief Implements the stackinfo class. + */ + +#include "stackinfo.h" +#include "memory.h" +#include "disasm_helper.h" +#include "disasm_fast.h" +#include "_exports.h" +#include "module.h" +#include "thread.h" + +bool stackcommentget(duint addr, STACK_COMMENT* comment) +{ + duint data = 0; + memset(comment, 0, sizeof(STACK_COMMENT)); + MemRead(addr, &data, sizeof(duint)); + if(!MemIsValidReadPtr(data)) //the stack value is no pointer + return false; + + duint size = 0; + duint base = MemFindBaseAddr(data, &size); + duint readStart = data - 16 * 4; + if(readStart < base) + readStart = base; + unsigned char disasmData[256]; + MemRead(readStart, disasmData, sizeof(disasmData)); + duint prev = disasmback(disasmData, 0, sizeof(disasmData), data - readStart, 1); + duint previousInstr = readStart + prev; + + BASIC_INSTRUCTION_INFO basicinfo; + bool valid = disasmfast(disasmData + prev, previousInstr, &basicinfo); + if(valid && basicinfo.call) //call + { + char label[MAX_LABEL_SIZE] = ""; + ADDRINFO addrinfo; + addrinfo.flags = flaglabel; + if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) + strcpy_s(label, addrinfo.label); + char module[MAX_MODULE_SIZE] = ""; + ModNameFromAddr(data, module, false); + char returnToAddr[MAX_COMMENT_SIZE] = ""; + if(*module) + sprintf(returnToAddr, "%s.", module); + if(!*label) + sprintf(label, fhex, data); + strcat(returnToAddr, label); + + data = basicinfo.addr; + if(data) + { + *label = 0; + addrinfo.flags = flaglabel; + if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) + strcpy_s(label, addrinfo.label); + *module = 0; + ModNameFromAddr(data, module, false); + char returnFromAddr[MAX_COMMENT_SIZE] = ""; + if(*module) + sprintf(returnFromAddr, "%s.", module); + if(!*label) + sprintf(label, fhex, data); + strcat_s(returnFromAddr, label); + sprintf_s(comment->comment, "return to %s from %s", returnToAddr, returnFromAddr); + } + else + sprintf_s(comment->comment, "return to %s from ???", returnToAddr); + strcpy_s(comment->color, "#ff0000"); + return true; + } + + //string + STRING_TYPE strtype; + char string[512] = ""; + if(disasmgetstringat(data, &strtype, string, string, 500)) + { + if(strtype == str_ascii) + sprintf(comment->comment, "\"%s\"", string); + else //unicode + sprintf(comment->comment, "L\"%s\"", string); + return true; + } + + //label + char label[MAX_LABEL_SIZE] = ""; + ADDRINFO addrinfo; + addrinfo.flags = flaglabel; + if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) + strcpy_s(label, addrinfo.label); + char module[MAX_MODULE_SIZE] = ""; + ModNameFromAddr(data, module, false); + + if(*module) //module + { + if(*label) //+label + sprintf(comment->comment, "%s.%s", module, label); + else //module only + sprintf(comment->comment, "%s." fhex, module, data); + return true; + } + else if(*label) //label only + { + sprintf(comment->comment, "<%s>", label); + return true; + } + + return false; +} + +BOOL CALLBACK StackReadProcessMemoryProc64(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) +{ + // Fix for 64-bit sizes + SIZE_T bytesRead = 0; + + if(MemRead((duint)lpBaseAddress, lpBuffer, nSize, &bytesRead)) + { + if(lpNumberOfBytesRead) + *lpNumberOfBytesRead = (DWORD)bytesRead; + + return true; + } + + return false; +} + +DWORD64 CALLBACK StackGetModuleBaseProc64(HANDLE hProcess, DWORD64 Address) +{ + return (DWORD64)ModBaseFromAddr((duint)Address); +} + +DWORD64 CALLBACK StackTranslateAddressProc64(HANDLE hProcess, HANDLE hThread, LPADDRESS64 lpaddr) +{ + ASSERT_ALWAYS("This function should never be called"); + return 0; +} + +void StackEntryFromFrame(CALLSTACKENTRY* Entry, duint Address, duint From, duint To) +{ + Entry->addr = Address; + Entry->from = From; + Entry->to = To; + + char label[MAX_LABEL_SIZE] = ""; + ADDRINFO addrinfo; + addrinfo.flags = flaglabel; + if(_dbg_addrinfoget(Entry->to, SEG_DEFAULT, &addrinfo)) + strcpy_s(label, addrinfo.label); + char module[MAX_MODULE_SIZE] = ""; + ModNameFromAddr(Entry->to, module, false); + char returnToAddr[MAX_COMMENT_SIZE] = ""; + if(*module) + sprintf(returnToAddr, "%s.", module); + if(!*label) + sprintf(label, fhex, Entry->to); + strcat(returnToAddr, label); + + if(Entry->from) + { + *label = 0; + addrinfo.flags = flaglabel; + if(_dbg_addrinfoget(Entry->from, SEG_DEFAULT, &addrinfo)) + strcpy_s(label, addrinfo.label); + *module = 0; + ModNameFromAddr(Entry->from, module, false); + char returnFromAddr[MAX_COMMENT_SIZE] = ""; + if(*module) + sprintf(returnFromAddr, "%s.", module); + if(!*label) + sprintf(label, fhex, Entry->from); + strcat(returnFromAddr, label); + + sprintf_s(Entry->comment, "return to %s from %s", returnToAddr, returnFromAddr); + } + else + sprintf_s(Entry->comment, "return to %s from ???", returnToAddr); +} + +void stackgetcallstack(duint csp, CALLSTACK* callstack) +{ + // Gather context data + CONTEXT context; + memset(&context, 0, sizeof(CONTEXT)); + + context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; + + if(SuspendThread(hActiveThread) == -1) + return; + + if(!GetThreadContext(hActiveThread, &context)) + return; + + if(ResumeThread(hActiveThread) == -1) + return; + + // Set up all frame data + STACKFRAME64 frame; + ZeroMemory(&frame, sizeof(STACKFRAME64)); + +#ifdef _M_IX86 + DWORD machineType = IMAGE_FILE_MACHINE_I386; + frame.AddrPC.Offset = context.Eip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.Ebp; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Offset = csp; + frame.AddrStack.Mode = AddrModeFlat; +#elif _M_X64 + DWORD machineType = IMAGE_FILE_MACHINE_AMD64; + frame.AddrPC.Offset = context.Rip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.Rsp; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Offset = csp; + frame.AddrStack.Mode = AddrModeFlat; +#endif + + // Container for each callstack entry (20 pre-allocated entries) + std::vector callstackVector; + callstackVector.reserve(20); + + while(true) + { + if(!StackWalk64( + machineType, + fdProcessInfo->hProcess, + hActiveThread, + &frame, + &context, + StackReadProcessMemoryProc64, + SymFunctionTableAccess64, + StackGetModuleBaseProc64, + StackTranslateAddressProc64)) + { + // Maybe it failed, maybe we have finished walking the stack + break; + } + + if(frame.AddrPC.Offset != 0) + { + // Valid frame + CALLSTACKENTRY entry; + memset(&entry, 0, sizeof(CALLSTACKENTRY)); + + StackEntryFromFrame(&entry, (duint)frame.AddrFrame.Offset, (duint)frame.AddrReturn.Offset, (duint)frame.AddrPC.Offset); + callstackVector.push_back(entry); + } + else + { + // Base reached + break; + } + } + + // Convert to a C data structure + callstack->total = (int)callstackVector.size(); + + if(callstack->total > 0) + { + callstack->entries = (CALLSTACKENTRY*)BridgeAlloc(callstack->total * sizeof(CALLSTACKENTRY)); + + // Copy data directly from the vector + memcpy(callstack->entries, callstackVector.data(), callstack->total * sizeof(CALLSTACKENTRY)); + } } \ No newline at end of file diff --git a/src/dbg/stackinfo.h b/src/dbg/stackinfo.h index 861bcccf..2bb2bb4a 100644 --- a/src/dbg/stackinfo.h +++ b/src/dbg/stackinfo.h @@ -1,23 +1,23 @@ -#ifndef _STACKINFO_H -#define _STACKINFO_H - -#include "_global.h" - -struct CALLSTACKENTRY -{ - duint addr; - duint from; - duint to; - char comment[MAX_COMMENT_SIZE]; -}; - -struct CALLSTACK -{ - int total; - CALLSTACKENTRY* entries; -}; - -bool stackcommentget(duint addr, STACK_COMMENT* comment); -void stackgetcallstack(duint csp, CALLSTACK* callstack); - +#ifndef _STACKINFO_H +#define _STACKINFO_H + +#include "_global.h" + +struct CALLSTACKENTRY +{ + duint addr; + duint from; + duint to; + char comment[MAX_COMMENT_SIZE]; +}; + +struct CALLSTACK +{ + int total; + CALLSTACKENTRY* entries; +}; + +bool stackcommentget(duint addr, STACK_COMMENT* comment); +void stackgetcallstack(duint csp, CALLSTACK* callstack); + #endif //_STACKINFO_H \ No newline at end of file diff --git a/src/dbg/stringformat.cpp b/src/dbg/stringformat.cpp index 78e808ca..fec6a7d1 100644 --- a/src/dbg/stringformat.cpp +++ b/src/dbg/stringformat.cpp @@ -1,140 +1,140 @@ -#include "stringformat.h" -#include "value.h" -#include "disasm_helper.h" - -namespace ValueType -{ -enum ValueType -{ - Unknown, - SignedDecimal, - UnsignedDecimal, - Hex, - Pointer, - String -}; -} - -static String printValue(FormatValueType value, ValueType::ValueType type) -{ - duint valuint = 0; - bool validval = valfromstring(value, &valuint); - char result[deflen] = "???"; - switch(type) - { - case ValueType::Unknown: - break; - case ValueType::SignedDecimal: - if(validval) - sprintf_s(result, "%" fext "d", valuint); - break; - case ValueType::UnsignedDecimal: - if(validval) - sprintf_s(result, "%" fext "u", valuint); - break; - case ValueType::Hex: - if(validval) - sprintf_s(result, "%" fext "X", valuint); - break; - case ValueType::Pointer: - if(validval) - sprintf_s(result, "0x%" fhex, valuint); - break; - case ValueType::String: - if(validval) - { - STRING_TYPE strtype; - char string[512] = ""; - if(disasmgetstringat(valuint, &strtype, string, string, 500)) - strcpy_s(result, string); - } - break; - } - return result; -} - -static unsigned int getArgNumType(const String & formatString, ValueType::ValueType & type) -{ - int add = 0; - switch(formatString[0]) - { - case 'd': - type = ValueType::SignedDecimal; - add++; - break; - case 'u': - type = ValueType::UnsignedDecimal; - add++; - break; - case 'p': - type = ValueType::Pointer; - add++; - break; - case 's': - type = ValueType::String; - add++; - break; - default: - type = ValueType::Hex; - } - unsigned int argnum = 0; - if(sscanf(formatString.c_str() + add, "%u", &argnum) != 1) - type = ValueType::Unknown; - return argnum; -} - -static String handleFormatString(const String & formatString, const FormatValueVector & values) -{ - ValueType::ValueType type = ValueType::Unknown; - unsigned int argnum = getArgNumType(formatString, type); - if(argnum < values.size()) - return printValue(values.at(argnum), type); - return "[Formatting Error]"; -} - -String stringformat(String format, const FormatValueVector & values) -{ - StringUtils::ReplaceAll(format, "\\n", "\n"); - int len = (int)format.length(); - String output; - String formatString; - bool inFormatter = false; - for(int i = 0; i < len; i++) - { - //handle escaped format sequences "{{" and "}}" - if(format[i] == '{' && (i + 1 < len && format[i + 1] == '{')) - { - output += "{"; - i++; - continue; - } - else if(format[i] == '}' && (i + 1 < len && format[i + 1] == '}')) - { - output += "}"; - i++; - continue; - } - //handle actual formatting - if(format[i] == '{' && !inFormatter) //opening bracket - { - inFormatter = true; - formatString.clear(); - } - else if(format[i] == '}' && inFormatter) //closing bracket - { - inFormatter = false; - if(formatString.length()) - { - output += handleFormatString(formatString, values); - formatString.clear(); - } - } - else if(inFormatter) //inside brackets - formatString += format[i]; - else //outside brackets - output += format[i]; - } - if(inFormatter && formatString.size()) - output += handleFormatString(formatString, values); - return output; +#include "stringformat.h" +#include "value.h" +#include "disasm_helper.h" + +namespace ValueType +{ +enum ValueType +{ + Unknown, + SignedDecimal, + UnsignedDecimal, + Hex, + Pointer, + String +}; +} + +static String printValue(FormatValueType value, ValueType::ValueType type) +{ + duint valuint = 0; + bool validval = valfromstring(value, &valuint); + char result[deflen] = "???"; + switch(type) + { + case ValueType::Unknown: + break; + case ValueType::SignedDecimal: + if(validval) + sprintf_s(result, "%" fext "d", valuint); + break; + case ValueType::UnsignedDecimal: + if(validval) + sprintf_s(result, "%" fext "u", valuint); + break; + case ValueType::Hex: + if(validval) + sprintf_s(result, "%" fext "X", valuint); + break; + case ValueType::Pointer: + if(validval) + sprintf_s(result, "0x%" fhex, valuint); + break; + case ValueType::String: + if(validval) + { + STRING_TYPE strtype; + char string[512] = ""; + if(disasmgetstringat(valuint, &strtype, string, string, 500)) + strcpy_s(result, string); + } + break; + } + return result; +} + +static unsigned int getArgNumType(const String & formatString, ValueType::ValueType & type) +{ + int add = 0; + switch(formatString[0]) + { + case 'd': + type = ValueType::SignedDecimal; + add++; + break; + case 'u': + type = ValueType::UnsignedDecimal; + add++; + break; + case 'p': + type = ValueType::Pointer; + add++; + break; + case 's': + type = ValueType::String; + add++; + break; + default: + type = ValueType::Hex; + } + unsigned int argnum = 0; + if(sscanf(formatString.c_str() + add, "%u", &argnum) != 1) + type = ValueType::Unknown; + return argnum; +} + +static String handleFormatString(const String & formatString, const FormatValueVector & values) +{ + ValueType::ValueType type = ValueType::Unknown; + unsigned int argnum = getArgNumType(formatString, type); + if(argnum < values.size()) + return printValue(values.at(argnum), type); + return "[Formatting Error]"; +} + +String stringformat(String format, const FormatValueVector & values) +{ + StringUtils::ReplaceAll(format, "\\n", "\n"); + int len = (int)format.length(); + String output; + String formatString; + bool inFormatter = false; + for(int i = 0; i < len; i++) + { + //handle escaped format sequences "{{" and "}}" + if(format[i] == '{' && (i + 1 < len && format[i + 1] == '{')) + { + output += "{"; + i++; + continue; + } + else if(format[i] == '}' && (i + 1 < len && format[i + 1] == '}')) + { + output += "}"; + i++; + continue; + } + //handle actual formatting + if(format[i] == '{' && !inFormatter) //opening bracket + { + inFormatter = true; + formatString.clear(); + } + else if(format[i] == '}' && inFormatter) //closing bracket + { + inFormatter = false; + if(formatString.length()) + { + output += handleFormatString(formatString, values); + formatString.clear(); + } + } + else if(inFormatter) //inside brackets + formatString += format[i]; + else //outside brackets + output += format[i]; + } + if(inFormatter && formatString.size()) + output += handleFormatString(formatString, values); + return output; } \ No newline at end of file diff --git a/src/dbg/stringformat.h b/src/dbg/stringformat.h index 00772eb6..cdd99f1e 100644 --- a/src/dbg/stringformat.h +++ b/src/dbg/stringformat.h @@ -1,11 +1,11 @@ -#ifndef _STRINGFORMAT_H -#define _STRINGFORMAT_H - -#include "_global.h" - -typedef const char* FormatValueType; -typedef std::vector FormatValueVector; - -String stringformat(String format, const FormatValueVector & values); - +#ifndef _STRINGFORMAT_H +#define _STRINGFORMAT_H + +#include "_global.h" + +typedef const char* FormatValueType; +typedef std::vector FormatValueVector; + +String stringformat(String format, const FormatValueVector & values); + #endif //_STRINGFORMAT_H \ No newline at end of file diff --git a/src/dbg/stringutils.cpp b/src/dbg/stringutils.cpp index 37141c97..d0d749c8 100644 --- a/src/dbg/stringutils.cpp +++ b/src/dbg/stringutils.cpp @@ -1,185 +1,185 @@ -#include -#include "stringutils.h" -#include "memory.h" - -StringList StringUtils::Split(const String & s, char delim, std::vector & elems) -{ - std::stringstream ss(s); - String item; - while(std::getline(ss, item, delim)) - { - if(!item.length()) - continue; - elems.push_back(item); - } - return elems; -} - -StringList StringUtils::Split(const String & s, char delim) -{ - std::vector elems; - Split(s, delim, elems); - return elems; -} - -String StringUtils::Escape(const String & s) -{ - String escaped = ""; - for(size_t i = 0; i < s.length(); i++) - { - char ch = s[i]; - switch(ch) - { - case '\t': - escaped += "\\t"; - break; - case '\f': - escaped += "\\f"; - break; - case '\v': - escaped += "\\v"; - break; - case '\n': - escaped += "\\n"; - break; - case '\r': - escaped += "\\r"; - break; - case '\\': - escaped += "\\\\"; - break; - case '\"': - escaped += "\\\""; - break; - default: - if(!isprint(ch)) //unknown unprintable character - { - char buf[16] = ""; - sprintf_s(buf, "\\x%.2X", (unsigned char)ch); - escaped += buf; - } - else - escaped += ch; - break; - } - } - return escaped; -} - -//Trim functions taken from: http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring/16743707#16743707 -const String StringUtils::WHITESPACE = " \n\r\t"; - -String StringUtils::Trim(const String & s) -{ - return TrimRight(TrimLeft(s)); -} - -String StringUtils::TrimLeft(const String & s) -{ - size_t startpos = s.find_first_not_of(StringUtils::WHITESPACE); - return (startpos == String::npos) ? "" : s.substr(startpos); -} - -String StringUtils::TrimRight(const String & s) -{ - size_t endpos = s.find_last_not_of(StringUtils::WHITESPACE); - return (endpos == String::npos) ? "" : s.substr(0, endpos + 1); -} - -//Conversion functions taken from: http://www.nubaria.com/en/blog/?p=289 -String StringUtils::Utf16ToUtf8(const WString & wstr) -{ - String convertedString; - int requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, 0, 0, 0, 0); - if(requiredSize > 0) - { - std::vector buffer(requiredSize); - WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &buffer[0], requiredSize, 0, 0); - convertedString.assign(buffer.begin(), buffer.end() - 1); - } - return convertedString; -} - -String StringUtils::Utf16ToUtf8(const wchar_t* wstr) -{ - return Utf16ToUtf8(wstr ? WString(wstr) : WString()); -} - -WString StringUtils::Utf8ToUtf16(const String & str) -{ - WString convertedString; - int requiredSize = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, 0, 0); - if(requiredSize > 0) - { - std::vector buffer(requiredSize); - MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &buffer[0], requiredSize); - convertedString.assign(buffer.begin(), buffer.end() - 1); - } - return convertedString; -} - -WString StringUtils::Utf8ToUtf16(const char* str) -{ - return Utf8ToUtf16(str ? String(str) : String()); -} - -//Taken from: http://stackoverflow.com/a/24315631 -void StringUtils::ReplaceAll(String & s, const String & from, const String & to) -{ - size_t start_pos = 0; - while((start_pos = s.find(from, start_pos)) != std::string::npos) - { - s.replace(start_pos, from.length(), to); - start_pos += to.length(); // Handles case where 'to' is a substring of 'from' - } -} - -void StringUtils::ReplaceAll(WString & s, const WString & from, const WString & to) -{ - size_t start_pos = 0; - while((start_pos = s.find(from, start_pos)) != std::string::npos) - { - s.replace(start_pos, from.length(), to); - start_pos += to.length(); // Handles case where 'to' is a substring of 'from' - } -} - -String StringUtils::sprintf(const char* format, ...) -{ - va_list args; - va_start(args, format); - Memory buffer(256 * sizeof(char), "StringUtils::sprintf"); - while(true) - { - int res = _vsnprintf_s(buffer(), buffer.size(), _TRUNCATE, format, args); - if(res == -1) - { - buffer.realloc(buffer.size() * 2, "StringUtils::sprintf"); - continue; - } - else - break; - } - va_end(args); - return String(buffer()); -} - -WString StringUtils::sprintf(const wchar_t* format, ...) -{ - va_list args; - va_start(args, format); - Memory buffer(256 * sizeof(wchar_t), "StringUtils::sprintf"); - while(true) - { - int res = _vsnwprintf_s(buffer(), buffer.size(), _TRUNCATE, format, args); - if(res == -1) - { - buffer.realloc(buffer.size() * 2, "StringUtils::sprintf"); - continue; - } - else - break; - } - va_end(args); - return WString(buffer()); +#include +#include "stringutils.h" +#include "memory.h" + +StringList StringUtils::Split(const String & s, char delim, std::vector & elems) +{ + std::stringstream ss(s); + String item; + while(std::getline(ss, item, delim)) + { + if(!item.length()) + continue; + elems.push_back(item); + } + return elems; +} + +StringList StringUtils::Split(const String & s, char delim) +{ + std::vector elems; + Split(s, delim, elems); + return elems; +} + +String StringUtils::Escape(const String & s) +{ + String escaped = ""; + for(size_t i = 0; i < s.length(); i++) + { + char ch = s[i]; + switch(ch) + { + case '\t': + escaped += "\\t"; + break; + case '\f': + escaped += "\\f"; + break; + case '\v': + escaped += "\\v"; + break; + case '\n': + escaped += "\\n"; + break; + case '\r': + escaped += "\\r"; + break; + case '\\': + escaped += "\\\\"; + break; + case '\"': + escaped += "\\\""; + break; + default: + if(!isprint(ch)) //unknown unprintable character + { + char buf[16] = ""; + sprintf_s(buf, "\\x%.2X", (unsigned char)ch); + escaped += buf; + } + else + escaped += ch; + break; + } + } + return escaped; +} + +//Trim functions taken from: http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring/16743707#16743707 +const String StringUtils::WHITESPACE = " \n\r\t"; + +String StringUtils::Trim(const String & s) +{ + return TrimRight(TrimLeft(s)); +} + +String StringUtils::TrimLeft(const String & s) +{ + size_t startpos = s.find_first_not_of(StringUtils::WHITESPACE); + return (startpos == String::npos) ? "" : s.substr(startpos); +} + +String StringUtils::TrimRight(const String & s) +{ + size_t endpos = s.find_last_not_of(StringUtils::WHITESPACE); + return (endpos == String::npos) ? "" : s.substr(0, endpos + 1); +} + +//Conversion functions taken from: http://www.nubaria.com/en/blog/?p=289 +String StringUtils::Utf16ToUtf8(const WString & wstr) +{ + String convertedString; + int requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, 0, 0, 0, 0); + if(requiredSize > 0) + { + std::vector buffer(requiredSize); + WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &buffer[0], requiredSize, 0, 0); + convertedString.assign(buffer.begin(), buffer.end() - 1); + } + return convertedString; +} + +String StringUtils::Utf16ToUtf8(const wchar_t* wstr) +{ + return Utf16ToUtf8(wstr ? WString(wstr) : WString()); +} + +WString StringUtils::Utf8ToUtf16(const String & str) +{ + WString convertedString; + int requiredSize = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, 0, 0); + if(requiredSize > 0) + { + std::vector buffer(requiredSize); + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &buffer[0], requiredSize); + convertedString.assign(buffer.begin(), buffer.end() - 1); + } + return convertedString; +} + +WString StringUtils::Utf8ToUtf16(const char* str) +{ + return Utf8ToUtf16(str ? String(str) : String()); +} + +//Taken from: http://stackoverflow.com/a/24315631 +void StringUtils::ReplaceAll(String & s, const String & from, const String & to) +{ + size_t start_pos = 0; + while((start_pos = s.find(from, start_pos)) != std::string::npos) + { + s.replace(start_pos, from.length(), to); + start_pos += to.length(); // Handles case where 'to' is a substring of 'from' + } +} + +void StringUtils::ReplaceAll(WString & s, const WString & from, const WString & to) +{ + size_t start_pos = 0; + while((start_pos = s.find(from, start_pos)) != std::string::npos) + { + s.replace(start_pos, from.length(), to); + start_pos += to.length(); // Handles case where 'to' is a substring of 'from' + } +} + +String StringUtils::sprintf(const char* format, ...) +{ + va_list args; + va_start(args, format); + Memory buffer(256 * sizeof(char), "StringUtils::sprintf"); + while(true) + { + int res = _vsnprintf_s(buffer(), buffer.size(), _TRUNCATE, format, args); + if(res == -1) + { + buffer.realloc(buffer.size() * 2, "StringUtils::sprintf"); + continue; + } + else + break; + } + va_end(args); + return String(buffer()); +} + +WString StringUtils::sprintf(const wchar_t* format, ...) +{ + va_list args; + va_start(args, format); + Memory buffer(256 * sizeof(wchar_t), "StringUtils::sprintf"); + while(true) + { + int res = _vsnwprintf_s(buffer(), buffer.size(), _TRUNCATE, format, args); + if(res == -1) + { + buffer.realloc(buffer.size() * 2, "StringUtils::sprintf"); + continue; + } + else + break; + } + va_end(args); + return WString(buffer()); } \ No newline at end of file diff --git a/src/dbg/stringutils.h b/src/dbg/stringutils.h index 73d4ac70..4d8d934f 100644 --- a/src/dbg/stringutils.h +++ b/src/dbg/stringutils.h @@ -1,34 +1,34 @@ -#ifndef _STRINGUTILS_H -#define _STRINGUTILS_H - -#include -#include - -typedef std::string String; -typedef std::wstring WString; -typedef std::vector StringList; -typedef std::vector WStringList; - -class StringUtils -{ -public: - static StringList Split(const String & s, char delim, std::vector & elems); - static StringList Split(const String & s, char delim); - static String Escape(const String & s); - static String Trim(const String & s); - static String TrimLeft(const String & s); - static String TrimRight(const String & s); - static String Utf16ToUtf8(const WString & wstr); - static String Utf16ToUtf8(const wchar_t* wstr); - static WString Utf8ToUtf16(const String & str); - static WString Utf8ToUtf16(const char* str); - static void ReplaceAll(String & s, const String & from, const String & to); - static void ReplaceAll(WString & s, const WString & from, const WString & to); - static String sprintf(const char* format, ...); - static WString sprintf(const wchar_t* format, ...); - -private: - static const String WHITESPACE; -}; - +#ifndef _STRINGUTILS_H +#define _STRINGUTILS_H + +#include +#include + +typedef std::string String; +typedef std::wstring WString; +typedef std::vector StringList; +typedef std::vector WStringList; + +class StringUtils +{ +public: + static StringList Split(const String & s, char delim, std::vector & elems); + static StringList Split(const String & s, char delim); + static String Escape(const String & s); + static String Trim(const String & s); + static String TrimLeft(const String & s); + static String TrimRight(const String & s); + static String Utf16ToUtf8(const WString & wstr); + static String Utf16ToUtf8(const wchar_t* wstr); + static WString Utf8ToUtf16(const String & str); + static WString Utf8ToUtf16(const char* str); + static void ReplaceAll(String & s, const String & from, const String & to); + static void ReplaceAll(WString & s, const WString & from, const WString & to); + static String sprintf(const char* format, ...); + static WString sprintf(const wchar_t* format, ...); + +private: + static const String WHITESPACE; +}; + #endif //_STRINGUTILS_H \ No newline at end of file diff --git a/src/dbg/symbolinfo.cpp b/src/dbg/symbolinfo.cpp index 9e6f5ead..3a5c77d5 100644 --- a/src/dbg/symbolinfo.cpp +++ b/src/dbg/symbolinfo.cpp @@ -1,304 +1,304 @@ -/** - @file symbolinfo.cpp - - @brief Implements the symbolinfo class. - */ - -#include "symbolinfo.h" -#include "debugger.h" -#include "console.h" -#include "module.h" -#include "label.h" - -struct SYMBOLCBDATA -{ - CBSYMBOLENUM cbSymbolEnum; - void* user; -}; - -BOOL CALLBACK EnumSymbols(PSYMBOL_INFO SymInfo, ULONG SymbolSize, PVOID UserContext) -{ - SYMBOLINFO curSymbol; - memset(&curSymbol, 0, sizeof(SYMBOLINFO)); - - curSymbol.addr = (duint)SymInfo->Address; - curSymbol.decoratedSymbol = (char*)BridgeAlloc(strlen(SymInfo->Name) + 1); - curSymbol.undecoratedSymbol = (char*)BridgeAlloc(MAX_SYM_NAME); - strcpy_s(curSymbol.decoratedSymbol, strlen(SymInfo->Name) + 1, SymInfo->Name); - - // Skip bad ordinals - if(strstr(SymInfo->Name, "Ordinal")) - { - // Does the symbol point to the module base? - if(SymInfo->Address == SymInfo->ModBase) - return TRUE; - } - - // Convert a mangled/decorated C++ name to a readable format - if(!SafeUnDecorateSymbolName(SymInfo->Name, curSymbol.undecoratedSymbol, MAX_SYM_NAME, UNDNAME_COMPLETE)) - { - BridgeFree(curSymbol.undecoratedSymbol); - curSymbol.undecoratedSymbol = nullptr; - } - else if(!strcmp(curSymbol.decoratedSymbol, curSymbol.undecoratedSymbol)) - { - BridgeFree(curSymbol.undecoratedSymbol); - curSymbol.undecoratedSymbol = nullptr; - } - - SYMBOLCBDATA* cbData = (SYMBOLCBDATA*)UserContext; - cbData->cbSymbolEnum(&curSymbol, cbData->user); - return TRUE; -} - -void SymEnum(duint Base, CBSYMBOLENUM EnumCallback, void* UserData) -{ - SYMBOLCBDATA symbolCbData; - symbolCbData.cbSymbolEnum = EnumCallback; - symbolCbData.user = UserData; - - // Enumerate every single symbol for the module in 'base' - if(!SafeSymEnumSymbols(fdProcessInfo->hProcess, Base, "*", EnumSymbols, &symbolCbData)) - dputs("SymEnumSymbols failed!"); -} - -bool SymGetModuleList(std::vector* List) -{ - // - // Inline lambda enum - // - auto EnumModules = [](LPCTSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext) -> BOOL - { - SYMBOLMODULEINFO curModule; - curModule.base = (duint)BaseOfDll; - - // Terminate module name if one isn't found - if(!ModNameFromAddr(curModule.base, curModule.name, true)) - curModule.name[0] = '\0'; - - ((std::vector*)UserContext)->push_back(curModule); - return TRUE; - }; - - // Execute the symbol enumerator (Force cast to STDCALL) - if(!SafeSymEnumerateModules64(fdProcessInfo->hProcess, EnumModules, List)) - { - dputs("SymEnumerateModules64 failed!"); - return false; - } - - return true; -} - -void SymUpdateModuleList() -{ - // Build the vector of modules - std::vector modList; - - if(!SymGetModuleList(&modList)) - { - GuiSymbolUpdateModuleList(0, nullptr); - return; - } - - // Create a new array to be sent to the GUI thread - size_t moduleCount = modList.size(); - SYMBOLMODULEINFO* data = (SYMBOLMODULEINFO*)BridgeAlloc(moduleCount * sizeof(SYMBOLMODULEINFO)); - - // Direct copy from std::vector data - memcpy(data, modList.data(), moduleCount * sizeof(SYMBOLMODULEINFO)); - - // Send the module data to the GUI for updating - GuiSymbolUpdateModuleList((int)moduleCount, data); -} - -void SymDownloadAllSymbols(const char* SymbolStore) -{ - // Default to Microsoft's symbol server - if(!SymbolStore) - SymbolStore = "http://msdl.microsoft.com/download/symbols"; - - // Build the vector of modules - std::vector modList; - - if(!SymGetModuleList(&modList)) - return; - - // Skip loading if there aren't any found modules - if(modList.size() <= 0) - return; - - // Backup the current symbol search path - wchar_t oldSearchPath[MAX_PATH]; - - if(!SafeSymGetSearchPathW(fdProcessInfo->hProcess, oldSearchPath, MAX_PATH)) - { - dputs("SymGetSearchPathW failed!"); - return; - } - - // Use the custom server path and directory - char customSearchPath[MAX_PATH * 2]; - sprintf_s(customSearchPath, "SRV*%s*%s", szSymbolCachePath, SymbolStore); - - if(!SafeSymSetSearchPathW(fdProcessInfo->hProcess, StringUtils::Utf8ToUtf16(customSearchPath).c_str())) - { - dputs("SymSetSearchPathW (1) failed!"); - return; - } - - // Reload - for(auto & module : modList) - { - dprintf("Downloading symbols for %s...\n", module.name); - - wchar_t modulePath[MAX_PATH]; - if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)module.base, modulePath, MAX_PATH)) - { - dprintf("GetModuleFileNameExW(" fhex ") failed!\n", module.base); - continue; - } - - if(!SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)module.base)) - { - dprintf("SymUnloadModule64(" fhex ") failed!\n", module.base); - continue; - } - - if(!SafeSymLoadModuleEx(fdProcessInfo->hProcess, 0, StringUtils::Utf16ToUtf8(modulePath).c_str(), 0, (DWORD64)module.base, 0, 0, 0)) - { - dprintf("SymLoadModuleEx(" fhex ") failed!\n", module.base); - continue; - } - } - - // Restore the old search path - if(!SafeSymSetSearchPathW(fdProcessInfo->hProcess, oldSearchPath)) - dputs("SymSetSearchPathW (2) failed!"); -} - -bool SymAddrFromName(const char* Name, duint* Address) -{ - if(!Name || Name[0] == '\0') - return false; - - if(!Address) - return false; - - // Skip 'OrdinalXXX' - if(!_strnicmp(Name, "Ordinal", 7)) - return false; - - // According to MSDN: - // Note that the total size of the data is the SizeOfStruct + (MaxNameLen - 1) * sizeof(TCHAR) - char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)]; - - PSYMBOL_INFO symbol = (PSYMBOL_INFO)&buffer; - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - symbol->MaxNameLen = MAX_LABEL_SIZE; - - if(!SafeSymFromName(fdProcessInfo->hProcess, Name, symbol)) - return false; - - *Address = (duint)symbol->Address; - return true; -} - -const char* SymGetSymbolicName(duint Address) -{ - // - // This resolves an address to a module and symbol: - // [modname.]symbolname - // - char label[MAX_SYM_NAME]; - - // User labels have priority, but if one wasn't found, - // default to a symbol lookup - if(!LabelGet(Address, label)) - { - char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)]; - - PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - symbol->MaxNameLen = MAX_LABEL_SIZE; - - // Perform a symbol lookup - DWORD64 displacement = 0; - - if(!SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)Address, &displacement, symbol)) - return nullptr; - - // If the symbol wasn't at offset 0 (start from the beginning) ignore it - if(displacement != 0) - return nullptr; - - // Terminate the string for sanity - symbol->Name[symbol->MaxNameLen - 1] = '\0'; - - if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(symbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE)) - strcpy_s(label, symbol->Name); - } - - // TODO: FIXME: STATIC VARIABLE - static char symbolicname[MAX_MODULE_SIZE + MAX_SYM_NAME]; - char modname[MAX_MODULE_SIZE]; - - if(ModNameFromAddr(Address, modname, false)) - sprintf_s(symbolicname, "%s.%s", modname, label); - else - sprintf_s(symbolicname, "<%s>", label); - - return symbolicname; -} - -bool SymGetSourceLine(duint Cip, char* FileName, int* Line) -{ - IMAGEHLP_LINEW64 lineInfo; - memset(&lineInfo, 0, sizeof(IMAGEHLP_LINE64)); - - lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); - - // Perform a symbol lookup from a specific address - DWORD displacement; - - if(!SymGetLineFromAddrW64(fdProcessInfo->hProcess, Cip, &displacement, &lineInfo)) - return false; - - String NewFile = StringUtils::Utf16ToUtf8(lineInfo.FileName); - - // Copy line number if requested - if(Line) - *Line = lineInfo.LineNumber; - - // Copy file name if requested - if(FileName) - { - // Check if it was a full path - if(NewFile[1] == ':' && NewFile[2] == '\\') - { - // Success: no more parsing - strcpy_s(FileName, MAX_STRING_SIZE, NewFile.c_str()); - return true; - } - - // Construct full path from pdb path - IMAGEHLP_MODULE64 modInfo; - memset(&modInfo, 0, sizeof(IMAGEHLP_MODULE64)); - modInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); - - if(!SafeSymGetModuleInfo64(fdProcessInfo->hProcess, Cip, &modInfo)) - return false; - - // Strip the name, leaving only the file directory - char* pdbFileName = strrchr(modInfo.LoadedPdbName, '\\'); - - if(pdbFileName) - pdbFileName[1] = '\0'; - - // Copy back to the caller's buffer - strcpy_s(FileName, MAX_STRING_SIZE, modInfo.LoadedPdbName); - strcat_s(FileName, MAX_STRING_SIZE, NewFile.c_str()); - } - - return true; +/** + @file symbolinfo.cpp + + @brief Implements the symbolinfo class. + */ + +#include "symbolinfo.h" +#include "debugger.h" +#include "console.h" +#include "module.h" +#include "label.h" + +struct SYMBOLCBDATA +{ + CBSYMBOLENUM cbSymbolEnum; + void* user; +}; + +BOOL CALLBACK EnumSymbols(PSYMBOL_INFO SymInfo, ULONG SymbolSize, PVOID UserContext) +{ + SYMBOLINFO curSymbol; + memset(&curSymbol, 0, sizeof(SYMBOLINFO)); + + curSymbol.addr = (duint)SymInfo->Address; + curSymbol.decoratedSymbol = (char*)BridgeAlloc(strlen(SymInfo->Name) + 1); + curSymbol.undecoratedSymbol = (char*)BridgeAlloc(MAX_SYM_NAME); + strcpy_s(curSymbol.decoratedSymbol, strlen(SymInfo->Name) + 1, SymInfo->Name); + + // Skip bad ordinals + if(strstr(SymInfo->Name, "Ordinal")) + { + // Does the symbol point to the module base? + if(SymInfo->Address == SymInfo->ModBase) + return TRUE; + } + + // Convert a mangled/decorated C++ name to a readable format + if(!SafeUnDecorateSymbolName(SymInfo->Name, curSymbol.undecoratedSymbol, MAX_SYM_NAME, UNDNAME_COMPLETE)) + { + BridgeFree(curSymbol.undecoratedSymbol); + curSymbol.undecoratedSymbol = nullptr; + } + else if(!strcmp(curSymbol.decoratedSymbol, curSymbol.undecoratedSymbol)) + { + BridgeFree(curSymbol.undecoratedSymbol); + curSymbol.undecoratedSymbol = nullptr; + } + + SYMBOLCBDATA* cbData = (SYMBOLCBDATA*)UserContext; + cbData->cbSymbolEnum(&curSymbol, cbData->user); + return TRUE; +} + +void SymEnum(duint Base, CBSYMBOLENUM EnumCallback, void* UserData) +{ + SYMBOLCBDATA symbolCbData; + symbolCbData.cbSymbolEnum = EnumCallback; + symbolCbData.user = UserData; + + // Enumerate every single symbol for the module in 'base' + if(!SafeSymEnumSymbols(fdProcessInfo->hProcess, Base, "*", EnumSymbols, &symbolCbData)) + dputs("SymEnumSymbols failed!"); +} + +bool SymGetModuleList(std::vector* List) +{ + // + // Inline lambda enum + // + auto EnumModules = [](LPCTSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext) -> BOOL + { + SYMBOLMODULEINFO curModule; + curModule.base = (duint)BaseOfDll; + + // Terminate module name if one isn't found + if(!ModNameFromAddr(curModule.base, curModule.name, true)) + curModule.name[0] = '\0'; + + ((std::vector*)UserContext)->push_back(curModule); + return TRUE; + }; + + // Execute the symbol enumerator (Force cast to STDCALL) + if(!SafeSymEnumerateModules64(fdProcessInfo->hProcess, EnumModules, List)) + { + dputs("SymEnumerateModules64 failed!"); + return false; + } + + return true; +} + +void SymUpdateModuleList() +{ + // Build the vector of modules + std::vector modList; + + if(!SymGetModuleList(&modList)) + { + GuiSymbolUpdateModuleList(0, nullptr); + return; + } + + // Create a new array to be sent to the GUI thread + size_t moduleCount = modList.size(); + SYMBOLMODULEINFO* data = (SYMBOLMODULEINFO*)BridgeAlloc(moduleCount * sizeof(SYMBOLMODULEINFO)); + + // Direct copy from std::vector data + memcpy(data, modList.data(), moduleCount * sizeof(SYMBOLMODULEINFO)); + + // Send the module data to the GUI for updating + GuiSymbolUpdateModuleList((int)moduleCount, data); +} + +void SymDownloadAllSymbols(const char* SymbolStore) +{ + // Default to Microsoft's symbol server + if(!SymbolStore) + SymbolStore = "http://msdl.microsoft.com/download/symbols"; + + // Build the vector of modules + std::vector modList; + + if(!SymGetModuleList(&modList)) + return; + + // Skip loading if there aren't any found modules + if(modList.size() <= 0) + return; + + // Backup the current symbol search path + wchar_t oldSearchPath[MAX_PATH]; + + if(!SafeSymGetSearchPathW(fdProcessInfo->hProcess, oldSearchPath, MAX_PATH)) + { + dputs("SymGetSearchPathW failed!"); + return; + } + + // Use the custom server path and directory + char customSearchPath[MAX_PATH * 2]; + sprintf_s(customSearchPath, "SRV*%s*%s", szSymbolCachePath, SymbolStore); + + if(!SafeSymSetSearchPathW(fdProcessInfo->hProcess, StringUtils::Utf8ToUtf16(customSearchPath).c_str())) + { + dputs("SymSetSearchPathW (1) failed!"); + return; + } + + // Reload + for(auto & module : modList) + { + dprintf("Downloading symbols for %s...\n", module.name); + + wchar_t modulePath[MAX_PATH]; + if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)module.base, modulePath, MAX_PATH)) + { + dprintf("GetModuleFileNameExW(" fhex ") failed!\n", module.base); + continue; + } + + if(!SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)module.base)) + { + dprintf("SymUnloadModule64(" fhex ") failed!\n", module.base); + continue; + } + + if(!SafeSymLoadModuleEx(fdProcessInfo->hProcess, 0, StringUtils::Utf16ToUtf8(modulePath).c_str(), 0, (DWORD64)module.base, 0, 0, 0)) + { + dprintf("SymLoadModuleEx(" fhex ") failed!\n", module.base); + continue; + } + } + + // Restore the old search path + if(!SafeSymSetSearchPathW(fdProcessInfo->hProcess, oldSearchPath)) + dputs("SymSetSearchPathW (2) failed!"); +} + +bool SymAddrFromName(const char* Name, duint* Address) +{ + if(!Name || Name[0] == '\0') + return false; + + if(!Address) + return false; + + // Skip 'OrdinalXXX' + if(!_strnicmp(Name, "Ordinal", 7)) + return false; + + // According to MSDN: + // Note that the total size of the data is the SizeOfStruct + (MaxNameLen - 1) * sizeof(TCHAR) + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)]; + + PSYMBOL_INFO symbol = (PSYMBOL_INFO)&buffer; + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + symbol->MaxNameLen = MAX_LABEL_SIZE; + + if(!SafeSymFromName(fdProcessInfo->hProcess, Name, symbol)) + return false; + + *Address = (duint)symbol->Address; + return true; +} + +const char* SymGetSymbolicName(duint Address) +{ + // + // This resolves an address to a module and symbol: + // [modname.]symbolname + // + char label[MAX_SYM_NAME]; + + // User labels have priority, but if one wasn't found, + // default to a symbol lookup + if(!LabelGet(Address, label)) + { + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)]; + + PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + symbol->MaxNameLen = MAX_LABEL_SIZE; + + // Perform a symbol lookup + DWORD64 displacement = 0; + + if(!SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)Address, &displacement, symbol)) + return nullptr; + + // If the symbol wasn't at offset 0 (start from the beginning) ignore it + if(displacement != 0) + return nullptr; + + // Terminate the string for sanity + symbol->Name[symbol->MaxNameLen - 1] = '\0'; + + if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(symbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE)) + strcpy_s(label, symbol->Name); + } + + // TODO: FIXME: STATIC VARIABLE + static char symbolicname[MAX_MODULE_SIZE + MAX_SYM_NAME]; + char modname[MAX_MODULE_SIZE]; + + if(ModNameFromAddr(Address, modname, false)) + sprintf_s(symbolicname, "%s.%s", modname, label); + else + sprintf_s(symbolicname, "<%s>", label); + + return symbolicname; +} + +bool SymGetSourceLine(duint Cip, char* FileName, int* Line) +{ + IMAGEHLP_LINEW64 lineInfo; + memset(&lineInfo, 0, sizeof(IMAGEHLP_LINE64)); + + lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + // Perform a symbol lookup from a specific address + DWORD displacement; + + if(!SymGetLineFromAddrW64(fdProcessInfo->hProcess, Cip, &displacement, &lineInfo)) + return false; + + String NewFile = StringUtils::Utf16ToUtf8(lineInfo.FileName); + + // Copy line number if requested + if(Line) + *Line = lineInfo.LineNumber; + + // Copy file name if requested + if(FileName) + { + // Check if it was a full path + if(NewFile[1] == ':' && NewFile[2] == '\\') + { + // Success: no more parsing + strcpy_s(FileName, MAX_STRING_SIZE, NewFile.c_str()); + return true; + } + + // Construct full path from pdb path + IMAGEHLP_MODULE64 modInfo; + memset(&modInfo, 0, sizeof(IMAGEHLP_MODULE64)); + modInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); + + if(!SafeSymGetModuleInfo64(fdProcessInfo->hProcess, Cip, &modInfo)) + return false; + + // Strip the name, leaving only the file directory + char* pdbFileName = strrchr(modInfo.LoadedPdbName, '\\'); + + if(pdbFileName) + pdbFileName[1] = '\0'; + + // Copy back to the caller's buffer + strcpy_s(FileName, MAX_STRING_SIZE, modInfo.LoadedPdbName); + strcat_s(FileName, MAX_STRING_SIZE, NewFile.c_str()); + } + + return true; } \ No newline at end of file diff --git a/src/dbg/symbolinfo.h b/src/dbg/symbolinfo.h index edf4736c..4b99a37d 100644 --- a/src/dbg/symbolinfo.h +++ b/src/dbg/symbolinfo.h @@ -1,19 +1,19 @@ -#pragma once - -#include "_global.h" - -void SymEnum(duint Base, CBSYMBOLENUM EnumCallback, void* UserData); -bool SymGetModuleList(std::vector* List); -void SymUpdateModuleList(); -void SymDownloadAllSymbols(const char* SymbolStore); -bool SymAddrFromName(const char* Name, duint* Address); -const char* SymGetSymbolicName(duint Address); - -/** -\brief Gets the source code file name and line from an address. -\param cip The address to check. -\param [out] szFileName Source code file. Buffer of MAX_STRING_SIZE length. UTF-8. Can be null. -\param [out] nLine Line number. Can be null. -\return true if it succeeds, false if it fails. -*/ +#pragma once + +#include "_global.h" + +void SymEnum(duint Base, CBSYMBOLENUM EnumCallback, void* UserData); +bool SymGetModuleList(std::vector* List); +void SymUpdateModuleList(); +void SymDownloadAllSymbols(const char* SymbolStore); +bool SymAddrFromName(const char* Name, duint* Address); +const char* SymGetSymbolicName(duint Address); + +/** +\brief Gets the source code file name and line from an address. +\param cip The address to check. +\param [out] szFileName Source code file. Buffer of MAX_STRING_SIZE length. UTF-8. Can be null. +\param [out] nLine Line number. Can be null. +\return true if it succeeds, false if it fails. +*/ bool SymGetSourceLine(duint Cip, char* FileName, int* Line); \ No newline at end of file diff --git a/src/dbg/test/general/dll/main.cpp b/src/dbg/test/general/dll/main.cpp index 8f28e124..537163ec 100644 --- a/src/dbg/test/general/dll/main.cpp +++ b/src/dbg/test/general/dll/main.cpp @@ -1,39 +1,39 @@ -#include "main.h" - -char global[10] = "0"; - -// a sample exported function -void DLL_EXPORT SomeFunction(const LPCSTR sometext) -{ - MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION); -} - -extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - switch(fdwReason) - { - case DLL_PROCESS_ATTACH: - { - GetTickCount(); - GetCurrentProcessId(); - GetCurrentProcess(); - DWORD old = 0; - VirtualProtect(global, 10, PAGE_GUARD, &old); - asm("int3"); - } - break; - - case DLL_PROCESS_DETACH: - // detach from process - break; - - case DLL_THREAD_ATTACH: - // attach to thread - break; - - case DLL_THREAD_DETACH: - // detach from thread - break; - } - return TRUE; // succesful -} +#include "main.h" + +char global[10] = "0"; + +// a sample exported function +void DLL_EXPORT SomeFunction(const LPCSTR sometext) +{ + MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION); +} + +extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + switch(fdwReason) + { + case DLL_PROCESS_ATTACH: + { + GetTickCount(); + GetCurrentProcessId(); + GetCurrentProcess(); + DWORD old = 0; + VirtualProtect(global, 10, PAGE_GUARD, &old); + asm("int3"); + } + break; + + case DLL_PROCESS_DETACH: + // detach from process + break; + + case DLL_THREAD_ATTACH: + // attach to thread + break; + + case DLL_THREAD_DETACH: + // detach from thread + break; + } + return TRUE; // succesful +} diff --git a/src/dbg/test/general/dll/main.h b/src/dbg/test/general/dll/main.h index 16832a6f..15fe3d47 100644 --- a/src/dbg/test/general/dll/main.h +++ b/src/dbg/test/general/dll/main.h @@ -1,28 +1,28 @@ -#ifndef __MAIN_H__ -#define __MAIN_H__ - -#include - -/* To use this exported function of dll, include this header - * in your project. - */ - -#ifdef BUILD_DLL -#define DLL_EXPORT __declspec(dllexport) -#else -#define DLL_EXPORT __declspec(dllimport) -#endif - - -#ifdef __cplusplus -extern "C" -{ -#endif - -void DLL_EXPORT SomeFunction(const LPCSTR sometext); - -#ifdef __cplusplus -} -#endif - -#endif // __MAIN_H__ +#ifndef __MAIN_H__ +#define __MAIN_H__ + +#include + +/* To use this exported function of dll, include this header + * in your project. + */ + +#ifdef BUILD_DLL +#define DLL_EXPORT __declspec(dllexport) +#else +#define DLL_EXPORT __declspec(dllimport) +#endif + + +#ifdef __cplusplus +extern "C" +{ +#endif + +void DLL_EXPORT SomeFunction(const LPCSTR sometext); + +#ifdef __cplusplus +} +#endif + +#endif // __MAIN_H__ diff --git a/src/dbg/test/general/exe/main.cpp b/src/dbg/test/general/exe/main.cpp index 0aee8f16..5607a64b 100644 --- a/src/dbg/test/general/exe/main.cpp +++ b/src/dbg/test/general/exe/main.cpp @@ -1,20 +1,20 @@ -#include - -char global[10] = "0"; - -int main() -{ - GetTickCount(); - char* a = 0; - - GetCurrentProcessId(); - GetCurrentProcess(); - DWORD old = 0; - VirtualProtect(global, 0x1000, PAGE_READWRITE | PAGE_GUARD, &old); - - /*throw exceptions*/ - global[0] = 0; //PAGE_GUARD - *a = 0; //ACCESS_VIOLATION - asm("int3"); //BREAKPOINT - return 0; -} +#include + +char global[10] = "0"; + +int main() +{ + GetTickCount(); + char* a = 0; + + GetCurrentProcessId(); + GetCurrentProcess(); + DWORD old = 0; + VirtualProtect(global, 0x1000, PAGE_READWRITE | PAGE_GUARD, &old); + + /*throw exceptions*/ + global[0] = 0; //PAGE_GUARD + *a = 0; //ACCESS_VIOLATION + asm("int3"); //BREAKPOINT + return 0; +} diff --git a/src/dbg/test/guard_page/main.cpp b/src/dbg/test/guard_page/main.cpp index 95b52297..47cf0be0 100644 --- a/src/dbg/test/guard_page/main.cpp +++ b/src/dbg/test/guard_page/main.cpp @@ -1,37 +1,37 @@ -#include -#include - -typedef bool (*CBRET)(); - -unsigned int globalvar = 0; - -int main() -{ - unsigned int lol; - unsigned char* page = (unsigned char*)VirtualAlloc(0, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); - if(!page) - { - puts("error: VirtualAlloc"); - return 1; - } - page[0] = 0x6A; - puts("write"); - page[1] = 0x01; - puts("write"); - page[2] = 0x58; - puts("write"); - page[3] = 0xC3; - puts("write"); - CBRET cb = (CBRET)page; - cb(); - puts("exec"); - lol = globalvar; - puts("read"); - lol = page[1]; - puts("read"); - lol = page[3]; - puts("read"); - lol = page[2]; - puts("read"); - return 0; -} +#include +#include + +typedef bool (*CBRET)(); + +unsigned int globalvar = 0; + +int main() +{ + unsigned int lol; + unsigned char* page = (unsigned char*)VirtualAlloc(0, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if(!page) + { + puts("error: VirtualAlloc"); + return 1; + } + page[0] = 0x6A; + puts("write"); + page[1] = 0x01; + puts("write"); + page[2] = 0x58; + puts("write"); + page[3] = 0xC3; + puts("write"); + CBRET cb = (CBRET)page; + cb(); + puts("exec"); + lol = globalvar; + puts("read"); + lol = page[1]; + puts("read"); + lol = page[3]; + puts("read"); + lol = page[2]; + puts("read"); + return 0; +} diff --git a/src/dbg/thread.cpp b/src/dbg/thread.cpp index 3f41db6c..95a995a5 100644 --- a/src/dbg/thread.cpp +++ b/src/dbg/thread.cpp @@ -1,240 +1,240 @@ -/** - @file thread.cpp - - @brief Implements the thread class. - */ - -#include "thread.h" -#include "memory.h" -#include "threading.h" -#include "dynamicptr.h" - -std::unordered_map threadList; - -void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread) -{ - THREADINFO curInfo; - memset(&curInfo, 0, sizeof(THREADINFO)); - - curInfo.ThreadNumber = ThreadGetCount(); - curInfo.Handle = CreateThread->hThread; - curInfo.ThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId; - curInfo.ThreadStartAddress = (duint)CreateThread->lpStartAddress; - curInfo.ThreadLocalBase = (duint)CreateThread->lpThreadLocalBase; - - // The first thread (#0) is always the main program thread - if(curInfo.ThreadNumber <= 0) - strcpy_s(curInfo.threadName, "Main Thread"); - - // Modify global thread list - EXCLUSIVE_ACQUIRE(LockThreads); - threadList.insert(std::make_pair(curInfo.ThreadId, curInfo)); - EXCLUSIVE_RELEASE(); - - // Notify GUI - GuiUpdateThreadView(); -} - -void ThreadExit(DWORD ThreadId) -{ - EXCLUSIVE_ACQUIRE(LockThreads); - - // Erase element using native functions - auto itr = threadList.find(ThreadId); - - if(itr != threadList.end()) - threadList.erase(itr); - - EXCLUSIVE_RELEASE(); - GuiUpdateThreadView(); -} - -void ThreadClear() -{ - // Clear the current array of threads - EXCLUSIVE_ACQUIRE(LockThreads); - threadList.clear(); - EXCLUSIVE_RELEASE(); - - // Update the GUI's list - GuiUpdateThreadView(); -} - -int ThreadGetCount() -{ - SHARED_ACQUIRE(LockThreads); - return (int)threadList.size(); -} - -void ThreadGetList(THREADLIST* List) -{ - ASSERT_NONNULL(List); - SHARED_ACQUIRE(LockThreads); - - // - // This function converts a C++ std::unordered_map to a C-style THREADLIST[]. - // Also assume BridgeAlloc zeros the returned buffer. - // - List->count = (int)threadList.size(); - List->list = nullptr; - - if (List->count <= 0) - return; - - // Allocate C-style array - List->list = (THREADALLINFO*)BridgeAlloc(List->count * sizeof(THREADALLINFO)); - - // Fill out the list data - int index = 0; - - for(auto & itr : threadList) - { - HANDLE threadHandle = itr.second.Handle; - - // Get the debugger's active thread index - if(threadHandle == hActiveThread) - List->CurrentThread = index; - - memcpy(&List->list[index].BasicInfo, &itr.second, sizeof(THREADINFO)); - - List->list[index].ThreadCip = GetContextDataEx(threadHandle, UE_CIP); - List->list[index].SuspendCount = ThreadGetSuspendCount(threadHandle); - List->list[index].Priority = ThreadGetPriority(threadHandle); - List->list[index].WaitReason = ThreadGetWaitReason(threadHandle); - List->list[index].LastError = ThreadGetLastErrorTEB(itr.second.ThreadLocalBase); - index++; - } -} - -bool ThreadIsValid(DWORD ThreadId) -{ - SHARED_ACQUIRE(LockThreads); - return threadList.find(ThreadId) != threadList.end(); -} - -bool ThreadGetTeb(duint TEBAddress, TEB* Teb) -{ - memset(Teb, 0, sizeof(TEB)); - return MemRead(TEBAddress, Teb, sizeof(TEB)); -} - -int ThreadGetSuspendCount(HANDLE Thread) -{ - // - // Suspend a thread in order to get the previous suspension count - // WARNING: This function is very bad (threads should not be randomly interrupted) - // - int suspendCount = (int)SuspendThread(Thread); - - if(suspendCount == -1) - return 0; - - // Resume the thread's normal execution - ResumeThread(Thread); - - return suspendCount; -} - -THREADPRIORITY ThreadGetPriority(HANDLE Thread) -{ - return (THREADPRIORITY)GetThreadPriority(Thread); -} - -THREADWAITREASON ThreadGetWaitReason(HANDLE Thread) -{ - UNREFERENCED_PARAMETER(Thread); - - // TODO: Implement this - return _Executive; -} - -DWORD ThreadGetLastErrorTEB(ULONG_PTR ThreadLocalBase) -{ - return RemoteMemberPtr(ThreadLocalBase, &TEB::LastErrorValue).get(); -} - -DWORD ThreadGetLastError(DWORD ThreadId) -{ - SHARED_ACQUIRE(LockThreads); - - if(threadList.find(ThreadId) != threadList.end()) - return ThreadGetLastErrorTEB(threadList[ThreadId].ThreadLocalBase); - - ASSERT_ALWAYS("Trying to get last error of a thread that doesn't exist!"); - return 0; -} - -bool ThreadSetName(DWORD ThreadId, const char* Name) -{ - EXCLUSIVE_ACQUIRE(LockThreads); - - // Modifies a variable (name), so an exclusive lock is required - if(threadList.find(ThreadId) != threadList.end()) - { - if(!Name) - Name = ""; - - strcpy_s(threadList[ThreadId].threadName, Name); - return true; - } - - return false; -} - -HANDLE ThreadGetHandle(DWORD ThreadId) -{ - SHARED_ACQUIRE(LockThreads); - - if(threadList.find(ThreadId) != threadList.end()) - return threadList[ThreadId].Handle; - - ASSERT_ALWAYS("Trying to get handle of a thread that doesn't exist!"); - return nullptr; -} - -DWORD ThreadGetId(HANDLE Thread) -{ - SHARED_ACQUIRE(LockThreads); - - // Search for the ID in the local list - for(auto & entry : threadList) - { - if(entry.second.Handle == Thread) - return entry.first; - } - - // Wasn't found, check with Windows - typedef DWORD (WINAPI * GETTHREADID)(HANDLE hThread); - static GETTHREADID _GetThreadId = (GETTHREADID)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetThreadId"); - return _GetThreadId ? _GetThreadId(Thread) : 0; -} - -int ThreadSuspendAll() -{ - // SuspendThread does not modify any internal variables - SHARED_ACQUIRE(LockThreads); - - int count = 0; - for(auto & entry : threadList) - { - if(SuspendThread(entry.second.Handle) != -1) - count++; - } - - return count; -} - -int ThreadResumeAll() -{ - // ResumeThread does not modify any internal variables - SHARED_ACQUIRE(LockThreads); - - int count = 0; - for(auto & entry : threadList) - { - if(ResumeThread(entry.second.Handle) != -1) - count++; - } - - return count; +/** + @file thread.cpp + + @brief Implements the thread class. + */ + +#include "thread.h" +#include "memory.h" +#include "threading.h" +#include "dynamicptr.h" + +std::unordered_map threadList; + +void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread) +{ + THREADINFO curInfo; + memset(&curInfo, 0, sizeof(THREADINFO)); + + curInfo.ThreadNumber = ThreadGetCount(); + curInfo.Handle = CreateThread->hThread; + curInfo.ThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId; + curInfo.ThreadStartAddress = (duint)CreateThread->lpStartAddress; + curInfo.ThreadLocalBase = (duint)CreateThread->lpThreadLocalBase; + + // The first thread (#0) is always the main program thread + if(curInfo.ThreadNumber <= 0) + strcpy_s(curInfo.threadName, "Main Thread"); + + // Modify global thread list + EXCLUSIVE_ACQUIRE(LockThreads); + threadList.insert(std::make_pair(curInfo.ThreadId, curInfo)); + EXCLUSIVE_RELEASE(); + + // Notify GUI + GuiUpdateThreadView(); +} + +void ThreadExit(DWORD ThreadId) +{ + EXCLUSIVE_ACQUIRE(LockThreads); + + // Erase element using native functions + auto itr = threadList.find(ThreadId); + + if(itr != threadList.end()) + threadList.erase(itr); + + EXCLUSIVE_RELEASE(); + GuiUpdateThreadView(); +} + +void ThreadClear() +{ + // Clear the current array of threads + EXCLUSIVE_ACQUIRE(LockThreads); + threadList.clear(); + EXCLUSIVE_RELEASE(); + + // Update the GUI's list + GuiUpdateThreadView(); +} + +int ThreadGetCount() +{ + SHARED_ACQUIRE(LockThreads); + return (int)threadList.size(); +} + +void ThreadGetList(THREADLIST* List) +{ + ASSERT_NONNULL(List); + SHARED_ACQUIRE(LockThreads); + + // + // This function converts a C++ std::unordered_map to a C-style THREADLIST[]. + // Also assume BridgeAlloc zeros the returned buffer. + // + List->count = (int)threadList.size(); + List->list = nullptr; + + if (List->count <= 0) + return; + + // Allocate C-style array + List->list = (THREADALLINFO*)BridgeAlloc(List->count * sizeof(THREADALLINFO)); + + // Fill out the list data + int index = 0; + + for(auto & itr : threadList) + { + HANDLE threadHandle = itr.second.Handle; + + // Get the debugger's active thread index + if(threadHandle == hActiveThread) + List->CurrentThread = index; + + memcpy(&List->list[index].BasicInfo, &itr.second, sizeof(THREADINFO)); + + List->list[index].ThreadCip = GetContextDataEx(threadHandle, UE_CIP); + List->list[index].SuspendCount = ThreadGetSuspendCount(threadHandle); + List->list[index].Priority = ThreadGetPriority(threadHandle); + List->list[index].WaitReason = ThreadGetWaitReason(threadHandle); + List->list[index].LastError = ThreadGetLastErrorTEB(itr.second.ThreadLocalBase); + index++; + } +} + +bool ThreadIsValid(DWORD ThreadId) +{ + SHARED_ACQUIRE(LockThreads); + return threadList.find(ThreadId) != threadList.end(); +} + +bool ThreadGetTeb(duint TEBAddress, TEB* Teb) +{ + memset(Teb, 0, sizeof(TEB)); + return MemRead(TEBAddress, Teb, sizeof(TEB)); +} + +int ThreadGetSuspendCount(HANDLE Thread) +{ + // + // Suspend a thread in order to get the previous suspension count + // WARNING: This function is very bad (threads should not be randomly interrupted) + // + int suspendCount = (int)SuspendThread(Thread); + + if(suspendCount == -1) + return 0; + + // Resume the thread's normal execution + ResumeThread(Thread); + + return suspendCount; +} + +THREADPRIORITY ThreadGetPriority(HANDLE Thread) +{ + return (THREADPRIORITY)GetThreadPriority(Thread); +} + +THREADWAITREASON ThreadGetWaitReason(HANDLE Thread) +{ + UNREFERENCED_PARAMETER(Thread); + + // TODO: Implement this + return _Executive; +} + +DWORD ThreadGetLastErrorTEB(ULONG_PTR ThreadLocalBase) +{ + return RemoteMemberPtr(ThreadLocalBase, &TEB::LastErrorValue).get(); +} + +DWORD ThreadGetLastError(DWORD ThreadId) +{ + SHARED_ACQUIRE(LockThreads); + + if(threadList.find(ThreadId) != threadList.end()) + return ThreadGetLastErrorTEB(threadList[ThreadId].ThreadLocalBase); + + ASSERT_ALWAYS("Trying to get last error of a thread that doesn't exist!"); + return 0; +} + +bool ThreadSetName(DWORD ThreadId, const char* Name) +{ + EXCLUSIVE_ACQUIRE(LockThreads); + + // Modifies a variable (name), so an exclusive lock is required + if(threadList.find(ThreadId) != threadList.end()) + { + if(!Name) + Name = ""; + + strcpy_s(threadList[ThreadId].threadName, Name); + return true; + } + + return false; +} + +HANDLE ThreadGetHandle(DWORD ThreadId) +{ + SHARED_ACQUIRE(LockThreads); + + if(threadList.find(ThreadId) != threadList.end()) + return threadList[ThreadId].Handle; + + ASSERT_ALWAYS("Trying to get handle of a thread that doesn't exist!"); + return nullptr; +} + +DWORD ThreadGetId(HANDLE Thread) +{ + SHARED_ACQUIRE(LockThreads); + + // Search for the ID in the local list + for(auto & entry : threadList) + { + if(entry.second.Handle == Thread) + return entry.first; + } + + // Wasn't found, check with Windows + typedef DWORD (WINAPI * GETTHREADID)(HANDLE hThread); + static GETTHREADID _GetThreadId = (GETTHREADID)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetThreadId"); + return _GetThreadId ? _GetThreadId(Thread) : 0; +} + +int ThreadSuspendAll() +{ + // SuspendThread does not modify any internal variables + SHARED_ACQUIRE(LockThreads); + + int count = 0; + for(auto & entry : threadList) + { + if(SuspendThread(entry.second.Handle) != -1) + count++; + } + + return count; +} + +int ThreadResumeAll() +{ + // ResumeThread does not modify any internal variables + SHARED_ACQUIRE(LockThreads); + + int count = 0; + for(auto & entry : threadList) + { + if(ResumeThread(entry.second.Handle) != -1) + count++; + } + + return count; } \ No newline at end of file diff --git a/src/dbg/thread.h b/src/dbg/thread.h index b8a4f2f3..e5e6a0d8 100644 --- a/src/dbg/thread.h +++ b/src/dbg/thread.h @@ -1,23 +1,23 @@ -#pragma once - -#include "_global.h" -#include "debugger.h" - -void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread); -void ThreadExit(DWORD ThreadId); -void ThreadClear(); -int ThreadGetCount(); -void ThreadGetList(THREADLIST* list); -bool ThreadIsValid(DWORD ThreadId); -bool ThreadSetName(DWORD ThreadId, const char* name); -bool ThreadGetTeb(duint TEBAddress, TEB* Teb); -int ThreadGetSuspendCount(HANDLE Thread); -THREADPRIORITY ThreadGetPriority(HANDLE Thread); -THREADWAITREASON ThreadGetWaitReason(HANDLE Thread); -DWORD ThreadGetLastErrorTEB(ULONG_PTR ThreadLocalBase); -DWORD ThreadGetLastError(DWORD ThreadId); -bool ThreadSetName(DWORD dwThreadId, const char* name); -HANDLE ThreadGetHandle(DWORD ThreadId); -DWORD ThreadGetId(HANDLE Thread); -int ThreadSuspendAll(); +#pragma once + +#include "_global.h" +#include "debugger.h" + +void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread); +void ThreadExit(DWORD ThreadId); +void ThreadClear(); +int ThreadGetCount(); +void ThreadGetList(THREADLIST* list); +bool ThreadIsValid(DWORD ThreadId); +bool ThreadSetName(DWORD ThreadId, const char* name); +bool ThreadGetTeb(duint TEBAddress, TEB* Teb); +int ThreadGetSuspendCount(HANDLE Thread); +THREADPRIORITY ThreadGetPriority(HANDLE Thread); +THREADWAITREASON ThreadGetWaitReason(HANDLE Thread); +DWORD ThreadGetLastErrorTEB(ULONG_PTR ThreadLocalBase); +DWORD ThreadGetLastError(DWORD ThreadId); +bool ThreadSetName(DWORD dwThreadId, const char* name); +HANDLE ThreadGetHandle(DWORD ThreadId); +DWORD ThreadGetId(HANDLE Thread); +int ThreadSuspendAll(); int ThreadResumeAll(); \ No newline at end of file diff --git a/src/dbg/threading.cpp b/src/dbg/threading.cpp index bb264d9d..4a0903ad 100644 --- a/src/dbg/threading.cpp +++ b/src/dbg/threading.cpp @@ -1,129 +1,129 @@ -#include "threading.h" - -static HANDLE waitArray[WAITID_LAST]; - -void waitclear() -{ - for(int i = 0; i < WAITID_LAST; i++) - unlock((WAIT_ID)i); -} - -void wait(WAIT_ID id) -{ - WaitForSingleObject(waitArray[id], INFINITE); -} - -void lock(WAIT_ID id) -{ - ResetEvent(waitArray[id]); -} - -void unlock(WAIT_ID id) -{ - SetEvent(waitArray[id]); -} - -bool waitislocked(WAIT_ID id) -{ - return !WaitForSingleObject(waitArray[id], 0) == WAIT_OBJECT_0; -} - -void waitinitialize() -{ - for(int i = 0; i < WAITID_LAST; i++) - waitArray[i] = CreateEventA(NULL, TRUE, TRUE, NULL); -} - -void waitdeinitialize() -{ - for(int i = 0; i < WAITID_LAST; i++) - { - wait((WAIT_ID)i); - CloseHandle(waitArray[i]); - } -} - -bool SectionLockerGlobal::m_Initialized = false; -bool SectionLockerGlobal::m_SRWLocks = false; -SRWLOCK SectionLockerGlobal::m_srwLocks[SectionLock::LockLast]; -CRITICAL_SECTION SectionLockerGlobal::m_crLocks[SectionLock::LockLast]; -SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_InitializeSRWLock; -SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_AcquireSRWLockShared; -SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_AcquireSRWLockExclusive; -SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_ReleaseSRWLockShared; -SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_ReleaseSRWLockExclusive; - -void SectionLockerGlobal::Initialize() -{ - // This is supposed to only be called once, but - // create a flag anyway - if(m_Initialized) - return; - - // Attempt to read the SRWLock API - HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll"); - m_InitializeSRWLock = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "InitializeSRWLock"); - m_AcquireSRWLockShared = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "AcquireSRWLockShared"); - m_AcquireSRWLockExclusive = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "AcquireSRWLockExclusive"); - m_ReleaseSRWLockShared = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "ReleaseSRWLockShared"); - m_ReleaseSRWLockExclusive = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "ReleaseSRWLockExclusive"); - - m_SRWLocks = m_InitializeSRWLock && - m_AcquireSRWLockShared && - m_AcquireSRWLockExclusive && - m_ReleaseSRWLockShared && - m_ReleaseSRWLockExclusive; - - if(m_SRWLocks) // Prefer SRWLocks - { - // Destroy previous data if any existed - memset(m_srwLocks, 0, sizeof(m_srwLocks)); - - for(int i = 0; i < ARRAYSIZE(m_srwLocks); i++) - m_InitializeSRWLock(&m_srwLocks[i]); - } - else // Fall back to critical sections otherwise - { - // Destroy previous data if any existed - memset(m_crLocks, 0, sizeof(m_crLocks)); - - for(int i = 0; i < ARRAYSIZE(m_crLocks); i++) - InitializeCriticalSection(&m_crLocks[i]); - } - - m_Initialized = true; -} - -void SectionLockerGlobal::Deinitialize() -{ - if(!m_Initialized) - return; - - if(m_SRWLocks) - { - for(int i = 0; i < ARRAYSIZE(m_srwLocks); i++) - { - // Wait for the lock's ownership to be released - m_AcquireSRWLockExclusive(&m_srwLocks[i]); - m_ReleaseSRWLockExclusive(&m_srwLocks[i]); - - // Invalidate data - memset(&m_srwLocks[i], 0, sizeof(SRWLOCK)); - } - } - else - { - for(int i = 0; i < ARRAYSIZE(m_crLocks); i++) - { - // Wait for the lock's ownership to be released - EnterCriticalSection(&m_crLocks[i]); - LeaveCriticalSection(&m_crLocks[i]); - - // Delete critical section - DeleteCriticalSection(&m_crLocks[i]); - memset(&m_crLocks[i], 0, sizeof(CRITICAL_SECTION)); - } - } - - m_Initialized = false; +#include "threading.h" + +static HANDLE waitArray[WAITID_LAST]; + +void waitclear() +{ + for(int i = 0; i < WAITID_LAST; i++) + unlock((WAIT_ID)i); +} + +void wait(WAIT_ID id) +{ + WaitForSingleObject(waitArray[id], INFINITE); +} + +void lock(WAIT_ID id) +{ + ResetEvent(waitArray[id]); +} + +void unlock(WAIT_ID id) +{ + SetEvent(waitArray[id]); +} + +bool waitislocked(WAIT_ID id) +{ + return !WaitForSingleObject(waitArray[id], 0) == WAIT_OBJECT_0; +} + +void waitinitialize() +{ + for(int i = 0; i < WAITID_LAST; i++) + waitArray[i] = CreateEventA(NULL, TRUE, TRUE, NULL); +} + +void waitdeinitialize() +{ + for(int i = 0; i < WAITID_LAST; i++) + { + wait((WAIT_ID)i); + CloseHandle(waitArray[i]); + } +} + +bool SectionLockerGlobal::m_Initialized = false; +bool SectionLockerGlobal::m_SRWLocks = false; +SRWLOCK SectionLockerGlobal::m_srwLocks[SectionLock::LockLast]; +CRITICAL_SECTION SectionLockerGlobal::m_crLocks[SectionLock::LockLast]; +SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_InitializeSRWLock; +SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_AcquireSRWLockShared; +SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_AcquireSRWLockExclusive; +SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_ReleaseSRWLockShared; +SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_ReleaseSRWLockExclusive; + +void SectionLockerGlobal::Initialize() +{ + // This is supposed to only be called once, but + // create a flag anyway + if(m_Initialized) + return; + + // Attempt to read the SRWLock API + HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll"); + m_InitializeSRWLock = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "InitializeSRWLock"); + m_AcquireSRWLockShared = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "AcquireSRWLockShared"); + m_AcquireSRWLockExclusive = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "AcquireSRWLockExclusive"); + m_ReleaseSRWLockShared = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "ReleaseSRWLockShared"); + m_ReleaseSRWLockExclusive = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "ReleaseSRWLockExclusive"); + + m_SRWLocks = m_InitializeSRWLock && + m_AcquireSRWLockShared && + m_AcquireSRWLockExclusive && + m_ReleaseSRWLockShared && + m_ReleaseSRWLockExclusive; + + if(m_SRWLocks) // Prefer SRWLocks + { + // Destroy previous data if any existed + memset(m_srwLocks, 0, sizeof(m_srwLocks)); + + for(int i = 0; i < ARRAYSIZE(m_srwLocks); i++) + m_InitializeSRWLock(&m_srwLocks[i]); + } + else // Fall back to critical sections otherwise + { + // Destroy previous data if any existed + memset(m_crLocks, 0, sizeof(m_crLocks)); + + for(int i = 0; i < ARRAYSIZE(m_crLocks); i++) + InitializeCriticalSection(&m_crLocks[i]); + } + + m_Initialized = true; +} + +void SectionLockerGlobal::Deinitialize() +{ + if(!m_Initialized) + return; + + if(m_SRWLocks) + { + for(int i = 0; i < ARRAYSIZE(m_srwLocks); i++) + { + // Wait for the lock's ownership to be released + m_AcquireSRWLockExclusive(&m_srwLocks[i]); + m_ReleaseSRWLockExclusive(&m_srwLocks[i]); + + // Invalidate data + memset(&m_srwLocks[i], 0, sizeof(SRWLOCK)); + } + } + else + { + for(int i = 0; i < ARRAYSIZE(m_crLocks); i++) + { + // Wait for the lock's ownership to be released + EnterCriticalSection(&m_crLocks[i]); + LeaveCriticalSection(&m_crLocks[i]); + + // Delete critical section + DeleteCriticalSection(&m_crLocks[i]); + memset(&m_crLocks[i], 0, sizeof(CRITICAL_SECTION)); + } + } + + m_Initialized = false; } \ No newline at end of file diff --git a/src/dbg/threading.h b/src/dbg/threading.h index 414e2438..298df16e 100644 --- a/src/dbg/threading.h +++ b/src/dbg/threading.h @@ -1,146 +1,146 @@ -#pragma once - -#include "_global.h" - -enum WAIT_ID -{ - WAITID_RUN, - WAITID_STOP, - WAITID_LAST -}; - -//functions -void waitclear(); -void wait(WAIT_ID id); -void lock(WAIT_ID id); -void unlock(WAIT_ID id); -bool waitislocked(WAIT_ID id); -void waitinitialize(); -void waitdeinitialize(); - -// -// THREAD SYNCHRONIZATION -// -// Win Vista and newer: (Faster) SRW locks used -// Win 2003 and older: (Slower) Critical sections used -// -#define EXCLUSIVE_ACQUIRE(Index) SectionLocker __ThreadLock -#define EXCLUSIVE_REACQUIRE() __ThreadLock.Lock() -#define EXCLUSIVE_RELEASE() __ThreadLock.Unlock() - -#define SHARED_ACQUIRE(Index) SectionLocker __SThreadLock -#define SHARED_REACQUIRE() __SThreadLock.Lock() -#define SHARED_RELEASE() __SThreadLock.Unlock() - -enum SectionLock -{ - LockMemoryPages, - LockVariables, - LockModules, - LockComments, - LockLabels, - LockBookmarks, - LockFunctions, - LockLoops, - LockBreakpoints, - LockPatches, - LockThreads, - LockSym, - LockPluginList, - LockPluginCallbackList, - LockPluginCommandList, - LockPluginMenuList, - LockLast, -}; - -class SectionLockerGlobal -{ - template - friend class SectionLocker; - -public: - static void Initialize(); - static void Deinitialize(); - -private: - static inline void AcquireLock(SectionLock LockIndex, bool Shared) - { - if(m_SRWLocks) - { - if(Shared) - m_AcquireSRWLockShared(&m_srwLocks[LockIndex]); - else - m_AcquireSRWLockExclusive(&m_srwLocks[LockIndex]); - } - else - EnterCriticalSection(&m_crLocks[LockIndex]); - } - - static inline void ReleaseLock(SectionLock LockIndex, bool Shared) - { - if(m_SRWLocks) - { - if(Shared) - m_ReleaseSRWLockShared(&m_srwLocks[LockIndex]); - else - m_ReleaseSRWLockExclusive(&m_srwLocks[LockIndex]); - } - else - LeaveCriticalSection(&m_crLocks[LockIndex]); - } - - typedef void (WINAPI* SRWLOCKFUNCTION)(PSRWLOCK SWRLock); - - static bool m_Initialized; - static bool m_SRWLocks; - static SRWLOCK m_srwLocks[SectionLock::LockLast]; - static CRITICAL_SECTION m_crLocks[SectionLock::LockLast]; - static SRWLOCKFUNCTION m_InitializeSRWLock; - static SRWLOCKFUNCTION m_AcquireSRWLockShared; - static SRWLOCKFUNCTION m_AcquireSRWLockExclusive; - static SRWLOCKFUNCTION m_ReleaseSRWLockShared; - static SRWLOCKFUNCTION m_ReleaseSRWLockExclusive; -}; - -template -class SectionLocker -{ -public: - SectionLocker() - { - m_LockCount = 0; - Lock(); - } - - ~SectionLocker() - { - if(m_LockCount > 0) - Unlock(); - -#ifdef _DEBUG - // Assert that the lock count is zero on destructor - if(m_LockCount > 0) - __debugbreak(); -#endif - } - - inline void Lock() - { - Internal::AcquireLock(LockIndex, Shared); - - m_LockCount++; - } - - inline void Unlock() - { - m_LockCount--; - - Internal::ReleaseLock(LockIndex, Shared); - } - -protected: - BYTE m_LockCount; - -private: - using Internal = SectionLockerGlobal; +#pragma once + +#include "_global.h" + +enum WAIT_ID +{ + WAITID_RUN, + WAITID_STOP, + WAITID_LAST +}; + +//functions +void waitclear(); +void wait(WAIT_ID id); +void lock(WAIT_ID id); +void unlock(WAIT_ID id); +bool waitislocked(WAIT_ID id); +void waitinitialize(); +void waitdeinitialize(); + +// +// THREAD SYNCHRONIZATION +// +// Win Vista and newer: (Faster) SRW locks used +// Win 2003 and older: (Slower) Critical sections used +// +#define EXCLUSIVE_ACQUIRE(Index) SectionLocker __ThreadLock +#define EXCLUSIVE_REACQUIRE() __ThreadLock.Lock() +#define EXCLUSIVE_RELEASE() __ThreadLock.Unlock() + +#define SHARED_ACQUIRE(Index) SectionLocker __SThreadLock +#define SHARED_REACQUIRE() __SThreadLock.Lock() +#define SHARED_RELEASE() __SThreadLock.Unlock() + +enum SectionLock +{ + LockMemoryPages, + LockVariables, + LockModules, + LockComments, + LockLabels, + LockBookmarks, + LockFunctions, + LockLoops, + LockBreakpoints, + LockPatches, + LockThreads, + LockSym, + LockPluginList, + LockPluginCallbackList, + LockPluginCommandList, + LockPluginMenuList, + LockLast, +}; + +class SectionLockerGlobal +{ + template + friend class SectionLocker; + +public: + static void Initialize(); + static void Deinitialize(); + +private: + static inline void AcquireLock(SectionLock LockIndex, bool Shared) + { + if(m_SRWLocks) + { + if(Shared) + m_AcquireSRWLockShared(&m_srwLocks[LockIndex]); + else + m_AcquireSRWLockExclusive(&m_srwLocks[LockIndex]); + } + else + EnterCriticalSection(&m_crLocks[LockIndex]); + } + + static inline void ReleaseLock(SectionLock LockIndex, bool Shared) + { + if(m_SRWLocks) + { + if(Shared) + m_ReleaseSRWLockShared(&m_srwLocks[LockIndex]); + else + m_ReleaseSRWLockExclusive(&m_srwLocks[LockIndex]); + } + else + LeaveCriticalSection(&m_crLocks[LockIndex]); + } + + typedef void (WINAPI* SRWLOCKFUNCTION)(PSRWLOCK SWRLock); + + static bool m_Initialized; + static bool m_SRWLocks; + static SRWLOCK m_srwLocks[SectionLock::LockLast]; + static CRITICAL_SECTION m_crLocks[SectionLock::LockLast]; + static SRWLOCKFUNCTION m_InitializeSRWLock; + static SRWLOCKFUNCTION m_AcquireSRWLockShared; + static SRWLOCKFUNCTION m_AcquireSRWLockExclusive; + static SRWLOCKFUNCTION m_ReleaseSRWLockShared; + static SRWLOCKFUNCTION m_ReleaseSRWLockExclusive; +}; + +template +class SectionLocker +{ +public: + SectionLocker() + { + m_LockCount = 0; + Lock(); + } + + ~SectionLocker() + { + if(m_LockCount > 0) + Unlock(); + +#ifdef _DEBUG + // Assert that the lock count is zero on destructor + if(m_LockCount > 0) + __debugbreak(); +#endif + } + + inline void Lock() + { + Internal::AcquireLock(LockIndex, Shared); + + m_LockCount++; + } + + inline void Unlock() + { + m_LockCount--; + + Internal::ReleaseLock(LockIndex, Shared); + } + +protected: + BYTE m_LockCount; + +private: + using Internal = SectionLockerGlobal; }; \ No newline at end of file diff --git a/src/dbg/undocumented.h b/src/dbg/undocumented.h index 57d1803b..48dd0132 100644 --- a/src/dbg/undocumented.h +++ b/src/dbg/undocumented.h @@ -1,219 +1,219 @@ -#include - -#ifndef _UNDOCUMENTED_H -#define _UNDOCUMENTED_H -//Thanks to: https://github.com/zer0fl4g/Nanomite - -typedef LONG NTSTATUS; - -typedef struct _UNICODE_STRING -{ - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} UNICODE_STRING; - -typedef struct _CLIENT_ID -{ - HANDLE UniqueProcess; - HANDLE UniqueThread; -} CLIENT_ID; - -typedef struct _RTL_USER_PROCESS_PARAMETERS -{ - BYTE Reserved1[16]; - PVOID Reserved2[10]; - UNICODE_STRING ImagePathName; - UNICODE_STRING CommandLine; -} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; - -#pragma pack(push) -#pragma pack(1) -template -struct LIST_ENTRY_T -{ - T Flink; - T Blink; -}; - -template -struct UNICODE_STRING_T -{ - union - { - struct - { - WORD Length; - WORD MaximumLength; - }; - T dummy; - }; - T _Buffer; -}; -template -struct _PEB_T -{ - union - { - struct - { - BYTE InheritedAddressSpace; - BYTE ReadImageFileExecOptions; - BYTE BeingDebugged; - BYTE BitField; - }; - T dummy01; - }; - T Mutant; - T ImageBaseAddress; - T Ldr; - T ProcessParameters; - T SubSystemData; - T ProcessHeap; - T FastPebLock; - T AtlThunkSListPtr; - T IFEOKey; - T CrossProcessFlags; - T UserSharedInfoPtr; - DWORD SystemReserved; - DWORD AtlThunkSListPtr32; - T ApiSetMap; - T TlsExpansionCounter; - T TlsBitmap; - DWORD TlsBitmapBits[2]; - T ReadOnlySharedMemoryBase; - T HotpatchInformation; - T ReadOnlyStaticServerData; - T AnsiCodePageData; - T OemCodePageData; - T UnicodeCaseTableData; - DWORD NumberOfProcessors; - union - { - DWORD NtGlobalFlag; - NGF dummy02; - }; - LARGE_INTEGER CriticalSectionTimeout; - T HeapSegmentReserve; - T HeapSegmentCommit; - T HeapDeCommitTotalFreeThreshold; - T HeapDeCommitFreeBlockThreshold; - DWORD NumberOfHeaps; - DWORD MaximumNumberOfHeaps; - T ProcessHeaps; - T GdiSharedHandleTable; - T ProcessStarterHelper; - T GdiDCAttributeList; - T LoaderLock; - DWORD OSMajorVersion; - DWORD OSMinorVersion; - WORD OSBuildNumber; - WORD OSCSDVersion; - DWORD OSPlatformId; - DWORD ImageSubsystem; - DWORD ImageSubsystemMajorVersion; - T ImageSubsystemMinorVersion; - T ActiveProcessAffinityMask; - T GdiHandleBuffer[A]; - T PostProcessInitRoutine; - T TlsExpansionBitmap; - DWORD TlsExpansionBitmapBits[32]; - T SessionId; - ULARGE_INTEGER AppCompatFlags; - ULARGE_INTEGER AppCompatFlagsUser; - T pShimData; - T AppCompatInfo; - UNICODE_STRING_T CSDVersion; - T ActivationContextData; - T ProcessAssemblyStorageMap; - T SystemDefaultActivationContextData; - T SystemAssemblyStorageMap; - T MinimumStackCommit; - T FlsCallback; - LIST_ENTRY_T FlsListHead; - T FlsBitmap; - DWORD FlsBitmapBits[4]; - T FlsHighIndex; - T WerRegistrationData; - T WerShipAssertPtr; - T pContextData; - T pImageHeaderHash; - T TracingFlags; -}; - -typedef _PEB_T PEB32; -typedef _PEB_T PEB64; - -#pragma pack(pop) - -#ifdef _WIN64 //x64 -typedef PEB64 PEB; -#else //x86 -typedef PEB32 PEB; -#endif //_WIN64 - -typedef PEB* PPEB; - -typedef struct _TEB -{ - NT_TIB Tib; - PVOID EnvironmentPointer; - CLIENT_ID Cid; - PVOID ActiveRpcInfo; - PVOID ThreadLocalStoragePointer; - PPEB Peb; - ULONG LastErrorValue; - ULONG CountOfOwnedCriticalSections; - PVOID CsrClientThread; - PVOID Win32ThreadInfo; - ULONG Win32ClientInfo[0x1F]; - PVOID WOW32Reserved; - ULONG CurrentLocale; - ULONG FpSoftwareStatusRegister; - PVOID SystemReserved1[0x36]; - PVOID Spare1; - ULONG ExceptionCode; - ULONG SpareBytes1[0x28]; - PVOID SystemReserved2[0xA]; - ULONG GdiRgn; - ULONG GdiPen; - ULONG GdiBrush; - CLIENT_ID RealClientId; - PVOID GdiCachedProcessHandle; - ULONG GdiClientPID; - ULONG GdiClientTID; - PVOID GdiThreadLocaleInfo; - PVOID UserReserved[5]; - PVOID GlDispatchTable[0x118]; - ULONG GlReserved1[0x1A]; - PVOID GlReserved2; - PVOID GlSectionInfo; - PVOID GlSection; - PVOID GlTable; - PVOID GlCurrentRC; - PVOID GlContext; - NTSTATUS LastStatusValue; - UNICODE_STRING StaticUnicodeString; - WCHAR StaticUnicodeBuffer[0x105]; - PVOID DeallocationStack; - PVOID TlsSlots[0x40]; - LIST_ENTRY TlsLinks; - PVOID Vdm; - PVOID ReservedForNtRpc; - PVOID DbgSsReserved[0x2]; - ULONG HardErrorDisabled; - PVOID Instrumentation[0x10]; - PVOID WinSockData; - ULONG GdiBatchCount; - ULONG Spare2; - ULONG Spare3; - ULONG Spare4; - PVOID ReservedForOle; - ULONG WaitingOnLoaderLock; - PVOID StackCommit; - PVOID StackCommitMax; - PVOID StackReserved; -} TEB, *PTEB; - - +#include + +#ifndef _UNDOCUMENTED_H +#define _UNDOCUMENTED_H +//Thanks to: https://github.com/zer0fl4g/Nanomite + +typedef LONG NTSTATUS; + +typedef struct _UNICODE_STRING +{ + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING; + +typedef struct _CLIENT_ID +{ + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID; + +typedef struct _RTL_USER_PROCESS_PARAMETERS +{ + BYTE Reserved1[16]; + PVOID Reserved2[10]; + UNICODE_STRING ImagePathName; + UNICODE_STRING CommandLine; +} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; + +#pragma pack(push) +#pragma pack(1) +template +struct LIST_ENTRY_T +{ + T Flink; + T Blink; +}; + +template +struct UNICODE_STRING_T +{ + union + { + struct + { + WORD Length; + WORD MaximumLength; + }; + T dummy; + }; + T _Buffer; +}; +template +struct _PEB_T +{ + union + { + struct + { + BYTE InheritedAddressSpace; + BYTE ReadImageFileExecOptions; + BYTE BeingDebugged; + BYTE BitField; + }; + T dummy01; + }; + T Mutant; + T ImageBaseAddress; + T Ldr; + T ProcessParameters; + T SubSystemData; + T ProcessHeap; + T FastPebLock; + T AtlThunkSListPtr; + T IFEOKey; + T CrossProcessFlags; + T UserSharedInfoPtr; + DWORD SystemReserved; + DWORD AtlThunkSListPtr32; + T ApiSetMap; + T TlsExpansionCounter; + T TlsBitmap; + DWORD TlsBitmapBits[2]; + T ReadOnlySharedMemoryBase; + T HotpatchInformation; + T ReadOnlyStaticServerData; + T AnsiCodePageData; + T OemCodePageData; + T UnicodeCaseTableData; + DWORD NumberOfProcessors; + union + { + DWORD NtGlobalFlag; + NGF dummy02; + }; + LARGE_INTEGER CriticalSectionTimeout; + T HeapSegmentReserve; + T HeapSegmentCommit; + T HeapDeCommitTotalFreeThreshold; + T HeapDeCommitFreeBlockThreshold; + DWORD NumberOfHeaps; + DWORD MaximumNumberOfHeaps; + T ProcessHeaps; + T GdiSharedHandleTable; + T ProcessStarterHelper; + T GdiDCAttributeList; + T LoaderLock; + DWORD OSMajorVersion; + DWORD OSMinorVersion; + WORD OSBuildNumber; + WORD OSCSDVersion; + DWORD OSPlatformId; + DWORD ImageSubsystem; + DWORD ImageSubsystemMajorVersion; + T ImageSubsystemMinorVersion; + T ActiveProcessAffinityMask; + T GdiHandleBuffer[A]; + T PostProcessInitRoutine; + T TlsExpansionBitmap; + DWORD TlsExpansionBitmapBits[32]; + T SessionId; + ULARGE_INTEGER AppCompatFlags; + ULARGE_INTEGER AppCompatFlagsUser; + T pShimData; + T AppCompatInfo; + UNICODE_STRING_T CSDVersion; + T ActivationContextData; + T ProcessAssemblyStorageMap; + T SystemDefaultActivationContextData; + T SystemAssemblyStorageMap; + T MinimumStackCommit; + T FlsCallback; + LIST_ENTRY_T FlsListHead; + T FlsBitmap; + DWORD FlsBitmapBits[4]; + T FlsHighIndex; + T WerRegistrationData; + T WerShipAssertPtr; + T pContextData; + T pImageHeaderHash; + T TracingFlags; +}; + +typedef _PEB_T PEB32; +typedef _PEB_T PEB64; + +#pragma pack(pop) + +#ifdef _WIN64 //x64 +typedef PEB64 PEB; +#else //x86 +typedef PEB32 PEB; +#endif //_WIN64 + +typedef PEB* PPEB; + +typedef struct _TEB +{ + NT_TIB Tib; + PVOID EnvironmentPointer; + CLIENT_ID Cid; + PVOID ActiveRpcInfo; + PVOID ThreadLocalStoragePointer; + PPEB Peb; + ULONG LastErrorValue; + ULONG CountOfOwnedCriticalSections; + PVOID CsrClientThread; + PVOID Win32ThreadInfo; + ULONG Win32ClientInfo[0x1F]; + PVOID WOW32Reserved; + ULONG CurrentLocale; + ULONG FpSoftwareStatusRegister; + PVOID SystemReserved1[0x36]; + PVOID Spare1; + ULONG ExceptionCode; + ULONG SpareBytes1[0x28]; + PVOID SystemReserved2[0xA]; + ULONG GdiRgn; + ULONG GdiPen; + ULONG GdiBrush; + CLIENT_ID RealClientId; + PVOID GdiCachedProcessHandle; + ULONG GdiClientPID; + ULONG GdiClientTID; + PVOID GdiThreadLocaleInfo; + PVOID UserReserved[5]; + PVOID GlDispatchTable[0x118]; + ULONG GlReserved1[0x1A]; + PVOID GlReserved2; + PVOID GlSectionInfo; + PVOID GlSection; + PVOID GlTable; + PVOID GlCurrentRC; + PVOID GlContext; + NTSTATUS LastStatusValue; + UNICODE_STRING StaticUnicodeString; + WCHAR StaticUnicodeBuffer[0x105]; + PVOID DeallocationStack; + PVOID TlsSlots[0x40]; + LIST_ENTRY TlsLinks; + PVOID Vdm; + PVOID ReservedForNtRpc; + PVOID DbgSsReserved[0x2]; + ULONG HardErrorDisabled; + PVOID Instrumentation[0x10]; + PVOID WinSockData; + ULONG GdiBatchCount; + ULONG Spare2; + ULONG Spare3; + ULONG Spare4; + PVOID ReservedForOle; + ULONG WaitingOnLoaderLock; + PVOID StackCommit; + PVOID StackCommitMax; + PVOID StackReserved; +} TEB, *PTEB; + + #endif /* _UNDOCUMENTED_H */ \ No newline at end of file diff --git a/src/dbg/value.cpp b/src/dbg/value.cpp index aa1e3ee8..1d40c319 100644 --- a/src/dbg/value.cpp +++ b/src/dbg/value.cpp @@ -1,2269 +1,2269 @@ -/** - @file value.cpp - - @brief Implements the value class. - */ - -#include "value.h" -#include "variable.h" -#include "debugger.h" -#include "console.h" -#include "memory.h" -#include "symbolinfo.h" -#include "module.h" -#include "label.h" -#include "expressionparser.h" - -static bool dosignedcalc = false; - -/** -\brief Returns whether we do signed or unsigned calculations. -\return true if we do signed calculations, false for unsigned calculationss. -*/ -bool valuesignedcalc() -{ - return dosignedcalc; -} - -/** -\brief Set whether we do signed or unsigned calculations. -\param a true for signed calculations, false for unsigned calculations. -*/ -void valuesetsignedcalc(bool a) -{ - dosignedcalc = a; -} - -/** -\brief Check if a string is a flag. -\param string The string to check. -\return true if the string is a flag, false otherwise. -*/ -static bool isflag(const char* string) -{ - if(scmp(string, "cf")) - return true; - if(scmp(string, "pf")) - return true; - if(scmp(string, "af")) - return true; - if(scmp(string, "zf")) - return true; - if(scmp(string, "sf")) - return true; - if(scmp(string, "tf")) - return true; - if(scmp(string, "if")) - return true; - if(scmp(string, "df")) - return true; - if(scmp(string, "of")) - return true; - if(scmp(string, "rf")) - return true; - if(scmp(string, "vm")) - return true; - if(scmp(string, "ac")) - return true; - if(scmp(string, "vif")) - return true; - if(scmp(string, "vip")) - return true; - if(scmp(string, "id")) - return true; - return false; -} - -/** -\brief Check if a string is a register. -\param string The string to check. -\return true if the string is a register, false otherwise. -*/ -static bool isregister(const char* string) -{ - if(scmp(string, "eax")) - return true; - if(scmp(string, "ebx")) - return true; - if(scmp(string, "ecx")) - return true; - if(scmp(string, "edx")) - return true; - if(scmp(string, "edi")) - return true; - if(scmp(string, "esi")) - return true; - if(scmp(string, "ebp")) - return true; - if(scmp(string, "esp")) - return true; - if(scmp(string, "eip")) - return true; - if(scmp(string, "eflags")) - return true; - - if(scmp(string, "ax")) - return true; - if(scmp(string, "bx")) - return true; - if(scmp(string, "cx")) - return true; - if(scmp(string, "dx")) - return true; - if(scmp(string, "si")) - return true; - if(scmp(string, "di")) - return true; - if(scmp(string, "bp")) - return true; - if(scmp(string, "sp")) - return true; - if(scmp(string, "ip")) - return true; - - if(scmp(string, "ah")) - return true; - if(scmp(string, "al")) - return true; - if(scmp(string, "bh")) - return true; - if(scmp(string, "bl")) - return true; - if(scmp(string, "ch")) - return true; - if(scmp(string, "cl")) - return true; - if(scmp(string, "dh")) - return true; - if(scmp(string, "dl")) - return true; - if(scmp(string, "sih")) - return true; - if(scmp(string, "sil")) - return true; - if(scmp(string, "dih")) - return true; - if(scmp(string, "dil")) - return true; - if(scmp(string, "bph")) - return true; - if(scmp(string, "bpl")) - return true; - if(scmp(string, "sph")) - return true; - if(scmp(string, "spl")) - return true; - if(scmp(string, "iph")) - return true; - if(scmp(string, "ipl")) - return true; - - if(scmp(string, "dr0")) - return true; - if(scmp(string, "dr1")) - return true; - if(scmp(string, "dr2")) - return true; - if(scmp(string, "dr3")) - return true; - if(scmp(string, "dr6") || scmp(string, "dr4")) - return true; - if(scmp(string, "dr7") || scmp(string, "dr5")) - return true; - - if(scmp(string, "cip")) - return true; - if(scmp(string, "csp")) - return true; - if(scmp(string, "cflags")) - return true; - - if(scmp(string, "gs")) - return true; - if(scmp(string, "fs")) - return true; - if(scmp(string, "es")) - return true; - if(scmp(string, "ds")) - return true; - if(scmp(string, "cs")) - return true; - if(scmp(string, "ss")) - return true; - -#ifndef _WIN64 - return false; -#endif // _WIN64 - if(scmp(string, "rax")) - return true; - if(scmp(string, "rbx")) - return true; - if(scmp(string, "rcx")) - return true; - if(scmp(string, "rdx")) - return true; - if(scmp(string, "rdi")) - return true; - if(scmp(string, "rsi")) - return true; - if(scmp(string, "rbp")) - return true; - if(scmp(string, "rsp")) - return true; - if(scmp(string, "rip")) - return true; - if(scmp(string, "rflags")) - return true; - if(scmp(string, "r8")) - return true; - if(scmp(string, "r9")) - return true; - if(scmp(string, "r10")) - return true; - if(scmp(string, "r11")) - return true; - if(scmp(string, "r12")) - return true; - if(scmp(string, "r13")) - return true; - if(scmp(string, "r14")) - return true; - if(scmp(string, "r15")) - return true; - if(scmp(string, "r8d")) - return true; - if(scmp(string, "r9d")) - return true; - if(scmp(string, "r10d")) - return true; - if(scmp(string, "r11d")) - return true; - if(scmp(string, "r12d")) - return true; - if(scmp(string, "r13d")) - return true; - if(scmp(string, "r14d")) - return true; - if(scmp(string, "r15d")) - return true; - if(scmp(string, "r8w")) - return true; - if(scmp(string, "r9w")) - return true; - if(scmp(string, "r10w")) - return true; - if(scmp(string, "r11w")) - return true; - if(scmp(string, "r12w")) - return true; - if(scmp(string, "r13w")) - return true; - if(scmp(string, "r14w")) - return true; - if(scmp(string, "r15w")) - return true; - if(scmp(string, "r8b")) - return true; - if(scmp(string, "r9b")) - return true; - if(scmp(string, "r10b")) - return true; - if(scmp(string, "r11b")) - return true; - if(scmp(string, "r12b")) - return true; - if(scmp(string, "r13b")) - return true; - if(scmp(string, "r14b")) - return true; - if(scmp(string, "r15b")) - return true; - return false; -} - -#define MXCSRFLAG_IE 0x1 -#define MXCSRFLAG_DE 0x2 -#define MXCSRFLAG_ZE 0x4 -#define MXCSRFLAG_OE 0x8 -#define MXCSRFLAG_UE 0x10 -#define MXCSRFLAG_PE 0x20 -#define MXCSRFLAG_DAZ 0x40 -#define MXCSRFLAG_IM 0x80 -#define MXCSRFLAG_DM 0x100 -#define MXCSRFLAG_ZM 0x200 -#define MXCSRFLAG_OM 0x400 -#define MXCSRFLAG_UM 0x800 -#define MXCSRFLAG_PM 0x1000 -#define MXCSRFLAG_FZ 0x8000 - -typedef struct -{ - char* name; - unsigned int flag; - -} FLAG_NAME_VALUE_TABLE_t; - -#define MXCSR_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, MXCSRFLAG_##flag_name } - -/** -\brief Gets the MXCSR flag AND value from a string. -\param string The flag name. -\return The value to AND the MXCSR value with to get the flag. 0 when not found. -*/ -static unsigned int getmxcsrflagfromstring(const char* string) -{ - static FLAG_NAME_VALUE_TABLE_t mxcsrnameflagtable[] = - { - MXCSR_NAME_FLAG_TABLE_ENTRY(IE), - MXCSR_NAME_FLAG_TABLE_ENTRY(DE), - MXCSR_NAME_FLAG_TABLE_ENTRY(ZE), - MXCSR_NAME_FLAG_TABLE_ENTRY(OE), - MXCSR_NAME_FLAG_TABLE_ENTRY(UE), - MXCSR_NAME_FLAG_TABLE_ENTRY(PE), - MXCSR_NAME_FLAG_TABLE_ENTRY(DAZ), - MXCSR_NAME_FLAG_TABLE_ENTRY(IM), - MXCSR_NAME_FLAG_TABLE_ENTRY(DM), - MXCSR_NAME_FLAG_TABLE_ENTRY(ZM), - MXCSR_NAME_FLAG_TABLE_ENTRY(OM), - MXCSR_NAME_FLAG_TABLE_ENTRY(UM), - MXCSR_NAME_FLAG_TABLE_ENTRY(PM), - MXCSR_NAME_FLAG_TABLE_ENTRY(FZ) - }; - - for(int i = 0; i < (sizeof(mxcsrnameflagtable) / sizeof(*mxcsrnameflagtable)); i++) - { - if(scmp(string, mxcsrnameflagtable[i].name)) - return mxcsrnameflagtable[i].flag; - } - - return 0; -} - -/** -\brief Gets the MXCSR flag from a string and a flags value. -\param mxcsrflags The flags value to get the flag from. -\param string The string with the flag name. -\return true if the flag is 1, false if the flag is 0. -*/ -bool valmxcsrflagfromstring(duint mxcsrflags, const char* string) -{ - unsigned int flag = getmxcsrflagfromstring(string); - if(flag == 0) - return false; - - return (bool)((int)(mxcsrflags & flag) != 0); -} - -#define x87STATUSWORD_FLAG_I 0x1 -#define x87STATUSWORD_FLAG_D 0x2 -#define x87STATUSWORD_FLAG_Z 0x4 -#define x87STATUSWORD_FLAG_O 0x8 -#define x87STATUSWORD_FLAG_U 0x10 -#define x87STATUSWORD_FLAG_P 0x20 -#define x87STATUSWORD_FLAG_SF 0x40 -#define x87STATUSWORD_FLAG_IR 0x80 -#define x87STATUSWORD_FLAG_C0 0x100 -#define x87STATUSWORD_FLAG_C1 0x200 -#define x87STATUSWORD_FLAG_C2 0x400 -#define x87STATUSWORD_FLAG_C3 0x4000 -#define x87STATUSWORD_FLAG_B 0x8000 - -#define X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, x87STATUSWORD_FLAG_##flag_name } - -/** -\brief Gets the x87 status word AND value from a string. -\param string The status word name. -\return The value to AND the status word with to get the flag. 0 when not found. -*/ -static unsigned int getx87statuswordflagfromstring(const char* string) -{ - static FLAG_NAME_VALUE_TABLE_t statuswordflagtable[] = - { - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(I), - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(D), - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(Z), - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(O), - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(U), - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(P), - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(SF), - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(IR), - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C0), - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C1), - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C2), - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C3), - X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(B) - }; - - for(int i = 0; i < (sizeof(statuswordflagtable) / sizeof(*statuswordflagtable)); i++) - { - if(scmp(string, statuswordflagtable[i].name)) - return statuswordflagtable[i].flag; - } - - return 0; -} - -/** -\brief Gets an x87 status flag from a string. -\param statusword The status word value. -\param string The flag name. -\return true if the flag is 1, false if the flag is 0. -*/ -bool valx87statuswordflagfromstring(duint statusword, const char* string) -{ - unsigned int flag = getx87statuswordflagfromstring(string); - if(flag == 0) - return false; - - return (bool)((int)(statusword & flag) != 0); -} - -#define x87CONTROLWORD_FLAG_IM 0x1 -#define x87CONTROLWORD_FLAG_DM 0x2 -#define x87CONTROLWORD_FLAG_ZM 0x4 -#define x87CONTROLWORD_FLAG_OM 0x8 -#define x87CONTROLWORD_FLAG_UM 0x10 -#define x87CONTROLWORD_FLAG_PM 0x20 -#define x87CONTROLWORD_FLAG_IEM 0x80 -#define x87CONTROLWORD_FLAG_IC 0x1000 - -#define X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, x87CONTROLWORD_FLAG_##flag_name } - -/** -\brief Gets the x87 control word flag AND value from a string. -\param string The name of the control word. -\return The value to AND the control word with to get the flag. 0 when not found. -*/ -static unsigned int getx87controlwordflagfromstring(const char* string) -{ - static FLAG_NAME_VALUE_TABLE_t controlwordflagtable[] = - { - X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IM), - X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(DM), - X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(ZM), - X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(OM), - X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(UM), - X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(PM), - X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IEM), - X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IC) - }; - - for(int i = 0; i < (sizeof(controlwordflagtable) / sizeof(*controlwordflagtable)); i++) - { - if(scmp(string, controlwordflagtable[i].name)) - return controlwordflagtable[i].flag; - } - - return 0; -} - -/** -\brief Get an x87 control word flag from a string. -\param controlword The control word to get the flag from. -\param string The flag name. -\return true if the flag is 1, false when the flag is 0. -*/ -bool valx87controlwordflagfromstring(duint controlword, const char* string) -{ - unsigned int flag = getx87controlwordflagfromstring(string); - - if(flag == 0) - return false; - - return (bool)((int)(controlword & flag) != 0); -} - -/** -\brief Gets the MXCSR field from a string. -\param mxcsrflags The mxcsrflags to get the field from. -\param string The name of the field (should be "RC"). -\return The MXCSR field word. -*/ -unsigned short valmxcsrfieldfromstring(duint mxcsrflags, const char* string) -{ - if(scmp(string, "RC")) - return ((mxcsrflags & 0x6000) >> 13); - - return 0; -} - -/** -\brief Gets the x87 status word field from a string. -\param statusword The status word to get the field from. -\param string The name of the field (should be "TOP"). -\return The x87 status word field. -*/ -unsigned short valx87statuswordfieldfromstring(duint statusword, const char* string) -{ - if(scmp(string, "TOP")) - return ((statusword & 0x3800) >> 11); - - return 0; -} - -/** -\brief Gets the x87 control word field from a string. -\param controlword The control word to get the field from. -\param string The name of the field. -\return The x87 control word field. -*/ -unsigned short valx87controlwordfieldfromstring(duint controlword, const char* string) -{ - if(scmp(string, "PC")) - return ((controlword & 0x300) >> 8); - if(scmp(string, "RC")) - return ((controlword & 0xC00) >> 10); - - return 0; -} - -/** -\brief Gets a flag from a string. -\param eflags The eflags value to get the flag from. -\param string The name of the flag. -\return true if the flag equals to 1, false if the flag is 0 or not found. -*/ -bool valflagfromstring(duint eflags, const char* string) -{ - if(scmp(string, "cf")) - return (bool)((int)(eflags & 0x1) != 0); - if(scmp(string, "pf")) - return (bool)((int)(eflags & 0x4) != 0); - if(scmp(string, "af")) - return (bool)((int)(eflags & 0x10) != 0); - if(scmp(string, "zf")) - return (bool)((int)(eflags & 0x40) != 0); - if(scmp(string, "sf")) - return (bool)((int)(eflags & 0x80) != 0); - if(scmp(string, "tf")) - return (bool)((int)(eflags & 0x100) != 0); - if(scmp(string, "if")) - return (bool)((int)(eflags & 0x200) != 0); - if(scmp(string, "df")) - return (bool)((int)(eflags & 0x400) != 0); - if(scmp(string, "of")) - return (bool)((int)(eflags & 0x800) != 0); - if(scmp(string, "rf")) - return (bool)((int)(eflags & 0x10000) != 0); - if(scmp(string, "vm")) - return (bool)((int)(eflags & 0x20000) != 0); - if(scmp(string, "ac")) - return (bool)((int)(eflags & 0x40000) != 0); - if(scmp(string, "vif")) - return (bool)((int)(eflags & 0x80000) != 0); - if(scmp(string, "vip")) - return (bool)((int)(eflags & 0x100000) != 0); - if(scmp(string, "id")) - return (bool)((int)(eflags & 0x200000) != 0); - return false; -} - -/** -\brief Sets a flag value. -\param string The name of the flag. -\param set The value of the flag. -\return true if the flag was successfully set, false otherwise. -*/ -bool setflag(const char* string, bool set) -{ - duint eflags = GetContextDataEx(hActiveThread, UE_CFLAGS); - duint xorval = 0; - duint flag = 0; - if(scmp(string, "cf")) - flag = 0x1; - else if(scmp(string, "pf")) - flag = 0x4; - else if(scmp(string, "af")) - flag = 0x10; - else if(scmp(string, "zf")) - flag = 0x40; - else if(scmp(string, "sf")) - flag = 0x80; - else if(scmp(string, "tf")) - flag = 0x100; - else if(scmp(string, "if")) - flag = 0x200; - else if(scmp(string, "df")) - flag = 0x400; - else if(scmp(string, "of")) - flag = 0x800; - else if(scmp(string, "rf")) - flag = 0x10000; - else if(scmp(string, "vm")) - flag = 0x20000; - else if(scmp(string, "ac")) - flag = 0x40000; - else if(scmp(string, "vif")) - flag = 0x80000; - else if(scmp(string, "vip")) - flag = 0x100000; - else if(scmp(string, "id")) - flag = 0x200000; - if(eflags & flag && !set) - xorval = flag; - else if(set) - xorval = flag; - return SetContextDataEx(hActiveThread, UE_CFLAGS, eflags ^ xorval); -} - -/** -\brief Gets a register from a string. -\param [out] size This function can store the register size in bytes in this parameter. Can be null, in that case it will be ignored. -\param string The name of the register to get. -\return The register value. -*/ -static duint getregister(int* size, const char* string) -{ - if(size) - *size = 4; - if(scmp(string, "eax")) - { - return GetContextDataEx(hActiveThread, UE_EAX); - } - if(scmp(string, "ebx")) - { - return GetContextDataEx(hActiveThread, UE_EBX); - } - if(scmp(string, "ecx")) - { - return GetContextDataEx(hActiveThread, UE_ECX); - } - if(scmp(string, "edx")) - { - return GetContextDataEx(hActiveThread, UE_EDX); - } - if(scmp(string, "edi")) - { - return GetContextDataEx(hActiveThread, UE_EDI); - } - if(scmp(string, "esi")) - { - return GetContextDataEx(hActiveThread, UE_ESI); - } - if(scmp(string, "ebp")) - { - return GetContextDataEx(hActiveThread, UE_EBP); - } - if(scmp(string, "esp")) - { - return GetContextDataEx(hActiveThread, UE_ESP); - } - if(scmp(string, "eip")) - { - return GetContextDataEx(hActiveThread, UE_EIP); - } - if(scmp(string, "eflags")) - { - return GetContextDataEx(hActiveThread, UE_EFLAGS); - } - - if(scmp(string, "gs")) - { - return GetContextDataEx(hActiveThread, UE_SEG_GS); - } - if(scmp(string, "fs")) - { - return GetContextDataEx(hActiveThread, UE_SEG_FS); - } - if(scmp(string, "es")) - { - return GetContextDataEx(hActiveThread, UE_SEG_ES); - } - if(scmp(string, "ds")) - { - return GetContextDataEx(hActiveThread, UE_SEG_DS); - } - if(scmp(string, "cs")) - { - return GetContextDataEx(hActiveThread, UE_SEG_CS); - } - if(scmp(string, "ss")) - { - return GetContextDataEx(hActiveThread, UE_SEG_SS); - } - - if(size) - *size = 2; - if(scmp(string, "ax")) - { - duint val = GetContextDataEx(hActiveThread, UE_EAX); - return val & 0xFFFF; - } - if(scmp(string, "bx")) - { - duint val = GetContextDataEx(hActiveThread, UE_EBX); - return val & 0xFFFF; - } - if(scmp(string, "cx")) - { - duint val = GetContextDataEx(hActiveThread, UE_ECX); - return val & 0xFFFF; - } - if(scmp(string, "dx")) - { - duint val = GetContextDataEx(hActiveThread, UE_EDX); - return val & 0xFFFF; - } - if(scmp(string, "si")) - { - duint val = GetContextDataEx(hActiveThread, UE_ESI); - return val & 0xFFFF; - } - if(scmp(string, "di")) - { - duint val = GetContextDataEx(hActiveThread, UE_EDI); - return val & 0xFFFF; - } - if(scmp(string, "bp")) - { - duint val = GetContextDataEx(hActiveThread, UE_EBP); - return val & 0xFFFF; - } - if(scmp(string, "sp")) - { - duint val = GetContextDataEx(hActiveThread, UE_ESP); - return val & 0xFFFF; - } - if(scmp(string, "ip")) - { - duint val = GetContextDataEx(hActiveThread, UE_EIP); - return val & 0xFFFF; - } - - if(size) - *size = 1; - if(scmp(string, "ah")) - { - duint val = GetContextDataEx(hActiveThread, UE_EAX); - return (val >> 8) & 0xFF; - } - if(scmp(string, "al")) - { - duint val = GetContextDataEx(hActiveThread, UE_EAX); - return val & 0xFF; - } - if(scmp(string, "bh")) - { - duint val = GetContextDataEx(hActiveThread, UE_EBX); - return (val >> 8) & 0xFF; - } - if(scmp(string, "bl")) - { - duint val = GetContextDataEx(hActiveThread, UE_EBX); - return val & 0xFF; - } - if(scmp(string, "ch")) - { - duint val = GetContextDataEx(hActiveThread, UE_ECX); - return (val >> 8) & 0xFF; - } - if(scmp(string, "cl")) - { - duint val = GetContextDataEx(hActiveThread, UE_ECX); - return val & 0xFF; - } - if(scmp(string, "dh")) - { - duint val = GetContextDataEx(hActiveThread, UE_EDX); - return (val >> 8) & 0xFF; - } - if(scmp(string, "dl")) - { - duint val = GetContextDataEx(hActiveThread, UE_EDX); - return val & 0xFF; - } - if(scmp(string, "sih")) - { - duint val = GetContextDataEx(hActiveThread, UE_ESI); - return (val >> 8) & 0xFF; - } - if(scmp(string, "sil")) - { - duint val = GetContextDataEx(hActiveThread, UE_ESI); - return val & 0xFF; - } - if(scmp(string, "dih")) - { - duint val = GetContextDataEx(hActiveThread, UE_EDI); - return (val >> 8) & 0xFF; - } - if(scmp(string, "dil")) - { - duint val = GetContextDataEx(hActiveThread, UE_EDI); - return val & 0xFF; - } - if(scmp(string, "bph")) - { - duint val = GetContextDataEx(hActiveThread, UE_EBP); - return (val >> 8) & 0xFF; - } - if(scmp(string, "bpl")) - { - duint val = GetContextDataEx(hActiveThread, UE_EBP); - return val & 0xFF; - } - if(scmp(string, "sph")) - { - duint val = GetContextDataEx(hActiveThread, UE_ESP); - return (val >> 8) & 0xFF; - } - if(scmp(string, "spl")) - { - duint val = GetContextDataEx(hActiveThread, UE_ESP); - return val & 0xFF; - } - if(scmp(string, "iph")) - { - duint val = GetContextDataEx(hActiveThread, UE_EIP); - return (val >> 8) & 0xFF; - } - if(scmp(string, "ipl")) - { - duint val = GetContextDataEx(hActiveThread, UE_EIP); - return val & 0xFF; - } - - if(size) - *size = sizeof(duint); - if(scmp(string, "dr0")) - { - return GetContextDataEx(hActiveThread, UE_DR0); - } - if(scmp(string, "dr1")) - { - return GetContextDataEx(hActiveThread, UE_DR1); - } - if(scmp(string, "dr2")) - { - return GetContextDataEx(hActiveThread, UE_DR2); - } - if(scmp(string, "dr3")) - { - return GetContextDataEx(hActiveThread, UE_DR3); - } - if(scmp(string, "dr6") || scmp(string, "dr4")) - { - return GetContextDataEx(hActiveThread, UE_DR6); - } - if(scmp(string, "dr7") || scmp(string, "dr5")) - { - return GetContextDataEx(hActiveThread, UE_DR7); - } - - if(scmp(string, "cip")) - { - return GetContextDataEx(hActiveThread, UE_CIP); - } - if(scmp(string, "csp")) - { - return GetContextDataEx(hActiveThread, UE_CSP); - } - if(scmp(string, "cflags")) - { - return GetContextDataEx(hActiveThread, UE_CFLAGS); - } - -#ifdef _WIN64 - if(size) - *size = 8; - if(scmp(string, "rax")) - { - return GetContextDataEx(hActiveThread, UE_RAX); - } - if(scmp(string, "rbx")) - { - return GetContextDataEx(hActiveThread, UE_RBX); - } - if(scmp(string, "rcx")) - { - return GetContextDataEx(hActiveThread, UE_RCX); - } - if(scmp(string, "rdx")) - { - return GetContextDataEx(hActiveThread, UE_RDX); - } - if(scmp(string, "rdi")) - { - return GetContextDataEx(hActiveThread, UE_RDI); - } - if(scmp(string, "rsi")) - { - return GetContextDataEx(hActiveThread, UE_RSI); - } - if(scmp(string, "rbp")) - { - return GetContextDataEx(hActiveThread, UE_RBP); - } - if(scmp(string, "rsp")) - { - return GetContextDataEx(hActiveThread, UE_RSP); - } - if(scmp(string, "rip")) - { - return GetContextDataEx(hActiveThread, UE_RIP); - } - if(scmp(string, "rflags")) - { - return GetContextDataEx(hActiveThread, UE_RFLAGS); - } - if(scmp(string, "r8")) - { - return GetContextDataEx(hActiveThread, UE_R8); - } - if(scmp(string, "r9")) - { - return GetContextDataEx(hActiveThread, UE_R9); - } - if(scmp(string, "r10")) - { - return GetContextDataEx(hActiveThread, UE_R10); - } - if(scmp(string, "r11")) - { - return GetContextDataEx(hActiveThread, UE_R11); - } - if(scmp(string, "r12")) - { - return GetContextDataEx(hActiveThread, UE_R12); - } - if(scmp(string, "r13")) - { - return GetContextDataEx(hActiveThread, UE_R13); - } - if(scmp(string, "r14")) - { - return GetContextDataEx(hActiveThread, UE_R14); - } - if(scmp(string, "r15")) - { - return GetContextDataEx(hActiveThread, UE_R15); - } - - if(size) - *size = 4; - if(scmp(string, "r8d")) - { - return GetContextDataEx(hActiveThread, UE_R8) & 0xFFFFFFFF; - } - if(scmp(string, "r9d")) - { - return GetContextDataEx(hActiveThread, UE_R9) & 0xFFFFFFFF; - } - if(scmp(string, "r10d")) - { - return GetContextDataEx(hActiveThread, UE_R10) & 0xFFFFFFFF; - } - if(scmp(string, "r11d")) - { - return GetContextDataEx(hActiveThread, UE_R11) & 0xFFFFFFFF; - } - if(scmp(string, "r12d")) - { - return GetContextDataEx(hActiveThread, UE_R12) & 0xFFFFFFFF; - } - if(scmp(string, "r13d")) - { - return GetContextDataEx(hActiveThread, UE_R13) & 0xFFFFFFFF; - } - if(scmp(string, "r14d")) - { - return GetContextDataEx(hActiveThread, UE_R14) & 0xFFFFFFFF; - } - if(scmp(string, "r15d")) - { - return GetContextDataEx(hActiveThread, UE_R15) & 0xFFFFFFFF; - } - - if(size) - *size = 2; - if(scmp(string, "r8w")) - { - return GetContextDataEx(hActiveThread, UE_R8) & 0xFFFF; - } - if(scmp(string, "r9w")) - { - return GetContextDataEx(hActiveThread, UE_R9) & 0xFFFF; - } - if(scmp(string, "r10w")) - { - return GetContextDataEx(hActiveThread, UE_R10) & 0xFFFF; - } - if(scmp(string, "r11w")) - { - return GetContextDataEx(hActiveThread, UE_R11) & 0xFFFF; - } - if(scmp(string, "r12w")) - { - return GetContextDataEx(hActiveThread, UE_R12) & 0xFFFF; - } - if(scmp(string, "r13w")) - { - return GetContextDataEx(hActiveThread, UE_R13) & 0xFFFF; - } - if(scmp(string, "r14w")) - { - return GetContextDataEx(hActiveThread, UE_R14) & 0xFFFF; - } - if(scmp(string, "r15w")) - { - return GetContextDataEx(hActiveThread, UE_R15) & 0xFFFF; - } - - if(size) - *size = 1; - if(scmp(string, "r8b")) - { - return GetContextDataEx(hActiveThread, UE_R8) & 0xFF; - } - if(scmp(string, "r9b")) - { - return GetContextDataEx(hActiveThread, UE_R9) & 0xFF; - } - if(scmp(string, "r10b")) - { - return GetContextDataEx(hActiveThread, UE_R10) & 0xFF; - } - if(scmp(string, "r11b")) - { - return GetContextDataEx(hActiveThread, UE_R11) & 0xFF; - } - if(scmp(string, "r12b")) - { - return GetContextDataEx(hActiveThread, UE_R12) & 0xFF; - } - if(scmp(string, "r13b")) - { - return GetContextDataEx(hActiveThread, UE_R13) & 0xFF; - } - if(scmp(string, "r14b")) - { - return GetContextDataEx(hActiveThread, UE_R14) & 0xFF; - } - if(scmp(string, "r15b")) - { - return GetContextDataEx(hActiveThread, UE_R15) & 0xFF; - } -#endif //_WIN64 - - if(size) - *size = 0; - return 0; -} - -/** -\brief Sets a register value based on the register name. -\param string The name of the register to set. -\param value The new register value. -\return true if the register was set, false otherwise. -*/ -bool setregister(const char* string, duint value) -{ - if(scmp(string, "eax")) - return SetContextDataEx(hActiveThread, UE_EAX, value & 0xFFFFFFFF); - if(scmp(string, "ebx")) - return SetContextDataEx(hActiveThread, UE_EBX, value & 0xFFFFFFFF); - if(scmp(string, "ecx")) - return SetContextDataEx(hActiveThread, UE_ECX, value & 0xFFFFFFFF); - if(scmp(string, "edx")) - return SetContextDataEx(hActiveThread, UE_EDX, value & 0xFFFFFFFF); - if(scmp(string, "edi")) - return SetContextDataEx(hActiveThread, UE_EDI, value & 0xFFFFFFFF); - if(scmp(string, "esi")) - return SetContextDataEx(hActiveThread, UE_ESI, value & 0xFFFFFFFF); - if(scmp(string, "ebp")) - return SetContextDataEx(hActiveThread, UE_EBP, value & 0xFFFFFFFF); - if(scmp(string, "esp")) - return SetContextDataEx(hActiveThread, UE_ESP, value & 0xFFFFFFFF); - if(scmp(string, "eip")) - return SetContextDataEx(hActiveThread, UE_EIP, value & 0xFFFFFFFF); - if(scmp(string, "eflags")) - return SetContextDataEx(hActiveThread, UE_EFLAGS, value & 0xFFFFFFFF); - - if(scmp(string, "gs")) - return SetContextDataEx(hActiveThread, UE_SEG_GS, value & 0xFFFF); - if(scmp(string, "fs")) - return SetContextDataEx(hActiveThread, UE_SEG_FS, value & 0xFFFF); - if(scmp(string, "es")) - return SetContextDataEx(hActiveThread, UE_SEG_ES, value & 0xFFFF); - if(scmp(string, "ds")) - return SetContextDataEx(hActiveThread, UE_SEG_DS, value & 0xFFFF); - if(scmp(string, "cs")) - return SetContextDataEx(hActiveThread, UE_SEG_CS, value & 0xFFFF); - if(scmp(string, "ss")) - return SetContextDataEx(hActiveThread, UE_SEG_SS, value & 0xFFFF); - - if(scmp(string, "ax")) - return SetContextDataEx(hActiveThread, UE_EAX, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_EAX) & 0xFFFF0000)); - if(scmp(string, "bx")) - return SetContextDataEx(hActiveThread, UE_EBX, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_EBX) & 0xFFFF0000)); - if(scmp(string, "cx")) - return SetContextDataEx(hActiveThread, UE_ECX, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_ECX) & 0xFFFF0000)); - if(scmp(string, "dx")) - return SetContextDataEx(hActiveThread, UE_EDX, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_EDX) & 0xFFFF0000)); - if(scmp(string, "si")) - return SetContextDataEx(hActiveThread, UE_ESI, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_ESI) & 0xFFFF0000)); - if(scmp(string, "di")) - return SetContextDataEx(hActiveThread, UE_EDI, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_EDI) & 0xFFFF0000)); - if(scmp(string, "bp")) - return SetContextDataEx(hActiveThread, UE_EBP, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_EBP) & 0xFFFF0000)); - if(scmp(string, "sp")) - return SetContextDataEx(hActiveThread, UE_ESP, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_ESP) & 0xFFFF0000)); - if(scmp(string, "ip")) - return SetContextDataEx(hActiveThread, UE_EIP, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_EIP) & 0xFFFF0000)); - - if(scmp(string, "ah")) - return SetContextDataEx(hActiveThread, UE_EAX, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_EAX) & 0xFFFF00FF)); - if(scmp(string, "al")) - return SetContextDataEx(hActiveThread, UE_EAX, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_EAX) & 0xFFFFFF00)); - if(scmp(string, "bh")) - return SetContextDataEx(hActiveThread, UE_EBX, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_EBX) & 0xFFFF00FF)); - if(scmp(string, "bl")) - return SetContextDataEx(hActiveThread, UE_EBX, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_EBX) & 0xFFFFFF00)); - if(scmp(string, "ch")) - return SetContextDataEx(hActiveThread, UE_ECX, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_ECX) & 0xFFFF00FF)); - if(scmp(string, "cl")) - return SetContextDataEx(hActiveThread, UE_ECX, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_ECX) & 0xFFFFFF00)); - if(scmp(string, "dh")) - return SetContextDataEx(hActiveThread, UE_EDX, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_EDX) & 0xFFFF00FF)); - if(scmp(string, "dl")) - return SetContextDataEx(hActiveThread, UE_EDX, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_EDX) & 0xFFFFFF00)); - if(scmp(string, "sih")) - return SetContextDataEx(hActiveThread, UE_ESI, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_ESI) & 0xFFFF00FF)); - if(scmp(string, "sil")) - return SetContextDataEx(hActiveThread, UE_ESI, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_ESI) & 0xFFFFFF00)); - if(scmp(string, "dih")) - return SetContextDataEx(hActiveThread, UE_EDI, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_EDI) & 0xFFFF00FF)); - if(scmp(string, "dil")) - return SetContextDataEx(hActiveThread, UE_EDI, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_EDI) & 0xFFFFFF00)); - if(scmp(string, "bph")) - return SetContextDataEx(hActiveThread, UE_EBP, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_EBP) & 0xFFFF00FF)); - if(scmp(string, "bpl")) - return SetContextDataEx(hActiveThread, UE_EBP, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_EBP) & 0xFFFFFF00)); - if(scmp(string, "sph")) - return SetContextDataEx(hActiveThread, UE_ESP, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_ESP) & 0xFFFF00FF)); - if(scmp(string, "spl")) - return SetContextDataEx(hActiveThread, UE_ESP, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_ESP) & 0xFFFFFF00)); - if(scmp(string, "iph")) - return SetContextDataEx(hActiveThread, UE_EIP, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_EIP) & 0xFFFF00FF)); - if(scmp(string, "ipl")) - return SetContextDataEx(hActiveThread, UE_EIP, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_EIP) & 0xFFFFFF00)); - - if(scmp(string, "dr0")) - return SetContextDataEx(hActiveThread, UE_DR0, value); - if(scmp(string, "dr1")) - return SetContextDataEx(hActiveThread, UE_DR1, value); - if(scmp(string, "dr2")) - return SetContextDataEx(hActiveThread, UE_DR2, value); - if(scmp(string, "dr3")) - return SetContextDataEx(hActiveThread, UE_DR3, value); - if(scmp(string, "dr6") || scmp(string, "dr4")) - return SetContextDataEx(hActiveThread, UE_DR6, value); - if(scmp(string, "dr7") || scmp(string, "dr5")) - return SetContextDataEx(hActiveThread, UE_DR7, value); - - if(scmp(string, "cip")) - return SetContextDataEx(hActiveThread, UE_CIP, value); - if(scmp(string, "csp")) - return SetContextDataEx(hActiveThread, UE_CSP, value); - if(scmp(string, "cflags")) - return SetContextDataEx(hActiveThread, UE_CFLAGS, value); - -#ifdef _WIN64 - if(scmp(string, "rax")) - return SetContextDataEx(hActiveThread, UE_RAX, value); - if(scmp(string, "rbx")) - return SetContextDataEx(hActiveThread, UE_RBX, value); - if(scmp(string, "rcx")) - return SetContextDataEx(hActiveThread, UE_RCX, value); - if(scmp(string, "rdx")) - return SetContextDataEx(hActiveThread, UE_RDX, value); - if(scmp(string, "rdi")) - return SetContextDataEx(hActiveThread, UE_RDI, value); - if(scmp(string, "rsi")) - return SetContextDataEx(hActiveThread, UE_RSI, value); - if(scmp(string, "rbp")) - return SetContextDataEx(hActiveThread, UE_RBP, value); - if(scmp(string, "rsp")) - return SetContextDataEx(hActiveThread, UE_RSP, value); - if(scmp(string, "rip")) - return SetContextDataEx(hActiveThread, UE_RIP, value); - if(scmp(string, "rflags")) - return SetContextDataEx(hActiveThread, UE_RFLAGS, value); - if(scmp(string, "r8")) - return SetContextDataEx(hActiveThread, UE_R8, value); - if(scmp(string, "r9")) - return SetContextDataEx(hActiveThread, UE_R9, value); - if(scmp(string, "r10")) - return SetContextDataEx(hActiveThread, UE_R10, value); - if(scmp(string, "r11")) - return SetContextDataEx(hActiveThread, UE_R11, value); - if(scmp(string, "r12")) - return SetContextDataEx(hActiveThread, UE_R12, value); - if(scmp(string, "r13")) - return SetContextDataEx(hActiveThread, UE_R13, value); - if(scmp(string, "r14")) - return SetContextDataEx(hActiveThread, UE_R14, value); - if(scmp(string, "r15")) - return SetContextDataEx(hActiveThread, UE_R15, value); - - if(scmp(string, "r8d")) - return SetContextDataEx(hActiveThread, UE_R8, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R8) & 0xFFFFFFFF00000000)); - if(scmp(string, "r9d")) - return SetContextDataEx(hActiveThread, UE_R9, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R9) & 0xFFFFFFFF00000000)); - if(scmp(string, "r10d")) - return SetContextDataEx(hActiveThread, UE_R10, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R10) & 0xFFFFFFFF00000000)); - if(scmp(string, "r11d")) - return SetContextDataEx(hActiveThread, UE_R11, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R11) & 0xFFFFFFFF00000000)); - if(scmp(string, "r12d")) - return SetContextDataEx(hActiveThread, UE_R12, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R12) & 0xFFFFFFFF00000000)); - if(scmp(string, "r13d")) - return SetContextDataEx(hActiveThread, UE_R13, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R13) & 0xFFFFFFFF00000000)); - if(scmp(string, "r14d")) - return SetContextDataEx(hActiveThread, UE_R14, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R14) & 0xFFFFFFFF00000000)); - if(scmp(string, "r15d")) - return SetContextDataEx(hActiveThread, UE_R15, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R15) & 0xFFFFFFFF00000000)); - - if(scmp(string, "r8w")) - return SetContextDataEx(hActiveThread, UE_R8, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R8) & 0xFFFFFFFFFFFF0000)); - if(scmp(string, "r9w")) - return SetContextDataEx(hActiveThread, UE_R9, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R9) & 0xFFFFFFFFFFFF0000)); - if(scmp(string, "r10w")) - return SetContextDataEx(hActiveThread, UE_R10, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R10) & 0xFFFFFFFFFFFF0000)); - if(scmp(string, "r11w")) - return SetContextDataEx(hActiveThread, UE_R11, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R11) & 0xFFFFFFFFFFFF0000)); - if(scmp(string, "r12w")) - return SetContextDataEx(hActiveThread, UE_R12, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R12) & 0xFFFFFFFFFFFF0000)); - if(scmp(string, "r13w")) - return SetContextDataEx(hActiveThread, UE_R13, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R13) & 0xFFFFFFFFFFFF0000)); - if(scmp(string, "r14w")) - return SetContextDataEx(hActiveThread, UE_R14, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R14) & 0xFFFFFFFFFFFF0000)); - if(scmp(string, "r15w")) - return SetContextDataEx(hActiveThread, UE_R15, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R15) & 0xFFFFFFFFFFFF0000)); - if(scmp(string, "r8b")) - return SetContextDataEx(hActiveThread, UE_R8, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R8) & 0xFFFFFFFFFFFFFF00)); - if(scmp(string, "r9b")) - return SetContextDataEx(hActiveThread, UE_R9, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R9) & 0xFFFFFFFFFFFFFF00)); - if(scmp(string, "r10b")) - return SetContextDataEx(hActiveThread, UE_R10, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R10) & 0xFFFFFFFFFFFFFF00)); - if(scmp(string, "r11b")) - return SetContextDataEx(hActiveThread, UE_R11, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R11) & 0xFFFFFFFFFFFFFF00)); - if(scmp(string, "r12b")) - return SetContextDataEx(hActiveThread, UE_R12, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R12) & 0xFFFFFFFFFFFFFF00)); - if(scmp(string, "r13b")) - return SetContextDataEx(hActiveThread, UE_R13, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R13) & 0xFFFFFFFFFFFFFF00)); - if(scmp(string, "r14b")) - return SetContextDataEx(hActiveThread, UE_R14, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R14) & 0xFFFFFFFFFFFFFF00)); - if(scmp(string, "r15b")) - return SetContextDataEx(hActiveThread, UE_R15, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R15) & 0xFFFFFFFFFFFFFF00)); -#endif // _WIN64 - - return false; -} - -/** -\brief Gets the address of an API from a name. -\param name The name of the API, see the command help for more information about valid constructions. -\param [out] value The address of the retrieved API. Cannot be null. -\param [out] value_size This function sets this value to the size of the address, sizeof(duint). -\param printall true to print all possible API values to the console. -\param silent true to have no console output. If true, the \p printall parameter is ignored. -\param [out] hexonly If set to true, the values should be printed in hex only. Usually this function sets it to true. -\return true if the API was found and a value retrieved, false otherwise. -*/ -bool valapifromstring(const char* name, duint* value, int* value_size, bool printall, bool silent, bool* hexonly) -{ - if(!value || !DbgIsDebugging()) - return false; - //explicit API handling - const char* apiname = strchr(name, ':'); //the ':' character cannot be in a path: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#naming_conventions - bool noexports = false; - if(!apiname) //not found - { - apiname = strrchr(name, '.'); //kernel32.GetProcAddress support - if(!apiname) //not found - { - apiname = strchr(name, '?'); //the '?' character cannot be in a path either - noexports = true; - } - } - if(apiname) - { - char modname[MAX_MODULE_SIZE] = ""; - if(name == apiname) //:[expression] <= currently selected module - { - SELECTIONDATA seldata; - memset(&seldata, 0, sizeof(seldata)); - GuiSelectionGet(GUI_DISASSEMBLY, &seldata); - if(!ModNameFromAddr(seldata.start, modname, true)) - return false; - } - else - { - strcpy_s(modname, name); - modname[apiname - name] = 0; - } - apiname++; - if(!strlen(apiname)) - return false; - duint modbase = ModBaseFromName(modname); - wchar_t szModName[MAX_PATH] = L""; - if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbase, szModName, MAX_PATH)) - { - if(!silent) - dprintf("could not get filename of module " fhex "\n", modbase); - } - else - { - HMODULE mod = LoadLibraryExW(szModName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); - if(!mod) - { - if(!silent) - dprintf("unable to load library %s\n", szModName); - } - else - { - duint addr = noexports ? 0 : (duint)GetProcAddress(mod, apiname); - if(addr) //found exported function - addr = modbase + (addr - (duint)mod); //correct for loaded base - else //not found - { - if(scmp(apiname, "base") || scmp(apiname, "imagebase") || scmp(apiname, "header")) //get loaded base - addr = modbase; - else if(scmp(apiname, "entrypoint") || scmp(apiname, "entry") || scmp(apiname, "oep") || scmp(apiname, "ep")) //get entry point - addr = modbase + GetPE32DataW(szModName, 0, UE_OEP); - else if(*apiname == '$') //RVA - { - duint rva; - if(valfromstring(apiname + 1, &rva)) - addr = modbase + rva; - } - else if(*apiname == '#') //File Offset - { - duint offset; - if(valfromstring(apiname + 1, &offset)) - addr = valfileoffsettova(modname, offset); - } - else - { - if(noexports) //get the exported functions with the '?' delimiter - { - addr = (duint)GetProcAddress(mod, apiname); - if(addr) //found exported function - addr = modbase + (addr - (duint)mod); //correct for loaded base - } - else - { - duint ordinal; - if(valfromstring(apiname, &ordinal)) - { - addr = (duint)GetProcAddress(mod, (LPCSTR)(ordinal & 0xFFFF)); - if(addr) //found exported function - addr = modbase + (addr - (duint)mod); //correct for loaded base - else if(!ordinal) //support for getting the image base using :0 - addr = modbase; - } - } - } - } - FreeLibrary(mod); - if(addr) //found! - { - if(value_size) - *value_size = sizeof(duint); - if(hexonly) - *hexonly = true; - *value = addr; - return true; - } - } - } - return false; - } - int found = 0; - int kernel32 = -1; - DWORD cbNeeded = 0; - Memory addrfound; - if(EnumProcessModules(fdProcessInfo->hProcess, 0, 0, &cbNeeded)) - { - addrfound.realloc(cbNeeded * sizeof(duint), "valapifromstring:addrfound"); - Memory hMods(cbNeeded * sizeof(HMODULE), "valapifromstring:hMods"); - if(EnumProcessModules(fdProcessInfo->hProcess, hMods(), cbNeeded, &cbNeeded)) - { - for(unsigned int i = 0; i < cbNeeded / sizeof(HMODULE); i++) - { - wchar_t szModuleName[MAX_PATH] = L""; - if(GetModuleFileNameExW(fdProcessInfo->hProcess, hMods()[i], szModuleName, MAX_PATH)) - { - wchar_t* szBaseName = wcsrchr(szModuleName, L'\\'); - if(szBaseName) - { - szBaseName++; - HMODULE hModule = LoadLibraryExW(szModuleName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); - if(hModule) - { - ULONG_PTR funcAddress = (ULONG_PTR)GetProcAddress(hModule, name); - if(funcAddress) - { - if(!_wcsicmp(szBaseName, L"kernel32.dll")) - kernel32 = found; - duint rva = funcAddress - (duint)hModule; - addrfound()[found] = (duint)hMods()[i] + rva; - found++; - } - FreeLibrary(hModule); - } - } - } - } - } - } - if(!found) - return false; - if(value_size) - *value_size = sizeof(duint); - if(hexonly) - *hexonly = true; - if(kernel32 != -1) //prioritize kernel32 exports - { - *value = addrfound()[kernel32]; - if(!printall || silent) - return true; - for(int i = 0; i < found; i++) - if(i != kernel32) - dprintf(fhex"\n", addrfound()[i]); - } - else - { - *value = *addrfound(); - if(!printall || silent) - return true; - for(int i = 1; i < found; i++) - dprintf(fhex"\n", addrfound()[i]); - } - return true; -} - -/** -\brief Check if a string is a valid decimal number. This function also accepts "-" or "." as prefix. -\param string The string to check. -\return true if the string is a valid decimal number. -*/ -static bool isdecnumber(const char* string) -{ - if(*string != '.' || !string[1]) //dec indicator/no number - return false; - int decAdd = 1; - if(string[1] == '-') //minus - { - if(!string[2]) //no number - return false; - decAdd++; - } - int len = (int)strlen(string + decAdd); - for(int i = 0; i < len; i++) - if(!isdigit(string[i + decAdd])) - return false; - return true; -} - -/** -\brief Check if a string is a valid hexadecimal number. This function also accepts "0x" or "x" as prefix. -\param string The string to check. -\return true if the string is a valid hexadecimal number. -*/ -static bool ishexnumber(const char* string) -{ - int add = 0; - if(*string == '0' && string[1] == 'x') //0x prefix - add = 2; - else if(*string == 'x') //hex indicator - add = 1; - if(!string[add]) //only an indicator, no number - return false; - int len = (int)strlen(string + add); - for(int i = 0; i < len; i++) - if(!isxdigit(string[i + add])) //all must be hex digits - return false; - return true; -} - -/** -\brief Gets a value from a string. This function can parse expressions, memory locations, registers, flags, API names, labels, symbols and variables. -\param string The string to parse. -\param [out] value The value of the expression. This value cannot be null. -\param silent true to not output anything to the console. -\param baseonly true to skip parsing API names, labels, symbols and variables (basic expressions only). -\param [out] value_size This function can output the value size parsed (for example memory location size or register size). Can be null. -\param [out] isvar This function can output if the expression is variable (for example memory locations, registers or variables are variable). Can be null. -\param [out] hexonly This function can output if the output value should only be printed as hexadecimal (for example addresses). Can be null. -\return true if the expression was parsed successful, false otherwise. -*/ -bool valfromstring_noexpr(const char* string, duint* value, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly) -{ - if(!value || !string) - return false; - if(!*string) - { - *value = 0; - return true; - } - else if(string[0] == '[' || (isdigit(string[0]) && string[1] == ':' && string[2] == '[')) //memory location - { - if(!DbgIsDebugging()) - { - if(!silent) - dputs("not debugging"); - *value = 0; - if(value_size) - *value_size = 0; - if(isvar) - *isvar = true; - return true; - } - int len = (int)strlen(string); - - String newstring; - bool foundStart = false; - for(int i = 0; i < len; i++) - { - if(string[i] == '[') - foundStart = true; - else if(string[i] == ']') - break; - else if(foundStart) - newstring += string[i]; - } - - int read_size = sizeof(duint); - int add = 1; - if(string[1] == ':') //n:[ (number of bytes to read) - { - add += 2; - int new_size = string[0] - '0'; - if(new_size < read_size) - read_size = new_size; - } - if(!valfromstring(newstring.c_str(), value, silent, baseonly)) - { - dprintf("noexpr failed on %s\n", newstring.c_str()); - return false; - } - duint addr = *value; - *value = 0; - if(!MemRead(addr, value, read_size)) - { - if(!silent) - dputs("failed to read memory"); - return false; - } - if(value_size) - *value_size = read_size; - if(isvar) - *isvar = true; - return true; - } - else if(isregister(string)) //register - { - if(!DbgIsDebugging()) - { - if(!silent) - dputs("not debugging!"); - *value = 0; - if(value_size) - *value_size = 0; - if(isvar) - *isvar = true; - return true; - } - *value = getregister(value_size, string); - if(isvar) - *isvar = true; - return true; - } - else if(*string == '!' && isflag(string + 1)) //flag - { - if(!DbgIsDebugging()) - { - if(!silent) - dputs("not debugging"); - *value = 0; - if(value_size) - *value_size = 0; - if(isvar) - *isvar = true; - return true; - } - duint eflags = GetContextDataEx(hActiveThread, UE_CFLAGS); - if(valflagfromstring(eflags, string + 1)) - *value = 1; - else - *value = 0; - if(value_size) - *value_size = 0; - if(isvar) - *isvar = true; - return true; - } - else if(isdecnumber(string)) //decimal numbers come 'first' - { - if(value_size) - *value_size = 0; - if(isvar) - *isvar = false; - sscanf(string + 1, "%" fext "u", value); - return true; - } - else if(ishexnumber(string)) //then hex numbers - { - if(value_size) - *value_size = 0; - if(isvar) - *isvar = false; - //hexadecimal value - int inc = 0; - if(*string == 'x') - inc = 1; - sscanf(string + inc, "%" fext "x", value); - return true; - } - if(baseonly) - return false; - else if(valapifromstring(string, value, value_size, true, silent, hexonly)) //then come APIs - return true; - else if(LabelFromString(string, value)) //then come labels - return true; - else if(SymAddrFromName(string, value)) //then come symbols - return true; - else if(varget(string, value, value_size, 0)) //finally variables - { - if(isvar) - *isvar = true; - return true; - } - if(!silent) - dprintf("invalid value: \"%s\"!\n", string); - return false; //nothing was OK -} - -/** -\brief Gets a value from a string. This function can parse expressions, memory locations, registers, flags, API names, labels, symbols and variables. -\param string The string to parse. -\param [out] value The value of the expression. This value cannot be null. -\param silent true to not output anything to the console. -\param baseonly true to skip parsing API names, labels, symbols and variables (basic expressions only). -\param [out] value_size This function can output the value size parsed (for example memory location size or register size). Can be null. -\param [out] isvar This function can output if the expression is variable (for example memory locations, registers or variables are variable). Can be null. -\param [out] hexonly This function can output if the output value should only be printed as hexadecimal (for example addresses). Can be null. -\return true if the expression was parsed successful, false otherwise. -*/ -bool valfromstring(const char* string, duint* value, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly) -{ - if(!value || !string) - return false; - if(!*string) - { - *value = 0; - return true; - } - ExpressionParser parser(string); - duint result; - if(!parser.calculate(result, valuesignedcalc(), silent, baseonly, value_size, isvar, hexonly)) - return false; - *value = result; - return true; -} - -/** -\brief Checks if a string is long enough. -\param str The string to check. -\param min_length The minimum length of \p str. -\return true if the string is long enough, false otherwise. -*/ -static bool longEnough(const char* str, size_t min_length) -{ - size_t length = 0; - while(str[length] && length < min_length) - length++; - if(length == min_length) - return true; - return false; -} - -/** -\brief Checks if a string starts with another string. -\param pre The desired prefix of the string. -\param str The complete string. -\return true if \p str starts with \p pre. -*/ -static bool startsWith(const char* pre, const char* str) -{ - size_t lenpre = strlen(pre); - return longEnough(str, lenpre) ? StrNCmpI(str, pre, (int) lenpre) == 0 : false; -} - -#define MxCsr_PRE_FIELD_STRING "MxCsr_" -#define x87SW_PRE_FIELD_STRING "x87SW_" -#define x87CW_PRE_FIELD_STRING "x87CW_" -#define x87TW_PRE_FIELD_STRING "x87TW_" -#define MMX_PRE_FIELD_STRING "MM" -#define XMM_PRE_FIELD_STRING "XMM" -#define YMM_PRE_FIELD_STRING "YMM" -#define x8780BITFPU_PRE_FIELD_STRING "x87r" -#define STRLEN_USING_SIZEOF(string) (sizeof(string) - 1) - -/** -\brief Sets an FPU value (MXCSR fields, MMX fields, etc.) by name. -\param string The name of the FPU value to set. -\param value The value to set. -*/ -static void setfpuvalue(const char* string, duint value) -{ - duint xorval = 0; - duint flags = 0; - duint flag = 0; - bool set = false; - - if(value) - set = true; - - if(startsWith(MxCsr_PRE_FIELD_STRING, string)) - { - if(StrNCmpI(string + STRLEN_USING_SIZEOF(MxCsr_PRE_FIELD_STRING), "RC", (int) strlen("RC")) == 0) - { - duint flags = GetContextDataEx(hActiveThread, UE_MXCSR); - int i = 3; - i <<= 13; - flags &= ~i; - value <<= 13; - flags |= value; - SetContextDataEx(hActiveThread, UE_MXCSR, flags); - } - else - { - duint flags = GetContextDataEx(hActiveThread, UE_MXCSR); - flag = getmxcsrflagfromstring(string + STRLEN_USING_SIZEOF(MxCsr_PRE_FIELD_STRING)); - if(flags & flag && !set) - xorval = flag; - else if(set) - xorval = flag; - SetContextDataEx(hActiveThread, UE_MXCSR, flags ^ xorval); - } - } - else if(startsWith(x87TW_PRE_FIELD_STRING, string)) - { - unsigned int i; - - string += STRLEN_USING_SIZEOF(x87TW_PRE_FIELD_STRING); - i = atoi(string); - - if(i > 7) - return; - - flags = GetContextDataEx(hActiveThread, UE_X87_TAGWORD); - - flag = 3; - flag <<= i * 2; - - flags &= ~flag; - - flag = value; - flag <<= i * 2; - - flags |= flag; - - SetContextDataEx(hActiveThread, UE_X87_TAGWORD, (unsigned short) flags); - - } - else if(startsWith(x87SW_PRE_FIELD_STRING, string)) - { - if(StrNCmpI(string + STRLEN_USING_SIZEOF(x87SW_PRE_FIELD_STRING), "TOP", (int) strlen("TOP")) == 0) - { - duint flags = GetContextDataEx(hActiveThread, UE_X87_STATUSWORD); - int i = 7; - i <<= 11; - flags &= ~i; - value <<= 11; - flags |= value; - SetContextDataEx(hActiveThread, UE_X87_STATUSWORD, flags); - } - else - { - duint flags = GetContextDataEx(hActiveThread, UE_X87_STATUSWORD); - flag = getx87statuswordflagfromstring(string + STRLEN_USING_SIZEOF(x87SW_PRE_FIELD_STRING)); - if(flags & flag && !set) - xorval = flag; - else if(set) - xorval = flag; - SetContextDataEx(hActiveThread, UE_X87_STATUSWORD, flags ^ xorval); - } - } - else if(startsWith(x87CW_PRE_FIELD_STRING, string)) - { - if(StrNCmpI(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING), "RC", (int) strlen("RC")) == 0) - { - duint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD); - int i = 3; - i <<= 10; - flags &= ~i; - value <<= 10; - flags |= value; - SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags); - } - else if(StrNCmpI(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING), "PC", (int) strlen("PC")) == 0) - { - duint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD); - int i = 3; - i <<= 8; - flags &= ~i; - value <<= 8; - flags |= value; - SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags); - } - else - { - duint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD); - flag = getx87controlwordflagfromstring(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING)); - if(flags & flag && !set) - xorval = flag; - else if(set) - xorval = flag; - SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags ^ xorval); - } - } - else if(StrNCmpI(string, "x87TagWord", (int) strlen(string)) == 0) - { - SetContextDataEx(hActiveThread, UE_X87_TAGWORD, (unsigned short) value); - } - else if(StrNCmpI(string, "x87StatusWord", (int) strlen(string)) == 0) - { - SetContextDataEx(hActiveThread, UE_X87_STATUSWORD, (unsigned short) value); - } - else if(StrNCmpI(string, "x87ControlWord", (int) strlen(string)) == 0) - { - SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, (unsigned short) value); - } - else if(StrNCmpI(string, "MxCsr", (int) strlen(string)) == 0) - { - SetContextDataEx(hActiveThread, UE_MXCSR, value); - } - else if(startsWith(x8780BITFPU_PRE_FIELD_STRING, string)) - { - string += STRLEN_USING_SIZEOF(x8780BITFPU_PRE_FIELD_STRING); - DWORD registerindex; - bool found = true; - switch(*string) - { - case '0': - registerindex = UE_x87_r0; - break; - - case '1': - registerindex = UE_x87_r1; - break; - - case '2': - registerindex = UE_x87_r2; - break; - - case '3': - registerindex = UE_x87_r3; - break; - - case '4': - registerindex = UE_x87_r4; - break; - - case '5': - registerindex = UE_x87_r5; - break; - - case '6': - registerindex = UE_x87_r6; - break; - - case '7': - registerindex = UE_x87_r7; - break; - - default: - found = false; - break; - } - if(found) - SetContextDataEx(hActiveThread, registerindex, value); - } - else if(startsWith(MMX_PRE_FIELD_STRING, string)) - { - string += STRLEN_USING_SIZEOF(MMX_PRE_FIELD_STRING); - DWORD registerindex; - bool found = true; - switch(*string) - { - case '0': - registerindex = UE_MMX0; - break; - - case '1': - registerindex = UE_MMX1; - break; - - case '2': - registerindex = UE_MMX2; - break; - - case '3': - registerindex = UE_MMX3; - break; - - case '4': - registerindex = UE_MMX4; - break; - - case '5': - registerindex = UE_MMX5; - break; - - case '6': - registerindex = UE_MMX6; - break; - - case '7': - registerindex = UE_MMX7; - break; - - default: - found = false; - break; - } - if(found) - SetContextDataEx(hActiveThread, registerindex, value); - } - else if(startsWith(XMM_PRE_FIELD_STRING, string)) - { - string += STRLEN_USING_SIZEOF(XMM_PRE_FIELD_STRING); - DWORD registerindex; - bool found = true; - switch(atoi(string)) - { - case 0: - registerindex = UE_XMM0; - break; - - case 1: - registerindex = UE_XMM1; - break; - - case 2: - registerindex = UE_XMM2; - break; - - case 3: - registerindex = UE_XMM3; - break; - - case 4: - registerindex = UE_XMM4; - break; - - case 5: - registerindex = UE_XMM5; - break; - - case 6: - registerindex = UE_XMM6; - break; - - case 7: - registerindex = UE_XMM7; - break; - - case 8: - registerindex = UE_XMM8; - break; - - case 9: - registerindex = UE_XMM9; - break; - - case 10: - registerindex = UE_XMM10; - break; - - case 11: - registerindex = UE_XMM11; - break; - - case 12: - registerindex = UE_XMM12; - break; - - case 13: - registerindex = UE_XMM13; - break; - - case 14: - registerindex = UE_XMM14; - break; - - case 15: - registerindex = UE_XMM15; - break; - - default: - found = false; - break; - } - if(found) - SetContextDataEx(hActiveThread, registerindex, value); - } - else if(startsWith(YMM_PRE_FIELD_STRING, string)) - { - string += STRLEN_USING_SIZEOF(YMM_PRE_FIELD_STRING); - DWORD registerindex; - bool found = true; - switch(atoi(string)) - { - case 0: - registerindex = UE_YMM0; - break; - - case 1: - registerindex = UE_YMM1; - break; - - case 2: - registerindex = UE_YMM2; - break; - - case 3: - registerindex = UE_YMM3; - break; - - case 4: - registerindex = UE_YMM4; - break; - - case 5: - registerindex = UE_YMM5; - break; - - case 6: - registerindex = UE_YMM6; - break; - - case 7: - registerindex = UE_YMM7; - break; - - case 8: - registerindex = UE_YMM8; - break; - - case 9: - registerindex = UE_YMM9; - break; - - case 10: - registerindex = UE_YMM10; - break; - - case 11: - registerindex = UE_YMM11; - break; - - case 12: - registerindex = UE_YMM12; - break; - - case 13: - registerindex = UE_YMM13; - break; - - case 14: - registerindex = UE_YMM14; - break; - - case 15: - registerindex = UE_YMM15; - break; - - default: - registerindex = 0; - found = false; - break; - } - if(found) - SetContextDataEx(hActiveThread, registerindex, value); - } -} - -/** -\brief Sets a register, variable, flag, memory location or FPU value by name. -\param string The name of the thing to set. -\param value The value to set. -\param silent true to not have output to the console. -\return true if the value was set successfully, false otherwise. -*/ -bool valtostring(const char* string, duint value, bool silent) -{ - if(!*string) - return false; - else if(*string == '@' || strstr(string, "[")) //memory location - { - if(!DbgIsDebugging()) - { - if(!silent) - dputs("not debugging"); - return false; - } - int len = (int)strlen(string); - Memory newstring(len * 2, "valfromstring:newstring"); - if(strstr(string, "[")) //memory brackets: [] - { - for(int i = 0, j = 0; i < len; i++) - { - if(string[i] == ']') - j += sprintf(newstring() + j, ")"); - else if(isdigit(string[i]) && string[i + 1] == ':' && string[i + 2] == '[') //n:[ - { - j += sprintf(newstring() + j, "@%c:(", string[i]); - i += 2; - } - else if(string[i] == '[') - j += sprintf(newstring() + j, "@("); - else - j += sprintf(newstring() + j, "%c", string[i]); - } - } - else - strcpy_s(newstring(), len * 2, string); - int read_size = sizeof(duint); - int add = 1; - if(newstring()[2] == ':' && isdigit((newstring()[1]))) - { - add += 2; - int new_size = newstring()[1] - 0x30; - if(new_size < read_size) - read_size = new_size; - } - duint temp; - if(!valfromstring(newstring() + add, &temp, silent, false)) - { - return false; - } - duint value_ = value; - if(!MemPatch(temp, &value_, read_size)) - { - if(!silent) - dputs("failed to write memory"); - return false; - } - GuiUpdateAllViews(); //repaint gui - GuiUpdatePatches(); //update patch dialog - return true; - } - else if(isregister(string)) //register - { - if(!DbgIsDebugging()) - { - if(!silent) - dputs("not debugging!"); - return false; - } - bool ok = setregister(string, value); - int len = (int)strlen(string); - Memory regName(len + 1, "valtostring:regname"); - strcpy_s(regName(), len + 1, string); - _strlwr(regName()); - if(strstr(regName(), "ip")) - DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), false); //update disassembly + register view - else if(strstr(regName(), "sp")) //update stack - { - duint csp = GetContextDataEx(hActiveThread, UE_CSP); - DebugUpdateStack(csp, csp); - GuiUpdateRegisterView(); - } - else - GuiUpdateAllViews(); //repaint gui - return ok; - } - else if((*string == '_')) //FPU values - { - if(!DbgIsDebugging()) - { - if(!silent) - dputs("not debugging!"); - return false; - } - setfpuvalue(string + 1, value); - GuiUpdateAllViews(); //repaint gui - return true; - } - else if(*string == '!' && isflag(string + 1)) //flag - { - if(!DbgIsDebugging()) - { - if(!silent) - dputs("not debugging"); - return false; - } - bool set = false; - if(value) - set = true; - setflag(string + 1, set); - GuiUpdateAllViews(); //repaint gui - return true; - } - return varset(string, value, false); //variable -} - -/** -\brief Converts a file offset to a virtual address. -\param modname The name (not the path) of the module the file offset is in. -\param offset The file offset. -\return The VA of the file offset, 0 when there was a problem with the conversion. -*/ -duint valfileoffsettova(const char* modname, duint offset) -{ - char modpath[MAX_PATH] = ""; - if(ModPathFromName(modname, modpath, MAX_PATH)) - { - HANDLE FileHandle; - DWORD LoadedSize; - HANDLE FileMap; - ULONG_PTR FileMapVA; - if(StaticFileLoadW(StringUtils::Utf8ToUtf16(modpath).c_str(), UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA)) - { - ULONGLONG rva = ConvertFileOffsetToVA(FileMapVA, //FileMapVA - FileMapVA + (ULONG_PTR)offset, //Offset inside FileMapVA - false); //Return without ImageBase - StaticFileUnloadW(StringUtils::Utf8ToUtf16(modpath).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA); - return offset < LoadedSize ? (duint)rva + ModBaseFromName(modname) : 0; - } - } - return 0; -} - -/** -\brief Converts a virtual address to a file offset. -\param va The virtual address (must be inside a module). -\return The file offset. 0 when there was a problem with the conversion. -*/ -duint valvatofileoffset(duint va) -{ - char modpath[MAX_PATH] = ""; - if(ModPathFromAddr(va, modpath, MAX_PATH)) - { - HANDLE FileHandle; - DWORD LoadedSize; - HANDLE FileMap; - ULONG_PTR FileMapVA; - if(StaticFileLoadW(StringUtils::Utf8ToUtf16(modpath).c_str(), UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA)) - { - ULONGLONG offset = ConvertVAtoFileOffsetEx(FileMapVA, LoadedSize, 0, va - ModBaseFromAddr(va), true, false); - StaticFileUnloadW(StringUtils::Utf8ToUtf16(modpath).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA); - return (duint)offset; - } - } - return 0; +/** + @file value.cpp + + @brief Implements the value class. + */ + +#include "value.h" +#include "variable.h" +#include "debugger.h" +#include "console.h" +#include "memory.h" +#include "symbolinfo.h" +#include "module.h" +#include "label.h" +#include "expressionparser.h" + +static bool dosignedcalc = false; + +/** +\brief Returns whether we do signed or unsigned calculations. +\return true if we do signed calculations, false for unsigned calculationss. +*/ +bool valuesignedcalc() +{ + return dosignedcalc; +} + +/** +\brief Set whether we do signed or unsigned calculations. +\param a true for signed calculations, false for unsigned calculations. +*/ +void valuesetsignedcalc(bool a) +{ + dosignedcalc = a; +} + +/** +\brief Check if a string is a flag. +\param string The string to check. +\return true if the string is a flag, false otherwise. +*/ +static bool isflag(const char* string) +{ + if(scmp(string, "cf")) + return true; + if(scmp(string, "pf")) + return true; + if(scmp(string, "af")) + return true; + if(scmp(string, "zf")) + return true; + if(scmp(string, "sf")) + return true; + if(scmp(string, "tf")) + return true; + if(scmp(string, "if")) + return true; + if(scmp(string, "df")) + return true; + if(scmp(string, "of")) + return true; + if(scmp(string, "rf")) + return true; + if(scmp(string, "vm")) + return true; + if(scmp(string, "ac")) + return true; + if(scmp(string, "vif")) + return true; + if(scmp(string, "vip")) + return true; + if(scmp(string, "id")) + return true; + return false; +} + +/** +\brief Check if a string is a register. +\param string The string to check. +\return true if the string is a register, false otherwise. +*/ +static bool isregister(const char* string) +{ + if(scmp(string, "eax")) + return true; + if(scmp(string, "ebx")) + return true; + if(scmp(string, "ecx")) + return true; + if(scmp(string, "edx")) + return true; + if(scmp(string, "edi")) + return true; + if(scmp(string, "esi")) + return true; + if(scmp(string, "ebp")) + return true; + if(scmp(string, "esp")) + return true; + if(scmp(string, "eip")) + return true; + if(scmp(string, "eflags")) + return true; + + if(scmp(string, "ax")) + return true; + if(scmp(string, "bx")) + return true; + if(scmp(string, "cx")) + return true; + if(scmp(string, "dx")) + return true; + if(scmp(string, "si")) + return true; + if(scmp(string, "di")) + return true; + if(scmp(string, "bp")) + return true; + if(scmp(string, "sp")) + return true; + if(scmp(string, "ip")) + return true; + + if(scmp(string, "ah")) + return true; + if(scmp(string, "al")) + return true; + if(scmp(string, "bh")) + return true; + if(scmp(string, "bl")) + return true; + if(scmp(string, "ch")) + return true; + if(scmp(string, "cl")) + return true; + if(scmp(string, "dh")) + return true; + if(scmp(string, "dl")) + return true; + if(scmp(string, "sih")) + return true; + if(scmp(string, "sil")) + return true; + if(scmp(string, "dih")) + return true; + if(scmp(string, "dil")) + return true; + if(scmp(string, "bph")) + return true; + if(scmp(string, "bpl")) + return true; + if(scmp(string, "sph")) + return true; + if(scmp(string, "spl")) + return true; + if(scmp(string, "iph")) + return true; + if(scmp(string, "ipl")) + return true; + + if(scmp(string, "dr0")) + return true; + if(scmp(string, "dr1")) + return true; + if(scmp(string, "dr2")) + return true; + if(scmp(string, "dr3")) + return true; + if(scmp(string, "dr6") || scmp(string, "dr4")) + return true; + if(scmp(string, "dr7") || scmp(string, "dr5")) + return true; + + if(scmp(string, "cip")) + return true; + if(scmp(string, "csp")) + return true; + if(scmp(string, "cflags")) + return true; + + if(scmp(string, "gs")) + return true; + if(scmp(string, "fs")) + return true; + if(scmp(string, "es")) + return true; + if(scmp(string, "ds")) + return true; + if(scmp(string, "cs")) + return true; + if(scmp(string, "ss")) + return true; + +#ifndef _WIN64 + return false; +#endif // _WIN64 + if(scmp(string, "rax")) + return true; + if(scmp(string, "rbx")) + return true; + if(scmp(string, "rcx")) + return true; + if(scmp(string, "rdx")) + return true; + if(scmp(string, "rdi")) + return true; + if(scmp(string, "rsi")) + return true; + if(scmp(string, "rbp")) + return true; + if(scmp(string, "rsp")) + return true; + if(scmp(string, "rip")) + return true; + if(scmp(string, "rflags")) + return true; + if(scmp(string, "r8")) + return true; + if(scmp(string, "r9")) + return true; + if(scmp(string, "r10")) + return true; + if(scmp(string, "r11")) + return true; + if(scmp(string, "r12")) + return true; + if(scmp(string, "r13")) + return true; + if(scmp(string, "r14")) + return true; + if(scmp(string, "r15")) + return true; + if(scmp(string, "r8d")) + return true; + if(scmp(string, "r9d")) + return true; + if(scmp(string, "r10d")) + return true; + if(scmp(string, "r11d")) + return true; + if(scmp(string, "r12d")) + return true; + if(scmp(string, "r13d")) + return true; + if(scmp(string, "r14d")) + return true; + if(scmp(string, "r15d")) + return true; + if(scmp(string, "r8w")) + return true; + if(scmp(string, "r9w")) + return true; + if(scmp(string, "r10w")) + return true; + if(scmp(string, "r11w")) + return true; + if(scmp(string, "r12w")) + return true; + if(scmp(string, "r13w")) + return true; + if(scmp(string, "r14w")) + return true; + if(scmp(string, "r15w")) + return true; + if(scmp(string, "r8b")) + return true; + if(scmp(string, "r9b")) + return true; + if(scmp(string, "r10b")) + return true; + if(scmp(string, "r11b")) + return true; + if(scmp(string, "r12b")) + return true; + if(scmp(string, "r13b")) + return true; + if(scmp(string, "r14b")) + return true; + if(scmp(string, "r15b")) + return true; + return false; +} + +#define MXCSRFLAG_IE 0x1 +#define MXCSRFLAG_DE 0x2 +#define MXCSRFLAG_ZE 0x4 +#define MXCSRFLAG_OE 0x8 +#define MXCSRFLAG_UE 0x10 +#define MXCSRFLAG_PE 0x20 +#define MXCSRFLAG_DAZ 0x40 +#define MXCSRFLAG_IM 0x80 +#define MXCSRFLAG_DM 0x100 +#define MXCSRFLAG_ZM 0x200 +#define MXCSRFLAG_OM 0x400 +#define MXCSRFLAG_UM 0x800 +#define MXCSRFLAG_PM 0x1000 +#define MXCSRFLAG_FZ 0x8000 + +typedef struct +{ + char* name; + unsigned int flag; + +} FLAG_NAME_VALUE_TABLE_t; + +#define MXCSR_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, MXCSRFLAG_##flag_name } + +/** +\brief Gets the MXCSR flag AND value from a string. +\param string The flag name. +\return The value to AND the MXCSR value with to get the flag. 0 when not found. +*/ +static unsigned int getmxcsrflagfromstring(const char* string) +{ + static FLAG_NAME_VALUE_TABLE_t mxcsrnameflagtable[] = + { + MXCSR_NAME_FLAG_TABLE_ENTRY(IE), + MXCSR_NAME_FLAG_TABLE_ENTRY(DE), + MXCSR_NAME_FLAG_TABLE_ENTRY(ZE), + MXCSR_NAME_FLAG_TABLE_ENTRY(OE), + MXCSR_NAME_FLAG_TABLE_ENTRY(UE), + MXCSR_NAME_FLAG_TABLE_ENTRY(PE), + MXCSR_NAME_FLAG_TABLE_ENTRY(DAZ), + MXCSR_NAME_FLAG_TABLE_ENTRY(IM), + MXCSR_NAME_FLAG_TABLE_ENTRY(DM), + MXCSR_NAME_FLAG_TABLE_ENTRY(ZM), + MXCSR_NAME_FLAG_TABLE_ENTRY(OM), + MXCSR_NAME_FLAG_TABLE_ENTRY(UM), + MXCSR_NAME_FLAG_TABLE_ENTRY(PM), + MXCSR_NAME_FLAG_TABLE_ENTRY(FZ) + }; + + for(int i = 0; i < (sizeof(mxcsrnameflagtable) / sizeof(*mxcsrnameflagtable)); i++) + { + if(scmp(string, mxcsrnameflagtable[i].name)) + return mxcsrnameflagtable[i].flag; + } + + return 0; +} + +/** +\brief Gets the MXCSR flag from a string and a flags value. +\param mxcsrflags The flags value to get the flag from. +\param string The string with the flag name. +\return true if the flag is 1, false if the flag is 0. +*/ +bool valmxcsrflagfromstring(duint mxcsrflags, const char* string) +{ + unsigned int flag = getmxcsrflagfromstring(string); + if(flag == 0) + return false; + + return (bool)((int)(mxcsrflags & flag) != 0); +} + +#define x87STATUSWORD_FLAG_I 0x1 +#define x87STATUSWORD_FLAG_D 0x2 +#define x87STATUSWORD_FLAG_Z 0x4 +#define x87STATUSWORD_FLAG_O 0x8 +#define x87STATUSWORD_FLAG_U 0x10 +#define x87STATUSWORD_FLAG_P 0x20 +#define x87STATUSWORD_FLAG_SF 0x40 +#define x87STATUSWORD_FLAG_IR 0x80 +#define x87STATUSWORD_FLAG_C0 0x100 +#define x87STATUSWORD_FLAG_C1 0x200 +#define x87STATUSWORD_FLAG_C2 0x400 +#define x87STATUSWORD_FLAG_C3 0x4000 +#define x87STATUSWORD_FLAG_B 0x8000 + +#define X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, x87STATUSWORD_FLAG_##flag_name } + +/** +\brief Gets the x87 status word AND value from a string. +\param string The status word name. +\return The value to AND the status word with to get the flag. 0 when not found. +*/ +static unsigned int getx87statuswordflagfromstring(const char* string) +{ + static FLAG_NAME_VALUE_TABLE_t statuswordflagtable[] = + { + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(I), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(D), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(Z), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(O), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(U), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(P), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(SF), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(IR), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C0), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C1), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C2), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C3), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(B) + }; + + for(int i = 0; i < (sizeof(statuswordflagtable) / sizeof(*statuswordflagtable)); i++) + { + if(scmp(string, statuswordflagtable[i].name)) + return statuswordflagtable[i].flag; + } + + return 0; +} + +/** +\brief Gets an x87 status flag from a string. +\param statusword The status word value. +\param string The flag name. +\return true if the flag is 1, false if the flag is 0. +*/ +bool valx87statuswordflagfromstring(duint statusword, const char* string) +{ + unsigned int flag = getx87statuswordflagfromstring(string); + if(flag == 0) + return false; + + return (bool)((int)(statusword & flag) != 0); +} + +#define x87CONTROLWORD_FLAG_IM 0x1 +#define x87CONTROLWORD_FLAG_DM 0x2 +#define x87CONTROLWORD_FLAG_ZM 0x4 +#define x87CONTROLWORD_FLAG_OM 0x8 +#define x87CONTROLWORD_FLAG_UM 0x10 +#define x87CONTROLWORD_FLAG_PM 0x20 +#define x87CONTROLWORD_FLAG_IEM 0x80 +#define x87CONTROLWORD_FLAG_IC 0x1000 + +#define X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, x87CONTROLWORD_FLAG_##flag_name } + +/** +\brief Gets the x87 control word flag AND value from a string. +\param string The name of the control word. +\return The value to AND the control word with to get the flag. 0 when not found. +*/ +static unsigned int getx87controlwordflagfromstring(const char* string) +{ + static FLAG_NAME_VALUE_TABLE_t controlwordflagtable[] = + { + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(DM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(ZM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(OM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(UM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(PM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IEM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IC) + }; + + for(int i = 0; i < (sizeof(controlwordflagtable) / sizeof(*controlwordflagtable)); i++) + { + if(scmp(string, controlwordflagtable[i].name)) + return controlwordflagtable[i].flag; + } + + return 0; +} + +/** +\brief Get an x87 control word flag from a string. +\param controlword The control word to get the flag from. +\param string The flag name. +\return true if the flag is 1, false when the flag is 0. +*/ +bool valx87controlwordflagfromstring(duint controlword, const char* string) +{ + unsigned int flag = getx87controlwordflagfromstring(string); + + if(flag == 0) + return false; + + return (bool)((int)(controlword & flag) != 0); +} + +/** +\brief Gets the MXCSR field from a string. +\param mxcsrflags The mxcsrflags to get the field from. +\param string The name of the field (should be "RC"). +\return The MXCSR field word. +*/ +unsigned short valmxcsrfieldfromstring(duint mxcsrflags, const char* string) +{ + if(scmp(string, "RC")) + return ((mxcsrflags & 0x6000) >> 13); + + return 0; +} + +/** +\brief Gets the x87 status word field from a string. +\param statusword The status word to get the field from. +\param string The name of the field (should be "TOP"). +\return The x87 status word field. +*/ +unsigned short valx87statuswordfieldfromstring(duint statusword, const char* string) +{ + if(scmp(string, "TOP")) + return ((statusword & 0x3800) >> 11); + + return 0; +} + +/** +\brief Gets the x87 control word field from a string. +\param controlword The control word to get the field from. +\param string The name of the field. +\return The x87 control word field. +*/ +unsigned short valx87controlwordfieldfromstring(duint controlword, const char* string) +{ + if(scmp(string, "PC")) + return ((controlword & 0x300) >> 8); + if(scmp(string, "RC")) + return ((controlword & 0xC00) >> 10); + + return 0; +} + +/** +\brief Gets a flag from a string. +\param eflags The eflags value to get the flag from. +\param string The name of the flag. +\return true if the flag equals to 1, false if the flag is 0 or not found. +*/ +bool valflagfromstring(duint eflags, const char* string) +{ + if(scmp(string, "cf")) + return (bool)((int)(eflags & 0x1) != 0); + if(scmp(string, "pf")) + return (bool)((int)(eflags & 0x4) != 0); + if(scmp(string, "af")) + return (bool)((int)(eflags & 0x10) != 0); + if(scmp(string, "zf")) + return (bool)((int)(eflags & 0x40) != 0); + if(scmp(string, "sf")) + return (bool)((int)(eflags & 0x80) != 0); + if(scmp(string, "tf")) + return (bool)((int)(eflags & 0x100) != 0); + if(scmp(string, "if")) + return (bool)((int)(eflags & 0x200) != 0); + if(scmp(string, "df")) + return (bool)((int)(eflags & 0x400) != 0); + if(scmp(string, "of")) + return (bool)((int)(eflags & 0x800) != 0); + if(scmp(string, "rf")) + return (bool)((int)(eflags & 0x10000) != 0); + if(scmp(string, "vm")) + return (bool)((int)(eflags & 0x20000) != 0); + if(scmp(string, "ac")) + return (bool)((int)(eflags & 0x40000) != 0); + if(scmp(string, "vif")) + return (bool)((int)(eflags & 0x80000) != 0); + if(scmp(string, "vip")) + return (bool)((int)(eflags & 0x100000) != 0); + if(scmp(string, "id")) + return (bool)((int)(eflags & 0x200000) != 0); + return false; +} + +/** +\brief Sets a flag value. +\param string The name of the flag. +\param set The value of the flag. +\return true if the flag was successfully set, false otherwise. +*/ +bool setflag(const char* string, bool set) +{ + duint eflags = GetContextDataEx(hActiveThread, UE_CFLAGS); + duint xorval = 0; + duint flag = 0; + if(scmp(string, "cf")) + flag = 0x1; + else if(scmp(string, "pf")) + flag = 0x4; + else if(scmp(string, "af")) + flag = 0x10; + else if(scmp(string, "zf")) + flag = 0x40; + else if(scmp(string, "sf")) + flag = 0x80; + else if(scmp(string, "tf")) + flag = 0x100; + else if(scmp(string, "if")) + flag = 0x200; + else if(scmp(string, "df")) + flag = 0x400; + else if(scmp(string, "of")) + flag = 0x800; + else if(scmp(string, "rf")) + flag = 0x10000; + else if(scmp(string, "vm")) + flag = 0x20000; + else if(scmp(string, "ac")) + flag = 0x40000; + else if(scmp(string, "vif")) + flag = 0x80000; + else if(scmp(string, "vip")) + flag = 0x100000; + else if(scmp(string, "id")) + flag = 0x200000; + if(eflags & flag && !set) + xorval = flag; + else if(set) + xorval = flag; + return SetContextDataEx(hActiveThread, UE_CFLAGS, eflags ^ xorval); +} + +/** +\brief Gets a register from a string. +\param [out] size This function can store the register size in bytes in this parameter. Can be null, in that case it will be ignored. +\param string The name of the register to get. +\return The register value. +*/ +static duint getregister(int* size, const char* string) +{ + if(size) + *size = 4; + if(scmp(string, "eax")) + { + return GetContextDataEx(hActiveThread, UE_EAX); + } + if(scmp(string, "ebx")) + { + return GetContextDataEx(hActiveThread, UE_EBX); + } + if(scmp(string, "ecx")) + { + return GetContextDataEx(hActiveThread, UE_ECX); + } + if(scmp(string, "edx")) + { + return GetContextDataEx(hActiveThread, UE_EDX); + } + if(scmp(string, "edi")) + { + return GetContextDataEx(hActiveThread, UE_EDI); + } + if(scmp(string, "esi")) + { + return GetContextDataEx(hActiveThread, UE_ESI); + } + if(scmp(string, "ebp")) + { + return GetContextDataEx(hActiveThread, UE_EBP); + } + if(scmp(string, "esp")) + { + return GetContextDataEx(hActiveThread, UE_ESP); + } + if(scmp(string, "eip")) + { + return GetContextDataEx(hActiveThread, UE_EIP); + } + if(scmp(string, "eflags")) + { + return GetContextDataEx(hActiveThread, UE_EFLAGS); + } + + if(scmp(string, "gs")) + { + return GetContextDataEx(hActiveThread, UE_SEG_GS); + } + if(scmp(string, "fs")) + { + return GetContextDataEx(hActiveThread, UE_SEG_FS); + } + if(scmp(string, "es")) + { + return GetContextDataEx(hActiveThread, UE_SEG_ES); + } + if(scmp(string, "ds")) + { + return GetContextDataEx(hActiveThread, UE_SEG_DS); + } + if(scmp(string, "cs")) + { + return GetContextDataEx(hActiveThread, UE_SEG_CS); + } + if(scmp(string, "ss")) + { + return GetContextDataEx(hActiveThread, UE_SEG_SS); + } + + if(size) + *size = 2; + if(scmp(string, "ax")) + { + duint val = GetContextDataEx(hActiveThread, UE_EAX); + return val & 0xFFFF; + } + if(scmp(string, "bx")) + { + duint val = GetContextDataEx(hActiveThread, UE_EBX); + return val & 0xFFFF; + } + if(scmp(string, "cx")) + { + duint val = GetContextDataEx(hActiveThread, UE_ECX); + return val & 0xFFFF; + } + if(scmp(string, "dx")) + { + duint val = GetContextDataEx(hActiveThread, UE_EDX); + return val & 0xFFFF; + } + if(scmp(string, "si")) + { + duint val = GetContextDataEx(hActiveThread, UE_ESI); + return val & 0xFFFF; + } + if(scmp(string, "di")) + { + duint val = GetContextDataEx(hActiveThread, UE_EDI); + return val & 0xFFFF; + } + if(scmp(string, "bp")) + { + duint val = GetContextDataEx(hActiveThread, UE_EBP); + return val & 0xFFFF; + } + if(scmp(string, "sp")) + { + duint val = GetContextDataEx(hActiveThread, UE_ESP); + return val & 0xFFFF; + } + if(scmp(string, "ip")) + { + duint val = GetContextDataEx(hActiveThread, UE_EIP); + return val & 0xFFFF; + } + + if(size) + *size = 1; + if(scmp(string, "ah")) + { + duint val = GetContextDataEx(hActiveThread, UE_EAX); + return (val >> 8) & 0xFF; + } + if(scmp(string, "al")) + { + duint val = GetContextDataEx(hActiveThread, UE_EAX); + return val & 0xFF; + } + if(scmp(string, "bh")) + { + duint val = GetContextDataEx(hActiveThread, UE_EBX); + return (val >> 8) & 0xFF; + } + if(scmp(string, "bl")) + { + duint val = GetContextDataEx(hActiveThread, UE_EBX); + return val & 0xFF; + } + if(scmp(string, "ch")) + { + duint val = GetContextDataEx(hActiveThread, UE_ECX); + return (val >> 8) & 0xFF; + } + if(scmp(string, "cl")) + { + duint val = GetContextDataEx(hActiveThread, UE_ECX); + return val & 0xFF; + } + if(scmp(string, "dh")) + { + duint val = GetContextDataEx(hActiveThread, UE_EDX); + return (val >> 8) & 0xFF; + } + if(scmp(string, "dl")) + { + duint val = GetContextDataEx(hActiveThread, UE_EDX); + return val & 0xFF; + } + if(scmp(string, "sih")) + { + duint val = GetContextDataEx(hActiveThread, UE_ESI); + return (val >> 8) & 0xFF; + } + if(scmp(string, "sil")) + { + duint val = GetContextDataEx(hActiveThread, UE_ESI); + return val & 0xFF; + } + if(scmp(string, "dih")) + { + duint val = GetContextDataEx(hActiveThread, UE_EDI); + return (val >> 8) & 0xFF; + } + if(scmp(string, "dil")) + { + duint val = GetContextDataEx(hActiveThread, UE_EDI); + return val & 0xFF; + } + if(scmp(string, "bph")) + { + duint val = GetContextDataEx(hActiveThread, UE_EBP); + return (val >> 8) & 0xFF; + } + if(scmp(string, "bpl")) + { + duint val = GetContextDataEx(hActiveThread, UE_EBP); + return val & 0xFF; + } + if(scmp(string, "sph")) + { + duint val = GetContextDataEx(hActiveThread, UE_ESP); + return (val >> 8) & 0xFF; + } + if(scmp(string, "spl")) + { + duint val = GetContextDataEx(hActiveThread, UE_ESP); + return val & 0xFF; + } + if(scmp(string, "iph")) + { + duint val = GetContextDataEx(hActiveThread, UE_EIP); + return (val >> 8) & 0xFF; + } + if(scmp(string, "ipl")) + { + duint val = GetContextDataEx(hActiveThread, UE_EIP); + return val & 0xFF; + } + + if(size) + *size = sizeof(duint); + if(scmp(string, "dr0")) + { + return GetContextDataEx(hActiveThread, UE_DR0); + } + if(scmp(string, "dr1")) + { + return GetContextDataEx(hActiveThread, UE_DR1); + } + if(scmp(string, "dr2")) + { + return GetContextDataEx(hActiveThread, UE_DR2); + } + if(scmp(string, "dr3")) + { + return GetContextDataEx(hActiveThread, UE_DR3); + } + if(scmp(string, "dr6") || scmp(string, "dr4")) + { + return GetContextDataEx(hActiveThread, UE_DR6); + } + if(scmp(string, "dr7") || scmp(string, "dr5")) + { + return GetContextDataEx(hActiveThread, UE_DR7); + } + + if(scmp(string, "cip")) + { + return GetContextDataEx(hActiveThread, UE_CIP); + } + if(scmp(string, "csp")) + { + return GetContextDataEx(hActiveThread, UE_CSP); + } + if(scmp(string, "cflags")) + { + return GetContextDataEx(hActiveThread, UE_CFLAGS); + } + +#ifdef _WIN64 + if(size) + *size = 8; + if(scmp(string, "rax")) + { + return GetContextDataEx(hActiveThread, UE_RAX); + } + if(scmp(string, "rbx")) + { + return GetContextDataEx(hActiveThread, UE_RBX); + } + if(scmp(string, "rcx")) + { + return GetContextDataEx(hActiveThread, UE_RCX); + } + if(scmp(string, "rdx")) + { + return GetContextDataEx(hActiveThread, UE_RDX); + } + if(scmp(string, "rdi")) + { + return GetContextDataEx(hActiveThread, UE_RDI); + } + if(scmp(string, "rsi")) + { + return GetContextDataEx(hActiveThread, UE_RSI); + } + if(scmp(string, "rbp")) + { + return GetContextDataEx(hActiveThread, UE_RBP); + } + if(scmp(string, "rsp")) + { + return GetContextDataEx(hActiveThread, UE_RSP); + } + if(scmp(string, "rip")) + { + return GetContextDataEx(hActiveThread, UE_RIP); + } + if(scmp(string, "rflags")) + { + return GetContextDataEx(hActiveThread, UE_RFLAGS); + } + if(scmp(string, "r8")) + { + return GetContextDataEx(hActiveThread, UE_R8); + } + if(scmp(string, "r9")) + { + return GetContextDataEx(hActiveThread, UE_R9); + } + if(scmp(string, "r10")) + { + return GetContextDataEx(hActiveThread, UE_R10); + } + if(scmp(string, "r11")) + { + return GetContextDataEx(hActiveThread, UE_R11); + } + if(scmp(string, "r12")) + { + return GetContextDataEx(hActiveThread, UE_R12); + } + if(scmp(string, "r13")) + { + return GetContextDataEx(hActiveThread, UE_R13); + } + if(scmp(string, "r14")) + { + return GetContextDataEx(hActiveThread, UE_R14); + } + if(scmp(string, "r15")) + { + return GetContextDataEx(hActiveThread, UE_R15); + } + + if(size) + *size = 4; + if(scmp(string, "r8d")) + { + return GetContextDataEx(hActiveThread, UE_R8) & 0xFFFFFFFF; + } + if(scmp(string, "r9d")) + { + return GetContextDataEx(hActiveThread, UE_R9) & 0xFFFFFFFF; + } + if(scmp(string, "r10d")) + { + return GetContextDataEx(hActiveThread, UE_R10) & 0xFFFFFFFF; + } + if(scmp(string, "r11d")) + { + return GetContextDataEx(hActiveThread, UE_R11) & 0xFFFFFFFF; + } + if(scmp(string, "r12d")) + { + return GetContextDataEx(hActiveThread, UE_R12) & 0xFFFFFFFF; + } + if(scmp(string, "r13d")) + { + return GetContextDataEx(hActiveThread, UE_R13) & 0xFFFFFFFF; + } + if(scmp(string, "r14d")) + { + return GetContextDataEx(hActiveThread, UE_R14) & 0xFFFFFFFF; + } + if(scmp(string, "r15d")) + { + return GetContextDataEx(hActiveThread, UE_R15) & 0xFFFFFFFF; + } + + if(size) + *size = 2; + if(scmp(string, "r8w")) + { + return GetContextDataEx(hActiveThread, UE_R8) & 0xFFFF; + } + if(scmp(string, "r9w")) + { + return GetContextDataEx(hActiveThread, UE_R9) & 0xFFFF; + } + if(scmp(string, "r10w")) + { + return GetContextDataEx(hActiveThread, UE_R10) & 0xFFFF; + } + if(scmp(string, "r11w")) + { + return GetContextDataEx(hActiveThread, UE_R11) & 0xFFFF; + } + if(scmp(string, "r12w")) + { + return GetContextDataEx(hActiveThread, UE_R12) & 0xFFFF; + } + if(scmp(string, "r13w")) + { + return GetContextDataEx(hActiveThread, UE_R13) & 0xFFFF; + } + if(scmp(string, "r14w")) + { + return GetContextDataEx(hActiveThread, UE_R14) & 0xFFFF; + } + if(scmp(string, "r15w")) + { + return GetContextDataEx(hActiveThread, UE_R15) & 0xFFFF; + } + + if(size) + *size = 1; + if(scmp(string, "r8b")) + { + return GetContextDataEx(hActiveThread, UE_R8) & 0xFF; + } + if(scmp(string, "r9b")) + { + return GetContextDataEx(hActiveThread, UE_R9) & 0xFF; + } + if(scmp(string, "r10b")) + { + return GetContextDataEx(hActiveThread, UE_R10) & 0xFF; + } + if(scmp(string, "r11b")) + { + return GetContextDataEx(hActiveThread, UE_R11) & 0xFF; + } + if(scmp(string, "r12b")) + { + return GetContextDataEx(hActiveThread, UE_R12) & 0xFF; + } + if(scmp(string, "r13b")) + { + return GetContextDataEx(hActiveThread, UE_R13) & 0xFF; + } + if(scmp(string, "r14b")) + { + return GetContextDataEx(hActiveThread, UE_R14) & 0xFF; + } + if(scmp(string, "r15b")) + { + return GetContextDataEx(hActiveThread, UE_R15) & 0xFF; + } +#endif //_WIN64 + + if(size) + *size = 0; + return 0; +} + +/** +\brief Sets a register value based on the register name. +\param string The name of the register to set. +\param value The new register value. +\return true if the register was set, false otherwise. +*/ +bool setregister(const char* string, duint value) +{ + if(scmp(string, "eax")) + return SetContextDataEx(hActiveThread, UE_EAX, value & 0xFFFFFFFF); + if(scmp(string, "ebx")) + return SetContextDataEx(hActiveThread, UE_EBX, value & 0xFFFFFFFF); + if(scmp(string, "ecx")) + return SetContextDataEx(hActiveThread, UE_ECX, value & 0xFFFFFFFF); + if(scmp(string, "edx")) + return SetContextDataEx(hActiveThread, UE_EDX, value & 0xFFFFFFFF); + if(scmp(string, "edi")) + return SetContextDataEx(hActiveThread, UE_EDI, value & 0xFFFFFFFF); + if(scmp(string, "esi")) + return SetContextDataEx(hActiveThread, UE_ESI, value & 0xFFFFFFFF); + if(scmp(string, "ebp")) + return SetContextDataEx(hActiveThread, UE_EBP, value & 0xFFFFFFFF); + if(scmp(string, "esp")) + return SetContextDataEx(hActiveThread, UE_ESP, value & 0xFFFFFFFF); + if(scmp(string, "eip")) + return SetContextDataEx(hActiveThread, UE_EIP, value & 0xFFFFFFFF); + if(scmp(string, "eflags")) + return SetContextDataEx(hActiveThread, UE_EFLAGS, value & 0xFFFFFFFF); + + if(scmp(string, "gs")) + return SetContextDataEx(hActiveThread, UE_SEG_GS, value & 0xFFFF); + if(scmp(string, "fs")) + return SetContextDataEx(hActiveThread, UE_SEG_FS, value & 0xFFFF); + if(scmp(string, "es")) + return SetContextDataEx(hActiveThread, UE_SEG_ES, value & 0xFFFF); + if(scmp(string, "ds")) + return SetContextDataEx(hActiveThread, UE_SEG_DS, value & 0xFFFF); + if(scmp(string, "cs")) + return SetContextDataEx(hActiveThread, UE_SEG_CS, value & 0xFFFF); + if(scmp(string, "ss")) + return SetContextDataEx(hActiveThread, UE_SEG_SS, value & 0xFFFF); + + if(scmp(string, "ax")) + return SetContextDataEx(hActiveThread, UE_EAX, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_EAX) & 0xFFFF0000)); + if(scmp(string, "bx")) + return SetContextDataEx(hActiveThread, UE_EBX, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_EBX) & 0xFFFF0000)); + if(scmp(string, "cx")) + return SetContextDataEx(hActiveThread, UE_ECX, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_ECX) & 0xFFFF0000)); + if(scmp(string, "dx")) + return SetContextDataEx(hActiveThread, UE_EDX, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_EDX) & 0xFFFF0000)); + if(scmp(string, "si")) + return SetContextDataEx(hActiveThread, UE_ESI, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_ESI) & 0xFFFF0000)); + if(scmp(string, "di")) + return SetContextDataEx(hActiveThread, UE_EDI, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_EDI) & 0xFFFF0000)); + if(scmp(string, "bp")) + return SetContextDataEx(hActiveThread, UE_EBP, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_EBP) & 0xFFFF0000)); + if(scmp(string, "sp")) + return SetContextDataEx(hActiveThread, UE_ESP, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_ESP) & 0xFFFF0000)); + if(scmp(string, "ip")) + return SetContextDataEx(hActiveThread, UE_EIP, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_EIP) & 0xFFFF0000)); + + if(scmp(string, "ah")) + return SetContextDataEx(hActiveThread, UE_EAX, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_EAX) & 0xFFFF00FF)); + if(scmp(string, "al")) + return SetContextDataEx(hActiveThread, UE_EAX, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_EAX) & 0xFFFFFF00)); + if(scmp(string, "bh")) + return SetContextDataEx(hActiveThread, UE_EBX, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_EBX) & 0xFFFF00FF)); + if(scmp(string, "bl")) + return SetContextDataEx(hActiveThread, UE_EBX, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_EBX) & 0xFFFFFF00)); + if(scmp(string, "ch")) + return SetContextDataEx(hActiveThread, UE_ECX, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_ECX) & 0xFFFF00FF)); + if(scmp(string, "cl")) + return SetContextDataEx(hActiveThread, UE_ECX, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_ECX) & 0xFFFFFF00)); + if(scmp(string, "dh")) + return SetContextDataEx(hActiveThread, UE_EDX, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_EDX) & 0xFFFF00FF)); + if(scmp(string, "dl")) + return SetContextDataEx(hActiveThread, UE_EDX, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_EDX) & 0xFFFFFF00)); + if(scmp(string, "sih")) + return SetContextDataEx(hActiveThread, UE_ESI, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_ESI) & 0xFFFF00FF)); + if(scmp(string, "sil")) + return SetContextDataEx(hActiveThread, UE_ESI, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_ESI) & 0xFFFFFF00)); + if(scmp(string, "dih")) + return SetContextDataEx(hActiveThread, UE_EDI, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_EDI) & 0xFFFF00FF)); + if(scmp(string, "dil")) + return SetContextDataEx(hActiveThread, UE_EDI, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_EDI) & 0xFFFFFF00)); + if(scmp(string, "bph")) + return SetContextDataEx(hActiveThread, UE_EBP, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_EBP) & 0xFFFF00FF)); + if(scmp(string, "bpl")) + return SetContextDataEx(hActiveThread, UE_EBP, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_EBP) & 0xFFFFFF00)); + if(scmp(string, "sph")) + return SetContextDataEx(hActiveThread, UE_ESP, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_ESP) & 0xFFFF00FF)); + if(scmp(string, "spl")) + return SetContextDataEx(hActiveThread, UE_ESP, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_ESP) & 0xFFFFFF00)); + if(scmp(string, "iph")) + return SetContextDataEx(hActiveThread, UE_EIP, ((value & 0xFF) << 8) | (GetContextDataEx(hActiveThread, UE_EIP) & 0xFFFF00FF)); + if(scmp(string, "ipl")) + return SetContextDataEx(hActiveThread, UE_EIP, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_EIP) & 0xFFFFFF00)); + + if(scmp(string, "dr0")) + return SetContextDataEx(hActiveThread, UE_DR0, value); + if(scmp(string, "dr1")) + return SetContextDataEx(hActiveThread, UE_DR1, value); + if(scmp(string, "dr2")) + return SetContextDataEx(hActiveThread, UE_DR2, value); + if(scmp(string, "dr3")) + return SetContextDataEx(hActiveThread, UE_DR3, value); + if(scmp(string, "dr6") || scmp(string, "dr4")) + return SetContextDataEx(hActiveThread, UE_DR6, value); + if(scmp(string, "dr7") || scmp(string, "dr5")) + return SetContextDataEx(hActiveThread, UE_DR7, value); + + if(scmp(string, "cip")) + return SetContextDataEx(hActiveThread, UE_CIP, value); + if(scmp(string, "csp")) + return SetContextDataEx(hActiveThread, UE_CSP, value); + if(scmp(string, "cflags")) + return SetContextDataEx(hActiveThread, UE_CFLAGS, value); + +#ifdef _WIN64 + if(scmp(string, "rax")) + return SetContextDataEx(hActiveThread, UE_RAX, value); + if(scmp(string, "rbx")) + return SetContextDataEx(hActiveThread, UE_RBX, value); + if(scmp(string, "rcx")) + return SetContextDataEx(hActiveThread, UE_RCX, value); + if(scmp(string, "rdx")) + return SetContextDataEx(hActiveThread, UE_RDX, value); + if(scmp(string, "rdi")) + return SetContextDataEx(hActiveThread, UE_RDI, value); + if(scmp(string, "rsi")) + return SetContextDataEx(hActiveThread, UE_RSI, value); + if(scmp(string, "rbp")) + return SetContextDataEx(hActiveThread, UE_RBP, value); + if(scmp(string, "rsp")) + return SetContextDataEx(hActiveThread, UE_RSP, value); + if(scmp(string, "rip")) + return SetContextDataEx(hActiveThread, UE_RIP, value); + if(scmp(string, "rflags")) + return SetContextDataEx(hActiveThread, UE_RFLAGS, value); + if(scmp(string, "r8")) + return SetContextDataEx(hActiveThread, UE_R8, value); + if(scmp(string, "r9")) + return SetContextDataEx(hActiveThread, UE_R9, value); + if(scmp(string, "r10")) + return SetContextDataEx(hActiveThread, UE_R10, value); + if(scmp(string, "r11")) + return SetContextDataEx(hActiveThread, UE_R11, value); + if(scmp(string, "r12")) + return SetContextDataEx(hActiveThread, UE_R12, value); + if(scmp(string, "r13")) + return SetContextDataEx(hActiveThread, UE_R13, value); + if(scmp(string, "r14")) + return SetContextDataEx(hActiveThread, UE_R14, value); + if(scmp(string, "r15")) + return SetContextDataEx(hActiveThread, UE_R15, value); + + if(scmp(string, "r8d")) + return SetContextDataEx(hActiveThread, UE_R8, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R8) & 0xFFFFFFFF00000000)); + if(scmp(string, "r9d")) + return SetContextDataEx(hActiveThread, UE_R9, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R9) & 0xFFFFFFFF00000000)); + if(scmp(string, "r10d")) + return SetContextDataEx(hActiveThread, UE_R10, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R10) & 0xFFFFFFFF00000000)); + if(scmp(string, "r11d")) + return SetContextDataEx(hActiveThread, UE_R11, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R11) & 0xFFFFFFFF00000000)); + if(scmp(string, "r12d")) + return SetContextDataEx(hActiveThread, UE_R12, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R12) & 0xFFFFFFFF00000000)); + if(scmp(string, "r13d")) + return SetContextDataEx(hActiveThread, UE_R13, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R13) & 0xFFFFFFFF00000000)); + if(scmp(string, "r14d")) + return SetContextDataEx(hActiveThread, UE_R14, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R14) & 0xFFFFFFFF00000000)); + if(scmp(string, "r15d")) + return SetContextDataEx(hActiveThread, UE_R15, (value & 0xFFFFFFFF) | (GetContextDataEx(hActiveThread, UE_R15) & 0xFFFFFFFF00000000)); + + if(scmp(string, "r8w")) + return SetContextDataEx(hActiveThread, UE_R8, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R8) & 0xFFFFFFFFFFFF0000)); + if(scmp(string, "r9w")) + return SetContextDataEx(hActiveThread, UE_R9, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R9) & 0xFFFFFFFFFFFF0000)); + if(scmp(string, "r10w")) + return SetContextDataEx(hActiveThread, UE_R10, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R10) & 0xFFFFFFFFFFFF0000)); + if(scmp(string, "r11w")) + return SetContextDataEx(hActiveThread, UE_R11, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R11) & 0xFFFFFFFFFFFF0000)); + if(scmp(string, "r12w")) + return SetContextDataEx(hActiveThread, UE_R12, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R12) & 0xFFFFFFFFFFFF0000)); + if(scmp(string, "r13w")) + return SetContextDataEx(hActiveThread, UE_R13, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R13) & 0xFFFFFFFFFFFF0000)); + if(scmp(string, "r14w")) + return SetContextDataEx(hActiveThread, UE_R14, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R14) & 0xFFFFFFFFFFFF0000)); + if(scmp(string, "r15w")) + return SetContextDataEx(hActiveThread, UE_R15, (value & 0xFFFF) | (GetContextDataEx(hActiveThread, UE_R15) & 0xFFFFFFFFFFFF0000)); + if(scmp(string, "r8b")) + return SetContextDataEx(hActiveThread, UE_R8, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R8) & 0xFFFFFFFFFFFFFF00)); + if(scmp(string, "r9b")) + return SetContextDataEx(hActiveThread, UE_R9, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R9) & 0xFFFFFFFFFFFFFF00)); + if(scmp(string, "r10b")) + return SetContextDataEx(hActiveThread, UE_R10, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R10) & 0xFFFFFFFFFFFFFF00)); + if(scmp(string, "r11b")) + return SetContextDataEx(hActiveThread, UE_R11, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R11) & 0xFFFFFFFFFFFFFF00)); + if(scmp(string, "r12b")) + return SetContextDataEx(hActiveThread, UE_R12, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R12) & 0xFFFFFFFFFFFFFF00)); + if(scmp(string, "r13b")) + return SetContextDataEx(hActiveThread, UE_R13, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R13) & 0xFFFFFFFFFFFFFF00)); + if(scmp(string, "r14b")) + return SetContextDataEx(hActiveThread, UE_R14, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R14) & 0xFFFFFFFFFFFFFF00)); + if(scmp(string, "r15b")) + return SetContextDataEx(hActiveThread, UE_R15, (value & 0xFF) | (GetContextDataEx(hActiveThread, UE_R15) & 0xFFFFFFFFFFFFFF00)); +#endif // _WIN64 + + return false; +} + +/** +\brief Gets the address of an API from a name. +\param name The name of the API, see the command help for more information about valid constructions. +\param [out] value The address of the retrieved API. Cannot be null. +\param [out] value_size This function sets this value to the size of the address, sizeof(duint). +\param printall true to print all possible API values to the console. +\param silent true to have no console output. If true, the \p printall parameter is ignored. +\param [out] hexonly If set to true, the values should be printed in hex only. Usually this function sets it to true. +\return true if the API was found and a value retrieved, false otherwise. +*/ +bool valapifromstring(const char* name, duint* value, int* value_size, bool printall, bool silent, bool* hexonly) +{ + if(!value || !DbgIsDebugging()) + return false; + //explicit API handling + const char* apiname = strchr(name, ':'); //the ':' character cannot be in a path: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#naming_conventions + bool noexports = false; + if(!apiname) //not found + { + apiname = strrchr(name, '.'); //kernel32.GetProcAddress support + if(!apiname) //not found + { + apiname = strchr(name, '?'); //the '?' character cannot be in a path either + noexports = true; + } + } + if(apiname) + { + char modname[MAX_MODULE_SIZE] = ""; + if(name == apiname) //:[expression] <= currently selected module + { + SELECTIONDATA seldata; + memset(&seldata, 0, sizeof(seldata)); + GuiSelectionGet(GUI_DISASSEMBLY, &seldata); + if(!ModNameFromAddr(seldata.start, modname, true)) + return false; + } + else + { + strcpy_s(modname, name); + modname[apiname - name] = 0; + } + apiname++; + if(!strlen(apiname)) + return false; + duint modbase = ModBaseFromName(modname); + wchar_t szModName[MAX_PATH] = L""; + if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbase, szModName, MAX_PATH)) + { + if(!silent) + dprintf("could not get filename of module " fhex "\n", modbase); + } + else + { + HMODULE mod = LoadLibraryExW(szModName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); + if(!mod) + { + if(!silent) + dprintf("unable to load library %s\n", szModName); + } + else + { + duint addr = noexports ? 0 : (duint)GetProcAddress(mod, apiname); + if(addr) //found exported function + addr = modbase + (addr - (duint)mod); //correct for loaded base + else //not found + { + if(scmp(apiname, "base") || scmp(apiname, "imagebase") || scmp(apiname, "header")) //get loaded base + addr = modbase; + else if(scmp(apiname, "entrypoint") || scmp(apiname, "entry") || scmp(apiname, "oep") || scmp(apiname, "ep")) //get entry point + addr = modbase + GetPE32DataW(szModName, 0, UE_OEP); + else if(*apiname == '$') //RVA + { + duint rva; + if(valfromstring(apiname + 1, &rva)) + addr = modbase + rva; + } + else if(*apiname == '#') //File Offset + { + duint offset; + if(valfromstring(apiname + 1, &offset)) + addr = valfileoffsettova(modname, offset); + } + else + { + if(noexports) //get the exported functions with the '?' delimiter + { + addr = (duint)GetProcAddress(mod, apiname); + if(addr) //found exported function + addr = modbase + (addr - (duint)mod); //correct for loaded base + } + else + { + duint ordinal; + if(valfromstring(apiname, &ordinal)) + { + addr = (duint)GetProcAddress(mod, (LPCSTR)(ordinal & 0xFFFF)); + if(addr) //found exported function + addr = modbase + (addr - (duint)mod); //correct for loaded base + else if(!ordinal) //support for getting the image base using :0 + addr = modbase; + } + } + } + } + FreeLibrary(mod); + if(addr) //found! + { + if(value_size) + *value_size = sizeof(duint); + if(hexonly) + *hexonly = true; + *value = addr; + return true; + } + } + } + return false; + } + int found = 0; + int kernel32 = -1; + DWORD cbNeeded = 0; + Memory addrfound; + if(EnumProcessModules(fdProcessInfo->hProcess, 0, 0, &cbNeeded)) + { + addrfound.realloc(cbNeeded * sizeof(duint), "valapifromstring:addrfound"); + Memory hMods(cbNeeded * sizeof(HMODULE), "valapifromstring:hMods"); + if(EnumProcessModules(fdProcessInfo->hProcess, hMods(), cbNeeded, &cbNeeded)) + { + for(unsigned int i = 0; i < cbNeeded / sizeof(HMODULE); i++) + { + wchar_t szModuleName[MAX_PATH] = L""; + if(GetModuleFileNameExW(fdProcessInfo->hProcess, hMods()[i], szModuleName, MAX_PATH)) + { + wchar_t* szBaseName = wcsrchr(szModuleName, L'\\'); + if(szBaseName) + { + szBaseName++; + HMODULE hModule = LoadLibraryExW(szModuleName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); + if(hModule) + { + ULONG_PTR funcAddress = (ULONG_PTR)GetProcAddress(hModule, name); + if(funcAddress) + { + if(!_wcsicmp(szBaseName, L"kernel32.dll")) + kernel32 = found; + duint rva = funcAddress - (duint)hModule; + addrfound()[found] = (duint)hMods()[i] + rva; + found++; + } + FreeLibrary(hModule); + } + } + } + } + } + } + if(!found) + return false; + if(value_size) + *value_size = sizeof(duint); + if(hexonly) + *hexonly = true; + if(kernel32 != -1) //prioritize kernel32 exports + { + *value = addrfound()[kernel32]; + if(!printall || silent) + return true; + for(int i = 0; i < found; i++) + if(i != kernel32) + dprintf(fhex"\n", addrfound()[i]); + } + else + { + *value = *addrfound(); + if(!printall || silent) + return true; + for(int i = 1; i < found; i++) + dprintf(fhex"\n", addrfound()[i]); + } + return true; +} + +/** +\brief Check if a string is a valid decimal number. This function also accepts "-" or "." as prefix. +\param string The string to check. +\return true if the string is a valid decimal number. +*/ +static bool isdecnumber(const char* string) +{ + if(*string != '.' || !string[1]) //dec indicator/no number + return false; + int decAdd = 1; + if(string[1] == '-') //minus + { + if(!string[2]) //no number + return false; + decAdd++; + } + int len = (int)strlen(string + decAdd); + for(int i = 0; i < len; i++) + if(!isdigit(string[i + decAdd])) + return false; + return true; +} + +/** +\brief Check if a string is a valid hexadecimal number. This function also accepts "0x" or "x" as prefix. +\param string The string to check. +\return true if the string is a valid hexadecimal number. +*/ +static bool ishexnumber(const char* string) +{ + int add = 0; + if(*string == '0' && string[1] == 'x') //0x prefix + add = 2; + else if(*string == 'x') //hex indicator + add = 1; + if(!string[add]) //only an indicator, no number + return false; + int len = (int)strlen(string + add); + for(int i = 0; i < len; i++) + if(!isxdigit(string[i + add])) //all must be hex digits + return false; + return true; +} + +/** +\brief Gets a value from a string. This function can parse expressions, memory locations, registers, flags, API names, labels, symbols and variables. +\param string The string to parse. +\param [out] value The value of the expression. This value cannot be null. +\param silent true to not output anything to the console. +\param baseonly true to skip parsing API names, labels, symbols and variables (basic expressions only). +\param [out] value_size This function can output the value size parsed (for example memory location size or register size). Can be null. +\param [out] isvar This function can output if the expression is variable (for example memory locations, registers or variables are variable). Can be null. +\param [out] hexonly This function can output if the output value should only be printed as hexadecimal (for example addresses). Can be null. +\return true if the expression was parsed successful, false otherwise. +*/ +bool valfromstring_noexpr(const char* string, duint* value, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly) +{ + if(!value || !string) + return false; + if(!*string) + { + *value = 0; + return true; + } + else if(string[0] == '[' || (isdigit(string[0]) && string[1] == ':' && string[2] == '[')) //memory location + { + if(!DbgIsDebugging()) + { + if(!silent) + dputs("not debugging"); + *value = 0; + if(value_size) + *value_size = 0; + if(isvar) + *isvar = true; + return true; + } + int len = (int)strlen(string); + + String newstring; + bool foundStart = false; + for(int i = 0; i < len; i++) + { + if(string[i] == '[') + foundStart = true; + else if(string[i] == ']') + break; + else if(foundStart) + newstring += string[i]; + } + + int read_size = sizeof(duint); + int add = 1; + if(string[1] == ':') //n:[ (number of bytes to read) + { + add += 2; + int new_size = string[0] - '0'; + if(new_size < read_size) + read_size = new_size; + } + if(!valfromstring(newstring.c_str(), value, silent, baseonly)) + { + dprintf("noexpr failed on %s\n", newstring.c_str()); + return false; + } + duint addr = *value; + *value = 0; + if(!MemRead(addr, value, read_size)) + { + if(!silent) + dputs("failed to read memory"); + return false; + } + if(value_size) + *value_size = read_size; + if(isvar) + *isvar = true; + return true; + } + else if(isregister(string)) //register + { + if(!DbgIsDebugging()) + { + if(!silent) + dputs("not debugging!"); + *value = 0; + if(value_size) + *value_size = 0; + if(isvar) + *isvar = true; + return true; + } + *value = getregister(value_size, string); + if(isvar) + *isvar = true; + return true; + } + else if(*string == '!' && isflag(string + 1)) //flag + { + if(!DbgIsDebugging()) + { + if(!silent) + dputs("not debugging"); + *value = 0; + if(value_size) + *value_size = 0; + if(isvar) + *isvar = true; + return true; + } + duint eflags = GetContextDataEx(hActiveThread, UE_CFLAGS); + if(valflagfromstring(eflags, string + 1)) + *value = 1; + else + *value = 0; + if(value_size) + *value_size = 0; + if(isvar) + *isvar = true; + return true; + } + else if(isdecnumber(string)) //decimal numbers come 'first' + { + if(value_size) + *value_size = 0; + if(isvar) + *isvar = false; + sscanf(string + 1, "%" fext "u", value); + return true; + } + else if(ishexnumber(string)) //then hex numbers + { + if(value_size) + *value_size = 0; + if(isvar) + *isvar = false; + //hexadecimal value + int inc = 0; + if(*string == 'x') + inc = 1; + sscanf(string + inc, "%" fext "x", value); + return true; + } + if(baseonly) + return false; + else if(valapifromstring(string, value, value_size, true, silent, hexonly)) //then come APIs + return true; + else if(LabelFromString(string, value)) //then come labels + return true; + else if(SymAddrFromName(string, value)) //then come symbols + return true; + else if(varget(string, value, value_size, 0)) //finally variables + { + if(isvar) + *isvar = true; + return true; + } + if(!silent) + dprintf("invalid value: \"%s\"!\n", string); + return false; //nothing was OK +} + +/** +\brief Gets a value from a string. This function can parse expressions, memory locations, registers, flags, API names, labels, symbols and variables. +\param string The string to parse. +\param [out] value The value of the expression. This value cannot be null. +\param silent true to not output anything to the console. +\param baseonly true to skip parsing API names, labels, symbols and variables (basic expressions only). +\param [out] value_size This function can output the value size parsed (for example memory location size or register size). Can be null. +\param [out] isvar This function can output if the expression is variable (for example memory locations, registers or variables are variable). Can be null. +\param [out] hexonly This function can output if the output value should only be printed as hexadecimal (for example addresses). Can be null. +\return true if the expression was parsed successful, false otherwise. +*/ +bool valfromstring(const char* string, duint* value, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly) +{ + if(!value || !string) + return false; + if(!*string) + { + *value = 0; + return true; + } + ExpressionParser parser(string); + duint result; + if(!parser.calculate(result, valuesignedcalc(), silent, baseonly, value_size, isvar, hexonly)) + return false; + *value = result; + return true; +} + +/** +\brief Checks if a string is long enough. +\param str The string to check. +\param min_length The minimum length of \p str. +\return true if the string is long enough, false otherwise. +*/ +static bool longEnough(const char* str, size_t min_length) +{ + size_t length = 0; + while(str[length] && length < min_length) + length++; + if(length == min_length) + return true; + return false; +} + +/** +\brief Checks if a string starts with another string. +\param pre The desired prefix of the string. +\param str The complete string. +\return true if \p str starts with \p pre. +*/ +static bool startsWith(const char* pre, const char* str) +{ + size_t lenpre = strlen(pre); + return longEnough(str, lenpre) ? StrNCmpI(str, pre, (int) lenpre) == 0 : false; +} + +#define MxCsr_PRE_FIELD_STRING "MxCsr_" +#define x87SW_PRE_FIELD_STRING "x87SW_" +#define x87CW_PRE_FIELD_STRING "x87CW_" +#define x87TW_PRE_FIELD_STRING "x87TW_" +#define MMX_PRE_FIELD_STRING "MM" +#define XMM_PRE_FIELD_STRING "XMM" +#define YMM_PRE_FIELD_STRING "YMM" +#define x8780BITFPU_PRE_FIELD_STRING "x87r" +#define STRLEN_USING_SIZEOF(string) (sizeof(string) - 1) + +/** +\brief Sets an FPU value (MXCSR fields, MMX fields, etc.) by name. +\param string The name of the FPU value to set. +\param value The value to set. +*/ +static void setfpuvalue(const char* string, duint value) +{ + duint xorval = 0; + duint flags = 0; + duint flag = 0; + bool set = false; + + if(value) + set = true; + + if(startsWith(MxCsr_PRE_FIELD_STRING, string)) + { + if(StrNCmpI(string + STRLEN_USING_SIZEOF(MxCsr_PRE_FIELD_STRING), "RC", (int) strlen("RC")) == 0) + { + duint flags = GetContextDataEx(hActiveThread, UE_MXCSR); + int i = 3; + i <<= 13; + flags &= ~i; + value <<= 13; + flags |= value; + SetContextDataEx(hActiveThread, UE_MXCSR, flags); + } + else + { + duint flags = GetContextDataEx(hActiveThread, UE_MXCSR); + flag = getmxcsrflagfromstring(string + STRLEN_USING_SIZEOF(MxCsr_PRE_FIELD_STRING)); + if(flags & flag && !set) + xorval = flag; + else if(set) + xorval = flag; + SetContextDataEx(hActiveThread, UE_MXCSR, flags ^ xorval); + } + } + else if(startsWith(x87TW_PRE_FIELD_STRING, string)) + { + unsigned int i; + + string += STRLEN_USING_SIZEOF(x87TW_PRE_FIELD_STRING); + i = atoi(string); + + if(i > 7) + return; + + flags = GetContextDataEx(hActiveThread, UE_X87_TAGWORD); + + flag = 3; + flag <<= i * 2; + + flags &= ~flag; + + flag = value; + flag <<= i * 2; + + flags |= flag; + + SetContextDataEx(hActiveThread, UE_X87_TAGWORD, (unsigned short) flags); + + } + else if(startsWith(x87SW_PRE_FIELD_STRING, string)) + { + if(StrNCmpI(string + STRLEN_USING_SIZEOF(x87SW_PRE_FIELD_STRING), "TOP", (int) strlen("TOP")) == 0) + { + duint flags = GetContextDataEx(hActiveThread, UE_X87_STATUSWORD); + int i = 7; + i <<= 11; + flags &= ~i; + value <<= 11; + flags |= value; + SetContextDataEx(hActiveThread, UE_X87_STATUSWORD, flags); + } + else + { + duint flags = GetContextDataEx(hActiveThread, UE_X87_STATUSWORD); + flag = getx87statuswordflagfromstring(string + STRLEN_USING_SIZEOF(x87SW_PRE_FIELD_STRING)); + if(flags & flag && !set) + xorval = flag; + else if(set) + xorval = flag; + SetContextDataEx(hActiveThread, UE_X87_STATUSWORD, flags ^ xorval); + } + } + else if(startsWith(x87CW_PRE_FIELD_STRING, string)) + { + if(StrNCmpI(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING), "RC", (int) strlen("RC")) == 0) + { + duint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD); + int i = 3; + i <<= 10; + flags &= ~i; + value <<= 10; + flags |= value; + SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags); + } + else if(StrNCmpI(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING), "PC", (int) strlen("PC")) == 0) + { + duint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD); + int i = 3; + i <<= 8; + flags &= ~i; + value <<= 8; + flags |= value; + SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags); + } + else + { + duint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD); + flag = getx87controlwordflagfromstring(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING)); + if(flags & flag && !set) + xorval = flag; + else if(set) + xorval = flag; + SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags ^ xorval); + } + } + else if(StrNCmpI(string, "x87TagWord", (int) strlen(string)) == 0) + { + SetContextDataEx(hActiveThread, UE_X87_TAGWORD, (unsigned short) value); + } + else if(StrNCmpI(string, "x87StatusWord", (int) strlen(string)) == 0) + { + SetContextDataEx(hActiveThread, UE_X87_STATUSWORD, (unsigned short) value); + } + else if(StrNCmpI(string, "x87ControlWord", (int) strlen(string)) == 0) + { + SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, (unsigned short) value); + } + else if(StrNCmpI(string, "MxCsr", (int) strlen(string)) == 0) + { + SetContextDataEx(hActiveThread, UE_MXCSR, value); + } + else if(startsWith(x8780BITFPU_PRE_FIELD_STRING, string)) + { + string += STRLEN_USING_SIZEOF(x8780BITFPU_PRE_FIELD_STRING); + DWORD registerindex; + bool found = true; + switch(*string) + { + case '0': + registerindex = UE_x87_r0; + break; + + case '1': + registerindex = UE_x87_r1; + break; + + case '2': + registerindex = UE_x87_r2; + break; + + case '3': + registerindex = UE_x87_r3; + break; + + case '4': + registerindex = UE_x87_r4; + break; + + case '5': + registerindex = UE_x87_r5; + break; + + case '6': + registerindex = UE_x87_r6; + break; + + case '7': + registerindex = UE_x87_r7; + break; + + default: + found = false; + break; + } + if(found) + SetContextDataEx(hActiveThread, registerindex, value); + } + else if(startsWith(MMX_PRE_FIELD_STRING, string)) + { + string += STRLEN_USING_SIZEOF(MMX_PRE_FIELD_STRING); + DWORD registerindex; + bool found = true; + switch(*string) + { + case '0': + registerindex = UE_MMX0; + break; + + case '1': + registerindex = UE_MMX1; + break; + + case '2': + registerindex = UE_MMX2; + break; + + case '3': + registerindex = UE_MMX3; + break; + + case '4': + registerindex = UE_MMX4; + break; + + case '5': + registerindex = UE_MMX5; + break; + + case '6': + registerindex = UE_MMX6; + break; + + case '7': + registerindex = UE_MMX7; + break; + + default: + found = false; + break; + } + if(found) + SetContextDataEx(hActiveThread, registerindex, value); + } + else if(startsWith(XMM_PRE_FIELD_STRING, string)) + { + string += STRLEN_USING_SIZEOF(XMM_PRE_FIELD_STRING); + DWORD registerindex; + bool found = true; + switch(atoi(string)) + { + case 0: + registerindex = UE_XMM0; + break; + + case 1: + registerindex = UE_XMM1; + break; + + case 2: + registerindex = UE_XMM2; + break; + + case 3: + registerindex = UE_XMM3; + break; + + case 4: + registerindex = UE_XMM4; + break; + + case 5: + registerindex = UE_XMM5; + break; + + case 6: + registerindex = UE_XMM6; + break; + + case 7: + registerindex = UE_XMM7; + break; + + case 8: + registerindex = UE_XMM8; + break; + + case 9: + registerindex = UE_XMM9; + break; + + case 10: + registerindex = UE_XMM10; + break; + + case 11: + registerindex = UE_XMM11; + break; + + case 12: + registerindex = UE_XMM12; + break; + + case 13: + registerindex = UE_XMM13; + break; + + case 14: + registerindex = UE_XMM14; + break; + + case 15: + registerindex = UE_XMM15; + break; + + default: + found = false; + break; + } + if(found) + SetContextDataEx(hActiveThread, registerindex, value); + } + else if(startsWith(YMM_PRE_FIELD_STRING, string)) + { + string += STRLEN_USING_SIZEOF(YMM_PRE_FIELD_STRING); + DWORD registerindex; + bool found = true; + switch(atoi(string)) + { + case 0: + registerindex = UE_YMM0; + break; + + case 1: + registerindex = UE_YMM1; + break; + + case 2: + registerindex = UE_YMM2; + break; + + case 3: + registerindex = UE_YMM3; + break; + + case 4: + registerindex = UE_YMM4; + break; + + case 5: + registerindex = UE_YMM5; + break; + + case 6: + registerindex = UE_YMM6; + break; + + case 7: + registerindex = UE_YMM7; + break; + + case 8: + registerindex = UE_YMM8; + break; + + case 9: + registerindex = UE_YMM9; + break; + + case 10: + registerindex = UE_YMM10; + break; + + case 11: + registerindex = UE_YMM11; + break; + + case 12: + registerindex = UE_YMM12; + break; + + case 13: + registerindex = UE_YMM13; + break; + + case 14: + registerindex = UE_YMM14; + break; + + case 15: + registerindex = UE_YMM15; + break; + + default: + registerindex = 0; + found = false; + break; + } + if(found) + SetContextDataEx(hActiveThread, registerindex, value); + } +} + +/** +\brief Sets a register, variable, flag, memory location or FPU value by name. +\param string The name of the thing to set. +\param value The value to set. +\param silent true to not have output to the console. +\return true if the value was set successfully, false otherwise. +*/ +bool valtostring(const char* string, duint value, bool silent) +{ + if(!*string) + return false; + else if(*string == '@' || strstr(string, "[")) //memory location + { + if(!DbgIsDebugging()) + { + if(!silent) + dputs("not debugging"); + return false; + } + int len = (int)strlen(string); + Memory newstring(len * 2, "valfromstring:newstring"); + if(strstr(string, "[")) //memory brackets: [] + { + for(int i = 0, j = 0; i < len; i++) + { + if(string[i] == ']') + j += sprintf(newstring() + j, ")"); + else if(isdigit(string[i]) && string[i + 1] == ':' && string[i + 2] == '[') //n:[ + { + j += sprintf(newstring() + j, "@%c:(", string[i]); + i += 2; + } + else if(string[i] == '[') + j += sprintf(newstring() + j, "@("); + else + j += sprintf(newstring() + j, "%c", string[i]); + } + } + else + strcpy_s(newstring(), len * 2, string); + int read_size = sizeof(duint); + int add = 1; + if(newstring()[2] == ':' && isdigit((newstring()[1]))) + { + add += 2; + int new_size = newstring()[1] - 0x30; + if(new_size < read_size) + read_size = new_size; + } + duint temp; + if(!valfromstring(newstring() + add, &temp, silent, false)) + { + return false; + } + duint value_ = value; + if(!MemPatch(temp, &value_, read_size)) + { + if(!silent) + dputs("failed to write memory"); + return false; + } + GuiUpdateAllViews(); //repaint gui + GuiUpdatePatches(); //update patch dialog + return true; + } + else if(isregister(string)) //register + { + if(!DbgIsDebugging()) + { + if(!silent) + dputs("not debugging!"); + return false; + } + bool ok = setregister(string, value); + int len = (int)strlen(string); + Memory regName(len + 1, "valtostring:regname"); + strcpy_s(regName(), len + 1, string); + _strlwr(regName()); + if(strstr(regName(), "ip")) + DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), false); //update disassembly + register view + else if(strstr(regName(), "sp")) //update stack + { + duint csp = GetContextDataEx(hActiveThread, UE_CSP); + DebugUpdateStack(csp, csp); + GuiUpdateRegisterView(); + } + else + GuiUpdateAllViews(); //repaint gui + return ok; + } + else if((*string == '_')) //FPU values + { + if(!DbgIsDebugging()) + { + if(!silent) + dputs("not debugging!"); + return false; + } + setfpuvalue(string + 1, value); + GuiUpdateAllViews(); //repaint gui + return true; + } + else if(*string == '!' && isflag(string + 1)) //flag + { + if(!DbgIsDebugging()) + { + if(!silent) + dputs("not debugging"); + return false; + } + bool set = false; + if(value) + set = true; + setflag(string + 1, set); + GuiUpdateAllViews(); //repaint gui + return true; + } + return varset(string, value, false); //variable +} + +/** +\brief Converts a file offset to a virtual address. +\param modname The name (not the path) of the module the file offset is in. +\param offset The file offset. +\return The VA of the file offset, 0 when there was a problem with the conversion. +*/ +duint valfileoffsettova(const char* modname, duint offset) +{ + char modpath[MAX_PATH] = ""; + if(ModPathFromName(modname, modpath, MAX_PATH)) + { + HANDLE FileHandle; + DWORD LoadedSize; + HANDLE FileMap; + ULONG_PTR FileMapVA; + if(StaticFileLoadW(StringUtils::Utf8ToUtf16(modpath).c_str(), UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA)) + { + ULONGLONG rva = ConvertFileOffsetToVA(FileMapVA, //FileMapVA + FileMapVA + (ULONG_PTR)offset, //Offset inside FileMapVA + false); //Return without ImageBase + StaticFileUnloadW(StringUtils::Utf8ToUtf16(modpath).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA); + return offset < LoadedSize ? (duint)rva + ModBaseFromName(modname) : 0; + } + } + return 0; +} + +/** +\brief Converts a virtual address to a file offset. +\param va The virtual address (must be inside a module). +\return The file offset. 0 when there was a problem with the conversion. +*/ +duint valvatofileoffset(duint va) +{ + char modpath[MAX_PATH] = ""; + if(ModPathFromAddr(va, modpath, MAX_PATH)) + { + HANDLE FileHandle; + DWORD LoadedSize; + HANDLE FileMap; + ULONG_PTR FileMapVA; + if(StaticFileLoadW(StringUtils::Utf8ToUtf16(modpath).c_str(), UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA)) + { + ULONGLONG offset = ConvertVAtoFileOffsetEx(FileMapVA, LoadedSize, 0, va - ModBaseFromAddr(va), true, false); + StaticFileUnloadW(StringUtils::Utf8ToUtf16(modpath).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA); + return (duint)offset; + } + } + return 0; } \ No newline at end of file diff --git a/src/dbg/value.h b/src/dbg/value.h index 2498b6b3..5b66917a 100644 --- a/src/dbg/value.h +++ b/src/dbg/value.h @@ -1,25 +1,25 @@ -#ifndef _VALUE_H -#define _VALUE_H - -#include "_global.h" - -//functions -bool valuesignedcalc(); -void valuesetsignedcalc(bool a); -bool valapifromstring(const char* name, duint* value, int* value_size, bool printall, bool silent, bool* hexonly); -bool valfromstring_noexpr(const char* string, duint* value, bool silent = true, bool baseonly = false, int* value_size = 0, bool* isvar = 0, bool* hexonly = 0); -bool valfromstring(const char* string, duint* value, bool silent = true, bool baseonly = false, int* value_size = 0, bool* isvar = 0, bool* hexonly = 0); -bool valflagfromstring(duint eflags, const char* string); -bool valtostring(const char* string, duint value, bool silent); -bool valmxcsrflagfromstring(duint mxcsrflags, const char* string); -bool valx87statuswordflagfromstring(duint statusword, const char* string); -bool valx87controlwordflagfromstring(duint controlword, const char* string); -unsigned short valmxcsrfieldfromstring(duint mxcsrflags, const char* string); -unsigned short valx87statuswordfieldfromstring(duint statusword, const char* string); -unsigned short valx87controlwordfieldfromstring(duint controlword, const char* string); -duint valfileoffsettova(const char* modname, duint offset); -duint valvatofileoffset(duint va); -bool setregister(const char* string, duint value); -bool setflag(const char* string, bool set); - -#endif // _VALUE_H +#ifndef _VALUE_H +#define _VALUE_H + +#include "_global.h" + +//functions +bool valuesignedcalc(); +void valuesetsignedcalc(bool a); +bool valapifromstring(const char* name, duint* value, int* value_size, bool printall, bool silent, bool* hexonly); +bool valfromstring_noexpr(const char* string, duint* value, bool silent = true, bool baseonly = false, int* value_size = 0, bool* isvar = 0, bool* hexonly = 0); +bool valfromstring(const char* string, duint* value, bool silent = true, bool baseonly = false, int* value_size = 0, bool* isvar = 0, bool* hexonly = 0); +bool valflagfromstring(duint eflags, const char* string); +bool valtostring(const char* string, duint value, bool silent); +bool valmxcsrflagfromstring(duint mxcsrflags, const char* string); +bool valx87statuswordflagfromstring(duint statusword, const char* string); +bool valx87controlwordflagfromstring(duint controlword, const char* string); +unsigned short valmxcsrfieldfromstring(duint mxcsrflags, const char* string); +unsigned short valx87statuswordfieldfromstring(duint statusword, const char* string); +unsigned short valx87controlwordfieldfromstring(duint controlword, const char* string); +duint valfileoffsettova(const char* modname, duint offset); +duint valvatofileoffset(duint va); +bool setregister(const char* string, duint value); +bool setflag(const char* string, bool set); + +#endif // _VALUE_H diff --git a/src/dbg/variable.cpp b/src/dbg/variable.cpp index cc783342..472ff9b7 100644 --- a/src/dbg/variable.cpp +++ b/src/dbg/variable.cpp @@ -1,376 +1,376 @@ -/** - @file variable.cpp - - @brief Implements the variable class. - */ - -#include "variable.h" -#include "threading.h" - -/** -\brief The container that stores all variables. -*/ -std::map variables; - -/** -\brief Sets a variable with a value. -\param [in,out] Var The variable to set the value of. The previous value will be freed. Cannot be null. -\param [in] Value The new value. Cannot be null. -*/ -void varsetvalue(VAR* Var, VAR_VALUE* Value) -{ - // VAR_STRING needs to be freed before destroying it - if(Var->value.type == VAR_STRING) - delete Var->value.u.data; - - // Replace all information in the struct - memcpy(&Var->value, Value, sizeof(VAR_VALUE)); -} - -/** -\brief Sets a variable by name. -\param Name The name of the variable. Cannot be null. -\param Value The new value. Cannot be null. -\param ReadOnly true to set read-only variables (like $hProcess etc.). -\return true if the variable was set correctly, false otherwise. -*/ -bool varset(const char* Name, VAR_VALUE* Value, bool ReadOnly) -{ - EXCLUSIVE_ACQUIRE(LockVariables); - - String name_; - if(*Name != '$') - name_ = "$"; - name_ += Name; - auto found = variables.find(name_); - if(found == variables.end()) //not found - return false; - if(found->second.alias.length()) - { - // Release the lock (potential deadlock here) - EXCLUSIVE_RELEASE(); - - return varset(found->second.alias.c_str(), Value, ReadOnly); - } - - if(!ReadOnly && (found->second.type == VAR_READONLY || found->second.type == VAR_HIDDEN)) - return false; - varsetvalue(&found->second, Value); - return true; -} - -/** -\brief Initializes various default variables. -*/ -void varinit() -{ - varfree(); - - // General variables - varnew("$result\1$res", 0, VAR_SYSTEM); - varnew("$result1\1$res1", 0, VAR_SYSTEM); - varnew("$result2\1$res2", 0, VAR_SYSTEM); - varnew("$result3\1$res3", 0, VAR_SYSTEM); - varnew("$result4\1$res4", 0, VAR_SYSTEM); - - // InitDebug variables - varnew("$hProcess\1$hp", 0, VAR_READONLY); // Process handle - varnew("$pid", 0, VAR_READONLY); // Process ID - - // Hidden variables - varnew("$ans\1$an", 0, VAR_HIDDEN); - - // Read-only variables - varnew("$lastalloc", 0, VAR_READONLY); // Last memory allocation - varnew("$_EZ_FLAG", 0, VAR_READONLY); // Equal/zero flag for internal use (1 = equal, 0 = unequal) - varnew("$_BS_FLAG", 0, VAR_READONLY); // Bigger/smaller flag for internal use (1 = bigger, 0 = smaller) -} - -/** -\brief Clears all variables. -*/ -void varfree() -{ - EXCLUSIVE_ACQUIRE(LockVariables); - - // Each variable must be deleted manually; strings especially - // because there are sub-allocations - VAR_VALUE emptyValue; - memset(&emptyValue, 0, sizeof(VAR_VALUE)); - - for(auto & itr : variables) - varsetvalue(&itr.second, &emptyValue); - - // Now clear all vector elements - variables.clear(); -} - -/** -\brief Creates a new variable. -\param Name The name of the variable. You can specify alias names by separating the names by '\1'. Cannot be null. -\param Value The new variable value. -\param Type The variable type. -\return true if the new variables was created and set successfully, false otherwise. -*/ -bool varnew(const char* Name, duint Value, VAR_TYPE Type) -{ - if(!Name) - return false; - - EXCLUSIVE_ACQUIRE(LockVariables); - - std::vector names = StringUtils::Split(Name, '\1'); - String firstName; - for(int i = 0; i < (int)names.size(); i++) - { - String name_; - Name = names.at(i).c_str(); - if(*Name != '$') - name_ = "$"; - name_ += Name; - if(!i) - firstName = Name; - if(variables.find(name_) != variables.end()) //found - return false; - VAR var; - var.name = name_; - if(i) - var.alias = firstName; - var.type = Type; - var.value.size = sizeof(duint); - var.value.type = VAR_UINT; - var.value.u.value = Value; - variables.insert(std::make_pair(name_, var)); - } - return true; -} - -/** -\brief Gets a variable value. -\param Name The name of the variable. -\param [out] Value This function can get the variable value. If this value is null, it is ignored. -\param [out] Size This function can get the variable size. If this value is null, it is ignored. -\param [out] Type This function can get the variable type. If this value is null, it is ignored. -\return true if the variable was found and the optional values were retrieved successfully, false otherwise. -*/ -bool varget(const char* Name, VAR_VALUE* Value, int* Size, VAR_TYPE* Type) -{ - SHARED_ACQUIRE(LockVariables); - - String name_; - if(*Name != '$') - name_ = "$"; - name_ += Name; - auto found = variables.find(name_); - if(found == variables.end()) //not found - return false; - if(found->second.alias.length()) - { - // Release the lock (potential deadlock here) - SHARED_RELEASE(); - - return varget(found->second.alias.c_str(), Value, Size, Type); - } - if(Type) - *Type = found->second.type; - if(Size) - *Size = found->second.value.size; - if(Value) - *Value = found->second.value; - return true; -} - -/** -\brief Gets a variable value. -\param Name The name of the variable. -\param [out] Value This function can get the variable value. If this value is null, it is ignored. -\param [out] Size This function can get the variable size. If this value is null, it is ignored. -\param [out] Type This function can get the variable type. If this value is null, it is ignored. -\return true if the variable was found and the optional values were retrieved successfully, false otherwise. -*/ -bool varget(const char* Name, duint* Value, int* Size, VAR_TYPE* Type) -{ - VAR_VALUE varvalue; - int varsize; - VAR_TYPE vartype; - if(!varget(Name, &varvalue, &varsize, &vartype) || varvalue.type != VAR_UINT) - return false; - if(Size) - *Size = varsize; - if(Type) - *Type = vartype; - if(Value) - *Value = varvalue.u.value; - return true; -} - -/** -\brief Gets a variable value. -\param Name The name of the variable. -\param [out] String This function can get the variable value. If this value is null, it is ignored. -\param [out] Size This function can get the variable size. If this value is null, it is ignored. -\param [out] Type This function can get the variable type. If this value is null, it is ignored. -\return true if the variable was found and the optional values were retrieved successfully, false otherwise. -*/ -bool varget(const char* Name, char* String, int* Size, VAR_TYPE* Type) -{ - VAR_VALUE varvalue; - int varsize; - VAR_TYPE vartype; - if(!varget(Name, &varvalue, &varsize, &vartype) || varvalue.type != VAR_STRING) - return false; - if(Size) - *Size = varsize; - if(Type) - *Type = vartype; - if(String) - memcpy(String, varvalue.u.data->data(), varsize); - return true; -} - -/** -\brief Sets a variable by name. -\param Name The name of the variable. Cannot be null. -\param Value The new value. -\param ReadOnly true to set read-only variables (like $hProcess etc.). -\return true if the variable was set successfully, false otherwise. -*/ -bool varset(const char* Name, duint Value, bool ReadOnly) -{ - // Insert variable as an unsigned integer - VAR_VALUE varValue; - varValue.size = sizeof(duint); - varValue.type = VAR_UINT; - varValue.u.value = Value; - - return varset(Name, &varValue, ReadOnly); -} - -/** -\brief Sets a variable by name. -\param Name The name of the variable. Cannot be null. -\param Value The new value. Cannot be null. -\param ReadOnly true to set read-only variables (like $hProcess etc.). -\return true if the variable was set successfully, false otherwise. -*/ -bool varset(const char* Name, const char* Value, bool ReadOnly) -{ - VAR_VALUE varValue; - int stringLen = (int)strlen(Value); - varValue.size = stringLen; - varValue.type = VAR_STRING; - varValue.u.data = new std::vector; - - // Allocate space for the string - varValue.u.data->resize(stringLen); - - // Copy directly to vector array - memcpy(varValue.u.data->data(), Value, stringLen); - - // Try to register variable - if(!varset(Name, &varValue, ReadOnly)) - { - delete varValue.u.data; - return false; - } - - return true; -} - -/** -\brief Deletes a variable. -\param Name The name of the variable to delete. Cannot be null. -\param DelSystem true to allow deleting system variables. -\return true if the variable was deleted successfully, false otherwise. -*/ -bool vardel(const char* Name, bool DelSystem) -{ - EXCLUSIVE_ACQUIRE(LockVariables); - - String name_; - if(*Name != '$') - name_ = "$"; - name_ += Name; - auto found = variables.find(name_); - if(found == variables.end()) //not found - return false; - if(found->second.alias.length()) - { - // Release the lock (potential deadlock here) - EXCLUSIVE_RELEASE(); - - return vardel(found->second.alias.c_str(), DelSystem); - } - - if(!DelSystem && found->second.type != VAR_USER) - return false; - found = variables.begin(); - while(found != variables.end()) - { - auto del = found; - found++; - if(found->second.name == String(Name)) - variables.erase(del); - } - return true; -} - -/** -\brief Gets a variable type. -\param Name The name of the variable. Cannot be null. -\param [out] Type This function can retrieve the variable type. If null it is ignored. -\param [out] ValueType This function can retrieve the variable value type. If null it is ignored. -\return true if getting the type was successful, false otherwise. -*/ -bool vargettype(const char* Name, VAR_TYPE* Type, VAR_VALUE_TYPE* ValueType) -{ - SHARED_ACQUIRE(LockVariables); - - String name_; - if(*Name != '$') - name_ = "$"; - name_ += Name; - auto found = variables.find(name_); - if(found == variables.end()) //not found - return false; - if(found->second.alias.length()) - return vargettype(found->second.alias.c_str(), Type, ValueType); - if(ValueType) - *ValueType = found->second.value.type; - if(Type) - *Type = found->second.type; - return true; -} - -/** -\brief Enumerates all variables. -\param [in,out] List A pointer to place the variables in. If null, \p cbsize will be filled to the number of bytes required. -\param [in,out] Size This function retrieves the number of bytes required to store all variables. Can be null if \p entries is not null. -\return true if it succeeds, false if it fails. -*/ -bool varenum(VAR* List, size_t* Size) -{ - // A list or size must be requested - if(!List && !Size) - return false; - - SHARED_ACQUIRE(LockVariables); - - if(Size) - { - // Size requested, so return it - *Size = variables.size() * sizeof(VAR); - - if(!List) - return true; - } - - // Fill out all list entries - for(auto & itr : variables) - { - *List = itr.second; - List++; - } - - return true; +/** + @file variable.cpp + + @brief Implements the variable class. + */ + +#include "variable.h" +#include "threading.h" + +/** +\brief The container that stores all variables. +*/ +std::map variables; + +/** +\brief Sets a variable with a value. +\param [in,out] Var The variable to set the value of. The previous value will be freed. Cannot be null. +\param [in] Value The new value. Cannot be null. +*/ +void varsetvalue(VAR* Var, VAR_VALUE* Value) +{ + // VAR_STRING needs to be freed before destroying it + if(Var->value.type == VAR_STRING) + delete Var->value.u.data; + + // Replace all information in the struct + memcpy(&Var->value, Value, sizeof(VAR_VALUE)); +} + +/** +\brief Sets a variable by name. +\param Name The name of the variable. Cannot be null. +\param Value The new value. Cannot be null. +\param ReadOnly true to set read-only variables (like $hProcess etc.). +\return true if the variable was set correctly, false otherwise. +*/ +bool varset(const char* Name, VAR_VALUE* Value, bool ReadOnly) +{ + EXCLUSIVE_ACQUIRE(LockVariables); + + String name_; + if(*Name != '$') + name_ = "$"; + name_ += Name; + auto found = variables.find(name_); + if(found == variables.end()) //not found + return false; + if(found->second.alias.length()) + { + // Release the lock (potential deadlock here) + EXCLUSIVE_RELEASE(); + + return varset(found->second.alias.c_str(), Value, ReadOnly); + } + + if(!ReadOnly && (found->second.type == VAR_READONLY || found->second.type == VAR_HIDDEN)) + return false; + varsetvalue(&found->second, Value); + return true; +} + +/** +\brief Initializes various default variables. +*/ +void varinit() +{ + varfree(); + + // General variables + varnew("$result\1$res", 0, VAR_SYSTEM); + varnew("$result1\1$res1", 0, VAR_SYSTEM); + varnew("$result2\1$res2", 0, VAR_SYSTEM); + varnew("$result3\1$res3", 0, VAR_SYSTEM); + varnew("$result4\1$res4", 0, VAR_SYSTEM); + + // InitDebug variables + varnew("$hProcess\1$hp", 0, VAR_READONLY); // Process handle + varnew("$pid", 0, VAR_READONLY); // Process ID + + // Hidden variables + varnew("$ans\1$an", 0, VAR_HIDDEN); + + // Read-only variables + varnew("$lastalloc", 0, VAR_READONLY); // Last memory allocation + varnew("$_EZ_FLAG", 0, VAR_READONLY); // Equal/zero flag for internal use (1 = equal, 0 = unequal) + varnew("$_BS_FLAG", 0, VAR_READONLY); // Bigger/smaller flag for internal use (1 = bigger, 0 = smaller) +} + +/** +\brief Clears all variables. +*/ +void varfree() +{ + EXCLUSIVE_ACQUIRE(LockVariables); + + // Each variable must be deleted manually; strings especially + // because there are sub-allocations + VAR_VALUE emptyValue; + memset(&emptyValue, 0, sizeof(VAR_VALUE)); + + for(auto & itr : variables) + varsetvalue(&itr.second, &emptyValue); + + // Now clear all vector elements + variables.clear(); +} + +/** +\brief Creates a new variable. +\param Name The name of the variable. You can specify alias names by separating the names by '\1'. Cannot be null. +\param Value The new variable value. +\param Type The variable type. +\return true if the new variables was created and set successfully, false otherwise. +*/ +bool varnew(const char* Name, duint Value, VAR_TYPE Type) +{ + if(!Name) + return false; + + EXCLUSIVE_ACQUIRE(LockVariables); + + std::vector names = StringUtils::Split(Name, '\1'); + String firstName; + for(int i = 0; i < (int)names.size(); i++) + { + String name_; + Name = names.at(i).c_str(); + if(*Name != '$') + name_ = "$"; + name_ += Name; + if(!i) + firstName = Name; + if(variables.find(name_) != variables.end()) //found + return false; + VAR var; + var.name = name_; + if(i) + var.alias = firstName; + var.type = Type; + var.value.size = sizeof(duint); + var.value.type = VAR_UINT; + var.value.u.value = Value; + variables.insert(std::make_pair(name_, var)); + } + return true; +} + +/** +\brief Gets a variable value. +\param Name The name of the variable. +\param [out] Value This function can get the variable value. If this value is null, it is ignored. +\param [out] Size This function can get the variable size. If this value is null, it is ignored. +\param [out] Type This function can get the variable type. If this value is null, it is ignored. +\return true if the variable was found and the optional values were retrieved successfully, false otherwise. +*/ +bool varget(const char* Name, VAR_VALUE* Value, int* Size, VAR_TYPE* Type) +{ + SHARED_ACQUIRE(LockVariables); + + String name_; + if(*Name != '$') + name_ = "$"; + name_ += Name; + auto found = variables.find(name_); + if(found == variables.end()) //not found + return false; + if(found->second.alias.length()) + { + // Release the lock (potential deadlock here) + SHARED_RELEASE(); + + return varget(found->second.alias.c_str(), Value, Size, Type); + } + if(Type) + *Type = found->second.type; + if(Size) + *Size = found->second.value.size; + if(Value) + *Value = found->second.value; + return true; +} + +/** +\brief Gets a variable value. +\param Name The name of the variable. +\param [out] Value This function can get the variable value. If this value is null, it is ignored. +\param [out] Size This function can get the variable size. If this value is null, it is ignored. +\param [out] Type This function can get the variable type. If this value is null, it is ignored. +\return true if the variable was found and the optional values were retrieved successfully, false otherwise. +*/ +bool varget(const char* Name, duint* Value, int* Size, VAR_TYPE* Type) +{ + VAR_VALUE varvalue; + int varsize; + VAR_TYPE vartype; + if(!varget(Name, &varvalue, &varsize, &vartype) || varvalue.type != VAR_UINT) + return false; + if(Size) + *Size = varsize; + if(Type) + *Type = vartype; + if(Value) + *Value = varvalue.u.value; + return true; +} + +/** +\brief Gets a variable value. +\param Name The name of the variable. +\param [out] String This function can get the variable value. If this value is null, it is ignored. +\param [out] Size This function can get the variable size. If this value is null, it is ignored. +\param [out] Type This function can get the variable type. If this value is null, it is ignored. +\return true if the variable was found and the optional values were retrieved successfully, false otherwise. +*/ +bool varget(const char* Name, char* String, int* Size, VAR_TYPE* Type) +{ + VAR_VALUE varvalue; + int varsize; + VAR_TYPE vartype; + if(!varget(Name, &varvalue, &varsize, &vartype) || varvalue.type != VAR_STRING) + return false; + if(Size) + *Size = varsize; + if(Type) + *Type = vartype; + if(String) + memcpy(String, varvalue.u.data->data(), varsize); + return true; +} + +/** +\brief Sets a variable by name. +\param Name The name of the variable. Cannot be null. +\param Value The new value. +\param ReadOnly true to set read-only variables (like $hProcess etc.). +\return true if the variable was set successfully, false otherwise. +*/ +bool varset(const char* Name, duint Value, bool ReadOnly) +{ + // Insert variable as an unsigned integer + VAR_VALUE varValue; + varValue.size = sizeof(duint); + varValue.type = VAR_UINT; + varValue.u.value = Value; + + return varset(Name, &varValue, ReadOnly); +} + +/** +\brief Sets a variable by name. +\param Name The name of the variable. Cannot be null. +\param Value The new value. Cannot be null. +\param ReadOnly true to set read-only variables (like $hProcess etc.). +\return true if the variable was set successfully, false otherwise. +*/ +bool varset(const char* Name, const char* Value, bool ReadOnly) +{ + VAR_VALUE varValue; + int stringLen = (int)strlen(Value); + varValue.size = stringLen; + varValue.type = VAR_STRING; + varValue.u.data = new std::vector; + + // Allocate space for the string + varValue.u.data->resize(stringLen); + + // Copy directly to vector array + memcpy(varValue.u.data->data(), Value, stringLen); + + // Try to register variable + if(!varset(Name, &varValue, ReadOnly)) + { + delete varValue.u.data; + return false; + } + + return true; +} + +/** +\brief Deletes a variable. +\param Name The name of the variable to delete. Cannot be null. +\param DelSystem true to allow deleting system variables. +\return true if the variable was deleted successfully, false otherwise. +*/ +bool vardel(const char* Name, bool DelSystem) +{ + EXCLUSIVE_ACQUIRE(LockVariables); + + String name_; + if(*Name != '$') + name_ = "$"; + name_ += Name; + auto found = variables.find(name_); + if(found == variables.end()) //not found + return false; + if(found->second.alias.length()) + { + // Release the lock (potential deadlock here) + EXCLUSIVE_RELEASE(); + + return vardel(found->second.alias.c_str(), DelSystem); + } + + if(!DelSystem && found->second.type != VAR_USER) + return false; + found = variables.begin(); + while(found != variables.end()) + { + auto del = found; + found++; + if(found->second.name == String(Name)) + variables.erase(del); + } + return true; +} + +/** +\brief Gets a variable type. +\param Name The name of the variable. Cannot be null. +\param [out] Type This function can retrieve the variable type. If null it is ignored. +\param [out] ValueType This function can retrieve the variable value type. If null it is ignored. +\return true if getting the type was successful, false otherwise. +*/ +bool vargettype(const char* Name, VAR_TYPE* Type, VAR_VALUE_TYPE* ValueType) +{ + SHARED_ACQUIRE(LockVariables); + + String name_; + if(*Name != '$') + name_ = "$"; + name_ += Name; + auto found = variables.find(name_); + if(found == variables.end()) //not found + return false; + if(found->second.alias.length()) + return vargettype(found->second.alias.c_str(), Type, ValueType); + if(ValueType) + *ValueType = found->second.value.type; + if(Type) + *Type = found->second.type; + return true; +} + +/** +\brief Enumerates all variables. +\param [in,out] List A pointer to place the variables in. If null, \p cbsize will be filled to the number of bytes required. +\param [in,out] Size This function retrieves the number of bytes required to store all variables. Can be null if \p entries is not null. +\return true if it succeeds, false if it fails. +*/ +bool varenum(VAR* List, size_t* Size) +{ + // A list or size must be requested + if(!List && !Size) + return false; + + SHARED_ACQUIRE(LockVariables); + + if(Size) + { + // Size requested, so return it + *Size = variables.size() * sizeof(VAR); + + if(!List) + return true; + } + + // Fill out all list entries + for(auto & itr : variables) + { + *List = itr.second; + List++; + } + + return true; } \ No newline at end of file diff --git a/src/dbg/variable.h b/src/dbg/variable.h index e7ce5a07..6e80f72a 100644 --- a/src/dbg/variable.h +++ b/src/dbg/variable.h @@ -1,64 +1,64 @@ -#ifndef _VARIABLE_H -#define _VARIABLE_H - -#include "_global.h" - -//enums -enum VAR_TYPE -{ - VAR_SYSTEM = 1, - VAR_USER = 2, - VAR_READONLY = 3, - VAR_HIDDEN = 4 -}; - -enum VAR_VALUE_TYPE -{ - VAR_UINT, - VAR_STRING, -}; - -//structures -struct VAR_VALUE -{ - union - { - duint value; - std::vector* data; - } u; - VAR_VALUE_TYPE type; - int size; -}; - -struct VAR -{ - String name; - String alias; - VAR_TYPE type; - VAR_VALUE value; -}; - -struct CaseInsensitiveCompare -{ - bool operator()(const String & str1, const String & str2) const - { - return _stricmp(str1.c_str(), str2.c_str()) < 0; - } -}; - -//functions -void varsetvalue(VAR* Var, VAR_VALUE* Value); -bool varset(const char* Name, VAR_VALUE* Value, bool ReadOnly); -void varinit(); -void varfree(); -bool varnew(const char* Name, duint Value, VAR_TYPE Type); -bool varget(const char* Name, VAR_VALUE* Value, int* Size, VAR_TYPE* Type); -bool varget(const char* Name, duint* Value, int* Size, VAR_TYPE* Type); -bool varget(const char* Name, char* String, int* Size, VAR_TYPE* Type); -bool varset(const char* Name, duint Value, bool ReadOnly); -bool varset(const char* Name, const char* Value, bool ReadOnly); -bool vardel(const char* Name, bool DelSystem); -bool vargettype(const char* Name, VAR_TYPE* Type = nullptr, VAR_VALUE_TYPE* ValueType = nullptr); -bool varenum(VAR* List, size_t* Size); - -#endif // _VARIABLE_H +#ifndef _VARIABLE_H +#define _VARIABLE_H + +#include "_global.h" + +//enums +enum VAR_TYPE +{ + VAR_SYSTEM = 1, + VAR_USER = 2, + VAR_READONLY = 3, + VAR_HIDDEN = 4 +}; + +enum VAR_VALUE_TYPE +{ + VAR_UINT, + VAR_STRING, +}; + +//structures +struct VAR_VALUE +{ + union + { + duint value; + std::vector* data; + } u; + VAR_VALUE_TYPE type; + int size; +}; + +struct VAR +{ + String name; + String alias; + VAR_TYPE type; + VAR_VALUE value; +}; + +struct CaseInsensitiveCompare +{ + bool operator()(const String & str1, const String & str2) const + { + return _stricmp(str1.c_str(), str2.c_str()) < 0; + } +}; + +//functions +void varsetvalue(VAR* Var, VAR_VALUE* Value); +bool varset(const char* Name, VAR_VALUE* Value, bool ReadOnly); +void varinit(); +void varfree(); +bool varnew(const char* Name, duint Value, VAR_TYPE Type); +bool varget(const char* Name, VAR_VALUE* Value, int* Size, VAR_TYPE* Type); +bool varget(const char* Name, duint* Value, int* Size, VAR_TYPE* Type); +bool varget(const char* Name, char* String, int* Size, VAR_TYPE* Type); +bool varset(const char* Name, duint Value, bool ReadOnly); +bool varset(const char* Name, const char* Value, bool ReadOnly); +bool vardel(const char* Name, bool DelSystem); +bool vargettype(const char* Name, VAR_TYPE* Type = nullptr, VAR_VALUE_TYPE* ValueType = nullptr); +bool varenum(VAR* List, size_t* Size); + +#endif // _VARIABLE_H diff --git a/src/dbg/x64_dbg.cpp b/src/dbg/x64_dbg.cpp index 03d1e7c4..0b1afb15 100644 --- a/src/dbg/x64_dbg.cpp +++ b/src/dbg/x64_dbg.cpp @@ -1,423 +1,423 @@ -/** - @file x64_dbg.cpp - - @brief Implements the 64 debug class. - */ - -#include "_global.h" -#include "command.h" -#include "variable.h" -#include "instruction.h" -#include "debugger.h" -#include "simplescript.h" -#include "console.h" -#include "x64_dbg.h" -#include "msgqueue.h" -#include "threading.h" -#include "plugin_loader.h" -#include "_dbgfunctions.h" -#include "debugger_commands.h" -#include -#include "_scriptapi_gui.h" -#include "filehelper.h" -#include "database.h" - -static MESSAGE_STACK* gMsgStack = 0; -static HANDLE hCommandLoopThread = 0; -static bool bStopCommandLoopThread = false; -static char alloctrace[MAX_PATH] = ""; -static bool bIsStopped = true; -static String notesFile; - -static CMDRESULT cbStrLen(int argc, char* argv[]) -{ - if(argc < 2) - { - dputs("not enough arguments!"); - return STATUS_ERROR; - } - dprintf("\"%s\"[%d]\n", argv[1], strlen(argv[1])); - return STATUS_CONTINUE; -} - -static CMDRESULT cbCls(int argc, char* argv[]) -{ - GuiLogClear(); - return STATUS_CONTINUE; -} - -static CMDRESULT cbPrintf(int argc, char* argv[]) -{ - if(argc < 2) - dprintf("\n"); - else - dprintf("%s", argv[1]); - return STATUS_CONTINUE; -} - -static void registercommands() -{ - cmdinit(); - - //debug control - dbgcmdnew("InitDebug\1init\1initdbg", cbDebugInit, false); //init debugger arg1:exefile,[arg2:commandline] - dbgcmdnew("StopDebug\1stop\1dbgstop", cbDebugStop, true); //stop debugger - dbgcmdnew("AttachDebugger\1attach", cbDebugAttach, false); //attach - dbgcmdnew("DetachDebugger\1detach", cbDebugDetach, true); //detach - dbgcmdnew("run\1go\1r\1g", cbDebugRun, true); //unlock WAITID_RUN - dbgcmdnew("erun\1egun\1er\1eg", cbDebugErun, true); //run + skip first chance exceptions - dbgcmdnew("pause", cbDebugPause, true); //pause debugger - dbgcmdnew("StepInto\1sti", cbDebugStepInto, true); //StepInto - dbgcmdnew("eStepInto\1esti", cbDebugeStepInto, true); //StepInto + skip first chance exceptions - dbgcmdnew("StepOver\1step\1sto\1st", cbDebugStepOver, true); //StepOver - dbgcmdnew("eStepOver\1estep\1esto\1est", cbDebugeStepOver, true); //StepOver + skip first chance exceptions - dbgcmdnew("SingleStep\1sstep\1sst", cbDebugSingleStep, true); //SingleStep arg1:count - dbgcmdnew("eSingleStep\1esstep\1esst", cbDebugeSingleStep, true); //SingleStep arg1:count + skip first chance exceptions - dbgcmdnew("StepOut\1rtr", cbDebugRtr, true); //rtr - dbgcmdnew("eStepOut\1ertr", cbDebugeRtr, true); //rtr + skip first chance exceptions - dbgcmdnew("DebugContinue\1con", cbDebugContinue, true); //set continue status - dbgcmdnew("LibrarianSetBreakPoint\1bpdll", cbDebugBpDll, true); //set dll breakpoint - dbgcmdnew("LibrarianRemoveBreakPoint\1bcdll", cbDebugBcDll, true); //remove dll breakpoint - dbgcmdnew("switchthread\1threadswitch", cbDebugSwitchthread, true); //switch thread - dbgcmdnew("suspendthread\1threadsuspend", cbDebugSuspendthread, true); //suspend thread - dbgcmdnew("resumethread\1threadresume", cbDebugResumethread, true); //resume thread - dbgcmdnew("killthread\1threadkill", cbDebugKillthread, true); //kill thread - dbgcmdnew("suspendallthreads\1threadsuspendall", cbDebugSuspendAllThreads, true); //suspend all threads - dbgcmdnew("resumeallthreads\1threadresumeall", cbDebugResumeAllThreads, true); //resume all threads - dbgcmdnew("setthreadpriority\1setprioritythread\1threadsetpriority", cbDebugSetPriority, true); //set thread priority - dbgcmdnew("symdownload\1downloadsym", cbDebugDownloadSymbol, true); //download symbols - dbgcmdnew("setjit\1jitset", cbDebugSetJIT, false); //set JIT - dbgcmdnew("getjit\1jitget", cbDebugGetJIT, false); //get JIT - dbgcmdnew("getjitauto\1jitgetauto", cbDebugGetJITAuto, false); //get JIT Auto - dbgcmdnew("setjitauto\1jitsetauto", cbDebugSetJITAuto, false); //set JIT Auto - dbgcmdnew("getcmdline\1getcommandline", cbDebugGetCmdline, true); //Get CmdLine - dbgcmdnew("setcmdline\1setcommandline", cbDebugSetCmdline, true); //Set CmdLine - dbgcmdnew("loadlib", cbDebugLoadLib, true); //Load DLL - dbgcmdnew("skip", cbDebugSkip, true); //skip one instruction - - //breakpoints - dbgcmdnew("bplist", cbDebugBplist, true); //breakpoint list - dbgcmdnew("SetBPXOptions\1bptype", cbDebugSetBPXOptions, false); //breakpoint type - dbgcmdnew("SetBPX\1bp\1bpx", cbDebugSetBPX, true); //breakpoint - dbgcmdnew("DeleteBPX\1bpc\1bc", cbDebugDeleteBPX, true); //breakpoint delete - dbgcmdnew("EnableBPX\1bpe\1be", cbDebugEnableBPX, true); //breakpoint enable - dbgcmdnew("DisableBPX\1bpd\1bd", cbDebugDisableBPX, true); //breakpoint disable - dbgcmdnew("SetHardwareBreakpoint\1bph\1bphws", cbDebugSetHardwareBreakpoint, true); //hardware breakpoint - dbgcmdnew("DeleteHardwareBreakpoint\1bphc\1bphwc", cbDebugDeleteHardwareBreakpoint, true); //delete hardware breakpoint - dbgcmdnew("EnableHardwareBreakpoint\1bphe\1bphwe", cbDebugEnableHardwareBreakpoint, true); //enable hardware breakpoint - dbgcmdnew("DisableHardwareBreakpoint\1bphd\1bphwd", cbDebugDisableHardwareBreakpoint, true); //disable hardware breakpoint - dbgcmdnew("SetMemoryBPX\1membp\1bpm", cbDebugSetMemoryBpx, true); //SetMemoryBPX - dbgcmdnew("DeleteMemoryBPX\1membpc\1bpmc", cbDebugDeleteMemoryBreakpoint, true); //delete memory breakpoint - dbgcmdnew("EnableMemoryBreakpoint\1membpe\1bpme", cbDebugEnableMemoryBreakpoint, true); //enable memory breakpoint - dbgcmdnew("DisableMemoryBreakpoint\1membpd\1bpmd", cbDebugDisableMemoryBreakpoint, true); //enable memory breakpoint - - //variables - dbgcmdnew("varnew\1var", cbInstrVar, false); //make a variable arg1:name,[arg2:value] - dbgcmdnew("vardel", cbInstrVarDel, false); //delete a variable, arg1:variable name - dbgcmdnew("varlist", cbInstrVarList, false); //list variables[arg1:type filter] - dbgcmdnew("mov\1set", cbInstrMov, false); //mov a variable, arg1:dest,arg2:src - - //misc - dbgcmdnew("strlen\1charcount\1ccount", cbStrLen, false); //get strlen, arg1:string - dbgcmdnew("cls\1lc\1lclr", cbCls, false); //clear the log - dbgcmdnew("chd", cbInstrChd, false); //Change directory - dbgcmdnew("disasm\1dis\1d", cbDebugDisasm, true); //doDisasm - dbgcmdnew("HideDebugger\1dbh\1hide", cbDebugHide, true); //HideDebugger - dbgcmdnew("dump", cbDebugDump, true); //dump at address - dbgcmdnew("sdump", cbDebugStackDump, true); //dump at stack address - dbgcmdnew("refinit", cbInstrRefinit, false); - dbgcmdnew("refadd", cbInstrRefadd, false); - dbgcmdnew("asm", cbInstrAssemble, true); //assemble instruction - dbgcmdnew("sleep", cbInstrSleep, false); //Sleep - - //user database - dbgcmdnew("cmt\1cmtset\1commentset", cbInstrCmt, true); //set/edit comment - dbgcmdnew("cmtc\1cmtdel\1commentdel", cbInstrCmtdel, true); //delete comment - dbgcmdnew("lbl\1lblset\1labelset", cbInstrLbl, true); //set/edit label - dbgcmdnew("lblc\1lbldel\1labeldel", cbInstrLbldel, true); //delete label - dbgcmdnew("bookmark\1bookmarkset", cbInstrBookmarkSet, true); //set bookmark - dbgcmdnew("bookmarkc\1bookmarkdel", cbInstrBookmarkDel, true); //delete bookmark - dbgcmdnew("savedb\1dbsave", cbInstrSavedb, true); //save program database - dbgcmdnew("loaddb\1dbload", cbInstrLoaddb, true); //load program database - dbgcmdnew("functionadd\1func", cbInstrFunctionAdd, true); //function - dbgcmdnew("functiondel\1funcc", cbInstrFunctionDel, true); //function - dbgcmdnew("commentlist", cbInstrCommentList, true); //list comments - dbgcmdnew("labellist", cbInstrLabelList, true); //list labels - dbgcmdnew("bookmarklist", cbInstrBookmarkList, true); //list bookmarks - dbgcmdnew("functionlist", cbInstrFunctionList, true); //list functions - - //memory operations - dbgcmdnew("alloc", cbDebugAlloc, true); //allocate memory - dbgcmdnew("free", cbDebugFree, true); //free memory - dbgcmdnew("Fill\1memset", cbDebugMemset, true); //memset - dbgcmdnew("getpagerights\1getrightspage", cbDebugGetPageRights, true); - dbgcmdnew("setpagerights\1setrightspage", cbDebugSetPageRights, true); - - //plugins - dbgcmdnew("StartScylla\1scylla\1imprec", cbDebugStartScylla, false); //start scylla - - //general purpose - dbgcmdnew("cmp", cbInstrCmp, false); //compare - dbgcmdnew("gpa", cbInstrGpa, true); - dbgcmdnew("add", cbInstrAdd, false); - dbgcmdnew("and", cbInstrAnd, false); - dbgcmdnew("dec", cbInstrDec, false); - dbgcmdnew("div", cbInstrDiv, false); - dbgcmdnew("inc", cbInstrInc, false); - dbgcmdnew("mul", cbInstrMul, false); - dbgcmdnew("neg", cbInstrNeg, false); - dbgcmdnew("not", cbInstrNot, false); - dbgcmdnew("or", cbInstrOr, false); - dbgcmdnew("rol", cbInstrRol, false); - dbgcmdnew("ror", cbInstrRor, false); - dbgcmdnew("shl", cbInstrShl, false); - dbgcmdnew("shr", cbInstrShr, false); - dbgcmdnew("sub", cbInstrSub, false); - dbgcmdnew("test", cbInstrTest, false); - dbgcmdnew("xor", cbInstrXor, false); - dbgcmdnew("push", cbInstrPush, true); - dbgcmdnew("pop", cbInstrPop, true); - - //script - dbgcmdnew("scriptload", cbScriptLoad, false); - dbgcmdnew("msg", cbScriptMsg, false); - dbgcmdnew("msgyn", cbScriptMsgyn, false); - dbgcmdnew("log", cbInstrLog, false); //log command with superawesome hax - - //data - dbgcmdnew("reffind\1findref\1ref", cbInstrRefFind, true); //find references to a value - dbgcmdnew("refstr\1strref", cbInstrRefStr, true); //find string references - dbgcmdnew("find", cbInstrFind, true); //find a pattern - dbgcmdnew("findall", cbInstrFindAll, true); //find all patterns - dbgcmdnew("modcallfind", cbInstrModCallFind, true); //find intermodular calls - dbgcmdnew("findasm\1asmfind", cbInstrFindAsm, true); //find instruction - dbgcmdnew("reffindrange\1findrefrange\1refrange", cbInstrRefFindRange, true); - dbgcmdnew("yara", cbInstrYara, true); //yara test command - dbgcmdnew("yaramod", cbInstrYaramod, true); //yara rule on module - dbgcmdnew("analyse\1analyze\1anal", cbInstrAnalyse, true); //secret analysis command - - //undocumented - dbgcmdnew("bench", cbDebugBenchmark, true); //benchmark test (readmem etc) - dbgcmdnew("dprintf", cbPrintf, false); //printf - dbgcmdnew("setstr\1strset", cbInstrSetstr, false); //set a string variable - dbgcmdnew("getstr\1strget", cbInstrGetstr, false); //get a string variable - dbgcmdnew("copystr\1strcpy", cbInstrCopystr, true); //write a string variable to memory - dbgcmdnew("looplist", cbInstrLoopList, true); //list loops - dbgcmdnew("capstone", cbInstrCapstone, true); //disassemble using capstone - dbgcmdnew("visualize", cbInstrVisualize, true); //visualize analysis - dbgcmdnew("meminfo", cbInstrMeminfo, true); //command to debug memory map bugs - dbgcmdnew("cfanal\1cfanalyse\1cfanalyze", cbInstrCfanalyse, true); //control flow analysis - dbgcmdnew("analyse_nukem\1analyze_nukem\1anal_nukem", cbInstrAnalyseNukem, true); //secret analysis command #2 - dbgcmdnew("exanal\1exanalyse\1exanalyze", cbInstrExanalyse, true); //exception directory analysis - dbgcmdnew("virtualmod", cbInstrVirtualmod, true); //virtual module - dbgcmdnew("findallmem\1findmemall", cbInstrFindMemAll, true); //memory map pattern find - dbgcmdnew("setmaxfindresult\1findsetmaxresult", cbInstrSetMaxFindResult, false); //set the maximum number of occurences found - dbgcmdnew("setfreezestack", cbDebugSetfreezestack, false); //freeze the stack from auto updates -} - -static bool cbCommandProvider(char* cmd, int maxlen) -{ - MESSAGE msg; - MsgWait(gMsgStack, &msg); - if(bStopCommandLoopThread) - return false; - char* newcmd = (char*)msg.param1; - if(strlen(newcmd) >= deflen) - { - dprintf("command cut at ~%d characters\n", deflen); - newcmd[deflen - 2] = 0; - } - strcpy_s(cmd, deflen, newcmd); - efree(newcmd, "cbCommandProvider:newcmd"); //free allocated command - return true; -} - -extern "C" DLL_EXPORT bool _dbg_dbgcmdexec(const char* cmd) -{ - int len = (int)strlen(cmd); - char* newcmd = (char*)emalloc((len + 1) * sizeof(char), "_dbg_dbgcmdexec:newcmd"); - strcpy_s(newcmd, len + 1, cmd); - return MsgSend(gMsgStack, 0, (duint)newcmd, 0); -} - -static DWORD WINAPI DbgCommandLoopThread(void* a) -{ - cmdloop(cbBadCmd, cbCommandProvider, cmdfindmain, false); - return 0; -} - -extern "C" DLL_EXPORT const char* _dbg_dbginit() -{ - if (!EngineCheckStructAlignment(UE_STRUCT_TITAN_ENGINE_CONTEXT, sizeof(TITAN_ENGINE_CONTEXT_t))) - return "Invalid TITAN_ENGINE_CONTEXT_t alignment!"; - - if (sizeof(TITAN_ENGINE_CONTEXT_t) != sizeof(REGISTERCONTEXT)) - return "Invalid REGISTERCONTEXT alignment!"; - - dputs("Initializing wait objects..."); - waitinitialize(); - dputs("Initializing debugger..."); - dbginit(); - dputs("Initializing debugger functions..."); - dbgfunctionsinit(); - dputs("Setting JSON memory management functions..."); - json_set_alloc_funcs(json_malloc, json_free); - dputs("Initializing capstone..."); - Capstone::GlobalInitialize(); - dputs("Initializing Yara..."); - if(yr_initialize() != ERROR_SUCCESS) - return "Failed to initialize Yara!"; - dputs("Getting directory information..."); - wchar_t wszDir[deflen] = L""; - if(!GetModuleFileNameW(hInst, wszDir, deflen)) - return "GetModuleFileNameW failed!"; - char dir[deflen] = ""; - strcpy_s(dir, StringUtils::Utf16ToUtf8(wszDir).c_str()); - int len = (int)strlen(dir); - while(dir[len] != '\\') - len--; - dir[len] = 0; - strcpy_s(alloctrace, dir); - strcat_s(alloctrace, "\\alloctrace.txt"); - DeleteFileW(StringUtils::Utf8ToUtf16(alloctrace).c_str()); - setalloctrace(alloctrace); - - // Create database directory in the local debugger folder - DBSetPath(StringUtils::sprintf("%s\\db", dir).c_str(), nullptr); - - char szLocalSymbolPath[MAX_PATH] = ""; - strcpy_s(szLocalSymbolPath, dir); - strcat_s(szLocalSymbolPath, "\\symbols"); - - char cachePath[MAX_SETTING_SIZE]; - if(!BridgeSettingGet("Symbols", "CachePath", cachePath) || !*cachePath) - { - strcpy_s(szSymbolCachePath, szLocalSymbolPath); - BridgeSettingSet("Symbols", "CachePath", ".\\symbols"); - } - else - { - if(_strnicmp(cachePath, ".\\", 2) == 0) - { - strncpy_s(szSymbolCachePath, dir, _TRUNCATE); - strncat_s(szSymbolCachePath, cachePath + 1, _TRUNCATE); - } - else - { - // Trim the buffer to fit inside MAX_PATH - strncpy_s(szSymbolCachePath, cachePath, _TRUNCATE); - } - - if(strstr(szSymbolCachePath, "http://") || strstr(szSymbolCachePath, "https://")) - { - if(Script::Gui::MessageYesNo("It is strongly discouraged to use symbol servers in your path directly (use the store option instead).\n\nDo you want me to fix this?")) - { - strcpy_s(szSymbolCachePath, szLocalSymbolPath); - BridgeSettingSet("Symbols", "CachePath", ".\\symbols"); - } - } - } - dputs(szSymbolCachePath); - SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(dir).c_str()); - dputs("Allocating message stack..."); - gMsgStack = MsgAllocStack(); - if(!gMsgStack) - return "Could not allocate message stack!"; - dputs("Initializing global script variables..."); - varinit(); - dputs("Registering debugger commands..."); - registercommands(); - dputs("Starting command loop..."); - hCommandLoopThread = CreateThread(0, 0, DbgCommandLoopThread, 0, 0, 0); - char plugindir[deflen] = ""; - strcpy_s(plugindir, dir); - strcat_s(plugindir, "\\plugins"); - CreateDirectoryW(StringUtils::Utf8ToUtf16(plugindir).c_str(), 0); - dputs("Loading plugins..."); - pluginload(plugindir); - dputs("Handling command line..."); - //handle command line - int argc = 0; - wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc); - if(argc == 2) //we have an argument - { - String str = "init \""; - str += StringUtils::Utf16ToUtf8(argv[1]); - str += "\""; - DbgCmdExec(str.c_str()); - } - else if(argc == 5) //4 arguments (JIT) - { - if(_wcsicmp(argv[1], L"-a") == 0 && !_wcsicmp(argv[3], L"-e")) - { - String str = "attach ."; - str += StringUtils::Utf16ToUtf8(argv[2]); - str += ", ."; - str += StringUtils::Utf16ToUtf8(argv[4]); - DbgCmdExec(str.c_str()); - } - } - LocalFree(argv); - dputs("Reading notes file..."); - notesFile = String(dir) + "\\notes.txt"; - String text; - FileHelper::ReadAllText(notesFile, text); - GuiSetGlobalNotes(text.c_str()); - dputs("Initialization successful!"); - bIsStopped = false; - return nullptr; -} - -extern "C" DLL_EXPORT void _dbg_dbgexitsignal() -{ - dputs("Stopping running debuggee..."); - cbDebugStop(0, 0); - dputs("Aborting scripts..."); - scriptabort(); - dputs("Waiting for the debuggee to be stopped..."); - wait(WAITID_STOP); //after this, debugging stopped - dputs("Unloading plugins..."); - pluginunload(); - dputs("Stopping command thread..."); - bStopCommandLoopThread = true; - MsgFreeStack(gMsgStack); - WaitForThreadTermination(hCommandLoopThread); - dputs("Cleaning up allocated data..."); - cmdfree(); - varfree(); - yr_finalize(); - Capstone::GlobalFinalize(); - dputs("Checking for mem leaks..."); - if(memleaks()) - dprintf("%d memory leak(s) found!\n", memleaks()); - else - DeleteFileA(alloctrace); - dputs("Cleaning up wait objects..."); - waitdeinitialize(); - dputs("Cleaning up debugger threads..."); - dbgstop(); - dputs("Saving notes..."); - char* text = nullptr; - GuiGetGlobalNotes(&text); - if(text) - { - FileHelper::WriteAllText(notesFile, String(text)); - BridgeFree(text); - } - else - DeleteFileW(StringUtils::Utf8ToUtf16(notesFile).c_str()); - dputs("Exit signal processed successfully!"); - bIsStopped = true; -} - -extern "C" DLL_EXPORT bool _dbg_dbgcmddirectexec(const char* cmd) -{ - if(cmddirectexec(cmd) == STATUS_ERROR) - return false; - return true; -} - -bool dbgisstopped() -{ - return bIsStopped; +/** + @file x64_dbg.cpp + + @brief Implements the 64 debug class. + */ + +#include "_global.h" +#include "command.h" +#include "variable.h" +#include "instruction.h" +#include "debugger.h" +#include "simplescript.h" +#include "console.h" +#include "x64_dbg.h" +#include "msgqueue.h" +#include "threading.h" +#include "plugin_loader.h" +#include "_dbgfunctions.h" +#include "debugger_commands.h" +#include +#include "_scriptapi_gui.h" +#include "filehelper.h" +#include "database.h" + +static MESSAGE_STACK* gMsgStack = 0; +static HANDLE hCommandLoopThread = 0; +static bool bStopCommandLoopThread = false; +static char alloctrace[MAX_PATH] = ""; +static bool bIsStopped = true; +static String notesFile; + +static CMDRESULT cbStrLen(int argc, char* argv[]) +{ + if(argc < 2) + { + dputs("not enough arguments!"); + return STATUS_ERROR; + } + dprintf("\"%s\"[%d]\n", argv[1], strlen(argv[1])); + return STATUS_CONTINUE; +} + +static CMDRESULT cbCls(int argc, char* argv[]) +{ + GuiLogClear(); + return STATUS_CONTINUE; +} + +static CMDRESULT cbPrintf(int argc, char* argv[]) +{ + if(argc < 2) + dprintf("\n"); + else + dprintf("%s", argv[1]); + return STATUS_CONTINUE; +} + +static void registercommands() +{ + cmdinit(); + + //debug control + dbgcmdnew("InitDebug\1init\1initdbg", cbDebugInit, false); //init debugger arg1:exefile,[arg2:commandline] + dbgcmdnew("StopDebug\1stop\1dbgstop", cbDebugStop, true); //stop debugger + dbgcmdnew("AttachDebugger\1attach", cbDebugAttach, false); //attach + dbgcmdnew("DetachDebugger\1detach", cbDebugDetach, true); //detach + dbgcmdnew("run\1go\1r\1g", cbDebugRun, true); //unlock WAITID_RUN + dbgcmdnew("erun\1egun\1er\1eg", cbDebugErun, true); //run + skip first chance exceptions + dbgcmdnew("pause", cbDebugPause, true); //pause debugger + dbgcmdnew("StepInto\1sti", cbDebugStepInto, true); //StepInto + dbgcmdnew("eStepInto\1esti", cbDebugeStepInto, true); //StepInto + skip first chance exceptions + dbgcmdnew("StepOver\1step\1sto\1st", cbDebugStepOver, true); //StepOver + dbgcmdnew("eStepOver\1estep\1esto\1est", cbDebugeStepOver, true); //StepOver + skip first chance exceptions + dbgcmdnew("SingleStep\1sstep\1sst", cbDebugSingleStep, true); //SingleStep arg1:count + dbgcmdnew("eSingleStep\1esstep\1esst", cbDebugeSingleStep, true); //SingleStep arg1:count + skip first chance exceptions + dbgcmdnew("StepOut\1rtr", cbDebugRtr, true); //rtr + dbgcmdnew("eStepOut\1ertr", cbDebugeRtr, true); //rtr + skip first chance exceptions + dbgcmdnew("DebugContinue\1con", cbDebugContinue, true); //set continue status + dbgcmdnew("LibrarianSetBreakPoint\1bpdll", cbDebugBpDll, true); //set dll breakpoint + dbgcmdnew("LibrarianRemoveBreakPoint\1bcdll", cbDebugBcDll, true); //remove dll breakpoint + dbgcmdnew("switchthread\1threadswitch", cbDebugSwitchthread, true); //switch thread + dbgcmdnew("suspendthread\1threadsuspend", cbDebugSuspendthread, true); //suspend thread + dbgcmdnew("resumethread\1threadresume", cbDebugResumethread, true); //resume thread + dbgcmdnew("killthread\1threadkill", cbDebugKillthread, true); //kill thread + dbgcmdnew("suspendallthreads\1threadsuspendall", cbDebugSuspendAllThreads, true); //suspend all threads + dbgcmdnew("resumeallthreads\1threadresumeall", cbDebugResumeAllThreads, true); //resume all threads + dbgcmdnew("setthreadpriority\1setprioritythread\1threadsetpriority", cbDebugSetPriority, true); //set thread priority + dbgcmdnew("symdownload\1downloadsym", cbDebugDownloadSymbol, true); //download symbols + dbgcmdnew("setjit\1jitset", cbDebugSetJIT, false); //set JIT + dbgcmdnew("getjit\1jitget", cbDebugGetJIT, false); //get JIT + dbgcmdnew("getjitauto\1jitgetauto", cbDebugGetJITAuto, false); //get JIT Auto + dbgcmdnew("setjitauto\1jitsetauto", cbDebugSetJITAuto, false); //set JIT Auto + dbgcmdnew("getcmdline\1getcommandline", cbDebugGetCmdline, true); //Get CmdLine + dbgcmdnew("setcmdline\1setcommandline", cbDebugSetCmdline, true); //Set CmdLine + dbgcmdnew("loadlib", cbDebugLoadLib, true); //Load DLL + dbgcmdnew("skip", cbDebugSkip, true); //skip one instruction + + //breakpoints + dbgcmdnew("bplist", cbDebugBplist, true); //breakpoint list + dbgcmdnew("SetBPXOptions\1bptype", cbDebugSetBPXOptions, false); //breakpoint type + dbgcmdnew("SetBPX\1bp\1bpx", cbDebugSetBPX, true); //breakpoint + dbgcmdnew("DeleteBPX\1bpc\1bc", cbDebugDeleteBPX, true); //breakpoint delete + dbgcmdnew("EnableBPX\1bpe\1be", cbDebugEnableBPX, true); //breakpoint enable + dbgcmdnew("DisableBPX\1bpd\1bd", cbDebugDisableBPX, true); //breakpoint disable + dbgcmdnew("SetHardwareBreakpoint\1bph\1bphws", cbDebugSetHardwareBreakpoint, true); //hardware breakpoint + dbgcmdnew("DeleteHardwareBreakpoint\1bphc\1bphwc", cbDebugDeleteHardwareBreakpoint, true); //delete hardware breakpoint + dbgcmdnew("EnableHardwareBreakpoint\1bphe\1bphwe", cbDebugEnableHardwareBreakpoint, true); //enable hardware breakpoint + dbgcmdnew("DisableHardwareBreakpoint\1bphd\1bphwd", cbDebugDisableHardwareBreakpoint, true); //disable hardware breakpoint + dbgcmdnew("SetMemoryBPX\1membp\1bpm", cbDebugSetMemoryBpx, true); //SetMemoryBPX + dbgcmdnew("DeleteMemoryBPX\1membpc\1bpmc", cbDebugDeleteMemoryBreakpoint, true); //delete memory breakpoint + dbgcmdnew("EnableMemoryBreakpoint\1membpe\1bpme", cbDebugEnableMemoryBreakpoint, true); //enable memory breakpoint + dbgcmdnew("DisableMemoryBreakpoint\1membpd\1bpmd", cbDebugDisableMemoryBreakpoint, true); //enable memory breakpoint + + //variables + dbgcmdnew("varnew\1var", cbInstrVar, false); //make a variable arg1:name,[arg2:value] + dbgcmdnew("vardel", cbInstrVarDel, false); //delete a variable, arg1:variable name + dbgcmdnew("varlist", cbInstrVarList, false); //list variables[arg1:type filter] + dbgcmdnew("mov\1set", cbInstrMov, false); //mov a variable, arg1:dest,arg2:src + + //misc + dbgcmdnew("strlen\1charcount\1ccount", cbStrLen, false); //get strlen, arg1:string + dbgcmdnew("cls\1lc\1lclr", cbCls, false); //clear the log + dbgcmdnew("chd", cbInstrChd, false); //Change directory + dbgcmdnew("disasm\1dis\1d", cbDebugDisasm, true); //doDisasm + dbgcmdnew("HideDebugger\1dbh\1hide", cbDebugHide, true); //HideDebugger + dbgcmdnew("dump", cbDebugDump, true); //dump at address + dbgcmdnew("sdump", cbDebugStackDump, true); //dump at stack address + dbgcmdnew("refinit", cbInstrRefinit, false); + dbgcmdnew("refadd", cbInstrRefadd, false); + dbgcmdnew("asm", cbInstrAssemble, true); //assemble instruction + dbgcmdnew("sleep", cbInstrSleep, false); //Sleep + + //user database + dbgcmdnew("cmt\1cmtset\1commentset", cbInstrCmt, true); //set/edit comment + dbgcmdnew("cmtc\1cmtdel\1commentdel", cbInstrCmtdel, true); //delete comment + dbgcmdnew("lbl\1lblset\1labelset", cbInstrLbl, true); //set/edit label + dbgcmdnew("lblc\1lbldel\1labeldel", cbInstrLbldel, true); //delete label + dbgcmdnew("bookmark\1bookmarkset", cbInstrBookmarkSet, true); //set bookmark + dbgcmdnew("bookmarkc\1bookmarkdel", cbInstrBookmarkDel, true); //delete bookmark + dbgcmdnew("savedb\1dbsave", cbInstrSavedb, true); //save program database + dbgcmdnew("loaddb\1dbload", cbInstrLoaddb, true); //load program database + dbgcmdnew("functionadd\1func", cbInstrFunctionAdd, true); //function + dbgcmdnew("functiondel\1funcc", cbInstrFunctionDel, true); //function + dbgcmdnew("commentlist", cbInstrCommentList, true); //list comments + dbgcmdnew("labellist", cbInstrLabelList, true); //list labels + dbgcmdnew("bookmarklist", cbInstrBookmarkList, true); //list bookmarks + dbgcmdnew("functionlist", cbInstrFunctionList, true); //list functions + + //memory operations + dbgcmdnew("alloc", cbDebugAlloc, true); //allocate memory + dbgcmdnew("free", cbDebugFree, true); //free memory + dbgcmdnew("Fill\1memset", cbDebugMemset, true); //memset + dbgcmdnew("getpagerights\1getrightspage", cbDebugGetPageRights, true); + dbgcmdnew("setpagerights\1setrightspage", cbDebugSetPageRights, true); + + //plugins + dbgcmdnew("StartScylla\1scylla\1imprec", cbDebugStartScylla, false); //start scylla + + //general purpose + dbgcmdnew("cmp", cbInstrCmp, false); //compare + dbgcmdnew("gpa", cbInstrGpa, true); + dbgcmdnew("add", cbInstrAdd, false); + dbgcmdnew("and", cbInstrAnd, false); + dbgcmdnew("dec", cbInstrDec, false); + dbgcmdnew("div", cbInstrDiv, false); + dbgcmdnew("inc", cbInstrInc, false); + dbgcmdnew("mul", cbInstrMul, false); + dbgcmdnew("neg", cbInstrNeg, false); + dbgcmdnew("not", cbInstrNot, false); + dbgcmdnew("or", cbInstrOr, false); + dbgcmdnew("rol", cbInstrRol, false); + dbgcmdnew("ror", cbInstrRor, false); + dbgcmdnew("shl", cbInstrShl, false); + dbgcmdnew("shr", cbInstrShr, false); + dbgcmdnew("sub", cbInstrSub, false); + dbgcmdnew("test", cbInstrTest, false); + dbgcmdnew("xor", cbInstrXor, false); + dbgcmdnew("push", cbInstrPush, true); + dbgcmdnew("pop", cbInstrPop, true); + + //script + dbgcmdnew("scriptload", cbScriptLoad, false); + dbgcmdnew("msg", cbScriptMsg, false); + dbgcmdnew("msgyn", cbScriptMsgyn, false); + dbgcmdnew("log", cbInstrLog, false); //log command with superawesome hax + + //data + dbgcmdnew("reffind\1findref\1ref", cbInstrRefFind, true); //find references to a value + dbgcmdnew("refstr\1strref", cbInstrRefStr, true); //find string references + dbgcmdnew("find", cbInstrFind, true); //find a pattern + dbgcmdnew("findall", cbInstrFindAll, true); //find all patterns + dbgcmdnew("modcallfind", cbInstrModCallFind, true); //find intermodular calls + dbgcmdnew("findasm\1asmfind", cbInstrFindAsm, true); //find instruction + dbgcmdnew("reffindrange\1findrefrange\1refrange", cbInstrRefFindRange, true); + dbgcmdnew("yara", cbInstrYara, true); //yara test command + dbgcmdnew("yaramod", cbInstrYaramod, true); //yara rule on module + dbgcmdnew("analyse\1analyze\1anal", cbInstrAnalyse, true); //secret analysis command + + //undocumented + dbgcmdnew("bench", cbDebugBenchmark, true); //benchmark test (readmem etc) + dbgcmdnew("dprintf", cbPrintf, false); //printf + dbgcmdnew("setstr\1strset", cbInstrSetstr, false); //set a string variable + dbgcmdnew("getstr\1strget", cbInstrGetstr, false); //get a string variable + dbgcmdnew("copystr\1strcpy", cbInstrCopystr, true); //write a string variable to memory + dbgcmdnew("looplist", cbInstrLoopList, true); //list loops + dbgcmdnew("capstone", cbInstrCapstone, true); //disassemble using capstone + dbgcmdnew("visualize", cbInstrVisualize, true); //visualize analysis + dbgcmdnew("meminfo", cbInstrMeminfo, true); //command to debug memory map bugs + dbgcmdnew("cfanal\1cfanalyse\1cfanalyze", cbInstrCfanalyse, true); //control flow analysis + dbgcmdnew("analyse_nukem\1analyze_nukem\1anal_nukem", cbInstrAnalyseNukem, true); //secret analysis command #2 + dbgcmdnew("exanal\1exanalyse\1exanalyze", cbInstrExanalyse, true); //exception directory analysis + dbgcmdnew("virtualmod", cbInstrVirtualmod, true); //virtual module + dbgcmdnew("findallmem\1findmemall", cbInstrFindMemAll, true); //memory map pattern find + dbgcmdnew("setmaxfindresult\1findsetmaxresult", cbInstrSetMaxFindResult, false); //set the maximum number of occurences found + dbgcmdnew("setfreezestack", cbDebugSetfreezestack, false); //freeze the stack from auto updates +} + +static bool cbCommandProvider(char* cmd, int maxlen) +{ + MESSAGE msg; + MsgWait(gMsgStack, &msg); + if(bStopCommandLoopThread) + return false; + char* newcmd = (char*)msg.param1; + if(strlen(newcmd) >= deflen) + { + dprintf("command cut at ~%d characters\n", deflen); + newcmd[deflen - 2] = 0; + } + strcpy_s(cmd, deflen, newcmd); + efree(newcmd, "cbCommandProvider:newcmd"); //free allocated command + return true; +} + +extern "C" DLL_EXPORT bool _dbg_dbgcmdexec(const char* cmd) +{ + int len = (int)strlen(cmd); + char* newcmd = (char*)emalloc((len + 1) * sizeof(char), "_dbg_dbgcmdexec:newcmd"); + strcpy_s(newcmd, len + 1, cmd); + return MsgSend(gMsgStack, 0, (duint)newcmd, 0); +} + +static DWORD WINAPI DbgCommandLoopThread(void* a) +{ + cmdloop(cbBadCmd, cbCommandProvider, cmdfindmain, false); + return 0; +} + +extern "C" DLL_EXPORT const char* _dbg_dbginit() +{ + if (!EngineCheckStructAlignment(UE_STRUCT_TITAN_ENGINE_CONTEXT, sizeof(TITAN_ENGINE_CONTEXT_t))) + return "Invalid TITAN_ENGINE_CONTEXT_t alignment!"; + + if (sizeof(TITAN_ENGINE_CONTEXT_t) != sizeof(REGISTERCONTEXT)) + return "Invalid REGISTERCONTEXT alignment!"; + + dputs("Initializing wait objects..."); + waitinitialize(); + dputs("Initializing debugger..."); + dbginit(); + dputs("Initializing debugger functions..."); + dbgfunctionsinit(); + dputs("Setting JSON memory management functions..."); + json_set_alloc_funcs(json_malloc, json_free); + dputs("Initializing capstone..."); + Capstone::GlobalInitialize(); + dputs("Initializing Yara..."); + if(yr_initialize() != ERROR_SUCCESS) + return "Failed to initialize Yara!"; + dputs("Getting directory information..."); + wchar_t wszDir[deflen] = L""; + if(!GetModuleFileNameW(hInst, wszDir, deflen)) + return "GetModuleFileNameW failed!"; + char dir[deflen] = ""; + strcpy_s(dir, StringUtils::Utf16ToUtf8(wszDir).c_str()); + int len = (int)strlen(dir); + while(dir[len] != '\\') + len--; + dir[len] = 0; + strcpy_s(alloctrace, dir); + strcat_s(alloctrace, "\\alloctrace.txt"); + DeleteFileW(StringUtils::Utf8ToUtf16(alloctrace).c_str()); + setalloctrace(alloctrace); + + // Create database directory in the local debugger folder + DBSetPath(StringUtils::sprintf("%s\\db", dir).c_str(), nullptr); + + char szLocalSymbolPath[MAX_PATH] = ""; + strcpy_s(szLocalSymbolPath, dir); + strcat_s(szLocalSymbolPath, "\\symbols"); + + char cachePath[MAX_SETTING_SIZE]; + if(!BridgeSettingGet("Symbols", "CachePath", cachePath) || !*cachePath) + { + strcpy_s(szSymbolCachePath, szLocalSymbolPath); + BridgeSettingSet("Symbols", "CachePath", ".\\symbols"); + } + else + { + if(_strnicmp(cachePath, ".\\", 2) == 0) + { + strncpy_s(szSymbolCachePath, dir, _TRUNCATE); + strncat_s(szSymbolCachePath, cachePath + 1, _TRUNCATE); + } + else + { + // Trim the buffer to fit inside MAX_PATH + strncpy_s(szSymbolCachePath, cachePath, _TRUNCATE); + } + + if(strstr(szSymbolCachePath, "http://") || strstr(szSymbolCachePath, "https://")) + { + if(Script::Gui::MessageYesNo("It is strongly discouraged to use symbol servers in your path directly (use the store option instead).\n\nDo you want me to fix this?")) + { + strcpy_s(szSymbolCachePath, szLocalSymbolPath); + BridgeSettingSet("Symbols", "CachePath", ".\\symbols"); + } + } + } + dputs(szSymbolCachePath); + SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(dir).c_str()); + dputs("Allocating message stack..."); + gMsgStack = MsgAllocStack(); + if(!gMsgStack) + return "Could not allocate message stack!"; + dputs("Initializing global script variables..."); + varinit(); + dputs("Registering debugger commands..."); + registercommands(); + dputs("Starting command loop..."); + hCommandLoopThread = CreateThread(0, 0, DbgCommandLoopThread, 0, 0, 0); + char plugindir[deflen] = ""; + strcpy_s(plugindir, dir); + strcat_s(plugindir, "\\plugins"); + CreateDirectoryW(StringUtils::Utf8ToUtf16(plugindir).c_str(), 0); + dputs("Loading plugins..."); + pluginload(plugindir); + dputs("Handling command line..."); + //handle command line + int argc = 0; + wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc); + if(argc == 2) //we have an argument + { + String str = "init \""; + str += StringUtils::Utf16ToUtf8(argv[1]); + str += "\""; + DbgCmdExec(str.c_str()); + } + else if(argc == 5) //4 arguments (JIT) + { + if(_wcsicmp(argv[1], L"-a") == 0 && !_wcsicmp(argv[3], L"-e")) + { + String str = "attach ."; + str += StringUtils::Utf16ToUtf8(argv[2]); + str += ", ."; + str += StringUtils::Utf16ToUtf8(argv[4]); + DbgCmdExec(str.c_str()); + } + } + LocalFree(argv); + dputs("Reading notes file..."); + notesFile = String(dir) + "\\notes.txt"; + String text; + FileHelper::ReadAllText(notesFile, text); + GuiSetGlobalNotes(text.c_str()); + dputs("Initialization successful!"); + bIsStopped = false; + return nullptr; +} + +extern "C" DLL_EXPORT void _dbg_dbgexitsignal() +{ + dputs("Stopping running debuggee..."); + cbDebugStop(0, 0); + dputs("Aborting scripts..."); + scriptabort(); + dputs("Waiting for the debuggee to be stopped..."); + wait(WAITID_STOP); //after this, debugging stopped + dputs("Unloading plugins..."); + pluginunload(); + dputs("Stopping command thread..."); + bStopCommandLoopThread = true; + MsgFreeStack(gMsgStack); + WaitForThreadTermination(hCommandLoopThread); + dputs("Cleaning up allocated data..."); + cmdfree(); + varfree(); + yr_finalize(); + Capstone::GlobalFinalize(); + dputs("Checking for mem leaks..."); + if(memleaks()) + dprintf("%d memory leak(s) found!\n", memleaks()); + else + DeleteFileA(alloctrace); + dputs("Cleaning up wait objects..."); + waitdeinitialize(); + dputs("Cleaning up debugger threads..."); + dbgstop(); + dputs("Saving notes..."); + char* text = nullptr; + GuiGetGlobalNotes(&text); + if(text) + { + FileHelper::WriteAllText(notesFile, String(text)); + BridgeFree(text); + } + else + DeleteFileW(StringUtils::Utf8ToUtf16(notesFile).c_str()); + dputs("Exit signal processed successfully!"); + bIsStopped = true; +} + +extern "C" DLL_EXPORT bool _dbg_dbgcmddirectexec(const char* cmd) +{ + if(cmddirectexec(cmd) == STATUS_ERROR) + return false; + return true; +} + +bool dbgisstopped() +{ + return bIsStopped; } \ No newline at end of file diff --git a/src/dbg/x64_dbg.h b/src/dbg/x64_dbg.h index 8c06205f..cc7a5345 100644 --- a/src/dbg/x64_dbg.h +++ b/src/dbg/x64_dbg.h @@ -1,23 +1,23 @@ -#ifndef _X64_DBG_H -#define _X64_DBG_H - -#include -#include "_global.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -DLL_EXPORT const char* _dbg_dbginit(); -DLL_EXPORT bool _dbg_dbgcmdexec(const char* cmd); -DLL_EXPORT bool _dbg_dbgcmddirectexec(const char* cmd); -DLL_EXPORT void _dbg_dbgexitsignal(); - -#ifdef __cplusplus -} -#endif - -bool dbgisstopped(); - -#endif // _X64_DBG_H +#ifndef _X64_DBG_H +#define _X64_DBG_H + +#include +#include "_global.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +DLL_EXPORT const char* _dbg_dbginit(); +DLL_EXPORT bool _dbg_dbgcmdexec(const char* cmd); +DLL_EXPORT bool _dbg_dbgcmddirectexec(const char* cmd); +DLL_EXPORT void _dbg_dbgexitsignal(); + +#ifdef __cplusplus +} +#endif + +bool dbgisstopped(); + +#endif // _X64_DBG_H diff --git a/src/dbg/x64_dbg_dbg.vcxproj b/src/dbg/x64_dbg_dbg.vcxproj index a3e52241..4b3241a1 100644 --- a/src/dbg/x64_dbg_dbg.vcxproj +++ b/src/dbg/x64_dbg_dbg.vcxproj @@ -1,378 +1,378 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {E6548308-401E-3A8A-5819-905DB90522A6} - Win32Proj - - - - DynamicLibrary - false - v120_xp - - - DynamicLibrary - false - v120_xp - - - DynamicLibrary - false - v120_xp - - - DynamicLibrary - false - v120_xp - - - - - - - - - - - - - - - - - - - false - $(ProjectDir)..\..\bin\x32\ - $(Platform)\$(Configuration)\ - x32dbg - $(ProjectDir)..\capstone_wrapper;$(IncludePath) - - - false - $(ProjectDir)..\..\bin\x32\ - $(Platform)\$(Configuration)\ - x32dbg - $(ProjectDir)..\capstone_wrapper;$(IncludePath) - - - false - $(ProjectDir)..\..\bin\x64\ - x64dbg - $(ProjectDir)..\capstone_wrapper;$(IncludePath) - - - false - $(ProjectDir)..\..\bin\x64\ - x64dbg - $(ProjectDir)..\capstone_wrapper;$(IncludePath) - - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;BUILD_DBG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDLL - Level3 - ProgramDatabase - true - MultiFile - true - true - AVXI - None - None - true - Speed - - - MachineX86 - true - Windows - true - true - $(ProjectDir)..\..\bin\x32\capstone_wrapper.lib;capstone\capstone_x86.lib;yara\yara_x86.lib;lz4\lz4_x86.lib;jansson\jansson_x86.lib;DeviceNameResolver\DeviceNameResolver_x86.lib;XEDParse\XEDParse_x86.lib;$(SolutionDir)bin\x32\x32bridge.lib;dbghelp\dbghelp_x86.lib;TitanEngine\TitanEngine_x86.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies) - - - - - WIN32;_DEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;BUILD_DBG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level3 - ProgramDatabase - true - NoIPO - false - true - Disabled - - - MachineX86 - true - Windows - false - false - $(ProjectDir)..\..\bin\x32\capstone_wrapper.lib;capstone\capstone_x86.lib;yara\yara_x86.lib;lz4\lz4_x86.lib;jansson\jansson_x86.lib;DeviceNameResolver\DeviceNameResolver_x86.lib;XEDParse\XEDParse_x86.lib;$(SolutionDir)bin\x32\x32bridge.lib;dbghelp\dbghelp_x86.lib;TitanEngine\TitanEngine_x86.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies) - - - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;BUILD_DBG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDLL - Level3 - ProgramDatabase - true - MultiFile - true - true - AVXI - None - None - true - Speed - AVXI - false - None - - - true - Windows - true - true - $(ProjectDir)..\..\bin\x64\capstone_wrapper.lib;capstone\capstone_x64.lib;yara\yara_x64.lib;lz4\lz4_x64.lib;jansson\jansson_x64.lib;DeviceNameResolver\DeviceNameResolver_x64.lib;XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64\x64bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies) - - - - - WIN32;_DEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;BUILD_DBG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level3 - ProgramDatabase - true - NoIPO - false - false - Disabled - None - None - false - true - - - true - Windows - false - false - $(ProjectDir)..\..\bin\x64\capstone_wrapper.lib;capstone\capstone_x64.lib;yara\yara_x64.lib;lz4\lz4_x64.lib;jansson\jansson_x64.lib;DeviceNameResolver\DeviceNameResolver_x64.lib;XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64\x64bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies) - - - - - + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {E6548308-401E-3A8A-5819-905DB90522A6} + Win32Proj + + + + DynamicLibrary + false + v120_xp + + + DynamicLibrary + false + v120_xp + + + DynamicLibrary + false + v120_xp + + + DynamicLibrary + false + v120_xp + + + + + + + + + + + + + + + + + + + false + $(ProjectDir)..\..\bin\x32\ + $(Platform)\$(Configuration)\ + x32dbg + $(ProjectDir)..\capstone_wrapper;$(IncludePath) + + + false + $(ProjectDir)..\..\bin\x32\ + $(Platform)\$(Configuration)\ + x32dbg + $(ProjectDir)..\capstone_wrapper;$(IncludePath) + + + false + $(ProjectDir)..\..\bin\x64\ + x64dbg + $(ProjectDir)..\capstone_wrapper;$(IncludePath) + + + false + $(ProjectDir)..\..\bin\x64\ + x64dbg + $(ProjectDir)..\capstone_wrapper;$(IncludePath) + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;BUILD_DBG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + true + MultiFile + true + true + AVXI + None + None + true + Speed + + + MachineX86 + true + Windows + true + true + $(ProjectDir)..\..\bin\x32\capstone_wrapper.lib;capstone\capstone_x86.lib;yara\yara_x86.lib;lz4\lz4_x86.lib;jansson\jansson_x86.lib;DeviceNameResolver\DeviceNameResolver_x86.lib;XEDParse\XEDParse_x86.lib;$(SolutionDir)bin\x32\x32bridge.lib;dbghelp\dbghelp_x86.lib;TitanEngine\TitanEngine_x86.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies) + + + + + WIN32;_DEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;BUILD_DBG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + true + NoIPO + false + true + Disabled + + + MachineX86 + true + Windows + false + false + $(ProjectDir)..\..\bin\x32\capstone_wrapper.lib;capstone\capstone_x86.lib;yara\yara_x86.lib;lz4\lz4_x86.lib;jansson\jansson_x86.lib;DeviceNameResolver\DeviceNameResolver_x86.lib;XEDParse\XEDParse_x86.lib;$(SolutionDir)bin\x32\x32bridge.lib;dbghelp\dbghelp_x86.lib;TitanEngine\TitanEngine_x86.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies) + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;BUILD_DBG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + true + MultiFile + true + true + AVXI + None + None + true + Speed + AVXI + false + None + + + true + Windows + true + true + $(ProjectDir)..\..\bin\x64\capstone_wrapper.lib;capstone\capstone_x64.lib;yara\yara_x64.lib;lz4\lz4_x64.lib;jansson\jansson_x64.lib;DeviceNameResolver\DeviceNameResolver_x64.lib;XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64\x64bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies) + + + + + WIN32;_DEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;BUILD_DBG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + true + NoIPO + false + false + Disabled + None + None + false + true + + + true + Windows + false + false + $(ProjectDir)..\..\bin\x64\capstone_wrapper.lib;capstone\capstone_x64.lib;yara\yara_x64.lib;lz4\lz4_x64.lib;jansson\jansson_x64.lib;DeviceNameResolver\DeviceNameResolver_x64.lib;XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64\x64bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies) + + + + + \ No newline at end of file diff --git a/src/dbg/yara/yara.h b/src/dbg/yara/yara.h index 0a176bbb..6542bbf3 100644 --- a/src/dbg/yara/yara.h +++ b/src/dbg/yara/yara.h @@ -1,28 +1,28 @@ -/* -Copyright (c) 2007-2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_YARA_H -#define YR_YARA_H - -#include "yara/utils.h" -#include "yara/filemap.h" -#include "yara/compiler.h" -#include "yara/modules.h" -#include "yara/object.h" -#include "yara/libyara.h" -#include "yara/error.h" - -#endif +/* +Copyright (c) 2007-2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_YARA_H +#define YR_YARA_H + +#include "yara/utils.h" +#include "yara/filemap.h" +#include "yara/compiler.h" +#include "yara/modules.h" +#include "yara/object.h" +#include "yara/libyara.h" +#include "yara/error.h" + +#endif diff --git a/src/dbg/yara/yara/ahocorasick.h b/src/dbg/yara/yara/ahocorasick.h index 7d88413d..032ce10e 100644 --- a/src/dbg/yara/yara/ahocorasick.h +++ b/src/dbg/yara/yara/ahocorasick.h @@ -1,50 +1,50 @@ -/* -Copyright (c) 2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _AHOCORASICK_H -#define _AHOCORASICK_H - -#include "limits.h" -#include "atoms.h" -#include "types.h" - - -int yr_ac_create_automaton( - YR_ARENA* arena, - YR_AC_AUTOMATON** automaton); - - -int yr_ac_add_string( - YR_ARENA* arena, - YR_AC_AUTOMATON* automaton, - YR_STRING* string, - YR_ATOM_LIST_ITEM* atom); - - -YR_AC_STATE* yr_ac_next_state( - YR_AC_STATE* state, - uint8_t input); - - -int yr_ac_create_failure_links( - YR_ARENA* arena, - YR_AC_AUTOMATON* automaton); - - -void yr_ac_print_automaton( - YR_AC_AUTOMATON* automaton); - -#endif +/* +Copyright (c) 2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _AHOCORASICK_H +#define _AHOCORASICK_H + +#include "limits.h" +#include "atoms.h" +#include "types.h" + + +int yr_ac_create_automaton( + YR_ARENA* arena, + YR_AC_AUTOMATON** automaton); + + +int yr_ac_add_string( + YR_ARENA* arena, + YR_AC_AUTOMATON* automaton, + YR_STRING* string, + YR_ATOM_LIST_ITEM* atom); + + +YR_AC_STATE* yr_ac_next_state( + YR_AC_STATE* state, + uint8_t input); + + +int yr_ac_create_failure_links( + YR_ARENA* arena, + YR_AC_AUTOMATON* automaton); + + +void yr_ac_print_automaton( + YR_AC_AUTOMATON* automaton); + +#endif diff --git a/src/dbg/yara/yara/arena.h b/src/dbg/yara/yara/arena.h index acc7d6f4..62a8b67d 100644 --- a/src/dbg/yara/yara/arena.h +++ b/src/dbg/yara/yara/arena.h @@ -1,151 +1,151 @@ -/* -Copyright (c) 2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_ARENA_H -#define YR_ARENA_H - -#include -#include - - -#define ARENA_FLAGS_FIXED_SIZE 1 -#define ARENA_FLAGS_COALESCED 2 -#define ARENA_FILE_VERSION 6 - -#define EOL ((size_t) -1) - - -typedef struct _YR_RELOC -{ - int32_t offset; - struct _YR_RELOC* next; - -} YR_RELOC; - - -typedef struct _YR_ARENA_PAGE -{ - - uint8_t* new_address; - uint8_t* address; - - size_t size; - size_t used; - - YR_RELOC* reloc_list_head; - YR_RELOC* reloc_list_tail; - - struct _YR_ARENA_PAGE* next; - struct _YR_ARENA_PAGE* prev; - -} YR_ARENA_PAGE; - - -typedef struct _YR_ARENA -{ - int flags; - - YR_ARENA_PAGE* page_list_head; - YR_ARENA_PAGE* current_page; - -} YR_ARENA; - - -int yr_arena_create( - size_t initial_size, - int flags, - YR_ARENA** arena); - - -void yr_arena_destroy( - YR_ARENA* arena); - - -void* yr_arena_base_address( - YR_ARENA* arena); - - -void* yr_arena_next_address( - YR_ARENA* arena, - void* address, - int offset); - - -int yr_arena_coalesce( - YR_ARENA* arena); - - -int yr_arena_reserve_memory( - YR_ARENA* arena, - size_t size); - - -int yr_arena_allocate_memory( - YR_ARENA* arena, - size_t size, - void** allocated_memory); - - -int yr_arena_allocate_struct( - YR_ARENA* arena, - size_t size, - void** allocated_memory, - ...); - - -int yr_arena_make_relocatable( - YR_ARENA* arena, - void* base, - ...); - - -int yr_arena_write_data( - YR_ARENA* arena, - void* data, - size_t size, - void** written_data); - - -int yr_arena_write_string( - YR_ARENA* arena, - const char* string, - char** written_string); - - -int yr_arena_append( - YR_ARENA* target_arena, - YR_ARENA* source_arena); - - -int yr_arena_save( - YR_ARENA* arena, - const char* filename); - - -int yr_arena_load( - const char* filename, - YR_ARENA** arena); - - -int yr_arena_duplicate( - YR_ARENA* arena, - YR_ARENA** duplicated); - - -void yr_arena_print( - YR_ARENA* arena); - -#endif +/* +Copyright (c) 2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_ARENA_H +#define YR_ARENA_H + +#include +#include + + +#define ARENA_FLAGS_FIXED_SIZE 1 +#define ARENA_FLAGS_COALESCED 2 +#define ARENA_FILE_VERSION 6 + +#define EOL ((size_t) -1) + + +typedef struct _YR_RELOC +{ + int32_t offset; + struct _YR_RELOC* next; + +} YR_RELOC; + + +typedef struct _YR_ARENA_PAGE +{ + + uint8_t* new_address; + uint8_t* address; + + size_t size; + size_t used; + + YR_RELOC* reloc_list_head; + YR_RELOC* reloc_list_tail; + + struct _YR_ARENA_PAGE* next; + struct _YR_ARENA_PAGE* prev; + +} YR_ARENA_PAGE; + + +typedef struct _YR_ARENA +{ + int flags; + + YR_ARENA_PAGE* page_list_head; + YR_ARENA_PAGE* current_page; + +} YR_ARENA; + + +int yr_arena_create( + size_t initial_size, + int flags, + YR_ARENA** arena); + + +void yr_arena_destroy( + YR_ARENA* arena); + + +void* yr_arena_base_address( + YR_ARENA* arena); + + +void* yr_arena_next_address( + YR_ARENA* arena, + void* address, + int offset); + + +int yr_arena_coalesce( + YR_ARENA* arena); + + +int yr_arena_reserve_memory( + YR_ARENA* arena, + size_t size); + + +int yr_arena_allocate_memory( + YR_ARENA* arena, + size_t size, + void** allocated_memory); + + +int yr_arena_allocate_struct( + YR_ARENA* arena, + size_t size, + void** allocated_memory, + ...); + + +int yr_arena_make_relocatable( + YR_ARENA* arena, + void* base, + ...); + + +int yr_arena_write_data( + YR_ARENA* arena, + void* data, + size_t size, + void** written_data); + + +int yr_arena_write_string( + YR_ARENA* arena, + const char* string, + char** written_string); + + +int yr_arena_append( + YR_ARENA* target_arena, + YR_ARENA* source_arena); + + +int yr_arena_save( + YR_ARENA* arena, + const char* filename); + + +int yr_arena_load( + const char* filename, + YR_ARENA** arena); + + +int yr_arena_duplicate( + YR_ARENA* arena, + YR_ARENA** duplicated); + + +void yr_arena_print( + YR_ARENA* arena); + +#endif diff --git a/src/dbg/yara/yara/atoms.h b/src/dbg/yara/yara/atoms.h index f0625cec..fd38d06b 100644 --- a/src/dbg/yara/yara/atoms.h +++ b/src/dbg/yara/yara/atoms.h @@ -1,89 +1,89 @@ -/* -Copyright (c) 2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_ATOMS_H -#define YR_ATOMS_H - -#include "limits.h" -#include "re.h" - -#define ATOM_TREE_LEAF 1 -#define ATOM_TREE_AND 2 -#define ATOM_TREE_OR 3 - - -typedef struct _ATOM_TREE_NODE -{ - uint8_t type; - uint8_t atom_length; - uint8_t atom[MAX_ATOM_LENGTH]; - - uint8_t* forward_code; - uint8_t* backward_code; - - RE_NODE* recent_nodes[MAX_ATOM_LENGTH]; - - struct _ATOM_TREE_NODE* children_head; - struct _ATOM_TREE_NODE* children_tail; - struct _ATOM_TREE_NODE* next_sibling; - -} ATOM_TREE_NODE; - - -typedef struct _ATOM_TREE -{ - ATOM_TREE_NODE* current_leaf; - ATOM_TREE_NODE* root_node; - -} ATOM_TREE; - - -typedef struct _YR_ATOM_LIST_ITEM -{ - uint8_t atom_length; - uint8_t atom[MAX_ATOM_LENGTH]; - - uint16_t backtrack; - - uint8_t* forward_code; - uint8_t* backward_code; - - struct _YR_ATOM_LIST_ITEM* next; - -} YR_ATOM_LIST_ITEM; - - -int yr_atoms_extract_from_re( - RE* re, - int flags, - YR_ATOM_LIST_ITEM** atoms); - - -int yr_atoms_extract_from_string( - uint8_t* string, - int string_length, - int flags, - YR_ATOM_LIST_ITEM** atoms); - - -int yr_atoms_min_quality( - YR_ATOM_LIST_ITEM* atom_list); - - -void yr_atoms_list_destroy( - YR_ATOM_LIST_ITEM* list_head); - -#endif +/* +Copyright (c) 2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_ATOMS_H +#define YR_ATOMS_H + +#include "limits.h" +#include "re.h" + +#define ATOM_TREE_LEAF 1 +#define ATOM_TREE_AND 2 +#define ATOM_TREE_OR 3 + + +typedef struct _ATOM_TREE_NODE +{ + uint8_t type; + uint8_t atom_length; + uint8_t atom[MAX_ATOM_LENGTH]; + + uint8_t* forward_code; + uint8_t* backward_code; + + RE_NODE* recent_nodes[MAX_ATOM_LENGTH]; + + struct _ATOM_TREE_NODE* children_head; + struct _ATOM_TREE_NODE* children_tail; + struct _ATOM_TREE_NODE* next_sibling; + +} ATOM_TREE_NODE; + + +typedef struct _ATOM_TREE +{ + ATOM_TREE_NODE* current_leaf; + ATOM_TREE_NODE* root_node; + +} ATOM_TREE; + + +typedef struct _YR_ATOM_LIST_ITEM +{ + uint8_t atom_length; + uint8_t atom[MAX_ATOM_LENGTH]; + + uint16_t backtrack; + + uint8_t* forward_code; + uint8_t* backward_code; + + struct _YR_ATOM_LIST_ITEM* next; + +} YR_ATOM_LIST_ITEM; + + +int yr_atoms_extract_from_re( + RE* re, + int flags, + YR_ATOM_LIST_ITEM** atoms); + + +int yr_atoms_extract_from_string( + uint8_t* string, + int string_length, + int flags, + YR_ATOM_LIST_ITEM** atoms); + + +int yr_atoms_min_quality( + YR_ATOM_LIST_ITEM* atom_list); + + +void yr_atoms_list_destroy( + YR_ATOM_LIST_ITEM* list_head); + +#endif diff --git a/src/dbg/yara/yara/compiler.h b/src/dbg/yara/yara/compiler.h index e7d29f09..b2ece9c7 100644 --- a/src/dbg/yara/yara/compiler.h +++ b/src/dbg/yara/yara/compiler.h @@ -1,196 +1,196 @@ -/* -Copyright (c) 2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_COMPILER_H -#define YR_COMPILER_H - -#include -#include - -#include "ahocorasick.h" -#include "arena.h" -#include "hash.h" -#include "utils.h" - - -#define YARA_ERROR_LEVEL_ERROR 0 -#define YARA_ERROR_LEVEL_WARNING 1 - - -typedef void (*YR_COMPILER_CALLBACK_FUNC)( - int error_level, - const char* file_name, - int line_number, - const char* message, - void* user_data); - - -typedef struct _YR_COMPILER -{ - int errors; - int error_line; - int last_error; - int last_error_line; - int last_result; - - jmp_buf error_recovery; - - YR_ARENA* sz_arena; - YR_ARENA* rules_arena; - YR_ARENA* strings_arena; - YR_ARENA* code_arena; - YR_ARENA* re_code_arena; - YR_ARENA* automaton_arena; - YR_ARENA* compiled_rules_arena; - YR_ARENA* externals_arena; - YR_ARENA* namespaces_arena; - YR_ARENA* metas_arena; - - YR_AC_AUTOMATON* automaton; - YR_HASH_TABLE* rules_table; - YR_HASH_TABLE* objects_table; - YR_NAMESPACE* current_namespace; - YR_STRING* current_rule_strings; - - int current_rule_flags; - int namespaces_count; - - int8_t* loop_address[MAX_LOOP_NESTING]; - char* loop_identifier[MAX_LOOP_NESTING]; - int loop_depth; - int loop_for_of_mem_offset; - - int allow_includes; - - char* file_name_stack[MAX_INCLUDE_DEPTH]; - int file_name_stack_ptr; - - FILE* file_stack[MAX_INCLUDE_DEPTH]; - int file_stack_ptr; - - char last_error_extra_info[MAX_COMPILER_ERROR_EXTRA_INFO]; - - char lex_buf[LEX_BUF_SIZE]; - char* lex_buf_ptr; - unsigned short lex_buf_len; - - char include_base_dir[MAX_PATH]; - void* user_data; - - YR_COMPILER_CALLBACK_FUNC callback; - -} YR_COMPILER; - - -#define yr_compiler_set_error_extra_info(compiler, info) \ - strlcpy( \ - compiler->last_error_extra_info, \ - info, \ - sizeof(compiler->last_error_extra_info)); \ - - -#define yr_compiler_set_error_extra_info_fmt(compiler, fmt, ...) \ - snprintf( \ - compiler->last_error_extra_info, \ - sizeof(compiler->last_error_extra_info), \ - fmt, __VA_ARGS__); - - -int _yr_compiler_push_file( - YR_COMPILER* compiler, - FILE* fh); - - -FILE* _yr_compiler_pop_file( - YR_COMPILER* compiler); - - -int _yr_compiler_push_file_name( - YR_COMPILER* compiler, - const char* file_name); - - -void _yr_compiler_pop_file_name( - YR_COMPILER* compiler); - - -YR_API int yr_compiler_create( - YR_COMPILER** compiler); - - -YR_API void yr_compiler_destroy( - YR_COMPILER* compiler); - - -YR_API void yr_compiler_set_callback( - YR_COMPILER* compiler, - YR_COMPILER_CALLBACK_FUNC callback, - void* user_data); - - -YR_API int yr_compiler_add_file( - YR_COMPILER* compiler, - FILE* rules_file, - const char* namespace_, - const char* file_name); - - -YR_API int yr_compiler_add_string( - YR_COMPILER* compiler, - const char* rules_string, - const char* namespace_); - - -YR_API char* yr_compiler_get_error_message( - YR_COMPILER* compiler, - char* buffer, - int buffer_size); - - -YR_API char* yr_compiler_get_current_file_name( - YR_COMPILER* context); - - -YR_API int yr_compiler_define_integer_variable( - YR_COMPILER* compiler, - const char* identifier, - int64_t value); - - -YR_API int yr_compiler_define_boolean_variable( - YR_COMPILER* compiler, - const char* identifier, - int value); - - -YR_API int yr_compiler_define_float_variable( - YR_COMPILER* compiler, - const char* identifier, - double value); - - -YR_API int yr_compiler_define_string_variable( - YR_COMPILER* compiler, - const char* identifier, - const char* value); - - -YR_API int yr_compiler_get_rules( - YR_COMPILER* compiler, - YR_RULES** rules); - - -#endif +/* +Copyright (c) 2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_COMPILER_H +#define YR_COMPILER_H + +#include +#include + +#include "ahocorasick.h" +#include "arena.h" +#include "hash.h" +#include "utils.h" + + +#define YARA_ERROR_LEVEL_ERROR 0 +#define YARA_ERROR_LEVEL_WARNING 1 + + +typedef void (*YR_COMPILER_CALLBACK_FUNC)( + int error_level, + const char* file_name, + int line_number, + const char* message, + void* user_data); + + +typedef struct _YR_COMPILER +{ + int errors; + int error_line; + int last_error; + int last_error_line; + int last_result; + + jmp_buf error_recovery; + + YR_ARENA* sz_arena; + YR_ARENA* rules_arena; + YR_ARENA* strings_arena; + YR_ARENA* code_arena; + YR_ARENA* re_code_arena; + YR_ARENA* automaton_arena; + YR_ARENA* compiled_rules_arena; + YR_ARENA* externals_arena; + YR_ARENA* namespaces_arena; + YR_ARENA* metas_arena; + + YR_AC_AUTOMATON* automaton; + YR_HASH_TABLE* rules_table; + YR_HASH_TABLE* objects_table; + YR_NAMESPACE* current_namespace; + YR_STRING* current_rule_strings; + + int current_rule_flags; + int namespaces_count; + + int8_t* loop_address[MAX_LOOP_NESTING]; + char* loop_identifier[MAX_LOOP_NESTING]; + int loop_depth; + int loop_for_of_mem_offset; + + int allow_includes; + + char* file_name_stack[MAX_INCLUDE_DEPTH]; + int file_name_stack_ptr; + + FILE* file_stack[MAX_INCLUDE_DEPTH]; + int file_stack_ptr; + + char last_error_extra_info[MAX_COMPILER_ERROR_EXTRA_INFO]; + + char lex_buf[LEX_BUF_SIZE]; + char* lex_buf_ptr; + unsigned short lex_buf_len; + + char include_base_dir[MAX_PATH]; + void* user_data; + + YR_COMPILER_CALLBACK_FUNC callback; + +} YR_COMPILER; + + +#define yr_compiler_set_error_extra_info(compiler, info) \ + strlcpy( \ + compiler->last_error_extra_info, \ + info, \ + sizeof(compiler->last_error_extra_info)); \ + + +#define yr_compiler_set_error_extra_info_fmt(compiler, fmt, ...) \ + snprintf( \ + compiler->last_error_extra_info, \ + sizeof(compiler->last_error_extra_info), \ + fmt, __VA_ARGS__); + + +int _yr_compiler_push_file( + YR_COMPILER* compiler, + FILE* fh); + + +FILE* _yr_compiler_pop_file( + YR_COMPILER* compiler); + + +int _yr_compiler_push_file_name( + YR_COMPILER* compiler, + const char* file_name); + + +void _yr_compiler_pop_file_name( + YR_COMPILER* compiler); + + +YR_API int yr_compiler_create( + YR_COMPILER** compiler); + + +YR_API void yr_compiler_destroy( + YR_COMPILER* compiler); + + +YR_API void yr_compiler_set_callback( + YR_COMPILER* compiler, + YR_COMPILER_CALLBACK_FUNC callback, + void* user_data); + + +YR_API int yr_compiler_add_file( + YR_COMPILER* compiler, + FILE* rules_file, + const char* namespace_, + const char* file_name); + + +YR_API int yr_compiler_add_string( + YR_COMPILER* compiler, + const char* rules_string, + const char* namespace_); + + +YR_API char* yr_compiler_get_error_message( + YR_COMPILER* compiler, + char* buffer, + int buffer_size); + + +YR_API char* yr_compiler_get_current_file_name( + YR_COMPILER* context); + + +YR_API int yr_compiler_define_integer_variable( + YR_COMPILER* compiler, + const char* identifier, + int64_t value); + + +YR_API int yr_compiler_define_boolean_variable( + YR_COMPILER* compiler, + const char* identifier, + int value); + + +YR_API int yr_compiler_define_float_variable( + YR_COMPILER* compiler, + const char* identifier, + double value); + + +YR_API int yr_compiler_define_string_variable( + YR_COMPILER* compiler, + const char* identifier, + const char* value); + + +YR_API int yr_compiler_get_rules( + YR_COMPILER* compiler, + YR_RULES** rules); + + +#endif diff --git a/src/dbg/yara/yara/elf.h b/src/dbg/yara/yara/elf.h index 973a57d2..5f6515ea 100644 --- a/src/dbg/yara/yara/elf.h +++ b/src/dbg/yara/yara/elf.h @@ -1,202 +1,202 @@ -/* -Copyright (c) 2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _ELF_H -#define _ELF_H - -#include - - -// 32-bit ELF base types - -typedef uint32_t elf32_addr_t; -typedef uint16_t elf32_half_t; -typedef uint32_t elf32_off_t; -typedef uint32_t elf32_word_t; - -// 64-bit ELF base types - -typedef uint64_t elf64_addr_t; -typedef uint16_t elf64_half_t; -typedef uint64_t elf64_off_t; -typedef uint32_t elf64_word_t; -typedef uint64_t elf64_xword_t; - -#define ELF_MAGIC 0x464C457F - -#define ELF_ET_NONE 0x0000 // no type -#define ELF_ET_REL 0x0001 // relocatable -#define ELF_ET_EXEC 0x0002 // executeable -#define ELF_ET_DYN 0x0003 // Shared-Object-File -#define ELF_ET_CORE 0x0004 // Corefile -#define ELF_ET_LOPROC 0xFF00 // Processor-specific -#define ELF_ET_HIPROC 0x00FF // Processor-specific - -#define ELF_EM_NONE 0x0000 // no type -#define ELF_EM_M32 0x0001 // AT&T WE 32100 -#define ELF_EM_SPARC 0x0002 // SPARC -#define ELF_EM_386 0x0003 // Intel 80386 -#define ELF_EM_68K 0x0004 // Motorola 68000 -#define ELF_EM_88K 0x0005 // Motorola 88000 -#define ELF_EM_860 0x0007 // Intel 80860 -#define ELF_EM_MIPS 0x0008 // MIPS RS3000 -#define ELF_EM_ARM 0x0032 // ARM -#define ELF_EM_X86_64 0x003E // AMD/Intel x86_64 - -#define ELF_CLASS_NONE 0x0000 -#define ELF_CLASS_32 0x0001 // 32bit file -#define ELF_CLASS_64 0x0002 // 64bit file - -#define ELF_DATA_NONE 0x0000 -#define ELF_DATA_2LSB 0x0001 -#define ELF_DATA_2MSB 0x002 - - -#define ELF_SHT_NULL 0 // Section header table entry unused -#define ELF_SHT_PROGBITS 1 // Program data -#define ELF_SHT_SYMTAB 2 // Symbol table -#define ELF_SHT_STRTAB 3 // String table -#define ELF_SHT_RELA 4 // Relocation entries with addends -#define ELF_SHT_HASH 5 // Symbol hash table -#define ELF_SHT_DYNAMIC 6 // Dynamic linking information -#define ELF_SHT_NOTE 7 // Notes -#define ELF_SHT_NOBITS 8 // Program space with no data (bss) -#define ELF_SHT_REL 9 // Relocation entries, no addends -#define ELF_SHT_SHLIB 10 // Reserved -#define ELF_SHT_DYNSYM 11 // Dynamic linker symbol table -#define ELF_SHT_NUM 12 // Number of defined types - -#define ELF_SHF_WRITE 0x1 // Section is writable -#define ELF_SHF_ALLOC 0x2 // Section is present during execution -#define ELF_SHF_EXECINSTR 0x4 // Section contains executable instructions - -#pragma pack(push,1) - -typedef struct -{ - uint32_t magic; - uint8_t _class; - uint8_t data; - uint8_t version; - uint8_t pad[8]; - uint8_t nident; - -} elf_ident_t; - - -typedef struct -{ - elf_ident_t ident; - elf32_half_t type; - elf32_half_t machine; - elf32_word_t version; - elf32_addr_t entry; - elf32_off_t ph_offset; - elf32_off_t sh_offset; - elf32_word_t flags; - elf32_half_t header_size; - elf32_half_t ph_entry_size; - elf32_half_t ph_entry_count; - elf32_half_t sh_entry_size; - elf32_half_t sh_entry_count; - elf32_half_t sh_str_table_index; - -} elf32_header_t; - - -typedef struct -{ - elf_ident_t ident; - elf64_half_t type; - elf64_half_t machine; - elf64_word_t version; - elf64_addr_t entry; - elf64_off_t ph_offset; - elf64_off_t sh_offset; - elf64_word_t flags; - elf64_half_t header_size; - elf64_half_t ph_entry_size; - elf64_half_t ph_entry_count; - elf64_half_t sh_entry_size; - elf64_half_t sh_entry_count; - elf64_half_t sh_str_table_index; - -} elf64_header_t; - - -typedef struct -{ - elf32_word_t type; - elf32_off_t offset; - elf32_addr_t virt_addr; - elf32_addr_t phys_addr; - elf32_word_t file_size; - elf32_word_t mem_size; - elf32_word_t flags; - elf32_word_t alignment; - -} elf32_program_header_t; - - -typedef struct -{ - elf64_word_t type; - elf64_word_t flags; - elf64_off_t offset; - elf64_addr_t virt_addr; - elf64_addr_t phys_addr; - elf64_xword_t file_size; - elf64_xword_t mem_size; - elf64_xword_t alignment; - -} elf64_program_header_t; - - -typedef struct -{ - elf32_word_t name; - elf32_word_t type; - elf32_word_t flags; - elf32_addr_t addr; - elf32_off_t offset; - elf32_word_t size; - elf32_word_t link; - elf32_word_t info; - elf32_word_t align; - elf32_word_t entry_size; - -} elf32_section_header_t; - - -typedef struct -{ - elf64_word_t name; - elf64_word_t type; - elf64_xword_t flags; - elf64_addr_t addr; - elf64_off_t offset; - elf64_xword_t size; - elf64_word_t link; - elf64_word_t info; - elf64_xword_t align; - elf64_xword_t entry_size; - -} elf64_section_header_t; - - -#pragma pack(pop) - -#endif +/* +Copyright (c) 2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _ELF_H +#define _ELF_H + +#include + + +// 32-bit ELF base types + +typedef uint32_t elf32_addr_t; +typedef uint16_t elf32_half_t; +typedef uint32_t elf32_off_t; +typedef uint32_t elf32_word_t; + +// 64-bit ELF base types + +typedef uint64_t elf64_addr_t; +typedef uint16_t elf64_half_t; +typedef uint64_t elf64_off_t; +typedef uint32_t elf64_word_t; +typedef uint64_t elf64_xword_t; + +#define ELF_MAGIC 0x464C457F + +#define ELF_ET_NONE 0x0000 // no type +#define ELF_ET_REL 0x0001 // relocatable +#define ELF_ET_EXEC 0x0002 // executeable +#define ELF_ET_DYN 0x0003 // Shared-Object-File +#define ELF_ET_CORE 0x0004 // Corefile +#define ELF_ET_LOPROC 0xFF00 // Processor-specific +#define ELF_ET_HIPROC 0x00FF // Processor-specific + +#define ELF_EM_NONE 0x0000 // no type +#define ELF_EM_M32 0x0001 // AT&T WE 32100 +#define ELF_EM_SPARC 0x0002 // SPARC +#define ELF_EM_386 0x0003 // Intel 80386 +#define ELF_EM_68K 0x0004 // Motorola 68000 +#define ELF_EM_88K 0x0005 // Motorola 88000 +#define ELF_EM_860 0x0007 // Intel 80860 +#define ELF_EM_MIPS 0x0008 // MIPS RS3000 +#define ELF_EM_ARM 0x0032 // ARM +#define ELF_EM_X86_64 0x003E // AMD/Intel x86_64 + +#define ELF_CLASS_NONE 0x0000 +#define ELF_CLASS_32 0x0001 // 32bit file +#define ELF_CLASS_64 0x0002 // 64bit file + +#define ELF_DATA_NONE 0x0000 +#define ELF_DATA_2LSB 0x0001 +#define ELF_DATA_2MSB 0x002 + + +#define ELF_SHT_NULL 0 // Section header table entry unused +#define ELF_SHT_PROGBITS 1 // Program data +#define ELF_SHT_SYMTAB 2 // Symbol table +#define ELF_SHT_STRTAB 3 // String table +#define ELF_SHT_RELA 4 // Relocation entries with addends +#define ELF_SHT_HASH 5 // Symbol hash table +#define ELF_SHT_DYNAMIC 6 // Dynamic linking information +#define ELF_SHT_NOTE 7 // Notes +#define ELF_SHT_NOBITS 8 // Program space with no data (bss) +#define ELF_SHT_REL 9 // Relocation entries, no addends +#define ELF_SHT_SHLIB 10 // Reserved +#define ELF_SHT_DYNSYM 11 // Dynamic linker symbol table +#define ELF_SHT_NUM 12 // Number of defined types + +#define ELF_SHF_WRITE 0x1 // Section is writable +#define ELF_SHF_ALLOC 0x2 // Section is present during execution +#define ELF_SHF_EXECINSTR 0x4 // Section contains executable instructions + +#pragma pack(push,1) + +typedef struct +{ + uint32_t magic; + uint8_t _class; + uint8_t data; + uint8_t version; + uint8_t pad[8]; + uint8_t nident; + +} elf_ident_t; + + +typedef struct +{ + elf_ident_t ident; + elf32_half_t type; + elf32_half_t machine; + elf32_word_t version; + elf32_addr_t entry; + elf32_off_t ph_offset; + elf32_off_t sh_offset; + elf32_word_t flags; + elf32_half_t header_size; + elf32_half_t ph_entry_size; + elf32_half_t ph_entry_count; + elf32_half_t sh_entry_size; + elf32_half_t sh_entry_count; + elf32_half_t sh_str_table_index; + +} elf32_header_t; + + +typedef struct +{ + elf_ident_t ident; + elf64_half_t type; + elf64_half_t machine; + elf64_word_t version; + elf64_addr_t entry; + elf64_off_t ph_offset; + elf64_off_t sh_offset; + elf64_word_t flags; + elf64_half_t header_size; + elf64_half_t ph_entry_size; + elf64_half_t ph_entry_count; + elf64_half_t sh_entry_size; + elf64_half_t sh_entry_count; + elf64_half_t sh_str_table_index; + +} elf64_header_t; + + +typedef struct +{ + elf32_word_t type; + elf32_off_t offset; + elf32_addr_t virt_addr; + elf32_addr_t phys_addr; + elf32_word_t file_size; + elf32_word_t mem_size; + elf32_word_t flags; + elf32_word_t alignment; + +} elf32_program_header_t; + + +typedef struct +{ + elf64_word_t type; + elf64_word_t flags; + elf64_off_t offset; + elf64_addr_t virt_addr; + elf64_addr_t phys_addr; + elf64_xword_t file_size; + elf64_xword_t mem_size; + elf64_xword_t alignment; + +} elf64_program_header_t; + + +typedef struct +{ + elf32_word_t name; + elf32_word_t type; + elf32_word_t flags; + elf32_addr_t addr; + elf32_off_t offset; + elf32_word_t size; + elf32_word_t link; + elf32_word_t info; + elf32_word_t align; + elf32_word_t entry_size; + +} elf32_section_header_t; + + +typedef struct +{ + elf64_word_t name; + elf64_word_t type; + elf64_xword_t flags; + elf64_addr_t addr; + elf64_off_t offset; + elf64_xword_t size; + elf64_word_t link; + elf64_word_t info; + elf64_xword_t align; + elf64_xword_t entry_size; + +} elf64_section_header_t; + + +#pragma pack(pop) + +#endif diff --git a/src/dbg/yara/yara/error.h b/src/dbg/yara/yara/error.h index 1e2b6f70..7f6a804b 100644 --- a/src/dbg/yara/yara/error.h +++ b/src/dbg/yara/yara/error.h @@ -1,100 +1,100 @@ -/* -Copyright (c) 2014. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_ERROR_H -#define YR_ERROR_H - -#include - -#ifndef ERROR_SUCCESS -#define ERROR_SUCCESS 0 -#endif - -#define ERROR_INSUFICIENT_MEMORY 1 -#define ERROR_COULD_NOT_ATTACH_TO_PROCESS 2 -#define ERROR_COULD_NOT_OPEN_FILE 3 -#define ERROR_COULD_NOT_MAP_FILE 4 -#define ERROR_INVALID_FILE 6 -#define ERROR_CORRUPT_FILE 7 -#define ERROR_UNSUPPORTED_FILE_VERSION 8 -#define ERROR_INVALID_REGULAR_EXPRESSION 9 -#define ERROR_INVALID_HEX_STRING 10 -#define ERROR_SYNTAX_ERROR 11 -#define ERROR_LOOP_NESTING_LIMIT_EXCEEDED 12 -#define ERROR_DUPLICATED_LOOP_IDENTIFIER 13 -#define ERROR_DUPLICATED_IDENTIFIER 14 -#define ERROR_DUPLICATED_TAG_IDENTIFIER 15 -#define ERROR_DUPLICATED_META_IDENTIFIER 16 -#define ERROR_DUPLICATED_STRING_IDENTIFIER 17 -#define ERROR_UNREFERENCED_STRING 18 -#define ERROR_UNDEFINED_STRING 19 -#define ERROR_UNDEFINED_IDENTIFIER 20 -#define ERROR_MISPLACED_ANONYMOUS_STRING 21 -#define ERROR_INCLUDES_CIRCULAR_REFERENCE 22 -#define ERROR_INCLUDE_DEPTH_EXCEEDED 23 -#define ERROR_WRONG_TYPE 24 -#define ERROR_EXEC_STACK_OVERFLOW 25 -#define ERROR_SCAN_TIMEOUT 26 -#define ERROR_TOO_MANY_SCAN_THREADS 27 -#define ERROR_CALLBACK_ERROR 28 -#define ERROR_INVALID_ARGUMENT 29 -#define ERROR_TOO_MANY_MATCHES 30 -#define ERROR_INTERNAL_FATAL_ERROR 31 -#define ERROR_NESTED_FOR_OF_LOOP 32 -#define ERROR_INVALID_FIELD_NAME 33 -#define ERROR_UNKNOWN_MODULE 34 -#define ERROR_NOT_A_STRUCTURE 35 -#define ERROR_NOT_INDEXABLE 36 -#define ERROR_NOT_A_FUNCTION 37 -#define ERROR_INVALID_FORMAT 38 -#define ERROR_TOO_MANY_ARGUMENTS 39 -#define ERROR_WRONG_ARGUMENTS 40 -#define ERROR_WRONG_RETURN_TYPE 41 -#define ERROR_DUPLICATED_STRUCTURE_MEMBER 42 - - -#define FAIL_ON_ERROR(x) { \ - int result = (x); \ - if (result != ERROR_SUCCESS) \ - return result; \ -} - -#define FAIL_ON_ERROR_WITH_CLEANUP(x, cleanup) { \ - int result = (x); \ - if (result != ERROR_SUCCESS) { \ - cleanup; \ - return result; \ - } \ -} - -#define FAIL_ON_COMPILER_ERROR(x) { \ - compiler->last_result = (x); \ - if (compiler->last_result != ERROR_SUCCESS) \ - return compiler->last_result; \ -} - - -#ifdef NDEBUG -#define assertf(expr, msg) ((void)0) -#else -#define assertf(expr, msg, ...) \ - if(!(expr)) { \ - fprintf(stderr, "%s:%d: " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ - abort(); \ - } -#endif - -#endif +/* +Copyright (c) 2014. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_ERROR_H +#define YR_ERROR_H + +#include + +#ifndef ERROR_SUCCESS +#define ERROR_SUCCESS 0 +#endif + +#define ERROR_INSUFICIENT_MEMORY 1 +#define ERROR_COULD_NOT_ATTACH_TO_PROCESS 2 +#define ERROR_COULD_NOT_OPEN_FILE 3 +#define ERROR_COULD_NOT_MAP_FILE 4 +#define ERROR_INVALID_FILE 6 +#define ERROR_CORRUPT_FILE 7 +#define ERROR_UNSUPPORTED_FILE_VERSION 8 +#define ERROR_INVALID_REGULAR_EXPRESSION 9 +#define ERROR_INVALID_HEX_STRING 10 +#define ERROR_SYNTAX_ERROR 11 +#define ERROR_LOOP_NESTING_LIMIT_EXCEEDED 12 +#define ERROR_DUPLICATED_LOOP_IDENTIFIER 13 +#define ERROR_DUPLICATED_IDENTIFIER 14 +#define ERROR_DUPLICATED_TAG_IDENTIFIER 15 +#define ERROR_DUPLICATED_META_IDENTIFIER 16 +#define ERROR_DUPLICATED_STRING_IDENTIFIER 17 +#define ERROR_UNREFERENCED_STRING 18 +#define ERROR_UNDEFINED_STRING 19 +#define ERROR_UNDEFINED_IDENTIFIER 20 +#define ERROR_MISPLACED_ANONYMOUS_STRING 21 +#define ERROR_INCLUDES_CIRCULAR_REFERENCE 22 +#define ERROR_INCLUDE_DEPTH_EXCEEDED 23 +#define ERROR_WRONG_TYPE 24 +#define ERROR_EXEC_STACK_OVERFLOW 25 +#define ERROR_SCAN_TIMEOUT 26 +#define ERROR_TOO_MANY_SCAN_THREADS 27 +#define ERROR_CALLBACK_ERROR 28 +#define ERROR_INVALID_ARGUMENT 29 +#define ERROR_TOO_MANY_MATCHES 30 +#define ERROR_INTERNAL_FATAL_ERROR 31 +#define ERROR_NESTED_FOR_OF_LOOP 32 +#define ERROR_INVALID_FIELD_NAME 33 +#define ERROR_UNKNOWN_MODULE 34 +#define ERROR_NOT_A_STRUCTURE 35 +#define ERROR_NOT_INDEXABLE 36 +#define ERROR_NOT_A_FUNCTION 37 +#define ERROR_INVALID_FORMAT 38 +#define ERROR_TOO_MANY_ARGUMENTS 39 +#define ERROR_WRONG_ARGUMENTS 40 +#define ERROR_WRONG_RETURN_TYPE 41 +#define ERROR_DUPLICATED_STRUCTURE_MEMBER 42 + + +#define FAIL_ON_ERROR(x) { \ + int result = (x); \ + if (result != ERROR_SUCCESS) \ + return result; \ +} + +#define FAIL_ON_ERROR_WITH_CLEANUP(x, cleanup) { \ + int result = (x); \ + if (result != ERROR_SUCCESS) { \ + cleanup; \ + return result; \ + } \ +} + +#define FAIL_ON_COMPILER_ERROR(x) { \ + compiler->last_result = (x); \ + if (compiler->last_result != ERROR_SUCCESS) \ + return compiler->last_result; \ +} + + +#ifdef NDEBUG +#define assertf(expr, msg) ((void)0) +#else +#define assertf(expr, msg, ...) \ + if(!(expr)) { \ + fprintf(stderr, "%s:%d: " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ + abort(); \ + } +#endif + +#endif diff --git a/src/dbg/yara/yara/exec.h b/src/dbg/yara/yara/exec.h index eaf8e02b..9ebb6973 100644 --- a/src/dbg/yara/yara/exec.h +++ b/src/dbg/yara/yara/exec.h @@ -1,156 +1,156 @@ -/* -Copyright (c) 2013-2014. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_EXEC_H -#define YR_EXEC_H - -#include "hash.h" -#include "scan.h" -#include "types.h" -#include "rules.h" - - -#define UNDEFINED 0xFFFABADAFABADAFFLL -#define IS_UNDEFINED(x) ((size_t)(x) == (size_t) UNDEFINED) - -#define OP_ERROR 0 -#define OP_HALT 255 - -#define OP_AND 1 -#define OP_OR 2 -#define OP_NOT 3 -#define OP_BITWISE_NOT 4 -#define OP_BITWISE_AND 5 -#define OP_BITWISE_OR 6 -#define OP_BITWISE_XOR 7 -#define OP_SHL 8 -#define OP_SHR 9 -#define OP_MOD 10 -#define OP_INT_TO_DBL 11 -#define OP_STR_TO_BOOL 12 -#define OP_PUSH 13 -#define OP_POP 14 -#define OP_CALL 15 -#define OP_OBJ_LOAD 16 -#define OP_OBJ_VALUE 17 -#define OP_OBJ_FIELD 18 -#define OP_INDEX_ARRAY 19 -#define OP_COUNT 20 -#define OP_FOUND 21 -#define OP_FOUND_AT 22 -#define OP_FOUND_IN 23 -#define OP_OFFSET 24 -#define OP_OF 25 -#define OP_PUSH_RULE 26 -#define OP_MATCH_RULE 27 -#define OP_INCR_M 28 -#define OP_CLEAR_M 29 -#define OP_ADD_M 30 -#define OP_POP_M 31 -#define OP_PUSH_M 32 -#define OP_SWAPUNDEF 33 -#define OP_JNUNDEF 34 -#define OP_JLE 35 -#define OP_FILESIZE 36 -#define OP_ENTRYPOINT 37 -#define OP_CONTAINS 38 -#define OP_MATCHES 39 -#define OP_IMPORT 40 -#define OP_LOOKUP_DICT 41 - -#define _OP_EQ 0 -#define _OP_NEQ 1 -#define _OP_LT 2 -#define _OP_GT 3 -#define _OP_LE 4 -#define _OP_GE 5 -#define _OP_ADD 6 -#define _OP_SUB 7 -#define _OP_MUL 8 -#define _OP_DIV 9 -#define _OP_MINUS 10 - -#define OP_INT_BEGIN 100 -#define OP_INT_EQ (OP_INT_BEGIN + _OP_EQ) -#define OP_INT_NEQ (OP_INT_BEGIN + _OP_NEQ) -#define OP_INT_LT (OP_INT_BEGIN + _OP_LT) -#define OP_INT_GT (OP_INT_BEGIN + _OP_GT) -#define OP_INT_LE (OP_INT_BEGIN + _OP_LE) -#define OP_INT_GE (OP_INT_BEGIN + _OP_GE) -#define OP_INT_ADD (OP_INT_BEGIN + _OP_ADD) -#define OP_INT_SUB (OP_INT_BEGIN + _OP_SUB) -#define OP_INT_MUL (OP_INT_BEGIN + _OP_MUL) -#define OP_INT_DIV (OP_INT_BEGIN + _OP_DIV) -#define OP_INT_MINUS (OP_INT_BEGIN + _OP_MINUS) -#define OP_INT_END OP_INT_MINUS - -#define OP_DBL_BEGIN 120 -#define OP_DBL_EQ (OP_DBL_BEGIN + _OP_EQ) -#define OP_DBL_NEQ (OP_DBL_BEGIN + _OP_NEQ) -#define OP_DBL_LT (OP_DBL_BEGIN + _OP_LT) -#define OP_DBL_GT (OP_DBL_BEGIN + _OP_GT) -#define OP_DBL_LE (OP_DBL_BEGIN + _OP_LE) -#define OP_DBL_GE (OP_DBL_BEGIN + _OP_GE) -#define OP_DBL_ADD (OP_DBL_BEGIN + _OP_ADD) -#define OP_DBL_SUB (OP_DBL_BEGIN + _OP_SUB) -#define OP_DBL_MUL (OP_DBL_BEGIN + _OP_MUL) -#define OP_DBL_DIV (OP_DBL_BEGIN + _OP_DIV) -#define OP_DBL_MINUS (OP_DBL_BEGIN + _OP_MINUS) -#define OP_DBL_END OP_DBL_MINUS - -#define OP_STR_BEGIN 140 -#define OP_STR_EQ (OP_STR_BEGIN + _OP_EQ) -#define OP_STR_NEQ (OP_STR_BEGIN + _OP_NEQ) -#define OP_STR_LT (OP_STR_BEGIN + _OP_LT) -#define OP_STR_GT (OP_STR_BEGIN + _OP_GT) -#define OP_STR_LE (OP_STR_BEGIN + _OP_LE) -#define OP_STR_GE (OP_STR_BEGIN + _OP_GE) -#define OP_STR_END OP_STR_GE - -#define IS_INT_OP(x) ((x) >= OP_INT_BEGIN && (x) <= OP_INT_END) -#define IS_DBL_OP(x) ((x) >= OP_DBL_BEGIN && (x) <= OP_DBL_END) -#define IS_STR_OP(x) ((x) >= OP_STR_BEGIN && (x) <= OP_STR_END) - -#define OP_READ_INT 240 -#define OP_INT8 (OP_READ_INT + 0) -#define OP_INT16 (OP_READ_INT + 1) -#define OP_INT32 (OP_READ_INT + 2) -#define OP_UINT8 (OP_READ_INT + 3) -#define OP_UINT16 (OP_READ_INT + 4) -#define OP_UINT32 (OP_READ_INT + 5) -#define OP_INT8BE (OP_READ_INT + 6) -#define OP_INT16BE (OP_READ_INT + 7) -#define OP_INT32BE (OP_READ_INT + 8) -#define OP_UINT8BE (OP_READ_INT + 9) -#define OP_UINT16BE (OP_READ_INT + 10) -#define OP_UINT32BE (OP_READ_INT + 11) - - -#define OPERATION(operator, op1, op2) \ - (IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (UNDEFINED) : (op1 operator op2) - - -#define COMPARISON(operator, op1, op2) \ - (IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (0) : (op1 operator op2) - - -int yr_execute_code( - YR_RULES* rules, - YR_SCAN_CONTEXT* context, - int timeout, - time_t start_time); - -#endif +/* +Copyright (c) 2013-2014. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_EXEC_H +#define YR_EXEC_H + +#include "hash.h" +#include "scan.h" +#include "types.h" +#include "rules.h" + + +#define UNDEFINED 0xFFFABADAFABADAFFLL +#define IS_UNDEFINED(x) ((size_t)(x) == (size_t) UNDEFINED) + +#define OP_ERROR 0 +#define OP_HALT 255 + +#define OP_AND 1 +#define OP_OR 2 +#define OP_NOT 3 +#define OP_BITWISE_NOT 4 +#define OP_BITWISE_AND 5 +#define OP_BITWISE_OR 6 +#define OP_BITWISE_XOR 7 +#define OP_SHL 8 +#define OP_SHR 9 +#define OP_MOD 10 +#define OP_INT_TO_DBL 11 +#define OP_STR_TO_BOOL 12 +#define OP_PUSH 13 +#define OP_POP 14 +#define OP_CALL 15 +#define OP_OBJ_LOAD 16 +#define OP_OBJ_VALUE 17 +#define OP_OBJ_FIELD 18 +#define OP_INDEX_ARRAY 19 +#define OP_COUNT 20 +#define OP_FOUND 21 +#define OP_FOUND_AT 22 +#define OP_FOUND_IN 23 +#define OP_OFFSET 24 +#define OP_OF 25 +#define OP_PUSH_RULE 26 +#define OP_MATCH_RULE 27 +#define OP_INCR_M 28 +#define OP_CLEAR_M 29 +#define OP_ADD_M 30 +#define OP_POP_M 31 +#define OP_PUSH_M 32 +#define OP_SWAPUNDEF 33 +#define OP_JNUNDEF 34 +#define OP_JLE 35 +#define OP_FILESIZE 36 +#define OP_ENTRYPOINT 37 +#define OP_CONTAINS 38 +#define OP_MATCHES 39 +#define OP_IMPORT 40 +#define OP_LOOKUP_DICT 41 + +#define _OP_EQ 0 +#define _OP_NEQ 1 +#define _OP_LT 2 +#define _OP_GT 3 +#define _OP_LE 4 +#define _OP_GE 5 +#define _OP_ADD 6 +#define _OP_SUB 7 +#define _OP_MUL 8 +#define _OP_DIV 9 +#define _OP_MINUS 10 + +#define OP_INT_BEGIN 100 +#define OP_INT_EQ (OP_INT_BEGIN + _OP_EQ) +#define OP_INT_NEQ (OP_INT_BEGIN + _OP_NEQ) +#define OP_INT_LT (OP_INT_BEGIN + _OP_LT) +#define OP_INT_GT (OP_INT_BEGIN + _OP_GT) +#define OP_INT_LE (OP_INT_BEGIN + _OP_LE) +#define OP_INT_GE (OP_INT_BEGIN + _OP_GE) +#define OP_INT_ADD (OP_INT_BEGIN + _OP_ADD) +#define OP_INT_SUB (OP_INT_BEGIN + _OP_SUB) +#define OP_INT_MUL (OP_INT_BEGIN + _OP_MUL) +#define OP_INT_DIV (OP_INT_BEGIN + _OP_DIV) +#define OP_INT_MINUS (OP_INT_BEGIN + _OP_MINUS) +#define OP_INT_END OP_INT_MINUS + +#define OP_DBL_BEGIN 120 +#define OP_DBL_EQ (OP_DBL_BEGIN + _OP_EQ) +#define OP_DBL_NEQ (OP_DBL_BEGIN + _OP_NEQ) +#define OP_DBL_LT (OP_DBL_BEGIN + _OP_LT) +#define OP_DBL_GT (OP_DBL_BEGIN + _OP_GT) +#define OP_DBL_LE (OP_DBL_BEGIN + _OP_LE) +#define OP_DBL_GE (OP_DBL_BEGIN + _OP_GE) +#define OP_DBL_ADD (OP_DBL_BEGIN + _OP_ADD) +#define OP_DBL_SUB (OP_DBL_BEGIN + _OP_SUB) +#define OP_DBL_MUL (OP_DBL_BEGIN + _OP_MUL) +#define OP_DBL_DIV (OP_DBL_BEGIN + _OP_DIV) +#define OP_DBL_MINUS (OP_DBL_BEGIN + _OP_MINUS) +#define OP_DBL_END OP_DBL_MINUS + +#define OP_STR_BEGIN 140 +#define OP_STR_EQ (OP_STR_BEGIN + _OP_EQ) +#define OP_STR_NEQ (OP_STR_BEGIN + _OP_NEQ) +#define OP_STR_LT (OP_STR_BEGIN + _OP_LT) +#define OP_STR_GT (OP_STR_BEGIN + _OP_GT) +#define OP_STR_LE (OP_STR_BEGIN + _OP_LE) +#define OP_STR_GE (OP_STR_BEGIN + _OP_GE) +#define OP_STR_END OP_STR_GE + +#define IS_INT_OP(x) ((x) >= OP_INT_BEGIN && (x) <= OP_INT_END) +#define IS_DBL_OP(x) ((x) >= OP_DBL_BEGIN && (x) <= OP_DBL_END) +#define IS_STR_OP(x) ((x) >= OP_STR_BEGIN && (x) <= OP_STR_END) + +#define OP_READ_INT 240 +#define OP_INT8 (OP_READ_INT + 0) +#define OP_INT16 (OP_READ_INT + 1) +#define OP_INT32 (OP_READ_INT + 2) +#define OP_UINT8 (OP_READ_INT + 3) +#define OP_UINT16 (OP_READ_INT + 4) +#define OP_UINT32 (OP_READ_INT + 5) +#define OP_INT8BE (OP_READ_INT + 6) +#define OP_INT16BE (OP_READ_INT + 7) +#define OP_INT32BE (OP_READ_INT + 8) +#define OP_UINT8BE (OP_READ_INT + 9) +#define OP_UINT16BE (OP_READ_INT + 10) +#define OP_UINT32BE (OP_READ_INT + 11) + + +#define OPERATION(operator, op1, op2) \ + (IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (UNDEFINED) : (op1 operator op2) + + +#define COMPARISON(operator, op1, op2) \ + (IS_UNDEFINED(op1) || IS_UNDEFINED(op2)) ? (0) : (op1 operator op2) + + +int yr_execute_code( + YR_RULES* rules, + YR_SCAN_CONTEXT* context, + int timeout, + time_t start_time); + +#endif diff --git a/src/dbg/yara/yara/exefiles.h b/src/dbg/yara/yara/exefiles.h index c52cd932..aadc35f8 100644 --- a/src/dbg/yara/yara/exefiles.h +++ b/src/dbg/yara/yara/exefiles.h @@ -1,30 +1,30 @@ -/* -Copyright (c) 2007. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_EXEFILES_H -#define YR_EXEFILES_H - -uint64_t yr_get_entry_point_offset( - uint8_t* buffer, - size_t buffer_length); - - -uint64_t yr_get_entry_point_address( - uint8_t* buffer, - size_t buffer_length, - size_t base_address); - -#endif +/* +Copyright (c) 2007. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_EXEFILES_H +#define YR_EXEFILES_H + +uint64_t yr_get_entry_point_offset( + uint8_t* buffer, + size_t buffer_length); + + +uint64_t yr_get_entry_point_address( + uint8_t* buffer, + size_t buffer_length, + size_t base_address); + +#endif diff --git a/src/dbg/yara/yara/filemap.h b/src/dbg/yara/yara/filemap.h index 7ea4318b..2de4cba1 100644 --- a/src/dbg/yara/yara/filemap.h +++ b/src/dbg/yara/yara/filemap.h @@ -1,62 +1,62 @@ -/* -Copyright (c) 2007-2015. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_FILEMAP_H -#define YR_FILEMAP_H - -#ifdef _WIN32 -#include -#define FILE_DESCRIPTOR HANDLE -#define off_t int64_t -#else -#include -#define FILE_DESCRIPTOR int -#endif - -#include -#include - -#include "utils.h" - - -typedef struct _YR_MAPPED_FILE -{ - FILE_DESCRIPTOR file; - size_t size; - uint8_t* data; -#ifdef _WIN32 - HANDLE mapping; -#endif - -} YR_MAPPED_FILE; - - -YR_API int yr_filemap_map( - const char* file_path, - YR_MAPPED_FILE* pmapped_file); - - -YR_API int yr_filemap_map_ex( - const char* file_path, - off_t offset, - size_t size, - YR_MAPPED_FILE* pmapped_file); - - -YR_API void yr_filemap_unmap( - YR_MAPPED_FILE* pmapped_file); - -#endif +/* +Copyright (c) 2007-2015. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_FILEMAP_H +#define YR_FILEMAP_H + +#ifdef _WIN32 +#include +#define FILE_DESCRIPTOR HANDLE +#define off_t int64_t +#else +#include +#define FILE_DESCRIPTOR int +#endif + +#include +#include + +#include "utils.h" + + +typedef struct _YR_MAPPED_FILE +{ + FILE_DESCRIPTOR file; + size_t size; + uint8_t* data; +#ifdef _WIN32 + HANDLE mapping; +#endif + +} YR_MAPPED_FILE; + + +YR_API int yr_filemap_map( + const char* file_path, + YR_MAPPED_FILE* pmapped_file); + + +YR_API int yr_filemap_map_ex( + const char* file_path, + off_t offset, + size_t size, + YR_MAPPED_FILE* pmapped_file); + + +YR_API void yr_filemap_unmap( + YR_MAPPED_FILE* pmapped_file); + +#endif diff --git a/src/dbg/yara/yara/globals.h b/src/dbg/yara/yara/globals.h index dfeb683d..b1831660 100644 --- a/src/dbg/yara/yara/globals.h +++ b/src/dbg/yara/yara/globals.h @@ -1,23 +1,23 @@ -/* -Copyright (c) 2014. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_GLOBALS_H -#define YR_GLOBALS_H - -extern char lowercase[256]; -extern char altercase[256]; - -#endif +/* +Copyright (c) 2014. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_GLOBALS_H +#define YR_GLOBALS_H + +extern char lowercase[256]; +extern char altercase[256]; + +#endif diff --git a/src/dbg/yara/yara/hash.h b/src/dbg/yara/yara/hash.h index 957afa09..ad96f229 100644 --- a/src/dbg/yara/yara/hash.h +++ b/src/dbg/yara/yara/hash.h @@ -1,66 +1,66 @@ -/* -Copyright (c) 2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_HASH_H -#define YR_HASH_H - - -typedef struct _YR_HASH_TABLE_ENTRY -{ - char* key; - char* ns; - void* value; - - struct _YR_HASH_TABLE_ENTRY* next; - -} YR_HASH_TABLE_ENTRY; - - -typedef struct _YR_HASH_TABLE -{ - int size; - - YR_HASH_TABLE_ENTRY* buckets[1]; - -} YR_HASH_TABLE; - - -typedef int (*YR_HASH_TABLE_FREE_VALUE_FUNC)(void* value); - - -int yr_hash_table_create( - int size, - YR_HASH_TABLE** table); - - -void yr_hash_table_destroy( - YR_HASH_TABLE* table, - YR_HASH_TABLE_FREE_VALUE_FUNC free_value); - - -void* yr_hash_table_lookup( - YR_HASH_TABLE* table, - const char* key, - const char* ns); - - -int yr_hash_table_add( - YR_HASH_TABLE* table, - const char* key, - const char* ns, - void* value); - -#endif +/* +Copyright (c) 2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_HASH_H +#define YR_HASH_H + + +typedef struct _YR_HASH_TABLE_ENTRY +{ + char* key; + char* ns; + void* value; + + struct _YR_HASH_TABLE_ENTRY* next; + +} YR_HASH_TABLE_ENTRY; + + +typedef struct _YR_HASH_TABLE +{ + int size; + + YR_HASH_TABLE_ENTRY* buckets[1]; + +} YR_HASH_TABLE; + + +typedef int (*YR_HASH_TABLE_FREE_VALUE_FUNC)(void* value); + + +int yr_hash_table_create( + int size, + YR_HASH_TABLE** table); + + +void yr_hash_table_destroy( + YR_HASH_TABLE* table, + YR_HASH_TABLE_FREE_VALUE_FUNC free_value); + + +void* yr_hash_table_lookup( + YR_HASH_TABLE* table, + const char* key, + const char* ns); + + +int yr_hash_table_add( + YR_HASH_TABLE* table, + const char* key, + const char* ns, + void* value); + +#endif diff --git a/src/dbg/yara/yara/hex_lexer.h b/src/dbg/yara/yara/hex_lexer.h index 27f1e332..daa43d2b 100644 --- a/src/dbg/yara/yara/hex_lexer.h +++ b/src/dbg/yara/yara/hex_lexer.h @@ -1,98 +1,98 @@ -/* -Copyright (c) 2007. Victor M. Alvarez [plusvic@gmail.com]. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "re.h" - -#undef yyparse -#undef yylex -#undef yyerror -#undef yyfatal -#undef yychar -#undef yydebug -#undef yynerrs -#undef yyget_extra -#undef yyget_lineno - -#undef YY_FATAL_ERROR -#undef YY_DECL -#undef LEX_ENV - -#define yyparse hex_yyparse -#define yylex hex_yylex -#define yyerror hex_yyerror -#define yyfatal hex_yyfatal -#define yychar hex_yychar -#define yydebug hex_yydebug -#define yynerrs hex_yynerrs -#define yyget_extra hex_yyget_extra -#define yyget_lineno hex_yyget_lineno - - -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -#define YY_EXTRA_TYPE RE* -#define YY_USE_CONST - - -typedef struct _HEX_LEX_ENVIRONMENT -{ - int token_count; - int inside_or; - int last_error_code; - char last_error_message[256]; - -} HEX_LEX_ENVIRONMENT; - - -#define YY_FATAL_ERROR(msg) hex_yyfatal(yyscanner, msg) - -#define LEX_ENV ((HEX_LEX_ENVIRONMENT*) lex_env) - -#include - -#define YY_DECL int hex_yylex \ - (YYSTYPE * yylval_param , yyscan_t yyscanner, HEX_LEX_ENVIRONMENT* lex_env) - - -YY_EXTRA_TYPE yyget_extra( - yyscan_t yyscanner); - -int yylex( - YYSTYPE* yylval_param, - yyscan_t yyscanner, - HEX_LEX_ENVIRONMENT* lex_env); - -int yyparse( - void* yyscanner, - HEX_LEX_ENVIRONMENT* lex_env); - -void yyerror( - yyscan_t yyscanner, - HEX_LEX_ENVIRONMENT* lex_env, - const char* error_message); - -void yyfatal( - yyscan_t yyscanner, - const char* error_message); - -int yr_parse_hex_string( - const char* hex_string, - int flags, - RE** re, - RE_ERROR* error); +/* +Copyright (c) 2007. Victor M. Alvarez [plusvic@gmail.com]. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "re.h" + +#undef yyparse +#undef yylex +#undef yyerror +#undef yyfatal +#undef yychar +#undef yydebug +#undef yynerrs +#undef yyget_extra +#undef yyget_lineno + +#undef YY_FATAL_ERROR +#undef YY_DECL +#undef LEX_ENV + +#define yyparse hex_yyparse +#define yylex hex_yylex +#define yyerror hex_yyerror +#define yyfatal hex_yyfatal +#define yychar hex_yychar +#define yydebug hex_yydebug +#define yynerrs hex_yynerrs +#define yyget_extra hex_yyget_extra +#define yyget_lineno hex_yyget_lineno + + +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +#define YY_EXTRA_TYPE RE* +#define YY_USE_CONST + + +typedef struct _HEX_LEX_ENVIRONMENT +{ + int token_count; + int inside_or; + int last_error_code; + char last_error_message[256]; + +} HEX_LEX_ENVIRONMENT; + + +#define YY_FATAL_ERROR(msg) hex_yyfatal(yyscanner, msg) + +#define LEX_ENV ((HEX_LEX_ENVIRONMENT*) lex_env) + +#include + +#define YY_DECL int hex_yylex \ + (YYSTYPE * yylval_param , yyscan_t yyscanner, HEX_LEX_ENVIRONMENT* lex_env) + + +YY_EXTRA_TYPE yyget_extra( + yyscan_t yyscanner); + +int yylex( + YYSTYPE* yylval_param, + yyscan_t yyscanner, + HEX_LEX_ENVIRONMENT* lex_env); + +int yyparse( + void* yyscanner, + HEX_LEX_ENVIRONMENT* lex_env); + +void yyerror( + yyscan_t yyscanner, + HEX_LEX_ENVIRONMENT* lex_env, + const char* error_message); + +void yyfatal( + yyscan_t yyscanner, + const char* error_message); + +int yr_parse_hex_string( + const char* hex_string, + int flags, + RE** re, + RE_ERROR* error); diff --git a/src/dbg/yara/yara/lexer.h b/src/dbg/yara/yara/lexer.h index 9e440327..ceeeea88 100644 --- a/src/dbg/yara/yara/lexer.h +++ b/src/dbg/yara/yara/lexer.h @@ -1,131 +1,131 @@ -/* -Copyright (c) 2007. Victor M. Alvarez [plusvic@gmail.com]. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "compiler.h" - - -#undef yyparse -#undef yylex -#undef yyerror -#undef yyfatal -#undef yychar -#undef yydebug -#undef yynerrs -#undef yyget_extra -#undef yyget_lineno - -#undef YY_DECL -#undef YY_FATAL_ERROR -#undef YY_EXTRA_TYPE - -#define yyparse yara_yyparse -#define yylex yara_yylex -#define yyerror yara_yyerror -#define yyfatal yara_yyfatal -#define yywarning yara_yywarning -#define yychar yara_yychar -#define yydebug yara_yydebug -#define yynerrs yara_yynerrs -#define yyget_extra yara_yyget_extra -#define yyget_lineno yara_yyget_lineno - - -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -#ifndef YY_TYPEDEF_EXPRESSION_T -#define YY_TYPEDEF_EXPRESSION_T - - -// Expression type constants are powers of two because they are used as flags. -// For example: -// CHECK_TYPE(whatever, EXPRESSION_TYPE_INTEGER | EXPRESSION_TYPE_FLOAT) -// The expression above is used to ensure that the type of "whatever" is either -// integer or float. - -#define EXPRESSION_TYPE_BOOLEAN 1 -#define EXPRESSION_TYPE_INTEGER 2 -#define EXPRESSION_TYPE_STRING 4 -#define EXPRESSION_TYPE_REGEXP 8 -#define EXPRESSION_TYPE_OBJECT 16 -#define EXPRESSION_TYPE_FLOAT 32 - -typedef struct _EXPRESSION -{ - int type; - - union - { - int64_t integer; - YR_OBJECT* object; - } value; - - const char* identifier; - -} EXPRESSION; - -union YYSTYPE; - -#endif - - -#define YY_DECL int yylex( \ - union YYSTYPE* yylval_param, yyscan_t yyscanner, YR_COMPILER* compiler) - - -#define YY_FATAL_ERROR(msg) yara_yyfatal(yyscanner, msg) - - -#define YY_EXTRA_TYPE YR_COMPILER* -#define YY_USE_CONST - - -int yyget_lineno(yyscan_t yyscanner); - -int yylex( - union YYSTYPE* yylval_param, - yyscan_t yyscanner, - YR_COMPILER* compiler); - -int yyparse( - void* yyscanner, - YR_COMPILER* compiler); - -void yyerror( - yyscan_t yyscanner, - YR_COMPILER* compiler, - const char* error_message); - -void yywarning( - yyscan_t yyscanner, - const char* warning_message); - -void yyfatal( - yyscan_t yyscanner, - const char* error_message); - -YY_EXTRA_TYPE yyget_extra( - yyscan_t yyscanner); - -int yr_lex_parse_rules_string( - const char* rules_string, - YR_COMPILER* compiler); - -int yr_lex_parse_rules_file( - FILE* rules_file, - YR_COMPILER* compiler); +/* +Copyright (c) 2007. Victor M. Alvarez [plusvic@gmail.com]. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "compiler.h" + + +#undef yyparse +#undef yylex +#undef yyerror +#undef yyfatal +#undef yychar +#undef yydebug +#undef yynerrs +#undef yyget_extra +#undef yyget_lineno + +#undef YY_DECL +#undef YY_FATAL_ERROR +#undef YY_EXTRA_TYPE + +#define yyparse yara_yyparse +#define yylex yara_yylex +#define yyerror yara_yyerror +#define yyfatal yara_yyfatal +#define yywarning yara_yywarning +#define yychar yara_yychar +#define yydebug yara_yydebug +#define yynerrs yara_yynerrs +#define yyget_extra yara_yyget_extra +#define yyget_lineno yara_yyget_lineno + + +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +#ifndef YY_TYPEDEF_EXPRESSION_T +#define YY_TYPEDEF_EXPRESSION_T + + +// Expression type constants are powers of two because they are used as flags. +// For example: +// CHECK_TYPE(whatever, EXPRESSION_TYPE_INTEGER | EXPRESSION_TYPE_FLOAT) +// The expression above is used to ensure that the type of "whatever" is either +// integer or float. + +#define EXPRESSION_TYPE_BOOLEAN 1 +#define EXPRESSION_TYPE_INTEGER 2 +#define EXPRESSION_TYPE_STRING 4 +#define EXPRESSION_TYPE_REGEXP 8 +#define EXPRESSION_TYPE_OBJECT 16 +#define EXPRESSION_TYPE_FLOAT 32 + +typedef struct _EXPRESSION +{ + int type; + + union + { + int64_t integer; + YR_OBJECT* object; + } value; + + const char* identifier; + +} EXPRESSION; + +union YYSTYPE; + +#endif + + +#define YY_DECL int yylex( \ + union YYSTYPE* yylval_param, yyscan_t yyscanner, YR_COMPILER* compiler) + + +#define YY_FATAL_ERROR(msg) yara_yyfatal(yyscanner, msg) + + +#define YY_EXTRA_TYPE YR_COMPILER* +#define YY_USE_CONST + + +int yyget_lineno(yyscan_t yyscanner); + +int yylex( + union YYSTYPE* yylval_param, + yyscan_t yyscanner, + YR_COMPILER* compiler); + +int yyparse( + void* yyscanner, + YR_COMPILER* compiler); + +void yyerror( + yyscan_t yyscanner, + YR_COMPILER* compiler, + const char* error_message); + +void yywarning( + yyscan_t yyscanner, + const char* warning_message); + +void yyfatal( + yyscan_t yyscanner, + const char* error_message); + +YY_EXTRA_TYPE yyget_extra( + yyscan_t yyscanner); + +int yr_lex_parse_rules_string( + const char* rules_string, + YR_COMPILER* compiler); + +int yr_lex_parse_rules_file( + FILE* rules_file, + YR_COMPILER* compiler); diff --git a/src/dbg/yara/yara/libyara.h b/src/dbg/yara/yara/libyara.h index 23a42906..2ffb4989 100644 --- a/src/dbg/yara/yara/libyara.h +++ b/src/dbg/yara/yara/libyara.h @@ -1,49 +1,49 @@ -/* -Copyright (c) 2014. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_LIBYARA_H -#define YR_LIBYARA_H - -#include "utils.h" - -#define YR_MAJOR_VERSION 3 -#define YR_MINOR_VERSION 3 -#define YR_MICRO_VERSION 0 - -// Version as a string -#define YR_VERSION "3.3.0" - -// Version as a single 4-byte hex number, e.g. 0x030401 == 3.4.1. -#define YR_VERSION_HEX ((YR_MAJOR_VERSION << 16) | \ - (YR_MINOR_VERSION << 8) | \ - (YR_MICRO_VERSION << 0) - - -YR_API int yr_initialize(void); - - -YR_API int yr_finalize(void); - - -YR_API void yr_finalize_thread(void); - - -YR_API int yr_get_tidx(void); - - -YR_API void yr_set_tidx(int); - -#endif +/* +Copyright (c) 2014. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_LIBYARA_H +#define YR_LIBYARA_H + +#include "utils.h" + +#define YR_MAJOR_VERSION 3 +#define YR_MINOR_VERSION 3 +#define YR_MICRO_VERSION 0 + +// Version as a string +#define YR_VERSION "3.3.0" + +// Version as a single 4-byte hex number, e.g. 0x030401 == 3.4.1. +#define YR_VERSION_HEX ((YR_MAJOR_VERSION << 16) | \ + (YR_MINOR_VERSION << 8) | \ + (YR_MICRO_VERSION << 0) + + +YR_API int yr_initialize(void); + + +YR_API int yr_finalize(void); + + +YR_API void yr_finalize_thread(void); + + +YR_API int yr_get_tidx(void); + + +YR_API void yr_set_tidx(int); + +#endif diff --git a/src/dbg/yara/yara/limits.h b/src/dbg/yara/yara/limits.h index 62ba7d74..03f230e1 100644 --- a/src/dbg/yara/yara/limits.h +++ b/src/dbg/yara/yara/limits.h @@ -1,48 +1,48 @@ -/* -Copyright (c) 2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_LIMITS_H -#define YR_LIMITS_H - - -// MAX_THREADS is the number of threads that can use a YR_RULES -// object simultaneosly. This value is limited by the number of -// bits in tidx_mask. - -#define MAX_THREADS 32 - - -#ifndef MAX_PATH -#define MAX_PATH 1024 -#endif - -#define MAX_COMPILER_ERROR_EXTRA_INFO 256 -#define MAX_ATOM_LENGTH 4 -#define MAX_LOOP_NESTING 4 -#define MAX_ARENA_PAGES 32 -#define MAX_INCLUDE_DEPTH 16 -#define MAX_STRING_MATCHES 1000000 -#define MAX_FUNCTION_ARGS 128 -#define MAX_FAST_HEX_RE_STACK 300 -#define MAX_OVERLOADED_FUNCTIONS 10 -#define MAX_HEX_STRING_TOKENS 10000 - -#define LOOP_LOCAL_VARS 4 -#define STRING_CHAINING_THRESHOLD 200 -#define LEX_BUF_SIZE 1024 - - -#endif +/* +Copyright (c) 2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_LIMITS_H +#define YR_LIMITS_H + + +// MAX_THREADS is the number of threads that can use a YR_RULES +// object simultaneosly. This value is limited by the number of +// bits in tidx_mask. + +#define MAX_THREADS 32 + + +#ifndef MAX_PATH +#define MAX_PATH 1024 +#endif + +#define MAX_COMPILER_ERROR_EXTRA_INFO 256 +#define MAX_ATOM_LENGTH 4 +#define MAX_LOOP_NESTING 4 +#define MAX_ARENA_PAGES 32 +#define MAX_INCLUDE_DEPTH 16 +#define MAX_STRING_MATCHES 1000000 +#define MAX_FUNCTION_ARGS 128 +#define MAX_FAST_HEX_RE_STACK 300 +#define MAX_OVERLOADED_FUNCTIONS 10 +#define MAX_HEX_STRING_TOKENS 10000 + +#define LOOP_LOCAL_VARS 4 +#define STRING_CHAINING_THRESHOLD 200 +#define LEX_BUF_SIZE 1024 + + +#endif diff --git a/src/dbg/yara/yara/mem.h b/src/dbg/yara/yara/mem.h index bbbc6075..0d77d879 100644 --- a/src/dbg/yara/yara/mem.h +++ b/src/dbg/yara/yara/mem.h @@ -1,63 +1,63 @@ -/* -Copyright (c) 2007. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_MEM_H -#define YR_MEM_H - -#include - -#include "config.h" - -#ifdef DMALLOC - -#define yr_malloc malloc -#define yr_calloc calloc -#define yr_realloc realloc -#define yr_free free -#define yr_strdup strdup -#define yr_strndup strndup - -#include - -#else - -void* yr_calloc( - size_t count, - size_t size); - -void* yr_malloc( - size_t size); - -void* yr_realloc( - void* ptr, - size_t size); - -void yr_free( - void* ptr); - -char* yr_strdup( - const char* str); - -char* yr_strndup( - const char* str, size_t n); - -#endif - -int yr_heap_alloc(); - -int yr_heap_free(); - -#endif +/* +Copyright (c) 2007. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_MEM_H +#define YR_MEM_H + +#include + +#include "config.h" + +#ifdef DMALLOC + +#define yr_malloc malloc +#define yr_calloc calloc +#define yr_realloc realloc +#define yr_free free +#define yr_strdup strdup +#define yr_strndup strndup + +#include + +#else + +void* yr_calloc( + size_t count, + size_t size); + +void* yr_malloc( + size_t size); + +void* yr_realloc( + void* ptr, + size_t size); + +void yr_free( + void* ptr); + +char* yr_strdup( + const char* str); + +char* yr_strndup( + const char* str, size_t n); + +#endif + +int yr_heap_alloc(); + +int yr_heap_free(); + +#endif diff --git a/src/dbg/yara/yara/modules.h b/src/dbg/yara/yara/modules.h index c9070d83..4d05dfb3 100644 --- a/src/dbg/yara/yara/modules.h +++ b/src/dbg/yara/yara/modules.h @@ -1,439 +1,439 @@ -/* -Copyright (c) 2014. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_MODULES_H -#define YR_MODULES_H - -#include -#include -#include -#include - -#include "utils.h" -#include "limits.h" -#include "error.h" -#include "exec.h" -#include "types.h" -#include "object.h" -#include "libyara.h" - -// Concatenation that macro-expands its arguments. - -#define CONCAT_ARGS(arg1, arg2) _CONCAT(arg1, arg2) // expands the arguments. -#define _CONCAT_ARGS(arg1, arg2) arg1 ## arg2 // do the actual concatenation. - - -#define module_declarations CONCAT_ARGS(MODULE_NAME, __declarations) -#define module_load CONCAT_ARGS(MODULE_NAME, __load) -#define module_unload CONCAT_ARGS(MODULE_NAME, __unload) -#define module_initialize CONCAT_ARGS(MODULE_NAME, __initialize) -#define module_finalize CONCAT_ARGS(MODULE_NAME, __finalize) - -#define begin_declarations \ - int module_declarations(YR_OBJECT* module) { \ - YR_OBJECT* stack[64]; \ - int stack_top = 0; \ - stack[stack_top] = module; - - -#define end_declarations \ - return ERROR_SUCCESS; } - - -#define begin_struct(name) { \ - YR_OBJECT* structure; \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_STRUCTURE, \ - name, \ - stack[stack_top], \ - &structure)); \ - assertf( \ - stack_top < sizeof(stack)/sizeof(stack[0]) - 1, \ - "too many nested structures"); \ - stack[++stack_top] = structure; \ - } - - -#define begin_struct_array(name) { \ - YR_OBJECT* structure; \ - YR_OBJECT* array; \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_ARRAY, \ - name, \ - stack[stack_top], \ - &array)); \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_STRUCTURE, \ - name, \ - array, \ - &structure)); \ - assertf( \ - stack_top < sizeof(stack)/sizeof(stack[0]) - 1, \ - "too many nested structures"); \ - stack[++stack_top] = structure; \ - } - - -#define begin_struct_dictionary(name) { \ - YR_OBJECT* structure; \ - YR_OBJECT* array; \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_DICTIONARY, \ - name, \ - stack[stack_top], \ - &array)); \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_STRUCTURE, \ - name, \ - array, \ - &structure)); \ - assertf( \ - stack_top < sizeof(stack)/sizeof(stack[0]) - 1, \ - "too many nested structures"); \ - stack[++stack_top] = structure; \ - } - - -#define end_struct(name) { \ - assert(stack[stack_top]->type == OBJECT_TYPE_STRUCTURE); \ - assertf( \ - strcmp(stack[stack_top]->identifier, name) == 0, \ - "unbalanced begin_struct/end_struct"); \ - stack_top--; \ - } - - -#define end_struct_array(name) end_struct(name) - - -#define end_struct_dictionary(name) end_struct(name) - - -#define declare_integer(name) { \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_INTEGER, \ - name, \ - stack[stack_top], \ - NULL)); \ - } - - -#define declare_integer_array(name) { \ - YR_OBJECT* array; \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_ARRAY, \ - name, \ - stack[stack_top], \ - &array)); \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_INTEGER, \ - name, \ - array, \ - NULL)); \ - } - - -#define declare_integer_dictionary(name) { \ - YR_OBJECT* dict; \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_DICTIONARY, \ - name, \ - stack[stack_top], \ - &dict)); \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_INTEGER, \ - name, \ - dict, \ - NULL)); \ - } - - -#define declare_float(name) { \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_FLOAT, \ - name, \ - stack[stack_top], \ - NULL)); \ - } - - -#define declare_float_array(name) { \ - YR_OBJECT* array; \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_ARRAY, \ - name, \ - stack[stack_top], \ - &array)); \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_FLOAT, \ - name, \ - array, \ - NULL)); \ - } - - -#define declare_float_dictionary(name) { \ - YR_OBJECT* dict; \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_DICTIONARY, \ - name, \ - stack[stack_top], \ - &dict)); \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_FLOAT, \ - name, \ - dict, \ - NULL)); \ - } - - -#define declare_string(name) { \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_STRING, \ - name, \ - stack[stack_top], \ - NULL)); \ - } - - -#define declare_string_array(name) { \ - YR_OBJECT* array; \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_ARRAY, \ - name, \ - stack[stack_top], \ - &array)); \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_STRING, \ - name, \ - array, \ - NULL)); \ - } - - -#define declare_string_dictionary(name) { \ - YR_OBJECT* dict; \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_DICTIONARY, \ - name, \ - stack[stack_top], \ - &dict)); \ - FAIL_ON_ERROR(yr_object_create( \ - OBJECT_TYPE_STRING, \ - name, \ - dict, \ - NULL)); \ - } - - -#define declare_function(name, args_fmt, ret_fmt, func) { \ - YR_OBJECT* function; \ - FAIL_ON_ERROR(yr_object_function_create( \ - name, \ - args_fmt, \ - ret_fmt, \ - func, \ - stack[stack_top], \ - &function)); \ - } - - -#define define_function(func) \ - int func ( \ - void* __args, \ - YR_SCAN_CONTEXT* __context, \ - YR_OBJECT_FUNCTION* __function_obj) - - -#define sized_string_argument(n) \ - ((SIZED_STRING*)(size_t)((int64_t*) __args)[n-1]) - -#define string_argument(n) \ - (sized_string_argument(n)->c_string) - -#define integer_argument(n) \ - (((int64_t*) __args)[n-1]) - -#define float_argument(n) \ - (((double*) __args)[n-1]) - -#define regexp_argument(n) \ - ((RE_CODE)((int64_t*) __args)[n-1]) - - -#define module() yr_object_get_root((YR_OBJECT*) __function_obj) -#define parent() (__function_obj->parent) -#define scan_context() (__context) - - -#define foreach_memory_block(context, block) \ - for (block = (context)->mem_block; \ - block != NULL; \ - block = block->next) \ - - -#define first_memory_block(context) \ - (context)->mem_block - - -#define is_undefined(object, ...) \ - yr_object_has_undefined_value(object, __VA_ARGS__) - - -#define get_object(object, ...) \ - yr_object_lookup(object, 0, __VA_ARGS__) - - -#define get_integer(object, ...) \ - yr_object_get_integer(object, __VA_ARGS__) - - -#define get_float(object, ...) \ - yr_object_get_float(object, __VA_ARGS__) - - -#define get_string(object, ...) \ - yr_object_get_string(object, __VA_ARGS__) - - -#define set_integer(value, object, ...) \ - yr_object_set_integer(value, object, __VA_ARGS__) - - -#define set_float(value, object, ...) \ - yr_object_set_float(value, object, __VA_ARGS__) - - -#define set_sized_string(value, len, object, ...) \ - yr_object_set_string(value, len, object, __VA_ARGS__) - - -#define set_string(value, object, ...) \ - set_sized_string(value, strlen(value), object, __VA_ARGS__) - - -#define return_integer(integer) { \ - assertf( \ - __function_obj->return_obj->type == OBJECT_TYPE_INTEGER, \ - "return type differs from function declaration"); \ - yr_object_set_integer( \ - (integer), \ - __function_obj->return_obj, \ - NULL); \ - return ERROR_SUCCESS; \ - } - - -#define return_float(double_) { \ - assertf( \ - __function_obj->return_obj->type == OBJECT_TYPE_FLOAT, \ - "return type differs from function declaration"); \ - double d = (double) (double_); \ - yr_object_set_float( \ - (d != (double) UNDEFINED) ? d : NAN, \ - __function_obj->return_obj, \ - NULL); \ - return ERROR_SUCCESS; \ - } - - -#define return_string(string) { \ - assertf( \ - __function_obj->return_obj->type == OBJECT_TYPE_STRING, \ - "return type differs from function declaration"); \ - char* s = (char*) (string); \ - yr_object_set_string( \ - (s != (char*) UNDEFINED) ? s : NULL, \ - (s != (char*) UNDEFINED) ? strlen(s) : 0, \ - __function_obj->return_obj, \ - NULL); \ - return ERROR_SUCCESS; \ - } - - -struct _YR_MODULE; - - -typedef int (*YR_EXT_INITIALIZE_FUNC)( - struct _YR_MODULE* module); - - -typedef int (*YR_EXT_FINALIZE_FUNC)( - struct _YR_MODULE* module); - - -typedef int (*YR_EXT_DECLARATIONS_FUNC)( - YR_OBJECT* module_object); - - -typedef int (*YR_EXT_LOAD_FUNC)( - YR_SCAN_CONTEXT* context, - YR_OBJECT* module_object, - void* module_data, - size_t module_data_size); - - -typedef int (*YR_EXT_UNLOAD_FUNC)( - YR_OBJECT* module_object); - - -typedef struct _YR_MODULE -{ - tidx_mask_t is_loaded; - - char* name; - - YR_EXT_DECLARATIONS_FUNC declarations; - YR_EXT_LOAD_FUNC load; - YR_EXT_UNLOAD_FUNC unload; - YR_EXT_INITIALIZE_FUNC initialize; - YR_EXT_FINALIZE_FUNC finalize; - -} YR_MODULE; - - -typedef struct _YR_MODULE_IMPORT -{ - const char* module_name; - void* module_data; - size_t module_data_size; - -} YR_MODULE_IMPORT; - - -int yr_modules_initialize(void); - - -int yr_modules_finalize(void); - - -int yr_modules_do_declarations( - const char* module_name, - YR_OBJECT* main_structure); - - -int yr_modules_load( - const char* module_name, - YR_SCAN_CONTEXT* context); - - -int yr_modules_unload_all( - YR_SCAN_CONTEXT* context); - - -void yr_modules_print_data( - YR_SCAN_CONTEXT* context); -#endif +/* +Copyright (c) 2014. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_MODULES_H +#define YR_MODULES_H + +#include +#include +#include +#include + +#include "utils.h" +#include "limits.h" +#include "error.h" +#include "exec.h" +#include "types.h" +#include "object.h" +#include "libyara.h" + +// Concatenation that macro-expands its arguments. + +#define CONCAT_ARGS(arg1, arg2) _CONCAT(arg1, arg2) // expands the arguments. +#define _CONCAT_ARGS(arg1, arg2) arg1 ## arg2 // do the actual concatenation. + + +#define module_declarations CONCAT_ARGS(MODULE_NAME, __declarations) +#define module_load CONCAT_ARGS(MODULE_NAME, __load) +#define module_unload CONCAT_ARGS(MODULE_NAME, __unload) +#define module_initialize CONCAT_ARGS(MODULE_NAME, __initialize) +#define module_finalize CONCAT_ARGS(MODULE_NAME, __finalize) + +#define begin_declarations \ + int module_declarations(YR_OBJECT* module) { \ + YR_OBJECT* stack[64]; \ + int stack_top = 0; \ + stack[stack_top] = module; + + +#define end_declarations \ + return ERROR_SUCCESS; } + + +#define begin_struct(name) { \ + YR_OBJECT* structure; \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_STRUCTURE, \ + name, \ + stack[stack_top], \ + &structure)); \ + assertf( \ + stack_top < sizeof(stack)/sizeof(stack[0]) - 1, \ + "too many nested structures"); \ + stack[++stack_top] = structure; \ + } + + +#define begin_struct_array(name) { \ + YR_OBJECT* structure; \ + YR_OBJECT* array; \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_ARRAY, \ + name, \ + stack[stack_top], \ + &array)); \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_STRUCTURE, \ + name, \ + array, \ + &structure)); \ + assertf( \ + stack_top < sizeof(stack)/sizeof(stack[0]) - 1, \ + "too many nested structures"); \ + stack[++stack_top] = structure; \ + } + + +#define begin_struct_dictionary(name) { \ + YR_OBJECT* structure; \ + YR_OBJECT* array; \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_DICTIONARY, \ + name, \ + stack[stack_top], \ + &array)); \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_STRUCTURE, \ + name, \ + array, \ + &structure)); \ + assertf( \ + stack_top < sizeof(stack)/sizeof(stack[0]) - 1, \ + "too many nested structures"); \ + stack[++stack_top] = structure; \ + } + + +#define end_struct(name) { \ + assert(stack[stack_top]->type == OBJECT_TYPE_STRUCTURE); \ + assertf( \ + strcmp(stack[stack_top]->identifier, name) == 0, \ + "unbalanced begin_struct/end_struct"); \ + stack_top--; \ + } + + +#define end_struct_array(name) end_struct(name) + + +#define end_struct_dictionary(name) end_struct(name) + + +#define declare_integer(name) { \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_INTEGER, \ + name, \ + stack[stack_top], \ + NULL)); \ + } + + +#define declare_integer_array(name) { \ + YR_OBJECT* array; \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_ARRAY, \ + name, \ + stack[stack_top], \ + &array)); \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_INTEGER, \ + name, \ + array, \ + NULL)); \ + } + + +#define declare_integer_dictionary(name) { \ + YR_OBJECT* dict; \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_DICTIONARY, \ + name, \ + stack[stack_top], \ + &dict)); \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_INTEGER, \ + name, \ + dict, \ + NULL)); \ + } + + +#define declare_float(name) { \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_FLOAT, \ + name, \ + stack[stack_top], \ + NULL)); \ + } + + +#define declare_float_array(name) { \ + YR_OBJECT* array; \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_ARRAY, \ + name, \ + stack[stack_top], \ + &array)); \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_FLOAT, \ + name, \ + array, \ + NULL)); \ + } + + +#define declare_float_dictionary(name) { \ + YR_OBJECT* dict; \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_DICTIONARY, \ + name, \ + stack[stack_top], \ + &dict)); \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_FLOAT, \ + name, \ + dict, \ + NULL)); \ + } + + +#define declare_string(name) { \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_STRING, \ + name, \ + stack[stack_top], \ + NULL)); \ + } + + +#define declare_string_array(name) { \ + YR_OBJECT* array; \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_ARRAY, \ + name, \ + stack[stack_top], \ + &array)); \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_STRING, \ + name, \ + array, \ + NULL)); \ + } + + +#define declare_string_dictionary(name) { \ + YR_OBJECT* dict; \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_DICTIONARY, \ + name, \ + stack[stack_top], \ + &dict)); \ + FAIL_ON_ERROR(yr_object_create( \ + OBJECT_TYPE_STRING, \ + name, \ + dict, \ + NULL)); \ + } + + +#define declare_function(name, args_fmt, ret_fmt, func) { \ + YR_OBJECT* function; \ + FAIL_ON_ERROR(yr_object_function_create( \ + name, \ + args_fmt, \ + ret_fmt, \ + func, \ + stack[stack_top], \ + &function)); \ + } + + +#define define_function(func) \ + int func ( \ + void* __args, \ + YR_SCAN_CONTEXT* __context, \ + YR_OBJECT_FUNCTION* __function_obj) + + +#define sized_string_argument(n) \ + ((SIZED_STRING*)(size_t)((int64_t*) __args)[n-1]) + +#define string_argument(n) \ + (sized_string_argument(n)->c_string) + +#define integer_argument(n) \ + (((int64_t*) __args)[n-1]) + +#define float_argument(n) \ + (((double*) __args)[n-1]) + +#define regexp_argument(n) \ + ((RE_CODE)((int64_t*) __args)[n-1]) + + +#define module() yr_object_get_root((YR_OBJECT*) __function_obj) +#define parent() (__function_obj->parent) +#define scan_context() (__context) + + +#define foreach_memory_block(context, block) \ + for (block = (context)->mem_block; \ + block != NULL; \ + block = block->next) \ + + +#define first_memory_block(context) \ + (context)->mem_block + + +#define is_undefined(object, ...) \ + yr_object_has_undefined_value(object, __VA_ARGS__) + + +#define get_object(object, ...) \ + yr_object_lookup(object, 0, __VA_ARGS__) + + +#define get_integer(object, ...) \ + yr_object_get_integer(object, __VA_ARGS__) + + +#define get_float(object, ...) \ + yr_object_get_float(object, __VA_ARGS__) + + +#define get_string(object, ...) \ + yr_object_get_string(object, __VA_ARGS__) + + +#define set_integer(value, object, ...) \ + yr_object_set_integer(value, object, __VA_ARGS__) + + +#define set_float(value, object, ...) \ + yr_object_set_float(value, object, __VA_ARGS__) + + +#define set_sized_string(value, len, object, ...) \ + yr_object_set_string(value, len, object, __VA_ARGS__) + + +#define set_string(value, object, ...) \ + set_sized_string(value, strlen(value), object, __VA_ARGS__) + + +#define return_integer(integer) { \ + assertf( \ + __function_obj->return_obj->type == OBJECT_TYPE_INTEGER, \ + "return type differs from function declaration"); \ + yr_object_set_integer( \ + (integer), \ + __function_obj->return_obj, \ + NULL); \ + return ERROR_SUCCESS; \ + } + + +#define return_float(double_) { \ + assertf( \ + __function_obj->return_obj->type == OBJECT_TYPE_FLOAT, \ + "return type differs from function declaration"); \ + double d = (double) (double_); \ + yr_object_set_float( \ + (d != (double) UNDEFINED) ? d : NAN, \ + __function_obj->return_obj, \ + NULL); \ + return ERROR_SUCCESS; \ + } + + +#define return_string(string) { \ + assertf( \ + __function_obj->return_obj->type == OBJECT_TYPE_STRING, \ + "return type differs from function declaration"); \ + char* s = (char*) (string); \ + yr_object_set_string( \ + (s != (char*) UNDEFINED) ? s : NULL, \ + (s != (char*) UNDEFINED) ? strlen(s) : 0, \ + __function_obj->return_obj, \ + NULL); \ + return ERROR_SUCCESS; \ + } + + +struct _YR_MODULE; + + +typedef int (*YR_EXT_INITIALIZE_FUNC)( + struct _YR_MODULE* module); + + +typedef int (*YR_EXT_FINALIZE_FUNC)( + struct _YR_MODULE* module); + + +typedef int (*YR_EXT_DECLARATIONS_FUNC)( + YR_OBJECT* module_object); + + +typedef int (*YR_EXT_LOAD_FUNC)( + YR_SCAN_CONTEXT* context, + YR_OBJECT* module_object, + void* module_data, + size_t module_data_size); + + +typedef int (*YR_EXT_UNLOAD_FUNC)( + YR_OBJECT* module_object); + + +typedef struct _YR_MODULE +{ + tidx_mask_t is_loaded; + + char* name; + + YR_EXT_DECLARATIONS_FUNC declarations; + YR_EXT_LOAD_FUNC load; + YR_EXT_UNLOAD_FUNC unload; + YR_EXT_INITIALIZE_FUNC initialize; + YR_EXT_FINALIZE_FUNC finalize; + +} YR_MODULE; + + +typedef struct _YR_MODULE_IMPORT +{ + const char* module_name; + void* module_data; + size_t module_data_size; + +} YR_MODULE_IMPORT; + + +int yr_modules_initialize(void); + + +int yr_modules_finalize(void); + + +int yr_modules_do_declarations( + const char* module_name, + YR_OBJECT* main_structure); + + +int yr_modules_load( + const char* module_name, + YR_SCAN_CONTEXT* context); + + +int yr_modules_unload_all( + YR_SCAN_CONTEXT* context); + + +void yr_modules_print_data( + YR_SCAN_CONTEXT* context); +#endif diff --git a/src/dbg/yara/yara/object.h b/src/dbg/yara/yara/object.h index 82ce6570..6159e505 100644 --- a/src/dbg/yara/yara/object.h +++ b/src/dbg/yara/yara/object.h @@ -1,156 +1,156 @@ -/* -Copyright (c) 2014. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_OBJECT_H -#define YR_OBJECT_H - -#ifdef _MSC_VER -#include -#define isnan _isnan -//#define INFINITY (DBL_MAX + DBL_MAX) -//#define NAN (INFINITY-INFINITY) -#endif - -#include "types.h" - - -#define OBJECT_CREATE 1 - -#define OBJECT_TYPE_INTEGER 1 -#define OBJECT_TYPE_STRING 2 -#define OBJECT_TYPE_STRUCTURE 3 -#define OBJECT_TYPE_ARRAY 4 -#define OBJECT_TYPE_FUNCTION 5 -#define OBJECT_TYPE_REGEXP 6 -#define OBJECT_TYPE_DICTIONARY 7 -#define OBJECT_TYPE_FLOAT 8 - - -int yr_object_create( - int8_t type, - const char* identifier, - YR_OBJECT* parent, - YR_OBJECT** object); - - -int yr_object_function_create( - const char* identifier, - const char* arguments_fmt, - const char* return_fmt, - YR_MODULE_FUNC func, - YR_OBJECT* parent, - YR_OBJECT** function); - - -int yr_object_from_external_variable( - YR_EXTERNAL_VARIABLE* external, - YR_OBJECT** object); - - -void yr_object_destroy( - YR_OBJECT* object); - - -YR_OBJECT* yr_object_lookup_field( - YR_OBJECT* object, - const char* field_name); - - -YR_OBJECT* yr_object_lookup( - YR_OBJECT* root, - int flags, - const char* pattern, - ...); - - -int yr_object_has_undefined_value( - YR_OBJECT* object, - const char* field, - ...); - -int64_t yr_object_get_integer( - YR_OBJECT* object, - const char* field, - ...); - - -SIZED_STRING* yr_object_get_string( - YR_OBJECT* object, - const char* field, - ...); - - -int yr_object_set_integer( - int64_t value, - YR_OBJECT* object, - const char* field, - ...); - - -int yr_object_set_float( - double value, - YR_OBJECT* object, - const char* field, - ...); - - -int yr_object_set_string( - const char* value, - size_t len, - YR_OBJECT* object, - const char* field, - ...); - - -YR_OBJECT* yr_object_array_get_item( - YR_OBJECT* object, - int flags, - int index); - - -int yr_object_array_set_item( - YR_OBJECT* object, - YR_OBJECT* item, - int index); - - -YR_OBJECT* yr_object_dict_get_item( - YR_OBJECT* object, - int flags, - const char* key); - - -int yr_object_dict_set_item( - YR_OBJECT* object, - YR_OBJECT* item, - const char* key); - - -int yr_object_structure_set_member( - YR_OBJECT* object, - YR_OBJECT* member); - - -YR_OBJECT* yr_object_get_root( - YR_OBJECT* object); - - -void yr_object_print_data( - YR_OBJECT* object, - int indent); - - -#endif +/* +Copyright (c) 2014. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_OBJECT_H +#define YR_OBJECT_H + +#ifdef _MSC_VER +#include +#define isnan _isnan +//#define INFINITY (DBL_MAX + DBL_MAX) +//#define NAN (INFINITY-INFINITY) +#endif + +#include "types.h" + + +#define OBJECT_CREATE 1 + +#define OBJECT_TYPE_INTEGER 1 +#define OBJECT_TYPE_STRING 2 +#define OBJECT_TYPE_STRUCTURE 3 +#define OBJECT_TYPE_ARRAY 4 +#define OBJECT_TYPE_FUNCTION 5 +#define OBJECT_TYPE_REGEXP 6 +#define OBJECT_TYPE_DICTIONARY 7 +#define OBJECT_TYPE_FLOAT 8 + + +int yr_object_create( + int8_t type, + const char* identifier, + YR_OBJECT* parent, + YR_OBJECT** object); + + +int yr_object_function_create( + const char* identifier, + const char* arguments_fmt, + const char* return_fmt, + YR_MODULE_FUNC func, + YR_OBJECT* parent, + YR_OBJECT** function); + + +int yr_object_from_external_variable( + YR_EXTERNAL_VARIABLE* external, + YR_OBJECT** object); + + +void yr_object_destroy( + YR_OBJECT* object); + + +YR_OBJECT* yr_object_lookup_field( + YR_OBJECT* object, + const char* field_name); + + +YR_OBJECT* yr_object_lookup( + YR_OBJECT* root, + int flags, + const char* pattern, + ...); + + +int yr_object_has_undefined_value( + YR_OBJECT* object, + const char* field, + ...); + +int64_t yr_object_get_integer( + YR_OBJECT* object, + const char* field, + ...); + + +SIZED_STRING* yr_object_get_string( + YR_OBJECT* object, + const char* field, + ...); + + +int yr_object_set_integer( + int64_t value, + YR_OBJECT* object, + const char* field, + ...); + + +int yr_object_set_float( + double value, + YR_OBJECT* object, + const char* field, + ...); + + +int yr_object_set_string( + const char* value, + size_t len, + YR_OBJECT* object, + const char* field, + ...); + + +YR_OBJECT* yr_object_array_get_item( + YR_OBJECT* object, + int flags, + int index); + + +int yr_object_array_set_item( + YR_OBJECT* object, + YR_OBJECT* item, + int index); + + +YR_OBJECT* yr_object_dict_get_item( + YR_OBJECT* object, + int flags, + const char* key); + + +int yr_object_dict_set_item( + YR_OBJECT* object, + YR_OBJECT* item, + const char* key); + + +int yr_object_structure_set_member( + YR_OBJECT* object, + YR_OBJECT* member); + + +YR_OBJECT* yr_object_get_root( + YR_OBJECT* object); + + +void yr_object_print_data( + YR_OBJECT* object, + int indent); + + +#endif diff --git a/src/dbg/yara/yara/parser.h b/src/dbg/yara/yara/parser.h index 41904be7..204b87bc 100644 --- a/src/dbg/yara/yara/parser.h +++ b/src/dbg/yara/yara/parser.h @@ -1,120 +1,120 @@ -/* -Copyright (c) 2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_PARSER_H -#define YR_PARSER_H - - -#include "lexer.h" - - -int yr_parser_emit( - yyscan_t yyscanner, - int8_t instruction, - int8_t** instruction_address); - - -int yr_parser_emit_with_arg( - yyscan_t yyscanner, - int8_t instruction, - int64_t argument, - int8_t** instruction_address); - - -int yr_parser_emit_with_arg_double( - yyscan_t yyscanner, - int8_t instruction, - double argument, - int8_t** instruction_address); - - -int yr_parser_emit_with_arg_reloc( - yyscan_t yyscanner, - int8_t instruction, - int64_t argument, - int8_t** instruction_address); - - -int yr_parser_check_types( - YR_COMPILER* compiler, - YR_OBJECT_FUNCTION* function, - const char* actual_args_fmt); - - -YR_STRING* yr_parser_lookup_string( - yyscan_t yyscanner, - const char* identifier); - - -int yr_parser_lookup_loop_variable( - yyscan_t yyscanner, - const char* identifier); - - -int yr_parser_reduce_rule_declaration( - yyscan_t yyscanner, - int flags, - const char* identifier, - char* tags, - YR_STRING* strings, - YR_META* metas); - - -YR_STRING* yr_parser_reduce_string_declaration( - yyscan_t yyscanner, - int flags, - const char* identifier, - SIZED_STRING* str); - - -YR_META* yr_parser_reduce_meta_declaration( - yyscan_t yyscanner, - int32_t type, - const char* identifier, - const char* string, - int32_t integer); - - -int yr_parser_reduce_string_identifier( - yyscan_t yyscanner, - const char* identifier, - int8_t instruction, - uint64_t at_offset); - - -int yr_parser_emit_pushes_for_strings( - yyscan_t yyscanner, - const char* identifier); - - -int yr_parser_reduce_external( - yyscan_t yyscanner, - const char* identifier, - int8_t intruction); - - -int yr_parser_reduce_import( - yyscan_t yyscanner, - SIZED_STRING* module_name); - - -int yr_parser_reduce_operation( - yyscan_t yyscanner, - const char* operation, - EXPRESSION left_operand, - EXPRESSION right_operand); - -#endif +/* +Copyright (c) 2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_PARSER_H +#define YR_PARSER_H + + +#include "lexer.h" + + +int yr_parser_emit( + yyscan_t yyscanner, + int8_t instruction, + int8_t** instruction_address); + + +int yr_parser_emit_with_arg( + yyscan_t yyscanner, + int8_t instruction, + int64_t argument, + int8_t** instruction_address); + + +int yr_parser_emit_with_arg_double( + yyscan_t yyscanner, + int8_t instruction, + double argument, + int8_t** instruction_address); + + +int yr_parser_emit_with_arg_reloc( + yyscan_t yyscanner, + int8_t instruction, + int64_t argument, + int8_t** instruction_address); + + +int yr_parser_check_types( + YR_COMPILER* compiler, + YR_OBJECT_FUNCTION* function, + const char* actual_args_fmt); + + +YR_STRING* yr_parser_lookup_string( + yyscan_t yyscanner, + const char* identifier); + + +int yr_parser_lookup_loop_variable( + yyscan_t yyscanner, + const char* identifier); + + +int yr_parser_reduce_rule_declaration( + yyscan_t yyscanner, + int flags, + const char* identifier, + char* tags, + YR_STRING* strings, + YR_META* metas); + + +YR_STRING* yr_parser_reduce_string_declaration( + yyscan_t yyscanner, + int flags, + const char* identifier, + SIZED_STRING* str); + + +YR_META* yr_parser_reduce_meta_declaration( + yyscan_t yyscanner, + int32_t type, + const char* identifier, + const char* string, + int32_t integer); + + +int yr_parser_reduce_string_identifier( + yyscan_t yyscanner, + const char* identifier, + int8_t instruction, + uint64_t at_offset); + + +int yr_parser_emit_pushes_for_strings( + yyscan_t yyscanner, + const char* identifier); + + +int yr_parser_reduce_external( + yyscan_t yyscanner, + const char* identifier, + int8_t intruction); + + +int yr_parser_reduce_import( + yyscan_t yyscanner, + SIZED_STRING* module_name); + + +int yr_parser_reduce_operation( + yyscan_t yyscanner, + const char* operation, + EXPRESSION left_operand, + EXPRESSION right_operand); + +#endif diff --git a/src/dbg/yara/yara/pe.h b/src/dbg/yara/yara/pe.h index f8518324..c97be621 100644 --- a/src/dbg/yara/yara/pe.h +++ b/src/dbg/yara/yara/pe.h @@ -1,491 +1,491 @@ -/* -Copyright (c) 2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#pragma pack(push, 1) - -#ifdef _WIN32 -#include - -// These definitions are not present in older Windows headers. - -#ifndef IMAGE_FILE_MACHINE_ARMNT -#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 -#endif - -#ifndef IMAGE_FILE_MACHINE_ARM64 -#define IMAGE_FILE_MACHINE_ARM64 0xaa64 -#endif - -#else - -#include -#include - -typedef uint8_t BYTE; -typedef uint16_t WORD; -typedef uint32_t DWORD; -typedef int32_t LONG; -typedef uint32_t ULONG; -typedef uint64_t ULONGLONG; - - -#define FIELD_OFFSET(type, field) ((size_t)&(((type *)0)->field)) - -#ifndef _MAC - -#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ -#define IMAGE_OS2_SIGNATURE 0x454E // NE -#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE -#define IMAGE_VXD_SIGNATURE 0x454C // LE -#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 - -#else - -#define IMAGE_DOS_SIGNATURE 0x4D5A // MZ -#define IMAGE_OS2_SIGNATURE 0x4E45 // NE -#define IMAGE_OS2_SIGNATURE_LE 0x4C45 // LE -#define IMAGE_NT_SIGNATURE 0x50450000 // PE00 - -#endif - -#pragma pack(push, 2) - -typedef struct _IMAGE_DOS_HEADER // DOS .EXE header -{ - WORD e_magic; // Magic number - WORD e_cblp; // Bytes on last page of file - WORD e_cp; // Pages in file - WORD e_crlc; // Relocations - WORD e_cparhdr; // Size of header in paragraphs - WORD e_minalloc; // Minimum extra paragraphs needed - WORD e_maxalloc; // Maximum extra paragraphs needed - WORD e_ss; // Initial (relative) SS value - WORD e_sp; // Initial SP value - WORD e_csum; // Checksum - WORD e_ip; // Initial IP value - WORD e_cs; // Initial (relative) CS value - WORD e_lfarlc; // File address of relocation table - WORD e_ovno; // Overlay number - WORD e_res[4]; // Reserved words - WORD e_oemid; // OEM identifier (for e_oeminfo) - WORD e_oeminfo; // OEM information; e_oemid specific - WORD e_res2[10]; // Reserved words - LONG e_lfanew; // File address of new exe header -} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; - -#pragma pack(pop) - -// -// File header format. -// - -#pragma pack(push,4) - -typedef struct _IMAGE_FILE_HEADER -{ - WORD Machine; - WORD NumberOfSections; - DWORD TimeDateStamp; - DWORD PointerToSymbolTable; - DWORD NumberOfSymbols; - WORD SizeOfOptionalHeader; - WORD Characteristics; -} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; - - - -#define IMAGE_SIZEOF_FILE_HEADER 20 - - -#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. -#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). -#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. -#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. -#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // Agressively trim working set -#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // App can handle >2gb addresses -#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. -#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. -#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file -#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file. -#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file. -#define IMAGE_FILE_SYSTEM 0x1000 // System File. -#define IMAGE_FILE_DLL 0x2000 // File is a DLL. -#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine -#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. - - -#define IMAGE_FILE_MACHINE_UNKNOWN 0x0000 -#define IMAGE_FILE_MACHINE_AM33 0x01d3 -#define IMAGE_FILE_MACHINE_AMD64 0x8664 -#define IMAGE_FILE_MACHINE_ARM 0x01c0 -#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 -#define IMAGE_FILE_MACHINE_ARM64 0xaa64 -#define IMAGE_FILE_MACHINE_EBC 0x0ebc -#define IMAGE_FILE_MACHINE_I386 0x014c -#define IMAGE_FILE_MACHINE_IA64 0x0200 -#define IMAGE_FILE_MACHINE_M32R 0x9041 -#define IMAGE_FILE_MACHINE_MIPS16 0x0266 -#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 -#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 -#define IMAGE_FILE_MACHINE_POWERPC 0x01f0 -#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 -#define IMAGE_FILE_MACHINE_R4000 0x0166 -#define IMAGE_FILE_MACHINE_SH3 0x01a2 -#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 -#define IMAGE_FILE_MACHINE_SH4 0x01a6 -#define IMAGE_FILE_MACHINE_SH5 0x01a8 -#define IMAGE_FILE_MACHINE_THUMB 0x01c2 -#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 - -// Section characteristics -#define IMAGE_SCN_CNT_CODE 0x00000020 -#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 -#define IMAGE_SCN_GPREL 0x00008000 -#define IMAGE_SCN_MEM_16BIT 0x00020000 -#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 -#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 -#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 -#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 -#define IMAGE_SCN_MEM_SHARED 0x10000000 -#define IMAGE_SCN_MEM_EXECUTE 0x20000000 -#define IMAGE_SCN_MEM_READ 0x40000000 -#define IMAGE_SCN_MEM_WRITE 0x80000000 - -// -// Directory format. -// - -typedef struct _IMAGE_DATA_DIRECTORY -{ - DWORD VirtualAddress; - DWORD Size; -} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; - -#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 - - -#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory -#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory -#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory -#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory -#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory -#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table -#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory -#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage) -#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data -#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP -#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory -#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory -#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers -#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table -#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors -#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor - - -// -// Optional header format. -// - -typedef struct _IMAGE_OPTIONAL_HEADER32 -{ - WORD Magic; - BYTE MajorLinkerVersion; - BYTE MinorLinkerVersion; - DWORD SizeOfCode; - DWORD SizeOfInitializedData; - DWORD SizeOfUninitializedData; - DWORD AddressOfEntryPoint; - DWORD BaseOfCode; - DWORD BaseOfData; - DWORD ImageBase; - DWORD SectionAlignment; - DWORD FileAlignment; - WORD MajorOperatingSystemVersion; - WORD MinorOperatingSystemVersion; - WORD MajorImageVersion; - WORD MinorImageVersion; - WORD MajorSubsystemVersion; - WORD MinorSubsystemVersion; - DWORD Win32VersionValue; - DWORD SizeOfImage; - DWORD SizeOfHeaders; - DWORD CheckSum; - WORD Subsystem; - WORD DllCharacteristics; - DWORD SizeOfStackReserve; - DWORD SizeOfStackCommit; - DWORD SizeOfHeapReserve; - DWORD SizeOfHeapCommit; - DWORD LoaderFlags; - DWORD NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; - -} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; - - -typedef struct _IMAGE_OPTIONAL_HEADER64 -{ - WORD Magic; - BYTE MajorLinkerVersion; - BYTE MinorLinkerVersion; - DWORD SizeOfCode; - DWORD SizeOfInitializedData; - DWORD SizeOfUninitializedData; - DWORD AddressOfEntryPoint; - DWORD BaseOfCode; - ULONGLONG ImageBase; - DWORD SectionAlignment; - DWORD FileAlignment; - WORD MajorOperatingSystemVersion; - WORD MinorOperatingSystemVersion; - WORD MajorImageVersion; - WORD MinorImageVersion; - WORD MajorSubsystemVersion; - WORD MinorSubsystemVersion; - DWORD Win32VersionValue; - DWORD SizeOfImage; - DWORD SizeOfHeaders; - DWORD CheckSum; - WORD Subsystem; - WORD DllCharacteristics; - ULONGLONG SizeOfStackReserve; - ULONGLONG SizeOfStackCommit; - ULONGLONG SizeOfHeapReserve; - ULONGLONG SizeOfHeapCommit; - DWORD LoaderFlags; - DWORD NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; - -} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; - - -#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b -#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b - - -typedef struct _IMAGE_NT_HEADERS32 -{ - DWORD Signature; - IMAGE_FILE_HEADER FileHeader; - IMAGE_OPTIONAL_HEADER32 OptionalHeader; - -} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; - - -typedef struct _IMAGE_NT_HEADERS64 -{ - DWORD Signature; - IMAGE_FILE_HEADER FileHeader; - IMAGE_OPTIONAL_HEADER64 OptionalHeader; - -} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; - - -// IMAGE_FIRST_SECTION doesn't need 32/64 versions since the file header is -// the same either way. - -#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \ - ((BYTE*)ntheader + \ - FIELD_OFFSET( IMAGE_NT_HEADERS32, OptionalHeader ) + \ - ((PIMAGE_NT_HEADERS32)(ntheader))->FileHeader.SizeOfOptionalHeader \ - )) - -// Subsystem Values - -#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. -#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. -#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. -#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. -#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. -#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image runs in the Posix character subsystem. -#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 // image is a native Win9x driver. - -// -// Section header format. -// - -#define IMAGE_SIZEOF_SHORT_NAME 8 - -typedef struct _IMAGE_SECTION_HEADER -{ - BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; - union - { - DWORD PhysicalAddress; - DWORD VirtualSize; - } Misc; - DWORD VirtualAddress; - DWORD SizeOfRawData; - DWORD PointerToRawData; - DWORD PointerToRelocations; - DWORD PointerToLinenumbers; - WORD NumberOfRelocations; - WORD NumberOfLinenumbers; - DWORD Characteristics; - -} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; - -#define IMAGE_SIZEOF_SECTION_HEADER 40 - - -typedef struct _IMAGE_EXPORT_DIRECTORY -{ - DWORD Characteristics; - DWORD TimeDateStamp; - WORD MajorVersion; - WORD MinorVersion; - DWORD Name; - DWORD Base; - DWORD NumberOfFunctions; - DWORD NumberOfNames; - DWORD AddressOfFunctions; - DWORD AddressOfNames; - DWORD AddressOfNameOrdinals; -} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; - - -typedef struct _IMAGE_IMPORT_DESCRIPTOR -{ - union - { - DWORD Characteristics; - DWORD OriginalFirstThunk; - } ; - DWORD TimeDateStamp; - DWORD ForwarderChain; - DWORD Name; - DWORD FirstThunk; - -} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; - - -typedef struct _IMAGE_IMPORT_BY_NAME -{ - WORD Hint; - BYTE Name[1]; - -} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; - -typedef struct _IMAGE_THUNK_DATA32 -{ - union - { - DWORD ForwarderString; - DWORD Function; - DWORD Ordinal; - DWORD AddressOfData; - } u1; - -} IMAGE_THUNK_DATA32, *PIMAGE_THUNK_DATA32; - - -#define IMAGE_ORDINAL_FLAG32 0x80000000 -#define IMAGE_ORDINAL_FLAG64 0x8000000000000000L - -typedef struct _IMAGE_THUNK_DATA64 -{ - union - { - ULONGLONG ForwarderString; - ULONGLONG Function; - ULONGLONG Ordinal; - ULONGLONG AddressOfData; - } u1; - -} IMAGE_THUNK_DATA64, *PIMAGE_THUNK_DATA64; - - -typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY -{ - DWORD Name; - DWORD OffsetToData; -} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY; - - -typedef struct _IMAGE_RESOURCE_DATA_ENTRY -{ - DWORD OffsetToData; - DWORD Size; - DWORD CodePage; - DWORD Reserved; -} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY; - - -typedef struct _IMAGE_RESOURCE_DIRECTORY -{ - DWORD Characteristics; - DWORD TimeDateStamp; - WORD MajorVersion; - WORD MinorVersion; - WORD NumberOfNamedEntries; - WORD NumberOfIdEntries; -} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY; - -#pragma pack(pop) - -#endif // _WIN32 - -typedef struct _VERSION_INFO -{ - WORD Length; - WORD ValueLength; - WORD Type; - char Key[0]; -} VERSION_INFO, *PVERSION_INFO; - - -#define WIN_CERT_REVISION_1_0 0x0100 -#define WIN_CERT_REVISION_2_0 0x0200 - -#define WIN_CERT_TYPE_X509 0x0001 -#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002 -#define WIN_CERT_TYPE_RESERVED_1 0x0003 -#define WIN_CERT_TYPE_TS_STACK_SIGNED 0x0004 - -typedef struct _WIN_CERTIFICATE -{ - DWORD Length; - WORD Revision; - WORD CertificateType; - BYTE Certificate[1]; -} WIN_CERTIFICATE, *PWIN_CERTIFICATE; - - -// -// Rich signature. -// http://www.ntcore.com/files/richsign.htm -// - -typedef struct _RICH_SIGNATURE -{ - DWORD dans; - DWORD key1; - DWORD key2; - DWORD key3; -} RICH_SIGNATURE, *PRICH_SIGNATURE; - -#define RICH_DANS 0x536e6144 // "DanS" -#define RICH_RICH 0x68636952 // "Rich" - -typedef struct _RICH_DATA -{ - size_t len; - BYTE* raw_data; - BYTE* clear_data; -} RICH_DATA, *PRICH_DATA; - -#pragma pack(pop) +/* +Copyright (c) 2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma pack(push, 1) + +#ifdef _WIN32 +#include + +// These definitions are not present in older Windows headers. + +#ifndef IMAGE_FILE_MACHINE_ARMNT +#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 +#endif + +#ifndef IMAGE_FILE_MACHINE_ARM64 +#define IMAGE_FILE_MACHINE_ARM64 0xaa64 +#endif + +#else + +#include +#include + +typedef uint8_t BYTE; +typedef uint16_t WORD; +typedef uint32_t DWORD; +typedef int32_t LONG; +typedef uint32_t ULONG; +typedef uint64_t ULONGLONG; + + +#define FIELD_OFFSET(type, field) ((size_t)&(((type *)0)->field)) + +#ifndef _MAC + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_OS2_SIGNATURE 0x454E // NE +#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE +#define IMAGE_VXD_SIGNATURE 0x454C // LE +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 + +#else + +#define IMAGE_DOS_SIGNATURE 0x4D5A // MZ +#define IMAGE_OS2_SIGNATURE 0x4E45 // NE +#define IMAGE_OS2_SIGNATURE_LE 0x4C45 // LE +#define IMAGE_NT_SIGNATURE 0x50450000 // PE00 + +#endif + +#pragma pack(push, 2) + +typedef struct _IMAGE_DOS_HEADER // DOS .EXE header +{ + WORD e_magic; // Magic number + WORD e_cblp; // Bytes on last page of file + WORD e_cp; // Pages in file + WORD e_crlc; // Relocations + WORD e_cparhdr; // Size of header in paragraphs + WORD e_minalloc; // Minimum extra paragraphs needed + WORD e_maxalloc; // Maximum extra paragraphs needed + WORD e_ss; // Initial (relative) SS value + WORD e_sp; // Initial SP value + WORD e_csum; // Checksum + WORD e_ip; // Initial IP value + WORD e_cs; // Initial (relative) CS value + WORD e_lfarlc; // File address of relocation table + WORD e_ovno; // Overlay number + WORD e_res[4]; // Reserved words + WORD e_oemid; // OEM identifier (for e_oeminfo) + WORD e_oeminfo; // OEM information; e_oemid specific + WORD e_res2[10]; // Reserved words + LONG e_lfanew; // File address of new exe header +} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +#pragma pack(pop) + +// +// File header format. +// + +#pragma pack(push,4) + +typedef struct _IMAGE_FILE_HEADER +{ + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + + + +#define IMAGE_SIZEOF_FILE_HEADER 20 + + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // Agressively trim working set +#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // App can handle >2gb addresses +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file. +#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file. +#define IMAGE_FILE_SYSTEM 0x1000 // System File. +#define IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. + + +#define IMAGE_FILE_MACHINE_UNKNOWN 0x0000 +#define IMAGE_FILE_MACHINE_AM33 0x01d3 +#define IMAGE_FILE_MACHINE_AMD64 0x8664 +#define IMAGE_FILE_MACHINE_ARM 0x01c0 +#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 +#define IMAGE_FILE_MACHINE_ARM64 0xaa64 +#define IMAGE_FILE_MACHINE_EBC 0x0ebc +#define IMAGE_FILE_MACHINE_I386 0x014c +#define IMAGE_FILE_MACHINE_IA64 0x0200 +#define IMAGE_FILE_MACHINE_M32R 0x9041 +#define IMAGE_FILE_MACHINE_MIPS16 0x0266 +#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 +#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 +#define IMAGE_FILE_MACHINE_POWERPC 0x01f0 +#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 +#define IMAGE_FILE_MACHINE_R4000 0x0166 +#define IMAGE_FILE_MACHINE_SH3 0x01a2 +#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 +#define IMAGE_FILE_MACHINE_SH4 0x01a6 +#define IMAGE_FILE_MACHINE_SH5 0x01a8 +#define IMAGE_FILE_MACHINE_THUMB 0x01c2 +#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 + +// Section characteristics +#define IMAGE_SCN_CNT_CODE 0x00000020 +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 +#define IMAGE_SCN_GPREL 0x00008000 +#define IMAGE_SCN_MEM_16BIT 0x00020000 +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 +#define IMAGE_SCN_MEM_SHARED 0x10000000 +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 +#define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_WRITE 0x80000000 + +// +// Directory format. +// + +typedef struct _IMAGE_DATA_DIRECTORY +{ + DWORD VirtualAddress; + DWORD Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage) +#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP +#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory +#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers +#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table +#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors +#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor + + +// +// Optional header format. +// + +typedef struct _IMAGE_OPTIONAL_HEADER32 +{ + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + DWORD ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD SizeOfHeapReserve; + DWORD SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; + +} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; + + +typedef struct _IMAGE_OPTIONAL_HEADER64 +{ + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + ULONGLONG ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + ULONGLONG SizeOfStackReserve; + ULONGLONG SizeOfStackCommit; + ULONGLONG SizeOfHeapReserve; + ULONGLONG SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; + +} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; + + +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + + +typedef struct _IMAGE_NT_HEADERS32 +{ + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER32 OptionalHeader; + +} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; + + +typedef struct _IMAGE_NT_HEADERS64 +{ + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; + +} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; + + +// IMAGE_FIRST_SECTION doesn't need 32/64 versions since the file header is +// the same either way. + +#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \ + ((BYTE*)ntheader + \ + FIELD_OFFSET( IMAGE_NT_HEADERS32, OptionalHeader ) + \ + ((PIMAGE_NT_HEADERS32)(ntheader))->FileHeader.SizeOfOptionalHeader \ + )) + +// Subsystem Values + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. +#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. +#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image runs in the Posix character subsystem. +#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 // image is a native Win9x driver. + +// +// Section header format. +// + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER +{ + BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; + union + { + DWORD PhysicalAddress; + DWORD VirtualSize; + } Misc; + DWORD VirtualAddress; + DWORD SizeOfRawData; + DWORD PointerToRawData; + DWORD PointerToRelocations; + DWORD PointerToLinenumbers; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD Characteristics; + +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + + +typedef struct _IMAGE_EXPORT_DIRECTORY +{ + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Name; + DWORD Base; + DWORD NumberOfFunctions; + DWORD NumberOfNames; + DWORD AddressOfFunctions; + DWORD AddressOfNames; + DWORD AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + + +typedef struct _IMAGE_IMPORT_DESCRIPTOR +{ + union + { + DWORD Characteristics; + DWORD OriginalFirstThunk; + } ; + DWORD TimeDateStamp; + DWORD ForwarderChain; + DWORD Name; + DWORD FirstThunk; + +} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; + + +typedef struct _IMAGE_IMPORT_BY_NAME +{ + WORD Hint; + BYTE Name[1]; + +} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; + +typedef struct _IMAGE_THUNK_DATA32 +{ + union + { + DWORD ForwarderString; + DWORD Function; + DWORD Ordinal; + DWORD AddressOfData; + } u1; + +} IMAGE_THUNK_DATA32, *PIMAGE_THUNK_DATA32; + + +#define IMAGE_ORDINAL_FLAG32 0x80000000 +#define IMAGE_ORDINAL_FLAG64 0x8000000000000000L + +typedef struct _IMAGE_THUNK_DATA64 +{ + union + { + ULONGLONG ForwarderString; + ULONGLONG Function; + ULONGLONG Ordinal; + ULONGLONG AddressOfData; + } u1; + +} IMAGE_THUNK_DATA64, *PIMAGE_THUNK_DATA64; + + +typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY +{ + DWORD Name; + DWORD OffsetToData; +} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY; + + +typedef struct _IMAGE_RESOURCE_DATA_ENTRY +{ + DWORD OffsetToData; + DWORD Size; + DWORD CodePage; + DWORD Reserved; +} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY; + + +typedef struct _IMAGE_RESOURCE_DIRECTORY +{ + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + WORD NumberOfNamedEntries; + WORD NumberOfIdEntries; +} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY; + +#pragma pack(pop) + +#endif // _WIN32 + +typedef struct _VERSION_INFO +{ + WORD Length; + WORD ValueLength; + WORD Type; + char Key[0]; +} VERSION_INFO, *PVERSION_INFO; + + +#define WIN_CERT_REVISION_1_0 0x0100 +#define WIN_CERT_REVISION_2_0 0x0200 + +#define WIN_CERT_TYPE_X509 0x0001 +#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002 +#define WIN_CERT_TYPE_RESERVED_1 0x0003 +#define WIN_CERT_TYPE_TS_STACK_SIGNED 0x0004 + +typedef struct _WIN_CERTIFICATE +{ + DWORD Length; + WORD Revision; + WORD CertificateType; + BYTE Certificate[1]; +} WIN_CERTIFICATE, *PWIN_CERTIFICATE; + + +// +// Rich signature. +// http://www.ntcore.com/files/richsign.htm +// + +typedef struct _RICH_SIGNATURE +{ + DWORD dans; + DWORD key1; + DWORD key2; + DWORD key3; +} RICH_SIGNATURE, *PRICH_SIGNATURE; + +#define RICH_DANS 0x536e6144 // "DanS" +#define RICH_RICH 0x68636952 // "Rich" + +typedef struct _RICH_DATA +{ + size_t len; + BYTE* raw_data; + BYTE* clear_data; +} RICH_DATA, *PRICH_DATA; + +#pragma pack(pop) diff --git a/src/dbg/yara/yara/proc.h b/src/dbg/yara/yara/proc.h index 0e894261..d64a1866 100644 --- a/src/dbg/yara/yara/proc.h +++ b/src/dbg/yara/yara/proc.h @@ -1,26 +1,26 @@ -/* -Copyright (c) 2007. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_PROC_H -#define YR_PROC_H - -#include "types.h" - -int yr_process_get_memory( - int pid, - YR_MEMORY_BLOCK** first_block); - -#endif +/* +Copyright (c) 2007. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_PROC_H +#define YR_PROC_H + +#include "types.h" + +int yr_process_get_memory( + int pid, + YR_MEMORY_BLOCK** first_block); + +#endif diff --git a/src/dbg/yara/yara/re.h b/src/dbg/yara/yara/re.h index b6e1ff78..3fb10324 100644 --- a/src/dbg/yara/yara/re.h +++ b/src/dbg/yara/yara/re.h @@ -1,240 +1,240 @@ -/* -Copyright (c) 2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_RE_H -#define YR_RE_H - -#include - -#include "arena.h" -#include "sizedstr.h" - -#define RE_NODE_LITERAL 1 -#define RE_NODE_MASKED_LITERAL 2 -#define RE_NODE_ANY 3 -#define RE_NODE_CONCAT 4 -#define RE_NODE_ALT 5 -#define RE_NODE_RANGE 6 -#define RE_NODE_STAR 7 -#define RE_NODE_PLUS 8 -#define RE_NODE_CLASS 9 -#define RE_NODE_WORD_CHAR 10 -#define RE_NODE_NON_WORD_CHAR 11 -#define RE_NODE_SPACE 12 -#define RE_NODE_NON_SPACE 13 -#define RE_NODE_DIGIT 14 -#define RE_NODE_NON_DIGIT 15 -#define RE_NODE_EMPTY 16 -#define RE_NODE_ANCHOR_START 17 -#define RE_NODE_ANCHOR_END 18 -#define RE_NODE_WORD_BOUNDARY 19 -#define RE_NODE_NON_WORD_BOUNDARY 20 - - -#define RE_OPCODE_ANY 0xA0 -#define RE_OPCODE_ANY_EXCEPT_NEW_LINE 0xA1 -#define RE_OPCODE_LITERAL 0xA2 -#define RE_OPCODE_LITERAL_NO_CASE 0xA3 -#define RE_OPCODE_MASKED_LITERAL 0xA4 -#define RE_OPCODE_CLASS 0xA5 -#define RE_OPCODE_CLASS_NO_CASE 0xA6 -#define RE_OPCODE_WORD_CHAR 0xA7 -#define RE_OPCODE_NON_WORD_CHAR 0xA8 -#define RE_OPCODE_SPACE 0xA9 -#define RE_OPCODE_NON_SPACE 0xAA -#define RE_OPCODE_DIGIT 0xAB -#define RE_OPCODE_NON_DIGIT 0xAC -#define RE_OPCODE_MATCH 0xAD - -#define RE_OPCODE_MATCH_AT_END 0xB0 -#define RE_OPCODE_MATCH_AT_START 0xB1 -#define RE_OPCODE_WORD_BOUNDARY 0xB2 -#define RE_OPCODE_NON_WORD_BOUNDARY 0xB3 - -#define RE_OPCODE_SPLIT_A 0xC0 -#define RE_OPCODE_SPLIT_B 0xC1 -#define RE_OPCODE_PUSH 0xC2 -#define RE_OPCODE_POP 0xC3 -#define RE_OPCODE_JNZ 0xC4 -#define RE_OPCODE_JUMP 0xC5 - - -#define RE_FLAGS_FAST_HEX_REGEXP 0x02 -#define RE_FLAGS_BACKWARDS 0x04 -#define RE_FLAGS_EXHAUSTIVE 0x08 -#define RE_FLAGS_WIDE 0x10 -#define RE_FLAGS_NO_CASE 0x20 -#define RE_FLAGS_SCAN 0x40 -#define RE_FLAGS_DOT_ALL 0x80 -#define RE_FLAGS_NOT_AT_START 0x100 - - -typedef struct RE RE; -typedef struct RE_NODE RE_NODE; -typedef struct RE_ERROR RE_ERROR; - -typedef uint8_t* RE_CODE; - -#define CHAR_IN_CLASS(chr, cls) \ - ((cls)[(chr) / 8] & 1 << ((chr) % 8)) - - -#define IS_WORD_CHAR(chr) \ - (isalnum(chr) || (chr) == '_') - - -struct RE_NODE -{ - int type; - - union - { - int value; - int count; - int start; - }; - - union - { - int mask; - int end; - }; - - int greedy; - - uint8_t* class_vector; - - RE_NODE* left; - RE_NODE* right; - - RE_CODE forward_code; - RE_CODE backward_code; -}; - - -struct RE -{ - - uint32_t flags; - RE_NODE* root_node; - YR_ARENA* code_arena; - RE_CODE code; -}; - - -struct RE_ERROR -{ - - char message[512]; - -}; - - -typedef int RE_MATCH_CALLBACK_FUNC( - uint8_t* match, - int match_length, - int flags, - void* args); - - -int yr_re_create( - RE** re); - - -int yr_re_parse( - const char* re_string, - int flags, - RE** re, - RE_ERROR* error); - - -int yr_re_parse_hex( - const char* hex_string, - int flags, - RE** re, - RE_ERROR* error); - - -int yr_re_compile( - const char* re_string, - int flags, - YR_ARENA* code_arena, - RE** re, - RE_ERROR* error); - - -void yr_re_destroy( - RE* re); - - -void yr_re_print( - RE* re); - - -RE_NODE* yr_re_node_create( - int type, - RE_NODE* left, - RE_NODE* right); - - -void yr_re_node_destroy( - RE_NODE* node); - - -SIZED_STRING* yr_re_extract_literal( - RE* re); - - -int yr_re_contains_dot_star( - RE* re); - - -int yr_re_split_at_chaining_point( - RE* re, - RE** result_re, - RE** remainder_re, - int32_t* min_gap, - int32_t* max_gap); - - -int yr_re_emit_code( - RE* re, - YR_ARENA* arena); - - -int yr_re_exec( - RE_CODE re_code, - uint8_t* input, - size_t input_size, - int flags, - RE_MATCH_CALLBACK_FUNC callback, - void* callback_args); - - -int yr_re_match( - RE_CODE re_code, - const char* target); - - -int yr_re_initialize(void); - - -int yr_re_finalize(void); - - -int yr_re_finalize_thread(void); - -#endif +/* +Copyright (c) 2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_RE_H +#define YR_RE_H + +#include + +#include "arena.h" +#include "sizedstr.h" + +#define RE_NODE_LITERAL 1 +#define RE_NODE_MASKED_LITERAL 2 +#define RE_NODE_ANY 3 +#define RE_NODE_CONCAT 4 +#define RE_NODE_ALT 5 +#define RE_NODE_RANGE 6 +#define RE_NODE_STAR 7 +#define RE_NODE_PLUS 8 +#define RE_NODE_CLASS 9 +#define RE_NODE_WORD_CHAR 10 +#define RE_NODE_NON_WORD_CHAR 11 +#define RE_NODE_SPACE 12 +#define RE_NODE_NON_SPACE 13 +#define RE_NODE_DIGIT 14 +#define RE_NODE_NON_DIGIT 15 +#define RE_NODE_EMPTY 16 +#define RE_NODE_ANCHOR_START 17 +#define RE_NODE_ANCHOR_END 18 +#define RE_NODE_WORD_BOUNDARY 19 +#define RE_NODE_NON_WORD_BOUNDARY 20 + + +#define RE_OPCODE_ANY 0xA0 +#define RE_OPCODE_ANY_EXCEPT_NEW_LINE 0xA1 +#define RE_OPCODE_LITERAL 0xA2 +#define RE_OPCODE_LITERAL_NO_CASE 0xA3 +#define RE_OPCODE_MASKED_LITERAL 0xA4 +#define RE_OPCODE_CLASS 0xA5 +#define RE_OPCODE_CLASS_NO_CASE 0xA6 +#define RE_OPCODE_WORD_CHAR 0xA7 +#define RE_OPCODE_NON_WORD_CHAR 0xA8 +#define RE_OPCODE_SPACE 0xA9 +#define RE_OPCODE_NON_SPACE 0xAA +#define RE_OPCODE_DIGIT 0xAB +#define RE_OPCODE_NON_DIGIT 0xAC +#define RE_OPCODE_MATCH 0xAD + +#define RE_OPCODE_MATCH_AT_END 0xB0 +#define RE_OPCODE_MATCH_AT_START 0xB1 +#define RE_OPCODE_WORD_BOUNDARY 0xB2 +#define RE_OPCODE_NON_WORD_BOUNDARY 0xB3 + +#define RE_OPCODE_SPLIT_A 0xC0 +#define RE_OPCODE_SPLIT_B 0xC1 +#define RE_OPCODE_PUSH 0xC2 +#define RE_OPCODE_POP 0xC3 +#define RE_OPCODE_JNZ 0xC4 +#define RE_OPCODE_JUMP 0xC5 + + +#define RE_FLAGS_FAST_HEX_REGEXP 0x02 +#define RE_FLAGS_BACKWARDS 0x04 +#define RE_FLAGS_EXHAUSTIVE 0x08 +#define RE_FLAGS_WIDE 0x10 +#define RE_FLAGS_NO_CASE 0x20 +#define RE_FLAGS_SCAN 0x40 +#define RE_FLAGS_DOT_ALL 0x80 +#define RE_FLAGS_NOT_AT_START 0x100 + + +typedef struct RE RE; +typedef struct RE_NODE RE_NODE; +typedef struct RE_ERROR RE_ERROR; + +typedef uint8_t* RE_CODE; + +#define CHAR_IN_CLASS(chr, cls) \ + ((cls)[(chr) / 8] & 1 << ((chr) % 8)) + + +#define IS_WORD_CHAR(chr) \ + (isalnum(chr) || (chr) == '_') + + +struct RE_NODE +{ + int type; + + union + { + int value; + int count; + int start; + }; + + union + { + int mask; + int end; + }; + + int greedy; + + uint8_t* class_vector; + + RE_NODE* left; + RE_NODE* right; + + RE_CODE forward_code; + RE_CODE backward_code; +}; + + +struct RE +{ + + uint32_t flags; + RE_NODE* root_node; + YR_ARENA* code_arena; + RE_CODE code; +}; + + +struct RE_ERROR +{ + + char message[512]; + +}; + + +typedef int RE_MATCH_CALLBACK_FUNC( + uint8_t* match, + int match_length, + int flags, + void* args); + + +int yr_re_create( + RE** re); + + +int yr_re_parse( + const char* re_string, + int flags, + RE** re, + RE_ERROR* error); + + +int yr_re_parse_hex( + const char* hex_string, + int flags, + RE** re, + RE_ERROR* error); + + +int yr_re_compile( + const char* re_string, + int flags, + YR_ARENA* code_arena, + RE** re, + RE_ERROR* error); + + +void yr_re_destroy( + RE* re); + + +void yr_re_print( + RE* re); + + +RE_NODE* yr_re_node_create( + int type, + RE_NODE* left, + RE_NODE* right); + + +void yr_re_node_destroy( + RE_NODE* node); + + +SIZED_STRING* yr_re_extract_literal( + RE* re); + + +int yr_re_contains_dot_star( + RE* re); + + +int yr_re_split_at_chaining_point( + RE* re, + RE** result_re, + RE** remainder_re, + int32_t* min_gap, + int32_t* max_gap); + + +int yr_re_emit_code( + RE* re, + YR_ARENA* arena); + + +int yr_re_exec( + RE_CODE re_code, + uint8_t* input, + size_t input_size, + int flags, + RE_MATCH_CALLBACK_FUNC callback, + void* callback_args); + + +int yr_re_match( + RE_CODE re_code, + const char* target); + + +int yr_re_initialize(void); + + +int yr_re_finalize(void); + + +int yr_re_finalize_thread(void); + +#endif diff --git a/src/dbg/yara/yara/re_lexer.h b/src/dbg/yara/yara/re_lexer.h index 1bf7aa30..4cf66bad 100644 --- a/src/dbg/yara/yara/re_lexer.h +++ b/src/dbg/yara/yara/re_lexer.h @@ -1,97 +1,97 @@ -/* -Copyright (c) 2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#undef yyparse -#undef yylex -#undef yyerror -#undef yyfatal -#undef yychar -#undef yydebug -#undef yynerrs -#undef yyget_extra -#undef yyget_lineno - -#undef YY_FATAL_ERROR -#undef YY_DECL -#undef LEX_ENV - - -#define yyparse re_yyparse -#define yylex re_yylex -#define yyerror re_yyerror -#define yyfatal re_yyfatal -#define yychar re_yychar -#define yydebug re_yydebug -#define yynerrs re_yynerrs -#define yyget_extra re_yyget_extra -#define yyget_lineno re_yyget_lineno - - -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -#define YY_EXTRA_TYPE RE* -#define YY_USE_CONST - - -typedef struct _RE_LEX_ENVIRONMENT -{ - int negated_class; - uint8_t class_vector[32]; - int last_error_code; - char last_error_message[256]; - -} RE_LEX_ENVIRONMENT; - - -#define LEX_ENV ((RE_LEX_ENVIRONMENT*) lex_env) - -#define YY_FATAL_ERROR(msg) re_yyfatal(yyscanner, msg) - -#include - -#define YY_DECL int re_yylex \ - (YYSTYPE * yylval_param , yyscan_t yyscanner, RE_LEX_ENVIRONMENT* lex_env) - - -YY_EXTRA_TYPE yyget_extra( - yyscan_t yyscanner); - -int yylex( - YYSTYPE* yylval_param, - yyscan_t yyscanner, - RE_LEX_ENVIRONMENT* lex_env); - -int yyparse( - void* yyscanner, - RE_LEX_ENVIRONMENT* lex_env); - -void yyerror( - yyscan_t yyscanner, - RE_LEX_ENVIRONMENT* lex_env, - const char* error_message); - -void yyfatal( - yyscan_t yyscanner, - const char* error_message); - -int yr_parse_re_string( - const char* re_string, - int flags, - RE** re, - RE_ERROR* error); +/* +Copyright (c) 2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#undef yyparse +#undef yylex +#undef yyerror +#undef yyfatal +#undef yychar +#undef yydebug +#undef yynerrs +#undef yyget_extra +#undef yyget_lineno + +#undef YY_FATAL_ERROR +#undef YY_DECL +#undef LEX_ENV + + +#define yyparse re_yyparse +#define yylex re_yylex +#define yyerror re_yyerror +#define yyfatal re_yyfatal +#define yychar re_yychar +#define yydebug re_yydebug +#define yynerrs re_yynerrs +#define yyget_extra re_yyget_extra +#define yyget_lineno re_yyget_lineno + + +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +#define YY_EXTRA_TYPE RE* +#define YY_USE_CONST + + +typedef struct _RE_LEX_ENVIRONMENT +{ + int negated_class; + uint8_t class_vector[32]; + int last_error_code; + char last_error_message[256]; + +} RE_LEX_ENVIRONMENT; + + +#define LEX_ENV ((RE_LEX_ENVIRONMENT*) lex_env) + +#define YY_FATAL_ERROR(msg) re_yyfatal(yyscanner, msg) + +#include + +#define YY_DECL int re_yylex \ + (YYSTYPE * yylval_param , yyscan_t yyscanner, RE_LEX_ENVIRONMENT* lex_env) + + +YY_EXTRA_TYPE yyget_extra( + yyscan_t yyscanner); + +int yylex( + YYSTYPE* yylval_param, + yyscan_t yyscanner, + RE_LEX_ENVIRONMENT* lex_env); + +int yyparse( + void* yyscanner, + RE_LEX_ENVIRONMENT* lex_env); + +void yyerror( + yyscan_t yyscanner, + RE_LEX_ENVIRONMENT* lex_env, + const char* error_message); + +void yyfatal( + yyscan_t yyscanner, + const char* error_message); + +int yr_parse_re_string( + const char* re_string, + int flags, + RE** re, + RE_ERROR* error); diff --git a/src/dbg/yara/yara/rules.h b/src/dbg/yara/yara/rules.h index 9bab0623..6112573c 100644 --- a/src/dbg/yara/yara/rules.h +++ b/src/dbg/yara/yara/rules.h @@ -1,127 +1,127 @@ -/* -Copyright (c) 2014. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#ifndef YR_RULES_H -#define YR_RULES_H - -#include "types.h" -#include "utils.h" - - -#define CALLBACK_MSG_RULE_MATCHING 1 -#define CALLBACK_MSG_RULE_NOT_MATCHING 2 -#define CALLBACK_MSG_SCAN_FINISHED 3 -#define CALLBACK_MSG_IMPORT_MODULE 4 - -#define CALLBACK_CONTINUE 0 -#define CALLBACK_ABORT 1 -#define CALLBACK_ERROR 2 - - -#define yr_rule_tags_foreach(rule, tag_name) \ - for (tag_name = rule->tags; \ - tag_name != NULL && *tag_name != '\0'; \ - tag_name += strlen(tag_name) + 1) - - -#define yr_rule_metas_foreach(rule, meta) \ - for (meta = rule->metas; !META_IS_NULL(meta); meta++) - - -#define yr_rule_strings_foreach(rule, string) \ - for (string = rule->strings; !STRING_IS_NULL(string); string++) - - -#define yr_string_matches_foreach(string, match) \ - for (match = STRING_MATCHES(string).head; match != NULL; match = match->next) - - -#define yr_rules_foreach(rules, rule) \ - for (rule = rules->rules_list_head; !RULE_IS_NULL(rule); rule++) - - - -YR_API int yr_rules_scan_mem( - YR_RULES* rules, - uint8_t* buffer, - size_t buffer_size, - int flags, - YR_CALLBACK_FUNC callback, - void* user_data, - int timeout); - - -YR_API int yr_rules_scan_file( - YR_RULES* rules, - const char* filename, - int flags, - YR_CALLBACK_FUNC callback, - void* user_data, - int timeout); - - -YR_API int yr_rules_scan_proc( - YR_RULES* rules, - int pid, - int flags, - YR_CALLBACK_FUNC callback, - void* user_data, - int timeout); - - -YR_API int yr_rules_save( - YR_RULES* rules, - const char* filename); - - -YR_API int yr_rules_load( - const char* filename, - YR_RULES** rules); - - -YR_API int yr_rules_destroy( - YR_RULES* rules); - - -YR_API int yr_rules_define_integer_variable( - YR_RULES* rules, - const char* identifier, - int64_t value); - - -YR_API int yr_rules_define_boolean_variable( - YR_RULES* rules, - const char* identifier, - int value); - - -YR_API int yr_rules_define_float_variable( - YR_RULES* rules, - const char* identifier, - double value); - - -YR_API int yr_rules_define_string_variable( - YR_RULES* rules, - const char* identifier, - const char* value); - - -YR_API void yr_rules_print_profiling_info( - YR_RULES* rules); - -#endif +/* +Copyright (c) 2014. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +#ifndef YR_RULES_H +#define YR_RULES_H + +#include "types.h" +#include "utils.h" + + +#define CALLBACK_MSG_RULE_MATCHING 1 +#define CALLBACK_MSG_RULE_NOT_MATCHING 2 +#define CALLBACK_MSG_SCAN_FINISHED 3 +#define CALLBACK_MSG_IMPORT_MODULE 4 + +#define CALLBACK_CONTINUE 0 +#define CALLBACK_ABORT 1 +#define CALLBACK_ERROR 2 + + +#define yr_rule_tags_foreach(rule, tag_name) \ + for (tag_name = rule->tags; \ + tag_name != NULL && *tag_name != '\0'; \ + tag_name += strlen(tag_name) + 1) + + +#define yr_rule_metas_foreach(rule, meta) \ + for (meta = rule->metas; !META_IS_NULL(meta); meta++) + + +#define yr_rule_strings_foreach(rule, string) \ + for (string = rule->strings; !STRING_IS_NULL(string); string++) + + +#define yr_string_matches_foreach(string, match) \ + for (match = STRING_MATCHES(string).head; match != NULL; match = match->next) + + +#define yr_rules_foreach(rules, rule) \ + for (rule = rules->rules_list_head; !RULE_IS_NULL(rule); rule++) + + + +YR_API int yr_rules_scan_mem( + YR_RULES* rules, + uint8_t* buffer, + size_t buffer_size, + int flags, + YR_CALLBACK_FUNC callback, + void* user_data, + int timeout); + + +YR_API int yr_rules_scan_file( + YR_RULES* rules, + const char* filename, + int flags, + YR_CALLBACK_FUNC callback, + void* user_data, + int timeout); + + +YR_API int yr_rules_scan_proc( + YR_RULES* rules, + int pid, + int flags, + YR_CALLBACK_FUNC callback, + void* user_data, + int timeout); + + +YR_API int yr_rules_save( + YR_RULES* rules, + const char* filename); + + +YR_API int yr_rules_load( + const char* filename, + YR_RULES** rules); + + +YR_API int yr_rules_destroy( + YR_RULES* rules); + + +YR_API int yr_rules_define_integer_variable( + YR_RULES* rules, + const char* identifier, + int64_t value); + + +YR_API int yr_rules_define_boolean_variable( + YR_RULES* rules, + const char* identifier, + int value); + + +YR_API int yr_rules_define_float_variable( + YR_RULES* rules, + const char* identifier, + double value); + + +YR_API int yr_rules_define_string_variable( + YR_RULES* rules, + const char* identifier, + const char* value); + + +YR_API void yr_rules_print_profiling_info( + YR_RULES* rules); + +#endif diff --git a/src/dbg/yara/yara/scan.h b/src/dbg/yara/yara/scan.h index ece9f766..34bcb306 100644 --- a/src/dbg/yara/yara/scan.h +++ b/src/dbg/yara/yara/scan.h @@ -1,35 +1,35 @@ -/* -Copyright (c) 2014. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_SCAN_H -#define YR_SCAN_H - -#include "types.h" - -#define SCAN_FLAGS_FAST_MODE 1 -#define SCAN_FLAGS_PROCESS_MEMORY 2 - - -int yr_scan_verify_match( - YR_AC_MATCH* ac_match, - uint8_t* data, - size_t data_size, - size_t data_base, - size_t offset, - YR_ARENA* matches_arena, - int flags); - -#endif +/* +Copyright (c) 2014. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_SCAN_H +#define YR_SCAN_H + +#include "types.h" + +#define SCAN_FLAGS_FAST_MODE 1 +#define SCAN_FLAGS_PROCESS_MEMORY 2 + + +int yr_scan_verify_match( + YR_AC_MATCH* ac_match, + uint8_t* data, + size_t data_size, + size_t data_base, + size_t offset, + YR_ARENA* matches_arena, + int flags); + +#endif diff --git a/src/dbg/yara/yara/sizedstr.h b/src/dbg/yara/yara/sizedstr.h index fe8a2833..7728c2f3 100644 --- a/src/dbg/yara/yara/sizedstr.h +++ b/src/dbg/yara/yara/sizedstr.h @@ -1,42 +1,42 @@ -/* -Copyright (c) 2007-2014. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _SIZEDSTR_H -#define _SIZEDSTR_H - -// -// This struct is used to support strings containing null chars. The length of -// the string is stored along the string data. However the string data is also -// terminated with a null char. -// - -#define SIZED_STRING_FLAGS_NO_CASE 1 -#define SIZED_STRING_FLAGS_DOT_ALL 2 - -typedef struct _SIZED_STRING -{ - int length; - int flags; - char c_string[1]; - -} SIZED_STRING; - - -int sized_string_cmp( - SIZED_STRING* s1, - SIZED_STRING* s2); - -#endif +/* +Copyright (c) 2007-2014. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _SIZEDSTR_H +#define _SIZEDSTR_H + +// +// This struct is used to support strings containing null chars. The length of +// the string is stored along the string data. However the string data is also +// terminated with a null char. +// + +#define SIZED_STRING_FLAGS_NO_CASE 1 +#define SIZED_STRING_FLAGS_DOT_ALL 2 + +typedef struct _SIZED_STRING +{ + int length; + int flags; + char c_string[1]; + +} SIZED_STRING; + + +int sized_string_cmp( + SIZED_STRING* s1, + SIZED_STRING* s2); + +#endif diff --git a/src/dbg/yara/yara/strutils.h b/src/dbg/yara/yara/strutils.h index 9ad7aa4e..788d5dc0 100644 --- a/src/dbg/yara/yara/strutils.h +++ b/src/dbg/yara/yara/strutils.h @@ -1,77 +1,77 @@ -/* -Copyright (c) 2007-2014. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_STRUTILS_H -#define YR_STRUTILS_H - -#include -#include -#include - -#include "config.h" - -#ifdef _WIN32 -#define snprintf _snprintf -#define strcasecmp _stricmp -#define strncasecmp _strnicmp -#endif - - -uint64_t xtoi( - const char* hexstr); - - -#if !HAVE_STRLCPY -size_t strlcpy( - char* dst, - const char* src, - size_t size); -#endif - - -#if !HAVE_STRLCAT -size_t strlcat( - char* dst, - const char* src, - size_t size); -#endif - - -#if !HAVE_MEMMEM -void* memmem( - const void* haystack, - size_t haystack_size, - const void* needle, - size_t needle_size); -#endif - - -int strlen_w( - const char* w_str); - - -int strcmp_w( - const char* w_str, - const char* str); - - -size_t strlcpy_w( - char* dst, - const char* w_src, - size_t n); - -#endif - +/* +Copyright (c) 2007-2014. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_STRUTILS_H +#define YR_STRUTILS_H + +#include +#include +#include + +#include "config.h" + +#ifdef _WIN32 +#define snprintf _snprintf +#define strcasecmp _stricmp +#define strncasecmp _strnicmp +#endif + + +uint64_t xtoi( + const char* hexstr); + + +#if !HAVE_STRLCPY +size_t strlcpy( + char* dst, + const char* src, + size_t size); +#endif + + +#if !HAVE_STRLCAT +size_t strlcat( + char* dst, + const char* src, + size_t size); +#endif + + +#if !HAVE_MEMMEM +void* memmem( + const void* haystack, + size_t haystack_size, + const void* needle, + size_t needle_size); +#endif + + +int strlen_w( + const char* w_str); + + +int strcmp_w( + const char* w_str, + const char* str); + + +size_t strlcpy_w( + char* dst, + const char* w_src, + size_t n); + +#endif + diff --git a/src/dbg/yara/yara/types.h b/src/dbg/yara/yara/types.h index 6c13aa80..1874d769 100644 --- a/src/dbg/yara/yara/types.h +++ b/src/dbg/yara/yara/types.h @@ -1,524 +1,524 @@ -/* -Copyright (c) 2013. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef YR_TYPES_H -#define YR_TYPES_H - - -#include "arena.h" -#include "re.h" -#include "limits.h" -#include "hash.h" - -#ifdef _WIN32 -#include -typedef HANDLE mutex_t; -#else -#include -typedef pthread_mutex_t mutex_t; -#endif - -typedef int32_t tidx_mask_t; - - -#define DECLARE_REFERENCE(type, name) \ - union { type name; int64_t name##_; } - -#pragma pack(push) -#pragma pack(1) - - -#define NAMESPACE_TFLAGS_UNSATISFIED_GLOBAL 0x01 - -#define NAMESPACE_HAS_UNSATISFIED_GLOBAL(x) \ - ((x)->t_flags[yr_get_tidx()] & NAMESPACE_TFLAGS_UNSATISFIED_GLOBAL) - - -typedef struct _YR_NAMESPACE -{ - int32_t t_flags[MAX_THREADS]; // Thread-specific flags - DECLARE_REFERENCE(char*, name); - -} YR_NAMESPACE; - - -#define META_TYPE_NULL 0 -#define META_TYPE_INTEGER 1 -#define META_TYPE_STRING 2 -#define META_TYPE_BOOLEAN 3 - -#define META_IS_NULL(x) \ - ((x) != NULL ? (x)->type == META_TYPE_NULL : TRUE) - - -typedef struct _YR_META -{ - int32_t type; - int32_t integer; - - DECLARE_REFERENCE(const char*, identifier); - DECLARE_REFERENCE(char*, string); - -} YR_META; - - -typedef struct _YR_MATCH -{ - int64_t base; - int64_t offset; - int32_t length; - - union - { - uint8_t* data; // Confirmed matches use "data", - int32_t chain_length; // unconfirmed ones use "chain_length" - }; - - struct _YR_MATCH* prev; - struct _YR_MATCH* next; - -} YR_MATCH; - - -typedef struct _YR_MATCHES -{ - int32_t count; - - DECLARE_REFERENCE(YR_MATCH*, head); - DECLARE_REFERENCE(YR_MATCH*, tail); - -} YR_MATCHES; - - -#define STRING_GFLAGS_REFERENCED 0x01 -#define STRING_GFLAGS_HEXADECIMAL 0x02 -#define STRING_GFLAGS_NO_CASE 0x04 -#define STRING_GFLAGS_ASCII 0x08 -#define STRING_GFLAGS_WIDE 0x10 -#define STRING_GFLAGS_REGEXP 0x20 -#define STRING_GFLAGS_FAST_HEX_REGEXP 0x40 -#define STRING_GFLAGS_FULL_WORD 0x80 -#define STRING_GFLAGS_ANONYMOUS 0x100 -#define STRING_GFLAGS_SINGLE_MATCH 0x200 -#define STRING_GFLAGS_LITERAL 0x400 -#define STRING_GFLAGS_FITS_IN_ATOM 0x800 -#define STRING_GFLAGS_NULL 0x1000 -#define STRING_GFLAGS_CHAIN_PART 0x2000 -#define STRING_GFLAGS_CHAIN_TAIL 0x4000 -#define STRING_GFLAGS_FIXED_OFFSET 0x8000 - - -#define STRING_IS_HEX(x) \ - (((x)->g_flags) & STRING_GFLAGS_HEXADECIMAL) - -#define STRING_IS_NO_CASE(x) \ - (((x)->g_flags) & STRING_GFLAGS_NO_CASE) - -#define STRING_IS_ASCII(x) \ - (((x)->g_flags) & STRING_GFLAGS_ASCII) - -#define STRING_IS_WIDE(x) \ - (((x)->g_flags) & STRING_GFLAGS_WIDE) - -#define STRING_IS_REGEXP(x) \ - (((x)->g_flags) & STRING_GFLAGS_REGEXP) - -#define STRING_IS_FULL_WORD(x) \ - (((x)->g_flags) & STRING_GFLAGS_FULL_WORD) - -#define STRING_IS_ANONYMOUS(x) \ - (((x)->g_flags) & STRING_GFLAGS_ANONYMOUS) - -#define STRING_IS_REFERENCED(x) \ - (((x)->g_flags) & STRING_GFLAGS_REFERENCED) - -#define STRING_IS_SINGLE_MATCH(x) \ - (((x)->g_flags) & STRING_GFLAGS_SINGLE_MATCH) - -#define STRING_IS_FIXED_OFFSET(x) \ - (((x)->g_flags) & STRING_GFLAGS_FIXED_OFFSET) - -#define STRING_IS_LITERAL(x) \ - (((x)->g_flags) & STRING_GFLAGS_LITERAL) - -#define STRING_IS_FAST_HEX_REGEXP(x) \ - (((x)->g_flags) & STRING_GFLAGS_FAST_HEX_REGEXP) - -#define STRING_IS_CHAIN_PART(x) \ - (((x)->g_flags) & STRING_GFLAGS_CHAIN_PART) - -#define STRING_IS_CHAIN_TAIL(x) \ - (((x)->g_flags) & STRING_GFLAGS_CHAIN_TAIL) - -#define STRING_IS_NULL(x) \ - ((x) == NULL || ((x)->g_flags) & STRING_GFLAGS_NULL) - -#define STRING_FITS_IN_ATOM(x) \ - (((x)->g_flags) & STRING_GFLAGS_FITS_IN_ATOM) - -#define STRING_FOUND(x) \ - ((x)->matches[yr_get_tidx()].tail != NULL) - -#define STRING_MATCHES(x) \ - ((x)->matches[yr_get_tidx()]) - - -typedef struct _YR_STRING -{ - int32_t g_flags; - int32_t length; - - DECLARE_REFERENCE(char*, identifier); - DECLARE_REFERENCE(uint8_t*, string); - DECLARE_REFERENCE(struct _YR_STRING*, chained_to); - - int32_t chain_gap_min; - int32_t chain_gap_max; - - int64_t fixed_offset; - - YR_MATCHES matches[MAX_THREADS]; - YR_MATCHES unconfirmed_matches[MAX_THREADS]; - -#ifdef PROFILING_ENABLED - uint64_t clock_ticks; -#endif - -} YR_STRING; - - -#define RULE_TFLAGS_MATCH 0x01 - -#define RULE_GFLAGS_PRIVATE 0x01 -#define RULE_GFLAGS_GLOBAL 0x02 -#define RULE_GFLAGS_REQUIRE_EXECUTABLE 0x04 -#define RULE_GFLAGS_REQUIRE_FILE 0x08 -#define RULE_GFLAGS_NULL 0x1000 - -#define RULE_IS_PRIVATE(x) \ - (((x)->g_flags) & RULE_GFLAGS_PRIVATE) - -#define RULE_IS_GLOBAL(x) \ - (((x)->g_flags) & RULE_GFLAGS_GLOBAL) - -#define RULE_IS_NULL(x) \ - (((x)->g_flags) & RULE_GFLAGS_NULL) - -#define RULE_MATCHES(x) \ - ((x)->t_flags[yr_get_tidx()] & RULE_TFLAGS_MATCH) - - -typedef struct _YR_RULE -{ - int32_t g_flags; // Global flags - int32_t t_flags[MAX_THREADS]; // Thread-specific flags - - DECLARE_REFERENCE(const char*, identifier); - DECLARE_REFERENCE(const char*, tags); - DECLARE_REFERENCE(YR_META*, metas); - DECLARE_REFERENCE(YR_STRING*, strings); - DECLARE_REFERENCE(YR_NAMESPACE*, ns); - -#ifdef PROFILING_ENABLED - uint64_t clock_ticks; -#endif - -} YR_RULE; - - -#define EXTERNAL_VARIABLE_TYPE_NULL 0 -#define EXTERNAL_VARIABLE_TYPE_FLOAT 1 -#define EXTERNAL_VARIABLE_TYPE_INTEGER 2 -#define EXTERNAL_VARIABLE_TYPE_BOOLEAN 3 -#define EXTERNAL_VARIABLE_TYPE_STRING 4 -#define EXTERNAL_VARIABLE_TYPE_MALLOC_STRING 5 - - -#define EXTERNAL_VARIABLE_IS_NULL(x) \ - ((x) != NULL ? (x)->type == EXTERNAL_VARIABLE_TYPE_NULL : TRUE) - - -typedef struct _YR_EXTERNAL_VARIABLE -{ - int32_t type; - - union - { - int64_t i; - double f; - char* s; - } value; - - DECLARE_REFERENCE(char*, identifier); - -} YR_EXTERNAL_VARIABLE; - - -typedef struct _YR_AC_MATCH -{ - uint16_t backtrack; - - DECLARE_REFERENCE(YR_STRING*, string); - DECLARE_REFERENCE(uint8_t*, forward_code); - DECLARE_REFERENCE(uint8_t*, backward_code); - DECLARE_REFERENCE(struct _YR_AC_MATCH*, next); - -} YR_AC_MATCH; - - -typedef struct _YR_AC_STATE -{ - int8_t depth; - - DECLARE_REFERENCE(struct _YR_AC_STATE*, failure); - DECLARE_REFERENCE(YR_AC_MATCH*, matches); - -} YR_AC_STATE; - - -typedef struct _YR_AC_STATE_TRANSITION -{ - uint8_t input; - - DECLARE_REFERENCE(YR_AC_STATE*, state); - DECLARE_REFERENCE(struct _YR_AC_STATE_TRANSITION*, next); - -} YR_AC_STATE_TRANSITION; - - -typedef struct _YR_AC_TABLE_BASED_STATE -{ - int8_t depth; - - DECLARE_REFERENCE(YR_AC_STATE*, failure); - DECLARE_REFERENCE(YR_AC_MATCH*, matches); - DECLARE_REFERENCE(YR_AC_STATE*, state) transitions[256]; - -} YR_AC_TABLE_BASED_STATE; - - -typedef struct _YR_AC_LIST_BASED_STATE -{ - int8_t depth; - - DECLARE_REFERENCE(YR_AC_STATE*, failure); - DECLARE_REFERENCE(YR_AC_MATCH*, matches); - DECLARE_REFERENCE(YR_AC_STATE_TRANSITION*, transitions); - -} YR_AC_LIST_BASED_STATE; - - -typedef struct _YR_AC_AUTOMATON -{ - DECLARE_REFERENCE(YR_AC_STATE*, root); - -} YR_AC_AUTOMATON; - - -typedef struct _YARA_RULES_FILE_HEADER -{ - uint32_t version; - - DECLARE_REFERENCE(YR_RULE*, rules_list_head); - DECLARE_REFERENCE(YR_EXTERNAL_VARIABLE*, externals_list_head); - DECLARE_REFERENCE(uint8_t*, code_start); - DECLARE_REFERENCE(YR_AC_AUTOMATON*, automaton); - -} YARA_RULES_FILE_HEADER; - - - -#pragma pack(pop) - - -typedef struct _YR_RULES -{ - - tidx_mask_t tidx_mask; - uint8_t* code_start; - - mutex_t mutex; - - YR_ARENA* arena; - YR_RULE* rules_list_head; - YR_EXTERNAL_VARIABLE* externals_list_head; - YR_AC_AUTOMATON* automaton; - -} YR_RULES; - - -typedef struct _YR_MEMORY_BLOCK -{ - uint8_t* data; - size_t size; - size_t base; - - struct _YR_MEMORY_BLOCK* next; - -} YR_MEMORY_BLOCK; - - -typedef int (*YR_CALLBACK_FUNC)( - int message, - void* message_data, - void* user_data); - - -typedef struct _YR_SCAN_CONTEXT -{ - uint64_t file_size; - uint64_t entry_point; - - int flags; - void* user_data; - - YR_MEMORY_BLOCK* mem_block; - YR_HASH_TABLE* objects_table; - YR_CALLBACK_FUNC callback; - -} YR_SCAN_CONTEXT; - - - -#define OBJECT_COMMON_FIELDS \ - int8_t type; \ - const char* identifier; \ - void* data; \ - struct _YR_OBJECT* parent; - - -typedef struct _YR_OBJECT -{ - OBJECT_COMMON_FIELDS - -} YR_OBJECT; - - -typedef struct _YR_OBJECT_INTEGER -{ - OBJECT_COMMON_FIELDS - int64_t value; - -} YR_OBJECT_INTEGER; - - -typedef struct _YR_OBJECT_DOUBLE -{ - OBJECT_COMMON_FIELDS - double value; - -} YR_OBJECT_DOUBLE; - - -typedef struct _YR_OBJECT_STRING -{ - OBJECT_COMMON_FIELDS - SIZED_STRING* value; - -} YR_OBJECT_STRING; - - -typedef struct _YR_OBJECT_REGEXP -{ - OBJECT_COMMON_FIELDS - RE* value; - -} YR_OBJECT_REGEXP; - - -typedef struct _YR_OBJECT_STRUCTURE -{ - OBJECT_COMMON_FIELDS - struct _YR_STRUCTURE_MEMBER* members; - -} YR_OBJECT_STRUCTURE; - - -typedef struct _YR_OBJECT_ARRAY -{ - OBJECT_COMMON_FIELDS - YR_OBJECT* prototype_item; - struct _YR_ARRAY_ITEMS* items; - -} YR_OBJECT_ARRAY; - - -typedef struct _YR_OBJECT_DICTIONARY -{ - OBJECT_COMMON_FIELDS - YR_OBJECT* prototype_item; - struct _YR_DICTIONARY_ITEMS* items; - -} YR_OBJECT_DICTIONARY; - - -struct _YR_OBJECT_FUNCTION; - - -typedef int (*YR_MODULE_FUNC)( - void* args, - YR_SCAN_CONTEXT* context, - struct _YR_OBJECT_FUNCTION* function_obj); - - -typedef struct _YR_OBJECT_FUNCTION -{ - OBJECT_COMMON_FIELDS - - YR_OBJECT* return_obj; - - struct - { - const char* arguments_fmt; - YR_MODULE_FUNC code; - } prototypes[MAX_OVERLOADED_FUNCTIONS]; - -} YR_OBJECT_FUNCTION; - - -typedef struct _YR_STRUCTURE_MEMBER -{ - YR_OBJECT* object; - struct _YR_STRUCTURE_MEMBER* next; - -} YR_STRUCTURE_MEMBER; - - -typedef struct _YR_ARRAY_ITEMS -{ - int count; - YR_OBJECT* objects[1]; - -} YR_ARRAY_ITEMS; - - -typedef struct _YR_DICTIONARY_ITEMS -{ - int used; - int free; - - struct - { - - char* key; - YR_OBJECT* obj; - - } objects[1]; - -} YR_DICTIONARY_ITEMS; - - -#endif +/* +Copyright (c) 2013. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef YR_TYPES_H +#define YR_TYPES_H + + +#include "arena.h" +#include "re.h" +#include "limits.h" +#include "hash.h" + +#ifdef _WIN32 +#include +typedef HANDLE mutex_t; +#else +#include +typedef pthread_mutex_t mutex_t; +#endif + +typedef int32_t tidx_mask_t; + + +#define DECLARE_REFERENCE(type, name) \ + union { type name; int64_t name##_; } + +#pragma pack(push) +#pragma pack(1) + + +#define NAMESPACE_TFLAGS_UNSATISFIED_GLOBAL 0x01 + +#define NAMESPACE_HAS_UNSATISFIED_GLOBAL(x) \ + ((x)->t_flags[yr_get_tidx()] & NAMESPACE_TFLAGS_UNSATISFIED_GLOBAL) + + +typedef struct _YR_NAMESPACE +{ + int32_t t_flags[MAX_THREADS]; // Thread-specific flags + DECLARE_REFERENCE(char*, name); + +} YR_NAMESPACE; + + +#define META_TYPE_NULL 0 +#define META_TYPE_INTEGER 1 +#define META_TYPE_STRING 2 +#define META_TYPE_BOOLEAN 3 + +#define META_IS_NULL(x) \ + ((x) != NULL ? (x)->type == META_TYPE_NULL : TRUE) + + +typedef struct _YR_META +{ + int32_t type; + int32_t integer; + + DECLARE_REFERENCE(const char*, identifier); + DECLARE_REFERENCE(char*, string); + +} YR_META; + + +typedef struct _YR_MATCH +{ + int64_t base; + int64_t offset; + int32_t length; + + union + { + uint8_t* data; // Confirmed matches use "data", + int32_t chain_length; // unconfirmed ones use "chain_length" + }; + + struct _YR_MATCH* prev; + struct _YR_MATCH* next; + +} YR_MATCH; + + +typedef struct _YR_MATCHES +{ + int32_t count; + + DECLARE_REFERENCE(YR_MATCH*, head); + DECLARE_REFERENCE(YR_MATCH*, tail); + +} YR_MATCHES; + + +#define STRING_GFLAGS_REFERENCED 0x01 +#define STRING_GFLAGS_HEXADECIMAL 0x02 +#define STRING_GFLAGS_NO_CASE 0x04 +#define STRING_GFLAGS_ASCII 0x08 +#define STRING_GFLAGS_WIDE 0x10 +#define STRING_GFLAGS_REGEXP 0x20 +#define STRING_GFLAGS_FAST_HEX_REGEXP 0x40 +#define STRING_GFLAGS_FULL_WORD 0x80 +#define STRING_GFLAGS_ANONYMOUS 0x100 +#define STRING_GFLAGS_SINGLE_MATCH 0x200 +#define STRING_GFLAGS_LITERAL 0x400 +#define STRING_GFLAGS_FITS_IN_ATOM 0x800 +#define STRING_GFLAGS_NULL 0x1000 +#define STRING_GFLAGS_CHAIN_PART 0x2000 +#define STRING_GFLAGS_CHAIN_TAIL 0x4000 +#define STRING_GFLAGS_FIXED_OFFSET 0x8000 + + +#define STRING_IS_HEX(x) \ + (((x)->g_flags) & STRING_GFLAGS_HEXADECIMAL) + +#define STRING_IS_NO_CASE(x) \ + (((x)->g_flags) & STRING_GFLAGS_NO_CASE) + +#define STRING_IS_ASCII(x) \ + (((x)->g_flags) & STRING_GFLAGS_ASCII) + +#define STRING_IS_WIDE(x) \ + (((x)->g_flags) & STRING_GFLAGS_WIDE) + +#define STRING_IS_REGEXP(x) \ + (((x)->g_flags) & STRING_GFLAGS_REGEXP) + +#define STRING_IS_FULL_WORD(x) \ + (((x)->g_flags) & STRING_GFLAGS_FULL_WORD) + +#define STRING_IS_ANONYMOUS(x) \ + (((x)->g_flags) & STRING_GFLAGS_ANONYMOUS) + +#define STRING_IS_REFERENCED(x) \ + (((x)->g_flags) & STRING_GFLAGS_REFERENCED) + +#define STRING_IS_SINGLE_MATCH(x) \ + (((x)->g_flags) & STRING_GFLAGS_SINGLE_MATCH) + +#define STRING_IS_FIXED_OFFSET(x) \ + (((x)->g_flags) & STRING_GFLAGS_FIXED_OFFSET) + +#define STRING_IS_LITERAL(x) \ + (((x)->g_flags) & STRING_GFLAGS_LITERAL) + +#define STRING_IS_FAST_HEX_REGEXP(x) \ + (((x)->g_flags) & STRING_GFLAGS_FAST_HEX_REGEXP) + +#define STRING_IS_CHAIN_PART(x) \ + (((x)->g_flags) & STRING_GFLAGS_CHAIN_PART) + +#define STRING_IS_CHAIN_TAIL(x) \ + (((x)->g_flags) & STRING_GFLAGS_CHAIN_TAIL) + +#define STRING_IS_NULL(x) \ + ((x) == NULL || ((x)->g_flags) & STRING_GFLAGS_NULL) + +#define STRING_FITS_IN_ATOM(x) \ + (((x)->g_flags) & STRING_GFLAGS_FITS_IN_ATOM) + +#define STRING_FOUND(x) \ + ((x)->matches[yr_get_tidx()].tail != NULL) + +#define STRING_MATCHES(x) \ + ((x)->matches[yr_get_tidx()]) + + +typedef struct _YR_STRING +{ + int32_t g_flags; + int32_t length; + + DECLARE_REFERENCE(char*, identifier); + DECLARE_REFERENCE(uint8_t*, string); + DECLARE_REFERENCE(struct _YR_STRING*, chained_to); + + int32_t chain_gap_min; + int32_t chain_gap_max; + + int64_t fixed_offset; + + YR_MATCHES matches[MAX_THREADS]; + YR_MATCHES unconfirmed_matches[MAX_THREADS]; + +#ifdef PROFILING_ENABLED + uint64_t clock_ticks; +#endif + +} YR_STRING; + + +#define RULE_TFLAGS_MATCH 0x01 + +#define RULE_GFLAGS_PRIVATE 0x01 +#define RULE_GFLAGS_GLOBAL 0x02 +#define RULE_GFLAGS_REQUIRE_EXECUTABLE 0x04 +#define RULE_GFLAGS_REQUIRE_FILE 0x08 +#define RULE_GFLAGS_NULL 0x1000 + +#define RULE_IS_PRIVATE(x) \ + (((x)->g_flags) & RULE_GFLAGS_PRIVATE) + +#define RULE_IS_GLOBAL(x) \ + (((x)->g_flags) & RULE_GFLAGS_GLOBAL) + +#define RULE_IS_NULL(x) \ + (((x)->g_flags) & RULE_GFLAGS_NULL) + +#define RULE_MATCHES(x) \ + ((x)->t_flags[yr_get_tidx()] & RULE_TFLAGS_MATCH) + + +typedef struct _YR_RULE +{ + int32_t g_flags; // Global flags + int32_t t_flags[MAX_THREADS]; // Thread-specific flags + + DECLARE_REFERENCE(const char*, identifier); + DECLARE_REFERENCE(const char*, tags); + DECLARE_REFERENCE(YR_META*, metas); + DECLARE_REFERENCE(YR_STRING*, strings); + DECLARE_REFERENCE(YR_NAMESPACE*, ns); + +#ifdef PROFILING_ENABLED + uint64_t clock_ticks; +#endif + +} YR_RULE; + + +#define EXTERNAL_VARIABLE_TYPE_NULL 0 +#define EXTERNAL_VARIABLE_TYPE_FLOAT 1 +#define EXTERNAL_VARIABLE_TYPE_INTEGER 2 +#define EXTERNAL_VARIABLE_TYPE_BOOLEAN 3 +#define EXTERNAL_VARIABLE_TYPE_STRING 4 +#define EXTERNAL_VARIABLE_TYPE_MALLOC_STRING 5 + + +#define EXTERNAL_VARIABLE_IS_NULL(x) \ + ((x) != NULL ? (x)->type == EXTERNAL_VARIABLE_TYPE_NULL : TRUE) + + +typedef struct _YR_EXTERNAL_VARIABLE +{ + int32_t type; + + union + { + int64_t i; + double f; + char* s; + } value; + + DECLARE_REFERENCE(char*, identifier); + +} YR_EXTERNAL_VARIABLE; + + +typedef struct _YR_AC_MATCH +{ + uint16_t backtrack; + + DECLARE_REFERENCE(YR_STRING*, string); + DECLARE_REFERENCE(uint8_t*, forward_code); + DECLARE_REFERENCE(uint8_t*, backward_code); + DECLARE_REFERENCE(struct _YR_AC_MATCH*, next); + +} YR_AC_MATCH; + + +typedef struct _YR_AC_STATE +{ + int8_t depth; + + DECLARE_REFERENCE(struct _YR_AC_STATE*, failure); + DECLARE_REFERENCE(YR_AC_MATCH*, matches); + +} YR_AC_STATE; + + +typedef struct _YR_AC_STATE_TRANSITION +{ + uint8_t input; + + DECLARE_REFERENCE(YR_AC_STATE*, state); + DECLARE_REFERENCE(struct _YR_AC_STATE_TRANSITION*, next); + +} YR_AC_STATE_TRANSITION; + + +typedef struct _YR_AC_TABLE_BASED_STATE +{ + int8_t depth; + + DECLARE_REFERENCE(YR_AC_STATE*, failure); + DECLARE_REFERENCE(YR_AC_MATCH*, matches); + DECLARE_REFERENCE(YR_AC_STATE*, state) transitions[256]; + +} YR_AC_TABLE_BASED_STATE; + + +typedef struct _YR_AC_LIST_BASED_STATE +{ + int8_t depth; + + DECLARE_REFERENCE(YR_AC_STATE*, failure); + DECLARE_REFERENCE(YR_AC_MATCH*, matches); + DECLARE_REFERENCE(YR_AC_STATE_TRANSITION*, transitions); + +} YR_AC_LIST_BASED_STATE; + + +typedef struct _YR_AC_AUTOMATON +{ + DECLARE_REFERENCE(YR_AC_STATE*, root); + +} YR_AC_AUTOMATON; + + +typedef struct _YARA_RULES_FILE_HEADER +{ + uint32_t version; + + DECLARE_REFERENCE(YR_RULE*, rules_list_head); + DECLARE_REFERENCE(YR_EXTERNAL_VARIABLE*, externals_list_head); + DECLARE_REFERENCE(uint8_t*, code_start); + DECLARE_REFERENCE(YR_AC_AUTOMATON*, automaton); + +} YARA_RULES_FILE_HEADER; + + + +#pragma pack(pop) + + +typedef struct _YR_RULES +{ + + tidx_mask_t tidx_mask; + uint8_t* code_start; + + mutex_t mutex; + + YR_ARENA* arena; + YR_RULE* rules_list_head; + YR_EXTERNAL_VARIABLE* externals_list_head; + YR_AC_AUTOMATON* automaton; + +} YR_RULES; + + +typedef struct _YR_MEMORY_BLOCK +{ + uint8_t* data; + size_t size; + size_t base; + + struct _YR_MEMORY_BLOCK* next; + +} YR_MEMORY_BLOCK; + + +typedef int (*YR_CALLBACK_FUNC)( + int message, + void* message_data, + void* user_data); + + +typedef struct _YR_SCAN_CONTEXT +{ + uint64_t file_size; + uint64_t entry_point; + + int flags; + void* user_data; + + YR_MEMORY_BLOCK* mem_block; + YR_HASH_TABLE* objects_table; + YR_CALLBACK_FUNC callback; + +} YR_SCAN_CONTEXT; + + + +#define OBJECT_COMMON_FIELDS \ + int8_t type; \ + const char* identifier; \ + void* data; \ + struct _YR_OBJECT* parent; + + +typedef struct _YR_OBJECT +{ + OBJECT_COMMON_FIELDS + +} YR_OBJECT; + + +typedef struct _YR_OBJECT_INTEGER +{ + OBJECT_COMMON_FIELDS + int64_t value; + +} YR_OBJECT_INTEGER; + + +typedef struct _YR_OBJECT_DOUBLE +{ + OBJECT_COMMON_FIELDS + double value; + +} YR_OBJECT_DOUBLE; + + +typedef struct _YR_OBJECT_STRING +{ + OBJECT_COMMON_FIELDS + SIZED_STRING* value; + +} YR_OBJECT_STRING; + + +typedef struct _YR_OBJECT_REGEXP +{ + OBJECT_COMMON_FIELDS + RE* value; + +} YR_OBJECT_REGEXP; + + +typedef struct _YR_OBJECT_STRUCTURE +{ + OBJECT_COMMON_FIELDS + struct _YR_STRUCTURE_MEMBER* members; + +} YR_OBJECT_STRUCTURE; + + +typedef struct _YR_OBJECT_ARRAY +{ + OBJECT_COMMON_FIELDS + YR_OBJECT* prototype_item; + struct _YR_ARRAY_ITEMS* items; + +} YR_OBJECT_ARRAY; + + +typedef struct _YR_OBJECT_DICTIONARY +{ + OBJECT_COMMON_FIELDS + YR_OBJECT* prototype_item; + struct _YR_DICTIONARY_ITEMS* items; + +} YR_OBJECT_DICTIONARY; + + +struct _YR_OBJECT_FUNCTION; + + +typedef int (*YR_MODULE_FUNC)( + void* args, + YR_SCAN_CONTEXT* context, + struct _YR_OBJECT_FUNCTION* function_obj); + + +typedef struct _YR_OBJECT_FUNCTION +{ + OBJECT_COMMON_FIELDS + + YR_OBJECT* return_obj; + + struct + { + const char* arguments_fmt; + YR_MODULE_FUNC code; + } prototypes[MAX_OVERLOADED_FUNCTIONS]; + +} YR_OBJECT_FUNCTION; + + +typedef struct _YR_STRUCTURE_MEMBER +{ + YR_OBJECT* object; + struct _YR_STRUCTURE_MEMBER* next; + +} YR_STRUCTURE_MEMBER; + + +typedef struct _YR_ARRAY_ITEMS +{ + int count; + YR_OBJECT* objects[1]; + +} YR_ARRAY_ITEMS; + + +typedef struct _YR_DICTIONARY_ITEMS +{ + int used; + int free; + + struct + { + + char* key; + YR_OBJECT* obj; + + } objects[1]; + +} YR_DICTIONARY_ITEMS; + + +#endif diff --git a/src/dbg/yara/yara/utils.h b/src/dbg/yara/yara/utils.h index 6fe4e64d..a148fbda 100644 --- a/src/dbg/yara/yara/utils.h +++ b/src/dbg/yara/yara/utils.h @@ -1,67 +1,67 @@ -/* -Copyright (c) 2014. The YARA Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#ifndef YR_UTILS_H -#define YR_UTILS_H - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#ifdef __cplusplus -#define YR_API extern "C" __declspec(dllimport) -#else -#define YR_API -#endif - -#ifndef min -#define min(x, y) ((x < y) ? (x) : (y)) -#endif - -#ifndef max -#define max(x, y) ((x > y) ? (x) : (y)) -#endif - - -#define PTR_TO_UINT64(x) ((uint64_t) (size_t) x) - - -#ifdef NDEBUG - -#define assertf(expr, msg) ((void)0) - -#else - -#include - -#define assertf(expr, msg, ...) \ - if(!(expr)) { \ - fprintf(stderr, "%s:%d: " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ - abort(); \ - } - -#endif - -#endif +/* +Copyright (c) 2014. The YARA Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + + +#ifndef YR_UTILS_H +#define YR_UTILS_H + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifdef __cplusplus +#define YR_API extern "C" __declspec(dllimport) +#else +#define YR_API +#endif + +#ifndef min +#define min(x, y) ((x < y) ? (x) : (y)) +#endif + +#ifndef max +#define max(x, y) ((x > y) ? (x) : (y)) +#endif + + +#define PTR_TO_UINT64(x) ((uint64_t) (size_t) x) + + +#ifdef NDEBUG + +#define assertf(expr, msg) ((void)0) + +#else + +#include + +#define assertf(expr, msg, ...) \ + if(!(expr)) { \ + fprintf(stderr, "%s:%d: " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ + abort(); \ + } + +#endif + +#endif diff --git a/src/dbg_assert.h b/src/dbg_assert.h index 905c96ed..cc47eb03 100644 --- a/src/dbg_assert.h +++ b/src/dbg_assert.h @@ -1,71 +1,71 @@ -/** - * Code originally from: - * - * (c) 2015 Alexandro Sanchez Bach. All rights reserved. - * https://github.com/AlexAltea/nucleus/blob/9103d7eb52cc861cb6e317f0007246bd03d663a2/nucleus/assert.h - * https://github.com/AlexAltea/nucleus/blob/9103d7eb52cc861cb6e317f0007246bd03d663a2/LICENSE - * Released under GPL v2 license. Read LICENSE for more details. - * - */ - -#pragma once - -#include - -// Count arguments -#define __DBG_ARGUMENT_EXPAND(x) x -#define __DBG_ARGUMENT_COUNT(...) \ - __DBG_ARGUMENT_EXPAND(__DBG_ARGUMENT_EXTRACT(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)) -#define __DBG_ARGUMENT_EXTRACT(a1, a2, a3, a4, a5, a6, a7, a8, N, ...) N - -// Dispatching macros -#define __DBG_MACRO_DISPATCH(function, ...) \ - __DBG_MACRO_SELECT(function, __DBG_ARGUMENT_COUNT(__VA_ARGS__)) -#define __DBG_MACRO_SELECT(function, argc) \ - __DBG_MACRO_CONCAT(function, argc) -#define __DBG_MACRO_CONCAT(a, b) a##b - -// Trigger an exception if the debugger is not currently active -#define ASSERT_DEBUGGING(message) ASSERT_TRUE(DbgIsDebugging(), message) - -// Trigger an exception if expression is false -#define ASSERT_TRUE(...) \ - __DBG_MACRO_DISPATCH(ASSERT_TRUE, __VA_ARGS__)(__VA_ARGS__) -#define ASSERT_TRUE1(expr) assert(expr) -#define ASSERT_TRUE2(expr, message) assert((expr) && (message)) - -// Trigger an exception if expression is true -#define ASSERT_FALSE(...) \ - __DBG_MACRO_DISPATCH(ASSERT_FALSE, __VA_ARGS__)(__VA_ARGS__) -#define ASSERT_FALSE1(expr) assert(!(expr)) -#define ASSERT_FALSE2(expr, message) assert(!(expr) && (message)) - -// Trigger an exception if expression is zero -#define ASSERT_ZERO(...) \ - __DBG_MACRO_DISPATCH(ASSERT_ZERO, __VA_ARGS__)(__VA_ARGS__) -#define ASSERT_ZERO1(expr) assert(expr) -#define ASSERT_ZERO2(expr, message) assert(((expr) == 0) && (message)) - -// Trigger an exception if expression is non-zero -#define ASSERT_NONZERO(...) \ - __DBG_MACRO_DISPATCH(ASSERT_TRUE, __VA_ARGS__)(__VA_ARGS__) -#define ASSERT_NONZERO1(expr) ASSERT_NONZERO(expr) -#define ASSERT_NONZERO2(expr, message) assert(((expr) != 0) && (message)) - -// Trigger an exception if expression is a nullptr -#define ASSERT_NULL(...) \ - __DBG_MACRO_DISPATCH(ASSERT_NULL, __VA_ARGS__)(__VA_ARGS__) -#define ASSERT_NULL1(expr) assert(expr) -#define ASSERT_NULL2(expr, message) assert(((expr) == nullptr) && (message)) - -// Trigger an exception if expression is not a nullptr -#define ASSERT_NONNULL(...) \ - __DBG_MACRO_DISPATCH(ASSERT_NONNULL, __VA_ARGS__)(__VA_ARGS__) -#define ASSERT_NONNULL1(expr) assert(expr) -#define ASSERT_NONNULL2(expr, message) assert(((expr) != nullptr) && (message)) - -// Trigger an exception -#define ASSERT_ALWAYS(...) \ - __DBG_MACRO_DISPATCH(ASSERT_ALWAYS, __VA_ARGS__)(__VA_ARGS__) -#define ASSERT_ALWAYS0(...) assert(0) +/** + * Code originally from: + * + * (c) 2015 Alexandro Sanchez Bach. All rights reserved. + * https://github.com/AlexAltea/nucleus/blob/9103d7eb52cc861cb6e317f0007246bd03d663a2/nucleus/assert.h + * https://github.com/AlexAltea/nucleus/blob/9103d7eb52cc861cb6e317f0007246bd03d663a2/LICENSE + * Released under GPL v2 license. Read LICENSE for more details. + * + */ + +#pragma once + +#include + +// Count arguments +#define __DBG_ARGUMENT_EXPAND(x) x +#define __DBG_ARGUMENT_COUNT(...) \ + __DBG_ARGUMENT_EXPAND(__DBG_ARGUMENT_EXTRACT(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)) +#define __DBG_ARGUMENT_EXTRACT(a1, a2, a3, a4, a5, a6, a7, a8, N, ...) N + +// Dispatching macros +#define __DBG_MACRO_DISPATCH(function, ...) \ + __DBG_MACRO_SELECT(function, __DBG_ARGUMENT_COUNT(__VA_ARGS__)) +#define __DBG_MACRO_SELECT(function, argc) \ + __DBG_MACRO_CONCAT(function, argc) +#define __DBG_MACRO_CONCAT(a, b) a##b + +// Trigger an exception if the debugger is not currently active +#define ASSERT_DEBUGGING(message) ASSERT_TRUE(DbgIsDebugging(), message) + +// Trigger an exception if expression is false +#define ASSERT_TRUE(...) \ + __DBG_MACRO_DISPATCH(ASSERT_TRUE, __VA_ARGS__)(__VA_ARGS__) +#define ASSERT_TRUE1(expr) assert(expr) +#define ASSERT_TRUE2(expr, message) assert((expr) && (message)) + +// Trigger an exception if expression is true +#define ASSERT_FALSE(...) \ + __DBG_MACRO_DISPATCH(ASSERT_FALSE, __VA_ARGS__)(__VA_ARGS__) +#define ASSERT_FALSE1(expr) assert(!(expr)) +#define ASSERT_FALSE2(expr, message) assert(!(expr) && (message)) + +// Trigger an exception if expression is zero +#define ASSERT_ZERO(...) \ + __DBG_MACRO_DISPATCH(ASSERT_ZERO, __VA_ARGS__)(__VA_ARGS__) +#define ASSERT_ZERO1(expr) assert(expr) +#define ASSERT_ZERO2(expr, message) assert(((expr) == 0) && (message)) + +// Trigger an exception if expression is non-zero +#define ASSERT_NONZERO(...) \ + __DBG_MACRO_DISPATCH(ASSERT_TRUE, __VA_ARGS__)(__VA_ARGS__) +#define ASSERT_NONZERO1(expr) ASSERT_NONZERO(expr) +#define ASSERT_NONZERO2(expr, message) assert(((expr) != 0) && (message)) + +// Trigger an exception if expression is a nullptr +#define ASSERT_NULL(...) \ + __DBG_MACRO_DISPATCH(ASSERT_NULL, __VA_ARGS__)(__VA_ARGS__) +#define ASSERT_NULL1(expr) assert(expr) +#define ASSERT_NULL2(expr, message) assert(((expr) == nullptr) && (message)) + +// Trigger an exception if expression is not a nullptr +#define ASSERT_NONNULL(...) \ + __DBG_MACRO_DISPATCH(ASSERT_NONNULL, __VA_ARGS__)(__VA_ARGS__) +#define ASSERT_NONNULL1(expr) assert(expr) +#define ASSERT_NONNULL2(expr, message) assert(((expr) != nullptr) && (message)) + +// Trigger an exception +#define ASSERT_ALWAYS(...) \ + __DBG_MACRO_DISPATCH(ASSERT_ALWAYS, __VA_ARGS__)(__VA_ARGS__) +#define ASSERT_ALWAYS0(...) assert(0) #define ASSERT_ALWAYS1(message) assert(0 && (message)) \ No newline at end of file diff --git a/src/dbg_types.h b/src/dbg_types.h index fad7f311..c2f4d8ea 100644 --- a/src/dbg_types.h +++ b/src/dbg_types.h @@ -1,41 +1,41 @@ -#pragma once - -/***************************************************************/ -// -// This file declares common types to be used -// throughout the project. Originally duint, int_t, -// or size_t were used to represent pointers and addresses. -// -// The purpose is to use a single type as the representation. -// -/***************************************************************/ -#undef COMPILE_X64 -#undef COMPILE_X32 - -#ifdef _WIN64 -#define COMPILE_X64 1 // Program is being compiled as 64-bit -#else -#define COMPILE_X32 1 // Program is being compiled as 32-bit -#endif // _WIN64 - -// -// Define types -// -#ifdef COMPILE_X64 -typedef unsigned long long duint; -typedef signed long long dsint; -#else -typedef unsigned long __w64 duint; -typedef signed long __w64 dsint; -#endif // COMPILE_X64 - -typedef short int16; -typedef unsigned short uint16; - -typedef int int32; -typedef unsigned int uint32; - -typedef long long int64; -typedef unsigned long long uint64; - +#pragma once + +/***************************************************************/ +// +// This file declares common types to be used +// throughout the project. Originally duint, int_t, +// or size_t were used to represent pointers and addresses. +// +// The purpose is to use a single type as the representation. +// +/***************************************************************/ +#undef COMPILE_X64 +#undef COMPILE_X32 + +#ifdef _WIN64 +#define COMPILE_X64 1 // Program is being compiled as 64-bit +#else +#define COMPILE_X32 1 // Program is being compiled as 32-bit +#endif // _WIN64 + +// +// Define types +// +#ifdef COMPILE_X64 +typedef unsigned long long duint; +typedef signed long long dsint; +#else +typedef unsigned long __w64 duint; +typedef signed long __w64 dsint; +#endif // COMPILE_X64 + +typedef short int16; +typedef unsigned short uint16; + +typedef int int32; +typedef unsigned int uint32; + +typedef long long int64; +typedef unsigned long long uint64; + typedef unsigned char byte_t; \ No newline at end of file diff --git a/src/exe/app.manifest b/src/exe/app.manifest index 376ba030..8541862e 100644 --- a/src/exe/app.manifest +++ b/src/exe/app.manifest @@ -1,17 +1,17 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/exe/crashdump.cpp b/src/exe/crashdump.cpp index d8afae72..60d3a79b 100644 --- a/src/exe/crashdump.cpp +++ b/src/exe/crashdump.cpp @@ -1,113 +1,113 @@ -#include -#include -#include -#include "crashdump.h" - -BOOL -(WINAPI* - MiniDumpWriteDumpPtr)( - _In_ HANDLE hProcess, - _In_ DWORD ProcessId, - _In_ HANDLE hFile, - _In_ MINIDUMP_TYPE DumpType, - _In_opt_ PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, - _In_opt_ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, - _In_opt_ PMINIDUMP_CALLBACK_INFORMATION CallbackParam - ); - -void CrashDumpInitialize() -{ - // Find the DbgHelp module first - HMODULE module = LoadLibrary("dbghelp.dll"); - - if(module) - *(FARPROC*)&MiniDumpWriteDumpPtr = GetProcAddress(module, "MiniDumpWriteDump"); - - if(MiniDumpWriteDumpPtr) - AddVectoredExceptionHandler(0, CrashDumpVectoredHandler); -} - -void CrashDumpFatal(const char* Format, ...) -{ - char buffer[1024]; - va_list va; - - va_start(va, Format); - vsnprintf_s(buffer, _TRUNCATE, Format, va); - va_end(va); - - MessageBox(nullptr, buffer, "Error", MB_ICONERROR); -} - -void CrashDumpCreate(EXCEPTION_POINTERS* ExceptionPointers) -{ - // Generate a crash dump file in the root directory - wchar_t dumpFile[MAX_PATH]; - wchar_t dumpDir[MAX_PATH]; - - if(!GetCurrentDirectoryW(ARRAYSIZE(dumpDir), dumpDir)) - { - CrashDumpFatal("Unable to obtain current directory during crash dump\n"); - return; - } - - // Create minidump subdirectory if needed - wcscat_s(dumpDir, L"\\minidump"); - CreateDirectoryW(dumpDir, nullptr); - - // Append the name with generated timestamp - SYSTEMTIME st; - GetLocalTime(&st); - - swprintf_s(dumpFile, L"%ws\\dump-%02d%02d%04d_%02d%02d%02d%04d.dmp", dumpDir, - st.wDay, - st.wMonth, - st.wYear, - st.wHour, - st.wMinute, - st.wSecond, - st.wMilliseconds); - - // Open the file - HANDLE fileHandle = CreateFileW(dumpFile, GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); - - if(fileHandle == INVALID_HANDLE_VALUE) - { - CrashDumpFatal("Failed to open file path '%ws' while generating crash dump\n", dumpFile); - return; - } - - // Create the minidump with DbgHelp - MINIDUMP_EXCEPTION_INFORMATION info; - memset(&info, 0, sizeof(MINIDUMP_EXCEPTION_INFORMATION)); - - info.ThreadId = GetCurrentThreadId(); - info.ExceptionPointers = ExceptionPointers; - info.ClientPointers = TRUE; - - if(!MiniDumpWriteDumpPtr(GetCurrentProcess(), GetCurrentProcessId(), fileHandle, MiniDumpNormal, &info, nullptr, nullptr)) - CrashDumpFatal("MiniDumpWriteDump failed. Error: %u\n", GetLastError()); - - // Close the file & done - CloseHandle(fileHandle); -} - -LONG CALLBACK CrashDumpVectoredHandler(EXCEPTION_POINTERS* ExceptionInfo) -{ - // Any "exception" under 0x1000 is usually just a failed RPC call - if(ExceptionInfo && ExceptionInfo->ExceptionRecord->ExceptionCode > 0x00001000) - { - // Skip OutputDebugString(A/W) and invalid handles from TitanEngine - switch(ExceptionInfo->ExceptionRecord->ExceptionCode) - { - case DBG_PRINTEXCEPTION_C: - case 0x4001000A: - case STATUS_INVALID_HANDLE: - return EXCEPTION_CONTINUE_SEARCH; - } - - CrashDumpCreate(ExceptionInfo); - } - - return EXCEPTION_CONTINUE_SEARCH; +#include +#include +#include +#include "crashdump.h" + +BOOL +(WINAPI* + MiniDumpWriteDumpPtr)( + _In_ HANDLE hProcess, + _In_ DWORD ProcessId, + _In_ HANDLE hFile, + _In_ MINIDUMP_TYPE DumpType, + _In_opt_ PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + _In_opt_ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + _In_opt_ PMINIDUMP_CALLBACK_INFORMATION CallbackParam + ); + +void CrashDumpInitialize() +{ + // Find the DbgHelp module first + HMODULE module = LoadLibrary("dbghelp.dll"); + + if(module) + *(FARPROC*)&MiniDumpWriteDumpPtr = GetProcAddress(module, "MiniDumpWriteDump"); + + if(MiniDumpWriteDumpPtr) + AddVectoredExceptionHandler(0, CrashDumpVectoredHandler); +} + +void CrashDumpFatal(const char* Format, ...) +{ + char buffer[1024]; + va_list va; + + va_start(va, Format); + vsnprintf_s(buffer, _TRUNCATE, Format, va); + va_end(va); + + MessageBox(nullptr, buffer, "Error", MB_ICONERROR); +} + +void CrashDumpCreate(EXCEPTION_POINTERS* ExceptionPointers) +{ + // Generate a crash dump file in the root directory + wchar_t dumpFile[MAX_PATH]; + wchar_t dumpDir[MAX_PATH]; + + if(!GetCurrentDirectoryW(ARRAYSIZE(dumpDir), dumpDir)) + { + CrashDumpFatal("Unable to obtain current directory during crash dump\n"); + return; + } + + // Create minidump subdirectory if needed + wcscat_s(dumpDir, L"\\minidump"); + CreateDirectoryW(dumpDir, nullptr); + + // Append the name with generated timestamp + SYSTEMTIME st; + GetLocalTime(&st); + + swprintf_s(dumpFile, L"%ws\\dump-%02d%02d%04d_%02d%02d%02d%04d.dmp", dumpDir, + st.wDay, + st.wMonth, + st.wYear, + st.wHour, + st.wMinute, + st.wSecond, + st.wMilliseconds); + + // Open the file + HANDLE fileHandle = CreateFileW(dumpFile, GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + + if(fileHandle == INVALID_HANDLE_VALUE) + { + CrashDumpFatal("Failed to open file path '%ws' while generating crash dump\n", dumpFile); + return; + } + + // Create the minidump with DbgHelp + MINIDUMP_EXCEPTION_INFORMATION info; + memset(&info, 0, sizeof(MINIDUMP_EXCEPTION_INFORMATION)); + + info.ThreadId = GetCurrentThreadId(); + info.ExceptionPointers = ExceptionPointers; + info.ClientPointers = TRUE; + + if(!MiniDumpWriteDumpPtr(GetCurrentProcess(), GetCurrentProcessId(), fileHandle, MiniDumpNormal, &info, nullptr, nullptr)) + CrashDumpFatal("MiniDumpWriteDump failed. Error: %u\n", GetLastError()); + + // Close the file & done + CloseHandle(fileHandle); +} + +LONG CALLBACK CrashDumpVectoredHandler(EXCEPTION_POINTERS* ExceptionInfo) +{ + // Any "exception" under 0x1000 is usually just a failed RPC call + if(ExceptionInfo && ExceptionInfo->ExceptionRecord->ExceptionCode > 0x00001000) + { + // Skip OutputDebugString(A/W) and invalid handles from TitanEngine + switch(ExceptionInfo->ExceptionRecord->ExceptionCode) + { + case DBG_PRINTEXCEPTION_C: + case 0x4001000A: + case STATUS_INVALID_HANDLE: + return EXCEPTION_CONTINUE_SEARCH; + } + + CrashDumpCreate(ExceptionInfo); + } + + return EXCEPTION_CONTINUE_SEARCH; } \ No newline at end of file diff --git a/src/exe/crashdump.h b/src/exe/crashdump.h index c28741c9..f456afad 100644 --- a/src/exe/crashdump.h +++ b/src/exe/crashdump.h @@ -1,4 +1,4 @@ -#pragma once - -void CrashDumpInitialize(); +#pragma once + +void CrashDumpInitialize(); LONG CALLBACK CrashDumpVectoredHandler(EXCEPTION_POINTERS* ExceptionInfo); \ No newline at end of file diff --git a/src/exe/manifest.xml b/src/exe/manifest.xml index 37e7b715..618fb8e3 100644 --- a/src/exe/manifest.xml +++ b/src/exe/manifest.xml @@ -1,17 +1,17 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/exe/resource.h b/src/exe/resource.h index ed4fffbb..6c94c163 100644 --- a/src/exe/resource.h +++ b/src/exe/resource.h @@ -1,16 +1,16 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by resource.rc -// -#define IDI_ICON1 100 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 105 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDI_ICON1 100 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 105 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/exe/x64_dbg_exe.cpp b/src/exe/x64_dbg_exe.cpp index 07b611cd..7385ec00 100644 --- a/src/exe/x64_dbg_exe.cpp +++ b/src/exe/x64_dbg_exe.cpp @@ -1,42 +1,42 @@ -/** - @file x64_dbg_exe.cpp - - @brief Implements the 64 debug executable class. - */ - -#include -#include -#include "crashdump.h" -#include "..\bridge\bridgemain.h" - -/** - @fn int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) - - @brief Window main. - - @param hInstance The instance. - @param hPrevInstance The previous instance. - @param lpCmdLine The command line. - @param nShowCmd The show command. - - @return An APIENTRY. - */ - -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) -{ - CrashDumpInitialize(); - - const char* errormsg = BridgeInit(); - if(errormsg) - { - MessageBoxA(0, errormsg, "BridgeInit Error", MB_ICONERROR | MB_SYSTEMMODAL); - return 1; - } - errormsg = BridgeStart(); - if(errormsg) - { - MessageBoxA(0, errormsg, "BridgeStart Error", MB_ICONERROR | MB_SYSTEMMODAL); - return 1; - } - return 0; -} +/** + @file x64_dbg_exe.cpp + + @brief Implements the 64 debug executable class. + */ + +#include +#include +#include "crashdump.h" +#include "..\bridge\bridgemain.h" + +/** + @fn int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) + + @brief Window main. + + @param hInstance The instance. + @param hPrevInstance The previous instance. + @param lpCmdLine The command line. + @param nShowCmd The show command. + + @return An APIENTRY. + */ + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) +{ + CrashDumpInitialize(); + + const char* errormsg = BridgeInit(); + if(errormsg) + { + MessageBoxA(0, errormsg, "BridgeInit Error", MB_ICONERROR | MB_SYSTEMMODAL); + return 1; + } + errormsg = BridgeStart(); + if(errormsg) + { + MessageBoxA(0, errormsg, "BridgeStart Error", MB_ICONERROR | MB_SYSTEMMODAL); + return 1; + } + return 0; +} diff --git a/src/exe/x64_dbg_exe.vcxproj b/src/exe/x64_dbg_exe.vcxproj index bab661d9..4459aade 100644 --- a/src/exe/x64_dbg_exe.vcxproj +++ b/src/exe/x64_dbg_exe.vcxproj @@ -1,183 +1,183 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - {3A22175E-6B72-FDCC-1603-C4A2163C7900} - Win32Proj - - - - Application - false - v120_xp - - - Application - false - v120_xp - - - Application - false - v120_xp - - - Application - false - v120_xp - - - - - - - - - - - - - - - - - - - false - $(ProjectDir)..\..\bin\x32\ - $(Platform)\$(Configuration)\ - x32dbg - false - - - false - $(ProjectDir)..\..\bin\x32\ - $(Platform)\$(Configuration)\ - x32dbg - false - - - false - $(ProjectDir)..\..\bin\x64\ - x64dbg - false - - - false - $(ProjectDir)..\..\bin\x64\ - x64dbg - false - - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDLL - Level3 - ProgramDatabase - - - MachineX86 - true - Windows - true - true - $(SolutionDir)bin\x32\x32bridge.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(TargetDir)$(TargetName)_exe.pdb - - - - - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level3 - ProgramDatabase - - - MachineX86 - true - Windows - true - true - $(SolutionDir)bin\x32\x32bridge.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(TargetDir)$(TargetName)_exe.pdb - - - - - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDLL - Level3 - ProgramDatabase - - - true - Windows - true - true - $(SolutionDir)bin\x64\x64bridge.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(TargetDir)$(TargetName)_exe.pdb - - - - - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level3 - ProgramDatabase - - - true - Windows - true - true - $(SolutionDir)bin\x64\x64bridge.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - $(TargetDir)$(TargetName)_exe.pdb - - - - - - - + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + {3A22175E-6B72-FDCC-1603-C4A2163C7900} + Win32Proj + + + + Application + false + v120_xp + + + Application + false + v120_xp + + + Application + false + v120_xp + + + Application + false + v120_xp + + + + + + + + + + + + + + + + + + + false + $(ProjectDir)..\..\bin\x32\ + $(Platform)\$(Configuration)\ + x32dbg + false + + + false + $(ProjectDir)..\..\bin\x32\ + $(Platform)\$(Configuration)\ + x32dbg + false + + + false + $(ProjectDir)..\..\bin\x64\ + x64dbg + false + + + false + $(ProjectDir)..\..\bin\x64\ + x64dbg + false + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + MachineX86 + true + Windows + true + true + $(SolutionDir)bin\x32\x32bridge.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(TargetDir)$(TargetName)_exe.pdb + + + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + + + MachineX86 + true + Windows + true + true + $(SolutionDir)bin\x32\x32bridge.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(TargetDir)$(TargetName)_exe.pdb + + + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + true + Windows + true + true + $(SolutionDir)bin\x64\x64bridge.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(TargetDir)$(TargetName)_exe.pdb + + + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + + + true + Windows + true + true + $(SolutionDir)bin\x64\x64bridge.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(TargetDir)$(TargetName)_exe.pdb + + + + + + + \ No newline at end of file diff --git a/src/gui/Src/BasicView/AbstractTableView.cpp b/src/gui/Src/BasicView/AbstractTableView.cpp index 7b4c862a..c4adcd60 100644 --- a/src/gui/Src/BasicView/AbstractTableView.cpp +++ b/src/gui/Src/BasicView/AbstractTableView.cpp @@ -1,1011 +1,1011 @@ -#include "AbstractTableView.h" -#include -#include "Configuration.h" - -AbstractTableView::AbstractTableView(QWidget* parent) : QAbstractScrollArea(parent) -{ - // Class variable initialization - mTableOffset = 0; - mPrevTableOffset = mTableOffset + 1; - Header_t data; - data.isVisible = true; - data.height = 20; - data.activeButtonIndex = -1; - mHeader = data; - - // Paint cell content only when debugger is running - setDrawDebugOnly(true); - - mRowCount = 0; - - mHeaderButtonSytle.setStyleSheet(" QPushButton {\n background-color: rgb(192, 192, 192);\n border-style: outset;\n border-width: 2px;\n border-color: rgb(128, 128, 128);\n }\n QPushButton:pressed {\n background-color: rgb(192, 192, 192);\n border-style: inset;\n }"); - - mNbrOfLineToPrint = 0; - - memset(&mColResizeData, 0, sizeof(mColResizeData)); - - mGuiState = AbstractTableView::NoState; - - mShouldReload = true; - mAllowPainting = true; - - // ScrollBar Init - setVerticalScrollBar(new AbstractTableScrollBar(verticalScrollBar())); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - memset(&mScrollBarAttributes, 0, sizeof(mScrollBarAttributes)); - horizontalScrollBar()->setRange(0, 0); - horizontalScrollBar()->setPageStep(650); - mMouseWheelScrollDelta = 4; - setMouseTracking(true); - - // Slots - connect(verticalScrollBar(), SIGNAL(actionTriggered(int)), this, SLOT(vertSliderActionSlot(int))); - connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(slot_updateColors())); - connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(slot_updateFonts())); - connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(slot_updateShortcuts())); - - // todo: try Qt::QueuedConnection to init - Initialize(); -} - -/************************************************************************************ - Configuration -************************************************************************************/ - -void AbstractTableView::Initialize() -{ - // Required to be called by each constructor because - // of VTable changes - // - // Init all other updates once - updateColors(); - updateFonts(); - updateShortcuts(); -} - -void AbstractTableView::updateColors() -{ - backgroundColor = ConfigColor("AbstractTableViewBackgroundColor"); - textColor = ConfigColor("AbstractTableViewTextColor"); - separatorColor = ConfigColor("AbstractTableViewSeparatorColor"); - headerTextColor = ConfigColor("AbstractTableViewHeaderTextColor"); - selectionColor = ConfigColor("AbstractTableViewSelectionColor"); -} - -void AbstractTableView::updateFonts() -{ - setFont(ConfigFont("AbstractTableView")); -} - -void AbstractTableView::updateShortcuts() -{ - for(const auto & actionShortcut : actionShortcutPairs) - actionShortcut.action->setShortcut(ConfigShortcut(actionShortcut.shortcut)); -} - -void AbstractTableView::slot_updateColors() -{ - updateColors(); -} - -void AbstractTableView::slot_updateFonts() -{ - updateFonts(); -} - -void AbstractTableView::slot_updateShortcuts() -{ - updateShortcuts(); -} - -/************************************************************************************ - Painting Stuff -************************************************************************************/ -/** - * @brief This method has been reimplemented. It paints the whole table. - * - * @param[in] event Paint event - * - * @return Nothing. - */ -void AbstractTableView::paintEvent(QPaintEvent* event) -{ - if(!mAllowPainting) - return; - if(getColumnCount()) //make sure the last column is never smaller than the window - { - int totalWidth = 0; - for(int i = 0; i < getColumnCount(); i++) - totalWidth += getColumnWidth(i); - int lastWidth = 0; - for(int i = 0; i < getColumnCount() - 1; i++) - lastWidth += getColumnWidth(i); - int width = this->viewport()->width(); - lastWidth = width > lastWidth ? width - lastWidth : 0; - int last = getColumnCount() - 1; - if(totalWidth < width) - setColumnWidth(last, lastWidth); - else - setColumnWidth(last, getColumnWidth(last)); - } - - Q_UNUSED(event); - QPainter wPainter(this->viewport()); - int wViewableRowsCount = getViewableRowsCount(); - - int scrollValue = -horizontalScrollBar()->value(); - - int x = scrollValue; - int y = 0; - - // Reload data if needed - if(mPrevTableOffset != mTableOffset || mShouldReload == true) - { - prepareData(); - mPrevTableOffset = mTableOffset; - mShouldReload = false; - } - - // Paints background - wPainter.fillRect(wPainter.viewport(), QBrush(backgroundColor)); - - // Paints header - if(mHeader.isVisible == true) - { - for(int i = 0; i < getColumnCount(); i++) - { - QStyleOptionButton wOpt; - if((mColumnList[i].header.isPressed == true) && (mColumnList[i].header.isMouseOver == true)) - wOpt.state = QStyle::State_Sunken; - else - wOpt.state = QStyle::State_Enabled; - - wOpt.rect = QRect(x, y, getColumnWidth(i), getHeaderHeight()); - - mHeaderButtonSytle.style()->drawControl(QStyle::CE_PushButton, &wOpt, &wPainter, &mHeaderButtonSytle); - - wPainter.setPen(headerTextColor); - wPainter.drawText(QRect(x + 4, y, getColumnWidth(i) - 8, getHeaderHeight()), Qt::AlignVCenter | Qt::AlignLeft, mColumnList[i].title); - - x += getColumnWidth(i); - } - } - - x = scrollValue; - y = getHeaderHeight(); - - // Iterate over all columns and cells - for(int j = 0; j < getColumnCount(); j++) - { - for(int i = 0; i < wViewableRowsCount; i++) - { - // Paints cell contents - if(i < mNbrOfLineToPrint) - { - // Don't draw cells if the flag is set, and no process is running - if (!mDrawDebugOnly || DbgIsDebugging()) - { - QString wStr = paintContent(&wPainter, mTableOffset, i, j, x, y, getColumnWidth(j), getRowHeight()); - - if(wStr.length()) - { - wPainter.setPen(textColor); - wPainter.drawText(QRect(x + 4, y, getColumnWidth(j) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, wStr); - } - } - } - - // Paints cell right borders - wPainter.setPen(separatorColor); - wPainter.drawLine(x + getColumnWidth(j) - 1, y, x + getColumnWidth(j) - 1, y + getRowHeight() - 1); - - // Update y for the next iteration - y += getRowHeight(); - } - - y = getHeaderHeight(); - x += getColumnWidth(j); - } - //emit repainted(); -} - - -/************************************************************************************ - Mouse Management -************************************************************************************/ -/** - * @brief This method has been reimplemented. It manages the following actions: - * - Column resizing - * - Header button - * - * @param[in] event Mouse event - * - * @return Nothing. - */ -void AbstractTableView::mouseMoveEvent(QMouseEvent* event) -{ - int wColIndex = getColumnIndexFromX(event->x()); - int wStartPos = getColumnPosition(wColIndex); // Position X of the start of column - int wEndPos = getColumnPosition(wColIndex) + getColumnWidth(wColIndex); // Position X of the end of column - bool wHandle = ((wColIndex != 0) && (event->x() >= wStartPos) && (event->x() <= (wStartPos + 2))) || ((event->x() <= wEndPos) && (event->x() >= (wEndPos - 2))); - if(wColIndex == getColumnCount() - 1 && event->x() > viewport()->width()) //last column - wHandle = false; - - switch(mGuiState) - { - case AbstractTableView::NoState: - { - if(event->buttons() == Qt::NoButton) - { - bool wHasCursor = cursor().shape() == Qt::SplitHCursor ? true : false; - - if((wHandle == true) && (wHasCursor == false)) - { - setCursor(Qt::SplitHCursor); - mColResizeData.splitHandle = true; - mGuiState = AbstractTableView::ReadyToResize; - } - if((wHandle == false) && (wHasCursor == true)) - { - unsetCursor(); - mColResizeData.splitHandle = false; - mGuiState = AbstractTableView::NoState; - } - } - else - { - QWidget::mouseMoveEvent(event); - } - } - break; - - case AbstractTableView::ReadyToResize: - { - if(event->buttons() == Qt::NoButton) - { - if((wHandle == false) && (mGuiState == AbstractTableView::ReadyToResize)) - { - unsetCursor(); - mColResizeData.splitHandle = false; - mGuiState = AbstractTableView::NoState; - } - } - } - break; - - case AbstractTableView::ResizeColumnState: - { - int delta = event->x() - mColResizeData.lastPosX; - bool bCanResize = (getColumnWidth(mColResizeData.index) + delta) >= 20; - if(bCanResize) - { - int wNewSize = getColumnWidth(mColResizeData.index) + delta; - setColumnWidth(mColResizeData.index, wNewSize); - mColResizeData.lastPosX = event->x(); - repaint(); - } - } - break; - - case AbstractTableView::HeaderButtonPressed: - { - int wColIndex = getColumnIndexFromX(event->x()); - - if((wColIndex == mHeader.activeButtonIndex) && (event->y() <= getHeaderHeight()) && (event->y() >= 0)) - { - mColumnList[mHeader.activeButtonIndex].header.isMouseOver = true; - } - else - { - mColumnList[mHeader.activeButtonIndex].header.isMouseOver = false; - } - - repaint(); - } - break; - - default: - break; - } -} - - -/** - * @brief This method has been reimplemented. It manages the following actions: - * - Column resizing - * - Header button - * - * @param[in] event Mouse event - * - * @return Nothing. - */ -void AbstractTableView::mousePressEvent(QMouseEvent* event) -{ - if(((event->buttons() & Qt::LeftButton) != 0) && ((event->buttons() & Qt::RightButton) == 0)) - { - if(mColResizeData.splitHandle == true) - { - int wColIndex = getColumnIndexFromX(event->x()); - int wStartPos = getColumnPosition(wColIndex); // Position X of the start of column - - mGuiState = AbstractTableView::ResizeColumnState; - - if(event->x() <= (wStartPos + 2)) - { - mColResizeData.index = wColIndex - 1; - } - else - { - mColResizeData.index = wColIndex; - } - - mColResizeData.lastPosX = event->x(); - } - else if(mHeader.isVisible && getColumnCount() && (event->y() <= getHeaderHeight()) && (event->y() >= 0)) - { - int wColIndex = getColumnIndexFromX(event->x()); - - //qDebug() << "Button " << wColIndex << "has been pressed."; - emit headerButtonPressed(wColIndex); - - mColumnList[wColIndex].header.isPressed = true; - mColumnList[wColIndex].header.isMouseOver = true; - - mHeader.activeButtonIndex = wColIndex; - - mGuiState = AbstractTableView::HeaderButtonPressed; - - repaint(); - } - } - - //QWidget::mousePressEvent(event); -} - -/** - * @brief This method has been reimplemented. It manages the following actions: - * - Column resizing - * - Header button - * - * @param[in] event Mouse event - * - * @return Nothing. - */ -void AbstractTableView::mouseReleaseEvent(QMouseEvent* event) -{ - if((event->buttons() & Qt::LeftButton) == 0) - { - if(mGuiState == AbstractTableView::ResizeColumnState) - { - mGuiState = AbstractTableView::NoState; - } - else if(mGuiState == AbstractTableView::HeaderButtonPressed) - { - if(mColumnList[mHeader.activeButtonIndex].header.isMouseOver == true) - { - //qDebug() << "Button " << mHeader.activeButtonIndex << "has been released."; - emit headerButtonReleased(mHeader.activeButtonIndex); - } - mGuiState = AbstractTableView::NoState; - } - else - { - QWidget::mouseReleaseEvent(event); - } - - // Release all buttons - for(int i = 0; i < getColumnCount(); i++) - { - mColumnList[i].header.isPressed = false; - } - - repaint(); - } -} - - -/** - * @brief This method has been reimplemented. It manages the following actions: - * - Mouse wheel - * - * @param[in] event Wheel event - * - * @return Nothing. - */ -void AbstractTableView::wheelEvent(QWheelEvent* event) -{ - int numDegrees = event->delta() / 8; - int numSteps = numDegrees / 15; - - if(numSteps > 0) - { - for(int i = 0; i < mMouseWheelScrollDelta * numSteps; i++) - verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepSub); - } - else - { - for(int i = 0; i < mMouseWheelScrollDelta * numSteps * -1; i++) - verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepAdd); - } -} - - -/** - * @brief This method has been reimplemented. It repaints the table when the height changes. - * - * @param[in] event Resize event - * - * @return Nothing. - */ -void AbstractTableView::resizeEvent(QResizeEvent* event) -{ - if(event->size().height() != event->oldSize().height()) - { - updateScrollBarRange(getRowCount()); - mShouldReload = true; - } - QWidget::resizeEvent(event); -} - - -/************************************************************************************ - Keyboard Management -************************************************************************************/ -/** - * @brief This method has been reimplemented. It manages the following actions: - * - Pressed keys - * - * @param[in] event Key event - * - * @return Nothing. - */ -void AbstractTableView::keyPressEvent(QKeyEvent* event) -{ - int wKey = event->key(); - - if(wKey == Qt::Key_Up) - { - verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepSub); - } - else if(wKey == Qt::Key_Down) - { - verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepAdd); - } - else if(wKey == Qt::Key_PageUp) - { - verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepSub); - } - else if(wKey == Qt::Key_PageDown) - { - verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepAdd); - } - else if(wKey == Qt::Key_Return || wKey == Qt::Key_Enter) //user pressed enter - emit enterPressedSignal(); -} - -/************************************************************************************ - ScrollBar Management - ***********************************************************************************/ -/** - * @brief This method is the slot connected to the actionTriggered signal of the vertical scrollbar. - * - * @param[in] action Slider action type - * - * @return Nothing. - */ -void AbstractTableView::vertSliderActionSlot(int action) -{ - dsint wDelta = 0; - int wSliderPos = verticalScrollBar()->sliderPosition(); - int wNewScrollBarValue; - - // Bounding - wSliderPos = wSliderPos > verticalScrollBar()->maximum() ? verticalScrollBar()->maximum() : wSliderPos; - wSliderPos = wSliderPos < 0 ? 0 : wSliderPos; - - // Determine the delta - switch(action) - { - case QAbstractSlider::SliderNoAction: - break; - case QAbstractSlider::SliderSingleStepAdd: - wDelta = 1; - break; - case QAbstractSlider::SliderSingleStepSub: - wDelta = -1; - break; - case QAbstractSlider::SliderPageStepAdd: - wDelta = 30; - break; - case QAbstractSlider::SliderPageStepSub: - wDelta = -30; - break; - case QAbstractSlider::SliderToMinimum: - case QAbstractSlider::SliderToMaximum: - case QAbstractSlider::SliderMove: -#ifdef _WIN64 - wDelta = scaleFromScrollBarRangeToUint64(wSliderPos) - mTableOffset; -#else - wDelta = wSliderPos - mTableOffset; -#endif - break; - default: - break; - } - - // Call the hook (Usefull for disassembly) - mTableOffset = sliderMovedHook(action, mTableOffset, wDelta); - - //this emit causes massive lag in the GUI - //emit tableOffsetChanged(mTableOffset); - - // Scale the new table offset to the 32bits scrollbar range -#ifdef _WIN64 - wNewScrollBarValue = scaleFromUint64ToScrollBarRange(mTableOffset); -#else - wNewScrollBarValue = mTableOffset; -#endif - - //this emit causes massive lag in the GUI - //emit repainted(); - - // Update scrollbar attributes - verticalScrollBar()->setValue(wNewScrollBarValue); - verticalScrollBar()->setSliderPosition(wNewScrollBarValue); -} - - -/** - * @brief This virtual method is called at the end of the vertSliderActionSlot(...) method. - * It allows changing the table offset according to the action type, the old table offset - * and delta between the old and the new table offset. - * - * @param[in] type Type of action (Refer to the QAbstractSlider::SliderAction enum) - * @param[in] value Old table offset - * @param[in] delta Scrollbar value delta compared to the previous state - * - * @return Return the value of the new table offset. - */ -dsint AbstractTableView::sliderMovedHook(int type, dsint value, dsint delta) -{ - Q_UNUSED(type); - dsint wValue = value + delta; - dsint wMax = getRowCount() - getViewableRowsCount() + 1; - - // Bounding - wValue = wValue > wMax ? wMax : wValue; - wValue = wValue < 0 ? 0 : wValue; - - return wValue; -} - - -/** - * @brief This method scale the given 64bits integer to the scrollbar range (32bits). - * - * @param[in] value 64bits integer to rescale - * - * @return 32bits integer. - */ -#ifdef _WIN64 -int AbstractTableView::scaleFromUint64ToScrollBarRange(dsint value) -{ - if(mScrollBarAttributes.is64 == true) - { - dsint wValue = ((dsint)value) >> mScrollBarAttributes.rightShiftCount; - dsint wValueMax = ((dsint)getRowCount() - 1) >> mScrollBarAttributes.rightShiftCount; - - if(value == ((dsint)getRowCount() - 1)) - return (int)(verticalScrollBar()->maximum()); - else - return (int)((dsint)((dsint)verticalScrollBar()->maximum() * (dsint)wValue) / (dsint)wValueMax); - } - else - { - return (int)value; - } -} -#endif - - -/** - * @brief This method scale the given 32bits integer to the table range (64bits). - * - * @param[in] value 32bits integer to rescale - * - * @return 64bits integer. - */ -#ifdef _WIN64 -dsint AbstractTableView::scaleFromScrollBarRangeToUint64(int value) -{ - if(mScrollBarAttributes.is64 == true) - { - dsint wValueMax = ((dsint)getRowCount() - 1) >> mScrollBarAttributes.rightShiftCount; - - if(value == (int)0x7FFFFFFF) - return (dsint)(getRowCount() - 1); - else - return (dsint)(((dsint)((dsint)wValueMax * (dsint)value) / (dsint)0x7FFFFFFF) << mScrollBarAttributes.rightShiftCount); - } - else - { - return (dsint)value; - } -} -#endif - - -/** - * @brief This method updates the scrollbar range and pre-computes some attributes for the 32<->64bits conversion methods. - * - * @param[in] range New table range (size) - * - * @return 32bits integer. - */ -void AbstractTableView::updateScrollBarRange(dsint range) -{ - dsint wMax = range - getViewableRowsCount() + 1; - - if(wMax > 0) - { -#ifdef _WIN64 - if((duint)wMax < (duint)0x0000000080000000) - { - mScrollBarAttributes.is64 = false; - mScrollBarAttributes.rightShiftCount = 0; - verticalScrollBar()->setRange(0, wMax); - } - else - { - duint wMask = 0x8000000000000000; - int wLeadingZeroCount; - - // Count leading zeros - for(wLeadingZeroCount = 0; wLeadingZeroCount < 64; wLeadingZeroCount++) - { - if((duint)wMax < wMask) - { - wMask = wMask >> 1; - } - else - { - break; - } - } - - mScrollBarAttributes.is64 = true; - mScrollBarAttributes.rightShiftCount = 32 - wLeadingZeroCount; - verticalScrollBar()->setRange(0, 0x7FFFFFFF); - } -#else - verticalScrollBar()->setRange(0, wMax); -#endif - } - else - verticalScrollBar()->setRange(0, 0); -} - -/************************************************************************************ - Coordinates Utils -************************************************************************************/ -/** - * @brief Returns the index offset (relative to the table offset) corresponding to the given y coordinate. - * - * @param[in] y Pixel offset starting from the top of the table (without the header) - * - * @return row index offset. - */ -int AbstractTableView::getIndexOffsetFromY(int y) -{ - return (y / getRowHeight()); -} - - -/** - * @brief Returns the index of the column corresponding to the given x coordinate. - * - * @param[in] x Pixel offset starting from the left of the table - * - * @return Column index. - */ -int AbstractTableView::getColumnIndexFromX(int x) -{ - int wX = -horizontalScrollBar()->value(); - int wColIndex = 0; - - while(wColIndex < getColumnCount()) - { - wX += getColumnWidth(wColIndex); - - if(x <= wX) - { - return wColIndex; - } - else if(wColIndex < getColumnCount()) - { - wColIndex++; - } - } - return getColumnCount() - 1; -} - - -/** - * @brief Returns the x coordinate of the beginning of the column at index index. - * - * @param[in] index Column index. - * - * @return X coordinate of the column index. - */ -int AbstractTableView::getColumnPosition(int index) -{ - int posX = -horizontalScrollBar()->value(); - - if((index >= 0) && (index < getColumnCount())) - { - for(int i = 0; i <= (index - 1); i++) - { - posX += getColumnWidth(i); - } - - return posX; - } - else - { - return -1; - } -} - - -/** - * @brief Substracts the header heigth from the given y. - * - * @param[in] y y coordinate - * - * @return y - getHeaderHeigth(). - */ -int AbstractTableView::transY(int y) -{ - return y - getHeaderHeight(); -} - - -/** - * @brief Returns the number of viewable rows in the current window (Partially viewable rows are aslo counted). - * - * @return Number of viewable rows. - */ -int AbstractTableView::getViewableRowsCount() -{ - int wTableHeight = this->viewport()->height() - getHeaderHeight(); - int wCount = wTableHeight / getRowHeight(); - - wCount += (wTableHeight % getRowHeight()) > 0 ? 1 : 0; - - emit viewableRows(wCount); - return wCount; -} - - -/** - * @brief This virtual method returns the number of remaining lines to print. - * - * @return Number of remaining lines to print. - */ -int AbstractTableView::getLineToPrintcount() -{ - int wViewableRowsCount = getViewableRowsCount(); - dsint wRemainingRowsCount = getRowCount() - mTableOffset; - int wCount = (dsint)wRemainingRowsCount > (dsint)wViewableRowsCount ? (int)wViewableRowsCount : (int)wRemainingRowsCount; - return wCount; -} - - -/************************************************************************************ - New Columns/New Size -************************************************************************************/ -/** - * @brief This mehtod adds a new column to the table. - * - * @param[in] width Width of the column in pixel - * @param[in] isClickable Boolean that tells whether the header is clickable or not - * - * @return Nothing. - */ -void AbstractTableView::addColumnAt(int width, QString title, bool isClickable) -{ - HeaderButton_t wHeaderButton; - Column_t wColumn; - - wHeaderButton.isPressed = false; - wHeaderButton.isClickable = isClickable; - wHeaderButton.isMouseOver = false; - - wColumn.header = wHeaderButton; - wColumn.width = width; - - wColumn.title = title; - - mColumnList.append(wColumn); -} - -void AbstractTableView::setRowCount(dsint count) -{ - updateScrollBarRange(count); - mRowCount = count; -} - -void AbstractTableView::deleteAllColumns() -{ - mColumnList.clear(); -} - -void AbstractTableView::setColTitle(int index, QString title) -{ - if(mColumnList.size() > 0 && index >= 0 && index < mColumnList.size()) - { - Column_t wColum = mColumnList.takeAt(index); - wColum.title = title; - mColumnList.insert(index - 1, wColum); - } -} - -QString AbstractTableView::getColTitle(int index) -{ - if(mColumnList.size() > 0 && index >= 0 && index < mColumnList.size()) - return mColumnList.at(index).title; - return ""; -} - -/************************************************************************************ - Getter & Setter -************************************************************************************/ -dsint AbstractTableView::getRowCount() -{ - return mRowCount; -} - -int AbstractTableView::getColumnCount() -{ - return mColumnList.size(); -} - -int AbstractTableView::getRowHeight() -{ - int wRowsHeight = QFontMetrics(this->font()).height(); - wRowsHeight = (wRowsHeight * 105) / 100; - wRowsHeight = (wRowsHeight % 2) == 0 ? wRowsHeight : wRowsHeight + 1; - return wRowsHeight; -} - -int AbstractTableView::getColumnWidth(int index) -{ - if(index < 0) - return -1; - else if(index < getColumnCount()) - return mColumnList.at(index).width; - return 0; -} - -void AbstractTableView::setColumnWidth(int index, int width) -{ - int totalWidth = 0; - for(int i = 0; i < getColumnCount(); i++) - totalWidth += getColumnWidth(i); - if(totalWidth > this->viewport()->width()) - horizontalScrollBar()->setRange(0, totalWidth - this->viewport()->width()); - else if(totalWidth <= this->viewport()->width()) - horizontalScrollBar()->setRange(0, 0); - - mColumnList[index].width = width; -} - -int AbstractTableView::getHeaderHeight() -{ - if(mHeader.isVisible == true) - return mHeader.height; - else - return 0; -} - -int AbstractTableView::getTableHeigth() -{ - return this->viewport()->height() - getHeaderHeight(); -} - -int AbstractTableView::getGuiState() -{ - return mGuiState; -} - -int AbstractTableView::getNbrOfLineToPrint() -{ - return mNbrOfLineToPrint; -} - -void AbstractTableView::setNbrOfLineToPrint(int parNbrOfLineToPrint) -{ - mNbrOfLineToPrint = parNbrOfLineToPrint; -} - -void AbstractTableView::setShowHeader(bool show) -{ - mHeader.isVisible = show; -} - -int AbstractTableView::getCharWidth() -{ - return QFontMetrics(this->font()).width(QChar(' ')); -} - -/************************************************************************************ - Content drawing control -************************************************************************************/ - -bool AbstractTableView::getDrawDebugOnly() -{ - return mDrawDebugOnly; -} - -void AbstractTableView::setDrawDebugOnly(bool value) -{ - mDrawDebugOnly = value; -} - -/************************************************************************************ - Table offset management -************************************************************************************/ -dsint AbstractTableView::getTableOffset() -{ - return mTableOffset; -} - - -void AbstractTableView::setTableOffset(dsint val) -{ - dsint wMaxOffset = getRowCount() - getViewableRowsCount() + 1; - wMaxOffset = wMaxOffset > 0 ? wMaxOffset : 0; - if(val > wMaxOffset) - return; - mTableOffset = val; - emit tableOffsetChanged(val); - -#ifdef _WIN64 - int wNewValue = scaleFromUint64ToScrollBarRange(mTableOffset); - verticalScrollBar()->setValue(wNewValue); - verticalScrollBar()->setSliderPosition(wNewValue); -#else - verticalScrollBar()->setValue(val); - verticalScrollBar()->setSliderPosition(val); -#endif -} - - -/************************************************************************************ - Update/Reload/Refresh/Repaint -************************************************************************************/ -void AbstractTableView::reloadData() -{ - mShouldReload = true; - emit tableOffsetChanged(mTableOffset); - repaint(); -} - - -void AbstractTableView::repaint() -{ - this->viewport()->repaint(); -} - - -/** - * @brief This method is called when data have to be reloaded (e.g. When table offset changes). - * - * @return Nothing. - */ -void AbstractTableView::prepareData() -{ - int wViewableRowsCount = getViewableRowsCount(); - dsint wRemainingRowsCount = getRowCount() - mTableOffset; - mNbrOfLineToPrint = (dsint)wRemainingRowsCount > (dsint)wViewableRowsCount ? (int)wViewableRowsCount : (int)wRemainingRowsCount; -} +#include "AbstractTableView.h" +#include +#include "Configuration.h" + +AbstractTableView::AbstractTableView(QWidget* parent) : QAbstractScrollArea(parent) +{ + // Class variable initialization + mTableOffset = 0; + mPrevTableOffset = mTableOffset + 1; + Header_t data; + data.isVisible = true; + data.height = 20; + data.activeButtonIndex = -1; + mHeader = data; + + // Paint cell content only when debugger is running + setDrawDebugOnly(true); + + mRowCount = 0; + + mHeaderButtonSytle.setStyleSheet(" QPushButton {\n background-color: rgb(192, 192, 192);\n border-style: outset;\n border-width: 2px;\n border-color: rgb(128, 128, 128);\n }\n QPushButton:pressed {\n background-color: rgb(192, 192, 192);\n border-style: inset;\n }"); + + mNbrOfLineToPrint = 0; + + memset(&mColResizeData, 0, sizeof(mColResizeData)); + + mGuiState = AbstractTableView::NoState; + + mShouldReload = true; + mAllowPainting = true; + + // ScrollBar Init + setVerticalScrollBar(new AbstractTableScrollBar(verticalScrollBar())); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + memset(&mScrollBarAttributes, 0, sizeof(mScrollBarAttributes)); + horizontalScrollBar()->setRange(0, 0); + horizontalScrollBar()->setPageStep(650); + mMouseWheelScrollDelta = 4; + setMouseTracking(true); + + // Slots + connect(verticalScrollBar(), SIGNAL(actionTriggered(int)), this, SLOT(vertSliderActionSlot(int))); + connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(slot_updateColors())); + connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(slot_updateFonts())); + connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(slot_updateShortcuts())); + + // todo: try Qt::QueuedConnection to init + Initialize(); +} + +/************************************************************************************ + Configuration +************************************************************************************/ + +void AbstractTableView::Initialize() +{ + // Required to be called by each constructor because + // of VTable changes + // + // Init all other updates once + updateColors(); + updateFonts(); + updateShortcuts(); +} + +void AbstractTableView::updateColors() +{ + backgroundColor = ConfigColor("AbstractTableViewBackgroundColor"); + textColor = ConfigColor("AbstractTableViewTextColor"); + separatorColor = ConfigColor("AbstractTableViewSeparatorColor"); + headerTextColor = ConfigColor("AbstractTableViewHeaderTextColor"); + selectionColor = ConfigColor("AbstractTableViewSelectionColor"); +} + +void AbstractTableView::updateFonts() +{ + setFont(ConfigFont("AbstractTableView")); +} + +void AbstractTableView::updateShortcuts() +{ + for(const auto & actionShortcut : actionShortcutPairs) + actionShortcut.action->setShortcut(ConfigShortcut(actionShortcut.shortcut)); +} + +void AbstractTableView::slot_updateColors() +{ + updateColors(); +} + +void AbstractTableView::slot_updateFonts() +{ + updateFonts(); +} + +void AbstractTableView::slot_updateShortcuts() +{ + updateShortcuts(); +} + +/************************************************************************************ + Painting Stuff +************************************************************************************/ +/** + * @brief This method has been reimplemented. It paints the whole table. + * + * @param[in] event Paint event + * + * @return Nothing. + */ +void AbstractTableView::paintEvent(QPaintEvent* event) +{ + if(!mAllowPainting) + return; + if(getColumnCount()) //make sure the last column is never smaller than the window + { + int totalWidth = 0; + for(int i = 0; i < getColumnCount(); i++) + totalWidth += getColumnWidth(i); + int lastWidth = 0; + for(int i = 0; i < getColumnCount() - 1; i++) + lastWidth += getColumnWidth(i); + int width = this->viewport()->width(); + lastWidth = width > lastWidth ? width - lastWidth : 0; + int last = getColumnCount() - 1; + if(totalWidth < width) + setColumnWidth(last, lastWidth); + else + setColumnWidth(last, getColumnWidth(last)); + } + + Q_UNUSED(event); + QPainter wPainter(this->viewport()); + int wViewableRowsCount = getViewableRowsCount(); + + int scrollValue = -horizontalScrollBar()->value(); + + int x = scrollValue; + int y = 0; + + // Reload data if needed + if(mPrevTableOffset != mTableOffset || mShouldReload == true) + { + prepareData(); + mPrevTableOffset = mTableOffset; + mShouldReload = false; + } + + // Paints background + wPainter.fillRect(wPainter.viewport(), QBrush(backgroundColor)); + + // Paints header + if(mHeader.isVisible == true) + { + for(int i = 0; i < getColumnCount(); i++) + { + QStyleOptionButton wOpt; + if((mColumnList[i].header.isPressed == true) && (mColumnList[i].header.isMouseOver == true)) + wOpt.state = QStyle::State_Sunken; + else + wOpt.state = QStyle::State_Enabled; + + wOpt.rect = QRect(x, y, getColumnWidth(i), getHeaderHeight()); + + mHeaderButtonSytle.style()->drawControl(QStyle::CE_PushButton, &wOpt, &wPainter, &mHeaderButtonSytle); + + wPainter.setPen(headerTextColor); + wPainter.drawText(QRect(x + 4, y, getColumnWidth(i) - 8, getHeaderHeight()), Qt::AlignVCenter | Qt::AlignLeft, mColumnList[i].title); + + x += getColumnWidth(i); + } + } + + x = scrollValue; + y = getHeaderHeight(); + + // Iterate over all columns and cells + for(int j = 0; j < getColumnCount(); j++) + { + for(int i = 0; i < wViewableRowsCount; i++) + { + // Paints cell contents + if(i < mNbrOfLineToPrint) + { + // Don't draw cells if the flag is set, and no process is running + if (!mDrawDebugOnly || DbgIsDebugging()) + { + QString wStr = paintContent(&wPainter, mTableOffset, i, j, x, y, getColumnWidth(j), getRowHeight()); + + if(wStr.length()) + { + wPainter.setPen(textColor); + wPainter.drawText(QRect(x + 4, y, getColumnWidth(j) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, wStr); + } + } + } + + // Paints cell right borders + wPainter.setPen(separatorColor); + wPainter.drawLine(x + getColumnWidth(j) - 1, y, x + getColumnWidth(j) - 1, y + getRowHeight() - 1); + + // Update y for the next iteration + y += getRowHeight(); + } + + y = getHeaderHeight(); + x += getColumnWidth(j); + } + //emit repainted(); +} + + +/************************************************************************************ + Mouse Management +************************************************************************************/ +/** + * @brief This method has been reimplemented. It manages the following actions: + * - Column resizing + * - Header button + * + * @param[in] event Mouse event + * + * @return Nothing. + */ +void AbstractTableView::mouseMoveEvent(QMouseEvent* event) +{ + int wColIndex = getColumnIndexFromX(event->x()); + int wStartPos = getColumnPosition(wColIndex); // Position X of the start of column + int wEndPos = getColumnPosition(wColIndex) + getColumnWidth(wColIndex); // Position X of the end of column + bool wHandle = ((wColIndex != 0) && (event->x() >= wStartPos) && (event->x() <= (wStartPos + 2))) || ((event->x() <= wEndPos) && (event->x() >= (wEndPos - 2))); + if(wColIndex == getColumnCount() - 1 && event->x() > viewport()->width()) //last column + wHandle = false; + + switch(mGuiState) + { + case AbstractTableView::NoState: + { + if(event->buttons() == Qt::NoButton) + { + bool wHasCursor = cursor().shape() == Qt::SplitHCursor ? true : false; + + if((wHandle == true) && (wHasCursor == false)) + { + setCursor(Qt::SplitHCursor); + mColResizeData.splitHandle = true; + mGuiState = AbstractTableView::ReadyToResize; + } + if((wHandle == false) && (wHasCursor == true)) + { + unsetCursor(); + mColResizeData.splitHandle = false; + mGuiState = AbstractTableView::NoState; + } + } + else + { + QWidget::mouseMoveEvent(event); + } + } + break; + + case AbstractTableView::ReadyToResize: + { + if(event->buttons() == Qt::NoButton) + { + if((wHandle == false) && (mGuiState == AbstractTableView::ReadyToResize)) + { + unsetCursor(); + mColResizeData.splitHandle = false; + mGuiState = AbstractTableView::NoState; + } + } + } + break; + + case AbstractTableView::ResizeColumnState: + { + int delta = event->x() - mColResizeData.lastPosX; + bool bCanResize = (getColumnWidth(mColResizeData.index) + delta) >= 20; + if(bCanResize) + { + int wNewSize = getColumnWidth(mColResizeData.index) + delta; + setColumnWidth(mColResizeData.index, wNewSize); + mColResizeData.lastPosX = event->x(); + repaint(); + } + } + break; + + case AbstractTableView::HeaderButtonPressed: + { + int wColIndex = getColumnIndexFromX(event->x()); + + if((wColIndex == mHeader.activeButtonIndex) && (event->y() <= getHeaderHeight()) && (event->y() >= 0)) + { + mColumnList[mHeader.activeButtonIndex].header.isMouseOver = true; + } + else + { + mColumnList[mHeader.activeButtonIndex].header.isMouseOver = false; + } + + repaint(); + } + break; + + default: + break; + } +} + + +/** + * @brief This method has been reimplemented. It manages the following actions: + * - Column resizing + * - Header button + * + * @param[in] event Mouse event + * + * @return Nothing. + */ +void AbstractTableView::mousePressEvent(QMouseEvent* event) +{ + if(((event->buttons() & Qt::LeftButton) != 0) && ((event->buttons() & Qt::RightButton) == 0)) + { + if(mColResizeData.splitHandle == true) + { + int wColIndex = getColumnIndexFromX(event->x()); + int wStartPos = getColumnPosition(wColIndex); // Position X of the start of column + + mGuiState = AbstractTableView::ResizeColumnState; + + if(event->x() <= (wStartPos + 2)) + { + mColResizeData.index = wColIndex - 1; + } + else + { + mColResizeData.index = wColIndex; + } + + mColResizeData.lastPosX = event->x(); + } + else if(mHeader.isVisible && getColumnCount() && (event->y() <= getHeaderHeight()) && (event->y() >= 0)) + { + int wColIndex = getColumnIndexFromX(event->x()); + + //qDebug() << "Button " << wColIndex << "has been pressed."; + emit headerButtonPressed(wColIndex); + + mColumnList[wColIndex].header.isPressed = true; + mColumnList[wColIndex].header.isMouseOver = true; + + mHeader.activeButtonIndex = wColIndex; + + mGuiState = AbstractTableView::HeaderButtonPressed; + + repaint(); + } + } + + //QWidget::mousePressEvent(event); +} + +/** + * @brief This method has been reimplemented. It manages the following actions: + * - Column resizing + * - Header button + * + * @param[in] event Mouse event + * + * @return Nothing. + */ +void AbstractTableView::mouseReleaseEvent(QMouseEvent* event) +{ + if((event->buttons() & Qt::LeftButton) == 0) + { + if(mGuiState == AbstractTableView::ResizeColumnState) + { + mGuiState = AbstractTableView::NoState; + } + else if(mGuiState == AbstractTableView::HeaderButtonPressed) + { + if(mColumnList[mHeader.activeButtonIndex].header.isMouseOver == true) + { + //qDebug() << "Button " << mHeader.activeButtonIndex << "has been released."; + emit headerButtonReleased(mHeader.activeButtonIndex); + } + mGuiState = AbstractTableView::NoState; + } + else + { + QWidget::mouseReleaseEvent(event); + } + + // Release all buttons + for(int i = 0; i < getColumnCount(); i++) + { + mColumnList[i].header.isPressed = false; + } + + repaint(); + } +} + + +/** + * @brief This method has been reimplemented. It manages the following actions: + * - Mouse wheel + * + * @param[in] event Wheel event + * + * @return Nothing. + */ +void AbstractTableView::wheelEvent(QWheelEvent* event) +{ + int numDegrees = event->delta() / 8; + int numSteps = numDegrees / 15; + + if(numSteps > 0) + { + for(int i = 0; i < mMouseWheelScrollDelta * numSteps; i++) + verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepSub); + } + else + { + for(int i = 0; i < mMouseWheelScrollDelta * numSteps * -1; i++) + verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepAdd); + } +} + + +/** + * @brief This method has been reimplemented. It repaints the table when the height changes. + * + * @param[in] event Resize event + * + * @return Nothing. + */ +void AbstractTableView::resizeEvent(QResizeEvent* event) +{ + if(event->size().height() != event->oldSize().height()) + { + updateScrollBarRange(getRowCount()); + mShouldReload = true; + } + QWidget::resizeEvent(event); +} + + +/************************************************************************************ + Keyboard Management +************************************************************************************/ +/** + * @brief This method has been reimplemented. It manages the following actions: + * - Pressed keys + * + * @param[in] event Key event + * + * @return Nothing. + */ +void AbstractTableView::keyPressEvent(QKeyEvent* event) +{ + int wKey = event->key(); + + if(wKey == Qt::Key_Up) + { + verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepSub); + } + else if(wKey == Qt::Key_Down) + { + verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepAdd); + } + else if(wKey == Qt::Key_PageUp) + { + verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepSub); + } + else if(wKey == Qt::Key_PageDown) + { + verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepAdd); + } + else if(wKey == Qt::Key_Return || wKey == Qt::Key_Enter) //user pressed enter + emit enterPressedSignal(); +} + +/************************************************************************************ + ScrollBar Management + ***********************************************************************************/ +/** + * @brief This method is the slot connected to the actionTriggered signal of the vertical scrollbar. + * + * @param[in] action Slider action type + * + * @return Nothing. + */ +void AbstractTableView::vertSliderActionSlot(int action) +{ + dsint wDelta = 0; + int wSliderPos = verticalScrollBar()->sliderPosition(); + int wNewScrollBarValue; + + // Bounding + wSliderPos = wSliderPos > verticalScrollBar()->maximum() ? verticalScrollBar()->maximum() : wSliderPos; + wSliderPos = wSliderPos < 0 ? 0 : wSliderPos; + + // Determine the delta + switch(action) + { + case QAbstractSlider::SliderNoAction: + break; + case QAbstractSlider::SliderSingleStepAdd: + wDelta = 1; + break; + case QAbstractSlider::SliderSingleStepSub: + wDelta = -1; + break; + case QAbstractSlider::SliderPageStepAdd: + wDelta = 30; + break; + case QAbstractSlider::SliderPageStepSub: + wDelta = -30; + break; + case QAbstractSlider::SliderToMinimum: + case QAbstractSlider::SliderToMaximum: + case QAbstractSlider::SliderMove: +#ifdef _WIN64 + wDelta = scaleFromScrollBarRangeToUint64(wSliderPos) - mTableOffset; +#else + wDelta = wSliderPos - mTableOffset; +#endif + break; + default: + break; + } + + // Call the hook (Usefull for disassembly) + mTableOffset = sliderMovedHook(action, mTableOffset, wDelta); + + //this emit causes massive lag in the GUI + //emit tableOffsetChanged(mTableOffset); + + // Scale the new table offset to the 32bits scrollbar range +#ifdef _WIN64 + wNewScrollBarValue = scaleFromUint64ToScrollBarRange(mTableOffset); +#else + wNewScrollBarValue = mTableOffset; +#endif + + //this emit causes massive lag in the GUI + //emit repainted(); + + // Update scrollbar attributes + verticalScrollBar()->setValue(wNewScrollBarValue); + verticalScrollBar()->setSliderPosition(wNewScrollBarValue); +} + + +/** + * @brief This virtual method is called at the end of the vertSliderActionSlot(...) method. + * It allows changing the table offset according to the action type, the old table offset + * and delta between the old and the new table offset. + * + * @param[in] type Type of action (Refer to the QAbstractSlider::SliderAction enum) + * @param[in] value Old table offset + * @param[in] delta Scrollbar value delta compared to the previous state + * + * @return Return the value of the new table offset. + */ +dsint AbstractTableView::sliderMovedHook(int type, dsint value, dsint delta) +{ + Q_UNUSED(type); + dsint wValue = value + delta; + dsint wMax = getRowCount() - getViewableRowsCount() + 1; + + // Bounding + wValue = wValue > wMax ? wMax : wValue; + wValue = wValue < 0 ? 0 : wValue; + + return wValue; +} + + +/** + * @brief This method scale the given 64bits integer to the scrollbar range (32bits). + * + * @param[in] value 64bits integer to rescale + * + * @return 32bits integer. + */ +#ifdef _WIN64 +int AbstractTableView::scaleFromUint64ToScrollBarRange(dsint value) +{ + if(mScrollBarAttributes.is64 == true) + { + dsint wValue = ((dsint)value) >> mScrollBarAttributes.rightShiftCount; + dsint wValueMax = ((dsint)getRowCount() - 1) >> mScrollBarAttributes.rightShiftCount; + + if(value == ((dsint)getRowCount() - 1)) + return (int)(verticalScrollBar()->maximum()); + else + return (int)((dsint)((dsint)verticalScrollBar()->maximum() * (dsint)wValue) / (dsint)wValueMax); + } + else + { + return (int)value; + } +} +#endif + + +/** + * @brief This method scale the given 32bits integer to the table range (64bits). + * + * @param[in] value 32bits integer to rescale + * + * @return 64bits integer. + */ +#ifdef _WIN64 +dsint AbstractTableView::scaleFromScrollBarRangeToUint64(int value) +{ + if(mScrollBarAttributes.is64 == true) + { + dsint wValueMax = ((dsint)getRowCount() - 1) >> mScrollBarAttributes.rightShiftCount; + + if(value == (int)0x7FFFFFFF) + return (dsint)(getRowCount() - 1); + else + return (dsint)(((dsint)((dsint)wValueMax * (dsint)value) / (dsint)0x7FFFFFFF) << mScrollBarAttributes.rightShiftCount); + } + else + { + return (dsint)value; + } +} +#endif + + +/** + * @brief This method updates the scrollbar range and pre-computes some attributes for the 32<->64bits conversion methods. + * + * @param[in] range New table range (size) + * + * @return 32bits integer. + */ +void AbstractTableView::updateScrollBarRange(dsint range) +{ + dsint wMax = range - getViewableRowsCount() + 1; + + if(wMax > 0) + { +#ifdef _WIN64 + if((duint)wMax < (duint)0x0000000080000000) + { + mScrollBarAttributes.is64 = false; + mScrollBarAttributes.rightShiftCount = 0; + verticalScrollBar()->setRange(0, wMax); + } + else + { + duint wMask = 0x8000000000000000; + int wLeadingZeroCount; + + // Count leading zeros + for(wLeadingZeroCount = 0; wLeadingZeroCount < 64; wLeadingZeroCount++) + { + if((duint)wMax < wMask) + { + wMask = wMask >> 1; + } + else + { + break; + } + } + + mScrollBarAttributes.is64 = true; + mScrollBarAttributes.rightShiftCount = 32 - wLeadingZeroCount; + verticalScrollBar()->setRange(0, 0x7FFFFFFF); + } +#else + verticalScrollBar()->setRange(0, wMax); +#endif + } + else + verticalScrollBar()->setRange(0, 0); +} + +/************************************************************************************ + Coordinates Utils +************************************************************************************/ +/** + * @brief Returns the index offset (relative to the table offset) corresponding to the given y coordinate. + * + * @param[in] y Pixel offset starting from the top of the table (without the header) + * + * @return row index offset. + */ +int AbstractTableView::getIndexOffsetFromY(int y) +{ + return (y / getRowHeight()); +} + + +/** + * @brief Returns the index of the column corresponding to the given x coordinate. + * + * @param[in] x Pixel offset starting from the left of the table + * + * @return Column index. + */ +int AbstractTableView::getColumnIndexFromX(int x) +{ + int wX = -horizontalScrollBar()->value(); + int wColIndex = 0; + + while(wColIndex < getColumnCount()) + { + wX += getColumnWidth(wColIndex); + + if(x <= wX) + { + return wColIndex; + } + else if(wColIndex < getColumnCount()) + { + wColIndex++; + } + } + return getColumnCount() - 1; +} + + +/** + * @brief Returns the x coordinate of the beginning of the column at index index. + * + * @param[in] index Column index. + * + * @return X coordinate of the column index. + */ +int AbstractTableView::getColumnPosition(int index) +{ + int posX = -horizontalScrollBar()->value(); + + if((index >= 0) && (index < getColumnCount())) + { + for(int i = 0; i <= (index - 1); i++) + { + posX += getColumnWidth(i); + } + + return posX; + } + else + { + return -1; + } +} + + +/** + * @brief Substracts the header heigth from the given y. + * + * @param[in] y y coordinate + * + * @return y - getHeaderHeigth(). + */ +int AbstractTableView::transY(int y) +{ + return y - getHeaderHeight(); +} + + +/** + * @brief Returns the number of viewable rows in the current window (Partially viewable rows are aslo counted). + * + * @return Number of viewable rows. + */ +int AbstractTableView::getViewableRowsCount() +{ + int wTableHeight = this->viewport()->height() - getHeaderHeight(); + int wCount = wTableHeight / getRowHeight(); + + wCount += (wTableHeight % getRowHeight()) > 0 ? 1 : 0; + + emit viewableRows(wCount); + return wCount; +} + + +/** + * @brief This virtual method returns the number of remaining lines to print. + * + * @return Number of remaining lines to print. + */ +int AbstractTableView::getLineToPrintcount() +{ + int wViewableRowsCount = getViewableRowsCount(); + dsint wRemainingRowsCount = getRowCount() - mTableOffset; + int wCount = (dsint)wRemainingRowsCount > (dsint)wViewableRowsCount ? (int)wViewableRowsCount : (int)wRemainingRowsCount; + return wCount; +} + + +/************************************************************************************ + New Columns/New Size +************************************************************************************/ +/** + * @brief This mehtod adds a new column to the table. + * + * @param[in] width Width of the column in pixel + * @param[in] isClickable Boolean that tells whether the header is clickable or not + * + * @return Nothing. + */ +void AbstractTableView::addColumnAt(int width, QString title, bool isClickable) +{ + HeaderButton_t wHeaderButton; + Column_t wColumn; + + wHeaderButton.isPressed = false; + wHeaderButton.isClickable = isClickable; + wHeaderButton.isMouseOver = false; + + wColumn.header = wHeaderButton; + wColumn.width = width; + + wColumn.title = title; + + mColumnList.append(wColumn); +} + +void AbstractTableView::setRowCount(dsint count) +{ + updateScrollBarRange(count); + mRowCount = count; +} + +void AbstractTableView::deleteAllColumns() +{ + mColumnList.clear(); +} + +void AbstractTableView::setColTitle(int index, QString title) +{ + if(mColumnList.size() > 0 && index >= 0 && index < mColumnList.size()) + { + Column_t wColum = mColumnList.takeAt(index); + wColum.title = title; + mColumnList.insert(index - 1, wColum); + } +} + +QString AbstractTableView::getColTitle(int index) +{ + if(mColumnList.size() > 0 && index >= 0 && index < mColumnList.size()) + return mColumnList.at(index).title; + return ""; +} + +/************************************************************************************ + Getter & Setter +************************************************************************************/ +dsint AbstractTableView::getRowCount() +{ + return mRowCount; +} + +int AbstractTableView::getColumnCount() +{ + return mColumnList.size(); +} + +int AbstractTableView::getRowHeight() +{ + int wRowsHeight = QFontMetrics(this->font()).height(); + wRowsHeight = (wRowsHeight * 105) / 100; + wRowsHeight = (wRowsHeight % 2) == 0 ? wRowsHeight : wRowsHeight + 1; + return wRowsHeight; +} + +int AbstractTableView::getColumnWidth(int index) +{ + if(index < 0) + return -1; + else if(index < getColumnCount()) + return mColumnList.at(index).width; + return 0; +} + +void AbstractTableView::setColumnWidth(int index, int width) +{ + int totalWidth = 0; + for(int i = 0; i < getColumnCount(); i++) + totalWidth += getColumnWidth(i); + if(totalWidth > this->viewport()->width()) + horizontalScrollBar()->setRange(0, totalWidth - this->viewport()->width()); + else if(totalWidth <= this->viewport()->width()) + horizontalScrollBar()->setRange(0, 0); + + mColumnList[index].width = width; +} + +int AbstractTableView::getHeaderHeight() +{ + if(mHeader.isVisible == true) + return mHeader.height; + else + return 0; +} + +int AbstractTableView::getTableHeigth() +{ + return this->viewport()->height() - getHeaderHeight(); +} + +int AbstractTableView::getGuiState() +{ + return mGuiState; +} + +int AbstractTableView::getNbrOfLineToPrint() +{ + return mNbrOfLineToPrint; +} + +void AbstractTableView::setNbrOfLineToPrint(int parNbrOfLineToPrint) +{ + mNbrOfLineToPrint = parNbrOfLineToPrint; +} + +void AbstractTableView::setShowHeader(bool show) +{ + mHeader.isVisible = show; +} + +int AbstractTableView::getCharWidth() +{ + return QFontMetrics(this->font()).width(QChar(' ')); +} + +/************************************************************************************ + Content drawing control +************************************************************************************/ + +bool AbstractTableView::getDrawDebugOnly() +{ + return mDrawDebugOnly; +} + +void AbstractTableView::setDrawDebugOnly(bool value) +{ + mDrawDebugOnly = value; +} + +/************************************************************************************ + Table offset management +************************************************************************************/ +dsint AbstractTableView::getTableOffset() +{ + return mTableOffset; +} + + +void AbstractTableView::setTableOffset(dsint val) +{ + dsint wMaxOffset = getRowCount() - getViewableRowsCount() + 1; + wMaxOffset = wMaxOffset > 0 ? wMaxOffset : 0; + if(val > wMaxOffset) + return; + mTableOffset = val; + emit tableOffsetChanged(val); + +#ifdef _WIN64 + int wNewValue = scaleFromUint64ToScrollBarRange(mTableOffset); + verticalScrollBar()->setValue(wNewValue); + verticalScrollBar()->setSliderPosition(wNewValue); +#else + verticalScrollBar()->setValue(val); + verticalScrollBar()->setSliderPosition(val); +#endif +} + + +/************************************************************************************ + Update/Reload/Refresh/Repaint +************************************************************************************/ +void AbstractTableView::reloadData() +{ + mShouldReload = true; + emit tableOffsetChanged(mTableOffset); + repaint(); +} + + +void AbstractTableView::repaint() +{ + this->viewport()->repaint(); +} + + +/** + * @brief This method is called when data have to be reloaded (e.g. When table offset changes). + * + * @return Nothing. + */ +void AbstractTableView::prepareData() +{ + int wViewableRowsCount = getViewableRowsCount(); + dsint wRemainingRowsCount = getRowCount() - mTableOffset; + mNbrOfLineToPrint = (dsint)wRemainingRowsCount > (dsint)wViewableRowsCount ? (int)wViewableRowsCount : (int)wRemainingRowsCount; +} diff --git a/src/gui/Src/BasicView/AbstractTableView.h b/src/gui/Src/BasicView/AbstractTableView.h index ec19395b..9803740c 100644 --- a/src/gui/Src/BasicView/AbstractTableView.h +++ b/src/gui/Src/BasicView/AbstractTableView.h @@ -1,297 +1,297 @@ -#ifndef ABSTRACTTABLEVIEW_H -#define ABSTRACTTABLEVIEW_H - -#include -#include -#include -#include -#include -#include -#include -#include "StringUtil.h" -#include "Configuration.h" -#include "MenuBuilder.h" - -//Hacky class that fixes a really annoying cursor problem -class AbstractTableScrollBar : public QScrollBar -{ - Q_OBJECT -public: - AbstractTableScrollBar(QScrollBar* scrollbar) - { - setOrientation(scrollbar->orientation()); - setParent(scrollbar->parentWidget()); - } - - void enterEvent(QEvent* event) - { - Q_UNUSED(event); - QApplication::setOverrideCursor(Qt::ArrowCursor); - } - - void leaveEvent(QEvent* event) - { - Q_UNUSED(event); - QApplication::restoreOverrideCursor(); - } -}; - -class AbstractTableView : public QAbstractScrollArea -{ - Q_OBJECT - -public: - enum GuiState_t {NoState, ReadyToResize, ResizeColumnState, HeaderButtonPressed}; - - // Constructor - explicit AbstractTableView(QWidget* parent = 0); - - // Configuration - virtual void Initialize(); - virtual void updateColors(); - virtual void updateFonts(); - virtual void updateShortcuts(); - - // Pure Virtual Methods - virtual QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) = 0; - - // Painting Stuff - void paintEvent(QPaintEvent* event); - - // Mouse Management - void mouseMoveEvent(QMouseEvent* event); - void mousePressEvent(QMouseEvent* event); - void mouseReleaseEvent(QMouseEvent* event); - void wheelEvent(QWheelEvent* event); - void resizeEvent(QResizeEvent* event); - void keyPressEvent(QKeyEvent* event); - - // ScrollBar Management - virtual dsint sliderMovedHook(int type, dsint value, dsint delta); - int scaleFromUint64ToScrollBarRange(dsint value); - dsint scaleFromScrollBarRangeToUint64(int value); - void updateScrollBarRange(dsint range); - - - // Coordinates Utils - int getIndexOffsetFromY(int y); - int getColumnIndexFromX(int x); - int getColumnPosition(int index); - int transY(int y); - int getViewableRowsCount(); - virtual int getLineToPrintcount(); - - // New Columns/New Size - virtual void addColumnAt(int width, QString title, bool isClickable); - virtual void setRowCount(dsint count); - virtual void deleteAllColumns(); - void setColTitle(int index, QString title); - QString getColTitle(int index); - - // Getter & Setter - dsint getRowCount(); - int getColumnCount(); - int getRowHeight(); - int getColumnWidth(int index); - void setColumnWidth(int index, int width); - int getHeaderHeight(); - int getTableHeigth(); - int getGuiState(); - int getNbrOfLineToPrint(); - void setNbrOfLineToPrint(int parNbrOfLineToPrint); - void setShowHeader(bool show); - int getCharWidth(); - - // Content drawing control - bool getDrawDebugOnly(); - void setDrawDebugOnly(bool value); - - // Table offset management - dsint getTableOffset(); - void setTableOffset(dsint val); - - // Update/Reload/Refresh/Repaint - virtual void prepareData(); - -signals: - void enterPressedSignal(); - void headerButtonPressed(int col); - void headerButtonReleased(int col); - void tableOffsetChanged(dsint i); - void viewableRows(int rows); - void repainted(); - -public slots: - // Configuration - void slot_updateColors(); - void slot_updateFonts(); - void slot_updateShortcuts(); - - // Update/Reload/Refresh/Repaint - virtual void reloadData(); - void repaint(); - - // ScrollBar Management - void vertSliderActionSlot(int action); - -private: - typedef struct _ColumnResizingData_t - { - bool splitHandle; - int index; - int lastPosX; - } ColumnResizingData_t; - - typedef struct _HeaderButton_t - { - bool isClickable; - bool isPressed; - bool isMouseOver; - } HeaderButton_t; - - typedef struct _Column_t - { - int width; - HeaderButton_t header; - QString title; - } Column_t; - - typedef struct _Header_t - { - bool isVisible; - int height; - int activeButtonIndex; - } Header_t; - - typedef struct _ScrollBar64_t - { - bool is64; - int rightShiftCount; - } ScrollBar64_t; - - GuiState_t mGuiState; - - ColumnResizingData_t mColResizeData; - - QPushButton mHeaderButtonSytle; - - QList mColumnList; - - dsint mRowCount; - - int mMouseWheelScrollDelta; - - dsint mTableOffset; - Header_t mHeader; - - int mNbrOfLineToPrint; - - dsint mPrevTableOffset; - - bool mShouldReload; - - ScrollBar64_t mScrollBarAttributes; - -protected: - bool mAllowPainting; - bool mDrawDebugOnly; - - // Configuration - QColor backgroundColor; - QColor textColor; - QColor separatorColor; - QColor headerTextColor; - QColor selectionColor; - - //action helpers -private: - struct ActionShortcut - { - QAction* action; - const char* shortcut; - - ActionShortcut(QAction* action, const char* shortcut) - : action(action), - shortcut(shortcut) - { - } - }; - - std::vector actionShortcutPairs; - - inline QAction* connectAction(QAction* action, const char* slot) - { - connect(action, SIGNAL(triggered(bool)), this, slot); - return action; - } - - inline QAction* connectShortcutAction(QAction* action, const char* shortcut) - { - actionShortcutPairs.push_back(ActionShortcut(action, shortcut)); - action->setShortcut(ConfigShortcut(shortcut)); - action->setShortcutContext(Qt::WidgetShortcut); - addAction(action); - return action; - } - - inline QAction* connectMenuAction(QMenu* menu, QAction* action) - { - menu->addAction(action); - return action; - } - -protected: - inline QMenu* makeMenu(const QString & title) - { - return new QMenu(title, this); - } - - inline QMenu* makeMenu(const QIcon & icon, const QString & title) - { - QMenu* menu = new QMenu(title, this); - menu->setIcon(icon); - return menu; - } - - inline QAction* makeAction(const QString & text, const char* slot) - { - return connectAction(new QAction(text, this), slot); - } - - inline QAction* makeAction(const QIcon & icon, const QString & text, const char* slot) - { - return connectAction(new QAction(icon, text, this), slot); - } - - inline QAction* makeShortcutAction(const QString & text, const char* slot, const char* shortcut) - { - return connectShortcutAction(makeAction(text, slot), shortcut); - } - - inline QAction* makeShortcutAction(const QIcon & icon, const QString & text, const char* slot, const char* shortcut) - { - return connectShortcutAction(makeAction(icon, text, slot), shortcut); - } - - inline QAction* makeMenuAction(QMenu* menu, const QString & text, const char* slot) - { - return connectMenuAction(menu, makeAction(text, slot)); - } - - inline QAction* makeMenuAction(QMenu* menu, const QIcon & icon, const QString & text, const char* slot) - { - return connectMenuAction(menu, makeAction(icon, text, slot)); - } - - inline QAction* makeShortcutMenuAction(QMenu* menu, const QString & text, const char* slot, const char* shortcut) - { - return connectShortcutAction(makeMenuAction(menu, text, slot), shortcut); - } - - inline QAction* makeShortcutMenuAction(QMenu* menu, const QIcon & icon, const QString & text, const char* slot, const char* shortcut) - { - return connectShortcutAction(makeMenuAction(menu, icon, text, slot), shortcut); - } -}; - -#endif // ABSTRACTTABLEVIEW_H +#ifndef ABSTRACTTABLEVIEW_H +#define ABSTRACTTABLEVIEW_H + +#include +#include +#include +#include +#include +#include +#include +#include "StringUtil.h" +#include "Configuration.h" +#include "MenuBuilder.h" + +//Hacky class that fixes a really annoying cursor problem +class AbstractTableScrollBar : public QScrollBar +{ + Q_OBJECT +public: + AbstractTableScrollBar(QScrollBar* scrollbar) + { + setOrientation(scrollbar->orientation()); + setParent(scrollbar->parentWidget()); + } + + void enterEvent(QEvent* event) + { + Q_UNUSED(event); + QApplication::setOverrideCursor(Qt::ArrowCursor); + } + + void leaveEvent(QEvent* event) + { + Q_UNUSED(event); + QApplication::restoreOverrideCursor(); + } +}; + +class AbstractTableView : public QAbstractScrollArea +{ + Q_OBJECT + +public: + enum GuiState_t {NoState, ReadyToResize, ResizeColumnState, HeaderButtonPressed}; + + // Constructor + explicit AbstractTableView(QWidget* parent = 0); + + // Configuration + virtual void Initialize(); + virtual void updateColors(); + virtual void updateFonts(); + virtual void updateShortcuts(); + + // Pure Virtual Methods + virtual QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) = 0; + + // Painting Stuff + void paintEvent(QPaintEvent* event); + + // Mouse Management + void mouseMoveEvent(QMouseEvent* event); + void mousePressEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event); + void wheelEvent(QWheelEvent* event); + void resizeEvent(QResizeEvent* event); + void keyPressEvent(QKeyEvent* event); + + // ScrollBar Management + virtual dsint sliderMovedHook(int type, dsint value, dsint delta); + int scaleFromUint64ToScrollBarRange(dsint value); + dsint scaleFromScrollBarRangeToUint64(int value); + void updateScrollBarRange(dsint range); + + + // Coordinates Utils + int getIndexOffsetFromY(int y); + int getColumnIndexFromX(int x); + int getColumnPosition(int index); + int transY(int y); + int getViewableRowsCount(); + virtual int getLineToPrintcount(); + + // New Columns/New Size + virtual void addColumnAt(int width, QString title, bool isClickable); + virtual void setRowCount(dsint count); + virtual void deleteAllColumns(); + void setColTitle(int index, QString title); + QString getColTitle(int index); + + // Getter & Setter + dsint getRowCount(); + int getColumnCount(); + int getRowHeight(); + int getColumnWidth(int index); + void setColumnWidth(int index, int width); + int getHeaderHeight(); + int getTableHeigth(); + int getGuiState(); + int getNbrOfLineToPrint(); + void setNbrOfLineToPrint(int parNbrOfLineToPrint); + void setShowHeader(bool show); + int getCharWidth(); + + // Content drawing control + bool getDrawDebugOnly(); + void setDrawDebugOnly(bool value); + + // Table offset management + dsint getTableOffset(); + void setTableOffset(dsint val); + + // Update/Reload/Refresh/Repaint + virtual void prepareData(); + +signals: + void enterPressedSignal(); + void headerButtonPressed(int col); + void headerButtonReleased(int col); + void tableOffsetChanged(dsint i); + void viewableRows(int rows); + void repainted(); + +public slots: + // Configuration + void slot_updateColors(); + void slot_updateFonts(); + void slot_updateShortcuts(); + + // Update/Reload/Refresh/Repaint + virtual void reloadData(); + void repaint(); + + // ScrollBar Management + void vertSliderActionSlot(int action); + +private: + typedef struct _ColumnResizingData_t + { + bool splitHandle; + int index; + int lastPosX; + } ColumnResizingData_t; + + typedef struct _HeaderButton_t + { + bool isClickable; + bool isPressed; + bool isMouseOver; + } HeaderButton_t; + + typedef struct _Column_t + { + int width; + HeaderButton_t header; + QString title; + } Column_t; + + typedef struct _Header_t + { + bool isVisible; + int height; + int activeButtonIndex; + } Header_t; + + typedef struct _ScrollBar64_t + { + bool is64; + int rightShiftCount; + } ScrollBar64_t; + + GuiState_t mGuiState; + + ColumnResizingData_t mColResizeData; + + QPushButton mHeaderButtonSytle; + + QList mColumnList; + + dsint mRowCount; + + int mMouseWheelScrollDelta; + + dsint mTableOffset; + Header_t mHeader; + + int mNbrOfLineToPrint; + + dsint mPrevTableOffset; + + bool mShouldReload; + + ScrollBar64_t mScrollBarAttributes; + +protected: + bool mAllowPainting; + bool mDrawDebugOnly; + + // Configuration + QColor backgroundColor; + QColor textColor; + QColor separatorColor; + QColor headerTextColor; + QColor selectionColor; + + //action helpers +private: + struct ActionShortcut + { + QAction* action; + const char* shortcut; + + ActionShortcut(QAction* action, const char* shortcut) + : action(action), + shortcut(shortcut) + { + } + }; + + std::vector actionShortcutPairs; + + inline QAction* connectAction(QAction* action, const char* slot) + { + connect(action, SIGNAL(triggered(bool)), this, slot); + return action; + } + + inline QAction* connectShortcutAction(QAction* action, const char* shortcut) + { + actionShortcutPairs.push_back(ActionShortcut(action, shortcut)); + action->setShortcut(ConfigShortcut(shortcut)); + action->setShortcutContext(Qt::WidgetShortcut); + addAction(action); + return action; + } + + inline QAction* connectMenuAction(QMenu* menu, QAction* action) + { + menu->addAction(action); + return action; + } + +protected: + inline QMenu* makeMenu(const QString & title) + { + return new QMenu(title, this); + } + + inline QMenu* makeMenu(const QIcon & icon, const QString & title) + { + QMenu* menu = new QMenu(title, this); + menu->setIcon(icon); + return menu; + } + + inline QAction* makeAction(const QString & text, const char* slot) + { + return connectAction(new QAction(text, this), slot); + } + + inline QAction* makeAction(const QIcon & icon, const QString & text, const char* slot) + { + return connectAction(new QAction(icon, text, this), slot); + } + + inline QAction* makeShortcutAction(const QString & text, const char* slot, const char* shortcut) + { + return connectShortcutAction(makeAction(text, slot), shortcut); + } + + inline QAction* makeShortcutAction(const QIcon & icon, const QString & text, const char* slot, const char* shortcut) + { + return connectShortcutAction(makeAction(icon, text, slot), shortcut); + } + + inline QAction* makeMenuAction(QMenu* menu, const QString & text, const char* slot) + { + return connectMenuAction(menu, makeAction(text, slot)); + } + + inline QAction* makeMenuAction(QMenu* menu, const QIcon & icon, const QString & text, const char* slot) + { + return connectMenuAction(menu, makeAction(icon, text, slot)); + } + + inline QAction* makeShortcutMenuAction(QMenu* menu, const QString & text, const char* slot, const char* shortcut) + { + return connectShortcutAction(makeMenuAction(menu, text, slot), shortcut); + } + + inline QAction* makeShortcutMenuAction(QMenu* menu, const QIcon & icon, const QString & text, const char* slot, const char* shortcut) + { + return connectShortcutAction(makeMenuAction(menu, icon, text, slot), shortcut); + } +}; + +#endif // ABSTRACTTABLEVIEW_H diff --git a/src/gui/Src/BasicView/Disassembly.cpp b/src/gui/Src/BasicView/Disassembly.cpp index 3fc853e8..acaa873c 100644 --- a/src/gui/Src/BasicView/Disassembly.cpp +++ b/src/gui/Src/BasicView/Disassembly.cpp @@ -1,1544 +1,1544 @@ -#include "Disassembly.h" -#include "Configuration.h" -#include "Bridge.h" - -Disassembly::Disassembly(QWidget* parent) : AbstractTableView(parent) -{ - mMemPage = new MemoryPage(0, 0); - - mInstBuffer.clear(); - - historyClear(); - - SelectionData_t data; - memset(&data, 0, sizeof(SelectionData_t)); - mSelection = data; - - mCipRva = 0; - mIsRunning = false; - - mHighlightToken.text = ""; - mHighlightingMode = false; - - int maxModuleSize = (int)ConfigUint("Disassembler", "MaxModuleSize"); - Config()->writeUints(); - - mDisasm = new QBeaEngine(maxModuleSize); - mDisasm->UpdateConfig(); - - mIsLastInstDisplayed = false; - - mGuiState = Disassembly::NoState; - - // Update fonts immediately because they are used in calculations - updateFonts(); - - setRowCount(mMemPage->getSize()); - - addColumnAt(getCharWidth() * 2 * sizeof(dsint) + 8, "", false); //address - addColumnAt(getCharWidth() * 2 * 12 + 8, "", false); //bytes - addColumnAt(getCharWidth() * 40, "", false); //disassembly - addColumnAt(1000, "", false); //comments - - setShowHeader(false); //hide header - - backgroundColor = ConfigColor("DisassemblyBackgroundColor"); - - // Slots - connect(Bridge::getBridge(), SIGNAL(repaintGui()), this, SLOT(reloadData())); - connect(Bridge::getBridge(), SIGNAL(updateDump()), this, SLOT(reloadData())); - connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE))); - - Initialize(); -} - -void Disassembly::updateColors() -{ - AbstractTableView::updateColors(); - backgroundColor = ConfigColor("DisassemblyBackgroundColor"); - - mInstructionHighlightColor = ConfigColor("InstructionHighlightColor"); - mSelectionColor = ConfigColor("DisassemblySelectionColor"); - mCipBackgroundColor = ConfigColor("DisassemblyCipBackgroundColor"); - mCipColor = ConfigColor("DisassemblyCipColor"); - mBreakpointBackgroundColor = ConfigColor("DisassemblyBreakpointBackgroundColor"); - mBreakpointColor = ConfigColor("DisassemblyBreakpointColor"); - mHardwareBreakpointBackgroundColor = ConfigColor("DisassemblyHardwareBreakpointBackgroundColor"); - mHardwareBreakpointColor = ConfigColor("DisassemblyHardwareBreakpointColor"); - mBookmarkBackgroundColor = ConfigColor("DisassemblyBookmarkBackgroundColor"); - mBookmarkColor = ConfigColor("DisassemblyBookmarkColor"); - mLabelColor = ConfigColor("DisassemblyLabelColor"); - mLabelBackgroundColor = ConfigColor("DisassemblyLabelBackgroundColor"); - mSelectedAddressBackgroundColor = ConfigColor("DisassemblySelectedAddressBackgroundColor"); - mSelectedAddressColor = ConfigColor("DisassemblySelectedAddressColor"); - mAddressBackgroundColor = ConfigColor("DisassemblyAddressBackgroundColor"); - mAddressColor = ConfigColor("DisassemblyAddressColor"); - mBytesColor = ConfigColor("DisassemblyBytesColor"); - mModifiedBytesColor = ConfigColor("DisassemblyModifiedBytesColor"); - mAutoCommentColor = ConfigColor("DisassemblyAutoCommentColor"); - mAutoCommentBackgroundColor = ConfigColor("DisassemblyAutoCommentBackgroundColor"); - mCommentColor = ConfigColor("DisassemblyCommentColor"); - mCommentBackgroundColor = ConfigColor("DisassemblyCommentBackgroundColor"); - mUnconditionalJumpLineColor = ConfigColor("DisassemblyUnconditionalJumpLineColor"); - mConditionalJumpLineTrueColor = ConfigColor("DisassemblyConditionalJumpLineTrueColor"); - mConditionalJumpLineFalseColor = ConfigColor("DisassemblyConditionalJumpLineFalseColor"); - mLoopColor = ConfigColor("DisassemblyLoopColor"); - mFunctionColor = ConfigColor("DisassemblyFunctionColor"); - - CapstoneTokenizer::UpdateColors(); - mDisasm->UpdateConfig(); -} - -void Disassembly::updateFonts() -{ - setFont(ConfigFont("Disassembly")); -} - -/************************************************************************************ - Reimplemented Functions -************************************************************************************/ -/** - * @brief This method has been reimplemented. It returns the string to paint or paints it - * by its own. - * - * @param[in] painter Pointer to the painter that allows painting by its own - * @param[in] rowBase Index of the top item (Table offset) - * @param[in] rowOffset Index offset starting from rowBase - * @param[in] col Column index - * @param[in] x Rectangle x - * @param[in] y Rectangle y - * @param[in] w Rectangle width - * @param[in] h Rectangle heigth - * - * @return String to paint. - */ -QString Disassembly::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) -{ - Q_UNUSED(rowBase); - - if(mHighlightingMode) - { - QPen pen(mInstructionHighlightColor); - pen.setWidth(2); - painter->setPen(pen); - QRect rect = viewport()->rect(); - rect.adjust(1, 1, -1, -1); - painter->drawRect(rect); - } - dsint wRVA = mInstBuffer.at(rowOffset).rva; - bool wIsSelected = isSelected(&mInstBuffer, rowOffset); - - // Highlight if selected - if(wIsSelected) - painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor)); - - switch(col) - { - case 0: // Draw address (+ label) - { - char label[MAX_LABEL_SIZE] = ""; - dsint cur_addr = rvaToVa(mInstBuffer.at(rowOffset).rva); - QString addrText = getAddrText(cur_addr, label); - BPXTYPE bpxtype = DbgGetBpxTypeAt(cur_addr); - bool isbookmark = DbgGetBookmarkAt(cur_addr); - if(mInstBuffer.at(rowOffset).rva == mCipRva && !mIsRunning) //cip + not running - { - painter->fillRect(QRect(x, y, w, h), QBrush(mCipBackgroundColor)); - if(!isbookmark) //no bookmark - { - if(bpxtype & bp_normal) //normal breakpoint - { - QColor& bpColor = mBreakpointBackgroundColor; - if(!bpColor.alpha()) //we don't want transparent text - bpColor = mBreakpointColor; - if(bpColor == mCipBackgroundColor) - bpColor = mCipColor; - painter->setPen(bpColor); - } - else if(bpxtype & bp_hardware) //hardware breakpoint only - { - QColor hwbpColor = mHardwareBreakpointBackgroundColor; - if(!hwbpColor.alpha()) //we don't want transparent text - hwbpColor = mHardwareBreakpointColor; - if(hwbpColor == mCipBackgroundColor) - hwbpColor = mCipColor; - painter->setPen(hwbpColor); - } - else //no breakpoint - { - painter->setPen(mCipColor); - } - } - else //bookmark - { - QColor bookmarkColor = mBookmarkBackgroundColor; - if(!bookmarkColor.alpha()) //we don't want transparent text - bookmarkColor = mBookmarkColor; - if(bookmarkColor == mCipBackgroundColor) - bookmarkColor = mCipColor; - painter->setPen(bookmarkColor); - } - } - else //non-cip address - { - if(!isbookmark) //no bookmark - { - if(*label) //label - { - if(bpxtype == bp_none) //label only - { - painter->setPen(mLabelColor); //red -> address + label text - painter->fillRect(QRect(x, y, w, h), QBrush(mLabelBackgroundColor)); //fill label background - } - else //label+breakpoint - { - if(bpxtype & bp_normal) //label + normal breakpoint - { - painter->setPen(mBreakpointColor); - painter->fillRect(QRect(x, y, w, h), QBrush(mBreakpointBackgroundColor)); //fill red - } - else if(bpxtype & bp_hardware) //label + hardware breakpoint only - { - painter->setPen(mHardwareBreakpointColor); - painter->fillRect(QRect(x, y, w, h), QBrush(mHardwareBreakpointBackgroundColor)); //fill ? - } - else //other cases -> do as normal - { - painter->setPen(mLabelColor); //red -> address + label text - painter->fillRect(QRect(x, y, w, h), QBrush(mLabelBackgroundColor)); //fill label background - } - } - } - else //no label - { - if(bpxtype == bp_none) //no label, no breakpoint - { - QColor background; - if(wIsSelected) - { - background = mSelectedAddressBackgroundColor; - painter->setPen(mSelectedAddressColor); //black address (DisassemblySelectedAddressColor) - } - else - { - background = mAddressBackgroundColor; - painter->setPen(mAddressColor); //DisassemblyAddressColor - } - if(background.alpha()) - painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background - } - else //breakpoint only - { - if(bpxtype & bp_normal) //normal breakpoint - { - painter->setPen(mBreakpointColor); - painter->fillRect(QRect(x, y, w, h), QBrush(mBreakpointBackgroundColor)); //fill red - } - else if(bpxtype & bp_hardware) //hardware breakpoint only - { - painter->setPen(mHardwareBreakpointColor); - painter->fillRect(QRect(x, y, w, h), QBrush(mHardwareBreakpointBackgroundColor)); //fill red - } - else //other cases (memory breakpoint in disassembly) -> do as normal - { - QColor background; - if(wIsSelected) - { - background = mSelectedAddressBackgroundColor; - painter->setPen(mSelectedAddressColor); //black address (DisassemblySelectedAddressColor) - } - else - { - background = mAddressBackgroundColor; - painter->setPen(mAddressColor); - } - if(background.alpha()) - painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background - } - } - } - } - else //bookmark - { - if(*label) //label + bookmark - { - if(bpxtype == bp_none) //label + bookmark - { - painter->setPen(mLabelColor); //red -> address + label text - painter->fillRect(QRect(x, y, w, h), QBrush(mBookmarkBackgroundColor)); //fill label background - } - else //label+breakpoint+bookmark - { - QColor color = mBookmarkBackgroundColor; - if(!color.alpha()) //we don't want transparent text - color = mAddressColor; - painter->setPen(color); - if(bpxtype & bp_normal) //label + bookmark + normal breakpoint - { - painter->fillRect(QRect(x, y, w, h), QBrush(mBreakpointBackgroundColor)); //fill red - } - else if(bpxtype & bp_hardware) //label + bookmark + hardware breakpoint only - { - painter->fillRect(QRect(x, y, w, h), QBrush(mHardwareBreakpointBackgroundColor)); //fill ? - } - } - } - else //bookmark, no label - { - if(bpxtype == bp_none) //bookmark only - { - painter->setPen(mBookmarkColor); //black address - painter->fillRect(QRect(x, y, w, h), QBrush(mBookmarkBackgroundColor)); //fill bookmark color - } - else //bookmark + breakpoint - { - QColor color = mBookmarkBackgroundColor; - if(!color.alpha()) //we don't want transparent text - color = mAddressColor; - painter->setPen(color); - if(bpxtype & bp_normal) //bookmark + normal breakpoint - { - painter->fillRect(QRect(x, y, w, h), QBrush(mBreakpointBackgroundColor)); //fill red - } - else if(bpxtype & bp_hardware) //bookmark + hardware breakpoint only - { - painter->fillRect(QRect(x, y, w, h), QBrush(mHardwareBreakpointBackgroundColor)); //fill red - } - else //other cases (bookmark + memory breakpoint in disassembly) -> do as normal - { - painter->setPen(mBookmarkColor); //black address - painter->fillRect(QRect(x, y, w, h), QBrush(mBookmarkBackgroundColor)); //fill bookmark color - } - } - } - } - } - painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, addrText); - } - break; - - case 1: //draw bytes (TODO: some spaces between bytes) - { - //draw functions - dsint cur_addr = rvaToVa(mInstBuffer.at(rowOffset).rva); - Function_t funcType; - FUNCTYPE funcFirst = DbgGetFunctionTypeAt(cur_addr); - FUNCTYPE funcLast = DbgGetFunctionTypeAt(cur_addr + mInstBuffer.at(rowOffset).length - 1); - if(funcLast == FUNC_END) - funcFirst = funcLast; - switch(funcFirst) - { - case FUNC_SINGLE: - funcType = Function_single; - break; - case FUNC_NONE: - funcType = Function_none; - break; - case FUNC_BEGIN: - funcType = Function_start; - break; - case FUNC_MIDDLE: - funcType = Function_middle; - break; - case FUNC_END: - funcType = Function_end; - break; - } - int funcsize = paintFunctionGraphic(painter, x, y, funcType, false); - - //draw jump arrows - int jumpsize = paintJumpsGraphic(painter, x + funcsize, y - 1, wRVA); //jump line - - //draw bytes - QList richBytes; - RichTextPainter::CustomRichText_t space; - space.highlight = false; - space.flags = RichTextPainter::FlagNone; - space.text = " "; - RichTextPainter::CustomRichText_t curByte; - curByte.highlight = false; - curByte.flags = RichTextPainter::FlagColor; - for(int i = 0; i < mInstBuffer.at(rowOffset).dump.size(); i++) - { - if(i) - richBytes.push_back(space); - curByte.text = QString("%1").arg((unsigned char)(mInstBuffer.at(rowOffset).dump.at(i)), 2, 16, QChar('0')).toUpper(); - curByte.textColor = DbgFunctions()->PatchGet(cur_addr + i) ? mModifiedBytesColor : mBytesColor; - richBytes.push_back(curByte); - } - RichTextPainter::paintRichText(painter, x, y, getColumnWidth(col), getRowHeight(), jumpsize + funcsize, &richBytes, getCharWidth()); - } - break; - - case 2: //draw disassembly (with colours needed) - { - dsint cur_addr = rvaToVa(mInstBuffer.at(rowOffset).rva); - int loopsize = 0; - int depth = 0; - - while(1) //paint all loop depths - { - LOOPTYPE loopType = DbgGetLoopTypeAt(cur_addr, depth); - if(loopType == LOOP_NONE) - break; - Function_t funcType; - switch(loopType) - { - case LOOP_BEGIN: - funcType = Function_start; - break; - case LOOP_ENTRY: - funcType = Function_loop_entry; - break; - case LOOP_MIDDLE: - funcType = Function_middle; - break; - case LOOP_END: - funcType = Function_end; - break; - default: - break; - } - loopsize += paintFunctionGraphic(painter, x + loopsize, y, funcType, true); - depth++; - } - - QList richText; - - auto & token = mInstBuffer[rowOffset].tokens; - if(mHighlightToken.text.length()) - CapstoneTokenizer::TokenToRichText(token, richText, &mHighlightToken); - else - CapstoneTokenizer::TokenToRichText(token, richText, 0); - int xinc = 4; - RichTextPainter::paintRichText(painter, x + loopsize, y, getColumnWidth(col) - loopsize, getRowHeight(), xinc, &richText, getCharWidth()); - token.x = x + loopsize + xinc; - } - break; - - case 3: //draw comments - { - char comment[MAX_COMMENT_SIZE] = ""; - if(DbgGetCommentAt(rvaToVa(mInstBuffer.at(rowOffset).rva), comment)) - { - QString commentText; - QColor backgroundColor; - if(comment[0] == '\1') //automatic comment - { - painter->setPen(mAutoCommentColor); - backgroundColor = mAutoCommentBackgroundColor; - commentText = QString(comment + 1); - } - else //user comment - { - painter->setPen(mCommentColor); - backgroundColor = mCommentBackgroundColor; - commentText = comment; - } - - int width = getCharWidth() * commentText.length() + 4; - if(width > w) - width = w; - if(width) - painter->fillRect(QRect(x + 2, y, width, h), QBrush(backgroundColor)); //fill comment color - painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, commentText); - } - } - break; - } - return ""; -} - - -/************************************************************************************ - Mouse Management -************************************************************************************/ -/** - * @brief This method has been reimplemented. It manages the following actions: - * - Multi-rows selection - * - * @param[in] event Mouse event - * - * @return Nothing. - */ -void Disassembly::mouseMoveEvent(QMouseEvent* event) -{ - //qDebug() << "Disassembly::mouseMoveEvent"; - - bool wAccept = true; - - if(mGuiState == Disassembly::MultiRowsSelectionState) - { - //qDebug() << "State = MultiRowsSelectionState"; - - if((transY(event->y()) >= 0) && (transY(event->y()) <= this->getTableHeigth())) - { - int wI = getIndexOffsetFromY(transY(event->y())); - - if(mMemPage->getSize() > 0) - { - // Bound - wI = wI >= mInstBuffer.size() ? mInstBuffer.size() - 1 : wI; - wI = wI < 0 ? 0 : wI; - - dsint wRowIndex = mInstBuffer.at(wI).rva; - dsint wInstrSize = getInstructionRVA(wRowIndex, 1) - wRowIndex - 1; - - if(wRowIndex < getRowCount()) - { - setSingleSelection(getInitialSelection()); - expandSelectionUpTo(getInstructionRVA(getInitialSelection(), 1) - 1); - if(wRowIndex > getInitialSelection()) //select down - expandSelectionUpTo(wRowIndex + wInstrSize); - else - expandSelectionUpTo(wRowIndex); - - repaint(); - - wAccept = false; - } - } - } - } - - if(wAccept == true) - AbstractTableView::mouseMoveEvent(event); -} - - -/** - * @brief This method has been reimplemented. It manages the following actions: - * - Multi-rows selection - * - * @param[in] event Mouse event - * - * @return Nothing. - */ -void Disassembly::mousePressEvent(QMouseEvent* event) -{ - bool wAccept = false; - - if(DbgIsDebugging() && ((event->buttons() & Qt::LeftButton) != 0) && ((event->buttons() & Qt::RightButton) == 0)) - { - if(getGuiState() == AbstractTableView::NoState) - { - if(mHighlightingMode) - { - if(getColumnIndexFromX(event->x()) == 2) //click in instruction column - { - int rowOffset = getIndexOffsetFromY(transY(event->y())); - if(rowOffset < mInstBuffer.size()) - { - CapstoneTokenizer::SingleToken token; - if(CapstoneTokenizer::TokenFromX(mInstBuffer.at(rowOffset).tokens, token, event->x(), getCharWidth())) - { - if(CapstoneTokenizer::IsHighlightableToken(token) && !CapstoneTokenizer::TokenEquals(&token, &mHighlightToken)) - mHighlightToken = token; - else - { - mHighlightToken = CapstoneTokenizer::SingleToken(); - } - } - else - { - mHighlightToken = CapstoneTokenizer::SingleToken(); - } - } - } - else - { - mHighlightToken = CapstoneTokenizer::SingleToken(); - } - } - else if(event->y() > getHeaderHeight()) - { - dsint wRowIndex = getInstructionRVA(getTableOffset(), getIndexOffsetFromY(transY(event->y()))); - dsint wInstrSize = getInstructionRVA(wRowIndex, 1) - wRowIndex - 1; - - if(wRowIndex < getRowCount()) - { - if(!(event->modifiers() & Qt::ShiftModifier)) //SHIFT pressed - setSingleSelection(wRowIndex); - if(getSelectionStart() > wRowIndex) //select up - { - setSingleSelection(getInitialSelection()); - expandSelectionUpTo(getInstructionRVA(getInitialSelection(), 1) - 1); - expandSelectionUpTo(wRowIndex); - } - else //select down - { - setSingleSelection(getInitialSelection()); - expandSelectionUpTo(wRowIndex + wInstrSize); - } - - mGuiState = Disassembly::MultiRowsSelectionState; - - repaint(); - - wAccept = true; - } - } - } - } - - if(wAccept == false) - AbstractTableView::mousePressEvent(event); -} - - -/** - * @brief This method has been reimplemented. It manages the following actions: - * - Multi-rows selection - * - * @param[in] event Mouse event - * - * @return Nothing. - */ -void Disassembly::mouseReleaseEvent(QMouseEvent* event) -{ - bool wAccept = true; - - if((event->buttons() & Qt::LeftButton) == 0) - { - if(mGuiState == Disassembly::MultiRowsSelectionState) - { - mGuiState = Disassembly::NoState; - - repaint(); - - wAccept = false; - } - } - - if(wAccept == true) - AbstractTableView::mouseReleaseEvent(event); -} - - -/************************************************************************************ - Keyboard Management -************************************************************************************/ -/** - * @brief This method has been reimplemented. It processes the Up/Down key events. - * - * @param[in] event Key event - * - * @return Nothing. - */ -void Disassembly::keyPressEvent(QKeyEvent* event) -{ - int key = event->key(); - - if(key == Qt::Key_Up || key == Qt::Key_Down) - { - dsint botRVA = getTableOffset(); - dsint topRVA = getInstructionRVA(getTableOffset(), getNbrOfLineToPrint() - 1); - - bool expand = false; - if(event->modifiers() & Qt::ShiftModifier) //SHIFT pressed - expand = true; - - if(key == Qt::Key_Up) - selectPrevious(expand); - else - selectNext(expand); - - if(getSelectionStart() < botRVA) - { - setTableOffset(getSelectionStart()); - } - else if(getSelectionEnd() >= topRVA) - { - setTableOffset(getInstructionRVA(getSelectionEnd(), -getNbrOfLineToPrint() + 2)); - } - - repaint(); - } - else if(key == Qt::Key_Return || key == Qt::Key_Enter) - { - duint dest = DbgGetBranchDestination(rvaToVa(getInitialSelection())); - if(!dest) - return; - QString cmd = "disasm " + QString("%1").arg(dest, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - DbgCmdExec(cmd.toUtf8().constData()); - } - else - AbstractTableView::keyPressEvent(event); -} - -/************************************************************************************ - ScrollBar Management - ***********************************************************************************/ -/** - * @brief This method has been reimplemented. It realigns the slider on real instructions except - * when the type is QAbstractSlider::SliderNoAction. This type (QAbstractSlider::SliderNoAction) - * is used to force the disassembling at a specific RVA. - * - * @param[in] type Type of action - * @param[in] value Old table offset - * @param[in] delta Scrollbar value delta compared to the previous state - * - * @return Return the value of the new table offset. - */ -dsint Disassembly::sliderMovedHook(int type, dsint value, dsint delta) -{ - // QAbstractSlider::SliderNoAction is used to disassembe at a specific address - if(type == QAbstractSlider::SliderNoAction) - return value + delta; - - // If it's a slider action, disassemble one instruction back and one instruction next in order to be aligned on a real instruction - if(type == QAbstractSlider::SliderMove) - { - dsint wNewValue = 0; - - if(value + delta > 0) - { - wNewValue = getInstructionRVA(value + delta, -1); - wNewValue = getInstructionRVA(wNewValue, 1); - } - - return wNewValue; - } - - // For other actions, disassemble according to the delta - return getInstructionRVA(value, delta); -} - - -/************************************************************************************ - Jumps Graphic -************************************************************************************/ -/** - * @brief This method paints the graphic for jumps. - * - * @param[in] painter Pointer to the painter that allows painting by its own - * @param[in] x Rectangle x - * @param[in] y Rectangle y - * @param[in] addr RVA of address to process - * - * @return Nothing. - */ -int Disassembly::paintJumpsGraphic(QPainter* painter, int x, int y, dsint addr) -{ - dsint selHeadRVA = mSelection.fromIndex; - dsint rva = addr; - Instruction_t instruction = DisassembleAt(selHeadRVA); - auto branchType = instruction.branchType; - - GraphicDump_t wPict = GD_Nothing; - - if(branchType != Instruction_t::None) - { - dsint destRVA = instruction.branchDestination; - - dsint base = mMemPage->getBase(); - if(destRVA >= base && destRVA < base + (dsint)mMemPage->getSize()) - { - destRVA -= (dsint)mMemPage->getBase(); - - if(destRVA < selHeadRVA) - { - if(rva == destRVA) - wPict = GD_HeadFromBottom; - else if(rva > destRVA && rva < selHeadRVA) - wPict = GD_Vert; - else if(rva == selHeadRVA) - wPict = GD_FootToTop; - } - else if(destRVA > selHeadRVA) - { - if(rva == selHeadRVA) - wPict = GD_FootToBottom; - else if(rva > selHeadRVA && rva < destRVA) - wPict = GD_Vert; - else if(rva == destRVA) - wPict = GD_HeadFromTop; - } - } - } - - bool bIsExecute = DbgIsJumpGoingToExecute(rvaToVa(instruction.rva)); - - if(branchType == Instruction_t::Unconditional) //unconditional - { - painter->setPen(mUnconditionalJumpLineColor); - } - else - { - if(bIsExecute) - painter->setPen(mConditionalJumpLineTrueColor); - else - painter->setPen(mConditionalJumpLineFalseColor); - } - - if(wPict == GD_Vert) - { - painter->drawLine(x, y, x, y + getRowHeight()); - } - else if(wPict == GD_FootToBottom) - { - painter->drawLine(x, y + getRowHeight() / 2, x + 5, y + getRowHeight() / 2); - painter->drawLine(x, y + getRowHeight() / 2, x, y + getRowHeight()); - } - else if(wPict == GD_FootToTop) - { - painter->drawLine(x, y + getRowHeight() / 2, x + 5, y + getRowHeight() / 2); - painter->drawLine(x, y, x, y + getRowHeight() / 2); - } - else if(wPict == GD_HeadFromBottom) - { - QPoint wPoints[] = - { - QPoint(x + 3, y + getRowHeight() / 2 - 2), - QPoint(x + 5, y + getRowHeight() / 2), - QPoint(x + 3, y + getRowHeight() / 2 + 2), - }; - - painter->drawLine(x, y + getRowHeight() / 2, x + 5, y + getRowHeight() / 2); - painter->drawLine(x, y + getRowHeight() / 2, x, y + getRowHeight()); - painter->drawPolyline(wPoints, 3); - } - else if(wPict == GD_HeadFromTop) - { - QPoint wPoints[] = - { - QPoint(x + 3, y + getRowHeight() / 2 - 2), - QPoint(x + 5, y + getRowHeight() / 2), - QPoint(x + 3, y + getRowHeight() / 2 + 2), - }; - - painter->drawLine(x, y + getRowHeight() / 2, x + 5, y + getRowHeight() / 2); - painter->drawLine(x, y, x, y + getRowHeight() / 2); - painter->drawPolyline(wPoints, 3); - } - - return 7; -} - -/************************************************************************************ - Function Graphic -************************************************************************************/ -/** - * @brief This method paints the graphic for functions/loops. - * - * @param[in] painter Pointer to the painter that allows painting by its own - * @param[in] x Rectangle x - * @param[in] y Rectangle y - * @param[in] funcType Type of drawing to make - * - * @return Width of the painted data. - */ - -int Disassembly::paintFunctionGraphic(QPainter* painter, int x, int y, Function_t funcType, bool loop) -{ - if(loop && funcType == Function_none) - return 0; - if(loop) - painter->setPen(QPen(mLoopColor, 2)); //thick black line - else - painter->setPen(QPen(mFunctionColor, 2)); //thick black line - int height = getRowHeight(); - int x_add = 5; - int y_add = 4; - int end_add = 2; - int line_width = 3; - if(loop) - { - end_add = -1; - x_add = 4; - } - switch(funcType) - { - case Function_single: - { - if(loop) - y_add = height / 2 + 1; - painter->drawLine(x + x_add + line_width, y + y_add, x + x_add, y + y_add); - painter->drawLine(x + x_add, y + y_add, x + x_add, y + height - y_add - 1); - if(loop) - y_add = height / 2 - 1; - painter->drawLine(x + x_add, y + height - y_add, x + x_add + line_width, y + height - y_add); - } - break; - - case Function_start: - { - if(loop) - y_add = height / 2 + 1; - painter->drawLine(x + x_add + line_width, y + y_add, x + x_add, y + y_add); - painter->drawLine(x + x_add, y + y_add, x + x_add, y + height); - } - break; - - case Function_middle: - { - painter->drawLine(x + x_add, y, x + x_add, y + height); - } - break; - - case Function_loop_entry: - { - int trisize = 2; - int y_start = (height - trisize * 2) / 2 + y; - painter->drawLine(x + x_add, y_start, x + trisize + x_add, y_start + trisize); - painter->drawLine(x + trisize + x_add, y_start + trisize, x + x_add, y_start + trisize * 2); - - painter->drawLine(x + x_add, y, x + x_add, y_start - 1); - painter->drawLine(x + x_add, y_start + trisize * 2 + 2, x + x_add, y + height); - } - break; - - case Function_end: - { - if(loop) - y_add = height / 2 - 1; - painter->drawLine(x + x_add, y, x + x_add, y + height - y_add); - painter->drawLine(x + x_add, y + height - y_add, x + x_add + line_width, y + height - y_add); - } - break; - - case Function_none: - { - - } - break; - } - return x_add + line_width + end_add; -} - - -/************************************************************************************ - Instructions Management - ***********************************************************************************/ -/** - * @brief Returns the RVA of count-th instructions before the given instruction RVA. - * - * @param[in] rva Instruction RVA - * @param[in] count Instruction count - * - * @return RVA of count-th instructions before the given instruction RVA. - */ -dsint Disassembly::getPreviousInstructionRVA(dsint rva, duint count) -{ - QByteArray wBuffer; - dsint wBottomByteRealRVA; - dsint wVirtualRVA; - dsint wMaxByteCountToRead ; - - wBottomByteRealRVA = (dsint)rva - 16 * (count + 3); - wBottomByteRealRVA = wBottomByteRealRVA < 0 ? 0 : wBottomByteRealRVA; - - wVirtualRVA = (dsint)rva - wBottomByteRealRVA; - - wMaxByteCountToRead = wVirtualRVA + 1 + 16; - wBuffer.resize(wMaxByteCountToRead); - - mMemPage->read(reinterpret_cast(wBuffer.data()), wBottomByteRealRVA, wMaxByteCountToRead); - - dsint addr = mDisasm->DisassembleBack(reinterpret_cast(wBuffer.data()), 0, wMaxByteCountToRead, wVirtualRVA, count); - - addr += rva - wVirtualRVA; - - return addr; -} - - -/** - * @brief Returns the RVA of count-th instructions after the given instruction RVA. - * - * @param[in] rva Instruction RVA - * @param[in] count Instruction count - * - * @return RVA of count-th instructions after the given instruction RVA. - */ -dsint Disassembly::getNextInstructionRVA(dsint rva, duint count) -{ - QByteArray wBuffer; - dsint wVirtualRVA = 0; - dsint wRemainingBytes; - dsint wMaxByteCountToRead; - dsint wNewRVA; - - if(mMemPage->getSize() < (duint)rva) - return rva; - wRemainingBytes = mMemPage->getSize() - rva; - - wMaxByteCountToRead = 16 * (count + 1); - wMaxByteCountToRead = wRemainingBytes > wMaxByteCountToRead ? wMaxByteCountToRead : wRemainingBytes; - wBuffer.resize(wMaxByteCountToRead); - - mMemPage->read(reinterpret_cast(wBuffer.data()), rva, wMaxByteCountToRead); - - wNewRVA = mDisasm->DisassembleNext(reinterpret_cast(wBuffer.data()), 0, wMaxByteCountToRead, wVirtualRVA, count); - wNewRVA += rva; - - return wNewRVA; -} - - -/** - * @brief Returns the RVA of count-th instructions before/after (depending on the sign) the given instruction RVA. - * - * @param[in] rva Instruction RVA - * @param[in] count Instruction count - * - * @return RVA of count-th instructions before/after the given instruction RVA. - */ -dsint Disassembly::getInstructionRVA(dsint index, dsint count) -{ - dsint wAddr = 0; - - if(count == 0) - wAddr = index; - if(count < 0) - wAddr = getPreviousInstructionRVA(index, qAbs(count)); - else if(count > 0) - wAddr = getNextInstructionRVA(index, qAbs(count)); - - - if(wAddr < 0) - wAddr = 0; - else if(wAddr > getRowCount() - 1) - wAddr = getRowCount() - 1; - - return wAddr; -} - - -/** - * @brief Disassembles the instruction at the given RVA. - * - * @param[in] rva RVA of instruction to disassemble - * - * @return Return the disassembled instruction. - */ -Instruction_t Disassembly::DisassembleAt(dsint rva) -{ - QByteArray wBuffer; - dsint base = mMemPage->getBase(); - dsint wMaxByteCountToRead = 16 * 2; - - // Bounding - //TODO: fix problems with negative sizes - dsint size = getSize(); - if(!size) - size = rva; - - wMaxByteCountToRead = wMaxByteCountToRead > (size - rva) ? (size - rva) : wMaxByteCountToRead; - - wBuffer.resize(wMaxByteCountToRead); - - mMemPage->read(reinterpret_cast(wBuffer.data()), rva, wMaxByteCountToRead); - - return mDisasm->DisassembleAt(reinterpret_cast(wBuffer.data()), wMaxByteCountToRead, 0, base, rva); -} - - -/** - * @brief Disassembles the instruction count instruction afterc the instruction at the given RVA. - * Count can be positive or negative. - * - * @param[in] rva RVA of reference instruction - * @param[in] count Number of instruction - * - * @return Return the disassembled instruction. - */ -Instruction_t Disassembly::DisassembleAt(dsint rva, dsint count) -{ - rva = getNextInstructionRVA(rva, count); - return DisassembleAt(rva); -} - - -/************************************************************************************ - Selection Management -************************************************************************************/ -void Disassembly::expandSelectionUpTo(dsint to) -{ - if(to < mSelection.firstSelectedIndex) - { - mSelection.fromIndex = to; - } - else if(to > mSelection.firstSelectedIndex) - { - mSelection.toIndex = to; - } - else if(to == mSelection.firstSelectedIndex) - { - setSingleSelection(to); - } -} - -void Disassembly::setSingleSelection(dsint index) -{ - mSelection.firstSelectedIndex = index; - mSelection.fromIndex = index; - mSelection.toIndex = index; - emit selectionChanged(rvaToVa(index)); -} - - -dsint Disassembly::getInitialSelection() -{ - return mSelection.firstSelectedIndex; -} - -dsint Disassembly::getSelectionSize() -{ - return mSelection.toIndex - mSelection.fromIndex; -} - -dsint Disassembly::getSelectionStart() -{ - return mSelection.fromIndex; -} - -dsint Disassembly::getSelectionEnd() -{ - return mSelection.toIndex; -} - -void Disassembly::selectNext(bool expand) -{ - dsint wAddr; - dsint wStart = getInstructionRVA(getSelectionStart(), 1) - 1; - if(expand) - { - if(getSelectionEnd() == getInitialSelection() && wStart != getSelectionEnd()) //decrease down - { - wAddr = getInstructionRVA(getSelectionStart(), 1); - expandSelectionUpTo(wAddr); - } - else //expand down - { - wAddr = getSelectionEnd() + 1; - dsint wInstrSize = getInstructionRVA(wAddr, 1) - wAddr - 1; - expandSelectionUpTo(wAddr + wInstrSize); - } - } - else //select next instruction - { - wAddr = getSelectionEnd() + 1; - setSingleSelection(wAddr); - dsint wInstrSize = getInstructionRVA(wAddr, 1) - wAddr - 1; - expandSelectionUpTo(wAddr + wInstrSize); - } -} - - -void Disassembly::selectPrevious(bool expand) -{ - dsint wAddr; - dsint wStart = getInstructionRVA(getSelectionStart(), 1) - 1; - if(expand) - { - if(getSelectionStart() == getInitialSelection() && wStart != getSelectionEnd()) //decrease up - { - wAddr = getInstructionRVA(getSelectionEnd() + 1, -2); - dsint wInstrSize = getInstructionRVA(wAddr, 1) - wAddr - 1; - expandSelectionUpTo(wAddr + wInstrSize); - } - else //expand up - { - wAddr = getInstructionRVA(wStart + 1, -2); - expandSelectionUpTo(wAddr); - } - } - else - { - wAddr = getInstructionRVA(getSelectionStart(), -1); - setSingleSelection(wAddr); - dsint wInstrSize = getInstructionRVA(wAddr, 1) - wAddr - 1; - expandSelectionUpTo(wAddr + wInstrSize); - } -} - - -bool Disassembly::isSelected(dsint base, dsint offset) -{ - dsint wAddr = base; - - if(offset < 0) - wAddr = getPreviousInstructionRVA(getTableOffset(), offset); - else if(offset > 0) - wAddr = getNextInstructionRVA(getTableOffset(), offset); - - if(wAddr >= mSelection.fromIndex && wAddr <= mSelection.toIndex) - return true; - else - return false; -} - - -bool Disassembly::isSelected(QList* buffer, int index) -{ - if(buffer->size() > 0 && index >= 0 && index < buffer->size()) - { - if((dsint)buffer->at(index).rva >= mSelection.fromIndex && (dsint)buffer->at(index).rva <= mSelection.toIndex) - return true; - else - return false; - } - else - { - return false; - } -} - -duint Disassembly::getSelectedVa() -{ - // Wrapper around commonly used code: - // Converts the selected index to a valid virtual address - return rvaToVa(getInitialSelection()); -} - -/************************************************************************************ - Update/Reload/Refresh/Repaint -************************************************************************************/ - -void Disassembly::prepareDataCount(dsint wRVA, int wCount, QList* instBuffer) -{ - instBuffer->clear(); - Instruction_t wInst; - for(int wI = 0; wI < wCount; wI++) - { - wInst = DisassembleAt(wRVA); - instBuffer->append(wInst); - wRVA += wInst.length; - } -} - -void Disassembly::prepareDataRange(dsint startRva, dsint endRva, QList* instBuffer) -{ - if(startRva == endRva) - prepareDataCount(startRva, 1, instBuffer); - else - { - int wCount = 0; - dsint addr = startRva; - while(addr <= endRva) - { - addr = getNextInstructionRVA(addr, 1); - wCount++; - } - prepareDataCount(startRva, wCount, instBuffer); - } -} - -void Disassembly::prepareData() -{ - dsint wViewableRowsCount = getViewableRowsCount(); - - dsint wAddrPrev = getTableOffset(); - dsint wAddr = wAddrPrev; - - int wCount = 0; - - for(int wI = 0; wI < wViewableRowsCount && getRowCount() > 0; wI++) - { - wAddrPrev = wAddr; - wAddr = getNextInstructionRVA(wAddr, 1); - - if(wAddr == wAddrPrev) - { - break; - } - - wCount++; - } - - setNbrOfLineToPrint(wCount); - - prepareDataCount(getTableOffset(), wCount, &mInstBuffer); -} - -void Disassembly::reloadData() -{ - emit selectionChanged(rvaToVa(mSelection.firstSelectedIndex)); - AbstractTableView::reloadData(); -} - - -/************************************************************************************ - Public Methods -************************************************************************************/ -duint Disassembly::rvaToVa(dsint rva) -{ - return mMemPage->va(rva); -} - -void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint newTableOffset) -{ - dsint wBase = DbgMemFindBaseAddr(parVA, 0); - dsint wSize = DbgMemGetPageSize(wBase); - if(!wBase || !wSize) - return; - dsint wRVA = parVA - wBase; - dsint wCipRva = parCIP - wBase; - - HistoryData_t newHistory; - - //VA history - if(history) - { - //truncate everything right from the current VA - if(mVaHistory.size() && mCurrentVa < mVaHistory.size() - 1) //mCurrentVa is not the last - mVaHistory.erase(mVaHistory.begin() + mCurrentVa + 1, mVaHistory.end()); - - //NOTE: mCurrentVa always points to the last entry of the list - - //add the currently selected address to the history - dsint selectionVA = rvaToVa(getInitialSelection()); //currently selected VA - dsint selectionTableOffset = getTableOffset(); - if(selectionVA && mVaHistory.size() && mVaHistory.last().va != selectionVA) //do not have 2x the same va in a row - { - if(mVaHistory.size() >= 1024) //max 1024 in the history - { - mCurrentVa--; - mVaHistory.erase(mVaHistory.begin()); //remove the oldest element - } - mCurrentVa++; - newHistory.va = selectionVA; - newHistory.tableOffset = selectionTableOffset; - mVaHistory.push_back(newHistory); - } - } - - // Set base and size (Useful when memory page changed) - mMemPage->setAttributes(wBase, wSize); - - if(mRvaDisplayEnabled && mMemPage->getBase() != mRvaDisplayPageBase) - mRvaDisplayEnabled = false; - - setRowCount(wSize); - - setSingleSelection(wRVA); // Selects disassembled instruction - dsint wInstrSize = getInstructionRVA(wRVA, 1) - wRVA - 1; - expandSelectionUpTo(wRVA + wInstrSize); - - //set CIP rva - mCipRva = wCipRva; - - if(newTableOffset == -1) //nothing specified - { - // Update table offset depending on the location of the instruction to disassemble - if(mInstBuffer.size() > 0 && wRVA >= (dsint)mInstBuffer.first().rva && wRVA < (dsint)mInstBuffer.last().rva) - { - int wI; - bool wIsAligned = false; - - // Check if the new RVA is aligned on an instruction from the cache (buffer) - for(wI = 0; wI < mInstBuffer.size(); wI++) - { - if(mInstBuffer.at(wI).rva == wRVA) - { - wIsAligned = true; - break; - } - } - - if(wIsAligned == true) - { - repaint(); - } - else - { - setTableOffset(wRVA); - } - } - else if(mInstBuffer.size() > 0 && wRVA == (dsint)mInstBuffer.last().rva) - { - setTableOffset(mInstBuffer.first().rva + mInstBuffer.first().length); - } - else - { - setTableOffset(wRVA); - } - - if(history) - { - //new disassembled address - newHistory.va = parVA; - newHistory.tableOffset = getTableOffset(); - if(mVaHistory.size()) - { - if(mVaHistory.last().va != parVA) //not 2x the same va in history - { - if(mVaHistory.size() >= 1024) //max 1024 in the history - { - mCurrentVa--; - mVaHistory.erase(mVaHistory.begin()); //remove the oldest element - } - mCurrentVa++; - mVaHistory.push_back(newHistory); //add a va to the history - } - } - else //the list is empty - mVaHistory.push_back(newHistory); - } - } - else //specified new table offset - setTableOffset(newTableOffset); - - /* - //print history - if(history) - { - QString strList = ""; - for(int i=0; i* Disassembly::instructionsBuffer() -{ - return &mInstBuffer; -} - -const dsint Disassembly::currentEIP() const -{ - return mCipRva; -} - - -void Disassembly::disassembleAt(dsint parVA, dsint parCIP) -{ - disassembleAt(parVA, parCIP, true, -1); -} - - -void Disassembly::disassembleClear() -{ - mHighlightingMode = false; - mHighlightToken = CapstoneTokenizer::SingleToken(); - historyClear(); - mMemPage->setAttributes(0, 0); - setRowCount(0); - reloadData(); -} - - -void Disassembly::debugStateChangedSlot(DBGSTATE state) -{ - switch(state) - { - case stopped: - disassembleClear(); - break; - case paused: - mIsRunning = false; - break; - case running: - mIsRunning = true; - break; - default: - break; - } -} - -const dsint Disassembly::getBase() const -{ - return mMemPage->getBase(); -} - -dsint Disassembly::getSize() -{ - return mMemPage->getSize(); -} - -duint Disassembly::getTableOffsetRva() -{ - return mInstBuffer.size() ? mInstBuffer.at(0).rva : 0; - -} - -void Disassembly::historyClear() -{ - mVaHistory.clear(); //clear history for new targets - mCurrentVa = 0; -} - -void Disassembly::historyPrevious() -{ - if(!mCurrentVa || !mVaHistory.size()) //we are at the earliest history entry - return; - mCurrentVa--; - disassembleAt(mVaHistory.at(mCurrentVa).va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset); -} - -void Disassembly::historyNext() -{ - int size = mVaHistory.size(); - if(!size || mCurrentVa >= mVaHistory.size() - 1) //we are at the newest history entry - return; - mCurrentVa++; - disassembleAt(mVaHistory.at(mCurrentVa).va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset); -} - -bool Disassembly::historyHasPrevious() -{ - if(!mCurrentVa || !mVaHistory.size()) //we are at the earliest history entry - return false; - return true; -} - -bool Disassembly::historyHasNext() -{ - int size = mVaHistory.size(); - if(!size || mCurrentVa >= mVaHistory.size() - 1) //we are at the newest history entry - return false; - return true; -} - -QString Disassembly::getAddrText(dsint cur_addr, char label[MAX_LABEL_SIZE]) -{ - QString addrText = ""; - if(mRvaDisplayEnabled) //RVA display - { - dsint rva = cur_addr - mRvaDisplayBase; - if(rva == 0) - { -#ifdef _WIN64 - addrText = "$ ==> "; -#else - addrText = "$ ==> "; -#endif //_WIN64 - } - else if(rva > 0) - { -#ifdef _WIN64 - addrText = "$+" + QString("%1").arg(rva, -15, 16, QChar(' ')).toUpper(); -#else - addrText = "$+" + QString("%1").arg(rva, -7, 16, QChar(' ')).toUpper(); -#endif //_WIN64 - } - else if(rva < 0) - { -#ifdef _WIN64 - addrText = "$-" + QString("%1").arg(-rva, -15, 16, QChar(' ')).toUpper(); -#else - addrText = "$-" + QString("%1").arg(-rva, -7, 16, QChar(' ')).toUpper(); -#endif //_WIN64 - } - } - addrText += ToPtrString(cur_addr); - char label_[MAX_LABEL_SIZE] = ""; - if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label_)) //has label - { - char module[MAX_MODULE_SIZE] = ""; - if(DbgGetModuleAt(cur_addr, module) && !QString(label_).startsWith("JMP.&")) - addrText += " <" + QString(module) + "." + QString(label_) + ">"; - else - addrText += " <" + QString(label_) + ">"; - } - else - *label_ = 0; - if(label) - strcpy_s(label, MAX_LABEL_SIZE, label_); - return addrText; -} +#include "Disassembly.h" +#include "Configuration.h" +#include "Bridge.h" + +Disassembly::Disassembly(QWidget* parent) : AbstractTableView(parent) +{ + mMemPage = new MemoryPage(0, 0); + + mInstBuffer.clear(); + + historyClear(); + + SelectionData_t data; + memset(&data, 0, sizeof(SelectionData_t)); + mSelection = data; + + mCipRva = 0; + mIsRunning = false; + + mHighlightToken.text = ""; + mHighlightingMode = false; + + int maxModuleSize = (int)ConfigUint("Disassembler", "MaxModuleSize"); + Config()->writeUints(); + + mDisasm = new QBeaEngine(maxModuleSize); + mDisasm->UpdateConfig(); + + mIsLastInstDisplayed = false; + + mGuiState = Disassembly::NoState; + + // Update fonts immediately because they are used in calculations + updateFonts(); + + setRowCount(mMemPage->getSize()); + + addColumnAt(getCharWidth() * 2 * sizeof(dsint) + 8, "", false); //address + addColumnAt(getCharWidth() * 2 * 12 + 8, "", false); //bytes + addColumnAt(getCharWidth() * 40, "", false); //disassembly + addColumnAt(1000, "", false); //comments + + setShowHeader(false); //hide header + + backgroundColor = ConfigColor("DisassemblyBackgroundColor"); + + // Slots + connect(Bridge::getBridge(), SIGNAL(repaintGui()), this, SLOT(reloadData())); + connect(Bridge::getBridge(), SIGNAL(updateDump()), this, SLOT(reloadData())); + connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE))); + + Initialize(); +} + +void Disassembly::updateColors() +{ + AbstractTableView::updateColors(); + backgroundColor = ConfigColor("DisassemblyBackgroundColor"); + + mInstructionHighlightColor = ConfigColor("InstructionHighlightColor"); + mSelectionColor = ConfigColor("DisassemblySelectionColor"); + mCipBackgroundColor = ConfigColor("DisassemblyCipBackgroundColor"); + mCipColor = ConfigColor("DisassemblyCipColor"); + mBreakpointBackgroundColor = ConfigColor("DisassemblyBreakpointBackgroundColor"); + mBreakpointColor = ConfigColor("DisassemblyBreakpointColor"); + mHardwareBreakpointBackgroundColor = ConfigColor("DisassemblyHardwareBreakpointBackgroundColor"); + mHardwareBreakpointColor = ConfigColor("DisassemblyHardwareBreakpointColor"); + mBookmarkBackgroundColor = ConfigColor("DisassemblyBookmarkBackgroundColor"); + mBookmarkColor = ConfigColor("DisassemblyBookmarkColor"); + mLabelColor = ConfigColor("DisassemblyLabelColor"); + mLabelBackgroundColor = ConfigColor("DisassemblyLabelBackgroundColor"); + mSelectedAddressBackgroundColor = ConfigColor("DisassemblySelectedAddressBackgroundColor"); + mSelectedAddressColor = ConfigColor("DisassemblySelectedAddressColor"); + mAddressBackgroundColor = ConfigColor("DisassemblyAddressBackgroundColor"); + mAddressColor = ConfigColor("DisassemblyAddressColor"); + mBytesColor = ConfigColor("DisassemblyBytesColor"); + mModifiedBytesColor = ConfigColor("DisassemblyModifiedBytesColor"); + mAutoCommentColor = ConfigColor("DisassemblyAutoCommentColor"); + mAutoCommentBackgroundColor = ConfigColor("DisassemblyAutoCommentBackgroundColor"); + mCommentColor = ConfigColor("DisassemblyCommentColor"); + mCommentBackgroundColor = ConfigColor("DisassemblyCommentBackgroundColor"); + mUnconditionalJumpLineColor = ConfigColor("DisassemblyUnconditionalJumpLineColor"); + mConditionalJumpLineTrueColor = ConfigColor("DisassemblyConditionalJumpLineTrueColor"); + mConditionalJumpLineFalseColor = ConfigColor("DisassemblyConditionalJumpLineFalseColor"); + mLoopColor = ConfigColor("DisassemblyLoopColor"); + mFunctionColor = ConfigColor("DisassemblyFunctionColor"); + + CapstoneTokenizer::UpdateColors(); + mDisasm->UpdateConfig(); +} + +void Disassembly::updateFonts() +{ + setFont(ConfigFont("Disassembly")); +} + +/************************************************************************************ + Reimplemented Functions +************************************************************************************/ +/** + * @brief This method has been reimplemented. It returns the string to paint or paints it + * by its own. + * + * @param[in] painter Pointer to the painter that allows painting by its own + * @param[in] rowBase Index of the top item (Table offset) + * @param[in] rowOffset Index offset starting from rowBase + * @param[in] col Column index + * @param[in] x Rectangle x + * @param[in] y Rectangle y + * @param[in] w Rectangle width + * @param[in] h Rectangle heigth + * + * @return String to paint. + */ +QString Disassembly::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) +{ + Q_UNUSED(rowBase); + + if(mHighlightingMode) + { + QPen pen(mInstructionHighlightColor); + pen.setWidth(2); + painter->setPen(pen); + QRect rect = viewport()->rect(); + rect.adjust(1, 1, -1, -1); + painter->drawRect(rect); + } + dsint wRVA = mInstBuffer.at(rowOffset).rva; + bool wIsSelected = isSelected(&mInstBuffer, rowOffset); + + // Highlight if selected + if(wIsSelected) + painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor)); + + switch(col) + { + case 0: // Draw address (+ label) + { + char label[MAX_LABEL_SIZE] = ""; + dsint cur_addr = rvaToVa(mInstBuffer.at(rowOffset).rva); + QString addrText = getAddrText(cur_addr, label); + BPXTYPE bpxtype = DbgGetBpxTypeAt(cur_addr); + bool isbookmark = DbgGetBookmarkAt(cur_addr); + if(mInstBuffer.at(rowOffset).rva == mCipRva && !mIsRunning) //cip + not running + { + painter->fillRect(QRect(x, y, w, h), QBrush(mCipBackgroundColor)); + if(!isbookmark) //no bookmark + { + if(bpxtype & bp_normal) //normal breakpoint + { + QColor& bpColor = mBreakpointBackgroundColor; + if(!bpColor.alpha()) //we don't want transparent text + bpColor = mBreakpointColor; + if(bpColor == mCipBackgroundColor) + bpColor = mCipColor; + painter->setPen(bpColor); + } + else if(bpxtype & bp_hardware) //hardware breakpoint only + { + QColor hwbpColor = mHardwareBreakpointBackgroundColor; + if(!hwbpColor.alpha()) //we don't want transparent text + hwbpColor = mHardwareBreakpointColor; + if(hwbpColor == mCipBackgroundColor) + hwbpColor = mCipColor; + painter->setPen(hwbpColor); + } + else //no breakpoint + { + painter->setPen(mCipColor); + } + } + else //bookmark + { + QColor bookmarkColor = mBookmarkBackgroundColor; + if(!bookmarkColor.alpha()) //we don't want transparent text + bookmarkColor = mBookmarkColor; + if(bookmarkColor == mCipBackgroundColor) + bookmarkColor = mCipColor; + painter->setPen(bookmarkColor); + } + } + else //non-cip address + { + if(!isbookmark) //no bookmark + { + if(*label) //label + { + if(bpxtype == bp_none) //label only + { + painter->setPen(mLabelColor); //red -> address + label text + painter->fillRect(QRect(x, y, w, h), QBrush(mLabelBackgroundColor)); //fill label background + } + else //label+breakpoint + { + if(bpxtype & bp_normal) //label + normal breakpoint + { + painter->setPen(mBreakpointColor); + painter->fillRect(QRect(x, y, w, h), QBrush(mBreakpointBackgroundColor)); //fill red + } + else if(bpxtype & bp_hardware) //label + hardware breakpoint only + { + painter->setPen(mHardwareBreakpointColor); + painter->fillRect(QRect(x, y, w, h), QBrush(mHardwareBreakpointBackgroundColor)); //fill ? + } + else //other cases -> do as normal + { + painter->setPen(mLabelColor); //red -> address + label text + painter->fillRect(QRect(x, y, w, h), QBrush(mLabelBackgroundColor)); //fill label background + } + } + } + else //no label + { + if(bpxtype == bp_none) //no label, no breakpoint + { + QColor background; + if(wIsSelected) + { + background = mSelectedAddressBackgroundColor; + painter->setPen(mSelectedAddressColor); //black address (DisassemblySelectedAddressColor) + } + else + { + background = mAddressBackgroundColor; + painter->setPen(mAddressColor); //DisassemblyAddressColor + } + if(background.alpha()) + painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background + } + else //breakpoint only + { + if(bpxtype & bp_normal) //normal breakpoint + { + painter->setPen(mBreakpointColor); + painter->fillRect(QRect(x, y, w, h), QBrush(mBreakpointBackgroundColor)); //fill red + } + else if(bpxtype & bp_hardware) //hardware breakpoint only + { + painter->setPen(mHardwareBreakpointColor); + painter->fillRect(QRect(x, y, w, h), QBrush(mHardwareBreakpointBackgroundColor)); //fill red + } + else //other cases (memory breakpoint in disassembly) -> do as normal + { + QColor background; + if(wIsSelected) + { + background = mSelectedAddressBackgroundColor; + painter->setPen(mSelectedAddressColor); //black address (DisassemblySelectedAddressColor) + } + else + { + background = mAddressBackgroundColor; + painter->setPen(mAddressColor); + } + if(background.alpha()) + painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background + } + } + } + } + else //bookmark + { + if(*label) //label + bookmark + { + if(bpxtype == bp_none) //label + bookmark + { + painter->setPen(mLabelColor); //red -> address + label text + painter->fillRect(QRect(x, y, w, h), QBrush(mBookmarkBackgroundColor)); //fill label background + } + else //label+breakpoint+bookmark + { + QColor color = mBookmarkBackgroundColor; + if(!color.alpha()) //we don't want transparent text + color = mAddressColor; + painter->setPen(color); + if(bpxtype & bp_normal) //label + bookmark + normal breakpoint + { + painter->fillRect(QRect(x, y, w, h), QBrush(mBreakpointBackgroundColor)); //fill red + } + else if(bpxtype & bp_hardware) //label + bookmark + hardware breakpoint only + { + painter->fillRect(QRect(x, y, w, h), QBrush(mHardwareBreakpointBackgroundColor)); //fill ? + } + } + } + else //bookmark, no label + { + if(bpxtype == bp_none) //bookmark only + { + painter->setPen(mBookmarkColor); //black address + painter->fillRect(QRect(x, y, w, h), QBrush(mBookmarkBackgroundColor)); //fill bookmark color + } + else //bookmark + breakpoint + { + QColor color = mBookmarkBackgroundColor; + if(!color.alpha()) //we don't want transparent text + color = mAddressColor; + painter->setPen(color); + if(bpxtype & bp_normal) //bookmark + normal breakpoint + { + painter->fillRect(QRect(x, y, w, h), QBrush(mBreakpointBackgroundColor)); //fill red + } + else if(bpxtype & bp_hardware) //bookmark + hardware breakpoint only + { + painter->fillRect(QRect(x, y, w, h), QBrush(mHardwareBreakpointBackgroundColor)); //fill red + } + else //other cases (bookmark + memory breakpoint in disassembly) -> do as normal + { + painter->setPen(mBookmarkColor); //black address + painter->fillRect(QRect(x, y, w, h), QBrush(mBookmarkBackgroundColor)); //fill bookmark color + } + } + } + } + } + painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, addrText); + } + break; + + case 1: //draw bytes (TODO: some spaces between bytes) + { + //draw functions + dsint cur_addr = rvaToVa(mInstBuffer.at(rowOffset).rva); + Function_t funcType; + FUNCTYPE funcFirst = DbgGetFunctionTypeAt(cur_addr); + FUNCTYPE funcLast = DbgGetFunctionTypeAt(cur_addr + mInstBuffer.at(rowOffset).length - 1); + if(funcLast == FUNC_END) + funcFirst = funcLast; + switch(funcFirst) + { + case FUNC_SINGLE: + funcType = Function_single; + break; + case FUNC_NONE: + funcType = Function_none; + break; + case FUNC_BEGIN: + funcType = Function_start; + break; + case FUNC_MIDDLE: + funcType = Function_middle; + break; + case FUNC_END: + funcType = Function_end; + break; + } + int funcsize = paintFunctionGraphic(painter, x, y, funcType, false); + + //draw jump arrows + int jumpsize = paintJumpsGraphic(painter, x + funcsize, y - 1, wRVA); //jump line + + //draw bytes + QList richBytes; + RichTextPainter::CustomRichText_t space; + space.highlight = false; + space.flags = RichTextPainter::FlagNone; + space.text = " "; + RichTextPainter::CustomRichText_t curByte; + curByte.highlight = false; + curByte.flags = RichTextPainter::FlagColor; + for(int i = 0; i < mInstBuffer.at(rowOffset).dump.size(); i++) + { + if(i) + richBytes.push_back(space); + curByte.text = QString("%1").arg((unsigned char)(mInstBuffer.at(rowOffset).dump.at(i)), 2, 16, QChar('0')).toUpper(); + curByte.textColor = DbgFunctions()->PatchGet(cur_addr + i) ? mModifiedBytesColor : mBytesColor; + richBytes.push_back(curByte); + } + RichTextPainter::paintRichText(painter, x, y, getColumnWidth(col), getRowHeight(), jumpsize + funcsize, &richBytes, getCharWidth()); + } + break; + + case 2: //draw disassembly (with colours needed) + { + dsint cur_addr = rvaToVa(mInstBuffer.at(rowOffset).rva); + int loopsize = 0; + int depth = 0; + + while(1) //paint all loop depths + { + LOOPTYPE loopType = DbgGetLoopTypeAt(cur_addr, depth); + if(loopType == LOOP_NONE) + break; + Function_t funcType; + switch(loopType) + { + case LOOP_BEGIN: + funcType = Function_start; + break; + case LOOP_ENTRY: + funcType = Function_loop_entry; + break; + case LOOP_MIDDLE: + funcType = Function_middle; + break; + case LOOP_END: + funcType = Function_end; + break; + default: + break; + } + loopsize += paintFunctionGraphic(painter, x + loopsize, y, funcType, true); + depth++; + } + + QList richText; + + auto & token = mInstBuffer[rowOffset].tokens; + if(mHighlightToken.text.length()) + CapstoneTokenizer::TokenToRichText(token, richText, &mHighlightToken); + else + CapstoneTokenizer::TokenToRichText(token, richText, 0); + int xinc = 4; + RichTextPainter::paintRichText(painter, x + loopsize, y, getColumnWidth(col) - loopsize, getRowHeight(), xinc, &richText, getCharWidth()); + token.x = x + loopsize + xinc; + } + break; + + case 3: //draw comments + { + char comment[MAX_COMMENT_SIZE] = ""; + if(DbgGetCommentAt(rvaToVa(mInstBuffer.at(rowOffset).rva), comment)) + { + QString commentText; + QColor backgroundColor; + if(comment[0] == '\1') //automatic comment + { + painter->setPen(mAutoCommentColor); + backgroundColor = mAutoCommentBackgroundColor; + commentText = QString(comment + 1); + } + else //user comment + { + painter->setPen(mCommentColor); + backgroundColor = mCommentBackgroundColor; + commentText = comment; + } + + int width = getCharWidth() * commentText.length() + 4; + if(width > w) + width = w; + if(width) + painter->fillRect(QRect(x + 2, y, width, h), QBrush(backgroundColor)); //fill comment color + painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, commentText); + } + } + break; + } + return ""; +} + + +/************************************************************************************ + Mouse Management +************************************************************************************/ +/** + * @brief This method has been reimplemented. It manages the following actions: + * - Multi-rows selection + * + * @param[in] event Mouse event + * + * @return Nothing. + */ +void Disassembly::mouseMoveEvent(QMouseEvent* event) +{ + //qDebug() << "Disassembly::mouseMoveEvent"; + + bool wAccept = true; + + if(mGuiState == Disassembly::MultiRowsSelectionState) + { + //qDebug() << "State = MultiRowsSelectionState"; + + if((transY(event->y()) >= 0) && (transY(event->y()) <= this->getTableHeigth())) + { + int wI = getIndexOffsetFromY(transY(event->y())); + + if(mMemPage->getSize() > 0) + { + // Bound + wI = wI >= mInstBuffer.size() ? mInstBuffer.size() - 1 : wI; + wI = wI < 0 ? 0 : wI; + + dsint wRowIndex = mInstBuffer.at(wI).rva; + dsint wInstrSize = getInstructionRVA(wRowIndex, 1) - wRowIndex - 1; + + if(wRowIndex < getRowCount()) + { + setSingleSelection(getInitialSelection()); + expandSelectionUpTo(getInstructionRVA(getInitialSelection(), 1) - 1); + if(wRowIndex > getInitialSelection()) //select down + expandSelectionUpTo(wRowIndex + wInstrSize); + else + expandSelectionUpTo(wRowIndex); + + repaint(); + + wAccept = false; + } + } + } + } + + if(wAccept == true) + AbstractTableView::mouseMoveEvent(event); +} + + +/** + * @brief This method has been reimplemented. It manages the following actions: + * - Multi-rows selection + * + * @param[in] event Mouse event + * + * @return Nothing. + */ +void Disassembly::mousePressEvent(QMouseEvent* event) +{ + bool wAccept = false; + + if(DbgIsDebugging() && ((event->buttons() & Qt::LeftButton) != 0) && ((event->buttons() & Qt::RightButton) == 0)) + { + if(getGuiState() == AbstractTableView::NoState) + { + if(mHighlightingMode) + { + if(getColumnIndexFromX(event->x()) == 2) //click in instruction column + { + int rowOffset = getIndexOffsetFromY(transY(event->y())); + if(rowOffset < mInstBuffer.size()) + { + CapstoneTokenizer::SingleToken token; + if(CapstoneTokenizer::TokenFromX(mInstBuffer.at(rowOffset).tokens, token, event->x(), getCharWidth())) + { + if(CapstoneTokenizer::IsHighlightableToken(token) && !CapstoneTokenizer::TokenEquals(&token, &mHighlightToken)) + mHighlightToken = token; + else + { + mHighlightToken = CapstoneTokenizer::SingleToken(); + } + } + else + { + mHighlightToken = CapstoneTokenizer::SingleToken(); + } + } + } + else + { + mHighlightToken = CapstoneTokenizer::SingleToken(); + } + } + else if(event->y() > getHeaderHeight()) + { + dsint wRowIndex = getInstructionRVA(getTableOffset(), getIndexOffsetFromY(transY(event->y()))); + dsint wInstrSize = getInstructionRVA(wRowIndex, 1) - wRowIndex - 1; + + if(wRowIndex < getRowCount()) + { + if(!(event->modifiers() & Qt::ShiftModifier)) //SHIFT pressed + setSingleSelection(wRowIndex); + if(getSelectionStart() > wRowIndex) //select up + { + setSingleSelection(getInitialSelection()); + expandSelectionUpTo(getInstructionRVA(getInitialSelection(), 1) - 1); + expandSelectionUpTo(wRowIndex); + } + else //select down + { + setSingleSelection(getInitialSelection()); + expandSelectionUpTo(wRowIndex + wInstrSize); + } + + mGuiState = Disassembly::MultiRowsSelectionState; + + repaint(); + + wAccept = true; + } + } + } + } + + if(wAccept == false) + AbstractTableView::mousePressEvent(event); +} + + +/** + * @brief This method has been reimplemented. It manages the following actions: + * - Multi-rows selection + * + * @param[in] event Mouse event + * + * @return Nothing. + */ +void Disassembly::mouseReleaseEvent(QMouseEvent* event) +{ + bool wAccept = true; + + if((event->buttons() & Qt::LeftButton) == 0) + { + if(mGuiState == Disassembly::MultiRowsSelectionState) + { + mGuiState = Disassembly::NoState; + + repaint(); + + wAccept = false; + } + } + + if(wAccept == true) + AbstractTableView::mouseReleaseEvent(event); +} + + +/************************************************************************************ + Keyboard Management +************************************************************************************/ +/** + * @brief This method has been reimplemented. It processes the Up/Down key events. + * + * @param[in] event Key event + * + * @return Nothing. + */ +void Disassembly::keyPressEvent(QKeyEvent* event) +{ + int key = event->key(); + + if(key == Qt::Key_Up || key == Qt::Key_Down) + { + dsint botRVA = getTableOffset(); + dsint topRVA = getInstructionRVA(getTableOffset(), getNbrOfLineToPrint() - 1); + + bool expand = false; + if(event->modifiers() & Qt::ShiftModifier) //SHIFT pressed + expand = true; + + if(key == Qt::Key_Up) + selectPrevious(expand); + else + selectNext(expand); + + if(getSelectionStart() < botRVA) + { + setTableOffset(getSelectionStart()); + } + else if(getSelectionEnd() >= topRVA) + { + setTableOffset(getInstructionRVA(getSelectionEnd(), -getNbrOfLineToPrint() + 2)); + } + + repaint(); + } + else if(key == Qt::Key_Return || key == Qt::Key_Enter) + { + duint dest = DbgGetBranchDestination(rvaToVa(getInitialSelection())); + if(!dest) + return; + QString cmd = "disasm " + QString("%1").arg(dest, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + DbgCmdExec(cmd.toUtf8().constData()); + } + else + AbstractTableView::keyPressEvent(event); +} + +/************************************************************************************ + ScrollBar Management + ***********************************************************************************/ +/** + * @brief This method has been reimplemented. It realigns the slider on real instructions except + * when the type is QAbstractSlider::SliderNoAction. This type (QAbstractSlider::SliderNoAction) + * is used to force the disassembling at a specific RVA. + * + * @param[in] type Type of action + * @param[in] value Old table offset + * @param[in] delta Scrollbar value delta compared to the previous state + * + * @return Return the value of the new table offset. + */ +dsint Disassembly::sliderMovedHook(int type, dsint value, dsint delta) +{ + // QAbstractSlider::SliderNoAction is used to disassembe at a specific address + if(type == QAbstractSlider::SliderNoAction) + return value + delta; + + // If it's a slider action, disassemble one instruction back and one instruction next in order to be aligned on a real instruction + if(type == QAbstractSlider::SliderMove) + { + dsint wNewValue = 0; + + if(value + delta > 0) + { + wNewValue = getInstructionRVA(value + delta, -1); + wNewValue = getInstructionRVA(wNewValue, 1); + } + + return wNewValue; + } + + // For other actions, disassemble according to the delta + return getInstructionRVA(value, delta); +} + + +/************************************************************************************ + Jumps Graphic +************************************************************************************/ +/** + * @brief This method paints the graphic for jumps. + * + * @param[in] painter Pointer to the painter that allows painting by its own + * @param[in] x Rectangle x + * @param[in] y Rectangle y + * @param[in] addr RVA of address to process + * + * @return Nothing. + */ +int Disassembly::paintJumpsGraphic(QPainter* painter, int x, int y, dsint addr) +{ + dsint selHeadRVA = mSelection.fromIndex; + dsint rva = addr; + Instruction_t instruction = DisassembleAt(selHeadRVA); + auto branchType = instruction.branchType; + + GraphicDump_t wPict = GD_Nothing; + + if(branchType != Instruction_t::None) + { + dsint destRVA = instruction.branchDestination; + + dsint base = mMemPage->getBase(); + if(destRVA >= base && destRVA < base + (dsint)mMemPage->getSize()) + { + destRVA -= (dsint)mMemPage->getBase(); + + if(destRVA < selHeadRVA) + { + if(rva == destRVA) + wPict = GD_HeadFromBottom; + else if(rva > destRVA && rva < selHeadRVA) + wPict = GD_Vert; + else if(rva == selHeadRVA) + wPict = GD_FootToTop; + } + else if(destRVA > selHeadRVA) + { + if(rva == selHeadRVA) + wPict = GD_FootToBottom; + else if(rva > selHeadRVA && rva < destRVA) + wPict = GD_Vert; + else if(rva == destRVA) + wPict = GD_HeadFromTop; + } + } + } + + bool bIsExecute = DbgIsJumpGoingToExecute(rvaToVa(instruction.rva)); + + if(branchType == Instruction_t::Unconditional) //unconditional + { + painter->setPen(mUnconditionalJumpLineColor); + } + else + { + if(bIsExecute) + painter->setPen(mConditionalJumpLineTrueColor); + else + painter->setPen(mConditionalJumpLineFalseColor); + } + + if(wPict == GD_Vert) + { + painter->drawLine(x, y, x, y + getRowHeight()); + } + else if(wPict == GD_FootToBottom) + { + painter->drawLine(x, y + getRowHeight() / 2, x + 5, y + getRowHeight() / 2); + painter->drawLine(x, y + getRowHeight() / 2, x, y + getRowHeight()); + } + else if(wPict == GD_FootToTop) + { + painter->drawLine(x, y + getRowHeight() / 2, x + 5, y + getRowHeight() / 2); + painter->drawLine(x, y, x, y + getRowHeight() / 2); + } + else if(wPict == GD_HeadFromBottom) + { + QPoint wPoints[] = + { + QPoint(x + 3, y + getRowHeight() / 2 - 2), + QPoint(x + 5, y + getRowHeight() / 2), + QPoint(x + 3, y + getRowHeight() / 2 + 2), + }; + + painter->drawLine(x, y + getRowHeight() / 2, x + 5, y + getRowHeight() / 2); + painter->drawLine(x, y + getRowHeight() / 2, x, y + getRowHeight()); + painter->drawPolyline(wPoints, 3); + } + else if(wPict == GD_HeadFromTop) + { + QPoint wPoints[] = + { + QPoint(x + 3, y + getRowHeight() / 2 - 2), + QPoint(x + 5, y + getRowHeight() / 2), + QPoint(x + 3, y + getRowHeight() / 2 + 2), + }; + + painter->drawLine(x, y + getRowHeight() / 2, x + 5, y + getRowHeight() / 2); + painter->drawLine(x, y, x, y + getRowHeight() / 2); + painter->drawPolyline(wPoints, 3); + } + + return 7; +} + +/************************************************************************************ + Function Graphic +************************************************************************************/ +/** + * @brief This method paints the graphic for functions/loops. + * + * @param[in] painter Pointer to the painter that allows painting by its own + * @param[in] x Rectangle x + * @param[in] y Rectangle y + * @param[in] funcType Type of drawing to make + * + * @return Width of the painted data. + */ + +int Disassembly::paintFunctionGraphic(QPainter* painter, int x, int y, Function_t funcType, bool loop) +{ + if(loop && funcType == Function_none) + return 0; + if(loop) + painter->setPen(QPen(mLoopColor, 2)); //thick black line + else + painter->setPen(QPen(mFunctionColor, 2)); //thick black line + int height = getRowHeight(); + int x_add = 5; + int y_add = 4; + int end_add = 2; + int line_width = 3; + if(loop) + { + end_add = -1; + x_add = 4; + } + switch(funcType) + { + case Function_single: + { + if(loop) + y_add = height / 2 + 1; + painter->drawLine(x + x_add + line_width, y + y_add, x + x_add, y + y_add); + painter->drawLine(x + x_add, y + y_add, x + x_add, y + height - y_add - 1); + if(loop) + y_add = height / 2 - 1; + painter->drawLine(x + x_add, y + height - y_add, x + x_add + line_width, y + height - y_add); + } + break; + + case Function_start: + { + if(loop) + y_add = height / 2 + 1; + painter->drawLine(x + x_add + line_width, y + y_add, x + x_add, y + y_add); + painter->drawLine(x + x_add, y + y_add, x + x_add, y + height); + } + break; + + case Function_middle: + { + painter->drawLine(x + x_add, y, x + x_add, y + height); + } + break; + + case Function_loop_entry: + { + int trisize = 2; + int y_start = (height - trisize * 2) / 2 + y; + painter->drawLine(x + x_add, y_start, x + trisize + x_add, y_start + trisize); + painter->drawLine(x + trisize + x_add, y_start + trisize, x + x_add, y_start + trisize * 2); + + painter->drawLine(x + x_add, y, x + x_add, y_start - 1); + painter->drawLine(x + x_add, y_start + trisize * 2 + 2, x + x_add, y + height); + } + break; + + case Function_end: + { + if(loop) + y_add = height / 2 - 1; + painter->drawLine(x + x_add, y, x + x_add, y + height - y_add); + painter->drawLine(x + x_add, y + height - y_add, x + x_add + line_width, y + height - y_add); + } + break; + + case Function_none: + { + + } + break; + } + return x_add + line_width + end_add; +} + + +/************************************************************************************ + Instructions Management + ***********************************************************************************/ +/** + * @brief Returns the RVA of count-th instructions before the given instruction RVA. + * + * @param[in] rva Instruction RVA + * @param[in] count Instruction count + * + * @return RVA of count-th instructions before the given instruction RVA. + */ +dsint Disassembly::getPreviousInstructionRVA(dsint rva, duint count) +{ + QByteArray wBuffer; + dsint wBottomByteRealRVA; + dsint wVirtualRVA; + dsint wMaxByteCountToRead ; + + wBottomByteRealRVA = (dsint)rva - 16 * (count + 3); + wBottomByteRealRVA = wBottomByteRealRVA < 0 ? 0 : wBottomByteRealRVA; + + wVirtualRVA = (dsint)rva - wBottomByteRealRVA; + + wMaxByteCountToRead = wVirtualRVA + 1 + 16; + wBuffer.resize(wMaxByteCountToRead); + + mMemPage->read(reinterpret_cast(wBuffer.data()), wBottomByteRealRVA, wMaxByteCountToRead); + + dsint addr = mDisasm->DisassembleBack(reinterpret_cast(wBuffer.data()), 0, wMaxByteCountToRead, wVirtualRVA, count); + + addr += rva - wVirtualRVA; + + return addr; +} + + +/** + * @brief Returns the RVA of count-th instructions after the given instruction RVA. + * + * @param[in] rva Instruction RVA + * @param[in] count Instruction count + * + * @return RVA of count-th instructions after the given instruction RVA. + */ +dsint Disassembly::getNextInstructionRVA(dsint rva, duint count) +{ + QByteArray wBuffer; + dsint wVirtualRVA = 0; + dsint wRemainingBytes; + dsint wMaxByteCountToRead; + dsint wNewRVA; + + if(mMemPage->getSize() < (duint)rva) + return rva; + wRemainingBytes = mMemPage->getSize() - rva; + + wMaxByteCountToRead = 16 * (count + 1); + wMaxByteCountToRead = wRemainingBytes > wMaxByteCountToRead ? wMaxByteCountToRead : wRemainingBytes; + wBuffer.resize(wMaxByteCountToRead); + + mMemPage->read(reinterpret_cast(wBuffer.data()), rva, wMaxByteCountToRead); + + wNewRVA = mDisasm->DisassembleNext(reinterpret_cast(wBuffer.data()), 0, wMaxByteCountToRead, wVirtualRVA, count); + wNewRVA += rva; + + return wNewRVA; +} + + +/** + * @brief Returns the RVA of count-th instructions before/after (depending on the sign) the given instruction RVA. + * + * @param[in] rva Instruction RVA + * @param[in] count Instruction count + * + * @return RVA of count-th instructions before/after the given instruction RVA. + */ +dsint Disassembly::getInstructionRVA(dsint index, dsint count) +{ + dsint wAddr = 0; + + if(count == 0) + wAddr = index; + if(count < 0) + wAddr = getPreviousInstructionRVA(index, qAbs(count)); + else if(count > 0) + wAddr = getNextInstructionRVA(index, qAbs(count)); + + + if(wAddr < 0) + wAddr = 0; + else if(wAddr > getRowCount() - 1) + wAddr = getRowCount() - 1; + + return wAddr; +} + + +/** + * @brief Disassembles the instruction at the given RVA. + * + * @param[in] rva RVA of instruction to disassemble + * + * @return Return the disassembled instruction. + */ +Instruction_t Disassembly::DisassembleAt(dsint rva) +{ + QByteArray wBuffer; + dsint base = mMemPage->getBase(); + dsint wMaxByteCountToRead = 16 * 2; + + // Bounding + //TODO: fix problems with negative sizes + dsint size = getSize(); + if(!size) + size = rva; + + wMaxByteCountToRead = wMaxByteCountToRead > (size - rva) ? (size - rva) : wMaxByteCountToRead; + + wBuffer.resize(wMaxByteCountToRead); + + mMemPage->read(reinterpret_cast(wBuffer.data()), rva, wMaxByteCountToRead); + + return mDisasm->DisassembleAt(reinterpret_cast(wBuffer.data()), wMaxByteCountToRead, 0, base, rva); +} + + +/** + * @brief Disassembles the instruction count instruction afterc the instruction at the given RVA. + * Count can be positive or negative. + * + * @param[in] rva RVA of reference instruction + * @param[in] count Number of instruction + * + * @return Return the disassembled instruction. + */ +Instruction_t Disassembly::DisassembleAt(dsint rva, dsint count) +{ + rva = getNextInstructionRVA(rva, count); + return DisassembleAt(rva); +} + + +/************************************************************************************ + Selection Management +************************************************************************************/ +void Disassembly::expandSelectionUpTo(dsint to) +{ + if(to < mSelection.firstSelectedIndex) + { + mSelection.fromIndex = to; + } + else if(to > mSelection.firstSelectedIndex) + { + mSelection.toIndex = to; + } + else if(to == mSelection.firstSelectedIndex) + { + setSingleSelection(to); + } +} + +void Disassembly::setSingleSelection(dsint index) +{ + mSelection.firstSelectedIndex = index; + mSelection.fromIndex = index; + mSelection.toIndex = index; + emit selectionChanged(rvaToVa(index)); +} + + +dsint Disassembly::getInitialSelection() +{ + return mSelection.firstSelectedIndex; +} + +dsint Disassembly::getSelectionSize() +{ + return mSelection.toIndex - mSelection.fromIndex; +} + +dsint Disassembly::getSelectionStart() +{ + return mSelection.fromIndex; +} + +dsint Disassembly::getSelectionEnd() +{ + return mSelection.toIndex; +} + +void Disassembly::selectNext(bool expand) +{ + dsint wAddr; + dsint wStart = getInstructionRVA(getSelectionStart(), 1) - 1; + if(expand) + { + if(getSelectionEnd() == getInitialSelection() && wStart != getSelectionEnd()) //decrease down + { + wAddr = getInstructionRVA(getSelectionStart(), 1); + expandSelectionUpTo(wAddr); + } + else //expand down + { + wAddr = getSelectionEnd() + 1; + dsint wInstrSize = getInstructionRVA(wAddr, 1) - wAddr - 1; + expandSelectionUpTo(wAddr + wInstrSize); + } + } + else //select next instruction + { + wAddr = getSelectionEnd() + 1; + setSingleSelection(wAddr); + dsint wInstrSize = getInstructionRVA(wAddr, 1) - wAddr - 1; + expandSelectionUpTo(wAddr + wInstrSize); + } +} + + +void Disassembly::selectPrevious(bool expand) +{ + dsint wAddr; + dsint wStart = getInstructionRVA(getSelectionStart(), 1) - 1; + if(expand) + { + if(getSelectionStart() == getInitialSelection() && wStart != getSelectionEnd()) //decrease up + { + wAddr = getInstructionRVA(getSelectionEnd() + 1, -2); + dsint wInstrSize = getInstructionRVA(wAddr, 1) - wAddr - 1; + expandSelectionUpTo(wAddr + wInstrSize); + } + else //expand up + { + wAddr = getInstructionRVA(wStart + 1, -2); + expandSelectionUpTo(wAddr); + } + } + else + { + wAddr = getInstructionRVA(getSelectionStart(), -1); + setSingleSelection(wAddr); + dsint wInstrSize = getInstructionRVA(wAddr, 1) - wAddr - 1; + expandSelectionUpTo(wAddr + wInstrSize); + } +} + + +bool Disassembly::isSelected(dsint base, dsint offset) +{ + dsint wAddr = base; + + if(offset < 0) + wAddr = getPreviousInstructionRVA(getTableOffset(), offset); + else if(offset > 0) + wAddr = getNextInstructionRVA(getTableOffset(), offset); + + if(wAddr >= mSelection.fromIndex && wAddr <= mSelection.toIndex) + return true; + else + return false; +} + + +bool Disassembly::isSelected(QList* buffer, int index) +{ + if(buffer->size() > 0 && index >= 0 && index < buffer->size()) + { + if((dsint)buffer->at(index).rva >= mSelection.fromIndex && (dsint)buffer->at(index).rva <= mSelection.toIndex) + return true; + else + return false; + } + else + { + return false; + } +} + +duint Disassembly::getSelectedVa() +{ + // Wrapper around commonly used code: + // Converts the selected index to a valid virtual address + return rvaToVa(getInitialSelection()); +} + +/************************************************************************************ + Update/Reload/Refresh/Repaint +************************************************************************************/ + +void Disassembly::prepareDataCount(dsint wRVA, int wCount, QList* instBuffer) +{ + instBuffer->clear(); + Instruction_t wInst; + for(int wI = 0; wI < wCount; wI++) + { + wInst = DisassembleAt(wRVA); + instBuffer->append(wInst); + wRVA += wInst.length; + } +} + +void Disassembly::prepareDataRange(dsint startRva, dsint endRva, QList* instBuffer) +{ + if(startRva == endRva) + prepareDataCount(startRva, 1, instBuffer); + else + { + int wCount = 0; + dsint addr = startRva; + while(addr <= endRva) + { + addr = getNextInstructionRVA(addr, 1); + wCount++; + } + prepareDataCount(startRva, wCount, instBuffer); + } +} + +void Disassembly::prepareData() +{ + dsint wViewableRowsCount = getViewableRowsCount(); + + dsint wAddrPrev = getTableOffset(); + dsint wAddr = wAddrPrev; + + int wCount = 0; + + for(int wI = 0; wI < wViewableRowsCount && getRowCount() > 0; wI++) + { + wAddrPrev = wAddr; + wAddr = getNextInstructionRVA(wAddr, 1); + + if(wAddr == wAddrPrev) + { + break; + } + + wCount++; + } + + setNbrOfLineToPrint(wCount); + + prepareDataCount(getTableOffset(), wCount, &mInstBuffer); +} + +void Disassembly::reloadData() +{ + emit selectionChanged(rvaToVa(mSelection.firstSelectedIndex)); + AbstractTableView::reloadData(); +} + + +/************************************************************************************ + Public Methods +************************************************************************************/ +duint Disassembly::rvaToVa(dsint rva) +{ + return mMemPage->va(rva); +} + +void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint newTableOffset) +{ + dsint wBase = DbgMemFindBaseAddr(parVA, 0); + dsint wSize = DbgMemGetPageSize(wBase); + if(!wBase || !wSize) + return; + dsint wRVA = parVA - wBase; + dsint wCipRva = parCIP - wBase; + + HistoryData_t newHistory; + + //VA history + if(history) + { + //truncate everything right from the current VA + if(mVaHistory.size() && mCurrentVa < mVaHistory.size() - 1) //mCurrentVa is not the last + mVaHistory.erase(mVaHistory.begin() + mCurrentVa + 1, mVaHistory.end()); + + //NOTE: mCurrentVa always points to the last entry of the list + + //add the currently selected address to the history + dsint selectionVA = rvaToVa(getInitialSelection()); //currently selected VA + dsint selectionTableOffset = getTableOffset(); + if(selectionVA && mVaHistory.size() && mVaHistory.last().va != selectionVA) //do not have 2x the same va in a row + { + if(mVaHistory.size() >= 1024) //max 1024 in the history + { + mCurrentVa--; + mVaHistory.erase(mVaHistory.begin()); //remove the oldest element + } + mCurrentVa++; + newHistory.va = selectionVA; + newHistory.tableOffset = selectionTableOffset; + mVaHistory.push_back(newHistory); + } + } + + // Set base and size (Useful when memory page changed) + mMemPage->setAttributes(wBase, wSize); + + if(mRvaDisplayEnabled && mMemPage->getBase() != mRvaDisplayPageBase) + mRvaDisplayEnabled = false; + + setRowCount(wSize); + + setSingleSelection(wRVA); // Selects disassembled instruction + dsint wInstrSize = getInstructionRVA(wRVA, 1) - wRVA - 1; + expandSelectionUpTo(wRVA + wInstrSize); + + //set CIP rva + mCipRva = wCipRva; + + if(newTableOffset == -1) //nothing specified + { + // Update table offset depending on the location of the instruction to disassemble + if(mInstBuffer.size() > 0 && wRVA >= (dsint)mInstBuffer.first().rva && wRVA < (dsint)mInstBuffer.last().rva) + { + int wI; + bool wIsAligned = false; + + // Check if the new RVA is aligned on an instruction from the cache (buffer) + for(wI = 0; wI < mInstBuffer.size(); wI++) + { + if(mInstBuffer.at(wI).rva == wRVA) + { + wIsAligned = true; + break; + } + } + + if(wIsAligned == true) + { + repaint(); + } + else + { + setTableOffset(wRVA); + } + } + else if(mInstBuffer.size() > 0 && wRVA == (dsint)mInstBuffer.last().rva) + { + setTableOffset(mInstBuffer.first().rva + mInstBuffer.first().length); + } + else + { + setTableOffset(wRVA); + } + + if(history) + { + //new disassembled address + newHistory.va = parVA; + newHistory.tableOffset = getTableOffset(); + if(mVaHistory.size()) + { + if(mVaHistory.last().va != parVA) //not 2x the same va in history + { + if(mVaHistory.size() >= 1024) //max 1024 in the history + { + mCurrentVa--; + mVaHistory.erase(mVaHistory.begin()); //remove the oldest element + } + mCurrentVa++; + mVaHistory.push_back(newHistory); //add a va to the history + } + } + else //the list is empty + mVaHistory.push_back(newHistory); + } + } + else //specified new table offset + setTableOffset(newTableOffset); + + /* + //print history + if(history) + { + QString strList = ""; + for(int i=0; i* Disassembly::instructionsBuffer() +{ + return &mInstBuffer; +} + +const dsint Disassembly::currentEIP() const +{ + return mCipRva; +} + + +void Disassembly::disassembleAt(dsint parVA, dsint parCIP) +{ + disassembleAt(parVA, parCIP, true, -1); +} + + +void Disassembly::disassembleClear() +{ + mHighlightingMode = false; + mHighlightToken = CapstoneTokenizer::SingleToken(); + historyClear(); + mMemPage->setAttributes(0, 0); + setRowCount(0); + reloadData(); +} + + +void Disassembly::debugStateChangedSlot(DBGSTATE state) +{ + switch(state) + { + case stopped: + disassembleClear(); + break; + case paused: + mIsRunning = false; + break; + case running: + mIsRunning = true; + break; + default: + break; + } +} + +const dsint Disassembly::getBase() const +{ + return mMemPage->getBase(); +} + +dsint Disassembly::getSize() +{ + return mMemPage->getSize(); +} + +duint Disassembly::getTableOffsetRva() +{ + return mInstBuffer.size() ? mInstBuffer.at(0).rva : 0; + +} + +void Disassembly::historyClear() +{ + mVaHistory.clear(); //clear history for new targets + mCurrentVa = 0; +} + +void Disassembly::historyPrevious() +{ + if(!mCurrentVa || !mVaHistory.size()) //we are at the earliest history entry + return; + mCurrentVa--; + disassembleAt(mVaHistory.at(mCurrentVa).va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset); +} + +void Disassembly::historyNext() +{ + int size = mVaHistory.size(); + if(!size || mCurrentVa >= mVaHistory.size() - 1) //we are at the newest history entry + return; + mCurrentVa++; + disassembleAt(mVaHistory.at(mCurrentVa).va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset); +} + +bool Disassembly::historyHasPrevious() +{ + if(!mCurrentVa || !mVaHistory.size()) //we are at the earliest history entry + return false; + return true; +} + +bool Disassembly::historyHasNext() +{ + int size = mVaHistory.size(); + if(!size || mCurrentVa >= mVaHistory.size() - 1) //we are at the newest history entry + return false; + return true; +} + +QString Disassembly::getAddrText(dsint cur_addr, char label[MAX_LABEL_SIZE]) +{ + QString addrText = ""; + if(mRvaDisplayEnabled) //RVA display + { + dsint rva = cur_addr - mRvaDisplayBase; + if(rva == 0) + { +#ifdef _WIN64 + addrText = "$ ==> "; +#else + addrText = "$ ==> "; +#endif //_WIN64 + } + else if(rva > 0) + { +#ifdef _WIN64 + addrText = "$+" + QString("%1").arg(rva, -15, 16, QChar(' ')).toUpper(); +#else + addrText = "$+" + QString("%1").arg(rva, -7, 16, QChar(' ')).toUpper(); +#endif //_WIN64 + } + else if(rva < 0) + { +#ifdef _WIN64 + addrText = "$-" + QString("%1").arg(-rva, -15, 16, QChar(' ')).toUpper(); +#else + addrText = "$-" + QString("%1").arg(-rva, -7, 16, QChar(' ')).toUpper(); +#endif //_WIN64 + } + } + addrText += ToPtrString(cur_addr); + char label_[MAX_LABEL_SIZE] = ""; + if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label_)) //has label + { + char module[MAX_MODULE_SIZE] = ""; + if(DbgGetModuleAt(cur_addr, module) && !QString(label_).startsWith("JMP.&")) + addrText += " <" + QString(module) + "." + QString(label_) + ">"; + else + addrText += " <" + QString(label_) + ">"; + } + else + *label_ = 0; + if(label) + strcpy_s(label, MAX_LABEL_SIZE, label_); + return addrText; +} diff --git a/src/gui/Src/BasicView/Disassembly.h b/src/gui/Src/BasicView/Disassembly.h index 5f6e861a..12fb6904 100644 --- a/src/gui/Src/BasicView/Disassembly.h +++ b/src/gui/Src/BasicView/Disassembly.h @@ -1,189 +1,189 @@ -#ifndef DISASSEMBLY_H -#define DISASSEMBLY_H - -#include "AbstractTableView.h" -#include "QBeaEngine.h" -#include "MemoryPage.h" - -class Disassembly : public AbstractTableView -{ - Q_OBJECT -public: - explicit Disassembly(QWidget* parent = 0); - - // Configuration - virtual void updateColors(); - virtual void updateFonts(); - - // Reimplemented Functions - QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); - - // Mouse Management - void mouseMoveEvent(QMouseEvent* event); - void mousePressEvent(QMouseEvent* event); - void mouseReleaseEvent(QMouseEvent* event); - - // Keyboard Management - void keyPressEvent(QKeyEvent* event); - - // ScrollBar Management - dsint sliderMovedHook(int type, dsint value, dsint delta); - - // Jumps Graphic - int paintJumpsGraphic(QPainter* painter, int x, int y, dsint addr); - - // Function Graphic - - enum Function_t - { - Function_none, - Function_single, - Function_start, - Function_middle, - Function_loop_entry, - Function_end - }; - - int paintFunctionGraphic(QPainter* painter, int x, int y, Function_t funcType, bool loop); - - // Instructions Management - dsint getPreviousInstructionRVA(dsint rva, duint count); - dsint getNextInstructionRVA(dsint rva, duint count); - dsint getInstructionRVA(dsint index, dsint count); - Instruction_t DisassembleAt(dsint rva); - Instruction_t DisassembleAt(dsint rva, dsint count); - - // Selection Management - void expandSelectionUpTo(dsint to); - void setSingleSelection(dsint index); - dsint getInitialSelection(); - dsint getSelectionSize(); - dsint getSelectionStart(); - dsint getSelectionEnd(); - void selectNext(bool expand); - void selectPrevious(bool expand); - bool isSelected(dsint base, dsint offset); - bool isSelected(QList* buffer, int index); - duint getSelectedVa(); - - // Update/Reload/Refresh/Repaint - void prepareData(); - void reloadData(); - - // Public Methods - duint rvaToVa(dsint rva); - void disassembleClear(); - const dsint getBase() const; - dsint getSize(); - duint getTableOffsetRva(); - - // history management - void historyClear(); - void historyPrevious(); - void historyNext(); - bool historyHasPrevious(); - bool historyHasNext(); - - //disassemble - void disassembleAt(dsint parVA, dsint parCIP, bool history, dsint newTableOffset); - - QList* instructionsBuffer(); - const dsint baseAddress() const; - const dsint currentEIP() const; - - QString getAddrText(dsint cur_addr, char label[MAX_LABEL_SIZE]); - void prepareDataCount(dsint wRVA, int wCount, QList* instBuffer); - void prepareDataRange(dsint startRva, dsint endRva, QList* instBuffer); - -signals: - void selectionChanged(dsint parVA); - void disassembledAt(dsint parVA, dsint parCIP, bool history, dsint newTableOffset); - -public slots: - void disassembleAt(dsint parVA, dsint parCIP); - void debugStateChangedSlot(DBGSTATE state); - -private: - enum GuiState_t {NoState, MultiRowsSelectionState}; - enum GraphicDump_t {GD_Nothing, GD_FootToTop, GD_FootToBottom, GD_HeadFromTop, GD_HeadFromBottom, GD_Vert}; // GD_FootToTop = '- , GD_FootToBottom = ,- , GD_HeadFromTop = '-> , GD_HeadFromBottom = ,-> , GD_Vert = | - - typedef struct _SelectionData_t - { - dsint firstSelectedIndex; - dsint fromIndex; - dsint toIndex; - } SelectionData_t; - - QBeaEngine* mDisasm; - - SelectionData_t mSelection; - - bool mIsLastInstDisplayed; - bool mIsRunning; - - GuiState_t mGuiState; - - dsint mCipRva; - - QList mInstBuffer; - - typedef struct _HistoryData_t - { - dsint va; - dsint tableOffset; - } HistoryData_t; - - QList mVaHistory; - int mCurrentVa; - CapstoneTokenizer::SingleToken mHighlightToken; - -protected: - // Configuration - QColor mInstructionHighlightColor; - QColor mSelectionColor; - - QColor mCipBackgroundColor; - QColor mCipColor; - - QColor mBreakpointBackgroundColor; - QColor mBreakpointColor; - - QColor mHardwareBreakpointBackgroundColor; - QColor mHardwareBreakpointColor; - - QColor mBookmarkBackgroundColor; - QColor mBookmarkColor; - - QColor mLabelColor; - QColor mLabelBackgroundColor; - - QColor mSelectedAddressBackgroundColor; - QColor mSelectedAddressColor; - QColor mAddressBackgroundColor; - QColor mAddressColor; - - QColor mBytesColor; - QColor mModifiedBytesColor; - - QColor mAutoCommentColor; - QColor mAutoCommentBackgroundColor; - - QColor mCommentColor; - QColor mCommentBackgroundColor; - - QColor mUnconditionalJumpLineColor; - QColor mConditionalJumpLineTrueColor; - QColor mConditionalJumpLineFalseColor; - - QColor mLoopColor; - QColor mFunctionColor; - - // Misc - bool mRvaDisplayEnabled; - duint mRvaDisplayBase; - dsint mRvaDisplayPageBase; - bool mHighlightingMode; - MemoryPage* mMemPage; -}; - -#endif // DISASSEMBLY_H +#ifndef DISASSEMBLY_H +#define DISASSEMBLY_H + +#include "AbstractTableView.h" +#include "QBeaEngine.h" +#include "MemoryPage.h" + +class Disassembly : public AbstractTableView +{ + Q_OBJECT +public: + explicit Disassembly(QWidget* parent = 0); + + // Configuration + virtual void updateColors(); + virtual void updateFonts(); + + // Reimplemented Functions + QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); + + // Mouse Management + void mouseMoveEvent(QMouseEvent* event); + void mousePressEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event); + + // Keyboard Management + void keyPressEvent(QKeyEvent* event); + + // ScrollBar Management + dsint sliderMovedHook(int type, dsint value, dsint delta); + + // Jumps Graphic + int paintJumpsGraphic(QPainter* painter, int x, int y, dsint addr); + + // Function Graphic + + enum Function_t + { + Function_none, + Function_single, + Function_start, + Function_middle, + Function_loop_entry, + Function_end + }; + + int paintFunctionGraphic(QPainter* painter, int x, int y, Function_t funcType, bool loop); + + // Instructions Management + dsint getPreviousInstructionRVA(dsint rva, duint count); + dsint getNextInstructionRVA(dsint rva, duint count); + dsint getInstructionRVA(dsint index, dsint count); + Instruction_t DisassembleAt(dsint rva); + Instruction_t DisassembleAt(dsint rva, dsint count); + + // Selection Management + void expandSelectionUpTo(dsint to); + void setSingleSelection(dsint index); + dsint getInitialSelection(); + dsint getSelectionSize(); + dsint getSelectionStart(); + dsint getSelectionEnd(); + void selectNext(bool expand); + void selectPrevious(bool expand); + bool isSelected(dsint base, dsint offset); + bool isSelected(QList* buffer, int index); + duint getSelectedVa(); + + // Update/Reload/Refresh/Repaint + void prepareData(); + void reloadData(); + + // Public Methods + duint rvaToVa(dsint rva); + void disassembleClear(); + const dsint getBase() const; + dsint getSize(); + duint getTableOffsetRva(); + + // history management + void historyClear(); + void historyPrevious(); + void historyNext(); + bool historyHasPrevious(); + bool historyHasNext(); + + //disassemble + void disassembleAt(dsint parVA, dsint parCIP, bool history, dsint newTableOffset); + + QList* instructionsBuffer(); + const dsint baseAddress() const; + const dsint currentEIP() const; + + QString getAddrText(dsint cur_addr, char label[MAX_LABEL_SIZE]); + void prepareDataCount(dsint wRVA, int wCount, QList* instBuffer); + void prepareDataRange(dsint startRva, dsint endRva, QList* instBuffer); + +signals: + void selectionChanged(dsint parVA); + void disassembledAt(dsint parVA, dsint parCIP, bool history, dsint newTableOffset); + +public slots: + void disassembleAt(dsint parVA, dsint parCIP); + void debugStateChangedSlot(DBGSTATE state); + +private: + enum GuiState_t {NoState, MultiRowsSelectionState}; + enum GraphicDump_t {GD_Nothing, GD_FootToTop, GD_FootToBottom, GD_HeadFromTop, GD_HeadFromBottom, GD_Vert}; // GD_FootToTop = '- , GD_FootToBottom = ,- , GD_HeadFromTop = '-> , GD_HeadFromBottom = ,-> , GD_Vert = | + + typedef struct _SelectionData_t + { + dsint firstSelectedIndex; + dsint fromIndex; + dsint toIndex; + } SelectionData_t; + + QBeaEngine* mDisasm; + + SelectionData_t mSelection; + + bool mIsLastInstDisplayed; + bool mIsRunning; + + GuiState_t mGuiState; + + dsint mCipRva; + + QList mInstBuffer; + + typedef struct _HistoryData_t + { + dsint va; + dsint tableOffset; + } HistoryData_t; + + QList mVaHistory; + int mCurrentVa; + CapstoneTokenizer::SingleToken mHighlightToken; + +protected: + // Configuration + QColor mInstructionHighlightColor; + QColor mSelectionColor; + + QColor mCipBackgroundColor; + QColor mCipColor; + + QColor mBreakpointBackgroundColor; + QColor mBreakpointColor; + + QColor mHardwareBreakpointBackgroundColor; + QColor mHardwareBreakpointColor; + + QColor mBookmarkBackgroundColor; + QColor mBookmarkColor; + + QColor mLabelColor; + QColor mLabelBackgroundColor; + + QColor mSelectedAddressBackgroundColor; + QColor mSelectedAddressColor; + QColor mAddressBackgroundColor; + QColor mAddressColor; + + QColor mBytesColor; + QColor mModifiedBytesColor; + + QColor mAutoCommentColor; + QColor mAutoCommentBackgroundColor; + + QColor mCommentColor; + QColor mCommentBackgroundColor; + + QColor mUnconditionalJumpLineColor; + QColor mConditionalJumpLineTrueColor; + QColor mConditionalJumpLineFalseColor; + + QColor mLoopColor; + QColor mFunctionColor; + + // Misc + bool mRvaDisplayEnabled; + duint mRvaDisplayBase; + dsint mRvaDisplayPageBase; + bool mHighlightingMode; + MemoryPage* mMemPage; +}; + +#endif // DISASSEMBLY_H diff --git a/src/gui/Src/BasicView/HeaderButton.h b/src/gui/Src/BasicView/HeaderButton.h index 2987915f..92d39b8d 100644 --- a/src/gui/Src/BasicView/HeaderButton.h +++ b/src/gui/Src/BasicView/HeaderButton.h @@ -1,20 +1,20 @@ -#ifndef HEADERBUTTON_H -#define HEADERBUTTON_H - -#include - -class HeaderButton : public QWidget -{ - Q_OBJECT -public: - explicit HeaderButton(QWidget* parent = 0); - void setGeometry(int x, int y, int w, int h); - -signals: - -public slots: - -}; - -#endif // HEADERBUTTON_H - +#ifndef HEADERBUTTON_H +#define HEADERBUTTON_H + +#include + +class HeaderButton : public QWidget +{ + Q_OBJECT +public: + explicit HeaderButton(QWidget* parent = 0); + void setGeometry(int x, int y, int w, int h); + +signals: + +public slots: + +}; + +#endif // HEADERBUTTON_H + diff --git a/src/gui/Src/BasicView/HexDump.cpp b/src/gui/Src/BasicView/HexDump.cpp index 5919e5b1..2b3e639f 100644 --- a/src/gui/Src/BasicView/HexDump.cpp +++ b/src/gui/Src/BasicView/HexDump.cpp @@ -1,1012 +1,1012 @@ -#include "HexDump.h" -#include -#include "Configuration.h" -#include "Bridge.h" - -HexDump::HexDump(QWidget* parent) : AbstractTableView(parent) -{ - SelectionData_t data; - memset(&data, 0, sizeof(SelectionData_t)); - mSelection = data; - - mGuiState = HexDump::NoState; - - setRowCount(0); - - mMemPage = new MemoryPage(0, 0); - mForceColumn = -1; - - clearDescriptors(); - - backgroundColor = ConfigColor("HexDumpBackgroundColor"); - textColor = ConfigColor("HexDumpTextColor"); - selectionColor = ConfigColor("HexDumpSelectionColor"); - - mRvaDisplayEnabled = false; - - // Slots - connect(Bridge::getBridge(), SIGNAL(updateDump()), this, SLOT(reloadData())); - connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChanged(DBGSTATE))); - - Initialize(); -} - -void HexDump::updateColors() -{ - AbstractTableView::updateColors(); - - backgroundColor = ConfigColor("HexDumpBackgroundColor"); - textColor = ConfigColor("HexDumpTextColor"); - selectionColor = ConfigColor("HexDumpSelectionColor"); - reloadData(); -} - -void HexDump::updateFonts() -{ - setFont(ConfigFont("HexDump")); -} - -void HexDump::printDumpAt(dsint parVA, bool select, bool repaint) -{ - dsint wBase = DbgMemFindBaseAddr(parVA, 0); //get memory base - dsint wSize = DbgMemGetPageSize(wBase); //get page size - if(!wBase || !wSize) - return; - dsint wRVA = parVA - wBase; //calculate rva - int wBytePerRowCount = getBytePerRowCount(); //get the number of bytes per row - dsint wRowCount; - - // Byte offset used to be aligned on the given RVA - mByteOffset = (int)((dsint)wRVA % (dsint)wBytePerRowCount); - mByteOffset = mByteOffset > 0 ? wBytePerRowCount - mByteOffset : 0; - - // Compute row count - wRowCount = wSize / wBytePerRowCount; - wRowCount += mByteOffset > 0 ? 1 : 0; - - if(mRvaDisplayEnabled && mMemPage->getBase() != mRvaDisplayPageBase) - mRvaDisplayEnabled = false; - - setRowCount(wRowCount); //set the number of rows - - mMemPage->setAttributes(wBase, wSize); // Set base and size (Useful when memory page changed) - - setTableOffset(-1); //make sure the requested address is always first - - setTableOffset((wRVA + mByteOffset) / wBytePerRowCount); //change the displayed offset - - if(select) - { - setSingleSelection(wRVA); - dsint wEndingAddress = wRVA + getSizeOf(mDescriptor.at(0).data.itemSize) - 1; - expandSelectionUpTo(wEndingAddress); - } - - if(repaint) - reloadData(); -} - -void HexDump::printDumpAt(dsint parVA) -{ - printDumpAt(parVA, true); -} - -duint HexDump::rvaToVa(dsint rva) -{ - return mMemPage->va(rva); -} - -duint HexDump::getTableOffsetRva() -{ - return getTableOffset() * getBytePerRowCount() - mByteOffset; -} - -void HexDump::mouseMoveEvent(QMouseEvent* event) -{ - bool wAccept = true; - - int x = event->x(); - int y = event->y(); - - if(mGuiState == HexDump::MultiRowsSelectionState) - { - //qDebug() << "State = MultiRowsSelectionState"; - - if((transY(y) >= 0) && y <= this->height()) - { - for(int wI = 1; wI < getColumnCount(); wI++) // Skip first column (Addresses) - { - int wColIndex = getColumnIndexFromX(x); - - if(mForceColumn != -1) - { - wColIndex = mForceColumn; - x = getColumnPosition(mForceColumn) + 1; - } - - if(wColIndex > 0) // No selection for first column (addresses) - { - dsint wStartingAddress = getItemStartingAddress(x, y); - dsint dataSize = getSizeOf(mDescriptor.at(wColIndex - 1).data.itemSize) - 1; - dsint wEndingAddress = wStartingAddress + dataSize; - - if(wEndingAddress < (dsint)mMemPage->getSize()) - { - if(wStartingAddress < getInitialSelection()) - { - expandSelectionUpTo(wStartingAddress); - mSelection.toIndex += dataSize; - emit selectionUpdated(); - } - else - expandSelectionUpTo(wEndingAddress); - - mGuiState = HexDump::MultiRowsSelectionState; - - repaint(); - } - } - } - - wAccept = true; - } - } - - if(wAccept == true) - AbstractTableView::mouseMoveEvent(event); -} - -void HexDump::mousePressEvent(QMouseEvent* event) -{ - if(event->buttons() == Qt::MiddleButton) //copy address to clipboard - { - if(!DbgIsDebugging()) - return; - MessageBeep(MB_OK); - QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - Bridge::CopyToClipboard(addrText); - return; - } - //qDebug() << "HexDump::mousePressEvent"; - - int x = event->x(); - int y = event->y(); - - bool wAccept = false; - - if(((event->buttons() & Qt::LeftButton) != 0) && ((event->buttons() & Qt::RightButton) == 0)) - { - if(getGuiState() == AbstractTableView::NoState) - { - if(y > getHeaderHeight() && y <= this->height()) - { - int wColIndex = getColumnIndexFromX(x); - - if(mForceColumn != -1) - { - wColIndex = mForceColumn; - x = getColumnPosition(mForceColumn) + 1; - } - - if(wColIndex > 0 && mDescriptor.at(wColIndex - 1).isData == true) // No selection for first column (addresses) and no data columns - { - dsint wStartingAddress = getItemStartingAddress(x, y); - dsint dataSize = getSizeOf(mDescriptor.at(wColIndex - 1).data.itemSize) - 1; - dsint wEndingAddress = wStartingAddress + dataSize; - - if(wEndingAddress < (dsint)mMemPage->getSize()) - { - bool bUpdateTo = false; - if(!(event->modifiers() & Qt::ShiftModifier)) - setSingleSelection(wStartingAddress); - else if(getInitialSelection() > wEndingAddress) - { - wEndingAddress -= dataSize; - bUpdateTo = true; - } - expandSelectionUpTo(wEndingAddress); - if(bUpdateTo) - { - mSelection.toIndex += dataSize; - emit selectionUpdated(); - } - - mGuiState = HexDump::MultiRowsSelectionState; - - repaint(); - } - } - - wAccept = true; - } - } - } - - if(wAccept == false) - AbstractTableView::mousePressEvent(event); -} - -void HexDump::mouseReleaseEvent(QMouseEvent* event) -{ - bool wAccept = true; - - if((event->buttons() & Qt::LeftButton) == 0) - { - if(mGuiState == HexDump::MultiRowsSelectionState) - { - mGuiState = HexDump::NoState; - - repaint(); - - wAccept = false; - } - } - - if(wAccept == true) - AbstractTableView::mouseReleaseEvent(event); -} - -QString HexDump::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) -{ - // Reset byte offset when base address is reached - if(rowBase == 0 && mByteOffset != 0) - printDumpAt(mMemPage->getBase(), false, false); - - // Compute RVA - int wBytePerRowCount = getBytePerRowCount(); - dsint wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset; - - QString wStr = ""; - if(col == 0) // Addresses - { - wStr += QString("%1").arg(rvaToVa(wRva), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - else if(mDescriptor.at(col - 1).isData == true) //paint data - { - printSelected(painter, rowBase, rowOffset, col, x, y, w, h); - QList richText; - getString(col - 1, wRva, &richText); - RichTextPainter::paintRichText(painter, x, y, w, h, 4, &richText, getCharWidth()); - } - - return wStr; -} - -void HexDump::printSelected(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) -{ - if((col > 0) && ((col - 1) < mDescriptor.size())) - { - ColumnDescriptor_t curDescriptor = mDescriptor.at(col - 1); - int wBytePerRowCount = getBytePerRowCount(); - dsint wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset; - int wItemPixWidth = getItemPixelWidth(curDescriptor); - int wCharWidth = getCharWidth(); - if(wItemPixWidth == wCharWidth) - x += 4; - - for(int i = 0; i < curDescriptor.itemCount; i++) - { - int wSelectionX = x + i * wItemPixWidth; - if(isSelected(wRva + i * getSizeOf(curDescriptor.data.itemSize)) == true) - { - int wSelectionWidth = wItemPixWidth > w - (wSelectionX - x) ? w - (wSelectionX - x) : wItemPixWidth; - wSelectionWidth = wSelectionWidth < 0 ? 0 : wSelectionWidth; - painter->setPen(textColor); - painter->fillRect(QRect(wSelectionX, y, wSelectionWidth, h), QBrush(selectionColor)); - } - int separator = curDescriptor.separator; - if(i && separator && !(i % separator)) - { - painter->setPen(separatorColor); - painter->drawLine(wSelectionX, y, wSelectionX, y + h); - } - } - } -} - -/************************************************************************************ - Selection Management -************************************************************************************/ -void HexDump::expandSelectionUpTo(dsint rva) -{ - if(rva < mSelection.firstSelectedIndex) - { - mSelection.fromIndex = rva; - mSelection.toIndex = mSelection.firstSelectedIndex; - emit selectionUpdated(); - } - else if(rva > mSelection.firstSelectedIndex) - { - mSelection.fromIndex = mSelection.firstSelectedIndex; - mSelection.toIndex = rva; - emit selectionUpdated(); - } - else if(rva == mSelection.firstSelectedIndex) - { - setSingleSelection(rva); - } -} - -void HexDump::setSingleSelection(dsint rva) -{ - mSelection.firstSelectedIndex = rva; - mSelection.fromIndex = rva; - mSelection.toIndex = rva; - emit selectionUpdated(); -} - -dsint HexDump::getInitialSelection() -{ - return mSelection.firstSelectedIndex; -} - -dsint HexDump::getSelectionStart() -{ - return mSelection.fromIndex; -} - -dsint HexDump::getSelectionEnd() -{ - return mSelection.toIndex; -} - -bool HexDump::isSelected(dsint rva) -{ - if(rva >= mSelection.fromIndex && rva <= mSelection.toIndex) - return true; - else - return false; -} - -void HexDump::getString(int col, dsint rva, QList* richText) -{ - int wI; - QString wStr = ""; - - int wByteCount = getSizeOf(mDescriptor.at(col).data.itemSize); - int wBufferByteCount = mDescriptor.at(col).itemCount * wByteCount; - - wBufferByteCount = wBufferByteCount > (dsint)(mMemPage->getSize() - rva) ? mMemPage->getSize() - rva : wBufferByteCount; - - byte_t* wData = new byte_t[wBufferByteCount]; - //byte_t wData[mDescriptor.at(col).itemCount * wByteCount]; - - mMemPage->read(wData, rva, wBufferByteCount); - - RichTextPainter::CustomRichText_t curData; - curData.highlight = false; - curData.flags = RichTextPainter::FlagColor; - - QColor highlightColor = ConfigColor("HexDumpModifiedBytesColor"); - - for(wI = 0; wI < mDescriptor.at(col).itemCount && (rva + wI) < (dsint)mMemPage->getSize(); wI++) - { - int maxLen = getStringMaxLength(mDescriptor.at(col).data); - QString append = " "; - if(!maxLen) - append = ""; - if((rva + wI + wByteCount - 1) < (dsint)mMemPage->getSize()) - wStr = toString(mDescriptor.at(col).data, (void*)(wData + wI * wByteCount)).rightJustified(maxLen, ' ') + append; - else - wStr = QString("?").rightJustified(maxLen, ' ') + append; - curData.text = wStr; - dsint start = rvaToVa(rva + wI * wByteCount); - dsint end = start + wByteCount - 1; - curData.textColor = DbgFunctions()->PatchInRange(start, end) ? highlightColor : textColor; - richText->push_back(curData); - } - - delete[] wData; -} - -QString HexDump::toString(DataDescriptor_t desc, void* data) //convert data to string -{ - QString wStr = ""; - - switch(desc.itemSize) - { - case Byte: - { - wStr = byteToString(*((byte_t*)data), desc.byteMode); - } - break; - - case Word: - { - wStr = wordToString(*((uint16*)data), desc.wordMode); - } - break; - - case Dword: - { - wStr = dwordToString(*((uint32*)data), desc.dwordMode); - } - break; - - case Qword: - { - wStr = qwordToString(*((uint64*)data), desc.qwordMode); - } - break; - - case Tword: - { - //TODO: sizeof(long double)=12, not 10 - wStr = twordToString(*((long double*)data), desc.twordMode); - } - break; - - default: - { - - } - break; - } - - return wStr; -} - -QString HexDump::byteToString(byte_t byte, ByteViewMode_e mode) -{ - QString wStr = ""; - - switch(mode) - { - case HexByte: - { - wStr = QString("%1").arg((unsigned char)byte, 2, 16, QChar('0')).toUpper(); - } - break; - - case AsciiByte: - { - QChar wChar = QChar::fromLatin1((char)byte); - - if(wChar.isPrint() == true) - wStr = QString(wChar); - else - wStr = "."; - } - break; - - case SignedDecByte: - { - wStr = QString::number((int)((char)byte)); - } - break; - - case UnsignedDecByte: - { - wStr = QString::number((unsigned int)byte); - } - break; - - default: - { - - } - break; - } - - return wStr; -} - -QString HexDump::wordToString(uint16 word, WordViewMode_e mode) -{ - QString wStr = ""; - - switch(mode) - { - case HexWord: - { - wStr = QString("%1").arg((unsigned short)word, 4, 16, QChar('0')).toUpper(); - } - break; - - case UnicodeWord: - { - QChar wChar = QChar::fromLatin1((char)word & 0xFF); - if(wChar.isPrint() == true && (word >> 8) == 0) - wStr = QString(wChar); - else - wStr = "."; - } - break; - - case SignedDecWord: - { - wStr = QString::number((int)((short)word)); - } - break; - - case UnsignedDecWord: - { - wStr = QString::number((unsigned int)word); - } - break; - - default: - { - - } - break; - } - - return wStr; -} - -QString HexDump::dwordToString(uint32 dword, DwordViewMode_e mode) -{ - QString wStr = ""; - - switch(mode) - { - case HexDword: - { - wStr = QString("%1").arg((unsigned int)dword, 8, 16, QChar('0')).toUpper(); - } - break; - - case SignedDecDword: - { - wStr = QString::number((int)dword); - } - break; - - case UnsignedDecDword: - { - wStr = QString::number((unsigned int)dword); - } - break; - - case FloatDword: - { - float* wPtr = (float*)&dword; - wStr = QString::number((double) * wPtr); - } - break; - - default: - { - - } - break; - } - - return wStr; -} - -QString HexDump::qwordToString(uint64 qword, QwordViewMode_e mode) -{ - QString wStr = ""; - - switch(mode) - { - case HexQword: - { - wStr = QString("%1").arg((unsigned long long)qword, 16, 16, QChar('0')).toUpper(); - } - break; - - case SignedDecQword: - { - wStr = QString::number((long long)qword); - } - break; - - case UnsignedDecQword: - { - wStr = QString::number((unsigned long long)qword); - } - break; - - case DoubleQword: - { - double* wPtr = (double*)&qword; - wStr = QString::number((double) * wPtr); - } - break; - - default: - { - - } - break; - } - - return wStr; -} - -QString HexDump::twordToString(long double tword, TwordViewMode_e mode) -{ - QString wStr = ""; - - switch(mode) - { - case FloatTword: - { - std::stringstream wlongDoubleStr; - wlongDoubleStr << std::scientific << (long double)tword; - - wStr = QString::fromStdString(wlongDoubleStr.str()); - } - break; - - default: - { - - } - break; - } - - return wStr; -} - -int HexDump::getSizeOf(DataSize_e size) -{ - int wSize = 0; - - switch(size) - { - case Byte: // 1 Byte - { - wSize = 1; - } - break; - - case Word: // 2 Bytes - { - wSize = 2; - } - break; - - case Dword: // 4 Bytes - { - wSize = 4; - } - break; - - case Qword: // 8 Bytes - { - wSize = 8; - } - break; - - case Tword: // 10 Bytes - { - wSize = 10; - } - break; - - default: - { - wSize = 0; - } - } - - return wSize; -} - -int HexDump::getStringMaxLength(DataDescriptor_t desc) -{ - int wLength = 0; - - switch(desc.itemSize) - { - case Byte: - { - wLength = byteStringMaxLength(desc.byteMode); - } - break; - - case Word: - { - wLength = wordStringMaxLength(desc.wordMode); - } - break; - - case Dword: - { - wLength = dwordStringMaxLength(desc.dwordMode); - } - break; - - case Qword: - { - wLength = qwordStringMaxLength(desc.qwordMode); - } - break; - - case Tword: - { - wLength = twordStringMaxLength(desc.twordMode); - } - break; - - default: - { - - } - break; - } - - return wLength; -} - -int HexDump::byteStringMaxLength(ByteViewMode_e mode) -{ - int wLength = 0; - - switch(mode) - { - case HexByte: - { - wLength = 2; - } - break; - - case AsciiByte: - { - wLength = 0; - } - break; - - case SignedDecByte: - { - wLength = 4; - } - break; - - case UnsignedDecByte: - { - wLength = 3; - } - break; - - default: - { - - } - break; - } - - return wLength; -} - -int HexDump::wordStringMaxLength(WordViewMode_e mode) -{ - int wLength = 0; - - switch(mode) - { - case HexWord: - { - wLength = 4; - } - break; - - case UnicodeWord: - { - wLength = 0; - } - break; - - case SignedDecWord: - { - wLength = 6; - } - break; - - case UnsignedDecWord: - { - wLength = 5; - } - break; - - default: - { - - } - break; - } - - return wLength; -} - -int HexDump::dwordStringMaxLength(DwordViewMode_e mode) -{ - int wLength = 0; - - switch(mode) - { - case HexDword: - { - wLength = 8; - } - break; - - case SignedDecDword: - { - wLength = 11; - } - break; - - case UnsignedDecDword: - { - wLength = 10; - } - break; - - case FloatDword: - { - wLength = 13; - } - break; - - default: - { - - } - break; - } - - return wLength; -} - -int HexDump::qwordStringMaxLength(QwordViewMode_e mode) -{ - int wLength = 0; - - switch(mode) - { - case HexQword: - { - wLength = 16; - } - break; - - case SignedDecQword: - { - wLength = 20; - } - break; - - case UnsignedDecQword: - { - wLength = 20; - } - break; - - case DoubleQword: - { - wLength = 23; - } - break; - - default: - { - - } - break; - } - - return wLength; -} - -int HexDump::twordStringMaxLength(TwordViewMode_e mode) -{ - int wLength = 0; - - switch(mode) - { - case FloatTword: - { - wLength = 29; - } - break; - - default: - { - - } - break; - } - - return wLength; -} - -int HexDump::getItemIndexFromX(int x) -{ - int wColIndex = getColumnIndexFromX(x); - - if(wColIndex > 0) - { - int wColStartingPos = getColumnPosition(wColIndex); - int wRelativeX = x - wColStartingPos; - - int wItemPixWidth = getItemPixelWidth(mDescriptor.at(wColIndex - 1)); - int wCharWidth = getCharWidth(); - if(wItemPixWidth == wCharWidth) - wRelativeX -= 4; - - int wItemIndex = wRelativeX / wItemPixWidth; - - wItemIndex = wItemIndex < 0 ? 0 : wItemIndex; - wItemIndex = wItemIndex > (mDescriptor.at(wColIndex - 1).itemCount - 1) ? (mDescriptor.at(wColIndex - 1).itemCount - 1) : wItemIndex; - - return wItemIndex; - } - else - { - return 0; - } -} - -dsint HexDump::getItemStartingAddress(int x, int y) -{ - int wRowOffset = getIndexOffsetFromY(transY(y)); - int wItemIndex = getItemIndexFromX(x); - int wColIndex = getColumnIndexFromX(x); - dsint wStartingAddress = 0; - - if(wColIndex > 0) - { - wColIndex -= 1; - wStartingAddress = (getTableOffset() + wRowOffset) * (mDescriptor.at(wColIndex).itemCount * getSizeOf(mDescriptor.at(wColIndex).data.itemSize)) + wItemIndex * getSizeOf(mDescriptor.at(wColIndex).data.itemSize) - mByteOffset; - } - - return wStartingAddress; -} - -int HexDump::getBytePerRowCount() -{ - return mDescriptor.at(0).itemCount * getSizeOf(mDescriptor.at(0).data.itemSize); -} - -int HexDump::getItemPixelWidth(ColumnDescriptor_t desc) -{ - int wCharWidth = getCharWidth(); - int wItemPixWidth = getStringMaxLength(desc.data) * wCharWidth + wCharWidth; - - return wItemPixWidth; -} - -void HexDump::appendDescriptor(int width, QString title, bool clickable, ColumnDescriptor_t descriptor) -{ - addColumnAt(width, title, clickable); - mDescriptor.append(descriptor); -} - -//Clears the descriptors, append a new descriptor and fix the tableOffset (use this instead of clearDescriptors() -void HexDump::appendResetDescriptor(int width, QString title, bool clickable, ColumnDescriptor_t descriptor) -{ - mAllowPainting = false; - if(mDescriptor.size()) - { - dsint wRVA = getTableOffset() * getBytePerRowCount() - mByteOffset; - clearDescriptors(); - appendDescriptor(width, title, clickable, descriptor); - printDumpAt(rvaToVa(wRVA), true, false); - } - else - appendDescriptor(width, title, clickable, descriptor); - mAllowPainting = true; -} - -void HexDump::clearDescriptors() -{ - deleteAllColumns(); - mDescriptor.clear(); - int charwidth = getCharWidth(); - addColumnAt(8 + charwidth * 2 * sizeof(duint), "Address", false); //address -} - -void HexDump::debugStateChanged(DBGSTATE state) -{ - if(state == stopped) - { - mMemPage->setAttributes(0, 0); - setRowCount(0); - reloadData(); - } -} +#include "HexDump.h" +#include +#include "Configuration.h" +#include "Bridge.h" + +HexDump::HexDump(QWidget* parent) : AbstractTableView(parent) +{ + SelectionData_t data; + memset(&data, 0, sizeof(SelectionData_t)); + mSelection = data; + + mGuiState = HexDump::NoState; + + setRowCount(0); + + mMemPage = new MemoryPage(0, 0); + mForceColumn = -1; + + clearDescriptors(); + + backgroundColor = ConfigColor("HexDumpBackgroundColor"); + textColor = ConfigColor("HexDumpTextColor"); + selectionColor = ConfigColor("HexDumpSelectionColor"); + + mRvaDisplayEnabled = false; + + // Slots + connect(Bridge::getBridge(), SIGNAL(updateDump()), this, SLOT(reloadData())); + connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChanged(DBGSTATE))); + + Initialize(); +} + +void HexDump::updateColors() +{ + AbstractTableView::updateColors(); + + backgroundColor = ConfigColor("HexDumpBackgroundColor"); + textColor = ConfigColor("HexDumpTextColor"); + selectionColor = ConfigColor("HexDumpSelectionColor"); + reloadData(); +} + +void HexDump::updateFonts() +{ + setFont(ConfigFont("HexDump")); +} + +void HexDump::printDumpAt(dsint parVA, bool select, bool repaint) +{ + dsint wBase = DbgMemFindBaseAddr(parVA, 0); //get memory base + dsint wSize = DbgMemGetPageSize(wBase); //get page size + if(!wBase || !wSize) + return; + dsint wRVA = parVA - wBase; //calculate rva + int wBytePerRowCount = getBytePerRowCount(); //get the number of bytes per row + dsint wRowCount; + + // Byte offset used to be aligned on the given RVA + mByteOffset = (int)((dsint)wRVA % (dsint)wBytePerRowCount); + mByteOffset = mByteOffset > 0 ? wBytePerRowCount - mByteOffset : 0; + + // Compute row count + wRowCount = wSize / wBytePerRowCount; + wRowCount += mByteOffset > 0 ? 1 : 0; + + if(mRvaDisplayEnabled && mMemPage->getBase() != mRvaDisplayPageBase) + mRvaDisplayEnabled = false; + + setRowCount(wRowCount); //set the number of rows + + mMemPage->setAttributes(wBase, wSize); // Set base and size (Useful when memory page changed) + + setTableOffset(-1); //make sure the requested address is always first + + setTableOffset((wRVA + mByteOffset) / wBytePerRowCount); //change the displayed offset + + if(select) + { + setSingleSelection(wRVA); + dsint wEndingAddress = wRVA + getSizeOf(mDescriptor.at(0).data.itemSize) - 1; + expandSelectionUpTo(wEndingAddress); + } + + if(repaint) + reloadData(); +} + +void HexDump::printDumpAt(dsint parVA) +{ + printDumpAt(parVA, true); +} + +duint HexDump::rvaToVa(dsint rva) +{ + return mMemPage->va(rva); +} + +duint HexDump::getTableOffsetRva() +{ + return getTableOffset() * getBytePerRowCount() - mByteOffset; +} + +void HexDump::mouseMoveEvent(QMouseEvent* event) +{ + bool wAccept = true; + + int x = event->x(); + int y = event->y(); + + if(mGuiState == HexDump::MultiRowsSelectionState) + { + //qDebug() << "State = MultiRowsSelectionState"; + + if((transY(y) >= 0) && y <= this->height()) + { + for(int wI = 1; wI < getColumnCount(); wI++) // Skip first column (Addresses) + { + int wColIndex = getColumnIndexFromX(x); + + if(mForceColumn != -1) + { + wColIndex = mForceColumn; + x = getColumnPosition(mForceColumn) + 1; + } + + if(wColIndex > 0) // No selection for first column (addresses) + { + dsint wStartingAddress = getItemStartingAddress(x, y); + dsint dataSize = getSizeOf(mDescriptor.at(wColIndex - 1).data.itemSize) - 1; + dsint wEndingAddress = wStartingAddress + dataSize; + + if(wEndingAddress < (dsint)mMemPage->getSize()) + { + if(wStartingAddress < getInitialSelection()) + { + expandSelectionUpTo(wStartingAddress); + mSelection.toIndex += dataSize; + emit selectionUpdated(); + } + else + expandSelectionUpTo(wEndingAddress); + + mGuiState = HexDump::MultiRowsSelectionState; + + repaint(); + } + } + } + + wAccept = true; + } + } + + if(wAccept == true) + AbstractTableView::mouseMoveEvent(event); +} + +void HexDump::mousePressEvent(QMouseEvent* event) +{ + if(event->buttons() == Qt::MiddleButton) //copy address to clipboard + { + if(!DbgIsDebugging()) + return; + MessageBeep(MB_OK); + QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + Bridge::CopyToClipboard(addrText); + return; + } + //qDebug() << "HexDump::mousePressEvent"; + + int x = event->x(); + int y = event->y(); + + bool wAccept = false; + + if(((event->buttons() & Qt::LeftButton) != 0) && ((event->buttons() & Qt::RightButton) == 0)) + { + if(getGuiState() == AbstractTableView::NoState) + { + if(y > getHeaderHeight() && y <= this->height()) + { + int wColIndex = getColumnIndexFromX(x); + + if(mForceColumn != -1) + { + wColIndex = mForceColumn; + x = getColumnPosition(mForceColumn) + 1; + } + + if(wColIndex > 0 && mDescriptor.at(wColIndex - 1).isData == true) // No selection for first column (addresses) and no data columns + { + dsint wStartingAddress = getItemStartingAddress(x, y); + dsint dataSize = getSizeOf(mDescriptor.at(wColIndex - 1).data.itemSize) - 1; + dsint wEndingAddress = wStartingAddress + dataSize; + + if(wEndingAddress < (dsint)mMemPage->getSize()) + { + bool bUpdateTo = false; + if(!(event->modifiers() & Qt::ShiftModifier)) + setSingleSelection(wStartingAddress); + else if(getInitialSelection() > wEndingAddress) + { + wEndingAddress -= dataSize; + bUpdateTo = true; + } + expandSelectionUpTo(wEndingAddress); + if(bUpdateTo) + { + mSelection.toIndex += dataSize; + emit selectionUpdated(); + } + + mGuiState = HexDump::MultiRowsSelectionState; + + repaint(); + } + } + + wAccept = true; + } + } + } + + if(wAccept == false) + AbstractTableView::mousePressEvent(event); +} + +void HexDump::mouseReleaseEvent(QMouseEvent* event) +{ + bool wAccept = true; + + if((event->buttons() & Qt::LeftButton) == 0) + { + if(mGuiState == HexDump::MultiRowsSelectionState) + { + mGuiState = HexDump::NoState; + + repaint(); + + wAccept = false; + } + } + + if(wAccept == true) + AbstractTableView::mouseReleaseEvent(event); +} + +QString HexDump::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) +{ + // Reset byte offset when base address is reached + if(rowBase == 0 && mByteOffset != 0) + printDumpAt(mMemPage->getBase(), false, false); + + // Compute RVA + int wBytePerRowCount = getBytePerRowCount(); + dsint wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset; + + QString wStr = ""; + if(col == 0) // Addresses + { + wStr += QString("%1").arg(rvaToVa(wRva), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + else if(mDescriptor.at(col - 1).isData == true) //paint data + { + printSelected(painter, rowBase, rowOffset, col, x, y, w, h); + QList richText; + getString(col - 1, wRva, &richText); + RichTextPainter::paintRichText(painter, x, y, w, h, 4, &richText, getCharWidth()); + } + + return wStr; +} + +void HexDump::printSelected(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) +{ + if((col > 0) && ((col - 1) < mDescriptor.size())) + { + ColumnDescriptor_t curDescriptor = mDescriptor.at(col - 1); + int wBytePerRowCount = getBytePerRowCount(); + dsint wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset; + int wItemPixWidth = getItemPixelWidth(curDescriptor); + int wCharWidth = getCharWidth(); + if(wItemPixWidth == wCharWidth) + x += 4; + + for(int i = 0; i < curDescriptor.itemCount; i++) + { + int wSelectionX = x + i * wItemPixWidth; + if(isSelected(wRva + i * getSizeOf(curDescriptor.data.itemSize)) == true) + { + int wSelectionWidth = wItemPixWidth > w - (wSelectionX - x) ? w - (wSelectionX - x) : wItemPixWidth; + wSelectionWidth = wSelectionWidth < 0 ? 0 : wSelectionWidth; + painter->setPen(textColor); + painter->fillRect(QRect(wSelectionX, y, wSelectionWidth, h), QBrush(selectionColor)); + } + int separator = curDescriptor.separator; + if(i && separator && !(i % separator)) + { + painter->setPen(separatorColor); + painter->drawLine(wSelectionX, y, wSelectionX, y + h); + } + } + } +} + +/************************************************************************************ + Selection Management +************************************************************************************/ +void HexDump::expandSelectionUpTo(dsint rva) +{ + if(rva < mSelection.firstSelectedIndex) + { + mSelection.fromIndex = rva; + mSelection.toIndex = mSelection.firstSelectedIndex; + emit selectionUpdated(); + } + else if(rva > mSelection.firstSelectedIndex) + { + mSelection.fromIndex = mSelection.firstSelectedIndex; + mSelection.toIndex = rva; + emit selectionUpdated(); + } + else if(rva == mSelection.firstSelectedIndex) + { + setSingleSelection(rva); + } +} + +void HexDump::setSingleSelection(dsint rva) +{ + mSelection.firstSelectedIndex = rva; + mSelection.fromIndex = rva; + mSelection.toIndex = rva; + emit selectionUpdated(); +} + +dsint HexDump::getInitialSelection() +{ + return mSelection.firstSelectedIndex; +} + +dsint HexDump::getSelectionStart() +{ + return mSelection.fromIndex; +} + +dsint HexDump::getSelectionEnd() +{ + return mSelection.toIndex; +} + +bool HexDump::isSelected(dsint rva) +{ + if(rva >= mSelection.fromIndex && rva <= mSelection.toIndex) + return true; + else + return false; +} + +void HexDump::getString(int col, dsint rva, QList* richText) +{ + int wI; + QString wStr = ""; + + int wByteCount = getSizeOf(mDescriptor.at(col).data.itemSize); + int wBufferByteCount = mDescriptor.at(col).itemCount * wByteCount; + + wBufferByteCount = wBufferByteCount > (dsint)(mMemPage->getSize() - rva) ? mMemPage->getSize() - rva : wBufferByteCount; + + byte_t* wData = new byte_t[wBufferByteCount]; + //byte_t wData[mDescriptor.at(col).itemCount * wByteCount]; + + mMemPage->read(wData, rva, wBufferByteCount); + + RichTextPainter::CustomRichText_t curData; + curData.highlight = false; + curData.flags = RichTextPainter::FlagColor; + + QColor highlightColor = ConfigColor("HexDumpModifiedBytesColor"); + + for(wI = 0; wI < mDescriptor.at(col).itemCount && (rva + wI) < (dsint)mMemPage->getSize(); wI++) + { + int maxLen = getStringMaxLength(mDescriptor.at(col).data); + QString append = " "; + if(!maxLen) + append = ""; + if((rva + wI + wByteCount - 1) < (dsint)mMemPage->getSize()) + wStr = toString(mDescriptor.at(col).data, (void*)(wData + wI * wByteCount)).rightJustified(maxLen, ' ') + append; + else + wStr = QString("?").rightJustified(maxLen, ' ') + append; + curData.text = wStr; + dsint start = rvaToVa(rva + wI * wByteCount); + dsint end = start + wByteCount - 1; + curData.textColor = DbgFunctions()->PatchInRange(start, end) ? highlightColor : textColor; + richText->push_back(curData); + } + + delete[] wData; +} + +QString HexDump::toString(DataDescriptor_t desc, void* data) //convert data to string +{ + QString wStr = ""; + + switch(desc.itemSize) + { + case Byte: + { + wStr = byteToString(*((byte_t*)data), desc.byteMode); + } + break; + + case Word: + { + wStr = wordToString(*((uint16*)data), desc.wordMode); + } + break; + + case Dword: + { + wStr = dwordToString(*((uint32*)data), desc.dwordMode); + } + break; + + case Qword: + { + wStr = qwordToString(*((uint64*)data), desc.qwordMode); + } + break; + + case Tword: + { + //TODO: sizeof(long double)=12, not 10 + wStr = twordToString(*((long double*)data), desc.twordMode); + } + break; + + default: + { + + } + break; + } + + return wStr; +} + +QString HexDump::byteToString(byte_t byte, ByteViewMode_e mode) +{ + QString wStr = ""; + + switch(mode) + { + case HexByte: + { + wStr = QString("%1").arg((unsigned char)byte, 2, 16, QChar('0')).toUpper(); + } + break; + + case AsciiByte: + { + QChar wChar = QChar::fromLatin1((char)byte); + + if(wChar.isPrint() == true) + wStr = QString(wChar); + else + wStr = "."; + } + break; + + case SignedDecByte: + { + wStr = QString::number((int)((char)byte)); + } + break; + + case UnsignedDecByte: + { + wStr = QString::number((unsigned int)byte); + } + break; + + default: + { + + } + break; + } + + return wStr; +} + +QString HexDump::wordToString(uint16 word, WordViewMode_e mode) +{ + QString wStr = ""; + + switch(mode) + { + case HexWord: + { + wStr = QString("%1").arg((unsigned short)word, 4, 16, QChar('0')).toUpper(); + } + break; + + case UnicodeWord: + { + QChar wChar = QChar::fromLatin1((char)word & 0xFF); + if(wChar.isPrint() == true && (word >> 8) == 0) + wStr = QString(wChar); + else + wStr = "."; + } + break; + + case SignedDecWord: + { + wStr = QString::number((int)((short)word)); + } + break; + + case UnsignedDecWord: + { + wStr = QString::number((unsigned int)word); + } + break; + + default: + { + + } + break; + } + + return wStr; +} + +QString HexDump::dwordToString(uint32 dword, DwordViewMode_e mode) +{ + QString wStr = ""; + + switch(mode) + { + case HexDword: + { + wStr = QString("%1").arg((unsigned int)dword, 8, 16, QChar('0')).toUpper(); + } + break; + + case SignedDecDword: + { + wStr = QString::number((int)dword); + } + break; + + case UnsignedDecDword: + { + wStr = QString::number((unsigned int)dword); + } + break; + + case FloatDword: + { + float* wPtr = (float*)&dword; + wStr = QString::number((double) * wPtr); + } + break; + + default: + { + + } + break; + } + + return wStr; +} + +QString HexDump::qwordToString(uint64 qword, QwordViewMode_e mode) +{ + QString wStr = ""; + + switch(mode) + { + case HexQword: + { + wStr = QString("%1").arg((unsigned long long)qword, 16, 16, QChar('0')).toUpper(); + } + break; + + case SignedDecQword: + { + wStr = QString::number((long long)qword); + } + break; + + case UnsignedDecQword: + { + wStr = QString::number((unsigned long long)qword); + } + break; + + case DoubleQword: + { + double* wPtr = (double*)&qword; + wStr = QString::number((double) * wPtr); + } + break; + + default: + { + + } + break; + } + + return wStr; +} + +QString HexDump::twordToString(long double tword, TwordViewMode_e mode) +{ + QString wStr = ""; + + switch(mode) + { + case FloatTword: + { + std::stringstream wlongDoubleStr; + wlongDoubleStr << std::scientific << (long double)tword; + + wStr = QString::fromStdString(wlongDoubleStr.str()); + } + break; + + default: + { + + } + break; + } + + return wStr; +} + +int HexDump::getSizeOf(DataSize_e size) +{ + int wSize = 0; + + switch(size) + { + case Byte: // 1 Byte + { + wSize = 1; + } + break; + + case Word: // 2 Bytes + { + wSize = 2; + } + break; + + case Dword: // 4 Bytes + { + wSize = 4; + } + break; + + case Qword: // 8 Bytes + { + wSize = 8; + } + break; + + case Tword: // 10 Bytes + { + wSize = 10; + } + break; + + default: + { + wSize = 0; + } + } + + return wSize; +} + +int HexDump::getStringMaxLength(DataDescriptor_t desc) +{ + int wLength = 0; + + switch(desc.itemSize) + { + case Byte: + { + wLength = byteStringMaxLength(desc.byteMode); + } + break; + + case Word: + { + wLength = wordStringMaxLength(desc.wordMode); + } + break; + + case Dword: + { + wLength = dwordStringMaxLength(desc.dwordMode); + } + break; + + case Qword: + { + wLength = qwordStringMaxLength(desc.qwordMode); + } + break; + + case Tword: + { + wLength = twordStringMaxLength(desc.twordMode); + } + break; + + default: + { + + } + break; + } + + return wLength; +} + +int HexDump::byteStringMaxLength(ByteViewMode_e mode) +{ + int wLength = 0; + + switch(mode) + { + case HexByte: + { + wLength = 2; + } + break; + + case AsciiByte: + { + wLength = 0; + } + break; + + case SignedDecByte: + { + wLength = 4; + } + break; + + case UnsignedDecByte: + { + wLength = 3; + } + break; + + default: + { + + } + break; + } + + return wLength; +} + +int HexDump::wordStringMaxLength(WordViewMode_e mode) +{ + int wLength = 0; + + switch(mode) + { + case HexWord: + { + wLength = 4; + } + break; + + case UnicodeWord: + { + wLength = 0; + } + break; + + case SignedDecWord: + { + wLength = 6; + } + break; + + case UnsignedDecWord: + { + wLength = 5; + } + break; + + default: + { + + } + break; + } + + return wLength; +} + +int HexDump::dwordStringMaxLength(DwordViewMode_e mode) +{ + int wLength = 0; + + switch(mode) + { + case HexDword: + { + wLength = 8; + } + break; + + case SignedDecDword: + { + wLength = 11; + } + break; + + case UnsignedDecDword: + { + wLength = 10; + } + break; + + case FloatDword: + { + wLength = 13; + } + break; + + default: + { + + } + break; + } + + return wLength; +} + +int HexDump::qwordStringMaxLength(QwordViewMode_e mode) +{ + int wLength = 0; + + switch(mode) + { + case HexQword: + { + wLength = 16; + } + break; + + case SignedDecQword: + { + wLength = 20; + } + break; + + case UnsignedDecQword: + { + wLength = 20; + } + break; + + case DoubleQword: + { + wLength = 23; + } + break; + + default: + { + + } + break; + } + + return wLength; +} + +int HexDump::twordStringMaxLength(TwordViewMode_e mode) +{ + int wLength = 0; + + switch(mode) + { + case FloatTword: + { + wLength = 29; + } + break; + + default: + { + + } + break; + } + + return wLength; +} + +int HexDump::getItemIndexFromX(int x) +{ + int wColIndex = getColumnIndexFromX(x); + + if(wColIndex > 0) + { + int wColStartingPos = getColumnPosition(wColIndex); + int wRelativeX = x - wColStartingPos; + + int wItemPixWidth = getItemPixelWidth(mDescriptor.at(wColIndex - 1)); + int wCharWidth = getCharWidth(); + if(wItemPixWidth == wCharWidth) + wRelativeX -= 4; + + int wItemIndex = wRelativeX / wItemPixWidth; + + wItemIndex = wItemIndex < 0 ? 0 : wItemIndex; + wItemIndex = wItemIndex > (mDescriptor.at(wColIndex - 1).itemCount - 1) ? (mDescriptor.at(wColIndex - 1).itemCount - 1) : wItemIndex; + + return wItemIndex; + } + else + { + return 0; + } +} + +dsint HexDump::getItemStartingAddress(int x, int y) +{ + int wRowOffset = getIndexOffsetFromY(transY(y)); + int wItemIndex = getItemIndexFromX(x); + int wColIndex = getColumnIndexFromX(x); + dsint wStartingAddress = 0; + + if(wColIndex > 0) + { + wColIndex -= 1; + wStartingAddress = (getTableOffset() + wRowOffset) * (mDescriptor.at(wColIndex).itemCount * getSizeOf(mDescriptor.at(wColIndex).data.itemSize)) + wItemIndex * getSizeOf(mDescriptor.at(wColIndex).data.itemSize) - mByteOffset; + } + + return wStartingAddress; +} + +int HexDump::getBytePerRowCount() +{ + return mDescriptor.at(0).itemCount * getSizeOf(mDescriptor.at(0).data.itemSize); +} + +int HexDump::getItemPixelWidth(ColumnDescriptor_t desc) +{ + int wCharWidth = getCharWidth(); + int wItemPixWidth = getStringMaxLength(desc.data) * wCharWidth + wCharWidth; + + return wItemPixWidth; +} + +void HexDump::appendDescriptor(int width, QString title, bool clickable, ColumnDescriptor_t descriptor) +{ + addColumnAt(width, title, clickable); + mDescriptor.append(descriptor); +} + +//Clears the descriptors, append a new descriptor and fix the tableOffset (use this instead of clearDescriptors() +void HexDump::appendResetDescriptor(int width, QString title, bool clickable, ColumnDescriptor_t descriptor) +{ + mAllowPainting = false; + if(mDescriptor.size()) + { + dsint wRVA = getTableOffset() * getBytePerRowCount() - mByteOffset; + clearDescriptors(); + appendDescriptor(width, title, clickable, descriptor); + printDumpAt(rvaToVa(wRVA), true, false); + } + else + appendDescriptor(width, title, clickable, descriptor); + mAllowPainting = true; +} + +void HexDump::clearDescriptors() +{ + deleteAllColumns(); + mDescriptor.clear(); + int charwidth = getCharWidth(); + addColumnAt(8 + charwidth * 2 * sizeof(duint), "Address", false); //address +} + +void HexDump::debugStateChanged(DBGSTATE state) +{ + if(state == stopped) + { + mMemPage->setAttributes(0, 0); + setRowCount(0); + reloadData(); + } +} diff --git a/src/gui/Src/BasicView/HexDump.h b/src/gui/Src/BasicView/HexDump.h index e36db3f0..60d31588 100644 --- a/src/gui/Src/BasicView/HexDump.h +++ b/src/gui/Src/BasicView/HexDump.h @@ -1,168 +1,168 @@ -#ifndef _HEXDUMP_H -#define _HEXDUMP_H - -#include "AbstractTableView.h" -#include "RichTextPainter.h" -#include "MemoryPage.h" - -class HexDump : public AbstractTableView -{ - Q_OBJECT -public: - enum DataSize_e - { - Byte, - Word, - Dword, - Qword, - Tword - }; - - enum ByteViewMode_e - { - HexByte, - AsciiByte, - SignedDecByte, - UnsignedDecByte - }; - - enum WordViewMode_e - { - HexWord, - UnicodeWord, - SignedDecWord, - UnsignedDecWord - }; - - enum DwordViewMode_e - { - HexDword, - SignedDecDword, - UnsignedDecDword, - FloatDword //sizeof(float)=4 - }; - - enum QwordViewMode_e - { - HexQword, - SignedDecQword, - UnsignedDecQword, - DoubleQword //sizeof(double)=8 - }; - - enum TwordViewMode_e - { - FloatTword - }; - - typedef struct _DataDescriptor_t - { - DataSize_e itemSize; // Items size - union // View mode - { - ByteViewMode_e byteMode; - WordViewMode_e wordMode; - DwordViewMode_e dwordMode; - QwordViewMode_e qwordMode; - TwordViewMode_e twordMode; - }; - } DataDescriptor_t; - - typedef struct _ColumnDescriptor_t - { - bool isData; - int itemCount; - int separator; - DataDescriptor_t data; - } ColumnDescriptor_t; - - explicit HexDump(QWidget* parent = 0); - - // Configuration - virtual void updateColors(); - virtual void updateFonts(); - - //QString getStringToPrint(int rowBase, int rowOffset, int col); - void mouseMoveEvent(QMouseEvent* event); - void mousePressEvent(QMouseEvent* event); - void mouseReleaseEvent(QMouseEvent* event); - - QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); - void paintGraphicDump(QPainter* painter, int x, int y, int addr); - - void printSelected(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); - - // Selection Management - void expandSelectionUpTo(dsint rva); - void setSingleSelection(dsint rva); - dsint getInitialSelection(); - dsint getSelectionStart(); - dsint getSelectionEnd(); - bool isSelected(dsint rva); - - void getString(int col, dsint rva, QList* richText); - int getSizeOf(DataSize_e size); - - QString toString(DataDescriptor_t desc, void* data); - - QString byteToString(byte_t byte, ByteViewMode_e mode); - QString wordToString(uint16 word, WordViewMode_e mode); - QString dwordToString(uint32 dword, DwordViewMode_e mode); - QString qwordToString(uint64 qword, QwordViewMode_e mode); - QString twordToString(long double tword, TwordViewMode_e mode); - - int getStringMaxLength(DataDescriptor_t desc); - - int byteStringMaxLength(ByteViewMode_e mode); - int wordStringMaxLength(WordViewMode_e mode); - int dwordStringMaxLength(DwordViewMode_e mode); - int qwordStringMaxLength(QwordViewMode_e mode); - int twordStringMaxLength(TwordViewMode_e mode); - - int getItemIndexFromX(int x); - dsint getItemStartingAddress(int x, int y); - - int getBytePerRowCount(); - int getItemPixelWidth(ColumnDescriptor_t desc); - - //descriptor management - void appendDescriptor(int width, QString title, bool clickable, ColumnDescriptor_t descriptor); - void appendResetDescriptor(int width, QString title, bool clickable, ColumnDescriptor_t descriptor); - void clearDescriptors(); - - void printDumpAt(dsint parVA, bool select, bool repaint = true); - duint rvaToVa(dsint rva); - duint getTableOffsetRva(); - -signals: - void selectionUpdated(); - -public slots: - void printDumpAt(dsint parVA); - void debugStateChanged(DBGSTATE state); - -private: - enum GuiState_t {NoState, MultiRowsSelectionState}; - - typedef struct _RowDescriptor_t - { - dsint firstSelectedIndex; - dsint fromIndex; - dsint toIndex; - } SelectionData_t; - - SelectionData_t mSelection; - - GuiState_t mGuiState; - -protected: - MemoryPage* mMemPage; - int mByteOffset; - QList mDescriptor; - int mForceColumn; - bool mRvaDisplayEnabled; - duint mRvaDisplayBase; - dsint mRvaDisplayPageBase; -}; - -#endif // _HEXDUMP_H +#ifndef _HEXDUMP_H +#define _HEXDUMP_H + +#include "AbstractTableView.h" +#include "RichTextPainter.h" +#include "MemoryPage.h" + +class HexDump : public AbstractTableView +{ + Q_OBJECT +public: + enum DataSize_e + { + Byte, + Word, + Dword, + Qword, + Tword + }; + + enum ByteViewMode_e + { + HexByte, + AsciiByte, + SignedDecByte, + UnsignedDecByte + }; + + enum WordViewMode_e + { + HexWord, + UnicodeWord, + SignedDecWord, + UnsignedDecWord + }; + + enum DwordViewMode_e + { + HexDword, + SignedDecDword, + UnsignedDecDword, + FloatDword //sizeof(float)=4 + }; + + enum QwordViewMode_e + { + HexQword, + SignedDecQword, + UnsignedDecQword, + DoubleQword //sizeof(double)=8 + }; + + enum TwordViewMode_e + { + FloatTword + }; + + typedef struct _DataDescriptor_t + { + DataSize_e itemSize; // Items size + union // View mode + { + ByteViewMode_e byteMode; + WordViewMode_e wordMode; + DwordViewMode_e dwordMode; + QwordViewMode_e qwordMode; + TwordViewMode_e twordMode; + }; + } DataDescriptor_t; + + typedef struct _ColumnDescriptor_t + { + bool isData; + int itemCount; + int separator; + DataDescriptor_t data; + } ColumnDescriptor_t; + + explicit HexDump(QWidget* parent = 0); + + // Configuration + virtual void updateColors(); + virtual void updateFonts(); + + //QString getStringToPrint(int rowBase, int rowOffset, int col); + void mouseMoveEvent(QMouseEvent* event); + void mousePressEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event); + + QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); + void paintGraphicDump(QPainter* painter, int x, int y, int addr); + + void printSelected(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); + + // Selection Management + void expandSelectionUpTo(dsint rva); + void setSingleSelection(dsint rva); + dsint getInitialSelection(); + dsint getSelectionStart(); + dsint getSelectionEnd(); + bool isSelected(dsint rva); + + void getString(int col, dsint rva, QList* richText); + int getSizeOf(DataSize_e size); + + QString toString(DataDescriptor_t desc, void* data); + + QString byteToString(byte_t byte, ByteViewMode_e mode); + QString wordToString(uint16 word, WordViewMode_e mode); + QString dwordToString(uint32 dword, DwordViewMode_e mode); + QString qwordToString(uint64 qword, QwordViewMode_e mode); + QString twordToString(long double tword, TwordViewMode_e mode); + + int getStringMaxLength(DataDescriptor_t desc); + + int byteStringMaxLength(ByteViewMode_e mode); + int wordStringMaxLength(WordViewMode_e mode); + int dwordStringMaxLength(DwordViewMode_e mode); + int qwordStringMaxLength(QwordViewMode_e mode); + int twordStringMaxLength(TwordViewMode_e mode); + + int getItemIndexFromX(int x); + dsint getItemStartingAddress(int x, int y); + + int getBytePerRowCount(); + int getItemPixelWidth(ColumnDescriptor_t desc); + + //descriptor management + void appendDescriptor(int width, QString title, bool clickable, ColumnDescriptor_t descriptor); + void appendResetDescriptor(int width, QString title, bool clickable, ColumnDescriptor_t descriptor); + void clearDescriptors(); + + void printDumpAt(dsint parVA, bool select, bool repaint = true); + duint rvaToVa(dsint rva); + duint getTableOffsetRva(); + +signals: + void selectionUpdated(); + +public slots: + void printDumpAt(dsint parVA); + void debugStateChanged(DBGSTATE state); + +private: + enum GuiState_t {NoState, MultiRowsSelectionState}; + + typedef struct _RowDescriptor_t + { + dsint firstSelectedIndex; + dsint fromIndex; + dsint toIndex; + } SelectionData_t; + + SelectionData_t mSelection; + + GuiState_t mGuiState; + +protected: + MemoryPage* mMemPage; + int mByteOffset; + QList mDescriptor; + int mForceColumn; + bool mRvaDisplayEnabled; + duint mRvaDisplayBase; + dsint mRvaDisplayPageBase; +}; + +#endif // _HEXDUMP_H diff --git a/src/gui/Src/BasicView/HistoryLineEdit.cpp b/src/gui/Src/BasicView/HistoryLineEdit.cpp index a41d6cca..2efa023a 100644 --- a/src/gui/Src/BasicView/HistoryLineEdit.cpp +++ b/src/gui/Src/BasicView/HistoryLineEdit.cpp @@ -1,67 +1,67 @@ -#include "HistoryLineEdit.h" - -HistoryLineEdit::HistoryLineEdit(QWidget* parent) : QLineEdit(parent) -{ - mCmdHistory.clear(); - mCmdIndex = -1; - bSixPressed = false; -} - -void HistoryLineEdit::addLineToHistory(QString parLine) -{ - mCmdHistory.prepend(parLine); - - if(mCmdHistory.size() > 32) - mCmdHistory.removeLast(); - - mCmdIndex = -1; -} - -void HistoryLineEdit::keyPressEvent(QKeyEvent* event) -{ - int wKey = event->key(); - - //This fixes a very annoying bug on some systems - if(bSixPressed) - { - bSixPressed = false; - if(event->text() == "^") - { - event->ignore(); - return; - } - } - if(wKey == Qt::Key_6) - bSixPressed = true; - - if(wKey == Qt::Key_Up || wKey == Qt::Key_Down) - { - if(wKey == Qt::Key_Up) - mCmdIndex++; - else if(wKey == Qt::Key_Down) - mCmdIndex--; - - mCmdIndex = mCmdIndex < -1 ? -1 : mCmdIndex; - mCmdIndex = mCmdIndex > mCmdHistory.size() - 1 ? mCmdHistory.size() - 1 : mCmdIndex; - - // Set the new text if an existing command was available - QString newText(""); - - if(mCmdIndex != -1) - newText = mCmdHistory.at(mCmdIndex); - - // Quote from QT docs: "Unlike textChanged(), this signal is not emitted when - // the text is changed programmatically, for example, by calling setText()." - setText(newText); - emit textEdited(newText); - } - - QLineEdit::keyPressEvent(event); -} - -void HistoryLineEdit::setFocus() -{ - mCmdIndex = -1; - QLineEdit::setFocus(); -} - +#include "HistoryLineEdit.h" + +HistoryLineEdit::HistoryLineEdit(QWidget* parent) : QLineEdit(parent) +{ + mCmdHistory.clear(); + mCmdIndex = -1; + bSixPressed = false; +} + +void HistoryLineEdit::addLineToHistory(QString parLine) +{ + mCmdHistory.prepend(parLine); + + if(mCmdHistory.size() > 32) + mCmdHistory.removeLast(); + + mCmdIndex = -1; +} + +void HistoryLineEdit::keyPressEvent(QKeyEvent* event) +{ + int wKey = event->key(); + + //This fixes a very annoying bug on some systems + if(bSixPressed) + { + bSixPressed = false; + if(event->text() == "^") + { + event->ignore(); + return; + } + } + if(wKey == Qt::Key_6) + bSixPressed = true; + + if(wKey == Qt::Key_Up || wKey == Qt::Key_Down) + { + if(wKey == Qt::Key_Up) + mCmdIndex++; + else if(wKey == Qt::Key_Down) + mCmdIndex--; + + mCmdIndex = mCmdIndex < -1 ? -1 : mCmdIndex; + mCmdIndex = mCmdIndex > mCmdHistory.size() - 1 ? mCmdHistory.size() - 1 : mCmdIndex; + + // Set the new text if an existing command was available + QString newText(""); + + if(mCmdIndex != -1) + newText = mCmdHistory.at(mCmdIndex); + + // Quote from QT docs: "Unlike textChanged(), this signal is not emitted when + // the text is changed programmatically, for example, by calling setText()." + setText(newText); + emit textEdited(newText); + } + + QLineEdit::keyPressEvent(event); +} + +void HistoryLineEdit::setFocus() +{ + mCmdIndex = -1; + QLineEdit::setFocus(); +} + diff --git a/src/gui/Src/BasicView/HistoryLineEdit.h b/src/gui/Src/BasicView/HistoryLineEdit.h index 04c13e82..c4ee8ad8 100644 --- a/src/gui/Src/BasicView/HistoryLineEdit.h +++ b/src/gui/Src/BasicView/HistoryLineEdit.h @@ -1,26 +1,26 @@ -#ifndef HISTORYLINEEDIT_H -#define HISTORYLINEEDIT_H - -#include -#include - -class HistoryLineEdit : public QLineEdit -{ - Q_OBJECT -public: - explicit HistoryLineEdit(QWidget* parent = 0); - void keyPressEvent(QKeyEvent* event); - void addLineToHistory(QString parLine); - void setFocus(); - -signals: - void keyPressed(int parKey); - -private: - QList mCmdHistory; - int mCmdIndex; - bool bSixPressed; - -}; - -#endif // HISTORYLINEEDIT_H +#ifndef HISTORYLINEEDIT_H +#define HISTORYLINEEDIT_H + +#include +#include + +class HistoryLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit HistoryLineEdit(QWidget* parent = 0); + void keyPressEvent(QKeyEvent* event); + void addLineToHistory(QString parLine); + void setFocus(); + +signals: + void keyPressed(int parKey); + +private: + QList mCmdHistory; + int mCmdIndex; + bool bSixPressed; + +}; + +#endif // HISTORYLINEEDIT_H diff --git a/src/gui/Src/BasicView/ReferenceView.cpp b/src/gui/Src/BasicView/ReferenceView.cpp index 0dd08bd5..44ea53f7 100644 --- a/src/gui/Src/BasicView/ReferenceView.cpp +++ b/src/gui/Src/BasicView/ReferenceView.cpp @@ -1,260 +1,260 @@ -#include "ReferenceView.h" -#include -#include "Configuration.h" -#include "Bridge.h" -#include - -ReferenceView::ReferenceView() -{ - // Setup SearchListView settings - mSearchStartCol = 1; - mFollowDumpDefault = false; - - QHBoxLayout* layout = new QHBoxLayout(); - - // Create search progress bar - mSearchProgress = new QProgressBar(); - mSearchProgress->setRange(0, 100); - mSearchProgress->setTextVisible(false); - mSearchProgress->setMaximumHeight(15); - layout->addWidget(mSearchProgress); - - // Label for the number of references - mCountLabel = new QLabel("tst"); - mCountLabel->setAlignment(Qt::AlignCenter); - mCountLabel->setMaximumHeight(16); - mCountLabel->setMinimumWidth(40); - mCountLabel->setContentsMargins(2, 0, 5, 0); - layout->addWidget(mCountLabel); - - // Add the progress bar and label to the main layout - mMainLayout->addLayout(layout); - - // Setup signals - connect(Bridge::getBridge(), SIGNAL(referenceAddColumnAt(int, QString)), this, SLOT(addColumnAt(int, QString))); - connect(Bridge::getBridge(), SIGNAL(referenceSetRowCount(dsint)), this, SLOT(setRowCount(dsint))); - connect(Bridge::getBridge(), SIGNAL(referenceSetCellContent(int, int, QString)), this, SLOT(setCellContent(int, int, QString))); - connect(Bridge::getBridge(), SIGNAL(referenceReloadData()), this, SLOT(reloadData())); - connect(Bridge::getBridge(), SIGNAL(referenceSetSingleSelection(int, bool)), this, SLOT(setSingleSelection(int, bool))); - connect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), mSearchProgress, SLOT(setValue(int))); - connect(Bridge::getBridge(), SIGNAL(referenceSetSearchStartCol(int)), this, SLOT(setSearchStartCol(int))); - connect(this, SIGNAL(listContextMenuSignal(QMenu*)), this, SLOT(referenceContextMenu(QMenu*))); - connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followGenericAddress())); - - setupContextMenu(); -} - -void ReferenceView::setupContextMenu() -{ - mFollowAddress = new QAction("&Follow in Disassembler", this); - connect(mFollowAddress, SIGNAL(triggered()), this, SLOT(followAddress())); - - mFollowDumpAddress = new QAction("Follow in &Dump", this); - connect(mFollowDumpAddress, SIGNAL(triggered()), this, SLOT(followDumpAddress())); - - mFollowApiAddress = new QAction("Follow &API Address", this); - connect(mFollowApiAddress, SIGNAL(triggered()), this, SLOT(followApiAddress())); - - mToggleBreakpoint = new QAction("Toggle Breakpoint", this); - mToggleBreakpoint->setShortcutContext(Qt::WidgetShortcut); - addAction(mToggleBreakpoint); - mList->addAction(mToggleBreakpoint); - mSearchList->addAction(mToggleBreakpoint); - connect(mToggleBreakpoint, SIGNAL(triggered()), this, SLOT(toggleBreakpoint())); - - mToggleBookmark = new QAction("Toggle Bookmark", this); - mToggleBookmark->setShortcutContext(Qt::WidgetShortcut); - addAction(mToggleBookmark); - mList->addAction(mToggleBookmark); - mSearchList->addAction(mToggleBookmark); - connect(mToggleBookmark, SIGNAL(triggered()), this, SLOT(toggleBookmark())); - - refreshShortcutsSlot(); - connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); -} - -void ReferenceView::disconnectBridge() -{ - disconnect(Bridge::getBridge(), SIGNAL(referenceAddColumnAt(int, QString)), this, SLOT(addColumnAt(int, QString))); - disconnect(Bridge::getBridge(), SIGNAL(referenceSetRowCount(dsint)), this, SLOT(setRowCount(dsint))); - disconnect(Bridge::getBridge(), SIGNAL(referenceSetCellContent(int, int, QString)), this, SLOT(setCellContent(int, int, QString))); - disconnect(Bridge::getBridge(), SIGNAL(referenceReloadData()), this, SLOT(reloadData())); - disconnect(Bridge::getBridge(), SIGNAL(referenceSetSingleSelection(int, bool)), this, SLOT(setSingleSelection(int, bool))); - disconnect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), mSearchProgress, SLOT(setValue(int))); - disconnect(Bridge::getBridge(), SIGNAL(referenceSetSearchStartCol(int)), this, SLOT(setSearchStartCol(int))); -} - -void ReferenceView::refreshShortcutsSlot() -{ - mToggleBreakpoint->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); - mToggleBookmark->setShortcut(ConfigShortcut("ActionToggleBookmark")); -} - -void ReferenceView::addColumnAt(int width, QString title) -{ - int charwidth = mList->getCharWidth(); - if(width) - width = charwidth * width + 8; - else - width = 0; - mSearchBox->setText(""); - if(title.toLower() == "&data&") - { - mFollowDumpDefault = true; - title = "Data"; - } - mList->addColumnAt(width, title, true); - mSearchList->addColumnAt(width, title, true); -} - -void ReferenceView::setRowCount(dsint count) -{ - emit mCountLabel->setText(QString("%1").arg(count)); - mSearchBox->setText(""); - mList->setRowCount(count); -} - -void ReferenceView::setCellContent(int r, int c, QString s) -{ - mSearchBox->setText(""); - mList->setCellContent(r, c, s); -} - -void ReferenceView::reloadData() -{ - mSearchBox->setText(""); - mList->reloadData(); -} - -void ReferenceView::setSingleSelection(int index, bool scroll) -{ - mSearchBox->setText(""); - mList->setSingleSelection(index); - if(scroll) //TODO: better scrolling - mList->setTableOffset(index); -} - -void ReferenceView::setSearchStartCol(int col) -{ - if(col < mList->getColumnCount()) - mSearchStartCol = col; -} - -void ReferenceView::referenceContextMenu(QMenu* wMenu) -{ - if(!mCurList->getRowCount()) - return; - QString text = mCurList->getCellContent(mCurList->getInitialSelection(), 0); - duint addr; - if(!DbgFunctions()->ValFromString(text.toUtf8().constData(), &addr)) - return; - if(!DbgMemIsValidReadPtr(addr)) - return; - wMenu->addAction(mFollowAddress); - wMenu->addAction(mFollowDumpAddress); - if(apiAddressFromString(mCurList->getCellContent(mCurList->getInitialSelection(), 1))) - wMenu->addAction(mFollowApiAddress); - wMenu->addSeparator(); - wMenu->addAction(mToggleBreakpoint); - wMenu->addAction(mToggleBookmark); -} - -void ReferenceView::followAddress() -{ - DbgCmdExecDirect(QString("disasm " + mCurList->getCellContent(mCurList->getInitialSelection(), 0)).toUtf8().constData()); - emit showCpu(); -} - -void ReferenceView::followDumpAddress() -{ - DbgCmdExecDirect(QString("dump " + mCurList->getCellContent(mCurList->getInitialSelection(), 0)).toUtf8().constData()); - emit showCpu(); -} - -void ReferenceView::followApiAddress() -{ - dsint apiValue = apiAddressFromString(mCurList->getCellContent(mCurList->getInitialSelection(), 1)); - DbgCmdExecDirect(QString("disasm " + QString().sprintf("%p", apiValue)).toUtf8().constData()); - emit showCpu(); -} - -void ReferenceView::followGenericAddress() -{ - if(mFollowDumpDefault) - followDumpAddress(); - else - followAddress(); -} - -void ReferenceView::toggleBreakpoint() -{ - if(!DbgIsDebugging()) - return; - - if(!mCurList->getRowCount()) - return; - QString addrText = mCurList->getCellContent(mCurList->getInitialSelection(), 0).toUtf8().constData(); - duint wVA; - if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &wVA)) - return; - if(!DbgMemIsValidReadPtr(wVA)) - return; - - BPXTYPE wBpType = DbgGetBpxTypeAt(wVA); - QString wCmd; - - if((wBpType & bp_normal) == bp_normal) - { - wCmd = "bc " + QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - else - { - wCmd = "bp " + QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - - DbgCmdExec(wCmd.toUtf8().constData()); -} - -void ReferenceView::toggleBookmark() -{ - if(!DbgIsDebugging()) - return; - - if(!mCurList->getRowCount()) - return; - QString addrText = mCurList->getCellContent(mCurList->getInitialSelection(), 0); - duint wVA; - if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &wVA)) - return; - if(!DbgMemIsValidReadPtr(wVA)) - return; - - bool result; - if(DbgGetBookmarkAt(wVA)) - result = DbgSetBookmarkAt(wVA, false); - else - result = DbgSetBookmarkAt(wVA, true); - if(!result) - { - QMessageBox msg(QMessageBox::Critical, "Error!", "DbgSetBookmarkAt failed!"); - msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - } - GuiUpdateAllViews(); -} - -dsint ReferenceView::apiAddressFromString(const QString & s) -{ - QRegExp regEx("call.+<(.+)>"); - regEx.indexIn(s); - QStringList list = regEx.capturedTexts(); - if(list.length() < 2) - return 0; - QString match = list[1]; - if(match[0] == QChar('&')) - match.remove(0, 1); - duint value; - return DbgFunctions()->ValFromString(match.toUtf8().constData(), &value) && DbgMemIsValidReadPtr(value) ? value : 0; -} +#include "ReferenceView.h" +#include +#include "Configuration.h" +#include "Bridge.h" +#include + +ReferenceView::ReferenceView() +{ + // Setup SearchListView settings + mSearchStartCol = 1; + mFollowDumpDefault = false; + + QHBoxLayout* layout = new QHBoxLayout(); + + // Create search progress bar + mSearchProgress = new QProgressBar(); + mSearchProgress->setRange(0, 100); + mSearchProgress->setTextVisible(false); + mSearchProgress->setMaximumHeight(15); + layout->addWidget(mSearchProgress); + + // Label for the number of references + mCountLabel = new QLabel("tst"); + mCountLabel->setAlignment(Qt::AlignCenter); + mCountLabel->setMaximumHeight(16); + mCountLabel->setMinimumWidth(40); + mCountLabel->setContentsMargins(2, 0, 5, 0); + layout->addWidget(mCountLabel); + + // Add the progress bar and label to the main layout + mMainLayout->addLayout(layout); + + // Setup signals + connect(Bridge::getBridge(), SIGNAL(referenceAddColumnAt(int, QString)), this, SLOT(addColumnAt(int, QString))); + connect(Bridge::getBridge(), SIGNAL(referenceSetRowCount(dsint)), this, SLOT(setRowCount(dsint))); + connect(Bridge::getBridge(), SIGNAL(referenceSetCellContent(int, int, QString)), this, SLOT(setCellContent(int, int, QString))); + connect(Bridge::getBridge(), SIGNAL(referenceReloadData()), this, SLOT(reloadData())); + connect(Bridge::getBridge(), SIGNAL(referenceSetSingleSelection(int, bool)), this, SLOT(setSingleSelection(int, bool))); + connect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), mSearchProgress, SLOT(setValue(int))); + connect(Bridge::getBridge(), SIGNAL(referenceSetSearchStartCol(int)), this, SLOT(setSearchStartCol(int))); + connect(this, SIGNAL(listContextMenuSignal(QMenu*)), this, SLOT(referenceContextMenu(QMenu*))); + connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followGenericAddress())); + + setupContextMenu(); +} + +void ReferenceView::setupContextMenu() +{ + mFollowAddress = new QAction("&Follow in Disassembler", this); + connect(mFollowAddress, SIGNAL(triggered()), this, SLOT(followAddress())); + + mFollowDumpAddress = new QAction("Follow in &Dump", this); + connect(mFollowDumpAddress, SIGNAL(triggered()), this, SLOT(followDumpAddress())); + + mFollowApiAddress = new QAction("Follow &API Address", this); + connect(mFollowApiAddress, SIGNAL(triggered()), this, SLOT(followApiAddress())); + + mToggleBreakpoint = new QAction("Toggle Breakpoint", this); + mToggleBreakpoint->setShortcutContext(Qt::WidgetShortcut); + addAction(mToggleBreakpoint); + mList->addAction(mToggleBreakpoint); + mSearchList->addAction(mToggleBreakpoint); + connect(mToggleBreakpoint, SIGNAL(triggered()), this, SLOT(toggleBreakpoint())); + + mToggleBookmark = new QAction("Toggle Bookmark", this); + mToggleBookmark->setShortcutContext(Qt::WidgetShortcut); + addAction(mToggleBookmark); + mList->addAction(mToggleBookmark); + mSearchList->addAction(mToggleBookmark); + connect(mToggleBookmark, SIGNAL(triggered()), this, SLOT(toggleBookmark())); + + refreshShortcutsSlot(); + connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); +} + +void ReferenceView::disconnectBridge() +{ + disconnect(Bridge::getBridge(), SIGNAL(referenceAddColumnAt(int, QString)), this, SLOT(addColumnAt(int, QString))); + disconnect(Bridge::getBridge(), SIGNAL(referenceSetRowCount(dsint)), this, SLOT(setRowCount(dsint))); + disconnect(Bridge::getBridge(), SIGNAL(referenceSetCellContent(int, int, QString)), this, SLOT(setCellContent(int, int, QString))); + disconnect(Bridge::getBridge(), SIGNAL(referenceReloadData()), this, SLOT(reloadData())); + disconnect(Bridge::getBridge(), SIGNAL(referenceSetSingleSelection(int, bool)), this, SLOT(setSingleSelection(int, bool))); + disconnect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), mSearchProgress, SLOT(setValue(int))); + disconnect(Bridge::getBridge(), SIGNAL(referenceSetSearchStartCol(int)), this, SLOT(setSearchStartCol(int))); +} + +void ReferenceView::refreshShortcutsSlot() +{ + mToggleBreakpoint->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); + mToggleBookmark->setShortcut(ConfigShortcut("ActionToggleBookmark")); +} + +void ReferenceView::addColumnAt(int width, QString title) +{ + int charwidth = mList->getCharWidth(); + if(width) + width = charwidth * width + 8; + else + width = 0; + mSearchBox->setText(""); + if(title.toLower() == "&data&") + { + mFollowDumpDefault = true; + title = "Data"; + } + mList->addColumnAt(width, title, true); + mSearchList->addColumnAt(width, title, true); +} + +void ReferenceView::setRowCount(dsint count) +{ + emit mCountLabel->setText(QString("%1").arg(count)); + mSearchBox->setText(""); + mList->setRowCount(count); +} + +void ReferenceView::setCellContent(int r, int c, QString s) +{ + mSearchBox->setText(""); + mList->setCellContent(r, c, s); +} + +void ReferenceView::reloadData() +{ + mSearchBox->setText(""); + mList->reloadData(); +} + +void ReferenceView::setSingleSelection(int index, bool scroll) +{ + mSearchBox->setText(""); + mList->setSingleSelection(index); + if(scroll) //TODO: better scrolling + mList->setTableOffset(index); +} + +void ReferenceView::setSearchStartCol(int col) +{ + if(col < mList->getColumnCount()) + mSearchStartCol = col; +} + +void ReferenceView::referenceContextMenu(QMenu* wMenu) +{ + if(!mCurList->getRowCount()) + return; + QString text = mCurList->getCellContent(mCurList->getInitialSelection(), 0); + duint addr; + if(!DbgFunctions()->ValFromString(text.toUtf8().constData(), &addr)) + return; + if(!DbgMemIsValidReadPtr(addr)) + return; + wMenu->addAction(mFollowAddress); + wMenu->addAction(mFollowDumpAddress); + if(apiAddressFromString(mCurList->getCellContent(mCurList->getInitialSelection(), 1))) + wMenu->addAction(mFollowApiAddress); + wMenu->addSeparator(); + wMenu->addAction(mToggleBreakpoint); + wMenu->addAction(mToggleBookmark); +} + +void ReferenceView::followAddress() +{ + DbgCmdExecDirect(QString("disasm " + mCurList->getCellContent(mCurList->getInitialSelection(), 0)).toUtf8().constData()); + emit showCpu(); +} + +void ReferenceView::followDumpAddress() +{ + DbgCmdExecDirect(QString("dump " + mCurList->getCellContent(mCurList->getInitialSelection(), 0)).toUtf8().constData()); + emit showCpu(); +} + +void ReferenceView::followApiAddress() +{ + dsint apiValue = apiAddressFromString(mCurList->getCellContent(mCurList->getInitialSelection(), 1)); + DbgCmdExecDirect(QString("disasm " + QString().sprintf("%p", apiValue)).toUtf8().constData()); + emit showCpu(); +} + +void ReferenceView::followGenericAddress() +{ + if(mFollowDumpDefault) + followDumpAddress(); + else + followAddress(); +} + +void ReferenceView::toggleBreakpoint() +{ + if(!DbgIsDebugging()) + return; + + if(!mCurList->getRowCount()) + return; + QString addrText = mCurList->getCellContent(mCurList->getInitialSelection(), 0).toUtf8().constData(); + duint wVA; + if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &wVA)) + return; + if(!DbgMemIsValidReadPtr(wVA)) + return; + + BPXTYPE wBpType = DbgGetBpxTypeAt(wVA); + QString wCmd; + + if((wBpType & bp_normal) == bp_normal) + { + wCmd = "bc " + QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + else + { + wCmd = "bp " + QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + + DbgCmdExec(wCmd.toUtf8().constData()); +} + +void ReferenceView::toggleBookmark() +{ + if(!DbgIsDebugging()) + return; + + if(!mCurList->getRowCount()) + return; + QString addrText = mCurList->getCellContent(mCurList->getInitialSelection(), 0); + duint wVA; + if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &wVA)) + return; + if(!DbgMemIsValidReadPtr(wVA)) + return; + + bool result; + if(DbgGetBookmarkAt(wVA)) + result = DbgSetBookmarkAt(wVA, false); + else + result = DbgSetBookmarkAt(wVA, true); + if(!result) + { + QMessageBox msg(QMessageBox::Critical, "Error!", "DbgSetBookmarkAt failed!"); + msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + } + GuiUpdateAllViews(); +} + +dsint ReferenceView::apiAddressFromString(const QString & s) +{ + QRegExp regEx("call.+<(.+)>"); + regEx.indexIn(s); + QStringList list = regEx.capturedTexts(); + if(list.length() < 2) + return 0; + QString match = list[1]; + if(match[0] == QChar('&')) + match.remove(0, 1); + duint value; + return DbgFunctions()->ValFromString(match.toUtf8().constData(), &value) && DbgMemIsValidReadPtr(value) ? value : 0; +} diff --git a/src/gui/Src/BasicView/ReferenceView.h b/src/gui/Src/BasicView/ReferenceView.h index 922982bf..07633283 100644 --- a/src/gui/Src/BasicView/ReferenceView.h +++ b/src/gui/Src/BasicView/ReferenceView.h @@ -1,49 +1,49 @@ -#ifndef REFERENCEVIEW_H -#define REFERENCEVIEW_H - -#include -#include -#include "SearchListView.h" - -class ReferenceView : public SearchListView -{ - Q_OBJECT - -public: - ReferenceView(); - void setupContextMenu(); - void disconnectBridge(); - -private slots: - void addColumnAt(int width, QString title); - void setRowCount(dsint count); - void setCellContent(int r, int c, QString s); - void reloadData(); - void setSingleSelection(int index, bool scroll); - void setSearchStartCol(int col); - void referenceContextMenu(QMenu* wMenu); - void followAddress(); - void followDumpAddress(); - void followApiAddress(); - void followGenericAddress(); - void toggleBreakpoint(); - void toggleBookmark(); - void refreshShortcutsSlot(); - -signals: - void showCpu(); - -private: - QProgressBar* mSearchProgress; - QAction* mFollowAddress; - QAction* mFollowDumpAddress; - QAction* mFollowApiAddress; - QAction* mToggleBreakpoint; - QAction* mToggleBookmark; - bool mFollowDumpDefault; - QLabel* mCountLabel; - - dsint apiAddressFromString(const QString & s); -}; - -#endif // REFERENCEVIEW_H +#ifndef REFERENCEVIEW_H +#define REFERENCEVIEW_H + +#include +#include +#include "SearchListView.h" + +class ReferenceView : public SearchListView +{ + Q_OBJECT + +public: + ReferenceView(); + void setupContextMenu(); + void disconnectBridge(); + +private slots: + void addColumnAt(int width, QString title); + void setRowCount(dsint count); + void setCellContent(int r, int c, QString s); + void reloadData(); + void setSingleSelection(int index, bool scroll); + void setSearchStartCol(int col); + void referenceContextMenu(QMenu* wMenu); + void followAddress(); + void followDumpAddress(); + void followApiAddress(); + void followGenericAddress(); + void toggleBreakpoint(); + void toggleBookmark(); + void refreshShortcutsSlot(); + +signals: + void showCpu(); + +private: + QProgressBar* mSearchProgress; + QAction* mFollowAddress; + QAction* mFollowDumpAddress; + QAction* mFollowApiAddress; + QAction* mToggleBreakpoint; + QAction* mToggleBookmark; + bool mFollowDumpDefault; + QLabel* mCountLabel; + + dsint apiAddressFromString(const QString & s); +}; + +#endif // REFERENCEVIEW_H diff --git a/src/gui/Src/BasicView/SearchListView.cpp b/src/gui/Src/BasicView/SearchListView.cpp index e14e43e9..7b525629 100644 --- a/src/gui/Src/BasicView/SearchListView.cpp +++ b/src/gui/Src/BasicView/SearchListView.cpp @@ -1,205 +1,205 @@ -#include "SearchListView.h" -#include "ui_SearchListView.h" -#include "FlickerThread.h" - -SearchListView::SearchListView(QWidget* parent) : - QWidget(parent), - ui(new Ui::SearchListView) -{ - ui->setupUi(this); - - setContextMenuPolicy(Qt::CustomContextMenu); - - // Create the reference list - mList = new SearchListViewTable(); - - // Create the search list - mSearchList = new SearchListViewTable(); - mSearchList->hide(); - - // Set global variables - mSearchBox = ui->searchBox; - mCurList = mList; - mSearchStartCol = 0; - - // Create list layout - mListLayout = new QVBoxLayout(); - mListLayout->setContentsMargins(0, 0, 0, 0); - mListLayout->setSpacing(0); - mListLayout->addWidget(mList); - mListLayout->addWidget(mSearchList); - - // Create list placeholder - mListPlaceHolder = new QWidget(); - mListPlaceHolder->setLayout(mListLayout); - - // Insert the placeholder - ui->mainSplitter->insertWidget(0, mListPlaceHolder); - - // Set the main layout - mMainLayout = new QVBoxLayout(); - mMainLayout->setContentsMargins(0, 0, 0, 0); - mMainLayout->addWidget(ui->mainSplitter); - setLayout(mMainLayout); - - // Minimal size for the search box - ui->mainSplitter->setStretchFactor(0, 1000); - ui->mainSplitter->setStretchFactor(0, 1); - - // Disable main splitter - for(int i = 0; i < ui->mainSplitter->count(); i++) - ui->mainSplitter->handle(i)->setEnabled(false); - - // Setup search menu action - mSearchAction = new QAction("Search...", this); - connect(mSearchAction, SIGNAL(triggered()), this, SLOT(searchSlot())); - - // Slots - connect(mList, SIGNAL(keyPressedSignal(QKeyEvent*)), this, SLOT(listKeyPressed(QKeyEvent*))); - connect(mList, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(listContextMenu(QPoint))); - connect(mList, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot())); - connect(mSearchList, SIGNAL(keyPressedSignal(QKeyEvent*)), this, SLOT(listKeyPressed(QKeyEvent*))); - connect(mSearchList, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(listContextMenu(QPoint))); - connect(mSearchList, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot())); - connect(mSearchBox, SIGNAL(textChanged(QString)), this, SLOT(searchTextChanged(QString))); -} - -SearchListView::~SearchListView() -{ - delete ui; -} - -void SearchListView::listKeyPressed(QKeyEvent* event) -{ - char ch = event->text().toUtf8().constData()[0]; - if(isprint(ch)) //add a char to the search box - mSearchBox->setText(mSearchBox->text().insert(mSearchBox->cursorPosition(), QString(QChar(ch)))); - else if(event->key() == Qt::Key_Backspace) //remove a char from the search box - { - QString newText; - if(event->modifiers() == Qt::ControlModifier) //clear the search box - newText = ""; - else - { - newText = mSearchBox->text(); - newText.chop(1); - } - mSearchBox->setText(newText); - } - else if((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)) //user pressed enter - emit enterPressedSignal(); -} - -bool SearchListView::findTextInList(SearchListViewTable* list, QString text, int row, int startcol, bool startswith) -{ - int count = list->getColumnCount(); - if(startcol + 1 > count) - return false; - if(startswith) - { - for(int i = startcol; i < count; i++) - if(list->getCellContent(row, i).startsWith(text, Qt::CaseInsensitive)) - return true; - } - else - { - for(int i = startcol; i < count; i++) - { - if(ui->checkBoxRegex->checkState() == Qt::Checked) - { - if(list->getCellContent(row, i).contains(QRegExp(text))) - return true; - } - else - { - if(list->getCellContent(row, i).contains(text, Qt::CaseInsensitive)) - return true; - } - } - } - return false; -} - -void SearchListView::searchTextChanged(const QString & arg1) -{ - if(arg1.length()) - { - mList->hide(); - mSearchList->show(); - mCurList = mSearchList; - } - else - { - mSearchList->hide(); - mList->show(); - if(ui->checkBoxRegex->checkState() != Qt::Checked) - mList->setFocus(); - mCurList = mList; - } - mSearchList->setRowCount(0); - int rows = mList->getRowCount(); - int columns = mList->getColumnCount(); - for(int i = 0, j = 0; i < rows; i++) - { - if(findTextInList(mList, arg1, i, mSearchStartCol, false)) - { - mSearchList->setRowCount(j + 1); - for(int k = 0; k < columns; k++) - mSearchList->setCellContent(j, k, mList->getCellContent(i, k)); - j++; - } - } - rows = mSearchList->getRowCount(); - mSearchList->setTableOffset(0); - for(int i = 0; i < rows; i++) - { - if(findTextInList(mSearchList, arg1, i, mSearchStartCol, true)) - { - if(rows > mSearchList->getViewableRowsCount()) - { - int cur = i - mSearchList->getViewableRowsCount() / 2; - if(!mSearchList->isValidIndex(cur, 0)) - cur = i; - mSearchList->setTableOffset(cur); - } - mSearchList->setSingleSelection(i); - break; - } - } - if(ui->checkBoxRegex->checkState() != Qt::Checked) //do not highlight with regex - mSearchList->highlightText = arg1; - mSearchList->reloadData(); - if(ui->checkBoxRegex->checkState() != Qt::Checked) - mSearchList->setFocus(); -} - -void SearchListView::listContextMenu(const QPoint & pos) -{ - QMenu* wMenu = new QMenu(this); - emit listContextMenuSignal(wMenu); - wMenu->addSeparator(); - wMenu->addAction(mSearchAction); - QMenu wCopyMenu("&Copy", this); - mCurList->setupCopyMenu(&wCopyMenu); - if(wCopyMenu.actions().length()) - wMenu->addMenu(&wCopyMenu); - wMenu->exec(mCurList->mapToGlobal(pos)); -} - -void SearchListView::doubleClickedSlot() -{ - emit enterPressedSignal(); -} - -void SearchListView::on_checkBoxRegex_toggled(bool checked) -{ - Q_UNUSED(checked); - searchTextChanged(ui->searchBox->text()); -} - -void SearchListView::searchSlot() -{ - FlickerThread* thread = new FlickerThread(ui->searchBox, this); - connect(thread, SIGNAL(setStyleSheet(QString)), ui->searchBox, SLOT(setStyleSheet(QString))); - thread->start(); -} +#include "SearchListView.h" +#include "ui_SearchListView.h" +#include "FlickerThread.h" + +SearchListView::SearchListView(QWidget* parent) : + QWidget(parent), + ui(new Ui::SearchListView) +{ + ui->setupUi(this); + + setContextMenuPolicy(Qt::CustomContextMenu); + + // Create the reference list + mList = new SearchListViewTable(); + + // Create the search list + mSearchList = new SearchListViewTable(); + mSearchList->hide(); + + // Set global variables + mSearchBox = ui->searchBox; + mCurList = mList; + mSearchStartCol = 0; + + // Create list layout + mListLayout = new QVBoxLayout(); + mListLayout->setContentsMargins(0, 0, 0, 0); + mListLayout->setSpacing(0); + mListLayout->addWidget(mList); + mListLayout->addWidget(mSearchList); + + // Create list placeholder + mListPlaceHolder = new QWidget(); + mListPlaceHolder->setLayout(mListLayout); + + // Insert the placeholder + ui->mainSplitter->insertWidget(0, mListPlaceHolder); + + // Set the main layout + mMainLayout = new QVBoxLayout(); + mMainLayout->setContentsMargins(0, 0, 0, 0); + mMainLayout->addWidget(ui->mainSplitter); + setLayout(mMainLayout); + + // Minimal size for the search box + ui->mainSplitter->setStretchFactor(0, 1000); + ui->mainSplitter->setStretchFactor(0, 1); + + // Disable main splitter + for(int i = 0; i < ui->mainSplitter->count(); i++) + ui->mainSplitter->handle(i)->setEnabled(false); + + // Setup search menu action + mSearchAction = new QAction("Search...", this); + connect(mSearchAction, SIGNAL(triggered()), this, SLOT(searchSlot())); + + // Slots + connect(mList, SIGNAL(keyPressedSignal(QKeyEvent*)), this, SLOT(listKeyPressed(QKeyEvent*))); + connect(mList, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(listContextMenu(QPoint))); + connect(mList, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot())); + connect(mSearchList, SIGNAL(keyPressedSignal(QKeyEvent*)), this, SLOT(listKeyPressed(QKeyEvent*))); + connect(mSearchList, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(listContextMenu(QPoint))); + connect(mSearchList, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot())); + connect(mSearchBox, SIGNAL(textChanged(QString)), this, SLOT(searchTextChanged(QString))); +} + +SearchListView::~SearchListView() +{ + delete ui; +} + +void SearchListView::listKeyPressed(QKeyEvent* event) +{ + char ch = event->text().toUtf8().constData()[0]; + if(isprint(ch)) //add a char to the search box + mSearchBox->setText(mSearchBox->text().insert(mSearchBox->cursorPosition(), QString(QChar(ch)))); + else if(event->key() == Qt::Key_Backspace) //remove a char from the search box + { + QString newText; + if(event->modifiers() == Qt::ControlModifier) //clear the search box + newText = ""; + else + { + newText = mSearchBox->text(); + newText.chop(1); + } + mSearchBox->setText(newText); + } + else if((event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)) //user pressed enter + emit enterPressedSignal(); +} + +bool SearchListView::findTextInList(SearchListViewTable* list, QString text, int row, int startcol, bool startswith) +{ + int count = list->getColumnCount(); + if(startcol + 1 > count) + return false; + if(startswith) + { + for(int i = startcol; i < count; i++) + if(list->getCellContent(row, i).startsWith(text, Qt::CaseInsensitive)) + return true; + } + else + { + for(int i = startcol; i < count; i++) + { + if(ui->checkBoxRegex->checkState() == Qt::Checked) + { + if(list->getCellContent(row, i).contains(QRegExp(text))) + return true; + } + else + { + if(list->getCellContent(row, i).contains(text, Qt::CaseInsensitive)) + return true; + } + } + } + return false; +} + +void SearchListView::searchTextChanged(const QString & arg1) +{ + if(arg1.length()) + { + mList->hide(); + mSearchList->show(); + mCurList = mSearchList; + } + else + { + mSearchList->hide(); + mList->show(); + if(ui->checkBoxRegex->checkState() != Qt::Checked) + mList->setFocus(); + mCurList = mList; + } + mSearchList->setRowCount(0); + int rows = mList->getRowCount(); + int columns = mList->getColumnCount(); + for(int i = 0, j = 0; i < rows; i++) + { + if(findTextInList(mList, arg1, i, mSearchStartCol, false)) + { + mSearchList->setRowCount(j + 1); + for(int k = 0; k < columns; k++) + mSearchList->setCellContent(j, k, mList->getCellContent(i, k)); + j++; + } + } + rows = mSearchList->getRowCount(); + mSearchList->setTableOffset(0); + for(int i = 0; i < rows; i++) + { + if(findTextInList(mSearchList, arg1, i, mSearchStartCol, true)) + { + if(rows > mSearchList->getViewableRowsCount()) + { + int cur = i - mSearchList->getViewableRowsCount() / 2; + if(!mSearchList->isValidIndex(cur, 0)) + cur = i; + mSearchList->setTableOffset(cur); + } + mSearchList->setSingleSelection(i); + break; + } + } + if(ui->checkBoxRegex->checkState() != Qt::Checked) //do not highlight with regex + mSearchList->highlightText = arg1; + mSearchList->reloadData(); + if(ui->checkBoxRegex->checkState() != Qt::Checked) + mSearchList->setFocus(); +} + +void SearchListView::listContextMenu(const QPoint & pos) +{ + QMenu* wMenu = new QMenu(this); + emit listContextMenuSignal(wMenu); + wMenu->addSeparator(); + wMenu->addAction(mSearchAction); + QMenu wCopyMenu("&Copy", this); + mCurList->setupCopyMenu(&wCopyMenu); + if(wCopyMenu.actions().length()) + wMenu->addMenu(&wCopyMenu); + wMenu->exec(mCurList->mapToGlobal(pos)); +} + +void SearchListView::doubleClickedSlot() +{ + emit enterPressedSignal(); +} + +void SearchListView::on_checkBoxRegex_toggled(bool checked) +{ + Q_UNUSED(checked); + searchTextChanged(ui->searchBox->text()); +} + +void SearchListView::searchSlot() +{ + FlickerThread* thread = new FlickerThread(ui->searchBox, this); + connect(thread, SIGNAL(setStyleSheet(QString)), ui->searchBox, SLOT(setStyleSheet(QString))); + thread->start(); +} diff --git a/src/gui/Src/BasicView/SearchListView.h b/src/gui/Src/BasicView/SearchListView.h index 35045944..7614128e 100644 --- a/src/gui/Src/BasicView/SearchListView.h +++ b/src/gui/Src/BasicView/SearchListView.h @@ -1,51 +1,51 @@ -#ifndef SEARCHLISTVIEW_H -#define SEARCHLISTVIEW_H - -#include -#include -#include -#include -#include "SearchListViewTable.h" - -namespace Ui -{ -class SearchListView; -} - -class SearchListView : public QWidget -{ - Q_OBJECT - -public: - explicit SearchListView(QWidget* parent = 0); - ~SearchListView(); - - QVBoxLayout* mMainLayout; - SearchListViewTable* mList; - SearchListViewTable* mSearchList; - SearchListViewTable* mCurList; - QLineEdit* mSearchBox; - int mSearchStartCol; - - bool findTextInList(SearchListViewTable* list, QString text, int row, int startcol, bool startswith); - -private slots: - void searchTextChanged(const QString & arg1); - void listKeyPressed(QKeyEvent* event); - void listContextMenu(const QPoint & pos); - void doubleClickedSlot(); - void searchSlot(); - void on_checkBoxRegex_toggled(bool checked); - -signals: - void enterPressedSignal(); - void listContextMenuSignal(QMenu* wMenu); - -private: - Ui::SearchListView* ui; - QVBoxLayout* mListLayout; - QWidget* mListPlaceHolder; - QAction* mSearchAction; -}; - -#endif // SEARCHLISTVIEW_H +#ifndef SEARCHLISTVIEW_H +#define SEARCHLISTVIEW_H + +#include +#include +#include +#include +#include "SearchListViewTable.h" + +namespace Ui +{ +class SearchListView; +} + +class SearchListView : public QWidget +{ + Q_OBJECT + +public: + explicit SearchListView(QWidget* parent = 0); + ~SearchListView(); + + QVBoxLayout* mMainLayout; + SearchListViewTable* mList; + SearchListViewTable* mSearchList; + SearchListViewTable* mCurList; + QLineEdit* mSearchBox; + int mSearchStartCol; + + bool findTextInList(SearchListViewTable* list, QString text, int row, int startcol, bool startswith); + +private slots: + void searchTextChanged(const QString & arg1); + void listKeyPressed(QKeyEvent* event); + void listContextMenu(const QPoint & pos); + void doubleClickedSlot(); + void searchSlot(); + void on_checkBoxRegex_toggled(bool checked); + +signals: + void enterPressedSignal(); + void listContextMenuSignal(QMenu* wMenu); + +private: + Ui::SearchListView* ui; + QVBoxLayout* mListLayout; + QWidget* mListPlaceHolder; + QAction* mSearchAction; +}; + +#endif // SEARCHLISTVIEW_H diff --git a/src/gui/Src/BasicView/SearchListViewTable.cpp b/src/gui/Src/BasicView/SearchListViewTable.cpp index eea3c142..24ad989e 100644 --- a/src/gui/Src/BasicView/SearchListViewTable.cpp +++ b/src/gui/Src/BasicView/SearchListViewTable.cpp @@ -1,107 +1,107 @@ -#include "SearchListViewTable.h" -#include "Configuration.h" -#include "RichTextPainter.h" - -SearchListViewTable::SearchListViewTable(StdTable* parent) : StdTable(parent) -{ - highlightText = ""; -} - -QString SearchListViewTable::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) -{ - bool isaddr = true; - QString text = StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h); - if(!DbgIsDebugging()) - isaddr = false; - if(!getRowCount()) - isaddr = false; - ULONGLONG val = 0; - duint wVA; - if(sscanf_s(text.toUtf8().constData(), "%llX", &val) != 1) - isaddr = false; - else - wVA = val; - if(col == 0 && isaddr) - { - BPXTYPE bpxtype = DbgGetBpxTypeAt(wVA); - bool isbookmark = DbgGetBookmarkAt(wVA); - painter->setPen(textColor); - if(!isbookmark) - { - if(bpxtype & bp_normal) //normal breakpoint - { - painter->setPen(QPen(ConfigColor("DisassemblyBreakpointColor"))); - painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBreakpointBackgroundColor"))); //fill red - } - else if(bpxtype & bp_hardware) //hardware breakpoint only - { - painter->setPen(QPen(ConfigColor("DisassemblyHardwareBreakpointColor"))); - painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyHardwareBreakpointBackgroundColor"))); //fill red - } - } - else //bookmark - { - if(bpxtype == bp_none) //bookmark only - { - painter->setPen(QPen(ConfigColor("DisassemblyBookmarkColor"))); //black address - painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBookmarkBackgroundColor"))); //fill bookmark color - } - else //bookmark + breakpoint - { - QColor color = ConfigColor("DisassemblyBookmarkBackgroundColor"); - if(!color.alpha()) //we don't want transparent text - color = textColor; - painter->setPen(QPen(color)); - if(bpxtype & bp_normal) //bookmark + normal breakpoint - { - painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBreakpointBackgroundColor"))); //fill red - } - else if(bpxtype & bp_hardware) //bookmark + hardware breakpoint only - { - painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyHardwareBreakpointBackgroundColor"))); //fill red - } - else //other cases (bookmark + memory breakpoint in disassembly) -> do as normal - { - painter->setPen(QPen(ConfigColor("DisassemblyBookmarkColor"))); //black address (DisassemblySelectedAddressColor) - painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBookmarkBackgroundColor"))); //fill bookmark color - } - } - } - painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, text); - text = ""; - } - else if(highlightText.length() && text.contains(highlightText, Qt::CaseInsensitive)) - { - //super smart way of splitting while keeping the delimiters (thanks to cypher for guidance) - int index = -2; - do - { - index = text.indexOf(highlightText, index + 2, Qt::CaseInsensitive); - if(index != -1) - { - text = text.insert(index + highlightText.length(), QChar('\1')); - text = text.insert(index, QChar('\1')); - } - } - while(index != -1); - QStringList split = text.split(QChar('\1'), QString::SkipEmptyParts, Qt::CaseInsensitive); - - //create rich text list - RichTextPainter::CustomRichText_t curRichText; - curRichText.flags = RichTextPainter::FlagColor; - curRichText.textColor = textColor; - curRichText.highlightColor = ConfigColor("SearchListViewHighlightColor"); - QList richText; - foreach(QString str, split) - { - curRichText.text = str; - curRichText.highlight = !str.compare(highlightText, Qt::CaseInsensitive); - richText.push_back(curRichText); - } - - //paint the rich text - RichTextPainter::paintRichText(painter, x + 1, y, w, h, 4, &richText, getCharWidth()); - text = ""; - } - return text; -} +#include "SearchListViewTable.h" +#include "Configuration.h" +#include "RichTextPainter.h" + +SearchListViewTable::SearchListViewTable(StdTable* parent) : StdTable(parent) +{ + highlightText = ""; +} + +QString SearchListViewTable::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) +{ + bool isaddr = true; + QString text = StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h); + if(!DbgIsDebugging()) + isaddr = false; + if(!getRowCount()) + isaddr = false; + ULONGLONG val = 0; + duint wVA; + if(sscanf_s(text.toUtf8().constData(), "%llX", &val) != 1) + isaddr = false; + else + wVA = val; + if(col == 0 && isaddr) + { + BPXTYPE bpxtype = DbgGetBpxTypeAt(wVA); + bool isbookmark = DbgGetBookmarkAt(wVA); + painter->setPen(textColor); + if(!isbookmark) + { + if(bpxtype & bp_normal) //normal breakpoint + { + painter->setPen(QPen(ConfigColor("DisassemblyBreakpointColor"))); + painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBreakpointBackgroundColor"))); //fill red + } + else if(bpxtype & bp_hardware) //hardware breakpoint only + { + painter->setPen(QPen(ConfigColor("DisassemblyHardwareBreakpointColor"))); + painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyHardwareBreakpointBackgroundColor"))); //fill red + } + } + else //bookmark + { + if(bpxtype == bp_none) //bookmark only + { + painter->setPen(QPen(ConfigColor("DisassemblyBookmarkColor"))); //black address + painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBookmarkBackgroundColor"))); //fill bookmark color + } + else //bookmark + breakpoint + { + QColor color = ConfigColor("DisassemblyBookmarkBackgroundColor"); + if(!color.alpha()) //we don't want transparent text + color = textColor; + painter->setPen(QPen(color)); + if(bpxtype & bp_normal) //bookmark + normal breakpoint + { + painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBreakpointBackgroundColor"))); //fill red + } + else if(bpxtype & bp_hardware) //bookmark + hardware breakpoint only + { + painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyHardwareBreakpointBackgroundColor"))); //fill red + } + else //other cases (bookmark + memory breakpoint in disassembly) -> do as normal + { + painter->setPen(QPen(ConfigColor("DisassemblyBookmarkColor"))); //black address (DisassemblySelectedAddressColor) + painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBookmarkBackgroundColor"))); //fill bookmark color + } + } + } + painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, text); + text = ""; + } + else if(highlightText.length() && text.contains(highlightText, Qt::CaseInsensitive)) + { + //super smart way of splitting while keeping the delimiters (thanks to cypher for guidance) + int index = -2; + do + { + index = text.indexOf(highlightText, index + 2, Qt::CaseInsensitive); + if(index != -1) + { + text = text.insert(index + highlightText.length(), QChar('\1')); + text = text.insert(index, QChar('\1')); + } + } + while(index != -1); + QStringList split = text.split(QChar('\1'), QString::SkipEmptyParts, Qt::CaseInsensitive); + + //create rich text list + RichTextPainter::CustomRichText_t curRichText; + curRichText.flags = RichTextPainter::FlagColor; + curRichText.textColor = textColor; + curRichText.highlightColor = ConfigColor("SearchListViewHighlightColor"); + QList richText; + foreach(QString str, split) + { + curRichText.text = str; + curRichText.highlight = !str.compare(highlightText, Qt::CaseInsensitive); + richText.push_back(curRichText); + } + + //paint the rich text + RichTextPainter::paintRichText(painter, x + 1, y, w, h, 4, &richText, getCharWidth()); + text = ""; + } + return text; +} diff --git a/src/gui/Src/BasicView/SearchListViewTable.h b/src/gui/Src/BasicView/SearchListViewTable.h index a61bc660..a7656a8b 100644 --- a/src/gui/Src/BasicView/SearchListViewTable.h +++ b/src/gui/Src/BasicView/SearchListViewTable.h @@ -1,17 +1,17 @@ -#ifndef SEARCHLISTVIEWTABLE_H -#define SEARCHLISTVIEWTABLE_H - -#include "StdTable.h" - -class SearchListViewTable : public StdTable -{ - Q_OBJECT -public: - explicit SearchListViewTable(StdTable* parent = 0); - QString highlightText; - -protected: - QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); -}; - -#endif // SEARCHLISTVIEWTABLE_H +#ifndef SEARCHLISTVIEWTABLE_H +#define SEARCHLISTVIEWTABLE_H + +#include "StdTable.h" + +class SearchListViewTable : public StdTable +{ + Q_OBJECT +public: + explicit SearchListViewTable(StdTable* parent = 0); + QString highlightText; + +protected: + QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); +}; + +#endif // SEARCHLISTVIEWTABLE_H diff --git a/src/gui/Src/BasicView/ShortcutEdit.cpp b/src/gui/Src/BasicView/ShortcutEdit.cpp index 9833832d..cfc4d68d 100644 --- a/src/gui/Src/BasicView/ShortcutEdit.cpp +++ b/src/gui/Src/BasicView/ShortcutEdit.cpp @@ -1,77 +1,77 @@ -#include "ShortcutEdit.h" - -ShortcutEdit::ShortcutEdit(QWidget* parent) : QLineEdit(parent) -{ - keyInt = -1; -} - -const QKeySequence ShortcutEdit::getKeysequence() const -{ - if(keyInt == -1) //return empty on -1 - return QKeySequence(); - // returns current keystroke combination - return QKeySequence(keyInt); -} - -void ShortcutEdit::setErrorState(bool error) -{ - if(error) - setStyleSheet("color: #DD0000"); - else - setStyleSheet("color: #222222"); -} - -void ShortcutEdit::keyPressEvent(QKeyEvent* event) -{ - keyInt = event->key(); - // find key-id - const Qt::Key key = static_cast(keyInt); - - // we do not know how to handle this case - if(key == Qt::Key_unknown) - { - keyInt = -1; - emit askForSave(); - return; - } - - // these keys will be ignored - if(key == Qt::Key_Escape || key == Qt::Key_Backspace) - { - setText(""); - keyInt = -1; - emit askForSave(); - return; - } - - // any combination of "Ctrl, Alt, Shift" ? - Qt::KeyboardModifiers modifiers = event->modifiers(); - if(modifiers.testFlag(Qt::ShiftModifier)) - keyInt += Qt::SHIFT; - if(modifiers.testFlag(Qt::ControlModifier)) - keyInt += Qt::CTRL; - if(modifiers.testFlag(Qt::AltModifier)) - keyInt += Qt::ALT; - - // some strange cases (only Ctrl) - QString KeyText = QKeySequence(keyInt).toString(QKeySequence::NativeText) ; - for(int i = 0; i < KeyText.length(); i++) - { - if(KeyText[i].toLatin1() == 0) - { - setText(""); - keyInt = -1; - emit askForSave(); - return; - } - } - - - // display key combination - setText(QKeySequence(keyInt).toString(QKeySequence::NativeText)); - // do not forward keypress-event - event->setAccepted(true); - - // everything is fine , so ask for saving - emit askForSave(); -} +#include "ShortcutEdit.h" + +ShortcutEdit::ShortcutEdit(QWidget* parent) : QLineEdit(parent) +{ + keyInt = -1; +} + +const QKeySequence ShortcutEdit::getKeysequence() const +{ + if(keyInt == -1) //return empty on -1 + return QKeySequence(); + // returns current keystroke combination + return QKeySequence(keyInt); +} + +void ShortcutEdit::setErrorState(bool error) +{ + if(error) + setStyleSheet("color: #DD0000"); + else + setStyleSheet("color: #222222"); +} + +void ShortcutEdit::keyPressEvent(QKeyEvent* event) +{ + keyInt = event->key(); + // find key-id + const Qt::Key key = static_cast(keyInt); + + // we do not know how to handle this case + if(key == Qt::Key_unknown) + { + keyInt = -1; + emit askForSave(); + return; + } + + // these keys will be ignored + if(key == Qt::Key_Escape || key == Qt::Key_Backspace) + { + setText(""); + keyInt = -1; + emit askForSave(); + return; + } + + // any combination of "Ctrl, Alt, Shift" ? + Qt::KeyboardModifiers modifiers = event->modifiers(); + if(modifiers.testFlag(Qt::ShiftModifier)) + keyInt += Qt::SHIFT; + if(modifiers.testFlag(Qt::ControlModifier)) + keyInt += Qt::CTRL; + if(modifiers.testFlag(Qt::AltModifier)) + keyInt += Qt::ALT; + + // some strange cases (only Ctrl) + QString KeyText = QKeySequence(keyInt).toString(QKeySequence::NativeText) ; + for(int i = 0; i < KeyText.length(); i++) + { + if(KeyText[i].toLatin1() == 0) + { + setText(""); + keyInt = -1; + emit askForSave(); + return; + } + } + + + // display key combination + setText(QKeySequence(keyInt).toString(QKeySequence::NativeText)); + // do not forward keypress-event + event->setAccepted(true); + + // everything is fine , so ask for saving + emit askForSave(); +} diff --git a/src/gui/Src/BasicView/ShortcutEdit.h b/src/gui/Src/BasicView/ShortcutEdit.h index 44763679..a62033a8 100644 --- a/src/gui/Src/BasicView/ShortcutEdit.h +++ b/src/gui/Src/BasicView/ShortcutEdit.h @@ -1,27 +1,27 @@ -#ifndef SHORTCUTEDIT_H -#define SHORTCUTEDIT_H - -#include -#include -#include - -class ShortcutEdit : public QLineEdit -{ - Q_OBJECT - int keyInt; - -public: - explicit ShortcutEdit(QWidget* parent = 0); - const QKeySequence getKeysequence() const; - -public slots: - void setErrorState(bool error); - -signals: - void askForSave(); - -protected: - void keyPressEvent(QKeyEvent* event); -}; - -#endif // SHORTCUTEDIT_H +#ifndef SHORTCUTEDIT_H +#define SHORTCUTEDIT_H + +#include +#include +#include + +class ShortcutEdit : public QLineEdit +{ + Q_OBJECT + int keyInt; + +public: + explicit ShortcutEdit(QWidget* parent = 0); + const QKeySequence getKeysequence() const; + +public slots: + void setErrorState(bool error); + +signals: + void askForSave(); + +protected: + void keyPressEvent(QKeyEvent* event); +}; + +#endif // SHORTCUTEDIT_H diff --git a/src/gui/Src/BasicView/StdTable.cpp b/src/gui/Src/BasicView/StdTable.cpp index beb78573..3d6b6340 100644 --- a/src/gui/Src/BasicView/StdTable.cpp +++ b/src/gui/Src/BasicView/StdTable.cpp @@ -1,453 +1,453 @@ -#include "StdTable.h" -#include "Bridge.h" - -StdTable::StdTable(QWidget* parent) : AbstractTableView(parent) -{ - SelectionData_t data; - memset(&data, 0, sizeof(SelectionData_t)); - mSelection = data; - - mIsMultiSelctionAllowed = false; - mIsColumnSortingAllowed = true; - - mData.clear(); - mSort.first = -1; - - mGuiState = StdTable::NoState; - - mCopyMenuOnly = false; - mCopyMenuDebugOnly = true; - setContextMenuPolicy(Qt::CustomContextMenu); - - connect(Bridge::getBridge(), SIGNAL(repaintTableView()), this, SLOT(reloadData())); - connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequestedSlot(QPoint))); - connect(this, SIGNAL(headerButtonPressed(int)), this, SLOT(headerButtonPressedSlot(int))); -} - -QString StdTable::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) -{ - if(isSelected(rowBase, rowOffset) == true) - painter->fillRect(QRect(x, y, w, h), QBrush(selectionColor)); - return getCellContent(rowBase + rowOffset, col); -} - -void StdTable::mouseMoveEvent(QMouseEvent* event) -{ - bool wAccept = true; - - if(mGuiState == StdTable::MultiRowsSelectionState) - { - //qDebug() << "State = MultiRowsSelectionState"; - - if((transY(event->y()) >= 0) && (transY(event->y()) <= this->getTableHeigth())) - { - int wRowIndex = getTableOffset() + getIndexOffsetFromY(transY(event->y())); - - if(wRowIndex < getRowCount()) - { - if(mIsMultiSelctionAllowed == true) - expandSelectionUpTo(wRowIndex); - else - setSingleSelection(wRowIndex); - - repaint(); - - wAccept = false; - } - } - } - - if(wAccept == true) - AbstractTableView::mouseMoveEvent(event); -} - -void StdTable::mousePressEvent(QMouseEvent* event) -{ - bool wAccept = false; - - if(((event->buttons() & Qt::LeftButton) != 0) && ((event->buttons() & Qt::RightButton) == 0)) - { - if(getGuiState() == AbstractTableView::NoState) - { - if(event->y() > getHeaderHeight()) - { - int wRowIndex = getTableOffset() + getIndexOffsetFromY(transY(event->y())); - - if(wRowIndex < getRowCount()) - { - if(mIsMultiSelctionAllowed && (event->modifiers() & Qt::ShiftModifier)) - expandSelectionUpTo(wRowIndex); - else - setSingleSelection(wRowIndex); - - mGuiState = StdTable::MultiRowsSelectionState; - - repaint(); - - wAccept = true; - } - } - } - } - - if(wAccept == false) - AbstractTableView::mousePressEvent(event); -} - -void StdTable::mouseDoubleClickEvent(QMouseEvent* event) -{ - if(event->y() > getHeaderHeight() && event->button() == Qt::LeftButton) - emit doubleClickedSignal(); - AbstractTableView::mouseDoubleClickEvent(event); -} - -void StdTable::mouseReleaseEvent(QMouseEvent* event) -{ - bool wAccept = true; - - if((event->buttons() & Qt::LeftButton) == 0) - { - if(mGuiState == StdTable::MultiRowsSelectionState) - { - mGuiState = StdTable::NoState; - - repaint(); - - wAccept = false; - } - } - - if(wAccept == true) - AbstractTableView::mouseReleaseEvent(event); -} - -void StdTable::keyPressEvent(QKeyEvent* event) -{ - emit keyPressedSignal(event); - int key = event->key(); - - if(key == Qt::Key_Up || key == Qt::Key_Down) - { - dsint wBotIndex = getTableOffset(); - dsint wTopIndex = wBotIndex + getNbrOfLineToPrint() - 1; - - if(key == Qt::Key_Up) - selectPrevious(); - else - selectNext(); - - if(getInitialSelection() < wBotIndex) - { - setTableOffset(getInitialSelection()); - } - else if(getInitialSelection() >= wTopIndex) - { - setTableOffset(getInitialSelection() - getNbrOfLineToPrint() + 2); - } - - repaint(); - } - else - { - AbstractTableView::keyPressEvent(event); - } -} - -void StdTable::enableMultiSelection(bool enabled) -{ - mIsMultiSelctionAllowed = enabled; -} - -void StdTable::enableColumnSorting(bool enabled) -{ - mIsColumnSortingAllowed = enabled; -} - -/************************************************************************************ - Selection Management -************************************************************************************/ -void StdTable::expandSelectionUpTo(int to) -{ - if(to < mSelection.firstSelectedIndex) - { - mSelection.fromIndex = to; - mSelection.toIndex = mSelection.firstSelectedIndex; - } - else if(to > mSelection.firstSelectedIndex) - { - mSelection.fromIndex = mSelection.firstSelectedIndex; - mSelection.toIndex = to; - } - else if(to == mSelection.firstSelectedIndex) - { - setSingleSelection(to); - } -} - -void StdTable::setSingleSelection(int index) -{ - mSelection.firstSelectedIndex = index; - mSelection.fromIndex = index; - mSelection.toIndex = index; - emit selectionChangedSignal(index); -} - -int StdTable::getInitialSelection() -{ - return mSelection.firstSelectedIndex; -} - -void StdTable::selectNext() -{ - int wNext = getInitialSelection() + 1; - - // Bounding - wNext = wNext > getRowCount() - 1 ? getRowCount() - 1 : wNext; - wNext = wNext < 0 ? 0 : wNext; - - setSingleSelection(wNext); -} - -void StdTable::selectPrevious() -{ - int wNext = getInitialSelection() - 1; - - // Bounding - wNext = wNext > getRowCount() - 1 ? getRowCount() - 1 : wNext; - wNext = wNext < 0 ? 0 : wNext; - - setSingleSelection(wNext); -} - -bool StdTable::isSelected(int base, int offset) -{ - int wIndex = base + offset; - - if(wIndex >= mSelection.fromIndex && wIndex <= mSelection.toIndex) - return true; - else - return false; -} - -/************************************************************************************ - Data Management -************************************************************************************/ -void StdTable::addColumnAt(int width, QString title, bool isClickable, QString copyTitle) -{ - AbstractTableView::addColumnAt(width, title, isClickable); - - //append empty column to list of rows - for(int i = 0; i < mData.size(); i++) - mData[i].append(""); - - //Append copy title - if(!copyTitle.length()) - mCopyTitles.append(title); - else - mCopyTitles.append(copyTitle); -} - -void StdTable::setRowCount(int count) -{ - int wRowToAddOrRemove = count - mData.size(); - for(int i = 0; i < qAbs(wRowToAddOrRemove); i++) - { - if(wRowToAddOrRemove > 0) - { - mData.append(QList()); - for(int j = 0; j < getColumnCount(); j++) - mData.last().append(""); - } - else - mData.removeLast(); - } - AbstractTableView::setRowCount(count); -} - -void StdTable::deleteAllColumns() -{ - setRowCount(0); - AbstractTableView::deleteAllColumns(); - mCopyTitles.clear(); -} - -void StdTable::setCellContent(int r, int c, QString s) -{ - if(isValidIndex(r, c) == true) - mData[r].replace(c, s); -} - -QString StdTable::getCellContent(int r, int c) -{ - if(isValidIndex(r, c) == true) - return mData[r][c]; - else - return QString(""); -} - -bool StdTable::isValidIndex(int r, int c) -{ - if(r < 0 || c < 0 || r >= mData.size()) - return false; - return c < mData.at(r).size(); -} - -void StdTable::copyLineSlot() -{ - int colCount = getColumnCount(); - QString finalText = ""; - if(colCount == 1) - finalText = getCellContent(getInitialSelection(), 0); - else - { - for(int i = 0; i < colCount; i++) - { - QString cellContent = getCellContent(getInitialSelection(), i); - if(!cellContent.length()) //skip empty cells - continue; - QString title = mCopyTitles.at(i); - if(title.length()) - finalText += title + "="; - while(cellContent.endsWith(" ")) cellContent.chop(1); - finalText += cellContent; - finalText += "\r\n"; - } - } - Bridge::CopyToClipboard(finalText); -} - -void StdTable::copyTableSlot() -{ - int colCount = getColumnCount(); - int rowCount = getRowCount(); - QString finalText = ""; - if(colCount == 1) - { - for(int i = 0; i < rowCount; i++) - { - QString cellContent = getCellContent(i, 0); - if(!cellContent.length()) //skip empty cells - continue; - finalText += cellContent + "\r\n"; - } - } - else - { - int charwidth = getCharWidth(); - for(int i = 0; i < colCount; i++) - { - if(i) - finalText += " "; - int colWidth = getColumnWidth(i) / charwidth; - if(colWidth) - finalText += getColTitle(i).leftJustified(colWidth, QChar(' '), true); - else - finalText += getColTitle(i); - } - finalText += "\r\n"; - for(int i = 0; i < rowCount; i++) - { - QString finalRowText = ""; - for(int j = 0; j < colCount; j++) - { - if(j) - finalRowText += " "; - QString cellContent = getCellContent(i, j); - int colWidth = getColumnWidth(j) / charwidth; - if(colWidth && j != colCount - 1) - finalRowText += cellContent.leftJustified(colWidth, QChar(' '), true); - else - finalRowText += cellContent; - } - finalText += finalRowText + "\r\n"; - } - } - Bridge::CopyToClipboard(finalText); -} - -void StdTable::copyEntrySlot() -{ - QAction* action = qobject_cast(sender()); - if(!action) - return; - int col = action->objectName().toInt(); - QString finalText = getCellContent(getInitialSelection(), col); - while(finalText.endsWith(" ")) finalText.chop(1); - Bridge::CopyToClipboard(finalText); -} - -void StdTable::setupCopyMenu(QMenu* copyMenu) -{ - if(!getColumnCount()) - return; - //Copy->Whole Line - QAction* mCopyLine = new QAction("Whole &Line", this); - connect(mCopyLine, SIGNAL(triggered()), this, SLOT(copyLineSlot())); - copyMenu->addAction(mCopyLine); - //Copy->Whole Table - QAction* mCopyTable = new QAction("Whole &Table", this); - connect(mCopyTable, SIGNAL(triggered()), this, SLOT(copyTableSlot())); - copyMenu->addAction(mCopyTable); - //Copy->Separator - copyMenu->addSeparator(); - //Copy->ColName - for(int i = 0; i < getColumnCount(); i++) - { - if(!getCellContent(getInitialSelection(), i).length()) //skip empty cells - continue; - QString title = mCopyTitles.at(i); - if(!title.length()) //skip empty copy titles - continue; - QAction* mCopyAction = new QAction(title, this); - mCopyAction->setObjectName(QString::number(i)); - connect(mCopyAction, SIGNAL(triggered()), this, SLOT(copyEntrySlot())); - copyMenu->addAction(mCopyAction); - } -} - -void StdTable::setCopyMenuOnly(bool bSet, bool bDebugOnly) -{ - mCopyMenuOnly = bSet; - mCopyMenuDebugOnly = bDebugOnly; -} - -void StdTable::contextMenuRequestedSlot(const QPoint & pos) -{ - if(!mCopyMenuOnly) - { - emit contextMenuSignal(pos); - return; - } - if(mCopyMenuDebugOnly && !DbgIsDebugging()) - return; - QMenu* wMenu = new QMenu(this); - QMenu wCopyMenu("&Copy", this); - setupCopyMenu(&wCopyMenu); - if(wCopyMenu.actions().length()) - { - wMenu->addSeparator(); - wMenu->addMenu(&wCopyMenu); - wMenu->exec(mapToGlobal(pos)); - } -} - -void StdTable::headerButtonPressedSlot(int col) -{ - if(!mIsColumnSortingAllowed) - return; - if(mSort.first != col) //first = column to sort - { - mSort.first = col; - mSort.second = false; //second = ascending/descending - } - else - mSort.second = !mSort.second; - reloadData(); -} - -void StdTable::reloadData() -{ - if(mSort.first != -1) //re-sort if the user wants to sort - qSort(mData.begin(), mData.end(), ColumnCompare(mSort.first, mSort.second)); - AbstractTableView::reloadData(); -} +#include "StdTable.h" +#include "Bridge.h" + +StdTable::StdTable(QWidget* parent) : AbstractTableView(parent) +{ + SelectionData_t data; + memset(&data, 0, sizeof(SelectionData_t)); + mSelection = data; + + mIsMultiSelctionAllowed = false; + mIsColumnSortingAllowed = true; + + mData.clear(); + mSort.first = -1; + + mGuiState = StdTable::NoState; + + mCopyMenuOnly = false; + mCopyMenuDebugOnly = true; + setContextMenuPolicy(Qt::CustomContextMenu); + + connect(Bridge::getBridge(), SIGNAL(repaintTableView()), this, SLOT(reloadData())); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequestedSlot(QPoint))); + connect(this, SIGNAL(headerButtonPressed(int)), this, SLOT(headerButtonPressedSlot(int))); +} + +QString StdTable::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) +{ + if(isSelected(rowBase, rowOffset) == true) + painter->fillRect(QRect(x, y, w, h), QBrush(selectionColor)); + return getCellContent(rowBase + rowOffset, col); +} + +void StdTable::mouseMoveEvent(QMouseEvent* event) +{ + bool wAccept = true; + + if(mGuiState == StdTable::MultiRowsSelectionState) + { + //qDebug() << "State = MultiRowsSelectionState"; + + if((transY(event->y()) >= 0) && (transY(event->y()) <= this->getTableHeigth())) + { + int wRowIndex = getTableOffset() + getIndexOffsetFromY(transY(event->y())); + + if(wRowIndex < getRowCount()) + { + if(mIsMultiSelctionAllowed == true) + expandSelectionUpTo(wRowIndex); + else + setSingleSelection(wRowIndex); + + repaint(); + + wAccept = false; + } + } + } + + if(wAccept == true) + AbstractTableView::mouseMoveEvent(event); +} + +void StdTable::mousePressEvent(QMouseEvent* event) +{ + bool wAccept = false; + + if(((event->buttons() & Qt::LeftButton) != 0) && ((event->buttons() & Qt::RightButton) == 0)) + { + if(getGuiState() == AbstractTableView::NoState) + { + if(event->y() > getHeaderHeight()) + { + int wRowIndex = getTableOffset() + getIndexOffsetFromY(transY(event->y())); + + if(wRowIndex < getRowCount()) + { + if(mIsMultiSelctionAllowed && (event->modifiers() & Qt::ShiftModifier)) + expandSelectionUpTo(wRowIndex); + else + setSingleSelection(wRowIndex); + + mGuiState = StdTable::MultiRowsSelectionState; + + repaint(); + + wAccept = true; + } + } + } + } + + if(wAccept == false) + AbstractTableView::mousePressEvent(event); +} + +void StdTable::mouseDoubleClickEvent(QMouseEvent* event) +{ + if(event->y() > getHeaderHeight() && event->button() == Qt::LeftButton) + emit doubleClickedSignal(); + AbstractTableView::mouseDoubleClickEvent(event); +} + +void StdTable::mouseReleaseEvent(QMouseEvent* event) +{ + bool wAccept = true; + + if((event->buttons() & Qt::LeftButton) == 0) + { + if(mGuiState == StdTable::MultiRowsSelectionState) + { + mGuiState = StdTable::NoState; + + repaint(); + + wAccept = false; + } + } + + if(wAccept == true) + AbstractTableView::mouseReleaseEvent(event); +} + +void StdTable::keyPressEvent(QKeyEvent* event) +{ + emit keyPressedSignal(event); + int key = event->key(); + + if(key == Qt::Key_Up || key == Qt::Key_Down) + { + dsint wBotIndex = getTableOffset(); + dsint wTopIndex = wBotIndex + getNbrOfLineToPrint() - 1; + + if(key == Qt::Key_Up) + selectPrevious(); + else + selectNext(); + + if(getInitialSelection() < wBotIndex) + { + setTableOffset(getInitialSelection()); + } + else if(getInitialSelection() >= wTopIndex) + { + setTableOffset(getInitialSelection() - getNbrOfLineToPrint() + 2); + } + + repaint(); + } + else + { + AbstractTableView::keyPressEvent(event); + } +} + +void StdTable::enableMultiSelection(bool enabled) +{ + mIsMultiSelctionAllowed = enabled; +} + +void StdTable::enableColumnSorting(bool enabled) +{ + mIsColumnSortingAllowed = enabled; +} + +/************************************************************************************ + Selection Management +************************************************************************************/ +void StdTable::expandSelectionUpTo(int to) +{ + if(to < mSelection.firstSelectedIndex) + { + mSelection.fromIndex = to; + mSelection.toIndex = mSelection.firstSelectedIndex; + } + else if(to > mSelection.firstSelectedIndex) + { + mSelection.fromIndex = mSelection.firstSelectedIndex; + mSelection.toIndex = to; + } + else if(to == mSelection.firstSelectedIndex) + { + setSingleSelection(to); + } +} + +void StdTable::setSingleSelection(int index) +{ + mSelection.firstSelectedIndex = index; + mSelection.fromIndex = index; + mSelection.toIndex = index; + emit selectionChangedSignal(index); +} + +int StdTable::getInitialSelection() +{ + return mSelection.firstSelectedIndex; +} + +void StdTable::selectNext() +{ + int wNext = getInitialSelection() + 1; + + // Bounding + wNext = wNext > getRowCount() - 1 ? getRowCount() - 1 : wNext; + wNext = wNext < 0 ? 0 : wNext; + + setSingleSelection(wNext); +} + +void StdTable::selectPrevious() +{ + int wNext = getInitialSelection() - 1; + + // Bounding + wNext = wNext > getRowCount() - 1 ? getRowCount() - 1 : wNext; + wNext = wNext < 0 ? 0 : wNext; + + setSingleSelection(wNext); +} + +bool StdTable::isSelected(int base, int offset) +{ + int wIndex = base + offset; + + if(wIndex >= mSelection.fromIndex && wIndex <= mSelection.toIndex) + return true; + else + return false; +} + +/************************************************************************************ + Data Management +************************************************************************************/ +void StdTable::addColumnAt(int width, QString title, bool isClickable, QString copyTitle) +{ + AbstractTableView::addColumnAt(width, title, isClickable); + + //append empty column to list of rows + for(int i = 0; i < mData.size(); i++) + mData[i].append(""); + + //Append copy title + if(!copyTitle.length()) + mCopyTitles.append(title); + else + mCopyTitles.append(copyTitle); +} + +void StdTable::setRowCount(int count) +{ + int wRowToAddOrRemove = count - mData.size(); + for(int i = 0; i < qAbs(wRowToAddOrRemove); i++) + { + if(wRowToAddOrRemove > 0) + { + mData.append(QList()); + for(int j = 0; j < getColumnCount(); j++) + mData.last().append(""); + } + else + mData.removeLast(); + } + AbstractTableView::setRowCount(count); +} + +void StdTable::deleteAllColumns() +{ + setRowCount(0); + AbstractTableView::deleteAllColumns(); + mCopyTitles.clear(); +} + +void StdTable::setCellContent(int r, int c, QString s) +{ + if(isValidIndex(r, c) == true) + mData[r].replace(c, s); +} + +QString StdTable::getCellContent(int r, int c) +{ + if(isValidIndex(r, c) == true) + return mData[r][c]; + else + return QString(""); +} + +bool StdTable::isValidIndex(int r, int c) +{ + if(r < 0 || c < 0 || r >= mData.size()) + return false; + return c < mData.at(r).size(); +} + +void StdTable::copyLineSlot() +{ + int colCount = getColumnCount(); + QString finalText = ""; + if(colCount == 1) + finalText = getCellContent(getInitialSelection(), 0); + else + { + for(int i = 0; i < colCount; i++) + { + QString cellContent = getCellContent(getInitialSelection(), i); + if(!cellContent.length()) //skip empty cells + continue; + QString title = mCopyTitles.at(i); + if(title.length()) + finalText += title + "="; + while(cellContent.endsWith(" ")) cellContent.chop(1); + finalText += cellContent; + finalText += "\r\n"; + } + } + Bridge::CopyToClipboard(finalText); +} + +void StdTable::copyTableSlot() +{ + int colCount = getColumnCount(); + int rowCount = getRowCount(); + QString finalText = ""; + if(colCount == 1) + { + for(int i = 0; i < rowCount; i++) + { + QString cellContent = getCellContent(i, 0); + if(!cellContent.length()) //skip empty cells + continue; + finalText += cellContent + "\r\n"; + } + } + else + { + int charwidth = getCharWidth(); + for(int i = 0; i < colCount; i++) + { + if(i) + finalText += " "; + int colWidth = getColumnWidth(i) / charwidth; + if(colWidth) + finalText += getColTitle(i).leftJustified(colWidth, QChar(' '), true); + else + finalText += getColTitle(i); + } + finalText += "\r\n"; + for(int i = 0; i < rowCount; i++) + { + QString finalRowText = ""; + for(int j = 0; j < colCount; j++) + { + if(j) + finalRowText += " "; + QString cellContent = getCellContent(i, j); + int colWidth = getColumnWidth(j) / charwidth; + if(colWidth && j != colCount - 1) + finalRowText += cellContent.leftJustified(colWidth, QChar(' '), true); + else + finalRowText += cellContent; + } + finalText += finalRowText + "\r\n"; + } + } + Bridge::CopyToClipboard(finalText); +} + +void StdTable::copyEntrySlot() +{ + QAction* action = qobject_cast(sender()); + if(!action) + return; + int col = action->objectName().toInt(); + QString finalText = getCellContent(getInitialSelection(), col); + while(finalText.endsWith(" ")) finalText.chop(1); + Bridge::CopyToClipboard(finalText); +} + +void StdTable::setupCopyMenu(QMenu* copyMenu) +{ + if(!getColumnCount()) + return; + //Copy->Whole Line + QAction* mCopyLine = new QAction("Whole &Line", this); + connect(mCopyLine, SIGNAL(triggered()), this, SLOT(copyLineSlot())); + copyMenu->addAction(mCopyLine); + //Copy->Whole Table + QAction* mCopyTable = new QAction("Whole &Table", this); + connect(mCopyTable, SIGNAL(triggered()), this, SLOT(copyTableSlot())); + copyMenu->addAction(mCopyTable); + //Copy->Separator + copyMenu->addSeparator(); + //Copy->ColName + for(int i = 0; i < getColumnCount(); i++) + { + if(!getCellContent(getInitialSelection(), i).length()) //skip empty cells + continue; + QString title = mCopyTitles.at(i); + if(!title.length()) //skip empty copy titles + continue; + QAction* mCopyAction = new QAction(title, this); + mCopyAction->setObjectName(QString::number(i)); + connect(mCopyAction, SIGNAL(triggered()), this, SLOT(copyEntrySlot())); + copyMenu->addAction(mCopyAction); + } +} + +void StdTable::setCopyMenuOnly(bool bSet, bool bDebugOnly) +{ + mCopyMenuOnly = bSet; + mCopyMenuDebugOnly = bDebugOnly; +} + +void StdTable::contextMenuRequestedSlot(const QPoint & pos) +{ + if(!mCopyMenuOnly) + { + emit contextMenuSignal(pos); + return; + } + if(mCopyMenuDebugOnly && !DbgIsDebugging()) + return; + QMenu* wMenu = new QMenu(this); + QMenu wCopyMenu("&Copy", this); + setupCopyMenu(&wCopyMenu); + if(wCopyMenu.actions().length()) + { + wMenu->addSeparator(); + wMenu->addMenu(&wCopyMenu); + wMenu->exec(mapToGlobal(pos)); + } +} + +void StdTable::headerButtonPressedSlot(int col) +{ + if(!mIsColumnSortingAllowed) + return; + if(mSort.first != col) //first = column to sort + { + mSort.first = col; + mSort.second = false; //second = ascending/descending + } + else + mSort.second = !mSort.second; + reloadData(); +} + +void StdTable::reloadData() +{ + if(mSort.first != -1) //re-sort if the user wants to sort + qSort(mData.begin(), mData.end(), ColumnCompare(mSort.first, mSort.second)); + AbstractTableView::reloadData(); +} diff --git a/src/gui/Src/BasicView/StdTable.h b/src/gui/Src/BasicView/StdTable.h index c7720658..dc069655 100644 --- a/src/gui/Src/BasicView/StdTable.h +++ b/src/gui/Src/BasicView/StdTable.h @@ -1,101 +1,101 @@ -#ifndef STDTABLE_H -#define STDTABLE_H - -#include "AbstractTableView.h" - -class StdTable : public AbstractTableView -{ - Q_OBJECT -public: - explicit StdTable(QWidget* parent = 0); - QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); - void reloadData(); - - void mouseMoveEvent(QMouseEvent* event); - void mousePressEvent(QMouseEvent* event); - void mouseDoubleClickEvent(QMouseEvent* event); - void mouseReleaseEvent(QMouseEvent* event); - void keyPressEvent(QKeyEvent* event); - - void enableMultiSelection(bool enabled); - void enableColumnSorting(bool enabled); - - // Selection Management - void expandSelectionUpTo(int to); - void setSingleSelection(int index); - int getInitialSelection(); - void selectNext(); - void selectPrevious(); - bool isSelected(int base, int offset); - - // Data Management - void addColumnAt(int width, QString title, bool isClickable, QString copyTitle = ""); - void setRowCount(int count); - void deleteAllColumns(); - void setCellContent(int r, int c, QString s); - QString getCellContent(int r, int c); - bool isValidIndex(int r, int c); - - //context menu helpers - void setupCopyMenu(QMenu* copyMenu); - void setCopyMenuOnly(bool bSet, bool bDebugOnly = true); - -signals: - void selectionChangedSignal(int index); - void keyPressedSignal(QKeyEvent* event); - void doubleClickedSignal(); - void contextMenuSignal(const QPoint & pos); - -public slots: - void copyLineSlot(); - void copyTableSlot(); - void copyEntrySlot(); - void contextMenuRequestedSlot(const QPoint & pos); - void headerButtonPressedSlot(int col); - -private: - class ColumnCompare - { - public: - ColumnCompare(int col, bool greater) - { - mCol = col; - mGreater = greater; - } - - inline bool operator()(const QList & a, const QList & b) const - { - bool less = QString::compare(a.at(mCol), b.at(mCol), Qt::CaseInsensitive) < 0; - if(mGreater) - return !less; - return less; - } - private: - int mCol; - int mGreater; - }; - - enum GuiState_t {NoState, MultiRowsSelectionState}; - - typedef struct _SelectionData_t - { - int firstSelectedIndex; - int fromIndex; - int toIndex; - } SelectionData_t; - - GuiState_t mGuiState; - - SelectionData_t mSelection; - - bool mIsMultiSelctionAllowed; - bool mCopyMenuOnly; - bool mCopyMenuDebugOnly; - bool mIsColumnSortingAllowed; - - QList> mData; - QList mCopyTitles; - QPair mSort; -}; - -#endif // STDTABLE_H +#ifndef STDTABLE_H +#define STDTABLE_H + +#include "AbstractTableView.h" + +class StdTable : public AbstractTableView +{ + Q_OBJECT +public: + explicit StdTable(QWidget* parent = 0); + QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); + void reloadData(); + + void mouseMoveEvent(QMouseEvent* event); + void mousePressEvent(QMouseEvent* event); + void mouseDoubleClickEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event); + void keyPressEvent(QKeyEvent* event); + + void enableMultiSelection(bool enabled); + void enableColumnSorting(bool enabled); + + // Selection Management + void expandSelectionUpTo(int to); + void setSingleSelection(int index); + int getInitialSelection(); + void selectNext(); + void selectPrevious(); + bool isSelected(int base, int offset); + + // Data Management + void addColumnAt(int width, QString title, bool isClickable, QString copyTitle = ""); + void setRowCount(int count); + void deleteAllColumns(); + void setCellContent(int r, int c, QString s); + QString getCellContent(int r, int c); + bool isValidIndex(int r, int c); + + //context menu helpers + void setupCopyMenu(QMenu* copyMenu); + void setCopyMenuOnly(bool bSet, bool bDebugOnly = true); + +signals: + void selectionChangedSignal(int index); + void keyPressedSignal(QKeyEvent* event); + void doubleClickedSignal(); + void contextMenuSignal(const QPoint & pos); + +public slots: + void copyLineSlot(); + void copyTableSlot(); + void copyEntrySlot(); + void contextMenuRequestedSlot(const QPoint & pos); + void headerButtonPressedSlot(int col); + +private: + class ColumnCompare + { + public: + ColumnCompare(int col, bool greater) + { + mCol = col; + mGreater = greater; + } + + inline bool operator()(const QList & a, const QList & b) const + { + bool less = QString::compare(a.at(mCol), b.at(mCol), Qt::CaseInsensitive) < 0; + if(mGreater) + return !less; + return less; + } + private: + int mCol; + int mGreater; + }; + + enum GuiState_t {NoState, MultiRowsSelectionState}; + + typedef struct _SelectionData_t + { + int firstSelectedIndex; + int fromIndex; + int toIndex; + } SelectionData_t; + + GuiState_t mGuiState; + + SelectionData_t mSelection; + + bool mIsMultiSelctionAllowed; + bool mCopyMenuOnly; + bool mCopyMenuDebugOnly; + bool mIsColumnSortingAllowed; + + QList> mData; + QList mCopyTitles; + QPair mSort; +}; + +#endif // STDTABLE_H diff --git a/src/gui/Src/Bridge/Bridge.cpp b/src/gui/Src/Bridge/Bridge.cpp index 1944af61..fed68d1a 100644 --- a/src/gui/Src/Bridge/Bridge.cpp +++ b/src/gui/Src/Bridge/Bridge.cpp @@ -1,536 +1,536 @@ -#include "Bridge.h" -#include -#include "QBeaEngine.h" -#include "main.h" -#include "Exports.h" - -/************************************************************************************ - Global Variables -************************************************************************************/ -static Bridge* mBridge; - -/************************************************************************************ - Class Members -************************************************************************************/ -Bridge::Bridge(QObject* parent) : QObject(parent) -{ - mBridgeMutex = new QMutex(); - winId = 0; - scriptView = 0; - referenceManager = 0; - bridgeResult = 0; - hasBridgeResult = false; - dbgStopped = false; -} - -Bridge::~Bridge() -{ - delete mBridgeMutex; -} - -void Bridge::CopyToClipboard(const QString & text) -{ - QClipboard* clipboard = QApplication::clipboard(); - clipboard->setText(text); -} - -void Bridge::setResult(dsint result) -{ - bridgeResult = result; - hasBridgeResult = true; -} - -/************************************************************************************ - Static Functions -************************************************************************************/ -Bridge* Bridge::getBridge() -{ - return mBridge; -} - -void Bridge::initBridge() -{ - mBridge = new Bridge(); -} - -/************************************************************************************ - Helper Functions -************************************************************************************/ - -void Bridge::emitLoadSourceFile(const QString path, int line, int selection) -{ - emit loadSourceFile(path, line, selection); -} - -void Bridge::emitMenuAddToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu) -{ - BridgeResult result; - emit menuAddMenuToList(parent, menu, hMenu, hParentMenu); - result.Wait(); -} - -void Bridge::setDbgStopped() -{ - dbgStopped = true; -} - -/************************************************************************************ - Message processing -************************************************************************************/ - -void* Bridge::processMessage(GUIMSG type, void* param1, void* param2) -{ - if(dbgStopped) //there can be no more messages if the debugger stopped = BUG - __debugbreak(); - switch(type) - { - case GUI_DISASSEMBLE_AT: - emit disassembleAt((dsint)param1, (dsint)param2); - break; - - case GUI_SET_DEBUG_STATE: - emit dbgStateChanged((DBGSTATE)(dsint)param1); - break; - - case GUI_ADD_MSG_TO_LOG: - emit addMsgToLog(QString((const char*)param1)); - break; - - case GUI_CLEAR_LOG: - emit clearLog(); - break; - - case GUI_UPDATE_REGISTER_VIEW: - emit updateRegisters(); - break; - - case GUI_UPDATE_DISASSEMBLY_VIEW: - emit repaintGui(); - break; - - case GUI_UPDATE_BREAKPOINTS_VIEW: - emit updateBreakpoints(); - break; - - case GUI_UPDATE_WINDOW_TITLE: - emit updateWindowTitle(QString((const char*)param1)); - break; - - case GUI_GET_WINDOW_HANDLE: - return winId; - - case GUI_DUMP_AT: - emit dumpAt((dsint)param1); - break; - - case GUI_SCRIPT_ADD: - { - BridgeResult result; - emit scriptAdd((int)param1, (const char**)param2); - result.Wait(); - } - break; - - case GUI_SCRIPT_CLEAR: - emit scriptClear(); - break; - - case GUI_SCRIPT_SETIP: - emit scriptSetIp((int)param1); - break; - - case GUI_SCRIPT_ERROR: - { - BridgeResult result; - emit scriptError((int)param1, QString((const char*)param2)); - result.Wait(); - } - break; - - case GUI_SCRIPT_SETTITLE: - emit scriptSetTitle(QString((const char*)param1)); - break; - - case GUI_SCRIPT_SETINFOLINE: - emit scriptSetInfoLine((int)param1, QString((const char*)param2)); - break; - - case GUI_SCRIPT_MESSAGE: - { - BridgeResult result; - emit scriptMessage(QString((const char*)param1)); - result.Wait(); - } - break; - - case GUI_SCRIPT_MSGYN: - { - BridgeResult result; - emit scriptQuestion(QString((const char*)param1)); - return (void*)result.Wait(); - } - break; - - case GUI_SCRIPT_ENABLEHIGHLIGHTING: - emit scriptEnableHighlighting((bool)param1); - break; - - case GUI_SYMBOL_UPDATE_MODULE_LIST: - emit updateSymbolList((int)param1, (SYMBOLMODULEINFO*)param2); - break; - - case GUI_SYMBOL_LOG_ADD: - emit addMsgToSymbolLog(QString((const char*)param1)); - break; - - case GUI_SYMBOL_LOG_CLEAR: - emit clearSymbolLog(); - break; - - case GUI_SYMBOL_SET_PROGRESS: - emit setSymbolProgress((int)param1); - break; - - case GUI_REF_ADDCOLUMN: - emit referenceAddColumnAt((int)param1, QString((const char*)param2)); - break; - - case GUI_REF_SETROWCOUNT: - emit referenceSetRowCount((dsint)param1); - break; - - case GUI_REF_GETROWCOUNT: - return (void*)referenceManager->currentReferenceView()->mList->getRowCount(); - - case GUI_REF_DELETEALLCOLUMNS: - GuiReferenceInitialize("References"); - break; - - case GUI_REF_SETCELLCONTENT: - { - CELLINFO* info = (CELLINFO*)param1; - emit referenceSetCellContent(info->row, info->col, QString(info->str)); - } - break; - - case GUI_REF_GETCELLCONTENT: - return (void*)referenceManager->currentReferenceView()->mList->getCellContent((int)param1, (int)param2).toUtf8().constData(); - - case GUI_REF_RELOADDATA: - emit referenceReloadData(); - break; - - case GUI_REF_SETSINGLESELECTION: - emit referenceSetSingleSelection((int)param1, (bool)param2); - break; - - case GUI_REF_SETPROGRESS: - emit referenceSetProgress((int)param1); - break; - - case GUI_REF_SETSEARCHSTARTCOL: - emit referenceSetSearchStartCol((int)param1); - break; - - case GUI_REF_INITIALIZE: - { - BridgeResult result; - emit referenceInitialize(QString((const char*)param1)); - result.Wait(); - } - break; - - case GUI_STACK_DUMP_AT: - emit stackDumpAt((duint)param1, (duint)param2); - break; - - case GUI_UPDATE_DUMP_VIEW: - emit updateDump(); - break; - - case GUI_UPDATE_THREAD_VIEW: - emit updateThreads(); - break; - - case GUI_UPDATE_MEMORY_VIEW: - emit updateMemory(); - break; - - case GUI_ADD_RECENT_FILE: - emit addRecentFile(QString((const char*)param1)); - break; - - case GUI_SET_LAST_EXCEPTION: - emit setLastException((unsigned int)param1); - break; - - case GUI_GET_DISASSEMBLY: - { - duint parVA = (duint)param1; - char* text = (char*)param2; - if(!text || !parVA || !DbgIsDebugging()) - return 0; - byte_t wBuffer[16]; - if(!DbgMemRead(parVA, wBuffer, 16)) - return 0; - QBeaEngine disasm(-1); - Instruction_t instr = disasm.DisassembleAt(wBuffer, 16, 0, 0, parVA); - QList richText; - CapstoneTokenizer::TokenToRichText(instr.tokens, richText, 0); - QString finalInstruction = ""; - for(int i = 0; i < richText.size(); i++) - finalInstruction += richText.at(i).text; - strcpy_s(text, GUI_MAX_DISASSEMBLY_SIZE, finalInstruction.toUtf8().constData()); - return (void*)1; - } - break; - - case GUI_MENU_ADD: - { - BridgeResult result; - emit menuAddMenu((int)param1, QString((const char*)param2)); - return (void*)result.Wait(); - } - break; - - case GUI_MENU_ADD_ENTRY: - { - BridgeResult result; - emit menuAddMenuEntry((int)param1, QString((const char*)param2)); - return (void*)result.Wait(); - } - break; - - case GUI_MENU_ADD_SEPARATOR: - { - BridgeResult result; - emit menuAddSeparator((int)param1); - result.Wait(); - } - break; - - case GUI_MENU_CLEAR: - { - BridgeResult result; - emit menuClearMenu((int)param1); - result.Wait(); - } - break; - - case GUI_SELECTION_GET: - { - int hWindow = (int)param1; - SELECTIONDATA* selection = (SELECTIONDATA*)param2; - if(!DbgIsDebugging()) - return (void*)false; - BridgeResult result; - switch(hWindow) - { - case GUI_DISASSEMBLY: - emit selectionDisasmGet(selection); - break; - case GUI_DUMP: - emit selectionDumpGet(selection); - break; - case GUI_STACK: - emit selectionStackGet(selection); - break; - default: - return (void*)false; - } - result.Wait(); - if(selection->start > selection->end) //swap start and end - { - dsint temp = selection->end; - selection->end = selection->start; - selection->start = temp; - } - return (void*)true; - } - break; - - case GUI_SELECTION_SET: - { - int hWindow = (int)param1; - const SELECTIONDATA* selection = (const SELECTIONDATA*)param2; - if(!DbgIsDebugging()) - return (void*)false; - BridgeResult result; - switch(hWindow) - { - case GUI_DISASSEMBLY: - emit selectionDisasmSet(selection); - break; - case GUI_DUMP: - emit selectionDumpSet(selection); - break; - case GUI_STACK: - emit selectionStackSet(selection); - break; - default: - return (void*)false; - } - return (void*)result.Wait(); - } - break; - - case GUI_GETLINE_WINDOW: - { - QString text = ""; - BridgeResult result; - emit getStrWindow(QString((const char*)param1), &text); - if(result.Wait()) - { - strcpy_s((char*)param2, GUI_MAX_LINE_SIZE, text.toUtf8().constData()); - return (void*)true; - } - return (void*)false; //cancel/escape - } - break; - - case GUI_AUTOCOMPLETE_ADDCMD: - emit autoCompleteAddCmd(QString((const char*)param1)); - break; - - case GUI_AUTOCOMPLETE_DELCMD: - emit autoCompleteDelCmd(QString((const char*)param1)); - break; - - case GUI_AUTOCOMPLETE_CLEARALL: - emit autoCompleteClearAll(); - break; - - case GUI_ADD_MSG_TO_STATUSBAR: - emit addMsgToStatusBar(QString((const char*)param1)); - break; - - case GUI_UPDATE_SIDEBAR: - emit updateSideBar(); - break; - - case GUI_REPAINT_TABLE_VIEW: - emit repaintTableView(); - break; - - case GUI_UPDATE_PATCHES: - emit updatePatches(); - break; - - case GUI_UPDATE_CALLSTACK: - emit updateCallStack(); - break; - - case GUI_SYMBOL_REFRESH_CURRENT: - emit symbolRefreshCurrent(); - break; - - case GUI_LOAD_SOURCE_FILE: - emitLoadSourceFile(QString((const char*)param1), (int)param2); - break; - - case GUI_MENU_SET_ICON: - { - int hMenu = (int)param1; - const ICONDATA* icon = (const ICONDATA*)param2; - BridgeResult result; - if(!icon) - emit setIconMenu(hMenu, QIcon()); - else - { - QImage img; - img.loadFromData((uchar*)icon->data, icon->size); - QIcon qIcon(QPixmap::fromImage(img)); - emit setIconMenu(hMenu, qIcon); - } - result.Wait(); - } - break; - - case GUI_MENU_SET_ENTRY_ICON: - { - int hEntry = (int)param1; - const ICONDATA* icon = (const ICONDATA*)param2; - BridgeResult result; - if(!icon) - emit setIconMenuEntry(hEntry, QIcon()); - else - { - QImage img; - img.loadFromData((uchar*)icon->data, icon->size); - QIcon qIcon(QPixmap::fromImage(img)); - emit setIconMenuEntry(hEntry, qIcon); - } - result.Wait(); - } - break; - - case GUI_SHOW_CPU: - emit showCpu(); - break; - - case GUI_ADD_QWIDGET_TAB: - emit addQWidgetTab((QWidget*)param1); - break; - - case GUI_SHOW_QWIDGET_TAB: - emit showQWidgetTab((QWidget*)param1); - break; - - case GUI_CLOSE_QWIDGET_TAB: - emit closeQWidgetTab((QWidget*)param1); - break; - - case GUI_EXECUTE_ON_GUI_THREAD: - GuiAddLogMessage(QString().sprintf("thread id (bridge) %X\n", GetCurrentThreadId()).toUtf8().constData()); - emit executeOnGuiThread(param1); - break; - - case GUI_UPDATE_TIME_WASTED_COUNTER: - emit updateTimeWastedCounter(); - break; - - case GUI_SET_GLOBAL_NOTES: - { - QString text = QString((const char*)param1); - emit setGlobalNotes(text); - } - break; - - case GUI_GET_GLOBAL_NOTES: - { - BridgeResult result; - emit getGlobalNotes(param1); - result.Wait(); - } - break; - - case GUI_SET_DEBUGGEE_NOTES: - { - QString text = QString((const char*)param1); - emit setDebuggeeNotes(text); - } - break; - - case GUI_GET_DEBUGGEE_NOTES: - { - BridgeResult result; - emit getDebuggeeNotes(param1); - result.Wait(); - } - break; - } - return nullptr; -} - -/************************************************************************************ - Exported Functions -************************************************************************************/ -__declspec(dllexport) int _gui_guiinit(int argc, char* argv[]) -{ - return main(argc, argv); -} - -__declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* param2) -{ - return Bridge::getBridge()->processMessage(type, param1, param2); -} +#include "Bridge.h" +#include +#include "QBeaEngine.h" +#include "main.h" +#include "Exports.h" + +/************************************************************************************ + Global Variables +************************************************************************************/ +static Bridge* mBridge; + +/************************************************************************************ + Class Members +************************************************************************************/ +Bridge::Bridge(QObject* parent) : QObject(parent) +{ + mBridgeMutex = new QMutex(); + winId = 0; + scriptView = 0; + referenceManager = 0; + bridgeResult = 0; + hasBridgeResult = false; + dbgStopped = false; +} + +Bridge::~Bridge() +{ + delete mBridgeMutex; +} + +void Bridge::CopyToClipboard(const QString & text) +{ + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(text); +} + +void Bridge::setResult(dsint result) +{ + bridgeResult = result; + hasBridgeResult = true; +} + +/************************************************************************************ + Static Functions +************************************************************************************/ +Bridge* Bridge::getBridge() +{ + return mBridge; +} + +void Bridge::initBridge() +{ + mBridge = new Bridge(); +} + +/************************************************************************************ + Helper Functions +************************************************************************************/ + +void Bridge::emitLoadSourceFile(const QString path, int line, int selection) +{ + emit loadSourceFile(path, line, selection); +} + +void Bridge::emitMenuAddToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu) +{ + BridgeResult result; + emit menuAddMenuToList(parent, menu, hMenu, hParentMenu); + result.Wait(); +} + +void Bridge::setDbgStopped() +{ + dbgStopped = true; +} + +/************************************************************************************ + Message processing +************************************************************************************/ + +void* Bridge::processMessage(GUIMSG type, void* param1, void* param2) +{ + if(dbgStopped) //there can be no more messages if the debugger stopped = BUG + __debugbreak(); + switch(type) + { + case GUI_DISASSEMBLE_AT: + emit disassembleAt((dsint)param1, (dsint)param2); + break; + + case GUI_SET_DEBUG_STATE: + emit dbgStateChanged((DBGSTATE)(dsint)param1); + break; + + case GUI_ADD_MSG_TO_LOG: + emit addMsgToLog(QString((const char*)param1)); + break; + + case GUI_CLEAR_LOG: + emit clearLog(); + break; + + case GUI_UPDATE_REGISTER_VIEW: + emit updateRegisters(); + break; + + case GUI_UPDATE_DISASSEMBLY_VIEW: + emit repaintGui(); + break; + + case GUI_UPDATE_BREAKPOINTS_VIEW: + emit updateBreakpoints(); + break; + + case GUI_UPDATE_WINDOW_TITLE: + emit updateWindowTitle(QString((const char*)param1)); + break; + + case GUI_GET_WINDOW_HANDLE: + return winId; + + case GUI_DUMP_AT: + emit dumpAt((dsint)param1); + break; + + case GUI_SCRIPT_ADD: + { + BridgeResult result; + emit scriptAdd((int)param1, (const char**)param2); + result.Wait(); + } + break; + + case GUI_SCRIPT_CLEAR: + emit scriptClear(); + break; + + case GUI_SCRIPT_SETIP: + emit scriptSetIp((int)param1); + break; + + case GUI_SCRIPT_ERROR: + { + BridgeResult result; + emit scriptError((int)param1, QString((const char*)param2)); + result.Wait(); + } + break; + + case GUI_SCRIPT_SETTITLE: + emit scriptSetTitle(QString((const char*)param1)); + break; + + case GUI_SCRIPT_SETINFOLINE: + emit scriptSetInfoLine((int)param1, QString((const char*)param2)); + break; + + case GUI_SCRIPT_MESSAGE: + { + BridgeResult result; + emit scriptMessage(QString((const char*)param1)); + result.Wait(); + } + break; + + case GUI_SCRIPT_MSGYN: + { + BridgeResult result; + emit scriptQuestion(QString((const char*)param1)); + return (void*)result.Wait(); + } + break; + + case GUI_SCRIPT_ENABLEHIGHLIGHTING: + emit scriptEnableHighlighting((bool)param1); + break; + + case GUI_SYMBOL_UPDATE_MODULE_LIST: + emit updateSymbolList((int)param1, (SYMBOLMODULEINFO*)param2); + break; + + case GUI_SYMBOL_LOG_ADD: + emit addMsgToSymbolLog(QString((const char*)param1)); + break; + + case GUI_SYMBOL_LOG_CLEAR: + emit clearSymbolLog(); + break; + + case GUI_SYMBOL_SET_PROGRESS: + emit setSymbolProgress((int)param1); + break; + + case GUI_REF_ADDCOLUMN: + emit referenceAddColumnAt((int)param1, QString((const char*)param2)); + break; + + case GUI_REF_SETROWCOUNT: + emit referenceSetRowCount((dsint)param1); + break; + + case GUI_REF_GETROWCOUNT: + return (void*)referenceManager->currentReferenceView()->mList->getRowCount(); + + case GUI_REF_DELETEALLCOLUMNS: + GuiReferenceInitialize("References"); + break; + + case GUI_REF_SETCELLCONTENT: + { + CELLINFO* info = (CELLINFO*)param1; + emit referenceSetCellContent(info->row, info->col, QString(info->str)); + } + break; + + case GUI_REF_GETCELLCONTENT: + return (void*)referenceManager->currentReferenceView()->mList->getCellContent((int)param1, (int)param2).toUtf8().constData(); + + case GUI_REF_RELOADDATA: + emit referenceReloadData(); + break; + + case GUI_REF_SETSINGLESELECTION: + emit referenceSetSingleSelection((int)param1, (bool)param2); + break; + + case GUI_REF_SETPROGRESS: + emit referenceSetProgress((int)param1); + break; + + case GUI_REF_SETSEARCHSTARTCOL: + emit referenceSetSearchStartCol((int)param1); + break; + + case GUI_REF_INITIALIZE: + { + BridgeResult result; + emit referenceInitialize(QString((const char*)param1)); + result.Wait(); + } + break; + + case GUI_STACK_DUMP_AT: + emit stackDumpAt((duint)param1, (duint)param2); + break; + + case GUI_UPDATE_DUMP_VIEW: + emit updateDump(); + break; + + case GUI_UPDATE_THREAD_VIEW: + emit updateThreads(); + break; + + case GUI_UPDATE_MEMORY_VIEW: + emit updateMemory(); + break; + + case GUI_ADD_RECENT_FILE: + emit addRecentFile(QString((const char*)param1)); + break; + + case GUI_SET_LAST_EXCEPTION: + emit setLastException((unsigned int)param1); + break; + + case GUI_GET_DISASSEMBLY: + { + duint parVA = (duint)param1; + char* text = (char*)param2; + if(!text || !parVA || !DbgIsDebugging()) + return 0; + byte_t wBuffer[16]; + if(!DbgMemRead(parVA, wBuffer, 16)) + return 0; + QBeaEngine disasm(-1); + Instruction_t instr = disasm.DisassembleAt(wBuffer, 16, 0, 0, parVA); + QList richText; + CapstoneTokenizer::TokenToRichText(instr.tokens, richText, 0); + QString finalInstruction = ""; + for(int i = 0; i < richText.size(); i++) + finalInstruction += richText.at(i).text; + strcpy_s(text, GUI_MAX_DISASSEMBLY_SIZE, finalInstruction.toUtf8().constData()); + return (void*)1; + } + break; + + case GUI_MENU_ADD: + { + BridgeResult result; + emit menuAddMenu((int)param1, QString((const char*)param2)); + return (void*)result.Wait(); + } + break; + + case GUI_MENU_ADD_ENTRY: + { + BridgeResult result; + emit menuAddMenuEntry((int)param1, QString((const char*)param2)); + return (void*)result.Wait(); + } + break; + + case GUI_MENU_ADD_SEPARATOR: + { + BridgeResult result; + emit menuAddSeparator((int)param1); + result.Wait(); + } + break; + + case GUI_MENU_CLEAR: + { + BridgeResult result; + emit menuClearMenu((int)param1); + result.Wait(); + } + break; + + case GUI_SELECTION_GET: + { + int hWindow = (int)param1; + SELECTIONDATA* selection = (SELECTIONDATA*)param2; + if(!DbgIsDebugging()) + return (void*)false; + BridgeResult result; + switch(hWindow) + { + case GUI_DISASSEMBLY: + emit selectionDisasmGet(selection); + break; + case GUI_DUMP: + emit selectionDumpGet(selection); + break; + case GUI_STACK: + emit selectionStackGet(selection); + break; + default: + return (void*)false; + } + result.Wait(); + if(selection->start > selection->end) //swap start and end + { + dsint temp = selection->end; + selection->end = selection->start; + selection->start = temp; + } + return (void*)true; + } + break; + + case GUI_SELECTION_SET: + { + int hWindow = (int)param1; + const SELECTIONDATA* selection = (const SELECTIONDATA*)param2; + if(!DbgIsDebugging()) + return (void*)false; + BridgeResult result; + switch(hWindow) + { + case GUI_DISASSEMBLY: + emit selectionDisasmSet(selection); + break; + case GUI_DUMP: + emit selectionDumpSet(selection); + break; + case GUI_STACK: + emit selectionStackSet(selection); + break; + default: + return (void*)false; + } + return (void*)result.Wait(); + } + break; + + case GUI_GETLINE_WINDOW: + { + QString text = ""; + BridgeResult result; + emit getStrWindow(QString((const char*)param1), &text); + if(result.Wait()) + { + strcpy_s((char*)param2, GUI_MAX_LINE_SIZE, text.toUtf8().constData()); + return (void*)true; + } + return (void*)false; //cancel/escape + } + break; + + case GUI_AUTOCOMPLETE_ADDCMD: + emit autoCompleteAddCmd(QString((const char*)param1)); + break; + + case GUI_AUTOCOMPLETE_DELCMD: + emit autoCompleteDelCmd(QString((const char*)param1)); + break; + + case GUI_AUTOCOMPLETE_CLEARALL: + emit autoCompleteClearAll(); + break; + + case GUI_ADD_MSG_TO_STATUSBAR: + emit addMsgToStatusBar(QString((const char*)param1)); + break; + + case GUI_UPDATE_SIDEBAR: + emit updateSideBar(); + break; + + case GUI_REPAINT_TABLE_VIEW: + emit repaintTableView(); + break; + + case GUI_UPDATE_PATCHES: + emit updatePatches(); + break; + + case GUI_UPDATE_CALLSTACK: + emit updateCallStack(); + break; + + case GUI_SYMBOL_REFRESH_CURRENT: + emit symbolRefreshCurrent(); + break; + + case GUI_LOAD_SOURCE_FILE: + emitLoadSourceFile(QString((const char*)param1), (int)param2); + break; + + case GUI_MENU_SET_ICON: + { + int hMenu = (int)param1; + const ICONDATA* icon = (const ICONDATA*)param2; + BridgeResult result; + if(!icon) + emit setIconMenu(hMenu, QIcon()); + else + { + QImage img; + img.loadFromData((uchar*)icon->data, icon->size); + QIcon qIcon(QPixmap::fromImage(img)); + emit setIconMenu(hMenu, qIcon); + } + result.Wait(); + } + break; + + case GUI_MENU_SET_ENTRY_ICON: + { + int hEntry = (int)param1; + const ICONDATA* icon = (const ICONDATA*)param2; + BridgeResult result; + if(!icon) + emit setIconMenuEntry(hEntry, QIcon()); + else + { + QImage img; + img.loadFromData((uchar*)icon->data, icon->size); + QIcon qIcon(QPixmap::fromImage(img)); + emit setIconMenuEntry(hEntry, qIcon); + } + result.Wait(); + } + break; + + case GUI_SHOW_CPU: + emit showCpu(); + break; + + case GUI_ADD_QWIDGET_TAB: + emit addQWidgetTab((QWidget*)param1); + break; + + case GUI_SHOW_QWIDGET_TAB: + emit showQWidgetTab((QWidget*)param1); + break; + + case GUI_CLOSE_QWIDGET_TAB: + emit closeQWidgetTab((QWidget*)param1); + break; + + case GUI_EXECUTE_ON_GUI_THREAD: + GuiAddLogMessage(QString().sprintf("thread id (bridge) %X\n", GetCurrentThreadId()).toUtf8().constData()); + emit executeOnGuiThread(param1); + break; + + case GUI_UPDATE_TIME_WASTED_COUNTER: + emit updateTimeWastedCounter(); + break; + + case GUI_SET_GLOBAL_NOTES: + { + QString text = QString((const char*)param1); + emit setGlobalNotes(text); + } + break; + + case GUI_GET_GLOBAL_NOTES: + { + BridgeResult result; + emit getGlobalNotes(param1); + result.Wait(); + } + break; + + case GUI_SET_DEBUGGEE_NOTES: + { + QString text = QString((const char*)param1); + emit setDebuggeeNotes(text); + } + break; + + case GUI_GET_DEBUGGEE_NOTES: + { + BridgeResult result; + emit getDebuggeeNotes(param1); + result.Wait(); + } + break; + } + return nullptr; +} + +/************************************************************************************ + Exported Functions +************************************************************************************/ +__declspec(dllexport) int _gui_guiinit(int argc, char* argv[]) +{ + return main(argc, argv); +} + +__declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* param2) +{ + return Bridge::getBridge()->processMessage(type, param1, param2); +} diff --git a/src/gui/Src/Bridge/Bridge.h b/src/gui/Src/Bridge/Bridge.h index 7cf26475..ad752bc6 100644 --- a/src/gui/Src/Bridge/Bridge.h +++ b/src/gui/Src/Bridge/Bridge.h @@ -1,124 +1,124 @@ -#ifndef BRIDGE_H -#define BRIDGE_H - -#include -#include -#include -#include -#include "Imports.h" -#include "ReferenceManager.h" -#include "BridgeResult.h" - -class Bridge : public QObject -{ - Q_OBJECT - - friend class BridgeResult; - -public: - explicit Bridge(QObject* parent = 0); - ~Bridge(); - - static Bridge* getBridge(); - static void initBridge(); - - // Message processing function - void* processMessage(GUIMSG type, void* param1, void* param2); - - // Misc functions - static void CopyToClipboard(const QString & text); - - //result function - void setResult(dsint result = 0); - - //helper functions - void emitLoadSourceFile(const QString path, int line = 0, int selection = 0); - void emitMenuAddToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu = -1); - void setDbgStopped(); - - //Public variables - void* winId; - QWidget* scriptView; - ReferenceManager* referenceManager; - -signals: - void disassembleAt(dsint va, dsint eip); - void repaintGui(); - void dbgStateChanged(DBGSTATE state); - void addMsgToLog(QString msg); - void clearLog(); - void updateRegisters(); - void updateBreakpoints(); - void updateWindowTitle(QString filename); - void dumpAt(dsint va); - void scriptAdd(int count, const char** lines); - void scriptClear(); - void scriptSetIp(int line); - void scriptError(int line, QString message); - void scriptSetTitle(QString title); - void scriptSetInfoLine(int line, QString info); - void scriptMessage(QString message); - void scriptQuestion(QString message); - void scriptEnableHighlighting(bool enable); - void updateSymbolList(int module_count, SYMBOLMODULEINFO* modules); - void addMsgToSymbolLog(QString msg); - void clearSymbolLog(); - void setSymbolProgress(int progress); - void referenceAddColumnAt(int width, QString title); - void referenceSetRowCount(dsint count); - void referenceSetCellContent(int r, int c, QString s); - void referenceReloadData(); - void referenceSetSingleSelection(int index, bool scroll); - void referenceSetProgress(int progress); - void referenceSetSearchStartCol(int col); - void referenceInitialize(QString name); - void stackDumpAt(duint va, duint csp); - void updateDump(); - void updateThreads(); - void updateMemory(); - void addRecentFile(QString file); - void setLastException(unsigned int exceptionCode); - void menuAddMenuToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu); - void menuAddMenu(int hMenu, QString title); - void menuAddMenuEntry(int hMenu, QString title); - void menuAddSeparator(int hMenu); - void menuClearMenu(int hMenu); - void menuRemoveMenuEntry(int hEntry); - void selectionDisasmGet(SELECTIONDATA* selection); - void selectionDisasmSet(const SELECTIONDATA* selection); - void selectionDumpGet(SELECTIONDATA* selection); - void selectionDumpSet(const SELECTIONDATA* selection); - void selectionStackGet(SELECTIONDATA* selection); - void selectionStackSet(const SELECTIONDATA* selection); - void getStrWindow(const QString title, QString* text); - void autoCompleteAddCmd(const QString cmd); - void autoCompleteDelCmd(const QString cmd); - void autoCompleteClearAll(); - void addMsgToStatusBar(QString msg); - void updateSideBar(); - void repaintTableView(); - void updatePatches(); - void updateCallStack(); - void symbolRefreshCurrent(); - void loadSourceFile(const QString path, int line, int selection); - void setIconMenuEntry(int hEntry, QIcon icon); - void setIconMenu(int hMenu, QIcon icon); - void showCpu(); - void addQWidgetTab(QWidget* qWidget); - void showQWidgetTab(QWidget* qWidget); - void closeQWidgetTab(QWidget* qWidget); - void executeOnGuiThread(void* cbGuiThread); - void updateTimeWastedCounter(); - void setGlobalNotes(const QString text); - void getGlobalNotes(void* text); - void setDebuggeeNotes(const QString text); - void getDebuggeeNotes(void* text); - -private: - QMutex* mBridgeMutex; - dsint bridgeResult; - volatile bool hasBridgeResult; - volatile bool dbgStopped; -}; - -#endif // BRIDGE_H +#ifndef BRIDGE_H +#define BRIDGE_H + +#include +#include +#include +#include +#include "Imports.h" +#include "ReferenceManager.h" +#include "BridgeResult.h" + +class Bridge : public QObject +{ + Q_OBJECT + + friend class BridgeResult; + +public: + explicit Bridge(QObject* parent = 0); + ~Bridge(); + + static Bridge* getBridge(); + static void initBridge(); + + // Message processing function + void* processMessage(GUIMSG type, void* param1, void* param2); + + // Misc functions + static void CopyToClipboard(const QString & text); + + //result function + void setResult(dsint result = 0); + + //helper functions + void emitLoadSourceFile(const QString path, int line = 0, int selection = 0); + void emitMenuAddToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu = -1); + void setDbgStopped(); + + //Public variables + void* winId; + QWidget* scriptView; + ReferenceManager* referenceManager; + +signals: + void disassembleAt(dsint va, dsint eip); + void repaintGui(); + void dbgStateChanged(DBGSTATE state); + void addMsgToLog(QString msg); + void clearLog(); + void updateRegisters(); + void updateBreakpoints(); + void updateWindowTitle(QString filename); + void dumpAt(dsint va); + void scriptAdd(int count, const char** lines); + void scriptClear(); + void scriptSetIp(int line); + void scriptError(int line, QString message); + void scriptSetTitle(QString title); + void scriptSetInfoLine(int line, QString info); + void scriptMessage(QString message); + void scriptQuestion(QString message); + void scriptEnableHighlighting(bool enable); + void updateSymbolList(int module_count, SYMBOLMODULEINFO* modules); + void addMsgToSymbolLog(QString msg); + void clearSymbolLog(); + void setSymbolProgress(int progress); + void referenceAddColumnAt(int width, QString title); + void referenceSetRowCount(dsint count); + void referenceSetCellContent(int r, int c, QString s); + void referenceReloadData(); + void referenceSetSingleSelection(int index, bool scroll); + void referenceSetProgress(int progress); + void referenceSetSearchStartCol(int col); + void referenceInitialize(QString name); + void stackDumpAt(duint va, duint csp); + void updateDump(); + void updateThreads(); + void updateMemory(); + void addRecentFile(QString file); + void setLastException(unsigned int exceptionCode); + void menuAddMenuToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu); + void menuAddMenu(int hMenu, QString title); + void menuAddMenuEntry(int hMenu, QString title); + void menuAddSeparator(int hMenu); + void menuClearMenu(int hMenu); + void menuRemoveMenuEntry(int hEntry); + void selectionDisasmGet(SELECTIONDATA* selection); + void selectionDisasmSet(const SELECTIONDATA* selection); + void selectionDumpGet(SELECTIONDATA* selection); + void selectionDumpSet(const SELECTIONDATA* selection); + void selectionStackGet(SELECTIONDATA* selection); + void selectionStackSet(const SELECTIONDATA* selection); + void getStrWindow(const QString title, QString* text); + void autoCompleteAddCmd(const QString cmd); + void autoCompleteDelCmd(const QString cmd); + void autoCompleteClearAll(); + void addMsgToStatusBar(QString msg); + void updateSideBar(); + void repaintTableView(); + void updatePatches(); + void updateCallStack(); + void symbolRefreshCurrent(); + void loadSourceFile(const QString path, int line, int selection); + void setIconMenuEntry(int hEntry, QIcon icon); + void setIconMenu(int hMenu, QIcon icon); + void showCpu(); + void addQWidgetTab(QWidget* qWidget); + void showQWidgetTab(QWidget* qWidget); + void closeQWidgetTab(QWidget* qWidget); + void executeOnGuiThread(void* cbGuiThread); + void updateTimeWastedCounter(); + void setGlobalNotes(const QString text); + void getGlobalNotes(void* text); + void setDebuggeeNotes(const QString text); + void getDebuggeeNotes(void* text); + +private: + QMutex* mBridgeMutex; + dsint bridgeResult; + volatile bool hasBridgeResult; + volatile bool dbgStopped; +}; + +#endif // BRIDGE_H diff --git a/src/gui/Src/Bridge/BridgeResult.cpp b/src/gui/Src/Bridge/BridgeResult.cpp index 5f52aad5..fdf4e124 100644 --- a/src/gui/Src/Bridge/BridgeResult.cpp +++ b/src/gui/Src/Bridge/BridgeResult.cpp @@ -1,20 +1,20 @@ -#include "BridgeResult.h" -#include "Bridge.h" - -BridgeResult::BridgeResult() -{ - Bridge::getBridge()->mBridgeMutex->lock(); - Bridge::getBridge()->hasBridgeResult = false; -} - -BridgeResult::~BridgeResult() -{ - Bridge::getBridge()->mBridgeMutex->unlock(); -} - -dsint BridgeResult::Wait() -{ - while(!Bridge::getBridge()->hasBridgeResult) //wait for thread completion - Sleep(100); - return Bridge::getBridge()->bridgeResult; -} +#include "BridgeResult.h" +#include "Bridge.h" + +BridgeResult::BridgeResult() +{ + Bridge::getBridge()->mBridgeMutex->lock(); + Bridge::getBridge()->hasBridgeResult = false; +} + +BridgeResult::~BridgeResult() +{ + Bridge::getBridge()->mBridgeMutex->unlock(); +} + +dsint BridgeResult::Wait() +{ + while(!Bridge::getBridge()->hasBridgeResult) //wait for thread completion + Sleep(100); + return Bridge::getBridge()->bridgeResult; +} diff --git a/src/gui/Src/Bridge/BridgeResult.h b/src/gui/Src/Bridge/BridgeResult.h index 74b42b00..d22002cc 100644 --- a/src/gui/Src/Bridge/BridgeResult.h +++ b/src/gui/Src/Bridge/BridgeResult.h @@ -1,14 +1,14 @@ -#ifndef BRIDGERESULT_H -#define BRIDGERESULT_H - -#include "Imports.h" - -class BridgeResult -{ -public: - BridgeResult(); - ~BridgeResult(); - dsint Wait(); -}; - -#endif // BRIDGERESULT_H +#ifndef BRIDGERESULT_H +#define BRIDGERESULT_H + +#include "Imports.h" + +class BridgeResult +{ +public: + BridgeResult(); + ~BridgeResult(); + dsint Wait(); +}; + +#endif // BRIDGERESULT_H diff --git a/src/gui/Src/Disassembler/QBeaEngine.cpp b/src/gui/Src/Disassembler/QBeaEngine.cpp index 85a98d21..6d83a967 100644 --- a/src/gui/Src/Disassembler/QBeaEngine.cpp +++ b/src/gui/Src/Disassembler/QBeaEngine.cpp @@ -1,184 +1,184 @@ -#include "QBeaEngine.h" - -QBeaEngine::QBeaEngine(int maxModuleSize) - : _tokenizer(maxModuleSize) -{ - CapstoneTokenizer::UpdateColors(); -} - -/** - * @brief Return the address of the nth instruction before the instruction pointed by ip. @n - * This function has been grabbed from OllyDbg ("Disassembleback" in asmserv.c) - * - * @param[in] data Address of the data to disassemble - * @param[in] base Original base address of the memory page (Required to disassemble destination addresses) - * @param[in] size Size of the data block pointed by data - * @param[in] ip RVA of the current instruction (Relative to data pointer) - * @param[in] n Number of instruction back - * - * @return Return the RVA (Relative to the data pointer) of the nth instruction before the instruction pointed by ip - */ -ulong QBeaEngine::DisassembleBack(byte_t* data, duint base, duint size, duint ip, int n) -{ - Q_UNUSED(base) - int i; - uint abuf[131], addr, back, cmdsize; - unsigned char* pdata; - - // Reset Disasm Structure - Capstone cp; - - // Check if the pointer is not null - if(data == NULL) - return 0; - - // Round the number of back instructions to 127 - if(n < 0) - n = 0; - else if(n > 127) - n = 127; - - // Check if the instruction pointer ip is not outside the memory range - if(ip >= size) - ip = size - 1; - - // Obvious answer - if(n == 0) - return ip; - - if(ip < (uint)n) - return ip; - - back = MAX_DISASM_BUFFER * (n + 3); // Instruction length limited to 16 - - if(ip < back) - back = ip; - - addr = ip - back; - - pdata = data + addr; - - for(i = 0; addr < ip; i++) - { - abuf[i % 128] = addr; - - if(!cp.Disassemble(0, pdata, (int)size)) - cmdsize = 1; - else - cmdsize = cp.Size(); - - pdata += cmdsize; - addr += cmdsize; - back -= cmdsize; - size -= cmdsize; - } - - if(i < n) - return abuf[0]; - else - return abuf[(i - n + 128) % 128]; - -} - -/** - * @brief Return the address of the nth instruction after the instruction pointed by ip. @n - * This function has been grabbed from OllyDbg ("Disassembleforward" in asmserv.c) - * - * @param[in] data Address of the data to disassemble - * @param[in] base Original base address of the memory page (Required to disassemble destination addresses) - * @param[in] size Size of the data block pointed by data - * @param[in] ip RVA of the current instruction (Relative to data pointer) - * @param[in] n Number of instruction next - * - * @return Return the RVA (Relative to the data pointer) of the nth instruction after the instruction pointed by ip - */ -ulong QBeaEngine::DisassembleNext(byte_t* data, duint base, duint size, duint ip, int n) -{ - Q_UNUSED(base) - int i; - uint cmdsize; - unsigned char* pdata; - - // Reset Disasm Structure - Capstone cp; - - if(data == NULL) - return 0; - - if(ip >= size) - ip = size - 1; - - if(n <= 0) - return ip; - - pdata = data + ip; - size -= ip; - - for(i = 0; i < n && size > 0; i++) - { - if(!cp.Disassemble(0, pdata, (int)size)) - cmdsize = 1; - else - cmdsize = cp.Size(); - - pdata += cmdsize; - ip += cmdsize; - size -= cmdsize; - } - - return ip; -} - -/** - * @brief Disassemble the instruction at the given ip RVA. - * - * @param[in] data Pointer to memory data (Can be either a buffer or the original data memory) - * @param[in] size Size of the memory pointed by data (Can be the memory page size if data points to the original memory page base address) - * @param[in] instIndex Offset to reach the instruction data from the data pointer - * @param[in] origBase Original base address of the memory page (Required to disassemble destination addresses) - * @param[in] origInstRVA Original Instruction RVA of the instruction to disassemble - * - * @return Return the disassembled instruction - */ - -Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint instIndex, duint origBase, duint origInstRVA) -{ - //tokenize - CapstoneTokenizer::InstructionToken cap; - _tokenizer.Tokenize(origBase + origInstRVA, data, size, cap); - int len = _tokenizer.Size(); - - const auto & cp = _tokenizer.GetCapstone(); - bool success = cp.Success(); - - auto branchType = Instruction_t::None; - if(success && (cp.InGroup(CS_GRP_JUMP) || cp.IsLoop())) - { - switch(cp.GetId()) - { - case X86_INS_JMP: - case X86_INS_LOOP: - branchType = Instruction_t::Unconditional; - break; - default: - branchType = Instruction_t::Conditional; - break; - } - } - - Instruction_t wInst; - wInst.instStr = QString(cp.InstructionText().c_str()); - wInst.dump = QByteArray((const char*)data, len); - wInst.rva = origInstRVA; - wInst.length = len; - wInst.branchType = branchType; - wInst.branchDestination = cp.BranchDestination(); - wInst.tokens = cap; - - return wInst; -} - -void QBeaEngine::UpdateConfig() -{ - _tokenizer.UpdateConfig(); +#include "QBeaEngine.h" + +QBeaEngine::QBeaEngine(int maxModuleSize) + : _tokenizer(maxModuleSize) +{ + CapstoneTokenizer::UpdateColors(); +} + +/** + * @brief Return the address of the nth instruction before the instruction pointed by ip. @n + * This function has been grabbed from OllyDbg ("Disassembleback" in asmserv.c) + * + * @param[in] data Address of the data to disassemble + * @param[in] base Original base address of the memory page (Required to disassemble destination addresses) + * @param[in] size Size of the data block pointed by data + * @param[in] ip RVA of the current instruction (Relative to data pointer) + * @param[in] n Number of instruction back + * + * @return Return the RVA (Relative to the data pointer) of the nth instruction before the instruction pointed by ip + */ +ulong QBeaEngine::DisassembleBack(byte_t* data, duint base, duint size, duint ip, int n) +{ + Q_UNUSED(base) + int i; + uint abuf[131], addr, back, cmdsize; + unsigned char* pdata; + + // Reset Disasm Structure + Capstone cp; + + // Check if the pointer is not null + if(data == NULL) + return 0; + + // Round the number of back instructions to 127 + if(n < 0) + n = 0; + else if(n > 127) + n = 127; + + // Check if the instruction pointer ip is not outside the memory range + if(ip >= size) + ip = size - 1; + + // Obvious answer + if(n == 0) + return ip; + + if(ip < (uint)n) + return ip; + + back = MAX_DISASM_BUFFER * (n + 3); // Instruction length limited to 16 + + if(ip < back) + back = ip; + + addr = ip - back; + + pdata = data + addr; + + for(i = 0; addr < ip; i++) + { + abuf[i % 128] = addr; + + if(!cp.Disassemble(0, pdata, (int)size)) + cmdsize = 1; + else + cmdsize = cp.Size(); + + pdata += cmdsize; + addr += cmdsize; + back -= cmdsize; + size -= cmdsize; + } + + if(i < n) + return abuf[0]; + else + return abuf[(i - n + 128) % 128]; + +} + +/** + * @brief Return the address of the nth instruction after the instruction pointed by ip. @n + * This function has been grabbed from OllyDbg ("Disassembleforward" in asmserv.c) + * + * @param[in] data Address of the data to disassemble + * @param[in] base Original base address of the memory page (Required to disassemble destination addresses) + * @param[in] size Size of the data block pointed by data + * @param[in] ip RVA of the current instruction (Relative to data pointer) + * @param[in] n Number of instruction next + * + * @return Return the RVA (Relative to the data pointer) of the nth instruction after the instruction pointed by ip + */ +ulong QBeaEngine::DisassembleNext(byte_t* data, duint base, duint size, duint ip, int n) +{ + Q_UNUSED(base) + int i; + uint cmdsize; + unsigned char* pdata; + + // Reset Disasm Structure + Capstone cp; + + if(data == NULL) + return 0; + + if(ip >= size) + ip = size - 1; + + if(n <= 0) + return ip; + + pdata = data + ip; + size -= ip; + + for(i = 0; i < n && size > 0; i++) + { + if(!cp.Disassemble(0, pdata, (int)size)) + cmdsize = 1; + else + cmdsize = cp.Size(); + + pdata += cmdsize; + ip += cmdsize; + size -= cmdsize; + } + + return ip; +} + +/** + * @brief Disassemble the instruction at the given ip RVA. + * + * @param[in] data Pointer to memory data (Can be either a buffer or the original data memory) + * @param[in] size Size of the memory pointed by data (Can be the memory page size if data points to the original memory page base address) + * @param[in] instIndex Offset to reach the instruction data from the data pointer + * @param[in] origBase Original base address of the memory page (Required to disassemble destination addresses) + * @param[in] origInstRVA Original Instruction RVA of the instruction to disassemble + * + * @return Return the disassembled instruction + */ + +Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint instIndex, duint origBase, duint origInstRVA) +{ + //tokenize + CapstoneTokenizer::InstructionToken cap; + _tokenizer.Tokenize(origBase + origInstRVA, data, size, cap); + int len = _tokenizer.Size(); + + const auto & cp = _tokenizer.GetCapstone(); + bool success = cp.Success(); + + auto branchType = Instruction_t::None; + if(success && (cp.InGroup(CS_GRP_JUMP) || cp.IsLoop())) + { + switch(cp.GetId()) + { + case X86_INS_JMP: + case X86_INS_LOOP: + branchType = Instruction_t::Unconditional; + break; + default: + branchType = Instruction_t::Conditional; + break; + } + } + + Instruction_t wInst; + wInst.instStr = QString(cp.InstructionText().c_str()); + wInst.dump = QByteArray((const char*)data, len); + wInst.rva = origInstRVA; + wInst.length = len; + wInst.branchType = branchType; + wInst.branchDestination = cp.BranchDestination(); + wInst.tokens = cap; + + return wInst; +} + +void QBeaEngine::UpdateConfig() +{ + _tokenizer.UpdateConfig(); } \ No newline at end of file diff --git a/src/gui/Src/Disassembler/QBeaEngine.h b/src/gui/Src/Disassembler/QBeaEngine.h index 75c9fbd9..b7b95041 100644 --- a/src/gui/Src/Disassembler/QBeaEngine.h +++ b/src/gui/Src/Disassembler/QBeaEngine.h @@ -1,48 +1,48 @@ -#ifndef QBEAENGINE_H -#define QBEAENGINE_H - -#include -#include "Imports.h" -#include "capstone_gui.h" - -struct Instruction_t -{ - enum BranchType - { - None, - Conditional, - Unconditional - }; - - Instruction_t() - : rva(0), - length(0), - branchDestination(0), - branchType(None) - { - } - - QString instStr; - QByteArray dump; - duint rva; - int length; - //DISASM disasm; - duint branchDestination; - BranchType branchType; - CapstoneTokenizer::InstructionToken tokens; -}; - -class QBeaEngine -{ -public: - explicit QBeaEngine(int maxModuleSize); - ulong DisassembleBack(byte_t* data, duint base, duint size, duint ip, int n); - ulong DisassembleNext(byte_t* data, duint base, duint size, duint ip, int n); - Instruction_t DisassembleAt(byte_t* data, duint size, duint instIndex, duint origBase, duint origInstRVA); - void UpdateConfig(); - -private: - CapstoneTokenizer _tokenizer; -}; - -#endif // QBEAENGINE_H +#ifndef QBEAENGINE_H +#define QBEAENGINE_H + +#include +#include "Imports.h" +#include "capstone_gui.h" + +struct Instruction_t +{ + enum BranchType + { + None, + Conditional, + Unconditional + }; + + Instruction_t() + : rva(0), + length(0), + branchDestination(0), + branchType(None) + { + } + + QString instStr; + QByteArray dump; + duint rva; + int length; + //DISASM disasm; + duint branchDestination; + BranchType branchType; + CapstoneTokenizer::InstructionToken tokens; +}; + +class QBeaEngine +{ +public: + explicit QBeaEngine(int maxModuleSize); + ulong DisassembleBack(byte_t* data, duint base, duint size, duint ip, int n); + ulong DisassembleNext(byte_t* data, duint base, duint size, duint ip, int n); + Instruction_t DisassembleAt(byte_t* data, duint size, duint instIndex, duint origBase, duint origInstRVA); + void UpdateConfig(); + +private: + CapstoneTokenizer _tokenizer; +}; + +#endif // QBEAENGINE_H diff --git a/src/gui/Src/Disassembler/capstone_gui.cpp b/src/gui/Src/Disassembler/capstone_gui.cpp index 01f2378d..5c030362 100644 --- a/src/gui/Src/Disassembler/capstone_gui.cpp +++ b/src/gui/Src/Disassembler/capstone_gui.cpp @@ -1,491 +1,491 @@ -#include "capstone_gui.h" -#include "Configuration.h" - -CapstoneTokenizer::CapstoneTokenizer(int maxModuleLength) - : _maxModuleLength(maxModuleLength), - _success(false) -{ - SetConfig(false, false, false, false); -} - -std::map CapstoneTokenizer::colorNamesMap; - -void CapstoneTokenizer::addColorName(TokenType type, QString color, QString backgroundColor) -{ - colorNamesMap.insert({type, TokenColor(color, backgroundColor)}); -} - -void CapstoneTokenizer::UpdateColors() -{ - //color names map - colorNamesMap.clear(); - //filling - addColorName(TokenType::Comma, "InstructionCommaColor", "InstructionCommaBackgroundColor"); - addColorName(TokenType::Space, "", ""); - addColorName(TokenType::ArgumentSpace, "", ""); - addColorName(TokenType::MemoryOperatorSpace, "", ""); - //general instruction parts - addColorName(TokenType::Prefix, "InstructionPrefixColor", "InstructionPrefixBackgroundColor"); - addColorName(TokenType::Uncategorized, "InstructionUncategorizedColor", "InstructionUncategorizedBackgroundColor"); - addColorName(TokenType::Address, "InstructionAddressColor", "InstructionAddressBackgroundColor"); //jump/call destinations - addColorName(TokenType::Value, "InstructionValueColor", "InstructionValueBackgroundColor"); - //mnemonics - addColorName(TokenType::MnemonicNormal, "InstructionMnemonicColor", "InstructionMnemonicBackgroundColor"); - addColorName(TokenType::MnemonicPushPop, "InstructionPushPopColor", "InstructionPushPopBackgroundColor"); - addColorName(TokenType::MnemonicCall, "InstructionCallColor", "InstructionCallBackgroundColor"); - addColorName(TokenType::MnemonicRet, "InstructionRetColor", "InstructionRetBackgroundColor"); - addColorName(TokenType::MnemonicCondJump, "InstructionConditionalJumpColor", "InstructionConditionalJumpBackgroundColor"); - addColorName(TokenType::MnemonicUncondJump, "InstructionUnconditionalJumpColor", "InstructionUnconditionalJumpBackgroundColor"); - addColorName(TokenType::MnemonicNop, "InstructionNopColor", "InstructionNopBackgroundColor"); - addColorName(TokenType::MnemonicFar, "InstructionFarColor", "InstructionFarBackgroundColor"); - addColorName(TokenType::MnemonicInt3, "InstructionInt3Color", "InstructionInt3BackgroundColor"); - //memory - addColorName(TokenType::MemorySize, "InstructionMemorySizeColor", "InstructionMemorySizeBackgroundColor"); - addColorName(TokenType::MemorySegment, "InstructionMemorySegmentColor", "InstructionMemorySegmentBackgroundColor"); - addColorName(TokenType::MemoryBrackets, "InstructionMemoryBracketsColor", "InstructionMemoryBracketsBackgroundColor"); - addColorName(TokenType::MemoryStackBrackets, "InstructionMemoryStackBracketsColor", "InstructionMemoryStackBracketsBackgroundColor"); - addColorName(TokenType::MemoryBaseRegister, "InstructionMemoryBaseRegisterColor", "InstructionMemoryBaseRegisterBackgroundColor"); - addColorName(TokenType::MemoryIndexRegister, "InstructionMemoryIndexRegisterColor", "InstructionMemoryIndexRegisterBackgroundColor"); - addColorName(TokenType::MemoryScale, "InstructionMemoryScaleColor", "InstructionMemoryScaleBackgroundColor"); - addColorName(TokenType::MemoryOperator, "InstructionMemoryOperatorColor", "InstructionMemoryOperatorBackgroundColor"); - //registers - addColorName(TokenType::GeneralRegister, "InstructionGeneralRegisterColor", "InstructionGeneralRegisterBackgroundColor"); - addColorName(TokenType::FpuRegister, "InstructionFpuRegisterColor", "InstructionFpuRegisterBackgroundColor"); - addColorName(TokenType::MmxRegister, "InstructionMmxRegisterColor", "InstructionMmxRegisterBackgroundColor"); - addColorName(TokenType::XmmRegister, "InstructionXmmRegisterColor", "InstructionXmmRegisterBackgroundColor"); - addColorName(TokenType::YmmRegister, "InstructionYmmRegisterColor", "InstructionYmmRegisterBackgroundColor"); - addColorName(TokenType::ZmmRegister, "InstructionZmmRegisterColor", "InstructionZmmRegisterBackgroundColor"); -} - -bool CapstoneTokenizer::Tokenize(duint addr, const unsigned char* data, int datasize, InstructionToken & instruction) -{ - _inst = InstructionToken(); - - _success = _cp.Disassemble(addr, data, datasize); - if(_success) - { - if(!tokenizeMnemonic()) - return false; - - for(int i = 0; i < _cp.OpCount(); i++) - { - if(i) - { - addToken(TokenType::Comma, ","); - if(_bArgumentSpaces) - addToken(TokenType::ArgumentSpace, " "); - } - if(!tokenizeOperand(_cp[i])) - return false; - } - } - else - addToken(TokenType::Uncategorized, "???"); - - instruction = _inst; - - return true; -} - -void CapstoneTokenizer::UpdateConfig() -{ - SetConfig(ConfigBool("Disassembler", "Uppercase"), - ConfigBool("Disassembler", "TabbedMnemonic"), - ConfigBool("Disassembler", "ArgumentSpaces"), - ConfigBool("Disassembler", "MemorySpaces")); -} - -void CapstoneTokenizer::SetConfig(bool bUppercase, bool bTabbedMnemonic, bool bArgumentSpaces, bool bMemorySpaces) -{ - _bUppercase = bUppercase; - _bTabbedMnemonic = bTabbedMnemonic; - _bArgumentSpaces = bArgumentSpaces; - _bMemorySpaces = bMemorySpaces; -} - -int CapstoneTokenizer::Size() const -{ - return _success ? _cp.Size() : 1; -} - -const Capstone & CapstoneTokenizer::GetCapstone() const -{ - return _cp; -} - -void CapstoneTokenizer::TokenToRichText(const InstructionToken & instr, QList & richTextList, const SingleToken* highlightToken) -{ - QColor highlightColor = ConfigColor("InstructionHighlightColor"); - for(const auto & token : instr.tokens) - { - RichTextPainter::CustomRichText_t richText; - richText.highlight = TokenEquals(&token, highlightToken); - richText.highlightColor = highlightColor; - richText.flags = RichTextPainter::FlagNone; - richText.text = token.text; - auto found = colorNamesMap.find(token.type); - if(found != colorNamesMap.end()) - { - auto tokenColor = found->second; - richText.flags = tokenColor.flags; - richText.textColor = tokenColor.color; - richText.textBackground = tokenColor.backgroundColor; - } - richTextList.append(richText); - } -} - -bool CapstoneTokenizer::TokenFromX(const InstructionToken & instr, SingleToken & token, int x, int charwidth) -{ - if(x < instr.x) //before the first token - return false; - int len = int(instr.tokens.size()); - for(int i = 0, xStart = instr.x; i < len; i++) - { - const auto & curToken = instr.tokens.at(i); - int curWidth = int(curToken.text.length()) * charwidth; - int xEnd = xStart + curWidth; - if(x >= xStart && x < xEnd) - { - token = curToken; - return true; - } - xStart = xEnd; - } - return false; //not found -} - -bool CapstoneTokenizer::IsHighlightableToken(const SingleToken & token) -{ - switch(token.type) - { - case TokenType::Comma: - case TokenType::Space: - case TokenType::ArgumentSpace: - case TokenType::MemoryOperatorSpace: - case TokenType::MemoryBrackets: - case TokenType::MemoryStackBrackets: - case TokenType::MemoryOperator: - return false; - break; - } - return true; -} - -bool CapstoneTokenizer::TokenEquals(const SingleToken* a, const SingleToken* b, bool ignoreSize) -{ - if(!a || !b) - return false; - if(a->value.size != 0 && b->value.size != 0) //we have a value - { - if(!ignoreSize && a->value.size != b->value.size) - return false; - else if(a->value.value != b->value.value) - return false; - } - else if(a->text != b->text) //text doesn't equal - return false; - return true; //passed all checks -} - -void CapstoneTokenizer::addToken(TokenType type, QString text, const TokenValue & value) -{ - switch(type) - { - case TokenType::Space: - case TokenType::ArgumentSpace: - case TokenType::MemoryOperatorSpace: - break; - default: - text = text.trimmed(); - break; - } - if(_bUppercase && !value.size) - text = text.toUpper(); - _inst.tokens.push_back(SingleToken(type, text, value)); -} - -void CapstoneTokenizer::addToken(TokenType type, const QString & text) -{ - addToken(type, text, TokenValue()); -} - -void CapstoneTokenizer::addMemoryOperator(char operatorText) -{ - if(_bMemorySpaces) - addToken(TokenType::MemoryOperatorSpace, " "); - QString text; - text += operatorText; - addToken(TokenType::MemoryOperator, text); - if(_bMemorySpaces) - addToken(TokenType::MemoryOperatorSpace, " "); -} - -QString CapstoneTokenizer::printValue(const TokenValue & value, bool expandModule, int maxModuleLength) const -{ - char labelText[MAX_LABEL_SIZE] = ""; - char module_[MAX_MODULE_SIZE] = ""; - QString moduleText; - duint addr = value.value; - bool bHasLabel = DbgGetLabelAt(addr, SEG_DEFAULT, labelText); - bool bHasModule = (expandModule && DbgGetModuleAt(addr, module_) && !QString(labelText).startsWith("JMP.&")); - moduleText = QString(module_); - if(maxModuleLength != -1) - moduleText.truncate(maxModuleLength); - if(moduleText.length()) - moduleText += "."; - QString addrText; - addrText = QString("%1").arg(addr & (duint) - 1, 0, 16, QChar('0')).toUpper(); - QString finalText; - if(bHasLabel && bHasModule) // - finalText = QString("<%1%2>").arg(moduleText).arg(labelText); - else if(bHasModule) //module.addr - finalText = QString("%1%2").arg(moduleText).arg(addrText); - else if(bHasLabel) //http://x64dbg.com

Attribution:
Icons8
Yusuke Kamiyamane

Compiled on:
"__DATE__", "__TIME__); - msg.setWindowIcon(QIcon(":/icons/images/information.png")); - msg.setTextFormat(Qt::RichText); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); -} - -void MainWindow::openFile() -{ - QString lastPath, filename; - QAction* fileToOpen = qobject_cast(sender()); - - //if sender is from recent list directly open file, otherwise show dialog - if(fileToOpen == NULL || !fileToOpen->objectName().startsWith("MRU") || !(fileToOpen->text().length())) - { - lastPath = (mMRUList.size() > 0) ? mMRUList.at(0) : 0; - filename = QFileDialog::getOpenFileName(this, tr("Open file"), lastPath, tr("Executables (*.exe *.dll);;All files (*.*)")); - if(!filename.length()) - return; - filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes) - } - else - { - filename = fileToOpen->text(); - } - DbgCmdExec(QString().sprintf("init \"%s\"", filename.toUtf8().constData()).toUtf8().constData()); - - //file is from recent menu - if(fileToOpen != NULL && fileToOpen->objectName().startsWith("MRU")) - { - fileToOpen->setObjectName(fileToOpen->objectName().split("U").at(1)); - int index = fileToOpen->objectName().toInt(); - - QString exists = getMRUEntry(index); - if(exists.length() == 0) - { - addMRUEntry(filename); - updateMRUMenu(); - saveMRUList(); - } - - fileToOpen->setObjectName(fileToOpen->objectName().prepend("MRU")); - } - - //file is from open button - bool update = true; - if(fileToOpen == NULL || fileToOpen->objectName().compare("actionOpen") == 0) - for(int i = 0; i < mMRUList.size(); i++) - if(mMRUList.at(i) == filename) - { - update = false; - break; - } - if(update) - { - addMRUEntry(filename); - updateMRUMenu(); - saveMRUList(); - } - - mCpuWidget->setDisasmFocus(); -} - -void MainWindow::execPause() -{ - DbgCmdExec("pause"); -} - -void MainWindow::startScylla() //this is executed -{ - DbgCmdExec("StartScylla"); -} - -void MainWindow::restartDebugging() -{ - if(!mMRUList.size()) - return; - DbgCmdExec(QString().sprintf("init \"%s\"", mMRUList.at(0).toUtf8().constData()).toUtf8().constData()); - - mCpuWidget->setDisasmFocus(); -} - -void MainWindow::displayBreakpointWidget() -{ - showQWidgetTab(mBreakpointsView); -} - -void MainWindow::dragEnterEvent(QDragEnterEvent* pEvent) -{ - if(pEvent->mimeData()->hasUrls()) - { - pEvent->acceptProposedAction(); - } -} - -void MainWindow::dropEvent(QDropEvent* pEvent) -{ - if(pEvent->mimeData()->hasUrls()) - { - QString filename = QDir::toNativeSeparators(pEvent->mimeData()->urls()[0].toLocalFile()); - DbgCmdExec(QString().sprintf("init \"%s\"", filename.toUtf8().constData()).toUtf8().constData()); - pEvent->acceptProposedAction(); - } -} - -void MainWindow::updateWindowTitleSlot(QString filename) -{ - if(filename.length()) - setWindowTitle(QString(mWindowMainTitle) + QString(" - ") + filename); - else - setWindowTitle(QString(mWindowMainTitle)); -} - -void MainWindow::execeStepOver() -{ - DbgCmdExec("eStepOver"); -} - -void MainWindow::execeStepInto() -{ - DbgCmdExec("eStepInto"); -} -void MainWindow::execeRun() -{ - DbgCmdExec("erun"); -} - -void MainWindow::execeRtr() -{ - DbgCmdExec("ertr"); -} - -void MainWindow::execSkip() -{ - DbgCmdExec("skip"); -} - -void MainWindow::displayCpuWidget() -{ - showQWidgetTab(mCpuWidget); -} - -void MainWindow::displaySymbolWidget() -{ - showQWidgetTab(mSymbolView); -} - -void MainWindow::displaySourceViewWidget() -{ - showQWidgetTab(mSourceViewManager); -} - -void MainWindow::displayReferencesWidget() -{ - showQWidgetTab(mReferenceManager); -} - -void MainWindow::displayThreadsWidget() -{ - showQWidgetTab(mThreadView); -} - -void MainWindow::displaySnowmanWidget() -{ - showQWidgetTab(mSnowmanView); -} - -void MainWindow::openSettings() -{ - SettingsDialog settings(this); - settings.lastException = lastException; - settings.exec(); -} - -void MainWindow::openAppearance() -{ - AppearanceDialog appearance(this); - appearance.exec(); -} - -void MainWindow::openCalculator() -{ - mCalculatorDialog->showNormal(); - mCalculatorDialog->setFocus(); - mCalculatorDialog->setExpressionFocus(); -} - -void MainWindow::openShortcuts() -{ - ShortcutsDialog shortcuts(this); - shortcuts.exec(); -} - -void MainWindow::changeTopmost(bool checked) -{ - if(checked) - SetWindowPos((HWND)this->winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - else - SetWindowPos((HWND)this->winId(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); -} - -void MainWindow::addRecentFile(QString file) -{ - addMRUEntry(file); - updateMRUMenu(); - saveMRUList(); -} - -void MainWindow::setLastException(unsigned int exceptionCode) -{ - lastException = exceptionCode; -} - -void MainWindow::findStrings() -{ - DbgCmdExec(QString("strref " + QString("%1").arg(mCpuWidget->getDisasmWidget()->getSelectedVa(), sizeof(dsint) * 2, 16, QChar('0')).toUpper()).toUtf8().constData()); - displayReferencesWidget(); -} - -void MainWindow::findModularCalls() -{ - DbgCmdExec(QString("modcallfind " + QString("%1").arg(mCpuWidget->getDisasmWidget()->getSelectedVa(), sizeof(dsint) * 2, 16, QChar('0')).toUpper()).toUtf8().constData()); - displayReferencesWidget(); -} - -const MainWindow::MenuInfo* MainWindow::findMenu(int hMenu) -{ - if(hMenu == -1) - return 0; - int nFound = -1; - for(int i = 0; i < mMenuList.size(); i++) - { - if(hMenu == mMenuList.at(i).hMenu) - { - nFound = i; - break; - } - } - return nFound == -1 ? 0 : &mMenuList.at(nFound); -} - -void MainWindow::addMenuToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu) -{ - if(!findMenu(hMenu)) - mMenuList.push_back(MenuInfo(parent, menu, hMenu, hParentMenu)); - Bridge::getBridge()->setResult(); -} - -void MainWindow::addMenu(int hMenu, QString title) -{ - const MenuInfo* menu = findMenu(hMenu); - if(!menu && hMenu != -1) - { - Bridge::getBridge()->setResult(-1); - return; - } - int hMenuNew = hMenuNext++; - QWidget* parent = hMenu == -1 ? this : menu->parent; - QMenu* wMenu = new QMenu(title, parent); - wMenu->menuAction()->setVisible(false); - mMenuList.push_back(MenuInfo(parent, wMenu, hMenuNew, hMenu)); - if(hMenu == -1) //top-level - ui->menuBar->addMenu(wMenu); - else //deeper level - menu->mMenu->addMenu(wMenu); - Bridge::getBridge()->setResult(hMenuNew); -} - -void MainWindow::addMenuEntry(int hMenu, QString title) -{ - const MenuInfo* menu = findMenu(hMenu); - if(!menu && hMenu != -1) - { - Bridge::getBridge()->setResult(-1); - return; - } - MenuEntryInfo newInfo; - int hEntryNew = hEntryNext++; - newInfo.hEntry = hEntryNew; - newInfo.hParentMenu = hMenu; - QWidget* parent = hMenu == -1 ? this : menu->parent; - QAction* wAction = new QAction(title, parent); - wAction->setObjectName(QString().sprintf("ENTRY|%d", hEntryNew)); - parent->addAction(wAction); - connect(wAction, SIGNAL(triggered()), this, SLOT(menuEntrySlot())); - newInfo.mAction = wAction; - mEntryList.push_back(newInfo); - if(hMenu == -1) //top level - ui->menuBar->addAction(wAction); - else //deeper level - { - menu->mMenu->addAction(wAction); - menu->mMenu->menuAction()->setVisible(true); - } - Bridge::getBridge()->setResult(hEntryNew); -} - -void MainWindow::addSeparator(int hMenu) -{ - const MenuInfo* menu = findMenu(hMenu); - if(menu) - { - MenuEntryInfo newInfo; - newInfo.hEntry = -1; - newInfo.hParentMenu = hMenu; - newInfo.mAction = menu->mMenu->addSeparator(); - mEntryList.push_back(newInfo); - } - Bridge::getBridge()->setResult(); -} - -void MainWindow::clearMenu(int hMenu) -{ - if(!mMenuList.size() || hMenu == -1) - { - Bridge::getBridge()->setResult(); - return; - } - const MenuInfo* menu = findMenu(hMenu); - //delete menu entries - for(int i = mEntryList.size() - 1; i > -1; i--) - { - if(hMenu == mEntryList.at(i).hParentMenu) //we found an entry that has the menu as parent - { - QWidget* parent = menu == 0 ? this : menu->parent; - parent->removeAction(mEntryList.at(i).mAction); - delete mEntryList.at(i).mAction; //delete the entry object - mEntryList.erase(mEntryList.begin() + i); - } - } - //recursively delete the menus - for(int i = mMenuList.size() - 1; i > -1; i--) - { - if(hMenu == mMenuList.at(i).hParentMenu) //we found a menu that has the menu as parent - { - clearMenu(mMenuList.at(i).hMenu); //delete children menus - delete mMenuList.at(i).mMenu; //delete the child menu object - mMenuList.erase(mMenuList.begin() + i); //delete the child entry - } - } - //hide the empty menu - if(menu) - menu->mMenu->menuAction()->setVisible(false); - Bridge::getBridge()->setResult(); -} - -void MainWindow::initMenuApi() -{ - //256 entries are reserved - mEntryList.clear(); - hEntryNext = 256; - mMenuList.clear(); - hMenuNext = 256; -} - -void MainWindow::menuEntrySlot() -{ - QAction* action = qobject_cast(sender()); - if(action && action->objectName().startsWith("ENTRY|")) - { - int hEntry = -1; - if(sscanf_s(action->objectName().mid(6).toUtf8().constData(), "%d", &hEntry) == 1) - DbgMenuEntryClicked(hEntry); - } -} - -void MainWindow::removeMenuEntry(int hEntry) -{ - for(int i = 0; i < mEntryList.size(); i++) - { - if(mEntryList.at(i).hEntry == hEntry) - { - const MenuEntryInfo & entry = mEntryList.at(i); - const MenuInfo* menu = findMenu(entry.hParentMenu); - QWidget* parent = menu == 0 ? this : menu->parent; - parent->removeAction(entry.mAction); - delete entry.mAction; - mEntryList.erase(mEntryList.begin() + i); - break; - } - } - Bridge::getBridge()->setResult(); -} - -void MainWindow::setIconMenuEntry(int hEntry, QIcon icon) -{ - for(int i = 0; i < mEntryList.size(); i++) - { - if(mEntryList.at(i).hEntry == hEntry) - { - const MenuEntryInfo & entry = mEntryList.at(i); - entry.mAction->setIcon(icon); - break; - } - } - Bridge::getBridge()->setResult(); -} - -void MainWindow::setIconMenu(int hMenu, QIcon icon) -{ - for(int i = 0; i < mMenuList.size(); i++) - { - if(mMenuList.at(i).hMenu == hMenu) - { - const MenuInfo & menu = mMenuList.at(i); - menu.mMenu->setIcon(icon); - } - } - Bridge::getBridge()->setResult(); -} - -void MainWindow::runSelection() -{ - if(!DbgIsDebugging()) - return; - - QString command = "bp " + QString("%1").arg(mCpuWidget->getDisasmWidget()->getSelectedVa(), sizeof(dsint) * 2, 16, QChar('0')).toUpper() + ", ss"; - if(DbgCmdExecDirect(command.toUtf8().constData())) - DbgCmdExecDirect("run"); -} - -void MainWindow::getStrWindow(const QString title, QString* text) -{ - LineEditDialog mLineEdit(this); - mLineEdit.setWindowTitle(title); - bool bResult = true; - if(mLineEdit.exec() != QDialog::Accepted) - bResult = false; - *text = mLineEdit.editText; - Bridge::getBridge()->setResult(bResult); -} - -void MainWindow::patchWindow() -{ - if(!DbgIsDebugging()) - { - QMessageBox msg(QMessageBox::Critical, "Error!", QString("Patches cannot be shown when not debugging...")); - msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return; - } - GuiUpdatePatches(); - mPatchDialog->showNormal(); - mPatchDialog->setFocus(); -} - -void MainWindow::displayComments() -{ - if(!DbgIsDebugging()) - return; - DbgCmdExec("commentlist"); - displayReferencesWidget(); -} - -void MainWindow::displayLabels() -{ - if(!DbgIsDebugging()) - return; - DbgCmdExec("labellist"); - displayReferencesWidget(); -} - -void MainWindow::displayBookmarks() -{ - if(!DbgIsDebugging()) - return; - DbgCmdExec("bookmarklist"); - displayReferencesWidget(); -} - -void MainWindow::displayFunctions() -{ - if(!DbgIsDebugging()) - return; - DbgCmdExec("functionlist"); - displayReferencesWidget(); -} - -void MainWindow::checkUpdates() -{ - mUpdateChecker->checkForUpdates(); -} - -void MainWindow::displayCallstack() -{ - showQWidgetTab(mCallStackView); -} - -void MainWindow::donate() -{ - QMessageBox msg(QMessageBox::Information, "Donate", "All the money will go to x64dbg development."); - msg.setWindowIcon(QIcon(":/icons/images/donate.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); - msg.setDefaultButton(QMessageBox::Ok); - if(msg.exec() != QMessageBox::Ok) - return; - QDesktopServices::openUrl(QUrl("http://donate.x64dbg.com")); -} - -void MainWindow::reportBug() -{ - QMessageBox msg(QMessageBox::Information, "Report Bug", "You will be taken to a website where you can report a bug.\nMake sure to fill in as much information as possible."); - msg.setWindowIcon(QIcon(":/icons/images/bug-report.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); - msg.setDefaultButton(QMessageBox::Ok); - if(msg.exec() != QMessageBox::Ok) - return; - QDesktopServices::openUrl(QUrl("http://report.x64dbg.com")); -} - -void MainWindow::displayAttach() -{ - AttachDialog attach(this); - attach.exec(); - - mCpuWidget->setDisasmFocus(); -} - -void MainWindow::detach() -{ - DbgCmdExec("detach"); -} - -void MainWindow::changeCommandLine() -{ - if(!DbgIsDebugging()) - return; - - LineEditDialog mLineEdit(this); - mLineEdit.setText(""); - mLineEdit.setWindowTitle("Change Command Line"); - mLineEdit.setWindowIcon(QIcon(":/icons/images/changeargs.png")); - - size_t cbsize = 0; - char* cmdline = 0; - if(!DbgFunctions()->GetCmdline(0, &cbsize)) - mLineEdit.setText("Cannot get remote command line, use the 'getcmdline' command for more information."); - else - { - cmdline = new char[cbsize]; - DbgFunctions()->GetCmdline(cmdline, 0); - mLineEdit.setText(QString(cmdline)); - delete[] cmdline; - } - - mLineEdit.setCursorPosition(0); - - if(mLineEdit.exec() != QDialog::Accepted) - return; //pressed cancel - - if(!DbgFunctions()->SetCmdline((char*)mLineEdit.editText.toUtf8().constData())) - { - QMessageBox msg(QMessageBox::Warning, "Error", "Could not set command line!"); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - } - else - { - DbgFunctions()->MemUpdateMap(); - GuiUpdateMemoryView(); - GuiAddStatusBarMessage(QString("New command line: " + mLineEdit.editText + "\n").toUtf8().constData()); - } -} - -void MainWindow::displayManual() -{ - // Open the Windows CHM in the upper directory - QDesktopServices::openUrl(QUrl("..\\x64dbg.chm")); -} - -void MainWindow::decompileAt(dsint start, dsint end) -{ - DecompileAt(mSnowmanView, start, end); -} - -void MainWindow::canClose() -{ - bCanClose = true; - close(); -} - -void MainWindow::addQWidgetTab(QWidget* qWidget) -{ - mTabWidget->addTab(qWidget, qWidget->windowIcon(), qWidget->windowTitle()); -} - -void MainWindow::showQWidgetTab(QWidget* qWidget) -{ - qWidget->show(); - qWidget->setFocus(); - setTab(qWidget); -} - -void MainWindow::closeQWidgetTab(QWidget* qWidget) -{ - for(int i = 0; i < mTabWidget->count(); i++) - { - if(mTabWidget->widget(i) == qWidget) - { - mTabWidget->DeleteTab(i); - break; - } - } -} - -void MainWindow::executeOnGuiThread(void* cbGuiThread) -{ - ((GUICALLBACK)cbGuiThread)(); -} +#include "MainWindow.h" +#include "ui_MainWindow.h" +#include +#include +#include +#include +#include +#include +#include "Configuration.h" +#include "SettingsDialog.h" +#include "AppearanceDialog.h" +#include "ShortcutsDialog.h" +#include "AttachDialog.h" +#include "LineEditDialog.h" + +MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + // Build information + QString buildText = QString().sprintf("v%d, "__DATE__, BridgeGetDbgVersion()); + QAction* buildInfo = new QAction(buildText, this); + buildInfo->setEnabled(false); + ui->menuBar->addAction(buildInfo); + + // Setup bridge signals + connect(Bridge::getBridge(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(QString))); + connect(Bridge::getBridge(), SIGNAL(addRecentFile(QString)), this, SLOT(addRecentFile(QString))); + connect(Bridge::getBridge(), SIGNAL(setLastException(uint)), this, SLOT(setLastException(uint))); + connect(Bridge::getBridge(), SIGNAL(menuAddMenuToList(QWidget*, QMenu*, int, int)), this, SLOT(addMenuToList(QWidget*, QMenu*, int, int))); + connect(Bridge::getBridge(), SIGNAL(menuAddMenu(int, QString)), this, SLOT(addMenu(int, QString))); + connect(Bridge::getBridge(), SIGNAL(menuAddMenuEntry(int, QString)), this, SLOT(addMenuEntry(int, QString))); + connect(Bridge::getBridge(), SIGNAL(menuAddSeparator(int)), this, SLOT(addSeparator(int))); + connect(Bridge::getBridge(), SIGNAL(menuClearMenu(int)), this, SLOT(clearMenu(int))); + connect(Bridge::getBridge(), SIGNAL(menuRemoveMenuEntry(int)), this, SLOT(removeMenuEntry(int))); + connect(Bridge::getBridge(), SIGNAL(getStrWindow(QString, QString*)), this, SLOT(getStrWindow(QString, QString*))); + connect(Bridge::getBridge(), SIGNAL(setIconMenu(int, QIcon)), this, SLOT(setIconMenu(int, QIcon))); + connect(Bridge::getBridge(), SIGNAL(setIconMenuEntry(int, QIcon)), this, SLOT(setIconMenuEntry(int, QIcon))); + connect(Bridge::getBridge(), SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); + connect(Bridge::getBridge(), SIGNAL(addQWidgetTab(QWidget*)), this, SLOT(addQWidgetTab(QWidget*))); + connect(Bridge::getBridge(), SIGNAL(showQWidgetTab(QWidget*)), this, SLOT(showQWidgetTab(QWidget*))); + connect(Bridge::getBridge(), SIGNAL(closeQWidgetTab(QWidget*)), this, SLOT(closeQWidgetTab(QWidget*))); + connect(Bridge::getBridge(), SIGNAL(executeOnGuiThread(void*)), this, SLOT(executeOnGuiThread(void*))); + + // Setup menu API + initMenuApi(); + addMenuToList(this, ui->menuPlugins, GUI_PLUGIN_MENU); + + this->showMaximized(); + +#ifdef _WIN64 + mWindowMainTitle = "x64dbg"; +#else + mWindowMainTitle = "x32dbg"; +#endif + + // Set window title + setWindowTitle(QString(mWindowMainTitle)); + + // Load application icon + HICON hIcon = LoadIcon(GetModuleHandleA(0), MAKEINTRESOURCE(100)); + SendMessageA((HWND)MainWindow::winId(), WM_SETICON, ICON_BIG, (LPARAM)hIcon); + DestroyIcon(hIcon); + + // Load recent files + loadMRUList(16); + + // Accept drops + setAcceptDrops(true); + + // Log view + mLogView = new LogView(); + mLogView->setWindowTitle("Log"); + mLogView->setWindowIcon(QIcon(":/icons/images/log.png")); + mLogView->hide(); + + // Symbol view + mSymbolView = new SymbolView(); + mSymbolView->setWindowTitle("Symbols"); + mSymbolView->setWindowIcon(QIcon(":/icons/images/pdb.png")); + mSymbolView->hide(); + + // Source view + mSourceViewManager = new SourceViewerManager(); + mSourceViewManager->setWindowTitle("Source"); + mSourceViewManager->setWindowIcon(QIcon(":/icons/images/source.png")); + mSourceViewManager->hide(); + connect(mSourceViewManager, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); + + // Breakpoints + mBreakpointsView = new BreakpointsView(); + mBreakpointsView->setWindowTitle("Breakpoints"); + mBreakpointsView->setWindowIcon(QIcon(":/icons/images/breakpoint.png")); + mBreakpointsView->hide(); + connect(mBreakpointsView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); + + // Memory map view + mMemMapView = new MemoryMapView(); + connect(mMemMapView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); + connect(mMemMapView, SIGNAL(showReferences()), this, SLOT(displayReferencesWidget())); + mMemMapView->setWindowTitle("Memory Map"); + mMemMapView->setWindowIcon(QIcon(":/icons/images/memory-map.png")); + mMemMapView->hide(); + + // Callstack view + mCallStackView = new CallStackView(); + mCallStackView->setWindowTitle("Call Stack"); + mCallStackView->setWindowIcon(QIcon(":/icons/images/callstack.png")); + connect(mCallStackView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); + + // Script view + mScriptView = new ScriptView(); + mScriptView->setWindowTitle("Script"); + mScriptView->setWindowIcon(QIcon(":/icons/images/script-code.png")); + mScriptView->hide(); + + // CPU view + mCpuWidget = new CPUWidget(); + mCpuWidget->setWindowTitle("CPU"); + mCpuWidget->setWindowIcon(QIcon(":/icons/images/processor-cpu.png")); + + // Reference manager + mReferenceManager = new ReferenceManager(this); + Bridge::getBridge()->referenceManager = mReferenceManager; + mReferenceManager->setWindowTitle("References"); + mReferenceManager->setWindowIcon(QIcon(":/icons/images/search.png")); + + // Thread view + mThreadView = new ThreadView(); + connect(mThreadView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); + mThreadView->setWindowTitle("Threads"); + mThreadView->setWindowIcon(QIcon(":/icons/images/arrow-threads.png")); + + // Snowman view (decompiler) + mSnowmanView = CreateSnowman(this); + mSnowmanView->setWindowTitle("Snowman"); + mSnowmanView->setWindowIcon(QIcon(":/icons/images/snowman.png")); + + // Notes manager + mNotesManager = new NotesManager(this); + mNotesManager->setWindowTitle("Notes"); + mNotesManager->setWindowIcon(QIcon(":/icons/images/notes.png")); + + // Create the tab widget + mTabWidget = new MHTabWidget(NULL); + + // Setup tabs + addQWidgetTab(mCpuWidget); + addQWidgetTab(mLogView); + addQWidgetTab(mNotesManager); + addQWidgetTab(mBreakpointsView); + addQWidgetTab(mMemMapView); + addQWidgetTab(mCallStackView); + addQWidgetTab(mScriptView); + addQWidgetTab(mSymbolView); + addQWidgetTab(mSourceViewManager); + addQWidgetTab(mReferenceManager); + addQWidgetTab(mThreadView); + addQWidgetTab(mSnowmanView); + + setCentralWidget(mTabWidget); + + // Setup the command bar + mCmdLineEdit = new CommandLineEdit(ui->cmdBar); + ui->cmdBar->addWidget(new QLabel("Command: ")); + ui->cmdBar->addWidget(mCmdLineEdit); + + // Status bar + mStatusLabel = new StatusLabel(ui->statusBar); + mStatusLabel->setText("Ready"); + ui->statusBar->addWidget(mStatusLabel); + mLastLogLabel = new StatusLabel(); + ui->statusBar->addPermanentWidget(mLastLogLabel, 1); + + // Time wasted counter + QLabel* timeWastedLabel = new QLabel(this); + ui->statusBar->addPermanentWidget(timeWastedLabel); + mTimeWastedCounter = new TimeWastedCounter(this, timeWastedLabel); + + mPatchDialog = new PatchDialog(this); + mCalculatorDialog = new CalculatorDialog(this); + connect(mCalculatorDialog, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); + + // Setup signals/slots + connect(mCmdLineEdit, SIGNAL(returnPressed()), this, SLOT(executeCommand())); + connect(ui->actionStepOver, SIGNAL(triggered()), this, SLOT(execStepOver())); + connect(ui->actionStepInto, SIGNAL(triggered()), this, SLOT(execStepInto())); + connect(ui->actionCommand, SIGNAL(triggered()), this, SLOT(setFocusToCommandBar())); + connect(ui->actionClose, SIGNAL(triggered()), this, SLOT(execClose())); + connect(ui->actionMemoryMap, SIGNAL(triggered()), this, SLOT(displayMemMapWidget())); + connect(ui->actionRun, SIGNAL(triggered()), this, SLOT(execRun())); + connect(ui->actionRtr, SIGNAL(triggered()), this, SLOT(execRtr())); + connect(ui->actionLog, SIGNAL(triggered()), this, SLOT(displayLogWidget())); + connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(displayAboutWidget())); + connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(openFile())); + connect(ui->actionPause, SIGNAL(triggered()), this, SLOT(execPause())); + connect(ui->actionScylla, SIGNAL(triggered()), this, SLOT(startScylla())); + connect(ui->actionRestart, SIGNAL(triggered()), this, SLOT(restartDebugging())); + connect(ui->actionBreakpoints, SIGNAL(triggered()), this, SLOT(displayBreakpointWidget())); + connect(ui->actioneStepOver, SIGNAL(triggered()), this, SLOT(execeStepOver())); + connect(ui->actioneStepInto, SIGNAL(triggered()), this, SLOT(execeStepInto())); + connect(ui->actioneRun, SIGNAL(triggered()), this, SLOT(execeRun())); + connect(ui->actioneRtr, SIGNAL(triggered()), this, SLOT(execeRtr())); + connect(ui->actionSkipNextInstruction, SIGNAL(triggered()), this, SLOT(execSkip())); + connect(ui->actionScript, SIGNAL(triggered()), this, SLOT(displayScriptWidget())); + connect(ui->actionRunSelection, SIGNAL(triggered()), this, SLOT(runSelection())); + connect(ui->actionCpu, SIGNAL(triggered()), this, SLOT(displayCpuWidget())); + connect(ui->actionSymbolInfo, SIGNAL(triggered()), this, SLOT(displaySymbolWidget())); + connect(ui->actionSource, SIGNAL(triggered()), this, SLOT(displaySourceViewWidget())); + connect(mSymbolView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); + connect(mSymbolView, SIGNAL(showReferences()), this, SLOT(displayReferencesWidget())); + connect(mReferenceManager, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); + connect(ui->actionReferences, SIGNAL(triggered()), this, SLOT(displayReferencesWidget())); + connect(ui->actionThreads, SIGNAL(triggered()), this, SLOT(displayThreadsWidget())); + connect(ui->actionSettings, SIGNAL(triggered()), this, SLOT(openSettings())); + connect(ui->actionStrings, SIGNAL(triggered()), this, SLOT(findStrings())); + connect(ui->actionCalls, SIGNAL(triggered()), this, SLOT(findModularCalls())); + connect(ui->actionAppearance, SIGNAL(triggered()), this, SLOT(openAppearance())); + connect(ui->actionShortcuts, SIGNAL(triggered()), this, SLOT(openShortcuts())); + connect(ui->actionTopmost, SIGNAL(toggled(bool)), this, SLOT(changeTopmost(bool))); + connect(ui->actionCalculator, SIGNAL(triggered()), this, SLOT(openCalculator())); + connect(ui->actionPatches, SIGNAL(triggered()), this, SLOT(patchWindow())); + connect(ui->actionComments, SIGNAL(triggered()), this, SLOT(displayComments())); + connect(ui->actionLabels, SIGNAL(triggered()), this, SLOT(displayLabels())); + connect(ui->actionBookmarks, SIGNAL(triggered()), this, SLOT(displayBookmarks())); + connect(ui->actionFunctions, SIGNAL(triggered()), this, SLOT(displayFunctions())); + connect(ui->actionCheckUpdates, SIGNAL(triggered()), this, SLOT(checkUpdates())); + connect(ui->actionCallStack, SIGNAL(triggered()), this, SLOT(displayCallstack())); + connect(ui->actionDonate, SIGNAL(triggered()), this, SLOT(donate())); + connect(ui->actionReportBug, SIGNAL(triggered()), this, SLOT(reportBug())); + connect(ui->actionAttach, SIGNAL(triggered()), this, SLOT(displayAttach())); + connect(ui->actionDetach, SIGNAL(triggered()), this, SLOT(detach())); + connect(ui->actionChangeCommandLine, SIGNAL(triggered()), this, SLOT(changeCommandLine())); + connect(ui->actionManual, SIGNAL(triggered()), this, SLOT(displayManual())); + + connect(mCpuWidget->getDisasmWidget(), SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidget())); + connect(mCpuWidget->getDisasmWidget(), SIGNAL(displaySourceManagerWidget()), this, SLOT(displaySourceViewWidget())); + connect(mCpuWidget->getDisasmWidget(), SIGNAL(displaySnowmanWidget()), this, SLOT(displaySnowmanWidget())); + connect(mCpuWidget->getDisasmWidget(), SIGNAL(showPatches()), this, SLOT(patchWindow())); + connect(mCpuWidget->getDisasmWidget(), SIGNAL(decompileAt(dsint, dsint)), this, SLOT(decompileAt(dsint, dsint))); + connect(mCpuWidget->getDumpWidget(), SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidget())); + connect(mCpuWidget->getStackWidget(), SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidget())); + connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcuts())); + + // Set default setttings (when not set) + SettingsDialog defaultSettings; + lastException = 0; + defaultSettings.SaveSettings(); + + // Create updatechecker + mUpdateChecker = new UpdateChecker(this); + + refreshShortcuts(); + + // Setup close thread and dialog + bCanClose = false; + mCloseThread = new MainWindowCloseThread(); + connect(mCloseThread, SIGNAL(canClose()), this, SLOT(canClose())); + mCloseDialog = new CloseDialog(this); + + mCpuWidget->setDisasmFocus(); + + GuiAddLogMessage(QString().sprintf("Thread id (GUI thread) %X\n", GetCurrentThreadId()).toUtf8().constData()); +} + +void MainWindow::closeEvent(QCloseEvent* event) +{ + mCloseDialog->show(); + mCloseDialog->setFocus(); + static volatile bool bExecuteThread = true; + if(bExecuteThread) + { + bExecuteThread = false; + CloseSnowman(mSnowmanView); + Sleep(100); + mCloseThread->start(); + } + if(bCanClose) + { + mCloseDialog->allowClose(); + mCloseDialog->close(); + event->accept(); + } + else + event->ignore(); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::setTab(QWidget* widget) +{ + for(int i = 0; i < mTabWidget->count(); i++) + { + if(mTabWidget->widget(i) == widget) + { + mTabWidget->setCurrentIndex(i); + break; + } + } +} + +void MainWindow::setGlobalShortcut(QAction* action, const QKeySequence & key) +{ + action->setShortcut(key); + action->setShortcutContext(Qt::ApplicationShortcut); +} + +void MainWindow::refreshShortcuts() +{ + setGlobalShortcut(ui->actionOpen, ConfigShortcut("FileOpen")); + setGlobalShortcut(ui->actionAttach, ConfigShortcut("FileAttach")); + setGlobalShortcut(ui->actionDetach, ConfigShortcut("FileDetach")); + setGlobalShortcut(ui->actionExit, ConfigShortcut("FileExit")); + + setGlobalShortcut(ui->actionCpu, ConfigShortcut("ViewCpu")); + setGlobalShortcut(ui->actionLog, ConfigShortcut("ViewLog")); + setGlobalShortcut(ui->actionBreakpoints, ConfigShortcut("ViewBreakpoints")); + setGlobalShortcut(ui->actionMemoryMap, ConfigShortcut("ViewMemoryMap")); + setGlobalShortcut(ui->actionCallStack, ConfigShortcut("ViewCallStack")); + setGlobalShortcut(ui->actionScript, ConfigShortcut("ViewScript")); + setGlobalShortcut(ui->actionSymbolInfo, ConfigShortcut("ViewSymbolInfo")); + setGlobalShortcut(ui->actionSource, ConfigShortcut("ViewSource")); + setGlobalShortcut(ui->actionReferences, ConfigShortcut("ViewReferences")); + setGlobalShortcut(ui->actionThreads, ConfigShortcut("ViewThreads")); + setGlobalShortcut(ui->actionPatches, ConfigShortcut("ViewPatches")); + setGlobalShortcut(ui->actionComments, ConfigShortcut("ViewComments")); + setGlobalShortcut(ui->actionLabels, ConfigShortcut("ViewLabels")); + setGlobalShortcut(ui->actionBookmarks, ConfigShortcut("ViewBookmarks")); + setGlobalShortcut(ui->actionFunctions, ConfigShortcut("ViewFunctions")); + + setGlobalShortcut(ui->actionRun, ConfigShortcut("DebugRun")); + setGlobalShortcut(ui->actioneRun, ConfigShortcut("DebugeRun")); + setGlobalShortcut(ui->actionRunSelection, ConfigShortcut("DebugRunSelection")); + setGlobalShortcut(ui->actionPause, ConfigShortcut("DebugPause")); + setGlobalShortcut(ui->actionRestart, ConfigShortcut("DebugRestart")); + setGlobalShortcut(ui->actionClose, ConfigShortcut("DebugClose")); + setGlobalShortcut(ui->actionStepInto, ConfigShortcut("DebugStepInto")); + setGlobalShortcut(ui->actioneStepInto, ConfigShortcut("DebugeStepInfo")); + setGlobalShortcut(ui->actionStepOver, ConfigShortcut("DebugStepOver")); + setGlobalShortcut(ui->actioneStepOver, ConfigShortcut("DebugeStepOver")); + setGlobalShortcut(ui->actionRtr, ConfigShortcut("DebugRtr")); + setGlobalShortcut(ui->actioneRtr, ConfigShortcut("DebugeRtr")); + setGlobalShortcut(ui->actionCommand, ConfigShortcut("DebugCommand")); + setGlobalShortcut(ui->actionSkipNextInstruction, ConfigShortcut("DebugSkipNextInstruction")); + + setGlobalShortcut(ui->actionScylla, ConfigShortcut("PluginsScylla")); + + setGlobalShortcut(ui->actionSettings, ConfigShortcut("OptionsPreferences")); + setGlobalShortcut(ui->actionAppearance, ConfigShortcut("OptionsAppearance")); + setGlobalShortcut(ui->actionShortcuts, ConfigShortcut("OptionsShortcuts")); + setGlobalShortcut(ui->actionTopmost, ConfigShortcut("OptionsTopmost")); + + setGlobalShortcut(ui->actionAbout, ConfigShortcut("HelpAbout")); + setGlobalShortcut(ui->actionDonate, ConfigShortcut("HelpDonate")); + setGlobalShortcut(ui->actionCheckUpdates, ConfigShortcut("HelpCheckForUpdates")); + setGlobalShortcut(ui->actionCalculator, ConfigShortcut("HelpCalculator")); + setGlobalShortcut(ui->actionReportBug, ConfigShortcut("HelpReportBug")); + setGlobalShortcut(ui->actionManual, ConfigShortcut("HelpManual")); + + setGlobalShortcut(ui->actionStrings, ConfigShortcut("ActionFindStrings")); + setGlobalShortcut(ui->actionCalls, ConfigShortcut("ActionFindIntermodularCalls")); +} + +//Reads recent files list from settings +void MainWindow::loadMRUList(int maxItems) +{ + mMaxMRU = maxItems; + for(int i = 0; i < mMaxMRU; i++) + { + char currentFile[MAX_SETTING_SIZE] = ""; + if(!BridgeSettingGet("Recent Files", QString().sprintf("%.2d", i + 1).toUtf8().constData(), currentFile)) + break; + if(QString(currentFile).size() && QFile(currentFile).exists()) + mMRUList.push_back(currentFile); + } + mMRUList.removeDuplicates(); + updateMRUMenu(); +} + +//save recent files to settings +void MainWindow::saveMRUList() +{ + BridgeSettingSet("Recent Files", 0, 0); //clear + mMRUList.removeDuplicates(); + int mruSize = mMRUList.size(); + for(int i = 0; i < mruSize; i++) + { + if(QFile(mMRUList.at(i)).exists()) + BridgeSettingSet("Recent Files", QString().sprintf("%.2d", i + 1).toUtf8().constData(), mMRUList.at(i).toUtf8().constData()); + } +} + +void MainWindow::addMRUEntry(QString entry) +{ + if(!entry.size()) + return; + //remove duplicate entry if it exists + removeMRUEntry(entry); + mMRUList.insert(mMRUList.begin(), entry); + if(mMRUList.size() > mMaxMRU) + mMRUList.erase(mMRUList.begin() + mMaxMRU, mMRUList.end()); +} + +void MainWindow::removeMRUEntry(QString entry) +{ + if(!entry.size()) + return; + QList::iterator it; + + for(it = mMRUList.begin(); it != mMRUList.end(); ++it) + { + if((*it) == entry) + { + mMRUList.erase(it); + break; + } + } +} + +void MainWindow::updateMRUMenu() +{ + if(mMaxMRU < 1) return; + + QMenu* fileMenu = this->menuBar()->findChild(QString::fromWCharArray(L"menuFile")); + if(fileMenu == NULL) + { + QMessageBox msg(QMessageBox::Critical, "Error!", "Failed to find menu!"); + msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return; + } + fileMenu = fileMenu->findChild(QString::fromWCharArray(L"menuRecent_Files")); + if(fileMenu == NULL) + { + QMessageBox msg(QMessageBox::Critical, "Error!", "Failed to find submenu!"); + msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return; + } + + QList list = fileMenu->actions(); + for(int i = 1; i < list.length(); ++i) + fileMenu->removeAction(list.at(i)); + + //add items to list + if(mMRUList.size() > 0) + { + list = fileMenu->actions(); + for(int index = 0; index < mMRUList.size(); ++index) + { + fileMenu->addAction(new QAction(mMRUList.at(index), this)); + fileMenu->actions().last()->setObjectName(QString("MRU").append(QString::number(index))); + connect(fileMenu->actions().last(), SIGNAL(triggered()), this, SLOT(openFile())); + } + } +} + +QString MainWindow::getMRUEntry(int index) +{ + QString path; + + if(index < mMRUList.size()) + path = mMRUList.at(index); + + return path; +} + +void MainWindow::executeCommand() +{ + QString wCmd = mCmdLineEdit->text(); + + DbgCmdExec(wCmd.toUtf8().constData()); + + mCmdLineEdit->addLineToHistory(wCmd); + mCmdLineEdit->setText(""); +} + + +void MainWindow::execStepOver() +{ + DbgCmdExec("StepOver"); +} + +void MainWindow::execStepInto() +{ + DbgCmdExec("StepInto"); +} + +void MainWindow::setFocusToCommandBar() +{ + mCmdLineEdit->setFocus(); +} + +void MainWindow::execClose() +{ + DbgCmdExec("stop"); +} + +void MainWindow::execRun() +{ + DbgCmdExec("run"); +} + +void MainWindow::execRtr() +{ + DbgCmdExec("rtr"); +} + +void MainWindow::displayMemMapWidget() +{ + showQWidgetTab(mMemMapView); +} + +void MainWindow::displayLogWidget() +{ + showQWidgetTab(mLogView); +} + +void MainWindow::displayScriptWidget() +{ + showQWidgetTab(mScriptView); +} + +void MainWindow::displayAboutWidget() +{ +#ifdef _WIN64 + QString title = "About x64dbg"; +#else + QString title = "About x32dbg"; +#endif + title += QString().sprintf(" v%d", BridgeGetDbgVersion()); + QMessageBox msg(QMessageBox::Information, title, "Website:
http://x64dbg.com

Attribution:
Icons8
Yusuke Kamiyamane

Compiled on:
"__DATE__", "__TIME__); + msg.setWindowIcon(QIcon(":/icons/images/information.png")); + msg.setTextFormat(Qt::RichText); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); +} + +void MainWindow::openFile() +{ + QString lastPath, filename; + QAction* fileToOpen = qobject_cast(sender()); + + //if sender is from recent list directly open file, otherwise show dialog + if(fileToOpen == NULL || !fileToOpen->objectName().startsWith("MRU") || !(fileToOpen->text().length())) + { + lastPath = (mMRUList.size() > 0) ? mMRUList.at(0) : 0; + filename = QFileDialog::getOpenFileName(this, tr("Open file"), lastPath, tr("Executables (*.exe *.dll);;All files (*.*)")); + if(!filename.length()) + return; + filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes) + } + else + { + filename = fileToOpen->text(); + } + DbgCmdExec(QString().sprintf("init \"%s\"", filename.toUtf8().constData()).toUtf8().constData()); + + //file is from recent menu + if(fileToOpen != NULL && fileToOpen->objectName().startsWith("MRU")) + { + fileToOpen->setObjectName(fileToOpen->objectName().split("U").at(1)); + int index = fileToOpen->objectName().toInt(); + + QString exists = getMRUEntry(index); + if(exists.length() == 0) + { + addMRUEntry(filename); + updateMRUMenu(); + saveMRUList(); + } + + fileToOpen->setObjectName(fileToOpen->objectName().prepend("MRU")); + } + + //file is from open button + bool update = true; + if(fileToOpen == NULL || fileToOpen->objectName().compare("actionOpen") == 0) + for(int i = 0; i < mMRUList.size(); i++) + if(mMRUList.at(i) == filename) + { + update = false; + break; + } + if(update) + { + addMRUEntry(filename); + updateMRUMenu(); + saveMRUList(); + } + + mCpuWidget->setDisasmFocus(); +} + +void MainWindow::execPause() +{ + DbgCmdExec("pause"); +} + +void MainWindow::startScylla() //this is executed +{ + DbgCmdExec("StartScylla"); +} + +void MainWindow::restartDebugging() +{ + if(!mMRUList.size()) + return; + DbgCmdExec(QString().sprintf("init \"%s\"", mMRUList.at(0).toUtf8().constData()).toUtf8().constData()); + + mCpuWidget->setDisasmFocus(); +} + +void MainWindow::displayBreakpointWidget() +{ + showQWidgetTab(mBreakpointsView); +} + +void MainWindow::dragEnterEvent(QDragEnterEvent* pEvent) +{ + if(pEvent->mimeData()->hasUrls()) + { + pEvent->acceptProposedAction(); + } +} + +void MainWindow::dropEvent(QDropEvent* pEvent) +{ + if(pEvent->mimeData()->hasUrls()) + { + QString filename = QDir::toNativeSeparators(pEvent->mimeData()->urls()[0].toLocalFile()); + DbgCmdExec(QString().sprintf("init \"%s\"", filename.toUtf8().constData()).toUtf8().constData()); + pEvent->acceptProposedAction(); + } +} + +void MainWindow::updateWindowTitleSlot(QString filename) +{ + if(filename.length()) + setWindowTitle(QString(mWindowMainTitle) + QString(" - ") + filename); + else + setWindowTitle(QString(mWindowMainTitle)); +} + +void MainWindow::execeStepOver() +{ + DbgCmdExec("eStepOver"); +} + +void MainWindow::execeStepInto() +{ + DbgCmdExec("eStepInto"); +} +void MainWindow::execeRun() +{ + DbgCmdExec("erun"); +} + +void MainWindow::execeRtr() +{ + DbgCmdExec("ertr"); +} + +void MainWindow::execSkip() +{ + DbgCmdExec("skip"); +} + +void MainWindow::displayCpuWidget() +{ + showQWidgetTab(mCpuWidget); +} + +void MainWindow::displaySymbolWidget() +{ + showQWidgetTab(mSymbolView); +} + +void MainWindow::displaySourceViewWidget() +{ + showQWidgetTab(mSourceViewManager); +} + +void MainWindow::displayReferencesWidget() +{ + showQWidgetTab(mReferenceManager); +} + +void MainWindow::displayThreadsWidget() +{ + showQWidgetTab(mThreadView); +} + +void MainWindow::displaySnowmanWidget() +{ + showQWidgetTab(mSnowmanView); +} + +void MainWindow::openSettings() +{ + SettingsDialog settings(this); + settings.lastException = lastException; + settings.exec(); +} + +void MainWindow::openAppearance() +{ + AppearanceDialog appearance(this); + appearance.exec(); +} + +void MainWindow::openCalculator() +{ + mCalculatorDialog->showNormal(); + mCalculatorDialog->setFocus(); + mCalculatorDialog->setExpressionFocus(); +} + +void MainWindow::openShortcuts() +{ + ShortcutsDialog shortcuts(this); + shortcuts.exec(); +} + +void MainWindow::changeTopmost(bool checked) +{ + if(checked) + SetWindowPos((HWND)this->winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + else + SetWindowPos((HWND)this->winId(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); +} + +void MainWindow::addRecentFile(QString file) +{ + addMRUEntry(file); + updateMRUMenu(); + saveMRUList(); +} + +void MainWindow::setLastException(unsigned int exceptionCode) +{ + lastException = exceptionCode; +} + +void MainWindow::findStrings() +{ + DbgCmdExec(QString("strref " + QString("%1").arg(mCpuWidget->getDisasmWidget()->getSelectedVa(), sizeof(dsint) * 2, 16, QChar('0')).toUpper()).toUtf8().constData()); + displayReferencesWidget(); +} + +void MainWindow::findModularCalls() +{ + DbgCmdExec(QString("modcallfind " + QString("%1").arg(mCpuWidget->getDisasmWidget()->getSelectedVa(), sizeof(dsint) * 2, 16, QChar('0')).toUpper()).toUtf8().constData()); + displayReferencesWidget(); +} + +const MainWindow::MenuInfo* MainWindow::findMenu(int hMenu) +{ + if(hMenu == -1) + return 0; + int nFound = -1; + for(int i = 0; i < mMenuList.size(); i++) + { + if(hMenu == mMenuList.at(i).hMenu) + { + nFound = i; + break; + } + } + return nFound == -1 ? 0 : &mMenuList.at(nFound); +} + +void MainWindow::addMenuToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu) +{ + if(!findMenu(hMenu)) + mMenuList.push_back(MenuInfo(parent, menu, hMenu, hParentMenu)); + Bridge::getBridge()->setResult(); +} + +void MainWindow::addMenu(int hMenu, QString title) +{ + const MenuInfo* menu = findMenu(hMenu); + if(!menu && hMenu != -1) + { + Bridge::getBridge()->setResult(-1); + return; + } + int hMenuNew = hMenuNext++; + QWidget* parent = hMenu == -1 ? this : menu->parent; + QMenu* wMenu = new QMenu(title, parent); + wMenu->menuAction()->setVisible(false); + mMenuList.push_back(MenuInfo(parent, wMenu, hMenuNew, hMenu)); + if(hMenu == -1) //top-level + ui->menuBar->addMenu(wMenu); + else //deeper level + menu->mMenu->addMenu(wMenu); + Bridge::getBridge()->setResult(hMenuNew); +} + +void MainWindow::addMenuEntry(int hMenu, QString title) +{ + const MenuInfo* menu = findMenu(hMenu); + if(!menu && hMenu != -1) + { + Bridge::getBridge()->setResult(-1); + return; + } + MenuEntryInfo newInfo; + int hEntryNew = hEntryNext++; + newInfo.hEntry = hEntryNew; + newInfo.hParentMenu = hMenu; + QWidget* parent = hMenu == -1 ? this : menu->parent; + QAction* wAction = new QAction(title, parent); + wAction->setObjectName(QString().sprintf("ENTRY|%d", hEntryNew)); + parent->addAction(wAction); + connect(wAction, SIGNAL(triggered()), this, SLOT(menuEntrySlot())); + newInfo.mAction = wAction; + mEntryList.push_back(newInfo); + if(hMenu == -1) //top level + ui->menuBar->addAction(wAction); + else //deeper level + { + menu->mMenu->addAction(wAction); + menu->mMenu->menuAction()->setVisible(true); + } + Bridge::getBridge()->setResult(hEntryNew); +} + +void MainWindow::addSeparator(int hMenu) +{ + const MenuInfo* menu = findMenu(hMenu); + if(menu) + { + MenuEntryInfo newInfo; + newInfo.hEntry = -1; + newInfo.hParentMenu = hMenu; + newInfo.mAction = menu->mMenu->addSeparator(); + mEntryList.push_back(newInfo); + } + Bridge::getBridge()->setResult(); +} + +void MainWindow::clearMenu(int hMenu) +{ + if(!mMenuList.size() || hMenu == -1) + { + Bridge::getBridge()->setResult(); + return; + } + const MenuInfo* menu = findMenu(hMenu); + //delete menu entries + for(int i = mEntryList.size() - 1; i > -1; i--) + { + if(hMenu == mEntryList.at(i).hParentMenu) //we found an entry that has the menu as parent + { + QWidget* parent = menu == 0 ? this : menu->parent; + parent->removeAction(mEntryList.at(i).mAction); + delete mEntryList.at(i).mAction; //delete the entry object + mEntryList.erase(mEntryList.begin() + i); + } + } + //recursively delete the menus + for(int i = mMenuList.size() - 1; i > -1; i--) + { + if(hMenu == mMenuList.at(i).hParentMenu) //we found a menu that has the menu as parent + { + clearMenu(mMenuList.at(i).hMenu); //delete children menus + delete mMenuList.at(i).mMenu; //delete the child menu object + mMenuList.erase(mMenuList.begin() + i); //delete the child entry + } + } + //hide the empty menu + if(menu) + menu->mMenu->menuAction()->setVisible(false); + Bridge::getBridge()->setResult(); +} + +void MainWindow::initMenuApi() +{ + //256 entries are reserved + mEntryList.clear(); + hEntryNext = 256; + mMenuList.clear(); + hMenuNext = 256; +} + +void MainWindow::menuEntrySlot() +{ + QAction* action = qobject_cast(sender()); + if(action && action->objectName().startsWith("ENTRY|")) + { + int hEntry = -1; + if(sscanf_s(action->objectName().mid(6).toUtf8().constData(), "%d", &hEntry) == 1) + DbgMenuEntryClicked(hEntry); + } +} + +void MainWindow::removeMenuEntry(int hEntry) +{ + for(int i = 0; i < mEntryList.size(); i++) + { + if(mEntryList.at(i).hEntry == hEntry) + { + const MenuEntryInfo & entry = mEntryList.at(i); + const MenuInfo* menu = findMenu(entry.hParentMenu); + QWidget* parent = menu == 0 ? this : menu->parent; + parent->removeAction(entry.mAction); + delete entry.mAction; + mEntryList.erase(mEntryList.begin() + i); + break; + } + } + Bridge::getBridge()->setResult(); +} + +void MainWindow::setIconMenuEntry(int hEntry, QIcon icon) +{ + for(int i = 0; i < mEntryList.size(); i++) + { + if(mEntryList.at(i).hEntry == hEntry) + { + const MenuEntryInfo & entry = mEntryList.at(i); + entry.mAction->setIcon(icon); + break; + } + } + Bridge::getBridge()->setResult(); +} + +void MainWindow::setIconMenu(int hMenu, QIcon icon) +{ + for(int i = 0; i < mMenuList.size(); i++) + { + if(mMenuList.at(i).hMenu == hMenu) + { + const MenuInfo & menu = mMenuList.at(i); + menu.mMenu->setIcon(icon); + } + } + Bridge::getBridge()->setResult(); +} + +void MainWindow::runSelection() +{ + if(!DbgIsDebugging()) + return; + + QString command = "bp " + QString("%1").arg(mCpuWidget->getDisasmWidget()->getSelectedVa(), sizeof(dsint) * 2, 16, QChar('0')).toUpper() + ", ss"; + if(DbgCmdExecDirect(command.toUtf8().constData())) + DbgCmdExecDirect("run"); +} + +void MainWindow::getStrWindow(const QString title, QString* text) +{ + LineEditDialog mLineEdit(this); + mLineEdit.setWindowTitle(title); + bool bResult = true; + if(mLineEdit.exec() != QDialog::Accepted) + bResult = false; + *text = mLineEdit.editText; + Bridge::getBridge()->setResult(bResult); +} + +void MainWindow::patchWindow() +{ + if(!DbgIsDebugging()) + { + QMessageBox msg(QMessageBox::Critical, "Error!", QString("Patches cannot be shown when not debugging...")); + msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return; + } + GuiUpdatePatches(); + mPatchDialog->showNormal(); + mPatchDialog->setFocus(); +} + +void MainWindow::displayComments() +{ + if(!DbgIsDebugging()) + return; + DbgCmdExec("commentlist"); + displayReferencesWidget(); +} + +void MainWindow::displayLabels() +{ + if(!DbgIsDebugging()) + return; + DbgCmdExec("labellist"); + displayReferencesWidget(); +} + +void MainWindow::displayBookmarks() +{ + if(!DbgIsDebugging()) + return; + DbgCmdExec("bookmarklist"); + displayReferencesWidget(); +} + +void MainWindow::displayFunctions() +{ + if(!DbgIsDebugging()) + return; + DbgCmdExec("functionlist"); + displayReferencesWidget(); +} + +void MainWindow::checkUpdates() +{ + mUpdateChecker->checkForUpdates(); +} + +void MainWindow::displayCallstack() +{ + showQWidgetTab(mCallStackView); +} + +void MainWindow::donate() +{ + QMessageBox msg(QMessageBox::Information, "Donate", "All the money will go to x64dbg development."); + msg.setWindowIcon(QIcon(":/icons/images/donate.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + msg.setDefaultButton(QMessageBox::Ok); + if(msg.exec() != QMessageBox::Ok) + return; + QDesktopServices::openUrl(QUrl("http://donate.x64dbg.com")); +} + +void MainWindow::reportBug() +{ + QMessageBox msg(QMessageBox::Information, "Report Bug", "You will be taken to a website where you can report a bug.\nMake sure to fill in as much information as possible."); + msg.setWindowIcon(QIcon(":/icons/images/bug-report.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + msg.setDefaultButton(QMessageBox::Ok); + if(msg.exec() != QMessageBox::Ok) + return; + QDesktopServices::openUrl(QUrl("http://report.x64dbg.com")); +} + +void MainWindow::displayAttach() +{ + AttachDialog attach(this); + attach.exec(); + + mCpuWidget->setDisasmFocus(); +} + +void MainWindow::detach() +{ + DbgCmdExec("detach"); +} + +void MainWindow::changeCommandLine() +{ + if(!DbgIsDebugging()) + return; + + LineEditDialog mLineEdit(this); + mLineEdit.setText(""); + mLineEdit.setWindowTitle("Change Command Line"); + mLineEdit.setWindowIcon(QIcon(":/icons/images/changeargs.png")); + + size_t cbsize = 0; + char* cmdline = 0; + if(!DbgFunctions()->GetCmdline(0, &cbsize)) + mLineEdit.setText("Cannot get remote command line, use the 'getcmdline' command for more information."); + else + { + cmdline = new char[cbsize]; + DbgFunctions()->GetCmdline(cmdline, 0); + mLineEdit.setText(QString(cmdline)); + delete[] cmdline; + } + + mLineEdit.setCursorPosition(0); + + if(mLineEdit.exec() != QDialog::Accepted) + return; //pressed cancel + + if(!DbgFunctions()->SetCmdline((char*)mLineEdit.editText.toUtf8().constData())) + { + QMessageBox msg(QMessageBox::Warning, "Error", "Could not set command line!"); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + } + else + { + DbgFunctions()->MemUpdateMap(); + GuiUpdateMemoryView(); + GuiAddStatusBarMessage(QString("New command line: " + mLineEdit.editText + "\n").toUtf8().constData()); + } +} + +void MainWindow::displayManual() +{ + // Open the Windows CHM in the upper directory + QDesktopServices::openUrl(QUrl("..\\x64dbg.chm")); +} + +void MainWindow::decompileAt(dsint start, dsint end) +{ + DecompileAt(mSnowmanView, start, end); +} + +void MainWindow::canClose() +{ + bCanClose = true; + close(); +} + +void MainWindow::addQWidgetTab(QWidget* qWidget) +{ + mTabWidget->addTab(qWidget, qWidget->windowIcon(), qWidget->windowTitle()); +} + +void MainWindow::showQWidgetTab(QWidget* qWidget) +{ + qWidget->show(); + qWidget->setFocus(); + setTab(qWidget); +} + +void MainWindow::closeQWidgetTab(QWidget* qWidget) +{ + for(int i = 0; i < mTabWidget->count(); i++) + { + if(mTabWidget->widget(i) == qWidget) + { + mTabWidget->DeleteTab(i); + break; + } + } +} + +void MainWindow::executeOnGuiThread(void* cbGuiThread) +{ + ((GUICALLBACK)cbGuiThread)(); +} diff --git a/src/gui/Src/Gui/MainWindow.h b/src/gui/Src/Gui/MainWindow.h index 044782f7..be0cb8bc 100644 --- a/src/gui/Src/Gui/MainWindow.h +++ b/src/gui/Src/Gui/MainWindow.h @@ -1,195 +1,195 @@ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include -#include "CloseDialog.h" -#include "CommandLineEdit.h" -#include "TabWidget.h" -#include "CPUWidget.h" -#include "MemoryMapView.h" -#include "CallStackView.h" -#include "LogView.h" -#include "SymbolView.h" -#include "BreakpointsView.h" -#include "ScriptView.h" -#include "ReferenceManager.h" -#include "ThreadView.h" -#include "PatchDialog.h" -#include "CalculatorDialog.h" -#include "StatusLabel.h" -#include "UpdateChecker.h" -#include "SourceViewerManager.h" -#include "SnowmanView.h" -#include "MainWindowCloseThread.h" -#include "TimeWastedCounter.h" -#include "NotesManager.h" - -namespace Ui -{ -class MainWindow; -} - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow(QWidget* parent = 0); - ~MainWindow(); - static DWORD WINAPI closeThread(void* ptr); - void closeEvent(QCloseEvent* event); - void setTab(QWidget* widget); - -public slots: - void executeCommand(); - void execStepOver(); - void execStepInto(); - void setFocusToCommandBar(); - void displayMemMapWidget(); - void displayLogWidget(); - void displayScriptWidget(); - void displayAboutWidget(); - void execClose(); - void execRun(); - void execRtr(); - void openFile(); - void execPause(); - void startScylla(); - void restartDebugging(); - void displayBreakpointWidget(); - void updateWindowTitleSlot(QString filename); - void execeStepOver(); - void execeStepInto(); - void execeRun(); - void execeRtr(); - void execSkip(); - void displayCpuWidget(); - void displaySymbolWidget(); - void displaySourceViewWidget(); - void displayReferencesWidget(); - void displayThreadsWidget(); - void displaySnowmanWidget(); - void openSettings(); - void openAppearance(); - void openCalculator(); - void addRecentFile(QString file); - void setLastException(unsigned int exceptionCode); - void findStrings(); - void findModularCalls(); - void addMenuToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu = -1); - void addMenu(int hMenu, QString title); - void addMenuEntry(int hMenu, QString title); - void addSeparator(int hMenu); - void clearMenu(int hMenu); - void menuEntrySlot(); - void removeMenuEntry(int hEntry); - void setIconMenuEntry(int hEntry, QIcon icon); - void setIconMenu(int hMenu, QIcon icon); - void runSelection(); - void getStrWindow(const QString title, QString* text); - void patchWindow(); - void displayComments(); - void displayLabels(); - void displayBookmarks(); - void displayFunctions(); - void checkUpdates(); - void displayCallstack(); - void setGlobalShortcut(QAction* action, const QKeySequence & key); - void refreshShortcuts(); - void openShortcuts(); - void changeTopmost(bool checked); - void donate(); - void reportBug(); - void displayAttach(); - void detach(); - void changeCommandLine(); - void displayManual(); - void decompileAt(dsint start, dsint end); - void canClose(); - void addQWidgetTab(QWidget* qWidget); - void showQWidgetTab(QWidget* qWidget); - void closeQWidgetTab(QWidget* qWidget); - void executeOnGuiThread(void* cbGuiThread); - -private: - Ui::MainWindow* ui; - CloseDialog* mCloseDialog; - CommandLineEdit* mCmdLineEdit; - MHTabWidget* mTabWidget; - CPUWidget* mCpuWidget; - MemoryMapView* mMemMapView; - CallStackView* mCallStackView; - LogView* mLogView; - SymbolView* mSymbolView; - SourceViewerManager* mSourceViewManager; - BreakpointsView* mBreakpointsView; - ScriptView* mScriptView; - ReferenceManager* mReferenceManager; - ThreadView* mThreadView; - PatchDialog* mPatchDialog; - CalculatorDialog* mCalculatorDialog; - SnowmanView* mSnowmanView; - NotesManager* mNotesManager; - - StatusLabel* mStatusLabel; - StatusLabel* mLastLogLabel; - - UpdateChecker* mUpdateChecker; - TimeWastedCounter* mTimeWastedCounter; - - const char* mWindowMainTitle; - - QStringList mMRUList; - int mMaxMRU; - unsigned int lastException; - - void loadMRUList(int maxItems); - void saveMRUList(); - void addMRUEntry(QString entry); - void removeMRUEntry(QString entry); - void updateMRUMenu(); - QString getMRUEntry(int index); - - //menu api - struct MenuEntryInfo - { - QAction* mAction; - int hEntry; - int hParentMenu; - }; - - struct MenuInfo - { - public: - MenuInfo(QWidget* parent, QMenu* mMenu, int hMenu, int hParentMenu) - { - this->parent = parent; - this->mMenu = mMenu; - this->hMenu = hMenu; - this->hParentMenu = hParentMenu; - } - - QWidget* parent; - QMenu* mMenu; - int hMenu; - int hParentMenu; - }; - - QList mEntryList; - int hEntryNext; - QList mMenuList; - int hMenuNext; - - void initMenuApi(); - const MenuInfo* findMenu(int hMenu); - - bool bCanClose; - MainWindowCloseThread* mCloseThread; - -protected: - void dragEnterEvent(QDragEnterEvent* pEvent); - void dropEvent(QDropEvent* pEvent); -}; - -#endif // MAINWINDOW_H +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include "CloseDialog.h" +#include "CommandLineEdit.h" +#include "TabWidget.h" +#include "CPUWidget.h" +#include "MemoryMapView.h" +#include "CallStackView.h" +#include "LogView.h" +#include "SymbolView.h" +#include "BreakpointsView.h" +#include "ScriptView.h" +#include "ReferenceManager.h" +#include "ThreadView.h" +#include "PatchDialog.h" +#include "CalculatorDialog.h" +#include "StatusLabel.h" +#include "UpdateChecker.h" +#include "SourceViewerManager.h" +#include "SnowmanView.h" +#include "MainWindowCloseThread.h" +#include "TimeWastedCounter.h" +#include "NotesManager.h" + +namespace Ui +{ +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget* parent = 0); + ~MainWindow(); + static DWORD WINAPI closeThread(void* ptr); + void closeEvent(QCloseEvent* event); + void setTab(QWidget* widget); + +public slots: + void executeCommand(); + void execStepOver(); + void execStepInto(); + void setFocusToCommandBar(); + void displayMemMapWidget(); + void displayLogWidget(); + void displayScriptWidget(); + void displayAboutWidget(); + void execClose(); + void execRun(); + void execRtr(); + void openFile(); + void execPause(); + void startScylla(); + void restartDebugging(); + void displayBreakpointWidget(); + void updateWindowTitleSlot(QString filename); + void execeStepOver(); + void execeStepInto(); + void execeRun(); + void execeRtr(); + void execSkip(); + void displayCpuWidget(); + void displaySymbolWidget(); + void displaySourceViewWidget(); + void displayReferencesWidget(); + void displayThreadsWidget(); + void displaySnowmanWidget(); + void openSettings(); + void openAppearance(); + void openCalculator(); + void addRecentFile(QString file); + void setLastException(unsigned int exceptionCode); + void findStrings(); + void findModularCalls(); + void addMenuToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu = -1); + void addMenu(int hMenu, QString title); + void addMenuEntry(int hMenu, QString title); + void addSeparator(int hMenu); + void clearMenu(int hMenu); + void menuEntrySlot(); + void removeMenuEntry(int hEntry); + void setIconMenuEntry(int hEntry, QIcon icon); + void setIconMenu(int hMenu, QIcon icon); + void runSelection(); + void getStrWindow(const QString title, QString* text); + void patchWindow(); + void displayComments(); + void displayLabels(); + void displayBookmarks(); + void displayFunctions(); + void checkUpdates(); + void displayCallstack(); + void setGlobalShortcut(QAction* action, const QKeySequence & key); + void refreshShortcuts(); + void openShortcuts(); + void changeTopmost(bool checked); + void donate(); + void reportBug(); + void displayAttach(); + void detach(); + void changeCommandLine(); + void displayManual(); + void decompileAt(dsint start, dsint end); + void canClose(); + void addQWidgetTab(QWidget* qWidget); + void showQWidgetTab(QWidget* qWidget); + void closeQWidgetTab(QWidget* qWidget); + void executeOnGuiThread(void* cbGuiThread); + +private: + Ui::MainWindow* ui; + CloseDialog* mCloseDialog; + CommandLineEdit* mCmdLineEdit; + MHTabWidget* mTabWidget; + CPUWidget* mCpuWidget; + MemoryMapView* mMemMapView; + CallStackView* mCallStackView; + LogView* mLogView; + SymbolView* mSymbolView; + SourceViewerManager* mSourceViewManager; + BreakpointsView* mBreakpointsView; + ScriptView* mScriptView; + ReferenceManager* mReferenceManager; + ThreadView* mThreadView; + PatchDialog* mPatchDialog; + CalculatorDialog* mCalculatorDialog; + SnowmanView* mSnowmanView; + NotesManager* mNotesManager; + + StatusLabel* mStatusLabel; + StatusLabel* mLastLogLabel; + + UpdateChecker* mUpdateChecker; + TimeWastedCounter* mTimeWastedCounter; + + const char* mWindowMainTitle; + + QStringList mMRUList; + int mMaxMRU; + unsigned int lastException; + + void loadMRUList(int maxItems); + void saveMRUList(); + void addMRUEntry(QString entry); + void removeMRUEntry(QString entry); + void updateMRUMenu(); + QString getMRUEntry(int index); + + //menu api + struct MenuEntryInfo + { + QAction* mAction; + int hEntry; + int hParentMenu; + }; + + struct MenuInfo + { + public: + MenuInfo(QWidget* parent, QMenu* mMenu, int hMenu, int hParentMenu) + { + this->parent = parent; + this->mMenu = mMenu; + this->hMenu = hMenu; + this->hParentMenu = hParentMenu; + } + + QWidget* parent; + QMenu* mMenu; + int hMenu; + int hParentMenu; + }; + + QList mEntryList; + int hEntryNext; + QList mMenuList; + int hMenuNext; + + void initMenuApi(); + const MenuInfo* findMenu(int hMenu); + + bool bCanClose; + MainWindowCloseThread* mCloseThread; + +protected: + void dragEnterEvent(QDragEnterEvent* pEvent); + void dropEvent(QDropEvent* pEvent); +}; + +#endif // MAINWINDOW_H diff --git a/src/gui/Src/Gui/MemoryMapView.cpp b/src/gui/Src/Gui/MemoryMapView.cpp index 25e48897..ee0cba4b 100644 --- a/src/gui/Src/Gui/MemoryMapView.cpp +++ b/src/gui/Src/Gui/MemoryMapView.cpp @@ -1,449 +1,449 @@ -#include "MemoryMapView.h" -#include "Configuration.h" -#include "Bridge.h" -#include "PageMemoryRights.h" -#include "YaraRuleSelectionDialog.h" -#include "EntropyDialog.h" -#include "HexEditDialog.h" - -MemoryMapView::MemoryMapView(StdTable* parent) : StdTable(parent) -{ - enableMultiSelection(false); - - int charwidth = getCharWidth(); - - addColumnAt(8 + charwidth * 2 * sizeof(duint), "Address", false, "Address"); //addr - addColumnAt(8 + charwidth * 2 * sizeof(duint), "Size", false, "Size"); //size - addColumnAt(8 + charwidth * 32, "Info", false, "Page Information"); //page information - addColumnAt(8 + charwidth * 5, "Type", false, "Allocation Type"); //allocation type - addColumnAt(8 + charwidth * 11, "Protection", false, "Current Protection"); //current protection - addColumnAt(8 + charwidth * 8, "Initial", false, "Allocation Protection"); //allocation protection - addColumnAt(100, "", false); - - connect(Bridge::getBridge(), SIGNAL(updateMemory()), this, SLOT(refreshMap())); - connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(stateChangedSlot(DBGSTATE))); - connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint))); - - setupContextMenu(); -} - -void MemoryMapView::setupContextMenu() -{ - //Follow in Dump - mFollowDump = new QAction("&Follow in Dump", this); - connect(mFollowDump, SIGNAL(triggered()), this, SLOT(followDumpSlot())); - - //Follow in Disassembler - mFollowDisassembly = new QAction("Follow in &Disassembler", this); - mFollowDisassembly->setShortcutContext(Qt::WidgetShortcut); - mFollowDisassembly->setShortcut(QKeySequence("enter")); - connect(mFollowDisassembly, SIGNAL(triggered()), this, SLOT(followDisassemblerSlot())); - connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followDisassemblerSlot())); - connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(followDisassemblerSlot())); - - //Yara - mYara = new QAction(QIcon(":/icons/images/yara.png"), "&Yara...", this); - connect(mYara, SIGNAL(triggered()), this, SLOT(yaraSlot())); - - //Set PageMemory Rights - mPageMemoryRights = new QAction("Set Page Memory Rights", this); - connect(mPageMemoryRights, SIGNAL(triggered()), this, SLOT(pageMemoryRights())); - - //Switch View - mSwitchView = new QAction("&Switch View", this); - connect(mSwitchView, SIGNAL(triggered()), this, SLOT(switchView())); - - //Breakpoint menu - mBreakpointMenu = new QMenu("Memory &Breakpoint", this); - - //Breakpoint->Memory Access - mMemoryAccessMenu = new QMenu("Access", this); - mMemoryAccessSingleshoot = new QAction("&Singleshoot", this); - connect(mMemoryAccessSingleshoot, SIGNAL(triggered()), this, SLOT(memoryAccessSingleshootSlot())); - mMemoryAccessMenu->addAction(mMemoryAccessSingleshoot); - mMemoryAccessRestore = new QAction("&Restore", this); - connect(mMemoryAccessRestore, SIGNAL(triggered()), this, SLOT(memoryAccessRestoreSlot())); - mMemoryAccessMenu->addAction(mMemoryAccessRestore); - mBreakpointMenu->addMenu(mMemoryAccessMenu); - - //Breakpoint->Memory Write - mMemoryWriteMenu = new QMenu("Write", this); - mMemoryWriteSingleshoot = new QAction("&Singleshoot", this); - connect(mMemoryWriteSingleshoot, SIGNAL(triggered()), this, SLOT(memoryWriteSingleshootSlot())); - mMemoryWriteMenu->addAction(mMemoryWriteSingleshoot); - mMemoryWriteRestore = new QAction("&Restore", this); - connect(mMemoryWriteRestore, SIGNAL(triggered()), this, SLOT(memoryWriteRestoreSlot())); - mMemoryWriteMenu->addAction(mMemoryWriteRestore); - mBreakpointMenu->addMenu(mMemoryWriteMenu); - - //Breakpoint->Memory Execute - mMemoryExecuteMenu = new QMenu("Execute", this); - mMemoryExecuteSingleshoot = new QAction("&Singleshoot", this); - mMemoryExecuteSingleshoot->setShortcutContext(Qt::WidgetShortcut); - connect(mMemoryExecuteSingleshoot, SIGNAL(triggered()), this, SLOT(memoryExecuteSingleshootSlot())); - mMemoryExecuteMenu->addAction(mMemoryExecuteSingleshoot); - mMemoryExecuteRestore = new QAction("&Restore", this); - connect(mMemoryExecuteRestore, SIGNAL(triggered()), this, SLOT(memoryExecuteRestoreSlot())); - mMemoryExecuteMenu->addAction(mMemoryExecuteRestore); - mBreakpointMenu->addMenu(mMemoryExecuteMenu); - - //Breakpoint->Remove - mMemoryRemove = new QAction("&Remove", this); - mMemoryRemove->setShortcutContext(Qt::WidgetShortcut); - connect(mMemoryRemove, SIGNAL(triggered()), this, SLOT(memoryRemoveSlot())); - mBreakpointMenu->addAction(mMemoryRemove); - - //Action shortcut action that does something - mMemoryExecuteSingleshootToggle = new QAction(this); - mMemoryExecuteSingleshootToggle->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mMemoryExecuteSingleshootToggle); - connect(mMemoryExecuteSingleshootToggle, SIGNAL(triggered()), this, SLOT(memoryExecuteSingleshootToggleSlot())); - - //Entropy - mEntropy = new QAction(QIcon(":/icons/images/entropy.png"), "Entropy...", this); - connect(mEntropy, SIGNAL(triggered()), this, SLOT(entropy())); - - //Find - mFindPattern = new QAction(QIcon(":/icons/images/search-for.png"), "&Find Pattern...", this); - this->addAction(mFindPattern); - mFindPattern->setShortcutContext(Qt::WidgetShortcut); - connect(mFindPattern, SIGNAL(triggered()), this, SLOT(findPatternSlot())); - - refreshShortcutsSlot(); - connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); -} - -void MemoryMapView::refreshShortcutsSlot() -{ - mMemoryExecuteSingleshoot->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); - mMemoryRemove->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); - mMemoryExecuteSingleshootToggle->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); - mFindPattern->setShortcut(ConfigShortcut("ActionFindPattern")); -} - -void MemoryMapView::contextMenuSlot(const QPoint & pos) -{ - if(!DbgIsDebugging()) - return; - QMenu* wMenu = new QMenu(this); //create context menu - wMenu->addAction(mFollowDisassembly); - wMenu->addAction(mFollowDump); - wMenu->addAction(mYara); - wMenu->addAction(mEntropy); - wMenu->addAction(mFindPattern); - wMenu->addAction(mSwitchView); - wMenu->addSeparator(); - wMenu->addAction(mPageMemoryRights); - wMenu->addSeparator(); - wMenu->addMenu(mBreakpointMenu); - QMenu wCopyMenu("&Copy", this); - setupCopyMenu(&wCopyMenu); - if(wCopyMenu.actions().length()) - { - wMenu->addSeparator(); - wMenu->addMenu(&wCopyMenu); - } - - QString wStr = getCellContent(getInitialSelection(), 0); -#ifdef _WIN64 - duint selectedAddr = wStr.toULongLong(0, 16); -#else //x86 - duint selectedAddr = wStr.toULong(0, 16); -#endif //_WIN64 - if((DbgGetBpxTypeAt(selectedAddr)&bp_memory) == bp_memory) //memory breakpoint set - { - mMemoryAccessMenu->menuAction()->setVisible(false); - mMemoryWriteMenu->menuAction()->setVisible(false); - mMemoryExecuteMenu->menuAction()->setVisible(false); - mMemoryRemove->setVisible(true); - } - else //memory breakpoint not set - { - mMemoryAccessMenu->menuAction()->setVisible(true); - mMemoryWriteMenu->menuAction()->setVisible(true); - mMemoryExecuteMenu->menuAction()->setVisible(true); - mMemoryRemove->setVisible(false); - } - - wMenu->exec(mapToGlobal(pos)); //execute context menu -} - -QString MemoryMapView::getProtectionString(DWORD Protect) -{ -#define RIGHTS_STRING (sizeof("ERWCG") + 1) - char rights[RIGHTS_STRING]; - - if(!DbgFunctions()->PageRightsToString(Protect, rights)) - return "bad"; - - return QString(rights); -} - -QString MemoryMapView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) -{ - if(col == 0) //address - { - QString wStr = getCellContent(rowBase + rowOffset, col); -#ifdef _WIN64 - duint addr = wStr.toULongLong(0, 16); -#else //x86 - duint addr = wStr.toULong(0, 16); -#endif //_WIN64 - if((DbgGetBpxTypeAt(addr)&bp_memory) == bp_memory) - { - QString wStr = getCellContent(rowBase + rowOffset, col); - QColor bpBackgroundColor = ConfigColor("MemoryMapBreakpointBackgroundColor"); - if(bpBackgroundColor.alpha()) - painter->fillRect(QRect(x, y, w - 1, h), QBrush(bpBackgroundColor)); - painter->setPen(ConfigColor("MemoryMapBreakpointColor")); - painter->drawText(QRect(x + 4, y, getColumnWidth(col) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, wStr); - return ""; - } - else if(isSelected(rowBase, rowOffset) == true) - painter->fillRect(QRect(x, y, w, h), QBrush(selectionColor)); - } - else if(col == 2) //info - { - QString wStr = StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);; - if(wStr.startsWith(" \"")) - { - painter->setPen(ConfigColor("MemoryMapSectionTextColor")); - painter->drawText(QRect(x + 4, y, getColumnWidth(col) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, wStr); - return ""; - } - } - else if(col == 4) //CPROT - { - QString wStr = StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);; - if(!ConfigBool("Engine", "ListAllPages")) - { - painter->setPen(ConfigColor("MemoryMapSectionTextColor")); - painter->drawText(QRect(x + 4, y, getColumnWidth(col) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, wStr); - return ""; - } - } - return StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h); -} - -void MemoryMapView::refreshMap() -{ - MEMMAP wMemMapStruct; - int wI; - - memset(&wMemMapStruct, 0, sizeof(MEMMAP)); - - DbgMemMap(&wMemMapStruct); - - setRowCount(wMemMapStruct.count); - - for(wI = 0; wI < wMemMapStruct.count; wI++) - { - QString wS; - MEMORY_BASIC_INFORMATION wMbi = (wMemMapStruct.page)[wI].mbi; - - // Base address - wS = QString("%1").arg((duint)wMbi.BaseAddress, sizeof(duint) * 2, 16, QChar('0')).toUpper(); - setCellContent(wI, 0, wS); - - // Size - wS = QString("%1").arg((duint)wMbi.RegionSize, sizeof(duint) * 2, 16, QChar('0')).toUpper(); - setCellContent(wI, 1, wS); - - // Information - wS = QString((wMemMapStruct.page)[wI].info); - setCellContent(wI, 2, wS); - - // State - switch(wMbi.State) - { - case MEM_FREE: - wS = QString("FREE"); - break; - case MEM_COMMIT: - wS = QString("COMM"); - break; - case MEM_RESERVE: - wS = QString("RESV"); - break; - default: - wS = QString("????"); - } - setCellContent(wI, 3, wS); - - // Type - switch(wMbi.Type) - { - case MEM_IMAGE: - wS = QString("IMG"); - break; - case MEM_MAPPED: - wS = QString("MAP"); - break; - case MEM_PRIVATE: - wS = QString("PRV"); - break; - default: - wS = QString("N/A"); - break; - } - setCellContent(wI, 3, wS); - - // current access protection - wS = getProtectionString(wMbi.Protect); - setCellContent(wI, 4, wS); - - // allocation protection - wS = getProtectionString(wMbi.AllocationProtect); - setCellContent(wI, 5, wS); - - } - if(wMemMapStruct.page != 0) - BridgeFree(wMemMapStruct.page); - reloadData(); //refresh memory map -} - -void MemoryMapView::stateChangedSlot(DBGSTATE state) -{ - if(state == paused) - refreshMap(); -} - -void MemoryMapView::followDumpSlot() -{ - QString addr_text = getCellContent(getInitialSelection(), 0); - DbgCmdExecDirect(QString("dump " + addr_text).toUtf8().constData()); - emit showCpu(); -} - -void MemoryMapView::followDisassemblerSlot() -{ - QString commandText = QString("disasm %1").arg(getCellContent(getInitialSelection(), 0)); - - // If there was no address loaded, the length - // will only be the command length - if(commandText.length() <= 8) - return; - - DbgCmdExecDirect(commandText.toUtf8().constData()); - emit showCpu(); -} - -void MemoryMapView::yaraSlot() -{ - YaraRuleSelectionDialog yaraDialog(this); - if(yaraDialog.exec() == QDialog::Accepted) - { - QString addr_text = getCellContent(getInitialSelection(), 0); - QString size_text = getCellContent(getInitialSelection(), 1); - DbgCmdExec(QString("yara \"%0\",%1,%2").arg(yaraDialog.getSelectedFile()).arg(addr_text).arg(size_text).toUtf8().constData()); - emit showReferences(); - } -} - -void MemoryMapView::memoryAccessSingleshootSlot() -{ - QString addr_text = getCellContent(getInitialSelection(), 0); - DbgCmdExec(QString("bpm " + addr_text + ", 0, r").toUtf8().constData()); -} - -void MemoryMapView::memoryAccessRestoreSlot() -{ - QString addr_text = getCellContent(getInitialSelection(), 0); - DbgCmdExec(QString("bpm " + addr_text + ", 1, r").toUtf8().constData()); -} - -void MemoryMapView::memoryWriteSingleshootSlot() -{ - QString addr_text = getCellContent(getInitialSelection(), 0); - DbgCmdExec(QString("bpm " + addr_text + ", 0, w").toUtf8().constData()); -} - -void MemoryMapView::memoryWriteRestoreSlot() -{ - QString addr_text = getCellContent(getInitialSelection(), 0); - DbgCmdExec(QString("bpm " + addr_text + ", 1, w").toUtf8().constData()); -} - -void MemoryMapView::memoryExecuteSingleshootSlot() -{ - QString addr_text = getCellContent(getInitialSelection(), 0); - DbgCmdExec(QString("bpm " + addr_text + ", 0, x").toUtf8().constData()); -} - -void MemoryMapView::memoryExecuteRestoreSlot() -{ - QString addr_text = getCellContent(getInitialSelection(), 0); - DbgCmdExec(QString("bpm " + addr_text + ", 1, x").toUtf8().constData()); -} - -void MemoryMapView::memoryRemoveSlot() -{ - QString addr_text = getCellContent(getInitialSelection(), 0); - DbgCmdExec(QString("bpmc " + addr_text).toUtf8().constData()); -} - -void MemoryMapView::memoryExecuteSingleshootToggleSlot() -{ - QString addr_text = getCellContent(getInitialSelection(), 0); -#ifdef _WIN64 - duint selectedAddr = addr_text.toULongLong(0, 16); -#else //x86 - duint selectedAddr = addr_text.toULong(0, 16); -#endif //_WIN64 - if((DbgGetBpxTypeAt(selectedAddr)&bp_memory) == bp_memory) //memory breakpoint set - memoryRemoveSlot(); - else - memoryExecuteSingleshootSlot(); -} - -void MemoryMapView::pageMemoryRights() -{ - PageMemoryRights PageMemoryRightsDialog(this); - connect(&PageMemoryRightsDialog, SIGNAL(refreshMemoryMap()), this, SLOT(refreshMap())); - duint addr = getCellContent(getInitialSelection(), 0).toULongLong(0, 16); - duint size = getCellContent(getInitialSelection(), 1).toULongLong(0, 16); - PageMemoryRightsDialog.RunAddrSize(addr, size, getCellContent(getInitialSelection(), 3)); -} - -void MemoryMapView::switchView() -{ - Config()->setBool("Engine", "ListAllPages", !ConfigBool("Engine", "ListAllPages")); - Config()->writeBools(); - DbgSettingsUpdated(); - DbgFunctions()->MemUpdateMap(); - setSingleSelection(0); - setTableOffset(0); - stateChangedSlot(paused); -} - -void MemoryMapView::entropy() -{ - duint addr = getCellContent(getInitialSelection(), 0).toULongLong(0, 16); - duint size = getCellContent(getInitialSelection(), 1).toULongLong(0, 16); - unsigned char* data = new unsigned char[size]; - DbgMemRead(addr, data, size); - - EntropyDialog entropyDialog(this); - entropyDialog.setWindowTitle(QString().sprintf("Entropy (Address: %p, Size: %p)", addr, size)); - entropyDialog.show(); - entropyDialog.GraphMemory(data, size); - entropyDialog.exec(); - - delete[] data; -} - -void MemoryMapView::findPatternSlot() -{ - HexEditDialog hexEdit(this); - hexEdit.showEntireBlock(true); - hexEdit.mHexEdit->setOverwriteMode(false); - hexEdit.setWindowTitle("Find Pattern..."); - if(hexEdit.exec() != QDialog::Accepted) - return; - duint addr = getCellContent(getInitialSelection(), 0).toULongLong(0, 16); - if(hexEdit.entireBlock()) - addr = 0; - QString addrText = QString("%1").arg(addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - DbgCmdExec(QString("findmemall " + addrText + ", \"" + hexEdit.mHexEdit->pattern() + "\", &data&").toUtf8().constData()); - emit showReferences(); -} +#include "MemoryMapView.h" +#include "Configuration.h" +#include "Bridge.h" +#include "PageMemoryRights.h" +#include "YaraRuleSelectionDialog.h" +#include "EntropyDialog.h" +#include "HexEditDialog.h" + +MemoryMapView::MemoryMapView(StdTable* parent) : StdTable(parent) +{ + enableMultiSelection(false); + + int charwidth = getCharWidth(); + + addColumnAt(8 + charwidth * 2 * sizeof(duint), "Address", false, "Address"); //addr + addColumnAt(8 + charwidth * 2 * sizeof(duint), "Size", false, "Size"); //size + addColumnAt(8 + charwidth * 32, "Info", false, "Page Information"); //page information + addColumnAt(8 + charwidth * 5, "Type", false, "Allocation Type"); //allocation type + addColumnAt(8 + charwidth * 11, "Protection", false, "Current Protection"); //current protection + addColumnAt(8 + charwidth * 8, "Initial", false, "Allocation Protection"); //allocation protection + addColumnAt(100, "", false); + + connect(Bridge::getBridge(), SIGNAL(updateMemory()), this, SLOT(refreshMap())); + connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(stateChangedSlot(DBGSTATE))); + connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint))); + + setupContextMenu(); +} + +void MemoryMapView::setupContextMenu() +{ + //Follow in Dump + mFollowDump = new QAction("&Follow in Dump", this); + connect(mFollowDump, SIGNAL(triggered()), this, SLOT(followDumpSlot())); + + //Follow in Disassembler + mFollowDisassembly = new QAction("Follow in &Disassembler", this); + mFollowDisassembly->setShortcutContext(Qt::WidgetShortcut); + mFollowDisassembly->setShortcut(QKeySequence("enter")); + connect(mFollowDisassembly, SIGNAL(triggered()), this, SLOT(followDisassemblerSlot())); + connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followDisassemblerSlot())); + connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(followDisassemblerSlot())); + + //Yara + mYara = new QAction(QIcon(":/icons/images/yara.png"), "&Yara...", this); + connect(mYara, SIGNAL(triggered()), this, SLOT(yaraSlot())); + + //Set PageMemory Rights + mPageMemoryRights = new QAction("Set Page Memory Rights", this); + connect(mPageMemoryRights, SIGNAL(triggered()), this, SLOT(pageMemoryRights())); + + //Switch View + mSwitchView = new QAction("&Switch View", this); + connect(mSwitchView, SIGNAL(triggered()), this, SLOT(switchView())); + + //Breakpoint menu + mBreakpointMenu = new QMenu("Memory &Breakpoint", this); + + //Breakpoint->Memory Access + mMemoryAccessMenu = new QMenu("Access", this); + mMemoryAccessSingleshoot = new QAction("&Singleshoot", this); + connect(mMemoryAccessSingleshoot, SIGNAL(triggered()), this, SLOT(memoryAccessSingleshootSlot())); + mMemoryAccessMenu->addAction(mMemoryAccessSingleshoot); + mMemoryAccessRestore = new QAction("&Restore", this); + connect(mMemoryAccessRestore, SIGNAL(triggered()), this, SLOT(memoryAccessRestoreSlot())); + mMemoryAccessMenu->addAction(mMemoryAccessRestore); + mBreakpointMenu->addMenu(mMemoryAccessMenu); + + //Breakpoint->Memory Write + mMemoryWriteMenu = new QMenu("Write", this); + mMemoryWriteSingleshoot = new QAction("&Singleshoot", this); + connect(mMemoryWriteSingleshoot, SIGNAL(triggered()), this, SLOT(memoryWriteSingleshootSlot())); + mMemoryWriteMenu->addAction(mMemoryWriteSingleshoot); + mMemoryWriteRestore = new QAction("&Restore", this); + connect(mMemoryWriteRestore, SIGNAL(triggered()), this, SLOT(memoryWriteRestoreSlot())); + mMemoryWriteMenu->addAction(mMemoryWriteRestore); + mBreakpointMenu->addMenu(mMemoryWriteMenu); + + //Breakpoint->Memory Execute + mMemoryExecuteMenu = new QMenu("Execute", this); + mMemoryExecuteSingleshoot = new QAction("&Singleshoot", this); + mMemoryExecuteSingleshoot->setShortcutContext(Qt::WidgetShortcut); + connect(mMemoryExecuteSingleshoot, SIGNAL(triggered()), this, SLOT(memoryExecuteSingleshootSlot())); + mMemoryExecuteMenu->addAction(mMemoryExecuteSingleshoot); + mMemoryExecuteRestore = new QAction("&Restore", this); + connect(mMemoryExecuteRestore, SIGNAL(triggered()), this, SLOT(memoryExecuteRestoreSlot())); + mMemoryExecuteMenu->addAction(mMemoryExecuteRestore); + mBreakpointMenu->addMenu(mMemoryExecuteMenu); + + //Breakpoint->Remove + mMemoryRemove = new QAction("&Remove", this); + mMemoryRemove->setShortcutContext(Qt::WidgetShortcut); + connect(mMemoryRemove, SIGNAL(triggered()), this, SLOT(memoryRemoveSlot())); + mBreakpointMenu->addAction(mMemoryRemove); + + //Action shortcut action that does something + mMemoryExecuteSingleshootToggle = new QAction(this); + mMemoryExecuteSingleshootToggle->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mMemoryExecuteSingleshootToggle); + connect(mMemoryExecuteSingleshootToggle, SIGNAL(triggered()), this, SLOT(memoryExecuteSingleshootToggleSlot())); + + //Entropy + mEntropy = new QAction(QIcon(":/icons/images/entropy.png"), "Entropy...", this); + connect(mEntropy, SIGNAL(triggered()), this, SLOT(entropy())); + + //Find + mFindPattern = new QAction(QIcon(":/icons/images/search-for.png"), "&Find Pattern...", this); + this->addAction(mFindPattern); + mFindPattern->setShortcutContext(Qt::WidgetShortcut); + connect(mFindPattern, SIGNAL(triggered()), this, SLOT(findPatternSlot())); + + refreshShortcutsSlot(); + connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); +} + +void MemoryMapView::refreshShortcutsSlot() +{ + mMemoryExecuteSingleshoot->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); + mMemoryRemove->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); + mMemoryExecuteSingleshootToggle->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); + mFindPattern->setShortcut(ConfigShortcut("ActionFindPattern")); +} + +void MemoryMapView::contextMenuSlot(const QPoint & pos) +{ + if(!DbgIsDebugging()) + return; + QMenu* wMenu = new QMenu(this); //create context menu + wMenu->addAction(mFollowDisassembly); + wMenu->addAction(mFollowDump); + wMenu->addAction(mYara); + wMenu->addAction(mEntropy); + wMenu->addAction(mFindPattern); + wMenu->addAction(mSwitchView); + wMenu->addSeparator(); + wMenu->addAction(mPageMemoryRights); + wMenu->addSeparator(); + wMenu->addMenu(mBreakpointMenu); + QMenu wCopyMenu("&Copy", this); + setupCopyMenu(&wCopyMenu); + if(wCopyMenu.actions().length()) + { + wMenu->addSeparator(); + wMenu->addMenu(&wCopyMenu); + } + + QString wStr = getCellContent(getInitialSelection(), 0); +#ifdef _WIN64 + duint selectedAddr = wStr.toULongLong(0, 16); +#else //x86 + duint selectedAddr = wStr.toULong(0, 16); +#endif //_WIN64 + if((DbgGetBpxTypeAt(selectedAddr)&bp_memory) == bp_memory) //memory breakpoint set + { + mMemoryAccessMenu->menuAction()->setVisible(false); + mMemoryWriteMenu->menuAction()->setVisible(false); + mMemoryExecuteMenu->menuAction()->setVisible(false); + mMemoryRemove->setVisible(true); + } + else //memory breakpoint not set + { + mMemoryAccessMenu->menuAction()->setVisible(true); + mMemoryWriteMenu->menuAction()->setVisible(true); + mMemoryExecuteMenu->menuAction()->setVisible(true); + mMemoryRemove->setVisible(false); + } + + wMenu->exec(mapToGlobal(pos)); //execute context menu +} + +QString MemoryMapView::getProtectionString(DWORD Protect) +{ +#define RIGHTS_STRING (sizeof("ERWCG") + 1) + char rights[RIGHTS_STRING]; + + if(!DbgFunctions()->PageRightsToString(Protect, rights)) + return "bad"; + + return QString(rights); +} + +QString MemoryMapView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) +{ + if(col == 0) //address + { + QString wStr = getCellContent(rowBase + rowOffset, col); +#ifdef _WIN64 + duint addr = wStr.toULongLong(0, 16); +#else //x86 + duint addr = wStr.toULong(0, 16); +#endif //_WIN64 + if((DbgGetBpxTypeAt(addr)&bp_memory) == bp_memory) + { + QString wStr = getCellContent(rowBase + rowOffset, col); + QColor bpBackgroundColor = ConfigColor("MemoryMapBreakpointBackgroundColor"); + if(bpBackgroundColor.alpha()) + painter->fillRect(QRect(x, y, w - 1, h), QBrush(bpBackgroundColor)); + painter->setPen(ConfigColor("MemoryMapBreakpointColor")); + painter->drawText(QRect(x + 4, y, getColumnWidth(col) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, wStr); + return ""; + } + else if(isSelected(rowBase, rowOffset) == true) + painter->fillRect(QRect(x, y, w, h), QBrush(selectionColor)); + } + else if(col == 2) //info + { + QString wStr = StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);; + if(wStr.startsWith(" \"")) + { + painter->setPen(ConfigColor("MemoryMapSectionTextColor")); + painter->drawText(QRect(x + 4, y, getColumnWidth(col) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, wStr); + return ""; + } + } + else if(col == 4) //CPROT + { + QString wStr = StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);; + if(!ConfigBool("Engine", "ListAllPages")) + { + painter->setPen(ConfigColor("MemoryMapSectionTextColor")); + painter->drawText(QRect(x + 4, y, getColumnWidth(col) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, wStr); + return ""; + } + } + return StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h); +} + +void MemoryMapView::refreshMap() +{ + MEMMAP wMemMapStruct; + int wI; + + memset(&wMemMapStruct, 0, sizeof(MEMMAP)); + + DbgMemMap(&wMemMapStruct); + + setRowCount(wMemMapStruct.count); + + for(wI = 0; wI < wMemMapStruct.count; wI++) + { + QString wS; + MEMORY_BASIC_INFORMATION wMbi = (wMemMapStruct.page)[wI].mbi; + + // Base address + wS = QString("%1").arg((duint)wMbi.BaseAddress, sizeof(duint) * 2, 16, QChar('0')).toUpper(); + setCellContent(wI, 0, wS); + + // Size + wS = QString("%1").arg((duint)wMbi.RegionSize, sizeof(duint) * 2, 16, QChar('0')).toUpper(); + setCellContent(wI, 1, wS); + + // Information + wS = QString((wMemMapStruct.page)[wI].info); + setCellContent(wI, 2, wS); + + // State + switch(wMbi.State) + { + case MEM_FREE: + wS = QString("FREE"); + break; + case MEM_COMMIT: + wS = QString("COMM"); + break; + case MEM_RESERVE: + wS = QString("RESV"); + break; + default: + wS = QString("????"); + } + setCellContent(wI, 3, wS); + + // Type + switch(wMbi.Type) + { + case MEM_IMAGE: + wS = QString("IMG"); + break; + case MEM_MAPPED: + wS = QString("MAP"); + break; + case MEM_PRIVATE: + wS = QString("PRV"); + break; + default: + wS = QString("N/A"); + break; + } + setCellContent(wI, 3, wS); + + // current access protection + wS = getProtectionString(wMbi.Protect); + setCellContent(wI, 4, wS); + + // allocation protection + wS = getProtectionString(wMbi.AllocationProtect); + setCellContent(wI, 5, wS); + + } + if(wMemMapStruct.page != 0) + BridgeFree(wMemMapStruct.page); + reloadData(); //refresh memory map +} + +void MemoryMapView::stateChangedSlot(DBGSTATE state) +{ + if(state == paused) + refreshMap(); +} + +void MemoryMapView::followDumpSlot() +{ + QString addr_text = getCellContent(getInitialSelection(), 0); + DbgCmdExecDirect(QString("dump " + addr_text).toUtf8().constData()); + emit showCpu(); +} + +void MemoryMapView::followDisassemblerSlot() +{ + QString commandText = QString("disasm %1").arg(getCellContent(getInitialSelection(), 0)); + + // If there was no address loaded, the length + // will only be the command length + if(commandText.length() <= 8) + return; + + DbgCmdExecDirect(commandText.toUtf8().constData()); + emit showCpu(); +} + +void MemoryMapView::yaraSlot() +{ + YaraRuleSelectionDialog yaraDialog(this); + if(yaraDialog.exec() == QDialog::Accepted) + { + QString addr_text = getCellContent(getInitialSelection(), 0); + QString size_text = getCellContent(getInitialSelection(), 1); + DbgCmdExec(QString("yara \"%0\",%1,%2").arg(yaraDialog.getSelectedFile()).arg(addr_text).arg(size_text).toUtf8().constData()); + emit showReferences(); + } +} + +void MemoryMapView::memoryAccessSingleshootSlot() +{ + QString addr_text = getCellContent(getInitialSelection(), 0); + DbgCmdExec(QString("bpm " + addr_text + ", 0, r").toUtf8().constData()); +} + +void MemoryMapView::memoryAccessRestoreSlot() +{ + QString addr_text = getCellContent(getInitialSelection(), 0); + DbgCmdExec(QString("bpm " + addr_text + ", 1, r").toUtf8().constData()); +} + +void MemoryMapView::memoryWriteSingleshootSlot() +{ + QString addr_text = getCellContent(getInitialSelection(), 0); + DbgCmdExec(QString("bpm " + addr_text + ", 0, w").toUtf8().constData()); +} + +void MemoryMapView::memoryWriteRestoreSlot() +{ + QString addr_text = getCellContent(getInitialSelection(), 0); + DbgCmdExec(QString("bpm " + addr_text + ", 1, w").toUtf8().constData()); +} + +void MemoryMapView::memoryExecuteSingleshootSlot() +{ + QString addr_text = getCellContent(getInitialSelection(), 0); + DbgCmdExec(QString("bpm " + addr_text + ", 0, x").toUtf8().constData()); +} + +void MemoryMapView::memoryExecuteRestoreSlot() +{ + QString addr_text = getCellContent(getInitialSelection(), 0); + DbgCmdExec(QString("bpm " + addr_text + ", 1, x").toUtf8().constData()); +} + +void MemoryMapView::memoryRemoveSlot() +{ + QString addr_text = getCellContent(getInitialSelection(), 0); + DbgCmdExec(QString("bpmc " + addr_text).toUtf8().constData()); +} + +void MemoryMapView::memoryExecuteSingleshootToggleSlot() +{ + QString addr_text = getCellContent(getInitialSelection(), 0); +#ifdef _WIN64 + duint selectedAddr = addr_text.toULongLong(0, 16); +#else //x86 + duint selectedAddr = addr_text.toULong(0, 16); +#endif //_WIN64 + if((DbgGetBpxTypeAt(selectedAddr)&bp_memory) == bp_memory) //memory breakpoint set + memoryRemoveSlot(); + else + memoryExecuteSingleshootSlot(); +} + +void MemoryMapView::pageMemoryRights() +{ + PageMemoryRights PageMemoryRightsDialog(this); + connect(&PageMemoryRightsDialog, SIGNAL(refreshMemoryMap()), this, SLOT(refreshMap())); + duint addr = getCellContent(getInitialSelection(), 0).toULongLong(0, 16); + duint size = getCellContent(getInitialSelection(), 1).toULongLong(0, 16); + PageMemoryRightsDialog.RunAddrSize(addr, size, getCellContent(getInitialSelection(), 3)); +} + +void MemoryMapView::switchView() +{ + Config()->setBool("Engine", "ListAllPages", !ConfigBool("Engine", "ListAllPages")); + Config()->writeBools(); + DbgSettingsUpdated(); + DbgFunctions()->MemUpdateMap(); + setSingleSelection(0); + setTableOffset(0); + stateChangedSlot(paused); +} + +void MemoryMapView::entropy() +{ + duint addr = getCellContent(getInitialSelection(), 0).toULongLong(0, 16); + duint size = getCellContent(getInitialSelection(), 1).toULongLong(0, 16); + unsigned char* data = new unsigned char[size]; + DbgMemRead(addr, data, size); + + EntropyDialog entropyDialog(this); + entropyDialog.setWindowTitle(QString().sprintf("Entropy (Address: %p, Size: %p)", addr, size)); + entropyDialog.show(); + entropyDialog.GraphMemory(data, size); + entropyDialog.exec(); + + delete[] data; +} + +void MemoryMapView::findPatternSlot() +{ + HexEditDialog hexEdit(this); + hexEdit.showEntireBlock(true); + hexEdit.mHexEdit->setOverwriteMode(false); + hexEdit.setWindowTitle("Find Pattern..."); + if(hexEdit.exec() != QDialog::Accepted) + return; + duint addr = getCellContent(getInitialSelection(), 0).toULongLong(0, 16); + if(hexEdit.entireBlock()) + addr = 0; + QString addrText = QString("%1").arg(addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + DbgCmdExec(QString("findmemall " + addrText + ", \"" + hexEdit.mHexEdit->pattern() + "\", &data&").toUtf8().constData()); + emit showReferences(); +} diff --git a/src/gui/Src/Gui/MemoryMapView.h b/src/gui/Src/Gui/MemoryMapView.h index df0b3a73..ed226629 100644 --- a/src/gui/Src/Gui/MemoryMapView.h +++ b/src/gui/Src/Gui/MemoryMapView.h @@ -1,64 +1,64 @@ -#ifndef MEMORYMAPVIEW_H -#define MEMORYMAPVIEW_H - -#include "StdTable.h" - -class MemoryMapView : public StdTable -{ - Q_OBJECT -public: - explicit MemoryMapView(StdTable* parent = 0); - QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); - void setupContextMenu(); - -signals: - void showCpu(); - void showReferences(); - -public slots: - void refreshShortcutsSlot(); - void stateChangedSlot(DBGSTATE state); - void followDumpSlot(); - void followDisassemblerSlot(); - void yaraSlot(); - void memoryAccessSingleshootSlot(); - void memoryAccessRestoreSlot(); - void memoryWriteSingleshootSlot(); - void memoryWriteRestoreSlot(); - void memoryExecuteSingleshootSlot(); - void memoryExecuteRestoreSlot(); - void memoryRemoveSlot(); - void memoryExecuteSingleshootToggleSlot(); - void contextMenuSlot(const QPoint & pos); - void switchView(); - void pageMemoryRights(); - void refreshMap(); - void entropy(); - void findPatternSlot(); - -private: - QString getProtectionString(DWORD Protect); - - QAction* mFollowDump; - QAction* mFollowDisassembly; - QAction* mYara; - QAction* mSwitchView; - QAction* mPageMemoryRights; - - QMenu* mBreakpointMenu; - QMenu* mMemoryAccessMenu; - QAction* mMemoryAccessSingleshoot; - QAction* mMemoryAccessRestore; - QMenu* mMemoryWriteMenu; - QAction* mMemoryWriteSingleshoot; - QAction* mMemoryWriteRestore; - QMenu* mMemoryExecuteMenu; - QAction* mMemoryExecuteSingleshoot; - QAction* mMemoryExecuteRestore; - QAction* mMemoryRemove; - QAction* mMemoryExecuteSingleshootToggle; - QAction* mEntropy; - QAction* mFindPattern; -}; - -#endif // MEMORYMAPVIEW_H +#ifndef MEMORYMAPVIEW_H +#define MEMORYMAPVIEW_H + +#include "StdTable.h" + +class MemoryMapView : public StdTable +{ + Q_OBJECT +public: + explicit MemoryMapView(StdTable* parent = 0); + QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); + void setupContextMenu(); + +signals: + void showCpu(); + void showReferences(); + +public slots: + void refreshShortcutsSlot(); + void stateChangedSlot(DBGSTATE state); + void followDumpSlot(); + void followDisassemblerSlot(); + void yaraSlot(); + void memoryAccessSingleshootSlot(); + void memoryAccessRestoreSlot(); + void memoryWriteSingleshootSlot(); + void memoryWriteRestoreSlot(); + void memoryExecuteSingleshootSlot(); + void memoryExecuteRestoreSlot(); + void memoryRemoveSlot(); + void memoryExecuteSingleshootToggleSlot(); + void contextMenuSlot(const QPoint & pos); + void switchView(); + void pageMemoryRights(); + void refreshMap(); + void entropy(); + void findPatternSlot(); + +private: + QString getProtectionString(DWORD Protect); + + QAction* mFollowDump; + QAction* mFollowDisassembly; + QAction* mYara; + QAction* mSwitchView; + QAction* mPageMemoryRights; + + QMenu* mBreakpointMenu; + QMenu* mMemoryAccessMenu; + QAction* mMemoryAccessSingleshoot; + QAction* mMemoryAccessRestore; + QMenu* mMemoryWriteMenu; + QAction* mMemoryWriteSingleshoot; + QAction* mMemoryWriteRestore; + QMenu* mMemoryExecuteMenu; + QAction* mMemoryExecuteSingleshoot; + QAction* mMemoryExecuteRestore; + QAction* mMemoryRemove; + QAction* mMemoryExecuteSingleshootToggle; + QAction* mEntropy; + QAction* mFindPattern; +}; + +#endif // MEMORYMAPVIEW_H diff --git a/src/gui/Src/Gui/NotepadView.cpp b/src/gui/Src/Gui/NotepadView.cpp index 08c3412d..a0f43421 100644 --- a/src/gui/Src/Gui/NotepadView.cpp +++ b/src/gui/Src/Gui/NotepadView.cpp @@ -1,35 +1,35 @@ -#include "NotepadView.h" -#include "Configuration.h" -#include "Bridge.h" -#include - -NotepadView::NotepadView(QWidget* parent) : QPlainTextEdit(parent) -{ - updateStyle(); - connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(updateStyle())); - connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(updateStyle())); -} - -void NotepadView::updateStyle() -{ - setFont(ConfigFont("Log")); - setStyleSheet(QString("QPlainTextEdit { color: %1; background-color: %2 }").arg(ConfigColor("AbstractTableViewTextColor").name(), ConfigColor("AbstractTableViewBackgroundColor").name())); -} - -void NotepadView::setNotes(const QString text) -{ - setPlainText(text); -} - -void NotepadView::getNotes(void* ptr) -{ - QByteArray text = toPlainText().replace('\n', "\r\n").toUtf8(); - char* result = 0; - if(text.length()) - { - result = (char*)BridgeAlloc(text.length() + 1); - strcpy_s(result, text.length() + 1, text.constData()); - } - *(char**)ptr = result; - Bridge::getBridge()->setResult(); -} +#include "NotepadView.h" +#include "Configuration.h" +#include "Bridge.h" +#include + +NotepadView::NotepadView(QWidget* parent) : QPlainTextEdit(parent) +{ + updateStyle(); + connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(updateStyle())); + connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(updateStyle())); +} + +void NotepadView::updateStyle() +{ + setFont(ConfigFont("Log")); + setStyleSheet(QString("QPlainTextEdit { color: %1; background-color: %2 }").arg(ConfigColor("AbstractTableViewTextColor").name(), ConfigColor("AbstractTableViewBackgroundColor").name())); +} + +void NotepadView::setNotes(const QString text) +{ + setPlainText(text); +} + +void NotepadView::getNotes(void* ptr) +{ + QByteArray text = toPlainText().replace('\n', "\r\n").toUtf8(); + char* result = 0; + if(text.length()) + { + result = (char*)BridgeAlloc(text.length() + 1); + strcpy_s(result, text.length() + 1, text.constData()); + } + *(char**)ptr = result; + Bridge::getBridge()->setResult(); +} diff --git a/src/gui/Src/Gui/NotepadView.h b/src/gui/Src/Gui/NotepadView.h index d084d3a3..9e10223c 100644 --- a/src/gui/Src/Gui/NotepadView.h +++ b/src/gui/Src/Gui/NotepadView.h @@ -1,19 +1,19 @@ -#ifndef NOTEPADVIEW_H -#define NOTEPADVIEW_H - -#include - -class NotepadView : public QPlainTextEdit -{ - Q_OBJECT -public: - explicit NotepadView(QWidget* parent = 0); - -public slots: - void updateStyle(); - void setNotes(const QString text); - void getNotes(void* ptr); - -}; - -#endif // NOTEPADVIEW_H +#ifndef NOTEPADVIEW_H +#define NOTEPADVIEW_H + +#include + +class NotepadView : public QPlainTextEdit +{ + Q_OBJECT +public: + explicit NotepadView(QWidget* parent = 0); + +public slots: + void updateStyle(); + void setNotes(const QString text); + void getNotes(void* ptr); + +}; + +#endif // NOTEPADVIEW_H diff --git a/src/gui/Src/Gui/NotesManager.cpp b/src/gui/Src/Gui/NotesManager.cpp index d35aa7f8..d4ae06dd 100644 --- a/src/gui/Src/Gui/NotesManager.cpp +++ b/src/gui/Src/Gui/NotesManager.cpp @@ -1,15 +1,15 @@ -#include "NotesManager.h" -#include "Bridge.h" - -NotesManager::NotesManager(QWidget* parent) : QTabWidget(parent) -{ - mGlobal = new NotepadView(this); - connect(Bridge::getBridge(), SIGNAL(setGlobalNotes(QString)), mGlobal, SLOT(setNotes(QString))); - connect(Bridge::getBridge(), SIGNAL(getGlobalNotes(void*)), mGlobal, SLOT(getNotes(void*))); - addTab(mGlobal, "Global"); - - mDebuggee = new NotepadView(this); - connect(Bridge::getBridge(), SIGNAL(setDebuggeeNotes(QString)), mDebuggee, SLOT(setNotes(QString))); - connect(Bridge::getBridge(), SIGNAL(getDebuggeeNotes(void*)), mDebuggee, SLOT(getNotes(void*))); - addTab(mDebuggee, "Debuggee"); -} +#include "NotesManager.h" +#include "Bridge.h" + +NotesManager::NotesManager(QWidget* parent) : QTabWidget(parent) +{ + mGlobal = new NotepadView(this); + connect(Bridge::getBridge(), SIGNAL(setGlobalNotes(QString)), mGlobal, SLOT(setNotes(QString))); + connect(Bridge::getBridge(), SIGNAL(getGlobalNotes(void*)), mGlobal, SLOT(getNotes(void*))); + addTab(mGlobal, "Global"); + + mDebuggee = new NotepadView(this); + connect(Bridge::getBridge(), SIGNAL(setDebuggeeNotes(QString)), mDebuggee, SLOT(setNotes(QString))); + connect(Bridge::getBridge(), SIGNAL(getDebuggeeNotes(void*)), mDebuggee, SLOT(getNotes(void*))); + addTab(mDebuggee, "Debuggee"); +} diff --git a/src/gui/Src/Gui/NotesManager.h b/src/gui/Src/Gui/NotesManager.h index e0f4083e..078ae4a8 100644 --- a/src/gui/Src/Gui/NotesManager.h +++ b/src/gui/Src/Gui/NotesManager.h @@ -1,19 +1,19 @@ -#ifndef NOTESMANAGER_H -#define NOTESMANAGER_H - -#include -#include -#include "NotepadView.h" - -class NotesManager : public QTabWidget -{ - Q_OBJECT -public: - explicit NotesManager(QWidget* parent = 0); - -private: - NotepadView* mGlobal; - NotepadView* mDebuggee; -}; - -#endif // NOTESMANAGER_H +#ifndef NOTESMANAGER_H +#define NOTESMANAGER_H + +#include +#include +#include "NotepadView.h" + +class NotesManager : public QTabWidget +{ + Q_OBJECT +public: + explicit NotesManager(QWidget* parent = 0); + +private: + NotepadView* mGlobal; + NotepadView* mDebuggee; +}; + +#endif // NOTESMANAGER_H diff --git a/src/gui/Src/Gui/PageMemoryRights.cpp b/src/gui/Src/Gui/PageMemoryRights.cpp index 8c50cf6b..7ce4ed06 100644 --- a/src/gui/Src/Gui/PageMemoryRights.cpp +++ b/src/gui/Src/Gui/PageMemoryRights.cpp @@ -1,130 +1,130 @@ -#include "Imports.h" -#include "PageMemoryRights.h" -#include "ui_PageMemoryRights.h" - -PageMemoryRights::PageMemoryRights(QWidget* parent) : QDialog(parent), ui(new Ui::PageMemoryRights) -{ - ui->setupUi(this); - //set window flags -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); -#endif - setModal(true); - addr = 0; - size = 0; -} - -PageMemoryRights::~PageMemoryRights() -{ - delete ui; -} - -void PageMemoryRights::RunAddrSize(duint addrin, duint sizein, QString pagetypein) -{ - addr = addrin; - size = sizein; - pagetype = pagetypein; - - QTableWidget* tableWidget = ui->pagetableWidget; - tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - duint nr_pages = size / PAGE_SIZE; - tableWidget->setColumnCount(2); - tableWidget->setRowCount(nr_pages); - tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(QString("Address"))); - tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(QString("Rights"))); - - duint actual_addr; - char rights[RIGHTS_STRING_SIZE]; - for(duint i = 0; i < nr_pages; i++) - { - actual_addr = addr + (i * PAGE_SIZE); - tableWidget->setItem(i, 0, new QTableWidgetItem(QString("%1").arg(actual_addr, sizeof(duint) * 2, 16, QChar('0')).toUpper())); - if(DbgFunctions()->GetPageRights(actual_addr, rights)) - tableWidget->setItem(i, 1, new QTableWidgetItem(QString(rights))); - } - - QModelIndex idx = (ui->pagetableWidget->model()->index(0, 0)); - ui->pagetableWidget->selectionModel()->select(idx, QItemSelectionModel::Select); - idx = (ui->pagetableWidget->model()->index(0, 1)); - ui->pagetableWidget->selectionModel()->select(idx, QItemSelectionModel::Select); - - ui->radioFullaccess->setChecked(true); - ui->chkPageguard->setCheckable(true); - exec(); -} - -void PageMemoryRights::on_btnSelectall_clicked() -{ - for(int i = 0; i < ui->pagetableWidget->rowCount(); i++) - { - for(int j = 0; j < ui->pagetableWidget->columnCount(); j++) - { - QModelIndex idx = (ui->pagetableWidget->model()->index(i, j)); - ui->pagetableWidget->selectionModel()->select(idx, QItemSelectionModel::Select); - } - } -} - -void PageMemoryRights::on_btnDeselectall_clicked() -{ - QModelIndexList indexList = ui->pagetableWidget->selectionModel()->selectedIndexes(); - foreach(QModelIndex index, indexList) - { - ui->pagetableWidget->selectionModel()->select(index, QItemSelectionModel::Deselect); - - } -} - -void PageMemoryRights::on_btnSetrights_clicked() -{ - duint actual_addr; - QString rights; - char newrights[RIGHTS_STRING_SIZE]; - bool one_right_changed = false; - - if(ui->radioExecute->isChecked()) - rights = "Execute"; - else if(ui->radioExecuteread->isChecked()) - rights = "ExecuteRead"; - else if(ui->radioNoaccess->isChecked()) - rights = "NoAccess"; - else if(ui->radioFullaccess ->isChecked()) - rights = "ExecuteReadWrite"; - else if(ui->radioReadonly->isChecked()) - rights = "ReadOnly"; - else if(ui->radioReadwrite->isChecked()) - rights = "ReadWrite"; - else if(ui->radioWritecopy->isChecked()) - rights = "WriteCopy"; - else if(ui->radioExecutewritecopy->isChecked()) - rights = "ExecuteWriteCopy"; - else - return; - - if(ui->chkPageguard->isChecked()) - rights = "G" + rights; - - QModelIndexList indexList = ui->pagetableWidget->selectionModel()->selectedIndexes(); - foreach(QModelIndex index, indexList) - { -#ifdef _WIN64 - actual_addr = ui->pagetableWidget->item(index.row(), 0)->text().toULongLong(0, 16); -#else //x86 - actual_addr = ui->pagetableWidget->item(index.row(), 0)->text().toULong(0, 16); -#endif //_WIN64 - if(DbgFunctions()->SetPageRights(actual_addr, (char*)rights.toUtf8().constData())) - { - one_right_changed = true; - if(DbgFunctions()->GetPageRights(actual_addr, newrights)) - ui->pagetableWidget->setItem(index.row(), 1, new QTableWidgetItem(QString(newrights))); - } - } - - DbgFunctions()->MemUpdateMap(); - emit refreshMemoryMap(); - - if(one_right_changed) - ui->LnEdStatus->setText("Pages Rights Changed to: " + rights); - else - ui->LnEdStatus->setText("Error setting rights, read the MSDN to learn the valid rights of: " + pagetype); -} +#include "Imports.h" +#include "PageMemoryRights.h" +#include "ui_PageMemoryRights.h" + +PageMemoryRights::PageMemoryRights(QWidget* parent) : QDialog(parent), ui(new Ui::PageMemoryRights) +{ + ui->setupUi(this); + //set window flags +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); +#endif + setModal(true); + addr = 0; + size = 0; +} + +PageMemoryRights::~PageMemoryRights() +{ + delete ui; +} + +void PageMemoryRights::RunAddrSize(duint addrin, duint sizein, QString pagetypein) +{ + addr = addrin; + size = sizein; + pagetype = pagetypein; + + QTableWidget* tableWidget = ui->pagetableWidget; + tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + duint nr_pages = size / PAGE_SIZE; + tableWidget->setColumnCount(2); + tableWidget->setRowCount(nr_pages); + tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(QString("Address"))); + tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(QString("Rights"))); + + duint actual_addr; + char rights[RIGHTS_STRING_SIZE]; + for(duint i = 0; i < nr_pages; i++) + { + actual_addr = addr + (i * PAGE_SIZE); + tableWidget->setItem(i, 0, new QTableWidgetItem(QString("%1").arg(actual_addr, sizeof(duint) * 2, 16, QChar('0')).toUpper())); + if(DbgFunctions()->GetPageRights(actual_addr, rights)) + tableWidget->setItem(i, 1, new QTableWidgetItem(QString(rights))); + } + + QModelIndex idx = (ui->pagetableWidget->model()->index(0, 0)); + ui->pagetableWidget->selectionModel()->select(idx, QItemSelectionModel::Select); + idx = (ui->pagetableWidget->model()->index(0, 1)); + ui->pagetableWidget->selectionModel()->select(idx, QItemSelectionModel::Select); + + ui->radioFullaccess->setChecked(true); + ui->chkPageguard->setCheckable(true); + exec(); +} + +void PageMemoryRights::on_btnSelectall_clicked() +{ + for(int i = 0; i < ui->pagetableWidget->rowCount(); i++) + { + for(int j = 0; j < ui->pagetableWidget->columnCount(); j++) + { + QModelIndex idx = (ui->pagetableWidget->model()->index(i, j)); + ui->pagetableWidget->selectionModel()->select(idx, QItemSelectionModel::Select); + } + } +} + +void PageMemoryRights::on_btnDeselectall_clicked() +{ + QModelIndexList indexList = ui->pagetableWidget->selectionModel()->selectedIndexes(); + foreach(QModelIndex index, indexList) + { + ui->pagetableWidget->selectionModel()->select(index, QItemSelectionModel::Deselect); + + } +} + +void PageMemoryRights::on_btnSetrights_clicked() +{ + duint actual_addr; + QString rights; + char newrights[RIGHTS_STRING_SIZE]; + bool one_right_changed = false; + + if(ui->radioExecute->isChecked()) + rights = "Execute"; + else if(ui->radioExecuteread->isChecked()) + rights = "ExecuteRead"; + else if(ui->radioNoaccess->isChecked()) + rights = "NoAccess"; + else if(ui->radioFullaccess ->isChecked()) + rights = "ExecuteReadWrite"; + else if(ui->radioReadonly->isChecked()) + rights = "ReadOnly"; + else if(ui->radioReadwrite->isChecked()) + rights = "ReadWrite"; + else if(ui->radioWritecopy->isChecked()) + rights = "WriteCopy"; + else if(ui->radioExecutewritecopy->isChecked()) + rights = "ExecuteWriteCopy"; + else + return; + + if(ui->chkPageguard->isChecked()) + rights = "G" + rights; + + QModelIndexList indexList = ui->pagetableWidget->selectionModel()->selectedIndexes(); + foreach(QModelIndex index, indexList) + { +#ifdef _WIN64 + actual_addr = ui->pagetableWidget->item(index.row(), 0)->text().toULongLong(0, 16); +#else //x86 + actual_addr = ui->pagetableWidget->item(index.row(), 0)->text().toULong(0, 16); +#endif //_WIN64 + if(DbgFunctions()->SetPageRights(actual_addr, (char*)rights.toUtf8().constData())) + { + one_right_changed = true; + if(DbgFunctions()->GetPageRights(actual_addr, newrights)) + ui->pagetableWidget->setItem(index.row(), 1, new QTableWidgetItem(QString(newrights))); + } + } + + DbgFunctions()->MemUpdateMap(); + emit refreshMemoryMap(); + + if(one_right_changed) + ui->LnEdStatus->setText("Pages Rights Changed to: " + rights); + else + ui->LnEdStatus->setText("Error setting rights, read the MSDN to learn the valid rights of: " + pagetype); +} diff --git a/src/gui/Src/Gui/PageMemoryRights.h b/src/gui/Src/Gui/PageMemoryRights.h index cfdf5f52..90d07a34 100644 --- a/src/gui/Src/Gui/PageMemoryRights.h +++ b/src/gui/Src/Gui/PageMemoryRights.h @@ -1,36 +1,36 @@ -#ifndef PAGEMEMORYRIGHTS_H -#define PAGEMEMORYRIGHTS_H - -#include -#include "dbg_types.h" - -namespace Ui -{ -class PageMemoryRights; -} - -class PageMemoryRights : public QDialog -{ - Q_OBJECT - -public: - explicit PageMemoryRights(QWidget* parent = 0); - void RunAddrSize(duint, duint, QString); - ~PageMemoryRights(); - -private slots: - void on_btnSelectall_clicked(); - void on_btnDeselectall_clicked(); - void on_btnSetrights_clicked(); - -signals: - void refreshMemoryMap(); - -private: - Ui::PageMemoryRights* ui; - duint addr; - duint size; - QString pagetype; -}; - -#endif // PAGEMEMORYRIGHTS_H +#ifndef PAGEMEMORYRIGHTS_H +#define PAGEMEMORYRIGHTS_H + +#include +#include "dbg_types.h" + +namespace Ui +{ +class PageMemoryRights; +} + +class PageMemoryRights : public QDialog +{ + Q_OBJECT + +public: + explicit PageMemoryRights(QWidget* parent = 0); + void RunAddrSize(duint, duint, QString); + ~PageMemoryRights(); + +private slots: + void on_btnSelectall_clicked(); + void on_btnDeselectall_clicked(); + void on_btnSetrights_clicked(); + +signals: + void refreshMemoryMap(); + +private: + Ui::PageMemoryRights* ui; + duint addr; + duint size; + QString pagetype; +}; + +#endif // PAGEMEMORYRIGHTS_H diff --git a/src/gui/Src/Gui/PatchDialog.cpp b/src/gui/Src/Gui/PatchDialog.cpp index 09a7079b..bad168e9 100644 --- a/src/gui/Src/Gui/PatchDialog.cpp +++ b/src/gui/Src/Gui/PatchDialog.cpp @@ -1,689 +1,689 @@ -#include "PatchDialog.h" -#include "ui_PatchDialog.h" -#include -#include -#include -#include - -PatchDialog::PatchDialog(QWidget* parent) : - QDialog(parent), - ui(new Ui::PatchDialog) -{ - ui->setupUi(this); -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); -#endif - setFixedSize(this->size()); //fixed size - setModal(false); //non-modal window - - connect(Bridge::getBridge(), SIGNAL(updatePatches()), this, SLOT(updatePatches())); - connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChanged(DBGSTATE))); - - mGroupSelector = new PatchDialogGroupSelector(parent); - mGroupSelector->setGroup(0); - connect(mGroupSelector, SIGNAL(rejected()), this, SLOT(showNormal())); - connect(mGroupSelector, SIGNAL(rejected()), this, SLOT(setFocus())); - connect(mGroupSelector, SIGNAL(groupToggle()), this, SLOT(groupToggle())); - connect(mGroupSelector, SIGNAL(groupPrevious()), this, SLOT(groupPrevious())); - connect(mGroupSelector, SIGNAL(groupNext()), this, SLOT(groupNext())); - - mPatches = new PatchMap(); - mIsWorking = false; -} - -PatchDialog::~PatchDialog() -{ - delete ui; -} - -bool PatchDialog::isPartOfPreviousGroup(const PatchInfoList & patchList, int index) -{ - if(!index) - return true; - uint addr = patchList.at(index).first.addr; - uint prevAddr = patchList.at(index - 1).first.addr; - for(int i = 1; i < 10; i++) //10 bytes in between groups - if(addr - i == prevAddr) - return true; - return false; -} - -bool PatchDialog::isGroupEnabled(const PatchInfoList & patchList, int group) -{ - for(int i = 0; i < patchList.size(); i++) - if(patchList.at(i).second.group == group && !patchList.at(i).second.checked) - return false; - return true; -} - -bool PatchDialog::hasPreviousGroup(const PatchInfoList & patchList, int group) -{ - for(int i = 0; i < patchList.size(); i++) - if(patchList.at(i).second.group < group) - return true; - return false; -} - -bool PatchDialog::hasNextGroup(const PatchInfoList & patchList, int group) -{ - for(int i = 0; i < patchList.size(); i++) - if(patchList.at(i).second.group > group) - return true; - return false; -} - -dsint PatchDialog::getGroupAddress(const PatchInfoList & patchList, int group) -{ - for(int i = 0; i < patchList.size(); i++) - if(patchList.at(i).second.group == group) - return patchList.at(i).first.addr; - return -1; -} - -void PatchDialog::dbgStateChanged(DBGSTATE state) -{ - if(state == stopped) - { - mGroupSelector->hide(); - reject(); - } -} - -void PatchDialog::updatePatches() -{ - if(this->isVisible()) - mGroupSelector->reject(); - mIsWorking = true; - //clear GUI - ui->listModules->clear(); - ui->listPatches->clear(); - delete mPatches; - mPatches = new PatchMap(); - - //get patches from DBG - size_t cbsize; - if(!DbgFunctions()->PatchEnum(0, &cbsize)) - return; - int numPatches = (int)cbsize / sizeof(DBGPATCHINFO); - if(!numPatches) - return; - DBGPATCHINFO* patches = new DBGPATCHINFO[numPatches]; - memset(patches, 0, numPatches * sizeof(DBGPATCHINFO)); - if(!DbgFunctions()->PatchEnum(patches, 0)) - { - delete [] patches; - mIsWorking = false; - return; - } - - //fill the patch list - STATUSINFO defaultStatus; - defaultStatus.group = 0; - defaultStatus.checked = true; - for(int i = 0; i < numPatches; i++) - { - if(!patches[i].addr) - continue; - if(!*patches[i].mod) - continue; - QString mod = patches[i].mod; - PatchMap::iterator found = mPatches->find(mod); - if(found != mPatches->end()) //found - (*mPatches)[mod].append(PatchPair(patches[i], defaultStatus)); - else //not found - { - PatchInfoList patchList; - patchList.append(PatchPair(patches[i], defaultStatus)); - mPatches->insert(mod, patchList); - } - } - delete [] patches; - - //sort the patches by address - for(PatchMap::iterator i = mPatches->begin(); i != mPatches->end(); ++i) - { - qSort(i.value().begin(), i.value().end(), PatchInfoLess); - PatchInfoList & curPatchList = i.value(); - //group the patched bytes - for(int j = 0, group = 0; j < curPatchList.size(); j++) - { - if(!isPartOfPreviousGroup(curPatchList, j)) - group++; - curPatchList[j].second.group = group; - } - ui->listModules->addItem(i.key()); - } - - if(mPatches->size()) - ui->listModules->item(0)->setSelected(true); //select first module - - mIsWorking = false; -} - -void PatchDialog::groupToggle() -{ - int group = mGroupSelector->group(); - if(mIsWorking || !ui->listModules->selectedItems().size()) - return; - QString mod = ui->listModules->selectedItems().at(0)->text(); - PatchMap::iterator found = mPatches->find(mod); - if(found == mPatches->end()) //not found - return; - PatchInfoList & curPatchList = found.value(); - bool enabled = !isGroupEnabled(curPatchList, group); - Qt::CheckState checkState = enabled ? Qt::Checked : Qt::Unchecked; - mIsWorking = true; - for(int i = 0; i < curPatchList.size(); i++) - { - if(curPatchList.at(i).second.group != group) - continue; - ui->listPatches->item(i)->setCheckState(checkState); - curPatchList[i].second.checked = enabled; - //change the byte to reflect the change for the user (cypherpunk reported this) - unsigned char writebyte = curPatchList[i].second.checked ? curPatchList[i].first.newbyte : curPatchList[i].first.oldbyte; - DbgMemWrite(curPatchList[i].first.addr, &writebyte, sizeof(writebyte)); - } - GuiUpdateAllViews(); - mIsWorking = false; - dsint groupStart = getGroupAddress(curPatchList, group); - if(!groupStart) - return; - QString color = enabled ? "#00DD00" : "red"; - QString addrText = QString("%1").arg(groupStart, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - QString title = "" + QString().sprintf("%d:", group) + addrText + ""; - mGroupSelector->setGroupTitle(title); - DbgCmdExecDirect(QString("disasm " + addrText).toUtf8().constData()); - DbgCmdExecDirect(QString("dump " + addrText).toUtf8().constData()); -} - -void PatchDialog::groupPrevious() -{ - int group = mGroupSelector->group(); - if(!ui->listModules->selectedItems().size()) - return; - QString mod = ui->listModules->selectedItems().at(0)->text(); - PatchMap::iterator found = mPatches->find(mod); - if(found == mPatches->end()) //not found - return; - PatchInfoList & curPatchList = found.value(); - if(!hasPreviousGroup(curPatchList, group)) - return; - group--; - QString color = isGroupEnabled(curPatchList, group) ? "#00DD00" : "red"; - QString addrText = QString("%1").arg(getGroupAddress(curPatchList, group), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - QString title = "" + QString().sprintf("%d:", group) + addrText + ""; - mGroupSelector->setGroupTitle(title); - mGroupSelector->setGroup(group); - mGroupSelector->setPreviousEnabled(hasPreviousGroup(curPatchList, group)); - mGroupSelector->setNextEnabled(hasNextGroup(curPatchList, group)); - mGroupSelector->showNormal(); - DbgCmdExecDirect(QString("disasm " + addrText).toUtf8().constData()); - DbgCmdExecDirect(QString("dump " + addrText).toUtf8().constData()); -} - -void PatchDialog::groupNext() -{ - int group = mGroupSelector->group(); - if(!ui->listModules->selectedItems().size()) - return; - QString mod = ui->listModules->selectedItems().at(0)->text(); - PatchMap::iterator found = mPatches->find(mod); - if(found == mPatches->end()) //not found - return; - PatchInfoList & curPatchList = found.value(); - if(!hasNextGroup(curPatchList, group)) - return; - group++; - QString color = isGroupEnabled(curPatchList, group) ? "#00DD00" : "red"; - QString addrText = QString("%1").arg(getGroupAddress(curPatchList, group), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - QString title = "" + QString().sprintf("%d:", group) + addrText + ""; - mGroupSelector->setGroupTitle(title); - mGroupSelector->setGroup(group); - mGroupSelector->setPreviousEnabled(hasPreviousGroup(curPatchList, group)); - mGroupSelector->setNextEnabled(hasNextGroup(curPatchList, group)); - mGroupSelector->showNormal(); - DbgCmdExecDirect(QString("disasm " + addrText).toUtf8().constData()); - DbgCmdExecDirect(QString("dump " + addrText).toUtf8().constData()); -} - -void PatchDialog::on_listModules_itemSelectionChanged() -{ - if(!ui->listModules->selectedItems().size()) - return; - QString mod(ui->listModules->selectedItems().at(0)->text()); - PatchMap::iterator found = mPatches->find(mod); - if(found == mPatches->end()) //not found - return; - mIsWorking = true; - PatchInfoList & patchList = found.value(); - ui->listPatches->clear(); - for(int i = 0; i < patchList.size(); i++) - { - const DBGPATCHINFO curPatch = patchList.at(i).first; - QString addrText = QString("%1").arg(curPatch.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - QListWidgetItem* item = new QListWidgetItem(QString().sprintf("%d", patchList.at(i).second.group).rightJustified(4, ' ', true) + "|" + addrText + QString().sprintf(":%.2X->%.2X", curPatch.oldbyte, curPatch.newbyte), ui->listPatches); - item->setFlags(item->flags() | Qt::ItemIsUserCheckable); - Qt::CheckState state = patchList.at(i).second.checked ? Qt::Checked : Qt::Unchecked; - item->setCheckState(state); - } - mIsWorking = false; -} - -void PatchDialog::on_listPatches_itemChanged(QListWidgetItem* item) //checkbox changed -{ - if(mIsWorking || !ui->listModules->selectedItems().size()) - return; - QString mod = ui->listModules->selectedItems().at(0)->text(); - PatchMap::iterator found = mPatches->find(mod); - if(found == mPatches->end()) //not found - return; - bool checked = item->checkState() == Qt::Checked; - PatchInfoList & curPatchList = found.value(); - PatchPair & patch = curPatchList[ui->listPatches->row(item)]; - if(patch.second.checked == checked) //check state did not change - return; - patch.second.checked = checked; - //change the byte to reflect the change for the user (cypherpunk reported this) - unsigned char writebyte = patch.second.checked ? patch.first.newbyte : patch.first.oldbyte; - DbgMemWrite(patch.first.addr, &writebyte, sizeof(writebyte)); - //check state changed - if((QApplication::keyboardModifiers() & Qt::ControlModifier) != Qt::ControlModifier) - { - mIsWorking = true; - //check/uncheck the complete group - for(int i = 0; i < curPatchList.size(); i++) - if(curPatchList.at(i).second.group == patch.second.group) - { - //change the patch state - curPatchList[i].second.checked = checked; - ui->listPatches->item(i)->setCheckState(item->checkState()); - //change the byte to reflect the change for the user (cypherpunk reported this) - unsigned char writebyte = curPatchList[i].second.checked ? curPatchList[i].first.newbyte : curPatchList[i].first.oldbyte; - DbgMemWrite(curPatchList[i].first.addr, &writebyte, sizeof(writebyte)); - } - mIsWorking = false; - } - GuiUpdateAllViews(); - int group = mGroupSelector->group(); - QString color = isGroupEnabled(curPatchList, group) ? "#00DD00" : "red"; - QString addrText = QString("%1").arg(getGroupAddress(curPatchList, group), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - QString title = "" + QString().sprintf("%d:", group) + addrText + ""; - mGroupSelector->setGroupTitle(title); - mGroupSelector->setPreviousEnabled(hasPreviousGroup(curPatchList, group)); - mGroupSelector->setNextEnabled(hasNextGroup(curPatchList, group)); -} - -void PatchDialog::on_btnSelectAll_clicked() -{ - if(!ui->listModules->selectedItems().size()) - return; - QString mod = ui->listModules->selectedItems().at(0)->text(); - PatchMap::iterator found = mPatches->find(mod); - if(found == mPatches->end()) //not found - return; - mIsWorking = true; - PatchInfoList & curPatchList = found.value(); - for(int i = 0; i < curPatchList.size(); i++) - { - ui->listPatches->item(i)->setCheckState(Qt::Checked); - curPatchList[i].second.checked = true; - //change the byte to reflect the change for the user (cypherpunk reported this) - DbgMemWrite(curPatchList[i].first.addr, &curPatchList[i].first.newbyte, sizeof(unsigned char)); - } - GuiUpdateAllViews(); - mIsWorking = false; -} - -void PatchDialog::on_btnDeselectAll_clicked() -{ - if(!ui->listModules->selectedItems().size()) - return; - QString mod = ui->listModules->selectedItems().at(0)->text(); - PatchMap::iterator found = mPatches->find(mod); - if(found == mPatches->end()) //not found - return; - mIsWorking = true; - PatchInfoList & curPatchList = found.value(); - for(int i = 0; i < curPatchList.size(); i++) - { - ui->listPatches->item(i)->setCheckState(Qt::Unchecked); - curPatchList[i].second.checked = false; - //change the byte to reflect the change for the user (cypherpunk reported this) - DbgMemWrite(curPatchList[i].first.addr, &curPatchList[i].first.oldbyte, sizeof(unsigned char)); - } - GuiUpdateAllViews(); - mIsWorking = false; -} - -void PatchDialog::on_btnRestoreSelected_clicked() -{ - if(!ui->listModules->selectedItems().size()) - return; - int selModIdx = ui->listModules->row(ui->listModules->selectedItems().at(0)); - QString mod = ui->listModules->selectedItems().at(0)->text(); - PatchMap::iterator found = mPatches->find(mod); - if(found == mPatches->end()) //not found - return; - mIsWorking = true; - PatchInfoList & curPatchList = found.value(); - int removed = 0; - int total = curPatchList.size(); - for(int i = 0; i < total; i++) - { - if(curPatchList.at(i).second.checked) - { - DbgFunctions()->PatchRestore(curPatchList.at(i).first.addr); - removed++; - } - } - mIsWorking = false; - updatePatches(); - if(removed != total) - ui->listModules->setCurrentRow(selModIdx); - GuiUpdateAllViews(); -} - -void PatchDialog::on_listPatches_itemSelectionChanged() -{ - if(!ui->listModules->selectedItems().size() || !ui->listPatches->selectedItems().size()) - return; - QString mod = ui->listModules->selectedItems().at(0)->text(); - PatchMap::iterator found = mPatches->find(mod); - if(found == mPatches->end()) //not found - return; - PatchInfoList & curPatchList = found.value(); - PatchPair & patch = curPatchList[ui->listPatches->row(ui->listPatches->selectedItems().at(0))]; //selected item - dsint groupStart = getGroupAddress(curPatchList, patch.second.group); - if(!groupStart) - return; - QString addrText = QString("%1").arg(groupStart, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - DbgCmdExecDirect(QString("disasm " + addrText).toUtf8().constData()); - DbgCmdExecDirect(QString("dump " + addrText).toUtf8().constData()); -} - -void PatchDialog::on_btnPickGroups_clicked() -{ - if(!ui->listModules->selectedItems().size()) - return; - QString mod = ui->listModules->selectedItems().at(0)->text(); - PatchMap::iterator found = mPatches->find(mod); - if(found == mPatches->end()) //not found - return; - PatchInfoList & curPatchList = found.value(); - if(!curPatchList.size()) - return; - this->showMinimized(); - - int group = mGroupSelector->group(); - QString color = isGroupEnabled(curPatchList, group) ? "#00DD00" : "red"; - QString addrText = QString("%1").arg(getGroupAddress(curPatchList, group), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - QString title = "" + QString().sprintf("%d:", group) + addrText + ""; - mGroupSelector->setGroupTitle(title); - mGroupSelector->setPreviousEnabled(hasPreviousGroup(curPatchList, group)); - mGroupSelector->setNextEnabled(hasNextGroup(curPatchList, group)); - mGroupSelector->show(); - DbgCmdExecDirect(QString("disasm " + addrText).toUtf8().constData()); - DbgCmdExecDirect(QString("dump " + addrText).toUtf8().constData()); -} - -void PatchDialog::on_btnPatchFile_clicked() -{ - //get current module - if(!ui->listModules->selectedItems().size()) - return; - QString mod = ui->listModules->selectedItems().at(0)->text(); - PatchMap::iterator found = mPatches->find(mod); - if(found == mPatches->end()) //not found - return; - PatchInfoList & curPatchList = found.value(); - - //get patches to save - QList patchList; - for(int i = 0; i < curPatchList.size(); i++) - if(curPatchList.at(i).second.checked) - patchList.push_back(curPatchList.at(i).first); - if(!curPatchList.size() || !patchList.size()) - { - QMessageBox msg(QMessageBox::Information, "Information", "Nothing to patch!"); - msg.setWindowIcon(QIcon(":/icons/images/information.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return; - } - char szModName[MAX_PATH] = ""; - if(!DbgFunctions()->ModPathFromAddr(DbgFunctions()->ModBaseFromName(mod.toUtf8().constData()), szModName, MAX_PATH)) - { - QMessageBox msg(QMessageBox::Critical, "Error!", "Failed to get module filename..."); - msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return; - } - - //open the save file dialog - int len = (int)strlen(szModName); - while(szModName[len] != '\\') - len--; - char szDirName[MAX_PATH] = ""; - strcpy_s(szDirName, szModName); - szDirName[len] = '\0'; - - QString filename = QFileDialog::getSaveFileName(this, "Save file", szDirName, "All files (*.*)"); - if(!filename.length()) - return; - filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes) - - //call patchSave function - DBGPATCHINFO* dbgPatchList = new DBGPATCHINFO[patchList.size()]; - for(int i = 0; i < patchList.size(); i++) - dbgPatchList[i] = patchList.at(i); - char error[MAX_ERROR_SIZE] = ""; - int patched = DbgFunctions()->PatchFile(dbgPatchList, patchList.size(), filename.toUtf8().constData(), error); - delete [] dbgPatchList; - if(patched == -1) - { - QMessageBox msg(QMessageBox::Critical, "Error!", QString("Failed to save patched file (" + QString(error) + ")")); - msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return; - } - QMessageBox msg(QMessageBox::Information, "Information", QString().sprintf("%d/%d patch(es) applied!", patched, patchList.size())); - msg.setWindowIcon(QIcon(":/icons/images/information.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); -} - -void PatchDialog::on_btnImport_clicked() -{ - QString filename = QFileDialog::getOpenFileName(this, tr("Open patch"), "", tr("Patch files (*.1337)")); - if(!filename.length()) - return; - filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes) - QFile file(filename); - file.open(QFile::ReadOnly | QFile::Text); - QTextStream in(&file); - QString patch = in.readAll(); - file.close(); - patch = patch.replace("\r\n", "\n"); - QStringList lines = patch.split("\n", QString::SkipEmptyParts); - if(!lines.size()) - { - QMessageBox msg(QMessageBox::Critical, "Error!", QString("The patch file is empty...")); - msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return; - } - - typedef struct _IMPORTSTATUS - { - bool badoriginal; - bool alreadypatched; - } IMPORTSTATUS; - QList> patchList; - DBGPATCHINFO curPatch; - dsint modbase = 0; - bool bBadOriginal = false; - bool bAlreadyDone = false; - for(int i = 0; i < lines.size(); i++) - { - ULONGLONG rva; - unsigned int oldbyte; - unsigned int newbyte; - QString curLine = lines.at(i); - if(curLine.startsWith(">")) //module - { - strcpy_s(curPatch.mod, curLine.toUtf8().constData() + 1); - modbase = DbgFunctions()->ModBaseFromName(curPatch.mod); - continue; - } - if(!modbase) - continue; - curLine = curLine.replace(" ", ""); - if(sscanf_s(curLine.toUtf8().constData(), "%llX:%X->%X", &rva, &oldbyte, &newbyte) != 3) - { - QMessageBox msg(QMessageBox::Critical, "Error!", QString("Patch file format is incorrect...")); - msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return; - } - oldbyte &= 0xFF; - newbyte &= 0xFF; - curPatch.addr = rva + modbase; - if(!DbgMemIsValidReadPtr(curPatch.addr)) - continue; - unsigned char checkbyte = 0; - DbgMemRead(curPatch.addr, &checkbyte, sizeof(checkbyte)); - IMPORTSTATUS status; - status.alreadypatched = (checkbyte == newbyte); - status.badoriginal = (checkbyte != oldbyte); - if(status.alreadypatched) - bAlreadyDone = true; - else if(status.badoriginal) - bBadOriginal = true; - curPatch.oldbyte = oldbyte; - curPatch.newbyte = newbyte; - patchList.push_back(QPair(curPatch, status)); - } - - if(!patchList.size()) - { - QMessageBox msg(QMessageBox::Information, "Information", QString().sprintf("No patches to apply in the current process.")); - msg.setWindowIcon(QIcon(":/icons/images/information.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return; - } - - bool bUndoPatched = false; - if(bAlreadyDone) - { - QMessageBox msg(QMessageBox::Question, "Question", "Some patches are already applied.\n\nDo you want to remove these patches?", QMessageBox::Yes | QMessageBox::No); - msg.setWindowIcon(QIcon(":/icons/images/question.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - if(msg.exec() == QMessageBox::Yes) - bUndoPatched = true; - } - - bool bPatchBadOriginals = false; - if(bBadOriginal) - { - QMessageBox msg(QMessageBox::Question, "Question", "Some bytes do not match the original in the patch file.\n\nDo you want to apply these patches anyway?", QMessageBox::Yes | QMessageBox::No); - msg.setWindowIcon(QIcon(":/icons/images/question.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - if(msg.exec() == QMessageBox::Yes) - bPatchBadOriginals = true; - } - - int patched = 0; - for(int i = 0; i < patchList.size(); i++) - { - if(!bPatchBadOriginals && patchList.at(i).second.badoriginal) - continue; - curPatch = patchList.at(i).first; - if(bUndoPatched && patchList.at(i).second.alreadypatched) - { - if(DbgFunctions()->MemPatch(curPatch.addr, &curPatch.oldbyte, 1)) - patched++; - } - else - { - if(DbgFunctions()->MemPatch(curPatch.addr, &curPatch.newbyte, 1)) - patched++; - } - } - - updatePatches(); - GuiUpdateAllViews(); - - QMessageBox msg(QMessageBox::Information, "Information", QString().sprintf("%d/%d patch(es) applied!", patched, patchList.size())); - msg.setWindowIcon(QIcon(":/icons/images/information.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); -} - -void PatchDialog::on_btnExport_clicked() -{ - if(!mPatches->size()) - return; - - QString filename = QFileDialog::getSaveFileName(this, tr("Save patch"), "", tr("Patch files (*.1337)")); - if(!filename.length()) - return; - filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes) - - QStringList lines; - - int patches = 0; - for(PatchMap::iterator i = mPatches->begin(); i != mPatches->end(); ++i) - { - const PatchInfoList & curPatchList = i.value(); - bool bModPlaced = false; - dsint modbase = DbgFunctions()->ModBaseFromName(i.key().toUtf8().constData()); - if(!modbase) - continue; - for(int j = 0; j < curPatchList.size(); j++) - { - if(!curPatchList.at(j).second.checked) //skip unchecked patches - continue; - if(!bModPlaced) - { - lines.push_back(">" + i.key()); - bModPlaced = true; - } - QString addrText = QString("%1").arg(curPatchList.at(j).first.addr - modbase, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - lines.push_back(addrText + QString().sprintf(":%.2X->%.2X", curPatchList.at(j).first.oldbyte, curPatchList.at(j).first.newbyte)); - patches++; - } - } - - if(!lines.size()) - { - QMessageBox msg(QMessageBox::Information, "Information", QString().sprintf("No patches to export.")); - msg.setWindowIcon(QIcon(":/icons/images/information.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return; - } - - QFile file(filename); - file.open(QFile::WriteOnly | QFile::Text); - QString text = lines.join("\n"); - file.write(text.toUtf8().constData(), text.length()); - file.close(); - - QMessageBox msg(QMessageBox::Information, "Information", QString().sprintf("%d patch(es) exported!", patches)); - msg.setWindowIcon(QIcon(":/icons/images/information.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); -} +#include "PatchDialog.h" +#include "ui_PatchDialog.h" +#include +#include +#include +#include + +PatchDialog::PatchDialog(QWidget* parent) : + QDialog(parent), + ui(new Ui::PatchDialog) +{ + ui->setupUi(this); +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); +#endif + setFixedSize(this->size()); //fixed size + setModal(false); //non-modal window + + connect(Bridge::getBridge(), SIGNAL(updatePatches()), this, SLOT(updatePatches())); + connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChanged(DBGSTATE))); + + mGroupSelector = new PatchDialogGroupSelector(parent); + mGroupSelector->setGroup(0); + connect(mGroupSelector, SIGNAL(rejected()), this, SLOT(showNormal())); + connect(mGroupSelector, SIGNAL(rejected()), this, SLOT(setFocus())); + connect(mGroupSelector, SIGNAL(groupToggle()), this, SLOT(groupToggle())); + connect(mGroupSelector, SIGNAL(groupPrevious()), this, SLOT(groupPrevious())); + connect(mGroupSelector, SIGNAL(groupNext()), this, SLOT(groupNext())); + + mPatches = new PatchMap(); + mIsWorking = false; +} + +PatchDialog::~PatchDialog() +{ + delete ui; +} + +bool PatchDialog::isPartOfPreviousGroup(const PatchInfoList & patchList, int index) +{ + if(!index) + return true; + uint addr = patchList.at(index).first.addr; + uint prevAddr = patchList.at(index - 1).first.addr; + for(int i = 1; i < 10; i++) //10 bytes in between groups + if(addr - i == prevAddr) + return true; + return false; +} + +bool PatchDialog::isGroupEnabled(const PatchInfoList & patchList, int group) +{ + for(int i = 0; i < patchList.size(); i++) + if(patchList.at(i).second.group == group && !patchList.at(i).second.checked) + return false; + return true; +} + +bool PatchDialog::hasPreviousGroup(const PatchInfoList & patchList, int group) +{ + for(int i = 0; i < patchList.size(); i++) + if(patchList.at(i).second.group < group) + return true; + return false; +} + +bool PatchDialog::hasNextGroup(const PatchInfoList & patchList, int group) +{ + for(int i = 0; i < patchList.size(); i++) + if(patchList.at(i).second.group > group) + return true; + return false; +} + +dsint PatchDialog::getGroupAddress(const PatchInfoList & patchList, int group) +{ + for(int i = 0; i < patchList.size(); i++) + if(patchList.at(i).second.group == group) + return patchList.at(i).first.addr; + return -1; +} + +void PatchDialog::dbgStateChanged(DBGSTATE state) +{ + if(state == stopped) + { + mGroupSelector->hide(); + reject(); + } +} + +void PatchDialog::updatePatches() +{ + if(this->isVisible()) + mGroupSelector->reject(); + mIsWorking = true; + //clear GUI + ui->listModules->clear(); + ui->listPatches->clear(); + delete mPatches; + mPatches = new PatchMap(); + + //get patches from DBG + size_t cbsize; + if(!DbgFunctions()->PatchEnum(0, &cbsize)) + return; + int numPatches = (int)cbsize / sizeof(DBGPATCHINFO); + if(!numPatches) + return; + DBGPATCHINFO* patches = new DBGPATCHINFO[numPatches]; + memset(patches, 0, numPatches * sizeof(DBGPATCHINFO)); + if(!DbgFunctions()->PatchEnum(patches, 0)) + { + delete [] patches; + mIsWorking = false; + return; + } + + //fill the patch list + STATUSINFO defaultStatus; + defaultStatus.group = 0; + defaultStatus.checked = true; + for(int i = 0; i < numPatches; i++) + { + if(!patches[i].addr) + continue; + if(!*patches[i].mod) + continue; + QString mod = patches[i].mod; + PatchMap::iterator found = mPatches->find(mod); + if(found != mPatches->end()) //found + (*mPatches)[mod].append(PatchPair(patches[i], defaultStatus)); + else //not found + { + PatchInfoList patchList; + patchList.append(PatchPair(patches[i], defaultStatus)); + mPatches->insert(mod, patchList); + } + } + delete [] patches; + + //sort the patches by address + for(PatchMap::iterator i = mPatches->begin(); i != mPatches->end(); ++i) + { + qSort(i.value().begin(), i.value().end(), PatchInfoLess); + PatchInfoList & curPatchList = i.value(); + //group the patched bytes + for(int j = 0, group = 0; j < curPatchList.size(); j++) + { + if(!isPartOfPreviousGroup(curPatchList, j)) + group++; + curPatchList[j].second.group = group; + } + ui->listModules->addItem(i.key()); + } + + if(mPatches->size()) + ui->listModules->item(0)->setSelected(true); //select first module + + mIsWorking = false; +} + +void PatchDialog::groupToggle() +{ + int group = mGroupSelector->group(); + if(mIsWorking || !ui->listModules->selectedItems().size()) + return; + QString mod = ui->listModules->selectedItems().at(0)->text(); + PatchMap::iterator found = mPatches->find(mod); + if(found == mPatches->end()) //not found + return; + PatchInfoList & curPatchList = found.value(); + bool enabled = !isGroupEnabled(curPatchList, group); + Qt::CheckState checkState = enabled ? Qt::Checked : Qt::Unchecked; + mIsWorking = true; + for(int i = 0; i < curPatchList.size(); i++) + { + if(curPatchList.at(i).second.group != group) + continue; + ui->listPatches->item(i)->setCheckState(checkState); + curPatchList[i].second.checked = enabled; + //change the byte to reflect the change for the user (cypherpunk reported this) + unsigned char writebyte = curPatchList[i].second.checked ? curPatchList[i].first.newbyte : curPatchList[i].first.oldbyte; + DbgMemWrite(curPatchList[i].first.addr, &writebyte, sizeof(writebyte)); + } + GuiUpdateAllViews(); + mIsWorking = false; + dsint groupStart = getGroupAddress(curPatchList, group); + if(!groupStart) + return; + QString color = enabled ? "#00DD00" : "red"; + QString addrText = QString("%1").arg(groupStart, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + QString title = "" + QString().sprintf("%d:", group) + addrText + ""; + mGroupSelector->setGroupTitle(title); + DbgCmdExecDirect(QString("disasm " + addrText).toUtf8().constData()); + DbgCmdExecDirect(QString("dump " + addrText).toUtf8().constData()); +} + +void PatchDialog::groupPrevious() +{ + int group = mGroupSelector->group(); + if(!ui->listModules->selectedItems().size()) + return; + QString mod = ui->listModules->selectedItems().at(0)->text(); + PatchMap::iterator found = mPatches->find(mod); + if(found == mPatches->end()) //not found + return; + PatchInfoList & curPatchList = found.value(); + if(!hasPreviousGroup(curPatchList, group)) + return; + group--; + QString color = isGroupEnabled(curPatchList, group) ? "#00DD00" : "red"; + QString addrText = QString("%1").arg(getGroupAddress(curPatchList, group), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + QString title = "" + QString().sprintf("%d:", group) + addrText + ""; + mGroupSelector->setGroupTitle(title); + mGroupSelector->setGroup(group); + mGroupSelector->setPreviousEnabled(hasPreviousGroup(curPatchList, group)); + mGroupSelector->setNextEnabled(hasNextGroup(curPatchList, group)); + mGroupSelector->showNormal(); + DbgCmdExecDirect(QString("disasm " + addrText).toUtf8().constData()); + DbgCmdExecDirect(QString("dump " + addrText).toUtf8().constData()); +} + +void PatchDialog::groupNext() +{ + int group = mGroupSelector->group(); + if(!ui->listModules->selectedItems().size()) + return; + QString mod = ui->listModules->selectedItems().at(0)->text(); + PatchMap::iterator found = mPatches->find(mod); + if(found == mPatches->end()) //not found + return; + PatchInfoList & curPatchList = found.value(); + if(!hasNextGroup(curPatchList, group)) + return; + group++; + QString color = isGroupEnabled(curPatchList, group) ? "#00DD00" : "red"; + QString addrText = QString("%1").arg(getGroupAddress(curPatchList, group), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + QString title = "" + QString().sprintf("%d:", group) + addrText + ""; + mGroupSelector->setGroupTitle(title); + mGroupSelector->setGroup(group); + mGroupSelector->setPreviousEnabled(hasPreviousGroup(curPatchList, group)); + mGroupSelector->setNextEnabled(hasNextGroup(curPatchList, group)); + mGroupSelector->showNormal(); + DbgCmdExecDirect(QString("disasm " + addrText).toUtf8().constData()); + DbgCmdExecDirect(QString("dump " + addrText).toUtf8().constData()); +} + +void PatchDialog::on_listModules_itemSelectionChanged() +{ + if(!ui->listModules->selectedItems().size()) + return; + QString mod(ui->listModules->selectedItems().at(0)->text()); + PatchMap::iterator found = mPatches->find(mod); + if(found == mPatches->end()) //not found + return; + mIsWorking = true; + PatchInfoList & patchList = found.value(); + ui->listPatches->clear(); + for(int i = 0; i < patchList.size(); i++) + { + const DBGPATCHINFO curPatch = patchList.at(i).first; + QString addrText = QString("%1").arg(curPatch.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + QListWidgetItem* item = new QListWidgetItem(QString().sprintf("%d", patchList.at(i).second.group).rightJustified(4, ' ', true) + "|" + addrText + QString().sprintf(":%.2X->%.2X", curPatch.oldbyte, curPatch.newbyte), ui->listPatches); + item->setFlags(item->flags() | Qt::ItemIsUserCheckable); + Qt::CheckState state = patchList.at(i).second.checked ? Qt::Checked : Qt::Unchecked; + item->setCheckState(state); + } + mIsWorking = false; +} + +void PatchDialog::on_listPatches_itemChanged(QListWidgetItem* item) //checkbox changed +{ + if(mIsWorking || !ui->listModules->selectedItems().size()) + return; + QString mod = ui->listModules->selectedItems().at(0)->text(); + PatchMap::iterator found = mPatches->find(mod); + if(found == mPatches->end()) //not found + return; + bool checked = item->checkState() == Qt::Checked; + PatchInfoList & curPatchList = found.value(); + PatchPair & patch = curPatchList[ui->listPatches->row(item)]; + if(patch.second.checked == checked) //check state did not change + return; + patch.second.checked = checked; + //change the byte to reflect the change for the user (cypherpunk reported this) + unsigned char writebyte = patch.second.checked ? patch.first.newbyte : patch.first.oldbyte; + DbgMemWrite(patch.first.addr, &writebyte, sizeof(writebyte)); + //check state changed + if((QApplication::keyboardModifiers() & Qt::ControlModifier) != Qt::ControlModifier) + { + mIsWorking = true; + //check/uncheck the complete group + for(int i = 0; i < curPatchList.size(); i++) + if(curPatchList.at(i).second.group == patch.second.group) + { + //change the patch state + curPatchList[i].second.checked = checked; + ui->listPatches->item(i)->setCheckState(item->checkState()); + //change the byte to reflect the change for the user (cypherpunk reported this) + unsigned char writebyte = curPatchList[i].second.checked ? curPatchList[i].first.newbyte : curPatchList[i].first.oldbyte; + DbgMemWrite(curPatchList[i].first.addr, &writebyte, sizeof(writebyte)); + } + mIsWorking = false; + } + GuiUpdateAllViews(); + int group = mGroupSelector->group(); + QString color = isGroupEnabled(curPatchList, group) ? "#00DD00" : "red"; + QString addrText = QString("%1").arg(getGroupAddress(curPatchList, group), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + QString title = "" + QString().sprintf("%d:", group) + addrText + ""; + mGroupSelector->setGroupTitle(title); + mGroupSelector->setPreviousEnabled(hasPreviousGroup(curPatchList, group)); + mGroupSelector->setNextEnabled(hasNextGroup(curPatchList, group)); +} + +void PatchDialog::on_btnSelectAll_clicked() +{ + if(!ui->listModules->selectedItems().size()) + return; + QString mod = ui->listModules->selectedItems().at(0)->text(); + PatchMap::iterator found = mPatches->find(mod); + if(found == mPatches->end()) //not found + return; + mIsWorking = true; + PatchInfoList & curPatchList = found.value(); + for(int i = 0; i < curPatchList.size(); i++) + { + ui->listPatches->item(i)->setCheckState(Qt::Checked); + curPatchList[i].second.checked = true; + //change the byte to reflect the change for the user (cypherpunk reported this) + DbgMemWrite(curPatchList[i].first.addr, &curPatchList[i].first.newbyte, sizeof(unsigned char)); + } + GuiUpdateAllViews(); + mIsWorking = false; +} + +void PatchDialog::on_btnDeselectAll_clicked() +{ + if(!ui->listModules->selectedItems().size()) + return; + QString mod = ui->listModules->selectedItems().at(0)->text(); + PatchMap::iterator found = mPatches->find(mod); + if(found == mPatches->end()) //not found + return; + mIsWorking = true; + PatchInfoList & curPatchList = found.value(); + for(int i = 0; i < curPatchList.size(); i++) + { + ui->listPatches->item(i)->setCheckState(Qt::Unchecked); + curPatchList[i].second.checked = false; + //change the byte to reflect the change for the user (cypherpunk reported this) + DbgMemWrite(curPatchList[i].first.addr, &curPatchList[i].first.oldbyte, sizeof(unsigned char)); + } + GuiUpdateAllViews(); + mIsWorking = false; +} + +void PatchDialog::on_btnRestoreSelected_clicked() +{ + if(!ui->listModules->selectedItems().size()) + return; + int selModIdx = ui->listModules->row(ui->listModules->selectedItems().at(0)); + QString mod = ui->listModules->selectedItems().at(0)->text(); + PatchMap::iterator found = mPatches->find(mod); + if(found == mPatches->end()) //not found + return; + mIsWorking = true; + PatchInfoList & curPatchList = found.value(); + int removed = 0; + int total = curPatchList.size(); + for(int i = 0; i < total; i++) + { + if(curPatchList.at(i).second.checked) + { + DbgFunctions()->PatchRestore(curPatchList.at(i).first.addr); + removed++; + } + } + mIsWorking = false; + updatePatches(); + if(removed != total) + ui->listModules->setCurrentRow(selModIdx); + GuiUpdateAllViews(); +} + +void PatchDialog::on_listPatches_itemSelectionChanged() +{ + if(!ui->listModules->selectedItems().size() || !ui->listPatches->selectedItems().size()) + return; + QString mod = ui->listModules->selectedItems().at(0)->text(); + PatchMap::iterator found = mPatches->find(mod); + if(found == mPatches->end()) //not found + return; + PatchInfoList & curPatchList = found.value(); + PatchPair & patch = curPatchList[ui->listPatches->row(ui->listPatches->selectedItems().at(0))]; //selected item + dsint groupStart = getGroupAddress(curPatchList, patch.second.group); + if(!groupStart) + return; + QString addrText = QString("%1").arg(groupStart, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + DbgCmdExecDirect(QString("disasm " + addrText).toUtf8().constData()); + DbgCmdExecDirect(QString("dump " + addrText).toUtf8().constData()); +} + +void PatchDialog::on_btnPickGroups_clicked() +{ + if(!ui->listModules->selectedItems().size()) + return; + QString mod = ui->listModules->selectedItems().at(0)->text(); + PatchMap::iterator found = mPatches->find(mod); + if(found == mPatches->end()) //not found + return; + PatchInfoList & curPatchList = found.value(); + if(!curPatchList.size()) + return; + this->showMinimized(); + + int group = mGroupSelector->group(); + QString color = isGroupEnabled(curPatchList, group) ? "#00DD00" : "red"; + QString addrText = QString("%1").arg(getGroupAddress(curPatchList, group), sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + QString title = "" + QString().sprintf("%d:", group) + addrText + ""; + mGroupSelector->setGroupTitle(title); + mGroupSelector->setPreviousEnabled(hasPreviousGroup(curPatchList, group)); + mGroupSelector->setNextEnabled(hasNextGroup(curPatchList, group)); + mGroupSelector->show(); + DbgCmdExecDirect(QString("disasm " + addrText).toUtf8().constData()); + DbgCmdExecDirect(QString("dump " + addrText).toUtf8().constData()); +} + +void PatchDialog::on_btnPatchFile_clicked() +{ + //get current module + if(!ui->listModules->selectedItems().size()) + return; + QString mod = ui->listModules->selectedItems().at(0)->text(); + PatchMap::iterator found = mPatches->find(mod); + if(found == mPatches->end()) //not found + return; + PatchInfoList & curPatchList = found.value(); + + //get patches to save + QList patchList; + for(int i = 0; i < curPatchList.size(); i++) + if(curPatchList.at(i).second.checked) + patchList.push_back(curPatchList.at(i).first); + if(!curPatchList.size() || !patchList.size()) + { + QMessageBox msg(QMessageBox::Information, "Information", "Nothing to patch!"); + msg.setWindowIcon(QIcon(":/icons/images/information.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return; + } + char szModName[MAX_PATH] = ""; + if(!DbgFunctions()->ModPathFromAddr(DbgFunctions()->ModBaseFromName(mod.toUtf8().constData()), szModName, MAX_PATH)) + { + QMessageBox msg(QMessageBox::Critical, "Error!", "Failed to get module filename..."); + msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return; + } + + //open the save file dialog + int len = (int)strlen(szModName); + while(szModName[len] != '\\') + len--; + char szDirName[MAX_PATH] = ""; + strcpy_s(szDirName, szModName); + szDirName[len] = '\0'; + + QString filename = QFileDialog::getSaveFileName(this, "Save file", szDirName, "All files (*.*)"); + if(!filename.length()) + return; + filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes) + + //call patchSave function + DBGPATCHINFO* dbgPatchList = new DBGPATCHINFO[patchList.size()]; + for(int i = 0; i < patchList.size(); i++) + dbgPatchList[i] = patchList.at(i); + char error[MAX_ERROR_SIZE] = ""; + int patched = DbgFunctions()->PatchFile(dbgPatchList, patchList.size(), filename.toUtf8().constData(), error); + delete [] dbgPatchList; + if(patched == -1) + { + QMessageBox msg(QMessageBox::Critical, "Error!", QString("Failed to save patched file (" + QString(error) + ")")); + msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return; + } + QMessageBox msg(QMessageBox::Information, "Information", QString().sprintf("%d/%d patch(es) applied!", patched, patchList.size())); + msg.setWindowIcon(QIcon(":/icons/images/information.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); +} + +void PatchDialog::on_btnImport_clicked() +{ + QString filename = QFileDialog::getOpenFileName(this, tr("Open patch"), "", tr("Patch files (*.1337)")); + if(!filename.length()) + return; + filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes) + QFile file(filename); + file.open(QFile::ReadOnly | QFile::Text); + QTextStream in(&file); + QString patch = in.readAll(); + file.close(); + patch = patch.replace("\r\n", "\n"); + QStringList lines = patch.split("\n", QString::SkipEmptyParts); + if(!lines.size()) + { + QMessageBox msg(QMessageBox::Critical, "Error!", QString("The patch file is empty...")); + msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return; + } + + typedef struct _IMPORTSTATUS + { + bool badoriginal; + bool alreadypatched; + } IMPORTSTATUS; + QList> patchList; + DBGPATCHINFO curPatch; + dsint modbase = 0; + bool bBadOriginal = false; + bool bAlreadyDone = false; + for(int i = 0; i < lines.size(); i++) + { + ULONGLONG rva; + unsigned int oldbyte; + unsigned int newbyte; + QString curLine = lines.at(i); + if(curLine.startsWith(">")) //module + { + strcpy_s(curPatch.mod, curLine.toUtf8().constData() + 1); + modbase = DbgFunctions()->ModBaseFromName(curPatch.mod); + continue; + } + if(!modbase) + continue; + curLine = curLine.replace(" ", ""); + if(sscanf_s(curLine.toUtf8().constData(), "%llX:%X->%X", &rva, &oldbyte, &newbyte) != 3) + { + QMessageBox msg(QMessageBox::Critical, "Error!", QString("Patch file format is incorrect...")); + msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return; + } + oldbyte &= 0xFF; + newbyte &= 0xFF; + curPatch.addr = rva + modbase; + if(!DbgMemIsValidReadPtr(curPatch.addr)) + continue; + unsigned char checkbyte = 0; + DbgMemRead(curPatch.addr, &checkbyte, sizeof(checkbyte)); + IMPORTSTATUS status; + status.alreadypatched = (checkbyte == newbyte); + status.badoriginal = (checkbyte != oldbyte); + if(status.alreadypatched) + bAlreadyDone = true; + else if(status.badoriginal) + bBadOriginal = true; + curPatch.oldbyte = oldbyte; + curPatch.newbyte = newbyte; + patchList.push_back(QPair(curPatch, status)); + } + + if(!patchList.size()) + { + QMessageBox msg(QMessageBox::Information, "Information", QString().sprintf("No patches to apply in the current process.")); + msg.setWindowIcon(QIcon(":/icons/images/information.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return; + } + + bool bUndoPatched = false; + if(bAlreadyDone) + { + QMessageBox msg(QMessageBox::Question, "Question", "Some patches are already applied.\n\nDo you want to remove these patches?", QMessageBox::Yes | QMessageBox::No); + msg.setWindowIcon(QIcon(":/icons/images/question.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + if(msg.exec() == QMessageBox::Yes) + bUndoPatched = true; + } + + bool bPatchBadOriginals = false; + if(bBadOriginal) + { + QMessageBox msg(QMessageBox::Question, "Question", "Some bytes do not match the original in the patch file.\n\nDo you want to apply these patches anyway?", QMessageBox::Yes | QMessageBox::No); + msg.setWindowIcon(QIcon(":/icons/images/question.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + if(msg.exec() == QMessageBox::Yes) + bPatchBadOriginals = true; + } + + int patched = 0; + for(int i = 0; i < patchList.size(); i++) + { + if(!bPatchBadOriginals && patchList.at(i).second.badoriginal) + continue; + curPatch = patchList.at(i).first; + if(bUndoPatched && patchList.at(i).second.alreadypatched) + { + if(DbgFunctions()->MemPatch(curPatch.addr, &curPatch.oldbyte, 1)) + patched++; + } + else + { + if(DbgFunctions()->MemPatch(curPatch.addr, &curPatch.newbyte, 1)) + patched++; + } + } + + updatePatches(); + GuiUpdateAllViews(); + + QMessageBox msg(QMessageBox::Information, "Information", QString().sprintf("%d/%d patch(es) applied!", patched, patchList.size())); + msg.setWindowIcon(QIcon(":/icons/images/information.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); +} + +void PatchDialog::on_btnExport_clicked() +{ + if(!mPatches->size()) + return; + + QString filename = QFileDialog::getSaveFileName(this, tr("Save patch"), "", tr("Patch files (*.1337)")); + if(!filename.length()) + return; + filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes) + + QStringList lines; + + int patches = 0; + for(PatchMap::iterator i = mPatches->begin(); i != mPatches->end(); ++i) + { + const PatchInfoList & curPatchList = i.value(); + bool bModPlaced = false; + dsint modbase = DbgFunctions()->ModBaseFromName(i.key().toUtf8().constData()); + if(!modbase) + continue; + for(int j = 0; j < curPatchList.size(); j++) + { + if(!curPatchList.at(j).second.checked) //skip unchecked patches + continue; + if(!bModPlaced) + { + lines.push_back(">" + i.key()); + bModPlaced = true; + } + QString addrText = QString("%1").arg(curPatchList.at(j).first.addr - modbase, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + lines.push_back(addrText + QString().sprintf(":%.2X->%.2X", curPatchList.at(j).first.oldbyte, curPatchList.at(j).first.newbyte)); + patches++; + } + } + + if(!lines.size()) + { + QMessageBox msg(QMessageBox::Information, "Information", QString().sprintf("No patches to export.")); + msg.setWindowIcon(QIcon(":/icons/images/information.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return; + } + + QFile file(filename); + file.open(QFile::WriteOnly | QFile::Text); + QString text = lines.join("\n"); + file.write(text.toUtf8().constData(), text.length()); + file.close(); + + QMessageBox msg(QMessageBox::Information, "Information", QString().sprintf("%d patch(es) exported!", patches)); + msg.setWindowIcon(QIcon(":/icons/images/information.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); +} diff --git a/src/gui/Src/Gui/PatchDialog.h b/src/gui/Src/Gui/PatchDialog.h index 7ffff158..062fec2b 100644 --- a/src/gui/Src/Gui/PatchDialog.h +++ b/src/gui/Src/Gui/PatchDialog.h @@ -1,67 +1,67 @@ -#ifndef PATCHDIALOG_H -#define PATCHDIALOG_H - -#include -#include -#include "PatchDialogGroupSelector.h" -#include "Bridge.h" - -namespace Ui -{ -class PatchDialog; -} - -class PatchDialog : public QDialog -{ - Q_OBJECT - - struct STATUSINFO - { - bool checked; - int group; - }; - - typedef QPair PatchPair; - typedef QList PatchInfoList; - typedef QMap PatchMap; - - static bool PatchInfoLess(const PatchPair & a, const PatchPair & b) - { - return a.first.addr < b.first.addr; - } - -public: - explicit PatchDialog(QWidget* parent = 0); - ~PatchDialog(); - -private: - Ui::PatchDialog* ui; - PatchMap* mPatches; - PatchDialogGroupSelector* mGroupSelector; - bool mIsWorking; - - bool isPartOfPreviousGroup(const PatchInfoList & patchList, int index); - bool isGroupEnabled(const PatchInfoList & patchList, int group); - bool hasPreviousGroup(const PatchInfoList & patchList, int group); - bool hasNextGroup(const PatchInfoList & patchList, int group); - dsint getGroupAddress(const PatchInfoList & patchList, int group); - -private slots: - void dbgStateChanged(DBGSTATE state); - void updatePatches(); - void groupToggle(); - void groupPrevious(); - void groupNext(); - void on_listModules_itemSelectionChanged(); - void on_listPatches_itemChanged(QListWidgetItem* item); - void on_btnSelectAll_clicked(); - void on_btnDeselectAll_clicked(); - void on_btnRestoreSelected_clicked(); - void on_listPatches_itemSelectionChanged(); - void on_btnPickGroups_clicked(); - void on_btnPatchFile_clicked(); - void on_btnImport_clicked(); - void on_btnExport_clicked(); -}; - -#endif // PATCHDIALOG_H +#ifndef PATCHDIALOG_H +#define PATCHDIALOG_H + +#include +#include +#include "PatchDialogGroupSelector.h" +#include "Bridge.h" + +namespace Ui +{ +class PatchDialog; +} + +class PatchDialog : public QDialog +{ + Q_OBJECT + + struct STATUSINFO + { + bool checked; + int group; + }; + + typedef QPair PatchPair; + typedef QList PatchInfoList; + typedef QMap PatchMap; + + static bool PatchInfoLess(const PatchPair & a, const PatchPair & b) + { + return a.first.addr < b.first.addr; + } + +public: + explicit PatchDialog(QWidget* parent = 0); + ~PatchDialog(); + +private: + Ui::PatchDialog* ui; + PatchMap* mPatches; + PatchDialogGroupSelector* mGroupSelector; + bool mIsWorking; + + bool isPartOfPreviousGroup(const PatchInfoList & patchList, int index); + bool isGroupEnabled(const PatchInfoList & patchList, int group); + bool hasPreviousGroup(const PatchInfoList & patchList, int group); + bool hasNextGroup(const PatchInfoList & patchList, int group); + dsint getGroupAddress(const PatchInfoList & patchList, int group); + +private slots: + void dbgStateChanged(DBGSTATE state); + void updatePatches(); + void groupToggle(); + void groupPrevious(); + void groupNext(); + void on_listModules_itemSelectionChanged(); + void on_listPatches_itemChanged(QListWidgetItem* item); + void on_btnSelectAll_clicked(); + void on_btnDeselectAll_clicked(); + void on_btnRestoreSelected_clicked(); + void on_listPatches_itemSelectionChanged(); + void on_btnPickGroups_clicked(); + void on_btnPatchFile_clicked(); + void on_btnImport_clicked(); + void on_btnExport_clicked(); +}; + +#endif // PATCHDIALOG_H diff --git a/src/gui/Src/Gui/PatchDialogGroupSelector.cpp b/src/gui/Src/Gui/PatchDialogGroupSelector.cpp index 4a7a4273..07fcb9dc 100644 --- a/src/gui/Src/Gui/PatchDialogGroupSelector.cpp +++ b/src/gui/Src/Gui/PatchDialogGroupSelector.cpp @@ -1,75 +1,75 @@ -#include "PatchDialogGroupSelector.h" -#include "ui_PatchDialogGroupSelector.h" - -PatchDialogGroupSelector::PatchDialogGroupSelector(QWidget* parent) : - QDialog(parent), - ui(new Ui::PatchDialogGroupSelector) -{ - ui->setupUi(this); -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); -#endif - setFixedSize(this->size()); //fixed size - setModal(false); //non-modal window - - mGroup = 0; -} - -PatchDialogGroupSelector::~PatchDialogGroupSelector() -{ - delete ui; -} - -void PatchDialogGroupSelector::keyPressEvent(QKeyEvent* event) -{ - if(event->modifiers() != Qt::NoModifier) - return; - if(event->key() == Qt::Key_Space) - on_btnToggle_clicked(); - else if(event->key() == Qt::Key_BracketLeft) - on_btnPrevious_clicked(); - else if(event->key() == Qt::Key_BracketRight) - on_btnNext_clicked(); -} - -void PatchDialogGroupSelector::setGroupTitle(const QString & title) -{ - ui->lblTitle->setText(title); -} - -void PatchDialogGroupSelector::setPreviousEnabled(bool enable) -{ - ui->btnPrevious->setEnabled(enable); -} - -void PatchDialogGroupSelector::setNextEnabled(bool enable) -{ - ui->btnNext->setEnabled(enable); -} - -void PatchDialogGroupSelector::setGroup(int group) -{ - mGroup = group; -} - -int PatchDialogGroupSelector::group() -{ - return mGroup; -} - -void PatchDialogGroupSelector::on_btnToggle_clicked() -{ - emit groupToggle(); -} - -void PatchDialogGroupSelector::on_btnPrevious_clicked() -{ - if(ui->btnPrevious->isEnabled()) - emit groupPrevious(); -} - -void PatchDialogGroupSelector::on_btnNext_clicked() -{ - if(ui->btnNext->isEnabled()) - emit groupNext(); -} +#include "PatchDialogGroupSelector.h" +#include "ui_PatchDialogGroupSelector.h" + +PatchDialogGroupSelector::PatchDialogGroupSelector(QWidget* parent) : + QDialog(parent), + ui(new Ui::PatchDialogGroupSelector) +{ + ui->setupUi(this); +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); +#endif + setFixedSize(this->size()); //fixed size + setModal(false); //non-modal window + + mGroup = 0; +} + +PatchDialogGroupSelector::~PatchDialogGroupSelector() +{ + delete ui; +} + +void PatchDialogGroupSelector::keyPressEvent(QKeyEvent* event) +{ + if(event->modifiers() != Qt::NoModifier) + return; + if(event->key() == Qt::Key_Space) + on_btnToggle_clicked(); + else if(event->key() == Qt::Key_BracketLeft) + on_btnPrevious_clicked(); + else if(event->key() == Qt::Key_BracketRight) + on_btnNext_clicked(); +} + +void PatchDialogGroupSelector::setGroupTitle(const QString & title) +{ + ui->lblTitle->setText(title); +} + +void PatchDialogGroupSelector::setPreviousEnabled(bool enable) +{ + ui->btnPrevious->setEnabled(enable); +} + +void PatchDialogGroupSelector::setNextEnabled(bool enable) +{ + ui->btnNext->setEnabled(enable); +} + +void PatchDialogGroupSelector::setGroup(int group) +{ + mGroup = group; +} + +int PatchDialogGroupSelector::group() +{ + return mGroup; +} + +void PatchDialogGroupSelector::on_btnToggle_clicked() +{ + emit groupToggle(); +} + +void PatchDialogGroupSelector::on_btnPrevious_clicked() +{ + if(ui->btnPrevious->isEnabled()) + emit groupPrevious(); +} + +void PatchDialogGroupSelector::on_btnNext_clicked() +{ + if(ui->btnNext->isEnabled()) + emit groupNext(); +} diff --git a/src/gui/Src/Gui/PatchDialogGroupSelector.h b/src/gui/Src/Gui/PatchDialogGroupSelector.h index 789364a9..369e77d4 100644 --- a/src/gui/Src/Gui/PatchDialogGroupSelector.h +++ b/src/gui/Src/Gui/PatchDialogGroupSelector.h @@ -1,43 +1,43 @@ -#ifndef PATCHDIALOGGROUPSELECTOR_H -#define PATCHDIALOGGROUPSELECTOR_H - -#include -#include - -namespace Ui -{ -class PatchDialogGroupSelector; -} - -class PatchDialogGroupSelector : public QDialog -{ - Q_OBJECT - -public: - explicit PatchDialogGroupSelector(QWidget* parent = 0); - ~PatchDialogGroupSelector(); - void setGroupTitle(const QString & title); - void setPreviousEnabled(bool enable); - void setNextEnabled(bool enable); - void setGroup(int group); - int group(); - -signals: - void groupToggle(); - void groupPrevious(); - void groupNext(); - -private slots: - void on_btnToggle_clicked(); - void on_btnPrevious_clicked(); - void on_btnNext_clicked(); - -protected: - void keyPressEvent(QKeyEvent* event); - -private: - Ui::PatchDialogGroupSelector* ui; - int mGroup; -}; - -#endif // PATCHDIALOGGROUPSELECTOR_H +#ifndef PATCHDIALOGGROUPSELECTOR_H +#define PATCHDIALOGGROUPSELECTOR_H + +#include +#include + +namespace Ui +{ +class PatchDialogGroupSelector; +} + +class PatchDialogGroupSelector : public QDialog +{ + Q_OBJECT + +public: + explicit PatchDialogGroupSelector(QWidget* parent = 0); + ~PatchDialogGroupSelector(); + void setGroupTitle(const QString & title); + void setPreviousEnabled(bool enable); + void setNextEnabled(bool enable); + void setGroup(int group); + int group(); + +signals: + void groupToggle(); + void groupPrevious(); + void groupNext(); + +private slots: + void on_btnToggle_clicked(); + void on_btnPrevious_clicked(); + void on_btnNext_clicked(); + +protected: + void keyPressEvent(QKeyEvent* event); + +private: + Ui::PatchDialogGroupSelector* ui; + int mGroup; +}; + +#endif // PATCHDIALOGGROUPSELECTOR_H diff --git a/src/gui/Src/Gui/ReferenceManager.cpp b/src/gui/Src/Gui/ReferenceManager.cpp index 433cf19f..8a7e9a54 100644 --- a/src/gui/Src/Gui/ReferenceManager.cpp +++ b/src/gui/Src/Gui/ReferenceManager.cpp @@ -1,46 +1,46 @@ -#include "ReferenceManager.h" -#include "Bridge.h" - -ReferenceManager::ReferenceManager(QWidget* parent) : QTabWidget(parent) -{ - setMovable(true); - setTabsClosable(true); - mCurrentReferenceView = 0; - - //Close All Tabs - mCloseAllTabs = new QPushButton(this); - mCloseAllTabs->setIcon(QIcon(":/icons/images/close-all-tabs.png")); - mCloseAllTabs->setToolTip("Close All Tabs"); - connect(mCloseAllTabs, SIGNAL(clicked()), this, SLOT(closeAllTabs())); - setCornerWidget(mCloseAllTabs, Qt::TopLeftCorner); - setContextMenuPolicy(Qt::CustomContextMenu); - - connect(Bridge::getBridge(), SIGNAL(referenceInitialize(QString)), this, SLOT(newReferenceView(QString))); - connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); -} - -ReferenceView* ReferenceManager::currentReferenceView() -{ - return mCurrentReferenceView; -} - -void ReferenceManager::newReferenceView(QString name) -{ - if(mCurrentReferenceView) //disconnect previous reference view - mCurrentReferenceView->disconnectBridge(); - mCurrentReferenceView = new ReferenceView(); - connect(mCurrentReferenceView, SIGNAL(showCpu()), this, SIGNAL(showCpu())); - insertTab(0, mCurrentReferenceView, name); - setCurrentIndex(0); - Bridge::getBridge()->setResult(1); -} - -void ReferenceManager::closeTab(int index) -{ - removeTab(index); -} - -void ReferenceManager::closeAllTabs() -{ - clear(); -} +#include "ReferenceManager.h" +#include "Bridge.h" + +ReferenceManager::ReferenceManager(QWidget* parent) : QTabWidget(parent) +{ + setMovable(true); + setTabsClosable(true); + mCurrentReferenceView = 0; + + //Close All Tabs + mCloseAllTabs = new QPushButton(this); + mCloseAllTabs->setIcon(QIcon(":/icons/images/close-all-tabs.png")); + mCloseAllTabs->setToolTip("Close All Tabs"); + connect(mCloseAllTabs, SIGNAL(clicked()), this, SLOT(closeAllTabs())); + setCornerWidget(mCloseAllTabs, Qt::TopLeftCorner); + setContextMenuPolicy(Qt::CustomContextMenu); + + connect(Bridge::getBridge(), SIGNAL(referenceInitialize(QString)), this, SLOT(newReferenceView(QString))); + connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); +} + +ReferenceView* ReferenceManager::currentReferenceView() +{ + return mCurrentReferenceView; +} + +void ReferenceManager::newReferenceView(QString name) +{ + if(mCurrentReferenceView) //disconnect previous reference view + mCurrentReferenceView->disconnectBridge(); + mCurrentReferenceView = new ReferenceView(); + connect(mCurrentReferenceView, SIGNAL(showCpu()), this, SIGNAL(showCpu())); + insertTab(0, mCurrentReferenceView, name); + setCurrentIndex(0); + Bridge::getBridge()->setResult(1); +} + +void ReferenceManager::closeTab(int index) +{ + removeTab(index); +} + +void ReferenceManager::closeAllTabs() +{ + clear(); +} diff --git a/src/gui/Src/Gui/ReferenceManager.h b/src/gui/Src/Gui/ReferenceManager.h index 66906472..3cf87575 100644 --- a/src/gui/Src/Gui/ReferenceManager.h +++ b/src/gui/Src/Gui/ReferenceManager.h @@ -1,28 +1,28 @@ -#ifndef REFERENCEMANAGER_H -#define REFERENCEMANAGER_H - -#include -#include -#include "ReferenceView.h" - -class ReferenceManager : public QTabWidget -{ - Q_OBJECT -public: - explicit ReferenceManager(QWidget* parent = 0); - ReferenceView* currentReferenceView(); - -private slots: - void newReferenceView(QString name); - void closeTab(int index); - void closeAllTabs(); - -signals: - void showCpu(); - -private: - ReferenceView* mCurrentReferenceView; - QPushButton* mCloseAllTabs; -}; - -#endif // REFERENCEMANAGER_H +#ifndef REFERENCEMANAGER_H +#define REFERENCEMANAGER_H + +#include +#include +#include "ReferenceView.h" + +class ReferenceManager : public QTabWidget +{ + Q_OBJECT +public: + explicit ReferenceManager(QWidget* parent = 0); + ReferenceView* currentReferenceView(); + +private slots: + void newReferenceView(QString name); + void closeTab(int index); + void closeAllTabs(); + +signals: + void showCpu(); + +private: + ReferenceView* mCurrentReferenceView; + QPushButton* mCloseAllTabs; +}; + +#endif // REFERENCEMANAGER_H diff --git a/src/gui/Src/Gui/RegistersView.cpp b/src/gui/Src/Gui/RegistersView.cpp index ef1732c5..7e746dc7 100644 --- a/src/gui/Src/Gui/RegistersView.cpp +++ b/src/gui/Src/Gui/RegistersView.cpp @@ -1,2465 +1,2465 @@ -#include "RegistersView.h" -#include -#include "Configuration.h" -#include "WordEditDialog.h" -#include "LineEditDialog.h" -#include "SelectFields.h" -#include -#include - -void RegistersView::SetChangeButton(QPushButton* push_button) -{ - mChangeViewButton = push_button; -} - -void RegistersView::InitMappings() -{ - // create mapping from internal id to name - mRegisterMapping.clear(); - mRegisterPlaces.clear(); - int offset = 0; - - /* Register_Position is a struct definition the position - * - * (line , start, labelwidth, valuesize ) - */ -#ifdef _WIN64 - mRegisterMapping.insert(CAX, "RAX"); - mRegisterPlaces.insert(CAX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CBX, "RBX"); - mRegisterPlaces.insert(CBX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CCX, "RCX"); - mRegisterPlaces.insert(CCX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CDX, "RDX"); - mRegisterPlaces.insert(CDX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CBP, "RBP"); - mRegisterPlaces.insert(CBP, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CSP, "RSP"); - mRegisterPlaces.insert(CSP, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CSI, "RSI"); - mRegisterPlaces.insert(CSI, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CDI, "RDI"); - mRegisterPlaces.insert(CDI, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - - offset++; - - mRegisterMapping.insert(R8, "R8"); - mRegisterPlaces.insert(R8 , Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(R9, "R9"); - mRegisterPlaces.insert(R9 , Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(R10, "R10"); - mRegisterPlaces.insert(R10, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(R11, "R11"); - mRegisterPlaces.insert(R11, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(R12, "R12"); - mRegisterPlaces.insert(R12, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(R13, "R13"); - mRegisterPlaces.insert(R13, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(R14, "R14"); - mRegisterPlaces.insert(R14, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(R15, "R15"); - mRegisterPlaces.insert(R15, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - - offset++; - - mRegisterMapping.insert(CIP, "RIP"); - mRegisterPlaces.insert(CIP, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - - offset++; - - mRegisterMapping.insert(EFLAGS, "RFLAGS"); - mRegisterPlaces.insert(EFLAGS, Register_Position(offset++, 0, 9, sizeof(duint) * 2)); -#else //x32 - mRegisterMapping.insert(CAX, "EAX"); - mRegisterPlaces.insert(CAX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CBX, "EBX"); - mRegisterPlaces.insert(CBX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CCX, "ECX"); - mRegisterPlaces.insert(CCX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CDX, "EDX"); - mRegisterPlaces.insert(CDX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CBP, "EBP"); - mRegisterPlaces.insert(CBP, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CSP, "ESP"); - mRegisterPlaces.insert(CSP, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CSI, "ESI"); - mRegisterPlaces.insert(CSI, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - mRegisterMapping.insert(CDI, "EDI"); - mRegisterPlaces.insert(CDI, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - - offset++; - - mRegisterMapping.insert(CIP, "EIP"); - mRegisterPlaces.insert(CIP, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); - - offset++; - - mRegisterMapping.insert(EFLAGS, "EFLAGS"); - mRegisterPlaces.insert(EFLAGS, Register_Position(offset++, 0, 9, sizeof(duint) * 2)); -#endif - - mRegisterMapping.insert(ZF, "ZF"); - mRegisterPlaces.insert(ZF, Register_Position(offset, 0, 3, 1)); - mRegisterMapping.insert(PF, "PF"); - mRegisterPlaces.insert(PF, Register_Position(offset, 6, 3, 1)); - mRegisterMapping.insert(AF, "AF"); - mRegisterPlaces.insert(AF, Register_Position(offset++, 12, 3, 1)); - - mRegisterMapping.insert(OF, "OF"); - mRegisterPlaces.insert(OF, Register_Position(offset, 0, 3, 1)); - mRegisterMapping.insert(SF, "SF"); - mRegisterPlaces.insert(SF, Register_Position(offset, 6, 3, 1)); - mRegisterMapping.insert(DF, "DF"); - mRegisterPlaces.insert(DF, Register_Position(offset++, 12, 3, 1)); - - mRegisterMapping.insert(CF, "CF"); - mRegisterPlaces.insert(CF, Register_Position(offset, 0, 3, 1)); - mRegisterMapping.insert(TF, "TF"); - mRegisterPlaces.insert(TF, Register_Position(offset, 6, 3, 1)); - mRegisterMapping.insert(IF, "IF"); - mRegisterPlaces.insert(IF, Register_Position(offset++, 12, 3, 1)); - - offset++; - - mRegisterMapping.insert(LastError, "LastError"); - mRegisterPlaces.insert(LastError, Register_Position(offset++, 0, 10, 20)); - - offset++; - - mRegisterMapping.insert(GS, "GS"); - mRegisterPlaces.insert(GS, Register_Position(offset, 0, 3, 4)); - mRegisterMapping.insert(FS, "FS"); - mRegisterPlaces.insert(FS, Register_Position(offset++, 9, 3, 4)); - mRegisterMapping.insert(ES, "ES"); - mRegisterPlaces.insert(ES, Register_Position(offset, 0, 3, 4)); - mRegisterMapping.insert(DS, "DS"); - mRegisterPlaces.insert(DS, Register_Position(offset++, 9, 3, 4)); - mRegisterMapping.insert(CS, "CS"); - mRegisterPlaces.insert(CS, Register_Position(offset, 0, 3, 4)); - mRegisterMapping.insert(SS, "SS"); - mRegisterPlaces.insert(SS, Register_Position(offset++, 9, 3, 4)); - - if(mShowFpu) - { - offset++; - - mRegisterMapping.insert(x87r0, "x87r0"); - mRegisterPlaces.insert(x87r0, Register_Position(offset++, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r1, "x87r1"); - mRegisterPlaces.insert(x87r1, Register_Position(offset++, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r2, "x87r2"); - mRegisterPlaces.insert(x87r2, Register_Position(offset++, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r3, "x87r3"); - mRegisterPlaces.insert(x87r3, Register_Position(offset++, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r4, "x87r4"); - mRegisterPlaces.insert(x87r4, Register_Position(offset++, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r5, "x87r5"); - mRegisterPlaces.insert(x87r5, Register_Position(offset++, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r6, "x87r6"); - mRegisterPlaces.insert(x87r6, Register_Position(offset++, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r7, "x87r7"); - mRegisterPlaces.insert(x87r7, Register_Position(offset++, 0, 6, 10 * 2)); - - offset++; - - mRegisterMapping.insert(x87TagWord, "x87TagWord"); - mRegisterPlaces.insert(x87TagWord, Register_Position(offset++, 0, 11, sizeof(WORD) * 2)); - - mRegisterMapping.insert(x87TW_0, "x87TW_0"); - mRegisterPlaces.insert(x87TW_0, Register_Position(offset, 0, 8, 10)); - mRegisterMapping.insert(x87TW_1, "x87TW_1"); - mRegisterPlaces.insert(x87TW_1, Register_Position(offset++, 20, 8, 10)); - - mRegisterMapping.insert(x87TW_2, "x87TW_2"); - mRegisterPlaces.insert(x87TW_2, Register_Position(offset, 0, 8, 10)); - mRegisterMapping.insert(x87TW_3, "x87TW_3"); - mRegisterPlaces.insert(x87TW_3, Register_Position(offset++, 20, 8, 10)); - - mRegisterMapping.insert(x87TW_4, "x87TW_4"); - mRegisterPlaces.insert(x87TW_4, Register_Position(offset, 0, 8, 10)); - mRegisterMapping.insert(x87TW_5, "x87TW_5"); - mRegisterPlaces.insert(x87TW_5, Register_Position(offset++, 20, 8, 10)); - - mRegisterMapping.insert(x87TW_6, "x87TW_6"); - mRegisterPlaces.insert(x87TW_6, Register_Position(offset, 0, 8, 10)); - mRegisterMapping.insert(x87TW_7, "x87TW_7"); - mRegisterPlaces.insert(x87TW_7, Register_Position(offset++, 20, 8, 10)); - - offset++; - - mRegisterMapping.insert(x87StatusWord, "x87StatusWord"); - mRegisterPlaces.insert(x87StatusWord, Register_Position(offset++, 0, 14, sizeof(WORD) * 2)); - - mRegisterMapping.insert(x87SW_B, "x87SW_B"); - mRegisterPlaces.insert(x87SW_B, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(x87SW_C3, "x87SW_C3"); - mRegisterPlaces.insert(x87SW_C3, Register_Position(offset, 12, 10, 1)); - mRegisterMapping.insert(x87SW_C2, "x87SW_C2"); - mRegisterPlaces.insert(x87SW_C2, Register_Position(offset++, 25, 10, 1)); - - mRegisterMapping.insert(x87SW_C1, "x87SW_C1"); - mRegisterPlaces.insert(x87SW_C1, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(x87SW_C0, "x87SW_C0"); - mRegisterPlaces.insert(x87SW_C0, Register_Position(offset, 12, 10, 1)); - mRegisterMapping.insert(x87SW_IR, "x87SW_IR"); - mRegisterPlaces.insert(x87SW_IR, Register_Position(offset++, 25, 10, 1)); - - mRegisterMapping.insert(x87SW_SF, "x87SW_SF"); - mRegisterPlaces.insert(x87SW_SF, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(x87SW_P, "x87SW_P"); - mRegisterPlaces.insert(x87SW_P, Register_Position(offset, 12, 10, 1)); - mRegisterMapping.insert(x87SW_U, "x87SW_U"); - mRegisterPlaces.insert(x87SW_U, Register_Position(offset++, 25, 10, 1)); - - mRegisterMapping.insert(x87SW_O, "x87SW_O"); - mRegisterPlaces.insert(x87SW_O, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(x87SW_Z, "x87SW_Z"); - mRegisterPlaces.insert(x87SW_Z, Register_Position(offset, 12, 10, 1)); - mRegisterMapping.insert(x87SW_D, "x87SW_D"); - mRegisterPlaces.insert(x87SW_D, Register_Position(offset++, 25, 10, 1)); - - mRegisterMapping.insert(x87SW_I, "x87SW_I"); - mRegisterPlaces.insert(x87SW_I, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(x87SW_TOP, "x87SW_TOP"); - mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset++, 12, 10, 13)); - - offset++; - - mRegisterMapping.insert(x87ControlWord, "x87ControlWord"); - mRegisterPlaces.insert(x87ControlWord, Register_Position(offset++, 0, 15, sizeof(WORD) * 2)); - - mRegisterMapping.insert(x87CW_IC, "x87CW_IC"); - mRegisterPlaces.insert(x87CW_IC, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(x87CW_IEM, "x87CW_IEM"); - mRegisterPlaces.insert(x87CW_IEM, Register_Position(offset, 12, 10, 1)); - mRegisterMapping.insert(x87CW_PM, "x87CW_PM"); - mRegisterPlaces.insert(x87CW_PM, Register_Position(offset++, 25, 10, 1)); - - mRegisterMapping.insert(x87CW_UM, "x87CW_UM"); - mRegisterPlaces.insert(x87CW_UM, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(x87CW_OM, "x87CW_OM"); - mRegisterPlaces.insert(x87CW_OM, Register_Position(offset, 12, 10, 1)); - mRegisterMapping.insert(x87CW_ZM, "x87CW_ZM"); - mRegisterPlaces.insert(x87CW_ZM, Register_Position(offset++, 25, 10, 1)); - - mRegisterMapping.insert(x87CW_DM, "x87CW_DM"); - mRegisterPlaces.insert(x87CW_DM, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(x87CW_IM, "x87CW_IM"); - mRegisterPlaces.insert(x87CW_IM, Register_Position(offset, 12, 10, 1)); - mRegisterMapping.insert(x87CW_RC, "x87CW_RC"); - mRegisterPlaces.insert(x87CW_RC, Register_Position(offset++, 25, 10, 14)); - - mRegisterMapping.insert(x87CW_PC, "x87CW_PC"); - mRegisterPlaces.insert(x87CW_PC, Register_Position(offset++, 0, 9, 14)); - - offset++; - - mRegisterMapping.insert(MxCsr, "MxCsr"); - mRegisterPlaces.insert(MxCsr, Register_Position(offset++, 0, 6, sizeof(DWORD) * 2)); - - mRegisterMapping.insert(MxCsr_FZ, "MxCsr_FZ"); - mRegisterPlaces.insert(MxCsr_FZ, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(MxCsr_PM, "MxCsr_PM"); - mRegisterPlaces.insert(MxCsr_PM, Register_Position(offset, 12, 10, 1)); - mRegisterMapping.insert(MxCsr_UM, "MxCsr_UM"); - mRegisterPlaces.insert(MxCsr_UM, Register_Position(offset++, 25, 10, 1)); - - mRegisterMapping.insert(MxCsr_OM, "MxCsr_OM"); - mRegisterPlaces.insert(MxCsr_OM, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(MxCsr_ZM, "MxCsr_ZM"); - mRegisterPlaces.insert(MxCsr_ZM, Register_Position(offset, 12, 10, 1)); - mRegisterMapping.insert(MxCsr_IM, "MxCsr_IM"); - mRegisterPlaces.insert(MxCsr_IM, Register_Position(offset++, 25, 10, 1)); - - mRegisterMapping.insert(MxCsr_UE, "MxCsr_UE"); - mRegisterPlaces.insert(MxCsr_UE, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(MxCsr_PE, "MxCsr_PE"); - mRegisterPlaces.insert(MxCsr_PE, Register_Position(offset, 12, 10, 1)); - mRegisterMapping.insert(MxCsr_DAZ, "MxCsr_DAZ"); - mRegisterPlaces.insert(MxCsr_DAZ, Register_Position(offset++, 25, 10, 1)); - - mRegisterMapping.insert(MxCsr_OE, "MxCsr_OE"); - mRegisterPlaces.insert(MxCsr_OE, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(MxCsr_ZE, "MxCsr_ZE"); - mRegisterPlaces.insert(MxCsr_ZE, Register_Position(offset, 12, 10, 1)); - mRegisterMapping.insert(MxCsr_DE, "MxCsr_DE"); - mRegisterPlaces.insert(MxCsr_DE, Register_Position(offset++, 25, 10, 1)); - - mRegisterMapping.insert(MxCsr_IE, "MxCsr_IE"); - mRegisterPlaces.insert(MxCsr_IE, Register_Position(offset, 0, 9, 1)); - mRegisterMapping.insert(MxCsr_DM, "MxCsr_DM"); - mRegisterPlaces.insert(MxCsr_DM, Register_Position(offset, 12, 10, 1)); - mRegisterMapping.insert(MxCsr_RC, "MxCsr_RC"); - mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset++, 25, 10, 19)); - - offset++; - - mRegisterMapping.insert(MM0, "MM0"); - mRegisterPlaces.insert(MM0, Register_Position(offset++, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM1, "MM1"); - mRegisterPlaces.insert(MM1, Register_Position(offset++, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM2, "MM2"); - mRegisterPlaces.insert(MM2, Register_Position(offset++, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM3, "MM3"); - mRegisterPlaces.insert(MM3, Register_Position(offset++, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM4, "MM4"); - mRegisterPlaces.insert(MM4, Register_Position(offset++, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM5, "MM5"); - mRegisterPlaces.insert(MM5, Register_Position(offset++, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM6, "MM6"); - mRegisterPlaces.insert(MM6, Register_Position(offset++, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM7, "MM7"); - mRegisterPlaces.insert(MM7, Register_Position(offset++, 0, 4, 8 * 2)); - - offset++; - - mRegisterMapping.insert(XMM0, "XMM0"); - mRegisterPlaces.insert(XMM0, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM1, "XMM1"); - mRegisterPlaces.insert(XMM1, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM2, "XMM2"); - mRegisterPlaces.insert(XMM2, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM3, "XMM3"); - mRegisterPlaces.insert(XMM3, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM4, "XMM4"); - mRegisterPlaces.insert(XMM4, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM5, "XMM5"); - mRegisterPlaces.insert(XMM5, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM6, "XMM6"); - mRegisterPlaces.insert(XMM6, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM7, "XMM7"); - mRegisterPlaces.insert(XMM7, Register_Position(offset++, 0, 6, 16 * 2)); -#ifdef _WIN64 - mRegisterMapping.insert(XMM8, "XMM8"); - mRegisterPlaces.insert(XMM8, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM9, "XMM9"); - mRegisterPlaces.insert(XMM9, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM10, "XMM10"); - mRegisterPlaces.insert(XMM10, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM11, "XMM11"); - mRegisterPlaces.insert(XMM11, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM12, "XMM12"); - mRegisterPlaces.insert(XMM12, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM13, "XMM13"); - mRegisterPlaces.insert(XMM13, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM14, "XMM14"); - mRegisterPlaces.insert(XMM14, Register_Position(offset++, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM15, "XMM15"); - mRegisterPlaces.insert(XMM15, Register_Position(offset++, 0, 6, 16 * 2)); -#endif - - offset++; - - mRegisterMapping.insert(YMM0, "YMM0"); - mRegisterPlaces.insert(YMM0, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM1, "YMM1"); - mRegisterPlaces.insert(YMM1, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM2, "YMM2"); - mRegisterPlaces.insert(YMM2, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM3, "YMM3"); - mRegisterPlaces.insert(YMM3, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM4, "YMM4"); - mRegisterPlaces.insert(YMM4, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM5, "YMM5"); - mRegisterPlaces.insert(YMM5, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM6, "YMM6"); - mRegisterPlaces.insert(YMM6, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM7, "YMM7"); - mRegisterPlaces.insert(YMM7, Register_Position(offset++, 0, 6, 32 * 2)); -#ifdef _WIN64 - mRegisterMapping.insert(YMM8, "YMM8"); - mRegisterPlaces.insert(YMM8, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM9, "YMM9"); - mRegisterPlaces.insert(YMM9, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM10, "YMM10"); - mRegisterPlaces.insert(YMM10, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM11, "YMM11"); - mRegisterPlaces.insert(YMM11, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM12, "YMM12"); - mRegisterPlaces.insert(YMM12, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM13, "YMM13"); - mRegisterPlaces.insert(YMM13, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM14, "YMM14"); - mRegisterPlaces.insert(YMM14, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM15, "YMM15"); - mRegisterPlaces.insert(YMM15, Register_Position(offset++, 0, 6, 32 * 2)); -#endif - } - - offset++; - - mRegisterMapping.insert(DR0, "DR0"); - mRegisterPlaces.insert(DR0, Register_Position(offset++, 0, 4, sizeof(duint) * 2)); - mRegisterMapping.insert(DR1, "DR1"); - mRegisterPlaces.insert(DR1, Register_Position(offset++, 0, 4, sizeof(duint) * 2)); - mRegisterMapping.insert(DR2, "DR2"); - mRegisterPlaces.insert(DR2, Register_Position(offset++, 0, 4, sizeof(duint) * 2)); - mRegisterMapping.insert(DR3, "DR3"); - mRegisterPlaces.insert(DR3, Register_Position(offset++, 0, 4, sizeof(duint) * 2)); - mRegisterMapping.insert(DR6, "DR6"); - mRegisterPlaces.insert(DR6, Register_Position(offset++, 0, 4, sizeof(duint) * 2)); - mRegisterMapping.insert(DR7, "DR7"); - mRegisterPlaces.insert(DR7, Register_Position(offset++, 0, 4, sizeof(duint) * 2)); - - mRowsNeeded = offset + 1; -} - -RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOffset(0) -{ - mChangeViewButton = NULL; - - // precreate ContextMenu Actions - wCM_Increment = new QAction(tr("Increment"), this); - wCM_Increment->setShortcutContext(Qt::WidgetShortcut); - this->addAction(wCM_Increment); - wCM_Decrement = new QAction(tr("Decrement"), this); - wCM_Decrement->setShortcutContext(Qt::WidgetShortcut); - this->addAction(wCM_Decrement); - wCM_Zero = new QAction(tr("Zero"), this); - wCM_Zero->setShortcutContext(Qt::WidgetShortcut); - this->addAction(wCM_Zero); - wCM_SetToOne = new QAction(tr("Set to 1"), this); - wCM_SetToOne->setShortcutContext(Qt::WidgetShortcut); - this->addAction(wCM_SetToOne); - wCM_Modify = new QAction(tr("Modify Value"), this); - wCM_Modify->setShortcut(QKeySequence(Qt::Key_Enter)); - wCM_ToggleValue = new QAction(tr("Toggle"), this); - wCM_ToggleValue->setShortcutContext(Qt::WidgetShortcut); - this->addAction(wCM_ToggleValue); - wCM_CopyToClipboard = new QAction(tr("Copy Value to Clipboard"), this); - wCM_CopyToClipboard->setShortcutContext(Qt::WidgetShortcut); - this->addAction(wCM_CopyToClipboard); - wCM_CopySymbolToClipboard = new QAction(tr("Copy Symbol Value to Clipboard"), this); - wCM_CopySymbolToClipboard->setShortcutContext(Qt::WidgetShortcut); - this->addAction(wCM_CopySymbolToClipboard); - wCM_FollowInDisassembly = new QAction(tr("Follow in Disassembler"), this); - wCM_FollowInDump = new QAction(tr("Follow in Dump"), this); - wCM_FollowInStack = new QAction("Follow in Stack", this); - wCM_Incrementx87Stack = new QAction(tr("Increment x87 Stack"), this); - wCM_Decrementx87Stack = new QAction("Decrement x87 Stack", this); - wCM_ChangeFPUView = new QAction("Change View", this); - - // general purposes register (we allow the user to modify the value) - mGPR.insert(CAX); - mCANSTOREADDRESS.insert(CAX); - mUINTDISPLAY.insert(CAX); - mLABELDISPLAY.insert(CAX); - mMODIFYDISPLAY.insert(CAX); - mINCREMENTDECREMET.insert(CAX); - mSETONEZEROTOGGLE.insert(CAX); - - mSETONEZEROTOGGLE.insert(CBX); - mINCREMENTDECREMET.insert(CBX); - mGPR.insert(CBX); - mUINTDISPLAY.insert(CBX); - mLABELDISPLAY.insert(CBX); - mMODIFYDISPLAY.insert(CBX); - mCANSTOREADDRESS.insert(CBX); - - mSETONEZEROTOGGLE.insert(CCX); - mINCREMENTDECREMET.insert(CCX); - mGPR.insert(CCX); - mUINTDISPLAY.insert(CCX); - mLABELDISPLAY.insert(CCX); - mMODIFYDISPLAY.insert(CCX); - mCANSTOREADDRESS.insert(CCX); - - mSETONEZEROTOGGLE.insert(CDX); - mINCREMENTDECREMET.insert(CDX); - mGPR.insert(CDX); - mUINTDISPLAY.insert(CDX); - mLABELDISPLAY.insert(CDX); - mMODIFYDISPLAY.insert(CDX); - mCANSTOREADDRESS.insert(CDX); - - mSETONEZEROTOGGLE.insert(CBP); - mINCREMENTDECREMET.insert(CBP); - mCANSTOREADDRESS.insert(CBP); - mGPR.insert(CBP); - mUINTDISPLAY.insert(CBP); - mLABELDISPLAY.insert(CBP); - mMODIFYDISPLAY.insert(CBP); - - mSETONEZEROTOGGLE.insert(CSP); - mINCREMENTDECREMET.insert(CSP); - mCANSTOREADDRESS.insert(CSP); - mGPR.insert(CSP); - mUINTDISPLAY.insert(CSP); - mLABELDISPLAY.insert(CSP); - mMODIFYDISPLAY.insert(CSP); - - mSETONEZEROTOGGLE.insert(CSI); - mINCREMENTDECREMET.insert(CSI); - mCANSTOREADDRESS.insert(CSI); - mGPR.insert(CSI); - mUINTDISPLAY.insert(CSI); - mLABELDISPLAY.insert(CSI); - mMODIFYDISPLAY.insert(CSI); - - mSETONEZEROTOGGLE.insert(CDI); - mINCREMENTDECREMET.insert(CDI); - mCANSTOREADDRESS.insert(CDI); - mGPR.insert(CDI); - mUINTDISPLAY.insert(CDI); - mLABELDISPLAY.insert(CDI); - mMODIFYDISPLAY.insert(CDI); - - mSETONEZEROTOGGLE.insert(R8); - mINCREMENTDECREMET.insert(R8); - mCANSTOREADDRESS.insert(R8); - mGPR.insert(R8); - mLABELDISPLAY.insert(R8); - mUINTDISPLAY.insert(R8); - mMODIFYDISPLAY.insert(R8); - - mSETONEZEROTOGGLE.insert(R9); - mINCREMENTDECREMET.insert(R9); - mCANSTOREADDRESS.insert(R9); - mGPR.insert(R9); - mLABELDISPLAY.insert(R9); - mUINTDISPLAY.insert(R9); - mMODIFYDISPLAY.insert(R9); - - mSETONEZEROTOGGLE.insert(R10); - mINCREMENTDECREMET.insert(R10); - mCANSTOREADDRESS.insert(R10); - mGPR.insert(R10); - mMODIFYDISPLAY.insert(R10); - mUINTDISPLAY.insert(R10); - mLABELDISPLAY.insert(R10); - - mSETONEZEROTOGGLE.insert(R11); - mINCREMENTDECREMET.insert(R11); - mCANSTOREADDRESS.insert(R11); - mGPR.insert(R11); - mMODIFYDISPLAY.insert(R11); - mUINTDISPLAY.insert(R11); - mLABELDISPLAY.insert(R11); - - mSETONEZEROTOGGLE.insert(R12); - mINCREMENTDECREMET.insert(R12); - mCANSTOREADDRESS.insert(R12); - mGPR.insert(R12); - mMODIFYDISPLAY.insert(R12); - mUINTDISPLAY.insert(R12); - mLABELDISPLAY.insert(R12); - - mSETONEZEROTOGGLE.insert(R13); - mINCREMENTDECREMET.insert(R13); - mCANSTOREADDRESS.insert(R13); - mGPR.insert(R13); - mMODIFYDISPLAY.insert(R13); - mUINTDISPLAY.insert(R13); - mLABELDISPLAY.insert(R13); - - mSETONEZEROTOGGLE.insert(R14); - mINCREMENTDECREMET.insert(R14); - mCANSTOREADDRESS.insert(R14); - mGPR.insert(R14); - mMODIFYDISPLAY.insert(R14); - mUINTDISPLAY.insert(R14); - mLABELDISPLAY.insert(R14); - - mSETONEZEROTOGGLE.insert(R15); - mINCREMENTDECREMET.insert(R15); - mCANSTOREADDRESS.insert(R15); - mGPR.insert(R15); - mMODIFYDISPLAY.insert(R15); - mUINTDISPLAY.insert(R15); - mLABELDISPLAY.insert(R15); - - mSETONEZEROTOGGLE.insert(EFLAGS); - mINCREMENTDECREMET.insert(EFLAGS); - mGPR.insert(EFLAGS); - mMODIFYDISPLAY.insert(EFLAGS); - mUINTDISPLAY.insert(EFLAGS); - - // flags (we allow the user to toggle them) - mFlags.insert(CF); - mBOOLDISPLAY.insert(CF); - mSETONEZEROTOGGLE.insert(CF); - - mSETONEZEROTOGGLE.insert(PF); - mFlags.insert(PF); - mBOOLDISPLAY.insert(PF); - - mSETONEZEROTOGGLE.insert(AF); - mFlags.insert(AF); - mBOOLDISPLAY.insert(AF); - - mSETONEZEROTOGGLE.insert(ZF); - mFlags.insert(ZF); - mBOOLDISPLAY.insert(ZF); - - mSETONEZEROTOGGLE.insert(SF); - mFlags.insert(SF); - mBOOLDISPLAY.insert(SF); - - mSETONEZEROTOGGLE.insert(TF); - mFlags.insert(TF); - mBOOLDISPLAY.insert(TF); - - mFlags.insert(IF); - mBOOLDISPLAY.insert(IF); - - mSETONEZEROTOGGLE.insert(DF); - mFlags.insert(DF); - mBOOLDISPLAY.insert(DF); - - mSETONEZEROTOGGLE.insert(OF); - mFlags.insert(OF); - mBOOLDISPLAY.insert(OF); - - // FPU: XMM, x87 and MMX registers - mSETONEZEROTOGGLE.insert(MxCsr); - mDWORDDISPLAY.insert(MxCsr); - mMODIFYDISPLAY.insert(MxCsr); - mFPU.insert(MxCsr); - - mMODIFYDISPLAY.insert(x87r0); - mFPUx87.insert(x87r0); - mFPUx87_80BITSDISPLAY.insert(x87r0); - mFPU.insert(x87r0); - - mMODIFYDISPLAY.insert(x87r1); - mFPUx87.insert(x87r1); - mFPUx87_80BITSDISPLAY.insert(x87r1); - mFPU.insert(x87r1); - - mMODIFYDISPLAY.insert(x87r2); - mFPUx87.insert(x87r2); - mFPUx87_80BITSDISPLAY.insert(x87r2); - mFPU.insert(x87r2); - - mMODIFYDISPLAY.insert(x87r3); - mFPUx87.insert(x87r3); - mFPUx87_80BITSDISPLAY.insert(x87r3); - mFPU.insert(x87r3); - - mMODIFYDISPLAY.insert(x87r4); - mFPUx87.insert(x87r4); - mFPUx87_80BITSDISPLAY.insert(x87r4); - mFPU.insert(x87r4); - - mMODIFYDISPLAY.insert(x87r5); - mFPUx87.insert(x87r5); - mFPU.insert(x87r5); - mFPUx87_80BITSDISPLAY.insert(x87r5); - - mMODIFYDISPLAY.insert(x87r6); - mFPUx87.insert(x87r6); - mFPU.insert(x87r6); - mFPUx87_80BITSDISPLAY.insert(x87r6); - - mMODIFYDISPLAY.insert(x87r7); - mFPUx87.insert(x87r7); - mFPU.insert(x87r7); - mFPUx87_80BITSDISPLAY.insert(x87r7); - - mSETONEZEROTOGGLE.insert(x87TagWord); - mFPUx87.insert(x87TagWord); - mMODIFYDISPLAY.insert(x87TagWord); - mUSHORTDISPLAY.insert(x87TagWord); - mFPU.insert(x87TagWord); - - mSETONEZEROTOGGLE.insert(x87StatusWord); - mUSHORTDISPLAY.insert(x87StatusWord); - mMODIFYDISPLAY.insert(x87StatusWord); - mFPUx87.insert(x87StatusWord); - mFPU.insert(x87StatusWord); - - mSETONEZEROTOGGLE.insert(x87ControlWord); - mFPUx87.insert(x87ControlWord); - mMODIFYDISPLAY.insert(x87ControlWord); - mUSHORTDISPLAY.insert(x87ControlWord); - mFPU.insert(x87ControlWord); - - mSETONEZEROTOGGLE.insert(x87SW_B); - mFPUx87.insert(x87SW_B); - mBOOLDISPLAY.insert(x87SW_B); - mFPU.insert(x87SW_B); - - mSETONEZEROTOGGLE.insert(x87SW_C3); - mFPUx87.insert(x87SW_C3); - mBOOLDISPLAY.insert(x87SW_C3); - mFPU.insert(x87SW_C3); - - mFPUx87.insert(x87SW_TOP); - mFIELDVALUE.insert(x87SW_TOP); - mFPU.insert(x87SW_TOP); - mMODIFYDISPLAY.insert(x87SW_TOP); - - mFPUx87.insert(x87SW_C2); - mBOOLDISPLAY.insert(x87SW_C2); - mSETONEZEROTOGGLE.insert(x87SW_C2); - mFPU.insert(x87SW_C2); - - mSETONEZEROTOGGLE.insert(x87SW_C1); - mFPUx87.insert(x87SW_C1); - mBOOLDISPLAY.insert(x87SW_C1); - mFPU.insert(x87SW_C1); - - mSETONEZEROTOGGLE.insert(x87SW_C0); - mFPUx87.insert(x87SW_C0); - mBOOLDISPLAY.insert(x87SW_C0); - mFPU.insert(x87SW_C0); - - mSETONEZEROTOGGLE.insert(x87SW_IR); - mFPUx87.insert(x87SW_IR); - mBOOLDISPLAY.insert(x87SW_IR); - mFPU.insert(x87SW_IR); - - mSETONEZEROTOGGLE.insert(x87SW_SF); - mFPUx87.insert(x87SW_SF); - mBOOLDISPLAY.insert(x87SW_SF); - mFPU.insert(x87SW_SF); - - mSETONEZEROTOGGLE.insert(x87SW_P); - mFPUx87.insert(x87SW_P); - mBOOLDISPLAY.insert(x87SW_P); - mFPU.insert(x87SW_P); - - mSETONEZEROTOGGLE.insert(x87SW_U); - mFPUx87.insert(x87SW_U); - mBOOLDISPLAY.insert(x87SW_U); - mFPU.insert(x87SW_U); - - mSETONEZEROTOGGLE.insert(x87SW_O); - mFPUx87.insert(x87SW_O); - mBOOLDISPLAY.insert(x87SW_O); - mFPU.insert(x87SW_O); - - mSETONEZEROTOGGLE.insert(x87SW_Z); - mFPUx87.insert(x87SW_Z); - mBOOLDISPLAY.insert(x87SW_Z); - mFPU.insert(x87SW_Z); - - mSETONEZEROTOGGLE.insert(x87SW_D); - mFPUx87.insert(x87SW_D); - mBOOLDISPLAY.insert(x87SW_D); - mFPU.insert(x87SW_D); - - mSETONEZEROTOGGLE.insert(x87SW_I); - mFPUx87.insert(x87SW_I); - mBOOLDISPLAY.insert(x87SW_I); - mFPU.insert(x87SW_I); - - mSETONEZEROTOGGLE.insert(x87CW_IC); - mFPUx87.insert(x87CW_IC); - mBOOLDISPLAY.insert(x87CW_IC); - mFPU.insert(x87CW_IC); - - mFPUx87.insert(x87CW_RC); - mFIELDVALUE.insert(x87CW_RC); - mFPU.insert(x87CW_RC); - mMODIFYDISPLAY.insert(x87CW_RC); - - mFPUx87.insert(x87TW_0); - mFIELDVALUE.insert(x87TW_0); - mTAGWORD.insert(x87TW_0); - mFPU.insert(x87TW_0); - mMODIFYDISPLAY.insert(x87TW_0); - - mFPUx87.insert(x87TW_1); - mFIELDVALUE.insert(x87TW_1); - mTAGWORD.insert(x87TW_1); - mFPU.insert(x87TW_1); - mMODIFYDISPLAY.insert(x87TW_1); - - mFPUx87.insert(x87TW_2); - mFIELDVALUE.insert(x87TW_2); - mTAGWORD.insert(x87TW_2); - mFPU.insert(x87TW_2); - mMODIFYDISPLAY.insert(x87TW_2); - - mFPUx87.insert(x87TW_3); - mFIELDVALUE.insert(x87TW_3); - mTAGWORD.insert(x87TW_3); - mFPU.insert(x87TW_3); - mMODIFYDISPLAY.insert(x87TW_3); - - mFPUx87.insert(x87TW_4); - mFIELDVALUE.insert(x87TW_4); - mTAGWORD.insert(x87TW_4); - mFPU.insert(x87TW_4); - mMODIFYDISPLAY.insert(x87TW_4); - - mFPUx87.insert(x87TW_5); - mFIELDVALUE.insert(x87TW_5); - mTAGWORD.insert(x87TW_5); - mFPU.insert(x87TW_5); - mMODIFYDISPLAY.insert(x87TW_5); - - mFPUx87.insert(x87TW_6); - mFIELDVALUE.insert(x87TW_6); - mTAGWORD.insert(x87TW_6); - mFPU.insert(x87TW_6); - mMODIFYDISPLAY.insert(x87TW_6); - - mFPUx87.insert(x87TW_7); - mFIELDVALUE.insert(x87TW_7); - mTAGWORD.insert(x87TW_7); - mFPU.insert(x87TW_7); - mMODIFYDISPLAY.insert(x87TW_7); - - mFPUx87.insert(x87CW_PC); - mFIELDVALUE.insert(x87CW_PC); - mFPU.insert(x87CW_PC); - mMODIFYDISPLAY.insert(x87CW_PC); - - mSETONEZEROTOGGLE.insert(x87CW_IEM); - mFPUx87.insert(x87CW_IEM); - mBOOLDISPLAY.insert(x87CW_IEM); - mFPU.insert(x87CW_IEM); - - mSETONEZEROTOGGLE.insert(x87CW_PM); - mFPUx87.insert(x87CW_PM); - mBOOLDISPLAY.insert(x87CW_PM); - mFPU.insert(x87CW_PM); - - mSETONEZEROTOGGLE.insert(x87CW_UM); - mFPUx87.insert(x87CW_UM); - mBOOLDISPLAY.insert(x87CW_UM); - mFPU.insert(x87CW_UM); - - mSETONEZEROTOGGLE.insert(x87CW_OM); - mFPUx87.insert(x87CW_OM); - mBOOLDISPLAY.insert(x87CW_OM); - mFPU.insert(x87CW_OM); - - mSETONEZEROTOGGLE.insert(x87CW_ZM); - mFPUx87.insert(x87CW_ZM); - mBOOLDISPLAY.insert(x87CW_ZM); - mFPU.insert(x87CW_ZM); - - mSETONEZEROTOGGLE.insert(x87CW_DM); - mFPUx87.insert(x87CW_DM); - mBOOLDISPLAY.insert(x87CW_DM); - mFPU.insert(x87CW_DM); - - mSETONEZEROTOGGLE.insert(x87CW_IM); - mFPUx87.insert(x87CW_IM); - mBOOLDISPLAY.insert(x87CW_IM); - mFPU.insert(x87CW_IM); - - mSETONEZEROTOGGLE.insert(MxCsr_FZ); - mBOOLDISPLAY.insert(MxCsr_FZ); - mFPU.insert(MxCsr_FZ); - - mSETONEZEROTOGGLE.insert(MxCsr_PM); - mBOOLDISPLAY.insert(MxCsr_PM); - mFPU.insert(MxCsr_PM); - - mSETONEZEROTOGGLE.insert(MxCsr_UM); - mBOOLDISPLAY.insert(MxCsr_UM); - mFPU.insert(MxCsr_UM); - - mSETONEZEROTOGGLE.insert(MxCsr_OM); - mBOOLDISPLAY.insert(MxCsr_OM); - mFPU.insert(MxCsr_OM); - - mSETONEZEROTOGGLE.insert(MxCsr_ZM); - mBOOLDISPLAY.insert(MxCsr_ZM); - mFPU.insert(MxCsr_ZM); - - mSETONEZEROTOGGLE.insert(MxCsr_IM); - mBOOLDISPLAY.insert(MxCsr_IM); - mFPU.insert(MxCsr_IM); - - mSETONEZEROTOGGLE.insert(MxCsr_DM); - mBOOLDISPLAY.insert(MxCsr_DM); - mFPU.insert(MxCsr_DM); - - mSETONEZEROTOGGLE.insert(MxCsr_DAZ); - mBOOLDISPLAY.insert(MxCsr_DAZ); - mFPU.insert(MxCsr_DAZ); - - mSETONEZEROTOGGLE.insert(MxCsr_PE); - mBOOLDISPLAY.insert(MxCsr_PE); - mFPU.insert(MxCsr_PE); - - mSETONEZEROTOGGLE.insert(MxCsr_UE); - mBOOLDISPLAY.insert(MxCsr_UE); - mFPU.insert(MxCsr_UE); - - mSETONEZEROTOGGLE.insert(MxCsr_OE); - mBOOLDISPLAY.insert(MxCsr_OE); - mFPU.insert(MxCsr_OE); - - mSETONEZEROTOGGLE.insert(MxCsr_ZE); - mBOOLDISPLAY.insert(MxCsr_ZE); - mFPU.insert(MxCsr_ZE); - - mSETONEZEROTOGGLE.insert(MxCsr_DE); - mBOOLDISPLAY.insert(MxCsr_DE); - mFPU.insert(MxCsr_DE); - - mSETONEZEROTOGGLE.insert(MxCsr_IE); - mBOOLDISPLAY.insert(MxCsr_IE); - mFPU.insert(MxCsr_IE); - - mFIELDVALUE.insert(MxCsr_RC); - mFPU.insert(MxCsr_RC); - mMODIFYDISPLAY.insert(MxCsr_RC); - - mMODIFYDISPLAY.insert(MM0); - mFPUMMX.insert(MM0); - mFPU.insert(MM0); - mMODIFYDISPLAY.insert(MM1); - mFPUMMX.insert(MM1); - mFPU.insert(MM1); - mFPUMMX.insert(MM2); - mMODIFYDISPLAY.insert(MM2); - mFPU.insert(MM2); - mFPUMMX.insert(MM3); - mMODIFYDISPLAY.insert(MM3); - mFPU.insert(MM3); - mFPUMMX.insert(MM4); - mMODIFYDISPLAY.insert(MM4); - mFPU.insert(MM4); - mFPUMMX.insert(MM5); - mMODIFYDISPLAY.insert(MM5); - mFPU.insert(MM5); - mFPUMMX.insert(MM6); - mMODIFYDISPLAY.insert(MM6); - mFPU.insert(MM6); - mFPUMMX.insert(MM7); - mMODIFYDISPLAY.insert(MM7); - mFPU.insert(MM7); - - mFPUXMM.insert(XMM0); - mMODIFYDISPLAY.insert(XMM0); - mFPU.insert(XMM0); - mFPUXMM.insert(XMM1); - mMODIFYDISPLAY.insert(XMM1); - mFPU.insert(XMM1); - mFPUXMM.insert(XMM2); - mMODIFYDISPLAY.insert(XMM2); - mFPU.insert(XMM2); - mFPUXMM.insert(XMM3); - mMODIFYDISPLAY.insert(XMM3); - mFPU.insert(XMM3); - mFPUXMM.insert(XMM4); - mMODIFYDISPLAY.insert(XMM4); - mFPU.insert(XMM4); - mFPUXMM.insert(XMM5); - mMODIFYDISPLAY.insert(XMM5); - mFPU.insert(XMM5); - mFPUXMM.insert(XMM6); - mMODIFYDISPLAY.insert(XMM6); - mFPU.insert(XMM6); - mFPUXMM.insert(XMM7); - mMODIFYDISPLAY.insert(XMM7); - mFPU.insert(XMM7); -#ifdef _WIN64 - mFPUXMM.insert(XMM8); - mMODIFYDISPLAY.insert(XMM8); - mFPU.insert(XMM8); - mFPUXMM.insert(XMM9); - mMODIFYDISPLAY.insert(XMM9); - mFPU.insert(XMM9); - mFPUXMM.insert(XMM10); - mMODIFYDISPLAY.insert(XMM10); - mFPU.insert(XMM10); - mFPUXMM.insert(XMM11); - mMODIFYDISPLAY.insert(XMM11); - mFPU.insert(XMM11); - mFPUXMM.insert(XMM12); - mMODIFYDISPLAY.insert(XMM12); - mFPU.insert(XMM12); - mFPUXMM.insert(XMM13); - mMODIFYDISPLAY.insert(XMM13); - mFPU.insert(XMM13); - mFPUXMM.insert(XMM14); - mMODIFYDISPLAY.insert(XMM14); - mFPU.insert(XMM14); - mFPUXMM.insert(XMM15); - mMODIFYDISPLAY.insert(XMM15); - mFPU.insert(XMM15); -#endif - - mFPUYMM.insert(YMM0); - mMODIFYDISPLAY.insert(YMM0); - mFPU.insert(YMM0); - mFPUYMM.insert(YMM1); - mMODIFYDISPLAY.insert(YMM1); - mFPU.insert(YMM1); - mFPUYMM.insert(YMM2); - mMODIFYDISPLAY.insert(YMM2); - mFPU.insert(YMM2); - mFPUYMM.insert(YMM3); - mMODIFYDISPLAY.insert(YMM3); - mFPU.insert(YMM3); - mFPUYMM.insert(YMM4); - mMODIFYDISPLAY.insert(YMM4); - mFPU.insert(YMM4); - mFPUYMM.insert(YMM5); - mMODIFYDISPLAY.insert(YMM5); - mFPU.insert(YMM5); - mFPUYMM.insert(YMM6); - mMODIFYDISPLAY.insert(YMM6); - mFPU.insert(YMM6); - mFPUYMM.insert(YMM7); - mMODIFYDISPLAY.insert(YMM7); - mFPU.insert(YMM7); - -#ifdef _WIN64 - mFPUYMM.insert(YMM8); - mMODIFYDISPLAY.insert(YMM8); - mFPU.insert(YMM8); - mFPUYMM.insert(YMM9); - mMODIFYDISPLAY.insert(YMM9); - mFPU.insert(YMM9); - mFPUYMM.insert(YMM10); - mMODIFYDISPLAY.insert(YMM10); - mFPU.insert(YMM10); - mFPUYMM.insert(YMM11); - mMODIFYDISPLAY.insert(YMM11); - mFPU.insert(YMM11); - mFPUYMM.insert(YMM12); - mMODIFYDISPLAY.insert(YMM12); - mFPU.insert(YMM12); - mFPUYMM.insert(YMM13); - mMODIFYDISPLAY.insert(YMM13); - mFPU.insert(YMM13); - mFPUYMM.insert(YMM14); - mMODIFYDISPLAY.insert(YMM14); - mFPU.insert(YMM14); - mFPUYMM.insert(YMM15); - mMODIFYDISPLAY.insert(YMM15); - mFPU.insert(YMM15); -#endif - //registers that should not be changed - mNoChange.insert(LastError); - - mNoChange.insert(GS); - mUSHORTDISPLAY.insert(GS); - - mNoChange.insert(FS); - mUSHORTDISPLAY.insert(FS); - - mNoChange.insert(ES); - mUSHORTDISPLAY.insert(ES); - - mNoChange.insert(DS); - mUSHORTDISPLAY.insert(DS); - - mNoChange.insert(CS); - mUSHORTDISPLAY.insert(CS); - - mNoChange.insert(SS); - mUSHORTDISPLAY.insert(SS); - - mNoChange.insert(DR0); - mUINTDISPLAY.insert(DR0); - mLABELDISPLAY.insert(DR0); - mONLYMODULEANDLABELDISPLAY.insert(DR0); - mCANSTOREADDRESS.insert(DR0); - - mNoChange.insert(DR1); - mONLYMODULEANDLABELDISPLAY.insert(DR1); - mUINTDISPLAY.insert(DR1); - mCANSTOREADDRESS.insert(DR1); - - mLABELDISPLAY.insert(DR2); - mONLYMODULEANDLABELDISPLAY.insert(DR2); - mNoChange.insert(DR2); - mUINTDISPLAY.insert(DR2); - mCANSTOREADDRESS.insert(DR2); - - mNoChange.insert(DR3); - mONLYMODULEANDLABELDISPLAY.insert(DR3); - mLABELDISPLAY.insert(DR3); - mUINTDISPLAY.insert(DR3); - mCANSTOREADDRESS.insert(DR3); - - mNoChange.insert(DR6); - mLABELDISPLAY.insert(DR6); - mONLYMODULEANDLABELDISPLAY.insert(DR6); - mUINTDISPLAY.insert(DR6); - mCANSTOREADDRESS.insert(DR6); - - mNoChange.insert(DR7); - mUINTDISPLAY.insert(DR7); - mONLYMODULEANDLABELDISPLAY.insert(DR7); - mCANSTOREADDRESS.insert(DR7); - mLABELDISPLAY.insert(DR7); - - mNoChange.insert(CIP); - mUINTDISPLAY.insert(CIP); - mLABELDISPLAY.insert(CIP); - mONLYMODULEANDLABELDISPLAY.insert(CIP); - mCANSTOREADDRESS.insert(CIP); - - InitMappings(); - - fontsUpdatedSlot(); - connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot())); - - memset(&wRegDumpStruct, 0, sizeof(REGDUMP)); - memset(&wCipRegDumpStruct, 0, sizeof(REGDUMP)); - mCip = 0; - mRegisterUpdates.clear(); - - mButtonHeight = 0; - yTopSpacing = 4; //set top spacing (in pixels) - - // Context Menu - this->setContextMenuPolicy(Qt::CustomContextMenu); - // foreign messages - connect(Bridge::getBridge(), SIGNAL(updateRegisters()), this, SLOT(updateRegistersSlot())); - connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(displayCustomContextMenuSlot(QPoint))); - connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE))); - // self communication for repainting (maybe some other widgets needs this information, too) - connect(this, SIGNAL(refresh()), this, SLOT(repaint())); - // context menu actions - connect(wCM_Increment, SIGNAL(triggered()), this, SLOT(onIncrementAction())); - connect(wCM_ChangeFPUView, SIGNAL(triggered()), this, SLOT(onChangeFPUViewAction())); - connect(wCM_Decrement, SIGNAL(triggered()), this, SLOT(onDecrementAction())); - connect(wCM_Incrementx87Stack, SIGNAL(triggered()), this, SLOT(onIncrementx87StackAction())); - connect(wCM_Decrementx87Stack, SIGNAL(triggered()), this, SLOT(onDecrementx87StackAction())); - connect(wCM_Zero, SIGNAL(triggered()), this, SLOT(onZeroAction())); - connect(wCM_SetToOne, SIGNAL(triggered()), this, SLOT(onSetToOneAction())); - connect(wCM_Modify, SIGNAL(triggered()), this, SLOT(onModifyAction())); - connect(wCM_ToggleValue, SIGNAL(triggered()), this, SLOT(onToggleValueAction())); - connect(wCM_CopyToClipboard, SIGNAL(triggered()), this, SLOT(onCopyToClipboardAction())); - connect(wCM_CopySymbolToClipboard, SIGNAL(triggered()), this, SLOT(onCopySymbolToClipboardAction())); - connect(wCM_FollowInDisassembly, SIGNAL(triggered()), this, SLOT(onFollowInDisassembly())); - connect(wCM_FollowInDump, SIGNAL(triggered()), this, SLOT(onFollowInDump())); - connect(wCM_FollowInStack, SIGNAL(triggered()), this, SLOT(onFollowInStack())); - - refreshShortcutsSlot(); - connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); -} - -void RegistersView::refreshShortcutsSlot() -{ - wCM_Increment->setShortcut(ConfigShortcut("ActionIncreaseRegister")); - wCM_Decrement->setShortcut(ConfigShortcut("ActionDecreaseRegister")); - wCM_Zero->setShortcut(ConfigShortcut("ActionZeroRegister")); - wCM_SetToOne->setShortcut(ConfigShortcut("ActionSetOneRegister")); - wCM_ToggleValue->setShortcut(ConfigShortcut("ActionToggleRegisterValue")); - wCM_CopyToClipboard->setShortcut(ConfigShortcut("ActionCopy")); - wCM_CopySymbolToClipboard->setShortcut(ConfigShortcut("ActionCopySymbol")); -} - -RegistersView::~RegistersView() -{ -} - -void RegistersView::fontsUpdatedSlot() -{ - setFont(ConfigFont("Registers")); - int wRowsHeight = QFontMetrics(this->font()).height(); - wRowsHeight = (wRowsHeight * 105) / 100; - wRowsHeight = (wRowsHeight % 2) == 0 ? wRowsHeight : wRowsHeight + 1; - mRowHeight = wRowsHeight; - mCharWidth = QFontMetrics(this->font()).averageCharWidth(); - repaint(); -} - -void RegistersView::ShowFPU(bool set_showfpu) -{ - mShowFpu = set_showfpu; - InitMappings(); - repaint(); -} - - -/** - * @brief retrieves the register id from given corrdinates of the viewport - * @param line - * @param offset (x-coord) - * @param resulting register-id - * @return true if register found - */ -bool RegistersView::identifyRegister(const int line, const int offset, REGISTER_NAME* clickedReg) -{ - // we start by an unknown register id - if(clickedReg) - *clickedReg = UNKNOWN; - bool found_flag = false; - QMap::const_iterator it = mRegisterPlaces.begin(); - // iterate all registers that being displayed - while(it != mRegisterPlaces.end()) - { - if((it.value().line == (line - mVScrollOffset)) /* same line ? */ - && ((1 + it.value().start) <= offset) /* between start ... ? */ - && (offset <= (1 + it.value().start + it.value().labelwidth + it.value().valuesize)) /* ... and end ? */ - ) - { - // we found a matching register in the viewport - if(clickedReg) - *clickedReg = (REGISTER_NAME)it.key(); - found_flag = true; - break; - - } - ++it; - } - return found_flag; -} - -void RegistersView::mousePressEvent(QMouseEvent* event) -{ - if(!DbgIsDebugging()) - return; - - if(event->y() < yTopSpacing - mButtonHeight) - { - onChangeFPUViewAction(); - } - else - { - // get mouse position - const int y = (event->y() - yTopSpacing) / (double)mRowHeight; - const int x = event->x() / (double)mCharWidth; - - REGISTER_NAME r; - // do we find a corresponding register? - if(identifyRegister(y, x, &r)) - { - mSelected = r; - emit refresh(); - } - else - mSelected = UNKNOWN; - } -} - -void RegistersView::mouseDoubleClickEvent(QMouseEvent* event) -{ - Q_UNUSED(event); - if(!DbgIsDebugging() || event->button() != Qt::LeftButton) - return; - // get mouse position - const int y = (event->y() - yTopSpacing) / (double)mRowHeight; - const int x = event->x() / (double)mCharWidth; - - // do we find a corresponding register? - if(!identifyRegister(y, x, 0)) - return; - // is current register general purposes register or FPU register? - if(mMODIFYDISPLAY.contains(mSelected)) - { - wCM_Modify->trigger(); - } - else if(mBOOLDISPLAY.contains(mSelected)) // is flag ? - wCM_ToggleValue->trigger(); - else if(mSelected == CIP) //double clicked on CIP register - DbgCmdExec("disasm cip"); -} - -void RegistersView::paintEvent(QPaintEvent* event) -{ - Q_UNUSED(event); - - if(mChangeViewButton != NULL) - { - if(mShowFpu) - mChangeViewButton->setText("Hide FPU"); - else - mChangeViewButton->setText("Show FPU"); - } - - QPainter wPainter(this->viewport()); - wPainter.fillRect(wPainter.viewport(), QBrush(ConfigColor("RegistersBackgroundColor"))); - - // Don't draw the registers if a program isn't actually running - if(!DbgIsDebugging()) - return; - - // Iterate all registers - for(auto itr = mRegisterMapping.begin(); itr != mRegisterMapping.end(); itr++) - { - // Paint register at given position - drawRegister(&wPainter, itr.key(), registerValue(&wRegDumpStruct, itr.key())); - } -} - -void RegistersView::keyPressEvent(QKeyEvent* event) -{ - if(!DbgIsDebugging()) - return; - if(event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) - wCM_Modify->trigger(); -} - -QSize RegistersView::sizeHint() const -{ - // 32 character width - return QSize(32 * mCharWidth , this->viewport()->height()); -} - -void* RegistersView::operator new(size_t size) -{ - return _aligned_malloc(size, 16); -} - -void RegistersView::operator delete(void* p) -{ - _aligned_free(p); -} - -QString RegistersView::getRegisterLabel(REGISTER_NAME register_selected) -{ - char label_text[MAX_LABEL_SIZE] = ""; - char module_text[MAX_MODULE_SIZE] = ""; - char string_text[MAX_STRING_SIZE] = ""; - - QString valueText = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, register_selected))), mRegisterPlaces[register_selected].valuesize, 16, QChar('0')).toUpper(); - duint register_value = (* ((duint*) registerValue(&wRegDumpStruct, register_selected))); - QString newText = QString(""); - - bool hasString = DbgGetStringAt(register_value, string_text); - bool hasLabel = DbgGetLabelAt(register_value, SEG_DEFAULT, label_text); - bool hasModule = DbgGetModuleAt(register_value, module_text); - - if(hasString && !mONLYMODULEANDLABELDISPLAY.contains(register_selected)) - { - newText = string_text; - } - else if(hasLabel && hasModule) - { - newText = "<" + QString(module_text) + "." + QString(label_text) + ">"; - } - else if(hasModule) - { - newText = QString(module_text) + "." + valueText; - } - else if(hasLabel) - { - newText = "<" + QString(label_text) + ">"; - } - else if(!mONLYMODULEANDLABELDISPLAY.contains(register_selected)) - { - bool isCharacter = false; - if(register_value == (register_value & 0xFF)) - { - QChar c = QChar((char)register_value); - if(c.isPrint()) - { - newText = QString("'%1'").arg((char)register_value); - isCharacter = IsCharacterRegister(register_selected); - } - } - else if(register_value == (register_value & 0xFFF)) //UNICODE? - { - QChar c = QChar((wchar_t)register_value); - if(c.isPrint()) - { - newText = "L'" + QString(c) + "'"; - isCharacter = IsCharacterRegister(register_selected); - } - } - } - - return newText; -} - -double readFloat80(const uint8_t buffer[10]) -{ - /* - * WE ARE LOSSING 2 BYTES WITH THIS FUNCTION. - * TODO: CHANGE THIS FOR ONE BETTER. - */ - //80 bit floating point value according to IEEE-754: - //1 bit sign, 15 bit exponent, 64 bit mantissa - - const uint16_t SIGNBIT = 1 << 15; - const uint16_t EXP_BIAS = (1 << 14) - 1; // 2^(n-1) - 1 = 16383 - const uint16_t SPECIALEXP = (1 << 15) - 1; // all bits set - const uint64_t HIGHBIT = (uint64_t)1 << 63; - const uint64_t QUIETBIT = (uint64_t)1 << 62; - - // Extract sign, exponent and mantissa - uint16_t exponent = *((uint16_t*)&buffer[8]); - uint64_t mantissa = *((uint64_t*)&buffer[0]); - - double sign = (exponent & SIGNBIT) ? -1.0 : 1.0; - exponent &= ~SIGNBIT; - - // Check for undefined values - if((!exponent && (mantissa & HIGHBIT)) || (exponent && !(mantissa & HIGHBIT))) - { - return std::numeric_limits::quiet_NaN(); - } - - // Check for special values (infinity, NaN) - if(exponent == 0) - { - if(mantissa == 0) - { - return sign * 0.0; - } - else - { - // denormalized - } - } - else if(exponent == SPECIALEXP) - { - if(!(mantissa & ~HIGHBIT)) - { - return sign * std::numeric_limits::infinity(); - } - else - { - if(mantissa & QUIETBIT) - { - return std::numeric_limits::quiet_NaN(); - } - else - { - return std::numeric_limits::signaling_NaN(); - } - } - } - - //value = (-1)^s * (m / 2^63) * 2^(e - 16383) - double significand = ((double)mantissa / ((uint64_t)1 << 63)); - return sign * ldexp(significand, exponent - EXP_BIAS); -} - -QString RegistersView::GetRegStringValueFromValue(REGISTER_NAME reg, char* value) -{ - QString valueText; - - if(mUINTDISPLAY.contains(reg)) - valueText = QString("%1").arg((* ((duint*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); - else if(mUSHORTDISPLAY.contains(reg)) - valueText = QString("%1").arg((* ((unsigned short*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); - else if(mDWORDDISPLAY.contains(reg)) - valueText = QString("%1").arg((* ((DWORD*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); - else if(mBOOLDISPLAY.contains(reg)) - valueText = QString("%1").arg((* ((bool*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); - else if(mFIELDVALUE.contains(reg)) - { - if(mTAGWORD.contains(reg)) - { - valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); - valueText += QString(" ("); - valueText += GetTagWordStateString((* ((unsigned short*) value))); - valueText += QString(")"); - } - if(reg == MxCsr_RC) - { - valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); - valueText += QString(" ("); - valueText += GetMxCsrRCStateString((* ((unsigned short*) value))); - valueText += QString(")"); - } - else if(reg == x87CW_RC) - { - valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); - valueText += QString(" ("); - valueText += GetControlWordRCStateString((* ((unsigned short*) value))); - valueText += QString(")"); - } - else if(reg == x87CW_PC) - { - valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); - valueText += QString(" ("); - valueText += GetControlWordPCStateString((* ((unsigned short*) value))); - valueText += QString(")"); - } - else if(reg == x87SW_TOP) - { - valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); - valueText += QString(" (ST0="); - valueText += GetStatusWordTOPStateString((* ((unsigned short*) value))); - valueText += QString(")"); - } - } - else if(reg == LastError) - { - LASTERROR* data = (LASTERROR*)value; - if(data->name) - valueText = QString().sprintf("%08X (%s)", data->code, data->name); - else - valueText = QString().sprintf("%08X", data->code); - mRegisterPlaces[LastError].valuesize = valueText.length(); - } - else - { - SIZE_T size = GetSizeRegister(reg); - if(size != 0) - valueText = QString(QByteArray(value, size).toHex()).toUpper(); - else - valueText = QString("???"); - } - - return valueText; -} - -#define MxCsr_RC_NEAR 0 -#define MxCsr_RC_NEGATIVE 1 -#define MxCsr_RC_POSITIVE 2 -#define MxCsr_RC_TOZERO 3 - -STRING_VALUE_TABLE_t MxCsrRCValueStringTable[] = -{ - {"Toward Zero", MxCsr_RC_TOZERO}, - {"Toward Positive", MxCsr_RC_POSITIVE}, - {"Toward Negative", MxCsr_RC_NEGATIVE}, - {"Round Near", MxCsr_RC_NEAR} -}; - -unsigned int RegistersView::GetMxCsrRCValueFromString(QString string) -{ - int i; - - for(i = 0; i < (sizeof(MxCsrRCValueStringTable) / sizeof(*MxCsrRCValueStringTable)); i++) - { - if(MxCsrRCValueStringTable[i].string == string) - return MxCsrRCValueStringTable[i].value; - } - - return i; -} - -QString RegistersView::GetMxCsrRCStateString(unsigned short state) -{ - int i; - - for(i = 0; i < (sizeof(MxCsrRCValueStringTable) / sizeof(*MxCsrRCValueStringTable)); i++) - { - if(MxCsrRCValueStringTable[i].value == state) - return MxCsrRCValueStringTable[i].string; - } - - return "Unknown"; -} - -#define x87CW_RC_NEAR 0 -#define x87CW_RC_DOWN 1 -#define x87CW_RC_UP 2 -#define x87CW_RC_TRUNCATE 3 - -STRING_VALUE_TABLE_t ControlWordRCValueStringTable[] = -{ - {"Truncate", x87CW_RC_TRUNCATE}, - {"Round Up", x87CW_RC_UP}, - {"Round Down", x87CW_RC_DOWN}, - {"Round Near", x87CW_RC_NEAR} -}; - -unsigned int RegistersView::GetControlWordRCValueFromString(QString string) -{ - int i; - - for(i = 0; i < (sizeof(ControlWordRCValueStringTable) / sizeof(*ControlWordRCValueStringTable)); i++) - { - if(ControlWordRCValueStringTable[i].string == string) - return ControlWordRCValueStringTable[i].value; - } - - return i; -} - -QString RegistersView::GetControlWordRCStateString(unsigned short state) -{ - int i; - - for(i = 0; i < (sizeof(ControlWordRCValueStringTable) / sizeof(*ControlWordRCValueStringTable)); i++) - { - if(ControlWordRCValueStringTable[i].value == state) - return ControlWordRCValueStringTable[i].string; - } - - return "unknown"; -} - -#define x87SW_TOP_0 0 -#define x87SW_TOP_1 1 -#define x87SW_TOP_2 2 -#define x87SW_TOP_3 3 -#define x87SW_TOP_4 4 -#define x87SW_TOP_5 5 -#define x87SW_TOP_6 6 -#define x87SW_TOP_7 7 - -STRING_VALUE_TABLE_t StatusWordTOPValueStringTable[] = -{ - {"x87r0", x87SW_TOP_0}, - {"x87r1", x87SW_TOP_1}, - {"x87r2", x87SW_TOP_2}, - {"x87r3", x87SW_TOP_3}, - {"x87r4", x87SW_TOP_4}, - {"x87r5", x87SW_TOP_5}, - {"x87r6", x87SW_TOP_6}, - {"x87r7", x87SW_TOP_7} -}; - -unsigned int RegistersView::GetStatusWordTOPValueFromString(QString string) -{ - int i; - - for(i = 0; i < (sizeof(StatusWordTOPValueStringTable) / sizeof(*StatusWordTOPValueStringTable)); i++) - { - if(StatusWordTOPValueStringTable[i].string == string) - return StatusWordTOPValueStringTable[i].value; - } - - return i; -} - -QString RegistersView::GetStatusWordTOPStateString(unsigned short state) -{ - int i; - - for(i = 0; i < (sizeof(StatusWordTOPValueStringTable) / sizeof(*StatusWordTOPValueStringTable)); i++) - { - if(StatusWordTOPValueStringTable[i].value == state) - return StatusWordTOPValueStringTable[i].string; - } - - return "unknown"; -} - - -#define x87CW_PC_REAL4 0 -#define x87CW_PC_NOTUSED 1 -#define x87CW_PC_REAL8 2 -#define x87CW_PC_REAL10 3 - -STRING_VALUE_TABLE_t ControlWordPCValueStringTable[] = -{ - {"Real4", x87CW_PC_REAL4}, - {"Not Used", x87CW_PC_NOTUSED}, - {"Real8", x87CW_PC_REAL8}, - {"Real10", x87CW_PC_REAL10} -}; - - -unsigned int RegistersView::GetControlWordPCValueFromString(QString string) -{ - int i; - - for(i = 0; i < (sizeof(ControlWordPCValueStringTable) / sizeof(*ControlWordPCValueStringTable)); i++) - { - if(ControlWordPCValueStringTable[i].string == string) - return ControlWordPCValueStringTable[i].value; - } - - return i; -} - - -QString RegistersView::GetControlWordPCStateString(unsigned short state) -{ - int i; - - for(i = 0; i < (sizeof(ControlWordPCValueStringTable) / sizeof(*ControlWordPCValueStringTable)); i++) - { - if(ControlWordPCValueStringTable[i].value == state) - return ControlWordPCValueStringTable[i].string; - } - - return "unknown"; -} - - -#define X87FPU_TAGWORD_NONZERO 0 -#define X87FPU_TAGWORD_ZERO 1 -#define X87FPU_TAGWORD_SPECIAL 2 -#define X87FPU_TAGWORD_EMPTY 3 - -STRING_VALUE_TABLE_t TagWordValueStringTable[] = -{ - {"Nonzero", X87FPU_TAGWORD_NONZERO}, - {"Zero", X87FPU_TAGWORD_ZERO}, - {"Special", X87FPU_TAGWORD_SPECIAL}, - {"Empty", X87FPU_TAGWORD_EMPTY} -}; - -unsigned int RegistersView::GetTagWordValueFromString(QString string) -{ - int i; - - for(i = 0; i < (sizeof(TagWordValueStringTable) / sizeof(*TagWordValueStringTable)); i++) - { - if(TagWordValueStringTable[i].string == string) - return TagWordValueStringTable[i].value; - } - - return i; -} - - -QString RegistersView::GetTagWordStateString(unsigned short state) -{ - int i; - - for(i = 0; i < (sizeof(TagWordValueStringTable) / sizeof(*TagWordValueStringTable)); i++) - { - if(TagWordValueStringTable[i].value == state) - return TagWordValueStringTable[i].string; - } - - return "Unknown"; -} - -void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) -{ - // is the register-id known? - if(mRegisterMapping.contains(reg)) - { - // padding to the left is at least one character (looks better) - int x = mCharWidth * (1 + mRegisterPlaces[reg].start); - int ySpace = yTopSpacing; - if(mVScrollOffset != 0) - ySpace = 0; - int y = mRowHeight * (mRegisterPlaces[reg].line + mVScrollOffset) + ySpace; - - //draw raster - /* - p->save(); - p->setPen(QColor("#FF0000")); - p->drawLine(0, y, this->viewport()->width(), y); - p->restore(); - */ - - // draw name of value - int width = mCharWidth * mRegisterMapping[reg].length(); - p->setPen(ConfigColor("RegistersLabelColor")); - p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, mRegisterMapping[reg]); - x += (mRegisterPlaces[reg].labelwidth) * mCharWidth; - //p->drawText(offset,mRowHeight*(mRegisterPlaces[reg].line+1),mRegisterMapping[reg]); - - //set highlighting - if(DbgIsDebugging() && mRegisterUpdates.contains(reg)) - p->setPen(ConfigColor("RegistersModifiedColor")); - else - p->setPen(ConfigColor("RegistersColor")); - - //get register value - QString valueText = GetRegStringValueFromValue(reg, value); - - //selection - if(mSelected == reg) - { - p->fillRect(x, y, mRegisterPlaces[reg].valuesize * mCharWidth, mRowHeight, QBrush(ConfigColor("RegistersSelectionColor"))); - //p->fillRect(QRect(x + (mRegisterPlaces[reg].labelwidth)*mCharWidth ,mRowHeight*(mRegisterPlaces[reg].line)+2, mRegisterPlaces[reg].valuesize*mCharWidth, mRowHeight), QBrush(ConfigColor("RegistersSelectionColor"))); - } - - // draw value - width = mCharWidth * valueText.length(); - p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, valueText); - //p->drawText(x + (mRegisterPlaces[reg].labelwidth)*mCharWidth ,mRowHeight*(mRegisterPlaces[reg].line+1),QString("%1").arg(value, mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper()); - - x += valueText.length() * mCharWidth; - - if(mFPUx87_80BITSDISPLAY.contains(reg) && DbgIsDebugging()) - { - p->setPen(ConfigColor("RegistersExtraInfoColor")); - x += 1 * mCharWidth; //1 space - QString newText; - if(mRegisterUpdates.contains(x87SW_TOP)) - p->setPen(ConfigColor("RegistersModifiedColor")); - - newText = QString("ST%1 ").arg(((X87FPUREGISTER*) registerValue(&wRegDumpStruct, reg))->st_value); - width = newText.length() * mCharWidth; - p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); - - x += width; - - newText = QString(""); - - p->setPen(ConfigColor("RegistersExtraInfoColor")); - - if(reg == x87r0 && mRegisterUpdates.contains(x87TW_0)) - { - p->setPen(ConfigColor("RegistersModifiedColor")); - } - else if(reg == x87r1 && mRegisterUpdates.contains(x87TW_1)) - { - p->setPen(ConfigColor("RegistersModifiedColor")); - } - else if(reg == x87r2 && mRegisterUpdates.contains(x87TW_2)) - { - p->setPen(ConfigColor("RegistersModifiedColor")); - } - else if(reg == x87r3 && mRegisterUpdates.contains(x87TW_3)) - { - p->setPen(ConfigColor("RegistersModifiedColor")); - } - else if(reg == x87r4 && mRegisterUpdates.contains(x87TW_4)) - { - p->setPen(ConfigColor("RegistersModifiedColor")); - } - else if(reg == x87r5 && mRegisterUpdates.contains(x87TW_5)) - { - p->setPen(ConfigColor("RegistersModifiedColor")); - } - else if(reg == x87r6 && mRegisterUpdates.contains(x87TW_6)) - { - p->setPen(ConfigColor("RegistersModifiedColor")); - } - else if(reg == x87r7 && mRegisterUpdates.contains(x87TW_7)) - { - p->setPen(ConfigColor("RegistersModifiedColor")); - } - - newText += GetTagWordStateString(((X87FPUREGISTER*) registerValue(&wRegDumpStruct, reg))->tag) + QString(" "); - - width = newText.length() * mCharWidth; - p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); - - x += width; - - newText = QString(""); - - p->setPen(ConfigColor("RegistersExtraInfoColor")); - - if(DbgIsDebugging() && mRegisterUpdates.contains(reg)) - p->setPen(ConfigColor("RegistersModifiedColor")); - - newText += QString::number(readFloat80(((X87FPUREGISTER*) registerValue(&wRegDumpStruct, reg))->data)); - width = newText.length() * mCharWidth; - p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); - } - - // do we have a label ? - if(mLABELDISPLAY.contains(reg)) - { - x += 5 * mCharWidth; //5 spaces - - QString newText = getRegisterLabel(reg); - - // are there additional informations? - if(newText != "") - { - width = newText.length() * mCharWidth; - p->setPen(ConfigColor("RegistersExtraInfoColor")); - p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); - //p->drawText(x,mRowHeight*(mRegisterPlaces[reg].line+1),newText); - } - } - } -} - -void RegistersView::updateRegistersSlot() -{ - // read registers - REGDUMP z; - memset(&z, 0, sizeof(REGDUMP)); - DbgGetRegDump(&z); - // update gui - setRegisters(&z); -} - -void RegistersView::ModifyFields(QString title, STRING_VALUE_TABLE_t* table, SIZE_T size) -{ - SelectFields mSelectFields(this); - QListWidget* mQListWidget = mSelectFields.GetList(); - - QStringList items; - unsigned int i; - - for(i = 0; i < size; i++) - items << table[i].string; - - mQListWidget->addItems(items); - - mSelectFields.setWindowTitle(title); - if(mSelectFields.exec() != QDialog::Accepted) - return; - - if(mQListWidget->selectedItems().count() != 1) - return; - - QListWidgetItem* item = mQListWidget->takeItem(mQListWidget->currentRow()); - - duint value; - - for(i = 0; i < size; i++) - { - if(table[i].string == item->text()) - break; - } - - value = table[i].value; - - setRegister(mSelected, (duint)value); -} - -#define MODIFY_FIELDS_DISPLAY(title, table) ModifyFields(QString("Edit ") + QString(title), (STRING_VALUE_TABLE_t *) & table, SIZE_TABLE(table) ) - -void RegistersView::displayEditDialog() -{ - if(mFPU.contains(mSelected)) - { - if(mTAGWORD.contains(mSelected)) - MODIFY_FIELDS_DISPLAY("Tag " + mRegisterMapping.constFind(mSelected).value(), TagWordValueStringTable); - else if(mSelected == MxCsr_RC) - MODIFY_FIELDS_DISPLAY("MxCsr_RC", MxCsrRCValueStringTable); - else if(mSelected == x87CW_RC) - MODIFY_FIELDS_DISPLAY("x87CW_RC", ControlWordRCValueStringTable); - else if(mSelected == x87CW_PC) - MODIFY_FIELDS_DISPLAY("x87CW_PC", ControlWordPCValueStringTable); - else if(mSelected == x87SW_TOP) - MODIFY_FIELDS_DISPLAY("x87SW_TOP ST0=", StatusWordTOPValueStringTable); - else - { - bool errorinput = false; - LineEditDialog mLineEdit(this); - - mLineEdit.setText(GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected))); - mLineEdit.setWindowTitle("Edit FPU register"); - mLineEdit.setWindowIcon(QIcon(":/icons/images/log.png")); - mLineEdit.setCursorPosition(0); - mLineEdit.ForceSize(GetSizeRegister(mSelected) * 2); - do - { - errorinput = false; - if(mLineEdit.exec() != QDialog::Accepted) - return; //pressed cancel - else - { - bool ok = false; - duint fpuvalue; - - if(mUSHORTDISPLAY.contains(mSelected)) - fpuvalue = (duint) mLineEdit.editText.toUShort(&ok, 16); - else if(mDWORDDISPLAY.contains(mSelected)) - fpuvalue = mLineEdit.editText.toUInt(&ok, 16); - else if(mFPUMMX.contains(mSelected) || mFPUXMM.contains(mSelected) || mFPUYMM.contains(mSelected) || mFPUx87_80BITSDISPLAY.contains(mSelected)) - { - QByteArray pArray = mLineEdit.editText.toLocal8Bit(); - if(pArray.size() == GetSizeRegister(mSelected) * 2) - { - char* pData = (char*) calloc(1, sizeof(char) * GetSizeRegister(mSelected)); - - if(pData != NULL) - { - ok = true; - char actual_char[3]; - unsigned int i; - for(i = 0; i < GetSizeRegister(mSelected); i++) - { - memset(actual_char, 0, sizeof(actual_char)); - memcpy(actual_char, (char*) pArray.data() + (i * 2), 2); - if(! isxdigit(actual_char[0]) || ! isxdigit(actual_char[1])) - { - ok = false; - break; - } - pData[i] = (char)strtol(actual_char, NULL, 16); - } - - if(ok) - setRegister(mSelected, (duint) pData); - - free(pData); - - if(ok) - return; - } - } - } - if(!ok) - { - errorinput = true; - - QMessageBox msg(QMessageBox::Warning, "ERROR CONVERTING TO HEX", "ERROR CONVERTING TO HEXADECIMAL"); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - } - else - setRegister(mSelected, fpuvalue); - } - - } - while(errorinput); - } - } - else - { - WordEditDialog wEditDial(this); - wEditDial.setup(QString("Edit"), (* ((duint*) registerValue(&wRegDumpStruct, mSelected))), sizeof(dsint)); - if(wEditDial.exec() == QDialog::Accepted) //OK button clicked - setRegister(mSelected, wEditDial.getVal()); - } -} - -void RegistersView::onIncrementx87StackAction() -{ - if(mFPUx87_80BITSDISPLAY.contains(mSelected)) - setRegister(x87SW_TOP, ((* ((duint*) registerValue(&wRegDumpStruct, x87SW_TOP))) + 1) % 8); -} - -void RegistersView::onDecrementx87StackAction() -{ - if(mFPUx87_80BITSDISPLAY.contains(mSelected)) - setRegister(x87SW_TOP, ((* ((duint*) registerValue(&wRegDumpStruct, x87SW_TOP))) - 1) % 8); -} - -void RegistersView::onIncrementAction() -{ - if(mINCREMENTDECREMET.contains(mSelected)) - setRegister(mSelected, (* ((duint*) registerValue(&wRegDumpStruct, mSelected))) + 1); -} - -void RegistersView::onDecrementAction() -{ - if(mINCREMENTDECREMET.contains(mSelected)) - setRegister(mSelected, (* ((duint*) registerValue(&wRegDumpStruct, mSelected))) - 1); -} - -void RegistersView::onZeroAction() -{ - if(mSETONEZEROTOGGLE.contains(mSelected)) - setRegister(mSelected, 0); -} - -void RegistersView::onSetToOneAction() -{ - if(mSETONEZEROTOGGLE.contains(mSelected)) - setRegister(mSelected, 1); -} - -void RegistersView::onModifyAction() -{ - if(mMODIFYDISPLAY.contains(mSelected)) - displayEditDialog(); -} - -void RegistersView::onToggleValueAction() -{ - if(mSETONEZEROTOGGLE.contains(mSelected)) - { - if(mBOOLDISPLAY.contains(mSelected)) - { - int value = (int)(* (bool*) registerValue(&wRegDumpStruct, mSelected)); - setRegister(mSelected, value ^ 1); - } - else - { - bool ok = false; - dsint val = GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected)).toInt(&ok, 16); - if(ok) - { - val++; - val *= -1; - setRegister(mSelected, val); - } - } - } -} - -void RegistersView::onCopyToClipboardAction() -{ - QClipboard* clipboard = QApplication::clipboard(); - clipboard->setText(GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected))); -} - -void RegistersView::onCopySymbolToClipboardAction() -{ - if(mLABELDISPLAY.contains(mSelected)) - { - QClipboard* clipboard = QApplication::clipboard(); - QString symbol = getRegisterLabel(mSelected); - if(symbol != "") - clipboard->setText(symbol); - } -} - -void RegistersView::onFollowInDisassembly() -{ - if(mCANSTOREADDRESS.contains(mSelected)) - { - QString addr = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); - if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&wRegDumpStruct, mSelected))))) - DbgCmdExec(QString().sprintf("disasm \"%s\"", addr.toUtf8().constData()).toUtf8().constData()); - } -} - -void RegistersView::onFollowInDump() -{ - if(mCANSTOREADDRESS.contains(mSelected)) - { - QString addr = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); - if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&wRegDumpStruct, mSelected))))) - DbgCmdExec(QString().sprintf("dump \"%s\"", addr.toUtf8().constData()).toUtf8().constData()); - } -} - -void RegistersView::onFollowInStack() -{ - if(mCANSTOREADDRESS.contains(mSelected)) - { - QString addr = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); - if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&wRegDumpStruct, mSelected))))) - DbgCmdExec(QString().sprintf("sdump \"%s\"", addr.toUtf8().constData()).toUtf8().constData()); - } -} - -void RegistersView::onChangeFPUViewAction() -{ - if(mShowFpu == true) - ShowFPU(false); - else - ShowFPU(true); -} - -void RegistersView::displayCustomContextMenuSlot(QPoint pos) -{ - if(!DbgIsDebugging()) - return; - QMenu wMenu(this); - - if(mSelected != UNKNOWN) - { - if(mSETONEZEROTOGGLE.contains(mSelected)) - { - if((* ((duint*) registerValue(&wRegDumpStruct, mSelected))) >= 1) - wMenu.addAction(wCM_Zero); - if((* ((duint*) registerValue(&wRegDumpStruct, mSelected))) == 0) - wMenu.addAction(wCM_SetToOne); - wMenu.addAction(wCM_ToggleValue); - } - - if(mFPUx87_80BITSDISPLAY.contains(mSelected)) - { - wMenu.addAction(wCM_Incrementx87Stack); - wMenu.addAction(wCM_Decrementx87Stack); - } - - if(mINCREMENTDECREMET.contains(mSelected)) - { - wMenu.addAction(wCM_Increment); - wMenu.addAction(wCM_Decrement); - } - - if(mMODIFYDISPLAY.contains(mSelected)) - { - wMenu.addAction(wCM_Modify); - } - - if(mCANSTOREADDRESS.contains(mSelected)) - { - duint addr = (* ((duint*) registerValue(&wRegDumpStruct, mSelected))); - if(DbgMemIsValidReadPtr(addr)) - { - wMenu.addAction(wCM_FollowInDump); - wMenu.addAction(wCM_FollowInDisassembly); - duint size = 0; - duint base = DbgMemFindBaseAddr(DbgValFromString("csp"), &size); - if(addr >= base && addr < base + size) - wMenu.addAction(wCM_FollowInStack); - } - } - - if(mLABELDISPLAY.contains(mSelected)) - { - QString symbol = getRegisterLabel(mSelected); - if(symbol != "") - wMenu.addAction(wCM_CopySymbolToClipboard); - } - - wMenu.addAction(wCM_CopyToClipboard); - - wMenu.exec(this->mapToGlobal(pos)); - } - else - { - wMenu.addSeparator(); - wMenu.addAction(wCM_ChangeFPUView); - wMenu.addSeparator(); -#ifdef _WIN64 - QAction* wHwbpCsp = wMenu.addAction("HW Break on [RSP]"); -#else - QAction* wHwbpCsp = wMenu.addAction("HW Break on [ESP]"); -#endif - QAction* wAction = wMenu.exec(this->mapToGlobal(pos)); - - if(wAction == wHwbpCsp) - DbgCmdExec("bphws csp,rw"); - } -} - -void RegistersView::setRegister(REGISTER_NAME reg, duint value) -{ - // is register-id known? - if(mRegisterMapping.contains(reg)) - { - // map "cax" to "eax" or "rax" - QString wRegName = mRegisterMapping.constFind(reg).value(); - - // flags need to '!' infront - if(mFlags.contains(reg)) - wRegName = "!" + wRegName; - - - // we change the value (so highlight it) - mRegisterUpdates.insert(reg); - // tell everything the compiler - if(mFPU.contains(reg)) - wRegName = "_" + wRegName; - - DbgValToString(wRegName.toUtf8().constData(), value); - - // force repaint - emit refresh(); - } -} - -void RegistersView::debugStateChangedSlot(DBGSTATE state) -{ - if(state == stopped) - { - updateRegistersSlot(); - } -} - -void RegistersView::repaint() -{ - this->viewport()->repaint(); -} - -SIZE_T RegistersView::GetSizeRegister(const REGISTER_NAME reg_name) -{ - SIZE_T size; - - if(mUINTDISPLAY.contains(reg_name)) - size = sizeof(duint); - else if(mUSHORTDISPLAY.contains(reg_name) || mFIELDVALUE.contains(reg_name)) - size = sizeof(unsigned short); - else if(mDWORDDISPLAY.contains(reg_name)) - size = sizeof(DWORD); - else if(mBOOLDISPLAY.contains(reg_name)) - size = sizeof(bool); - else if(mFPUx87_80BITSDISPLAY.contains(reg_name)) - size = 10; - else if(mFPUMMX.contains(reg_name)) - size = 8; - else if(mFPUXMM.contains(reg_name)) - size = 16; - else if(mFPUYMM.contains(reg_name)) - size = 32; - else if(reg_name == LastError) - return sizeof(DWORD); - else - size = 0; - - return size; -} - -int RegistersView::CompareRegisters(const REGISTER_NAME reg_name, REGDUMP* regdump1, REGDUMP* regdump2) -{ - SIZE_T size = GetSizeRegister(reg_name); - char* reg1_data = registerValue(regdump1, reg_name); - char* reg2_data = registerValue(regdump2, reg_name); - - if(size != 0) - return memcmp(reg1_data, reg2_data, size); - - return -1; -} - -char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) -{ - static int null_value = 0; - // this is probably the most efficient general method to access the values of the struct - // TODO: add an array with something like: return array[reg].data, this is more fast :-) - if(reg == CAX) return (char*) & (regd->regcontext.cax); - if(reg == CBX) return (char*) & (regd->regcontext.cbx); - if(reg == CCX) return (char*) & (regd->regcontext.ccx); - if(reg == CDX) return (char*) & (regd->regcontext.cdx); - if(reg == CSI) return (char*) & (regd->regcontext.csi); - if(reg == CDI) return (char*) & (regd->regcontext.cdi); - if(reg == CBP) return (char*) & (regd->regcontext.cbp); - if(reg == CSP) return (char*) & (regd->regcontext.csp); - - if(reg == CIP) return (char*) & (regd->regcontext.cip); - if(reg == EFLAGS) return (char*) & (regd->regcontext.eflags); -#ifdef _WIN64 - if(reg == R8) return (char*) & (regd->regcontext.r8); - if(reg == R9) return (char*) & (regd->regcontext.r9); - if(reg == R10) return (char*) & (regd->regcontext.r10); - if(reg == R11) return (char*) & (regd->regcontext.r11); - if(reg == R12) return (char*) & (regd->regcontext.r12); - if(reg == R13) return (char*) & (regd->regcontext.r13); - if(reg == R14) return (char*) & (regd->regcontext.r14); - if(reg == R15) return (char*) & (regd->regcontext.r15); -#endif - // CF,PF,AF,ZF,SF,TF,IF,DF,OF - if(reg == CF) return (char*) & (regd->flags.c); - if(reg == PF) return (char*) & (regd->flags.p); - if(reg == AF) return (char*) & (regd->flags.a); - if(reg == ZF) return (char*) & (regd->flags.z); - if(reg == SF) return (char*) & (regd->flags.s); - if(reg == TF) return (char*) & (regd->flags.t); - if(reg == IF) return (char*) & (regd->flags.i); - if(reg == DF) return (char*) & (regd->flags.d); - if(reg == OF) return (char*) & (regd->flags.o); - - // GS,FS,ES,DS,CS,SS - if(reg == GS) return (char*) & (regd->regcontext.gs); - if(reg == FS) return (char*) & (regd->regcontext.fs); - if(reg == ES) return (char*) & (regd->regcontext.es); - if(reg == DS) return (char*) & (regd->regcontext.ds); - if(reg == CS) return (char*) & (regd->regcontext.cs); - if(reg == SS) return (char*) & (regd->regcontext.ss); - - if(reg == LastError) return (char*) & (regd->lastError); - - if(reg == DR0) return (char*) & (regd->regcontext.dr0); - if(reg == DR1) return (char*) & (regd->regcontext.dr1); - if(reg == DR2) return (char*) & (regd->regcontext.dr2); - if(reg == DR3) return (char*) & (regd->regcontext.dr3); - if(reg == DR6) return (char*) & (regd->regcontext.dr6); - if(reg == DR7) return (char*) & (regd->regcontext.dr7); - - if(reg == MM0) return (char*) & (regd->mmx[0]); - if(reg == MM1) return (char*) & (regd->mmx[1]); - if(reg == MM2) return (char*) & (regd->mmx[2]); - if(reg == MM3) return (char*) & (regd->mmx[3]); - if(reg == MM4) return (char*) & (regd->mmx[4]); - if(reg == MM5) return (char*) & (regd->mmx[5]); - if(reg == MM6) return (char*) & (regd->mmx[6]); - if(reg == MM7) return (char*) & (regd->mmx[7]); - - if(reg == x87r0) return (char*) & (regd->x87FPURegisters[0]); - if(reg == x87r1) return (char*) & (regd->x87FPURegisters[1]); - if(reg == x87r2) return (char*) & (regd->x87FPURegisters[2]); - if(reg == x87r3) return (char*) & (regd->x87FPURegisters[3]); - if(reg == x87r4) return (char*) & (regd->x87FPURegisters[4]); - if(reg == x87r5) return (char*) & (regd->x87FPURegisters[5]); - if(reg == x87r6) return (char*) & (regd->x87FPURegisters[6]); - if(reg == x87r7) return (char*) & (regd->x87FPURegisters[7]); - - if(reg == x87TagWord) return (char*) & (regd->regcontext.x87fpu.TagWord); - - if(reg == x87ControlWord) return (char*) & (regd->regcontext.x87fpu.ControlWord); - - if(reg == x87TW_0) return (char*) & (regd->x87FPURegisters[0].tag); - if(reg == x87TW_1) return (char*) & (regd->x87FPURegisters[1].tag); - if(reg == x87TW_2) return (char*) & (regd->x87FPURegisters[2].tag); - if(reg == x87TW_3) return (char*) & (regd->x87FPURegisters[3].tag); - if(reg == x87TW_4) return (char*) & (regd->x87FPURegisters[4].tag); - if(reg == x87TW_5) return (char*) & (regd->x87FPURegisters[5].tag); - if(reg == x87TW_6) return (char*) & (regd->x87FPURegisters[6].tag); - if(reg == x87TW_7) return (char*) & (regd->x87FPURegisters[7].tag); - - if(reg == x87CW_IC) return (char*) & (regd->x87ControlWordFields.IC); - if(reg == x87CW_IEM) return (char*) & (regd->x87ControlWordFields.IEM); - if(reg == x87CW_PM) return (char*) & (regd->x87ControlWordFields.PM); - if(reg == x87CW_UM) return (char*) & (regd->x87ControlWordFields.UM); - if(reg == x87CW_OM) return (char*) & (regd->x87ControlWordFields.OM); - if(reg == x87CW_ZM) return (char*) & (regd->x87ControlWordFields.ZM); - if(reg == x87CW_DM) return (char*) & (regd->x87ControlWordFields.DM); - if(reg == x87CW_IM) return (char*) & (regd->x87ControlWordFields.IM); - if(reg == x87CW_RC) return (char*) & (regd->x87ControlWordFields.RC); - if(reg == x87CW_PC) return (char*) & (regd->x87ControlWordFields.PC); - - if(reg == x87StatusWord) return (char*) & (regd->regcontext.x87fpu.StatusWord); - - if(reg == x87SW_B) return (char*) & (regd->x87StatusWordFields.B); - if(reg == x87SW_C3) return (char*) & (regd->x87StatusWordFields.C3); - if(reg == x87SW_C2) return (char*) & (regd->x87StatusWordFields.C2); - if(reg == x87SW_C1) return (char*) & (regd->x87StatusWordFields.C1); - if(reg == x87SW_O) return (char*) & (regd->x87StatusWordFields.O); - if(reg == x87SW_IR) return (char*) & (regd->x87StatusWordFields.IR); - if(reg == x87SW_SF) return (char*) & (regd->x87StatusWordFields.SF); - if(reg == x87SW_P) return (char*) & (regd->x87StatusWordFields.P); - if(reg == x87SW_U) return (char*) & (regd->x87StatusWordFields.U); - if(reg == x87SW_Z) return (char*) & (regd->x87StatusWordFields.Z); - if(reg == x87SW_D) return (char*) & (regd->x87StatusWordFields.D); - if(reg == x87SW_I) return (char*) & (regd->x87StatusWordFields.I); - if(reg == x87SW_C0) return (char*) & (regd->x87StatusWordFields.C0); - if(reg == x87SW_TOP) return (char*) & (regd->x87StatusWordFields.TOP); - - if(reg == MxCsr) return (char*) & (regd->regcontext.MxCsr); - - if(reg == MxCsr_FZ) return (char*) & (regd->MxCsrFields.FZ); - if(reg == MxCsr_PM) return (char*) & (regd->MxCsrFields.PM); - if(reg == MxCsr_UM) return (char*) & (regd->MxCsrFields.UM); - if(reg == MxCsr_OM) return (char*) & (regd->MxCsrFields.OM); - if(reg == MxCsr_ZM) return (char*) & (regd->MxCsrFields.ZM); - if(reg == MxCsr_IM) return (char*) & (regd->MxCsrFields.IM); - if(reg == MxCsr_DM) return (char*) & (regd->MxCsrFields.DM); - if(reg == MxCsr_DAZ) return (char*) & (regd->MxCsrFields.DAZ); - if(reg == MxCsr_PE) return (char*) & (regd->MxCsrFields.PE); - if(reg == MxCsr_UE) return (char*) & (regd->MxCsrFields.UE); - if(reg == MxCsr_OE) return (char*) & (regd->MxCsrFields.OE); - if(reg == MxCsr_ZE) return (char*) & (regd->MxCsrFields.ZE); - if(reg == MxCsr_DE) return (char*) & (regd->MxCsrFields.DE); - if(reg == MxCsr_IE) return (char*) & (regd->MxCsrFields.IE); - if(reg == MxCsr_RC) return (char*) & (regd->MxCsrFields.RC); - - if(reg == XMM0) return (char*) & (regd->regcontext.XmmRegisters[0]); - if(reg == XMM1) return (char*) & (regd->regcontext.XmmRegisters[1]); - if(reg == XMM2) return (char*) & (regd->regcontext.XmmRegisters[2]); - if(reg == XMM3) return (char*) & (regd->regcontext.XmmRegisters[3]); - if(reg == XMM4) return (char*) & (regd->regcontext.XmmRegisters[4]); - if(reg == XMM5) return (char*) & (regd->regcontext.XmmRegisters[5]); - if(reg == XMM6) return (char*) & (regd->regcontext.XmmRegisters[6]); - if(reg == XMM7) return (char*) & (regd->regcontext.XmmRegisters[7]); -#ifdef _WIN64 - if(reg == XMM8) return (char*) & (regd->regcontext.XmmRegisters[8]); - if(reg == XMM9) return (char*) & (regd->regcontext.XmmRegisters[9]); - if(reg == XMM10) return (char*) & (regd->regcontext.XmmRegisters[10]); - if(reg == XMM11) return (char*) & (regd->regcontext.XmmRegisters[11]); - if(reg == XMM12) return (char*) & (regd->regcontext.XmmRegisters[12]); - if(reg == XMM13) return (char*) & (regd->regcontext.XmmRegisters[13]); - if(reg == XMM14) return (char*) & (regd->regcontext.XmmRegisters[14]); - if(reg == XMM15) return (char*) & (regd->regcontext.XmmRegisters[15]); -#endif //_WIN64 - - if(reg == YMM0) return (char*) & (regd->regcontext.YmmRegisters[0]); - if(reg == YMM1) return (char*) & (regd->regcontext.YmmRegisters[1]); - if(reg == YMM2) return (char*) & (regd->regcontext.YmmRegisters[2]); - if(reg == YMM3) return (char*) & (regd->regcontext.YmmRegisters[3]); - if(reg == YMM4) return (char*) & (regd->regcontext.YmmRegisters[4]); - if(reg == YMM5) return (char*) & (regd->regcontext.YmmRegisters[5]); - if(reg == YMM6) return (char*) & (regd->regcontext.YmmRegisters[6]); - if(reg == YMM7) return (char*) & (regd->regcontext.YmmRegisters[7]); -#ifdef _WIN64 - if(reg == YMM8) return (char*) & (regd->regcontext.YmmRegisters[8]); - if(reg == YMM9) return (char*) & (regd->regcontext.YmmRegisters[9]); - if(reg == YMM10) return (char*) & (regd->regcontext.YmmRegisters[10]); - if(reg == YMM11) return (char*) & (regd->regcontext.YmmRegisters[11]); - if(reg == YMM12) return (char*) & (regd->regcontext.YmmRegisters[12]); - if(reg == YMM13) return (char*) & (regd->regcontext.YmmRegisters[13]); - if(reg == YMM14) return (char*) & (regd->regcontext.YmmRegisters[14]); - if(reg == YMM15) return (char*) & (regd->regcontext.YmmRegisters[15]); -#endif //_WIN64 - - return (char*) & null_value; -} - -void RegistersView::setRegisters(REGDUMP* reg) -{ - // tests if new-register-value == old-register-value holds - if(mCip != reg->regcontext.cip) //CIP changed - { - wCipRegDumpStruct = wRegDumpStruct; - mRegisterUpdates.clear(); - mCip = reg->regcontext.cip; - } - - QMap::const_iterator it = mRegisterMapping.begin(); - // iterate all ids (CAX, CBX, ...) - while(it != mRegisterMapping.end()) - { - if(CompareRegisters(it.key(), reg, &wCipRegDumpStruct) != 0) - mRegisterUpdates.insert(it.key()); - else if(mRegisterUpdates.contains(it.key())) //registers are equal - mRegisterUpdates.remove(it.key()); - it++; - } - - // now we can save the values - wRegDumpStruct = (*reg); - - if(mCip != reg->regcontext.cip) - wCipRegDumpStruct = wRegDumpStruct; - - // force repaint - emit refresh(); - -} +#include "RegistersView.h" +#include +#include "Configuration.h" +#include "WordEditDialog.h" +#include "LineEditDialog.h" +#include "SelectFields.h" +#include +#include + +void RegistersView::SetChangeButton(QPushButton* push_button) +{ + mChangeViewButton = push_button; +} + +void RegistersView::InitMappings() +{ + // create mapping from internal id to name + mRegisterMapping.clear(); + mRegisterPlaces.clear(); + int offset = 0; + + /* Register_Position is a struct definition the position + * + * (line , start, labelwidth, valuesize ) + */ +#ifdef _WIN64 + mRegisterMapping.insert(CAX, "RAX"); + mRegisterPlaces.insert(CAX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CBX, "RBX"); + mRegisterPlaces.insert(CBX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CCX, "RCX"); + mRegisterPlaces.insert(CCX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CDX, "RDX"); + mRegisterPlaces.insert(CDX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CBP, "RBP"); + mRegisterPlaces.insert(CBP, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CSP, "RSP"); + mRegisterPlaces.insert(CSP, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CSI, "RSI"); + mRegisterPlaces.insert(CSI, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CDI, "RDI"); + mRegisterPlaces.insert(CDI, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + + offset++; + + mRegisterMapping.insert(R8, "R8"); + mRegisterPlaces.insert(R8 , Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(R9, "R9"); + mRegisterPlaces.insert(R9 , Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(R10, "R10"); + mRegisterPlaces.insert(R10, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(R11, "R11"); + mRegisterPlaces.insert(R11, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(R12, "R12"); + mRegisterPlaces.insert(R12, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(R13, "R13"); + mRegisterPlaces.insert(R13, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(R14, "R14"); + mRegisterPlaces.insert(R14, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(R15, "R15"); + mRegisterPlaces.insert(R15, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + + offset++; + + mRegisterMapping.insert(CIP, "RIP"); + mRegisterPlaces.insert(CIP, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + + offset++; + + mRegisterMapping.insert(EFLAGS, "RFLAGS"); + mRegisterPlaces.insert(EFLAGS, Register_Position(offset++, 0, 9, sizeof(duint) * 2)); +#else //x32 + mRegisterMapping.insert(CAX, "EAX"); + mRegisterPlaces.insert(CAX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CBX, "EBX"); + mRegisterPlaces.insert(CBX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CCX, "ECX"); + mRegisterPlaces.insert(CCX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CDX, "EDX"); + mRegisterPlaces.insert(CDX, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CBP, "EBP"); + mRegisterPlaces.insert(CBP, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CSP, "ESP"); + mRegisterPlaces.insert(CSP, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CSI, "ESI"); + mRegisterPlaces.insert(CSI, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + mRegisterMapping.insert(CDI, "EDI"); + mRegisterPlaces.insert(CDI, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + + offset++; + + mRegisterMapping.insert(CIP, "EIP"); + mRegisterPlaces.insert(CIP, Register_Position(offset++, 0, 6, sizeof(duint) * 2)); + + offset++; + + mRegisterMapping.insert(EFLAGS, "EFLAGS"); + mRegisterPlaces.insert(EFLAGS, Register_Position(offset++, 0, 9, sizeof(duint) * 2)); +#endif + + mRegisterMapping.insert(ZF, "ZF"); + mRegisterPlaces.insert(ZF, Register_Position(offset, 0, 3, 1)); + mRegisterMapping.insert(PF, "PF"); + mRegisterPlaces.insert(PF, Register_Position(offset, 6, 3, 1)); + mRegisterMapping.insert(AF, "AF"); + mRegisterPlaces.insert(AF, Register_Position(offset++, 12, 3, 1)); + + mRegisterMapping.insert(OF, "OF"); + mRegisterPlaces.insert(OF, Register_Position(offset, 0, 3, 1)); + mRegisterMapping.insert(SF, "SF"); + mRegisterPlaces.insert(SF, Register_Position(offset, 6, 3, 1)); + mRegisterMapping.insert(DF, "DF"); + mRegisterPlaces.insert(DF, Register_Position(offset++, 12, 3, 1)); + + mRegisterMapping.insert(CF, "CF"); + mRegisterPlaces.insert(CF, Register_Position(offset, 0, 3, 1)); + mRegisterMapping.insert(TF, "TF"); + mRegisterPlaces.insert(TF, Register_Position(offset, 6, 3, 1)); + mRegisterMapping.insert(IF, "IF"); + mRegisterPlaces.insert(IF, Register_Position(offset++, 12, 3, 1)); + + offset++; + + mRegisterMapping.insert(LastError, "LastError"); + mRegisterPlaces.insert(LastError, Register_Position(offset++, 0, 10, 20)); + + offset++; + + mRegisterMapping.insert(GS, "GS"); + mRegisterPlaces.insert(GS, Register_Position(offset, 0, 3, 4)); + mRegisterMapping.insert(FS, "FS"); + mRegisterPlaces.insert(FS, Register_Position(offset++, 9, 3, 4)); + mRegisterMapping.insert(ES, "ES"); + mRegisterPlaces.insert(ES, Register_Position(offset, 0, 3, 4)); + mRegisterMapping.insert(DS, "DS"); + mRegisterPlaces.insert(DS, Register_Position(offset++, 9, 3, 4)); + mRegisterMapping.insert(CS, "CS"); + mRegisterPlaces.insert(CS, Register_Position(offset, 0, 3, 4)); + mRegisterMapping.insert(SS, "SS"); + mRegisterPlaces.insert(SS, Register_Position(offset++, 9, 3, 4)); + + if(mShowFpu) + { + offset++; + + mRegisterMapping.insert(x87r0, "x87r0"); + mRegisterPlaces.insert(x87r0, Register_Position(offset++, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r1, "x87r1"); + mRegisterPlaces.insert(x87r1, Register_Position(offset++, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r2, "x87r2"); + mRegisterPlaces.insert(x87r2, Register_Position(offset++, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r3, "x87r3"); + mRegisterPlaces.insert(x87r3, Register_Position(offset++, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r4, "x87r4"); + mRegisterPlaces.insert(x87r4, Register_Position(offset++, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r5, "x87r5"); + mRegisterPlaces.insert(x87r5, Register_Position(offset++, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r6, "x87r6"); + mRegisterPlaces.insert(x87r6, Register_Position(offset++, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r7, "x87r7"); + mRegisterPlaces.insert(x87r7, Register_Position(offset++, 0, 6, 10 * 2)); + + offset++; + + mRegisterMapping.insert(x87TagWord, "x87TagWord"); + mRegisterPlaces.insert(x87TagWord, Register_Position(offset++, 0, 11, sizeof(WORD) * 2)); + + mRegisterMapping.insert(x87TW_0, "x87TW_0"); + mRegisterPlaces.insert(x87TW_0, Register_Position(offset, 0, 8, 10)); + mRegisterMapping.insert(x87TW_1, "x87TW_1"); + mRegisterPlaces.insert(x87TW_1, Register_Position(offset++, 20, 8, 10)); + + mRegisterMapping.insert(x87TW_2, "x87TW_2"); + mRegisterPlaces.insert(x87TW_2, Register_Position(offset, 0, 8, 10)); + mRegisterMapping.insert(x87TW_3, "x87TW_3"); + mRegisterPlaces.insert(x87TW_3, Register_Position(offset++, 20, 8, 10)); + + mRegisterMapping.insert(x87TW_4, "x87TW_4"); + mRegisterPlaces.insert(x87TW_4, Register_Position(offset, 0, 8, 10)); + mRegisterMapping.insert(x87TW_5, "x87TW_5"); + mRegisterPlaces.insert(x87TW_5, Register_Position(offset++, 20, 8, 10)); + + mRegisterMapping.insert(x87TW_6, "x87TW_6"); + mRegisterPlaces.insert(x87TW_6, Register_Position(offset, 0, 8, 10)); + mRegisterMapping.insert(x87TW_7, "x87TW_7"); + mRegisterPlaces.insert(x87TW_7, Register_Position(offset++, 20, 8, 10)); + + offset++; + + mRegisterMapping.insert(x87StatusWord, "x87StatusWord"); + mRegisterPlaces.insert(x87StatusWord, Register_Position(offset++, 0, 14, sizeof(WORD) * 2)); + + mRegisterMapping.insert(x87SW_B, "x87SW_B"); + mRegisterPlaces.insert(x87SW_B, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(x87SW_C3, "x87SW_C3"); + mRegisterPlaces.insert(x87SW_C3, Register_Position(offset, 12, 10, 1)); + mRegisterMapping.insert(x87SW_C2, "x87SW_C2"); + mRegisterPlaces.insert(x87SW_C2, Register_Position(offset++, 25, 10, 1)); + + mRegisterMapping.insert(x87SW_C1, "x87SW_C1"); + mRegisterPlaces.insert(x87SW_C1, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(x87SW_C0, "x87SW_C0"); + mRegisterPlaces.insert(x87SW_C0, Register_Position(offset, 12, 10, 1)); + mRegisterMapping.insert(x87SW_IR, "x87SW_IR"); + mRegisterPlaces.insert(x87SW_IR, Register_Position(offset++, 25, 10, 1)); + + mRegisterMapping.insert(x87SW_SF, "x87SW_SF"); + mRegisterPlaces.insert(x87SW_SF, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(x87SW_P, "x87SW_P"); + mRegisterPlaces.insert(x87SW_P, Register_Position(offset, 12, 10, 1)); + mRegisterMapping.insert(x87SW_U, "x87SW_U"); + mRegisterPlaces.insert(x87SW_U, Register_Position(offset++, 25, 10, 1)); + + mRegisterMapping.insert(x87SW_O, "x87SW_O"); + mRegisterPlaces.insert(x87SW_O, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(x87SW_Z, "x87SW_Z"); + mRegisterPlaces.insert(x87SW_Z, Register_Position(offset, 12, 10, 1)); + mRegisterMapping.insert(x87SW_D, "x87SW_D"); + mRegisterPlaces.insert(x87SW_D, Register_Position(offset++, 25, 10, 1)); + + mRegisterMapping.insert(x87SW_I, "x87SW_I"); + mRegisterPlaces.insert(x87SW_I, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(x87SW_TOP, "x87SW_TOP"); + mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset++, 12, 10, 13)); + + offset++; + + mRegisterMapping.insert(x87ControlWord, "x87ControlWord"); + mRegisterPlaces.insert(x87ControlWord, Register_Position(offset++, 0, 15, sizeof(WORD) * 2)); + + mRegisterMapping.insert(x87CW_IC, "x87CW_IC"); + mRegisterPlaces.insert(x87CW_IC, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(x87CW_IEM, "x87CW_IEM"); + mRegisterPlaces.insert(x87CW_IEM, Register_Position(offset, 12, 10, 1)); + mRegisterMapping.insert(x87CW_PM, "x87CW_PM"); + mRegisterPlaces.insert(x87CW_PM, Register_Position(offset++, 25, 10, 1)); + + mRegisterMapping.insert(x87CW_UM, "x87CW_UM"); + mRegisterPlaces.insert(x87CW_UM, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(x87CW_OM, "x87CW_OM"); + mRegisterPlaces.insert(x87CW_OM, Register_Position(offset, 12, 10, 1)); + mRegisterMapping.insert(x87CW_ZM, "x87CW_ZM"); + mRegisterPlaces.insert(x87CW_ZM, Register_Position(offset++, 25, 10, 1)); + + mRegisterMapping.insert(x87CW_DM, "x87CW_DM"); + mRegisterPlaces.insert(x87CW_DM, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(x87CW_IM, "x87CW_IM"); + mRegisterPlaces.insert(x87CW_IM, Register_Position(offset, 12, 10, 1)); + mRegisterMapping.insert(x87CW_RC, "x87CW_RC"); + mRegisterPlaces.insert(x87CW_RC, Register_Position(offset++, 25, 10, 14)); + + mRegisterMapping.insert(x87CW_PC, "x87CW_PC"); + mRegisterPlaces.insert(x87CW_PC, Register_Position(offset++, 0, 9, 14)); + + offset++; + + mRegisterMapping.insert(MxCsr, "MxCsr"); + mRegisterPlaces.insert(MxCsr, Register_Position(offset++, 0, 6, sizeof(DWORD) * 2)); + + mRegisterMapping.insert(MxCsr_FZ, "MxCsr_FZ"); + mRegisterPlaces.insert(MxCsr_FZ, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_PM, "MxCsr_PM"); + mRegisterPlaces.insert(MxCsr_PM, Register_Position(offset, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_UM, "MxCsr_UM"); + mRegisterPlaces.insert(MxCsr_UM, Register_Position(offset++, 25, 10, 1)); + + mRegisterMapping.insert(MxCsr_OM, "MxCsr_OM"); + mRegisterPlaces.insert(MxCsr_OM, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_ZM, "MxCsr_ZM"); + mRegisterPlaces.insert(MxCsr_ZM, Register_Position(offset, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_IM, "MxCsr_IM"); + mRegisterPlaces.insert(MxCsr_IM, Register_Position(offset++, 25, 10, 1)); + + mRegisterMapping.insert(MxCsr_UE, "MxCsr_UE"); + mRegisterPlaces.insert(MxCsr_UE, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_PE, "MxCsr_PE"); + mRegisterPlaces.insert(MxCsr_PE, Register_Position(offset, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_DAZ, "MxCsr_DAZ"); + mRegisterPlaces.insert(MxCsr_DAZ, Register_Position(offset++, 25, 10, 1)); + + mRegisterMapping.insert(MxCsr_OE, "MxCsr_OE"); + mRegisterPlaces.insert(MxCsr_OE, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_ZE, "MxCsr_ZE"); + mRegisterPlaces.insert(MxCsr_ZE, Register_Position(offset, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_DE, "MxCsr_DE"); + mRegisterPlaces.insert(MxCsr_DE, Register_Position(offset++, 25, 10, 1)); + + mRegisterMapping.insert(MxCsr_IE, "MxCsr_IE"); + mRegisterPlaces.insert(MxCsr_IE, Register_Position(offset, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_DM, "MxCsr_DM"); + mRegisterPlaces.insert(MxCsr_DM, Register_Position(offset, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_RC, "MxCsr_RC"); + mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset++, 25, 10, 19)); + + offset++; + + mRegisterMapping.insert(MM0, "MM0"); + mRegisterPlaces.insert(MM0, Register_Position(offset++, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM1, "MM1"); + mRegisterPlaces.insert(MM1, Register_Position(offset++, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM2, "MM2"); + mRegisterPlaces.insert(MM2, Register_Position(offset++, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM3, "MM3"); + mRegisterPlaces.insert(MM3, Register_Position(offset++, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM4, "MM4"); + mRegisterPlaces.insert(MM4, Register_Position(offset++, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM5, "MM5"); + mRegisterPlaces.insert(MM5, Register_Position(offset++, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM6, "MM6"); + mRegisterPlaces.insert(MM6, Register_Position(offset++, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM7, "MM7"); + mRegisterPlaces.insert(MM7, Register_Position(offset++, 0, 4, 8 * 2)); + + offset++; + + mRegisterMapping.insert(XMM0, "XMM0"); + mRegisterPlaces.insert(XMM0, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM1, "XMM1"); + mRegisterPlaces.insert(XMM1, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM2, "XMM2"); + mRegisterPlaces.insert(XMM2, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM3, "XMM3"); + mRegisterPlaces.insert(XMM3, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM4, "XMM4"); + mRegisterPlaces.insert(XMM4, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM5, "XMM5"); + mRegisterPlaces.insert(XMM5, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM6, "XMM6"); + mRegisterPlaces.insert(XMM6, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM7, "XMM7"); + mRegisterPlaces.insert(XMM7, Register_Position(offset++, 0, 6, 16 * 2)); +#ifdef _WIN64 + mRegisterMapping.insert(XMM8, "XMM8"); + mRegisterPlaces.insert(XMM8, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM9, "XMM9"); + mRegisterPlaces.insert(XMM9, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM10, "XMM10"); + mRegisterPlaces.insert(XMM10, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM11, "XMM11"); + mRegisterPlaces.insert(XMM11, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM12, "XMM12"); + mRegisterPlaces.insert(XMM12, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM13, "XMM13"); + mRegisterPlaces.insert(XMM13, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM14, "XMM14"); + mRegisterPlaces.insert(XMM14, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM15, "XMM15"); + mRegisterPlaces.insert(XMM15, Register_Position(offset++, 0, 6, 16 * 2)); +#endif + + offset++; + + mRegisterMapping.insert(YMM0, "YMM0"); + mRegisterPlaces.insert(YMM0, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM1, "YMM1"); + mRegisterPlaces.insert(YMM1, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM2, "YMM2"); + mRegisterPlaces.insert(YMM2, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM3, "YMM3"); + mRegisterPlaces.insert(YMM3, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM4, "YMM4"); + mRegisterPlaces.insert(YMM4, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM5, "YMM5"); + mRegisterPlaces.insert(YMM5, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM6, "YMM6"); + mRegisterPlaces.insert(YMM6, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM7, "YMM7"); + mRegisterPlaces.insert(YMM7, Register_Position(offset++, 0, 6, 32 * 2)); +#ifdef _WIN64 + mRegisterMapping.insert(YMM8, "YMM8"); + mRegisterPlaces.insert(YMM8, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM9, "YMM9"); + mRegisterPlaces.insert(YMM9, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM10, "YMM10"); + mRegisterPlaces.insert(YMM10, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM11, "YMM11"); + mRegisterPlaces.insert(YMM11, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM12, "YMM12"); + mRegisterPlaces.insert(YMM12, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM13, "YMM13"); + mRegisterPlaces.insert(YMM13, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM14, "YMM14"); + mRegisterPlaces.insert(YMM14, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM15, "YMM15"); + mRegisterPlaces.insert(YMM15, Register_Position(offset++, 0, 6, 32 * 2)); +#endif + } + + offset++; + + mRegisterMapping.insert(DR0, "DR0"); + mRegisterPlaces.insert(DR0, Register_Position(offset++, 0, 4, sizeof(duint) * 2)); + mRegisterMapping.insert(DR1, "DR1"); + mRegisterPlaces.insert(DR1, Register_Position(offset++, 0, 4, sizeof(duint) * 2)); + mRegisterMapping.insert(DR2, "DR2"); + mRegisterPlaces.insert(DR2, Register_Position(offset++, 0, 4, sizeof(duint) * 2)); + mRegisterMapping.insert(DR3, "DR3"); + mRegisterPlaces.insert(DR3, Register_Position(offset++, 0, 4, sizeof(duint) * 2)); + mRegisterMapping.insert(DR6, "DR6"); + mRegisterPlaces.insert(DR6, Register_Position(offset++, 0, 4, sizeof(duint) * 2)); + mRegisterMapping.insert(DR7, "DR7"); + mRegisterPlaces.insert(DR7, Register_Position(offset++, 0, 4, sizeof(duint) * 2)); + + mRowsNeeded = offset + 1; +} + +RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOffset(0) +{ + mChangeViewButton = NULL; + + // precreate ContextMenu Actions + wCM_Increment = new QAction(tr("Increment"), this); + wCM_Increment->setShortcutContext(Qt::WidgetShortcut); + this->addAction(wCM_Increment); + wCM_Decrement = new QAction(tr("Decrement"), this); + wCM_Decrement->setShortcutContext(Qt::WidgetShortcut); + this->addAction(wCM_Decrement); + wCM_Zero = new QAction(tr("Zero"), this); + wCM_Zero->setShortcutContext(Qt::WidgetShortcut); + this->addAction(wCM_Zero); + wCM_SetToOne = new QAction(tr("Set to 1"), this); + wCM_SetToOne->setShortcutContext(Qt::WidgetShortcut); + this->addAction(wCM_SetToOne); + wCM_Modify = new QAction(tr("Modify Value"), this); + wCM_Modify->setShortcut(QKeySequence(Qt::Key_Enter)); + wCM_ToggleValue = new QAction(tr("Toggle"), this); + wCM_ToggleValue->setShortcutContext(Qt::WidgetShortcut); + this->addAction(wCM_ToggleValue); + wCM_CopyToClipboard = new QAction(tr("Copy Value to Clipboard"), this); + wCM_CopyToClipboard->setShortcutContext(Qt::WidgetShortcut); + this->addAction(wCM_CopyToClipboard); + wCM_CopySymbolToClipboard = new QAction(tr("Copy Symbol Value to Clipboard"), this); + wCM_CopySymbolToClipboard->setShortcutContext(Qt::WidgetShortcut); + this->addAction(wCM_CopySymbolToClipboard); + wCM_FollowInDisassembly = new QAction(tr("Follow in Disassembler"), this); + wCM_FollowInDump = new QAction(tr("Follow in Dump"), this); + wCM_FollowInStack = new QAction("Follow in Stack", this); + wCM_Incrementx87Stack = new QAction(tr("Increment x87 Stack"), this); + wCM_Decrementx87Stack = new QAction("Decrement x87 Stack", this); + wCM_ChangeFPUView = new QAction("Change View", this); + + // general purposes register (we allow the user to modify the value) + mGPR.insert(CAX); + mCANSTOREADDRESS.insert(CAX); + mUINTDISPLAY.insert(CAX); + mLABELDISPLAY.insert(CAX); + mMODIFYDISPLAY.insert(CAX); + mINCREMENTDECREMET.insert(CAX); + mSETONEZEROTOGGLE.insert(CAX); + + mSETONEZEROTOGGLE.insert(CBX); + mINCREMENTDECREMET.insert(CBX); + mGPR.insert(CBX); + mUINTDISPLAY.insert(CBX); + mLABELDISPLAY.insert(CBX); + mMODIFYDISPLAY.insert(CBX); + mCANSTOREADDRESS.insert(CBX); + + mSETONEZEROTOGGLE.insert(CCX); + mINCREMENTDECREMET.insert(CCX); + mGPR.insert(CCX); + mUINTDISPLAY.insert(CCX); + mLABELDISPLAY.insert(CCX); + mMODIFYDISPLAY.insert(CCX); + mCANSTOREADDRESS.insert(CCX); + + mSETONEZEROTOGGLE.insert(CDX); + mINCREMENTDECREMET.insert(CDX); + mGPR.insert(CDX); + mUINTDISPLAY.insert(CDX); + mLABELDISPLAY.insert(CDX); + mMODIFYDISPLAY.insert(CDX); + mCANSTOREADDRESS.insert(CDX); + + mSETONEZEROTOGGLE.insert(CBP); + mINCREMENTDECREMET.insert(CBP); + mCANSTOREADDRESS.insert(CBP); + mGPR.insert(CBP); + mUINTDISPLAY.insert(CBP); + mLABELDISPLAY.insert(CBP); + mMODIFYDISPLAY.insert(CBP); + + mSETONEZEROTOGGLE.insert(CSP); + mINCREMENTDECREMET.insert(CSP); + mCANSTOREADDRESS.insert(CSP); + mGPR.insert(CSP); + mUINTDISPLAY.insert(CSP); + mLABELDISPLAY.insert(CSP); + mMODIFYDISPLAY.insert(CSP); + + mSETONEZEROTOGGLE.insert(CSI); + mINCREMENTDECREMET.insert(CSI); + mCANSTOREADDRESS.insert(CSI); + mGPR.insert(CSI); + mUINTDISPLAY.insert(CSI); + mLABELDISPLAY.insert(CSI); + mMODIFYDISPLAY.insert(CSI); + + mSETONEZEROTOGGLE.insert(CDI); + mINCREMENTDECREMET.insert(CDI); + mCANSTOREADDRESS.insert(CDI); + mGPR.insert(CDI); + mUINTDISPLAY.insert(CDI); + mLABELDISPLAY.insert(CDI); + mMODIFYDISPLAY.insert(CDI); + + mSETONEZEROTOGGLE.insert(R8); + mINCREMENTDECREMET.insert(R8); + mCANSTOREADDRESS.insert(R8); + mGPR.insert(R8); + mLABELDISPLAY.insert(R8); + mUINTDISPLAY.insert(R8); + mMODIFYDISPLAY.insert(R8); + + mSETONEZEROTOGGLE.insert(R9); + mINCREMENTDECREMET.insert(R9); + mCANSTOREADDRESS.insert(R9); + mGPR.insert(R9); + mLABELDISPLAY.insert(R9); + mUINTDISPLAY.insert(R9); + mMODIFYDISPLAY.insert(R9); + + mSETONEZEROTOGGLE.insert(R10); + mINCREMENTDECREMET.insert(R10); + mCANSTOREADDRESS.insert(R10); + mGPR.insert(R10); + mMODIFYDISPLAY.insert(R10); + mUINTDISPLAY.insert(R10); + mLABELDISPLAY.insert(R10); + + mSETONEZEROTOGGLE.insert(R11); + mINCREMENTDECREMET.insert(R11); + mCANSTOREADDRESS.insert(R11); + mGPR.insert(R11); + mMODIFYDISPLAY.insert(R11); + mUINTDISPLAY.insert(R11); + mLABELDISPLAY.insert(R11); + + mSETONEZEROTOGGLE.insert(R12); + mINCREMENTDECREMET.insert(R12); + mCANSTOREADDRESS.insert(R12); + mGPR.insert(R12); + mMODIFYDISPLAY.insert(R12); + mUINTDISPLAY.insert(R12); + mLABELDISPLAY.insert(R12); + + mSETONEZEROTOGGLE.insert(R13); + mINCREMENTDECREMET.insert(R13); + mCANSTOREADDRESS.insert(R13); + mGPR.insert(R13); + mMODIFYDISPLAY.insert(R13); + mUINTDISPLAY.insert(R13); + mLABELDISPLAY.insert(R13); + + mSETONEZEROTOGGLE.insert(R14); + mINCREMENTDECREMET.insert(R14); + mCANSTOREADDRESS.insert(R14); + mGPR.insert(R14); + mMODIFYDISPLAY.insert(R14); + mUINTDISPLAY.insert(R14); + mLABELDISPLAY.insert(R14); + + mSETONEZEROTOGGLE.insert(R15); + mINCREMENTDECREMET.insert(R15); + mCANSTOREADDRESS.insert(R15); + mGPR.insert(R15); + mMODIFYDISPLAY.insert(R15); + mUINTDISPLAY.insert(R15); + mLABELDISPLAY.insert(R15); + + mSETONEZEROTOGGLE.insert(EFLAGS); + mINCREMENTDECREMET.insert(EFLAGS); + mGPR.insert(EFLAGS); + mMODIFYDISPLAY.insert(EFLAGS); + mUINTDISPLAY.insert(EFLAGS); + + // flags (we allow the user to toggle them) + mFlags.insert(CF); + mBOOLDISPLAY.insert(CF); + mSETONEZEROTOGGLE.insert(CF); + + mSETONEZEROTOGGLE.insert(PF); + mFlags.insert(PF); + mBOOLDISPLAY.insert(PF); + + mSETONEZEROTOGGLE.insert(AF); + mFlags.insert(AF); + mBOOLDISPLAY.insert(AF); + + mSETONEZEROTOGGLE.insert(ZF); + mFlags.insert(ZF); + mBOOLDISPLAY.insert(ZF); + + mSETONEZEROTOGGLE.insert(SF); + mFlags.insert(SF); + mBOOLDISPLAY.insert(SF); + + mSETONEZEROTOGGLE.insert(TF); + mFlags.insert(TF); + mBOOLDISPLAY.insert(TF); + + mFlags.insert(IF); + mBOOLDISPLAY.insert(IF); + + mSETONEZEROTOGGLE.insert(DF); + mFlags.insert(DF); + mBOOLDISPLAY.insert(DF); + + mSETONEZEROTOGGLE.insert(OF); + mFlags.insert(OF); + mBOOLDISPLAY.insert(OF); + + // FPU: XMM, x87 and MMX registers + mSETONEZEROTOGGLE.insert(MxCsr); + mDWORDDISPLAY.insert(MxCsr); + mMODIFYDISPLAY.insert(MxCsr); + mFPU.insert(MxCsr); + + mMODIFYDISPLAY.insert(x87r0); + mFPUx87.insert(x87r0); + mFPUx87_80BITSDISPLAY.insert(x87r0); + mFPU.insert(x87r0); + + mMODIFYDISPLAY.insert(x87r1); + mFPUx87.insert(x87r1); + mFPUx87_80BITSDISPLAY.insert(x87r1); + mFPU.insert(x87r1); + + mMODIFYDISPLAY.insert(x87r2); + mFPUx87.insert(x87r2); + mFPUx87_80BITSDISPLAY.insert(x87r2); + mFPU.insert(x87r2); + + mMODIFYDISPLAY.insert(x87r3); + mFPUx87.insert(x87r3); + mFPUx87_80BITSDISPLAY.insert(x87r3); + mFPU.insert(x87r3); + + mMODIFYDISPLAY.insert(x87r4); + mFPUx87.insert(x87r4); + mFPUx87_80BITSDISPLAY.insert(x87r4); + mFPU.insert(x87r4); + + mMODIFYDISPLAY.insert(x87r5); + mFPUx87.insert(x87r5); + mFPU.insert(x87r5); + mFPUx87_80BITSDISPLAY.insert(x87r5); + + mMODIFYDISPLAY.insert(x87r6); + mFPUx87.insert(x87r6); + mFPU.insert(x87r6); + mFPUx87_80BITSDISPLAY.insert(x87r6); + + mMODIFYDISPLAY.insert(x87r7); + mFPUx87.insert(x87r7); + mFPU.insert(x87r7); + mFPUx87_80BITSDISPLAY.insert(x87r7); + + mSETONEZEROTOGGLE.insert(x87TagWord); + mFPUx87.insert(x87TagWord); + mMODIFYDISPLAY.insert(x87TagWord); + mUSHORTDISPLAY.insert(x87TagWord); + mFPU.insert(x87TagWord); + + mSETONEZEROTOGGLE.insert(x87StatusWord); + mUSHORTDISPLAY.insert(x87StatusWord); + mMODIFYDISPLAY.insert(x87StatusWord); + mFPUx87.insert(x87StatusWord); + mFPU.insert(x87StatusWord); + + mSETONEZEROTOGGLE.insert(x87ControlWord); + mFPUx87.insert(x87ControlWord); + mMODIFYDISPLAY.insert(x87ControlWord); + mUSHORTDISPLAY.insert(x87ControlWord); + mFPU.insert(x87ControlWord); + + mSETONEZEROTOGGLE.insert(x87SW_B); + mFPUx87.insert(x87SW_B); + mBOOLDISPLAY.insert(x87SW_B); + mFPU.insert(x87SW_B); + + mSETONEZEROTOGGLE.insert(x87SW_C3); + mFPUx87.insert(x87SW_C3); + mBOOLDISPLAY.insert(x87SW_C3); + mFPU.insert(x87SW_C3); + + mFPUx87.insert(x87SW_TOP); + mFIELDVALUE.insert(x87SW_TOP); + mFPU.insert(x87SW_TOP); + mMODIFYDISPLAY.insert(x87SW_TOP); + + mFPUx87.insert(x87SW_C2); + mBOOLDISPLAY.insert(x87SW_C2); + mSETONEZEROTOGGLE.insert(x87SW_C2); + mFPU.insert(x87SW_C2); + + mSETONEZEROTOGGLE.insert(x87SW_C1); + mFPUx87.insert(x87SW_C1); + mBOOLDISPLAY.insert(x87SW_C1); + mFPU.insert(x87SW_C1); + + mSETONEZEROTOGGLE.insert(x87SW_C0); + mFPUx87.insert(x87SW_C0); + mBOOLDISPLAY.insert(x87SW_C0); + mFPU.insert(x87SW_C0); + + mSETONEZEROTOGGLE.insert(x87SW_IR); + mFPUx87.insert(x87SW_IR); + mBOOLDISPLAY.insert(x87SW_IR); + mFPU.insert(x87SW_IR); + + mSETONEZEROTOGGLE.insert(x87SW_SF); + mFPUx87.insert(x87SW_SF); + mBOOLDISPLAY.insert(x87SW_SF); + mFPU.insert(x87SW_SF); + + mSETONEZEROTOGGLE.insert(x87SW_P); + mFPUx87.insert(x87SW_P); + mBOOLDISPLAY.insert(x87SW_P); + mFPU.insert(x87SW_P); + + mSETONEZEROTOGGLE.insert(x87SW_U); + mFPUx87.insert(x87SW_U); + mBOOLDISPLAY.insert(x87SW_U); + mFPU.insert(x87SW_U); + + mSETONEZEROTOGGLE.insert(x87SW_O); + mFPUx87.insert(x87SW_O); + mBOOLDISPLAY.insert(x87SW_O); + mFPU.insert(x87SW_O); + + mSETONEZEROTOGGLE.insert(x87SW_Z); + mFPUx87.insert(x87SW_Z); + mBOOLDISPLAY.insert(x87SW_Z); + mFPU.insert(x87SW_Z); + + mSETONEZEROTOGGLE.insert(x87SW_D); + mFPUx87.insert(x87SW_D); + mBOOLDISPLAY.insert(x87SW_D); + mFPU.insert(x87SW_D); + + mSETONEZEROTOGGLE.insert(x87SW_I); + mFPUx87.insert(x87SW_I); + mBOOLDISPLAY.insert(x87SW_I); + mFPU.insert(x87SW_I); + + mSETONEZEROTOGGLE.insert(x87CW_IC); + mFPUx87.insert(x87CW_IC); + mBOOLDISPLAY.insert(x87CW_IC); + mFPU.insert(x87CW_IC); + + mFPUx87.insert(x87CW_RC); + mFIELDVALUE.insert(x87CW_RC); + mFPU.insert(x87CW_RC); + mMODIFYDISPLAY.insert(x87CW_RC); + + mFPUx87.insert(x87TW_0); + mFIELDVALUE.insert(x87TW_0); + mTAGWORD.insert(x87TW_0); + mFPU.insert(x87TW_0); + mMODIFYDISPLAY.insert(x87TW_0); + + mFPUx87.insert(x87TW_1); + mFIELDVALUE.insert(x87TW_1); + mTAGWORD.insert(x87TW_1); + mFPU.insert(x87TW_1); + mMODIFYDISPLAY.insert(x87TW_1); + + mFPUx87.insert(x87TW_2); + mFIELDVALUE.insert(x87TW_2); + mTAGWORD.insert(x87TW_2); + mFPU.insert(x87TW_2); + mMODIFYDISPLAY.insert(x87TW_2); + + mFPUx87.insert(x87TW_3); + mFIELDVALUE.insert(x87TW_3); + mTAGWORD.insert(x87TW_3); + mFPU.insert(x87TW_3); + mMODIFYDISPLAY.insert(x87TW_3); + + mFPUx87.insert(x87TW_4); + mFIELDVALUE.insert(x87TW_4); + mTAGWORD.insert(x87TW_4); + mFPU.insert(x87TW_4); + mMODIFYDISPLAY.insert(x87TW_4); + + mFPUx87.insert(x87TW_5); + mFIELDVALUE.insert(x87TW_5); + mTAGWORD.insert(x87TW_5); + mFPU.insert(x87TW_5); + mMODIFYDISPLAY.insert(x87TW_5); + + mFPUx87.insert(x87TW_6); + mFIELDVALUE.insert(x87TW_6); + mTAGWORD.insert(x87TW_6); + mFPU.insert(x87TW_6); + mMODIFYDISPLAY.insert(x87TW_6); + + mFPUx87.insert(x87TW_7); + mFIELDVALUE.insert(x87TW_7); + mTAGWORD.insert(x87TW_7); + mFPU.insert(x87TW_7); + mMODIFYDISPLAY.insert(x87TW_7); + + mFPUx87.insert(x87CW_PC); + mFIELDVALUE.insert(x87CW_PC); + mFPU.insert(x87CW_PC); + mMODIFYDISPLAY.insert(x87CW_PC); + + mSETONEZEROTOGGLE.insert(x87CW_IEM); + mFPUx87.insert(x87CW_IEM); + mBOOLDISPLAY.insert(x87CW_IEM); + mFPU.insert(x87CW_IEM); + + mSETONEZEROTOGGLE.insert(x87CW_PM); + mFPUx87.insert(x87CW_PM); + mBOOLDISPLAY.insert(x87CW_PM); + mFPU.insert(x87CW_PM); + + mSETONEZEROTOGGLE.insert(x87CW_UM); + mFPUx87.insert(x87CW_UM); + mBOOLDISPLAY.insert(x87CW_UM); + mFPU.insert(x87CW_UM); + + mSETONEZEROTOGGLE.insert(x87CW_OM); + mFPUx87.insert(x87CW_OM); + mBOOLDISPLAY.insert(x87CW_OM); + mFPU.insert(x87CW_OM); + + mSETONEZEROTOGGLE.insert(x87CW_ZM); + mFPUx87.insert(x87CW_ZM); + mBOOLDISPLAY.insert(x87CW_ZM); + mFPU.insert(x87CW_ZM); + + mSETONEZEROTOGGLE.insert(x87CW_DM); + mFPUx87.insert(x87CW_DM); + mBOOLDISPLAY.insert(x87CW_DM); + mFPU.insert(x87CW_DM); + + mSETONEZEROTOGGLE.insert(x87CW_IM); + mFPUx87.insert(x87CW_IM); + mBOOLDISPLAY.insert(x87CW_IM); + mFPU.insert(x87CW_IM); + + mSETONEZEROTOGGLE.insert(MxCsr_FZ); + mBOOLDISPLAY.insert(MxCsr_FZ); + mFPU.insert(MxCsr_FZ); + + mSETONEZEROTOGGLE.insert(MxCsr_PM); + mBOOLDISPLAY.insert(MxCsr_PM); + mFPU.insert(MxCsr_PM); + + mSETONEZEROTOGGLE.insert(MxCsr_UM); + mBOOLDISPLAY.insert(MxCsr_UM); + mFPU.insert(MxCsr_UM); + + mSETONEZEROTOGGLE.insert(MxCsr_OM); + mBOOLDISPLAY.insert(MxCsr_OM); + mFPU.insert(MxCsr_OM); + + mSETONEZEROTOGGLE.insert(MxCsr_ZM); + mBOOLDISPLAY.insert(MxCsr_ZM); + mFPU.insert(MxCsr_ZM); + + mSETONEZEROTOGGLE.insert(MxCsr_IM); + mBOOLDISPLAY.insert(MxCsr_IM); + mFPU.insert(MxCsr_IM); + + mSETONEZEROTOGGLE.insert(MxCsr_DM); + mBOOLDISPLAY.insert(MxCsr_DM); + mFPU.insert(MxCsr_DM); + + mSETONEZEROTOGGLE.insert(MxCsr_DAZ); + mBOOLDISPLAY.insert(MxCsr_DAZ); + mFPU.insert(MxCsr_DAZ); + + mSETONEZEROTOGGLE.insert(MxCsr_PE); + mBOOLDISPLAY.insert(MxCsr_PE); + mFPU.insert(MxCsr_PE); + + mSETONEZEROTOGGLE.insert(MxCsr_UE); + mBOOLDISPLAY.insert(MxCsr_UE); + mFPU.insert(MxCsr_UE); + + mSETONEZEROTOGGLE.insert(MxCsr_OE); + mBOOLDISPLAY.insert(MxCsr_OE); + mFPU.insert(MxCsr_OE); + + mSETONEZEROTOGGLE.insert(MxCsr_ZE); + mBOOLDISPLAY.insert(MxCsr_ZE); + mFPU.insert(MxCsr_ZE); + + mSETONEZEROTOGGLE.insert(MxCsr_DE); + mBOOLDISPLAY.insert(MxCsr_DE); + mFPU.insert(MxCsr_DE); + + mSETONEZEROTOGGLE.insert(MxCsr_IE); + mBOOLDISPLAY.insert(MxCsr_IE); + mFPU.insert(MxCsr_IE); + + mFIELDVALUE.insert(MxCsr_RC); + mFPU.insert(MxCsr_RC); + mMODIFYDISPLAY.insert(MxCsr_RC); + + mMODIFYDISPLAY.insert(MM0); + mFPUMMX.insert(MM0); + mFPU.insert(MM0); + mMODIFYDISPLAY.insert(MM1); + mFPUMMX.insert(MM1); + mFPU.insert(MM1); + mFPUMMX.insert(MM2); + mMODIFYDISPLAY.insert(MM2); + mFPU.insert(MM2); + mFPUMMX.insert(MM3); + mMODIFYDISPLAY.insert(MM3); + mFPU.insert(MM3); + mFPUMMX.insert(MM4); + mMODIFYDISPLAY.insert(MM4); + mFPU.insert(MM4); + mFPUMMX.insert(MM5); + mMODIFYDISPLAY.insert(MM5); + mFPU.insert(MM5); + mFPUMMX.insert(MM6); + mMODIFYDISPLAY.insert(MM6); + mFPU.insert(MM6); + mFPUMMX.insert(MM7); + mMODIFYDISPLAY.insert(MM7); + mFPU.insert(MM7); + + mFPUXMM.insert(XMM0); + mMODIFYDISPLAY.insert(XMM0); + mFPU.insert(XMM0); + mFPUXMM.insert(XMM1); + mMODIFYDISPLAY.insert(XMM1); + mFPU.insert(XMM1); + mFPUXMM.insert(XMM2); + mMODIFYDISPLAY.insert(XMM2); + mFPU.insert(XMM2); + mFPUXMM.insert(XMM3); + mMODIFYDISPLAY.insert(XMM3); + mFPU.insert(XMM3); + mFPUXMM.insert(XMM4); + mMODIFYDISPLAY.insert(XMM4); + mFPU.insert(XMM4); + mFPUXMM.insert(XMM5); + mMODIFYDISPLAY.insert(XMM5); + mFPU.insert(XMM5); + mFPUXMM.insert(XMM6); + mMODIFYDISPLAY.insert(XMM6); + mFPU.insert(XMM6); + mFPUXMM.insert(XMM7); + mMODIFYDISPLAY.insert(XMM7); + mFPU.insert(XMM7); +#ifdef _WIN64 + mFPUXMM.insert(XMM8); + mMODIFYDISPLAY.insert(XMM8); + mFPU.insert(XMM8); + mFPUXMM.insert(XMM9); + mMODIFYDISPLAY.insert(XMM9); + mFPU.insert(XMM9); + mFPUXMM.insert(XMM10); + mMODIFYDISPLAY.insert(XMM10); + mFPU.insert(XMM10); + mFPUXMM.insert(XMM11); + mMODIFYDISPLAY.insert(XMM11); + mFPU.insert(XMM11); + mFPUXMM.insert(XMM12); + mMODIFYDISPLAY.insert(XMM12); + mFPU.insert(XMM12); + mFPUXMM.insert(XMM13); + mMODIFYDISPLAY.insert(XMM13); + mFPU.insert(XMM13); + mFPUXMM.insert(XMM14); + mMODIFYDISPLAY.insert(XMM14); + mFPU.insert(XMM14); + mFPUXMM.insert(XMM15); + mMODIFYDISPLAY.insert(XMM15); + mFPU.insert(XMM15); +#endif + + mFPUYMM.insert(YMM0); + mMODIFYDISPLAY.insert(YMM0); + mFPU.insert(YMM0); + mFPUYMM.insert(YMM1); + mMODIFYDISPLAY.insert(YMM1); + mFPU.insert(YMM1); + mFPUYMM.insert(YMM2); + mMODIFYDISPLAY.insert(YMM2); + mFPU.insert(YMM2); + mFPUYMM.insert(YMM3); + mMODIFYDISPLAY.insert(YMM3); + mFPU.insert(YMM3); + mFPUYMM.insert(YMM4); + mMODIFYDISPLAY.insert(YMM4); + mFPU.insert(YMM4); + mFPUYMM.insert(YMM5); + mMODIFYDISPLAY.insert(YMM5); + mFPU.insert(YMM5); + mFPUYMM.insert(YMM6); + mMODIFYDISPLAY.insert(YMM6); + mFPU.insert(YMM6); + mFPUYMM.insert(YMM7); + mMODIFYDISPLAY.insert(YMM7); + mFPU.insert(YMM7); + +#ifdef _WIN64 + mFPUYMM.insert(YMM8); + mMODIFYDISPLAY.insert(YMM8); + mFPU.insert(YMM8); + mFPUYMM.insert(YMM9); + mMODIFYDISPLAY.insert(YMM9); + mFPU.insert(YMM9); + mFPUYMM.insert(YMM10); + mMODIFYDISPLAY.insert(YMM10); + mFPU.insert(YMM10); + mFPUYMM.insert(YMM11); + mMODIFYDISPLAY.insert(YMM11); + mFPU.insert(YMM11); + mFPUYMM.insert(YMM12); + mMODIFYDISPLAY.insert(YMM12); + mFPU.insert(YMM12); + mFPUYMM.insert(YMM13); + mMODIFYDISPLAY.insert(YMM13); + mFPU.insert(YMM13); + mFPUYMM.insert(YMM14); + mMODIFYDISPLAY.insert(YMM14); + mFPU.insert(YMM14); + mFPUYMM.insert(YMM15); + mMODIFYDISPLAY.insert(YMM15); + mFPU.insert(YMM15); +#endif + //registers that should not be changed + mNoChange.insert(LastError); + + mNoChange.insert(GS); + mUSHORTDISPLAY.insert(GS); + + mNoChange.insert(FS); + mUSHORTDISPLAY.insert(FS); + + mNoChange.insert(ES); + mUSHORTDISPLAY.insert(ES); + + mNoChange.insert(DS); + mUSHORTDISPLAY.insert(DS); + + mNoChange.insert(CS); + mUSHORTDISPLAY.insert(CS); + + mNoChange.insert(SS); + mUSHORTDISPLAY.insert(SS); + + mNoChange.insert(DR0); + mUINTDISPLAY.insert(DR0); + mLABELDISPLAY.insert(DR0); + mONLYMODULEANDLABELDISPLAY.insert(DR0); + mCANSTOREADDRESS.insert(DR0); + + mNoChange.insert(DR1); + mONLYMODULEANDLABELDISPLAY.insert(DR1); + mUINTDISPLAY.insert(DR1); + mCANSTOREADDRESS.insert(DR1); + + mLABELDISPLAY.insert(DR2); + mONLYMODULEANDLABELDISPLAY.insert(DR2); + mNoChange.insert(DR2); + mUINTDISPLAY.insert(DR2); + mCANSTOREADDRESS.insert(DR2); + + mNoChange.insert(DR3); + mONLYMODULEANDLABELDISPLAY.insert(DR3); + mLABELDISPLAY.insert(DR3); + mUINTDISPLAY.insert(DR3); + mCANSTOREADDRESS.insert(DR3); + + mNoChange.insert(DR6); + mLABELDISPLAY.insert(DR6); + mONLYMODULEANDLABELDISPLAY.insert(DR6); + mUINTDISPLAY.insert(DR6); + mCANSTOREADDRESS.insert(DR6); + + mNoChange.insert(DR7); + mUINTDISPLAY.insert(DR7); + mONLYMODULEANDLABELDISPLAY.insert(DR7); + mCANSTOREADDRESS.insert(DR7); + mLABELDISPLAY.insert(DR7); + + mNoChange.insert(CIP); + mUINTDISPLAY.insert(CIP); + mLABELDISPLAY.insert(CIP); + mONLYMODULEANDLABELDISPLAY.insert(CIP); + mCANSTOREADDRESS.insert(CIP); + + InitMappings(); + + fontsUpdatedSlot(); + connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot())); + + memset(&wRegDumpStruct, 0, sizeof(REGDUMP)); + memset(&wCipRegDumpStruct, 0, sizeof(REGDUMP)); + mCip = 0; + mRegisterUpdates.clear(); + + mButtonHeight = 0; + yTopSpacing = 4; //set top spacing (in pixels) + + // Context Menu + this->setContextMenuPolicy(Qt::CustomContextMenu); + // foreign messages + connect(Bridge::getBridge(), SIGNAL(updateRegisters()), this, SLOT(updateRegistersSlot())); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(displayCustomContextMenuSlot(QPoint))); + connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE))); + // self communication for repainting (maybe some other widgets needs this information, too) + connect(this, SIGNAL(refresh()), this, SLOT(repaint())); + // context menu actions + connect(wCM_Increment, SIGNAL(triggered()), this, SLOT(onIncrementAction())); + connect(wCM_ChangeFPUView, SIGNAL(triggered()), this, SLOT(onChangeFPUViewAction())); + connect(wCM_Decrement, SIGNAL(triggered()), this, SLOT(onDecrementAction())); + connect(wCM_Incrementx87Stack, SIGNAL(triggered()), this, SLOT(onIncrementx87StackAction())); + connect(wCM_Decrementx87Stack, SIGNAL(triggered()), this, SLOT(onDecrementx87StackAction())); + connect(wCM_Zero, SIGNAL(triggered()), this, SLOT(onZeroAction())); + connect(wCM_SetToOne, SIGNAL(triggered()), this, SLOT(onSetToOneAction())); + connect(wCM_Modify, SIGNAL(triggered()), this, SLOT(onModifyAction())); + connect(wCM_ToggleValue, SIGNAL(triggered()), this, SLOT(onToggleValueAction())); + connect(wCM_CopyToClipboard, SIGNAL(triggered()), this, SLOT(onCopyToClipboardAction())); + connect(wCM_CopySymbolToClipboard, SIGNAL(triggered()), this, SLOT(onCopySymbolToClipboardAction())); + connect(wCM_FollowInDisassembly, SIGNAL(triggered()), this, SLOT(onFollowInDisassembly())); + connect(wCM_FollowInDump, SIGNAL(triggered()), this, SLOT(onFollowInDump())); + connect(wCM_FollowInStack, SIGNAL(triggered()), this, SLOT(onFollowInStack())); + + refreshShortcutsSlot(); + connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); +} + +void RegistersView::refreshShortcutsSlot() +{ + wCM_Increment->setShortcut(ConfigShortcut("ActionIncreaseRegister")); + wCM_Decrement->setShortcut(ConfigShortcut("ActionDecreaseRegister")); + wCM_Zero->setShortcut(ConfigShortcut("ActionZeroRegister")); + wCM_SetToOne->setShortcut(ConfigShortcut("ActionSetOneRegister")); + wCM_ToggleValue->setShortcut(ConfigShortcut("ActionToggleRegisterValue")); + wCM_CopyToClipboard->setShortcut(ConfigShortcut("ActionCopy")); + wCM_CopySymbolToClipboard->setShortcut(ConfigShortcut("ActionCopySymbol")); +} + +RegistersView::~RegistersView() +{ +} + +void RegistersView::fontsUpdatedSlot() +{ + setFont(ConfigFont("Registers")); + int wRowsHeight = QFontMetrics(this->font()).height(); + wRowsHeight = (wRowsHeight * 105) / 100; + wRowsHeight = (wRowsHeight % 2) == 0 ? wRowsHeight : wRowsHeight + 1; + mRowHeight = wRowsHeight; + mCharWidth = QFontMetrics(this->font()).averageCharWidth(); + repaint(); +} + +void RegistersView::ShowFPU(bool set_showfpu) +{ + mShowFpu = set_showfpu; + InitMappings(); + repaint(); +} + + +/** + * @brief retrieves the register id from given corrdinates of the viewport + * @param line + * @param offset (x-coord) + * @param resulting register-id + * @return true if register found + */ +bool RegistersView::identifyRegister(const int line, const int offset, REGISTER_NAME* clickedReg) +{ + // we start by an unknown register id + if(clickedReg) + *clickedReg = UNKNOWN; + bool found_flag = false; + QMap::const_iterator it = mRegisterPlaces.begin(); + // iterate all registers that being displayed + while(it != mRegisterPlaces.end()) + { + if((it.value().line == (line - mVScrollOffset)) /* same line ? */ + && ((1 + it.value().start) <= offset) /* between start ... ? */ + && (offset <= (1 + it.value().start + it.value().labelwidth + it.value().valuesize)) /* ... and end ? */ + ) + { + // we found a matching register in the viewport + if(clickedReg) + *clickedReg = (REGISTER_NAME)it.key(); + found_flag = true; + break; + + } + ++it; + } + return found_flag; +} + +void RegistersView::mousePressEvent(QMouseEvent* event) +{ + if(!DbgIsDebugging()) + return; + + if(event->y() < yTopSpacing - mButtonHeight) + { + onChangeFPUViewAction(); + } + else + { + // get mouse position + const int y = (event->y() - yTopSpacing) / (double)mRowHeight; + const int x = event->x() / (double)mCharWidth; + + REGISTER_NAME r; + // do we find a corresponding register? + if(identifyRegister(y, x, &r)) + { + mSelected = r; + emit refresh(); + } + else + mSelected = UNKNOWN; + } +} + +void RegistersView::mouseDoubleClickEvent(QMouseEvent* event) +{ + Q_UNUSED(event); + if(!DbgIsDebugging() || event->button() != Qt::LeftButton) + return; + // get mouse position + const int y = (event->y() - yTopSpacing) / (double)mRowHeight; + const int x = event->x() / (double)mCharWidth; + + // do we find a corresponding register? + if(!identifyRegister(y, x, 0)) + return; + // is current register general purposes register or FPU register? + if(mMODIFYDISPLAY.contains(mSelected)) + { + wCM_Modify->trigger(); + } + else if(mBOOLDISPLAY.contains(mSelected)) // is flag ? + wCM_ToggleValue->trigger(); + else if(mSelected == CIP) //double clicked on CIP register + DbgCmdExec("disasm cip"); +} + +void RegistersView::paintEvent(QPaintEvent* event) +{ + Q_UNUSED(event); + + if(mChangeViewButton != NULL) + { + if(mShowFpu) + mChangeViewButton->setText("Hide FPU"); + else + mChangeViewButton->setText("Show FPU"); + } + + QPainter wPainter(this->viewport()); + wPainter.fillRect(wPainter.viewport(), QBrush(ConfigColor("RegistersBackgroundColor"))); + + // Don't draw the registers if a program isn't actually running + if(!DbgIsDebugging()) + return; + + // Iterate all registers + for(auto itr = mRegisterMapping.begin(); itr != mRegisterMapping.end(); itr++) + { + // Paint register at given position + drawRegister(&wPainter, itr.key(), registerValue(&wRegDumpStruct, itr.key())); + } +} + +void RegistersView::keyPressEvent(QKeyEvent* event) +{ + if(!DbgIsDebugging()) + return; + if(event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) + wCM_Modify->trigger(); +} + +QSize RegistersView::sizeHint() const +{ + // 32 character width + return QSize(32 * mCharWidth , this->viewport()->height()); +} + +void* RegistersView::operator new(size_t size) +{ + return _aligned_malloc(size, 16); +} + +void RegistersView::operator delete(void* p) +{ + _aligned_free(p); +} + +QString RegistersView::getRegisterLabel(REGISTER_NAME register_selected) +{ + char label_text[MAX_LABEL_SIZE] = ""; + char module_text[MAX_MODULE_SIZE] = ""; + char string_text[MAX_STRING_SIZE] = ""; + + QString valueText = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, register_selected))), mRegisterPlaces[register_selected].valuesize, 16, QChar('0')).toUpper(); + duint register_value = (* ((duint*) registerValue(&wRegDumpStruct, register_selected))); + QString newText = QString(""); + + bool hasString = DbgGetStringAt(register_value, string_text); + bool hasLabel = DbgGetLabelAt(register_value, SEG_DEFAULT, label_text); + bool hasModule = DbgGetModuleAt(register_value, module_text); + + if(hasString && !mONLYMODULEANDLABELDISPLAY.contains(register_selected)) + { + newText = string_text; + } + else if(hasLabel && hasModule) + { + newText = "<" + QString(module_text) + "." + QString(label_text) + ">"; + } + else if(hasModule) + { + newText = QString(module_text) + "." + valueText; + } + else if(hasLabel) + { + newText = "<" + QString(label_text) + ">"; + } + else if(!mONLYMODULEANDLABELDISPLAY.contains(register_selected)) + { + bool isCharacter = false; + if(register_value == (register_value & 0xFF)) + { + QChar c = QChar((char)register_value); + if(c.isPrint()) + { + newText = QString("'%1'").arg((char)register_value); + isCharacter = IsCharacterRegister(register_selected); + } + } + else if(register_value == (register_value & 0xFFF)) //UNICODE? + { + QChar c = QChar((wchar_t)register_value); + if(c.isPrint()) + { + newText = "L'" + QString(c) + "'"; + isCharacter = IsCharacterRegister(register_selected); + } + } + } + + return newText; +} + +double readFloat80(const uint8_t buffer[10]) +{ + /* + * WE ARE LOSSING 2 BYTES WITH THIS FUNCTION. + * TODO: CHANGE THIS FOR ONE BETTER. + */ + //80 bit floating point value according to IEEE-754: + //1 bit sign, 15 bit exponent, 64 bit mantissa + + const uint16_t SIGNBIT = 1 << 15; + const uint16_t EXP_BIAS = (1 << 14) - 1; // 2^(n-1) - 1 = 16383 + const uint16_t SPECIALEXP = (1 << 15) - 1; // all bits set + const uint64_t HIGHBIT = (uint64_t)1 << 63; + const uint64_t QUIETBIT = (uint64_t)1 << 62; + + // Extract sign, exponent and mantissa + uint16_t exponent = *((uint16_t*)&buffer[8]); + uint64_t mantissa = *((uint64_t*)&buffer[0]); + + double sign = (exponent & SIGNBIT) ? -1.0 : 1.0; + exponent &= ~SIGNBIT; + + // Check for undefined values + if((!exponent && (mantissa & HIGHBIT)) || (exponent && !(mantissa & HIGHBIT))) + { + return std::numeric_limits::quiet_NaN(); + } + + // Check for special values (infinity, NaN) + if(exponent == 0) + { + if(mantissa == 0) + { + return sign * 0.0; + } + else + { + // denormalized + } + } + else if(exponent == SPECIALEXP) + { + if(!(mantissa & ~HIGHBIT)) + { + return sign * std::numeric_limits::infinity(); + } + else + { + if(mantissa & QUIETBIT) + { + return std::numeric_limits::quiet_NaN(); + } + else + { + return std::numeric_limits::signaling_NaN(); + } + } + } + + //value = (-1)^s * (m / 2^63) * 2^(e - 16383) + double significand = ((double)mantissa / ((uint64_t)1 << 63)); + return sign * ldexp(significand, exponent - EXP_BIAS); +} + +QString RegistersView::GetRegStringValueFromValue(REGISTER_NAME reg, char* value) +{ + QString valueText; + + if(mUINTDISPLAY.contains(reg)) + valueText = QString("%1").arg((* ((duint*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + else if(mUSHORTDISPLAY.contains(reg)) + valueText = QString("%1").arg((* ((unsigned short*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + else if(mDWORDDISPLAY.contains(reg)) + valueText = QString("%1").arg((* ((DWORD*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + else if(mBOOLDISPLAY.contains(reg)) + valueText = QString("%1").arg((* ((bool*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + else if(mFIELDVALUE.contains(reg)) + { + if(mTAGWORD.contains(reg)) + { + valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); + valueText += QString(" ("); + valueText += GetTagWordStateString((* ((unsigned short*) value))); + valueText += QString(")"); + } + if(reg == MxCsr_RC) + { + valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); + valueText += QString(" ("); + valueText += GetMxCsrRCStateString((* ((unsigned short*) value))); + valueText += QString(")"); + } + else if(reg == x87CW_RC) + { + valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); + valueText += QString(" ("); + valueText += GetControlWordRCStateString((* ((unsigned short*) value))); + valueText += QString(")"); + } + else if(reg == x87CW_PC) + { + valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); + valueText += QString(" ("); + valueText += GetControlWordPCStateString((* ((unsigned short*) value))); + valueText += QString(")"); + } + else if(reg == x87SW_TOP) + { + valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); + valueText += QString(" (ST0="); + valueText += GetStatusWordTOPStateString((* ((unsigned short*) value))); + valueText += QString(")"); + } + } + else if(reg == LastError) + { + LASTERROR* data = (LASTERROR*)value; + if(data->name) + valueText = QString().sprintf("%08X (%s)", data->code, data->name); + else + valueText = QString().sprintf("%08X", data->code); + mRegisterPlaces[LastError].valuesize = valueText.length(); + } + else + { + SIZE_T size = GetSizeRegister(reg); + if(size != 0) + valueText = QString(QByteArray(value, size).toHex()).toUpper(); + else + valueText = QString("???"); + } + + return valueText; +} + +#define MxCsr_RC_NEAR 0 +#define MxCsr_RC_NEGATIVE 1 +#define MxCsr_RC_POSITIVE 2 +#define MxCsr_RC_TOZERO 3 + +STRING_VALUE_TABLE_t MxCsrRCValueStringTable[] = +{ + {"Toward Zero", MxCsr_RC_TOZERO}, + {"Toward Positive", MxCsr_RC_POSITIVE}, + {"Toward Negative", MxCsr_RC_NEGATIVE}, + {"Round Near", MxCsr_RC_NEAR} +}; + +unsigned int RegistersView::GetMxCsrRCValueFromString(QString string) +{ + int i; + + for(i = 0; i < (sizeof(MxCsrRCValueStringTable) / sizeof(*MxCsrRCValueStringTable)); i++) + { + if(MxCsrRCValueStringTable[i].string == string) + return MxCsrRCValueStringTable[i].value; + } + + return i; +} + +QString RegistersView::GetMxCsrRCStateString(unsigned short state) +{ + int i; + + for(i = 0; i < (sizeof(MxCsrRCValueStringTable) / sizeof(*MxCsrRCValueStringTable)); i++) + { + if(MxCsrRCValueStringTable[i].value == state) + return MxCsrRCValueStringTable[i].string; + } + + return "Unknown"; +} + +#define x87CW_RC_NEAR 0 +#define x87CW_RC_DOWN 1 +#define x87CW_RC_UP 2 +#define x87CW_RC_TRUNCATE 3 + +STRING_VALUE_TABLE_t ControlWordRCValueStringTable[] = +{ + {"Truncate", x87CW_RC_TRUNCATE}, + {"Round Up", x87CW_RC_UP}, + {"Round Down", x87CW_RC_DOWN}, + {"Round Near", x87CW_RC_NEAR} +}; + +unsigned int RegistersView::GetControlWordRCValueFromString(QString string) +{ + int i; + + for(i = 0; i < (sizeof(ControlWordRCValueStringTable) / sizeof(*ControlWordRCValueStringTable)); i++) + { + if(ControlWordRCValueStringTable[i].string == string) + return ControlWordRCValueStringTable[i].value; + } + + return i; +} + +QString RegistersView::GetControlWordRCStateString(unsigned short state) +{ + int i; + + for(i = 0; i < (sizeof(ControlWordRCValueStringTable) / sizeof(*ControlWordRCValueStringTable)); i++) + { + if(ControlWordRCValueStringTable[i].value == state) + return ControlWordRCValueStringTable[i].string; + } + + return "unknown"; +} + +#define x87SW_TOP_0 0 +#define x87SW_TOP_1 1 +#define x87SW_TOP_2 2 +#define x87SW_TOP_3 3 +#define x87SW_TOP_4 4 +#define x87SW_TOP_5 5 +#define x87SW_TOP_6 6 +#define x87SW_TOP_7 7 + +STRING_VALUE_TABLE_t StatusWordTOPValueStringTable[] = +{ + {"x87r0", x87SW_TOP_0}, + {"x87r1", x87SW_TOP_1}, + {"x87r2", x87SW_TOP_2}, + {"x87r3", x87SW_TOP_3}, + {"x87r4", x87SW_TOP_4}, + {"x87r5", x87SW_TOP_5}, + {"x87r6", x87SW_TOP_6}, + {"x87r7", x87SW_TOP_7} +}; + +unsigned int RegistersView::GetStatusWordTOPValueFromString(QString string) +{ + int i; + + for(i = 0; i < (sizeof(StatusWordTOPValueStringTable) / sizeof(*StatusWordTOPValueStringTable)); i++) + { + if(StatusWordTOPValueStringTable[i].string == string) + return StatusWordTOPValueStringTable[i].value; + } + + return i; +} + +QString RegistersView::GetStatusWordTOPStateString(unsigned short state) +{ + int i; + + for(i = 0; i < (sizeof(StatusWordTOPValueStringTable) / sizeof(*StatusWordTOPValueStringTable)); i++) + { + if(StatusWordTOPValueStringTable[i].value == state) + return StatusWordTOPValueStringTable[i].string; + } + + return "unknown"; +} + + +#define x87CW_PC_REAL4 0 +#define x87CW_PC_NOTUSED 1 +#define x87CW_PC_REAL8 2 +#define x87CW_PC_REAL10 3 + +STRING_VALUE_TABLE_t ControlWordPCValueStringTable[] = +{ + {"Real4", x87CW_PC_REAL4}, + {"Not Used", x87CW_PC_NOTUSED}, + {"Real8", x87CW_PC_REAL8}, + {"Real10", x87CW_PC_REAL10} +}; + + +unsigned int RegistersView::GetControlWordPCValueFromString(QString string) +{ + int i; + + for(i = 0; i < (sizeof(ControlWordPCValueStringTable) / sizeof(*ControlWordPCValueStringTable)); i++) + { + if(ControlWordPCValueStringTable[i].string == string) + return ControlWordPCValueStringTable[i].value; + } + + return i; +} + + +QString RegistersView::GetControlWordPCStateString(unsigned short state) +{ + int i; + + for(i = 0; i < (sizeof(ControlWordPCValueStringTable) / sizeof(*ControlWordPCValueStringTable)); i++) + { + if(ControlWordPCValueStringTable[i].value == state) + return ControlWordPCValueStringTable[i].string; + } + + return "unknown"; +} + + +#define X87FPU_TAGWORD_NONZERO 0 +#define X87FPU_TAGWORD_ZERO 1 +#define X87FPU_TAGWORD_SPECIAL 2 +#define X87FPU_TAGWORD_EMPTY 3 + +STRING_VALUE_TABLE_t TagWordValueStringTable[] = +{ + {"Nonzero", X87FPU_TAGWORD_NONZERO}, + {"Zero", X87FPU_TAGWORD_ZERO}, + {"Special", X87FPU_TAGWORD_SPECIAL}, + {"Empty", X87FPU_TAGWORD_EMPTY} +}; + +unsigned int RegistersView::GetTagWordValueFromString(QString string) +{ + int i; + + for(i = 0; i < (sizeof(TagWordValueStringTable) / sizeof(*TagWordValueStringTable)); i++) + { + if(TagWordValueStringTable[i].string == string) + return TagWordValueStringTable[i].value; + } + + return i; +} + + +QString RegistersView::GetTagWordStateString(unsigned short state) +{ + int i; + + for(i = 0; i < (sizeof(TagWordValueStringTable) / sizeof(*TagWordValueStringTable)); i++) + { + if(TagWordValueStringTable[i].value == state) + return TagWordValueStringTable[i].string; + } + + return "Unknown"; +} + +void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) +{ + // is the register-id known? + if(mRegisterMapping.contains(reg)) + { + // padding to the left is at least one character (looks better) + int x = mCharWidth * (1 + mRegisterPlaces[reg].start); + int ySpace = yTopSpacing; + if(mVScrollOffset != 0) + ySpace = 0; + int y = mRowHeight * (mRegisterPlaces[reg].line + mVScrollOffset) + ySpace; + + //draw raster + /* + p->save(); + p->setPen(QColor("#FF0000")); + p->drawLine(0, y, this->viewport()->width(), y); + p->restore(); + */ + + // draw name of value + int width = mCharWidth * mRegisterMapping[reg].length(); + p->setPen(ConfigColor("RegistersLabelColor")); + p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, mRegisterMapping[reg]); + x += (mRegisterPlaces[reg].labelwidth) * mCharWidth; + //p->drawText(offset,mRowHeight*(mRegisterPlaces[reg].line+1),mRegisterMapping[reg]); + + //set highlighting + if(DbgIsDebugging() && mRegisterUpdates.contains(reg)) + p->setPen(ConfigColor("RegistersModifiedColor")); + else + p->setPen(ConfigColor("RegistersColor")); + + //get register value + QString valueText = GetRegStringValueFromValue(reg, value); + + //selection + if(mSelected == reg) + { + p->fillRect(x, y, mRegisterPlaces[reg].valuesize * mCharWidth, mRowHeight, QBrush(ConfigColor("RegistersSelectionColor"))); + //p->fillRect(QRect(x + (mRegisterPlaces[reg].labelwidth)*mCharWidth ,mRowHeight*(mRegisterPlaces[reg].line)+2, mRegisterPlaces[reg].valuesize*mCharWidth, mRowHeight), QBrush(ConfigColor("RegistersSelectionColor"))); + } + + // draw value + width = mCharWidth * valueText.length(); + p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, valueText); + //p->drawText(x + (mRegisterPlaces[reg].labelwidth)*mCharWidth ,mRowHeight*(mRegisterPlaces[reg].line+1),QString("%1").arg(value, mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper()); + + x += valueText.length() * mCharWidth; + + if(mFPUx87_80BITSDISPLAY.contains(reg) && DbgIsDebugging()) + { + p->setPen(ConfigColor("RegistersExtraInfoColor")); + x += 1 * mCharWidth; //1 space + QString newText; + if(mRegisterUpdates.contains(x87SW_TOP)) + p->setPen(ConfigColor("RegistersModifiedColor")); + + newText = QString("ST%1 ").arg(((X87FPUREGISTER*) registerValue(&wRegDumpStruct, reg))->st_value); + width = newText.length() * mCharWidth; + p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); + + x += width; + + newText = QString(""); + + p->setPen(ConfigColor("RegistersExtraInfoColor")); + + if(reg == x87r0 && mRegisterUpdates.contains(x87TW_0)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r1 && mRegisterUpdates.contains(x87TW_1)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r2 && mRegisterUpdates.contains(x87TW_2)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r3 && mRegisterUpdates.contains(x87TW_3)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r4 && mRegisterUpdates.contains(x87TW_4)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r5 && mRegisterUpdates.contains(x87TW_5)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r6 && mRegisterUpdates.contains(x87TW_6)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r7 && mRegisterUpdates.contains(x87TW_7)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + + newText += GetTagWordStateString(((X87FPUREGISTER*) registerValue(&wRegDumpStruct, reg))->tag) + QString(" "); + + width = newText.length() * mCharWidth; + p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); + + x += width; + + newText = QString(""); + + p->setPen(ConfigColor("RegistersExtraInfoColor")); + + if(DbgIsDebugging() && mRegisterUpdates.contains(reg)) + p->setPen(ConfigColor("RegistersModifiedColor")); + + newText += QString::number(readFloat80(((X87FPUREGISTER*) registerValue(&wRegDumpStruct, reg))->data)); + width = newText.length() * mCharWidth; + p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); + } + + // do we have a label ? + if(mLABELDISPLAY.contains(reg)) + { + x += 5 * mCharWidth; //5 spaces + + QString newText = getRegisterLabel(reg); + + // are there additional informations? + if(newText != "") + { + width = newText.length() * mCharWidth; + p->setPen(ConfigColor("RegistersExtraInfoColor")); + p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); + //p->drawText(x,mRowHeight*(mRegisterPlaces[reg].line+1),newText); + } + } + } +} + +void RegistersView::updateRegistersSlot() +{ + // read registers + REGDUMP z; + memset(&z, 0, sizeof(REGDUMP)); + DbgGetRegDump(&z); + // update gui + setRegisters(&z); +} + +void RegistersView::ModifyFields(QString title, STRING_VALUE_TABLE_t* table, SIZE_T size) +{ + SelectFields mSelectFields(this); + QListWidget* mQListWidget = mSelectFields.GetList(); + + QStringList items; + unsigned int i; + + for(i = 0; i < size; i++) + items << table[i].string; + + mQListWidget->addItems(items); + + mSelectFields.setWindowTitle(title); + if(mSelectFields.exec() != QDialog::Accepted) + return; + + if(mQListWidget->selectedItems().count() != 1) + return; + + QListWidgetItem* item = mQListWidget->takeItem(mQListWidget->currentRow()); + + duint value; + + for(i = 0; i < size; i++) + { + if(table[i].string == item->text()) + break; + } + + value = table[i].value; + + setRegister(mSelected, (duint)value); +} + +#define MODIFY_FIELDS_DISPLAY(title, table) ModifyFields(QString("Edit ") + QString(title), (STRING_VALUE_TABLE_t *) & table, SIZE_TABLE(table) ) + +void RegistersView::displayEditDialog() +{ + if(mFPU.contains(mSelected)) + { + if(mTAGWORD.contains(mSelected)) + MODIFY_FIELDS_DISPLAY("Tag " + mRegisterMapping.constFind(mSelected).value(), TagWordValueStringTable); + else if(mSelected == MxCsr_RC) + MODIFY_FIELDS_DISPLAY("MxCsr_RC", MxCsrRCValueStringTable); + else if(mSelected == x87CW_RC) + MODIFY_FIELDS_DISPLAY("x87CW_RC", ControlWordRCValueStringTable); + else if(mSelected == x87CW_PC) + MODIFY_FIELDS_DISPLAY("x87CW_PC", ControlWordPCValueStringTable); + else if(mSelected == x87SW_TOP) + MODIFY_FIELDS_DISPLAY("x87SW_TOP ST0=", StatusWordTOPValueStringTable); + else + { + bool errorinput = false; + LineEditDialog mLineEdit(this); + + mLineEdit.setText(GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected))); + mLineEdit.setWindowTitle("Edit FPU register"); + mLineEdit.setWindowIcon(QIcon(":/icons/images/log.png")); + mLineEdit.setCursorPosition(0); + mLineEdit.ForceSize(GetSizeRegister(mSelected) * 2); + do + { + errorinput = false; + if(mLineEdit.exec() != QDialog::Accepted) + return; //pressed cancel + else + { + bool ok = false; + duint fpuvalue; + + if(mUSHORTDISPLAY.contains(mSelected)) + fpuvalue = (duint) mLineEdit.editText.toUShort(&ok, 16); + else if(mDWORDDISPLAY.contains(mSelected)) + fpuvalue = mLineEdit.editText.toUInt(&ok, 16); + else if(mFPUMMX.contains(mSelected) || mFPUXMM.contains(mSelected) || mFPUYMM.contains(mSelected) || mFPUx87_80BITSDISPLAY.contains(mSelected)) + { + QByteArray pArray = mLineEdit.editText.toLocal8Bit(); + if(pArray.size() == GetSizeRegister(mSelected) * 2) + { + char* pData = (char*) calloc(1, sizeof(char) * GetSizeRegister(mSelected)); + + if(pData != NULL) + { + ok = true; + char actual_char[3]; + unsigned int i; + for(i = 0; i < GetSizeRegister(mSelected); i++) + { + memset(actual_char, 0, sizeof(actual_char)); + memcpy(actual_char, (char*) pArray.data() + (i * 2), 2); + if(! isxdigit(actual_char[0]) || ! isxdigit(actual_char[1])) + { + ok = false; + break; + } + pData[i] = (char)strtol(actual_char, NULL, 16); + } + + if(ok) + setRegister(mSelected, (duint) pData); + + free(pData); + + if(ok) + return; + } + } + } + if(!ok) + { + errorinput = true; + + QMessageBox msg(QMessageBox::Warning, "ERROR CONVERTING TO HEX", "ERROR CONVERTING TO HEXADECIMAL"); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + } + else + setRegister(mSelected, fpuvalue); + } + + } + while(errorinput); + } + } + else + { + WordEditDialog wEditDial(this); + wEditDial.setup(QString("Edit"), (* ((duint*) registerValue(&wRegDumpStruct, mSelected))), sizeof(dsint)); + if(wEditDial.exec() == QDialog::Accepted) //OK button clicked + setRegister(mSelected, wEditDial.getVal()); + } +} + +void RegistersView::onIncrementx87StackAction() +{ + if(mFPUx87_80BITSDISPLAY.contains(mSelected)) + setRegister(x87SW_TOP, ((* ((duint*) registerValue(&wRegDumpStruct, x87SW_TOP))) + 1) % 8); +} + +void RegistersView::onDecrementx87StackAction() +{ + if(mFPUx87_80BITSDISPLAY.contains(mSelected)) + setRegister(x87SW_TOP, ((* ((duint*) registerValue(&wRegDumpStruct, x87SW_TOP))) - 1) % 8); +} + +void RegistersView::onIncrementAction() +{ + if(mINCREMENTDECREMET.contains(mSelected)) + setRegister(mSelected, (* ((duint*) registerValue(&wRegDumpStruct, mSelected))) + 1); +} + +void RegistersView::onDecrementAction() +{ + if(mINCREMENTDECREMET.contains(mSelected)) + setRegister(mSelected, (* ((duint*) registerValue(&wRegDumpStruct, mSelected))) - 1); +} + +void RegistersView::onZeroAction() +{ + if(mSETONEZEROTOGGLE.contains(mSelected)) + setRegister(mSelected, 0); +} + +void RegistersView::onSetToOneAction() +{ + if(mSETONEZEROTOGGLE.contains(mSelected)) + setRegister(mSelected, 1); +} + +void RegistersView::onModifyAction() +{ + if(mMODIFYDISPLAY.contains(mSelected)) + displayEditDialog(); +} + +void RegistersView::onToggleValueAction() +{ + if(mSETONEZEROTOGGLE.contains(mSelected)) + { + if(mBOOLDISPLAY.contains(mSelected)) + { + int value = (int)(* (bool*) registerValue(&wRegDumpStruct, mSelected)); + setRegister(mSelected, value ^ 1); + } + else + { + bool ok = false; + dsint val = GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected)).toInt(&ok, 16); + if(ok) + { + val++; + val *= -1; + setRegister(mSelected, val); + } + } + } +} + +void RegistersView::onCopyToClipboardAction() +{ + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected))); +} + +void RegistersView::onCopySymbolToClipboardAction() +{ + if(mLABELDISPLAY.contains(mSelected)) + { + QClipboard* clipboard = QApplication::clipboard(); + QString symbol = getRegisterLabel(mSelected); + if(symbol != "") + clipboard->setText(symbol); + } +} + +void RegistersView::onFollowInDisassembly() +{ + if(mCANSTOREADDRESS.contains(mSelected)) + { + QString addr = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); + if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&wRegDumpStruct, mSelected))))) + DbgCmdExec(QString().sprintf("disasm \"%s\"", addr.toUtf8().constData()).toUtf8().constData()); + } +} + +void RegistersView::onFollowInDump() +{ + if(mCANSTOREADDRESS.contains(mSelected)) + { + QString addr = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); + if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&wRegDumpStruct, mSelected))))) + DbgCmdExec(QString().sprintf("dump \"%s\"", addr.toUtf8().constData()).toUtf8().constData()); + } +} + +void RegistersView::onFollowInStack() +{ + if(mCANSTOREADDRESS.contains(mSelected)) + { + QString addr = QString("%1").arg((* ((duint*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); + if(DbgMemIsValidReadPtr((* ((duint*) registerValue(&wRegDumpStruct, mSelected))))) + DbgCmdExec(QString().sprintf("sdump \"%s\"", addr.toUtf8().constData()).toUtf8().constData()); + } +} + +void RegistersView::onChangeFPUViewAction() +{ + if(mShowFpu == true) + ShowFPU(false); + else + ShowFPU(true); +} + +void RegistersView::displayCustomContextMenuSlot(QPoint pos) +{ + if(!DbgIsDebugging()) + return; + QMenu wMenu(this); + + if(mSelected != UNKNOWN) + { + if(mSETONEZEROTOGGLE.contains(mSelected)) + { + if((* ((duint*) registerValue(&wRegDumpStruct, mSelected))) >= 1) + wMenu.addAction(wCM_Zero); + if((* ((duint*) registerValue(&wRegDumpStruct, mSelected))) == 0) + wMenu.addAction(wCM_SetToOne); + wMenu.addAction(wCM_ToggleValue); + } + + if(mFPUx87_80BITSDISPLAY.contains(mSelected)) + { + wMenu.addAction(wCM_Incrementx87Stack); + wMenu.addAction(wCM_Decrementx87Stack); + } + + if(mINCREMENTDECREMET.contains(mSelected)) + { + wMenu.addAction(wCM_Increment); + wMenu.addAction(wCM_Decrement); + } + + if(mMODIFYDISPLAY.contains(mSelected)) + { + wMenu.addAction(wCM_Modify); + } + + if(mCANSTOREADDRESS.contains(mSelected)) + { + duint addr = (* ((duint*) registerValue(&wRegDumpStruct, mSelected))); + if(DbgMemIsValidReadPtr(addr)) + { + wMenu.addAction(wCM_FollowInDump); + wMenu.addAction(wCM_FollowInDisassembly); + duint size = 0; + duint base = DbgMemFindBaseAddr(DbgValFromString("csp"), &size); + if(addr >= base && addr < base + size) + wMenu.addAction(wCM_FollowInStack); + } + } + + if(mLABELDISPLAY.contains(mSelected)) + { + QString symbol = getRegisterLabel(mSelected); + if(symbol != "") + wMenu.addAction(wCM_CopySymbolToClipboard); + } + + wMenu.addAction(wCM_CopyToClipboard); + + wMenu.exec(this->mapToGlobal(pos)); + } + else + { + wMenu.addSeparator(); + wMenu.addAction(wCM_ChangeFPUView); + wMenu.addSeparator(); +#ifdef _WIN64 + QAction* wHwbpCsp = wMenu.addAction("HW Break on [RSP]"); +#else + QAction* wHwbpCsp = wMenu.addAction("HW Break on [ESP]"); +#endif + QAction* wAction = wMenu.exec(this->mapToGlobal(pos)); + + if(wAction == wHwbpCsp) + DbgCmdExec("bphws csp,rw"); + } +} + +void RegistersView::setRegister(REGISTER_NAME reg, duint value) +{ + // is register-id known? + if(mRegisterMapping.contains(reg)) + { + // map "cax" to "eax" or "rax" + QString wRegName = mRegisterMapping.constFind(reg).value(); + + // flags need to '!' infront + if(mFlags.contains(reg)) + wRegName = "!" + wRegName; + + + // we change the value (so highlight it) + mRegisterUpdates.insert(reg); + // tell everything the compiler + if(mFPU.contains(reg)) + wRegName = "_" + wRegName; + + DbgValToString(wRegName.toUtf8().constData(), value); + + // force repaint + emit refresh(); + } +} + +void RegistersView::debugStateChangedSlot(DBGSTATE state) +{ + if(state == stopped) + { + updateRegistersSlot(); + } +} + +void RegistersView::repaint() +{ + this->viewport()->repaint(); +} + +SIZE_T RegistersView::GetSizeRegister(const REGISTER_NAME reg_name) +{ + SIZE_T size; + + if(mUINTDISPLAY.contains(reg_name)) + size = sizeof(duint); + else if(mUSHORTDISPLAY.contains(reg_name) || mFIELDVALUE.contains(reg_name)) + size = sizeof(unsigned short); + else if(mDWORDDISPLAY.contains(reg_name)) + size = sizeof(DWORD); + else if(mBOOLDISPLAY.contains(reg_name)) + size = sizeof(bool); + else if(mFPUx87_80BITSDISPLAY.contains(reg_name)) + size = 10; + else if(mFPUMMX.contains(reg_name)) + size = 8; + else if(mFPUXMM.contains(reg_name)) + size = 16; + else if(mFPUYMM.contains(reg_name)) + size = 32; + else if(reg_name == LastError) + return sizeof(DWORD); + else + size = 0; + + return size; +} + +int RegistersView::CompareRegisters(const REGISTER_NAME reg_name, REGDUMP* regdump1, REGDUMP* regdump2) +{ + SIZE_T size = GetSizeRegister(reg_name); + char* reg1_data = registerValue(regdump1, reg_name); + char* reg2_data = registerValue(regdump2, reg_name); + + if(size != 0) + return memcmp(reg1_data, reg2_data, size); + + return -1; +} + +char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) +{ + static int null_value = 0; + // this is probably the most efficient general method to access the values of the struct + // TODO: add an array with something like: return array[reg].data, this is more fast :-) + if(reg == CAX) return (char*) & (regd->regcontext.cax); + if(reg == CBX) return (char*) & (regd->regcontext.cbx); + if(reg == CCX) return (char*) & (regd->regcontext.ccx); + if(reg == CDX) return (char*) & (regd->regcontext.cdx); + if(reg == CSI) return (char*) & (regd->regcontext.csi); + if(reg == CDI) return (char*) & (regd->regcontext.cdi); + if(reg == CBP) return (char*) & (regd->regcontext.cbp); + if(reg == CSP) return (char*) & (regd->regcontext.csp); + + if(reg == CIP) return (char*) & (regd->regcontext.cip); + if(reg == EFLAGS) return (char*) & (regd->regcontext.eflags); +#ifdef _WIN64 + if(reg == R8) return (char*) & (regd->regcontext.r8); + if(reg == R9) return (char*) & (regd->regcontext.r9); + if(reg == R10) return (char*) & (regd->regcontext.r10); + if(reg == R11) return (char*) & (regd->regcontext.r11); + if(reg == R12) return (char*) & (regd->regcontext.r12); + if(reg == R13) return (char*) & (regd->regcontext.r13); + if(reg == R14) return (char*) & (regd->regcontext.r14); + if(reg == R15) return (char*) & (regd->regcontext.r15); +#endif + // CF,PF,AF,ZF,SF,TF,IF,DF,OF + if(reg == CF) return (char*) & (regd->flags.c); + if(reg == PF) return (char*) & (regd->flags.p); + if(reg == AF) return (char*) & (regd->flags.a); + if(reg == ZF) return (char*) & (regd->flags.z); + if(reg == SF) return (char*) & (regd->flags.s); + if(reg == TF) return (char*) & (regd->flags.t); + if(reg == IF) return (char*) & (regd->flags.i); + if(reg == DF) return (char*) & (regd->flags.d); + if(reg == OF) return (char*) & (regd->flags.o); + + // GS,FS,ES,DS,CS,SS + if(reg == GS) return (char*) & (regd->regcontext.gs); + if(reg == FS) return (char*) & (regd->regcontext.fs); + if(reg == ES) return (char*) & (regd->regcontext.es); + if(reg == DS) return (char*) & (regd->regcontext.ds); + if(reg == CS) return (char*) & (regd->regcontext.cs); + if(reg == SS) return (char*) & (regd->regcontext.ss); + + if(reg == LastError) return (char*) & (regd->lastError); + + if(reg == DR0) return (char*) & (regd->regcontext.dr0); + if(reg == DR1) return (char*) & (regd->regcontext.dr1); + if(reg == DR2) return (char*) & (regd->regcontext.dr2); + if(reg == DR3) return (char*) & (regd->regcontext.dr3); + if(reg == DR6) return (char*) & (regd->regcontext.dr6); + if(reg == DR7) return (char*) & (regd->regcontext.dr7); + + if(reg == MM0) return (char*) & (regd->mmx[0]); + if(reg == MM1) return (char*) & (regd->mmx[1]); + if(reg == MM2) return (char*) & (regd->mmx[2]); + if(reg == MM3) return (char*) & (regd->mmx[3]); + if(reg == MM4) return (char*) & (regd->mmx[4]); + if(reg == MM5) return (char*) & (regd->mmx[5]); + if(reg == MM6) return (char*) & (regd->mmx[6]); + if(reg == MM7) return (char*) & (regd->mmx[7]); + + if(reg == x87r0) return (char*) & (regd->x87FPURegisters[0]); + if(reg == x87r1) return (char*) & (regd->x87FPURegisters[1]); + if(reg == x87r2) return (char*) & (regd->x87FPURegisters[2]); + if(reg == x87r3) return (char*) & (regd->x87FPURegisters[3]); + if(reg == x87r4) return (char*) & (regd->x87FPURegisters[4]); + if(reg == x87r5) return (char*) & (regd->x87FPURegisters[5]); + if(reg == x87r6) return (char*) & (regd->x87FPURegisters[6]); + if(reg == x87r7) return (char*) & (regd->x87FPURegisters[7]); + + if(reg == x87TagWord) return (char*) & (regd->regcontext.x87fpu.TagWord); + + if(reg == x87ControlWord) return (char*) & (regd->regcontext.x87fpu.ControlWord); + + if(reg == x87TW_0) return (char*) & (regd->x87FPURegisters[0].tag); + if(reg == x87TW_1) return (char*) & (regd->x87FPURegisters[1].tag); + if(reg == x87TW_2) return (char*) & (regd->x87FPURegisters[2].tag); + if(reg == x87TW_3) return (char*) & (regd->x87FPURegisters[3].tag); + if(reg == x87TW_4) return (char*) & (regd->x87FPURegisters[4].tag); + if(reg == x87TW_5) return (char*) & (regd->x87FPURegisters[5].tag); + if(reg == x87TW_6) return (char*) & (regd->x87FPURegisters[6].tag); + if(reg == x87TW_7) return (char*) & (regd->x87FPURegisters[7].tag); + + if(reg == x87CW_IC) return (char*) & (regd->x87ControlWordFields.IC); + if(reg == x87CW_IEM) return (char*) & (regd->x87ControlWordFields.IEM); + if(reg == x87CW_PM) return (char*) & (regd->x87ControlWordFields.PM); + if(reg == x87CW_UM) return (char*) & (regd->x87ControlWordFields.UM); + if(reg == x87CW_OM) return (char*) & (regd->x87ControlWordFields.OM); + if(reg == x87CW_ZM) return (char*) & (regd->x87ControlWordFields.ZM); + if(reg == x87CW_DM) return (char*) & (regd->x87ControlWordFields.DM); + if(reg == x87CW_IM) return (char*) & (regd->x87ControlWordFields.IM); + if(reg == x87CW_RC) return (char*) & (regd->x87ControlWordFields.RC); + if(reg == x87CW_PC) return (char*) & (regd->x87ControlWordFields.PC); + + if(reg == x87StatusWord) return (char*) & (regd->regcontext.x87fpu.StatusWord); + + if(reg == x87SW_B) return (char*) & (regd->x87StatusWordFields.B); + if(reg == x87SW_C3) return (char*) & (regd->x87StatusWordFields.C3); + if(reg == x87SW_C2) return (char*) & (regd->x87StatusWordFields.C2); + if(reg == x87SW_C1) return (char*) & (regd->x87StatusWordFields.C1); + if(reg == x87SW_O) return (char*) & (regd->x87StatusWordFields.O); + if(reg == x87SW_IR) return (char*) & (regd->x87StatusWordFields.IR); + if(reg == x87SW_SF) return (char*) & (regd->x87StatusWordFields.SF); + if(reg == x87SW_P) return (char*) & (regd->x87StatusWordFields.P); + if(reg == x87SW_U) return (char*) & (regd->x87StatusWordFields.U); + if(reg == x87SW_Z) return (char*) & (regd->x87StatusWordFields.Z); + if(reg == x87SW_D) return (char*) & (regd->x87StatusWordFields.D); + if(reg == x87SW_I) return (char*) & (regd->x87StatusWordFields.I); + if(reg == x87SW_C0) return (char*) & (regd->x87StatusWordFields.C0); + if(reg == x87SW_TOP) return (char*) & (regd->x87StatusWordFields.TOP); + + if(reg == MxCsr) return (char*) & (regd->regcontext.MxCsr); + + if(reg == MxCsr_FZ) return (char*) & (regd->MxCsrFields.FZ); + if(reg == MxCsr_PM) return (char*) & (regd->MxCsrFields.PM); + if(reg == MxCsr_UM) return (char*) & (regd->MxCsrFields.UM); + if(reg == MxCsr_OM) return (char*) & (regd->MxCsrFields.OM); + if(reg == MxCsr_ZM) return (char*) & (regd->MxCsrFields.ZM); + if(reg == MxCsr_IM) return (char*) & (regd->MxCsrFields.IM); + if(reg == MxCsr_DM) return (char*) & (regd->MxCsrFields.DM); + if(reg == MxCsr_DAZ) return (char*) & (regd->MxCsrFields.DAZ); + if(reg == MxCsr_PE) return (char*) & (regd->MxCsrFields.PE); + if(reg == MxCsr_UE) return (char*) & (regd->MxCsrFields.UE); + if(reg == MxCsr_OE) return (char*) & (regd->MxCsrFields.OE); + if(reg == MxCsr_ZE) return (char*) & (regd->MxCsrFields.ZE); + if(reg == MxCsr_DE) return (char*) & (regd->MxCsrFields.DE); + if(reg == MxCsr_IE) return (char*) & (regd->MxCsrFields.IE); + if(reg == MxCsr_RC) return (char*) & (regd->MxCsrFields.RC); + + if(reg == XMM0) return (char*) & (regd->regcontext.XmmRegisters[0]); + if(reg == XMM1) return (char*) & (regd->regcontext.XmmRegisters[1]); + if(reg == XMM2) return (char*) & (regd->regcontext.XmmRegisters[2]); + if(reg == XMM3) return (char*) & (regd->regcontext.XmmRegisters[3]); + if(reg == XMM4) return (char*) & (regd->regcontext.XmmRegisters[4]); + if(reg == XMM5) return (char*) & (regd->regcontext.XmmRegisters[5]); + if(reg == XMM6) return (char*) & (regd->regcontext.XmmRegisters[6]); + if(reg == XMM7) return (char*) & (regd->regcontext.XmmRegisters[7]); +#ifdef _WIN64 + if(reg == XMM8) return (char*) & (regd->regcontext.XmmRegisters[8]); + if(reg == XMM9) return (char*) & (regd->regcontext.XmmRegisters[9]); + if(reg == XMM10) return (char*) & (regd->regcontext.XmmRegisters[10]); + if(reg == XMM11) return (char*) & (regd->regcontext.XmmRegisters[11]); + if(reg == XMM12) return (char*) & (regd->regcontext.XmmRegisters[12]); + if(reg == XMM13) return (char*) & (regd->regcontext.XmmRegisters[13]); + if(reg == XMM14) return (char*) & (regd->regcontext.XmmRegisters[14]); + if(reg == XMM15) return (char*) & (regd->regcontext.XmmRegisters[15]); +#endif //_WIN64 + + if(reg == YMM0) return (char*) & (regd->regcontext.YmmRegisters[0]); + if(reg == YMM1) return (char*) & (regd->regcontext.YmmRegisters[1]); + if(reg == YMM2) return (char*) & (regd->regcontext.YmmRegisters[2]); + if(reg == YMM3) return (char*) & (regd->regcontext.YmmRegisters[3]); + if(reg == YMM4) return (char*) & (regd->regcontext.YmmRegisters[4]); + if(reg == YMM5) return (char*) & (regd->regcontext.YmmRegisters[5]); + if(reg == YMM6) return (char*) & (regd->regcontext.YmmRegisters[6]); + if(reg == YMM7) return (char*) & (regd->regcontext.YmmRegisters[7]); +#ifdef _WIN64 + if(reg == YMM8) return (char*) & (regd->regcontext.YmmRegisters[8]); + if(reg == YMM9) return (char*) & (regd->regcontext.YmmRegisters[9]); + if(reg == YMM10) return (char*) & (regd->regcontext.YmmRegisters[10]); + if(reg == YMM11) return (char*) & (regd->regcontext.YmmRegisters[11]); + if(reg == YMM12) return (char*) & (regd->regcontext.YmmRegisters[12]); + if(reg == YMM13) return (char*) & (regd->regcontext.YmmRegisters[13]); + if(reg == YMM14) return (char*) & (regd->regcontext.YmmRegisters[14]); + if(reg == YMM15) return (char*) & (regd->regcontext.YmmRegisters[15]); +#endif //_WIN64 + + return (char*) & null_value; +} + +void RegistersView::setRegisters(REGDUMP* reg) +{ + // tests if new-register-value == old-register-value holds + if(mCip != reg->regcontext.cip) //CIP changed + { + wCipRegDumpStruct = wRegDumpStruct; + mRegisterUpdates.clear(); + mCip = reg->regcontext.cip; + } + + QMap::const_iterator it = mRegisterMapping.begin(); + // iterate all ids (CAX, CBX, ...) + while(it != mRegisterMapping.end()) + { + if(CompareRegisters(it.key(), reg, &wCipRegDumpStruct) != 0) + mRegisterUpdates.insert(it.key()); + else if(mRegisterUpdates.contains(it.key())) //registers are equal + mRegisterUpdates.remove(it.key()); + it++; + } + + // now we can save the values + wRegDumpStruct = (*reg); + + if(mCip != reg->regcontext.cip) + wCipRegDumpStruct = wRegDumpStruct; + + // force repaint + emit refresh(); + +} diff --git a/src/gui/Src/Gui/RegistersView.h b/src/gui/Src/Gui/RegistersView.h index ea25542f..cc4d3e22 100644 --- a/src/gui/Src/Gui/RegistersView.h +++ b/src/gui/Src/Gui/RegistersView.h @@ -1,223 +1,223 @@ -#ifndef REGISTERSVIEW_H -#define REGISTERSVIEW_H - -#include -#include -#include -#include "Bridge.h" - -#define IsCharacterRegister(x) ((x>=CAX && x mUINTDISPLAY; - QSet mUSHORTDISPLAY; - QSet mDWORDDISPLAY; - QSet mBOOLDISPLAY; - QSet mLABELDISPLAY; - QSet mONLYMODULEANDLABELDISPLAY; - QSet mSETONEZEROTOGGLE; - QSet mMODIFYDISPLAY; - QSet mFIELDVALUE; - QSet mTAGWORD; - QSet mCANSTOREADDRESS; - QSet mINCREMENTDECREMET; - QSet mFPUx87_80BITSDISPLAY; - QSet mFPU; - // holds current selected register - REGISTER_NAME mSelected; - // general purposes register id s (cax, ..., r8, ....) - QSet mGPR; - // all flags - QSet mFlags; - // FPU x87, XMM and MMX registers - QSet mFPUx87; - QSet mFPUMMX; - QSet mFPUXMM; - QSet mFPUYMM; - // contains all id's of registers if there occurs a change - QSet mRegisterUpdates; - // registers that do not allow changes - QSet mNoChange; - // maps from id to name - QMap mRegisterMapping; - // contains viewport positions - QMap mRegisterPlaces; - // contains a dump of the current register values - REGDUMP wRegDumpStruct; - REGDUMP wCipRegDumpStruct; - // font measures (TODO: create a class that calculates all thos values) - unsigned int mRowHeight, mCharWidth; - // context menu actions - QAction* wCM_Increment; - QAction* wCM_Decrement; - QAction* wCM_Zero; - QAction* wCM_SetToOne; - QAction* wCM_Modify; - QAction* wCM_ToggleValue; - QAction* wCM_CopyToClipboard; - QAction* wCM_CopySymbolToClipboard; - QAction* wCM_FollowInDisassembly; - QAction* wCM_FollowInDump; - QAction* wCM_FollowInStack; - QAction* wCM_Incrementx87Stack; - QAction* wCM_Decrementx87Stack; - QAction* wCM_ChangeFPUView; - dsint mCip; -}; - -#endif // REGISTERSVIEW_H +#ifndef REGISTERSVIEW_H +#define REGISTERSVIEW_H + +#include +#include +#include +#include "Bridge.h" + +#define IsCharacterRegister(x) ((x>=CAX && x mUINTDISPLAY; + QSet mUSHORTDISPLAY; + QSet mDWORDDISPLAY; + QSet mBOOLDISPLAY; + QSet mLABELDISPLAY; + QSet mONLYMODULEANDLABELDISPLAY; + QSet mSETONEZEROTOGGLE; + QSet mMODIFYDISPLAY; + QSet mFIELDVALUE; + QSet mTAGWORD; + QSet mCANSTOREADDRESS; + QSet mINCREMENTDECREMET; + QSet mFPUx87_80BITSDISPLAY; + QSet mFPU; + // holds current selected register + REGISTER_NAME mSelected; + // general purposes register id s (cax, ..., r8, ....) + QSet mGPR; + // all flags + QSet mFlags; + // FPU x87, XMM and MMX registers + QSet mFPUx87; + QSet mFPUMMX; + QSet mFPUXMM; + QSet mFPUYMM; + // contains all id's of registers if there occurs a change + QSet mRegisterUpdates; + // registers that do not allow changes + QSet mNoChange; + // maps from id to name + QMap mRegisterMapping; + // contains viewport positions + QMap mRegisterPlaces; + // contains a dump of the current register values + REGDUMP wRegDumpStruct; + REGDUMP wCipRegDumpStruct; + // font measures (TODO: create a class that calculates all thos values) + unsigned int mRowHeight, mCharWidth; + // context menu actions + QAction* wCM_Increment; + QAction* wCM_Decrement; + QAction* wCM_Zero; + QAction* wCM_SetToOne; + QAction* wCM_Modify; + QAction* wCM_ToggleValue; + QAction* wCM_CopyToClipboard; + QAction* wCM_CopySymbolToClipboard; + QAction* wCM_FollowInDisassembly; + QAction* wCM_FollowInDump; + QAction* wCM_FollowInStack; + QAction* wCM_Incrementx87Stack; + QAction* wCM_Decrementx87Stack; + QAction* wCM_ChangeFPUView; + dsint mCip; +}; + +#endif // REGISTERSVIEW_H diff --git a/src/gui/Src/Gui/ScriptView.cpp b/src/gui/Src/Gui/ScriptView.cpp index a5e8951c..9bf30177 100644 --- a/src/gui/Src/Gui/ScriptView.cpp +++ b/src/gui/Src/Gui/ScriptView.cpp @@ -1,615 +1,615 @@ -#include "ScriptView.h" -#include -#include -#include "Configuration.h" -#include "Bridge.h" -#include "RichTextPainter.h" -#include "LineEditDialog.h" - -ScriptView::ScriptView(StdTable* parent) : StdTable(parent) -{ - mEnableSyntaxHighlighting = false; - enableMultiSelection(false); - enableColumnSorting(false); - - int charwidth = getCharWidth(); - - addColumnAt(8 + charwidth * 4, "Line", false); - addColumnAt(8 + charwidth * 60, "Text", false); - addColumnAt(8 + charwidth * 40, "Info", false); - - setIp(0); //no IP - - setupContextMenu(); - - // Slots - connect(Bridge::getBridge(), SIGNAL(scriptAdd(int, const char**)), this, SLOT(add(int, const char**))); - connect(Bridge::getBridge(), SIGNAL(scriptClear()), this, SLOT(clear())); - connect(Bridge::getBridge(), SIGNAL(scriptSetIp(int)), this, SLOT(setIp(int))); - connect(Bridge::getBridge(), SIGNAL(scriptError(int, QString)), this, SLOT(error(int, QString))); - connect(Bridge::getBridge(), SIGNAL(scriptSetTitle(QString)), this, SLOT(setTitle(QString))); - connect(Bridge::getBridge(), SIGNAL(scriptSetInfoLine(int, QString)), this, SLOT(setInfoLine(int, QString))); - connect(Bridge::getBridge(), SIGNAL(scriptMessage(QString)), this, SLOT(message(QString))); - connect(Bridge::getBridge(), SIGNAL(scriptQuestion(QString)), this, SLOT(question(QString))); - connect(Bridge::getBridge(), SIGNAL(scriptEnableHighlighting(bool)), this, SLOT(enableHighlighting(bool))); - connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint))); - - Initialize(); -} - -void ScriptView::updateColors() -{ - StdTable::updateColors(); - - selectionColor = ConfigColor("DisassemblySelectionColor"); - backgroundColor = ConfigColor("DisassemblyBackgroundColor"); -} - -QString ScriptView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) -{ - bool wIsSelected = isSelected(rowBase, rowOffset); - // Highlight if selected - if(wIsSelected) - painter->fillRect(QRect(x, y, w, h), QBrush(selectionColor)); //ScriptViewSelectionColor - QString returnString; - int line = rowBase + rowOffset + 1; - SCRIPTLINETYPE linetype = DbgScriptGetLineType(line); - switch(col) - { - case 0: //line number - { - returnString = returnString.sprintf("%.4d", line); - if(line == mIpLine) //IP - { - painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyCipBackgroundColor"))); - if(DbgScriptBpGet(line)) //breakpoint - { - QColor bpColor = ConfigColor("DisassemblyBreakpointBackgroundColor"); - if(!bpColor.alpha()) //we don't want transparent text - bpColor = ConfigColor("DisassemblyBreakpointColor"); - painter->setPen(QPen(bpColor)); - } - else - painter->setPen(QPen(ConfigColor("DisassemblyCipColor"))); //white address (ScriptViewIpTextColor) - } - else if(DbgScriptBpGet(line)) //breakpoint - { - painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBreakpointBackgroundColor"))); - painter->setPen(QPen(ConfigColor("DisassemblyBreakpointColor"))); //black address //ScripViewMainBpTextColor - } - else - { - QColor background; - if(linetype == linecommand || linetype == linebranch) - { - background = ConfigColor("DisassemblySelectedAddressBackgroundColor"); - painter->setPen(QPen(ConfigColor("DisassemblySelectedAddressColor"))); //black address (DisassemblySelectedAddressColor) - } - else - { - background = ConfigColor("DisassemblyAddressBackgroundColor"); - painter->setPen(QPen(ConfigColor("DisassemblyAddressColor"))); //grey address - } - if(background.alpha()) - painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background - } - painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, returnString); - returnString = ""; - } - break; - - case 1: //command - { - if(mEnableSyntaxHighlighting) - { - //initialize - int charwidth = getCharWidth(); - int xadd = charwidth; //for testing - QList richText; - RichTextPainter::CustomRichText_t newRichText; - newRichText.highlight = false; - QString command = getCellContent(rowBase + rowOffset, col); - - //handle comments - int comment_idx = command.indexOf("//"); //find the index of the space - QString comment = ""; - if(comment_idx != -1 && command.at(0) != QChar('/')) //there is a comment - { - comment = command.right(command.length() - comment_idx); - if(command.at(comment_idx - 1) == QChar(' ')) - command.truncate(comment_idx - 1); - else - command.truncate(comment_idx); - } - - //setup the richText list - switch(linetype) - { - case linecommand: - { - if(isScriptCommand(command, "ret")) - { - newRichText.flags = RichTextPainter::FlagAll; - newRichText.textColor = ConfigColor("InstructionRetColor"); - newRichText.textBackground = ConfigColor("InstructionRetBackgroundColor"); - newRichText.text = "ret"; - richText.push_back(newRichText); - QString remainder = command.right(command.length() - 3); - if(remainder.length()) - { - newRichText.flags = RichTextPainter::FlagAll; - newRichText.textColor = ConfigColor("InstructionUncategorizedColor"); - newRichText.textBackground = ConfigColor("InstructionUncategorizedBackgroundColor"); - newRichText.text = remainder; - richText.push_back(newRichText); - } - } - else - { - newRichText.flags = RichTextPainter::FlagAll; - newRichText.textColor = ConfigColor("InstructionUncategorizedColor"); - newRichText.textBackground = ConfigColor("InstructionUncategorizedBackgroundColor"); - newRichText.text = command; - richText.push_back(newRichText); - } - } - break; - - case linebranch: - { - SCRIPTBRANCH branchinfo; - DbgScriptGetBranchInfo(line, &branchinfo); - //jumps - int i = command.indexOf(" "); //find the index of the space - switch(branchinfo.type) - { - case scriptjmp: //unconditional jumps - newRichText.flags = RichTextPainter::FlagAll; - newRichText.textColor = ConfigColor("InstructionUnconditionalJumpColor"); - newRichText.textBackground = ConfigColor("InstructionUnconditionalJumpBackgroundColor"); - break; - - case scriptjnejnz: //conditional jumps - case scriptjejz: - case scriptjbjl: - case scriptjajg: - case scriptjbejle: - case scriptjaejge: - newRichText.flags = RichTextPainter::FlagAll; - newRichText.textColor = ConfigColor("InstructionConditionalJumpColor"); - newRichText.textBackground = ConfigColor("InstructionConditionalJumpBackgroundColor"); - break; - - case scriptcall: //calls - newRichText.flags = RichTextPainter::FlagAll; - newRichText.textColor = ConfigColor("InstructionCallColor"); - newRichText.textBackground = ConfigColor("InstructionCallBackgroundColor"); - break; - - default: - newRichText.flags = RichTextPainter::FlagAll; - newRichText.textColor = ConfigColor("InstructionUncategorizedColor"); - newRichText.textBackground = ConfigColor("InstructionUncategorizedBackgroundColor"); - break; - } - newRichText.text = command.left(i); - richText.push_back(newRichText); - //space - newRichText.flags = RichTextPainter::FlagNone; - newRichText.text = " "; - richText.push_back(newRichText); - //label - QString label = branchinfo.branchlabel; - newRichText.flags = RichTextPainter::FlagAll; - newRichText.textColor = ConfigColor("InstructionAddressColor"); - newRichText.textBackground = ConfigColor("InstructionAddressBackgroundColor"); - newRichText.text = label; - richText.push_back(newRichText); - //remainder - QString remainder = command.right(command.length() - command.indexOf(label) - label.length()); - if(remainder.length()) - { - newRichText.textColor = ConfigColor("InstructionUncategorizedColor"); - newRichText.textBackground = ConfigColor("InstructionUncategorizedBackgroundColor"); - newRichText.text = remainder; - richText.push_back(newRichText); - } - } - break; - - case linelabel: - { - newRichText.flags = RichTextPainter::FlagAll; - newRichText.textColor = ConfigColor("DisassemblyAddressColor"); - newRichText.textBackground = ConfigColor("DisassemblyAddressBackgroundColor"); - newRichText.text = command; - richText.push_back(newRichText); - painter->drawLine(QPoint(x + xadd + 2, y + h - 2), QPoint(x + w - 4, y + h - 2)); - } - break; - - case linecomment: - { - newRichText.flags = RichTextPainter::FlagAll; - newRichText.textColor = ConfigColor("DisassemblyAddressColor"); - newRichText.textBackground = ConfigColor("DisassemblyAddressBackgroundColor"); - newRichText.text = command; - richText.push_back(newRichText); - } - break; - - case lineempty: - { - } - break; - } - - //append the comment (when present) - if(comment.length()) - { - RichTextPainter::CustomRichText_t newRichText; - newRichText.highlight = false; - newRichText.flags = RichTextPainter::FlagNone; - newRichText.text = " "; - richText.push_back(newRichText); //space - newRichText.flags = RichTextPainter::FlagAll; - newRichText.textColor = ConfigColor("DisassemblyAddressColor"); - newRichText.textBackground = ConfigColor("DisassemblyAddressBackgroundColor"); - newRichText.text = comment; - richText.push_back(newRichText); //comment - } - - //paint the rich text - RichTextPainter::paintRichText(painter, x + 1, y, w, h, xadd, &richText, charwidth); - returnString = ""; - } - else //no syntax highlighting - returnString = getCellContent(rowBase + rowOffset, col); - } - break; - - case 2: //info - { - returnString = getCellContent(rowBase + rowOffset, col); - } - break; - } - return returnString; -} - -void ScriptView::contextMenuSlot(const QPoint & pos) -{ - QMenu* wMenu = new QMenu(this); - wMenu->addMenu(mLoadMenu); - if(getRowCount()) - { - wMenu->addAction(mScriptReload); - wMenu->addAction(mScriptUnload); - wMenu->addSeparator(); - wMenu->addAction(mScriptBpToggle); - wMenu->addAction(mScriptRunCursor); - wMenu->addAction(mScriptStep); - wMenu->addAction(mScriptRun); - wMenu->addAction(mScriptAbort); - wMenu->addAction(mScriptNewIp); - } - wMenu->addSeparator(); - wMenu->addAction(mScriptCmdExec); - wMenu->exec(mapToGlobal(pos)); -} - -void ScriptView::mouseDoubleClickEvent(QMouseEvent* event) -{ - if(event->button() != Qt::LeftButton) - return; - Q_UNUSED(event); - if(!getRowCount()) - return; - newIp(); -} - -void ScriptView::keyPressEvent(QKeyEvent* event) -{ - int key = event->key(); - if(key == Qt::Key_Up || key == Qt::Key_Down) - { - dsint botRVA = getTableOffset(); - dsint topRVA = botRVA + getNbrOfLineToPrint() - 1; - if(key == Qt::Key_Up) - selectPrevious(); - else - selectNext(); - if(getInitialSelection() < botRVA) - { - setTableOffset(getInitialSelection()); - } - else if(getInitialSelection() >= topRVA) - { - setTableOffset(getInitialSelection() - getNbrOfLineToPrint() + 2); - } - repaint(); - } - else if(key == Qt::Key_Return || key == Qt::Key_Enter) - { - int line = getInitialSelection() + 1; - SCRIPTBRANCH branchinfo; - memset(&branchinfo, 0, sizeof(SCRIPTBRANCH)); - if(DbgScriptGetBranchInfo(line, &branchinfo)) - setSelection(branchinfo.dest); - } - else - { - AbstractTableView::keyPressEvent(event); - } -} - -void ScriptView::setupContextMenu() -{ - mLoadMenu = new QMenu("Load Script", this); - - mScriptLoad = new QAction("Open...", this); - mScriptLoad->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mScriptLoad); - connect(mScriptLoad, SIGNAL(triggered()), this, SLOT(openFile())); - mLoadMenu->addAction(mScriptLoad); - - mScriptReload = new QAction("Reload Script", this); - mScriptReload->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mScriptReload); - connect(mScriptReload, SIGNAL(triggered()), this, SLOT(reload())); - - mScriptUnload = new QAction("Unload Script", this); - mScriptUnload->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mScriptUnload); - connect(mScriptUnload, SIGNAL(triggered()), this, SLOT(unload())); - - mScriptRun = new QAction("Run", this); - mScriptRun->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mScriptRun); - connect(mScriptRun, SIGNAL(triggered()), this, SLOT(run())); - - mScriptBpToggle = new QAction("Toggle BP", this); - mScriptBpToggle->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mScriptBpToggle); - connect(mScriptBpToggle, SIGNAL(triggered()), this, SLOT(bpToggle())); - - mScriptRunCursor = new QAction("Run until selection", this); - mScriptRunCursor->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mScriptRunCursor); - connect(mScriptRunCursor, SIGNAL(triggered()), this, SLOT(runCursor())); - - mScriptStep = new QAction("Step", this); - mScriptStep->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mScriptStep); - connect(mScriptStep, SIGNAL(triggered()), this, SLOT(step())); - - mScriptAbort = new QAction("Abort", this); - mScriptAbort->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mScriptAbort); - connect(mScriptAbort, SIGNAL(triggered()), this, SLOT(abort())); - - mScriptCmdExec = new QAction("Execute Command...", this); - mScriptCmdExec->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mScriptCmdExec); - connect(mScriptCmdExec, SIGNAL(triggered()), this, SLOT(cmdExec())); - - mScriptNewIp = new QAction("Continue here...", this); - mScriptNewIp->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mScriptNewIp); - connect(mScriptNewIp, SIGNAL(triggered()), this, SLOT(newIp())); - - refreshShortcutsSlot(); - connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); -} - -void ScriptView::refreshShortcutsSlot() -{ - mScriptLoad->setShortcut(ConfigShortcut("ActionLoadScript")); - mScriptReload->setShortcut(ConfigShortcut("ActionReloadScript")); - mScriptUnload->setShortcut(ConfigShortcut("ActionUnloadScript")); - mScriptRun->setShortcut(ConfigShortcut("ActionRunScript")); - mScriptBpToggle->setShortcut(ConfigShortcut("ActionToggleBreakpointScript")); - mScriptRunCursor->setShortcut(ConfigShortcut("ActionRunToCursorScript")); - mScriptStep->setShortcut(ConfigShortcut("ActionStepScript")); - mScriptAbort->setShortcut(ConfigShortcut("ActionAbortScript")); - mScriptCmdExec->setShortcut(ConfigShortcut("ActionExecuteCommandScript")); -} - -bool ScriptView::isScriptCommand(QString text, QString cmd) -{ - int len = text.length(); - int cmdlen = cmd.length(); - if(cmdlen > len) - return false; - else if(cmdlen == len) - return (text.compare(cmd, Qt::CaseInsensitive) == 0); - else if(text.at(cmdlen) == ' ') - return (text.left(cmdlen).compare(cmd, Qt::CaseInsensitive) == 0); - return false; -} - -//slots -void ScriptView::add(int count, const char** lines) -{ - setRowCount(count); - for(int i = 0; i < count; i++) - setCellContent(i, 1, QString(lines[i])); - BridgeFree(lines); - reloadData(); //repaint - Bridge::getBridge()->setResult(1); -} - -void ScriptView::clear() -{ - setRowCount(0); - mIpLine = 0; - reloadData(); //repaint -} - -void ScriptView::setIp(int line) -{ - int offset = line - 1; - if(!isValidIndex(offset, 0)) - { - mIpLine = 0; - return; - } - mIpLine = line; - int rangefrom = getTableOffset(); - int rangeto = rangefrom + getViewableRowsCount() - 1; - if(offset < rangefrom) //ip lays before the current view - setTableOffset(offset); - else if(offset > (rangeto - 1)) //ip lays after the current view - setTableOffset(offset - getViewableRowsCount() + 2); - setSingleSelection(offset); - reloadData(); //repaint -} - -void ScriptView::setSelection(int line) -{ - int offset = line - 1; - if(!isValidIndex(offset, 0)) - return; - int rangefrom = getTableOffset(); - int rangeto = rangefrom + getViewableRowsCount() - 1; - if(offset < rangefrom) //ip lays before the current view - setTableOffset(offset); - else if(offset > (rangeto - 1)) //ip lays after the current view - setTableOffset(offset - getViewableRowsCount() + 2); - setSingleSelection(offset); - reloadData(); //repaint -} - -void ScriptView::error(int line, QString message) -{ - QString title; - if(isValidIndex(line - 1, 0)) - title = title.sprintf("Error on line %.4d!", line); - else - title = "Script Error!"; - QMessageBox msg(QMessageBox::Critical, title, message); - msg.setWindowIcon(QIcon(":/icons/images/script-error.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - Bridge::getBridge()->setResult(); -} - -void ScriptView::setTitle(QString title) -{ - setWindowTitle(title); -} - -void ScriptView::setInfoLine(int line, QString info) -{ - setCellContent(line - 1, 2, info); - reloadData(); //repaint -} - -void ScriptView::openFile() -{ - filename = QFileDialog::getOpenFileName(this, tr("Select script"), 0, tr("Script files (*.txt *.scr);;All files (*.*)")); - if(!filename.length()) - return; - filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes) - DbgScriptUnload(); - DbgScriptLoad(filename.toUtf8().constData()); -} - -void ScriptView::reload() -{ - if(!filename.length()) - return; - DbgScriptUnload(); - DbgScriptLoad(filename.toUtf8().constData()); -} - -void ScriptView::unload() -{ - DbgScriptUnload(); -} - -void ScriptView::run() -{ - if(!getRowCount()) - return; - DbgScriptRun(0); -} - -void ScriptView::bpToggle() -{ - if(!getRowCount()) - return; - int selected = getInitialSelection() + 1; - if(!DbgScriptBpToggle(selected)) - error(selected, "Error setting script breakpoint!"); - reloadData(); -} - -void ScriptView::runCursor() -{ - if(!getRowCount()) - return; - int selected = getInitialSelection() + 1; - DbgScriptRun(selected); -} - -void ScriptView::step() -{ - if(!getRowCount()) - return; - DbgScriptStep(); -} - -void ScriptView::abort() -{ - if(!getRowCount()) - return; - DbgScriptAbort(); -} - -void ScriptView::cmdExec() -{ - LineEditDialog mLineEdit(this); - mLineEdit.setWindowTitle("Execute Script Command..."); - if(mLineEdit.exec() != QDialog::Accepted) - return; - if(!DbgScriptCmdExec(mLineEdit.editText.toUtf8().constData())) - error(0, "Error executing command!"); -} - -void ScriptView::message(QString message) -{ - QMessageBox msg(QMessageBox::Information, "Message", message); - msg.setWindowIcon(QIcon(":/icons/images/information.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - Bridge::getBridge()->setResult(); -} - -void ScriptView::newIp() -{ - if(!getRowCount()) - return; - int selected = getInitialSelection() + 1; - if(isValidIndex(selected - 1, 0)) - DbgScriptSetIp(selected); -} - -void ScriptView::question(QString message) -{ - QMessageBox msg(QMessageBox::Question, "Question", message, QMessageBox::Yes | QMessageBox::No); - msg.setWindowIcon(QIcon(":/icons/images/question.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - if(msg.exec() == QMessageBox::Yes) - Bridge::getBridge()->setResult(1); - else - Bridge::getBridge()->setResult(0); -} - -void ScriptView::enableHighlighting(bool enable) -{ - mEnableSyntaxHighlighting = enable; -} +#include "ScriptView.h" +#include +#include +#include "Configuration.h" +#include "Bridge.h" +#include "RichTextPainter.h" +#include "LineEditDialog.h" + +ScriptView::ScriptView(StdTable* parent) : StdTable(parent) +{ + mEnableSyntaxHighlighting = false; + enableMultiSelection(false); + enableColumnSorting(false); + + int charwidth = getCharWidth(); + + addColumnAt(8 + charwidth * 4, "Line", false); + addColumnAt(8 + charwidth * 60, "Text", false); + addColumnAt(8 + charwidth * 40, "Info", false); + + setIp(0); //no IP + + setupContextMenu(); + + // Slots + connect(Bridge::getBridge(), SIGNAL(scriptAdd(int, const char**)), this, SLOT(add(int, const char**))); + connect(Bridge::getBridge(), SIGNAL(scriptClear()), this, SLOT(clear())); + connect(Bridge::getBridge(), SIGNAL(scriptSetIp(int)), this, SLOT(setIp(int))); + connect(Bridge::getBridge(), SIGNAL(scriptError(int, QString)), this, SLOT(error(int, QString))); + connect(Bridge::getBridge(), SIGNAL(scriptSetTitle(QString)), this, SLOT(setTitle(QString))); + connect(Bridge::getBridge(), SIGNAL(scriptSetInfoLine(int, QString)), this, SLOT(setInfoLine(int, QString))); + connect(Bridge::getBridge(), SIGNAL(scriptMessage(QString)), this, SLOT(message(QString))); + connect(Bridge::getBridge(), SIGNAL(scriptQuestion(QString)), this, SLOT(question(QString))); + connect(Bridge::getBridge(), SIGNAL(scriptEnableHighlighting(bool)), this, SLOT(enableHighlighting(bool))); + connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint))); + + Initialize(); +} + +void ScriptView::updateColors() +{ + StdTable::updateColors(); + + selectionColor = ConfigColor("DisassemblySelectionColor"); + backgroundColor = ConfigColor("DisassemblyBackgroundColor"); +} + +QString ScriptView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) +{ + bool wIsSelected = isSelected(rowBase, rowOffset); + // Highlight if selected + if(wIsSelected) + painter->fillRect(QRect(x, y, w, h), QBrush(selectionColor)); //ScriptViewSelectionColor + QString returnString; + int line = rowBase + rowOffset + 1; + SCRIPTLINETYPE linetype = DbgScriptGetLineType(line); + switch(col) + { + case 0: //line number + { + returnString = returnString.sprintf("%.4d", line); + if(line == mIpLine) //IP + { + painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyCipBackgroundColor"))); + if(DbgScriptBpGet(line)) //breakpoint + { + QColor bpColor = ConfigColor("DisassemblyBreakpointBackgroundColor"); + if(!bpColor.alpha()) //we don't want transparent text + bpColor = ConfigColor("DisassemblyBreakpointColor"); + painter->setPen(QPen(bpColor)); + } + else + painter->setPen(QPen(ConfigColor("DisassemblyCipColor"))); //white address (ScriptViewIpTextColor) + } + else if(DbgScriptBpGet(line)) //breakpoint + { + painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBreakpointBackgroundColor"))); + painter->setPen(QPen(ConfigColor("DisassemblyBreakpointColor"))); //black address //ScripViewMainBpTextColor + } + else + { + QColor background; + if(linetype == linecommand || linetype == linebranch) + { + background = ConfigColor("DisassemblySelectedAddressBackgroundColor"); + painter->setPen(QPen(ConfigColor("DisassemblySelectedAddressColor"))); //black address (DisassemblySelectedAddressColor) + } + else + { + background = ConfigColor("DisassemblyAddressBackgroundColor"); + painter->setPen(QPen(ConfigColor("DisassemblyAddressColor"))); //grey address + } + if(background.alpha()) + painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background + } + painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, returnString); + returnString = ""; + } + break; + + case 1: //command + { + if(mEnableSyntaxHighlighting) + { + //initialize + int charwidth = getCharWidth(); + int xadd = charwidth; //for testing + QList richText; + RichTextPainter::CustomRichText_t newRichText; + newRichText.highlight = false; + QString command = getCellContent(rowBase + rowOffset, col); + + //handle comments + int comment_idx = command.indexOf("//"); //find the index of the space + QString comment = ""; + if(comment_idx != -1 && command.at(0) != QChar('/')) //there is a comment + { + comment = command.right(command.length() - comment_idx); + if(command.at(comment_idx - 1) == QChar(' ')) + command.truncate(comment_idx - 1); + else + command.truncate(comment_idx); + } + + //setup the richText list + switch(linetype) + { + case linecommand: + { + if(isScriptCommand(command, "ret")) + { + newRichText.flags = RichTextPainter::FlagAll; + newRichText.textColor = ConfigColor("InstructionRetColor"); + newRichText.textBackground = ConfigColor("InstructionRetBackgroundColor"); + newRichText.text = "ret"; + richText.push_back(newRichText); + QString remainder = command.right(command.length() - 3); + if(remainder.length()) + { + newRichText.flags = RichTextPainter::FlagAll; + newRichText.textColor = ConfigColor("InstructionUncategorizedColor"); + newRichText.textBackground = ConfigColor("InstructionUncategorizedBackgroundColor"); + newRichText.text = remainder; + richText.push_back(newRichText); + } + } + else + { + newRichText.flags = RichTextPainter::FlagAll; + newRichText.textColor = ConfigColor("InstructionUncategorizedColor"); + newRichText.textBackground = ConfigColor("InstructionUncategorizedBackgroundColor"); + newRichText.text = command; + richText.push_back(newRichText); + } + } + break; + + case linebranch: + { + SCRIPTBRANCH branchinfo; + DbgScriptGetBranchInfo(line, &branchinfo); + //jumps + int i = command.indexOf(" "); //find the index of the space + switch(branchinfo.type) + { + case scriptjmp: //unconditional jumps + newRichText.flags = RichTextPainter::FlagAll; + newRichText.textColor = ConfigColor("InstructionUnconditionalJumpColor"); + newRichText.textBackground = ConfigColor("InstructionUnconditionalJumpBackgroundColor"); + break; + + case scriptjnejnz: //conditional jumps + case scriptjejz: + case scriptjbjl: + case scriptjajg: + case scriptjbejle: + case scriptjaejge: + newRichText.flags = RichTextPainter::FlagAll; + newRichText.textColor = ConfigColor("InstructionConditionalJumpColor"); + newRichText.textBackground = ConfigColor("InstructionConditionalJumpBackgroundColor"); + break; + + case scriptcall: //calls + newRichText.flags = RichTextPainter::FlagAll; + newRichText.textColor = ConfigColor("InstructionCallColor"); + newRichText.textBackground = ConfigColor("InstructionCallBackgroundColor"); + break; + + default: + newRichText.flags = RichTextPainter::FlagAll; + newRichText.textColor = ConfigColor("InstructionUncategorizedColor"); + newRichText.textBackground = ConfigColor("InstructionUncategorizedBackgroundColor"); + break; + } + newRichText.text = command.left(i); + richText.push_back(newRichText); + //space + newRichText.flags = RichTextPainter::FlagNone; + newRichText.text = " "; + richText.push_back(newRichText); + //label + QString label = branchinfo.branchlabel; + newRichText.flags = RichTextPainter::FlagAll; + newRichText.textColor = ConfigColor("InstructionAddressColor"); + newRichText.textBackground = ConfigColor("InstructionAddressBackgroundColor"); + newRichText.text = label; + richText.push_back(newRichText); + //remainder + QString remainder = command.right(command.length() - command.indexOf(label) - label.length()); + if(remainder.length()) + { + newRichText.textColor = ConfigColor("InstructionUncategorizedColor"); + newRichText.textBackground = ConfigColor("InstructionUncategorizedBackgroundColor"); + newRichText.text = remainder; + richText.push_back(newRichText); + } + } + break; + + case linelabel: + { + newRichText.flags = RichTextPainter::FlagAll; + newRichText.textColor = ConfigColor("DisassemblyAddressColor"); + newRichText.textBackground = ConfigColor("DisassemblyAddressBackgroundColor"); + newRichText.text = command; + richText.push_back(newRichText); + painter->drawLine(QPoint(x + xadd + 2, y + h - 2), QPoint(x + w - 4, y + h - 2)); + } + break; + + case linecomment: + { + newRichText.flags = RichTextPainter::FlagAll; + newRichText.textColor = ConfigColor("DisassemblyAddressColor"); + newRichText.textBackground = ConfigColor("DisassemblyAddressBackgroundColor"); + newRichText.text = command; + richText.push_back(newRichText); + } + break; + + case lineempty: + { + } + break; + } + + //append the comment (when present) + if(comment.length()) + { + RichTextPainter::CustomRichText_t newRichText; + newRichText.highlight = false; + newRichText.flags = RichTextPainter::FlagNone; + newRichText.text = " "; + richText.push_back(newRichText); //space + newRichText.flags = RichTextPainter::FlagAll; + newRichText.textColor = ConfigColor("DisassemblyAddressColor"); + newRichText.textBackground = ConfigColor("DisassemblyAddressBackgroundColor"); + newRichText.text = comment; + richText.push_back(newRichText); //comment + } + + //paint the rich text + RichTextPainter::paintRichText(painter, x + 1, y, w, h, xadd, &richText, charwidth); + returnString = ""; + } + else //no syntax highlighting + returnString = getCellContent(rowBase + rowOffset, col); + } + break; + + case 2: //info + { + returnString = getCellContent(rowBase + rowOffset, col); + } + break; + } + return returnString; +} + +void ScriptView::contextMenuSlot(const QPoint & pos) +{ + QMenu* wMenu = new QMenu(this); + wMenu->addMenu(mLoadMenu); + if(getRowCount()) + { + wMenu->addAction(mScriptReload); + wMenu->addAction(mScriptUnload); + wMenu->addSeparator(); + wMenu->addAction(mScriptBpToggle); + wMenu->addAction(mScriptRunCursor); + wMenu->addAction(mScriptStep); + wMenu->addAction(mScriptRun); + wMenu->addAction(mScriptAbort); + wMenu->addAction(mScriptNewIp); + } + wMenu->addSeparator(); + wMenu->addAction(mScriptCmdExec); + wMenu->exec(mapToGlobal(pos)); +} + +void ScriptView::mouseDoubleClickEvent(QMouseEvent* event) +{ + if(event->button() != Qt::LeftButton) + return; + Q_UNUSED(event); + if(!getRowCount()) + return; + newIp(); +} + +void ScriptView::keyPressEvent(QKeyEvent* event) +{ + int key = event->key(); + if(key == Qt::Key_Up || key == Qt::Key_Down) + { + dsint botRVA = getTableOffset(); + dsint topRVA = botRVA + getNbrOfLineToPrint() - 1; + if(key == Qt::Key_Up) + selectPrevious(); + else + selectNext(); + if(getInitialSelection() < botRVA) + { + setTableOffset(getInitialSelection()); + } + else if(getInitialSelection() >= topRVA) + { + setTableOffset(getInitialSelection() - getNbrOfLineToPrint() + 2); + } + repaint(); + } + else if(key == Qt::Key_Return || key == Qt::Key_Enter) + { + int line = getInitialSelection() + 1; + SCRIPTBRANCH branchinfo; + memset(&branchinfo, 0, sizeof(SCRIPTBRANCH)); + if(DbgScriptGetBranchInfo(line, &branchinfo)) + setSelection(branchinfo.dest); + } + else + { + AbstractTableView::keyPressEvent(event); + } +} + +void ScriptView::setupContextMenu() +{ + mLoadMenu = new QMenu("Load Script", this); + + mScriptLoad = new QAction("Open...", this); + mScriptLoad->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mScriptLoad); + connect(mScriptLoad, SIGNAL(triggered()), this, SLOT(openFile())); + mLoadMenu->addAction(mScriptLoad); + + mScriptReload = new QAction("Reload Script", this); + mScriptReload->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mScriptReload); + connect(mScriptReload, SIGNAL(triggered()), this, SLOT(reload())); + + mScriptUnload = new QAction("Unload Script", this); + mScriptUnload->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mScriptUnload); + connect(mScriptUnload, SIGNAL(triggered()), this, SLOT(unload())); + + mScriptRun = new QAction("Run", this); + mScriptRun->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mScriptRun); + connect(mScriptRun, SIGNAL(triggered()), this, SLOT(run())); + + mScriptBpToggle = new QAction("Toggle BP", this); + mScriptBpToggle->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mScriptBpToggle); + connect(mScriptBpToggle, SIGNAL(triggered()), this, SLOT(bpToggle())); + + mScriptRunCursor = new QAction("Run until selection", this); + mScriptRunCursor->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mScriptRunCursor); + connect(mScriptRunCursor, SIGNAL(triggered()), this, SLOT(runCursor())); + + mScriptStep = new QAction("Step", this); + mScriptStep->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mScriptStep); + connect(mScriptStep, SIGNAL(triggered()), this, SLOT(step())); + + mScriptAbort = new QAction("Abort", this); + mScriptAbort->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mScriptAbort); + connect(mScriptAbort, SIGNAL(triggered()), this, SLOT(abort())); + + mScriptCmdExec = new QAction("Execute Command...", this); + mScriptCmdExec->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mScriptCmdExec); + connect(mScriptCmdExec, SIGNAL(triggered()), this, SLOT(cmdExec())); + + mScriptNewIp = new QAction("Continue here...", this); + mScriptNewIp->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mScriptNewIp); + connect(mScriptNewIp, SIGNAL(triggered()), this, SLOT(newIp())); + + refreshShortcutsSlot(); + connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); +} + +void ScriptView::refreshShortcutsSlot() +{ + mScriptLoad->setShortcut(ConfigShortcut("ActionLoadScript")); + mScriptReload->setShortcut(ConfigShortcut("ActionReloadScript")); + mScriptUnload->setShortcut(ConfigShortcut("ActionUnloadScript")); + mScriptRun->setShortcut(ConfigShortcut("ActionRunScript")); + mScriptBpToggle->setShortcut(ConfigShortcut("ActionToggleBreakpointScript")); + mScriptRunCursor->setShortcut(ConfigShortcut("ActionRunToCursorScript")); + mScriptStep->setShortcut(ConfigShortcut("ActionStepScript")); + mScriptAbort->setShortcut(ConfigShortcut("ActionAbortScript")); + mScriptCmdExec->setShortcut(ConfigShortcut("ActionExecuteCommandScript")); +} + +bool ScriptView::isScriptCommand(QString text, QString cmd) +{ + int len = text.length(); + int cmdlen = cmd.length(); + if(cmdlen > len) + return false; + else if(cmdlen == len) + return (text.compare(cmd, Qt::CaseInsensitive) == 0); + else if(text.at(cmdlen) == ' ') + return (text.left(cmdlen).compare(cmd, Qt::CaseInsensitive) == 0); + return false; +} + +//slots +void ScriptView::add(int count, const char** lines) +{ + setRowCount(count); + for(int i = 0; i < count; i++) + setCellContent(i, 1, QString(lines[i])); + BridgeFree(lines); + reloadData(); //repaint + Bridge::getBridge()->setResult(1); +} + +void ScriptView::clear() +{ + setRowCount(0); + mIpLine = 0; + reloadData(); //repaint +} + +void ScriptView::setIp(int line) +{ + int offset = line - 1; + if(!isValidIndex(offset, 0)) + { + mIpLine = 0; + return; + } + mIpLine = line; + int rangefrom = getTableOffset(); + int rangeto = rangefrom + getViewableRowsCount() - 1; + if(offset < rangefrom) //ip lays before the current view + setTableOffset(offset); + else if(offset > (rangeto - 1)) //ip lays after the current view + setTableOffset(offset - getViewableRowsCount() + 2); + setSingleSelection(offset); + reloadData(); //repaint +} + +void ScriptView::setSelection(int line) +{ + int offset = line - 1; + if(!isValidIndex(offset, 0)) + return; + int rangefrom = getTableOffset(); + int rangeto = rangefrom + getViewableRowsCount() - 1; + if(offset < rangefrom) //ip lays before the current view + setTableOffset(offset); + else if(offset > (rangeto - 1)) //ip lays after the current view + setTableOffset(offset - getViewableRowsCount() + 2); + setSingleSelection(offset); + reloadData(); //repaint +} + +void ScriptView::error(int line, QString message) +{ + QString title; + if(isValidIndex(line - 1, 0)) + title = title.sprintf("Error on line %.4d!", line); + else + title = "Script Error!"; + QMessageBox msg(QMessageBox::Critical, title, message); + msg.setWindowIcon(QIcon(":/icons/images/script-error.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + Bridge::getBridge()->setResult(); +} + +void ScriptView::setTitle(QString title) +{ + setWindowTitle(title); +} + +void ScriptView::setInfoLine(int line, QString info) +{ + setCellContent(line - 1, 2, info); + reloadData(); //repaint +} + +void ScriptView::openFile() +{ + filename = QFileDialog::getOpenFileName(this, tr("Select script"), 0, tr("Script files (*.txt *.scr);;All files (*.*)")); + if(!filename.length()) + return; + filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes) + DbgScriptUnload(); + DbgScriptLoad(filename.toUtf8().constData()); +} + +void ScriptView::reload() +{ + if(!filename.length()) + return; + DbgScriptUnload(); + DbgScriptLoad(filename.toUtf8().constData()); +} + +void ScriptView::unload() +{ + DbgScriptUnload(); +} + +void ScriptView::run() +{ + if(!getRowCount()) + return; + DbgScriptRun(0); +} + +void ScriptView::bpToggle() +{ + if(!getRowCount()) + return; + int selected = getInitialSelection() + 1; + if(!DbgScriptBpToggle(selected)) + error(selected, "Error setting script breakpoint!"); + reloadData(); +} + +void ScriptView::runCursor() +{ + if(!getRowCount()) + return; + int selected = getInitialSelection() + 1; + DbgScriptRun(selected); +} + +void ScriptView::step() +{ + if(!getRowCount()) + return; + DbgScriptStep(); +} + +void ScriptView::abort() +{ + if(!getRowCount()) + return; + DbgScriptAbort(); +} + +void ScriptView::cmdExec() +{ + LineEditDialog mLineEdit(this); + mLineEdit.setWindowTitle("Execute Script Command..."); + if(mLineEdit.exec() != QDialog::Accepted) + return; + if(!DbgScriptCmdExec(mLineEdit.editText.toUtf8().constData())) + error(0, "Error executing command!"); +} + +void ScriptView::message(QString message) +{ + QMessageBox msg(QMessageBox::Information, "Message", message); + msg.setWindowIcon(QIcon(":/icons/images/information.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + Bridge::getBridge()->setResult(); +} + +void ScriptView::newIp() +{ + if(!getRowCount()) + return; + int selected = getInitialSelection() + 1; + if(isValidIndex(selected - 1, 0)) + DbgScriptSetIp(selected); +} + +void ScriptView::question(QString message) +{ + QMessageBox msg(QMessageBox::Question, "Question", message, QMessageBox::Yes | QMessageBox::No); + msg.setWindowIcon(QIcon(":/icons/images/question.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + if(msg.exec() == QMessageBox::Yes) + Bridge::getBridge()->setResult(1); + else + Bridge::getBridge()->setResult(0); +} + +void ScriptView::enableHighlighting(bool enable) +{ + mEnableSyntaxHighlighting = enable; +} diff --git a/src/gui/Src/Gui/ScriptView.h b/src/gui/Src/Gui/ScriptView.h index 72ee9d58..4e2a3aa8 100644 --- a/src/gui/Src/Gui/ScriptView.h +++ b/src/gui/Src/Gui/ScriptView.h @@ -1,67 +1,67 @@ -#ifndef SCRIPTVIEW_H -#define SCRIPTVIEW_H - -#include "StdTable.h" - -class ScriptView : public StdTable -{ - Q_OBJECT -public: - explicit ScriptView(StdTable* parent = 0); - - // Configuration - void updateColors(); - - // Reimplemented Functions - QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); - void mouseDoubleClickEvent(QMouseEvent* event); - void keyPressEvent(QKeyEvent* event); - -public slots: - void refreshShortcutsSlot(); - void contextMenuSlot(const QPoint & pos); - void add(int count, const char** lines); - void clear(); - void setIp(int line); - void error(int line, QString message); - void setTitle(QString title); - void setInfoLine(int line, QString info); - void openFile(); - void reload(); - void unload(); - void run(); - void bpToggle(); - void runCursor(); - void step(); - void abort(); - void cmdExec(); - void message(QString message); - void newIp(); - void question(QString message); - void enableHighlighting(bool enable); - -private: - //private functions - void setupContextMenu(); - void setSelection(int line); - bool isScriptCommand(QString text, QString cmd); - - //private variables - int mIpLine; - bool mEnableSyntaxHighlighting; - QString filename; - - QMenu* mLoadMenu; - QAction* mScriptLoad; - QAction* mScriptReload; - QAction* mScriptUnload; - QAction* mScriptRun; - QAction* mScriptRunCursor; - QAction* mScriptStep; - QAction* mScriptBpToggle; - QAction* mScriptCmdExec; - QAction* mScriptAbort; - QAction* mScriptNewIp; -}; - -#endif // SCRIPTVIEW_H +#ifndef SCRIPTVIEW_H +#define SCRIPTVIEW_H + +#include "StdTable.h" + +class ScriptView : public StdTable +{ + Q_OBJECT +public: + explicit ScriptView(StdTable* parent = 0); + + // Configuration + void updateColors(); + + // Reimplemented Functions + QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); + void mouseDoubleClickEvent(QMouseEvent* event); + void keyPressEvent(QKeyEvent* event); + +public slots: + void refreshShortcutsSlot(); + void contextMenuSlot(const QPoint & pos); + void add(int count, const char** lines); + void clear(); + void setIp(int line); + void error(int line, QString message); + void setTitle(QString title); + void setInfoLine(int line, QString info); + void openFile(); + void reload(); + void unload(); + void run(); + void bpToggle(); + void runCursor(); + void step(); + void abort(); + void cmdExec(); + void message(QString message); + void newIp(); + void question(QString message); + void enableHighlighting(bool enable); + +private: + //private functions + void setupContextMenu(); + void setSelection(int line); + bool isScriptCommand(QString text, QString cmd); + + //private variables + int mIpLine; + bool mEnableSyntaxHighlighting; + QString filename; + + QMenu* mLoadMenu; + QAction* mScriptLoad; + QAction* mScriptReload; + QAction* mScriptUnload; + QAction* mScriptRun; + QAction* mScriptRunCursor; + QAction* mScriptStep; + QAction* mScriptBpToggle; + QAction* mScriptCmdExec; + QAction* mScriptAbort; + QAction* mScriptNewIp; +}; + +#endif // SCRIPTVIEW_H diff --git a/src/gui/Src/Gui/SelectFields.cpp b/src/gui/Src/Gui/SelectFields.cpp index 98093885..33878d08 100644 --- a/src/gui/Src/Gui/SelectFields.cpp +++ b/src/gui/Src/Gui/SelectFields.cpp @@ -1,23 +1,23 @@ -#include "selectfields.h" -#include "ui_selectfields.h" - -SelectFields::SelectFields(QWidget* parent) : - QDialog(parent), - ui(new Ui::SelectFields) -{ - ui->setupUi(this); -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); -#endif - setModal(true); -} - -QListWidget* SelectFields::GetList(void) -{ - return ui->listWidget; -} - -SelectFields::~SelectFields() -{ - delete ui; -} +#include "selectfields.h" +#include "ui_selectfields.h" + +SelectFields::SelectFields(QWidget* parent) : + QDialog(parent), + ui(new Ui::SelectFields) +{ + ui->setupUi(this); +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); +#endif + setModal(true); +} + +QListWidget* SelectFields::GetList(void) +{ + return ui->listWidget; +} + +SelectFields::~SelectFields() +{ + delete ui; +} diff --git a/src/gui/Src/Gui/SelectFields.h b/src/gui/Src/Gui/SelectFields.h index e365ff93..b4775683 100644 --- a/src/gui/Src/Gui/SelectFields.h +++ b/src/gui/Src/Gui/SelectFields.h @@ -1,25 +1,25 @@ -#ifndef SELECTFIELDS_H -#define SELECTFIELDS_H - -#include -#include - -namespace Ui -{ -class SelectFields; -} - -class SelectFields : public QDialog -{ - Q_OBJECT - -public: - explicit SelectFields(QWidget* parent = 0); - QListWidget* GetList(void); - ~SelectFields(); - -private: - Ui::SelectFields* ui; -}; - -#endif // SELECTFIELDS_H +#ifndef SELECTFIELDS_H +#define SELECTFIELDS_H + +#include +#include + +namespace Ui +{ +class SelectFields; +} + +class SelectFields : public QDialog +{ + Q_OBJECT + +public: + explicit SelectFields(QWidget* parent = 0); + QListWidget* GetList(void); + ~SelectFields(); + +private: + Ui::SelectFields* ui; +}; + +#endif // SELECTFIELDS_H diff --git a/src/gui/Src/Gui/SettingsDialog.cpp b/src/gui/Src/Gui/SettingsDialog.cpp index 16f59a83..86be1ea2 100644 --- a/src/gui/Src/Gui/SettingsDialog.cpp +++ b/src/gui/Src/Gui/SettingsDialog.cpp @@ -1,626 +1,626 @@ -#include "SettingsDialog.h" -#include "ui_SettingsDialog.h" -#include -#include "Configuration.h" -#include "Bridge.h" -#include "ExceptionRangeDialog.h" - -SettingsDialog::SettingsDialog(QWidget* parent) : - QDialog(parent), - ui(new Ui::SettingsDialog) -{ - ui->setupUi(this); - //set window flags -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint); -#endif - setModal(true); - LoadSettings(); //load settings from file - connect(Bridge::getBridge(), SIGNAL(setLastException(uint)), this, SLOT(setLastException(uint))); - lastException = 0; -} - -SettingsDialog::~SettingsDialog() -{ - disconnect(Bridge::getBridge(), SIGNAL(setLastException(uint)), this, SLOT(setLastException(uint))); - delete ui; -} - -void SettingsDialog::GetSettingBool(const char* section, const char* name, bool* set) -{ - duint currentSetting; - if(!set || !BridgeSettingGetUint(section, name, ¤tSetting)) - return; - if(currentSetting) - *set = true; - else - *set = false; -} - -Qt::CheckState SettingsDialog::bool2check(bool checked) -{ - if(checked) - return Qt::Checked; - return Qt::Unchecked; -} - -void SettingsDialog::LoadSettings() -{ - //Defaults - memset(&settings, 0, sizeof(SettingsStruct)); - settings.eventSystemBreakpoint = true; - settings.eventTlsCallbacks = true; - settings.eventEntryBreakpoint = true; - settings.eventAttachBreakpoint = true; - settings.engineCalcType = calc_unsigned; - settings.engineBreakpointType = break_int3short; - settings.engineUndecorateSymbolNames = true; - settings.engineEnableSourceDebugging = true; - settings.exceptionRanges = &realExceptionRanges; - settings.disasmArgumentSpaces = false; - settings.disasmMemorySpaces = false; - settings.disasmUppercase = false; - settings.disasmOnlyCipAutoComments = false; - settings.disasmTabBetweenMnemonicAndArguments = false; - - //Events tab - GetSettingBool("Events", "SystemBreakpoint", &settings.eventSystemBreakpoint); - GetSettingBool("Events", "TlsCallbacks", &settings.eventTlsCallbacks); - GetSettingBool("Events", "EntryBreakpoint", &settings.eventEntryBreakpoint); - GetSettingBool("Events", "DllEntry", &settings.eventDllEntry); - GetSettingBool("Events", "ThreadEntry", &settings.eventThreadEntry); - GetSettingBool("Events", "AttachBreakpoint", &settings.eventAttachBreakpoint); - GetSettingBool("Events", "DllLoad", &settings.eventDllLoad); - GetSettingBool("Events", "DllUnload", &settings.eventDllUnload); - GetSettingBool("Events", "ThreadStart", &settings.eventThreadStart); - GetSettingBool("Events", "ThreadEnd", &settings.eventThreadEnd); - GetSettingBool("Events", "DebugStrings", &settings.eventDebugStrings); - ui->chkSystemBreakpoint->setCheckState(bool2check(settings.eventSystemBreakpoint)); - ui->chkTlsCallbacks->setCheckState(bool2check(settings.eventTlsCallbacks)); - ui->chkEntryBreakpoint->setCheckState(bool2check(settings.eventEntryBreakpoint)); - ui->chkDllEntry->setCheckState(bool2check(settings.eventDllEntry)); - ui->chkThreadEntry->setCheckState(bool2check(settings.eventThreadEntry)); - ui->chkAttachBreakpoint->setCheckState(bool2check(settings.eventAttachBreakpoint)); - ui->chkDllLoad->setCheckState(bool2check(settings.eventDllLoad)); - ui->chkDllUnload->setCheckState(bool2check(settings.eventDllUnload)); - ui->chkThreadStart->setCheckState(bool2check(settings.eventThreadStart)); - ui->chkThreadEnd->setCheckState(bool2check(settings.eventThreadEnd)); - ui->chkDebugStrings->setCheckState(bool2check(settings.eventDebugStrings)); - - //Engine tab - duint cur; - if(BridgeSettingGetUint("Engine", "CalculationType", &cur)) - { - switch(cur) - { - case calc_signed: - case calc_unsigned: - settings.engineCalcType = (CalcType)cur; - break; - } - } - if(BridgeSettingGetUint("Engine", "BreakpointType", &cur)) - { - switch(cur) - { - case break_int3short: - case break_int3long: - case break_ud2: - settings.engineBreakpointType = (BreakpointType)cur; - break; - } - } - GetSettingBool("Engine", "UndecorateSymbolNames", &settings.engineUndecorateSymbolNames); - GetSettingBool("Engine", "EnableDebugPrivilege", &settings.engineEnableDebugPrivilege); - GetSettingBool("Engine", "EnableSourceDebugging", &settings.engineEnableSourceDebugging); - GetSettingBool("Engine", "SaveDatabaseInProgramDirectory", &settings.engineSaveDatabaseInProgramDirectory); - GetSettingBool("Engine", "DisableDatabaseCompression", &settings.engineDisableDatabaseCompression); - switch(settings.engineCalcType) - { - case calc_signed: - ui->radioSigned->setChecked(true); - break; - case calc_unsigned: - ui->radioUnsigned->setChecked(true); - break; - } - switch(settings.engineBreakpointType) - { - case break_int3short: - ui->radioInt3Short->setChecked(true); - break; - case break_int3long: - ui->radioInt3Long->setChecked(true); - break; - case break_ud2: - ui->radioUd2->setChecked(true); - break; - } - ui->chkUndecorateSymbolNames->setChecked(settings.engineUndecorateSymbolNames); - ui->chkEnableDebugPrivilege->setChecked(settings.engineEnableDebugPrivilege); - ui->chkEnableSourceDebugging->setChecked(settings.engineEnableSourceDebugging); - ui->chkSaveDatabaseInProgramDirectory->setChecked(settings.engineSaveDatabaseInProgramDirectory); - ui->chkDisableDatabaseCompression->setChecked(settings.engineDisableDatabaseCompression); - - //Exceptions tab - char exceptionRange[MAX_SETTING_SIZE] = ""; - if(BridgeSettingGet("Exceptions", "IgnoreRange", exceptionRange)) - { - QStringList ranges = QString(exceptionRange).split(QString(","), QString::SkipEmptyParts); - for(int i = 0; i < ranges.size(); i++) - { - unsigned long start; - unsigned long end; - if(sscanf_s(ranges.at(i).toUtf8().constData(), "%08X-%08X", &start, &end) == 2 && start <= end) - { - RangeStruct newRange; - newRange.start = start; - newRange.end = end; - AddRangeToList(newRange); - } - } - } - - //Disasm tab - GetSettingBool("Disassembler", "ArgumentSpaces", &settings.disasmArgumentSpaces); - GetSettingBool("Disassembler", "MemorySpaces", &settings.disasmMemorySpaces); - GetSettingBool("Disassembler", "Uppercase", &settings.disasmUppercase); - GetSettingBool("Disassembler", "OnlyCipAutoComments", &settings.disasmOnlyCipAutoComments); - GetSettingBool("Disassembler", "TabbedMnemonic", &settings.disasmTabBetweenMnemonicAndArguments); - ui->chkArgumentSpaces->setChecked(settings.disasmArgumentSpaces); - ui->chkMemorySpaces->setChecked(settings.disasmMemorySpaces); - ui->chkUppercase->setChecked(settings.disasmUppercase); - ui->chkOnlyCipAutoComments->setChecked(settings.disasmOnlyCipAutoComments); - ui->chkTabBetweenMnemonicAndArguments->setChecked(settings.disasmTabBetweenMnemonicAndArguments); - - //Misc tab - if(DbgFunctions()->GetJit) - { - char jit_entry[MAX_SETTING_SIZE] = ""; - char jit_def_entry[MAX_SETTING_SIZE] = ""; - bool isx64 = true; -#ifndef _WIN64 - isx64 = false; -#endif - bool jit_auto_on; - bool get_jit_works; - get_jit_works = DbgFunctions()->GetJit(jit_entry, isx64); - DbgFunctions()->GetDefJit(jit_def_entry); - - if(get_jit_works) - { - if(_strcmpi(jit_entry, jit_def_entry) == 0) - settings.miscSetJIT = true; - } - else - settings.miscSetJIT = false; - ui->editJIT->setText(jit_entry); - ui->editJIT->setCursorPosition(0); - - ui->chkSetJIT->setCheckState(bool2check(settings.miscSetJIT)); - - bool get_jit_auto_works = DbgFunctions()->GetJitAuto(&jit_auto_on); - if(!get_jit_auto_works || !jit_auto_on) - settings.miscSetJITAuto = true; - else - settings.miscSetJITAuto = false; - - ui->chkConfirmBeforeAtt->setCheckState(bool2check(settings.miscSetJITAuto)); - - if(!DbgFunctions()->IsProcessElevated()) - { - ui->chkSetJIT->setDisabled(true); - ui->chkConfirmBeforeAtt->setDisabled(true); - ui->lblAdminWarning->setText(QString("Warning: Run the debugger as Admin to enable JIT.")); - } - else - ui->lblAdminWarning->setText(""); - } - char setting[MAX_SETTING_SIZE] = ""; - if(BridgeSettingGet("Symbols", "DefaultStore", setting)) - ui->editSymbolStore->setText(QString(setting)); - else - { - QString defaultStore = "http://msdl.microsoft.com/download/symbols"; - ui->editSymbolStore->setText(defaultStore); - BridgeSettingSet("Symbols", "DefaultStore", defaultStore.toUtf8().constData()); - } - if(BridgeSettingGet("Symbols", "CachePath", setting)) - ui->editSymbolCache->setText(QString(setting)); - - bJitOld = settings.miscSetJIT; - bJitAutoOld = settings.miscSetJITAuto; -} - -void SettingsDialog::SaveSettings() -{ - //Events tab - BridgeSettingSetUint("Events", "SystemBreakpoint", settings.eventSystemBreakpoint); - BridgeSettingSetUint("Events", "TlsCallbacks", settings.eventTlsCallbacks); - BridgeSettingSetUint("Events", "EntryBreakpoint", settings.eventEntryBreakpoint); - BridgeSettingSetUint("Events", "DllEntry", settings.eventDllEntry); - BridgeSettingSetUint("Events", "ThreadEntry", settings.eventThreadEntry); - BridgeSettingSetUint("Events", "AttachBreakpoint", settings.eventAttachBreakpoint); - BridgeSettingSetUint("Events", "DllLoad", settings.eventDllLoad); - BridgeSettingSetUint("Events", "DllUnload", settings.eventDllUnload); - BridgeSettingSetUint("Events", "ThreadStart", settings.eventThreadStart); - BridgeSettingSetUint("Events", "ThreadEnd", settings.eventThreadEnd); - BridgeSettingSetUint("Events", "DebugStrings", settings.eventDebugStrings); - - //Engine tab - BridgeSettingSetUint("Engine", "CalculationType", settings.engineCalcType); - BridgeSettingSetUint("Engine", "BreakpointType", settings.engineBreakpointType); - BridgeSettingSetUint("Engine", "UndecorateSymbolNames", settings.engineUndecorateSymbolNames); - BridgeSettingSetUint("Engine", "EnableDebugPrivilege", settings.engineEnableDebugPrivilege); - BridgeSettingSetUint("Engine", "EnableSourceDebugging", settings.engineEnableSourceDebugging); - BridgeSettingSetUint("Engine", "SaveDatabaseInProgramDirectory", settings.engineSaveDatabaseInProgramDirectory); - BridgeSettingSetUint("Engine", "DisableDatabaseCompression", settings.engineDisableDatabaseCompression); - - //Exceptions tab - QString exceptionRange = ""; - for(int i = 0; i < settings.exceptionRanges->size(); i++) - exceptionRange.append(QString().sprintf("%.8X-%.8X", settings.exceptionRanges->at(i).start, settings.exceptionRanges->at(i).end) + QString(",")); - exceptionRange.chop(1); //remove last comma - if(exceptionRange.size()) - BridgeSettingSet("Exceptions", "IgnoreRange", exceptionRange.toUtf8().constData()); - else - BridgeSettingSet("Exceptions", "IgnoreRange", ""); - - //Disasm tab - BridgeSettingSetUint("Disassembler", "ArgumentSpaces", settings.disasmArgumentSpaces); - BridgeSettingSetUint("Disassembler", "MemorySpaces", settings.disasmMemorySpaces); - BridgeSettingSetUint("Disassembler", "Uppercase", settings.disasmUppercase); - BridgeSettingSetUint("Disassembler", "OnlyCipAutoComments", settings.disasmOnlyCipAutoComments); - BridgeSettingSetUint("Disassembler", "TabbedMnemonic", settings.disasmTabBetweenMnemonicAndArguments); - - //Misc tab - if(DbgFunctions()->GetJit) - { - if(bJitOld != settings.miscSetJIT) - { - if(settings.miscSetJIT) - DbgCmdExecDirect("setjit oldsave"); - else - DbgCmdExecDirect("setjit restore"); - } - - if(bJitAutoOld != settings.miscSetJITAuto) - { - if(!settings.miscSetJITAuto) - DbgCmdExecDirect("setjitauto on"); - else - DbgCmdExecDirect("setjitauto off"); - } - } - if(settings.miscSymbolStore) - BridgeSettingSet("Symbols", "DefaultStore", ui->editSymbolStore->text().toUtf8().constData()); - if(settings.miscSymbolCache) - BridgeSettingSet("Symbols", "CachePath", ui->editSymbolCache->text().toUtf8().constData()); - - BridgeSettingFlush(); - Config()->load(); - DbgSettingsUpdated(); - GuiUpdateAllViews(); -} - -void SettingsDialog::AddRangeToList(RangeStruct range) -{ - //check range - unsigned long start = range.start; - unsigned long end = range.end; - - for(int i = settings.exceptionRanges->size() - 1; i > -1; i--) - { - unsigned long curStart = settings.exceptionRanges->at(i).start; - unsigned long curEnd = settings.exceptionRanges->at(i).end; - if(curStart <= end && curEnd >= start) //ranges overlap - { - if(curStart < start) //extend range to the left - start = curStart; - if(curEnd > end) //extend range to the right - end = curEnd; - settings.exceptionRanges->erase(settings.exceptionRanges->begin() + i); //remove old range - } - } - range.start = start; - range.end = end; - settings.exceptionRanges->push_back(range); - qSort(settings.exceptionRanges->begin(), settings.exceptionRanges->end(), RangeStructLess()); - ui->listExceptions->clear(); - for(int i = 0; i < settings.exceptionRanges->size(); i++) - ui->listExceptions->addItem(QString().sprintf("%.8X-%.8X", settings.exceptionRanges->at(i).start, settings.exceptionRanges->at(i).end)); -} - -void SettingsDialog::setLastException(unsigned int exceptionCode) -{ - lastException = exceptionCode; -} - -void SettingsDialog::on_btnSave_clicked() -{ - SaveSettings(); - GuiAddStatusBarMessage("Settings saved!\n"); -} - -void SettingsDialog::on_chkSystemBreakpoint_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.eventSystemBreakpoint = false; - else - settings.eventSystemBreakpoint = true; -} - -void SettingsDialog::on_chkTlsCallbacks_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.eventTlsCallbacks = false; - else - settings.eventTlsCallbacks = true; -} - -void SettingsDialog::on_chkEntryBreakpoint_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.eventEntryBreakpoint = false; - else - settings.eventEntryBreakpoint = true; -} - -void SettingsDialog::on_chkDllEntry_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.eventDllEntry = false; - else - settings.eventDllEntry = true; -} - -void SettingsDialog::on_chkThreadEntry_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.eventThreadEntry = false; - else - settings.eventThreadEntry = true; -} - -void SettingsDialog::on_chkAttachBreakpoint_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.eventAttachBreakpoint = false; - else - settings.eventAttachBreakpoint = true; -} - -void SettingsDialog::on_chkConfirmBeforeAtt_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.miscSetJITAuto = false; - else - settings.miscSetJITAuto = true; -} - -void SettingsDialog::on_chkSetJIT_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - { - if(DbgFunctions()->GetJit) - { - char jit_def_entry[MAX_SETTING_SIZE] = ""; - QString qsjit_def_entry; - - DbgFunctions()->GetDefJit(jit_def_entry); - - qsjit_def_entry = jit_def_entry; - - // if there are not an OLD JIT Stored GetJit(NULL,) returns false. - if((DbgFunctions()->GetJit(NULL, true) == false) && (ui->editJIT->text() == qsjit_def_entry)) - { - /* - * Only do this when the user wants uncheck the JIT and there are not an OLD JIT Stored - * and the JIT in Windows registry its this debugger. - * Scenario 1: the JIT in Windows registry its this debugger, if the database of the - * debugger was removed and the user wants uncheck the JIT: he cant (this block its executed then) - * - - * Scenario 2: the JIT in Windows registry its NOT this debugger, if the database of the debugger - * was removed and the user in MISC tab wants check and uncheck the JIT checkbox: he can (this block its NOT executed then). - */ - QMessageBox msg(QMessageBox::Warning, "ERROR NOT FOUND OLD JIT", "NOT FOUND OLD JIT ENTRY STORED, USE SETJIT COMMAND"); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - - settings.miscSetJIT = true; - } - else - settings.miscSetJIT = false; - - ui->chkSetJIT->setCheckState(bool2check(settings.miscSetJIT)); - } - settings.miscSetJIT = false; - } - else - settings.miscSetJIT = true; -} - -void SettingsDialog::on_chkDllLoad_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.eventDllLoad = false; - else - settings.eventDllLoad = true; -} - -void SettingsDialog::on_chkDllUnload_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.eventDllUnload = false; - else - settings.eventDllUnload = true; -} - -void SettingsDialog::on_chkThreadStart_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.eventThreadStart = false; - else - settings.eventThreadStart = true; -} - -void SettingsDialog::on_chkThreadEnd_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.eventThreadEnd = false; - else - settings.eventThreadEnd = true; -} - -void SettingsDialog::on_chkDebugStrings_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.eventDebugStrings = false; - else - settings.eventDebugStrings = true; -} - -void SettingsDialog::on_radioUnsigned_clicked() -{ - settings.engineCalcType = calc_unsigned; -} - -void SettingsDialog::on_radioSigned_clicked() -{ - settings.engineCalcType = calc_signed; -} - -void SettingsDialog::on_radioInt3Short_clicked() -{ - settings.engineBreakpointType = break_int3short; -} - -void SettingsDialog::on_radioInt3Long_clicked() -{ - settings.engineBreakpointType = break_int3long; -} - -void SettingsDialog::on_radioUd2_clicked() -{ - settings.engineBreakpointType = break_ud2; -} - -void SettingsDialog::on_chkUndecorateSymbolNames_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.engineUndecorateSymbolNames = false; - else - settings.engineUndecorateSymbolNames = true; -} - -void SettingsDialog::on_chkEnableDebugPrivilege_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) //wtf stupid shit - settings.engineEnableDebugPrivilege = false; - else - settings.engineEnableDebugPrivilege = true; -} - -void SettingsDialog::on_chkEnableSourceDebugging_stateChanged(int arg1) -{ - settings.engineEnableSourceDebugging = arg1 == Qt::Checked; -} - -void SettingsDialog::on_chkDisableDatabaseCompression_stateChanged(int arg1) -{ - settings.engineDisableDatabaseCompression = arg1 == Qt::Checked; -} - -void SettingsDialog::on_chkSaveDatabaseInProgramDirectory_stateChanged(int arg1) -{ - settings.engineSaveDatabaseInProgramDirectory = arg1 == Qt::Checked; -} - -void SettingsDialog::on_btnAddRange_clicked() -{ - ExceptionRangeDialog exceptionRange(this); - if(exceptionRange.exec() != QDialog::Accepted) - return; - RangeStruct range; - range.start = exceptionRange.rangeStart; - range.end = exceptionRange.rangeEnd; - AddRangeToList(range); -} - -void SettingsDialog::on_btnDeleteRange_clicked() -{ - QModelIndexList indexes = ui->listExceptions->selectionModel()->selectedIndexes(); - if(!indexes.size()) //no selection - return; - settings.exceptionRanges->erase(settings.exceptionRanges->begin() + indexes.at(0).row()); - ui->listExceptions->clear(); - for(int i = 0; i < settings.exceptionRanges->size(); i++) - ui->listExceptions->addItem(QString().sprintf("%.8X-%.8X", settings.exceptionRanges->at(i).start, settings.exceptionRanges->at(i).end)); -} - -void SettingsDialog::on_btnAddLast_clicked() -{ - QMessageBox msg(QMessageBox::Question, "Question", QString().sprintf("Are you sure you want to add %.8X?", lastException)); - msg.setWindowIcon(QIcon(":/icons/images/question.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.setStandardButtons(QMessageBox::No | QMessageBox::Yes); - msg.setDefaultButton(QMessageBox::Yes); - if(msg.exec() != QMessageBox::Yes) - return; - RangeStruct range; - range.start = lastException; - range.end = lastException; - AddRangeToList(range); -} - -void SettingsDialog::on_chkArgumentSpaces_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.disasmArgumentSpaces = false; - else - settings.disasmArgumentSpaces = true; -} - -void SettingsDialog::on_chkMemorySpaces_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.disasmMemorySpaces = false; - else - settings.disasmMemorySpaces = true; -} - -void SettingsDialog::on_chkUppercase_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.disasmUppercase = false; - else - settings.disasmUppercase = true; -} - -void SettingsDialog::on_chkOnlyCipAutoComments_stateChanged(int arg1) -{ - if(arg1 == Qt::Unchecked) - settings.disasmOnlyCipAutoComments = false; - else - settings.disasmOnlyCipAutoComments = true; -} - -void SettingsDialog::on_chkTabBetweenMnemonicAndArguments_stateChanged(int arg1) -{ - settings.disasmTabBetweenMnemonicAndArguments = arg1 == Qt::Checked; -} - -void SettingsDialog::on_editSymbolStore_textEdited(const QString & arg1) -{ - Q_UNUSED(arg1); - settings.miscSymbolStore = true; -} - -void SettingsDialog::on_editSymbolCache_textEdited(const QString & arg1) -{ - Q_UNUSED(arg1); - settings.miscSymbolCache = true; -} +#include "SettingsDialog.h" +#include "ui_SettingsDialog.h" +#include +#include "Configuration.h" +#include "Bridge.h" +#include "ExceptionRangeDialog.h" + +SettingsDialog::SettingsDialog(QWidget* parent) : + QDialog(parent), + ui(new Ui::SettingsDialog) +{ + ui->setupUi(this); + //set window flags +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint); +#endif + setModal(true); + LoadSettings(); //load settings from file + connect(Bridge::getBridge(), SIGNAL(setLastException(uint)), this, SLOT(setLastException(uint))); + lastException = 0; +} + +SettingsDialog::~SettingsDialog() +{ + disconnect(Bridge::getBridge(), SIGNAL(setLastException(uint)), this, SLOT(setLastException(uint))); + delete ui; +} + +void SettingsDialog::GetSettingBool(const char* section, const char* name, bool* set) +{ + duint currentSetting; + if(!set || !BridgeSettingGetUint(section, name, ¤tSetting)) + return; + if(currentSetting) + *set = true; + else + *set = false; +} + +Qt::CheckState SettingsDialog::bool2check(bool checked) +{ + if(checked) + return Qt::Checked; + return Qt::Unchecked; +} + +void SettingsDialog::LoadSettings() +{ + //Defaults + memset(&settings, 0, sizeof(SettingsStruct)); + settings.eventSystemBreakpoint = true; + settings.eventTlsCallbacks = true; + settings.eventEntryBreakpoint = true; + settings.eventAttachBreakpoint = true; + settings.engineCalcType = calc_unsigned; + settings.engineBreakpointType = break_int3short; + settings.engineUndecorateSymbolNames = true; + settings.engineEnableSourceDebugging = true; + settings.exceptionRanges = &realExceptionRanges; + settings.disasmArgumentSpaces = false; + settings.disasmMemorySpaces = false; + settings.disasmUppercase = false; + settings.disasmOnlyCipAutoComments = false; + settings.disasmTabBetweenMnemonicAndArguments = false; + + //Events tab + GetSettingBool("Events", "SystemBreakpoint", &settings.eventSystemBreakpoint); + GetSettingBool("Events", "TlsCallbacks", &settings.eventTlsCallbacks); + GetSettingBool("Events", "EntryBreakpoint", &settings.eventEntryBreakpoint); + GetSettingBool("Events", "DllEntry", &settings.eventDllEntry); + GetSettingBool("Events", "ThreadEntry", &settings.eventThreadEntry); + GetSettingBool("Events", "AttachBreakpoint", &settings.eventAttachBreakpoint); + GetSettingBool("Events", "DllLoad", &settings.eventDllLoad); + GetSettingBool("Events", "DllUnload", &settings.eventDllUnload); + GetSettingBool("Events", "ThreadStart", &settings.eventThreadStart); + GetSettingBool("Events", "ThreadEnd", &settings.eventThreadEnd); + GetSettingBool("Events", "DebugStrings", &settings.eventDebugStrings); + ui->chkSystemBreakpoint->setCheckState(bool2check(settings.eventSystemBreakpoint)); + ui->chkTlsCallbacks->setCheckState(bool2check(settings.eventTlsCallbacks)); + ui->chkEntryBreakpoint->setCheckState(bool2check(settings.eventEntryBreakpoint)); + ui->chkDllEntry->setCheckState(bool2check(settings.eventDllEntry)); + ui->chkThreadEntry->setCheckState(bool2check(settings.eventThreadEntry)); + ui->chkAttachBreakpoint->setCheckState(bool2check(settings.eventAttachBreakpoint)); + ui->chkDllLoad->setCheckState(bool2check(settings.eventDllLoad)); + ui->chkDllUnload->setCheckState(bool2check(settings.eventDllUnload)); + ui->chkThreadStart->setCheckState(bool2check(settings.eventThreadStart)); + ui->chkThreadEnd->setCheckState(bool2check(settings.eventThreadEnd)); + ui->chkDebugStrings->setCheckState(bool2check(settings.eventDebugStrings)); + + //Engine tab + duint cur; + if(BridgeSettingGetUint("Engine", "CalculationType", &cur)) + { + switch(cur) + { + case calc_signed: + case calc_unsigned: + settings.engineCalcType = (CalcType)cur; + break; + } + } + if(BridgeSettingGetUint("Engine", "BreakpointType", &cur)) + { + switch(cur) + { + case break_int3short: + case break_int3long: + case break_ud2: + settings.engineBreakpointType = (BreakpointType)cur; + break; + } + } + GetSettingBool("Engine", "UndecorateSymbolNames", &settings.engineUndecorateSymbolNames); + GetSettingBool("Engine", "EnableDebugPrivilege", &settings.engineEnableDebugPrivilege); + GetSettingBool("Engine", "EnableSourceDebugging", &settings.engineEnableSourceDebugging); + GetSettingBool("Engine", "SaveDatabaseInProgramDirectory", &settings.engineSaveDatabaseInProgramDirectory); + GetSettingBool("Engine", "DisableDatabaseCompression", &settings.engineDisableDatabaseCompression); + switch(settings.engineCalcType) + { + case calc_signed: + ui->radioSigned->setChecked(true); + break; + case calc_unsigned: + ui->radioUnsigned->setChecked(true); + break; + } + switch(settings.engineBreakpointType) + { + case break_int3short: + ui->radioInt3Short->setChecked(true); + break; + case break_int3long: + ui->radioInt3Long->setChecked(true); + break; + case break_ud2: + ui->radioUd2->setChecked(true); + break; + } + ui->chkUndecorateSymbolNames->setChecked(settings.engineUndecorateSymbolNames); + ui->chkEnableDebugPrivilege->setChecked(settings.engineEnableDebugPrivilege); + ui->chkEnableSourceDebugging->setChecked(settings.engineEnableSourceDebugging); + ui->chkSaveDatabaseInProgramDirectory->setChecked(settings.engineSaveDatabaseInProgramDirectory); + ui->chkDisableDatabaseCompression->setChecked(settings.engineDisableDatabaseCompression); + + //Exceptions tab + char exceptionRange[MAX_SETTING_SIZE] = ""; + if(BridgeSettingGet("Exceptions", "IgnoreRange", exceptionRange)) + { + QStringList ranges = QString(exceptionRange).split(QString(","), QString::SkipEmptyParts); + for(int i = 0; i < ranges.size(); i++) + { + unsigned long start; + unsigned long end; + if(sscanf_s(ranges.at(i).toUtf8().constData(), "%08X-%08X", &start, &end) == 2 && start <= end) + { + RangeStruct newRange; + newRange.start = start; + newRange.end = end; + AddRangeToList(newRange); + } + } + } + + //Disasm tab + GetSettingBool("Disassembler", "ArgumentSpaces", &settings.disasmArgumentSpaces); + GetSettingBool("Disassembler", "MemorySpaces", &settings.disasmMemorySpaces); + GetSettingBool("Disassembler", "Uppercase", &settings.disasmUppercase); + GetSettingBool("Disassembler", "OnlyCipAutoComments", &settings.disasmOnlyCipAutoComments); + GetSettingBool("Disassembler", "TabbedMnemonic", &settings.disasmTabBetweenMnemonicAndArguments); + ui->chkArgumentSpaces->setChecked(settings.disasmArgumentSpaces); + ui->chkMemorySpaces->setChecked(settings.disasmMemorySpaces); + ui->chkUppercase->setChecked(settings.disasmUppercase); + ui->chkOnlyCipAutoComments->setChecked(settings.disasmOnlyCipAutoComments); + ui->chkTabBetweenMnemonicAndArguments->setChecked(settings.disasmTabBetweenMnemonicAndArguments); + + //Misc tab + if(DbgFunctions()->GetJit) + { + char jit_entry[MAX_SETTING_SIZE] = ""; + char jit_def_entry[MAX_SETTING_SIZE] = ""; + bool isx64 = true; +#ifndef _WIN64 + isx64 = false; +#endif + bool jit_auto_on; + bool get_jit_works; + get_jit_works = DbgFunctions()->GetJit(jit_entry, isx64); + DbgFunctions()->GetDefJit(jit_def_entry); + + if(get_jit_works) + { + if(_strcmpi(jit_entry, jit_def_entry) == 0) + settings.miscSetJIT = true; + } + else + settings.miscSetJIT = false; + ui->editJIT->setText(jit_entry); + ui->editJIT->setCursorPosition(0); + + ui->chkSetJIT->setCheckState(bool2check(settings.miscSetJIT)); + + bool get_jit_auto_works = DbgFunctions()->GetJitAuto(&jit_auto_on); + if(!get_jit_auto_works || !jit_auto_on) + settings.miscSetJITAuto = true; + else + settings.miscSetJITAuto = false; + + ui->chkConfirmBeforeAtt->setCheckState(bool2check(settings.miscSetJITAuto)); + + if(!DbgFunctions()->IsProcessElevated()) + { + ui->chkSetJIT->setDisabled(true); + ui->chkConfirmBeforeAtt->setDisabled(true); + ui->lblAdminWarning->setText(QString("Warning: Run the debugger as Admin to enable JIT.")); + } + else + ui->lblAdminWarning->setText(""); + } + char setting[MAX_SETTING_SIZE] = ""; + if(BridgeSettingGet("Symbols", "DefaultStore", setting)) + ui->editSymbolStore->setText(QString(setting)); + else + { + QString defaultStore = "http://msdl.microsoft.com/download/symbols"; + ui->editSymbolStore->setText(defaultStore); + BridgeSettingSet("Symbols", "DefaultStore", defaultStore.toUtf8().constData()); + } + if(BridgeSettingGet("Symbols", "CachePath", setting)) + ui->editSymbolCache->setText(QString(setting)); + + bJitOld = settings.miscSetJIT; + bJitAutoOld = settings.miscSetJITAuto; +} + +void SettingsDialog::SaveSettings() +{ + //Events tab + BridgeSettingSetUint("Events", "SystemBreakpoint", settings.eventSystemBreakpoint); + BridgeSettingSetUint("Events", "TlsCallbacks", settings.eventTlsCallbacks); + BridgeSettingSetUint("Events", "EntryBreakpoint", settings.eventEntryBreakpoint); + BridgeSettingSetUint("Events", "DllEntry", settings.eventDllEntry); + BridgeSettingSetUint("Events", "ThreadEntry", settings.eventThreadEntry); + BridgeSettingSetUint("Events", "AttachBreakpoint", settings.eventAttachBreakpoint); + BridgeSettingSetUint("Events", "DllLoad", settings.eventDllLoad); + BridgeSettingSetUint("Events", "DllUnload", settings.eventDllUnload); + BridgeSettingSetUint("Events", "ThreadStart", settings.eventThreadStart); + BridgeSettingSetUint("Events", "ThreadEnd", settings.eventThreadEnd); + BridgeSettingSetUint("Events", "DebugStrings", settings.eventDebugStrings); + + //Engine tab + BridgeSettingSetUint("Engine", "CalculationType", settings.engineCalcType); + BridgeSettingSetUint("Engine", "BreakpointType", settings.engineBreakpointType); + BridgeSettingSetUint("Engine", "UndecorateSymbolNames", settings.engineUndecorateSymbolNames); + BridgeSettingSetUint("Engine", "EnableDebugPrivilege", settings.engineEnableDebugPrivilege); + BridgeSettingSetUint("Engine", "EnableSourceDebugging", settings.engineEnableSourceDebugging); + BridgeSettingSetUint("Engine", "SaveDatabaseInProgramDirectory", settings.engineSaveDatabaseInProgramDirectory); + BridgeSettingSetUint("Engine", "DisableDatabaseCompression", settings.engineDisableDatabaseCompression); + + //Exceptions tab + QString exceptionRange = ""; + for(int i = 0; i < settings.exceptionRanges->size(); i++) + exceptionRange.append(QString().sprintf("%.8X-%.8X", settings.exceptionRanges->at(i).start, settings.exceptionRanges->at(i).end) + QString(",")); + exceptionRange.chop(1); //remove last comma + if(exceptionRange.size()) + BridgeSettingSet("Exceptions", "IgnoreRange", exceptionRange.toUtf8().constData()); + else + BridgeSettingSet("Exceptions", "IgnoreRange", ""); + + //Disasm tab + BridgeSettingSetUint("Disassembler", "ArgumentSpaces", settings.disasmArgumentSpaces); + BridgeSettingSetUint("Disassembler", "MemorySpaces", settings.disasmMemorySpaces); + BridgeSettingSetUint("Disassembler", "Uppercase", settings.disasmUppercase); + BridgeSettingSetUint("Disassembler", "OnlyCipAutoComments", settings.disasmOnlyCipAutoComments); + BridgeSettingSetUint("Disassembler", "TabbedMnemonic", settings.disasmTabBetweenMnemonicAndArguments); + + //Misc tab + if(DbgFunctions()->GetJit) + { + if(bJitOld != settings.miscSetJIT) + { + if(settings.miscSetJIT) + DbgCmdExecDirect("setjit oldsave"); + else + DbgCmdExecDirect("setjit restore"); + } + + if(bJitAutoOld != settings.miscSetJITAuto) + { + if(!settings.miscSetJITAuto) + DbgCmdExecDirect("setjitauto on"); + else + DbgCmdExecDirect("setjitauto off"); + } + } + if(settings.miscSymbolStore) + BridgeSettingSet("Symbols", "DefaultStore", ui->editSymbolStore->text().toUtf8().constData()); + if(settings.miscSymbolCache) + BridgeSettingSet("Symbols", "CachePath", ui->editSymbolCache->text().toUtf8().constData()); + + BridgeSettingFlush(); + Config()->load(); + DbgSettingsUpdated(); + GuiUpdateAllViews(); +} + +void SettingsDialog::AddRangeToList(RangeStruct range) +{ + //check range + unsigned long start = range.start; + unsigned long end = range.end; + + for(int i = settings.exceptionRanges->size() - 1; i > -1; i--) + { + unsigned long curStart = settings.exceptionRanges->at(i).start; + unsigned long curEnd = settings.exceptionRanges->at(i).end; + if(curStart <= end && curEnd >= start) //ranges overlap + { + if(curStart < start) //extend range to the left + start = curStart; + if(curEnd > end) //extend range to the right + end = curEnd; + settings.exceptionRanges->erase(settings.exceptionRanges->begin() + i); //remove old range + } + } + range.start = start; + range.end = end; + settings.exceptionRanges->push_back(range); + qSort(settings.exceptionRanges->begin(), settings.exceptionRanges->end(), RangeStructLess()); + ui->listExceptions->clear(); + for(int i = 0; i < settings.exceptionRanges->size(); i++) + ui->listExceptions->addItem(QString().sprintf("%.8X-%.8X", settings.exceptionRanges->at(i).start, settings.exceptionRanges->at(i).end)); +} + +void SettingsDialog::setLastException(unsigned int exceptionCode) +{ + lastException = exceptionCode; +} + +void SettingsDialog::on_btnSave_clicked() +{ + SaveSettings(); + GuiAddStatusBarMessage("Settings saved!\n"); +} + +void SettingsDialog::on_chkSystemBreakpoint_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.eventSystemBreakpoint = false; + else + settings.eventSystemBreakpoint = true; +} + +void SettingsDialog::on_chkTlsCallbacks_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.eventTlsCallbacks = false; + else + settings.eventTlsCallbacks = true; +} + +void SettingsDialog::on_chkEntryBreakpoint_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.eventEntryBreakpoint = false; + else + settings.eventEntryBreakpoint = true; +} + +void SettingsDialog::on_chkDllEntry_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.eventDllEntry = false; + else + settings.eventDllEntry = true; +} + +void SettingsDialog::on_chkThreadEntry_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.eventThreadEntry = false; + else + settings.eventThreadEntry = true; +} + +void SettingsDialog::on_chkAttachBreakpoint_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.eventAttachBreakpoint = false; + else + settings.eventAttachBreakpoint = true; +} + +void SettingsDialog::on_chkConfirmBeforeAtt_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.miscSetJITAuto = false; + else + settings.miscSetJITAuto = true; +} + +void SettingsDialog::on_chkSetJIT_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + { + if(DbgFunctions()->GetJit) + { + char jit_def_entry[MAX_SETTING_SIZE] = ""; + QString qsjit_def_entry; + + DbgFunctions()->GetDefJit(jit_def_entry); + + qsjit_def_entry = jit_def_entry; + + // if there are not an OLD JIT Stored GetJit(NULL,) returns false. + if((DbgFunctions()->GetJit(NULL, true) == false) && (ui->editJIT->text() == qsjit_def_entry)) + { + /* + * Only do this when the user wants uncheck the JIT and there are not an OLD JIT Stored + * and the JIT in Windows registry its this debugger. + * Scenario 1: the JIT in Windows registry its this debugger, if the database of the + * debugger was removed and the user wants uncheck the JIT: he cant (this block its executed then) + * - + * Scenario 2: the JIT in Windows registry its NOT this debugger, if the database of the debugger + * was removed and the user in MISC tab wants check and uncheck the JIT checkbox: he can (this block its NOT executed then). + */ + QMessageBox msg(QMessageBox::Warning, "ERROR NOT FOUND OLD JIT", "NOT FOUND OLD JIT ENTRY STORED, USE SETJIT COMMAND"); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + + settings.miscSetJIT = true; + } + else + settings.miscSetJIT = false; + + ui->chkSetJIT->setCheckState(bool2check(settings.miscSetJIT)); + } + settings.miscSetJIT = false; + } + else + settings.miscSetJIT = true; +} + +void SettingsDialog::on_chkDllLoad_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.eventDllLoad = false; + else + settings.eventDllLoad = true; +} + +void SettingsDialog::on_chkDllUnload_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.eventDllUnload = false; + else + settings.eventDllUnload = true; +} + +void SettingsDialog::on_chkThreadStart_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.eventThreadStart = false; + else + settings.eventThreadStart = true; +} + +void SettingsDialog::on_chkThreadEnd_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.eventThreadEnd = false; + else + settings.eventThreadEnd = true; +} + +void SettingsDialog::on_chkDebugStrings_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.eventDebugStrings = false; + else + settings.eventDebugStrings = true; +} + +void SettingsDialog::on_radioUnsigned_clicked() +{ + settings.engineCalcType = calc_unsigned; +} + +void SettingsDialog::on_radioSigned_clicked() +{ + settings.engineCalcType = calc_signed; +} + +void SettingsDialog::on_radioInt3Short_clicked() +{ + settings.engineBreakpointType = break_int3short; +} + +void SettingsDialog::on_radioInt3Long_clicked() +{ + settings.engineBreakpointType = break_int3long; +} + +void SettingsDialog::on_radioUd2_clicked() +{ + settings.engineBreakpointType = break_ud2; +} + +void SettingsDialog::on_chkUndecorateSymbolNames_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.engineUndecorateSymbolNames = false; + else + settings.engineUndecorateSymbolNames = true; +} + +void SettingsDialog::on_chkEnableDebugPrivilege_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) //wtf stupid shit + settings.engineEnableDebugPrivilege = false; + else + settings.engineEnableDebugPrivilege = true; +} + +void SettingsDialog::on_chkEnableSourceDebugging_stateChanged(int arg1) +{ + settings.engineEnableSourceDebugging = arg1 == Qt::Checked; +} + +void SettingsDialog::on_chkDisableDatabaseCompression_stateChanged(int arg1) +{ + settings.engineDisableDatabaseCompression = arg1 == Qt::Checked; +} + +void SettingsDialog::on_chkSaveDatabaseInProgramDirectory_stateChanged(int arg1) +{ + settings.engineSaveDatabaseInProgramDirectory = arg1 == Qt::Checked; +} + +void SettingsDialog::on_btnAddRange_clicked() +{ + ExceptionRangeDialog exceptionRange(this); + if(exceptionRange.exec() != QDialog::Accepted) + return; + RangeStruct range; + range.start = exceptionRange.rangeStart; + range.end = exceptionRange.rangeEnd; + AddRangeToList(range); +} + +void SettingsDialog::on_btnDeleteRange_clicked() +{ + QModelIndexList indexes = ui->listExceptions->selectionModel()->selectedIndexes(); + if(!indexes.size()) //no selection + return; + settings.exceptionRanges->erase(settings.exceptionRanges->begin() + indexes.at(0).row()); + ui->listExceptions->clear(); + for(int i = 0; i < settings.exceptionRanges->size(); i++) + ui->listExceptions->addItem(QString().sprintf("%.8X-%.8X", settings.exceptionRanges->at(i).start, settings.exceptionRanges->at(i).end)); +} + +void SettingsDialog::on_btnAddLast_clicked() +{ + QMessageBox msg(QMessageBox::Question, "Question", QString().sprintf("Are you sure you want to add %.8X?", lastException)); + msg.setWindowIcon(QIcon(":/icons/images/question.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.setStandardButtons(QMessageBox::No | QMessageBox::Yes); + msg.setDefaultButton(QMessageBox::Yes); + if(msg.exec() != QMessageBox::Yes) + return; + RangeStruct range; + range.start = lastException; + range.end = lastException; + AddRangeToList(range); +} + +void SettingsDialog::on_chkArgumentSpaces_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.disasmArgumentSpaces = false; + else + settings.disasmArgumentSpaces = true; +} + +void SettingsDialog::on_chkMemorySpaces_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.disasmMemorySpaces = false; + else + settings.disasmMemorySpaces = true; +} + +void SettingsDialog::on_chkUppercase_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.disasmUppercase = false; + else + settings.disasmUppercase = true; +} + +void SettingsDialog::on_chkOnlyCipAutoComments_stateChanged(int arg1) +{ + if(arg1 == Qt::Unchecked) + settings.disasmOnlyCipAutoComments = false; + else + settings.disasmOnlyCipAutoComments = true; +} + +void SettingsDialog::on_chkTabBetweenMnemonicAndArguments_stateChanged(int arg1) +{ + settings.disasmTabBetweenMnemonicAndArguments = arg1 == Qt::Checked; +} + +void SettingsDialog::on_editSymbolStore_textEdited(const QString & arg1) +{ + Q_UNUSED(arg1); + settings.miscSymbolStore = true; +} + +void SettingsDialog::on_editSymbolCache_textEdited(const QString & arg1) +{ + Q_UNUSED(arg1); + settings.miscSymbolCache = true; +} diff --git a/src/gui/Src/Gui/SettingsDialog.h b/src/gui/Src/Gui/SettingsDialog.h index bcb7fb21..2ff2e96b 100644 --- a/src/gui/Src/Gui/SettingsDialog.h +++ b/src/gui/Src/Gui/SettingsDialog.h @@ -1,146 +1,146 @@ -#ifndef SETTINGSDIALOG_H -#define SETTINGSDIALOG_H - -#include - -namespace Ui -{ -class SettingsDialog; -} - -class SettingsDialog : public QDialog -{ - Q_OBJECT - -public: - explicit SettingsDialog(QWidget* parent = 0); - ~SettingsDialog(); - void SaveSettings(); - unsigned int lastException; - -private slots: - //Manual slots - void setLastException(unsigned int exceptionCode); - //General - void on_btnSave_clicked(); - //Event tab - void on_chkSystemBreakpoint_stateChanged(int arg1); - void on_chkTlsCallbacks_stateChanged(int arg1); - void on_chkEntryBreakpoint_stateChanged(int arg1); - void on_chkDllEntry_stateChanged(int arg1); - void on_chkThreadEntry_stateChanged(int arg1); - void on_chkAttachBreakpoint_stateChanged(int arg1); - void on_chkDllLoad_stateChanged(int arg1); - void on_chkDllUnload_stateChanged(int arg1); - void on_chkThreadStart_stateChanged(int arg1); - void on_chkThreadEnd_stateChanged(int arg1); - void on_chkDebugStrings_stateChanged(int arg1); - //Engine tab - void on_radioUnsigned_clicked(); - void on_radioSigned_clicked(); - void on_radioInt3Short_clicked(); - void on_radioInt3Long_clicked(); - void on_radioUd2_clicked(); - void on_chkUndecorateSymbolNames_stateChanged(int arg1); - void on_chkEnableDebugPrivilege_stateChanged(int arg1); - void on_chkEnableSourceDebugging_stateChanged(int arg1); - void on_chkDisableDatabaseCompression_stateChanged(int arg1); - void on_chkSaveDatabaseInProgramDirectory_stateChanged(int arg1); - //Exception tab - void on_btnAddRange_clicked(); - void on_btnDeleteRange_clicked(); - void on_btnAddLast_clicked(); - //Disasm tab - void on_chkArgumentSpaces_stateChanged(int arg1); - void on_chkMemorySpaces_stateChanged(int arg1); - void on_chkUppercase_stateChanged(int arg1); - void on_chkOnlyCipAutoComments_stateChanged(int arg1); - void on_chkTabBetweenMnemonicAndArguments_stateChanged(int arg1); - //Misc tab - void on_chkSetJIT_stateChanged(int arg1); - void on_chkConfirmBeforeAtt_stateChanged(int arg1); - void on_editSymbolStore_textEdited(const QString & arg1); - void on_editSymbolCache_textEdited(const QString & arg1); - -private: - //enums - enum CalcType - { - calc_signed = 0, - calc_unsigned = 1 - }; - - enum BreakpointType - { - break_int3short = 0, - break_int3long = 1, - break_ud2 = 2 - }; - - //structures - struct RangeStruct - { - unsigned long start; - unsigned long end; - }; - - struct RangeStructLess - { - bool operator()(const RangeStruct a, const RangeStruct b) const - { - return a.start < b.start; - } - }; - - struct SettingsStruct - { - //Event Tab - bool eventSystemBreakpoint; - bool eventTlsCallbacks; - bool eventEntryBreakpoint; - bool eventDllEntry; - bool eventThreadEntry; - bool eventAttachBreakpoint; - bool eventDllLoad; - bool eventDllUnload; - bool eventThreadStart; - bool eventThreadEnd; - bool eventDebugStrings; - //Engine Tab - CalcType engineCalcType; - BreakpointType engineBreakpointType; - bool engineUndecorateSymbolNames; - bool engineEnableDebugPrivilege; - bool engineEnableSourceDebugging; - bool engineSaveDatabaseInProgramDirectory; - bool engineDisableDatabaseCompression; - //Exception Tab - QList* exceptionRanges; - //Disasm Tab - bool disasmArgumentSpaces; - bool disasmMemorySpaces; - bool disasmUppercase; - bool disasmOnlyCipAutoComments; - bool disasmTabBetweenMnemonicAndArguments; - //Misc Tab - bool miscSetJIT; - bool miscSetJITAuto; - bool miscSymbolStore; - bool miscSymbolCache; - }; - - //variables - Ui::SettingsDialog* ui; - SettingsStruct settings; - QList realExceptionRanges; - bool bJitOld; - bool bJitAutoOld; - - //functions - void GetSettingBool(const char* section, const char* name, bool* set); - Qt::CheckState bool2check(bool checked); - void LoadSettings(); - void AddRangeToList(RangeStruct range); -}; - -#endif // SETTINGSDIALOG_H +#ifndef SETTINGSDIALOG_H +#define SETTINGSDIALOG_H + +#include + +namespace Ui +{ +class SettingsDialog; +} + +class SettingsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SettingsDialog(QWidget* parent = 0); + ~SettingsDialog(); + void SaveSettings(); + unsigned int lastException; + +private slots: + //Manual slots + void setLastException(unsigned int exceptionCode); + //General + void on_btnSave_clicked(); + //Event tab + void on_chkSystemBreakpoint_stateChanged(int arg1); + void on_chkTlsCallbacks_stateChanged(int arg1); + void on_chkEntryBreakpoint_stateChanged(int arg1); + void on_chkDllEntry_stateChanged(int arg1); + void on_chkThreadEntry_stateChanged(int arg1); + void on_chkAttachBreakpoint_stateChanged(int arg1); + void on_chkDllLoad_stateChanged(int arg1); + void on_chkDllUnload_stateChanged(int arg1); + void on_chkThreadStart_stateChanged(int arg1); + void on_chkThreadEnd_stateChanged(int arg1); + void on_chkDebugStrings_stateChanged(int arg1); + //Engine tab + void on_radioUnsigned_clicked(); + void on_radioSigned_clicked(); + void on_radioInt3Short_clicked(); + void on_radioInt3Long_clicked(); + void on_radioUd2_clicked(); + void on_chkUndecorateSymbolNames_stateChanged(int arg1); + void on_chkEnableDebugPrivilege_stateChanged(int arg1); + void on_chkEnableSourceDebugging_stateChanged(int arg1); + void on_chkDisableDatabaseCompression_stateChanged(int arg1); + void on_chkSaveDatabaseInProgramDirectory_stateChanged(int arg1); + //Exception tab + void on_btnAddRange_clicked(); + void on_btnDeleteRange_clicked(); + void on_btnAddLast_clicked(); + //Disasm tab + void on_chkArgumentSpaces_stateChanged(int arg1); + void on_chkMemorySpaces_stateChanged(int arg1); + void on_chkUppercase_stateChanged(int arg1); + void on_chkOnlyCipAutoComments_stateChanged(int arg1); + void on_chkTabBetweenMnemonicAndArguments_stateChanged(int arg1); + //Misc tab + void on_chkSetJIT_stateChanged(int arg1); + void on_chkConfirmBeforeAtt_stateChanged(int arg1); + void on_editSymbolStore_textEdited(const QString & arg1); + void on_editSymbolCache_textEdited(const QString & arg1); + +private: + //enums + enum CalcType + { + calc_signed = 0, + calc_unsigned = 1 + }; + + enum BreakpointType + { + break_int3short = 0, + break_int3long = 1, + break_ud2 = 2 + }; + + //structures + struct RangeStruct + { + unsigned long start; + unsigned long end; + }; + + struct RangeStructLess + { + bool operator()(const RangeStruct a, const RangeStruct b) const + { + return a.start < b.start; + } + }; + + struct SettingsStruct + { + //Event Tab + bool eventSystemBreakpoint; + bool eventTlsCallbacks; + bool eventEntryBreakpoint; + bool eventDllEntry; + bool eventThreadEntry; + bool eventAttachBreakpoint; + bool eventDllLoad; + bool eventDllUnload; + bool eventThreadStart; + bool eventThreadEnd; + bool eventDebugStrings; + //Engine Tab + CalcType engineCalcType; + BreakpointType engineBreakpointType; + bool engineUndecorateSymbolNames; + bool engineEnableDebugPrivilege; + bool engineEnableSourceDebugging; + bool engineSaveDatabaseInProgramDirectory; + bool engineDisableDatabaseCompression; + //Exception Tab + QList* exceptionRanges; + //Disasm Tab + bool disasmArgumentSpaces; + bool disasmMemorySpaces; + bool disasmUppercase; + bool disasmOnlyCipAutoComments; + bool disasmTabBetweenMnemonicAndArguments; + //Misc Tab + bool miscSetJIT; + bool miscSetJITAuto; + bool miscSymbolStore; + bool miscSymbolCache; + }; + + //variables + Ui::SettingsDialog* ui; + SettingsStruct settings; + QList realExceptionRanges; + bool bJitOld; + bool bJitAutoOld; + + //functions + void GetSettingBool(const char* section, const char* name, bool* set); + Qt::CheckState bool2check(bool checked); + void LoadSettings(); + void AddRangeToList(RangeStruct range); +}; + +#endif // SETTINGSDIALOG_H diff --git a/src/gui/Src/Gui/ShortcutsDialog.cpp b/src/gui/Src/Gui/ShortcutsDialog.cpp index 1ea9dd3e..6d035313 100644 --- a/src/gui/Src/Gui/ShortcutsDialog.cpp +++ b/src/gui/Src/Gui/ShortcutsDialog.cpp @@ -1,132 +1,132 @@ -#include "ShortcutsDialog.h" -#include "ui_ShortcutsDialog.h" - -ShortcutsDialog::ShortcutsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ShortcutsDialog) -{ - ui->setupUi(this); - //set window flags -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); -#endif - setFixedSize(this->size()); //fixed size - setModal(true); - - // x64 has no model-view-controler pattern - QStringList tblHeader; - tblHeader << "Instruction" << "Shortcut"; - - currentRow = 0; - - ui->tblShortcuts->setColumnCount(2); - ui->tblShortcuts->verticalHeader()->setVisible(false); - ui->tblShortcuts->setHorizontalHeaderLabels(tblHeader); - ui->tblShortcuts->setEditTriggers(QAbstractItemView::NoEditTriggers); - ui->tblShortcuts->setSelectionBehavior(QAbstractItemView::SelectRows); - ui->tblShortcuts->setSelectionMode(QAbstractItemView::SingleSelection); - ui->tblShortcuts->setShowGrid(false); -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - ui->tblShortcuts->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch); -#else - ui->tblShortcuts->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); -#endif - - ui->tblShortcuts->verticalHeader()->setDefaultSectionSize(15); - - const unsigned int numShortcuts = Config()->Shortcuts.count(); - ui->tblShortcuts->setRowCount(numShortcuts); - int j = 0; - for(QMap::iterator i = Config()->Shortcuts.begin(); i != Config()->Shortcuts.end(); ++i, j++) - { - QTableWidgetItem* shortcutName = new QTableWidgetItem(i.value().Name); - QTableWidgetItem* shortcutKey = new QTableWidgetItem(i.value().Hotkey.toString(QKeySequence::NativeText)); - ui->tblShortcuts->setItem(j, 0, shortcutName); - ui->tblShortcuts->setItem(j, 1, shortcutKey); - } - - connect(ui->tblShortcuts, SIGNAL(itemSelectionChanged()), this, SLOT(syncTextfield())); - connect(ui->shortcutEdit, SIGNAL(askForSave()), this, SLOT(updateShortcut())); - connect(this, SIGNAL(rejected()), this, SLOT(rejectedSlot())); -} - -void ShortcutsDialog::updateShortcut() -{ - const QKeySequence newKey = ui->shortcutEdit->getKeysequence(); - if(newKey != currentShortcut.Hotkey) - { - bool good = true; - if(!newKey.isEmpty()) - { - int idx = 0; - for(QMap::iterator i = Config()->Shortcuts.begin(); i != Config()->Shortcuts.end(); ++i, idx++) - { - if(i.value().Name == currentShortcut.Name) //skip current shortcut in list - continue; - if(i.value().GlobalShortcut && i.value().Hotkey == newKey) //newkey is trying to override a global shortcut - { - good = false; - break; - } - else if(currentShortcut.GlobalShortcut && i.value().Hotkey == newKey) //current shortcut is global and overrides another local hotkey - { - ui->tblShortcuts->setItem(idx, 1, new QTableWidgetItem("")); - Config()->setShortcut(i.key(), QKeySequence()); - } - } - } - if(good) - { - for(QMap::iterator i = Config()->Shortcuts.begin(); i != Config()->Shortcuts.end(); ++i) - { - if(i.value().Name == currentShortcut.Name) - { - Config()->setShortcut(i.key(), newKey); - break; - } - } - QString keyText = ""; - if(!newKey.isEmpty()) - keyText = newKey.toString(QKeySequence::NativeText); - ui->tblShortcuts->item(currentRow, 1)->setText(keyText); - ui->shortcutEdit->setErrorState(false); - } - else - { - ui->shortcutEdit->setErrorState(true); - } - } -} - -void ShortcutsDialog::syncTextfield() -{ - QModelIndexList indexes = ui->tblShortcuts->selectionModel()->selectedRows(); - if(indexes.count() < 1) - return; - currentRow = indexes.at(0).row(); - for(QMap::iterator i = Config()->Shortcuts.begin(); i != Config()->Shortcuts.end(); ++i) - { - if(i.value().Name == ui->tblShortcuts->item(currentRow, 0)->text()) - { - currentShortcut = i.value(); - break; - } - } - ui->shortcutEdit->setErrorState(false); - ui->shortcutEdit->setText(currentShortcut.Hotkey.toString(QKeySequence::NativeText)); - ui->shortcutEdit->setFocus(); -} - -ShortcutsDialog::~ShortcutsDialog() -{ - delete ui; -} - -void ShortcutsDialog::on_btnSave_clicked() -{ - Config()->writeShortcuts(); - GuiAddStatusBarMessage("Settings saved!\n"); -} - -void ShortcutsDialog::rejectedSlot() -{ - Config()->readShortcuts(); -} +#include "ShortcutsDialog.h" +#include "ui_ShortcutsDialog.h" + +ShortcutsDialog::ShortcutsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ShortcutsDialog) +{ + ui->setupUi(this); + //set window flags +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); +#endif + setFixedSize(this->size()); //fixed size + setModal(true); + + // x64 has no model-view-controler pattern + QStringList tblHeader; + tblHeader << "Instruction" << "Shortcut"; + + currentRow = 0; + + ui->tblShortcuts->setColumnCount(2); + ui->tblShortcuts->verticalHeader()->setVisible(false); + ui->tblShortcuts->setHorizontalHeaderLabels(tblHeader); + ui->tblShortcuts->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->tblShortcuts->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->tblShortcuts->setSelectionMode(QAbstractItemView::SingleSelection); + ui->tblShortcuts->setShowGrid(false); +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + ui->tblShortcuts->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch); +#else + ui->tblShortcuts->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); +#endif + + ui->tblShortcuts->verticalHeader()->setDefaultSectionSize(15); + + const unsigned int numShortcuts = Config()->Shortcuts.count(); + ui->tblShortcuts->setRowCount(numShortcuts); + int j = 0; + for(QMap::iterator i = Config()->Shortcuts.begin(); i != Config()->Shortcuts.end(); ++i, j++) + { + QTableWidgetItem* shortcutName = new QTableWidgetItem(i.value().Name); + QTableWidgetItem* shortcutKey = new QTableWidgetItem(i.value().Hotkey.toString(QKeySequence::NativeText)); + ui->tblShortcuts->setItem(j, 0, shortcutName); + ui->tblShortcuts->setItem(j, 1, shortcutKey); + } + + connect(ui->tblShortcuts, SIGNAL(itemSelectionChanged()), this, SLOT(syncTextfield())); + connect(ui->shortcutEdit, SIGNAL(askForSave()), this, SLOT(updateShortcut())); + connect(this, SIGNAL(rejected()), this, SLOT(rejectedSlot())); +} + +void ShortcutsDialog::updateShortcut() +{ + const QKeySequence newKey = ui->shortcutEdit->getKeysequence(); + if(newKey != currentShortcut.Hotkey) + { + bool good = true; + if(!newKey.isEmpty()) + { + int idx = 0; + for(QMap::iterator i = Config()->Shortcuts.begin(); i != Config()->Shortcuts.end(); ++i, idx++) + { + if(i.value().Name == currentShortcut.Name) //skip current shortcut in list + continue; + if(i.value().GlobalShortcut && i.value().Hotkey == newKey) //newkey is trying to override a global shortcut + { + good = false; + break; + } + else if(currentShortcut.GlobalShortcut && i.value().Hotkey == newKey) //current shortcut is global and overrides another local hotkey + { + ui->tblShortcuts->setItem(idx, 1, new QTableWidgetItem("")); + Config()->setShortcut(i.key(), QKeySequence()); + } + } + } + if(good) + { + for(QMap::iterator i = Config()->Shortcuts.begin(); i != Config()->Shortcuts.end(); ++i) + { + if(i.value().Name == currentShortcut.Name) + { + Config()->setShortcut(i.key(), newKey); + break; + } + } + QString keyText = ""; + if(!newKey.isEmpty()) + keyText = newKey.toString(QKeySequence::NativeText); + ui->tblShortcuts->item(currentRow, 1)->setText(keyText); + ui->shortcutEdit->setErrorState(false); + } + else + { + ui->shortcutEdit->setErrorState(true); + } + } +} + +void ShortcutsDialog::syncTextfield() +{ + QModelIndexList indexes = ui->tblShortcuts->selectionModel()->selectedRows(); + if(indexes.count() < 1) + return; + currentRow = indexes.at(0).row(); + for(QMap::iterator i = Config()->Shortcuts.begin(); i != Config()->Shortcuts.end(); ++i) + { + if(i.value().Name == ui->tblShortcuts->item(currentRow, 0)->text()) + { + currentShortcut = i.value(); + break; + } + } + ui->shortcutEdit->setErrorState(false); + ui->shortcutEdit->setText(currentShortcut.Hotkey.toString(QKeySequence::NativeText)); + ui->shortcutEdit->setFocus(); +} + +ShortcutsDialog::~ShortcutsDialog() +{ + delete ui; +} + +void ShortcutsDialog::on_btnSave_clicked() +{ + Config()->writeShortcuts(); + GuiAddStatusBarMessage("Settings saved!\n"); +} + +void ShortcutsDialog::rejectedSlot() +{ + Config()->readShortcuts(); +} diff --git a/src/gui/Src/Gui/ShortcutsDialog.h b/src/gui/Src/Gui/ShortcutsDialog.h index 992c20ce..735b0e71 100644 --- a/src/gui/Src/Gui/ShortcutsDialog.h +++ b/src/gui/Src/Gui/ShortcutsDialog.h @@ -1,36 +1,36 @@ -#ifndef SHORTCUTSDIALOG_H -#define SHORTCUTSDIALOG_H - -#include -#include -#include "Configuration.h" - -namespace Ui -{ -class ShortcutsDialog; -} - -class ShortcutsDialog : public QDialog -{ - Q_OBJECT - Configuration::Shortcut currentShortcut; - int currentRow; - -public: - explicit ShortcutsDialog(QWidget* parent = 0); - ~ShortcutsDialog(); - -protected slots: - void syncTextfield(); - void updateShortcut(); - -private slots: - void on_btnSave_clicked(); - void rejectedSlot(); - -private: - Ui::ShortcutsDialog* ui; - QMap ShortcutsBackup; -}; - -#endif // SHORTCUTSDIALOG_H +#ifndef SHORTCUTSDIALOG_H +#define SHORTCUTSDIALOG_H + +#include +#include +#include "Configuration.h" + +namespace Ui +{ +class ShortcutsDialog; +} + +class ShortcutsDialog : public QDialog +{ + Q_OBJECT + Configuration::Shortcut currentShortcut; + int currentRow; + +public: + explicit ShortcutsDialog(QWidget* parent = 0); + ~ShortcutsDialog(); + +protected slots: + void syncTextfield(); + void updateShortcut(); + +private slots: + void on_btnSave_clicked(); + void rejectedSlot(); + +private: + Ui::ShortcutsDialog* ui; + QMap ShortcutsBackup; +}; + +#endif // SHORTCUTSDIALOG_H diff --git a/src/gui/Src/Gui/SourceView.cpp b/src/gui/Src/Gui/SourceView.cpp index e724b08c..a3eae5cf 100644 --- a/src/gui/Src/Gui/SourceView.cpp +++ b/src/gui/Src/Gui/SourceView.cpp @@ -1,140 +1,140 @@ -#include "SourceView.h" -#include -#include -#include -#include "Configuration.h" - -SourceView::SourceView(QString path, int line, StdTable* parent) : StdTable(parent) -{ - mSourcePath = path; - - addColumnAt(8 + 4 * getCharWidth(), "Line", true); - addColumnAt(0, "Code", true); - - loadFile(); - setInstructionPointer(line); - - connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint))); - setupContextMenu(); -} - -void SourceView::contextMenuSlot(const QPoint & pos) -{ - QMenu* wMenu = new QMenu(this); - - int line = getInitialSelection() + 1; - dsint addr = DbgFunctions()->GetAddrFromLine(mSourcePath.toUtf8().constData(), line); - if(addr) - wMenu->addAction(mFollowInDisasm); - - wMenu->exec(mapToGlobal(pos)); -} - -void SourceView::setupContextMenu() -{ - mFollowInDisasm = new QAction("Follow in &Disassembler", this); - connect(mFollowInDisasm, SIGNAL(triggered()), this, SLOT(followInDisasmSlot())); -} - -void SourceView::setSelection(int line) -{ - int offset = line - 1; - if(isValidIndex(offset, 0)) - { - int rangefrom = getTableOffset(); - int rangeto = rangefrom + getViewableRowsCount() - 1; - if(offset < rangefrom) //ip lays before the current view - setTableOffset(offset); - else if(offset > (rangeto - 1)) //ip lays after the current view - setTableOffset(offset - getViewableRowsCount() + 2); - setSingleSelection(offset); - } - reloadData(); //repaint -} - -void SourceView::setInstructionPointer(int line) -{ - int offset = line - 1; - if(!isValidIndex(offset, 0)) - { - mIpLine = 0; - return; - } - mIpLine = line; - int rangefrom = getTableOffset(); - int rangeto = rangefrom + getViewableRowsCount() - 1; - if(offset < rangefrom) //ip lays before the current view - setTableOffset(offset); - else if(offset > (rangeto - 1)) //ip lays after the current view - setTableOffset(offset - getViewableRowsCount() + 2); - setSingleSelection(offset); - reloadData(); //repaint -} - -QString SourceView::getSourcePath() -{ - return mSourcePath; -} - -void SourceView::loadFile() -{ - QFile file(mSourcePath); - if(!file.open(QIODevice::ReadOnly)) - { - return; //error? - } - QTextStream in(&file); - int lineNum = 0; - while(!in.atEnd()) - { - QString line = in.readLine().replace('\t', " "); //replace tabs with four spaces - setRowCount(lineNum + 1); - setCellContent(lineNum, 0, QString().sprintf("%04d", lineNum + 1)); - setCellContent(lineNum, 1, line); - lineNum++; - } - reloadData(); - file.close(); -} - -QString SourceView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) -{ - painter->save(); - bool wIsSelected = isSelected(rowBase, rowOffset); - // Highlight if selected - if(wIsSelected) - painter->fillRect(QRect(x, y, w, h), QBrush(selectionColor)); //ScriptViewSelectionColor - QString returnString; - int line = rowBase + rowOffset + 1; - switch(col) - { - case 0: //line number - { - if(line == mIpLine) //IP - { - painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyCipBackgroundColor"))); - painter->setPen(QPen(ConfigColor("DisassemblyCipColor"))); //white address (ScriptViewIpTextColor) - } - else - painter->setPen(QPen(this->textColor)); - painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, QString().sprintf("%04d", line)); - } - break; - - case 1: //command - { - returnString = getCellContent(rowBase + rowOffset, col); //TODO: simple keyword/regex-based syntax highlighting - } - break; - } - painter->restore(); - return returnString; -} - -void SourceView::followInDisasmSlot() -{ - int line = getInitialSelection() + 1; - dsint addr = DbgFunctions()->GetAddrFromLine(mSourcePath.toUtf8().constData(), line); - DbgCmdExecDirect(QString().sprintf("disasm %p", addr).toUtf8().constData()); - emit showCpu(); -} +#include "SourceView.h" +#include +#include +#include +#include "Configuration.h" + +SourceView::SourceView(QString path, int line, StdTable* parent) : StdTable(parent) +{ + mSourcePath = path; + + addColumnAt(8 + 4 * getCharWidth(), "Line", true); + addColumnAt(0, "Code", true); + + loadFile(); + setInstructionPointer(line); + + connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint))); + setupContextMenu(); +} + +void SourceView::contextMenuSlot(const QPoint & pos) +{ + QMenu* wMenu = new QMenu(this); + + int line = getInitialSelection() + 1; + dsint addr = DbgFunctions()->GetAddrFromLine(mSourcePath.toUtf8().constData(), line); + if(addr) + wMenu->addAction(mFollowInDisasm); + + wMenu->exec(mapToGlobal(pos)); +} + +void SourceView::setupContextMenu() +{ + mFollowInDisasm = new QAction("Follow in &Disassembler", this); + connect(mFollowInDisasm, SIGNAL(triggered()), this, SLOT(followInDisasmSlot())); +} + +void SourceView::setSelection(int line) +{ + int offset = line - 1; + if(isValidIndex(offset, 0)) + { + int rangefrom = getTableOffset(); + int rangeto = rangefrom + getViewableRowsCount() - 1; + if(offset < rangefrom) //ip lays before the current view + setTableOffset(offset); + else if(offset > (rangeto - 1)) //ip lays after the current view + setTableOffset(offset - getViewableRowsCount() + 2); + setSingleSelection(offset); + } + reloadData(); //repaint +} + +void SourceView::setInstructionPointer(int line) +{ + int offset = line - 1; + if(!isValidIndex(offset, 0)) + { + mIpLine = 0; + return; + } + mIpLine = line; + int rangefrom = getTableOffset(); + int rangeto = rangefrom + getViewableRowsCount() - 1; + if(offset < rangefrom) //ip lays before the current view + setTableOffset(offset); + else if(offset > (rangeto - 1)) //ip lays after the current view + setTableOffset(offset - getViewableRowsCount() + 2); + setSingleSelection(offset); + reloadData(); //repaint +} + +QString SourceView::getSourcePath() +{ + return mSourcePath; +} + +void SourceView::loadFile() +{ + QFile file(mSourcePath); + if(!file.open(QIODevice::ReadOnly)) + { + return; //error? + } + QTextStream in(&file); + int lineNum = 0; + while(!in.atEnd()) + { + QString line = in.readLine().replace('\t', " "); //replace tabs with four spaces + setRowCount(lineNum + 1); + setCellContent(lineNum, 0, QString().sprintf("%04d", lineNum + 1)); + setCellContent(lineNum, 1, line); + lineNum++; + } + reloadData(); + file.close(); +} + +QString SourceView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) +{ + painter->save(); + bool wIsSelected = isSelected(rowBase, rowOffset); + // Highlight if selected + if(wIsSelected) + painter->fillRect(QRect(x, y, w, h), QBrush(selectionColor)); //ScriptViewSelectionColor + QString returnString; + int line = rowBase + rowOffset + 1; + switch(col) + { + case 0: //line number + { + if(line == mIpLine) //IP + { + painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyCipBackgroundColor"))); + painter->setPen(QPen(ConfigColor("DisassemblyCipColor"))); //white address (ScriptViewIpTextColor) + } + else + painter->setPen(QPen(this->textColor)); + painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, QString().sprintf("%04d", line)); + } + break; + + case 1: //command + { + returnString = getCellContent(rowBase + rowOffset, col); //TODO: simple keyword/regex-based syntax highlighting + } + break; + } + painter->restore(); + return returnString; +} + +void SourceView::followInDisasmSlot() +{ + int line = getInitialSelection() + 1; + dsint addr = DbgFunctions()->GetAddrFromLine(mSourcePath.toUtf8().constData(), line); + DbgCmdExecDirect(QString().sprintf("disasm %p", addr).toUtf8().constData()); + emit showCpu(); +} diff --git a/src/gui/Src/Gui/SourceView.h b/src/gui/Src/Gui/SourceView.h index ee870163..66844ddb 100644 --- a/src/gui/Src/Gui/SourceView.h +++ b/src/gui/Src/Gui/SourceView.h @@ -1,35 +1,35 @@ -#ifndef SOURCEVIEW_H -#define SOURCEVIEW_H - -#include -#include -#include -#include "StdTable.h" - -class SourceView : public StdTable -{ - Q_OBJECT -public: - explicit SourceView(QString path, int line = 0, StdTable* parent = 0); - QString getSourcePath(); - void setInstructionPointer(int line); - QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); - void setupContextMenu(); - void setSelection(int line); - -signals: - void showCpu(); - -public slots: - void contextMenuSlot(const QPoint & pos); - void followInDisasmSlot(); - -private: - QAction* mFollowInDisasm; - - QString mSourcePath; - int mIpLine; - void loadFile(); -}; - -#endif // SOURCEVIEW_H +#ifndef SOURCEVIEW_H +#define SOURCEVIEW_H + +#include +#include +#include +#include "StdTable.h" + +class SourceView : public StdTable +{ + Q_OBJECT +public: + explicit SourceView(QString path, int line = 0, StdTable* parent = 0); + QString getSourcePath(); + void setInstructionPointer(int line); + QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); + void setupContextMenu(); + void setSelection(int line); + +signals: + void showCpu(); + +public slots: + void contextMenuSlot(const QPoint & pos); + void followInDisasmSlot(); + +private: + QAction* mFollowInDisasm; + + QString mSourcePath; + int mIpLine; + void loadFile(); +}; + +#endif // SOURCEVIEW_H diff --git a/src/gui/Src/Gui/SourceViewerManager.cpp b/src/gui/Src/Gui/SourceViewerManager.cpp index 54a88ee7..606caa3c 100644 --- a/src/gui/Src/Gui/SourceViewerManager.cpp +++ b/src/gui/Src/Gui/SourceViewerManager.cpp @@ -1,71 +1,71 @@ -#include "SourceViewerManager.h" -#include "Bridge.h" -#include -#include - -SourceViewerManager::SourceViewerManager(QWidget* parent) : QTabWidget(parent) -{ - setMovable(true); - setTabsClosable(true); - - //Close All Tabs - mCloseAllTabs = new QPushButton(this); - mCloseAllTabs->setIcon(QIcon(":/icons/images/close-all-tabs.png")); - mCloseAllTabs->setToolTip("Close All Tabs"); - connect(mCloseAllTabs, SIGNAL(clicked()), this, SLOT(closeAllTabs())); - setCornerWidget(mCloseAllTabs, Qt::TopLeftCorner); - - connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); - connect(Bridge::getBridge(), SIGNAL(loadSourceFile(QString, int, int)), this, SLOT(loadSourceFile(QString, int, int))); -} - -void SourceViewerManager::loadSourceFile(QString path, int line, int selection) -{ - if(!selection) - { - for(int i = 0; i < count(); i++) //remove all other instruction pointers (only one is possible) - ((SourceView*)this->widget(i))->setInstructionPointer(0); - } - for(int i = 0; i < count(); i++) - { - SourceView* curView = (SourceView*)this->widget(i); - if(curView->getSourcePath().compare(path, Qt::CaseInsensitive) == 0) //file already loaded - { - if(selection) - curView->setSelection(selection); - else - curView->setInstructionPointer(line); - setCurrentIndex(i); //show that loaded tab - return; - } - } - //check if file actually exists - if(!QFileInfo(path).exists()) - { - return; //error? - } - //load the new file - QString title = path; - int idx = path.lastIndexOf(QDir::separator()); - if(idx != -1) - title = path.mid(idx + 1); - SourceView* newView = new SourceView(path, line); - connect(newView, SIGNAL(showCpu()), this, SIGNAL(showCpu())); - if(selection) - { - newView->setInstructionPointer(0); - newView->setSelection(selection); - } - addTab(newView, title); - setCurrentIndex(count() - 1); -} - -void SourceViewerManager::closeTab(int index) -{ - removeTab(index); -} - -void SourceViewerManager::closeAllTabs() -{ - clear(); -} +#include "SourceViewerManager.h" +#include "Bridge.h" +#include +#include + +SourceViewerManager::SourceViewerManager(QWidget* parent) : QTabWidget(parent) +{ + setMovable(true); + setTabsClosable(true); + + //Close All Tabs + mCloseAllTabs = new QPushButton(this); + mCloseAllTabs->setIcon(QIcon(":/icons/images/close-all-tabs.png")); + mCloseAllTabs->setToolTip("Close All Tabs"); + connect(mCloseAllTabs, SIGNAL(clicked()), this, SLOT(closeAllTabs())); + setCornerWidget(mCloseAllTabs, Qt::TopLeftCorner); + + connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); + connect(Bridge::getBridge(), SIGNAL(loadSourceFile(QString, int, int)), this, SLOT(loadSourceFile(QString, int, int))); +} + +void SourceViewerManager::loadSourceFile(QString path, int line, int selection) +{ + if(!selection) + { + for(int i = 0; i < count(); i++) //remove all other instruction pointers (only one is possible) + ((SourceView*)this->widget(i))->setInstructionPointer(0); + } + for(int i = 0; i < count(); i++) + { + SourceView* curView = (SourceView*)this->widget(i); + if(curView->getSourcePath().compare(path, Qt::CaseInsensitive) == 0) //file already loaded + { + if(selection) + curView->setSelection(selection); + else + curView->setInstructionPointer(line); + setCurrentIndex(i); //show that loaded tab + return; + } + } + //check if file actually exists + if(!QFileInfo(path).exists()) + { + return; //error? + } + //load the new file + QString title = path; + int idx = path.lastIndexOf(QDir::separator()); + if(idx != -1) + title = path.mid(idx + 1); + SourceView* newView = new SourceView(path, line); + connect(newView, SIGNAL(showCpu()), this, SIGNAL(showCpu())); + if(selection) + { + newView->setInstructionPointer(0); + newView->setSelection(selection); + } + addTab(newView, title); + setCurrentIndex(count() - 1); +} + +void SourceViewerManager::closeTab(int index) +{ + removeTab(index); +} + +void SourceViewerManager::closeAllTabs() +{ + clear(); +} diff --git a/src/gui/Src/Gui/SourceViewerManager.h b/src/gui/Src/Gui/SourceViewerManager.h index 22e064d1..02ed881f 100644 --- a/src/gui/Src/Gui/SourceViewerManager.h +++ b/src/gui/Src/Gui/SourceViewerManager.h @@ -1,27 +1,27 @@ -#ifndef SOURCEVIEWERMANAGER_H -#define SOURCEVIEWERMANAGER_H - -#include -#include -#include -#include "SourceView.h" - -class SourceViewerManager : public QTabWidget -{ - Q_OBJECT -public: - explicit SourceViewerManager(QWidget* parent = 0); - -public slots: - void loadSourceFile(QString path, int line, int selection = 0); - void closeTab(int index); - void closeAllTabs(); - -signals: - void showCpu(); - -private: - QPushButton* mCloseAllTabs; -}; - -#endif // SOURCEVIEWERMANAGER_H +#ifndef SOURCEVIEWERMANAGER_H +#define SOURCEVIEWERMANAGER_H + +#include +#include +#include +#include "SourceView.h" + +class SourceViewerManager : public QTabWidget +{ + Q_OBJECT +public: + explicit SourceViewerManager(QWidget* parent = 0); + +public slots: + void loadSourceFile(QString path, int line, int selection = 0); + void closeTab(int index); + void closeAllTabs(); + +signals: + void showCpu(); + +private: + QPushButton* mCloseAllTabs; +}; + +#endif // SOURCEVIEWERMANAGER_H diff --git a/src/gui/Src/Gui/StatusLabel.cpp b/src/gui/Src/Gui/StatusLabel.cpp index c411c039..8bf34455 100644 --- a/src/gui/Src/Gui/StatusLabel.cpp +++ b/src/gui/Src/Gui/StatusLabel.cpp @@ -1,62 +1,62 @@ -#include "StatusLabel.h" -#include - -StatusLabel::StatusLabel(QStatusBar* parent) : QLabel(parent) -{ - this->setFrameStyle(QFrame::Sunken | QFrame::Panel); //sunken style - this->setStyleSheet("QLabel { background-color : #c0c0c0; }"); - this->setTextFormat(Qt::RichText); //rich text - if(parent) //the debug-status label only has a parent - { - parent->setStyleSheet("QStatusBar { background-color: #c0c0c0; } QStatusBar::item { border: none; }"); - this->setFixedHeight(parent->height()); - this->setAlignment(Qt::AlignCenter); - this->setFixedWidth(65); - connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE))); - } - else //last log message - { - connect(Bridge::getBridge(), SIGNAL(addMsgToLog(QString)), this, SLOT(logUpdate(QString))); - connect(Bridge::getBridge(), SIGNAL(addMsgToStatusBar(QString)), this, SLOT(logUpdate(QString))); - } -} - -void StatusLabel::debugStateChangedSlot(DBGSTATE state) -{ - switch(state) - { - case initialized: - this->setText("Initialized"); - this->setStyleSheet("QLabel { background-color : #c0c0c0; }"); - break; - case paused: - this->setText("Paused"); - this->setStyleSheet("QLabel { background-color : #ffff00; }"); - break; - case running: - this->setText("Running"); - this->setStyleSheet("QLabel { background-color : #c0c0c0; }"); - break; - case stopped: - this->setText("Terminated"); - this->setStyleSheet("QLabel { background-color : #c0c0c0; }"); - GuiUpdateWindowTitle(""); - break; - } - - this->repaint(); -} - -void StatusLabel::logUpdate(QString message) -{ - if(labelText.contains(QChar('\n'))) //newline - labelText = ""; - labelText += message; - //only show the last line in the status label - QStringList lineList = labelText.split(QChar('\n'), QString::SkipEmptyParts); - if(lineList.size()) - setText(Qt::convertFromPlainText(lineList[lineList.length() - 1])); - else - setText(Qt::convertFromPlainText(labelText)); - this->repaint(); -} +#include "StatusLabel.h" +#include + +StatusLabel::StatusLabel(QStatusBar* parent) : QLabel(parent) +{ + this->setFrameStyle(QFrame::Sunken | QFrame::Panel); //sunken style + this->setStyleSheet("QLabel { background-color : #c0c0c0; }"); + this->setTextFormat(Qt::RichText); //rich text + if(parent) //the debug-status label only has a parent + { + parent->setStyleSheet("QStatusBar { background-color: #c0c0c0; } QStatusBar::item { border: none; }"); + this->setFixedHeight(parent->height()); + this->setAlignment(Qt::AlignCenter); + this->setFixedWidth(65); + connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE))); + } + else //last log message + { + connect(Bridge::getBridge(), SIGNAL(addMsgToLog(QString)), this, SLOT(logUpdate(QString))); + connect(Bridge::getBridge(), SIGNAL(addMsgToStatusBar(QString)), this, SLOT(logUpdate(QString))); + } +} + +void StatusLabel::debugStateChangedSlot(DBGSTATE state) +{ + switch(state) + { + case initialized: + this->setText("Initialized"); + this->setStyleSheet("QLabel { background-color : #c0c0c0; }"); + break; + case paused: + this->setText("Paused"); + this->setStyleSheet("QLabel { background-color : #ffff00; }"); + break; + case running: + this->setText("Running"); + this->setStyleSheet("QLabel { background-color : #c0c0c0; }"); + break; + case stopped: + this->setText("Terminated"); + this->setStyleSheet("QLabel { background-color : #c0c0c0; }"); + GuiUpdateWindowTitle(""); + break; + } + + this->repaint(); +} + +void StatusLabel::logUpdate(QString message) +{ + if(labelText.contains(QChar('\n'))) //newline + labelText = ""; + labelText += message; + //only show the last line in the status label + QStringList lineList = labelText.split(QChar('\n'), QString::SkipEmptyParts); + if(lineList.size()) + setText(Qt::convertFromPlainText(lineList[lineList.length() - 1])); + else + setText(Qt::convertFromPlainText(labelText)); + this->repaint(); +} diff --git a/src/gui/Src/Gui/StatusLabel.h b/src/gui/Src/Gui/StatusLabel.h index 5c69bf37..812bbaa8 100644 --- a/src/gui/Src/Gui/StatusLabel.h +++ b/src/gui/Src/Gui/StatusLabel.h @@ -1,23 +1,23 @@ -#ifndef LABELCLASS_H -#define LABELCLASS_H - -#include -#include -#include "Bridge.h" - -class StatusLabel : public QLabel -{ - Q_OBJECT -public: - explicit StatusLabel(QStatusBar* parent = 0); - -public slots: - void debugStateChangedSlot(DBGSTATE state); - void logUpdate(QString message); - -private: - QString labelText; - -}; - -#endif // LABELCLASS_H +#ifndef LABELCLASS_H +#define LABELCLASS_H + +#include +#include +#include "Bridge.h" + +class StatusLabel : public QLabel +{ + Q_OBJECT +public: + explicit StatusLabel(QStatusBar* parent = 0); + +public slots: + void debugStateChangedSlot(DBGSTATE state); + void logUpdate(QString message); + +private: + QString labelText; + +}; + +#endif // LABELCLASS_H diff --git a/src/gui/Src/Gui/SymbolView.cpp b/src/gui/Src/Gui/SymbolView.cpp index 9addc899..a66a1d65 100644 --- a/src/gui/Src/Gui/SymbolView.cpp +++ b/src/gui/Src/Gui/SymbolView.cpp @@ -1,380 +1,380 @@ -#include "SymbolView.h" -#include "ui_SymbolView.h" -#include -#include "Configuration.h" -#include "Bridge.h" -#include "YaraRuleSelectionDialog.h" -#include "EntropyDialog.h" - -SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView) -{ - ui->setupUi(this); - - // Set main layout - mMainLayout = new QVBoxLayout; - mMainLayout->setContentsMargins(0, 0, 0, 0); - mMainLayout->addWidget(ui->mainSplitter); - setLayout(mMainLayout); - - // Create reference view - mSearchListView = new SearchListView(); - mSearchListView->mSearchStartCol = 1; - - // Create module list - mModuleList = new StdTable(); - int charwidth = mModuleList->getCharWidth(); - mModuleList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, "Base", false); - mModuleList->addColumnAt(500, "Module", true); - - // Setup symbol list - mSearchListView->mList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, "Address", true); - mSearchListView->mList->addColumnAt(charwidth * 80, "Symbol", true); - mSearchListView->mList->addColumnAt(2000, "Symbol (undecorated)", true); - - // Setup search list - mSearchListView->mSearchList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, "Address", true); - mSearchListView->mSearchList->addColumnAt(charwidth * 80, "Symbol", true); - mSearchListView->mSearchList->addColumnAt(2000, "Symbol (undecorated)", true); - - // Setup list splitter - ui->listSplitter->addWidget(mModuleList); - ui->listSplitter->addWidget(mSearchListView); -#ifdef _WIN64 - // mModuleList : mSymbolList = 40 : 100 - ui->listSplitter->setStretchFactor(0, 40); - ui->listSplitter->setStretchFactor(1, 100); -#else - // mModuleList : mSymbolList = 30 : 100 - ui->listSplitter->setStretchFactor(0, 30); - ui->listSplitter->setStretchFactor(1, 100); -#endif //_WIN64 - - // Setup log edit - ui->symbolLogEdit->setFont(mModuleList->font()); - ui->symbolLogEdit->setStyleSheet("QTextEdit { background-color: rgb(255, 251, 240) }"); - ui->symbolLogEdit->setUndoRedoEnabled(false); - ui->symbolLogEdit->setReadOnly(true); - // Log : List = 2 : 9 - ui->mainSplitter->setStretchFactor(1, 9); - ui->mainSplitter->setStretchFactor(0, 2); - - //setup context menu - setupContextMenu(); - - //Signals and slots - connect(Bridge::getBridge(), SIGNAL(repaintTableView()), this, SLOT(updateStyle())); - connect(Bridge::getBridge(), SIGNAL(addMsgToSymbolLog(QString)), this, SLOT(addMsgToSymbolLogSlot(QString))); - connect(Bridge::getBridge(), SIGNAL(clearLog()), this, SLOT(clearSymbolLogSlot())); - connect(Bridge::getBridge(), SIGNAL(clearSymbolLog()), this, SLOT(clearSymbolLogSlot())); - connect(mModuleList, SIGNAL(selectionChangedSignal(int)), this, SLOT(moduleSelectionChanged(int))); - connect(mModuleList, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(moduleContextMenu(QPoint))); - connect(mModuleList, SIGNAL(enterPressedSignal()), this, SLOT(moduleFollow())); - connect(mModuleList, SIGNAL(doubleClickedSignal()), this, SLOT(moduleFollow())); - connect(Bridge::getBridge(), SIGNAL(updateSymbolList(int, SYMBOLMODULEINFO*)), this, SLOT(updateSymbolList(int, SYMBOLMODULEINFO*))); - connect(Bridge::getBridge(), SIGNAL(setSymbolProgress(int)), ui->symbolProgress, SLOT(setValue(int))); - connect(Bridge::getBridge(), SIGNAL(symbolRefreshCurrent()), this, SLOT(symbolRefreshCurrent())); - connect(mSearchListView, SIGNAL(listContextMenuSignal(QMenu*)), this, SLOT(symbolContextMenu(QMenu*))); - connect(mSearchListView, SIGNAL(enterPressedSignal()), this, SLOT(symbolFollow())); -} - -SymbolView::~SymbolView() -{ - delete ui; -} - -void SymbolView::setupContextMenu() -{ - //Symbols - mFollowSymbolAction = new QAction("&Follow in Disassembler", this); - mFollowSymbolAction->setShortcutContext(Qt::WidgetShortcut); - mFollowSymbolAction->setShortcut(QKeySequence("enter")); - connect(mFollowSymbolAction, SIGNAL(triggered()), this, SLOT(symbolFollow())); - - mFollowSymbolDumpAction = new QAction("Follow in &Dump", this); - connect(mFollowSymbolDumpAction, SIGNAL(triggered()), this, SLOT(symbolFollowDump())); - - mToggleBreakpoint = new QAction("Toggle Breakpoint", this); - mToggleBreakpoint->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mToggleBreakpoint); - mSearchListView->mList->addAction(mToggleBreakpoint); - mSearchListView->mSearchList->addAction(mToggleBreakpoint); - connect(mToggleBreakpoint, SIGNAL(triggered()), this, SLOT(toggleBreakpoint())); - - mToggleBookmark = new QAction("Toggle Bookmark", this); - mToggleBookmark->setShortcutContext(Qt::WidgetShortcut); - this->addAction(mToggleBookmark); - mSearchListView->mList->addAction(mToggleBookmark); - mSearchListView->mSearchList->addAction(mToggleBookmark); - connect(mToggleBookmark, SIGNAL(triggered()), this, SLOT(toggleBookmark())); - - //Modules - mFollowModuleAction = new QAction("&Follow in Disassembler", this); - mFollowModuleAction->setShortcutContext(Qt::WidgetShortcut); - mFollowModuleAction->setShortcut(QKeySequence("enter")); - connect(mFollowModuleAction, SIGNAL(triggered()), this, SLOT(moduleFollow())); - - mFollowModuleEntryAction = new QAction("Follow &Entry Point in Disassembler", this); - connect(mFollowModuleEntryAction, SIGNAL(triggered()), this, SLOT(moduleEntryFollow())); - - mDownloadSymbolsAction = new QAction("&Download Symbols for This Module", this); - connect(mDownloadSymbolsAction, SIGNAL(triggered()), this, SLOT(moduleDownloadSymbols())); - - mDownloadAllSymbolsAction = new QAction("Download Symbols for &All Modules", this); - connect(mDownloadAllSymbolsAction, SIGNAL(triggered()), this, SLOT(moduleDownloadAllSymbols())); - - mCopyPathAction = new QAction("Copy File &Path", this); - connect(mCopyPathAction, SIGNAL(triggered()), this, SLOT(moduleCopyPath())); - - mYaraAction = new QAction(QIcon(":/icons/images/yara.png"), "&Yara...", this); - connect(mYaraAction, SIGNAL(triggered()), this, SLOT(moduleYara())); - - mEntropyAction = new QAction(QIcon(":/icons/images/entropy.png"), "Entropy...", this); - connect(mEntropyAction, SIGNAL(triggered()), this, SLOT(moduleEntropy())); - - //Shortcuts - refreshShortcutsSlot(); - connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); -} - -void SymbolView::refreshShortcutsSlot() -{ - mToggleBreakpoint->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); - mToggleBookmark->setShortcut(ConfigShortcut("ActionToggleBookmark")); -} - -void SymbolView::updateStyle() -{ - ui->symbolLogEdit->setStyleSheet(QString("QTextEdit { color: %1; background-color: %2 }").arg(ConfigColor("AbstractTableViewTextColor").name(), ConfigColor("AbstractTableViewBackgroundColor").name())); -} - -void SymbolView::addMsgToSymbolLogSlot(QString msg) -{ - ui->symbolLogEdit->moveCursor(QTextCursor::End); - ui->symbolLogEdit->insertPlainText(msg); -} - -void SymbolView::clearSymbolLogSlot() -{ - ui->symbolLogEdit->clear(); -} - -void SymbolView::cbSymbolEnum(SYMBOLINFO* symbol, void* user) -{ - StdTable* symbolList = (StdTable*)user; - dsint index = symbolList->getRowCount(); - symbolList->setRowCount(index + 1); - symbolList->setCellContent(index, 0, QString("%1").arg(symbol->addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper()); - if(symbol->decoratedSymbol) - { - symbolList->setCellContent(index, 1, symbol->decoratedSymbol); - BridgeFree(symbol->decoratedSymbol); - } - if(symbol->undecoratedSymbol) - { - symbolList->setCellContent(index, 2, symbol->undecoratedSymbol); - BridgeFree(symbol->undecoratedSymbol); - } -} - -void SymbolView::moduleSelectionChanged(int index) -{ - QString mod = mModuleList->getCellContent(index, 1); - if(!mModuleBaseList.count(mod)) - return; - mSearchListView->mList->setRowCount(0); - DbgSymbolEnum(mModuleBaseList[mod], cbSymbolEnum, mSearchListView->mList); - mSearchListView->mList->reloadData(); - mSearchListView->mList->setSingleSelection(0); - mSearchListView->mList->setTableOffset(0); - mSearchListView->mList->setFocus(); - mSearchListView->mSearchBox->setText(""); -} - -void SymbolView::updateSymbolList(int module_count, SYMBOLMODULEINFO* modules) -{ - mModuleList->setRowCount(module_count); - if(!module_count) - { - mSearchListView->mList->setRowCount(0); - mSearchListView->mList->setSingleSelection(0); - mModuleList->setSingleSelection(0); - } - mModuleBaseList.clear(); - for(int i = 0; i < module_count; i++) - { - mModuleBaseList.insert(modules[i].name, modules[i].base); - mModuleList->setCellContent(i, 0, QString("%1").arg(modules[i].base, sizeof(dsint) * 2, 16, QChar('0')).toUpper()); - mModuleList->setCellContent(i, 1, modules[i].name); - } - mModuleList->reloadData(); - if(modules) - BridgeFree(modules); -} - -void SymbolView::symbolContextMenu(QMenu* wMenu) -{ - if(!mSearchListView->mCurList->getRowCount()) - return; - wMenu->addAction(mFollowSymbolAction); - wMenu->addAction(mFollowSymbolDumpAction); - wMenu->addSeparator(); - wMenu->addAction(mToggleBreakpoint); - wMenu->addAction(mToggleBookmark); -} - -void SymbolView::symbolRefreshCurrent() -{ - mModuleList->setSingleSelection(mModuleList->getInitialSelection()); -} - -void SymbolView::symbolFollow() -{ - DbgCmdExecDirect(QString("disasm " + mSearchListView->mCurList->getCellContent(mSearchListView->mCurList->getInitialSelection(), 0)).toUtf8().constData()); - emit showCpu(); -} - -void SymbolView::symbolFollowDump() -{ - DbgCmdExecDirect(QString("dump " + mSearchListView->mCurList->getCellContent(mSearchListView->mCurList->getInitialSelection(), 0)).toUtf8().constData()); - emit showCpu(); -} - -void SymbolView::moduleContextMenu(const QPoint & pos) -{ - if(!DbgIsDebugging()) - return; - QMenu* wMenu = new QMenu(this); //create context menu - wMenu->addAction(mFollowModuleAction); - wMenu->addAction(mFollowModuleEntryAction); - wMenu->addAction(mDownloadSymbolsAction); - wMenu->addAction(mDownloadAllSymbolsAction); - dsint modbase = DbgValFromString(mModuleList->getCellContent(mModuleList->getInitialSelection(), 0).toUtf8().constData()); - char szModPath[MAX_PATH] = ""; - if(DbgFunctions()->ModPathFromAddr(modbase, szModPath, _countof(szModPath))) - wMenu->addAction(mCopyPathAction); - wMenu->addAction(mYaraAction); - wMenu->addAction(mEntropyAction); - QMenu wCopyMenu("&Copy", this); - mModuleList->setupCopyMenu(&wCopyMenu); - if(wCopyMenu.actions().length()) - { - wMenu->addSeparator(); - wMenu->addMenu(&wCopyMenu); - } - wMenu->exec(mapToGlobal(pos)); //execute context menu -} - -void SymbolView::moduleFollow() -{ - DbgCmdExecDirect(QString("disasm " + mModuleList->getCellContent(mModuleList->getInitialSelection(), 0) + "+1000").toUtf8().constData()); - emit showCpu(); -} - -void SymbolView::moduleEntryFollow() -{ - DbgCmdExecDirect(QString("disasm " + mModuleList->getCellContent(mModuleList->getInitialSelection(), 1) + "?entry").toUtf8().constData()); - emit showCpu(); -} - -void SymbolView::moduleCopyPath() -{ - dsint modbase = DbgValFromString(mModuleList->getCellContent(mModuleList->getInitialSelection(), 0).toUtf8().constData()); - char szModPath[MAX_PATH] = ""; - if(DbgFunctions()->ModPathFromAddr(modbase, szModPath, _countof(szModPath))) - Bridge::CopyToClipboard(szModPath); -} - -void SymbolView::moduleYara() -{ - QString modname = mModuleList->getCellContent(mModuleList->getInitialSelection(), 1); - YaraRuleSelectionDialog yaraDialog(this); - if(yaraDialog.exec() == QDialog::Accepted) - { - DbgCmdExec(QString("yara \"%0\",\"%1\"").arg(yaraDialog.getSelectedFile()).arg(modname).toUtf8().constData()); - emit showReferences(); - } -} - -void SymbolView::moduleDownloadSymbols() -{ - DbgCmdExec(QString("symdownload " + mModuleList->getCellContent(mModuleList->getInitialSelection(), 1)).toUtf8().constData()); -} - -void SymbolView::moduleDownloadAllSymbols() -{ - DbgCmdExec("symdownload"); -} - -void SymbolView::toggleBreakpoint() -{ - if(!DbgIsDebugging()) - return; - - if(!mSearchListView->mCurList->getRowCount()) - return; - QString addrText = mSearchListView->mCurList->getCellContent(mSearchListView->mCurList->getInitialSelection(), 0); - duint wVA; - if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &wVA)) - return; - - if(!DbgMemIsValidReadPtr(wVA)) - return; - - BPXTYPE wBpType = DbgGetBpxTypeAt(wVA); - QString wCmd; - - if((wBpType & bp_normal) == bp_normal) - { - wCmd = "bc " + QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - else - { - wCmd = "bp " + QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - - DbgCmdExec(wCmd.toUtf8().constData()); -} - -void SymbolView::toggleBookmark() -{ - if(!DbgIsDebugging()) - return; - - if(!mSearchListView->mCurList->getRowCount()) - return; - QString addrText = mSearchListView->mCurList->getCellContent(mSearchListView->mCurList->getInitialSelection(), 0); - duint wVA; - if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &wVA)) - return; - if(!DbgMemIsValidReadPtr(wVA)) - return; - - bool result; - if(DbgGetBookmarkAt(wVA)) - result = DbgSetBookmarkAt(wVA, false); - else - result = DbgSetBookmarkAt(wVA, true); - if(!result) - { - QMessageBox msg(QMessageBox::Critical, "Error!", "DbgSetBookmarkAt failed!"); - msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - } - GuiUpdateAllViews(); -} - -void SymbolView::moduleEntropy() -{ - dsint modbase = DbgValFromString(mModuleList->getCellContent(mModuleList->getInitialSelection(), 0).toUtf8().constData()); - char szModPath[MAX_PATH] = ""; - if(DbgFunctions()->ModPathFromAddr(modbase, szModPath, _countof(szModPath))) - { - EntropyDialog entropyDialog(this); - entropyDialog.setWindowTitle(QString("Entropy (%1)").arg(mModuleList->getCellContent(mModuleList->getInitialSelection(), 1))); - entropyDialog.show(); - entropyDialog.GraphFile(QString(szModPath)); - entropyDialog.exec(); - } -} +#include "SymbolView.h" +#include "ui_SymbolView.h" +#include +#include "Configuration.h" +#include "Bridge.h" +#include "YaraRuleSelectionDialog.h" +#include "EntropyDialog.h" + +SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView) +{ + ui->setupUi(this); + + // Set main layout + mMainLayout = new QVBoxLayout; + mMainLayout->setContentsMargins(0, 0, 0, 0); + mMainLayout->addWidget(ui->mainSplitter); + setLayout(mMainLayout); + + // Create reference view + mSearchListView = new SearchListView(); + mSearchListView->mSearchStartCol = 1; + + // Create module list + mModuleList = new StdTable(); + int charwidth = mModuleList->getCharWidth(); + mModuleList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, "Base", false); + mModuleList->addColumnAt(500, "Module", true); + + // Setup symbol list + mSearchListView->mList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, "Address", true); + mSearchListView->mList->addColumnAt(charwidth * 80, "Symbol", true); + mSearchListView->mList->addColumnAt(2000, "Symbol (undecorated)", true); + + // Setup search list + mSearchListView->mSearchList->addColumnAt(charwidth * 2 * sizeof(dsint) + 8, "Address", true); + mSearchListView->mSearchList->addColumnAt(charwidth * 80, "Symbol", true); + mSearchListView->mSearchList->addColumnAt(2000, "Symbol (undecorated)", true); + + // Setup list splitter + ui->listSplitter->addWidget(mModuleList); + ui->listSplitter->addWidget(mSearchListView); +#ifdef _WIN64 + // mModuleList : mSymbolList = 40 : 100 + ui->listSplitter->setStretchFactor(0, 40); + ui->listSplitter->setStretchFactor(1, 100); +#else + // mModuleList : mSymbolList = 30 : 100 + ui->listSplitter->setStretchFactor(0, 30); + ui->listSplitter->setStretchFactor(1, 100); +#endif //_WIN64 + + // Setup log edit + ui->symbolLogEdit->setFont(mModuleList->font()); + ui->symbolLogEdit->setStyleSheet("QTextEdit { background-color: rgb(255, 251, 240) }"); + ui->symbolLogEdit->setUndoRedoEnabled(false); + ui->symbolLogEdit->setReadOnly(true); + // Log : List = 2 : 9 + ui->mainSplitter->setStretchFactor(1, 9); + ui->mainSplitter->setStretchFactor(0, 2); + + //setup context menu + setupContextMenu(); + + //Signals and slots + connect(Bridge::getBridge(), SIGNAL(repaintTableView()), this, SLOT(updateStyle())); + connect(Bridge::getBridge(), SIGNAL(addMsgToSymbolLog(QString)), this, SLOT(addMsgToSymbolLogSlot(QString))); + connect(Bridge::getBridge(), SIGNAL(clearLog()), this, SLOT(clearSymbolLogSlot())); + connect(Bridge::getBridge(), SIGNAL(clearSymbolLog()), this, SLOT(clearSymbolLogSlot())); + connect(mModuleList, SIGNAL(selectionChangedSignal(int)), this, SLOT(moduleSelectionChanged(int))); + connect(mModuleList, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(moduleContextMenu(QPoint))); + connect(mModuleList, SIGNAL(enterPressedSignal()), this, SLOT(moduleFollow())); + connect(mModuleList, SIGNAL(doubleClickedSignal()), this, SLOT(moduleFollow())); + connect(Bridge::getBridge(), SIGNAL(updateSymbolList(int, SYMBOLMODULEINFO*)), this, SLOT(updateSymbolList(int, SYMBOLMODULEINFO*))); + connect(Bridge::getBridge(), SIGNAL(setSymbolProgress(int)), ui->symbolProgress, SLOT(setValue(int))); + connect(Bridge::getBridge(), SIGNAL(symbolRefreshCurrent()), this, SLOT(symbolRefreshCurrent())); + connect(mSearchListView, SIGNAL(listContextMenuSignal(QMenu*)), this, SLOT(symbolContextMenu(QMenu*))); + connect(mSearchListView, SIGNAL(enterPressedSignal()), this, SLOT(symbolFollow())); +} + +SymbolView::~SymbolView() +{ + delete ui; +} + +void SymbolView::setupContextMenu() +{ + //Symbols + mFollowSymbolAction = new QAction("&Follow in Disassembler", this); + mFollowSymbolAction->setShortcutContext(Qt::WidgetShortcut); + mFollowSymbolAction->setShortcut(QKeySequence("enter")); + connect(mFollowSymbolAction, SIGNAL(triggered()), this, SLOT(symbolFollow())); + + mFollowSymbolDumpAction = new QAction("Follow in &Dump", this); + connect(mFollowSymbolDumpAction, SIGNAL(triggered()), this, SLOT(symbolFollowDump())); + + mToggleBreakpoint = new QAction("Toggle Breakpoint", this); + mToggleBreakpoint->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mToggleBreakpoint); + mSearchListView->mList->addAction(mToggleBreakpoint); + mSearchListView->mSearchList->addAction(mToggleBreakpoint); + connect(mToggleBreakpoint, SIGNAL(triggered()), this, SLOT(toggleBreakpoint())); + + mToggleBookmark = new QAction("Toggle Bookmark", this); + mToggleBookmark->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mToggleBookmark); + mSearchListView->mList->addAction(mToggleBookmark); + mSearchListView->mSearchList->addAction(mToggleBookmark); + connect(mToggleBookmark, SIGNAL(triggered()), this, SLOT(toggleBookmark())); + + //Modules + mFollowModuleAction = new QAction("&Follow in Disassembler", this); + mFollowModuleAction->setShortcutContext(Qt::WidgetShortcut); + mFollowModuleAction->setShortcut(QKeySequence("enter")); + connect(mFollowModuleAction, SIGNAL(triggered()), this, SLOT(moduleFollow())); + + mFollowModuleEntryAction = new QAction("Follow &Entry Point in Disassembler", this); + connect(mFollowModuleEntryAction, SIGNAL(triggered()), this, SLOT(moduleEntryFollow())); + + mDownloadSymbolsAction = new QAction("&Download Symbols for This Module", this); + connect(mDownloadSymbolsAction, SIGNAL(triggered()), this, SLOT(moduleDownloadSymbols())); + + mDownloadAllSymbolsAction = new QAction("Download Symbols for &All Modules", this); + connect(mDownloadAllSymbolsAction, SIGNAL(triggered()), this, SLOT(moduleDownloadAllSymbols())); + + mCopyPathAction = new QAction("Copy File &Path", this); + connect(mCopyPathAction, SIGNAL(triggered()), this, SLOT(moduleCopyPath())); + + mYaraAction = new QAction(QIcon(":/icons/images/yara.png"), "&Yara...", this); + connect(mYaraAction, SIGNAL(triggered()), this, SLOT(moduleYara())); + + mEntropyAction = new QAction(QIcon(":/icons/images/entropy.png"), "Entropy...", this); + connect(mEntropyAction, SIGNAL(triggered()), this, SLOT(moduleEntropy())); + + //Shortcuts + refreshShortcutsSlot(); + connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot())); +} + +void SymbolView::refreshShortcutsSlot() +{ + mToggleBreakpoint->setShortcut(ConfigShortcut("ActionToggleBreakpoint")); + mToggleBookmark->setShortcut(ConfigShortcut("ActionToggleBookmark")); +} + +void SymbolView::updateStyle() +{ + ui->symbolLogEdit->setStyleSheet(QString("QTextEdit { color: %1; background-color: %2 }").arg(ConfigColor("AbstractTableViewTextColor").name(), ConfigColor("AbstractTableViewBackgroundColor").name())); +} + +void SymbolView::addMsgToSymbolLogSlot(QString msg) +{ + ui->symbolLogEdit->moveCursor(QTextCursor::End); + ui->symbolLogEdit->insertPlainText(msg); +} + +void SymbolView::clearSymbolLogSlot() +{ + ui->symbolLogEdit->clear(); +} + +void SymbolView::cbSymbolEnum(SYMBOLINFO* symbol, void* user) +{ + StdTable* symbolList = (StdTable*)user; + dsint index = symbolList->getRowCount(); + symbolList->setRowCount(index + 1); + symbolList->setCellContent(index, 0, QString("%1").arg(symbol->addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper()); + if(symbol->decoratedSymbol) + { + symbolList->setCellContent(index, 1, symbol->decoratedSymbol); + BridgeFree(symbol->decoratedSymbol); + } + if(symbol->undecoratedSymbol) + { + symbolList->setCellContent(index, 2, symbol->undecoratedSymbol); + BridgeFree(symbol->undecoratedSymbol); + } +} + +void SymbolView::moduleSelectionChanged(int index) +{ + QString mod = mModuleList->getCellContent(index, 1); + if(!mModuleBaseList.count(mod)) + return; + mSearchListView->mList->setRowCount(0); + DbgSymbolEnum(mModuleBaseList[mod], cbSymbolEnum, mSearchListView->mList); + mSearchListView->mList->reloadData(); + mSearchListView->mList->setSingleSelection(0); + mSearchListView->mList->setTableOffset(0); + mSearchListView->mList->setFocus(); + mSearchListView->mSearchBox->setText(""); +} + +void SymbolView::updateSymbolList(int module_count, SYMBOLMODULEINFO* modules) +{ + mModuleList->setRowCount(module_count); + if(!module_count) + { + mSearchListView->mList->setRowCount(0); + mSearchListView->mList->setSingleSelection(0); + mModuleList->setSingleSelection(0); + } + mModuleBaseList.clear(); + for(int i = 0; i < module_count; i++) + { + mModuleBaseList.insert(modules[i].name, modules[i].base); + mModuleList->setCellContent(i, 0, QString("%1").arg(modules[i].base, sizeof(dsint) * 2, 16, QChar('0')).toUpper()); + mModuleList->setCellContent(i, 1, modules[i].name); + } + mModuleList->reloadData(); + if(modules) + BridgeFree(modules); +} + +void SymbolView::symbolContextMenu(QMenu* wMenu) +{ + if(!mSearchListView->mCurList->getRowCount()) + return; + wMenu->addAction(mFollowSymbolAction); + wMenu->addAction(mFollowSymbolDumpAction); + wMenu->addSeparator(); + wMenu->addAction(mToggleBreakpoint); + wMenu->addAction(mToggleBookmark); +} + +void SymbolView::symbolRefreshCurrent() +{ + mModuleList->setSingleSelection(mModuleList->getInitialSelection()); +} + +void SymbolView::symbolFollow() +{ + DbgCmdExecDirect(QString("disasm " + mSearchListView->mCurList->getCellContent(mSearchListView->mCurList->getInitialSelection(), 0)).toUtf8().constData()); + emit showCpu(); +} + +void SymbolView::symbolFollowDump() +{ + DbgCmdExecDirect(QString("dump " + mSearchListView->mCurList->getCellContent(mSearchListView->mCurList->getInitialSelection(), 0)).toUtf8().constData()); + emit showCpu(); +} + +void SymbolView::moduleContextMenu(const QPoint & pos) +{ + if(!DbgIsDebugging()) + return; + QMenu* wMenu = new QMenu(this); //create context menu + wMenu->addAction(mFollowModuleAction); + wMenu->addAction(mFollowModuleEntryAction); + wMenu->addAction(mDownloadSymbolsAction); + wMenu->addAction(mDownloadAllSymbolsAction); + dsint modbase = DbgValFromString(mModuleList->getCellContent(mModuleList->getInitialSelection(), 0).toUtf8().constData()); + char szModPath[MAX_PATH] = ""; + if(DbgFunctions()->ModPathFromAddr(modbase, szModPath, _countof(szModPath))) + wMenu->addAction(mCopyPathAction); + wMenu->addAction(mYaraAction); + wMenu->addAction(mEntropyAction); + QMenu wCopyMenu("&Copy", this); + mModuleList->setupCopyMenu(&wCopyMenu); + if(wCopyMenu.actions().length()) + { + wMenu->addSeparator(); + wMenu->addMenu(&wCopyMenu); + } + wMenu->exec(mapToGlobal(pos)); //execute context menu +} + +void SymbolView::moduleFollow() +{ + DbgCmdExecDirect(QString("disasm " + mModuleList->getCellContent(mModuleList->getInitialSelection(), 0) + "+1000").toUtf8().constData()); + emit showCpu(); +} + +void SymbolView::moduleEntryFollow() +{ + DbgCmdExecDirect(QString("disasm " + mModuleList->getCellContent(mModuleList->getInitialSelection(), 1) + "?entry").toUtf8().constData()); + emit showCpu(); +} + +void SymbolView::moduleCopyPath() +{ + dsint modbase = DbgValFromString(mModuleList->getCellContent(mModuleList->getInitialSelection(), 0).toUtf8().constData()); + char szModPath[MAX_PATH] = ""; + if(DbgFunctions()->ModPathFromAddr(modbase, szModPath, _countof(szModPath))) + Bridge::CopyToClipboard(szModPath); +} + +void SymbolView::moduleYara() +{ + QString modname = mModuleList->getCellContent(mModuleList->getInitialSelection(), 1); + YaraRuleSelectionDialog yaraDialog(this); + if(yaraDialog.exec() == QDialog::Accepted) + { + DbgCmdExec(QString("yara \"%0\",\"%1\"").arg(yaraDialog.getSelectedFile()).arg(modname).toUtf8().constData()); + emit showReferences(); + } +} + +void SymbolView::moduleDownloadSymbols() +{ + DbgCmdExec(QString("symdownload " + mModuleList->getCellContent(mModuleList->getInitialSelection(), 1)).toUtf8().constData()); +} + +void SymbolView::moduleDownloadAllSymbols() +{ + DbgCmdExec("symdownload"); +} + +void SymbolView::toggleBreakpoint() +{ + if(!DbgIsDebugging()) + return; + + if(!mSearchListView->mCurList->getRowCount()) + return; + QString addrText = mSearchListView->mCurList->getCellContent(mSearchListView->mCurList->getInitialSelection(), 0); + duint wVA; + if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &wVA)) + return; + + if(!DbgMemIsValidReadPtr(wVA)) + return; + + BPXTYPE wBpType = DbgGetBpxTypeAt(wVA); + QString wCmd; + + if((wBpType & bp_normal) == bp_normal) + { + wCmd = "bc " + QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + else + { + wCmd = "bp " + QString("%1").arg(wVA, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + + DbgCmdExec(wCmd.toUtf8().constData()); +} + +void SymbolView::toggleBookmark() +{ + if(!DbgIsDebugging()) + return; + + if(!mSearchListView->mCurList->getRowCount()) + return; + QString addrText = mSearchListView->mCurList->getCellContent(mSearchListView->mCurList->getInitialSelection(), 0); + duint wVA; + if(!DbgFunctions()->ValFromString(addrText.toUtf8().constData(), &wVA)) + return; + if(!DbgMemIsValidReadPtr(wVA)) + return; + + bool result; + if(DbgGetBookmarkAt(wVA)) + result = DbgSetBookmarkAt(wVA, false); + else + result = DbgSetBookmarkAt(wVA, true); + if(!result) + { + QMessageBox msg(QMessageBox::Critical, "Error!", "DbgSetBookmarkAt failed!"); + msg.setWindowIcon(QIcon(":/icons/images/compile-error.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + } + GuiUpdateAllViews(); +} + +void SymbolView::moduleEntropy() +{ + dsint modbase = DbgValFromString(mModuleList->getCellContent(mModuleList->getInitialSelection(), 0).toUtf8().constData()); + char szModPath[MAX_PATH] = ""; + if(DbgFunctions()->ModPathFromAddr(modbase, szModPath, _countof(szModPath))) + { + EntropyDialog entropyDialog(this); + entropyDialog.setWindowTitle(QString("Entropy (%1)").arg(mModuleList->getCellContent(mModuleList->getInitialSelection(), 1))); + entropyDialog.show(); + entropyDialog.GraphFile(QString(szModPath)); + entropyDialog.exec(); + } +} diff --git a/src/gui/Src/Gui/SymbolView.h b/src/gui/Src/Gui/SymbolView.h index e839eb19..b37ccf24 100644 --- a/src/gui/Src/Gui/SymbolView.h +++ b/src/gui/Src/Gui/SymbolView.h @@ -1,70 +1,70 @@ -#ifndef SYMBOLVIEW_H -#define SYMBOLVIEW_H - -#include -#include "Bridge.h" - -namespace Ui -{ -class SymbolView; -} - -class SymbolView : public QWidget -{ - Q_OBJECT - -public: - explicit SymbolView(QWidget* parent = 0); - ~SymbolView(); - void setupContextMenu(); - -private slots: - void updateStyle(); - void addMsgToSymbolLogSlot(QString msg); - void clearSymbolLogSlot(); - void moduleSelectionChanged(int index); - void updateSymbolList(int module_count, SYMBOLMODULEINFO* modules); - void symbolFollow(); - void symbolFollowDump(); - void symbolContextMenu(QMenu* wMenu); - void symbolRefreshCurrent(); - void moduleContextMenu(const QPoint & pos); - void moduleFollow(); - void moduleEntryFollow(); - void moduleDownloadSymbols(); - void moduleDownloadAllSymbols(); - void moduleCopyPath(); - void moduleYara(); - void toggleBreakpoint(); - void toggleBookmark(); - void refreshShortcutsSlot(); - void moduleEntropy(); - -signals: - void showCpu(); - void showReferences(); - -private: - Ui::SymbolView* ui; - QVBoxLayout* mMainLayout; - QVBoxLayout* mSymbolLayout; - QWidget* mSymbolPlaceHolder; - SearchListView* mSearchListView; - StdTable* mModuleList; - QMap mModuleBaseList; - QAction* mFollowSymbolAction; - QAction* mFollowSymbolDumpAction; - QAction* mToggleBreakpoint; - QAction* mToggleBookmark; - QAction* mFollowModuleAction; - QAction* mFollowModuleEntryAction; - QAction* mDownloadSymbolsAction; - QAction* mDownloadAllSymbolsAction; - QAction* mCopyPathAction; - QAction* mYaraAction; - QAction* mEntropyAction; - - static void cbSymbolEnum(SYMBOLINFO* symbol, void* user); -}; - -#endif // SYMBOLVIEW_H +#ifndef SYMBOLVIEW_H +#define SYMBOLVIEW_H + +#include +#include "Bridge.h" + +namespace Ui +{ +class SymbolView; +} + +class SymbolView : public QWidget +{ + Q_OBJECT + +public: + explicit SymbolView(QWidget* parent = 0); + ~SymbolView(); + void setupContextMenu(); + +private slots: + void updateStyle(); + void addMsgToSymbolLogSlot(QString msg); + void clearSymbolLogSlot(); + void moduleSelectionChanged(int index); + void updateSymbolList(int module_count, SYMBOLMODULEINFO* modules); + void symbolFollow(); + void symbolFollowDump(); + void symbolContextMenu(QMenu* wMenu); + void symbolRefreshCurrent(); + void moduleContextMenu(const QPoint & pos); + void moduleFollow(); + void moduleEntryFollow(); + void moduleDownloadSymbols(); + void moduleDownloadAllSymbols(); + void moduleCopyPath(); + void moduleYara(); + void toggleBreakpoint(); + void toggleBookmark(); + void refreshShortcutsSlot(); + void moduleEntropy(); + +signals: + void showCpu(); + void showReferences(); + +private: + Ui::SymbolView* ui; + QVBoxLayout* mMainLayout; + QVBoxLayout* mSymbolLayout; + QWidget* mSymbolPlaceHolder; + SearchListView* mSearchListView; + StdTable* mModuleList; + QMap mModuleBaseList; + QAction* mFollowSymbolAction; + QAction* mFollowSymbolDumpAction; + QAction* mToggleBreakpoint; + QAction* mToggleBookmark; + QAction* mFollowModuleAction; + QAction* mFollowModuleEntryAction; + QAction* mDownloadSymbolsAction; + QAction* mDownloadAllSymbolsAction; + QAction* mCopyPathAction; + QAction* mYaraAction; + QAction* mEntropyAction; + + static void cbSymbolEnum(SYMBOLINFO* symbol, void* user); +}; + +#endif // SYMBOLVIEW_H diff --git a/src/gui/Src/Gui/TabBar.cpp b/src/gui/Src/Gui/TabBar.cpp index 246ef281..c43df9d3 100644 --- a/src/gui/Src/Gui/TabBar.cpp +++ b/src/gui/Src/Gui/TabBar.cpp @@ -1,55 +1,55 @@ -// Qt includes -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tabbar.h" -#include "tabwidget.h" - -////////////////////////////////////////////////////////////// -// Default Constructor -////////////////////////////////////////////////////////////// -MHTabBar::MHTabBar(QWidget* parent, bool allowDetach, bool allowDelete) : QTabBar(parent) -{ - mAllowDetach = allowDetach; - mAllowDelete = allowDelete; - setAcceptDrops(true); - setElideMode(Qt::ElideRight); - setSelectionBehaviorOnRemove(QTabBar::SelectLeftTab); - setMovable(true); -} - -////////////////////////////////////////////////////////////// -// Default Destructor -////////////////////////////////////////////////////////////// -MHTabBar::~MHTabBar(void) -{ -} - -void MHTabBar::contextMenuEvent(QContextMenuEvent* event) -{ - if(!mAllowDetach && !mAllowDelete) - return; - QMenu wMenu(this); - QAction wDetach("&Detach", this); - if(mAllowDetach) - wMenu.addAction(&wDetach); - QAction wDelete("&Delete", this); - if(mAllowDelete) - wMenu.addAction(&wDelete); - QAction* executed = wMenu.exec(event->globalPos()); - if(executed == &wDetach) - { - QPoint p(0, 0); - OnDetachTab((int)tabAt(event->pos()), p); - } - else if(executed == &wDelete) - { - OnDeleteTab((int)tabAt(event->pos())); - } -} +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tabbar.h" +#include "tabwidget.h" + +////////////////////////////////////////////////////////////// +// Default Constructor +////////////////////////////////////////////////////////////// +MHTabBar::MHTabBar(QWidget* parent, bool allowDetach, bool allowDelete) : QTabBar(parent) +{ + mAllowDetach = allowDetach; + mAllowDelete = allowDelete; + setAcceptDrops(true); + setElideMode(Qt::ElideRight); + setSelectionBehaviorOnRemove(QTabBar::SelectLeftTab); + setMovable(true); +} + +////////////////////////////////////////////////////////////// +// Default Destructor +////////////////////////////////////////////////////////////// +MHTabBar::~MHTabBar(void) +{ +} + +void MHTabBar::contextMenuEvent(QContextMenuEvent* event) +{ + if(!mAllowDetach && !mAllowDelete) + return; + QMenu wMenu(this); + QAction wDetach("&Detach", this); + if(mAllowDetach) + wMenu.addAction(&wDetach); + QAction wDelete("&Delete", this); + if(mAllowDelete) + wMenu.addAction(&wDelete); + QAction* executed = wMenu.exec(event->globalPos()); + if(executed == &wDetach) + { + QPoint p(0, 0); + OnDetachTab((int)tabAt(event->pos()), p); + } + else if(executed == &wDelete) + { + OnDeleteTab((int)tabAt(event->pos())); + } +} diff --git a/src/gui/Src/Gui/TabBar.h b/src/gui/Src/Gui/TabBar.h index 87ab6cfe..7f280d23 100644 --- a/src/gui/Src/Gui/TabBar.h +++ b/src/gui/Src/Gui/TabBar.h @@ -1,41 +1,41 @@ -#ifndef __MHTABBAR_H__ -#define __MHTABBAR_H__ - -// Qt includes -#include -#include -#include - -// Qt forward class definitions -class MHTabBar; -class QMainWindow; - -////////////////////////////////////////////////////////////////////////////// -// Summary: -// MHTabBar implements the a Tab Bar with detach functionality. -////////////////////////////////////////////////////////////////////////////// -class MHTabBar: public QTabBar -{ - Q_OBJECT - -public: - MHTabBar(QWidget* parent, bool allowDetach, bool allowDelete); - ~MHTabBar(void); - -protected: - void contextMenuEvent(QContextMenuEvent* event); - -signals: - // Detach Tab - void OnDetachTab(int index, QPoint & dropPoint); - // Move Tab - void OnMoveTab(int fromIndex, int toIndex); - // Delete Tab - void OnDeleteTab(int index); - -private: - bool mAllowDetach; - bool mAllowDelete; -}; - -#endif // __MHTABBAR_H__ +#ifndef __MHTABBAR_H__ +#define __MHTABBAR_H__ + +// Qt includes +#include +#include +#include + +// Qt forward class definitions +class MHTabBar; +class QMainWindow; + +////////////////////////////////////////////////////////////////////////////// +// Summary: +// MHTabBar implements the a Tab Bar with detach functionality. +////////////////////////////////////////////////////////////////////////////// +class MHTabBar: public QTabBar +{ + Q_OBJECT + +public: + MHTabBar(QWidget* parent, bool allowDetach, bool allowDelete); + ~MHTabBar(void); + +protected: + void contextMenuEvent(QContextMenuEvent* event); + +signals: + // Detach Tab + void OnDetachTab(int index, QPoint & dropPoint); + // Move Tab + void OnMoveTab(int fromIndex, int toIndex); + // Delete Tab + void OnDeleteTab(int index); + +private: + bool mAllowDetach; + bool mAllowDelete; +}; + +#endif // __MHTABBAR_H__ diff --git a/src/gui/Src/Gui/TabWidget.cpp b/src/gui/Src/Gui/TabWidget.cpp index 7893099e..7179ee17 100644 --- a/src/gui/Src/Gui/TabWidget.cpp +++ b/src/gui/Src/Gui/TabWidget.cpp @@ -1,168 +1,168 @@ -// Qt includes -#include "tabbar.h" -#include "tabwidget.h" - -////////////////////////////////////////////////////////////// -// Default Constructor -////////////////////////////////////////////////////////////// -MHTabWidget::MHTabWidget(QWidget* parent, bool allowDetach, bool allowDelete) : QTabWidget(parent) -{ - m_tabBar = new MHTabBar(this, allowDetach, allowDelete); - connect(m_tabBar, SIGNAL(OnDetachTab(int, QPoint &)), this, SLOT(DetachTab(int, QPoint &))); - connect(m_tabBar, SIGNAL(OnMoveTab(int, int)), this, SLOT(MoveTab(int, int))); - connect(m_tabBar, SIGNAL(OnDeleteTab(int)), this, SLOT(DeleteTab(int))); - - setTabBar(m_tabBar); - setMovable(true); - - m_Windows.clear(); -} - -////////////////////////////////////////////////////////////// -// Default Destructor -////////////////////////////////////////////////////////////// -MHTabWidget::~MHTabWidget(void) -{ - disconnect(m_tabBar, SIGNAL(OnMoveTab(int, int)), this, SLOT(MoveTab(int, int))); - disconnect(m_tabBar, SIGNAL(OnDetachTab(int, QPoint &)), this, SLOT(DetachTab(int, QPoint &))); - disconnect(m_tabBar, SIGNAL(OnDeleteTab(int)), this, SLOT(DeleteTab(int))); - delete m_tabBar; -} - -QWidget* MHTabWidget::widget(int index) const -{ - int baseCount = QTabWidget::count(); - - // Check if it's just a normal tab - if(index < baseCount) - return QTabWidget::widget(index); - - // Otherwise it's going to be a window - return m_Windows.at(index - baseCount); -} - -int MHTabWidget::count() const -{ - return QTabWidget::count() + m_Windows.size(); -} - -// Convert an external window to a widget tab -void MHTabWidget::AttachTab(QWidget* parent) -{ - // Retrieve widget - MHDetachedWindow* detachedWidget = reinterpret_cast(parent); - QWidget* tearOffWidget = detachedWidget->centralWidget(); - - // Reattach the tab - int newIndex = addTab(tearOffWidget, detachedWidget->windowIcon(), detachedWidget->windowTitle()); - - // Remove it from the windows list - for(int i = 0; i < m_Windows.size(); i++) - { - if(m_Windows.at(i) == tearOffWidget) - m_Windows.removeAt(i); - } - - // Make Active - if(newIndex != -1) - setCurrentIndex(newIndex); - - // Cleanup Window - disconnect(detachedWidget, SIGNAL(OnClose(QWidget*)), this, SLOT(AttachTab(QWidget*))); - detachedWidget->hide(); - detachedWidget->close(); -} - -// Convert a tab to an external window -void MHTabWidget::DetachTab(int index, QPoint & dropPoint) -{ - Q_UNUSED(dropPoint); - // Create the window - MHDetachedWindow* detachedWidget = new MHDetachedWindow(parentWidget(), this); - detachedWidget->setWindowModality(Qt::NonModal); - - // Find Widget and connect - connect(detachedWidget, SIGNAL(OnClose(QWidget*)), this, SLOT(AttachTab(QWidget*))); - - detachedWidget->setWindowTitle(tabText(index)); - detachedWidget->setWindowIcon(tabIcon(index)); - - // Remove from tab bar - QWidget* tearOffWidget = widget(index); - tearOffWidget->setParent(detachedWidget); - - // Add it to the windows list - m_Windows.append(tearOffWidget); - - // Make first active - if(count() > 0) - setCurrentIndex(0); - - // Create and show - detachedWidget->setCentralWidget(tearOffWidget); - - // Needs to be done explicitly - tearOffWidget->showNormal(); - QRect screenGeometry = QApplication::desktop()->screenGeometry(); - int w = 640; - int h = 480; - int x = (screenGeometry.width() - w) / 2; - int y = (screenGeometry.height() - h) / 2; - detachedWidget->showNormal(); - detachedWidget->setGeometry(x, y, w, h); - detachedWidget->showNormal(); -} - -// Swap two tab indices -void MHTabWidget::MoveTab(int fromIndex, int toIndex) -{ - removeTab(fromIndex); - insertTab(toIndex, widget(fromIndex), tabIcon(fromIndex), tabText(fromIndex)); - setCurrentIndex(toIndex); -} - -// Remove a tab, while still keeping the widget intact -void MHTabWidget::DeleteTab(int index) -{ - removeTab(index); -} - -void MHTabWidget::setCurrentIndex(int index) -{ - // Check if it's just a normal tab - if(index < QTabWidget::count()) - { - QTabWidget::setCurrentIndex(index); - } - else - { - // Otherwise it's going to be a window (just bring it up) - MHDetachedWindow* window = dynamic_cast(widget(index)->parent()); - window->activateWindow(); - window->showNormal(); - window->setFocus(); - } -} - -QTabBar* MHTabWidget::tabBar() const -{ - return m_tabBar; -} - -//---------------------------------------------------------------------------- - -MHDetachedWindow::MHDetachedWindow(QWidget* parent, MHTabWidget* tabwidget) : QMainWindow(parent) -{ - m_TabWidget = tabwidget; -} - -MHDetachedWindow::~MHDetachedWindow(void) -{ -} - -void MHDetachedWindow::closeEvent(QCloseEvent* event) -{ - Q_UNUSED(event); - - emit OnClose(this); -} +// Qt includes +#include "tabbar.h" +#include "tabwidget.h" + +////////////////////////////////////////////////////////////// +// Default Constructor +////////////////////////////////////////////////////////////// +MHTabWidget::MHTabWidget(QWidget* parent, bool allowDetach, bool allowDelete) : QTabWidget(parent) +{ + m_tabBar = new MHTabBar(this, allowDetach, allowDelete); + connect(m_tabBar, SIGNAL(OnDetachTab(int, QPoint &)), this, SLOT(DetachTab(int, QPoint &))); + connect(m_tabBar, SIGNAL(OnMoveTab(int, int)), this, SLOT(MoveTab(int, int))); + connect(m_tabBar, SIGNAL(OnDeleteTab(int)), this, SLOT(DeleteTab(int))); + + setTabBar(m_tabBar); + setMovable(true); + + m_Windows.clear(); +} + +////////////////////////////////////////////////////////////// +// Default Destructor +////////////////////////////////////////////////////////////// +MHTabWidget::~MHTabWidget(void) +{ + disconnect(m_tabBar, SIGNAL(OnMoveTab(int, int)), this, SLOT(MoveTab(int, int))); + disconnect(m_tabBar, SIGNAL(OnDetachTab(int, QPoint &)), this, SLOT(DetachTab(int, QPoint &))); + disconnect(m_tabBar, SIGNAL(OnDeleteTab(int)), this, SLOT(DeleteTab(int))); + delete m_tabBar; +} + +QWidget* MHTabWidget::widget(int index) const +{ + int baseCount = QTabWidget::count(); + + // Check if it's just a normal tab + if(index < baseCount) + return QTabWidget::widget(index); + + // Otherwise it's going to be a window + return m_Windows.at(index - baseCount); +} + +int MHTabWidget::count() const +{ + return QTabWidget::count() + m_Windows.size(); +} + +// Convert an external window to a widget tab +void MHTabWidget::AttachTab(QWidget* parent) +{ + // Retrieve widget + MHDetachedWindow* detachedWidget = reinterpret_cast(parent); + QWidget* tearOffWidget = detachedWidget->centralWidget(); + + // Reattach the tab + int newIndex = addTab(tearOffWidget, detachedWidget->windowIcon(), detachedWidget->windowTitle()); + + // Remove it from the windows list + for(int i = 0; i < m_Windows.size(); i++) + { + if(m_Windows.at(i) == tearOffWidget) + m_Windows.removeAt(i); + } + + // Make Active + if(newIndex != -1) + setCurrentIndex(newIndex); + + // Cleanup Window + disconnect(detachedWidget, SIGNAL(OnClose(QWidget*)), this, SLOT(AttachTab(QWidget*))); + detachedWidget->hide(); + detachedWidget->close(); +} + +// Convert a tab to an external window +void MHTabWidget::DetachTab(int index, QPoint & dropPoint) +{ + Q_UNUSED(dropPoint); + // Create the window + MHDetachedWindow* detachedWidget = new MHDetachedWindow(parentWidget(), this); + detachedWidget->setWindowModality(Qt::NonModal); + + // Find Widget and connect + connect(detachedWidget, SIGNAL(OnClose(QWidget*)), this, SLOT(AttachTab(QWidget*))); + + detachedWidget->setWindowTitle(tabText(index)); + detachedWidget->setWindowIcon(tabIcon(index)); + + // Remove from tab bar + QWidget* tearOffWidget = widget(index); + tearOffWidget->setParent(detachedWidget); + + // Add it to the windows list + m_Windows.append(tearOffWidget); + + // Make first active + if(count() > 0) + setCurrentIndex(0); + + // Create and show + detachedWidget->setCentralWidget(tearOffWidget); + + // Needs to be done explicitly + tearOffWidget->showNormal(); + QRect screenGeometry = QApplication::desktop()->screenGeometry(); + int w = 640; + int h = 480; + int x = (screenGeometry.width() - w) / 2; + int y = (screenGeometry.height() - h) / 2; + detachedWidget->showNormal(); + detachedWidget->setGeometry(x, y, w, h); + detachedWidget->showNormal(); +} + +// Swap two tab indices +void MHTabWidget::MoveTab(int fromIndex, int toIndex) +{ + removeTab(fromIndex); + insertTab(toIndex, widget(fromIndex), tabIcon(fromIndex), tabText(fromIndex)); + setCurrentIndex(toIndex); +} + +// Remove a tab, while still keeping the widget intact +void MHTabWidget::DeleteTab(int index) +{ + removeTab(index); +} + +void MHTabWidget::setCurrentIndex(int index) +{ + // Check if it's just a normal tab + if(index < QTabWidget::count()) + { + QTabWidget::setCurrentIndex(index); + } + else + { + // Otherwise it's going to be a window (just bring it up) + MHDetachedWindow* window = dynamic_cast(widget(index)->parent()); + window->activateWindow(); + window->showNormal(); + window->setFocus(); + } +} + +QTabBar* MHTabWidget::tabBar() const +{ + return m_tabBar; +} + +//---------------------------------------------------------------------------- + +MHDetachedWindow::MHDetachedWindow(QWidget* parent, MHTabWidget* tabwidget) : QMainWindow(parent) +{ + m_TabWidget = tabwidget; +} + +MHDetachedWindow::~MHDetachedWindow(void) +{ +} + +void MHDetachedWindow::closeEvent(QCloseEvent* event) +{ + Q_UNUSED(event); + + emit OnClose(this); +} diff --git a/src/gui/Src/Gui/TabWidget.h b/src/gui/Src/Gui/TabWidget.h index 5afc86af..e94e7a47 100644 --- a/src/gui/Src/Gui/TabWidget.h +++ b/src/gui/Src/Gui/TabWidget.h @@ -1,74 +1,74 @@ -#ifndef __MHTABWIDGET_H__ -#define __MHTABWIDGET_H__ - -// Qt includes -#include -#include -#include -#include -#include -#include - -// Qt forward class definitions -class MHTabBar; - -////////////////////////////////////////////////////////////////////////////// -// Summary: -// MHTabWidget implements the a Tab Widget with detach and attach -// functionality for MHTabBar. -////////////////////////////////////////////////////////////////////////////// -class MHTabWidget: public QTabWidget -{ - Q_OBJECT - -public: - MHTabWidget(QWidget* parent, bool allowDetach = true, bool allowDelete = false); - virtual ~MHTabWidget(void); - - QWidget* widget(int index) const; - int count() const; - -public slots: - void AttachTab(QWidget* parent); - void DetachTab(int index, QPoint &); - void MoveTab(int fromIndex, int toIndex); - void DeleteTab(int index); - -public Q_SLOTS: - void setCurrentIndex(int index); - -protected: - QTabBar* tabBar() const; - -private: - MHTabBar* m_tabBar; - - QList m_Windows; -}; - -////////////////////////////////////////////////////////////////////////////// -// Summary: -// MHDetachedWindow implements the WindowContainer for the Detached Widget -// -// Conditions: -// Header : MHTabWidget.h -////////////////////////////////////////////////////////////////////////////// -class MHDetachedWindow : public QMainWindow -{ - Q_OBJECT - -public: - MHDetachedWindow(QWidget* parent = 0, MHTabWidget* tabwidget = 0); - ~MHDetachedWindow(void); - -protected: - MHTabWidget* m_TabWidget; - - void closeEvent(QCloseEvent* event); - -signals: - void OnClose(QWidget* widget); -}; - -#endif // __MHTABWIDGET_H__ - +#ifndef __MHTABWIDGET_H__ +#define __MHTABWIDGET_H__ + +// Qt includes +#include +#include +#include +#include +#include +#include + +// Qt forward class definitions +class MHTabBar; + +////////////////////////////////////////////////////////////////////////////// +// Summary: +// MHTabWidget implements the a Tab Widget with detach and attach +// functionality for MHTabBar. +////////////////////////////////////////////////////////////////////////////// +class MHTabWidget: public QTabWidget +{ + Q_OBJECT + +public: + MHTabWidget(QWidget* parent, bool allowDetach = true, bool allowDelete = false); + virtual ~MHTabWidget(void); + + QWidget* widget(int index) const; + int count() const; + +public slots: + void AttachTab(QWidget* parent); + void DetachTab(int index, QPoint &); + void MoveTab(int fromIndex, int toIndex); + void DeleteTab(int index); + +public Q_SLOTS: + void setCurrentIndex(int index); + +protected: + QTabBar* tabBar() const; + +private: + MHTabBar* m_tabBar; + + QList m_Windows; +}; + +////////////////////////////////////////////////////////////////////////////// +// Summary: +// MHDetachedWindow implements the WindowContainer for the Detached Widget +// +// Conditions: +// Header : MHTabWidget.h +////////////////////////////////////////////////////////////////////////////// +class MHDetachedWindow : public QMainWindow +{ + Q_OBJECT + +public: + MHDetachedWindow(QWidget* parent = 0, MHTabWidget* tabwidget = 0); + ~MHDetachedWindow(void); + +protected: + MHTabWidget* m_TabWidget; + + void closeEvent(QCloseEvent* event); + +signals: + void OnClose(QWidget* widget); +}; + +#endif // __MHTABWIDGET_H__ + diff --git a/src/gui/Src/Gui/ThreadView.cpp b/src/gui/Src/Gui/ThreadView.cpp index d0f54cef..6f866254 100644 --- a/src/gui/Src/Gui/ThreadView.cpp +++ b/src/gui/Src/Gui/ThreadView.cpp @@ -1,406 +1,406 @@ -#include "ThreadView.h" -#include "Configuration.h" -#include "Bridge.h" - -void ThreadView::contextMenuSlot(const QPoint & pos) -{ - if(!DbgIsDebugging()) - return; - - QMenu* wMenu = new QMenu(this); //create context menu - wMenu->addAction(mSwitchThread); - wMenu->addAction(mSuspendThread); - wMenu->addAction(mResumeThread); - wMenu->addAction(mKillThread); - wMenu->addSeparator(); - wMenu->addMenu(mSetPriority); - bool ok; - ULONGLONG entry = getCellContent(getInitialSelection(), 2).toULongLong(&ok, 16); - if(ok && DbgMemIsValidReadPtr(entry)) - { - wMenu->addSeparator(); - wMenu->addAction(mGoToThreadEntry); - } - wMenu->addSeparator(); - QMenu wCopyMenu("&Copy", this); - setupCopyMenu(&wCopyMenu); - if(wCopyMenu.actions().length()) - { - wMenu->addSeparator(); - wMenu->addMenu(&wCopyMenu); - } - - - foreach(QAction * action, mSetPriority->actions()) - { - action->setCheckable(true); - action->setChecked(false); - } - - QString priority = getCellContent(getInitialSelection(), 6); - if(priority == "Normal") - mSetPriorityNormal->setChecked(true); - else if(priority == "AboveNormal") - mSetPriorityAboveNormal->setChecked(true); - else if(priority == "TimeCritical") - mSetPriorityTimeCritical ->setChecked(true); - else if(priority == "Idle") - mSetPriorityIdle->setChecked(true); - else if(priority == "BelowNormal") - mSetPriorityBelowNormal->setChecked(true); - else if(priority == "Highest") - mSetPriorityHighest->setChecked(true); - else if(priority == "Lowest") - mSetPriorityLowest->setChecked(true); - - wMenu->exec(mapToGlobal(pos)); //execute context menu -} - -void ThreadView::GoToThreadEntry() -{ - QString addr_text = getCellContent(getInitialSelection(), 2); - DbgCmdExecDirect(QString("disasm " + addr_text).toUtf8().constData()); - emit showCpu(); -} - -void ThreadView::SwitchThread() -{ - QString threadId = getCellContent(getInitialSelection(), 1); - DbgCmdExecDirect(QString("switchthread " + threadId).toUtf8().constData()); -} - -void ThreadView::SuspendThread() -{ - QString threadId = getCellContent(getInitialSelection(), 1); - DbgCmdExecDirect(QString("suspendthread " + threadId).toUtf8().constData()); -} - -void ThreadView::ResumeThread() -{ - QString threadId = getCellContent(getInitialSelection(), 1); - DbgCmdExecDirect(QString("resumethread " + threadId).toUtf8().constData()); -} - -void ThreadView::KillThread() -{ - QString threadId = getCellContent(getInitialSelection(), 1); - DbgCmdExecDirect(QString("killthread " + threadId).toUtf8().constData()); -} - -void ThreadView::SetPriorityIdleSlot() -{ - QString threadId = getCellContent(getInitialSelection(), 1); - DbgCmdExecDirect(QString("setprioritythread " + threadId + ", Idle").toUtf8().constData()); -} - -void ThreadView::SetPriorityAboveNormalSlot() -{ - QString threadId = getCellContent(getInitialSelection(), 1); - DbgCmdExecDirect(QString("setprioritythread " + threadId + ", AboveNormal").toUtf8().constData()); -} - -void ThreadView::SetPriorityBelowNormalSlot() -{ - QString threadId = getCellContent(getInitialSelection(), 1); - DbgCmdExecDirect(QString("setprioritythread " + threadId + ", BelowNormal").toUtf8().constData()); -} - -void ThreadView::SetPriorityHighestSlot() -{ - QString threadId = getCellContent(getInitialSelection(), 1); - DbgCmdExecDirect(QString("setprioritythread " + threadId + ", Highest").toUtf8().constData()); -} - -void ThreadView::SetPriorityLowestSlot() -{ - QString threadId = getCellContent(getInitialSelection(), 1); - DbgCmdExecDirect(QString("setprioritythread " + threadId + ", Lowest").toUtf8().constData()); -} - -void ThreadView::SetPriorityNormalSlot() -{ - QString threadId = getCellContent(getInitialSelection(), 1); - DbgCmdExecDirect(QString("setprioritythread " + threadId + ", Normal").toUtf8().constData()); -} - -void ThreadView::SetPriorityTimeCriticalSlot() -{ - QString threadId = getCellContent(getInitialSelection(), 1); - DbgCmdExecDirect(QString("setprioritythread " + threadId + ", TimeCritical").toUtf8().constData()); -} - -void ThreadView::setupContextMenu() -{ - //Switch thread menu - mSwitchThread = new QAction("Switch Thread", this); - connect(mSwitchThread, SIGNAL(triggered()), this, SLOT(SwitchThread())); - - //Suspend thread menu - mSuspendThread = new QAction("Suspend Thread", this); - connect(mSuspendThread, SIGNAL(triggered()), this, SLOT(SuspendThread())); - - //Resume thread menu - mResumeThread = new QAction("Resume Thread", this); - connect(mResumeThread, SIGNAL(triggered()), this, SLOT(ResumeThread())); - - //Kill thread menu - mKillThread = new QAction("Kill Thread", this); - connect(mKillThread, SIGNAL(triggered()), this, SLOT(KillThread())); - - // Set priority - mSetPriority = new QMenu("Set Priority", this); - - mSetPriorityIdle = new QAction("Idle", this); - connect(mSetPriorityIdle, SIGNAL(triggered()), this, SLOT(SetPriorityIdleSlot())); - mSetPriority->addAction(mSetPriorityIdle); - - mSetPriorityAboveNormal = new QAction("Above Normal", this); - connect(mSetPriorityAboveNormal, SIGNAL(triggered()), this, SLOT(SetPriorityAboveNormalSlot())); - mSetPriority->addAction(mSetPriorityAboveNormal); - - mSetPriorityBelowNormal = new QAction("Below Normal", this); - connect(mSetPriorityBelowNormal, SIGNAL(triggered()), this, SLOT(SetPriorityBelowNormalSlot())); - mSetPriority->addAction(mSetPriorityBelowNormal); - - mSetPriorityHighest = new QAction("Highest", this); - connect(mSetPriorityHighest, SIGNAL(triggered()), this, SLOT(SetPriorityHighestSlot())); - mSetPriority->addAction(mSetPriorityHighest); - - mSetPriorityLowest = new QAction("Lowest", this); - connect(mSetPriorityLowest, SIGNAL(triggered()), this, SLOT(SetPriorityLowestSlot())); - mSetPriority->addAction(mSetPriorityLowest); - - mSetPriorityNormal = new QAction("Normal", this); - connect(mSetPriorityNormal, SIGNAL(triggered()), this, SLOT(SetPriorityNormalSlot())); - mSetPriority->addAction(mSetPriorityNormal); - - mSetPriorityTimeCritical = new QAction("Time Critical", this); - connect(mSetPriorityTimeCritical, SIGNAL(triggered()), this, SLOT(SetPriorityTimeCriticalSlot())); - mSetPriority->addAction(mSetPriorityTimeCritical); - - // GoToThreadEntry - mGoToThreadEntry = new QAction("Go to Thread Entry", this); - connect(mGoToThreadEntry, SIGNAL(triggered()), this, SLOT(GoToThreadEntry())); - -} - -ThreadView::ThreadView(StdTable* parent) : StdTable(parent) -{ - int charwidth = getCharWidth(); - addColumnAt(8 + charwidth * sizeof(unsigned int) * 2, "Number", false); - addColumnAt(8 + charwidth * sizeof(unsigned int) * 2, "ID", false); - addColumnAt(8 + charwidth * sizeof(duint) * 2, "Entry", false); - addColumnAt(8 + charwidth * sizeof(duint) * 2, "TEB", false); -#ifdef _WIN64 - addColumnAt(8 + charwidth * sizeof(duint) * 2, "RIP", false); -#else - addColumnAt(8 + charwidth * sizeof(duint) * 2, "EIP", false); -#endif //_WIN64 - addColumnAt(8 + charwidth * 14, "Suspend Count", false); - addColumnAt(8 + charwidth * 12, "Priority", false); - addColumnAt(8 + charwidth * 12, "Wait Reason", false); - addColumnAt(8 + charwidth * 11, "Last Error", false); - addColumnAt(0, "Name", false); - - //setCopyMenuOnly(true); - - connect(Bridge::getBridge(), SIGNAL(updateThreads()), this, SLOT(updateThreadList())); - connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot())); - connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint))); - - setupContextMenu(); -} - -void ThreadView::updateThreadList() -{ - THREADLIST threadList; - memset(&threadList, 0, sizeof(THREADLIST)); - DbgGetThreadList(&threadList); - setRowCount(threadList.count); - for(int i = 0; i < threadList.count; i++) - { - if(!threadList.list[i].BasicInfo.ThreadNumber) - setCellContent(i, 0, "Main"); - else - setCellContent(i, 0, QString("%1").arg(threadList.list[i].BasicInfo.ThreadNumber, 0, 10)); - setCellContent(i, 1, QString("%1").arg(threadList.list[i].BasicInfo.ThreadId, 0, 16).toUpper()); - setCellContent(i, 2, QString("%1").arg(threadList.list[i].BasicInfo.ThreadStartAddress, sizeof(dsint) * 2, 16, QChar('0')).toUpper()); - setCellContent(i, 3, QString("%1").arg(threadList.list[i].BasicInfo.ThreadLocalBase, sizeof(dsint) * 2, 16, QChar('0')).toUpper()); - setCellContent(i, 4, QString("%1").arg(threadList.list[i].ThreadCip, sizeof(dsint) * 2, 16, QChar('0')).toUpper()); - setCellContent(i, 5, QString().sprintf("%d", threadList.list[i].SuspendCount)); - QString priorityString; - switch(threadList.list[i].Priority) - { - case _PriorityIdle: - priorityString = "Idle"; - break; - case _PriorityAboveNormal: - priorityString = "AboveNormal"; - break; - case _PriorityBelowNormal: - priorityString = "BelowNormal"; - break; - case _PriorityHighest: - priorityString = "Highest"; - break; - case _PriorityLowest: - priorityString = "Lowest"; - break; - case _PriorityNormal: - priorityString = "Normal"; - break; - case _PriorityTimeCritical: - priorityString = "TimeCritical"; - break; - default: - priorityString = "Unknown"; - break; - } - setCellContent(i, 6, priorityString); - QString waitReasonString; - switch(threadList.list[i].WaitReason) - { - case _Executive: - waitReasonString = "Executive"; - break; - case _FreePage: - waitReasonString = "FreePage"; - break; - case _PageIn: - waitReasonString = "PageIn"; - break; - case _PoolAllocation: - waitReasonString = "PoolAllocation"; - break; - case _DelayExecution: - waitReasonString = "DelayExecution"; - break; - case _Suspended: - waitReasonString = "Suspended"; - break; - case _UserRequest: - waitReasonString = "UserRequest"; - break; - case _WrExecutive: - waitReasonString = "WrExecutive"; - break; - case _WrFreePage: - waitReasonString = "WrFreePage"; - break; - case _WrPageIn: - waitReasonString = "WrPageIn"; - break; - case _WrPoolAllocation: - waitReasonString = "WrPoolAllocation"; - break; - case _WrDelayExecution: - waitReasonString = "WrDelayExecution"; - break; - case _WrSuspended: - waitReasonString = "WrSuspended"; - break; - case _WrUserRequest: - waitReasonString = "WrUserRequest"; - break; - case _WrEventPair: - waitReasonString = "WrEventPair"; - break; - case _WrQueue: - waitReasonString = "WrQueue"; - break; - case _WrLpcReceive: - waitReasonString = "WrLpcReceive"; - break; - case _WrLpcReply: - waitReasonString = "WrLpcReply"; - break; - case _WrVirtualMemory: - waitReasonString = "WrVirtualMemory"; - break; - case _WrPageOut: - waitReasonString = "WrPageOut"; - break; - case _WrRendezvous: - waitReasonString = "WrRendezvous"; - break; - case _Spare2: - waitReasonString = "Spare2"; - break; - case _Spare3: - waitReasonString = "Spare3"; - break; - case _Spare4: - waitReasonString = "Spare4"; - break; - case _Spare5: - waitReasonString = "Spare5"; - break; - case _WrCalloutStack: - waitReasonString = "WrCalloutStack"; - break; - case _WrKernel: - waitReasonString = "WrKernel"; - break; - case _WrResource: - waitReasonString = "WrResource"; - break; - case _WrPushLock: - waitReasonString = "WrPushLock"; - break; - case _WrMutex: - waitReasonString = "WrMutex"; - break; - case _WrQuantumEnd: - waitReasonString = "WrQuantumEnd"; - break; - case _WrDispatchInt: - waitReasonString = "WrDispatchInt"; - break; - case _WrPreempted: - waitReasonString = "WrPreempted"; - break; - case _WrYieldExecution: - waitReasonString = "WrYieldExecution"; - break; - case _WrFastMutex: - waitReasonString = "WrFastMutex"; - break; - case _WrGuardedMutex: - waitReasonString = "WrGuardedMutex"; - break; - case _WrRundown: - waitReasonString = "WrRundown"; - break; - default: - waitReasonString = "Unknown"; - break; - } - setCellContent(i, 7, waitReasonString); - setCellContent(i, 8, QString("%1").arg(threadList.list[i].LastError, sizeof(unsigned int) * 2, 16, QChar('0')).toUpper()); - setCellContent(i, 9, threadList.list[i].BasicInfo.threadName); - } - if(threadList.count) - BridgeFree(threadList.list); - mCurrentThread = threadList.CurrentThread; - reloadData(); -} - -QString ThreadView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) -{ - QString ret = StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h); - if(rowBase + rowOffset == mCurrentThread && !col) - { - painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("ThreadCurrentBackgroundColor"))); - painter->setPen(QPen(ConfigColor("ThreadCurrentColor"))); //white text - painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, ret); - ret = ""; - } - return ret; -} - -void ThreadView::doubleClickedSlot() -{ - QString threadId = getCellContent(getInitialSelection(), 1); - DbgCmdExecDirect(QString("switchthread " + threadId).toUtf8().constData()); - emit showCpu(); -} +#include "ThreadView.h" +#include "Configuration.h" +#include "Bridge.h" + +void ThreadView::contextMenuSlot(const QPoint & pos) +{ + if(!DbgIsDebugging()) + return; + + QMenu* wMenu = new QMenu(this); //create context menu + wMenu->addAction(mSwitchThread); + wMenu->addAction(mSuspendThread); + wMenu->addAction(mResumeThread); + wMenu->addAction(mKillThread); + wMenu->addSeparator(); + wMenu->addMenu(mSetPriority); + bool ok; + ULONGLONG entry = getCellContent(getInitialSelection(), 2).toULongLong(&ok, 16); + if(ok && DbgMemIsValidReadPtr(entry)) + { + wMenu->addSeparator(); + wMenu->addAction(mGoToThreadEntry); + } + wMenu->addSeparator(); + QMenu wCopyMenu("&Copy", this); + setupCopyMenu(&wCopyMenu); + if(wCopyMenu.actions().length()) + { + wMenu->addSeparator(); + wMenu->addMenu(&wCopyMenu); + } + + + foreach(QAction * action, mSetPriority->actions()) + { + action->setCheckable(true); + action->setChecked(false); + } + + QString priority = getCellContent(getInitialSelection(), 6); + if(priority == "Normal") + mSetPriorityNormal->setChecked(true); + else if(priority == "AboveNormal") + mSetPriorityAboveNormal->setChecked(true); + else if(priority == "TimeCritical") + mSetPriorityTimeCritical ->setChecked(true); + else if(priority == "Idle") + mSetPriorityIdle->setChecked(true); + else if(priority == "BelowNormal") + mSetPriorityBelowNormal->setChecked(true); + else if(priority == "Highest") + mSetPriorityHighest->setChecked(true); + else if(priority == "Lowest") + mSetPriorityLowest->setChecked(true); + + wMenu->exec(mapToGlobal(pos)); //execute context menu +} + +void ThreadView::GoToThreadEntry() +{ + QString addr_text = getCellContent(getInitialSelection(), 2); + DbgCmdExecDirect(QString("disasm " + addr_text).toUtf8().constData()); + emit showCpu(); +} + +void ThreadView::SwitchThread() +{ + QString threadId = getCellContent(getInitialSelection(), 1); + DbgCmdExecDirect(QString("switchthread " + threadId).toUtf8().constData()); +} + +void ThreadView::SuspendThread() +{ + QString threadId = getCellContent(getInitialSelection(), 1); + DbgCmdExecDirect(QString("suspendthread " + threadId).toUtf8().constData()); +} + +void ThreadView::ResumeThread() +{ + QString threadId = getCellContent(getInitialSelection(), 1); + DbgCmdExecDirect(QString("resumethread " + threadId).toUtf8().constData()); +} + +void ThreadView::KillThread() +{ + QString threadId = getCellContent(getInitialSelection(), 1); + DbgCmdExecDirect(QString("killthread " + threadId).toUtf8().constData()); +} + +void ThreadView::SetPriorityIdleSlot() +{ + QString threadId = getCellContent(getInitialSelection(), 1); + DbgCmdExecDirect(QString("setprioritythread " + threadId + ", Idle").toUtf8().constData()); +} + +void ThreadView::SetPriorityAboveNormalSlot() +{ + QString threadId = getCellContent(getInitialSelection(), 1); + DbgCmdExecDirect(QString("setprioritythread " + threadId + ", AboveNormal").toUtf8().constData()); +} + +void ThreadView::SetPriorityBelowNormalSlot() +{ + QString threadId = getCellContent(getInitialSelection(), 1); + DbgCmdExecDirect(QString("setprioritythread " + threadId + ", BelowNormal").toUtf8().constData()); +} + +void ThreadView::SetPriorityHighestSlot() +{ + QString threadId = getCellContent(getInitialSelection(), 1); + DbgCmdExecDirect(QString("setprioritythread " + threadId + ", Highest").toUtf8().constData()); +} + +void ThreadView::SetPriorityLowestSlot() +{ + QString threadId = getCellContent(getInitialSelection(), 1); + DbgCmdExecDirect(QString("setprioritythread " + threadId + ", Lowest").toUtf8().constData()); +} + +void ThreadView::SetPriorityNormalSlot() +{ + QString threadId = getCellContent(getInitialSelection(), 1); + DbgCmdExecDirect(QString("setprioritythread " + threadId + ", Normal").toUtf8().constData()); +} + +void ThreadView::SetPriorityTimeCriticalSlot() +{ + QString threadId = getCellContent(getInitialSelection(), 1); + DbgCmdExecDirect(QString("setprioritythread " + threadId + ", TimeCritical").toUtf8().constData()); +} + +void ThreadView::setupContextMenu() +{ + //Switch thread menu + mSwitchThread = new QAction("Switch Thread", this); + connect(mSwitchThread, SIGNAL(triggered()), this, SLOT(SwitchThread())); + + //Suspend thread menu + mSuspendThread = new QAction("Suspend Thread", this); + connect(mSuspendThread, SIGNAL(triggered()), this, SLOT(SuspendThread())); + + //Resume thread menu + mResumeThread = new QAction("Resume Thread", this); + connect(mResumeThread, SIGNAL(triggered()), this, SLOT(ResumeThread())); + + //Kill thread menu + mKillThread = new QAction("Kill Thread", this); + connect(mKillThread, SIGNAL(triggered()), this, SLOT(KillThread())); + + // Set priority + mSetPriority = new QMenu("Set Priority", this); + + mSetPriorityIdle = new QAction("Idle", this); + connect(mSetPriorityIdle, SIGNAL(triggered()), this, SLOT(SetPriorityIdleSlot())); + mSetPriority->addAction(mSetPriorityIdle); + + mSetPriorityAboveNormal = new QAction("Above Normal", this); + connect(mSetPriorityAboveNormal, SIGNAL(triggered()), this, SLOT(SetPriorityAboveNormalSlot())); + mSetPriority->addAction(mSetPriorityAboveNormal); + + mSetPriorityBelowNormal = new QAction("Below Normal", this); + connect(mSetPriorityBelowNormal, SIGNAL(triggered()), this, SLOT(SetPriorityBelowNormalSlot())); + mSetPriority->addAction(mSetPriorityBelowNormal); + + mSetPriorityHighest = new QAction("Highest", this); + connect(mSetPriorityHighest, SIGNAL(triggered()), this, SLOT(SetPriorityHighestSlot())); + mSetPriority->addAction(mSetPriorityHighest); + + mSetPriorityLowest = new QAction("Lowest", this); + connect(mSetPriorityLowest, SIGNAL(triggered()), this, SLOT(SetPriorityLowestSlot())); + mSetPriority->addAction(mSetPriorityLowest); + + mSetPriorityNormal = new QAction("Normal", this); + connect(mSetPriorityNormal, SIGNAL(triggered()), this, SLOT(SetPriorityNormalSlot())); + mSetPriority->addAction(mSetPriorityNormal); + + mSetPriorityTimeCritical = new QAction("Time Critical", this); + connect(mSetPriorityTimeCritical, SIGNAL(triggered()), this, SLOT(SetPriorityTimeCriticalSlot())); + mSetPriority->addAction(mSetPriorityTimeCritical); + + // GoToThreadEntry + mGoToThreadEntry = new QAction("Go to Thread Entry", this); + connect(mGoToThreadEntry, SIGNAL(triggered()), this, SLOT(GoToThreadEntry())); + +} + +ThreadView::ThreadView(StdTable* parent) : StdTable(parent) +{ + int charwidth = getCharWidth(); + addColumnAt(8 + charwidth * sizeof(unsigned int) * 2, "Number", false); + addColumnAt(8 + charwidth * sizeof(unsigned int) * 2, "ID", false); + addColumnAt(8 + charwidth * sizeof(duint) * 2, "Entry", false); + addColumnAt(8 + charwidth * sizeof(duint) * 2, "TEB", false); +#ifdef _WIN64 + addColumnAt(8 + charwidth * sizeof(duint) * 2, "RIP", false); +#else + addColumnAt(8 + charwidth * sizeof(duint) * 2, "EIP", false); +#endif //_WIN64 + addColumnAt(8 + charwidth * 14, "Suspend Count", false); + addColumnAt(8 + charwidth * 12, "Priority", false); + addColumnAt(8 + charwidth * 12, "Wait Reason", false); + addColumnAt(8 + charwidth * 11, "Last Error", false); + addColumnAt(0, "Name", false); + + //setCopyMenuOnly(true); + + connect(Bridge::getBridge(), SIGNAL(updateThreads()), this, SLOT(updateThreadList())); + connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot())); + connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint))); + + setupContextMenu(); +} + +void ThreadView::updateThreadList() +{ + THREADLIST threadList; + memset(&threadList, 0, sizeof(THREADLIST)); + DbgGetThreadList(&threadList); + setRowCount(threadList.count); + for(int i = 0; i < threadList.count; i++) + { + if(!threadList.list[i].BasicInfo.ThreadNumber) + setCellContent(i, 0, "Main"); + else + setCellContent(i, 0, QString("%1").arg(threadList.list[i].BasicInfo.ThreadNumber, 0, 10)); + setCellContent(i, 1, QString("%1").arg(threadList.list[i].BasicInfo.ThreadId, 0, 16).toUpper()); + setCellContent(i, 2, QString("%1").arg(threadList.list[i].BasicInfo.ThreadStartAddress, sizeof(dsint) * 2, 16, QChar('0')).toUpper()); + setCellContent(i, 3, QString("%1").arg(threadList.list[i].BasicInfo.ThreadLocalBase, sizeof(dsint) * 2, 16, QChar('0')).toUpper()); + setCellContent(i, 4, QString("%1").arg(threadList.list[i].ThreadCip, sizeof(dsint) * 2, 16, QChar('0')).toUpper()); + setCellContent(i, 5, QString().sprintf("%d", threadList.list[i].SuspendCount)); + QString priorityString; + switch(threadList.list[i].Priority) + { + case _PriorityIdle: + priorityString = "Idle"; + break; + case _PriorityAboveNormal: + priorityString = "AboveNormal"; + break; + case _PriorityBelowNormal: + priorityString = "BelowNormal"; + break; + case _PriorityHighest: + priorityString = "Highest"; + break; + case _PriorityLowest: + priorityString = "Lowest"; + break; + case _PriorityNormal: + priorityString = "Normal"; + break; + case _PriorityTimeCritical: + priorityString = "TimeCritical"; + break; + default: + priorityString = "Unknown"; + break; + } + setCellContent(i, 6, priorityString); + QString waitReasonString; + switch(threadList.list[i].WaitReason) + { + case _Executive: + waitReasonString = "Executive"; + break; + case _FreePage: + waitReasonString = "FreePage"; + break; + case _PageIn: + waitReasonString = "PageIn"; + break; + case _PoolAllocation: + waitReasonString = "PoolAllocation"; + break; + case _DelayExecution: + waitReasonString = "DelayExecution"; + break; + case _Suspended: + waitReasonString = "Suspended"; + break; + case _UserRequest: + waitReasonString = "UserRequest"; + break; + case _WrExecutive: + waitReasonString = "WrExecutive"; + break; + case _WrFreePage: + waitReasonString = "WrFreePage"; + break; + case _WrPageIn: + waitReasonString = "WrPageIn"; + break; + case _WrPoolAllocation: + waitReasonString = "WrPoolAllocation"; + break; + case _WrDelayExecution: + waitReasonString = "WrDelayExecution"; + break; + case _WrSuspended: + waitReasonString = "WrSuspended"; + break; + case _WrUserRequest: + waitReasonString = "WrUserRequest"; + break; + case _WrEventPair: + waitReasonString = "WrEventPair"; + break; + case _WrQueue: + waitReasonString = "WrQueue"; + break; + case _WrLpcReceive: + waitReasonString = "WrLpcReceive"; + break; + case _WrLpcReply: + waitReasonString = "WrLpcReply"; + break; + case _WrVirtualMemory: + waitReasonString = "WrVirtualMemory"; + break; + case _WrPageOut: + waitReasonString = "WrPageOut"; + break; + case _WrRendezvous: + waitReasonString = "WrRendezvous"; + break; + case _Spare2: + waitReasonString = "Spare2"; + break; + case _Spare3: + waitReasonString = "Spare3"; + break; + case _Spare4: + waitReasonString = "Spare4"; + break; + case _Spare5: + waitReasonString = "Spare5"; + break; + case _WrCalloutStack: + waitReasonString = "WrCalloutStack"; + break; + case _WrKernel: + waitReasonString = "WrKernel"; + break; + case _WrResource: + waitReasonString = "WrResource"; + break; + case _WrPushLock: + waitReasonString = "WrPushLock"; + break; + case _WrMutex: + waitReasonString = "WrMutex"; + break; + case _WrQuantumEnd: + waitReasonString = "WrQuantumEnd"; + break; + case _WrDispatchInt: + waitReasonString = "WrDispatchInt"; + break; + case _WrPreempted: + waitReasonString = "WrPreempted"; + break; + case _WrYieldExecution: + waitReasonString = "WrYieldExecution"; + break; + case _WrFastMutex: + waitReasonString = "WrFastMutex"; + break; + case _WrGuardedMutex: + waitReasonString = "WrGuardedMutex"; + break; + case _WrRundown: + waitReasonString = "WrRundown"; + break; + default: + waitReasonString = "Unknown"; + break; + } + setCellContent(i, 7, waitReasonString); + setCellContent(i, 8, QString("%1").arg(threadList.list[i].LastError, sizeof(unsigned int) * 2, 16, QChar('0')).toUpper()); + setCellContent(i, 9, threadList.list[i].BasicInfo.threadName); + } + if(threadList.count) + BridgeFree(threadList.list); + mCurrentThread = threadList.CurrentThread; + reloadData(); +} + +QString ThreadView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) +{ + QString ret = StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h); + if(rowBase + rowOffset == mCurrentThread && !col) + { + painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("ThreadCurrentBackgroundColor"))); + painter->setPen(QPen(ConfigColor("ThreadCurrentColor"))); //white text + painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, ret); + ret = ""; + } + return ret; +} + +void ThreadView::doubleClickedSlot() +{ + QString threadId = getCellContent(getInitialSelection(), 1); + DbgCmdExecDirect(QString("switchthread " + threadId).toUtf8().constData()); + emit showCpu(); +} diff --git a/src/gui/Src/Gui/ThreadView.h b/src/gui/Src/Gui/ThreadView.h index 4e4eadae..797eae3c 100644 --- a/src/gui/Src/Gui/ThreadView.h +++ b/src/gui/Src/Gui/ThreadView.h @@ -1,52 +1,52 @@ -#ifndef THREADVIEW_H -#define THREADVIEW_H - -#include "StdTable.h" -#include - -class ThreadView : public StdTable -{ - Q_OBJECT -public: - explicit ThreadView(StdTable* parent = 0); - QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); - void setupContextMenu(); - -public slots: - void updateThreadList(); - void doubleClickedSlot(); - void SwitchThread(); - void SuspendThread(); - void ResumeThread(); - void KillThread(); - void GoToThreadEntry(); - void contextMenuSlot(const QPoint & pos); - void SetPriorityIdleSlot(); - void SetPriorityAboveNormalSlot(); - void SetPriorityBelowNormalSlot(); - void SetPriorityHighestSlot(); - void SetPriorityLowestSlot(); - void SetPriorityNormalSlot(); - void SetPriorityTimeCriticalSlot(); - -signals: - void showCpu(); - -private: - int mCurrentThread; - QAction* mSwitchThread; - QAction* mSuspendThread; - QAction* mGoToThreadEntry; - QAction* mResumeThread; - QAction* mKillThread; - QAction* mSetPriorityIdle; - QAction* mSetPriorityAboveNormal; - QAction* mSetPriorityBelowNormal; - QAction* mSetPriorityHighest; - QAction* mSetPriorityLowest; - QAction* mSetPriorityNormal; - QAction* mSetPriorityTimeCritical; - QMenu* mSetPriority; -}; - -#endif // THREADVIEW_H +#ifndef THREADVIEW_H +#define THREADVIEW_H + +#include "StdTable.h" +#include + +class ThreadView : public StdTable +{ + Q_OBJECT +public: + explicit ThreadView(StdTable* parent = 0); + QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h); + void setupContextMenu(); + +public slots: + void updateThreadList(); + void doubleClickedSlot(); + void SwitchThread(); + void SuspendThread(); + void ResumeThread(); + void KillThread(); + void GoToThreadEntry(); + void contextMenuSlot(const QPoint & pos); + void SetPriorityIdleSlot(); + void SetPriorityAboveNormalSlot(); + void SetPriorityBelowNormalSlot(); + void SetPriorityHighestSlot(); + void SetPriorityLowestSlot(); + void SetPriorityNormalSlot(); + void SetPriorityTimeCriticalSlot(); + +signals: + void showCpu(); + +private: + int mCurrentThread; + QAction* mSwitchThread; + QAction* mSuspendThread; + QAction* mGoToThreadEntry; + QAction* mResumeThread; + QAction* mKillThread; + QAction* mSetPriorityIdle; + QAction* mSetPriorityAboveNormal; + QAction* mSetPriorityBelowNormal; + QAction* mSetPriorityHighest; + QAction* mSetPriorityLowest; + QAction* mSetPriorityNormal; + QAction* mSetPriorityTimeCritical; + QMenu* mSetPriority; +}; + +#endif // THREADVIEW_H diff --git a/src/gui/Src/Gui/TimeWastedCounter.cpp b/src/gui/Src/Gui/TimeWastedCounter.cpp index 9407bfc9..c0f5095e 100644 --- a/src/gui/Src/Gui/TimeWastedCounter.cpp +++ b/src/gui/Src/Gui/TimeWastedCounter.cpp @@ -1,20 +1,20 @@ -#include "TimeWastedCounter.h" -#include "Bridge.h" - -TimeWastedCounter::TimeWastedCounter(QObject* parent, QLabel* label) - : QObject(parent), mLabel(label) -{ - mLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel); //sunken style - mLabel->setStyleSheet("QLabel { background-color : #c0c0c0; }"); - connect(Bridge::getBridge(), SIGNAL(updateTimeWastedCounter()), this, SLOT(updateTimeWastedCounter())); -} - -void TimeWastedCounter::updateTimeWastedCounter() -{ - duint timeWasted = DbgGetTimeWastedCounter(); - int days = timeWasted / (60 * 60 * 24); - int hours = (timeWasted / (60 * 60)) % 24; - int minutes = (timeWasted / 60) % 60; - int seconds = timeWasted % 60; - mLabel->setText(QString().sprintf("Time Wasted Debugging: %d:%02d:%02d:%02d", days, hours, minutes, seconds)); -} +#include "TimeWastedCounter.h" +#include "Bridge.h" + +TimeWastedCounter::TimeWastedCounter(QObject* parent, QLabel* label) + : QObject(parent), mLabel(label) +{ + mLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel); //sunken style + mLabel->setStyleSheet("QLabel { background-color : #c0c0c0; }"); + connect(Bridge::getBridge(), SIGNAL(updateTimeWastedCounter()), this, SLOT(updateTimeWastedCounter())); +} + +void TimeWastedCounter::updateTimeWastedCounter() +{ + duint timeWasted = DbgGetTimeWastedCounter(); + int days = timeWasted / (60 * 60 * 24); + int hours = (timeWasted / (60 * 60)) % 24; + int minutes = (timeWasted / 60) % 60; + int seconds = timeWasted % 60; + mLabel->setText(QString().sprintf("Time Wasted Debugging: %d:%02d:%02d:%02d", days, hours, minutes, seconds)); +} diff --git a/src/gui/Src/Gui/TimeWastedCounter.h b/src/gui/Src/Gui/TimeWastedCounter.h index 3ca06c5f..f0b79195 100644 --- a/src/gui/Src/Gui/TimeWastedCounter.h +++ b/src/gui/Src/Gui/TimeWastedCounter.h @@ -1,20 +1,20 @@ -#ifndef TIMEWASTEDCOUNTER_H -#define TIMEWASTEDCOUNTER_H - -#include -#include - -class TimeWastedCounter : public QObject -{ - Q_OBJECT -public: - explicit TimeWastedCounter(QObject* parent, QLabel* label); - -private slots: - void updateTimeWastedCounter(); - -private: - QLabel* mLabel; -}; - -#endif // TIMEWASTEDCOUNTER_H +#ifndef TIMEWASTEDCOUNTER_H +#define TIMEWASTEDCOUNTER_H + +#include +#include + +class TimeWastedCounter : public QObject +{ + Q_OBJECT +public: + explicit TimeWastedCounter(QObject* parent, QLabel* label); + +private slots: + void updateTimeWastedCounter(); + +private: + QLabel* mLabel; +}; + +#endif // TIMEWASTEDCOUNTER_H diff --git a/src/gui/Src/Gui/WordEditDialog.cpp b/src/gui/Src/Gui/WordEditDialog.cpp index f0442041..31a3b86b 100644 --- a/src/gui/Src/Gui/WordEditDialog.cpp +++ b/src/gui/Src/Gui/WordEditDialog.cpp @@ -1,130 +1,130 @@ -#include "WordEditDialog.h" -#include "ui_WordEditDialog.h" - -WordEditDialog::WordEditDialog(QWidget* parent) : QDialog(parent), ui(new Ui::WordEditDialog) -{ - ui->setupUi(this); -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); -#endif - setModal(true); - - mValidateThread = new ValidateExpressionThread(this); - connect(mValidateThread, SIGNAL(expressionChanged(bool, bool, dsint)), this, SLOT(expressionChanged(bool, bool, dsint))); - connect(ui->expressionLineEdit, SIGNAL(textEdited(QString)), mValidateThread, SLOT(textChanged(QString))); - mWord = 0; -} - -WordEditDialog::~WordEditDialog() -{ - delete ui; -} - -void WordEditDialog::showEvent(QShowEvent* event) -{ - Q_UNUSED(event); - mValidateThread->start(ui->expressionLineEdit->text()); -} - -void WordEditDialog::hideEvent(QHideEvent* event) -{ - Q_UNUSED(event); - mValidateThread->stop(); - mValidateThread->wait(); -} - -void WordEditDialog::setup(QString title, duint defVal, int byteCount) -{ - this->setWindowTitle(title); - ui->hexLineEdit->setInputMask(QString("hh").repeated(byteCount)); - ui->expressionLineEdit->setText(QString("%1").arg(defVal, byteCount * 2, 16, QChar('0')).toUpper()); - - ui->expressionLineEdit->selectAll(); - ui->expressionLineEdit->setFocus(); -} - -duint WordEditDialog::getVal() -{ - return mWord; -} - -void WordEditDialog::expressionChanged(bool validExpression, bool validPointer, dsint value) -{ - Q_UNUSED(validPointer); - if(validExpression) - { - ui->expressionLineEdit->setStyleSheet(""); - ui->unsignedLineEdit->setStyleSheet(""); - ui->signedLineEdit->setStyleSheet(""); - ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(true); - - //hex - mWord = value; - duint hexWord = 0; - unsigned char* hex = (unsigned char*)&hexWord; - unsigned char* word = (unsigned char*)&mWord; -#ifdef _WIN64 - hex[0] = word[7]; - hex[1] = word[6]; - hex[2] = word[5]; - hex[3] = word[4]; - hex[4] = word[3]; - hex[5] = word[2]; - hex[6] = word[1]; - hex[7] = word[0]; -#else //x86 - hex[0] = word[3]; - hex[1] = word[2]; - hex[2] = word[1]; - hex[3] = word[0]; -#endif //_WIN64 - ui->hexLineEdit->setText(QString("%1").arg(hexWord, sizeof(duint) * 2, 16, QChar('0')).toUpper()); - //signed - ui->signedLineEdit->setText(QString::number((dsint)mWord)); - //unsigned - ui->unsignedLineEdit->setText(QString::number((duint)mWord)); - } - else - { - ui->expressionLineEdit->setStyleSheet("border: 1px solid red"); - ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(false); - } -} - -void WordEditDialog::on_expressionLineEdit_textChanged(const QString & arg1) -{ - Q_UNUSED(arg1); - ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(false); -} - -void WordEditDialog::on_signedLineEdit_textEdited(const QString & arg1) -{ - LONGLONG value; - if(sscanf_s(arg1.toUtf8().constData(), "%lld", &value) == 1) - { - ui->signedLineEdit->setStyleSheet(""); - ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(true); - ui->expressionLineEdit->setText(QString("%1").arg((duint)value, sizeof(duint) * 2, 16, QChar('0')).toUpper()); - } - else - { - ui->signedLineEdit->setStyleSheet("border: 1px solid red"); - ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(false); - } -} - -void WordEditDialog::on_unsignedLineEdit_textEdited(const QString & arg1) -{ - LONGLONG value; - if(sscanf_s(arg1.toUtf8().constData(), "%llu", &value) == 1) - { - ui->unsignedLineEdit->setStyleSheet(""); - ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(true); - ui->expressionLineEdit->setText(QString("%1").arg((duint)value, sizeof(duint) * 2, 16, QChar('0')).toUpper()); - } - else - { - ui->unsignedLineEdit->setStyleSheet("border: 1px solid red"); - ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(false); - } -} +#include "WordEditDialog.h" +#include "ui_WordEditDialog.h" + +WordEditDialog::WordEditDialog(QWidget* parent) : QDialog(parent), ui(new Ui::WordEditDialog) +{ + ui->setupUi(this); +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); +#endif + setModal(true); + + mValidateThread = new ValidateExpressionThread(this); + connect(mValidateThread, SIGNAL(expressionChanged(bool, bool, dsint)), this, SLOT(expressionChanged(bool, bool, dsint))); + connect(ui->expressionLineEdit, SIGNAL(textEdited(QString)), mValidateThread, SLOT(textChanged(QString))); + mWord = 0; +} + +WordEditDialog::~WordEditDialog() +{ + delete ui; +} + +void WordEditDialog::showEvent(QShowEvent* event) +{ + Q_UNUSED(event); + mValidateThread->start(ui->expressionLineEdit->text()); +} + +void WordEditDialog::hideEvent(QHideEvent* event) +{ + Q_UNUSED(event); + mValidateThread->stop(); + mValidateThread->wait(); +} + +void WordEditDialog::setup(QString title, duint defVal, int byteCount) +{ + this->setWindowTitle(title); + ui->hexLineEdit->setInputMask(QString("hh").repeated(byteCount)); + ui->expressionLineEdit->setText(QString("%1").arg(defVal, byteCount * 2, 16, QChar('0')).toUpper()); + + ui->expressionLineEdit->selectAll(); + ui->expressionLineEdit->setFocus(); +} + +duint WordEditDialog::getVal() +{ + return mWord; +} + +void WordEditDialog::expressionChanged(bool validExpression, bool validPointer, dsint value) +{ + Q_UNUSED(validPointer); + if(validExpression) + { + ui->expressionLineEdit->setStyleSheet(""); + ui->unsignedLineEdit->setStyleSheet(""); + ui->signedLineEdit->setStyleSheet(""); + ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(true); + + //hex + mWord = value; + duint hexWord = 0; + unsigned char* hex = (unsigned char*)&hexWord; + unsigned char* word = (unsigned char*)&mWord; +#ifdef _WIN64 + hex[0] = word[7]; + hex[1] = word[6]; + hex[2] = word[5]; + hex[3] = word[4]; + hex[4] = word[3]; + hex[5] = word[2]; + hex[6] = word[1]; + hex[7] = word[0]; +#else //x86 + hex[0] = word[3]; + hex[1] = word[2]; + hex[2] = word[1]; + hex[3] = word[0]; +#endif //_WIN64 + ui->hexLineEdit->setText(QString("%1").arg(hexWord, sizeof(duint) * 2, 16, QChar('0')).toUpper()); + //signed + ui->signedLineEdit->setText(QString::number((dsint)mWord)); + //unsigned + ui->unsignedLineEdit->setText(QString::number((duint)mWord)); + } + else + { + ui->expressionLineEdit->setStyleSheet("border: 1px solid red"); + ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(false); + } +} + +void WordEditDialog::on_expressionLineEdit_textChanged(const QString & arg1) +{ + Q_UNUSED(arg1); + ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(false); +} + +void WordEditDialog::on_signedLineEdit_textEdited(const QString & arg1) +{ + LONGLONG value; + if(sscanf_s(arg1.toUtf8().constData(), "%lld", &value) == 1) + { + ui->signedLineEdit->setStyleSheet(""); + ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(true); + ui->expressionLineEdit->setText(QString("%1").arg((duint)value, sizeof(duint) * 2, 16, QChar('0')).toUpper()); + } + else + { + ui->signedLineEdit->setStyleSheet("border: 1px solid red"); + ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(false); + } +} + +void WordEditDialog::on_unsignedLineEdit_textEdited(const QString & arg1) +{ + LONGLONG value; + if(sscanf_s(arg1.toUtf8().constData(), "%llu", &value) == 1) + { + ui->unsignedLineEdit->setStyleSheet(""); + ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(true); + ui->expressionLineEdit->setText(QString("%1").arg((duint)value, sizeof(duint) * 2, 16, QChar('0')).toUpper()); + } + else + { + ui->unsignedLineEdit->setStyleSheet("border: 1px solid red"); + ui->buttons->button(QDialogButtonBox::Ok)->setEnabled(false); + } +} diff --git a/src/gui/Src/Gui/WordEditDialog.h b/src/gui/Src/Gui/WordEditDialog.h index a3a3c43e..a1302cac 100644 --- a/src/gui/Src/Gui/WordEditDialog.h +++ b/src/gui/Src/Gui/WordEditDialog.h @@ -1,38 +1,38 @@ -#ifndef WORDEDITDIALOG_H -#define WORDEDITDIALOG_H - -#include -#include -#include "ValidateExpressionThread.h" -#include "Imports.h" - -namespace Ui -{ -class WordEditDialog; -} - -class WordEditDialog : public QDialog -{ - Q_OBJECT - -public: - explicit WordEditDialog(QWidget* parent = 0); - ~WordEditDialog(); - void setup(QString title, duint defVal, int byteCount); - duint getVal(); - void showEvent(QShowEvent* event); - void hideEvent(QHideEvent* event); - -private slots: - void expressionChanged(bool validExpression, bool validPointer, dsint value); - void on_expressionLineEdit_textChanged(const QString & arg1); - void on_signedLineEdit_textEdited(const QString & arg1); - void on_unsignedLineEdit_textEdited(const QString & arg1); - -private: - Ui::WordEditDialog* ui; - duint mWord; - ValidateExpressionThread* mValidateThread; -}; - -#endif // WORDEDITDIALOG_H +#ifndef WORDEDITDIALOG_H +#define WORDEDITDIALOG_H + +#include +#include +#include "ValidateExpressionThread.h" +#include "Imports.h" + +namespace Ui +{ +class WordEditDialog; +} + +class WordEditDialog : public QDialog +{ + Q_OBJECT + +public: + explicit WordEditDialog(QWidget* parent = 0); + ~WordEditDialog(); + void setup(QString title, duint defVal, int byteCount); + duint getVal(); + void showEvent(QShowEvent* event); + void hideEvent(QHideEvent* event); + +private slots: + void expressionChanged(bool validExpression, bool validPointer, dsint value); + void on_expressionLineEdit_textChanged(const QString & arg1); + void on_signedLineEdit_textEdited(const QString & arg1); + void on_unsignedLineEdit_textEdited(const QString & arg1); + +private: + Ui::WordEditDialog* ui; + duint mWord; + ValidateExpressionThread* mValidateThread; +}; + +#endif // WORDEDITDIALOG_H diff --git a/src/gui/Src/Gui/YaraRuleSelectionDialog.cpp b/src/gui/Src/Gui/YaraRuleSelectionDialog.cpp index 41492f6d..a5e80320 100644 --- a/src/gui/Src/Gui/YaraRuleSelectionDialog.cpp +++ b/src/gui/Src/Gui/YaraRuleSelectionDialog.cpp @@ -1,77 +1,77 @@ -#include "YaraRuleSelectionDialog.h" -#include "ui_YaraRuleSelectionDialog.h" -#include -#include -#include -#include -#include "Imports.h" - -YaraRuleSelectionDialog::YaraRuleSelectionDialog(QWidget* parent) : - QDialog(parent), - ui(new Ui::YaraRuleSelectionDialog) -{ - ui->setupUi(this); -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) - setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); -#endif - setFixedSize(this->size()); //fixed size - - char setting[MAX_SETTING_SIZE] = ""; - if(BridgeSettingGet("Misc", "YaraRulesDirectory", setting)) - { - rulesDirectory = QString(setting); - enumRulesDirectory(); - } -} - -YaraRuleSelectionDialog::~YaraRuleSelectionDialog() -{ - delete ui; -} - -QString YaraRuleSelectionDialog::getSelectedFile() -{ - return selectedFile; -} - -void YaraRuleSelectionDialog::on_buttonDirectory_clicked() -{ - QString dir = QFileDialog::getExistingDirectory(this, "Select Yara Rules Directory..."); - if(!dir.length()) - return; - rulesDirectory = QDir::toNativeSeparators(dir); - BridgeSettingSet("Misc", "YaraRulesDirectory", dir.toUtf8().constData()); - enumRulesDirectory(); -} - -void YaraRuleSelectionDialog::on_buttonFile_clicked() -{ - QString file = QFileDialog::getOpenFileName(this, "Select Yara Rule...", rulesDirectory); - if(!file.length()) - return; - selectedFile = QDir::toNativeSeparators(file); - this->accept(); -} - -void YaraRuleSelectionDialog::on_buttonSelect_clicked() -{ - if(!ui->listRules->selectedItems().size()) //no selection - return; - int selectedIndex = ui->listRules->row(ui->listRules->selectedItems().at(0)); - selectedFile = ruleFiles.at(selectedIndex).first; - this->accept(); -} - -void YaraRuleSelectionDialog::enumRulesDirectory() -{ - ruleFiles.clear(); - ui->listRules->clear(); - QDirIterator it(rulesDirectory, QDir::Files, QDirIterator::Subdirectories); - while(it.hasNext()) - { - it.next(); - ruleFiles.append(QPair(QDir::toNativeSeparators(it.filePath()), it.fileName())); - ui->listRules->addItem(it.fileName()); - } - ui->listRules->setCurrentRow(0); -} +#include "YaraRuleSelectionDialog.h" +#include "ui_YaraRuleSelectionDialog.h" +#include +#include +#include +#include +#include "Imports.h" + +YaraRuleSelectionDialog::YaraRuleSelectionDialog(QWidget* parent) : + QDialog(parent), + ui(new Ui::YaraRuleSelectionDialog) +{ + ui->setupUi(this); +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); +#endif + setFixedSize(this->size()); //fixed size + + char setting[MAX_SETTING_SIZE] = ""; + if(BridgeSettingGet("Misc", "YaraRulesDirectory", setting)) + { + rulesDirectory = QString(setting); + enumRulesDirectory(); + } +} + +YaraRuleSelectionDialog::~YaraRuleSelectionDialog() +{ + delete ui; +} + +QString YaraRuleSelectionDialog::getSelectedFile() +{ + return selectedFile; +} + +void YaraRuleSelectionDialog::on_buttonDirectory_clicked() +{ + QString dir = QFileDialog::getExistingDirectory(this, "Select Yara Rules Directory..."); + if(!dir.length()) + return; + rulesDirectory = QDir::toNativeSeparators(dir); + BridgeSettingSet("Misc", "YaraRulesDirectory", dir.toUtf8().constData()); + enumRulesDirectory(); +} + +void YaraRuleSelectionDialog::on_buttonFile_clicked() +{ + QString file = QFileDialog::getOpenFileName(this, "Select Yara Rule...", rulesDirectory); + if(!file.length()) + return; + selectedFile = QDir::toNativeSeparators(file); + this->accept(); +} + +void YaraRuleSelectionDialog::on_buttonSelect_clicked() +{ + if(!ui->listRules->selectedItems().size()) //no selection + return; + int selectedIndex = ui->listRules->row(ui->listRules->selectedItems().at(0)); + selectedFile = ruleFiles.at(selectedIndex).first; + this->accept(); +} + +void YaraRuleSelectionDialog::enumRulesDirectory() +{ + ruleFiles.clear(); + ui->listRules->clear(); + QDirIterator it(rulesDirectory, QDir::Files, QDirIterator::Subdirectories); + while(it.hasNext()) + { + it.next(); + ruleFiles.append(QPair(QDir::toNativeSeparators(it.filePath()), it.fileName())); + ui->listRules->addItem(it.fileName()); + } + ui->listRules->setCurrentRow(0); +} diff --git a/src/gui/Src/Gui/YaraRuleSelectionDialog.h b/src/gui/Src/Gui/YaraRuleSelectionDialog.h index 68caf8fe..a29e50f5 100644 --- a/src/gui/Src/Gui/YaraRuleSelectionDialog.h +++ b/src/gui/Src/Gui/YaraRuleSelectionDialog.h @@ -1,34 +1,34 @@ -#ifndef YARARULESELECTIONDIALOG_H -#define YARARULESELECTIONDIALOG_H - -#include - -namespace Ui -{ -class YaraRuleSelectionDialog; -} - -class YaraRuleSelectionDialog : public QDialog -{ - Q_OBJECT - -public: - explicit YaraRuleSelectionDialog(QWidget* parent = 0); - ~YaraRuleSelectionDialog(); - QString getSelectedFile(); - -private slots: - void on_buttonDirectory_clicked(); - void on_buttonFile_clicked(); - void on_buttonSelect_clicked(); - -private: - Ui::YaraRuleSelectionDialog* ui; - QList> ruleFiles; - QString rulesDirectory; - QString selectedFile; - - void enumRulesDirectory(); -}; - -#endif // YARARULESELECTIONDIALOG_H +#ifndef YARARULESELECTIONDIALOG_H +#define YARARULESELECTIONDIALOG_H + +#include + +namespace Ui +{ +class YaraRuleSelectionDialog; +} + +class YaraRuleSelectionDialog : public QDialog +{ + Q_OBJECT + +public: + explicit YaraRuleSelectionDialog(QWidget* parent = 0); + ~YaraRuleSelectionDialog(); + QString getSelectedFile(); + +private slots: + void on_buttonDirectory_clicked(); + void on_buttonFile_clicked(); + void on_buttonSelect_clicked(); + +private: + Ui::YaraRuleSelectionDialog* ui; + QList> ruleFiles; + QString rulesDirectory; + QString selectedFile; + + void enumRulesDirectory(); +}; + +#endif // YARARULESELECTIONDIALOG_H diff --git a/src/gui/Src/Imports.h b/src/gui/Src/Imports.h index a26d561e..91ae10ef 100644 --- a/src/gui/Src/Imports.h +++ b/src/gui/Src/Imports.h @@ -1,8 +1,8 @@ -#ifndef IMPORTS_H -#define IMPORTS_H - -#include "bridge\bridgemain.h" -#include "dbg\_dbgfunctions.h" -#include "dbg_types.h" - -#endif // IMPORTS_H +#ifndef IMPORTS_H +#define IMPORTS_H + +#include "bridge\bridgemain.h" +#include "dbg\_dbgfunctions.h" +#include "dbg_types.h" + +#endif // IMPORTS_H diff --git a/src/gui/Src/Memory/MemoryPage.cpp b/src/gui/Src/Memory/MemoryPage.cpp index 667ef84f..1f095f53 100644 --- a/src/gui/Src/Memory/MemoryPage.cpp +++ b/src/gui/Src/Memory/MemoryPage.cpp @@ -1,50 +1,50 @@ -#include "MemoryPage.h" - -MemoryPage::MemoryPage(duint parBase, duint parSize, QObject* parent) : QObject(parent), mBase(0), mSize(0) -{ - Q_UNUSED(parBase); - Q_UNUSED(parSize); -} - -bool MemoryPage::read(void* parDest, duint parRVA, duint parSize) const -{ - return DbgMemRead(mBase + parRVA, reinterpret_cast(parDest), parSize); -} - -bool MemoryPage::read(byte_t* parDest, duint parRVA, duint parSize) const -{ - return read(reinterpret_cast(parDest), parRVA, parSize); -} - -bool MemoryPage::write(const void* parDest, duint parRVA, duint parSize) -{ - bool ret = DbgFunctions()->MemPatch(mBase + parRVA, reinterpret_cast(parDest), parSize); - GuiUpdatePatches(); - return ret; -} - -bool MemoryPage::write(const byte_t* parDest, duint parRVA, duint parSize) -{ - return write(reinterpret_cast(parDest), parRVA, parSize); -} - -duint MemoryPage::getSize() const -{ - return mSize; -} - -duint MemoryPage::getBase() const -{ - return mBase; -} - -duint MemoryPage::va(dsint rva) const -{ - return mBase + rva; -} - -void MemoryPage::setAttributes(duint base, duint size) -{ - mBase = base; - mSize = size; -} +#include "MemoryPage.h" + +MemoryPage::MemoryPage(duint parBase, duint parSize, QObject* parent) : QObject(parent), mBase(0), mSize(0) +{ + Q_UNUSED(parBase); + Q_UNUSED(parSize); +} + +bool MemoryPage::read(void* parDest, duint parRVA, duint parSize) const +{ + return DbgMemRead(mBase + parRVA, reinterpret_cast(parDest), parSize); +} + +bool MemoryPage::read(byte_t* parDest, duint parRVA, duint parSize) const +{ + return read(reinterpret_cast(parDest), parRVA, parSize); +} + +bool MemoryPage::write(const void* parDest, duint parRVA, duint parSize) +{ + bool ret = DbgFunctions()->MemPatch(mBase + parRVA, reinterpret_cast(parDest), parSize); + GuiUpdatePatches(); + return ret; +} + +bool MemoryPage::write(const byte_t* parDest, duint parRVA, duint parSize) +{ + return write(reinterpret_cast(parDest), parRVA, parSize); +} + +duint MemoryPage::getSize() const +{ + return mSize; +} + +duint MemoryPage::getBase() const +{ + return mBase; +} + +duint MemoryPage::va(dsint rva) const +{ + return mBase + rva; +} + +void MemoryPage::setAttributes(duint base, duint size) +{ + mBase = base; + mSize = size; +} diff --git a/src/gui/Src/Memory/MemoryPage.h b/src/gui/Src/Memory/MemoryPage.h index aa1ef8a9..f17f8474 100644 --- a/src/gui/Src/Memory/MemoryPage.h +++ b/src/gui/Src/Memory/MemoryPage.h @@ -1,27 +1,27 @@ -#ifndef MEMORYPAGE_H -#define MEMORYPAGE_H - -#include -#include "Imports.h" - -class MemoryPage : public QObject -{ - Q_OBJECT -public: - explicit MemoryPage(duint parBase, duint parSize, QObject* parent = 0); - - bool read(void* parDest, duint parRVA, duint parSize) const; - bool read(byte_t* parDest, duint parRVA, duint parSize) const; - bool write(const void* parDest, duint parRVA, duint parSize); - bool write(const byte_t* parDest, duint parRVA, duint parSize); - duint getSize() const; - duint getBase() const; - duint va(dsint rva) const; - void setAttributes(duint base, duint size); - -private: - duint mBase; - duint mSize; -}; - -#endif // MEMORYPAGE_H +#ifndef MEMORYPAGE_H +#define MEMORYPAGE_H + +#include +#include "Imports.h" + +class MemoryPage : public QObject +{ + Q_OBJECT +public: + explicit MemoryPage(duint parBase, duint parSize, QObject* parent = 0); + + bool read(void* parDest, duint parRVA, duint parSize) const; + bool read(byte_t* parDest, duint parRVA, duint parSize) const; + bool write(const void* parDest, duint parRVA, duint parSize); + bool write(const byte_t* parDest, duint parRVA, duint parSize); + duint getSize() const; + duint getBase() const; + duint va(dsint rva) const; + void setAttributes(duint base, duint size); + +private: + duint mBase; + duint mSize; +}; + +#endif // MEMORYPAGE_H diff --git a/src/gui/Src/QEntropyView/Entropy.h b/src/gui/Src/QEntropyView/Entropy.h index a4e06d61..759c03e9 100644 --- a/src/gui/Src/QEntropyView/Entropy.h +++ b/src/gui/Src/QEntropyView/Entropy.h @@ -1,66 +1,66 @@ -#ifndef ENTROPY_H -#define ENTROPY_H - -#include -#include - -class Entropy -{ -public: - static double MeasureData(const unsigned char* data, int dataSize) - { - int occurrences[256] = {}; - for(int i = 0; i < dataSize; i++) - occurrences[data[i]]++; - double entropy = 0.0; - double logBase = log(256); - for(int i = 0; i < 256; i++) - { - if(occurrences[i] == 0) - continue; - double p = (double)occurrences[i] / (double)dataSize; - entropy += p * log(p) / logBase; - } - return -entropy; - } - - static double MeasureByte(const unsigned char* data, int dataSize, int index, unsigned char* block, int blockSize) - { - if(dataSize < blockSize) - return -1; - int start = index - blockSize / 2; - int end = index + blockSize / 2; - if(start < 0) - { - end += -start; - start = 0; - } - else if(end > dataSize) - { - start -= end - dataSize; - end = dataSize; - } - for(int i = start; i < end; i++) - block[i - start] = data[i]; - return MeasureData(block, blockSize); - } - - static void MeasurePoints(const unsigned char* data, int dataSize, int blockSize, std::vector & points, int pointCount) - { - points.clear(); - if(dataSize < pointCount) - return; - if(dataSize % pointCount != 0) - pointCount += dataSize % pointCount; - - unsigned char* block = new unsigned char[blockSize]; - int interval = dataSize / pointCount; - points.reserve(pointCount); - for(int i = 0; i < dataSize; i += interval) - points.push_back(MeasureByte(data, dataSize, i, block, blockSize)); - delete[] block; - } -}; - -#endif // ENTROPY_H - +#ifndef ENTROPY_H +#define ENTROPY_H + +#include +#include + +class Entropy +{ +public: + static double MeasureData(const unsigned char* data, int dataSize) + { + int occurrences[256] = {}; + for(int i = 0; i < dataSize; i++) + occurrences[data[i]]++; + double entropy = 0.0; + double logBase = log(256); + for(int i = 0; i < 256; i++) + { + if(occurrences[i] == 0) + continue; + double p = (double)occurrences[i] / (double)dataSize; + entropy += p * log(p) / logBase; + } + return -entropy; + } + + static double MeasureByte(const unsigned char* data, int dataSize, int index, unsigned char* block, int blockSize) + { + if(dataSize < blockSize) + return -1; + int start = index - blockSize / 2; + int end = index + blockSize / 2; + if(start < 0) + { + end += -start; + start = 0; + } + else if(end > dataSize) + { + start -= end - dataSize; + end = dataSize; + } + for(int i = start; i < end; i++) + block[i - start] = data[i]; + return MeasureData(block, blockSize); + } + + static void MeasurePoints(const unsigned char* data, int dataSize, int blockSize, std::vector & points, int pointCount) + { + points.clear(); + if(dataSize < pointCount) + return; + if(dataSize % pointCount != 0) + pointCount += dataSize % pointCount; + + unsigned char* block = new unsigned char[blockSize]; + int interval = dataSize / pointCount; + points.reserve(pointCount); + for(int i = 0; i < dataSize; i += interval) + points.push_back(MeasureByte(data, dataSize, i, block, blockSize)); + delete[] block; + } +}; + +#endif // ENTROPY_H + diff --git a/src/gui/Src/QEntropyView/QEntropyView.cpp b/src/gui/Src/QEntropyView/QEntropyView.cpp index 961c73e6..cc83afed 100644 --- a/src/gui/Src/QEntropyView/QEntropyView.cpp +++ b/src/gui/Src/QEntropyView/QEntropyView.cpp @@ -1,83 +1,83 @@ -#include "QEntropyView.h" -#include -#include "Entropy.h" - -QEntropyView::QEntropyView(QWidget* parent) : QGraphicsView(parent) -{ - mScene = new QGraphicsScene(this); -} - -void QEntropyView::InitializeGraph(int penSize) -{ - //initialize scene - qreal width = this->width() - 5; - qreal height = this->height() - 5; - mRect = QRectF(25, 10, width - 35, height - 20); - mPenSize = penSize; - mScene->clear(); - - //draw bounding box - mScene->addRect(QRectF(1, 1, width, height), QPen(Qt::black)); - - //draw scale - mScene->addLine(15, mRect.top(), 15, mRect.bottom(), QPen(Qt::black, 2)); - const int xBegin = 10; - const int xEnd = 20; - qreal intervalY = mRect.height() / 10; - for(int i = 0; i < 11; i++) - { - qreal y = mRect.top() + i * intervalY; - mScene->addLine(xBegin, y, xEnd, y, QPen(Qt::black, 2)); - } - - //set scene - setRenderHints(QPainter::Antialiasing); - setScene(mScene); -} - -void QEntropyView::AddGraph(const std::vector & points, QColor color) -{ - int pointCount = (int)points.size(); - if(!pointCount) - return; - qreal intervalX = mRect.width() / ((qreal)pointCount - 1); - qreal intervalY = mRect.height() / 1; - QPolygonF polyLine; - for(int i = 0; i < pointCount; i++) - { - qreal x = i * intervalX; - qreal y = points[i] * intervalY; - QPointF point(mRect.x() + x, mRect.bottom() - y); //y direction is inverted... - polyLine.append(point); - } - QPainterPath path; - path.addPolygon(polyLine); - mScene->addPath(path, QPen(color, mPenSize)); -} - -void QEntropyView::GraphFile(const QString & fileName, int blockSize, int pointCount, QColor color) -{ - QFile file(fileName); - if(!file.open(QIODevice::ReadOnly)) - return; - - QByteArray fileData = file.readAll(); - file.close(); - - GraphMemory((unsigned char*)fileData.constData(), fileData.size(), blockSize, pointCount, color); -} - -void QEntropyView::GraphMemory(const unsigned char* data, int dataSize, int blockSize, int pointCount, QColor color) -{ - std::vector points; - if(dataSize < blockSize) - { - blockSize = dataSize / 2; - if(!blockSize) - blockSize = 1; - } - if(dataSize < pointCount) - pointCount = (int)dataSize; - Entropy::MeasurePoints(data, dataSize, blockSize, points, pointCount); - AddGraph(points, color); -} +#include "QEntropyView.h" +#include +#include "Entropy.h" + +QEntropyView::QEntropyView(QWidget* parent) : QGraphicsView(parent) +{ + mScene = new QGraphicsScene(this); +} + +void QEntropyView::InitializeGraph(int penSize) +{ + //initialize scene + qreal width = this->width() - 5; + qreal height = this->height() - 5; + mRect = QRectF(25, 10, width - 35, height - 20); + mPenSize = penSize; + mScene->clear(); + + //draw bounding box + mScene->addRect(QRectF(1, 1, width, height), QPen(Qt::black)); + + //draw scale + mScene->addLine(15, mRect.top(), 15, mRect.bottom(), QPen(Qt::black, 2)); + const int xBegin = 10; + const int xEnd = 20; + qreal intervalY = mRect.height() / 10; + for(int i = 0; i < 11; i++) + { + qreal y = mRect.top() + i * intervalY; + mScene->addLine(xBegin, y, xEnd, y, QPen(Qt::black, 2)); + } + + //set scene + setRenderHints(QPainter::Antialiasing); + setScene(mScene); +} + +void QEntropyView::AddGraph(const std::vector & points, QColor color) +{ + int pointCount = (int)points.size(); + if(!pointCount) + return; + qreal intervalX = mRect.width() / ((qreal)pointCount - 1); + qreal intervalY = mRect.height() / 1; + QPolygonF polyLine; + for(int i = 0; i < pointCount; i++) + { + qreal x = i * intervalX; + qreal y = points[i] * intervalY; + QPointF point(mRect.x() + x, mRect.bottom() - y); //y direction is inverted... + polyLine.append(point); + } + QPainterPath path; + path.addPolygon(polyLine); + mScene->addPath(path, QPen(color, mPenSize)); +} + +void QEntropyView::GraphFile(const QString & fileName, int blockSize, int pointCount, QColor color) +{ + QFile file(fileName); + if(!file.open(QIODevice::ReadOnly)) + return; + + QByteArray fileData = file.readAll(); + file.close(); + + GraphMemory((unsigned char*)fileData.constData(), fileData.size(), blockSize, pointCount, color); +} + +void QEntropyView::GraphMemory(const unsigned char* data, int dataSize, int blockSize, int pointCount, QColor color) +{ + std::vector points; + if(dataSize < blockSize) + { + blockSize = dataSize / 2; + if(!blockSize) + blockSize = 1; + } + if(dataSize < pointCount) + pointCount = (int)dataSize; + Entropy::MeasurePoints(data, dataSize, blockSize, points, pointCount); + AddGraph(points, color); +} diff --git a/src/gui/Src/QEntropyView/QEntropyView.h b/src/gui/Src/QEntropyView/QEntropyView.h index 8e63ab99..84db8d2b 100644 --- a/src/gui/Src/QEntropyView/QEntropyView.h +++ b/src/gui/Src/QEntropyView/QEntropyView.h @@ -1,23 +1,23 @@ -#ifndef QENTROPYVIEW_H -#define QENTROPYVIEW_H - -#include -#include - -class QEntropyView : public QGraphicsView -{ - Q_OBJECT -public: - explicit QEntropyView(QWidget* parent = 0); - void InitializeGraph(int penSize = 1); - void AddGraph(const std::vector & points, QColor color = Qt::black); - void GraphFile(const QString & fileName, int blockSize, int pointCount, QColor = Qt::black); - void GraphMemory(const unsigned char* data, int dataSize, int blockSize, int pointCount, QColor = Qt::black); - -private: - QGraphicsScene* mScene; - QRectF mRect; - int mPenSize; -}; - -#endif // QENTROPYVIEW_H +#ifndef QENTROPYVIEW_H +#define QENTROPYVIEW_H + +#include +#include + +class QEntropyView : public QGraphicsView +{ + Q_OBJECT +public: + explicit QEntropyView(QWidget* parent = 0); + void InitializeGraph(int penSize = 1); + void AddGraph(const std::vector & points, QColor color = Qt::black); + void GraphFile(const QString & fileName, int blockSize, int pointCount, QColor = Qt::black); + void GraphMemory(const unsigned char* data, int dataSize, int blockSize, int pointCount, QColor = Qt::black); + +private: + QGraphicsScene* mScene; + QRectF mRect; + int mPenSize; +}; + +#endif // QENTROPYVIEW_H diff --git a/src/gui/Src/QHexEdit/ArrayCommand.cpp b/src/gui/Src/QHexEdit/ArrayCommand.cpp index 353450e4..a197538d 100644 --- a/src/gui/Src/QHexEdit/ArrayCommand.cpp +++ b/src/gui/Src/QHexEdit/ArrayCommand.cpp @@ -1,107 +1,107 @@ -#include "ArrayCommand.h" - -CharCommand::CharCommand(XByteArray* xData, Cmd cmd, int charPos, char newChar, QUndoCommand* parent) : QUndoCommand(parent) -{ - _xData = xData; - _charPos = charPos; - _newChar = newChar; - _cmd = cmd; - _oldChar = 0; -} - -bool CharCommand::mergeWith(const QUndoCommand* command) -{ - const CharCommand* nextCommand = static_cast(command); - bool result = false; - - if(_cmd != remove) - { - if(nextCommand->_cmd == replace) - if(nextCommand->_charPos == _charPos) - { - _newChar = nextCommand->_newChar; - result = true; - } - } - return result; -} - -void CharCommand::undo() -{ - switch(_cmd) - { - case insert: - _xData->remove(_charPos, 1); - break; - case replace: - _xData->replace(_charPos, _oldChar); - break; - case remove: - _xData->insert(_charPos, _oldChar); - break; - } -} - -void CharCommand::redo() -{ - switch(_cmd) - { - case insert: - _xData->insert(_charPos, _newChar); - break; - case replace: - _oldChar = _xData->data()[_charPos]; - _xData->replace(_charPos, _newChar); - break; - case remove: - _oldChar = _xData->data()[_charPos]; - _xData->remove(_charPos, 1); - break; - } -} - - - -ArrayCommand::ArrayCommand(XByteArray* xData, Cmd cmd, int baPos, QByteArray newBa, int len, QUndoCommand* parent) - : QUndoCommand(parent) -{ - _cmd = cmd; - _xData = xData; - _baPos = baPos; - _newBa = newBa; - _len = len; -} - -void ArrayCommand::undo() -{ - switch(_cmd) - { - case insert: - _xData->remove(_baPos, _newBa.length()); - break; - case replace: - _xData->replace(_baPos, _oldBa); - break; - case remove: - _xData->insert(_baPos, _oldBa); - break; - } -} - -void ArrayCommand::redo() -{ - switch(_cmd) - { - case insert: - _xData->insert(_baPos, _newBa); - break; - case replace: - _oldBa = _xData->data().mid(_baPos, _len); - _xData->replace(_baPos, _newBa); - break; - case remove: - _oldBa = _xData->data().mid(_baPos, _len); - _xData->remove(_baPos, _len); - break; - } -} +#include "ArrayCommand.h" + +CharCommand::CharCommand(XByteArray* xData, Cmd cmd, int charPos, char newChar, QUndoCommand* parent) : QUndoCommand(parent) +{ + _xData = xData; + _charPos = charPos; + _newChar = newChar; + _cmd = cmd; + _oldChar = 0; +} + +bool CharCommand::mergeWith(const QUndoCommand* command) +{ + const CharCommand* nextCommand = static_cast(command); + bool result = false; + + if(_cmd != remove) + { + if(nextCommand->_cmd == replace) + if(nextCommand->_charPos == _charPos) + { + _newChar = nextCommand->_newChar; + result = true; + } + } + return result; +} + +void CharCommand::undo() +{ + switch(_cmd) + { + case insert: + _xData->remove(_charPos, 1); + break; + case replace: + _xData->replace(_charPos, _oldChar); + break; + case remove: + _xData->insert(_charPos, _oldChar); + break; + } +} + +void CharCommand::redo() +{ + switch(_cmd) + { + case insert: + _xData->insert(_charPos, _newChar); + break; + case replace: + _oldChar = _xData->data()[_charPos]; + _xData->replace(_charPos, _newChar); + break; + case remove: + _oldChar = _xData->data()[_charPos]; + _xData->remove(_charPos, 1); + break; + } +} + + + +ArrayCommand::ArrayCommand(XByteArray* xData, Cmd cmd, int baPos, QByteArray newBa, int len, QUndoCommand* parent) + : QUndoCommand(parent) +{ + _cmd = cmd; + _xData = xData; + _baPos = baPos; + _newBa = newBa; + _len = len; +} + +void ArrayCommand::undo() +{ + switch(_cmd) + { + case insert: + _xData->remove(_baPos, _newBa.length()); + break; + case replace: + _xData->replace(_baPos, _oldBa); + break; + case remove: + _xData->insert(_baPos, _oldBa); + break; + } +} + +void ArrayCommand::redo() +{ + switch(_cmd) + { + case insert: + _xData->insert(_baPos, _newBa); + break; + case replace: + _oldBa = _xData->data().mid(_baPos, _len); + _xData->replace(_baPos, _newBa); + break; + case remove: + _oldBa = _xData->data().mid(_baPos, _len); + _xData->remove(_baPos, _len); + break; + } +} diff --git a/src/gui/Src/QHexEdit/ArrayCommand.h b/src/gui/Src/QHexEdit/ArrayCommand.h index b0257a53..bc43040d 100644 --- a/src/gui/Src/QHexEdit/ArrayCommand.h +++ b/src/gui/Src/QHexEdit/ArrayCommand.h @@ -1,50 +1,50 @@ -#ifndef ARRAYCOMMAND_H -#define ARRAYCOMMAND_H - -#include -#include "XByteArray.h" - -class CharCommand : public QUndoCommand -{ -public: - enum { Id = 1234 }; - enum Cmd {insert, remove, replace}; - - CharCommand(XByteArray* xData, Cmd cmd, int charPos, char newChar, - QUndoCommand* parent = 0); - - void undo(); - void redo(); - bool mergeWith(const QUndoCommand* command); - int id() const - { - return Id; - } - -private: - XByteArray* _xData; - int _charPos; - char _newChar; - char _oldChar; - Cmd _cmd; -}; - -class ArrayCommand : public QUndoCommand -{ -public: - enum Cmd {insert, remove, replace}; - ArrayCommand(XByteArray* xData, Cmd cmd, int baPos, QByteArray newBa = QByteArray(), int len = 0, QUndoCommand* parent = 0); - void undo(); - void redo(); - -private: - Cmd _cmd; - XByteArray* _xData; - int _baPos; - int _len; - QByteArray _wasChanged; - QByteArray _newBa; - QByteArray _oldBa; -}; - -#endif // ARRAYCOMMAND_H +#ifndef ARRAYCOMMAND_H +#define ARRAYCOMMAND_H + +#include +#include "XByteArray.h" + +class CharCommand : public QUndoCommand +{ +public: + enum { Id = 1234 }; + enum Cmd {insert, remove, replace}; + + CharCommand(XByteArray* xData, Cmd cmd, int charPos, char newChar, + QUndoCommand* parent = 0); + + void undo(); + void redo(); + bool mergeWith(const QUndoCommand* command); + int id() const + { + return Id; + } + +private: + XByteArray* _xData; + int _charPos; + char _newChar; + char _oldChar; + Cmd _cmd; +}; + +class ArrayCommand : public QUndoCommand +{ +public: + enum Cmd {insert, remove, replace}; + ArrayCommand(XByteArray* xData, Cmd cmd, int baPos, QByteArray newBa = QByteArray(), int len = 0, QUndoCommand* parent = 0); + void undo(); + void redo(); + +private: + Cmd _cmd; + XByteArray* _xData; + int _baPos; + int _len; + QByteArray _wasChanged; + QByteArray _newBa; + QByteArray _oldBa; +}; + +#endif // ARRAYCOMMAND_H diff --git a/src/gui/Src/QHexEdit/QHexEdit.cpp b/src/gui/Src/QHexEdit/QHexEdit.cpp index 571d7e3c..db47e07f 100644 --- a/src/gui/Src/QHexEdit/QHexEdit.cpp +++ b/src/gui/Src/QHexEdit/QHexEdit.cpp @@ -1,258 +1,258 @@ -#include - -#include "QHexEdit.h" - -QHexEdit::QHexEdit(QWidget* parent) : QScrollArea(parent) -{ - qHexEdit_p = new QHexEditPrivate(this); - setWidget(qHexEdit_p); - setWidgetResizable(true); - - connect(qHexEdit_p, SIGNAL(currentAddressChanged(int)), this, SIGNAL(currentAddressChanged(int))); - connect(qHexEdit_p, SIGNAL(currentSizeChanged(int)), this, SIGNAL(currentSizeChanged(int))); - connect(qHexEdit_p, SIGNAL(dataChanged()), this, SIGNAL(dataChanged())); - connect(qHexEdit_p, SIGNAL(overwriteModeChanged(bool)), this, SIGNAL(overwriteModeChanged(bool))); - setFocusPolicy(Qt::NoFocus); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); -} - -void QHexEdit::setEditFont(const QFont & font) -{ - qHexEdit_p->setFont(font); -} - -void QHexEdit::insert(int i, const QByteArray & ba, const QByteArray & mask) -{ - qHexEdit_p->insert(i, ba, mask); -} - -void QHexEdit::insert(int i, char ch, char mask) -{ - qHexEdit_p->insert(i, ch, mask); -} - -void QHexEdit::remove(int pos, int len) -{ - qHexEdit_p->remove(pos, len); -} - -void QHexEdit::replace(int pos, int len, const QByteArray & after, const QByteArray & mask) -{ - qHexEdit_p->replace(pos, len, after, mask); -} - -void QHexEdit::fill(int index, const QString & pattern) -{ - QString convert; - for(int i = 0; i < pattern.length(); i++) - { - QChar ch = pattern[i].toLower(); - if((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (wildcardEnabled() && ch == '?')) - convert += ch; - } - if(convert.length() % 2) //odd length - convert += "0"; - QByteArray data(convert.length(), 0); - QByteArray mask(data.length(), 0); - for(int i = 0; i < convert.length(); i++) - { - if(convert[i] == '?') - { - data[i] = '0'; - mask[i] = '1'; - } - else - { - data[i] = convert[i].toLatin1(); - mask[i] = '0'; - } - } - qHexEdit_p->fill(index, QByteArray().fromHex(data), QByteArray().fromHex(mask)); -} - -void QHexEdit::redo() -{ - qHexEdit_p->redo(); -} - -void QHexEdit::undo() -{ - qHexEdit_p->undo(); -} - -void QHexEdit::setCursorPosition(int cursorPos) -{ - // cursorPos in QHexEditPrivate is the position of the textcoursor without - // blanks, means bytePos*2 - qHexEdit_p->setCursorPos(cursorPos * 2); -} - -int QHexEdit::cursorPosition() -{ - return qHexEdit_p->cursorPos() / 2; -} - -void QHexEdit::setData(const QByteArray & data, const QByteArray & mask) -{ - qHexEdit_p->setData(data, mask); -} - -void QHexEdit::setData(const QByteArray & data) -{ - qHexEdit_p->setData(data, QByteArray(data.size(), 0)); -} - -void QHexEdit::setData(const QString & pattern) -{ - QString convert; - for(int i = 0; i < pattern.length(); i++) - { - QChar ch = pattern[i].toLower(); - if((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (wildcardEnabled() && ch == '?')) - convert += ch; - } - if(convert.length() % 2) //odd length - convert += "0"; - QByteArray data(convert.length(), 0); - QByteArray mask(data.length(), 0); - for(int i = 0; i < convert.length(); i++) - { - if(convert[i] == '?') - { - data[i] = '0'; - mask[i] = '1'; - } - else - { - data[i] = convert[i].toLatin1(); - mask[i] = '0'; - } - } - qHexEdit_p->setData(QByteArray().fromHex(data), QByteArray().fromHex(mask)); -} - -QByteArray QHexEdit::applyMaskedData(const QByteArray & data) -{ - QByteArray ret = data.toHex(); - QByteArray _data = this->data().toHex(); - QByteArray _mask = this->mask().toHex(); - if(ret.size() != _data.size()) - ret.resize(_data.size()); - for(int i = 0; i < _data.size(); i++) - { - if(_mask[i] != '1') - ret[i] = _data[i]; - } - return QByteArray().fromHex(ret); -} - -QByteArray QHexEdit::data() -{ - return qHexEdit_p->data(); -} - -QByteArray QHexEdit::mask() -{ - return qHexEdit_p->mask(); -} - -QString QHexEdit::pattern(bool space) -{ - QString result; - for(int i = 0; i < this->data().size(); i++) - { - QString byte = this->data().mid(i, 1).toHex(); - QString mask = this->mask().mid(i, 1).toHex(); - if(mask[0] == '1') - result += "?"; - else - result += byte[0]; - if(mask[1] == '1') - result += "?"; - else - result += byte[1]; - if(space) - result += " "; - } - return result.toUpper().trimmed(); -} - -void QHexEdit::setOverwriteMode(bool overwriteMode) -{ - qHexEdit_p->setOverwriteMode(overwriteMode); -} - -bool QHexEdit::overwriteMode() -{ - return qHexEdit_p->overwriteMode(); -} - -void QHexEdit::setWildcardEnabled(bool enabled) -{ - qHexEdit_p->setWildcardEnabled(enabled); -} - -bool QHexEdit::wildcardEnabled() -{ - return qHexEdit_p->wildcardEnabled(); -} - -void QHexEdit::setKeepSize(bool enabled) -{ - qHexEdit_p->setKeepSize(enabled); -} - -bool QHexEdit::keepSize() -{ - return qHexEdit_p->keepSize(); -} - -void QHexEdit::setTextColor(QColor color) -{ - qHexEdit_p->setTextColor(color); -} - -void QHexEdit::setHorizontalSpacing(int x) -{ - qHexEdit_p->setHorizontalSpacing(x); -} - -int QHexEdit::horizontalSpacing() -{ - return qHexEdit_p->horizontalSpacing(); -} - -QColor QHexEdit::textColor() -{ - return qHexEdit_p->textColor(); -} - -void QHexEdit::setWildcardColor(QColor color) -{ - qHexEdit_p->setWildcardColor(color); -} - -QColor QHexEdit::wildcardColor() -{ - return qHexEdit_p->wildcardColor(); -} - -void QHexEdit::setBackgroundColor(QColor color) -{ - qHexEdit_p->setBackgroundColor(color); -} - -QColor QHexEdit::backgroundColor() -{ - return qHexEdit_p->backgroundColor(); -} - -void QHexEdit::setSelectionColor(QColor color) -{ - qHexEdit_p->setSelectionColor(color); -} - -QColor QHexEdit::selectionColor() -{ - return qHexEdit_p->selectionColor(); -} +#include + +#include "QHexEdit.h" + +QHexEdit::QHexEdit(QWidget* parent) : QScrollArea(parent) +{ + qHexEdit_p = new QHexEditPrivate(this); + setWidget(qHexEdit_p); + setWidgetResizable(true); + + connect(qHexEdit_p, SIGNAL(currentAddressChanged(int)), this, SIGNAL(currentAddressChanged(int))); + connect(qHexEdit_p, SIGNAL(currentSizeChanged(int)), this, SIGNAL(currentSizeChanged(int))); + connect(qHexEdit_p, SIGNAL(dataChanged()), this, SIGNAL(dataChanged())); + connect(qHexEdit_p, SIGNAL(overwriteModeChanged(bool)), this, SIGNAL(overwriteModeChanged(bool))); + setFocusPolicy(Qt::NoFocus); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); +} + +void QHexEdit::setEditFont(const QFont & font) +{ + qHexEdit_p->setFont(font); +} + +void QHexEdit::insert(int i, const QByteArray & ba, const QByteArray & mask) +{ + qHexEdit_p->insert(i, ba, mask); +} + +void QHexEdit::insert(int i, char ch, char mask) +{ + qHexEdit_p->insert(i, ch, mask); +} + +void QHexEdit::remove(int pos, int len) +{ + qHexEdit_p->remove(pos, len); +} + +void QHexEdit::replace(int pos, int len, const QByteArray & after, const QByteArray & mask) +{ + qHexEdit_p->replace(pos, len, after, mask); +} + +void QHexEdit::fill(int index, const QString & pattern) +{ + QString convert; + for(int i = 0; i < pattern.length(); i++) + { + QChar ch = pattern[i].toLower(); + if((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (wildcardEnabled() && ch == '?')) + convert += ch; + } + if(convert.length() % 2) //odd length + convert += "0"; + QByteArray data(convert.length(), 0); + QByteArray mask(data.length(), 0); + for(int i = 0; i < convert.length(); i++) + { + if(convert[i] == '?') + { + data[i] = '0'; + mask[i] = '1'; + } + else + { + data[i] = convert[i].toLatin1(); + mask[i] = '0'; + } + } + qHexEdit_p->fill(index, QByteArray().fromHex(data), QByteArray().fromHex(mask)); +} + +void QHexEdit::redo() +{ + qHexEdit_p->redo(); +} + +void QHexEdit::undo() +{ + qHexEdit_p->undo(); +} + +void QHexEdit::setCursorPosition(int cursorPos) +{ + // cursorPos in QHexEditPrivate is the position of the textcoursor without + // blanks, means bytePos*2 + qHexEdit_p->setCursorPos(cursorPos * 2); +} + +int QHexEdit::cursorPosition() +{ + return qHexEdit_p->cursorPos() / 2; +} + +void QHexEdit::setData(const QByteArray & data, const QByteArray & mask) +{ + qHexEdit_p->setData(data, mask); +} + +void QHexEdit::setData(const QByteArray & data) +{ + qHexEdit_p->setData(data, QByteArray(data.size(), 0)); +} + +void QHexEdit::setData(const QString & pattern) +{ + QString convert; + for(int i = 0; i < pattern.length(); i++) + { + QChar ch = pattern[i].toLower(); + if((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (wildcardEnabled() && ch == '?')) + convert += ch; + } + if(convert.length() % 2) //odd length + convert += "0"; + QByteArray data(convert.length(), 0); + QByteArray mask(data.length(), 0); + for(int i = 0; i < convert.length(); i++) + { + if(convert[i] == '?') + { + data[i] = '0'; + mask[i] = '1'; + } + else + { + data[i] = convert[i].toLatin1(); + mask[i] = '0'; + } + } + qHexEdit_p->setData(QByteArray().fromHex(data), QByteArray().fromHex(mask)); +} + +QByteArray QHexEdit::applyMaskedData(const QByteArray & data) +{ + QByteArray ret = data.toHex(); + QByteArray _data = this->data().toHex(); + QByteArray _mask = this->mask().toHex(); + if(ret.size() != _data.size()) + ret.resize(_data.size()); + for(int i = 0; i < _data.size(); i++) + { + if(_mask[i] != '1') + ret[i] = _data[i]; + } + return QByteArray().fromHex(ret); +} + +QByteArray QHexEdit::data() +{ + return qHexEdit_p->data(); +} + +QByteArray QHexEdit::mask() +{ + return qHexEdit_p->mask(); +} + +QString QHexEdit::pattern(bool space) +{ + QString result; + for(int i = 0; i < this->data().size(); i++) + { + QString byte = this->data().mid(i, 1).toHex(); + QString mask = this->mask().mid(i, 1).toHex(); + if(mask[0] == '1') + result += "?"; + else + result += byte[0]; + if(mask[1] == '1') + result += "?"; + else + result += byte[1]; + if(space) + result += " "; + } + return result.toUpper().trimmed(); +} + +void QHexEdit::setOverwriteMode(bool overwriteMode) +{ + qHexEdit_p->setOverwriteMode(overwriteMode); +} + +bool QHexEdit::overwriteMode() +{ + return qHexEdit_p->overwriteMode(); +} + +void QHexEdit::setWildcardEnabled(bool enabled) +{ + qHexEdit_p->setWildcardEnabled(enabled); +} + +bool QHexEdit::wildcardEnabled() +{ + return qHexEdit_p->wildcardEnabled(); +} + +void QHexEdit::setKeepSize(bool enabled) +{ + qHexEdit_p->setKeepSize(enabled); +} + +bool QHexEdit::keepSize() +{ + return qHexEdit_p->keepSize(); +} + +void QHexEdit::setTextColor(QColor color) +{ + qHexEdit_p->setTextColor(color); +} + +void QHexEdit::setHorizontalSpacing(int x) +{ + qHexEdit_p->setHorizontalSpacing(x); +} + +int QHexEdit::horizontalSpacing() +{ + return qHexEdit_p->horizontalSpacing(); +} + +QColor QHexEdit::textColor() +{ + return qHexEdit_p->textColor(); +} + +void QHexEdit::setWildcardColor(QColor color) +{ + qHexEdit_p->setWildcardColor(color); +} + +QColor QHexEdit::wildcardColor() +{ + return qHexEdit_p->wildcardColor(); +} + +void QHexEdit::setBackgroundColor(QColor color) +{ + qHexEdit_p->setBackgroundColor(color); +} + +QColor QHexEdit::backgroundColor() +{ + return qHexEdit_p->backgroundColor(); +} + +void QHexEdit::setSelectionColor(QColor color) +{ + qHexEdit_p->setSelectionColor(color); +} + +QColor QHexEdit::selectionColor() +{ + return qHexEdit_p->selectionColor(); +} diff --git a/src/gui/Src/QHexEdit/QHexEdit.h b/src/gui/Src/QHexEdit/QHexEdit.h index 481d9381..762c560a 100644 --- a/src/gui/Src/QHexEdit/QHexEdit.h +++ b/src/gui/Src/QHexEdit/QHexEdit.h @@ -1,64 +1,64 @@ -#ifndef QHEXEDIT_H -#define QHEXEDIT_H - -#include -#include -#include "QHexEditPrivate.h" - -class QHexEdit : public QScrollArea -{ - Q_OBJECT -public: - QHexEdit(QWidget* parent = 0); - - //data management - void setData(const QByteArray & data, const QByteArray & mask); - void setData(const QByteArray & data); - void setData(const QString & pattern); - QByteArray applyMaskedData(const QByteArray & data); - QByteArray data(); - QByteArray mask(); - QString pattern(bool space = false); - void insert(int i, const QByteArray & ba, const QByteArray & mask); - void insert(int i, char ch, char mask); - void remove(int pos, int len = 1); - void replace(int pos, int len, const QByteArray & after, const QByteArray & mask); - void fill(int index, const QString & pattern); - - //properties - void setCursorPosition(int cusorPos); - int cursorPosition(); - void setOverwriteMode(bool overwriteMode); - bool overwriteMode(); - void setWildcardEnabled(bool enabled); - bool wildcardEnabled(); - void setKeepSize(bool enabled); - bool keepSize(); - void setHorizontalSpacing(int x); - int horizontalSpacing(); - void setTextColor(QColor color); - QColor textColor(); - void setWildcardColor(QColor color); - QColor wildcardColor(); - void setBackgroundColor(QColor color); - QColor backgroundColor(); - void setSelectionColor(QColor color); - QColor selectionColor(); - void setEditFont(const QFont & font); - -public slots: - void redo(); - void undo(); - -signals: - void currentAddressChanged(int address); - void currentSizeChanged(int size); - void dataChanged(); - void overwriteModeChanged(bool state); - -private: - QHexEditPrivate* qHexEdit_p; -}; - -#endif - +#ifndef QHEXEDIT_H +#define QHEXEDIT_H + +#include +#include +#include "QHexEditPrivate.h" + +class QHexEdit : public QScrollArea +{ + Q_OBJECT +public: + QHexEdit(QWidget* parent = 0); + + //data management + void setData(const QByteArray & data, const QByteArray & mask); + void setData(const QByteArray & data); + void setData(const QString & pattern); + QByteArray applyMaskedData(const QByteArray & data); + QByteArray data(); + QByteArray mask(); + QString pattern(bool space = false); + void insert(int i, const QByteArray & ba, const QByteArray & mask); + void insert(int i, char ch, char mask); + void remove(int pos, int len = 1); + void replace(int pos, int len, const QByteArray & after, const QByteArray & mask); + void fill(int index, const QString & pattern); + + //properties + void setCursorPosition(int cusorPos); + int cursorPosition(); + void setOverwriteMode(bool overwriteMode); + bool overwriteMode(); + void setWildcardEnabled(bool enabled); + bool wildcardEnabled(); + void setKeepSize(bool enabled); + bool keepSize(); + void setHorizontalSpacing(int x); + int horizontalSpacing(); + void setTextColor(QColor color); + QColor textColor(); + void setWildcardColor(QColor color); + QColor wildcardColor(); + void setBackgroundColor(QColor color); + QColor backgroundColor(); + void setSelectionColor(QColor color); + QColor selectionColor(); + void setEditFont(const QFont & font); + +public slots: + void redo(); + void undo(); + +signals: + void currentAddressChanged(int address); + void currentSizeChanged(int size); + void dataChanged(); + void overwriteModeChanged(bool state); + +private: + QHexEditPrivate* qHexEdit_p; +}; + +#endif + diff --git a/src/gui/Src/QHexEdit/QHexEditPrivate.cpp b/src/gui/Src/QHexEdit/QHexEditPrivate.cpp index 971d8498..35de9149 100644 --- a/src/gui/Src/QHexEdit/QHexEditPrivate.cpp +++ b/src/gui/Src/QHexEdit/QHexEditPrivate.cpp @@ -1,909 +1,909 @@ -#include "QHexEditPrivate.h" -#include -#include -#include -#include "ArrayCommand.h" - -const int HEXCHARS_IN_LINE = 47; -const int BYTES_PER_LINE = 16; - -QHexEditPrivate::QHexEditPrivate(QScrollArea* parent) : QWidget(parent) -{ - _undoDataStack = new QUndoStack(this); - _undoMaskStack = new QUndoStack(this); - - _scrollArea = parent; - setOverwriteMode(true); - - QFont font("Monospace", 8, QFont::Normal, false); - font.setFixedPitch(true); - font.setStyleHint(QFont::Monospace); - this->setFont(font); - - _size = 0; - _horizonalSpacing = 3; - resetSelection(0); - setCursorPos(0); - - setFocusPolicy(Qt::StrongFocus); - - connect(&_cursorTimer, SIGNAL(timeout()), this, SLOT(updateCursor())); - _cursorTimer.setInterval(500); - _cursorTimer.start(); - - _textColor = QColor("#000000"); - _wildcardColor = QColor("#FF0000"); - _backgroundColor = QColor("#FFF8F0"); - _selectionColor = QColor("#C0C0C0"); - _overwriteMode = false; - _wildcardEnabled = true; - _keepSize = false; -} - -void QHexEditPrivate::setData(const QByteArray & data, const QByteArray & mask) -{ - _xData.setData(data); - _xMask.setData(mask); - _undoDataStack->clear(); - _undoMaskStack->clear(); - _initSize = _xData.size(); - adjust(); - setCursorPos(0); - emit dataChanged(); -} - -QByteArray QHexEditPrivate::data() -{ - return _xData.data(); -} - -QByteArray QHexEditPrivate::mask() -{ - return _xMask.data(); -} - -void QHexEditPrivate::insert(int index, const QByteArray & ba, const QByteArray & mask) -{ - if(ba.length() > 0) - { - if(_overwriteMode) - { - _undoDataStack->push(new ArrayCommand(&_xData, ArrayCommand::replace, index, ba, ba.length())); - _undoMaskStack->push(new ArrayCommand(&_xMask, ArrayCommand::replace, index, mask, mask.length())); - emit dataChanged(); - } - else - { - _undoDataStack->push(new ArrayCommand(&_xData, ArrayCommand::insert, index, ba, ba.length())); - _undoMaskStack->push(new ArrayCommand(&_xMask, ArrayCommand::insert, index, mask, mask.length())); - emit dataChanged(); - } - } -} - -void QHexEditPrivate::insert(int index, char ch, char mask) -{ - _undoDataStack->push(new CharCommand(&_xData, CharCommand::insert, index, ch)); - _undoMaskStack->push(new CharCommand(&_xMask, CharCommand::insert, index, mask)); - emit dataChanged(); -} - -void QHexEditPrivate::remove(int index, int len) -{ - if(len > 0) - { - if(len == 1) - { - if(_overwriteMode) - { - _undoDataStack->push(new CharCommand(&_xData, CharCommand::replace, index, char(0))); - _undoMaskStack->push(new CharCommand(&_xMask, CharCommand::replace, index, char(0))); - emit dataChanged(); - } - else - { - _undoDataStack->push(new CharCommand(&_xData, CharCommand::remove, index, char(0))); - _undoMaskStack->push(new CharCommand(&_xMask, CharCommand::remove, index, char(0))); - emit dataChanged(); - } - } - else - { - QByteArray ba = QByteArray(len, char(0)); - if(_overwriteMode) - { - _undoDataStack->push(new ArrayCommand(&_xData, ArrayCommand::replace, index, ba, ba.length())); - _undoMaskStack->push(new ArrayCommand(&_xMask, ArrayCommand::replace, index, ba, ba.length())); - emit dataChanged(); - } - else - { - _undoDataStack->push(new ArrayCommand(&_xData, ArrayCommand::remove, index, ba, len)); - _undoMaskStack->push(new ArrayCommand(&_xMask, ArrayCommand::remove, index, ba, len)); - emit dataChanged(); - } - } - } -} - -void QHexEditPrivate::replace(int index, char ch, char mask) -{ - _undoDataStack->push(new CharCommand(&_xData, CharCommand::replace, index, ch)); - _undoMaskStack->push(new CharCommand(&_xMask, CharCommand::replace, index, mask)); - resetSelection(); - emit dataChanged(); -} - -void QHexEditPrivate::replace(int index, const QByteArray & ba, const QByteArray & mask) -{ - _undoDataStack->push(new ArrayCommand(&_xData, ArrayCommand::replace, index, ba, ba.length())); - _undoMaskStack->push(new ArrayCommand(&_xMask, ArrayCommand::replace, index, mask, mask.length())); - resetSelection(); - emit dataChanged(); -} - -void QHexEditPrivate::replace(int pos, int len, const QByteArray & after, const QByteArray & mask) -{ - _undoDataStack->push(new ArrayCommand(&_xData, ArrayCommand::replace, pos, after, len)); - _undoMaskStack->push(new ArrayCommand(&_xMask, ArrayCommand::replace, pos, mask, len)); - resetSelection(); - emit dataChanged(); -} - -void QHexEditPrivate::fill(int index, const QByteArray & ba, const QByteArray & mask) -{ - int dataSize = _xData.size(); - if(index >= dataSize) - return; - int repeat = dataSize / ba.size() + 1; - QByteArray fillData = ba.repeated(repeat); - fillData.resize(dataSize); - fillData = fillData.toHex(); - QByteArray fillMask = mask.repeated(repeat); - fillMask.resize(dataSize); - fillMask = fillMask.toHex(); - QByteArray origData = _xData.data().mid(index).toHex(); - for(int i = 0; i < dataSize * 2; i++) - if(fillMask[i] == '1') - fillData[i] = origData[i]; - this->replace(index, QByteArray().fromHex(fillData), QByteArray().fromHex(fillMask)); -} - -void QHexEditPrivate::setOverwriteMode(bool overwriteMode) -{ - _overwriteMode = overwriteMode; -} - -bool QHexEditPrivate::overwriteMode() -{ - return _overwriteMode; -} - -void QHexEditPrivate::setWildcardEnabled(bool enabled) -{ - _wildcardEnabled = enabled; -} - -bool QHexEditPrivate::wildcardEnabled() -{ - return _wildcardEnabled; -} - -void QHexEditPrivate::setKeepSize(bool enabled) -{ - _keepSize = enabled; -} - -bool QHexEditPrivate::keepSize() -{ - return _keepSize; -} - -void QHexEditPrivate::setHorizontalSpacing(int x) -{ - _horizonalSpacing = x; - adjust(); - setCursorPos(cursorPos()); - this->repaint(); -} - -int QHexEditPrivate::horizontalSpacing() -{ - return _horizonalSpacing; -} - -void QHexEditPrivate::setTextColor(QColor color) -{ - _textColor = color; -} - -QColor QHexEditPrivate::textColor() -{ - return _textColor; -} - -void QHexEditPrivate::setWildcardColor(QColor color) -{ - _wildcardColor = color; -} - -QColor QHexEditPrivate::wildcardColor() -{ - return _wildcardColor; -} - -void QHexEditPrivate::setBackgroundColor(QColor color) -{ - _backgroundColor = color; -} - -QColor QHexEditPrivate::backgroundColor() -{ - return _backgroundColor; -} - -void QHexEditPrivate::setSelectionColor(QColor color) -{ - _selectionColor = color; -} - -QColor QHexEditPrivate::selectionColor() -{ - return _selectionColor; -} - -void QHexEditPrivate::redo() -{ - if(!_undoDataStack->canRedo() || !_undoMaskStack->canRedo()) - return; - _undoDataStack->redo(); - _undoMaskStack->redo(); - emit dataChanged(); - setCursorPos(_cursorPosition); - update(); -} - -void QHexEditPrivate::undo() -{ - if(!_undoDataStack->canUndo() || !_undoMaskStack->canUndo()) - return; - _undoDataStack->undo(); - _undoMaskStack->undo(); - emit dataChanged(); - setCursorPos(_cursorPosition); - update(); -} - -void QHexEditPrivate::focusInEvent(QFocusEvent* event) -{ - ensureVisible(); - QWidget::focusInEvent(event); -} - -void QHexEditPrivate::resizeEvent(QResizeEvent* event) -{ - adjust(); - QWidget::resizeEvent(event); -} - -void QHexEditPrivate::keyPressEvent(QKeyEvent* event) -{ - int charX = (_cursorX - _xPosHex) / _charWidth; - int posX = (charX / 3) * 2 + (charX % 3); - int posBa = (_cursorY / _charHeight) * BYTES_PER_LINE + posX / 2; - - - /*****************************************************************************/ - /* Cursor movements */ - /*****************************************************************************/ - - if(event->matches(QKeySequence::MoveToNextChar)) - { - setCursorPos(_cursorPosition + 1); - resetSelection(_cursorPosition); - } - if(event->matches(QKeySequence::MoveToPreviousChar)) - { - setCursorPos(_cursorPosition - 1); - resetSelection(_cursorPosition); - } - if(event->matches(QKeySequence::MoveToEndOfLine)) - { - setCursorPos(_cursorPosition | (2 * BYTES_PER_LINE - 1)); - resetSelection(_cursorPosition); - } - if(event->matches(QKeySequence::MoveToStartOfLine)) - { - setCursorPos(_cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE))); - resetSelection(_cursorPosition); - } - if(event->matches(QKeySequence::MoveToPreviousLine)) - { - setCursorPos(_cursorPosition - (2 * BYTES_PER_LINE)); - resetSelection(_cursorPosition); - } - if(event->matches(QKeySequence::MoveToNextLine)) - { - setCursorPos(_cursorPosition + (2 * BYTES_PER_LINE)); - resetSelection(_cursorPosition); - } - - if(event->matches(QKeySequence::MoveToNextPage)) - { - setCursorPos(_cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE)); - resetSelection(_cursorPosition); - } - if(event->matches(QKeySequence::MoveToPreviousPage)) - { - setCursorPos(_cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE)); - resetSelection(_cursorPosition); - } - if(event->matches(QKeySequence::MoveToEndOfDocument)) - { - setCursorPos(_xData.size() * 2); - resetSelection(_cursorPosition); - } - if(event->matches(QKeySequence::MoveToStartOfDocument)) - { - setCursorPos(0); - resetSelection(_cursorPosition); - } - - /*****************************************************************************/ - /* Select commands */ - /*****************************************************************************/ - if(event->matches(QKeySequence::SelectAll)) - { - resetSelection(0); - setSelection(2 * _xData.size() + 1); - } - if(event->matches(QKeySequence::SelectNextChar)) - { - int pos = _cursorPosition + 1; - setCursorPos(pos); - setSelection(pos); - } - if(event->matches(QKeySequence::SelectPreviousChar)) - { - int pos = _cursorPosition - 1; - setSelection(pos); - setCursorPos(pos); - } - if(event->matches(QKeySequence::SelectEndOfLine)) - { - int pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)) + (2 * BYTES_PER_LINE); - setCursorPos(pos); - setSelection(pos); - } - if(event->matches(QKeySequence::SelectStartOfLine)) - { - int pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)); - setCursorPos(pos); - setSelection(pos); - } - if(event->matches(QKeySequence::SelectPreviousLine)) - { - int pos = _cursorPosition - (2 * BYTES_PER_LINE); - setCursorPos(pos); - setSelection(pos); - } - if(event->matches(QKeySequence::SelectNextLine)) - { - int pos = _cursorPosition + (2 * BYTES_PER_LINE); - setCursorPos(pos); - setSelection(pos); - } - - if(event->matches(QKeySequence::SelectNextPage)) - { - int pos = _cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE); - setCursorPos(pos); - setSelection(pos); - } - if(event->matches(QKeySequence::SelectPreviousPage)) - { - int pos = _cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE); - setCursorPos(pos); - setSelection(pos); - } - if(event->matches(QKeySequence::SelectEndOfDocument)) - { - int pos = _xData.size() * 2; - setCursorPos(pos); - setSelection(pos); - } - if(event->matches(QKeySequence::SelectStartOfDocument)) - { - int pos = 0; - setCursorPos(pos); - setSelection(pos); - } - - /*****************************************************************************/ - /* Edit Commands */ - /*****************************************************************************/ - /* Hex input */ - int key = int(event->text().toLower()[0].toLatin1()); - if((key >= '0' && key <= '9') || (key >= 'a' && key <= 'f') || (_wildcardEnabled && key == '?')) - { - if(getSelectionBegin() != getSelectionEnd()) - { - posBa = getSelectionBegin(); - remove(posBa, getSelectionEnd() - posBa); - setCursorPos(2 * posBa); - resetSelection(2 * posBa); - } - - // If insert mode, then insert a byte - if(_overwriteMode == false) - { - if(_keepSize && _xData.size() >= _initSize) - { - QWidget::keyPressEvent(event); - return; - } - if((charX % 3) == 0) - insert(posBa, char(0), char(0)); - } - - // Change content - if(_xData.size() > 0) - { - QByteArray hexMask = _xMask.data().mid(posBa, 1).toHex(); - QByteArray hexValue = _xData.data().mid(posBa, 1).toHex(); - if(key == '?') //wildcard - { - if((charX % 3) == 0) - hexMask[0] = '1'; - else - hexMask[1] = '1'; - } - else - { - if((charX % 3) == 0) - { - hexValue[0] = key; - hexMask[0] = '0'; - } - else - { - hexValue[1] = key; - hexMask[1] = '0'; - } - } - replace(posBa, QByteArray().fromHex(hexValue)[0], QByteArray().fromHex(hexMask)[0]); - - setCursorPos(_cursorPosition + 1); - resetSelection(_cursorPosition); - } - } - - /* Cut & Paste */ - if(event->matches(QKeySequence::Cut)) - { - QString result; - for(int idx = getSelectionBegin(); idx < getSelectionEnd(); idx++) - { - QString byte = _xData.data().mid(idx, 1).toHex(); - QString mask = _xMask.data().mid(idx, 1).toHex(); - if(mask[0] == '1') - result += "?"; - else - result += byte[0]; - if(mask[1] == '1') - result += "?"; - else - result += byte[1]; - result += " "; - } - remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); - QClipboard* clipboard = QApplication::clipboard(); - clipboard->setText(result.toUpper()); - setCursorPos(getSelectionBegin() + 2); - resetSelection(getSelectionBegin() + 2); - } - - if(event->matches(QKeySequence::Paste)) - { - QClipboard* clipboard = QApplication::clipboard(); - QString convert; - QString pattern = clipboard->text(); - for(int i = 0; i < pattern.length(); i++) - { - QChar ch = pattern[i].toLower(); - if((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (_wildcardEnabled && ch == '?')) - convert += ch; - } - if(convert.length() % 2) //odd length - convert += "0"; - if(_keepSize && convert.length() / 2 >= _initSize) - convert.truncate((_initSize - _xData.size()) * 2 - 1); - QByteArray data(convert.length(), 0); - QByteArray mask(data.length(), 0); - for(int i = 0; i < convert.length(); i++) - { - if(convert[i] == '?') - { - data[i] = '0'; - mask[i] = '1'; - } - else - { - data[i] = convert[i].toLatin1(); - mask[i] = '0'; - } - } - data = QByteArray().fromHex(data); - mask = QByteArray().fromHex(mask); - insert(_cursorPosition / 2, data, mask); - setCursorPos(_cursorPosition + 2 * data.length()); - resetSelection(getSelectionBegin()); - } - - - /* Delete char */ - if(event->matches(QKeySequence::Delete)) - { - if(getSelectionBegin() != getSelectionEnd()) - { - posBa = getSelectionBegin(); - remove(posBa, getSelectionEnd() - posBa); - setCursorPos(2 * posBa); - resetSelection(2 * posBa); - } - else - { - if(_overwriteMode) - replace(posBa, char(0), char(0)); - else - remove(posBa, 1); - } - } - - /* Backspace */ - if((event->key() == Qt::Key_Backspace) && (event->modifiers() == Qt::NoModifier)) - { - if(getSelectionBegin() != getSelectionEnd()) - { - posBa = getSelectionBegin(); - remove(posBa, getSelectionEnd() - posBa); - setCursorPos(2 * posBa); - resetSelection(2 * posBa); - } - else if(_cursorPosition == 1) - { - if(getSelectionBegin() != getSelectionEnd()) - { - posBa = getSelectionBegin(); - remove(posBa, getSelectionEnd() - posBa); - setCursorPos(2 * posBa); - resetSelection(2 * posBa); - } - else - { - if(_overwriteMode) - replace(posBa, char(0), char(0)); - else - remove(posBa, 1); - } - setCursorPos(0); - } - else if(posBa > 0) - { - int delta = 1; - if(_cursorPosition % 2) //odd cursor position - delta = 0; - if(_overwriteMode) - replace(posBa - delta, char(0), char(0)); - else - remove(posBa - delta, 1); - setCursorPos(_cursorPosition - 1 - delta); - } - } - - /* undo */ - if(event->matches(QKeySequence::Undo)) - { - undo(); - } - - /* redo */ - if(event->matches(QKeySequence::Redo)) - { - redo(); - } - - if(event->matches(QKeySequence::Copy)) - { - QString result; - for(int idx = getSelectionBegin(); idx < getSelectionEnd(); idx++) - { - QString byte = _xData.data().mid(idx, 1).toHex(); - if(!byte.length()) - break; - QString mask = _xMask.data().mid(idx, 1).toHex(); - if(mask[0] == '1') - result += "?"; - else - result += byte[0]; - if(mask[1] == '1') - result += "?"; - else - result += byte[1]; - result += " "; - } - QClipboard* clipboard = QApplication::clipboard(); - if(result.length()) - clipboard->setText(result.toUpper().trimmed()); - } - - // Switch between insert/overwrite mode - if((event->key() == Qt::Key_Insert) && (event->modifiers() == Qt::NoModifier)) - { - _overwriteMode = !_overwriteMode; - setCursorPos(_cursorPosition); - overwriteModeChanged(_overwriteMode); - } - - ensureVisible(); - update(); - QWidget::keyPressEvent(event); -} - -void QHexEditPrivate::mouseMoveEvent(QMouseEvent* event) -{ - _blink = false; - update(); - int actPos = cursorPos(event->pos()); - setCursorPos(actPos); - setSelection(actPos); - QWidget::mouseMoveEvent(event); -} - -void QHexEditPrivate::mousePressEvent(QMouseEvent* event) -{ - _blink = false; - update(); - int cPos = cursorPos(event->pos()); - if((event->modifiers()&Qt::ShiftModifier) == Qt::ShiftModifier) - { - setCursorPos(cPos); - setSelection(cPos); - } - else - { - resetSelection(cPos); - setCursorPos(cPos); - } - QWidget::mousePressEvent(event); -} - -void QHexEditPrivate::paintEvent(QPaintEvent* event) -{ - QPainter painter(this); - - painter.fillRect(event->rect(), _backgroundColor); - - // calc position - int firstLineIdx = ((event->rect().top() / _charHeight) - _charHeight) * BYTES_PER_LINE; - if(firstLineIdx < 0) - firstLineIdx = 0; - int lastLineIdx = ((event->rect().bottom() / _charHeight) + _charHeight) * BYTES_PER_LINE; - if(lastLineIdx > _xData.size()) - lastLineIdx = _xData.size(); - int yPosStart = ((firstLineIdx) / BYTES_PER_LINE) * _charHeight + _charHeight; - - // paint hex area - QByteArray hexBa(_xData.data().mid(firstLineIdx, lastLineIdx - firstLineIdx + 1).toHex()); - if(_wildcardEnabled) - { - QByteArray hexMask(_xMask.data().mid(firstLineIdx, lastLineIdx - firstLineIdx + 1).toHex()); - for(int i = 0; i < hexBa.size(); i++) - if(hexMask[i] == '1') - hexBa[i] = '?'; - } - - for(int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos += _charHeight) - { - QString hex; - int xPos = _xPosHex; - for(int colIdx = 0; ((lineIdx + colIdx) < _xData.size() && (colIdx < BYTES_PER_LINE)); colIdx++) - { - int posBa = lineIdx + colIdx; - if((getSelectionBegin() <= posBa) && (getSelectionEnd() > posBa)) - { - painter.setBackground(_selectionColor); - painter.setBackgroundMode(Qt::OpaqueMode); - } - else - { - painter.setBackground(_backgroundColor); - painter.setBackgroundMode(Qt::TransparentMode); - } - - // render hex value - painter.setPen(_textColor); - if(colIdx == 0) - { - hex = hexBa.mid((lineIdx - firstLineIdx) * 2, 2).toUpper(); - for(int i = 0; i < hex.length(); i++) - { - if(hex[i] == '?') //wildcard - painter.setPen(_wildcardColor); - else - painter.setPen(_textColor); - painter.drawText(xPos + _charWidth * i, yPos, QString(hex[i])); - } - xPos += 2 * _charWidth; - } - else - { - if(getSelectionBegin() == posBa) - { - hex = hexBa.mid((lineIdx + colIdx - firstLineIdx) * 2, 2).toUpper(); - xPos += _charWidth; - } - else - hex = hexBa.mid((lineIdx + colIdx - firstLineIdx) * 2, 2).prepend(" ").toUpper(); - for(int i = 0; i < hex.length(); i++) - { - if(hex[i] == '?') //wildcard - painter.setPen(_wildcardColor); - else - painter.setPen(_textColor); - painter.drawText(xPos + _charWidth * i, yPos, QString(hex[i])); - } - xPos += hex.length() * _charWidth; - } - } - } - painter.setBackgroundMode(Qt::TransparentMode); - painter.setPen(this->palette().color(QPalette::WindowText)); - - // paint cursor - if(_blink && hasFocus()) - { - if(_overwriteMode) - painter.fillRect(_cursorX, _cursorY + _charHeight - 2, _charWidth, 2, this->palette().color(QPalette::WindowText)); - else - painter.fillRect(_cursorX, _cursorY, 2, _charHeight, this->palette().color(QPalette::WindowText)); - } - - if(_size != _xData.size()) - { - _size = _xData.size(); - emit currentSizeChanged(_size); - } -} - -void QHexEditPrivate::setCursorPos(int position) -{ - // delete cursor - _blink = false; - update(); - - // cursor in range? - if(_overwriteMode) - { - if(position > (_xData.size() * 2 - 1)) - position = _xData.size() * 2 - 1; - } - else - { - if(position > (_xData.size() * 2)) - position = _xData.size() * 2; - } - - if(position < 0) - position = 0; - - // calc position - _cursorPosition = position; - _cursorY = (position / (2 * BYTES_PER_LINE)) * _charHeight + 4; - int x = (position % (2 * BYTES_PER_LINE)); - _cursorX = (((x / 2) * 3) + (x % 2)) * _charWidth + _xPosHex; - - // immiadately draw cursor - _blink = true; - update(); - emit currentAddressChanged(_cursorPosition / 2); -} - -int QHexEditPrivate::cursorPos(QPoint pos) -{ - int result = -1; - // find char under cursor - if((pos.x() >= _xPosHex) && (pos.x() < (_xPosHex + HEXCHARS_IN_LINE * _charWidth))) - { - int x = (pos.x() - _xPosHex) / _charWidth; - if((x % 3) == 0) - x = (x / 3) * 2; - else - x = ((x / 3) * 2) + 1; - int y = ((pos.y() - 3) / _charHeight) * 2 * BYTES_PER_LINE; - result = x + y; - } - return result; -} - -int QHexEditPrivate::cursorPos() -{ - return _cursorPosition; -} - -void QHexEditPrivate::resetSelection() -{ - _selectionBegin = _selectionInit; - _selectionEnd = _selectionInit; -} - -void QHexEditPrivate::resetSelection(int pos) -{ - if(pos < 0) - pos = 0; - pos++; - pos = pos / 2; - _selectionInit = pos; - _selectionBegin = pos; - _selectionEnd = pos; -} - -void QHexEditPrivate::setSelection(int pos) -{ - if(pos < 0) - pos = 0; - pos++; - pos = pos / 2; - if(pos >= _selectionInit) - { - _selectionEnd = pos; - _selectionBegin = _selectionInit; - } - else - { - _selectionBegin = pos; - _selectionEnd = _selectionInit; - } -} - -int QHexEditPrivate::getSelectionBegin() -{ - return _selectionBegin; -} - -int QHexEditPrivate::getSelectionEnd() -{ - return _selectionEnd; -} - - -void QHexEditPrivate::updateCursor() -{ - if(_blink) - _blink = false; - else - _blink = true; - update(_cursorX, _cursorY, _charWidth, _charHeight); -} - -void QHexEditPrivate::adjust() -{ - QFontMetrics metrics(this->font()); - _charWidth = metrics.width(QLatin1Char('9')); - _charHeight = metrics.height(); - - _xPosHex = _horizonalSpacing; - - // tell QAbstractScollbar, how big we are - setMinimumHeight(((_xData.size() / 16 + 1) * _charHeight) + 5); - setMinimumWidth(_xPosHex + HEXCHARS_IN_LINE * _charWidth); - - update(); -} - -void QHexEditPrivate::ensureVisible() -{ - // scrolls to cursorx, cusory (which are set by setCursorPos) - // x-margin is 3 pixels, y-margin is half of charHeight - _scrollArea->ensureVisible(_cursorX, _cursorY + _charHeight / 2, 3, _charHeight / 2 + 2); -} +#include "QHexEditPrivate.h" +#include +#include +#include +#include "ArrayCommand.h" + +const int HEXCHARS_IN_LINE = 47; +const int BYTES_PER_LINE = 16; + +QHexEditPrivate::QHexEditPrivate(QScrollArea* parent) : QWidget(parent) +{ + _undoDataStack = new QUndoStack(this); + _undoMaskStack = new QUndoStack(this); + + _scrollArea = parent; + setOverwriteMode(true); + + QFont font("Monospace", 8, QFont::Normal, false); + font.setFixedPitch(true); + font.setStyleHint(QFont::Monospace); + this->setFont(font); + + _size = 0; + _horizonalSpacing = 3; + resetSelection(0); + setCursorPos(0); + + setFocusPolicy(Qt::StrongFocus); + + connect(&_cursorTimer, SIGNAL(timeout()), this, SLOT(updateCursor())); + _cursorTimer.setInterval(500); + _cursorTimer.start(); + + _textColor = QColor("#000000"); + _wildcardColor = QColor("#FF0000"); + _backgroundColor = QColor("#FFF8F0"); + _selectionColor = QColor("#C0C0C0"); + _overwriteMode = false; + _wildcardEnabled = true; + _keepSize = false; +} + +void QHexEditPrivate::setData(const QByteArray & data, const QByteArray & mask) +{ + _xData.setData(data); + _xMask.setData(mask); + _undoDataStack->clear(); + _undoMaskStack->clear(); + _initSize = _xData.size(); + adjust(); + setCursorPos(0); + emit dataChanged(); +} + +QByteArray QHexEditPrivate::data() +{ + return _xData.data(); +} + +QByteArray QHexEditPrivate::mask() +{ + return _xMask.data(); +} + +void QHexEditPrivate::insert(int index, const QByteArray & ba, const QByteArray & mask) +{ + if(ba.length() > 0) + { + if(_overwriteMode) + { + _undoDataStack->push(new ArrayCommand(&_xData, ArrayCommand::replace, index, ba, ba.length())); + _undoMaskStack->push(new ArrayCommand(&_xMask, ArrayCommand::replace, index, mask, mask.length())); + emit dataChanged(); + } + else + { + _undoDataStack->push(new ArrayCommand(&_xData, ArrayCommand::insert, index, ba, ba.length())); + _undoMaskStack->push(new ArrayCommand(&_xMask, ArrayCommand::insert, index, mask, mask.length())); + emit dataChanged(); + } + } +} + +void QHexEditPrivate::insert(int index, char ch, char mask) +{ + _undoDataStack->push(new CharCommand(&_xData, CharCommand::insert, index, ch)); + _undoMaskStack->push(new CharCommand(&_xMask, CharCommand::insert, index, mask)); + emit dataChanged(); +} + +void QHexEditPrivate::remove(int index, int len) +{ + if(len > 0) + { + if(len == 1) + { + if(_overwriteMode) + { + _undoDataStack->push(new CharCommand(&_xData, CharCommand::replace, index, char(0))); + _undoMaskStack->push(new CharCommand(&_xMask, CharCommand::replace, index, char(0))); + emit dataChanged(); + } + else + { + _undoDataStack->push(new CharCommand(&_xData, CharCommand::remove, index, char(0))); + _undoMaskStack->push(new CharCommand(&_xMask, CharCommand::remove, index, char(0))); + emit dataChanged(); + } + } + else + { + QByteArray ba = QByteArray(len, char(0)); + if(_overwriteMode) + { + _undoDataStack->push(new ArrayCommand(&_xData, ArrayCommand::replace, index, ba, ba.length())); + _undoMaskStack->push(new ArrayCommand(&_xMask, ArrayCommand::replace, index, ba, ba.length())); + emit dataChanged(); + } + else + { + _undoDataStack->push(new ArrayCommand(&_xData, ArrayCommand::remove, index, ba, len)); + _undoMaskStack->push(new ArrayCommand(&_xMask, ArrayCommand::remove, index, ba, len)); + emit dataChanged(); + } + } + } +} + +void QHexEditPrivate::replace(int index, char ch, char mask) +{ + _undoDataStack->push(new CharCommand(&_xData, CharCommand::replace, index, ch)); + _undoMaskStack->push(new CharCommand(&_xMask, CharCommand::replace, index, mask)); + resetSelection(); + emit dataChanged(); +} + +void QHexEditPrivate::replace(int index, const QByteArray & ba, const QByteArray & mask) +{ + _undoDataStack->push(new ArrayCommand(&_xData, ArrayCommand::replace, index, ba, ba.length())); + _undoMaskStack->push(new ArrayCommand(&_xMask, ArrayCommand::replace, index, mask, mask.length())); + resetSelection(); + emit dataChanged(); +} + +void QHexEditPrivate::replace(int pos, int len, const QByteArray & after, const QByteArray & mask) +{ + _undoDataStack->push(new ArrayCommand(&_xData, ArrayCommand::replace, pos, after, len)); + _undoMaskStack->push(new ArrayCommand(&_xMask, ArrayCommand::replace, pos, mask, len)); + resetSelection(); + emit dataChanged(); +} + +void QHexEditPrivate::fill(int index, const QByteArray & ba, const QByteArray & mask) +{ + int dataSize = _xData.size(); + if(index >= dataSize) + return; + int repeat = dataSize / ba.size() + 1; + QByteArray fillData = ba.repeated(repeat); + fillData.resize(dataSize); + fillData = fillData.toHex(); + QByteArray fillMask = mask.repeated(repeat); + fillMask.resize(dataSize); + fillMask = fillMask.toHex(); + QByteArray origData = _xData.data().mid(index).toHex(); + for(int i = 0; i < dataSize * 2; i++) + if(fillMask[i] == '1') + fillData[i] = origData[i]; + this->replace(index, QByteArray().fromHex(fillData), QByteArray().fromHex(fillMask)); +} + +void QHexEditPrivate::setOverwriteMode(bool overwriteMode) +{ + _overwriteMode = overwriteMode; +} + +bool QHexEditPrivate::overwriteMode() +{ + return _overwriteMode; +} + +void QHexEditPrivate::setWildcardEnabled(bool enabled) +{ + _wildcardEnabled = enabled; +} + +bool QHexEditPrivate::wildcardEnabled() +{ + return _wildcardEnabled; +} + +void QHexEditPrivate::setKeepSize(bool enabled) +{ + _keepSize = enabled; +} + +bool QHexEditPrivate::keepSize() +{ + return _keepSize; +} + +void QHexEditPrivate::setHorizontalSpacing(int x) +{ + _horizonalSpacing = x; + adjust(); + setCursorPos(cursorPos()); + this->repaint(); +} + +int QHexEditPrivate::horizontalSpacing() +{ + return _horizonalSpacing; +} + +void QHexEditPrivate::setTextColor(QColor color) +{ + _textColor = color; +} + +QColor QHexEditPrivate::textColor() +{ + return _textColor; +} + +void QHexEditPrivate::setWildcardColor(QColor color) +{ + _wildcardColor = color; +} + +QColor QHexEditPrivate::wildcardColor() +{ + return _wildcardColor; +} + +void QHexEditPrivate::setBackgroundColor(QColor color) +{ + _backgroundColor = color; +} + +QColor QHexEditPrivate::backgroundColor() +{ + return _backgroundColor; +} + +void QHexEditPrivate::setSelectionColor(QColor color) +{ + _selectionColor = color; +} + +QColor QHexEditPrivate::selectionColor() +{ + return _selectionColor; +} + +void QHexEditPrivate::redo() +{ + if(!_undoDataStack->canRedo() || !_undoMaskStack->canRedo()) + return; + _undoDataStack->redo(); + _undoMaskStack->redo(); + emit dataChanged(); + setCursorPos(_cursorPosition); + update(); +} + +void QHexEditPrivate::undo() +{ + if(!_undoDataStack->canUndo() || !_undoMaskStack->canUndo()) + return; + _undoDataStack->undo(); + _undoMaskStack->undo(); + emit dataChanged(); + setCursorPos(_cursorPosition); + update(); +} + +void QHexEditPrivate::focusInEvent(QFocusEvent* event) +{ + ensureVisible(); + QWidget::focusInEvent(event); +} + +void QHexEditPrivate::resizeEvent(QResizeEvent* event) +{ + adjust(); + QWidget::resizeEvent(event); +} + +void QHexEditPrivate::keyPressEvent(QKeyEvent* event) +{ + int charX = (_cursorX - _xPosHex) / _charWidth; + int posX = (charX / 3) * 2 + (charX % 3); + int posBa = (_cursorY / _charHeight) * BYTES_PER_LINE + posX / 2; + + + /*****************************************************************************/ + /* Cursor movements */ + /*****************************************************************************/ + + if(event->matches(QKeySequence::MoveToNextChar)) + { + setCursorPos(_cursorPosition + 1); + resetSelection(_cursorPosition); + } + if(event->matches(QKeySequence::MoveToPreviousChar)) + { + setCursorPos(_cursorPosition - 1); + resetSelection(_cursorPosition); + } + if(event->matches(QKeySequence::MoveToEndOfLine)) + { + setCursorPos(_cursorPosition | (2 * BYTES_PER_LINE - 1)); + resetSelection(_cursorPosition); + } + if(event->matches(QKeySequence::MoveToStartOfLine)) + { + setCursorPos(_cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE))); + resetSelection(_cursorPosition); + } + if(event->matches(QKeySequence::MoveToPreviousLine)) + { + setCursorPos(_cursorPosition - (2 * BYTES_PER_LINE)); + resetSelection(_cursorPosition); + } + if(event->matches(QKeySequence::MoveToNextLine)) + { + setCursorPos(_cursorPosition + (2 * BYTES_PER_LINE)); + resetSelection(_cursorPosition); + } + + if(event->matches(QKeySequence::MoveToNextPage)) + { + setCursorPos(_cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE)); + resetSelection(_cursorPosition); + } + if(event->matches(QKeySequence::MoveToPreviousPage)) + { + setCursorPos(_cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE)); + resetSelection(_cursorPosition); + } + if(event->matches(QKeySequence::MoveToEndOfDocument)) + { + setCursorPos(_xData.size() * 2); + resetSelection(_cursorPosition); + } + if(event->matches(QKeySequence::MoveToStartOfDocument)) + { + setCursorPos(0); + resetSelection(_cursorPosition); + } + + /*****************************************************************************/ + /* Select commands */ + /*****************************************************************************/ + if(event->matches(QKeySequence::SelectAll)) + { + resetSelection(0); + setSelection(2 * _xData.size() + 1); + } + if(event->matches(QKeySequence::SelectNextChar)) + { + int pos = _cursorPosition + 1; + setCursorPos(pos); + setSelection(pos); + } + if(event->matches(QKeySequence::SelectPreviousChar)) + { + int pos = _cursorPosition - 1; + setSelection(pos); + setCursorPos(pos); + } + if(event->matches(QKeySequence::SelectEndOfLine)) + { + int pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)) + (2 * BYTES_PER_LINE); + setCursorPos(pos); + setSelection(pos); + } + if(event->matches(QKeySequence::SelectStartOfLine)) + { + int pos = _cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)); + setCursorPos(pos); + setSelection(pos); + } + if(event->matches(QKeySequence::SelectPreviousLine)) + { + int pos = _cursorPosition - (2 * BYTES_PER_LINE); + setCursorPos(pos); + setSelection(pos); + } + if(event->matches(QKeySequence::SelectNextLine)) + { + int pos = _cursorPosition + (2 * BYTES_PER_LINE); + setCursorPos(pos); + setSelection(pos); + } + + if(event->matches(QKeySequence::SelectNextPage)) + { + int pos = _cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE); + setCursorPos(pos); + setSelection(pos); + } + if(event->matches(QKeySequence::SelectPreviousPage)) + { + int pos = _cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE); + setCursorPos(pos); + setSelection(pos); + } + if(event->matches(QKeySequence::SelectEndOfDocument)) + { + int pos = _xData.size() * 2; + setCursorPos(pos); + setSelection(pos); + } + if(event->matches(QKeySequence::SelectStartOfDocument)) + { + int pos = 0; + setCursorPos(pos); + setSelection(pos); + } + + /*****************************************************************************/ + /* Edit Commands */ + /*****************************************************************************/ + /* Hex input */ + int key = int(event->text().toLower()[0].toLatin1()); + if((key >= '0' && key <= '9') || (key >= 'a' && key <= 'f') || (_wildcardEnabled && key == '?')) + { + if(getSelectionBegin() != getSelectionEnd()) + { + posBa = getSelectionBegin(); + remove(posBa, getSelectionEnd() - posBa); + setCursorPos(2 * posBa); + resetSelection(2 * posBa); + } + + // If insert mode, then insert a byte + if(_overwriteMode == false) + { + if(_keepSize && _xData.size() >= _initSize) + { + QWidget::keyPressEvent(event); + return; + } + if((charX % 3) == 0) + insert(posBa, char(0), char(0)); + } + + // Change content + if(_xData.size() > 0) + { + QByteArray hexMask = _xMask.data().mid(posBa, 1).toHex(); + QByteArray hexValue = _xData.data().mid(posBa, 1).toHex(); + if(key == '?') //wildcard + { + if((charX % 3) == 0) + hexMask[0] = '1'; + else + hexMask[1] = '1'; + } + else + { + if((charX % 3) == 0) + { + hexValue[0] = key; + hexMask[0] = '0'; + } + else + { + hexValue[1] = key; + hexMask[1] = '0'; + } + } + replace(posBa, QByteArray().fromHex(hexValue)[0], QByteArray().fromHex(hexMask)[0]); + + setCursorPos(_cursorPosition + 1); + resetSelection(_cursorPosition); + } + } + + /* Cut & Paste */ + if(event->matches(QKeySequence::Cut)) + { + QString result; + for(int idx = getSelectionBegin(); idx < getSelectionEnd(); idx++) + { + QString byte = _xData.data().mid(idx, 1).toHex(); + QString mask = _xMask.data().mid(idx, 1).toHex(); + if(mask[0] == '1') + result += "?"; + else + result += byte[0]; + if(mask[1] == '1') + result += "?"; + else + result += byte[1]; + result += " "; + } + remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(result.toUpper()); + setCursorPos(getSelectionBegin() + 2); + resetSelection(getSelectionBegin() + 2); + } + + if(event->matches(QKeySequence::Paste)) + { + QClipboard* clipboard = QApplication::clipboard(); + QString convert; + QString pattern = clipboard->text(); + for(int i = 0; i < pattern.length(); i++) + { + QChar ch = pattern[i].toLower(); + if((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (_wildcardEnabled && ch == '?')) + convert += ch; + } + if(convert.length() % 2) //odd length + convert += "0"; + if(_keepSize && convert.length() / 2 >= _initSize) + convert.truncate((_initSize - _xData.size()) * 2 - 1); + QByteArray data(convert.length(), 0); + QByteArray mask(data.length(), 0); + for(int i = 0; i < convert.length(); i++) + { + if(convert[i] == '?') + { + data[i] = '0'; + mask[i] = '1'; + } + else + { + data[i] = convert[i].toLatin1(); + mask[i] = '0'; + } + } + data = QByteArray().fromHex(data); + mask = QByteArray().fromHex(mask); + insert(_cursorPosition / 2, data, mask); + setCursorPos(_cursorPosition + 2 * data.length()); + resetSelection(getSelectionBegin()); + } + + + /* Delete char */ + if(event->matches(QKeySequence::Delete)) + { + if(getSelectionBegin() != getSelectionEnd()) + { + posBa = getSelectionBegin(); + remove(posBa, getSelectionEnd() - posBa); + setCursorPos(2 * posBa); + resetSelection(2 * posBa); + } + else + { + if(_overwriteMode) + replace(posBa, char(0), char(0)); + else + remove(posBa, 1); + } + } + + /* Backspace */ + if((event->key() == Qt::Key_Backspace) && (event->modifiers() == Qt::NoModifier)) + { + if(getSelectionBegin() != getSelectionEnd()) + { + posBa = getSelectionBegin(); + remove(posBa, getSelectionEnd() - posBa); + setCursorPos(2 * posBa); + resetSelection(2 * posBa); + } + else if(_cursorPosition == 1) + { + if(getSelectionBegin() != getSelectionEnd()) + { + posBa = getSelectionBegin(); + remove(posBa, getSelectionEnd() - posBa); + setCursorPos(2 * posBa); + resetSelection(2 * posBa); + } + else + { + if(_overwriteMode) + replace(posBa, char(0), char(0)); + else + remove(posBa, 1); + } + setCursorPos(0); + } + else if(posBa > 0) + { + int delta = 1; + if(_cursorPosition % 2) //odd cursor position + delta = 0; + if(_overwriteMode) + replace(posBa - delta, char(0), char(0)); + else + remove(posBa - delta, 1); + setCursorPos(_cursorPosition - 1 - delta); + } + } + + /* undo */ + if(event->matches(QKeySequence::Undo)) + { + undo(); + } + + /* redo */ + if(event->matches(QKeySequence::Redo)) + { + redo(); + } + + if(event->matches(QKeySequence::Copy)) + { + QString result; + for(int idx = getSelectionBegin(); idx < getSelectionEnd(); idx++) + { + QString byte = _xData.data().mid(idx, 1).toHex(); + if(!byte.length()) + break; + QString mask = _xMask.data().mid(idx, 1).toHex(); + if(mask[0] == '1') + result += "?"; + else + result += byte[0]; + if(mask[1] == '1') + result += "?"; + else + result += byte[1]; + result += " "; + } + QClipboard* clipboard = QApplication::clipboard(); + if(result.length()) + clipboard->setText(result.toUpper().trimmed()); + } + + // Switch between insert/overwrite mode + if((event->key() == Qt::Key_Insert) && (event->modifiers() == Qt::NoModifier)) + { + _overwriteMode = !_overwriteMode; + setCursorPos(_cursorPosition); + overwriteModeChanged(_overwriteMode); + } + + ensureVisible(); + update(); + QWidget::keyPressEvent(event); +} + +void QHexEditPrivate::mouseMoveEvent(QMouseEvent* event) +{ + _blink = false; + update(); + int actPos = cursorPos(event->pos()); + setCursorPos(actPos); + setSelection(actPos); + QWidget::mouseMoveEvent(event); +} + +void QHexEditPrivate::mousePressEvent(QMouseEvent* event) +{ + _blink = false; + update(); + int cPos = cursorPos(event->pos()); + if((event->modifiers()&Qt::ShiftModifier) == Qt::ShiftModifier) + { + setCursorPos(cPos); + setSelection(cPos); + } + else + { + resetSelection(cPos); + setCursorPos(cPos); + } + QWidget::mousePressEvent(event); +} + +void QHexEditPrivate::paintEvent(QPaintEvent* event) +{ + QPainter painter(this); + + painter.fillRect(event->rect(), _backgroundColor); + + // calc position + int firstLineIdx = ((event->rect().top() / _charHeight) - _charHeight) * BYTES_PER_LINE; + if(firstLineIdx < 0) + firstLineIdx = 0; + int lastLineIdx = ((event->rect().bottom() / _charHeight) + _charHeight) * BYTES_PER_LINE; + if(lastLineIdx > _xData.size()) + lastLineIdx = _xData.size(); + int yPosStart = ((firstLineIdx) / BYTES_PER_LINE) * _charHeight + _charHeight; + + // paint hex area + QByteArray hexBa(_xData.data().mid(firstLineIdx, lastLineIdx - firstLineIdx + 1).toHex()); + if(_wildcardEnabled) + { + QByteArray hexMask(_xMask.data().mid(firstLineIdx, lastLineIdx - firstLineIdx + 1).toHex()); + for(int i = 0; i < hexBa.size(); i++) + if(hexMask[i] == '1') + hexBa[i] = '?'; + } + + for(int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos += _charHeight) + { + QString hex; + int xPos = _xPosHex; + for(int colIdx = 0; ((lineIdx + colIdx) < _xData.size() && (colIdx < BYTES_PER_LINE)); colIdx++) + { + int posBa = lineIdx + colIdx; + if((getSelectionBegin() <= posBa) && (getSelectionEnd() > posBa)) + { + painter.setBackground(_selectionColor); + painter.setBackgroundMode(Qt::OpaqueMode); + } + else + { + painter.setBackground(_backgroundColor); + painter.setBackgroundMode(Qt::TransparentMode); + } + + // render hex value + painter.setPen(_textColor); + if(colIdx == 0) + { + hex = hexBa.mid((lineIdx - firstLineIdx) * 2, 2).toUpper(); + for(int i = 0; i < hex.length(); i++) + { + if(hex[i] == '?') //wildcard + painter.setPen(_wildcardColor); + else + painter.setPen(_textColor); + painter.drawText(xPos + _charWidth * i, yPos, QString(hex[i])); + } + xPos += 2 * _charWidth; + } + else + { + if(getSelectionBegin() == posBa) + { + hex = hexBa.mid((lineIdx + colIdx - firstLineIdx) * 2, 2).toUpper(); + xPos += _charWidth; + } + else + hex = hexBa.mid((lineIdx + colIdx - firstLineIdx) * 2, 2).prepend(" ").toUpper(); + for(int i = 0; i < hex.length(); i++) + { + if(hex[i] == '?') //wildcard + painter.setPen(_wildcardColor); + else + painter.setPen(_textColor); + painter.drawText(xPos + _charWidth * i, yPos, QString(hex[i])); + } + xPos += hex.length() * _charWidth; + } + } + } + painter.setBackgroundMode(Qt::TransparentMode); + painter.setPen(this->palette().color(QPalette::WindowText)); + + // paint cursor + if(_blink && hasFocus()) + { + if(_overwriteMode) + painter.fillRect(_cursorX, _cursorY + _charHeight - 2, _charWidth, 2, this->palette().color(QPalette::WindowText)); + else + painter.fillRect(_cursorX, _cursorY, 2, _charHeight, this->palette().color(QPalette::WindowText)); + } + + if(_size != _xData.size()) + { + _size = _xData.size(); + emit currentSizeChanged(_size); + } +} + +void QHexEditPrivate::setCursorPos(int position) +{ + // delete cursor + _blink = false; + update(); + + // cursor in range? + if(_overwriteMode) + { + if(position > (_xData.size() * 2 - 1)) + position = _xData.size() * 2 - 1; + } + else + { + if(position > (_xData.size() * 2)) + position = _xData.size() * 2; + } + + if(position < 0) + position = 0; + + // calc position + _cursorPosition = position; + _cursorY = (position / (2 * BYTES_PER_LINE)) * _charHeight + 4; + int x = (position % (2 * BYTES_PER_LINE)); + _cursorX = (((x / 2) * 3) + (x % 2)) * _charWidth + _xPosHex; + + // immiadately draw cursor + _blink = true; + update(); + emit currentAddressChanged(_cursorPosition / 2); +} + +int QHexEditPrivate::cursorPos(QPoint pos) +{ + int result = -1; + // find char under cursor + if((pos.x() >= _xPosHex) && (pos.x() < (_xPosHex + HEXCHARS_IN_LINE * _charWidth))) + { + int x = (pos.x() - _xPosHex) / _charWidth; + if((x % 3) == 0) + x = (x / 3) * 2; + else + x = ((x / 3) * 2) + 1; + int y = ((pos.y() - 3) / _charHeight) * 2 * BYTES_PER_LINE; + result = x + y; + } + return result; +} + +int QHexEditPrivate::cursorPos() +{ + return _cursorPosition; +} + +void QHexEditPrivate::resetSelection() +{ + _selectionBegin = _selectionInit; + _selectionEnd = _selectionInit; +} + +void QHexEditPrivate::resetSelection(int pos) +{ + if(pos < 0) + pos = 0; + pos++; + pos = pos / 2; + _selectionInit = pos; + _selectionBegin = pos; + _selectionEnd = pos; +} + +void QHexEditPrivate::setSelection(int pos) +{ + if(pos < 0) + pos = 0; + pos++; + pos = pos / 2; + if(pos >= _selectionInit) + { + _selectionEnd = pos; + _selectionBegin = _selectionInit; + } + else + { + _selectionBegin = pos; + _selectionEnd = _selectionInit; + } +} + +int QHexEditPrivate::getSelectionBegin() +{ + return _selectionBegin; +} + +int QHexEditPrivate::getSelectionEnd() +{ + return _selectionEnd; +} + + +void QHexEditPrivate::updateCursor() +{ + if(_blink) + _blink = false; + else + _blink = true; + update(_cursorX, _cursorY, _charWidth, _charHeight); +} + +void QHexEditPrivate::adjust() +{ + QFontMetrics metrics(this->font()); + _charWidth = metrics.width(QLatin1Char('9')); + _charHeight = metrics.height(); + + _xPosHex = _horizonalSpacing; + + // tell QAbstractScollbar, how big we are + setMinimumHeight(((_xData.size() / 16 + 1) * _charHeight) + 5); + setMinimumWidth(_xPosHex + HEXCHARS_IN_LINE * _charWidth); + + update(); +} + +void QHexEditPrivate::ensureVisible() +{ + // scrolls to cursorx, cusory (which are set by setCursorPos) + // x-margin is 3 pixels, y-margin is half of charHeight + _scrollArea->ensureVisible(_cursorX, _cursorY + _charHeight / 2, 3, _charHeight / 2 + 2); +} diff --git a/src/gui/Src/QHexEdit/QHexEditPrivate.h b/src/gui/Src/QHexEdit/QHexEditPrivate.h index d5b69860..e2738c73 100644 --- a/src/gui/Src/QHexEdit/QHexEditPrivate.h +++ b/src/gui/Src/QHexEdit/QHexEditPrivate.h @@ -1,113 +1,113 @@ -#ifndef QHEXEDITPRIVATE_H -#define QHEXEDITPRIVATE_H - -#include -#include -#include -#include -#include "XByteArray.h" - -class QHexEditPrivate : public QWidget -{ - Q_OBJECT -public: - QHexEditPrivate(QScrollArea* parent); - - //properties - void setCursorPos(int position); - int cursorPos(); - void setOverwriteMode(bool overwriteMode); - bool overwriteMode(); - void setWildcardEnabled(bool enabled); - bool wildcardEnabled(); - void setKeepSize(bool enabled); - bool keepSize(); - void setHorizontalSpacing(int x); - int horizontalSpacing(); - void setTextColor(QColor color); - QColor textColor(); - void setWildcardColor(QColor color); - QColor wildcardColor(); - void setBackgroundColor(QColor color); - QColor backgroundColor(); - void setSelectionColor(QColor color); - QColor selectionColor(); - - //data management - void setData(const QByteArray & data, const QByteArray & mask); - QByteArray data(); - QByteArray mask(); - void insert(int index, const QByteArray & ba, const QByteArray & mask); - void insert(int index, char ch, char mask); - void remove(int index, int len = 1); - void replace(int index, char ch, char mask); - void replace(int index, const QByteArray & ba, const QByteArray & mask); - void replace(int pos, int len, const QByteArray & after, const QByteArray & mask); - void fill(int index, const QByteArray & ba, const QByteArray & mask); - void undo(); - void redo(); - -signals: - void currentAddressChanged(int address); - void currentSizeChanged(int size); - void dataChanged(); - void overwriteModeChanged(bool state); - -protected: - void focusInEvent(QFocusEvent* event); - void resizeEvent(QResizeEvent* event); - void keyPressEvent(QKeyEvent* event); - void mouseMoveEvent(QMouseEvent* event); - void mousePressEvent(QMouseEvent* event); - - void paintEvent(QPaintEvent* event); - - int cursorPos(QPoint pos); // calc cursorpos from graphics position. DOES NOT STORE POSITION - - void resetSelection(int pos); // set selectionStart && selectionEnd to pos - void resetSelection(); // set selectionEnd to selectionStart - void setSelection(int pos); // set min (if below init) || max (if greater init) - int getSelectionBegin(); - int getSelectionEnd(); - -private slots: - void updateCursor(); - -private: - void adjust(); - void ensureVisible(); - - QScrollArea* _scrollArea; - QTimer _cursorTimer; - QUndoStack* _undoDataStack; - QUndoStack* _undoMaskStack; - - XByteArray _xData; - XByteArray _xMask; - - QColor _textColor; - QColor _wildcardColor; - QColor _backgroundColor; - QColor _selectionColor; - - bool _blink; // true: then cursor blinks - bool _overwriteMode; - bool _wildcardEnabled; - bool _keepSize; - - int _charWidth, _charHeight; // char dimensions (dpendend on font) - int _cursorX, _cursorY; // graphics position of the cursor - int _cursorPosition; // character positioin in stream (on byte ends in to steps) - int _xPosHex; // graphics x-position of the areas - - int _selectionBegin; // First selected char - int _selectionEnd; // Last selected char - int _selectionInit; // That's, where we pressed the mouse button - - int _size; - int _initSize; - int _horizonalSpacing; -}; - -#endif //QHEXEDITPRIVATE_H - +#ifndef QHEXEDITPRIVATE_H +#define QHEXEDITPRIVATE_H + +#include +#include +#include +#include +#include "XByteArray.h" + +class QHexEditPrivate : public QWidget +{ + Q_OBJECT +public: + QHexEditPrivate(QScrollArea* parent); + + //properties + void setCursorPos(int position); + int cursorPos(); + void setOverwriteMode(bool overwriteMode); + bool overwriteMode(); + void setWildcardEnabled(bool enabled); + bool wildcardEnabled(); + void setKeepSize(bool enabled); + bool keepSize(); + void setHorizontalSpacing(int x); + int horizontalSpacing(); + void setTextColor(QColor color); + QColor textColor(); + void setWildcardColor(QColor color); + QColor wildcardColor(); + void setBackgroundColor(QColor color); + QColor backgroundColor(); + void setSelectionColor(QColor color); + QColor selectionColor(); + + //data management + void setData(const QByteArray & data, const QByteArray & mask); + QByteArray data(); + QByteArray mask(); + void insert(int index, const QByteArray & ba, const QByteArray & mask); + void insert(int index, char ch, char mask); + void remove(int index, int len = 1); + void replace(int index, char ch, char mask); + void replace(int index, const QByteArray & ba, const QByteArray & mask); + void replace(int pos, int len, const QByteArray & after, const QByteArray & mask); + void fill(int index, const QByteArray & ba, const QByteArray & mask); + void undo(); + void redo(); + +signals: + void currentAddressChanged(int address); + void currentSizeChanged(int size); + void dataChanged(); + void overwriteModeChanged(bool state); + +protected: + void focusInEvent(QFocusEvent* event); + void resizeEvent(QResizeEvent* event); + void keyPressEvent(QKeyEvent* event); + void mouseMoveEvent(QMouseEvent* event); + void mousePressEvent(QMouseEvent* event); + + void paintEvent(QPaintEvent* event); + + int cursorPos(QPoint pos); // calc cursorpos from graphics position. DOES NOT STORE POSITION + + void resetSelection(int pos); // set selectionStart && selectionEnd to pos + void resetSelection(); // set selectionEnd to selectionStart + void setSelection(int pos); // set min (if below init) || max (if greater init) + int getSelectionBegin(); + int getSelectionEnd(); + +private slots: + void updateCursor(); + +private: + void adjust(); + void ensureVisible(); + + QScrollArea* _scrollArea; + QTimer _cursorTimer; + QUndoStack* _undoDataStack; + QUndoStack* _undoMaskStack; + + XByteArray _xData; + XByteArray _xMask; + + QColor _textColor; + QColor _wildcardColor; + QColor _backgroundColor; + QColor _selectionColor; + + bool _blink; // true: then cursor blinks + bool _overwriteMode; + bool _wildcardEnabled; + bool _keepSize; + + int _charWidth, _charHeight; // char dimensions (dpendend on font) + int _cursorX, _cursorY; // graphics position of the cursor + int _cursorPosition; // character positioin in stream (on byte ends in to steps) + int _xPosHex; // graphics x-position of the areas + + int _selectionBegin; // First selected char + int _selectionEnd; // Last selected char + int _selectionInit; // That's, where we pressed the mouse button + + int _size; + int _initSize; + int _horizonalSpacing; +}; + +#endif //QHEXEDITPRIVATE_H + diff --git a/src/gui/Src/QHexEdit/XByteArray.cpp b/src/gui/Src/QHexEdit/XByteArray.cpp index cfc57049..db189e04 100644 --- a/src/gui/Src/QHexEdit/XByteArray.cpp +++ b/src/gui/Src/QHexEdit/XByteArray.cpp @@ -1,61 +1,61 @@ -#include "XByteArray.h" - -XByteArray::XByteArray() -{ -} - -QByteArray & XByteArray::data() -{ - return _data; -} - -void XByteArray::setData(QByteArray data) -{ - _data = data; -} - -int XByteArray::size() -{ - return _data.size(); -} - -QByteArray & XByteArray::insert(int i, char ch) -{ - _data.insert(i, ch); - return _data; -} - -QByteArray & XByteArray::insert(int i, const QByteArray & ba) -{ - _data.insert(i, ba); - return _data; -} - -QByteArray & XByteArray::remove(int i, int len) -{ - _data.remove(i, len); - return _data; -} - -QByteArray & XByteArray::replace(int index, char ch) -{ - _data[index] = ch; - return _data; -} - -QByteArray & XByteArray::replace(int index, const QByteArray & ba) -{ - int len = ba.length(); - return replace(index, len, ba); -} - -QByteArray & XByteArray::replace(int index, int length, const QByteArray & ba) -{ - int len; - if((index + length) > _data.length()) - len = _data.length() - index; - else - len = length; - _data.replace(index, len, ba.mid(0, len)); - return _data; -} +#include "XByteArray.h" + +XByteArray::XByteArray() +{ +} + +QByteArray & XByteArray::data() +{ + return _data; +} + +void XByteArray::setData(QByteArray data) +{ + _data = data; +} + +int XByteArray::size() +{ + return _data.size(); +} + +QByteArray & XByteArray::insert(int i, char ch) +{ + _data.insert(i, ch); + return _data; +} + +QByteArray & XByteArray::insert(int i, const QByteArray & ba) +{ + _data.insert(i, ba); + return _data; +} + +QByteArray & XByteArray::remove(int i, int len) +{ + _data.remove(i, len); + return _data; +} + +QByteArray & XByteArray::replace(int index, char ch) +{ + _data[index] = ch; + return _data; +} + +QByteArray & XByteArray::replace(int index, const QByteArray & ba) +{ + int len = ba.length(); + return replace(index, len, ba); +} + +QByteArray & XByteArray::replace(int index, int length, const QByteArray & ba) +{ + int len; + if((index + length) > _data.length()) + len = _data.length() - index; + else + len = length; + _data.replace(index, len, ba.mid(0, len)); + return _data; +} diff --git a/src/gui/Src/QHexEdit/XByteArray.h b/src/gui/Src/QHexEdit/XByteArray.h index f70998e3..f4b078eb 100644 --- a/src/gui/Src/QHexEdit/XByteArray.h +++ b/src/gui/Src/QHexEdit/XByteArray.h @@ -1,32 +1,32 @@ -#ifndef XBYTEARRAY_H -#define XBYTEARRAY_H - -#include - -class XByteArray -{ -public: - explicit XByteArray(); - - QByteArray & data(); - void setData(QByteArray data); - int size(); - - QByteArray & insert(int i, char ch); - QByteArray & insert(int i, const QByteArray & ba); - - QByteArray & remove(int pos, int len); - - QByteArray & replace(int index, char ch); - QByteArray & replace(int index, const QByteArray & ba); - QByteArray & replace(int index, int length, const QByteArray & ba); - -signals: - -public slots: - -private: - QByteArray _data; //raw byte array -}; - -#endif // XBYTEARRAY_H +#ifndef XBYTEARRAY_H +#define XBYTEARRAY_H + +#include + +class XByteArray +{ +public: + explicit XByteArray(); + + QByteArray & data(); + void setData(QByteArray data); + int size(); + + QByteArray & insert(int i, char ch); + QByteArray & insert(int i, const QByteArray & ba); + + QByteArray & remove(int pos, int len); + + QByteArray & replace(int index, char ch); + QByteArray & replace(int index, const QByteArray & ba); + QByteArray & replace(int index, int length, const QByteArray & ba); + +signals: + +public slots: + +private: + QByteArray _data; //raw byte array +}; + +#endif // XBYTEARRAY_H diff --git a/src/gui/Src/ThirdPartyLibs/snowman/SnowmanView.h b/src/gui/Src/ThirdPartyLibs/snowman/SnowmanView.h index 030e9856..ce0ff1c8 100644 --- a/src/gui/Src/ThirdPartyLibs/snowman/SnowmanView.h +++ b/src/gui/Src/ThirdPartyLibs/snowman/SnowmanView.h @@ -1,15 +1,15 @@ -#ifndef SNOWMANVIEW_H -#define SNOWMANVIEW_H - -#include - -class SnowmanView : public QWidget -{ - Q_OBJECT -}; - -extern "C" __declspec(dllexport) SnowmanView* CreateSnowman(QWidget* parent); -extern "C" __declspec(dllexport) void DecompileAt(SnowmanView* snowman, dsint start, dsint end); -extern "C" __declspec(dllexport) void CloseSnowman(SnowmanView* snowman); - -#endif // SNOWMANVIEW_H +#ifndef SNOWMANVIEW_H +#define SNOWMANVIEW_H + +#include + +class SnowmanView : public QWidget +{ + Q_OBJECT +}; + +extern "C" __declspec(dllexport) SnowmanView* CreateSnowman(QWidget* parent); +extern "C" __declspec(dllexport) void DecompileAt(SnowmanView* snowman, dsint start, dsint end); +extern "C" __declspec(dllexport) void CloseSnowman(SnowmanView* snowman); + +#endif // SNOWMANVIEW_H diff --git a/src/gui/Src/Utils/Breakpoints.cpp b/src/gui/Src/Utils/Breakpoints.cpp index 84268994..06f6b377 100644 --- a/src/gui/Src/Utils/Breakpoints.cpp +++ b/src/gui/Src/Utils/Breakpoints.cpp @@ -1,381 +1,381 @@ -#include "Breakpoints.h" - -Breakpoints::Breakpoints(QObject* parent) : QObject(parent) -{ - -} - -/** - * @brief Set a new breakpoint according to the given type at the given address. - * - * @param[in] type Type of the breakpoint - * @param[in] va Virtual Address - * - * @return Nothing. - */ -void Breakpoints::setBP(BPXTYPE type, duint va) -{ - QString wCmd = ""; - - switch(type) - { - case bp_normal: - { - wCmd = "bp " + QString("%1").arg(va, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - break; - - case bp_hardware: - { - wCmd = "bph " + QString("%1").arg(va, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - break; - - case bp_memory: - { - wCmd = "bpm " + QString("%1").arg(va, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - break; - - default: - { - - } - break; - } - - DbgCmdExec(wCmd.toUtf8().constData()); -} - -/** - * @brief Enable breakpoint according to the given breakpoint descriptor. - * - * @param[in] bp Breakpoint descriptor - * - * @return Nothing. - */ -void Breakpoints::enableBP(const BRIDGEBP & bp) -{ - QString wCmd = ""; - - if(bp.type == bp_hardware) - { - wCmd = "bphwe " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - else if(bp.type == bp_normal) - { - wCmd = "be " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - else if(bp.type == bp_memory) - { - wCmd = "bpme " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - - DbgCmdExec(wCmd.toUtf8().constData()); -} - -/** - * @brief Enable breakpoint that has been previously disabled according to its type and virtual address. - * If breakpoint was removed, this method has no effect.@n - * Breakpoint type is usefull when there are several types of breakpoints on the same address. - * bp_none enables all breakpoints at the given address. - * - * @param[in] type Type of the breakpoint. - * @param[in] va Virtual Address - * - * @return Nothing. - */ -void Breakpoints::enableBP(BPXTYPE type, duint va) -{ - BPMAP wBPList; - - // Get breakpoints list - DbgGetBpList(type, &wBPList); - - // Find breakpoint at address VA - for(int wI = 0; wI < wBPList.count; wI++) - { - if(wBPList.bp[wI].addr == va) - { - enableBP(wBPList.bp[wI]); - } - } - if(wBPList.count) - BridgeFree(wBPList.bp); -} - -/** - * @brief Disable breakpoint according to the given breakpoint descriptor. - * - * @param[in] bp Breakpoint descriptor - * - * @return Nothing. - */ -void Breakpoints::disableBP(const BRIDGEBP & bp) -{ - QString wCmd = ""; - - if(bp.type == bp_hardware) - { - wCmd = "bphwd " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - else if(bp.type == bp_normal) - { - wCmd = "bd " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - else if(bp.type == bp_memory) - { - wCmd = "bpmd " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - - DbgCmdExec(wCmd.toUtf8().constData()); -} - -/** - * @brief Disable breakpoint that has been previously enabled according to its type and virtual address. - * If breakpoint was removed, this method has no effect.@n - * Breakpoint type is usefull when there are several types of breakpoints on the same address. - * bp_none disbales all breakpoints at the given address. - * - * @param[in] type Type of the breakpoint. - * @param[in] va Virtual Address - * - * @return Nothing. - */ -void Breakpoints::disableBP(BPXTYPE type, duint va) -{ - BPMAP wBPList; - - // Get breakpoints list - DbgGetBpList(type, &wBPList); - - // Find breakpoint at address VA - for(int wI = 0; wI < wBPList.count; wI++) - { - if(wBPList.bp[wI].addr == va) - { - disableBP(wBPList.bp[wI]); - } - } - if(wBPList.count) - BridgeFree(wBPList.bp); -} - -/** - * @brief Remove breakpoint according to the given breakpoint descriptor. - * - * @param[in] bp Breakpoint descriptor - * - * @return Nothing. - */ -void Breakpoints::removeBP(const BRIDGEBP & bp) -{ - QString wCmd = ""; - - switch(bp.type) - { - case bp_normal: - { - wCmd = "bc " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - break; - - case bp_hardware: - { - wCmd = "bphc " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - break; - - case bp_memory: - { - wCmd = "bpmc " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); - } - break; - - default: - { - - } - break; - } - - DbgCmdExec(wCmd.toUtf8().constData()); -} - -/** - * @brief Remove breakpoint at the given given address and type - * If breakpoint doesn't exists, this method has no effect.@n - * Breakpoint type is usefull when there are several types of breakpoints on the same address. - * bp_none disbales all breakpoints at the given address. - * - * @param[in] type Type of the breakpoint. - * @param[in] va Virtual Address - * - * @return Nothing. - */ -void Breakpoints::removeBP(BPXTYPE type, duint va) -{ - BPMAP wBPList; - - // Get breakpoints list - DbgGetBpList(type, &wBPList); - - // Find breakpoint at address VA - for(int wI = 0; wI < wBPList.count; wI++) - { - if(wBPList.bp[wI].addr == va) - { - removeBP(wBPList.bp[wI]); - } - } - if(wBPList.count) - BridgeFree(wBPList.bp); -} - -/** - * @brief Toggle the given breakpoint by disabling it when enabled.@n - * If breakpoint is initially active and enabled, it will be disabled.@n - * If breakpoint is initially active and disabled, it will stay disabled.@n - * - * @param[in] bp Breakpoint descriptor - * - * @return Nothing. - */ -void Breakpoints::toggleBPByDisabling(const BRIDGEBP & bp) -{ - if(bp.enabled == true) - disableBP(bp); - else - enableBP(bp); -} - -/** - * @brief Toggle the given breakpoint by disabling it when enabled.@n - * If breakpoint is initially active and enabled, it will be disabled.@n - * If breakpoint is initially active and disabled, it will stay disabled.@n - * If breakpoint was previously removed, this method has no effect.@n - * - * @param[in] type Type of the breakpoint. - * @param[in] va Virtual Address - * - * @return Nothing. - */ -void Breakpoints::toggleBPByDisabling(BPXTYPE type, duint va) -{ - BPMAP wBPList; - - // Get breakpoints list - DbgGetBpList(type, &wBPList); - - // Find breakpoint at address VA - for(int wI = 0; wI < wBPList.count; wI++) - { - if(wBPList.bp[wI].addr == va) - { - toggleBPByDisabling(wBPList.bp[wI]); - } - } - if(wBPList.count) - BridgeFree(wBPList.bp); -} - -/** - * @brief returns if a breakpoint is disabled or not - * - * @param[in] type Type of the breakpoint. - * @param[in] va Virtual Address - * - * @return enabled/disabled. - */ -BPXSTATE Breakpoints::BPState(BPXTYPE type, duint va) -{ - BPMAP wBPList; - BPXSTATE result = bp_non_existent; - - // Get breakpoints list - DbgGetBpList(type, &wBPList); - - // Find breakpoint at address VA - for(int wI = 0; wI < wBPList.count; wI++) - { - if(wBPList.bp[wI].addr == va) - { - if(wBPList.bp[wI].enabled) - { - result = bp_enabled; - break; - } - else - { - result = bp_disabled; - break; - } - } - } - if(wBPList.count) - BridgeFree(wBPList.bp); - - return result; -} - - -/** - * @brief Toggle the given breakpoint by disabling it when enabled.@n - * If breakpoint is initially active and enabled, it will be disabled.@n - * If breakpoint is initially active and disabled, it will stay disabled.@n - * If breakpoint was previously removed, this method has no effect.@n - * - * @param[in] type Type of the breakpoint. - * @param[in] va Virtual Address - * - * @return Nothing. - */ -void Breakpoints::toggleBPByRemoving(BPXTYPE type, duint va) -{ - BPMAP wBPList; - bool wNormalWasRemoved = false; - bool wMemoryWasRemoved = false; - bool wHardwareWasRemoved = false; - - // Get breakpoints list - DbgGetBpList(type, &wBPList); - - // Find breakpoints at address VA and remove them - for(int wI = 0; wI < wBPList.count; wI++) - { - if(wBPList.bp[wI].addr == va) - { - removeBP(wBPList.bp[wI]); - - switch(wBPList.bp[wI].type) - { - case bp_normal: - wNormalWasRemoved = true; - break; - case bp_memory: - wMemoryWasRemoved = true; - break; - case bp_hardware: - wHardwareWasRemoved = true; - break; - default: - break; - } - } - } - if(wBPList.count) - BridgeFree(wBPList.bp); - - if((type == bp_none || type == bp_normal) && (wNormalWasRemoved == false)) - { - setBP(bp_normal, va); - } - else if((type == bp_none || type == bp_memory) && (wMemoryWasRemoved == false)) - { - setBP(bp_memory, va); - } - else if((type == bp_none || type == bp_hardware) && (wHardwareWasRemoved == false)) - { - setBP(bp_hardware, va); - } -} +#include "Breakpoints.h" + +Breakpoints::Breakpoints(QObject* parent) : QObject(parent) +{ + +} + +/** + * @brief Set a new breakpoint according to the given type at the given address. + * + * @param[in] type Type of the breakpoint + * @param[in] va Virtual Address + * + * @return Nothing. + */ +void Breakpoints::setBP(BPXTYPE type, duint va) +{ + QString wCmd = ""; + + switch(type) + { + case bp_normal: + { + wCmd = "bp " + QString("%1").arg(va, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + break; + + case bp_hardware: + { + wCmd = "bph " + QString("%1").arg(va, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + break; + + case bp_memory: + { + wCmd = "bpm " + QString("%1").arg(va, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + break; + + default: + { + + } + break; + } + + DbgCmdExec(wCmd.toUtf8().constData()); +} + +/** + * @brief Enable breakpoint according to the given breakpoint descriptor. + * + * @param[in] bp Breakpoint descriptor + * + * @return Nothing. + */ +void Breakpoints::enableBP(const BRIDGEBP & bp) +{ + QString wCmd = ""; + + if(bp.type == bp_hardware) + { + wCmd = "bphwe " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + else if(bp.type == bp_normal) + { + wCmd = "be " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + else if(bp.type == bp_memory) + { + wCmd = "bpme " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + + DbgCmdExec(wCmd.toUtf8().constData()); +} + +/** + * @brief Enable breakpoint that has been previously disabled according to its type and virtual address. + * If breakpoint was removed, this method has no effect.@n + * Breakpoint type is usefull when there are several types of breakpoints on the same address. + * bp_none enables all breakpoints at the given address. + * + * @param[in] type Type of the breakpoint. + * @param[in] va Virtual Address + * + * @return Nothing. + */ +void Breakpoints::enableBP(BPXTYPE type, duint va) +{ + BPMAP wBPList; + + // Get breakpoints list + DbgGetBpList(type, &wBPList); + + // Find breakpoint at address VA + for(int wI = 0; wI < wBPList.count; wI++) + { + if(wBPList.bp[wI].addr == va) + { + enableBP(wBPList.bp[wI]); + } + } + if(wBPList.count) + BridgeFree(wBPList.bp); +} + +/** + * @brief Disable breakpoint according to the given breakpoint descriptor. + * + * @param[in] bp Breakpoint descriptor + * + * @return Nothing. + */ +void Breakpoints::disableBP(const BRIDGEBP & bp) +{ + QString wCmd = ""; + + if(bp.type == bp_hardware) + { + wCmd = "bphwd " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + else if(bp.type == bp_normal) + { + wCmd = "bd " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + else if(bp.type == bp_memory) + { + wCmd = "bpmd " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + + DbgCmdExec(wCmd.toUtf8().constData()); +} + +/** + * @brief Disable breakpoint that has been previously enabled according to its type and virtual address. + * If breakpoint was removed, this method has no effect.@n + * Breakpoint type is usefull when there are several types of breakpoints on the same address. + * bp_none disbales all breakpoints at the given address. + * + * @param[in] type Type of the breakpoint. + * @param[in] va Virtual Address + * + * @return Nothing. + */ +void Breakpoints::disableBP(BPXTYPE type, duint va) +{ + BPMAP wBPList; + + // Get breakpoints list + DbgGetBpList(type, &wBPList); + + // Find breakpoint at address VA + for(int wI = 0; wI < wBPList.count; wI++) + { + if(wBPList.bp[wI].addr == va) + { + disableBP(wBPList.bp[wI]); + } + } + if(wBPList.count) + BridgeFree(wBPList.bp); +} + +/** + * @brief Remove breakpoint according to the given breakpoint descriptor. + * + * @param[in] bp Breakpoint descriptor + * + * @return Nothing. + */ +void Breakpoints::removeBP(const BRIDGEBP & bp) +{ + QString wCmd = ""; + + switch(bp.type) + { + case bp_normal: + { + wCmd = "bc " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + break; + + case bp_hardware: + { + wCmd = "bphc " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + break; + + case bp_memory: + { + wCmd = "bpmc " + QString("%1").arg(bp.addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper(); + } + break; + + default: + { + + } + break; + } + + DbgCmdExec(wCmd.toUtf8().constData()); +} + +/** + * @brief Remove breakpoint at the given given address and type + * If breakpoint doesn't exists, this method has no effect.@n + * Breakpoint type is usefull when there are several types of breakpoints on the same address. + * bp_none disbales all breakpoints at the given address. + * + * @param[in] type Type of the breakpoint. + * @param[in] va Virtual Address + * + * @return Nothing. + */ +void Breakpoints::removeBP(BPXTYPE type, duint va) +{ + BPMAP wBPList; + + // Get breakpoints list + DbgGetBpList(type, &wBPList); + + // Find breakpoint at address VA + for(int wI = 0; wI < wBPList.count; wI++) + { + if(wBPList.bp[wI].addr == va) + { + removeBP(wBPList.bp[wI]); + } + } + if(wBPList.count) + BridgeFree(wBPList.bp); +} + +/** + * @brief Toggle the given breakpoint by disabling it when enabled.@n + * If breakpoint is initially active and enabled, it will be disabled.@n + * If breakpoint is initially active and disabled, it will stay disabled.@n + * + * @param[in] bp Breakpoint descriptor + * + * @return Nothing. + */ +void Breakpoints::toggleBPByDisabling(const BRIDGEBP & bp) +{ + if(bp.enabled == true) + disableBP(bp); + else + enableBP(bp); +} + +/** + * @brief Toggle the given breakpoint by disabling it when enabled.@n + * If breakpoint is initially active and enabled, it will be disabled.@n + * If breakpoint is initially active and disabled, it will stay disabled.@n + * If breakpoint was previously removed, this method has no effect.@n + * + * @param[in] type Type of the breakpoint. + * @param[in] va Virtual Address + * + * @return Nothing. + */ +void Breakpoints::toggleBPByDisabling(BPXTYPE type, duint va) +{ + BPMAP wBPList; + + // Get breakpoints list + DbgGetBpList(type, &wBPList); + + // Find breakpoint at address VA + for(int wI = 0; wI < wBPList.count; wI++) + { + if(wBPList.bp[wI].addr == va) + { + toggleBPByDisabling(wBPList.bp[wI]); + } + } + if(wBPList.count) + BridgeFree(wBPList.bp); +} + +/** + * @brief returns if a breakpoint is disabled or not + * + * @param[in] type Type of the breakpoint. + * @param[in] va Virtual Address + * + * @return enabled/disabled. + */ +BPXSTATE Breakpoints::BPState(BPXTYPE type, duint va) +{ + BPMAP wBPList; + BPXSTATE result = bp_non_existent; + + // Get breakpoints list + DbgGetBpList(type, &wBPList); + + // Find breakpoint at address VA + for(int wI = 0; wI < wBPList.count; wI++) + { + if(wBPList.bp[wI].addr == va) + { + if(wBPList.bp[wI].enabled) + { + result = bp_enabled; + break; + } + else + { + result = bp_disabled; + break; + } + } + } + if(wBPList.count) + BridgeFree(wBPList.bp); + + return result; +} + + +/** + * @brief Toggle the given breakpoint by disabling it when enabled.@n + * If breakpoint is initially active and enabled, it will be disabled.@n + * If breakpoint is initially active and disabled, it will stay disabled.@n + * If breakpoint was previously removed, this method has no effect.@n + * + * @param[in] type Type of the breakpoint. + * @param[in] va Virtual Address + * + * @return Nothing. + */ +void Breakpoints::toggleBPByRemoving(BPXTYPE type, duint va) +{ + BPMAP wBPList; + bool wNormalWasRemoved = false; + bool wMemoryWasRemoved = false; + bool wHardwareWasRemoved = false; + + // Get breakpoints list + DbgGetBpList(type, &wBPList); + + // Find breakpoints at address VA and remove them + for(int wI = 0; wI < wBPList.count; wI++) + { + if(wBPList.bp[wI].addr == va) + { + removeBP(wBPList.bp[wI]); + + switch(wBPList.bp[wI].type) + { + case bp_normal: + wNormalWasRemoved = true; + break; + case bp_memory: + wMemoryWasRemoved = true; + break; + case bp_hardware: + wHardwareWasRemoved = true; + break; + default: + break; + } + } + } + if(wBPList.count) + BridgeFree(wBPList.bp); + + if((type == bp_none || type == bp_normal) && (wNormalWasRemoved == false)) + { + setBP(bp_normal, va); + } + else if((type == bp_none || type == bp_memory) && (wMemoryWasRemoved == false)) + { + setBP(bp_memory, va); + } + else if((type == bp_none || type == bp_hardware) && (wHardwareWasRemoved == false)) + { + setBP(bp_hardware, va); + } +} diff --git a/src/gui/Src/Utils/Breakpoints.h b/src/gui/Src/Utils/Breakpoints.h index bf283d05..834a3513 100644 --- a/src/gui/Src/Utils/Breakpoints.h +++ b/src/gui/Src/Utils/Breakpoints.h @@ -1,33 +1,33 @@ -#ifndef BREAKPOINTS_H -#define BREAKPOINTS_H - -#include -#include "Bridge.h" - -enum BPXSTATE -{ - bp_enabled = 0, - bp_disabled = 1, - bp_non_existent = -1 -}; - -class Breakpoints : public QObject -{ - Q_OBJECT - -public: - explicit Breakpoints(QObject* parent = 0); - static void setBP(BPXTYPE type, duint va); - static void enableBP(const BRIDGEBP & bp); - static void enableBP(BPXTYPE type, duint va); - static void disableBP(const BRIDGEBP & bp); - static void disableBP(BPXTYPE type, duint va); - static void removeBP(const BRIDGEBP & bp); - static void removeBP(BPXTYPE type, duint va); - static void toggleBPByDisabling(const BRIDGEBP & bp); - static void toggleBPByDisabling(BPXTYPE type, duint va); - static void toggleBPByRemoving(BPXTYPE type, duint va); - static BPXSTATE BPState(BPXTYPE type, duint va); -}; - -#endif // BREAKPOINTS_H +#ifndef BREAKPOINTS_H +#define BREAKPOINTS_H + +#include +#include "Bridge.h" + +enum BPXSTATE +{ + bp_enabled = 0, + bp_disabled = 1, + bp_non_existent = -1 +}; + +class Breakpoints : public QObject +{ + Q_OBJECT + +public: + explicit Breakpoints(QObject* parent = 0); + static void setBP(BPXTYPE type, duint va); + static void enableBP(const BRIDGEBP & bp); + static void enableBP(BPXTYPE type, duint va); + static void disableBP(const BRIDGEBP & bp); + static void disableBP(BPXTYPE type, duint va); + static void removeBP(const BRIDGEBP & bp); + static void removeBP(BPXTYPE type, duint va); + static void toggleBPByDisabling(const BRIDGEBP & bp); + static void toggleBPByDisabling(BPXTYPE type, duint va); + static void toggleBPByRemoving(BPXTYPE type, duint va); + static BPXSTATE BPState(BPXTYPE type, duint va); +}; + +#endif // BREAKPOINTS_H diff --git a/src/gui/Src/Utils/Configuration.cpp b/src/gui/Src/Utils/Configuration.cpp index edebcb33..8ba69dbb 100644 --- a/src/gui/Src/Utils/Configuration.cpp +++ b/src/gui/Src/Utils/Configuration.cpp @@ -1,750 +1,750 @@ -#include "Configuration.h" -#include -#include -#include -#include - -Configuration* Configuration::mPtr = NULL; - -Configuration::Configuration() : QObject() -{ - //setup default color map - defaultColors.clear(); - defaultColors.insert("AbstractTableViewSeparatorColor", QColor("#808080")); - defaultColors.insert("AbstractTableViewBackgroundColor", QColor("#FFF8F0")); - defaultColors.insert("AbstractTableViewTextColor", QColor("#000000")); - defaultColors.insert("AbstractTableViewHeaderTextColor", QColor("#000000")); - defaultColors.insert("AbstractTableViewSelectionColor", QColor("#C0C0C0")); - - defaultColors.insert("DisassemblyCipColor", QColor("#FFFFFF")); - defaultColors.insert("DisassemblyCipBackgroundColor", QColor("#000000")); - defaultColors.insert("DisassemblyBreakpointColor", QColor("#000000")); - defaultColors.insert("DisassemblyBreakpointBackgroundColor", QColor("#FF0000")); - defaultColors.insert("DisassemblyHardwareBreakpointColor", QColor("#000000")); - defaultColors.insert("DisassemblyHardwareBreakpointBackgroundColor", Qt::transparent); - defaultColors.insert("DisassemblyBookmarkColor", QColor("#000000")); - defaultColors.insert("DisassemblyBookmarkBackgroundColor", QColor("#FEE970")); - defaultColors.insert("DisassemblyLabelColor", QColor("#FF0000")); - defaultColors.insert("DisassemblyLabelBackgroundColor", Qt::transparent); - defaultColors.insert("DisassemblyBackgroundColor", QColor("#FFF8F0")); - defaultColors.insert("DisassemblySelectionColor", QColor("#C0C0C0")); - defaultColors.insert("DisassemblyAddressColor", QColor("#808080")); - defaultColors.insert("DisassemblyAddressBackgroundColor", Qt::transparent); - defaultColors.insert("DisassemblySelectedAddressColor", QColor("#000000")); - defaultColors.insert("DisassemblySelectedAddressBackgroundColor", Qt::transparent); - defaultColors.insert("DisassemblyConditionalJumpLineTrueColor", QColor("#FF0000")); - defaultColors.insert("DisassemblyConditionalJumpLineFalseColor", QColor("#808080")); - defaultColors.insert("DisassemblyUnconditionalJumpLineColor", QColor("#FF0000")); - defaultColors.insert("DisassemblyBytesColor", QColor("#000000")); - defaultColors.insert("DisassemblyModifiedBytesColor", QColor("#FF0000")); - defaultColors.insert("DisassemblyCommentColor", QColor("#000000")); - defaultColors.insert("DisassemblyCommentBackgroundColor", Qt::transparent); - defaultColors.insert("DisassemblyAutoCommentColor", QColor("#808080")); - defaultColors.insert("DisassemblyAutoCommentBackgroundColor", Qt::transparent); - defaultColors.insert("DisassemblyFunctionColor", QColor("#000000")); - defaultColors.insert("DisassemblyLoopColor", QColor("#000000")); - - defaultColors.insert("SideBarCipLabelColor", QColor("#FFFFFF")); - defaultColors.insert("SideBarCipLabelBackgroundColor", QColor("#4040FF")); - defaultColors.insert("SideBarBackgroundColor", QColor("#FFF8F0")); - defaultColors.insert("SideBarConditionalJumpLineTrueColor", QColor("#FF0000")); - defaultColors.insert("SideBarConditionalJumpLineFalseColor", QColor("#808080")); - defaultColors.insert("SideBarUnconditionalJumpLineTrueColor", QColor("#FF0000")); - defaultColors.insert("SideBarUnconditionalJumpLineFalseColor", QColor("#808080")); - defaultColors.insert("SideBarBulletColor", QColor("#808080")); - defaultColors.insert("SideBarBulletBreakpointColor", QColor("#FF0000")); - defaultColors.insert("SideBarBulletDisabledBreakpointColor", QColor("#00AA00")); - defaultColors.insert("SideBarBulletBookmarkColor", QColor("#FEE970")); - - defaultColors.insert("RegistersBackgroundColor", QColor("#FFF8F0")); - defaultColors.insert("RegistersColor", QColor("#000000")); - defaultColors.insert("RegistersModifiedColor", QColor("#FF0000")); - defaultColors.insert("RegistersSelectionColor", QColor("#EEEEEE")); - defaultColors.insert("RegistersLabelColor", QColor("#000000")); - defaultColors.insert("RegistersExtraInfoColor", QColor("#000000")); - - defaultColors.insert("InstructionHighlightColor", QColor("#FF0000")); - defaultColors.insert("InstructionCommaColor", QColor("#000000")); - defaultColors.insert("InstructionCommaBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionPrefixColor", QColor("#000000")); - defaultColors.insert("InstructionPrefixBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionUncategorizedColor", QColor("#000000")); - defaultColors.insert("InstructionUncategorizedBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionAddressColor", QColor("#000000")); - defaultColors.insert("InstructionAddressBackgroundColor", QColor("#FFFF00")); - defaultColors.insert("InstructionValueColor", QColor("#828200")); - defaultColors.insert("InstructionValueBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionMnemonicColor", QColor("#000000")); - defaultColors.insert("InstructionMnemonicBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionPushPopColor", QColor("#0000FF")); - defaultColors.insert("InstructionPushPopBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionCallColor", QColor("#000000")); - defaultColors.insert("InstructionCallBackgroundColor", QColor("#00FFFF")); - defaultColors.insert("InstructionRetColor", QColor("#000000")); - defaultColors.insert("InstructionRetBackgroundColor", QColor("#00FFFF")); - defaultColors.insert("InstructionConditionalJumpColor", QColor("#FF0000")); - defaultColors.insert("InstructionConditionalJumpBackgroundColor", QColor("#FFFF00")); - defaultColors.insert("InstructionUnconditionalJumpColor", QColor("#000000")); - defaultColors.insert("InstructionUnconditionalJumpBackgroundColor", QColor("#FFFF00")); - defaultColors.insert("InstructionNopColor", QColor("#808080")); - defaultColors.insert("InstructionNopBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionFarColor", QColor("#000000")); - defaultColors.insert("InstructionFarBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionInt3Color", QColor("#000000")); - defaultColors.insert("InstructionInt3BackgroundColor", Qt::transparent); - defaultColors.insert("InstructionMemorySizeColor", QColor("#000080")); - defaultColors.insert("InstructionMemorySizeBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionMemorySegmentColor", QColor("#FF00FF")); - defaultColors.insert("InstructionMemorySegmentBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionMemoryBracketsColor", QColor("#000000")); - defaultColors.insert("InstructionMemoryBracketsBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionMemoryStackBracketsColor", QColor("#000000")); - defaultColors.insert("InstructionMemoryStackBracketsBackgroundColor", QColor("#00FFFF")); - defaultColors.insert("InstructionMemoryBaseRegisterColor", QColor("#B03434")); - defaultColors.insert("InstructionMemoryBaseRegisterBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionMemoryIndexRegisterColor", QColor("#3838BC")); - defaultColors.insert("InstructionMemoryIndexRegisterBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionMemoryScaleColor", QColor("#B30059")); - defaultColors.insert("InstructionMemoryScaleBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionMemoryOperatorColor", QColor("#F27711")); - defaultColors.insert("InstructionMemoryOperatorBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionGeneralRegisterColor", QColor("#008300")); - defaultColors.insert("InstructionGeneralRegisterBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionFpuRegisterColor", QColor("#000080")); - defaultColors.insert("InstructionFpuRegisterBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionMmxRegisterColor", QColor("#000080")); - defaultColors.insert("InstructionMmxRegisterBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionXmmRegisterColor", QColor("#000080")); - defaultColors.insert("InstructionXmmRegisterBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionYmmRegisterColor", QColor("#000080")); - defaultColors.insert("InstructionYmmRegisterBackgroundColor", Qt::transparent); - defaultColors.insert("InstructionZmmRegisterColor", QColor("#000080")); - defaultColors.insert("InstructionZmmRegisterBackgroundColor", Qt::transparent); - - defaultColors.insert("HexDumpTextColor", QColor("#000000")); - defaultColors.insert("HexDumpModifiedBytesColor", QColor("#FF0000")); - defaultColors.insert("HexDumpBackgroundColor", QColor("#FFF8F0")); - defaultColors.insert("HexDumpSelectionColor", QColor("#C0C0C0")); - defaultColors.insert("HexDumpAddressColor", QColor("#000000")); - defaultColors.insert("HexDumpAddressBackgroundColor", Qt::transparent); - defaultColors.insert("HexDumpLabelColor", QColor("#FF0000")); - defaultColors.insert("HexDumpLabelBackgroundColor", Qt::transparent); - - defaultColors.insert("StackTextColor", QColor("#000000")); - defaultColors.insert("StackInactiveTextColor", QColor("#808080")); - defaultColors.insert("StackBackgroundColor", QColor("#FFF8F0")); - defaultColors.insert("StackSelectionColor", QColor("#C0C0C0")); - defaultColors.insert("StackCspColor", QColor("#FFFFFF")); - defaultColors.insert("StackCspBackgroundColor", QColor("#000000")); - defaultColors.insert("StackAddressColor", QColor("#808080")); - defaultColors.insert("StackAddressBackgroundColor", Qt::transparent); - defaultColors.insert("StackSelectedAddressColor", QColor("#000000")); - defaultColors.insert("StackSelectedAddressBackgroundColor", Qt::transparent); - defaultColors.insert("StackLabelColor", QColor("#FF0000")); - defaultColors.insert("StackLabelBackgroundColor", Qt::transparent); - - defaultColors.insert("HexEditTextColor", QColor("#000000")); - defaultColors.insert("HexEditWildcardColor", QColor("#FF0000")); - defaultColors.insert("HexEditBackgroundColor", QColor("#FFF8F0")); - defaultColors.insert("HexEditSelectionColor", QColor("#C0C0C0")); - - defaultColors.insert("ThreadCurrentColor", QColor("#FFFFFF")); - defaultColors.insert("ThreadCurrentBackgroundColor", QColor("#000000")); - defaultColors.insert("MemoryMapBreakpointColor", QColor("#FFFBF0")); - defaultColors.insert("MemoryMapBreakpointBackgroundColor", QColor("#FF0000")); - defaultColors.insert("MemoryMapSectionTextColor", QColor("#8B671F")); - defaultColors.insert("SearchListViewHighlightColor", QColor("#FF0000")); - - //bool settings - QMap disassemblyBool; - disassemblyBool.insert("ArgumentSpaces", false); - disassemblyBool.insert("MemorySpaces", false); - disassemblyBool.insert("FillNOPs", false); - disassemblyBool.insert("Uppercase", false); - disassemblyBool.insert("FindCommandEntireBlock", false); - disassemblyBool.insert("OnlyCipAutoComments", false); - disassemblyBool.insert("TabbedMnemonic", false); - defaultBools.insert("Disassembler", disassemblyBool); - - QMap engineBool; - engineBool.insert("ListAllPages", false); - defaultBools.insert("Engine", engineBool); - - //uint settings - QMap hexdumpUint; - hexdumpUint.insert("DefaultView", 0); - defaultUints.insert("HexDump", hexdumpUint); - QMap disasmUint; - disasmUint.insert("MaxModuleSize", -1); - defaultUints.insert("Disassembler", disasmUint); - - //font settings - QFont font("Lucida Console", 8, QFont::Normal, false); - defaultFonts.insert("AbstractTableView", font); - defaultFonts.insert("Disassembly", font); - defaultFonts.insert("HexDump", font); - defaultFonts.insert("Stack", font); - defaultFonts.insert("Registers", font); - defaultFonts.insert("HexEdit", font); - defaultFonts.insert("Application", QApplication::font()); - defaultFonts.insert("Log", QFont("Courier", 8, QFont::Normal, false)); - - // hotkeys settings - defaultShortcuts.insert("FileOpen", Shortcut(tr("File -> Open"), "F3", true)); - defaultShortcuts.insert("FileAttach", Shortcut(tr("File -> Attach"), "Alt+A", true)); - defaultShortcuts.insert("FileDetach", Shortcut(tr("File -> Detach"), "Ctrl+Alt+F2", true)); - defaultShortcuts.insert("FileExit", Shortcut(tr("File -> Exit"), "Alt+X", true)); - - defaultShortcuts.insert("ViewCpu", Shortcut(tr("View -> CPU"), "Alt+C", true)); - defaultShortcuts.insert("ViewLog", Shortcut(tr("View -> Log"), "Alt+L", true)); - defaultShortcuts.insert("ViewBreakpoints", Shortcut(tr("View -> Breakpoints"), "Alt+B", true)); - defaultShortcuts.insert("ViewMemoryMap", Shortcut(tr("View -> Memory Map"), "Alt+M", true)); - defaultShortcuts.insert("ViewCallStack", Shortcut(tr("View -> Call Stack"), "Alt+K", true)); - defaultShortcuts.insert("ViewScript", Shortcut(tr("View -> Script"), "Alt+S", true)); - defaultShortcuts.insert("ViewSymbolInfo", Shortcut(tr("View -> Symbol Info"), "Ctrl+Alt+S", true)); - defaultShortcuts.insert("ViewSource", Shortcut(tr("View -> Source"), "Ctrl+Shift+S", true)); - defaultShortcuts.insert("ViewReferences", Shortcut(tr("View -> References"), "Alt+R", true)); - defaultShortcuts.insert("ViewThreads", Shortcut(tr("View -> Threads"), "Alt+T", true)); - defaultShortcuts.insert("ViewPatches", Shortcut(tr("View -> Patches"), "Ctrl+P", true)); - defaultShortcuts.insert("ViewComments", Shortcut(tr("View -> Comments"), "Ctrl+Alt+C", true)); - defaultShortcuts.insert("ViewLabels", Shortcut(tr("View -> Labels"), "Ctrl+Alt+L", true)); - defaultShortcuts.insert("ViewBookmarks", Shortcut(tr("View -> Bookmarks"), "Ctrl+Alt+B", true)); - defaultShortcuts.insert("ViewFunctions", Shortcut(tr("View -> Functions"), "Alt+F", true)); - - defaultShortcuts.insert("DebugRun", Shortcut(tr("Debug -> Run"), "F9", true)); - defaultShortcuts.insert("DebugeRun", Shortcut(tr("Debug -> Run (skip exceptions)"), "Shift+F9", true)); - defaultShortcuts.insert("DebugRunSelection", Shortcut(tr("Debug -> Run until selection"), "F4", true)); - defaultShortcuts.insert("DebugPause", Shortcut(tr("Debug -> Pause"), "F12", true)); - defaultShortcuts.insert("DebugRestart", Shortcut(tr("Debug -> Restart"), "Ctrl+F2", true)); - defaultShortcuts.insert("DebugClose", Shortcut(tr("Debug -> Close"), "Alt+F2", true)); - defaultShortcuts.insert("DebugStepInto", Shortcut(tr("Debug -> Step into"), "F7", true)); - defaultShortcuts.insert("DebugeStepInfo", Shortcut(tr("Debug -> Step into (skip execptions)"), "Shift+F7", true)); - defaultShortcuts.insert("DebugStepOver", Shortcut(tr("Debug -> Step over"), "F8", true)); - defaultShortcuts.insert("DebugeStepOver", Shortcut(tr("Debug -> Step over (skip execptions)"), "Shift+F8", true)); - defaultShortcuts.insert("DebugRtr", Shortcut(tr("Debug -> Execute till return"), "Ctrl+F9", true)); - defaultShortcuts.insert("DebugeRtr", Shortcut(tr("Debug -> Execute till return (skip exceptions)"), "Ctrl+Shift+F9", true)); - defaultShortcuts.insert("DebugSkipNextInstruction", Shortcut(tr("Debug -> Skip next instruction"), "Ctrl+F8", true)); - defaultShortcuts.insert("DebugCommand", Shortcut(tr("Debug -> Command"), "Ctrl+Return", true)); - - defaultShortcuts.insert("PluginsScylla", Shortcut(tr("Plugins -> Scylla"), "Ctrl+I", true)); - - defaultShortcuts.insert("OptionsPreferences", Shortcut(tr("Options -> Preferences"), "", true)); - defaultShortcuts.insert("OptionsAppearance", Shortcut(tr("Options -> Appearance"), "", true)); - defaultShortcuts.insert("OptionsShortcuts", Shortcut(tr("Options -> Shortcuts"), "", true)); - defaultShortcuts.insert("OptionsTopmost", Shortcut(tr("Options -> Topmost"), "Ctrl+F5", true)); - - defaultShortcuts.insert("HelpAbout", Shortcut(tr("Help -> About"), "", true)); - defaultShortcuts.insert("HelpDonate", Shortcut(tr("Help -> Donate"), "", true)); - defaultShortcuts.insert("HelpCheckForUpdates", Shortcut(tr("Help -> Check for Updates"), "", true)); - defaultShortcuts.insert("HelpCalculator", Shortcut(tr("Help -> Calculator"), "?")); - defaultShortcuts.insert("HelpReportBug", Shortcut(tr("Help -> Report Bug"), "", true)); - defaultShortcuts.insert("HelpManual", Shortcut(tr("Help -> Manual"), "F1", true)); - - defaultShortcuts.insert("ActionFindStrings", Shortcut(tr("Actions -> Find Strings"), "", true)); - defaultShortcuts.insert("ActionFindIntermodularCalls", Shortcut(tr("Actions -> Find Intermodular Calls"), "", true)); - defaultShortcuts.insert("ActionToggleBreakpoint", Shortcut(tr("Actions -> Toggle Breakpoint"), "F2")); - defaultShortcuts.insert("ActionToggleBookmark", Shortcut(tr("Actions -> Toggle Bookmark"), "Ctrl+D")); - defaultShortcuts.insert("ActionDeleteBreakpoint", Shortcut(tr("Actions -> Delete Breakpoint"), "Delete")); - defaultShortcuts.insert("ActionEnableDisableBreakpoint", Shortcut(tr("Actions -> Enable/Disable Breakpoint"), "Space")); - - defaultShortcuts.insert("ActionBinaryEdit", Shortcut(tr("Actions -> Binary Edit"), "Ctrl+E")); - defaultShortcuts.insert("ActionBinaryFill", Shortcut(tr("Actions -> Binary Fill"), "F")); - defaultShortcuts.insert("ActionBinaryFillNops", Shortcut(tr("Actions -> Binary Fill NOPs"), "Ctrl+9")); - defaultShortcuts.insert("ActionBinaryCopy", Shortcut(tr("Actions -> Binary Copy"), "Shift+C")); - defaultShortcuts.insert("ActionBinaryPaste", Shortcut(tr("Actions -> Binary Paste"), "Shift+V")); - defaultShortcuts.insert("ActionBinaryPasteIgnoreSize", Shortcut(tr("Actions -> Binary Paste (Ignore Size)"), "Ctrl+Shift+V")); - defaultShortcuts.insert("ActionUndoSelection", Shortcut(tr("Actions -> Undo Selection"), "Ctrl+Backspace")); - defaultShortcuts.insert("ActionSetLabel", Shortcut(tr("Actions -> Set Label"), ":")); - defaultShortcuts.insert("ActionSetComment", Shortcut(tr("Actions -> Set Comment"), ";")); - defaultShortcuts.insert("ActionToggleFunction", Shortcut(tr("Actions -> Toggle Function"), "Shift+F")); - defaultShortcuts.insert("ActionAssemble", Shortcut(tr("Actions -> Assemble"), "Space")); - defaultShortcuts.insert("ActionYara", Shortcut(tr("Actions -> Yara"), "Ctrl+Y")); - defaultShortcuts.insert("ActionSetNewOriginHere", Shortcut(tr("Actions -> Set New Origin Here"), "Ctrl+*")); - defaultShortcuts.insert("ActionGotoOrigin", Shortcut(tr("Actions -> Goto Origin"), "*")); - defaultShortcuts.insert("ActionGotoPrevious", Shortcut(tr("Actions -> Goto Previous"), "-")); - defaultShortcuts.insert("ActionGotoNext", Shortcut(tr("Actions -> Goto Next"), "+")); - defaultShortcuts.insert("ActionGotoExpression", Shortcut(tr("Actions -> Goto Expression"), "Ctrl+G")); - defaultShortcuts.insert("ActionGotoStart", Shortcut(tr("Actions -> Goto Start of Page"), "Home")); - defaultShortcuts.insert("ActionGotoEnd", Shortcut(tr("Actions -> Goto End of Page"), "End")); - defaultShortcuts.insert("ActionGotoFileOffset", Shortcut(tr("Actions -> Goto File Offset"), "Ctrl+Shift+G")); - defaultShortcuts.insert("ActionFindReferencesToSelectedAddress", Shortcut(tr("Actions -> Find References to Selected Address"), "Ctrl+R")); - defaultShortcuts.insert("ActionFindPattern", Shortcut(tr("Actions -> Find Pattern"), "Ctrl+B")); - defaultShortcuts.insert("ActionFindReferences", Shortcut(tr("Actions -> Find References"), "Ctrl+R")); - defaultShortcuts.insert("ActionHighlightingMode", Shortcut(tr("Actions -> Highlighting Mode"), "Ctrl+H")); - defaultShortcuts.insert("ActionFind", Shortcut(tr("Actions -> Find"), "Ctrl+F")); - defaultShortcuts.insert("ActionDecompileFunction", Shortcut(tr("Actions -> Decompile Function"), "F5")); - defaultShortcuts.insert("ActionDecompileSelection", Shortcut(tr("Actions -> Decompile Selection"), "Shift+F5")); - - defaultShortcuts.insert("ActionIncreaseRegister", Shortcut(tr("Actions -> Increase Register"), "+")); - defaultShortcuts.insert("ActionDecreaseRegister", Shortcut(tr("Actions -> Decrease Register"), "-")); - defaultShortcuts.insert("ActionZeroRegister", Shortcut(tr("Actions -> Zero Register"), "0")); - defaultShortcuts.insert("ActionSetOneRegister", Shortcut(tr("Actions -> Set Register to One"), "1")); - defaultShortcuts.insert("ActionToggleRegisterValue", Shortcut(tr("Actions -> Toggle Register Value"), "Space")); - defaultShortcuts.insert("ActionCopy", Shortcut(tr("Actions -> Copy"), "Ctrl+C")); - defaultShortcuts.insert("ActionCopyAddress", Shortcut(tr("Actions -> Copy Address"), "Alt+INS")); - defaultShortcuts.insert("ActionCopySymbol", Shortcut(tr("Actions -> Copy Symbol"), "Ctrl+S")); - defaultShortcuts.insert("ActionLoadScript", Shortcut(tr("Actions -> Load Script"), "Ctrl+O")); - defaultShortcuts.insert("ActionReloadScript", Shortcut(tr("Actions -> Reload Script"), "Ctrl+R")); - defaultShortcuts.insert("ActionUnloadScript", Shortcut(tr("Actions -> Unload Script"), "Ctrl+U")); - defaultShortcuts.insert("ActionRunScript", Shortcut(tr("Actions -> Run Script"), "Space")); - defaultShortcuts.insert("ActionToggleBreakpointScript", Shortcut(tr("Actions -> Toggle Script Breakpoint"), "F2")); - defaultShortcuts.insert("ActionRunToCursorScript", Shortcut(tr("Actions -> Run Script to Cursor"), "Shift+F4")); - defaultShortcuts.insert("ActionStepScript", Shortcut(tr("Actions -> Step Script"), "Tab")); - defaultShortcuts.insert("ActionAbortScript", Shortcut(tr("Actions -> Abort Script"), "Esc")); - defaultShortcuts.insert("ActionExecuteCommandScript", Shortcut(tr("Actions -> Execute Script Command"), "X")); - - Shortcuts = defaultShortcuts; - - load(); - mPtr = this; -} - -Configuration* Config() -{ - return mPtr; -} - -void Configuration::load() -{ - readColors(); - readBools(); - readUints(); - readFonts(); - readShortcuts(); -} - -void Configuration::save() -{ - writeColors(); - writeBools(); - writeUints(); - writeFonts(); - writeShortcuts(); -} - -void Configuration::readColors() -{ - Colors = defaultColors; - //read config - for(int i = 0; i < Colors.size(); i++) - { - QString id = Colors.keys().at(i); - Colors[id] = colorFromConfig(id); - } -} - -void Configuration::writeColors() -{ - //write config - for(int i = 0; i < Colors.size(); i++) - { - QString id = Colors.keys().at(i); - colorToConfig(id, Colors[id]); - } - emit colorsUpdated(); -} - -void Configuration::emitColorsUpdated() -{ - emit colorsUpdated(); -} - -void Configuration::readBools() -{ - Bools = defaultBools; - //read config - for(int i = 0; i < Bools.size(); i++) - { - QString category = Bools.keys().at(i); - QMap* currentBool = &Bools[category]; - for(int j = 0; j < currentBool->size(); j++) - { - QString id = (*currentBool).keys().at(j); - (*currentBool)[id] = boolFromConfig(category, id); - } - } -} - -void Configuration::writeBools() -{ - //write config - for(int i = 0; i < Bools.size(); i++) - { - QString category = Bools.keys().at(i); - QMap* currentBool = &Bools[category]; - for(int j = 0; j < currentBool->size(); j++) - { - QString id = (*currentBool).keys().at(j); - boolToConfig(category, id, (*currentBool)[id]); - } - } -} - -void Configuration::readUints() -{ - Uints = defaultUints; - //read config - for(int i = 0; i < Uints.size(); i++) - { - QString category = Uints.keys().at(i); - QMap* currentUint = &Uints[category]; - for(int j = 0; j < currentUint->size(); j++) - { - QString id = (*currentUint).keys().at(j); - (*currentUint)[id] = uintFromConfig(category, id); - } - } -} - -void Configuration::writeUints() -{ - //write config - for(int i = 0; i < Uints.size(); i++) - { - QString category = Uints.keys().at(i); - QMap* currentUint = &Uints[category]; - for(int j = 0; j < currentUint->size(); j++) - { - QString id = (*currentUint).keys().at(j); - uintToConfig(category, id, (*currentUint)[id]); - } - } -} - -void Configuration::readFonts() -{ - Fonts = defaultFonts; - //read config - for(int i = 0; i < Fonts.size(); i++) - { - QString id = Fonts.keys().at(i); - QFont font = fontFromConfig(id); - QFontInfo fontInfo(font); - if(id == "Application" || fontInfo.fixedPitch()) - Fonts[id] = font; - } -} - -void Configuration::writeFonts() -{ - //write config - for(int i = 0; i < Fonts.size(); i++) - { - QString id = Fonts.keys().at(i); - fontToConfig(id, Fonts[id]); - } - emit fontsUpdated(); -} - -void Configuration::emitFontsUpdated() -{ - emit fontsUpdated(); -} - -void Configuration::readShortcuts() -{ - Shortcuts = defaultShortcuts; - QMap::const_iterator it = Shortcuts.begin(); - - while(it != Shortcuts.end()) - { - const QString id = it.key(); - QString key = shortcutFromConfig(id); - if(key != "") - { - if(key == "NOT_SET") - Shortcuts[it.key()].Hotkey = QKeySequence(); - else - { - QKeySequence KeySequence(key); - Shortcuts[it.key()].Hotkey = KeySequence; - } - } - it++; - } - emit shortcutsUpdated(); -} - -void Configuration::writeShortcuts() -{ - QMap::const_iterator it = Shortcuts.begin(); - - while(it != Shortcuts.end()) - { - shortcutToConfig(it.key(), it.value().Hotkey); - it++; - } - emit shortcutsUpdated(); -} - -const QColor Configuration::getColor(const QString id) const -{ - if(Colors.contains(id)) - return Colors.constFind(id).value(); - QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", id); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return Qt::black; -} - -const bool Configuration::getBool(const QString category, const QString id) const -{ - if(Bools.contains(category)) - { - if(Bools[category].contains(id)) - return Bools[category][id]; - QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category + ":" + id); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return false; - } - QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return false; -} - -void Configuration::setBool(const QString category, const QString id, const bool b) -{ - if(Bools.contains(category)) - { - if(Bools[category].contains(id)) - { - Bools[category][id] = b; - return; - } - QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category + ":" + id); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return; - } - QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); -} - -const duint Configuration::getUint(const QString category, const QString id) const -{ - if(Uints.contains(category)) - { - if(Uints[category].contains(id)) - return Uints[category][id]; - QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category + ":" + id); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return 0; - } - QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return 0; -} - -void Configuration::setUint(const QString category, const QString id, const duint i) -{ - if(Uints.contains(category)) - { - if(Uints[category].contains(id)) - { - Uints[category][id] = i; - return; - } - QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category + ":" + id); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return; - } - QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); -} - -const QFont Configuration::getFont(const QString id) const -{ - if(Fonts.contains(id)) - return Fonts.constFind(id).value(); - QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", id); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - QFont ret("Lucida Console", 8, QFont::Normal, false); - ret.setFixedPitch(true); - ret.setStyleHint(QFont::Monospace); - return ret; -} - -const Configuration::Shortcut Configuration::getShortcut(const QString key_id) const -{ - if(Shortcuts.contains(key_id)) - return Shortcuts.constFind(key_id).value(); - QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", key_id); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - return Shortcut(); -} - -void Configuration::setShortcut(const QString key_id, const QKeySequence key_sequence) -{ - if(Shortcuts.contains(key_id)) - { - Shortcuts[key_id].Hotkey = key_sequence; - return; - } - QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", key_id); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); -} - -QColor Configuration::colorFromConfig(const QString id) -{ - char setting[MAX_SETTING_SIZE] = ""; - if(!BridgeSettingGet("Colors", id.toUtf8().constData(), setting)) - { - if(defaultColors.contains(id)) - { - QColor ret = defaultColors.find(id).value(); - colorToConfig(id, ret); - return ret; - } - return Qt::black; //black is default - } - if(QString(setting).toUpper() == "#XXXXXX") //support custom transparent color name - return Qt::transparent; - QColor color(setting); - if(!color.isValid()) - { - if(defaultColors.contains(id)) - { - QColor ret = defaultColors.find(id).value(); - colorToConfig(id, ret); - return ret; - } - return Qt::black; //black is default - } - return color; -} - -bool Configuration::colorToConfig(const QString id, const QColor color) -{ - QString colorName = color.name().toUpper(); - if(!color.alpha()) - colorName = "#XXXXXX"; - return BridgeSettingSet("Colors", id.toUtf8().constData(), colorName.toUtf8().constData()); -} - -bool Configuration::boolFromConfig(const QString category, const QString id) -{ - duint setting; - if(!BridgeSettingGetUint(category.toUtf8().constData(), id.toUtf8().constData(), &setting)) - { - if(defaultBools.contains(category) && defaultBools[category].contains(id)) - { - bool ret = defaultBools[category][id]; - boolToConfig(category, id, ret); - return ret; - } - return false; //DAFUG - } - return (setting != 0); -} - -bool Configuration::boolToConfig(const QString category, const QString id, const bool bBool) -{ - return BridgeSettingSetUint(category.toUtf8().constData(), id.toUtf8().constData(), bBool); -} - -duint Configuration::uintFromConfig(const QString category, const QString id) -{ - duint setting; - if(!BridgeSettingGetUint(category.toUtf8().constData(), id.toUtf8().constData(), &setting)) - { - if(defaultUints.contains(category) && defaultUints[category].contains(id)) - { - setting = defaultUints[category][id]; - uintToConfig(category, id, setting); - return setting; - } - return 0; //DAFUG - } - return setting; -} - -bool Configuration::uintToConfig(const QString category, const QString id, duint i) -{ - return BridgeSettingSetUint(category.toUtf8().constData(), id.toUtf8().constData(), i); -} - -QFont Configuration::fontFromConfig(const QString id) -{ - char setting[MAX_SETTING_SIZE] = ""; - if(!BridgeSettingGet("Fonts", id.toUtf8().constData(), setting)) - { - if(defaultFonts.contains(id)) - { - QFont ret = defaultFonts.find(id).value(); - fontToConfig(id, ret); - return ret; - } - if(id == "Application") - return QApplication::font(); - QFont ret("Lucida Console", 8, QFont::Normal, false); - ret.setFixedPitch(true); - ret.setStyleHint(QFont::Monospace); - return ret; - } - QFont font; - if(!font.fromString(setting)) - { - if(defaultFonts.contains(id)) - { - QFont ret = defaultFonts.find(id).value(); - fontToConfig(id, ret); - return ret; - } - if(id == "Application") - return QApplication::font(); - QFont ret("Lucida Console", 8, QFont::Normal, false); - ret.setFixedPitch(true); - ret.setStyleHint(QFont::Monospace); - return ret; - } - return font; -} - -bool Configuration::fontToConfig(const QString id, const QFont font) -{ - return BridgeSettingSet("Fonts", id.toUtf8().constData(), font.toString().toUtf8().constData()); -} - -QString Configuration::shortcutFromConfig(const QString id) -{ - QString _id = QString("%1").arg(id); - char setting[MAX_SETTING_SIZE] = ""; - if(BridgeSettingGet("Shortcuts", _id.toUtf8().constData(), setting)) - { - return QString(setting); - } - return ""; -} - -bool Configuration::shortcutToConfig(const QString id, const QKeySequence shortcut) -{ - QString _id = QString("%1").arg(id); - QString _key = ""; - if(!shortcut.isEmpty()) - _key = shortcut.toString(QKeySequence::NativeText); - else - _key = "NOT_SET"; - return BridgeSettingSet("Shortcuts", _id.toUtf8().constData(), _key.toUtf8().constData()); -} +#include "Configuration.h" +#include +#include +#include +#include + +Configuration* Configuration::mPtr = NULL; + +Configuration::Configuration() : QObject() +{ + //setup default color map + defaultColors.clear(); + defaultColors.insert("AbstractTableViewSeparatorColor", QColor("#808080")); + defaultColors.insert("AbstractTableViewBackgroundColor", QColor("#FFF8F0")); + defaultColors.insert("AbstractTableViewTextColor", QColor("#000000")); + defaultColors.insert("AbstractTableViewHeaderTextColor", QColor("#000000")); + defaultColors.insert("AbstractTableViewSelectionColor", QColor("#C0C0C0")); + + defaultColors.insert("DisassemblyCipColor", QColor("#FFFFFF")); + defaultColors.insert("DisassemblyCipBackgroundColor", QColor("#000000")); + defaultColors.insert("DisassemblyBreakpointColor", QColor("#000000")); + defaultColors.insert("DisassemblyBreakpointBackgroundColor", QColor("#FF0000")); + defaultColors.insert("DisassemblyHardwareBreakpointColor", QColor("#000000")); + defaultColors.insert("DisassemblyHardwareBreakpointBackgroundColor", Qt::transparent); + defaultColors.insert("DisassemblyBookmarkColor", QColor("#000000")); + defaultColors.insert("DisassemblyBookmarkBackgroundColor", QColor("#FEE970")); + defaultColors.insert("DisassemblyLabelColor", QColor("#FF0000")); + defaultColors.insert("DisassemblyLabelBackgroundColor", Qt::transparent); + defaultColors.insert("DisassemblyBackgroundColor", QColor("#FFF8F0")); + defaultColors.insert("DisassemblySelectionColor", QColor("#C0C0C0")); + defaultColors.insert("DisassemblyAddressColor", QColor("#808080")); + defaultColors.insert("DisassemblyAddressBackgroundColor", Qt::transparent); + defaultColors.insert("DisassemblySelectedAddressColor", QColor("#000000")); + defaultColors.insert("DisassemblySelectedAddressBackgroundColor", Qt::transparent); + defaultColors.insert("DisassemblyConditionalJumpLineTrueColor", QColor("#FF0000")); + defaultColors.insert("DisassemblyConditionalJumpLineFalseColor", QColor("#808080")); + defaultColors.insert("DisassemblyUnconditionalJumpLineColor", QColor("#FF0000")); + defaultColors.insert("DisassemblyBytesColor", QColor("#000000")); + defaultColors.insert("DisassemblyModifiedBytesColor", QColor("#FF0000")); + defaultColors.insert("DisassemblyCommentColor", QColor("#000000")); + defaultColors.insert("DisassemblyCommentBackgroundColor", Qt::transparent); + defaultColors.insert("DisassemblyAutoCommentColor", QColor("#808080")); + defaultColors.insert("DisassemblyAutoCommentBackgroundColor", Qt::transparent); + defaultColors.insert("DisassemblyFunctionColor", QColor("#000000")); + defaultColors.insert("DisassemblyLoopColor", QColor("#000000")); + + defaultColors.insert("SideBarCipLabelColor", QColor("#FFFFFF")); + defaultColors.insert("SideBarCipLabelBackgroundColor", QColor("#4040FF")); + defaultColors.insert("SideBarBackgroundColor", QColor("#FFF8F0")); + defaultColors.insert("SideBarConditionalJumpLineTrueColor", QColor("#FF0000")); + defaultColors.insert("SideBarConditionalJumpLineFalseColor", QColor("#808080")); + defaultColors.insert("SideBarUnconditionalJumpLineTrueColor", QColor("#FF0000")); + defaultColors.insert("SideBarUnconditionalJumpLineFalseColor", QColor("#808080")); + defaultColors.insert("SideBarBulletColor", QColor("#808080")); + defaultColors.insert("SideBarBulletBreakpointColor", QColor("#FF0000")); + defaultColors.insert("SideBarBulletDisabledBreakpointColor", QColor("#00AA00")); + defaultColors.insert("SideBarBulletBookmarkColor", QColor("#FEE970")); + + defaultColors.insert("RegistersBackgroundColor", QColor("#FFF8F0")); + defaultColors.insert("RegistersColor", QColor("#000000")); + defaultColors.insert("RegistersModifiedColor", QColor("#FF0000")); + defaultColors.insert("RegistersSelectionColor", QColor("#EEEEEE")); + defaultColors.insert("RegistersLabelColor", QColor("#000000")); + defaultColors.insert("RegistersExtraInfoColor", QColor("#000000")); + + defaultColors.insert("InstructionHighlightColor", QColor("#FF0000")); + defaultColors.insert("InstructionCommaColor", QColor("#000000")); + defaultColors.insert("InstructionCommaBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionPrefixColor", QColor("#000000")); + defaultColors.insert("InstructionPrefixBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionUncategorizedColor", QColor("#000000")); + defaultColors.insert("InstructionUncategorizedBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionAddressColor", QColor("#000000")); + defaultColors.insert("InstructionAddressBackgroundColor", QColor("#FFFF00")); + defaultColors.insert("InstructionValueColor", QColor("#828200")); + defaultColors.insert("InstructionValueBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionMnemonicColor", QColor("#000000")); + defaultColors.insert("InstructionMnemonicBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionPushPopColor", QColor("#0000FF")); + defaultColors.insert("InstructionPushPopBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionCallColor", QColor("#000000")); + defaultColors.insert("InstructionCallBackgroundColor", QColor("#00FFFF")); + defaultColors.insert("InstructionRetColor", QColor("#000000")); + defaultColors.insert("InstructionRetBackgroundColor", QColor("#00FFFF")); + defaultColors.insert("InstructionConditionalJumpColor", QColor("#FF0000")); + defaultColors.insert("InstructionConditionalJumpBackgroundColor", QColor("#FFFF00")); + defaultColors.insert("InstructionUnconditionalJumpColor", QColor("#000000")); + defaultColors.insert("InstructionUnconditionalJumpBackgroundColor", QColor("#FFFF00")); + defaultColors.insert("InstructionNopColor", QColor("#808080")); + defaultColors.insert("InstructionNopBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionFarColor", QColor("#000000")); + defaultColors.insert("InstructionFarBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionInt3Color", QColor("#000000")); + defaultColors.insert("InstructionInt3BackgroundColor", Qt::transparent); + defaultColors.insert("InstructionMemorySizeColor", QColor("#000080")); + defaultColors.insert("InstructionMemorySizeBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionMemorySegmentColor", QColor("#FF00FF")); + defaultColors.insert("InstructionMemorySegmentBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionMemoryBracketsColor", QColor("#000000")); + defaultColors.insert("InstructionMemoryBracketsBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionMemoryStackBracketsColor", QColor("#000000")); + defaultColors.insert("InstructionMemoryStackBracketsBackgroundColor", QColor("#00FFFF")); + defaultColors.insert("InstructionMemoryBaseRegisterColor", QColor("#B03434")); + defaultColors.insert("InstructionMemoryBaseRegisterBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionMemoryIndexRegisterColor", QColor("#3838BC")); + defaultColors.insert("InstructionMemoryIndexRegisterBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionMemoryScaleColor", QColor("#B30059")); + defaultColors.insert("InstructionMemoryScaleBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionMemoryOperatorColor", QColor("#F27711")); + defaultColors.insert("InstructionMemoryOperatorBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionGeneralRegisterColor", QColor("#008300")); + defaultColors.insert("InstructionGeneralRegisterBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionFpuRegisterColor", QColor("#000080")); + defaultColors.insert("InstructionFpuRegisterBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionMmxRegisterColor", QColor("#000080")); + defaultColors.insert("InstructionMmxRegisterBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionXmmRegisterColor", QColor("#000080")); + defaultColors.insert("InstructionXmmRegisterBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionYmmRegisterColor", QColor("#000080")); + defaultColors.insert("InstructionYmmRegisterBackgroundColor", Qt::transparent); + defaultColors.insert("InstructionZmmRegisterColor", QColor("#000080")); + defaultColors.insert("InstructionZmmRegisterBackgroundColor", Qt::transparent); + + defaultColors.insert("HexDumpTextColor", QColor("#000000")); + defaultColors.insert("HexDumpModifiedBytesColor", QColor("#FF0000")); + defaultColors.insert("HexDumpBackgroundColor", QColor("#FFF8F0")); + defaultColors.insert("HexDumpSelectionColor", QColor("#C0C0C0")); + defaultColors.insert("HexDumpAddressColor", QColor("#000000")); + defaultColors.insert("HexDumpAddressBackgroundColor", Qt::transparent); + defaultColors.insert("HexDumpLabelColor", QColor("#FF0000")); + defaultColors.insert("HexDumpLabelBackgroundColor", Qt::transparent); + + defaultColors.insert("StackTextColor", QColor("#000000")); + defaultColors.insert("StackInactiveTextColor", QColor("#808080")); + defaultColors.insert("StackBackgroundColor", QColor("#FFF8F0")); + defaultColors.insert("StackSelectionColor", QColor("#C0C0C0")); + defaultColors.insert("StackCspColor", QColor("#FFFFFF")); + defaultColors.insert("StackCspBackgroundColor", QColor("#000000")); + defaultColors.insert("StackAddressColor", QColor("#808080")); + defaultColors.insert("StackAddressBackgroundColor", Qt::transparent); + defaultColors.insert("StackSelectedAddressColor", QColor("#000000")); + defaultColors.insert("StackSelectedAddressBackgroundColor", Qt::transparent); + defaultColors.insert("StackLabelColor", QColor("#FF0000")); + defaultColors.insert("StackLabelBackgroundColor", Qt::transparent); + + defaultColors.insert("HexEditTextColor", QColor("#000000")); + defaultColors.insert("HexEditWildcardColor", QColor("#FF0000")); + defaultColors.insert("HexEditBackgroundColor", QColor("#FFF8F0")); + defaultColors.insert("HexEditSelectionColor", QColor("#C0C0C0")); + + defaultColors.insert("ThreadCurrentColor", QColor("#FFFFFF")); + defaultColors.insert("ThreadCurrentBackgroundColor", QColor("#000000")); + defaultColors.insert("MemoryMapBreakpointColor", QColor("#FFFBF0")); + defaultColors.insert("MemoryMapBreakpointBackgroundColor", QColor("#FF0000")); + defaultColors.insert("MemoryMapSectionTextColor", QColor("#8B671F")); + defaultColors.insert("SearchListViewHighlightColor", QColor("#FF0000")); + + //bool settings + QMap disassemblyBool; + disassemblyBool.insert("ArgumentSpaces", false); + disassemblyBool.insert("MemorySpaces", false); + disassemblyBool.insert("FillNOPs", false); + disassemblyBool.insert("Uppercase", false); + disassemblyBool.insert("FindCommandEntireBlock", false); + disassemblyBool.insert("OnlyCipAutoComments", false); + disassemblyBool.insert("TabbedMnemonic", false); + defaultBools.insert("Disassembler", disassemblyBool); + + QMap engineBool; + engineBool.insert("ListAllPages", false); + defaultBools.insert("Engine", engineBool); + + //uint settings + QMap hexdumpUint; + hexdumpUint.insert("DefaultView", 0); + defaultUints.insert("HexDump", hexdumpUint); + QMap disasmUint; + disasmUint.insert("MaxModuleSize", -1); + defaultUints.insert("Disassembler", disasmUint); + + //font settings + QFont font("Lucida Console", 8, QFont::Normal, false); + defaultFonts.insert("AbstractTableView", font); + defaultFonts.insert("Disassembly", font); + defaultFonts.insert("HexDump", font); + defaultFonts.insert("Stack", font); + defaultFonts.insert("Registers", font); + defaultFonts.insert("HexEdit", font); + defaultFonts.insert("Application", QApplication::font()); + defaultFonts.insert("Log", QFont("Courier", 8, QFont::Normal, false)); + + // hotkeys settings + defaultShortcuts.insert("FileOpen", Shortcut(tr("File -> Open"), "F3", true)); + defaultShortcuts.insert("FileAttach", Shortcut(tr("File -> Attach"), "Alt+A", true)); + defaultShortcuts.insert("FileDetach", Shortcut(tr("File -> Detach"), "Ctrl+Alt+F2", true)); + defaultShortcuts.insert("FileExit", Shortcut(tr("File -> Exit"), "Alt+X", true)); + + defaultShortcuts.insert("ViewCpu", Shortcut(tr("View -> CPU"), "Alt+C", true)); + defaultShortcuts.insert("ViewLog", Shortcut(tr("View -> Log"), "Alt+L", true)); + defaultShortcuts.insert("ViewBreakpoints", Shortcut(tr("View -> Breakpoints"), "Alt+B", true)); + defaultShortcuts.insert("ViewMemoryMap", Shortcut(tr("View -> Memory Map"), "Alt+M", true)); + defaultShortcuts.insert("ViewCallStack", Shortcut(tr("View -> Call Stack"), "Alt+K", true)); + defaultShortcuts.insert("ViewScript", Shortcut(tr("View -> Script"), "Alt+S", true)); + defaultShortcuts.insert("ViewSymbolInfo", Shortcut(tr("View -> Symbol Info"), "Ctrl+Alt+S", true)); + defaultShortcuts.insert("ViewSource", Shortcut(tr("View -> Source"), "Ctrl+Shift+S", true)); + defaultShortcuts.insert("ViewReferences", Shortcut(tr("View -> References"), "Alt+R", true)); + defaultShortcuts.insert("ViewThreads", Shortcut(tr("View -> Threads"), "Alt+T", true)); + defaultShortcuts.insert("ViewPatches", Shortcut(tr("View -> Patches"), "Ctrl+P", true)); + defaultShortcuts.insert("ViewComments", Shortcut(tr("View -> Comments"), "Ctrl+Alt+C", true)); + defaultShortcuts.insert("ViewLabels", Shortcut(tr("View -> Labels"), "Ctrl+Alt+L", true)); + defaultShortcuts.insert("ViewBookmarks", Shortcut(tr("View -> Bookmarks"), "Ctrl+Alt+B", true)); + defaultShortcuts.insert("ViewFunctions", Shortcut(tr("View -> Functions"), "Alt+F", true)); + + defaultShortcuts.insert("DebugRun", Shortcut(tr("Debug -> Run"), "F9", true)); + defaultShortcuts.insert("DebugeRun", Shortcut(tr("Debug -> Run (skip exceptions)"), "Shift+F9", true)); + defaultShortcuts.insert("DebugRunSelection", Shortcut(tr("Debug -> Run until selection"), "F4", true)); + defaultShortcuts.insert("DebugPause", Shortcut(tr("Debug -> Pause"), "F12", true)); + defaultShortcuts.insert("DebugRestart", Shortcut(tr("Debug -> Restart"), "Ctrl+F2", true)); + defaultShortcuts.insert("DebugClose", Shortcut(tr("Debug -> Close"), "Alt+F2", true)); + defaultShortcuts.insert("DebugStepInto", Shortcut(tr("Debug -> Step into"), "F7", true)); + defaultShortcuts.insert("DebugeStepInfo", Shortcut(tr("Debug -> Step into (skip execptions)"), "Shift+F7", true)); + defaultShortcuts.insert("DebugStepOver", Shortcut(tr("Debug -> Step over"), "F8", true)); + defaultShortcuts.insert("DebugeStepOver", Shortcut(tr("Debug -> Step over (skip execptions)"), "Shift+F8", true)); + defaultShortcuts.insert("DebugRtr", Shortcut(tr("Debug -> Execute till return"), "Ctrl+F9", true)); + defaultShortcuts.insert("DebugeRtr", Shortcut(tr("Debug -> Execute till return (skip exceptions)"), "Ctrl+Shift+F9", true)); + defaultShortcuts.insert("DebugSkipNextInstruction", Shortcut(tr("Debug -> Skip next instruction"), "Ctrl+F8", true)); + defaultShortcuts.insert("DebugCommand", Shortcut(tr("Debug -> Command"), "Ctrl+Return", true)); + + defaultShortcuts.insert("PluginsScylla", Shortcut(tr("Plugins -> Scylla"), "Ctrl+I", true)); + + defaultShortcuts.insert("OptionsPreferences", Shortcut(tr("Options -> Preferences"), "", true)); + defaultShortcuts.insert("OptionsAppearance", Shortcut(tr("Options -> Appearance"), "", true)); + defaultShortcuts.insert("OptionsShortcuts", Shortcut(tr("Options -> Shortcuts"), "", true)); + defaultShortcuts.insert("OptionsTopmost", Shortcut(tr("Options -> Topmost"), "Ctrl+F5", true)); + + defaultShortcuts.insert("HelpAbout", Shortcut(tr("Help -> About"), "", true)); + defaultShortcuts.insert("HelpDonate", Shortcut(tr("Help -> Donate"), "", true)); + defaultShortcuts.insert("HelpCheckForUpdates", Shortcut(tr("Help -> Check for Updates"), "", true)); + defaultShortcuts.insert("HelpCalculator", Shortcut(tr("Help -> Calculator"), "?")); + defaultShortcuts.insert("HelpReportBug", Shortcut(tr("Help -> Report Bug"), "", true)); + defaultShortcuts.insert("HelpManual", Shortcut(tr("Help -> Manual"), "F1", true)); + + defaultShortcuts.insert("ActionFindStrings", Shortcut(tr("Actions -> Find Strings"), "", true)); + defaultShortcuts.insert("ActionFindIntermodularCalls", Shortcut(tr("Actions -> Find Intermodular Calls"), "", true)); + defaultShortcuts.insert("ActionToggleBreakpoint", Shortcut(tr("Actions -> Toggle Breakpoint"), "F2")); + defaultShortcuts.insert("ActionToggleBookmark", Shortcut(tr("Actions -> Toggle Bookmark"), "Ctrl+D")); + defaultShortcuts.insert("ActionDeleteBreakpoint", Shortcut(tr("Actions -> Delete Breakpoint"), "Delete")); + defaultShortcuts.insert("ActionEnableDisableBreakpoint", Shortcut(tr("Actions -> Enable/Disable Breakpoint"), "Space")); + + defaultShortcuts.insert("ActionBinaryEdit", Shortcut(tr("Actions -> Binary Edit"), "Ctrl+E")); + defaultShortcuts.insert("ActionBinaryFill", Shortcut(tr("Actions -> Binary Fill"), "F")); + defaultShortcuts.insert("ActionBinaryFillNops", Shortcut(tr("Actions -> Binary Fill NOPs"), "Ctrl+9")); + defaultShortcuts.insert("ActionBinaryCopy", Shortcut(tr("Actions -> Binary Copy"), "Shift+C")); + defaultShortcuts.insert("ActionBinaryPaste", Shortcut(tr("Actions -> Binary Paste"), "Shift+V")); + defaultShortcuts.insert("ActionBinaryPasteIgnoreSize", Shortcut(tr("Actions -> Binary Paste (Ignore Size)"), "Ctrl+Shift+V")); + defaultShortcuts.insert("ActionUndoSelection", Shortcut(tr("Actions -> Undo Selection"), "Ctrl+Backspace")); + defaultShortcuts.insert("ActionSetLabel", Shortcut(tr("Actions -> Set Label"), ":")); + defaultShortcuts.insert("ActionSetComment", Shortcut(tr("Actions -> Set Comment"), ";")); + defaultShortcuts.insert("ActionToggleFunction", Shortcut(tr("Actions -> Toggle Function"), "Shift+F")); + defaultShortcuts.insert("ActionAssemble", Shortcut(tr("Actions -> Assemble"), "Space")); + defaultShortcuts.insert("ActionYara", Shortcut(tr("Actions -> Yara"), "Ctrl+Y")); + defaultShortcuts.insert("ActionSetNewOriginHere", Shortcut(tr("Actions -> Set New Origin Here"), "Ctrl+*")); + defaultShortcuts.insert("ActionGotoOrigin", Shortcut(tr("Actions -> Goto Origin"), "*")); + defaultShortcuts.insert("ActionGotoPrevious", Shortcut(tr("Actions -> Goto Previous"), "-")); + defaultShortcuts.insert("ActionGotoNext", Shortcut(tr("Actions -> Goto Next"), "+")); + defaultShortcuts.insert("ActionGotoExpression", Shortcut(tr("Actions -> Goto Expression"), "Ctrl+G")); + defaultShortcuts.insert("ActionGotoStart", Shortcut(tr("Actions -> Goto Start of Page"), "Home")); + defaultShortcuts.insert("ActionGotoEnd", Shortcut(tr("Actions -> Goto End of Page"), "End")); + defaultShortcuts.insert("ActionGotoFileOffset", Shortcut(tr("Actions -> Goto File Offset"), "Ctrl+Shift+G")); + defaultShortcuts.insert("ActionFindReferencesToSelectedAddress", Shortcut(tr("Actions -> Find References to Selected Address"), "Ctrl+R")); + defaultShortcuts.insert("ActionFindPattern", Shortcut(tr("Actions -> Find Pattern"), "Ctrl+B")); + defaultShortcuts.insert("ActionFindReferences", Shortcut(tr("Actions -> Find References"), "Ctrl+R")); + defaultShortcuts.insert("ActionHighlightingMode", Shortcut(tr("Actions -> Highlighting Mode"), "Ctrl+H")); + defaultShortcuts.insert("ActionFind", Shortcut(tr("Actions -> Find"), "Ctrl+F")); + defaultShortcuts.insert("ActionDecompileFunction", Shortcut(tr("Actions -> Decompile Function"), "F5")); + defaultShortcuts.insert("ActionDecompileSelection", Shortcut(tr("Actions -> Decompile Selection"), "Shift+F5")); + + defaultShortcuts.insert("ActionIncreaseRegister", Shortcut(tr("Actions -> Increase Register"), "+")); + defaultShortcuts.insert("ActionDecreaseRegister", Shortcut(tr("Actions -> Decrease Register"), "-")); + defaultShortcuts.insert("ActionZeroRegister", Shortcut(tr("Actions -> Zero Register"), "0")); + defaultShortcuts.insert("ActionSetOneRegister", Shortcut(tr("Actions -> Set Register to One"), "1")); + defaultShortcuts.insert("ActionToggleRegisterValue", Shortcut(tr("Actions -> Toggle Register Value"), "Space")); + defaultShortcuts.insert("ActionCopy", Shortcut(tr("Actions -> Copy"), "Ctrl+C")); + defaultShortcuts.insert("ActionCopyAddress", Shortcut(tr("Actions -> Copy Address"), "Alt+INS")); + defaultShortcuts.insert("ActionCopySymbol", Shortcut(tr("Actions -> Copy Symbol"), "Ctrl+S")); + defaultShortcuts.insert("ActionLoadScript", Shortcut(tr("Actions -> Load Script"), "Ctrl+O")); + defaultShortcuts.insert("ActionReloadScript", Shortcut(tr("Actions -> Reload Script"), "Ctrl+R")); + defaultShortcuts.insert("ActionUnloadScript", Shortcut(tr("Actions -> Unload Script"), "Ctrl+U")); + defaultShortcuts.insert("ActionRunScript", Shortcut(tr("Actions -> Run Script"), "Space")); + defaultShortcuts.insert("ActionToggleBreakpointScript", Shortcut(tr("Actions -> Toggle Script Breakpoint"), "F2")); + defaultShortcuts.insert("ActionRunToCursorScript", Shortcut(tr("Actions -> Run Script to Cursor"), "Shift+F4")); + defaultShortcuts.insert("ActionStepScript", Shortcut(tr("Actions -> Step Script"), "Tab")); + defaultShortcuts.insert("ActionAbortScript", Shortcut(tr("Actions -> Abort Script"), "Esc")); + defaultShortcuts.insert("ActionExecuteCommandScript", Shortcut(tr("Actions -> Execute Script Command"), "X")); + + Shortcuts = defaultShortcuts; + + load(); + mPtr = this; +} + +Configuration* Config() +{ + return mPtr; +} + +void Configuration::load() +{ + readColors(); + readBools(); + readUints(); + readFonts(); + readShortcuts(); +} + +void Configuration::save() +{ + writeColors(); + writeBools(); + writeUints(); + writeFonts(); + writeShortcuts(); +} + +void Configuration::readColors() +{ + Colors = defaultColors; + //read config + for(int i = 0; i < Colors.size(); i++) + { + QString id = Colors.keys().at(i); + Colors[id] = colorFromConfig(id); + } +} + +void Configuration::writeColors() +{ + //write config + for(int i = 0; i < Colors.size(); i++) + { + QString id = Colors.keys().at(i); + colorToConfig(id, Colors[id]); + } + emit colorsUpdated(); +} + +void Configuration::emitColorsUpdated() +{ + emit colorsUpdated(); +} + +void Configuration::readBools() +{ + Bools = defaultBools; + //read config + for(int i = 0; i < Bools.size(); i++) + { + QString category = Bools.keys().at(i); + QMap* currentBool = &Bools[category]; + for(int j = 0; j < currentBool->size(); j++) + { + QString id = (*currentBool).keys().at(j); + (*currentBool)[id] = boolFromConfig(category, id); + } + } +} + +void Configuration::writeBools() +{ + //write config + for(int i = 0; i < Bools.size(); i++) + { + QString category = Bools.keys().at(i); + QMap* currentBool = &Bools[category]; + for(int j = 0; j < currentBool->size(); j++) + { + QString id = (*currentBool).keys().at(j); + boolToConfig(category, id, (*currentBool)[id]); + } + } +} + +void Configuration::readUints() +{ + Uints = defaultUints; + //read config + for(int i = 0; i < Uints.size(); i++) + { + QString category = Uints.keys().at(i); + QMap* currentUint = &Uints[category]; + for(int j = 0; j < currentUint->size(); j++) + { + QString id = (*currentUint).keys().at(j); + (*currentUint)[id] = uintFromConfig(category, id); + } + } +} + +void Configuration::writeUints() +{ + //write config + for(int i = 0; i < Uints.size(); i++) + { + QString category = Uints.keys().at(i); + QMap* currentUint = &Uints[category]; + for(int j = 0; j < currentUint->size(); j++) + { + QString id = (*currentUint).keys().at(j); + uintToConfig(category, id, (*currentUint)[id]); + } + } +} + +void Configuration::readFonts() +{ + Fonts = defaultFonts; + //read config + for(int i = 0; i < Fonts.size(); i++) + { + QString id = Fonts.keys().at(i); + QFont font = fontFromConfig(id); + QFontInfo fontInfo(font); + if(id == "Application" || fontInfo.fixedPitch()) + Fonts[id] = font; + } +} + +void Configuration::writeFonts() +{ + //write config + for(int i = 0; i < Fonts.size(); i++) + { + QString id = Fonts.keys().at(i); + fontToConfig(id, Fonts[id]); + } + emit fontsUpdated(); +} + +void Configuration::emitFontsUpdated() +{ + emit fontsUpdated(); +} + +void Configuration::readShortcuts() +{ + Shortcuts = defaultShortcuts; + QMap::const_iterator it = Shortcuts.begin(); + + while(it != Shortcuts.end()) + { + const QString id = it.key(); + QString key = shortcutFromConfig(id); + if(key != "") + { + if(key == "NOT_SET") + Shortcuts[it.key()].Hotkey = QKeySequence(); + else + { + QKeySequence KeySequence(key); + Shortcuts[it.key()].Hotkey = KeySequence; + } + } + it++; + } + emit shortcutsUpdated(); +} + +void Configuration::writeShortcuts() +{ + QMap::const_iterator it = Shortcuts.begin(); + + while(it != Shortcuts.end()) + { + shortcutToConfig(it.key(), it.value().Hotkey); + it++; + } + emit shortcutsUpdated(); +} + +const QColor Configuration::getColor(const QString id) const +{ + if(Colors.contains(id)) + return Colors.constFind(id).value(); + QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", id); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return Qt::black; +} + +const bool Configuration::getBool(const QString category, const QString id) const +{ + if(Bools.contains(category)) + { + if(Bools[category].contains(id)) + return Bools[category][id]; + QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category + ":" + id); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return false; + } + QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return false; +} + +void Configuration::setBool(const QString category, const QString id, const bool b) +{ + if(Bools.contains(category)) + { + if(Bools[category].contains(id)) + { + Bools[category][id] = b; + return; + } + QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category + ":" + id); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return; + } + QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); +} + +const duint Configuration::getUint(const QString category, const QString id) const +{ + if(Uints.contains(category)) + { + if(Uints[category].contains(id)) + return Uints[category][id]; + QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category + ":" + id); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return 0; + } + QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return 0; +} + +void Configuration::setUint(const QString category, const QString id, const duint i) +{ + if(Uints.contains(category)) + { + if(Uints[category].contains(id)) + { + Uints[category][id] = i; + return; + } + QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category + ":" + id); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return; + } + QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", category); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); +} + +const QFont Configuration::getFont(const QString id) const +{ + if(Fonts.contains(id)) + return Fonts.constFind(id).value(); + QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", id); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + QFont ret("Lucida Console", 8, QFont::Normal, false); + ret.setFixedPitch(true); + ret.setStyleHint(QFont::Monospace); + return ret; +} + +const Configuration::Shortcut Configuration::getShortcut(const QString key_id) const +{ + if(Shortcuts.contains(key_id)) + return Shortcuts.constFind(key_id).value(); + QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", key_id); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + return Shortcut(); +} + +void Configuration::setShortcut(const QString key_id, const QKeySequence key_sequence) +{ + if(Shortcuts.contains(key_id)) + { + Shortcuts[key_id].Hotkey = key_sequence; + return; + } + QMessageBox msg(QMessageBox::Warning, "NOT FOUND IN CONFIG!", key_id); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); +} + +QColor Configuration::colorFromConfig(const QString id) +{ + char setting[MAX_SETTING_SIZE] = ""; + if(!BridgeSettingGet("Colors", id.toUtf8().constData(), setting)) + { + if(defaultColors.contains(id)) + { + QColor ret = defaultColors.find(id).value(); + colorToConfig(id, ret); + return ret; + } + return Qt::black; //black is default + } + if(QString(setting).toUpper() == "#XXXXXX") //support custom transparent color name + return Qt::transparent; + QColor color(setting); + if(!color.isValid()) + { + if(defaultColors.contains(id)) + { + QColor ret = defaultColors.find(id).value(); + colorToConfig(id, ret); + return ret; + } + return Qt::black; //black is default + } + return color; +} + +bool Configuration::colorToConfig(const QString id, const QColor color) +{ + QString colorName = color.name().toUpper(); + if(!color.alpha()) + colorName = "#XXXXXX"; + return BridgeSettingSet("Colors", id.toUtf8().constData(), colorName.toUtf8().constData()); +} + +bool Configuration::boolFromConfig(const QString category, const QString id) +{ + duint setting; + if(!BridgeSettingGetUint(category.toUtf8().constData(), id.toUtf8().constData(), &setting)) + { + if(defaultBools.contains(category) && defaultBools[category].contains(id)) + { + bool ret = defaultBools[category][id]; + boolToConfig(category, id, ret); + return ret; + } + return false; //DAFUG + } + return (setting != 0); +} + +bool Configuration::boolToConfig(const QString category, const QString id, const bool bBool) +{ + return BridgeSettingSetUint(category.toUtf8().constData(), id.toUtf8().constData(), bBool); +} + +duint Configuration::uintFromConfig(const QString category, const QString id) +{ + duint setting; + if(!BridgeSettingGetUint(category.toUtf8().constData(), id.toUtf8().constData(), &setting)) + { + if(defaultUints.contains(category) && defaultUints[category].contains(id)) + { + setting = defaultUints[category][id]; + uintToConfig(category, id, setting); + return setting; + } + return 0; //DAFUG + } + return setting; +} + +bool Configuration::uintToConfig(const QString category, const QString id, duint i) +{ + return BridgeSettingSetUint(category.toUtf8().constData(), id.toUtf8().constData(), i); +} + +QFont Configuration::fontFromConfig(const QString id) +{ + char setting[MAX_SETTING_SIZE] = ""; + if(!BridgeSettingGet("Fonts", id.toUtf8().constData(), setting)) + { + if(defaultFonts.contains(id)) + { + QFont ret = defaultFonts.find(id).value(); + fontToConfig(id, ret); + return ret; + } + if(id == "Application") + return QApplication::font(); + QFont ret("Lucida Console", 8, QFont::Normal, false); + ret.setFixedPitch(true); + ret.setStyleHint(QFont::Monospace); + return ret; + } + QFont font; + if(!font.fromString(setting)) + { + if(defaultFonts.contains(id)) + { + QFont ret = defaultFonts.find(id).value(); + fontToConfig(id, ret); + return ret; + } + if(id == "Application") + return QApplication::font(); + QFont ret("Lucida Console", 8, QFont::Normal, false); + ret.setFixedPitch(true); + ret.setStyleHint(QFont::Monospace); + return ret; + } + return font; +} + +bool Configuration::fontToConfig(const QString id, const QFont font) +{ + return BridgeSettingSet("Fonts", id.toUtf8().constData(), font.toString().toUtf8().constData()); +} + +QString Configuration::shortcutFromConfig(const QString id) +{ + QString _id = QString("%1").arg(id); + char setting[MAX_SETTING_SIZE] = ""; + if(BridgeSettingGet("Shortcuts", _id.toUtf8().constData(), setting)) + { + return QString(setting); + } + return ""; +} + +bool Configuration::shortcutToConfig(const QString id, const QKeySequence shortcut) +{ + QString _id = QString("%1").arg(id); + QString _key = ""; + if(!shortcut.isEmpty()) + _key = shortcut.toString(QKeySequence::NativeText); + else + _key = "NOT_SET"; + return BridgeSettingSet("Shortcuts", _id.toUtf8().constData(), _key.toUtf8().constData()); +} diff --git a/src/gui/Src/Utils/Configuration.h b/src/gui/Src/Utils/Configuration.h index fe6b5c04..df99f1d0 100644 --- a/src/gui/Src/Utils/Configuration.h +++ b/src/gui/Src/Utils/Configuration.h @@ -1,98 +1,98 @@ -#ifndef CONFIGURATION_H -#define CONFIGURATION_H - -#include -#include -#include -#include -#include -#include "Imports.h" - -#define Config() (Configuration::instance()) -#define ConfigColor(x) (Config()->getColor(x)) -#define ConfigBool(x,y) (Config()->getBool(x,y)) -#define ConfigUint(x,y) (Config()->getUint(x,y)) -#define ConfigFont(x) (Config()->getFont(x)) -#define ConfigShortcut(x) (Config()->getShortcut(x).Hotkey) - -class Configuration : public QObject -{ - Q_OBJECT -public: - //Structures - struct Shortcut - { - QString Name; - QKeySequence Hotkey; - bool GlobalShortcut; - - Shortcut(QString n = QString(), QString h = QString(), bool g = false) - { - Name = n; - Hotkey = QKeySequence(h); - GlobalShortcut = g; - } - }; - - //Functions - Configuration(); - static Configuration* instance(); - void load(); - void save(); - void readColors(); - void writeColors(); - void emitColorsUpdated(); - void readBools(); - void writeBools(); - void readUints(); - void writeUints(); - void readFonts(); - void writeFonts(); - void emitFontsUpdated(); - void readShortcuts(); - void writeShortcuts(); - - const QColor getColor(const QString id) const; - const bool getBool(const QString category, const QString id) const; - void setBool(const QString category, const QString id, const bool b); - const duint getUint(const QString category, const QString id) const; - void setUint(const QString category, const QString id, const duint i); - const QFont getFont(const QString id) const; - const Shortcut getShortcut(const QString key_id) const; - void setShortcut(const QString key_id, const QKeySequence key_sequence); - - //default setting maps - QMap defaultColors; - QMap> defaultBools; - QMap> defaultUints; - QMap defaultFonts; - QMap defaultShortcuts; - - //public variables - QMap Colors; - QMap> Bools; - QMap> Uints; - QMap Fonts; - QMap Shortcuts; - - static Configuration* mPtr; - -signals: - void colorsUpdated(); - void fontsUpdated(); - void shortcutsUpdated(); - -private: - QColor colorFromConfig(const QString id); - bool colorToConfig(const QString id, const QColor color); - bool boolFromConfig(const QString category, const QString id); - bool boolToConfig(const QString category, const QString id, bool bBool); - duint uintFromConfig(const QString category, const QString id); - bool uintToConfig(const QString category, const QString id, duint i); - QFont fontFromConfig(const QString id); - bool fontToConfig(const QString id, const QFont font); - QString shortcutFromConfig(const QString id); - bool shortcutToConfig(const QString id, const QKeySequence shortcut); -}; - -#endif // CONFIGURATION_H +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +#include +#include +#include +#include +#include +#include "Imports.h" + +#define Config() (Configuration::instance()) +#define ConfigColor(x) (Config()->getColor(x)) +#define ConfigBool(x,y) (Config()->getBool(x,y)) +#define ConfigUint(x,y) (Config()->getUint(x,y)) +#define ConfigFont(x) (Config()->getFont(x)) +#define ConfigShortcut(x) (Config()->getShortcut(x).Hotkey) + +class Configuration : public QObject +{ + Q_OBJECT +public: + //Structures + struct Shortcut + { + QString Name; + QKeySequence Hotkey; + bool GlobalShortcut; + + Shortcut(QString n = QString(), QString h = QString(), bool g = false) + { + Name = n; + Hotkey = QKeySequence(h); + GlobalShortcut = g; + } + }; + + //Functions + Configuration(); + static Configuration* instance(); + void load(); + void save(); + void readColors(); + void writeColors(); + void emitColorsUpdated(); + void readBools(); + void writeBools(); + void readUints(); + void writeUints(); + void readFonts(); + void writeFonts(); + void emitFontsUpdated(); + void readShortcuts(); + void writeShortcuts(); + + const QColor getColor(const QString id) const; + const bool getBool(const QString category, const QString id) const; + void setBool(const QString category, const QString id, const bool b); + const duint getUint(const QString category, const QString id) const; + void setUint(const QString category, const QString id, const duint i); + const QFont getFont(const QString id) const; + const Shortcut getShortcut(const QString key_id) const; + void setShortcut(const QString key_id, const QKeySequence key_sequence); + + //default setting maps + QMap defaultColors; + QMap> defaultBools; + QMap> defaultUints; + QMap defaultFonts; + QMap defaultShortcuts; + + //public variables + QMap Colors; + QMap> Bools; + QMap> Uints; + QMap Fonts; + QMap Shortcuts; + + static Configuration* mPtr; + +signals: + void colorsUpdated(); + void fontsUpdated(); + void shortcutsUpdated(); + +private: + QColor colorFromConfig(const QString id); + bool colorToConfig(const QString id, const QColor color); + bool boolFromConfig(const QString category, const QString id); + bool boolToConfig(const QString category, const QString id, bool bBool); + duint uintFromConfig(const QString category, const QString id); + bool uintToConfig(const QString category, const QString id, duint i); + QFont fontFromConfig(const QString id); + bool fontToConfig(const QString id, const QFont font); + QString shortcutFromConfig(const QString id); + bool shortcutToConfig(const QString id, const QKeySequence shortcut); +}; + +#endif // CONFIGURATION_H diff --git a/src/gui/Src/Utils/FlickerThread.cpp b/src/gui/Src/Utils/FlickerThread.cpp index 87cafa9a..e9367af9 100644 --- a/src/gui/Src/Utils/FlickerThread.cpp +++ b/src/gui/Src/Utils/FlickerThread.cpp @@ -1,21 +1,21 @@ -#include "FlickerThread.h" -#include -#include - -FlickerThread::FlickerThread(QWidget* widget, QObject* parent) : QThread(parent) -{ - mWidget = widget; -} - -void FlickerThread::run() -{ - QString oldStyle = mWidget->styleSheet(); - int delay = 300; - for(int i = 0; i < 3 ; i++) - { - emit setStyleSheet("QWidget { border: 2px solid red; }"); - Sleep(delay); - emit setStyleSheet(oldStyle); - Sleep(delay); - } -} +#include "FlickerThread.h" +#include +#include + +FlickerThread::FlickerThread(QWidget* widget, QObject* parent) : QThread(parent) +{ + mWidget = widget; +} + +void FlickerThread::run() +{ + QString oldStyle = mWidget->styleSheet(); + int delay = 300; + for(int i = 0; i < 3 ; i++) + { + emit setStyleSheet("QWidget { border: 2px solid red; }"); + Sleep(delay); + emit setStyleSheet(oldStyle); + Sleep(delay); + } +} diff --git a/src/gui/Src/Utils/FlickerThread.h b/src/gui/Src/Utils/FlickerThread.h index e3b99d21..4db9465b 100644 --- a/src/gui/Src/Utils/FlickerThread.h +++ b/src/gui/Src/Utils/FlickerThread.h @@ -1,21 +1,21 @@ -#ifndef FLICKERTHREAD_H -#define FLICKERTHREAD_H - -#include -#include - -class FlickerThread : public QThread -{ - Q_OBJECT -public: - explicit FlickerThread(QWidget* widget, QObject* parent = 0); - -signals: - void setStyleSheet(QString style); - -private: - void run(); - QWidget* mWidget; -}; - -#endif // FLICKERTHREAD_H +#ifndef FLICKERTHREAD_H +#define FLICKERTHREAD_H + +#include +#include + +class FlickerThread : public QThread +{ + Q_OBJECT +public: + explicit FlickerThread(QWidget* widget, QObject* parent = 0); + +signals: + void setStyleSheet(QString style); + +private: + void run(); + QWidget* mWidget; +}; + +#endif // FLICKERTHREAD_H diff --git a/src/gui/Src/Utils/MainWindowCloseThread.cpp b/src/gui/Src/Utils/MainWindowCloseThread.cpp index f8f0570f..b3c8611b 100644 --- a/src/gui/Src/Utils/MainWindowCloseThread.cpp +++ b/src/gui/Src/Utils/MainWindowCloseThread.cpp @@ -1,10 +1,10 @@ -#include "MainWindowCloseThread.h" -#include "Imports.h" -#include "Bridge.h" - -void MainWindowCloseThread::run() -{ - DbgExit(); - Bridge::getBridge()->setDbgStopped(); - emit canClose(); -} +#include "MainWindowCloseThread.h" +#include "Imports.h" +#include "Bridge.h" + +void MainWindowCloseThread::run() +{ + DbgExit(); + Bridge::getBridge()->setDbgStopped(); + emit canClose(); +} diff --git a/src/gui/Src/Utils/MainWindowCloseThread.h b/src/gui/Src/Utils/MainWindowCloseThread.h index 2f52e19a..9d937f0a 100644 --- a/src/gui/Src/Utils/MainWindowCloseThread.h +++ b/src/gui/Src/Utils/MainWindowCloseThread.h @@ -1,16 +1,16 @@ -#ifndef MAINWINDOWCLOSETHREAD_H -#define MAINWINDOWCLOSETHREAD_H - -#include - -class MainWindowCloseThread : public QThread -{ - Q_OBJECT -signals: - void canClose(); - -private: - void run(); -}; - -#endif // MAINWINDOWCLOSETHREAD_H +#ifndef MAINWINDOWCLOSETHREAD_H +#define MAINWINDOWCLOSETHREAD_H + +#include + +class MainWindowCloseThread : public QThread +{ + Q_OBJECT +signals: + void canClose(); + +private: + void run(); +}; + +#endif // MAINWINDOWCLOSETHREAD_H diff --git a/src/gui/Src/Utils/RichTextPainter.cpp b/src/gui/Src/Utils/RichTextPainter.cpp index 302244d0..44a0e89f 100644 --- a/src/gui/Src/Utils/RichTextPainter.cpp +++ b/src/gui/Src/Utils/RichTextPainter.cpp @@ -1,46 +1,46 @@ -#include "RichTextPainter.h" - -//TODO: sometimes this function takes 15/16ms, it is not clear to me why this is (no noticable performance impact) -void RichTextPainter::paintRichText(QPainter* painter, int x, int y, int w, int h, int xinc, const QList* richText, int charwidth) -{ - int len =