1
0
Fork 0

PROJECT: RESTRUCTURE

This commit is contained in:
Nukem 2015-10-17 16:35:38 -04:00
parent cb173d28a1
commit 2297a92935
561 changed files with 92503 additions and 92708 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,2 +0,0 @@
# this file is only for the people who have serious mental issues (USE WITH CAUTION, THIS DOESN'T WORK)
/\s*([\^+\-*=&|<>\/%!]|<<|>>)?\s*=\s*/ -> / \1= /

View File

@ -4,13 +4,13 @@
#
#check if the formatter is present
if [ ! -f ./AStyleWhore.exe ]; then
if [ ! -f ./hooks/AStyleWhore.exe ]; then
echo "AStyleWhore not found!"
exit 0
fi
#format the code
"./AStyleWhore.exe" Silent
"./hooks/AStyleWhore.exe" Silent
#exit when nothing needs to be done
if [ $? == 0 ]; then
@ -28,6 +28,6 @@ fi
#cancel commit if the changes were undone by the formatting
gitFiles=$(git diff-index --name-only --cached HEAD)
if [ -z "$gitFiles" ]; then
"./AStyleWhore.exe" "After formatting, no files were staged..."
"./hooks/AStyleWhore.exe" "After formatting, no files were staged..."
exit 1
fi

View File

@ -1,326 +1,326 @@
#ifndef _UTF8INI_H
#define _UTF8INI_H
#include <string>
#include <map>
#include <vector>
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<std::string> 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<std::string, std::string> KeyValueMap;
std::map<std::string, KeyValueMap> _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 <string>
#include <map>
#include <vector>
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<std::string> 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<std::string, std::string> KeyValueMap;
std::map<std::string, KeyValueMap> _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

View File

@ -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;

View File

@ -1,61 +1,61 @@
#ifndef _GLOBAL_H
#define _GLOBAL_H
#include <windows.h>
#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 <windows.h>
#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

View File

@ -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 <vector>
/**
\brief A list object. This object is NOT thread safe.
\tparam Type List contents type.
*/
template<typename Type>
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<Type*>(_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<Type> & 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<Type*>(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 <vector>
/**
\brief A list object. This object is NOT thread safe.
\tparam Type List contents type.
*/
template<typename Type>
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<Type*>(_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<Type> & 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<Type*>(listInfo->data);
for(const auto & item : listData)
{
*curItem = item;
++curItem;
}
}
else
listInfo->data = nullptr;
return true;
}
private:
ListInfo _listInfo;
};
#endif //__cplusplus
#endif //_LIST_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,157 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="bridgemain.cpp" />
<ClCompile Include="_global.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="bridgemain.h" />
<ClInclude Include="bridgelist.h" />
<ClInclude Include="Utf8Ini.h" />
<ClInclude Include="_global.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\x32\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>x32bridge</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\x32\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>x32bridge</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\x64\</OutDir>
<TargetName>x64bridge</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\x64\</OutDir>
<TargetName>x64bridge</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>MaxSpeed</Optimization>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>MaxSpeed</Optimization>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="bridgemain.cpp" />
<ClCompile Include="_global.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="bridgemain.h" />
<ClInclude Include="bridgelist.h" />
<ClInclude Include="Utf8Ini.h" />
<ClInclude Include="_global.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>..\..\bin\x32\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>x32bridge</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>..\..\bin\x32\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>x32bridge</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>..\..\bin\x64\</OutDir>
<TargetName>x64bridge</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>..\..\bin\x64\</OutDir>
<TargetName>x64bridge</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>MaxSpeed</Optimization>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>MaxSpeed</Optimization>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,35 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="_global.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="bridgemain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="_global.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="bridgemain.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Utf8Ini.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="bridgelist.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="_global.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="bridgemain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="_global.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="bridgemain.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Utf8Ini.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="bridgelist.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 105 KiB

View File

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -1,22 +1,22 @@
#ifndef _DEVICENAMERESOLVER_H
#define _DEVICENAMERESOLVER_H
#include <windows.h>
#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 <windows.h>
#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

View File

@ -1,53 +1,53 @@
#ifndef _XEDPARSE_H
#define _XEDPARSE_H
#include <windows.h>
//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 <windows.h>
//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

View File

@ -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 "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))
{
uint rva = addr - (uint)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<PROCESSENTRY32> 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()
{
dbggetprivateusage(fdProcessInfo->hProcess, true);
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 "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))
{
uint rva = addr - (uint)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<PROCESSENTRY32> 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()
{
dbggetprivateusage(fdProcessInfo->hProcess, true);
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;
}

View File

@ -1,118 +1,118 @@
#ifndef _DBGFUNCTIONS_H
#define _DBGFUNCTIONS_H
#ifndef __cplusplus
#include <stdbool.h>
#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 <stdbool.h>
#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

File diff suppressed because it is too large Load Diff

View File

@ -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 uint _dbg_getbranchdestination(uint addr);
DLL_EXPORT bool _dbg_functionoverlaps(uint start, uint end);
DLL_EXPORT uint _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 uint _dbg_getbranchdestination(uint addr);
DLL_EXPORT bool _dbg_functionoverlaps(uint start, uint end);
DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* param2);
#ifdef __cplusplus
}
#endif
#endif // _EXPORTS_H

View File

@ -1,364 +1,364 @@
/**
\file _global.cpp
\brief Implements the global class.
*/
#include "_global.h"
#include <objbase.h>
#include <shlobj.h>
/**
\brief x64dbg library instance.
*/
HINSTANCE hInst;
/**
\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[3 * deflen] = "";
/**
\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)
{
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)
{
if(!ptr)
return emalloc(size, reason);
unsigned char* a = (unsigned char*)GlobalReAlloc(ptr, size, GMEM_ZEROINIT | GMEM_MOVEABLE);
if(!a)
{
MessageBoxA(0, "Could not reallocate memory", "Error", MB_ICONERROR);
ExitProcess(1);
}
memset(a, 0, size);
/*
FILE* file = fopen(alloctrace, "a+");
fprintf(file, "DBG%.5d:realloc:" fhex ":%s:" fhex "\n", emalloc_count, a, reason, size);
fclose(file);
*/
return a;
}
/**
\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<char*> 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<char*> 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)
{
uint 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 <objbase.h>
#include <shlobj.h>
/**
\brief x64dbg library instance.
*/
HINSTANCE hInst;
/**
\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[3 * deflen] = "";
/**
\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)
{
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)
{
if(!ptr)
return emalloc(size, reason);
unsigned char* a = (unsigned char*)GlobalReAlloc(ptr, size, GMEM_ZEROINIT | GMEM_MOVEABLE);
if(!a)
{
MessageBoxA(0, "Could not reallocate memory", "Error", MB_ICONERROR);
ExitProcess(1);
}
memset(a, 0, size);
/*
FILE* file = fopen(alloctrace, "a+");
fprintf(file, "DBG%.5d:realloc:" fhex ":%s:" fhex "\n", emalloc_count, a, reason, size);
fclose(file);
*/
return a;
}
/**
\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<char*> 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<char*> 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)
{
uint 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);
}

View File

@ -1,88 +1,88 @@
#ifndef _GLOBAL_H
#define _GLOBAL_H
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501
#define _WIN32_IE 0x0500
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <windows.h>
#include <psapi.h>
#include <shlwapi.h>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <unordered_map>
#include <tlhelp32.h>
#include "..\x64_dbg_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"
typedef unsigned long long uint;
typedef long long sint;
#else
#define fhex "%.8X"
#define fext ""
typedef unsigned long uint;
typedef long sint;
#endif // _WIN64
enum arch
{
notfound,
invalid,
x32,
x64
};
//superglobal variables
extern HINSTANCE hInst;
extern char dbbasepath[deflen];
extern char dbpath[3 * deflen];
//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 <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <windows.h>
#include <psapi.h>
#include <shlwapi.h>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <unordered_map>
#include <tlhelp32.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"
typedef unsigned long long uint;
typedef long long sint;
#else
#define fhex "%.8X"
#define fext ""
typedef unsigned long uint;
typedef long sint;
#endif // _WIN64
enum arch
{
notfound,
invalid,
x32,
x64
};
//superglobal variables
extern HINSTANCE hInst;
extern char dbbasepath[deflen];
extern char dbpath[3 * deflen];
//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

View File

@ -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 <dbghelp.h>
#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 <dbghelp.h>
#endif // __GNUC__
#ifndef deflen
#define deflen 1024
#endif // deflen
#include "bridgemain.h"
#include "_dbgfunctions.h"
#endif // BUILD_DBG
#endif // _PLUGIN_DATA_H

View File

@ -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();
}

View File

@ -1,230 +1,230 @@
#ifndef _PLUGINS_H
#define _PLUGINS_H
#ifndef __cplusplus
#include <stdbool.h>
#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 <stdbool.h>
#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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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<char*> 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<char*> 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);
}

View File

@ -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

View File

@ -1,89 +1,89 @@
#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);
}
#ifdef _WIN64
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);
}
#endif //_WIN64
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);
}
#ifdef _WIN64
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);
}
#endif //_WIN64
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);
}

View File

@ -1,31 +1,31 @@
#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);
#ifdef _WIN64
SCRIPT_EXPORT unsigned long long ReadQword(duint addr);
SCRIPT_EXPORT bool WriteQword(duint addr, unsigned long long data);
#endif //_WIN64
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);
#ifdef _WIN64
SCRIPT_EXPORT unsigned long long ReadQword(duint addr);
SCRIPT_EXPORT bool WriteQword(duint addr, unsigned long long data);
#endif //_WIN64
SCRIPT_EXPORT duint ReadPtr(duint addr);
SCRIPT_EXPORT bool WritePtr(duint addr, duint data);
}; //Memory
}; //Script
#endif //_SCRIPTAPI_MEMORY_H

View File

@ -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);
}

View File

@ -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

View File

@ -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<ModuleSectionInfo> 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<ModuleSectionInfo>::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<MODINFO> modList;
ModGetList(modList);
std::vector<ModuleInfo> 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<ModuleInfo>::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<ModuleSectionInfo> 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<ModuleSectionInfo>::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<MODINFO> modList;
ModGetList(modList);
std::vector<ModuleInfo> 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<ModuleInfo>::CopyData(listInfo, modScriptList);
}

View File

@ -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

View File

@ -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<unsigned char*> 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<unsigned char*> 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<unsigned char*> 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<unsigned char*> 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<unsigned char*> 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<unsigned char*> 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;
}

View File

@ -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

View File

@ -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

View File

@ -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));
}

View File

@ -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

View File

@ -1,236 +1,236 @@
/**
@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"
//database functions
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<char*> 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();
}
///api functions
bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum)
{
MEMORY_BASIC_INFORMATION mbi;
VirtualQueryEx(fdProcessInfo->hProcess, (const void*)base, &mbi, sizeof(mbi));
uint size = mbi.RegionSize;
Memory<void*> buffer(size, "apienumexports:buffer");
if(!MemRead(base, buffer(), size))
return false;
IMAGE_NT_HEADERS* pnth = (IMAGE_NT_HEADERS*)((uint)buffer() + GetPE32DataFromMappedFile((ULONG_PTR)buffer(), 0, UE_PE_OFFSET));
uint export_dir_rva = pnth->OptionalHeader.DataDirectory[0].VirtualAddress;
uint 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);
uint 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((uint)(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((uint)cur_name_va, cur_name, deflen);
WORD curAddrOfNameOrdinals = 0;
MemRead((uint)(AddrOfNameOrdinals_va + sizeof(WORD)*i), &curAddrOfNameOrdinals, sizeof(WORD));
DWORD curFunctionRva = 0;
MemRead((uint)(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)
{
uint local_addr = (uint)GetProcAddress(hTempDll, forwarded_api + j + 1);
if(local_addr)
{
uint 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"
//database functions
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<char*> 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();
}
///api functions
bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum)
{
MEMORY_BASIC_INFORMATION mbi;
VirtualQueryEx(fdProcessInfo->hProcess, (const void*)base, &mbi, sizeof(mbi));
uint size = mbi.RegionSize;
Memory<void*> buffer(size, "apienumexports:buffer");
if(!MemRead(base, buffer(), size))
return false;
IMAGE_NT_HEADERS* pnth = (IMAGE_NT_HEADERS*)((uint)buffer() + GetPE32DataFromMappedFile((ULONG_PTR)buffer(), 0, UE_PE_OFFSET));
uint export_dir_rva = pnth->OptionalHeader.DataDirectory[0].VirtualAddress;
uint 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);
uint 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((uint)(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((uint)cur_name_va, cur_name, deflen);
WORD curAddrOfNameOrdinals = 0;
MemRead((uint)(AddrOfNameOrdinals_va + sizeof(WORD)*i), &curAddrOfNameOrdinals, sizeof(WORD));
DWORD curFunctionRva = 0;
MemRead((uint)(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)
{
uint local_addr = (uint)GetProcAddress(hTempDll, forwarded_api + j + 1);
if(local_addr)
{
uint remote_addr = ImporterGetRemoteAPIAddress(fdProcessInfo->hProcess, local_addr);
cbEnum(base, modname, cur_name, remote_addr);
}
}
}
}
else
{
cbEnum(base, modname, cur_name, curFunctionRva + base);
}
}
return true;
}

View File

@ -1,65 +1,65 @@
#ifndef _ADDRINFO_H
#define _ADDRINFO_H
#include "_global.h"
#include <functional>
//ranges
typedef std::pair<uint, uint> Range;
typedef std::pair<uint, Range> ModuleRange; //modhash + RVA range
typedef std::pair<int, ModuleRange> 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<void (uint base, const char* mod, const char* name, uint addr)> EXPORTENUMCALLBACK;
void dbsave();
void dbload();
void dbclose();
bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum);
#endif // _ADDRINFO_H
#ifndef _ADDRINFO_H
#define _ADDRINFO_H
#include "_global.h"
#include <functional>
//ranges
typedef std::pair<uint, uint> Range;
typedef std::pair<uint, Range> ModuleRange; //modhash + RVA range
typedef std::pair<int, ModuleRange> 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<void (uint base, const char* mod, const char* name, uint addr)> EXPORTENUMCALLBACK;
void dbsave();
void dbload();
void dbclose();
bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum);
#endif // _ADDRINFO_H

View File

@ -1,81 +1,81 @@
/**
@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;
uint val;
if(!valfromstring(text, &val))
return false;
*value = val;
return true;
}
bool assemble(uint 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(uint 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 && fillnop && nopsize)
{
if(size)
*size += nopsize;
// Ignored if the memory patch for NOPs fail (although it should not)
MemPatch(addr + destSize, nops, nopsize);
}
GuiUpdatePatches();
return true;
}
/**
@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;
uint val;
if(!valfromstring(text, &val))
return false;
*value = val;
return true;
}
bool assemble(uint 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(uint 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 && fillnop && nopsize)
{
if(size)
*size += nopsize;
// Ignored if the memory patch for NOPs fail (although it should not)
MemPatch(addr + destSize, nops, nopsize);
}
GuiUpdatePatches();
return true;
}

View File

@ -1,9 +1,9 @@
#ifndef _ASSEMBLE_H
#define _ASSEMBLE_H
#include "_global.h"
bool assemble(uint addr, unsigned char* dest, int* size, const char* instruction, char* error);
bool assembleat(uint addr, const char* instruction, int* size, char* error, bool fillnop);
#endif // _ASSEMBLE_H
#ifndef _ASSEMBLE_H
#define _ASSEMBLE_H
#include "_global.h"
bool assemble(uint addr, unsigned char* dest, int* size, const char* instruction, char* error);
bool assembleat(uint addr, const char* instruction, int* size, char* error, bool fillnop);
#endif // _ASSEMBLE_H

View File

@ -1,209 +1,209 @@
#include "bookmark.h"
#include "threading.h"
#include "module.h"
#include "memory.h"
std::unordered_map<uint, BOOKMARKSINFO> bookmarks;
bool BookmarkSet(uint Address, bool Manual)
{
// CHECK: Export call
if(!DbgIsDebugging())
return false;
// 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(uint Address)
{
// CHECK: Export call
if(!DbgIsDebugging())
return false;
SHARED_ACQUIRE(LockBookmarks);
return (bookmarks.count(ModHashFromAddr(Address)) > 0);
}
bool BookmarkDelete(uint Address)
{
// CHECK: Export call
if(!DbgIsDebugging())
return false;
EXCLUSIVE_ACQUIRE(LockBookmarks);
return (bookmarks.erase(ModHashFromAddr(Address)) > 0);
}
void BookmarkDelRange(uint Start, uint End)
{
// CHECK: Export call
if(!DbgIsDebugging())
return;
// 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
uint 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 = (uint)json_hex_value(json_object_get(value, "address"));
bookmarkInfo.manual = Manual;
const uint 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
if(!List && !Size)
return false;
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<uint, BOOKMARKSINFO> bookmarks;
bool BookmarkSet(uint Address, bool Manual)
{
// CHECK: Export call
if(!DbgIsDebugging())
return false;
// 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(uint Address)
{
// CHECK: Export call
if(!DbgIsDebugging())
return false;
SHARED_ACQUIRE(LockBookmarks);
return (bookmarks.count(ModHashFromAddr(Address)) > 0);
}
bool BookmarkDelete(uint Address)
{
// CHECK: Export call
if(!DbgIsDebugging())
return false;
EXCLUSIVE_ACQUIRE(LockBookmarks);
return (bookmarks.erase(ModHashFromAddr(Address)) > 0);
}
void BookmarkDelRange(uint Start, uint End)
{
// CHECK: Export call
if(!DbgIsDebugging())
return;
// 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
uint 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 = (uint)json_hex_value(json_object_get(value, "address"));
bookmarkInfo.manual = Manual;
const uint 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
if(!List && !Size)
return false;
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();
}

View File

@ -1,19 +1,19 @@
#pragma once
#include "_global.h"
struct BOOKMARKSINFO
{
char mod[MAX_MODULE_SIZE];
uint addr;
bool manual;
};
bool BookmarkSet(uint Address, bool Manual);
bool BookmarkGet(uint Address);
bool BookmarkDelete(uint Address);
void BookmarkDelRange(uint Start, uint 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];
uint addr;
bool manual;
};
bool BookmarkSet(uint Address, bool Manual);
bool BookmarkGet(uint Address);
bool BookmarkDelete(uint Address);
void BookmarkDelRange(uint Start, uint End);
void BookmarkCacheSave(JSON Root);
void BookmarkCacheLoad(JSON Root);
bool BookmarkEnum(BOOKMARKSINFO* List, size_t* Size);
void BookmarkClear();

View File

@ -1,406 +1,406 @@
/**
@file breakpoint.cpp
@brief Implements the breakpoint class.
*/
#include "breakpoint.h"
#include "memory.h"
#include "threading.h"
#include "module.h"
typedef std::pair<BP_TYPE, uint> BreakpointKey;
std::map<BreakpointKey, BREAKPOINT> breakpoints;
BREAKPOINT* BpInfoFromAddr(BP_TYPE Type, uint 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<BREAKPOINT>* List)
{
// CHECK: Exported function
if(!DbgIsDebugging())
return false;
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(uint Address, bool Enable, bool Singleshot, short OldBytes, BP_TYPE Type, DWORD TitanType, const char* Name)
{
// CHECK: Command function
if(!DbgIsDebugging())
return false;
// 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(uint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
{
// CHECK: Export/Command function
if(!DbgIsDebugging())
return false;
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(uint Address, BP_TYPE Type)
{
// CHECK: Command function
if(!DbgIsDebugging())
return false;
// Erase the index from the global list
EXCLUSIVE_ACQUIRE(LockBreakpoints);
return (breakpoints.erase(BreakpointKey(Type, ModHashFromAddr(Address))) > 0);
}
bool BpEnable(uint Address, BP_TYPE Type, bool Enable)
{
// CHECK: Command function
if(!DbgIsDebugging())
return false;
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(uint Address, BP_TYPE Type, const char* Name)
{
// CHECK: Future(?); This is not used anywhere
if(!DbgIsDebugging())
return false;
// If a name wasn't supplied, set to nothing
if(!Name)
Name = "";
EXCLUSIVE_ACQUIRE(LockBreakpoints);
// Check if the breakpoint exists first
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
if(!bpInfo)
return false;
strcpy_s(bpInfo->name, Name);
return true;
}
bool BpSetTitanType(uint Address, BP_TYPE Type, int TitanType)
{
// CHECK: Command function
if(!DbgIsDebugging())
return false;
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)
{
if(!DbgIsDebugging())
return false;
SHARED_ACQUIRE(LockBreakpoints);
// Loop each entry, executing the user's callback
bool callbackStatus = true;
auto i = breakpoints.begin();
while(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
//
// TOOD: ASSERT(?) These should never be null
if(!Bp || !BridgeBp)
return;
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 = (uint)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 uint 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<BP_TYPE, uint> BreakpointKey;
std::map<BreakpointKey, BREAKPOINT> breakpoints;
BREAKPOINT* BpInfoFromAddr(BP_TYPE Type, uint 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<BREAKPOINT>* List)
{
// CHECK: Exported function
if(!DbgIsDebugging())
return false;
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(uint Address, bool Enable, bool Singleshot, short OldBytes, BP_TYPE Type, DWORD TitanType, const char* Name)
{
// CHECK: Command function
if(!DbgIsDebugging())
return false;
// 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(uint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
{
// CHECK: Export/Command function
if(!DbgIsDebugging())
return false;
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(uint Address, BP_TYPE Type)
{
// CHECK: Command function
if(!DbgIsDebugging())
return false;
// Erase the index from the global list
EXCLUSIVE_ACQUIRE(LockBreakpoints);
return (breakpoints.erase(BreakpointKey(Type, ModHashFromAddr(Address))) > 0);
}
bool BpEnable(uint Address, BP_TYPE Type, bool Enable)
{
// CHECK: Command function
if(!DbgIsDebugging())
return false;
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(uint Address, BP_TYPE Type, const char* Name)
{
// CHECK: Future(?); This is not used anywhere
if(!DbgIsDebugging())
return false;
// If a name wasn't supplied, set to nothing
if(!Name)
Name = "";
EXCLUSIVE_ACQUIRE(LockBreakpoints);
// Check if the breakpoint exists first
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
if(!bpInfo)
return false;
strcpy_s(bpInfo->name, Name);
return true;
}
bool BpSetTitanType(uint Address, BP_TYPE Type, int TitanType)
{
// CHECK: Command function
if(!DbgIsDebugging())
return false;
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)
{
if(!DbgIsDebugging())
return false;
SHARED_ACQUIRE(LockBreakpoints);
// Loop each entry, executing the user's callback
bool callbackStatus = true;
auto i = breakpoints.begin();
while(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
//
// TOOD: ASSERT(?) These should never be null
if(!Bp || !BridgeBp)
return;
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 = (uint)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 uint key = ModHashFromName(breakpoint.mod) + breakpoint.addr;
breakpoints.insert(std::make_pair(BreakpointKey(breakpoint.type, key), breakpoint));
}
}
void BpClear()
{
EXCLUSIVE_ACQUIRE(LockBreakpoints);
breakpoints.clear();
}

View File

@ -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
{
uint 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, uint Address);
int BpGetList(std::vector<BREAKPOINT>* List);
bool BpNew(uint Address, bool Enable, bool Singleshot, short OldBytes, BP_TYPE Type, DWORD TitanType, const char* Name);
bool BpGet(uint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp);
bool BpDelete(uint Address, BP_TYPE Type);
bool BpEnable(uint Address, BP_TYPE Type, bool Enable);
bool BpSetName(uint Address, BP_TYPE Type, const char* Name);
bool BpSetTitanType(uint 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
{
uint 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, uint Address);
int BpGetList(std::vector<BREAKPOINT>* List);
bool BpNew(uint Address, bool Enable, bool Singleshot, short OldBytes, BP_TYPE Type, DWORD TitanType, const char* Name);
bool BpGet(uint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp);
bool BpDelete(uint Address, BP_TYPE Type);
bool BpEnable(uint Address, BP_TYPE Type, bool Enable);
bool BpSetName(uint Address, BP_TYPE Type, const char* Name);
bool BpSetTitanType(uint 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();

View File

@ -1,199 +1,199 @@
#include "console.h"
#include "capstone_wrapper.h"
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;
mError = CS_ERR_OK;
}
Capstone::~Capstone()
{
if(mInstr) //free last disassembled instruction
cs_free(mInstr, 1);
}
bool Capstone::Disassemble(uint addr, const unsigned char data[MAX_DISASM_BUFFER])
{
return Disassemble(addr, data, MAX_DISASM_BUFFER);
}
bool Capstone::Disassemble(uint addr, const unsigned char* data, int size)
{
if(!data)
return false;
if(mInstr) //free last disassembled instruction
{
cs_free(mInstr, 1);
mInstr = nullptr;
}
return !!cs_disasm(mHandle, data, size, addr, 1, &mInstr);
}
const cs_insn* Capstone::GetInstr() const
{
return mInstr;
}
cs_err Capstone::GetError() const
{
return mError;
}
const char* Capstone::RegName(x86_reg reg) const
{
return cs_reg_name(mHandle, reg);
}
bool Capstone::InGroup(cs_group_type group) const
{
return cs_insn_group(mHandle, mInstr, group);
}
String Capstone::OperandText(int opindex) const
{
if(opindex >= mInstr->detail->x86.op_count)
return "";
const auto & op = mInstr->detail->x86.operands[opindex];
String result;
char temp[32] = "";
switch(op.type)
{
case X86_OP_REG:
{
result = RegName(x86_reg(op.reg));
}
break;
case X86_OP_IMM:
{
if(InGroup(CS_GRP_JUMP) || InGroup(CS_GRP_CALL) || IsLoop())
sprintf_s(temp, "%" fext "X", op.imm + mInstr->size);
else
sprintf_s(temp, "%" fext "X", 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, "%" fext "X", mInstr->address + op.mem.disp + mInstr->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, "%" fext "X", mem.disp * -1);
}
else
sprintf_s(temp, "%" fext "X", mem.disp);
if(prependPlus)
result += operatorText;
result += temp;
}
}
}
break;
case X86_OP_FP:
case X86_OP_INVALID:
{
}
break;
}
return result;
}
int Capstone::Size() const
{
return GetInstr()->size;
}
uint Capstone::Address() const
{
return uint(GetInstr()->address);
}
const cs_x86 & Capstone::x86() const
{
return GetInstr()->detail->x86;
}
bool Capstone::IsFilling() const
{
switch(GetId())
{
case X86_INS_NOP:
case X86_INS_INT3:
return true;
default:
return false;
}
}
bool Capstone::IsLoop() const
{
switch(GetId())
{
case X86_INS_LOOP:
case X86_INS_LOOPE:
case X86_INS_LOOPNE:
return true;
default:
return false;
}
}
x86_insn Capstone::GetId() const
{
return x86_insn(mInstr->id);
}
String Capstone::InstructionText() const
{
String result = mInstr->mnemonic;
result += " ";
result += mInstr->op_str;
return result;
#include "console.h"
#include "capstone_wrapper.h"
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;
mError = CS_ERR_OK;
}
Capstone::~Capstone()
{
if(mInstr) //free last disassembled instruction
cs_free(mInstr, 1);
}
bool Capstone::Disassemble(uint addr, const unsigned char data[MAX_DISASM_BUFFER])
{
return Disassemble(addr, data, MAX_DISASM_BUFFER);
}
bool Capstone::Disassemble(uint addr, const unsigned char* data, int size)
{
if(!data)
return false;
if(mInstr) //free last disassembled instruction
{
cs_free(mInstr, 1);
mInstr = nullptr;
}
return !!cs_disasm(mHandle, data, size, addr, 1, &mInstr);
}
const cs_insn* Capstone::GetInstr() const
{
return mInstr;
}
cs_err Capstone::GetError() const
{
return mError;
}
const char* Capstone::RegName(x86_reg reg) const
{
return cs_reg_name(mHandle, reg);
}
bool Capstone::InGroup(cs_group_type group) const
{
return cs_insn_group(mHandle, mInstr, group);
}
String Capstone::OperandText(int opindex) const
{
if(opindex >= mInstr->detail->x86.op_count)
return "";
const auto & op = mInstr->detail->x86.operands[opindex];
String result;
char temp[32] = "";
switch(op.type)
{
case X86_OP_REG:
{
result = RegName(x86_reg(op.reg));
}
break;
case X86_OP_IMM:
{
if(InGroup(CS_GRP_JUMP) || InGroup(CS_GRP_CALL) || IsLoop())
sprintf_s(temp, "%" fext "X", op.imm + mInstr->size);
else
sprintf_s(temp, "%" fext "X", 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, "%" fext "X", mInstr->address + op.mem.disp + mInstr->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, "%" fext "X", mem.disp * -1);
}
else
sprintf_s(temp, "%" fext "X", mem.disp);
if(prependPlus)
result += operatorText;
result += temp;
}
}
}
break;
case X86_OP_FP:
case X86_OP_INVALID:
{
}
break;
}
return result;
}
int Capstone::Size() const
{
return GetInstr()->size;
}
uint Capstone::Address() const
{
return uint(GetInstr()->address);
}
const cs_x86 & Capstone::x86() const
{
return GetInstr()->detail->x86;
}
bool Capstone::IsFilling() const
{
switch(GetId())
{
case X86_INS_NOP:
case X86_INS_INT3:
return true;
default:
return false;
}
}
bool Capstone::IsLoop() const
{
switch(GetId())
{
case X86_INS_LOOP:
case X86_INS_LOOPE:
case X86_INS_LOOPNE:
return true;
default:
return false;
}
}
x86_insn Capstone::GetId() const
{
return x86_insn(mInstr->id);
}
String Capstone::InstructionText() const
{
String result = mInstr->mnemonic;
result += " ";
result += mInstr->op_str;
return result;
}

View File

@ -1,37 +1,37 @@
#ifndef _CAPSTONE_WRAPPER_H
#define _CAPSTONE_WRAPPER_H
#include "capstone\capstone.h"
#define MAX_DISASM_BUFFER 16
#define INVALID_TITAN_REG 0
class Capstone
{
public:
static void GlobalInitialize();
static void GlobalFinalize();
Capstone();
~Capstone();
bool Disassemble(uint addr, const unsigned char data[MAX_DISASM_BUFFER]);
bool Disassemble(uint addr, const unsigned char* data, int size);
const cs_insn* GetInstr() const;
cs_err GetError() const;
const char* RegName(x86_reg reg) const;
bool InGroup(cs_group_type group) const;
String OperandText(int opindex) const;
int Size() const;
uint Address() const;
const cs_x86 & x86() const;
bool IsFilling() const;
bool IsLoop() const;
x86_insn GetId() const;
String InstructionText() const;
private:
static csh mHandle;
cs_insn* mInstr;
cs_err mError;
};
#ifndef _CAPSTONE_WRAPPER_H
#define _CAPSTONE_WRAPPER_H
#include "capstone\capstone.h"
#define MAX_DISASM_BUFFER 16
#define INVALID_TITAN_REG 0
class Capstone
{
public:
static void GlobalInitialize();
static void GlobalFinalize();
Capstone();
~Capstone();
bool Disassemble(uint addr, const unsigned char data[MAX_DISASM_BUFFER]);
bool Disassemble(uint addr, const unsigned char* data, int size);
const cs_insn* GetInstr() const;
cs_err GetError() const;
const char* RegName(x86_reg reg) const;
bool InGroup(cs_group_type group) const;
String OperandText(int opindex) const;
int Size() const;
uint Address() const;
const cs_x86 & x86() const;
bool IsFilling() const;
bool IsLoop() const;
x86_insn GetId() const;
String InstructionText() const;
private:
static csh mHandle;
cs_insn* mInstr;
cs_err mError;
};
#endif //_CAPSTONE_WRAPPER_H

View File

@ -1,400 +1,400 @@
/**
@file command.cpp
@brief Implements the command class.
*/
#include "command.h"
#include "value.h"
#include "console.h"
#include "commandparser.h"
/**
\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(COMMAND* command_list, const char* name, COMMAND** link)
{
COMMAND* cur = command_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()
{
COMMAND* cmd = (COMMAND*)emalloc(sizeof(COMMAND), "cmdinit:cmd");
memset(cmd, 0, sizeof(COMMAND));
return cmd;
}
/**
\brief Clear a command list.
\param [in] cmd_list Command list to clear.
*/
void cmdfree(COMMAND* cmd_list)
{
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(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool debugonly)
{
if(!command_list || !cbCommand || !name || !*name || cmdfind(command_list, name, 0))
return false;
COMMAND* cmd;
bool nonext = false;
if(!command_list->name)
{
cmd = command_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 = command_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(COMMAND* command_list, 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(command_list, 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(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool debugonly)
{
if(!cbCommand)
return 0;
COMMAND* found = cmdfind(command_list, 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(COMMAND* command_list, const char* name)
{
COMMAND* prev = 0;
COMMAND* found = cmdfind(command_list, name, &prev);
if(!found)
return false;
efree(found->name, "cmddel:found->name");
if(found == command_list)
{
COMMAND* next = command_list->next;
if(next)
{
memcpy(command_list, command_list->next, sizeof(COMMAND));
command_list->next = next->next;
efree(next, "cmddel:next");
}
else
memset(command_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(COMMAND* command_list, 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_list, command);
else //'dirty' command processing
cmd = cbCommandFinder(command_list, 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)
{
uint 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(COMMAND* cmd_list, char* command)
{
COMMAND* cmd = cmdfind(cmd_list, command, 0);
if(!cmd)
{
specialformat(command);
cmd = cmdget(cmd_list, 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(COMMAND* cmd_list, const char* cmd)
{
if(!cmd || !strlen(cmd))
return STATUS_ERROR;
char command[deflen] = "";
strcpy_s(command, StringUtils::Trim(cmd).c_str());
COMMAND* found = cmdfindmain(cmd_list, 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"
/**
\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(COMMAND* command_list, const char* name, COMMAND** link)
{
COMMAND* cur = command_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()
{
COMMAND* cmd = (COMMAND*)emalloc(sizeof(COMMAND), "cmdinit:cmd");
memset(cmd, 0, sizeof(COMMAND));
return cmd;
}
/**
\brief Clear a command list.
\param [in] cmd_list Command list to clear.
*/
void cmdfree(COMMAND* cmd_list)
{
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(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool debugonly)
{
if(!command_list || !cbCommand || !name || !*name || cmdfind(command_list, name, 0))
return false;
COMMAND* cmd;
bool nonext = false;
if(!command_list->name)
{
cmd = command_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 = command_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(COMMAND* command_list, 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(command_list, 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(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool debugonly)
{
if(!cbCommand)
return 0;
COMMAND* found = cmdfind(command_list, 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(COMMAND* command_list, const char* name)
{
COMMAND* prev = 0;
COMMAND* found = cmdfind(command_list, name, &prev);
if(!found)
return false;
efree(found->name, "cmddel:found->name");
if(found == command_list)
{
COMMAND* next = command_list->next;
if(next)
{
memcpy(command_list, command_list->next, sizeof(COMMAND));
command_list->next = next->next;
efree(next, "cmddel:next");
}
else
memset(command_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(COMMAND* command_list, 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_list, command);
else //'dirty' command processing
cmd = cbCommandFinder(command_list, 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)
{
uint 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(COMMAND* cmd_list, char* command)
{
COMMAND* cmd = cmdfind(cmd_list, command, 0);
if(!cmd)
{
specialformat(command);
cmd = cmdget(cmd_list, 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(COMMAND* cmd_list, const char* cmd)
{
if(!cmd || !strlen(cmd))
return STATUS_ERROR;
char command[deflen] = "";
strcpy_s(command, StringUtils::Trim(cmd).c_str());
COMMAND* found = cmdfindmain(cmd_list, 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;
}

View File

@ -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)(COMMAND*, char*);
struct COMMAND
{
char* name;
CBCOMMAND cbCommand;
bool debugonly;
COMMAND* next;
};
//functions
COMMAND* cmdinit();
void cmdfree(COMMAND* cmd_list);
COMMAND* cmdfind(COMMAND* command_list, const char* name, COMMAND** link);
bool cmdnew(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool debugonly);
COMMAND* cmdget(COMMAND* command_list, const char* cmd);
CBCOMMAND cmdset(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool debugonly);
bool cmddel(COMMAND* command_list, const char* name);
CMDRESULT cmdloop(COMMAND* command_list, CBCOMMAND cbUnknownCommand, CBCOMMANDPROVIDER cbCommandProvider, CBCOMMANDFINDER cbCommandFinder, bool error_is_fatal);
COMMAND* cmdfindmain(COMMAND* cmd_list, char* command);
CMDRESULT cmddirectexec(COMMAND* cmd_list, 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)(COMMAND*, char*);
struct COMMAND
{
char* name;
CBCOMMAND cbCommand;
bool debugonly;
COMMAND* next;
};
//functions
COMMAND* cmdinit();
void cmdfree(COMMAND* cmd_list);
COMMAND* cmdfind(COMMAND* command_list, const char* name, COMMAND** link);
bool cmdnew(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool debugonly);
COMMAND* cmdget(COMMAND* command_list, const char* cmd);
CBCOMMAND cmdset(COMMAND* command_list, const char* name, CBCOMMAND cbCommand, bool debugonly);
bool cmddel(COMMAND* command_list, const char* name);
CMDRESULT cmdloop(COMMAND* command_list, CBCOMMAND cbUnknownCommand, CBCOMMANDPROVIDER cbCommandProvider, CBCOMMANDFINDER cbCommandFinder, bool error_is_fatal);
COMMAND* cmdfindmain(COMMAND* cmd_list, char* command);
CMDRESULT cmddirectexec(COMMAND* cmd_list, const char* cmd);
#endif // _COMMAND_H

View File

@ -1,114 +1,114 @@
#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 ' ':
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 ' ':
dataAppend(ch);
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 ' ':
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 ' ':
dataAppend(ch);
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();
}
}

View File

@ -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<String> _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<String> _tokens;
enum ParseState
{
Default,
Escaped,
Text,
TextEscaped
};
void dataFinish();
void dataAppend(const char ch);
};
#endif // _COMMANDPARSER_H

View File

@ -1,249 +1,249 @@
#include "comment.h"
#include "threading.h"
#include "module.h"
#include "memory.h"
std::unordered_map<uint, COMMENTSINFO> comments;
bool CommentSet(uint Address, const char* Text, bool Manual)
{
// CHECK: Exported/Command function
if(!DbgIsDebugging())
return false;
// 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 uint 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(uint Address, char* Text)
{
// CHECK: Exported/Command function
if(!DbgIsDebugging())
return false;
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(uint Address)
{
// CHECK: Command/Sub function
if(!DbgIsDebugging())
return false;
EXCLUSIVE_ACQUIRE(LockComments);
return (comments.erase(ModHashFromAddr(Address)) > 0);
}
void CommentDelRange(uint Start, uint End)
{
// CHECK: Export function
if(!DbgIsDebugging())
return;
// 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
uint 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 = (uint)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 uint 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)
{
// CHECK: Command function
if(!DbgIsDebugging())
return false;
// At least 1 parameter must be supplied
if(!List && !Size)
return false;
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<uint, COMMENTSINFO> comments;
bool CommentSet(uint Address, const char* Text, bool Manual)
{
// CHECK: Exported/Command function
if(!DbgIsDebugging())
return false;
// 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 uint 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(uint Address, char* Text)
{
// CHECK: Exported/Command function
if(!DbgIsDebugging())
return false;
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(uint Address)
{
// CHECK: Command/Sub function
if(!DbgIsDebugging())
return false;
EXCLUSIVE_ACQUIRE(LockComments);
return (comments.erase(ModHashFromAddr(Address)) > 0);
}
void CommentDelRange(uint Start, uint End)
{
// CHECK: Export function
if(!DbgIsDebugging())
return;
// 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
uint 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 = (uint)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 uint 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)
{
// CHECK: Command function
if(!DbgIsDebugging())
return false;
// At least 1 parameter must be supplied
if(!List && !Size)
return false;
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();
}

View File

@ -1,20 +1,20 @@
#pragma once
#include "_global.h"
struct COMMENTSINFO
{
char mod[MAX_MODULE_SIZE];
uint addr;
char text[MAX_COMMENT_SIZE];
bool manual;
};
bool CommentSet(uint Address, const char* Text, bool Manual);
bool CommentGet(uint Address, char* Text);
bool CommentDelete(uint Address);
void CommentDelRange(uint Start, uint 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];
uint addr;
char text[MAX_COMMENT_SIZE];
bool manual;
};
bool CommentSet(uint Address, const char* Text, bool Manual);
bool CommentGet(uint Address, char* Text);
bool CommentDelete(uint Address);
void CommentDelRange(uint Start, uint End);
void CommentCacheSave(JSON Root);
void CommentCacheLoad(JSON Root);
bool CommentEnum(COMMENTSINFO* List, size_t* Size);
void CommentClear();

View File

@ -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);
}

View File

@ -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);

View File

@ -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(uint base, uint 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 = (uint)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<uint, int> 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(uint i = 0; i < _size;)
{
uint 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
{
uint dest1 = GetReferenceOperand();
uint 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))
{
uint dest1 = GetReferenceOperand();
if(dest1)
{
_blockStarts.insert(dest1);
_functionStarts.insert(dest1);
}
}
else
{
uint dest1 = GetReferenceOperand();
if(dest1)
_blockStarts.insert(dest1);
}
i += _cp.Size();
}
else
i++;
}
}
void ControlFlowAnalysis::BasicBlocks()
{
for(auto i = _blockStarts.begin(); i != _blockStarts.end(); ++i)
{
uint start = *i;
if(!IsValidAddress(start))
continue;
uint nextStart = _base + _size;
auto next = std::next(i);
if(next != _blockStarts.end())
nextStart = *next;
for(uint 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())
{
uint dest1 = GetReferenceOperand();
uint 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 uint funcAddr = _moduleBase + Function->BeginAddress;
const uint 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<BasicBlock*, UintSet*> DelayedBlock;
std::vector<DelayedBlock> 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
{
uint functionStart = block->start;
block->function = functionStart;
UintSet functionBlocks;
functionBlocks.insert(functionStart);
_functions[functionStart] = functionBlocks;
}
else //in function
{
uint 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;
uint 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)
{
uint start = function.first;
uint 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(uint start)
{
if(!start)
return nullptr;
auto found = _blocks.find(start);
return found != _blocks.end() ? &found->second : nullptr;
}
void ControlFlowAnalysis::insertParent(uint child, uint 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(uint child)
{
if(!child)
return nullptr;
auto found = _parentMap.find(child);
return found != _parentMap.end() ? &found->second : nullptr;
}
uint 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();
}
uint 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)
{
uint dest = (uint)operand.imm;
if(dest >= _base && dest < _base + _size)
return dest;
}
}
return 0;
}
#ifdef _WIN64
void ControlFlowAnalysis::EnumerateFunctionRuntimeEntries64(std::function<bool(PRUNTIME_FUNCTION)> Callback)
{
if(!_functionInfoData)
return;
// Get the table pointer and size
auto functionTable = (PRUNTIME_FUNCTION)_functionInfoData;
uint 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(uint base, uint 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 = (uint)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<uint, int> 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(uint i = 0; i < _size;)
{
uint 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
{
uint dest1 = GetReferenceOperand();
uint 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))
{
uint dest1 = GetReferenceOperand();
if(dest1)
{
_blockStarts.insert(dest1);
_functionStarts.insert(dest1);
}
}
else
{
uint dest1 = GetReferenceOperand();
if(dest1)
_blockStarts.insert(dest1);
}
i += _cp.Size();
}
else
i++;
}
}
void ControlFlowAnalysis::BasicBlocks()
{
for(auto i = _blockStarts.begin(); i != _blockStarts.end(); ++i)
{
uint start = *i;
if(!IsValidAddress(start))
continue;
uint nextStart = _base + _size;
auto next = std::next(i);
if(next != _blockStarts.end())
nextStart = *next;
for(uint 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())
{
uint dest1 = GetReferenceOperand();
uint 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 uint funcAddr = _moduleBase + Function->BeginAddress;
const uint 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<BasicBlock*, UintSet*> DelayedBlock;
std::vector<DelayedBlock> 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
{
uint functionStart = block->start;
block->function = functionStart;
UintSet functionBlocks;
functionBlocks.insert(functionStart);
_functions[functionStart] = functionBlocks;
}
else //in function
{
uint 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;
uint 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)
{
uint start = function.first;
uint 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(uint start)
{
if(!start)
return nullptr;
auto found = _blocks.find(start);
return found != _blocks.end() ? &found->second : nullptr;
}
void ControlFlowAnalysis::insertParent(uint child, uint 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(uint child)
{
if(!child)
return nullptr;
auto found = _parentMap.find(child);
return found != _parentMap.end() ? &found->second : nullptr;
}
uint 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();
}
uint 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)
{
uint dest = (uint)operand.imm;
if(dest >= _base && dest < _base + _size)
return dest;
}
}
return 0;
}
#ifdef _WIN64
void ControlFlowAnalysis::EnumerateFunctionRuntimeEntries64(std::function<bool(PRUNTIME_FUNCTION)> Callback)
{
if(!_functionInfoData)
return;
// Get the table pointer and size
auto functionTable = (PRUNTIME_FUNCTION)_functionInfoData;
uint totalCount = (_functionInfoSize / sizeof(RUNTIME_FUNCTION));
// Enumerate each entry
for(ULONG i = 0; i < totalCount; i++)
{
if(!Callback(&functionTable[i]))
break;
}
}
#endif // _WIN64

Some files were not shown because too many files have changed in this diff Show More