1
0
Fork 0

Merge branch 'master' into doxygen

Conflicts:
	x64_dbg_dbg/_dbgfunctions.cpp
	x64_dbg_dbg/_exports.cpp
	x64_dbg_dbg/_global.cpp
	x64_dbg_dbg/instruction.cpp
	x64_dbg_dbg/patches.cpp
	x64_dbg_dbg/value.cpp
	x64_dbg_dbg/variable.cpp
This commit is contained in:
Mr. eXoDia 2014-12-09 11:12:40 +01:00
commit fde43663fd
84 changed files with 4888 additions and 3009 deletions

1368
LICENSE

File diff suppressed because it is too large Load Diff

View File

@ -63,7 +63,8 @@ Releases of *x64_dbg* can be found on [here](http://download.x64dbg.com).
- Nukem
- ahmadmansoor
## Developers
- Mr. eXoDia
## Developers (in order of joining)
- [Mr. eXoDia](http://mrexodia.cf)
- Sigma
- tr4ceflow
- [tr4ceflow](http://blog.tr4ceflow.com)
- [Dreg](http://www.fr33project.org)

View File

@ -46,43 +46,36 @@ del /Q Project\Src\Bridge\x32_bridge.lib
del /Q Project\Src\Bridge\x64_bridge.lib
cd ..
echo cleaning bin\
cd bin
del /Q *.pdb
del /Q *.exp
del /Q *.a
del /Q *.lib
del /Q *.def
del /Q x96_dbg.exe
cd..
del /Q bin\*.pdb
del /Q bin\*.exp
del /Q bin\*.a
del /Q bin\*.lib
del /Q bin\*.def
del /Q bin\x96_dbg.exe
echo cleaning bin\x32...
cd bin\x32
rmdir /S /Q db
del /Q *.pdb
del /Q *.exp
del /Q *.a
del /Q *.lib
del /Q *.def
del /Q x32_dbg.exe
del /Q x32_dbg.dll
del /Q x32_gui.dll
del /Q x32_bridge.dll
cd ..
cd ..
rmdir /S /Q bin\x32\db
del /Q bin\x32\*.pdb
del /Q bin\x32\*.exp
del /Q bin\x32\*.a
del /Q bin\x32\*.lib
del /Q bin\x32\*.def
del /Q bin\x32\x32_dbg.exe
del /Q bin\x32\x32_dbg.dll
del /Q bin\x32\x32_gui.dll
del /Q bin\x32\x32_bridge.dll
echo cleaning bin\x64...
cd bin\x64
rmdir /S /Q db
del /Q *.pdb
del /Q *.exp
del /Q *.a
del /Q *.lib
del /Q *.def
del /Q x64_dbg.exe
del /Q x64_dbg.dll
del /Q x64_gui.dll
del /Q x64_bridge.dll
cd ..
cd ..
rmdir /S /Q bin\x64\db
del /Q bin\x64\*.pdb
del /Q bin\x64\*.exp
del /Q bin\x64\*.a
del /Q bin\x64\*.lib
del /Q bin\x64\*.def
del /Q bin\x64\x64_dbg.exe
del /Q bin\x64\x64_dbg.dll
del /Q bin\x64\x64_gui.dll
del /Q bin\x64\x64_bridge.dll
echo cleaning help...
cd help
del /Q *.chm
rmdir /S /Q output
rmdir /S /Q output
exit 0

View File

@ -64,13 +64,17 @@ ahmadmansoor </P>
</P>
<UL>
<LI>
<DIV><A href="http://mrexodia.cf/" target=_blank>Mr.
<DIV><A href="http://mrexodia.cf" target=_blank>Mr.
eXoDia</A>
&nbsp; </DIV>
<LI>
<DIV>
Sigma </DIV>
<LI>
<DIV><A href="http://blog.tr4ceflow.com/"
<DIV><A href="http://blog.tr4ceflow.com"
target=_blank>tr4ceflow</A>
&nbsp; </DIV></LI></UL></body></HTML>
</DIV>
<LI>
<DIV><A href="http://www.fr33project.org"
target=_blank>Dreg</A>
&nbsp;&nbsp; </DIV></LI></UL></body></HTML>

View File

@ -0,0 +1,43 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>reffindrange/findrefrange/refrange</title>
<meta name="GENERATOR" content="WinCHM">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
html,body {
/* Default Font */
font-family: Courier New;
font-size: 11pt;
}
</style>
</head>
<body>
<P><STRONG>reffindrange[,findrefrange,ref</STRONG><STRONG>range</STRONG><STRONG>]<BR></STRONG>Find references to a certain range of values.</P>
<P class=rvps3>
<SPAN class=rvts11>
<U>
arguments
</U>
<BR>
</SPAN>
<SPAN class=rvts9 >&nbsp; arg1: Start of the range (will be
included in the results when found).</SPAN></P>
<P class=rvps3>
<SPAN class=rvts9 >
[arg2]: End of range (will be included in the results when
found). When not specified the first argument will be used.</SPAN></P>
<P class=rvps3 >
<SPAN class=rvts9>
[arg3]: Address&nbsp;of/inside a memory page to look in.
When not specified CIP will be used.&nbsp;</SPAN></P>
<P class=rvps3><SPAN class=rvts9>[arg4]: The size of the data to search in. </SPAN></P>
<P class=rvps3><SPAN class=rvts11><U>result <BR></U></SPAN><SPAN
class=rvts9>The $result variable is set to the number of
references found.</SPAN> </P>
<P>&nbsp;</P></body>
</html>

Binary file not shown.

View File

@ -1,5 +1,6 @@
@echo off
set RELEASEDIR=.\release
rmdir /S /Q %RELEASEDIR%
mkdir %RELEASEDIR%
echo qt_base
@ -40,22 +41,6 @@ copy bin\x64\lz4.dll %RELEASEDIR%\bin_base\x64\lz4.dll
copy bin\x64\TitanEngine.dll %RELEASEDIR%\bin_base\x64\TitanEngine.dll
copy bin\x64\XEDParse.dll %RELEASEDIR%\bin_base\x64\XEDParse.dll
echo release
mkdir %RELEASEDIR%\release
mkdir %RELEASEDIR%\release\x32
mkdir %RELEASEDIR%\release\x64
copy bin\x96_dbg.exe %RELEASEDIR%\release\x96_dbg.exe
copy bin\x32\x32_bridge.dll %RELEASEDIR%\release\x32\x32_bridge.dll
copy bin\x32\x32_dbg.dll %RELEASEDIR%\release\x32\x32_dbg.dll
copy bin\x32\x32_dbg.exe %RELEASEDIR%\release\x32\x32_dbg.exe
copy bin\x32\x32_gui.dll %RELEASEDIR%\release\x32\x32_gui.dll
copy bin\x64\x64_bridge.dll %RELEASEDIR%\release\x64\x64_bridge.dll
copy bin\x64\x64_dbg.dll %RELEASEDIR%\release\x64\x64_dbg.dll
copy bin\x64\x64_dbg.exe %RELEASEDIR%\release\x64\x64_dbg.exe
copy bin\x64\x64_gui.dll %RELEASEDIR%\release\x64\x64_gui.dll
echo help
mkdir %RELEASEDIR%\help
@ -110,12 +95,24 @@ del x64_dbg.def
del x64_dbg.a
copy bin\x64\x64_dbg.lib %RELEASEDIR%\pluginsdk\x64_dbg.lib
echo test
echo release
rmdir %RELEASEDIR%\test /S /Q
mkdir %RELEASEDIR%\test
mkdir %RELEASEDIR%\release
mkdir %RELEASEDIR%\release\x32
mkdir %RELEASEDIR%\release\x64
xcopy %RELEASEDIR%\qt_base %RELEASEDIR%\test /S /Y
xcopy %RELEASEDIR%\bin_base %RELEASEDIR%\test /S /Y
xcopy %RELEASEDIR%\release %RELEASEDIR%\test /S /Y
xcopy %RELEASEDIR%\help %RELEASEDIR%\test /S /Y
copy bin\x96_dbg.exe %RELEASEDIR%\release\x96_dbg.exe
copy bin\x32\x32_bridge.dll %RELEASEDIR%\release\x32\x32_bridge.dll
copy bin\x32\x32_dbg.dll %RELEASEDIR%\release\x32\x32_dbg.dll
copy bin\x32\x32_dbg.exe %RELEASEDIR%\release\x32\x32_dbg.exe
copy bin\x32\x32_gui.dll %RELEASEDIR%\release\x32\x32_gui.dll
copy bin\x64\x64_bridge.dll %RELEASEDIR%\release\x64\x64_bridge.dll
copy bin\x64\x64_dbg.dll %RELEASEDIR%\release\x64\x64_dbg.dll
copy bin\x64\x64_dbg.exe %RELEASEDIR%\release\x64\x64_dbg.exe
copy bin\x64\x64_gui.dll %RELEASEDIR%\release\x64\x64_gui.dll
xcopy %RELEASEDIR%\qt_base %RELEASEDIR%\release /S /Y
xcopy %RELEASEDIR%\bin_base %RELEASEDIR%\release /S /Y
xcopy %RELEASEDIR%\help %RELEASEDIR%\release /S /Y
exit 0

View File

@ -73,7 +73,7 @@ BRIDGE_IMPEXP const char* BridgeInit()
if(szIniFile[len] == L'\\')
wcscat_s(szIniFile, L".ini");
else
wcscpy_s(&szIniFile[len], sizeof(szIniFile) - len, L".ini");
wcscpy_s(&szIniFile[len], _countof(szIniFile) - len, L".ini");
HINSTANCE hInst;
const char* szLib;
@ -722,7 +722,7 @@ BRIDGE_IMPEXP duint DbgGetBranchDestination(duint addr)
/**
* \brief Loads a script.
*
* \param [in] filename
* \param [in] filename
*/
BRIDGE_IMPEXP void DbgScriptLoad(const char* filename)
{
@ -821,7 +821,7 @@ BRIDGE_IMPEXP SCRIPTLINETYPE DbgScriptGetLineType(int line)
/**
* \brief Sets the current script's instruction pointer, i.e. a
* line that should be executed next.
* line that should be executed next.
*
* \param [in] line The line.
*/

View File

@ -37,7 +37,7 @@ extern "C"
//Bridge defines
#define MAX_SETTING_SIZE 65536
#define DBG_VERSION 22
#define DBG_VERSION 23
//Bridge functions
BRIDGE_IMPEXP const char* BridgeInit();
@ -369,39 +369,134 @@ typedef struct
typedef struct
{
duint cax;
duint ccx;
duint cdx;
duint cbx;
duint csp;
duint cbp;
duint csi;
duint cdi;
bool FZ;
bool PM;
bool UM;
bool OM;
bool ZM;
bool IM;
bool DM;
bool DAZ;
bool PE;
bool UE;
bool OE;
bool ZE;
bool DE;
bool IE;
unsigned short RC;
} MXCSRFIELDS;
typedef struct
{
bool B;
bool C3;
bool C2;
bool C1;
bool C0;
bool IR;
bool SF;
bool P;
bool U;
bool O;
bool Z;
bool D;
bool I;
unsigned short TOP;
} X87STATUSWORDFIELDS;
typedef struct
{
bool IC;
bool IEM;
bool PM;
bool UM;
bool OM;
bool ZM;
bool DM;
bool IM;
unsigned short RC;
unsigned short PC;
} X87CONTROLWORDFIELDS;
typedef struct
{
BYTE data[10];
int st_value;
int tag;
} X87FPUREGISTER;
typedef struct
{
WORD ControlWord;
WORD StatusWord;
WORD TagWord;
DWORD ErrorOffset;
DWORD ErrorSelector;
DWORD DataOffset;
DWORD DataSelector;
DWORD Cr0NpxState;
} X87FPU;
typedef struct
{
ULONG_PTR cax;
ULONG_PTR ccx;
ULONG_PTR cdx;
ULONG_PTR cbx;
ULONG_PTR csp;
ULONG_PTR cbp;
ULONG_PTR csi;
ULONG_PTR cdi;
#ifdef _WIN64
duint r8;
duint r9;
duint r10;
duint r11;
duint r12;
duint r13;
duint r14;
duint r15;
ULONG_PTR r8;
ULONG_PTR r9;
ULONG_PTR r10;
ULONG_PTR r11;
ULONG_PTR r12;
ULONG_PTR r13;
ULONG_PTR r14;
ULONG_PTR r15;
#endif //_WIN64
duint cip;
unsigned int eflags;
FLAGS flags;
ULONG_PTR cip;
ULONG_PTR eflags;
unsigned short gs;
unsigned short fs;
unsigned short es;
unsigned short ds;
unsigned short cs;
unsigned short ss;
duint dr0;
duint dr1;
duint dr2;
duint dr3;
duint dr6;
duint dr7;
ULONG_PTR dr0;
ULONG_PTR dr1;
ULONG_PTR dr2;
ULONG_PTR dr3;
ULONG_PTR dr6;
ULONG_PTR dr7;
BYTE RegisterArea[80];
X87FPU x87fpu;
DWORD MxCsr;
#ifdef _WIN64
M128A XmmRegisters[16];
BYTE YmmRegisters[32 * 16];
#else // x86
M128A XmmRegisters[8];
BYTE YmmRegisters[32 * 8];
#endif
} REGISTERCONTEXT;
typedef struct
{
REGISTERCONTEXT regcontext;
FLAGS flags;
X87FPUREGISTER x87FPURegisters[8];
unsigned long long mmx[8];
MXCSRFIELDS MxCsrFields;
X87STATUSWORDFIELDS x87StatusWordFields;
X87CONTROLWORDFIELDS x87ControlWordFields;
} REGDUMP;
typedef struct

View File

@ -2070,7 +2070,8 @@ CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::AddEntry(
{
DeleteString(a_pComment);
a_pComment = pComment;
CopyString(a_pComment);
rc = CopyString(a_pComment);
if(rc < 0) return rc;
}
Delete(a_pSection, a_pKey);
iKey = keyval.end();

View File

@ -59,6 +59,7 @@
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>MaxSpeed</Optimization>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>

View File

@ -8,6 +8,15 @@
#endif
#include <windows.h>
#include <stdint.h>
#ifdef __GNUC__
typedef struct DECLSPEC_ALIGN(16) _M128A
{
ULONGLONG Low;
LONGLONG High;
} M128A, *PM128A;
#endif //__GNUC__
#pragma pack(push, 1)
@ -26,6 +35,9 @@
#define UE_STRUCT_HOOK_ENTRY 11
#define UE_STRUCT_FILE_STATUS_INFO 12
#define UE_STRUCT_FILE_FIX_INFO 13
#define UE_STRUCT_X87FPUREGISTER 14
#define UE_STRUCT_X87FPU 15
#define UE_STRUCT_TITAN_ENGINE_CONTEXT 16
#define UE_ACCESS_READ 0
#define UE_ACCESS_WRITE 1
@ -252,6 +264,70 @@
#define UE_SEG_DS 40
#define UE_SEG_CS 41
#define UE_SEG_SS 42
#define UE_x87_r0 43
#define UE_x87_r1 44
#define UE_x87_r2 45
#define UE_x87_r3 46
#define UE_x87_r4 47
#define UE_x87_r5 48
#define UE_x87_r6 49
#define UE_x87_r7 50
#define UE_X87_STATUSWORD 51
#define UE_X87_CONTROLWORD 52
#define UE_X87_TAGWORD 53
#define UE_MXCSR 54
#define UE_MMX0 55
#define UE_MMX1 56
#define UE_MMX2 57
#define UE_MMX3 58
#define UE_MMX4 59
#define UE_MMX5 60
#define UE_MMX6 61
#define UE_MMX7 62
#define UE_XMM0 63
#define UE_XMM1 64
#define UE_XMM2 65
#define UE_XMM3 66
#define UE_XMM4 67
#define UE_XMM5 68
#define UE_XMM6 69
#define UE_XMM7 70
#define UE_XMM8 71
#define UE_XMM9 72
#define UE_XMM10 73
#define UE_XMM11 74
#define UE_XMM12 75
#define UE_XMM13 76
#define UE_XMM14 77
#define UE_XMM15 78
#define UE_x87_ST0 79
#define UE_x87_ST1 80
#define UE_x87_ST2 81
#define UE_x87_ST3 82
#define UE_x87_ST4 83
#define UE_x87_ST5 84
#define UE_x87_ST6 85
#define UE_x87_ST7 86
#define UE_YMM0 87
#define UE_YMM1 88
#define UE_YMM2 89
#define UE_YMM3 90
#define UE_YMM4 91
#define UE_YMM5 92
#define UE_YMM6 93
#define UE_YMM7 94
#define UE_YMM8 95
#define UE_YMM9 96
#define UE_YMM10 97
#define UE_YMM11 98
#define UE_YMM12 99
#define UE_YMM13 100
#define UE_YMM14 101
#define UE_YMM15 102
#ifndef CONTEXT_EXTENDED_REGISTERS
#define CONTEXT_EXTENDED_REGISTERS 0
#endif
typedef struct
{
@ -518,6 +594,77 @@ typedef struct
DWORD OriginalCOMTableSize;
} FILE_FIX_INFO, *PFILE_FIX_INFO;
typedef struct
{
M128A Low; //XMM/SSE part
M128A High; //AVX part
} YmmRegister_t;
typedef struct
{
BYTE data[10];
int st_value;
int tag;
} x87FPURegister_t;
typedef struct
{
WORD ControlWord;
WORD StatusWord;
WORD TagWord;
DWORD ErrorOffset;
DWORD ErrorSelector;
DWORD DataOffset;
DWORD DataSelector;
DWORD Cr0NpxState;
} x87FPU_t;
typedef struct
{
ULONG_PTR cax;
ULONG_PTR ccx;
ULONG_PTR cdx;
ULONG_PTR cbx;
ULONG_PTR csp;
ULONG_PTR cbp;
ULONG_PTR csi;
ULONG_PTR cdi;
#ifdef _WIN64
ULONG_PTR r8;
ULONG_PTR r9;
ULONG_PTR r10;
ULONG_PTR r11;
ULONG_PTR r12;
ULONG_PTR r13;
ULONG_PTR r14;
ULONG_PTR r15;
#endif //_WIN64
ULONG_PTR cip;
ULONG_PTR eflags;
unsigned short gs;
unsigned short fs;
unsigned short es;
unsigned short ds;
unsigned short cs;
unsigned short ss;
ULONG_PTR dr0;
ULONG_PTR dr1;
ULONG_PTR dr2;
ULONG_PTR dr3;
ULONG_PTR dr6;
ULONG_PTR dr7;
BYTE RegisterArea[80];
x87FPU_t x87fpu;
DWORD MxCsr;
#ifdef _WIN64
M128A XmmRegisters[16];
YmmRegister_t YmmRegisters[16];
#else // x86
M128A XmmRegisters[8];
YmmRegister_t YmmRegisters[8];
#endif
} TITAN_ENGINE_CONTEXT_t;
#ifdef __cplusplus
extern "C"
{
@ -696,11 +843,17 @@ __declspec(dllexport) bool TITCALL SetMemoryBPX(ULONG_PTR MemoryStart, SIZE_T Si
__declspec(dllexport) bool TITCALL SetMemoryBPXEx(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory, DWORD BreakPointType, bool RestoreOnHit, LPVOID bpxCallBack);
__declspec(dllexport) bool TITCALL RemoveMemoryBPX(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory);
__declspec(dllexport) bool TITCALL GetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea);
__declspec(dllexport) void TITCALL Getx87FPURegisters(x87FPURegister_t x87FPURegisters[8], TITAN_ENGINE_CONTEXT_t* titcontext);
__declspec(dllexport) void TITCALL GetMMXRegisters(uint64_t mmx[8], TITAN_ENGINE_CONTEXT_t* titcontext);
__declspec(dllexport) bool TITCALL GetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext);
__declspec(dllexport) bool TITCALL SetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext);
__declspec(dllexport) ULONG_PTR TITCALL GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister);
__declspec(dllexport) ULONG_PTR TITCALL GetContextData(DWORD IndexOfRegister);
__declspec(dllexport) bool TITCALL SetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea);
__declspec(dllexport) bool TITCALL SetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister, ULONG_PTR NewRegisterValue);
__declspec(dllexport) bool TITCALL SetContextData(DWORD IndexOfRegister, ULONG_PTR NewRegisterValue);
__declspec(dllexport) bool TITCALL GetAVXContext(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext);
__declspec(dllexport) bool TITCALL SetAVXContext(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext);
__declspec(dllexport) void TITCALL ClearExceptionNumber();
__declspec(dllexport) long TITCALL CurrentExceptionNumber();
__declspec(dllexport) bool TITCALL MatchPatternEx(HANDLE hProcess, void* MemoryToCheck, int SizeOfMemoryToCheck, void* PatternToMatch, int SizeOfPatternToMatch, PBYTE WildCard);

View File

@ -1,50 +0,0 @@
/**
* UTF8 string library.
*
* Allows to use native UTF8 sequences as a string class. Has many overloaded
* operators that provides such features as concatenation, types converting and
* much more.
*
* Distributed under GPL v3
*
* Author:
* Grigory Gorelov (gorelov@grigory.info)
* See more information on grigory.info
*/
#include "Exception.h"
UTF8::Exception::Exception(const std::string & error, const int & StatusCode)
{
this->error = error;
this->StatusCode = StatusCode;
}
UTF8::Exception::Exception(std::string error)
{
this->error = error;
this->StatusCode = UnspecifiedException;
}
UTF8::Exception::Exception(const UTF8::Exception & e)
{
error = e.error;
StatusCode = e.StatusCode;
}
std::string UTF8::Exception::GetErrorString() const
{
return error;
}
int UTF8::Exception::GetErrorCode() const
{
return StatusCode;
}
UTF8::Exception & UTF8::Exception::operator =(const UTF8::Exception & e)
{
error = e.error;
error = e.StatusCode;
return *this;
}

View File

@ -1,64 +0,0 @@
/**
* UTF8 string library.
*
* Allows to use native UTF8 sequences as a string class. Has many overloaded
* operators that provides such features as concatenation, types converting and
* much more.
*
* Distributed under GPL v3
*
* Author:
* Grigory Gorelov (gorelov@grigory.info)
* See more information on grigory.info
*/
#ifndef _UTF8_Exception_H
#define _UTF8_Exception_H
#include <string>
namespace UTF8
{
/**
* Exception class. When something bad happens it is thowed by UTF8::String.
*/
class Exception
{
public:
enum
{
UnspecifiedException = 1,
StringToIntConversionError = 2,
StringToDoubleConversionError = 3,
FileNotFound = 4,
StringIsNotACharacter = 5
};
/**
* Just a constructor
*/
Exception(std::string error);
/// Just a constructor
Exception(const std::string & error, const int & StatusCode);
/// Copying constructor
Exception(const Exception & e);
/// Returns error string
std::string GetErrorString() const;
/// Returns error code
int GetErrorCode() const;
/// Assing operator
Exception & operator =(const Exception &);
private:
std::string error;
int StatusCode;
};
}
#endif /* _EXCEPTION_H */

View File

@ -1,882 +0,0 @@
/**
* UTF8 string library.
*
* Allows to use native UTF8 sequences as a string class. Has many overloaded
* operators that provides such features as concatenation, types converting and
* much more.
*
* Distributed under GPL v3
*
* Author:
* Grigory Gorelov (gorelov@grigory.info)
* See more information on grigory.info
*/
#include "String.h"
#include <string>
#include <sstream>
#include <iostream>
#include <stdlib.h>
#include <ostream>
#include <stdint.h>
#include <errno.h>
#include "Exception.h"
bool UTF8::String::HasThisString(const UTF8::String & Str) const
{
return GetSubstringPosition(Str) != -1;
}
bool UTF8::String::CharacterIsOneOfThese(const UTF8::String & Characters) const
{
if(Length() == 1)
{
for(unsigned int i = 0; i < Characters.Length(); i++)
{
if(Characters[i] == *this)
{
return true;
}
}
return false;
}
else
{
throw Exception("[CharacterIsOneOfThese] String is more then one character length: \"" + ToString() + "\"", UTF8::Exception::StringIsNotACharacter);
}
}
UTF8::String UTF8::String::FromFile(const UTF8::String & Path)
{
UTF8::String s;
std::ifstream File;
File.open(Path.ToConstCharPtr());
if(File.is_open())
{
File.seekg(0, std::ios::end);
size_t Length = (size_t)File.tellg();
File.seekg(0, std::ios::beg);
char* buf = new char[Length + 1];
memset(buf, 0, Length + 1);
File.read(buf, Length);
s.AppendString(buf);
delete buf;
}
else
{
throw Exception("Cannot open file \"" + Path.ToString() + "\"", UTF8::Exception::FileNotFound);
}
File.close();
return s;
}
long UTF8::String::Search(const UTF8::String & SubString, unsigned int StartPosition, int Direction) const
{
unsigned int SubstringLength = SubString.Length();
unsigned int n = StartPosition;
if(n > Length() - SubstringLength)
{
if(Direction == SearchDirectionFromLeftToRight)
{
return -1;
}
else
{
n = Length() - SubstringLength;
}
}
if(n < 0)
{
if(Direction == SearchDirectionFromRightToLeft)
{
return -1;
}
else
{
n = 0;
}
}
while(((Direction == SearchDirectionFromLeftToRight) && (n < Length() - SubstringLength + 1)) || ((Direction == SearchDirectionFromRightToLeft) && (n >= 0)))
{
if(this->Substring(n, SubstringLength) == SubString)
{
return n;
}
n += Direction == SearchDirectionFromLeftToRight ? 1 : -1;
}
return -1;
}
std::ostream & operator<<(std::ostream & os, const UTF8::String & s)
{
os << s.ToString();
return os;
}
bool operator==(const char* str, const UTF8::String & StringObj)
{
return StringObj == str;
}
bool operator==(const std::string & str, const UTF8::String & StringObj)
{
return StringObj == str;
}
bool operator!=(const char* str, const UTF8::String & StringObj)
{
return StringObj != str;
}
bool operator!=(const std::string & str, const UTF8::String & StringObj)
{
return StringObj != str;
}
UTF8::String UTF8::String::Quote() const
{
return "\"" + (*this) + "\"";
}
UTF8::String UTF8::String::Trim() const
{
UTF8::String result = *this;
unsigned int i = 0;
while((result[i] == " ") || (result[i] == "\n") || (result[i] == "\r") || (result[i] == "\t"))
{
i++;
}
if(i == result.Length())
{
return UTF8::String();
}
long j = result.Length();
while((result[j - 1] == " ") || (result[j - 1] == "\n") || (result[j - 1] == "\r") || (result[j - 1] == "\t"))
{
j--;
}
result = result.Substring(i, j - i);
return result;
}
UTF8::String UTF8::String::Replace(const UTF8::String & Search, const UTF8::String & Replace) const
{
UTF8::String result = *this;
// Long to cover unsigned int and -1
long pos = 0;
while((pos = result.Search(Search, pos)) != -1)
{
result = result.SubstringReplace(pos, Search.Length(), Replace);
// Next time we search after replacement
pos += Replace.Length();
}
return result;
}
UTF8::String UTF8::String::SubstringReplace(unsigned int Start, unsigned int Count, const UTF8::String & Replace) const
{
if(Start < Length())
{
return (Start ? Substring(0, Start) : UTF8::String()) + Replace + Substring(Start + Count);
}
else
{
return *this;
}
}
UTF8::String UTF8::String::Implode(const std::vector <UTF8::String> & Strings, const UTF8::String & Separator)
{
if(Strings.size())
{
UTF8::String Result;
for(unsigned int i = 0; i < Strings.size(); i++)
{
if(Result.Length())
{
Result += Separator;
}
Result += Strings[i];
}
return Result;
}
else
{
return UTF8::String();
}
}
std::vector <UTF8::String> UTF8::String::Explode(const String & Separator) const
{
std::vector <UTF8::String> v;
unsigned int prev = 0;
unsigned int i = 0;
while(i < Length() - Separator.Length() + 1)
{
if(Substring(i, Separator.Length()) == Separator)
{
if(i - prev > 0)
{
v.push_back(Substring(prev, i - prev));
}
i += Separator.Length();
prev = i;
}
else
{
i++;
}
}
if(prev < Length())
{
v.push_back(Substring(prev, Length() - prev));
}
return v;
}
UTF8::String operator+(const char* CharPtr, const UTF8::String & StringObj)
{
UTF8::String s(CharPtr);
s += StringObj;
return s;
}
UTF8::String operator+(const std::string & str, const UTF8::String & StringObj)
{
UTF8::String s(str);
s += StringObj;
return s;
}
UTF8::String UTF8::String::operator+(const UTF8::String & s) const
{
UTF8::String res(*this);
res.AppendString(s.Data);
return res;
}
UTF8::String & UTF8::String::operator+=(const UTF8::String & s)
{
AppendString(s.Data);
return *this;
}
void UTF8::String::AppendString(const char* str)
{
// The functions that can fill buffer directly:
//
// SetString AppendString
//
// Make sure all preparations are done there
if(str && strlen(str))
{
if(DataArrayLength)
{
CheckIfStringIsCorrect(str);
unsigned int StrLength = (unsigned int)strlen(str);
Data = (char*) realloc(Data, DataArrayLength + StrLength + 1);
if(Data != NULL)
{
memcpy(Data + DataArrayLength, str, StrLength);
DataArrayLength += StrLength;
Data[DataArrayLength] = 0;
CalculateStringLength();
}
else
{
throw Exception("[AppendString] Cannot realloc any more memory");
}
}
else
{
SetString(str);
}
}
}
void UTF8::String::SetString(const char* str)
{
// The functions that can fill buffer directly:
//
// SetString AppendString
//
// Make sure all preparations are done there
if(str && strlen(str))
{
CheckIfStringIsCorrect(str);
Empty();
DataArrayLength = (unsigned int)strlen(str);
Data = new char[DataArrayLength + 1];
Data[DataArrayLength] = 0;
memcpy(Data, str, DataArrayLength);
CalculateStringLength();
}
else
{
Empty();
}
}
void UTF8::String::ConvertFromInt64(int64_t n)
{
Empty();
if(n)
{
bool minus;
if(n < 0)
{
n = -n;
minus = true;
}
else
{
minus = false;
}
char tmp[32] = "0";
const char* num = "0123456789";
memset(tmp, 0, 32);
unsigned int i = 30;
while(n)
{
tmp[i] = num[n % 10];
n /= 10;
i--;
if((i < 0) || ((i < 1) && minus))
{
throw Exception("[ConvertFromInt] Cycle terminated, buffer overflow.");
}
}
if(minus)
{
tmp[i] = '-';
i--;
}
SetString(tmp + i + 1);
}
else
{
SetString("0");
}
CalculateStringLength();
}
void UTF8::String::InitString()
{
Data = NULL;
DataArrayLength = 0;
StringLength = 0;
}
UTF8::String::String()
{
InitString();
}
UTF8::String::String(const std::string & s)
{
InitString();
CheckIfStringIsCorrect(s.c_str());
AppendString(s.c_str());
CalculateStringLength();
}
int UTF8::String::GetSymbolIndexInDataArray(unsigned int Position) const
{
if(Position >= StringLength)
{
throw Exception(UTF8::String("[GetSymbolIndexInDataArray] trying to get position beyond the end of string."));
}
unsigned int n = 0;
for(unsigned int i = 0; i < Position; i++)
{
n += GetSequenceLength(Data + n);
}
return n;
}
long UTF8::String::GetSubstringPosition(const UTF8::String & SubString, unsigned int Start) const
{
if(SubString.Length() > StringLength)
{
return -1;
}
unsigned int ScansCount = StringLength - SubString.StringLength + 1 - Start;
for(unsigned int i = 0; i < ScansCount; i++)
{
if(this->Substring(i + Start, SubString.StringLength) == SubString)
{
return i + Start;
}
}
return -1;
}
UTF8::String UTF8::String::Substring(unsigned int Start, unsigned int Count) const
{
if(Start >= StringLength)
{
return UTF8::String();
}
if((Start + Count > StringLength) || (Count == 0))
{
Count = StringLength - Start;
}
unsigned int StartIndex = GetSymbolIndexInDataArray(Start);
unsigned int CopyAmount = 0;
for(unsigned int i = 0; i < Count; i++)
{
CopyAmount += GetSequenceLength(Data + StartIndex + CopyAmount);
}
char* tmp = new char[CopyAmount + 1];
memcpy(tmp, Data + StartIndex, CopyAmount);
tmp[CopyAmount] = 0;
UTF8::String r(tmp);
delete tmp;
return r;
}
UTF8::String::String(const char* str)
{
InitString();
SetString(str);
}
UTF8::String::String(const uint32_t* str)
{
InitString();
ConvertFromUTF32(str);
}
void UTF8::String::ConvertFromUTF32(const uint32_t* s)
{
if(s)
{
unsigned int WideStringLength = 0;
do
{
WideStringLength++;
if(WideStringLength == 4294967295UL)
{
throw Exception("[ConvertFromUTF32] Cannot find termination symbol in incoming string.");
}
}
while(s[WideStringLength]);
char* tmp = new char[WideStringLength * 4 + 1];
memset(tmp, 0, WideStringLength * 4 + 1);
unsigned int pos = 0;
for(unsigned int i = 0; i < WideStringLength; i++)
{
uint32_t wc = s[i];
if(wc < 0x80)
{
tmp[pos++] = wc;
}
else if(wc < 0x800)
{
tmp[pos++] = (wc >> 6) | 0xC0 /* 0b11000000 */;
tmp[pos++] = (wc & 0x3F /* 0b00111111 */) | 0x80 /* 0b10000000 */;
}
else if(wc < 0x10000)
{
tmp[pos++] = (wc >> 12) | 0xE0 /* 0b11100000 */;
tmp[pos++] = ((wc >> 6) & 0x3F /* 0b00111111 */) | 0x80 /* 0b10000000 */;
tmp[pos++] = (wc & 0x3F /* 0b00111111 */) | 0x80 /* 0b10000000 */;
}
else
{
tmp[pos++] = (wc >> 18) | 0xF0 /* 0b11110000 */;
tmp[pos++] = ((wc >> 12) & 0x3F /* 0b00111111 */) | 0x80 /* 0b10000000 */;
tmp[pos++] = ((wc >> 6) & 0x3F /* 0b00111111 */) | 0x80 /* 0b10000000 */;
tmp[pos++] = (wc & 0x3F /* 0b00111111 */) | 0x80 /* 0b10000000 */;
}
}
SetString(tmp);
delete tmp;
}
}
void UTF8::String::CalculateStringLength()
{
// We are not writing anything to memory so limits are not needed
if(Data)
{
unsigned int n = 0, count = 0;
do
{
// We do not need to check line end here, it is checked when string is changed
n += GetSequenceLength(Data + n);
count++;
}
while(Data[n]);
StringLength = count;
}
else
{
StringLength = 0;
}
}
void UTF8::String::CheckIfStringIsCorrect(const char* str) const
{
if(str)
{
// We are not writing anything to memory so limits are not needed
unsigned int n = 0, i;
unsigned int SequenceLength;
while(str[n])
{
SequenceLength = GetSequenceLength(str + n);
for(i = 1; i < SequenceLength; i++)
{
if((((unsigned char) str[n + i]) >> 6) != 0x2 /* 0b00000010 */)
{
std::string s(str);
throw Exception("[CheckIfStringIsCorrect] Incorrect byte in UTF8 sequence: \"" + s + "\"");
}
}
n += SequenceLength;
if(n >= 0xFFFFFFFF - 4)
{
std::string s(str);
throw Exception("[CheckIfStringIsCorrect] termination char was not found in string: \"" + s + "\"");
}
}
}
}
bool UTF8::String::operator>(const UTF8::String & s) const
{
if(*this == s)
{
return false;
}
if(*this < s)
{
return false;
}
return true;
}
bool UTF8::String::operator<(const UTF8::String & s) const
{
unsigned int MinLength = StringLength < s.StringLength ? StringLength : s.StringLength;
//std::cout << "MinLength=" << MinLength;
unsigned int MyPos = 0, RemotePos = 0;
unsigned int MySequenceLength, RemoteSequenceLength;
for(unsigned int i = 0; i < MinLength; i++)
{
MySequenceLength = GetSequenceLength(Data + MyPos);
RemoteSequenceLength = GetSequenceLength(s.Data + RemotePos);
if(MySequenceLength < RemoteSequenceLength)
{
return true;
}
if(MySequenceLength > RemoteSequenceLength)
{
return false;
}
for(unsigned int j = 0; j < MySequenceLength; j++)
{
if(Data[MyPos + j] < s.Data[RemotePos + j])
{
return true;
}
if(Data[MyPos + j] > s.Data[RemotePos + j])
{
return false;
}
}
MyPos += MySequenceLength;
RemotePos += RemoteSequenceLength;
}
// If this string is substring of s (from left side) then it is lower
return StringLength < s.StringLength;
}
UTF8::String UTF8::String::operator[](unsigned int const n) const
{
if(n >= StringLength)
{
return UTF8::String();
}
if(n < 0)
{
return UTF8::String();
}
unsigned int pos = 0;
for(unsigned int i = 0; i < n; i++)
{
pos += GetSequenceLength(Data + pos);
}
char t[5];
memset(t, 0, 5);
memcpy(t, Data + pos, GetSequenceLength(Data + pos));
return UTF8::String(t);
}
unsigned int UTF8::String::GetSequenceLength(const char* StartByte) const
{
if(StartByte && strlen(StartByte))
{
unsigned char Byte = StartByte[0];
if(Byte < 128)
{
return 1;
}
// Here we need back order due to mask operation
if((Byte >> 5) == 0x6 /* 0b00000110 */)
{
return 2;
}
if((Byte >> 4) == 0xE /* 0b00001110 */)
{
return 3;
}
if((Byte >> 3) == 0x1E /* 0b00011110 */)
{
return 4;
}
throw Exception(std::string("[GetSequenceLength] Invalid UTF8 start byte. My own string is: [") + Data + "] Argument is: [" + StartByte + "]");
}
else
{
throw Exception(std::string("[GetSequenceLength] Invalid UTF8 start byte (it is empty). My own string is: [") + Data + "] Argument is: [" + StartByte + "]");
}
}
UTF8::String & UTF8::String::operator=(const String & Original)
{
// Check if objects are not same
if((unsigned int long) &Original != (unsigned int long) this)
{
Empty();
SetString(Original.Data);
}
return *this;
}
UTF8::String & UTF8::String::operator=(const char* str)
{
Empty();
SetString(str);
return *this;
}
UTF8::String & UTF8::String::operator=(const uint32_t* str)
{
Empty();
ConvertFromUTF32(str);
return *this;
}
UTF8::String::operator std::string() const
{
return this->ToString();
}
void UTF8::String::Empty()
{
if(DataArrayLength)
{
delete Data;
InitString();
}
}
std::string UTF8::String::ToString() const
{
if(DataArrayLength)
{
return std::string(Data);
}
else
{
return std::string();
}
}
UTF8::String UTF8::String::operator+(const char* s) const
{
UTF8::String res(*this);
res.AppendString(s);
return res;
}
bool UTF8::String::operator==(const UTF8::String & s) const
{
if(DataArrayLength != s.DataArrayLength)
{
return false;
}
else
{
for(unsigned int i = 0; i < DataArrayLength; i++)
{
if(Data[i] != s.Data[i])
{
return false;
}
}
return true;
}
}
bool UTF8::String::operator!=(const UTF8::String & s) const
{
return !(*this == s);
}
bool UTF8::String::operator==(const char* str) const
{
if(str && strlen(str))
{
if(DataArrayLength != strlen(str))
{
return false;
}
else
{
for(unsigned int i = 0; i < DataArrayLength; i++)
{
if(Data[i] != str[i])
{
return false;
}
}
return true;
}
}
else
{
return StringLength == 0;
}
}
bool UTF8::String::operator!=(const char* str) const
{
return !(*this == str);
}
const char* UTF8::String::ToConstCharPtr() const
{
return Data;
}
const char* UTF8::String::c_str() const
{
return Data;
}
unsigned int UTF8::String::Length() const
{
return StringLength;
}
unsigned int UTF8::String::DataLength() const
{
return DataArrayLength;
}
UTF8::String::~String()
{
Empty();
}
UTF8::String::String(const String & orig)
{
InitString();
SetString(orig.Data);
}

View File

@ -1,309 +0,0 @@
/**
* UTF8 string library.
*
* Allows to use native UTF8 sequences as a string class. Has many overloaded
* operators that provides such features as concatenation, types converting and
* much more.
*
* Distributed under GPL v3
*
* Author:
* Grigory Gorelov (gorelov@grigory.info)
* See more information on grigory.info
*/
#ifndef _UTF8_String_H
#define _UTF8_String_H
#include "Exception.h"
#include <string.h>
#include <stdint.h>
#include <fstream>
#include <vector>
namespace UTF8
{
/**
* The only string class containing everything to work with UTF8 strings
*/
class String
{
public:
static const int SearchDirectionFromLeftToRight = 1;
static const int SearchDirectionFromRightToLeft = 2;
/**
* Search substring in string
* @param StartPosition Position to start search
* @param Direction Search forward or backward, uses SearchDirectionFromLeftToRight and SearchDirectionFromRightToLeft
* @return Returns position of substring if found. Otherwise returns -1
*/
long Search(const UTF8::String & SubString, unsigned int StartPosition = 0, int Direction = SearchDirectionFromLeftToRight) const;
/// Simple constructor only initiates buffers
String();
/**
* Create string object from UTF8 char * string
*/
String(const char* str);
/**
* Create string object from UTF-32 string
*/
String(const uint32_t*);
/**
* Create string object from UTF8 std::string
*/
String(const std::string &);
/**
* Copying constructor. Feel free to such things UTF8::String s2=s1;
*/
String(const String & orig);
/**
* Deconstructor.
*/
~String();
/**
* Converts UTF8::String to std::string
*/
std::string ToString() const;
/**
* Reads content from a file and returns as UTF8::String
*/
static String FromFile(const UTF8::String & Path);
/**
* Converts UTF8::String to const char *
*/
const char* ToConstCharPtr() const;
/**
* Converts UTF8::String to const char *
*/
const char* c_str() const;
/**
* Separates string using given separator and returns vector
*/
std::vector <String> Explode(const String & Separator) const;
/**
* Creating String from array of String adding separator between them.
*/
static String Implode(const std::vector <String> & Strings, const String & Separator);
/**
* Sum operator. Provides String1+String2 exression.
*/
String operator+(const String &) const;
/**
* Sum operator. Provides String1+"Str" exression.
*/
String operator+(const char*) const;
/**
* Unary sum operator. Provides String1+=String2 expression.
*/
String & operator+=(const String &);
/**
* Assign operator. Provides String1=String2 expression.
*/
String & operator=(const String &);
/**
* Assign operator. Provides String1="New value" expression.
*/
String & operator=(const char*);
/**
* Assign operator. Provides String1=(uint32_t*) UTF32_StringPointer expression.
* Automatically converts UNICODE to UTF-8 ans stores in itself
*/
String & operator=(const uint32_t*);
/**
* Provides std::string test=String expression.
*/
operator std::string() const;
/**
* Returns substring of current string.
* @param Start Start position of substring
* @param Count Number of sybmols after start position. If number==0 string from Start till end is returned.
*/
String Substring(unsigned int Start, unsigned int Count = 0) const;
/**
* Replaces one text peace by another and returns result
* @param Search Search string
* @param Replace Replace string
* @return Returns result of replacement
*/
String Replace(const String & Search, const String & Replace) const;
/**
* Returns trimmed string. Removes whitespaces from left and right
*/
String Trim() const;
/**
* Returns string with nice quotes like this « ».
*/
String Quote() const;
/**
* Replaces region of string by text peace and returns result.
* @param Search Search string
* @param Replace Replace string
* @return Returns result of replacement
*/
String SubstringReplace(unsigned int Start, unsigned int Count, const String & Replace) const;
/**
* Returns position of substring in current string.
* @param Start Position to start search. Default is 0.
* @return If substring not found returns -1.
*/
long GetSubstringPosition(const UTF8::String & SubString, unsigned int Start = 0) const;
/**
* Get one char operator. Provides UTF8::String c=String1[1];
*/
String operator[](unsigned int const) const;
/**
* Test operator. Provides String1==String2 expression.
*/
bool operator==(const UTF8::String &) const;
/**
* Test operator. Provides String1!=String2 expression.
*/
bool operator!=(const UTF8::String &) const;
/**
* Test operator. Provides String1=="Test" expression.
*/
bool operator==(const char*) const;
/**
* Test operator. Provides String1!="Test" expression.
*/
bool operator!=(const char*) const;
/** Test operator. Provides String1<String2 expression.
* Operator compares left characters of two strings.
* If String1[0] value is less then the String2[0] returns true.
* If they are equal then goes to second character and so on.
* Can be used to sort strings alphabetical.
*/
bool operator<(const UTF8::String &) const;
/** Test operator. Provides String1>String2 expression.
* Operator compares left characters of two strings.
* If String1[0] value is greater then the String2[0] returns true.
* If they are equal then goes to second character and so on.
* Can be used to sort strings alphabetical.
*/
bool operator>(const UTF8::String &) const;
/**
* Returns current string length. Also see DataLength to get buffer
* size
*/
unsigned int Length() const;
/**
* Returns current char data array length, containig UTF8 string.
* As one character in UTF8 can be stored by more then one byte use
* this function to know how much memory allocated for the string.
*/
unsigned int DataLength() const;
/**
* Clears current string as if it is just created
*/
void Empty();
/**
* If string is a one character check if it is one of given
*/
bool CharacterIsOneOfThese(const UTF8::String & Characters) const;
/**
* Checks if this string contains given another string
*/
bool HasThisString(const UTF8::String & Str) const;
/**
* Special function to convert from very big integers
* Normally it is ok to assing UTF8::String to number. Or construct from it.
* This function exists only for very very big integers conversion.
*/
void ConvertFromInt64(int64_t n);
private:
char* Data;
unsigned int DataArrayLength;
unsigned int StringLength;
unsigned int GetSequenceLength(const char* StartByte) const;
void CheckIfStringIsCorrect(const char* str) const;
void CalculateStringLength();
void InitString();
void AppendString(const char* str);
void SetString(const char* str);
int GetSymbolIndexInDataArray(unsigned int Position) const;
void ConvertFromUTF32(const uint32_t*);
};
}
/**
* Not in class overloaded operator +. Provides "Sample"+String1 expression.
*/
UTF8::String operator+(const char*, const UTF8::String &);
/**
* Not in class overloaded operator +. Provides std::string("123")+String1 expression.
*/
UTF8::String operator+(const std::string &, const UTF8::String &);
/**
* Not in class overloaded operator ==. Provides "Test"==String1 expression.
*/
bool operator==(const char*, const UTF8::String &);
/**
* Not in class overloaded operator ==. Provides std::string==String1 expression.
*/
bool operator==(const std::string &, const UTF8::String &);
/**
* Not in class overloaded operator !=. Provides "Test"!=String1 expression.
*/
bool operator!=(const char*, const UTF8::String &);
/**
* Not in class overloaded operator !=. Provides std::string!=String1 expression.
*/
bool operator!=(const std::string &, const UTF8::String &);
/**
* Overloading for cout. Provides std::cout << (UTF8::String) operation;
*/
std::ostream & operator<<(std::ostream & os, const UTF8::String & s);
#endif /* _UTF8STRING_H */

View File

@ -1,29 +0,0 @@
#include "UString.h"
#include <windows.h>
//Functions taken from: http://www.nubaria.com/en/blog/?p=289
UString ConvertUtf16ToUtf8(const std::wstring & wstr)
{
std::string convertedString;
int requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, 0, 0, 0, 0);
if(requiredSize > 0)
{
std::vector<char> buffer(requiredSize);
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &buffer[0], requiredSize, 0, 0);
convertedString.assign(buffer.begin(), buffer.end() - 1);
}
return convertedString;
}
std::wstring ConvertUtf8ToUtf16(const UString & str)
{
std::wstring convertedString;
int requiredSize = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, 0, 0);
if(requiredSize > 0)
{
std::vector<wchar_t> buffer(requiredSize);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &buffer[0], requiredSize);
convertedString.assign(buffer.begin(), buffer.end() - 1);
}
return convertedString;
}

View File

@ -1,12 +0,0 @@
#ifndef _USTRING_H
#define _USTRING_H
#include "String.h"
#include <string>
typedef UTF8::String UString;
UString ConvertUtf16ToUtf8(const std::wstring & wstr);
std::wstring ConvertUtf8ToUtf16(const UString & str);
#endif // _USTRING_H

View File

@ -201,12 +201,12 @@ static bool _patchrestore(duint addr)
static int _modpathfromaddr(duint addr, char* path, int size)
{
Memory<wchar_t*> wszModPath(size * sizeof(wchar_t), "_modpathfromaddr:wszModPath");
if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)addr, wszModPath, size))
if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbasefromaddr(addr), wszModPath, size))
{
*path = '\0';
return 0;
}
strcpy_s(path, size, ConvertUtf16ToUtf8(wszModPath).c_str());
strcpy_s(path, size, StringUtils::Utf16ToUtf8(wszModPath()).c_str());
return (int)strlen(path);
}
@ -372,6 +372,46 @@ static void _memupdatemap()
@brief Dbgfunctionsinits this object.
*/
static duint _fileoffsettova(const char* modname, duint offset)
{
char modpath[MAX_PATH] = "";
if(DbgFunctions()->ModPathFromName(modname, modpath, MAX_PATH))
{
HANDLE FileHandle;
DWORD LoadedSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(StaticFileLoadW(StringUtils::Utf8ToUtf16(modpath).c_str(), UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA))
{
ULONGLONG rva = ConvertFileOffsetToVA(FileMapVA, //FileMapVA
FileMapVA + (ULONG_PTR)offset, //Offset inside FileMapVA
false); //Return without ImageBase
StaticFileUnloadW(StringUtils::Utf8ToUtf16(modpath).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA);
return offset < LoadedSize ? (duint)rva + modbasefromname(modname) : 0;
}
}
return 0;
}
static duint _vatofileoffset(duint va)
{
char modpath[MAX_PATH] = "";
if(DbgFunctions()->ModPathFromAddr(va, modpath, MAX_PATH))
{
HANDLE FileHandle;
DWORD LoadedSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(StaticFileLoadW(StringUtils::Utf8ToUtf16(modpath).c_str(), UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA))
{
ULONGLONG offset = ConvertVAtoFileOffsetEx(FileMapVA, LoadedSize, 0, va - modbasefromaddr(va), true, false);
StaticFileUnloadW(StringUtils::Utf8ToUtf16(modpath).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA);
return (duint)offset;
}
}
return 0;
}
void dbgfunctionsinit()
{
_dbgfunctions.AssembleAtEx = _assembleatex;
@ -404,4 +444,6 @@ void dbgfunctionsinit()
_dbgfunctions.IsProcessElevated = IsProcessElevated;
_dbgfunctions.GetCmdline = _getcmdline;
_dbgfunctions.SetCmdline = _setcmdline;
_dbgfunctions.FileOffsetToVa = _fileoffsettova;
_dbgfunctions.VaToFileOffset = _vatofileoffset;
}

View File

@ -63,6 +63,8 @@ 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 struct DBGFUNCTIONS_
{
@ -96,6 +98,8 @@ typedef struct DBGFUNCTIONS_
ISPROCESSELEVATED IsProcessElevated;
GETCMDLINE GetCmdline;
SETCMDLINE SetCmdline;
FILEOFFSETTOVA FileOffsetToVa;
VATOFILEOFFSET VaToFileOffset;
} DBGFUNCTIONS;
#ifdef BUILD_DBG

View File

@ -209,13 +209,14 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
else //no user labels
{
DWORD64 displacement = 0;
char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)];
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement)
{
if(bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE))
pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
if(!bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE))
strcpy_s(addrinfo->label, pSymbol->Name);
retval = true;
}
@ -230,7 +231,8 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
{
if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) and !displacement)
{
if(bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE))
pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
if(!bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE))
sprintf_s(addrinfo->label, "JMP.&%s", pSymbol->Name);
retval = true;
}
@ -279,7 +281,8 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
else if(!bOnlyCipAutoComments || addr == GetContextDataEx(hActiveThread, UE_CIP)) //no line number
{
DISASM_INSTR instr;
std::string temp_string;
String temp_string;
String comment;
ADDRINFO newinfo;
char ascii[256 * 2] = "";
char unicode[256 * 2] = "";
@ -287,7 +290,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
memset(&instr, 0, sizeof(DISASM_INSTR));
disasmget(addr, &instr);
int len_left = MAX_COMMENT_SIZE;
for(int i = 0, j = 0; i < instr.argcount; i++)
for(int i = 0; i < instr.argcount; i++)
{
memset(&newinfo, 0, sizeof(ADDRINFO));
newinfo.flags = flaglabel;
@ -374,18 +377,16 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
else
continue;
if(!strstr(addrinfo->comment, temp_string.c_str()))
if(!strstr(comment.c_str(), temp_string.c_str()))
{
unsigned int maxlen = MAX_COMMENT_SIZE - j - 1;
if(maxlen < temp_string.length())
temp_string.at(maxlen - 1) = 0;
if(j)
j += sprintf(addrinfo->comment + j, ", %s", temp_string.c_str());
else
j += sprintf(addrinfo->comment + j, "%s", temp_string.c_str());
if(comment.length())
comment.append(", ");
comment.append(temp_string);
retval = true;
}
}
comment.resize(MAX_COMMENT_SIZE - 1);
strcpy_s(addrinfo->comment, comment.c_str());
}
}
}
@ -461,15 +462,125 @@ extern "C" DLL_EXPORT int _dbg_bpgettypeat(duint addr)
return cacheResult;
}
/**
@fn extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump)
static void GetMxCsrFields(MXCSRFIELDS* MxCsrFields, DWORD MxCsr)
{
MxCsrFields->DAZ = valmxcsrflagfromstring(MxCsr, "DAZ");
MxCsrFields->DE = valmxcsrflagfromstring(MxCsr, "DE");
MxCsrFields->FZ = valmxcsrflagfromstring(MxCsr, "FZ");
MxCsrFields->IE = valmxcsrflagfromstring(MxCsr, "IE");
MxCsrFields->IM = valmxcsrflagfromstring(MxCsr, "IM");
MxCsrFields->DM = valmxcsrflagfromstring(MxCsr, "DM");
MxCsrFields->OE = valmxcsrflagfromstring(MxCsr, "OE");
MxCsrFields->OM = valmxcsrflagfromstring(MxCsr, "OM");
MxCsrFields->PE = valmxcsrflagfromstring(MxCsr, "PE");
MxCsrFields->PM = valmxcsrflagfromstring(MxCsr, "PM");
MxCsrFields->UE = valmxcsrflagfromstring(MxCsr, "UE");
MxCsrFields->UM = valmxcsrflagfromstring(MxCsr, "UM");
MxCsrFields->ZE = valmxcsrflagfromstring(MxCsr, "ZE");
MxCsrFields->ZM = valmxcsrflagfromstring(MxCsr, "ZM");
@brief Debug getregdump.
MxCsrFields->RC = valmxcsrfieldfromstring(MxCsr, "RC");
}
@param [in,out] regdump If non-null, the regdump.
static void Getx87ControlWordFields(X87CONTROLWORDFIELDS* x87ControlWordFields, WORD ControlWord)
{
x87ControlWordFields->DM = valx87controlwordflagfromstring(ControlWord, "DM");
x87ControlWordFields->IC = valx87controlwordflagfromstring(ControlWord, "IC");
x87ControlWordFields->IEM = valx87controlwordflagfromstring(ControlWord, "IEM");
x87ControlWordFields->IM = valx87controlwordflagfromstring(ControlWord, "IM");
x87ControlWordFields->OM = valx87controlwordflagfromstring(ControlWord, "OM");
x87ControlWordFields->PM = valx87controlwordflagfromstring(ControlWord, "PM");
x87ControlWordFields->UM = valx87controlwordflagfromstring(ControlWord, "UM");
x87ControlWordFields->ZM = valx87controlwordflagfromstring(ControlWord, "ZM");
@return true if it succeeds, false if it fails.
*/
x87ControlWordFields->RC = valx87controlwordfieldfromstring(ControlWord, "RC");
x87ControlWordFields->PC = valx87controlwordfieldfromstring(ControlWord, "PC");
}
static void Getx87StatusWordFields(X87STATUSWORDFIELDS* x87StatusWordFields, WORD StatusWord)
{
x87StatusWordFields->B = valx87statuswordflagfromstring(StatusWord, "B");
x87StatusWordFields->C0 = valx87statuswordflagfromstring(StatusWord, "C0");
x87StatusWordFields->C1 = valx87statuswordflagfromstring(StatusWord, "C1");
x87StatusWordFields->C2 = valx87statuswordflagfromstring(StatusWord, "C2");
x87StatusWordFields->C3 = valx87statuswordflagfromstring(StatusWord, "C3");
x87StatusWordFields->D = valx87statuswordflagfromstring(StatusWord, "D");
x87StatusWordFields->I = valx87statuswordflagfromstring(StatusWord, "I");
x87StatusWordFields->IR = valx87statuswordflagfromstring(StatusWord, "IR");
x87StatusWordFields->O = valx87statuswordflagfromstring(StatusWord, "O");
x87StatusWordFields->P = valx87statuswordflagfromstring(StatusWord, "P");
x87StatusWordFields->SF = valx87statuswordflagfromstring(StatusWord, "SF");
x87StatusWordFields->U = valx87statuswordflagfromstring(StatusWord, "U");
x87StatusWordFields->Z = valx87statuswordflagfromstring(StatusWord, "Z");
x87StatusWordFields->TOP = valx87statuswordfieldfromstring(StatusWord, "TOP");
}
static void TranslateTitanFpu(const x87FPU_t* titanfpu, X87FPU* fpu)
{
fpu->ControlWord = titanfpu->ControlWord;
fpu->StatusWord = titanfpu->StatusWord;
fpu->TagWord = titanfpu->TagWord;
fpu->ErrorOffset = titanfpu->ErrorOffset;
fpu->ErrorSelector = titanfpu->ErrorSelector;
fpu->DataOffset = titanfpu->DataOffset;
fpu->DataSelector = titanfpu->DataSelector;
fpu->Cr0NpxState = titanfpu->Cr0NpxState;
}
static void TranslateTitanContextToRegContext(const TITAN_ENGINE_CONTEXT_t* titcontext, REGISTERCONTEXT* regcontext)
{
regcontext->cax = titcontext->cax;
regcontext->ccx = titcontext->ccx;
regcontext->cdx = titcontext->cdx;
regcontext->cbx = titcontext->cbx;
regcontext->csp = titcontext->csp;
regcontext->cbp = titcontext->cbp;
regcontext->csi = titcontext->csi;
regcontext->cdi = titcontext->cdi;
#ifdef _WIN64
regcontext->r8 = titcontext->r8;
regcontext->r9 = titcontext->r9;
regcontext->r10 = titcontext->r10;
regcontext->r11 = titcontext->r11;
regcontext->r12 = titcontext->r12;
regcontext->r13 = titcontext->r13;
regcontext->r14 = titcontext->r14;
regcontext->r15 = titcontext->r15;
#endif //_WIN64
regcontext->cip = titcontext->cip;
regcontext->eflags = titcontext->eflags;
regcontext->gs = titcontext->gs;
regcontext->fs = titcontext->fs;
regcontext->es = titcontext->es;
regcontext->ds = titcontext->ds;
regcontext->cs = titcontext->cs;
regcontext->ss = titcontext->ss;
regcontext->dr0 = titcontext->dr0;
regcontext->dr1 = titcontext->dr1;
regcontext->dr2 = titcontext->dr2;
regcontext->dr3 = titcontext->dr3;
regcontext->dr6 = titcontext->dr6;
regcontext->dr7 = titcontext->dr7;
memcpy(regcontext->RegisterArea, titcontext->RegisterArea, sizeof(regcontext->RegisterArea));
TranslateTitanFpu(&titcontext->x87fpu, &regcontext->x87fpu);
regcontext->MxCsr = titcontext->MxCsr;
memcpy(regcontext->XmmRegisters, titcontext->XmmRegisters, sizeof(regcontext->XmmRegisters));
memcpy(regcontext->YmmRegisters, titcontext->YmmRegisters, sizeof(regcontext->YmmRegisters));
}
static void TranslateTitanFpuRegister(const x87FPURegister_t* titanReg, X87FPUREGISTER* reg)
{
memcpy(reg->data, titanReg->data, sizeof(reg->data));
reg->st_value = titanReg->st_value;
reg->tag = titanReg->tag;
}
static void TranslateTitanFpuRegisters(const x87FPURegister_t titanFpu[8], X87FPUREGISTER fpu[8])
{
for(int i = 0; i < 8; i++)
TranslateTitanFpuRegister(&titanFpu[i], &fpu[i]);
}
extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump)
{
@ -479,59 +590,30 @@ extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump)
return true;
}
REGDUMP & r = *regdump;
TITAN_ENGINE_CONTEXT_t titcontext;
if(!GetFullContextDataEx(hActiveThread, &titcontext))
return false;
TranslateTitanContextToRegContext(&titcontext, &regdump->regcontext);
#ifdef _WIN64
r.cax = GetContextDataEx(hActiveThread, UE_RAX);
r.ccx = GetContextDataEx(hActiveThread, UE_RCX);
r.cdx = GetContextDataEx(hActiveThread, UE_RDX);
r.cbx = GetContextDataEx(hActiveThread, UE_RBX);
r.cbp = GetContextDataEx(hActiveThread, UE_RBP);
r.csi = GetContextDataEx(hActiveThread, UE_RSI);
r.cdi = GetContextDataEx(hActiveThread, UE_RDI);
r.r8 = GetContextDataEx(hActiveThread, UE_R8);
r.r9 = GetContextDataEx(hActiveThread, UE_R9);
r.r10 = GetContextDataEx(hActiveThread, UE_R10);
r.r11 = GetContextDataEx(hActiveThread, UE_R11);
r.r12 = GetContextDataEx(hActiveThread, UE_R12);
r.r13 = GetContextDataEx(hActiveThread, UE_R13);
r.r14 = GetContextDataEx(hActiveThread, UE_R14);
r.r15 = GetContextDataEx(hActiveThread, UE_R15);
#else
r.cax = GetContextDataEx(hActiveThread, UE_EAX);
r.ccx = GetContextDataEx(hActiveThread, UE_ECX);
r.cdx = GetContextDataEx(hActiveThread, UE_EDX);
r.cbx = GetContextDataEx(hActiveThread, UE_EBX);
r.cbp = GetContextDataEx(hActiveThread, UE_EBP);
r.csi = GetContextDataEx(hActiveThread, UE_ESI);
r.cdi = GetContextDataEx(hActiveThread, UE_EDI);
#endif
duint cflags = regdump->regcontext.eflags;
regdump->flags.c = valflagfromstring(cflags, "cf");
regdump->flags.p = valflagfromstring(cflags, "pf");
regdump->flags.a = valflagfromstring(cflags, "af");
regdump->flags.z = valflagfromstring(cflags, "zf");
regdump->flags.s = valflagfromstring(cflags, "sf");
regdump->flags.t = valflagfromstring(cflags, "tf");
regdump->flags.i = valflagfromstring(cflags, "if");
regdump->flags.d = valflagfromstring(cflags, "df");
regdump->flags.o = valflagfromstring(cflags, "of");
r.csp = GetContextDataEx(hActiveThread, UE_CSP);
r.cip = GetContextDataEx(hActiveThread, UE_CIP);
r.eflags = (unsigned int)GetContextDataEx(hActiveThread, UE_EFLAGS);
r.gs = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_GS) & 0xFFFF);
r.fs = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_FS) & 0xFFFF);
r.es = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_ES) & 0xFFFF);
r.ds = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_DS) & 0xFFFF);
r.cs = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_CS) & 0xFFFF);
r.ss = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_SS) & 0xFFFF);
r.dr0 = GetContextDataEx(hActiveThread, UE_DR0);
r.dr1 = GetContextDataEx(hActiveThread, UE_DR1);
r.dr2 = GetContextDataEx(hActiveThread, UE_DR2);
r.dr3 = GetContextDataEx(hActiveThread, UE_DR3);
r.dr6 = GetContextDataEx(hActiveThread, UE_DR6);
r.dr7 = GetContextDataEx(hActiveThread, UE_DR7);
duint cflags = r.eflags;
r.flags.c = valflagfromstring(cflags, "cf");
r.flags.p = valflagfromstring(cflags, "pf");
r.flags.a = valflagfromstring(cflags, "af");
r.flags.z = valflagfromstring(cflags, "zf");
r.flags.s = valflagfromstring(cflags, "sf");
r.flags.t = valflagfromstring(cflags, "tf");
r.flags.i = valflagfromstring(cflags, "if");
r.flags.d = valflagfromstring(cflags, "df");
r.flags.o = valflagfromstring(cflags, "of");
x87FPURegister_t x87FPURegisters[8];
Getx87FPURegisters(x87FPURegisters, &titcontext);
TranslateTitanFpuRegisters(x87FPURegisters, regdump->x87FPURegisters);
GetMMXRegisters(regdump->mmx, &titcontext);
GetMxCsrFields(& (regdump->MxCsrFields), regdump->regcontext.MxCsr);
Getx87ControlWordFields(& (regdump->x87ControlWordFields), regdump->regcontext.x87fpu.ControlWord);
Getx87StatusWordFields(& (regdump->x87StatusWordFields), regdump->regcontext.x87fpu.StatusWord);
return true;
}

View File

@ -35,11 +35,6 @@ char dbpath[3 * deflen] = "";
@return null if it fails, else a void*.
*/
void* emalloc(size_t size)
{
return emalloc(size, "emalloc:???");
}
/**
@fn void* erealloc(void* ptr, size_t size)
@ -51,11 +46,6 @@ void* emalloc(size_t size)
@return null if it fails, else a void*.
*/
void* erealloc(void* ptr, size_t size)
{
return erealloc(ptr, size, "erealloc:???");
}
/**
@fn void efree(void* ptr)
@ -64,11 +54,6 @@ void* erealloc(void* ptr, size_t size)
@param [in,out] ptr If non-null, the pointer.
*/
void efree(void* ptr)
{
efree(ptr, "efree:???");
}
/**
@brief Number of emallocs.
*/
@ -295,7 +280,7 @@ void formatdec(char* string)
bool FileExists(const char* file)
{
DWORD attrib = GetFileAttributesW(ConvertUtf8ToUtf16(file).c_str());
DWORD attrib = GetFileAttributesW(StringUtils::Utf8ToUtf16(file).c_str());
return (attrib != INVALID_FILE_ATTRIBUTES && !(attrib & FILE_ATTRIBUTE_DIRECTORY));
}
@ -311,7 +296,7 @@ bool FileExists(const char* file)
bool DirExists(const char* dir)
{
DWORD attrib = GetFileAttributesW(ConvertUtf8ToUtf16(dir).c_str());
DWORD attrib = GetFileAttributesW(StringUtils::Utf8ToUtf16(dir).c_str());
return (attrib == FILE_ATTRIBUTE_DIRECTORY);
}
@ -331,7 +316,7 @@ 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, ConvertUtf16ToUtf8(wszFileName).c_str());
strcpy_s(szFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str());
return true;
}
@ -369,7 +354,7 @@ bool settingboolget(const char* section, const char* name)
arch GetFileArchitecture(const char* szFileName)
{
arch retval = notfound;
HANDLE hFile = CreateFileW(ConvertUtf8ToUtf16(szFileName).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
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];

View File

@ -21,7 +21,7 @@
#include "jansson\jansson.h"
#include "DeviceNameResolver\DeviceNameResolver.h"
#include "handle.h"
#include "UString\UString.h"
#include "stringutils.h"
#ifdef __GNUC__
#include "dbghelp\dbghelp.h"
@ -107,12 +107,9 @@ extern char dbbasepath[deflen];
extern char dbpath[3 * deflen];
//functions
void* emalloc(size_t size);
void* erealloc(void* ptr, size_t size);
void efree(void* ptr);
void* emalloc(size_t size, const char* reason);
void* erealloc(void* ptr, size_t size, const char* reason);
void efree(void* ptr, const char* reason);
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:???");
int memleaks();
void setalloctrace(const char* file);
bool arraycontains(const char* cmd_list, const char* cmd);

View File

@ -68,7 +68,7 @@ void dbsave()
functioncachesave(root);
loopcachesave(root);
bpcachesave(root);
std::wstring wdbpath = ConvertUtf8ToUtf16(dbpath);
WString wdbpath = StringUtils::Utf8ToUtf16(dbpath);
if(json_object_size(root))
{
FILE* jsonFile = 0;
@ -105,7 +105,7 @@ void dbload()
return;
dprintf("loading database...");
DWORD ticks = GetTickCount();
std::wstring wdbpath = ConvertUtf8ToUtf16(dbpath);
WString wdbpath = StringUtils::Utf8ToUtf16(dbpath);
LZ4_STATUS status = LZ4_decompress_fileW(wdbpath.c_str(), wdbpath.c_str());
if(status != LZ4_SUCCESS && status != LZ4_INVALID_ARCHIVE)
{
@ -146,11 +146,21 @@ void dbload()
void dbclose()
{
dbsave();
CriticalSectionLocker commentLocker(LockComments);
CommentsInfo().swap(comments);
CriticalSectionLocker labelLocker(LockLabels);
LabelsInfo().swap(labels);
CriticalSectionLocker bookmarkLocker(LockBookmarks);
BookmarksInfo().swap(bookmarks);
CriticalSectionLocker functionLocker(LockFunctions);
FunctionsInfo().swap(functions);
CriticalSectionLocker loopLocker(LockLoops);
LoopsInfo().swap(loops);
bpclear();
patchclear();
}
@ -202,7 +212,7 @@ bool modload(uint base, uint size, const char* fullpath)
DWORD LoadedSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
std::wstring wszFullPath = ConvertUtf8ToUtf16(fullpath);
WString wszFullPath = StringUtils::Utf8ToUtf16(fullpath);
if(StaticFileLoadW(wszFullPath.c_str(), UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA))
{
info.entry = GetPE32DataFromMappedFile(FileMapVA, 0, UE_OEP) + info.base; //get entry point
@ -264,6 +274,7 @@ bool modload(uint base, uint size, const char* fullpath)
}
//add module to list
CriticalSectionLocker locker(LockModules);
modinfo.insert(std::make_pair(Range(base, base + size - 1), info));
symupdatemodulelist();
return true;
@ -281,6 +292,7 @@ bool modload(uint base, uint size, const char* fullpath)
bool modunload(uint base)
{
CriticalSectionLocker locker(LockModules);
const ModulesInfo::iterator found = modinfo.find(Range(base, base));
if(found == modinfo.end()) //not found
return false;
@ -297,6 +309,7 @@ bool modunload(uint base)
void modclear()
{
CriticalSectionLocker locker(LockModules);
ModulesInfo().swap(modinfo);
symupdatemodulelist();
}
@ -318,6 +331,7 @@ bool modnamefromaddr(uint addr, char* modname, bool extension)
if(!modname)
return false;
*modname = '\0';
CriticalSectionLocker locker(LockModules);
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
if(found == modinfo.end()) //not found
return false;
@ -339,6 +353,7 @@ bool modnamefromaddr(uint addr, char* modname, bool extension)
uint modbasefromaddr(uint addr)
{
CriticalSectionLocker locker(LockModules);
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
if(found == modinfo.end()) //not found
return 0;
@ -357,6 +372,7 @@ uint modbasefromaddr(uint addr)
uint modhashfromva(uint va) //return a unique hash from a VA
{
CriticalSectionLocker locker(LockModules);
const ModulesInfo::iterator found = modinfo.find(Range(va, va));
if(found == modinfo.end()) //not found
return va;
@ -395,6 +411,7 @@ uint modbasefromname(const char* modname)
{
if(!modname or strlen(modname) >= MAX_MODULE_SIZE)
return 0;
CriticalSectionLocker locker(LockModules);
for(ModulesInfo::iterator i = modinfo.begin(); i != modinfo.end(); ++i)
{
MODINFO* curMod = &i->second;
@ -420,6 +437,7 @@ uint modbasefromname(const char* modname)
uint modsizefromaddr(uint addr)
{
CriticalSectionLocker locker(LockModules);
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
if(found == modinfo.end()) //not found
return 0;
@ -439,6 +457,7 @@ uint modsizefromaddr(uint addr)
bool modsectionsfromaddr(uint addr, std::vector<MODSECTIONINFO>* sections)
{
CriticalSectionLocker locker(LockModules);
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
if(found == modinfo.end()) //not found
return false;
@ -458,6 +477,7 @@ bool modsectionsfromaddr(uint addr, std::vector<MODSECTIONINFO>* sections)
uint modentryfromaddr(uint addr)
{
CriticalSectionLocker locker(LockModules);
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
if(found == modinfo.end()) //not found
return 0;
@ -573,6 +593,7 @@ bool commentset(uint addr, const char* text, bool manual)
modnamefromaddr(addr, comment.mod, true);
comment.addr = addr - modbasefromaddr(addr);
const uint key = modhashfromva(addr);
CriticalSectionLocker locker(LockComments);
if(!comments.insert(std::make_pair(key, comment)).second) //key already present
comments[key] = comment;
return true;
@ -593,6 +614,7 @@ bool commentget(uint addr, char* text)
{
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockComments);
const CommentsInfo::iterator found = comments.find(modhashfromva(addr));
if(found == comments.end()) //not found
return false;
@ -614,6 +636,7 @@ bool commentdel(uint addr)
{
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockComments);
return (comments.erase(modhashfromva(addr)) == 1);
}
@ -636,6 +659,7 @@ void commentdelrange(uint start, uint end)
return;
start -= modbase;
end -= modbase;
CriticalSectionLocker locker(LockComments);
CommentsInfo::iterator i = comments.begin();
while(i != comments.end())
{
@ -661,6 +685,7 @@ void commentdelrange(uint start, uint end)
void commentcachesave(JSON root)
{
CriticalSectionLocker locker(LockComments);
const JSON jsoncomments = json_array();
const JSON jsonautocomments = json_array();
for(CommentsInfo::iterator i = comments.begin(); i != comments.end(); ++i)
@ -685,6 +710,7 @@ void commentcachesave(JSON root)
void commentcacheload(JSON root)
{
CriticalSectionLocker locker(LockComments);
comments.clear();
const JSON jsoncomments = json_object_get(root, "comments");
if(jsoncomments)
@ -786,6 +812,7 @@ bool commentenum(COMMENTSINFO* commentlist, size_t* cbsize)
return false;
if(!commentlist && !cbsize)
return false;
CriticalSectionLocker locker(LockComments);
if(!commentlist && cbsize)
{
*cbsize = comments.size() * sizeof(COMMENTSINFO);
@ -827,6 +854,7 @@ bool labelset(uint addr, const char* text, bool manual)
modnamefromaddr(addr, label.mod, true);
label.addr = addr - modbasefromaddr(addr);
uint key = modhashfromva(addr);
CriticalSectionLocker locker(LockLabels);
if(!labels.insert(std::make_pair(modhashfromva(key), label)).second) //already present
labels[key] = label;
return true;
@ -847,6 +875,7 @@ bool labelfromstring(const char* text, uint* addr)
{
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockLabels);
for(LabelsInfo::iterator i = labels.begin(); i != labels.end(); ++i)
{
if(!strcmp(i->second.text, text))
@ -874,6 +903,7 @@ bool labelget(uint addr, char* text)
{
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockLabels);
const LabelsInfo::iterator found = labels.find(modhashfromva(addr));
if(found == labels.end()) //not found
return false;
@ -896,6 +926,7 @@ bool labeldel(uint addr)
{
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockLabels);
return (labels.erase(modhashfromva(addr)) > 0);
}
@ -918,6 +949,7 @@ void labeldelrange(uint start, uint end)
return;
start -= modbase;
end -= modbase;
CriticalSectionLocker locker(LockLabels);
LabelsInfo::iterator i = labels.begin();
while(i != labels.end())
{
@ -943,6 +975,7 @@ void labeldelrange(uint start, uint end)
void labelcachesave(JSON root)
{
CriticalSectionLocker locker(LockLabels);
const JSON jsonlabels = json_array();
const JSON jsonautolabels = json_array();
for(LabelsInfo::iterator i = labels.begin(); i != labels.end(); ++i)
@ -967,6 +1000,7 @@ void labelcachesave(JSON root)
void labelcacheload(JSON root)
{
CriticalSectionLocker locker(LockLabels);
labels.clear();
const JSON jsonlabels = json_object_get(root, "labels");
if(jsonlabels)
@ -1072,6 +1106,7 @@ bool labelenum(LABELSINFO* labellist, size_t* cbsize)
return false;
if(!labellist && !cbsize)
return false;
CriticalSectionLocker locker(LockLabels);
if(!labellist && cbsize)
{
*cbsize = labels.size() * sizeof(LABELSINFO);
@ -1105,6 +1140,7 @@ bool bookmarkset(uint addr, bool manual)
modnamefromaddr(addr, bookmark.mod, true);
bookmark.addr = addr - modbasefromaddr(addr);
bookmark.manual = manual;
CriticalSectionLocker locker(LockBookmarks);
if(!bookmarks.insert(std::make_pair(modhashfromva(addr), bookmark)).second)
return bookmarkdel(addr);
return true;
@ -1124,6 +1160,7 @@ bool bookmarkget(uint addr)
{
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockBookmarks);
if(bookmarks.count(modhashfromva(addr)))
return true;
return false;
@ -1143,6 +1180,7 @@ bool bookmarkdel(uint addr)
{
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockBookmarks);
return (bookmarks.erase(modhashfromva(addr)) > 0);
}
@ -1165,6 +1203,7 @@ void bookmarkdelrange(uint start, uint end)
return;
start -= modbase;
end -= modbase;
CriticalSectionLocker locker(LockBookmarks);
BookmarksInfo::iterator i = bookmarks.begin();
while(i != bookmarks.end())
{
@ -1190,6 +1229,7 @@ void bookmarkdelrange(uint start, uint end)
void bookmarkcachesave(JSON root)
{
CriticalSectionLocker locker(LockBookmarks);
const JSON jsonbookmarks = json_array();
const JSON jsonautobookmarks = json_array();
for(BookmarksInfo::iterator i = bookmarks.begin(); i != bookmarks.end(); ++i)
@ -1213,6 +1253,7 @@ void bookmarkcachesave(JSON root)
void bookmarkcacheload(JSON root)
{
CriticalSectionLocker locker(LockBookmarks);
bookmarks.clear();
const JSON jsonbookmarks = json_object_get(root, "bookmarks");
if(jsonbookmarks)
@ -1304,6 +1345,7 @@ bool bookmarkenum(BOOKMARKSINFO* bookmarklist, size_t* cbsize)
return false;
if(!bookmarklist && !cbsize)
return false;
CriticalSectionLocker locker(LockBookmarks);
if(!bookmarklist && cbsize)
{
*cbsize = bookmarks.size() * sizeof(BOOKMARKSINFO);
@ -1344,6 +1386,7 @@ bool functionadd(uint start, uint end, bool manual)
function.start = start - modbase;
function.end = end - modbase;
function.manual = manual;
CriticalSectionLocker locker(LockFunctions);
functions.insert(std::make_pair(ModuleRange(modhashfromva(modbase), Range(function.start, function.end)), function));
return true;
}
@ -1365,6 +1408,7 @@ bool functionget(uint addr, uint* start, uint* end)
if(!DbgIsDebugging())
return false;
uint modbase = modbasefromaddr(addr);
CriticalSectionLocker locker(LockFunctions);
const FunctionsInfo::iterator found = functions.find(ModuleRange(modhashfromva(modbase), Range(addr - modbase, addr - modbase)));
if(found == functions.end()) //not found
return false;
@ -1391,6 +1435,7 @@ bool functionoverlaps(uint start, uint end)
if(!DbgIsDebugging() or end < start)
return false;
const uint modbase = modbasefromaddr(start);
CriticalSectionLocker locker(LockFunctions);
return (functions.count(ModuleRange(modhashfromva(modbase), Range(start - modbase, end - modbase))) > 0);
}
@ -1409,6 +1454,7 @@ bool functiondel(uint addr)
if(!DbgIsDebugging())
return false;
const uint modbase = modbasefromaddr(addr);
CriticalSectionLocker locker(LockFunctions);
return (functions.erase(ModuleRange(modhashfromva(modbase), Range(addr - modbase, addr - modbase))) > 0);
}
@ -1431,6 +1477,7 @@ void functiondelrange(uint start, uint end)
return;
start -= modbase;
end -= modbase;
CriticalSectionLocker locker(LockFunctions);
FunctionsInfo::iterator i = functions.begin();
while(i != functions.end())
{
@ -1456,6 +1503,7 @@ void functiondelrange(uint start, uint end)
void functioncachesave(JSON root)
{
CriticalSectionLocker locker(LockFunctions);
const JSON jsonfunctions = json_array();
const JSON jsonautofunctions = json_array();
for(FunctionsInfo::iterator i = functions.begin(); i != functions.end(); ++i)
@ -1480,6 +1528,7 @@ void functioncachesave(JSON root)
void functioncacheload(JSON root)
{
CriticalSectionLocker locker(LockFunctions);
functions.clear();
const JSON jsonfunctions = json_object_get(root, "functions");
if(jsonfunctions)
@ -1577,6 +1626,7 @@ bool functionenum(FUNCTIONSINFO* functionlist, size_t* cbsize)
return false;
if(!functionlist && !cbsize)
return false;
CriticalSectionLocker locker(LockFunctions);
if(!functionlist && cbsize)
{
*cbsize = functions.size() * sizeof(FUNCTIONSINFO);
@ -1625,6 +1675,7 @@ bool loopadd(uint start, uint end, bool manual)
else
loop.parent = 0;
loop.manual = manual;
CriticalSectionLocker locker(LockLoops);
loops.insert(std::make_pair(DepthModuleRange(finaldepth, ModuleRange(modhashfromva(modbase), Range(loop.start, loop.end))), loop));
return true;
}
@ -1647,6 +1698,7 @@ bool loopget(int depth, uint addr, uint* start, uint* end)
if(!DbgIsDebugging())
return false;
const uint modbase = modbasefromaddr(addr);
CriticalSectionLocker locker(LockLoops);
LoopsInfo::iterator found = loops.find(DepthModuleRange(depth, ModuleRange(modhashfromva(modbase), Range(addr - modbase, addr - modbase))));
if(found == loops.end()) //not found
return false;
@ -1680,6 +1732,8 @@ bool loopoverlaps(int depth, uint start, uint end, int* finaldepth)
uint curEnd = end - modbase;
const uint key = modhashfromva(modbase);
CriticalSectionLocker locker(LockLoops);
//check if the new loop fits in the old loop
for(LoopsInfo::iterator i = loops.begin(); i != loops.end(); ++i)
{
@ -1731,6 +1785,7 @@ bool loopdel(int depth, uint addr)
void loopcachesave(JSON root)
{
CriticalSectionLocker locker(LockLoops);
const JSON jsonloops = json_array();
const JSON jsonautoloops = json_array();
for(LoopsInfo::iterator i = loops.begin(); i != loops.end(); ++i)
@ -1757,6 +1812,7 @@ void loopcachesave(JSON root)
void loopcacheload(JSON root)
{
CriticalSectionLocker locker(LockLoops);
loops.clear();
const JSON jsonloops = json_object_get(root, "loops");
if(jsonloops)
@ -1856,6 +1912,7 @@ bool loopenum(LOOPSINFO* looplist, size_t* cbsize)
return false;
if(!looplist && !cbsize)
return false;
CriticalSectionLocker locker(LockLoops);
if(!looplist && cbsize)
{
*cbsize = loops.size() * sizeof(LOOPSINFO);

View File

@ -6,7 +6,6 @@
#include "argument.h"
#include "console.h"
#include "UString/UString.h"
/*
formatarg:

View File

@ -33,6 +33,7 @@ int bpgetlist(std::vector<BREAKPOINT>* list)
return false;
BREAKPOINT curBp;
int count = 0;
CriticalSectionLocker locker(LockBreakpoints);
for(BreakpointsInfo::iterator i = breakpoints.begin(); i != breakpoints.end(); ++i)
{
curBp = i->second;
@ -79,6 +80,7 @@ bool bpnew(uint addr, bool enabled, bool singleshoot, short oldbytes, BP_TYPE ty
bp.singleshoot = singleshoot;
bp.titantype = titantype;
bp.type = type;
CriticalSectionLocker locker(LockBreakpoints);
breakpoints.insert(std::make_pair(BreakpointKey(type, modhashfromva(addr)), bp));
return true;
}
@ -101,6 +103,7 @@ bool bpget(uint addr, BP_TYPE type, const char* name, BREAKPOINT* bp)
if(!DbgIsDebugging())
return false;
BREAKPOINT curBp;
CriticalSectionLocker locker(LockBreakpoints);
if(!name)
{
BreakpointsInfo::iterator found = breakpoints.find(BreakpointKey(type, modhashfromva(addr)));
@ -149,6 +152,7 @@ bool bpdel(uint addr, BP_TYPE type)
{
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockBreakpoints);
return (breakpoints.erase(BreakpointKey(type, modhashfromva(addr))) > 0);
}
@ -168,6 +172,7 @@ bool bpenable(uint addr, BP_TYPE type, bool enable)
{
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockBreakpoints);
BreakpointsInfo::iterator found = breakpoints.find(BreakpointKey(type, modhashfromva(addr)));
if(found == breakpoints.end()) //not found
return false;
@ -191,6 +196,7 @@ bool bpsetname(uint addr, BP_TYPE type, const char* name)
{
if(!DbgIsDebugging() or !name or !*name)
return false;
CriticalSectionLocker locker(LockBreakpoints);
BreakpointsInfo::iterator found = breakpoints.find(BreakpointKey(type, modhashfromva(addr)));
if(found == breakpoints.end()) //not found
return false;
@ -214,6 +220,7 @@ bool bpsettitantype(uint addr, BP_TYPE type, int titantype)
{
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockBreakpoints);
BreakpointsInfo::iterator found = breakpoints.find(BreakpointKey(type, modhashfromva(addr)));
if(found == breakpoints.end()) //not found
return false;
@ -238,6 +245,7 @@ bool bpenumall(BPENUMCALLBACK cbEnum, const char* module)
return false;
bool retval = true;
BREAKPOINT curBp;
CriticalSectionLocker locker(LockBreakpoints);
BreakpointsInfo::iterator i = breakpoints.begin();
while(i != breakpoints.end())
{
@ -292,6 +300,7 @@ bool bpenumall(BPENUMCALLBACK cbEnum)
int bpgetcount(BP_TYPE type, bool enabledonly)
{
int count = 0;
CriticalSectionLocker locker(LockBreakpoints);
for(BreakpointsInfo::iterator i = breakpoints.begin(); i != breakpoints.end(); ++i)
{
if(i->first.first == type && (!enabledonly || i->second.enabled))
@ -347,6 +356,7 @@ void bptobridge(const BREAKPOINT* bp, BRIDGEBP* bridge)
void bpcachesave(JSON root)
{
CriticalSectionLocker locker(LockBreakpoints);
const JSON jsonbreakpoints = json_array();
for(BreakpointsInfo::iterator i = breakpoints.begin(); i != breakpoints.end(); ++i)
{
@ -371,6 +381,7 @@ void bpcachesave(JSON root)
void bpcacheload(JSON root)
{
CriticalSectionLocker locker(LockBreakpoints);
breakpoints.clear();
const JSON jsonbreakpoints = json_object_get(root, "breakpoints");
if(jsonbreakpoints)
@ -421,5 +432,6 @@ void bpcacheload(JSON root)
void bpclear()
{
CriticalSectionLocker locker(LockBreakpoints);
BreakpointsInfo().swap(breakpoints);
}

View File

@ -1,31 +0,0 @@
#ifndef _DATA_H
#define _DATA_H
#include "_global.h"
enum DATA_TYPE //how to display the current struct entry?
{
thex, //%X
tint, //%d
tuint, //%u
ttext, //%c
};
struct STRUCT_INFO
{
unsigned int size; //size of one entry (with type) (max 256)
DATA_TYPE display_type; //display type
unsigned int count; //number of entries with the same content (reserved[12])
void* description; //reserved for later use (for example name of variable)
};
struct DATA
{
uint page_start; //remote/local memory
uint page_size; //size of memory
uint ip; //real start of data (relative from page_start)
int struct_size; //number of entries in a struct
STRUCT_INFO* info; //actual info
};
#endif // _DATA_H

View File

@ -243,6 +243,7 @@ void dbginit()
exceptionNames.insert(std::make_pair(0x04242420, "CLRDBG_NOTIFICATION_EXCEPTION_CODE"));
exceptionNames.insert(std::make_pair(0xE0434352, "CLR_EXCEPTION"));
exceptionNames.insert(std::make_pair(0xE06D7363, "CPP_EH_EXCEPTION"));
exceptionNames.insert(std::make_pair(MS_VC_EXCEPTION, "MS_VC_EXCEPTION"));
CloseHandle(CreateThread(0, 0, memMapThread, 0, 0, 0));
}
@ -1031,7 +1032,7 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
if(!DevicePathFromFileHandleW(CreateProcessInfo->hFile, wszFileName, sizeof(wszFileName)))
strcpy(DebugFileName, "??? (GetFileNameFromHandle failed!)");
else
strcpy_s(DebugFileName, MAX_PATH, ConvertUtf16ToUtf8(wszFileName).c_str());
strcpy_s(DebugFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str());
}
dprintf("Process Started: "fhex" %s\n", base, DebugFileName);
@ -1076,12 +1077,12 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
if(settingboolget("Events", "TlsCallbacks"))
{
DWORD NumberOfCallBacks = 0;
TLSGrabCallBackDataW(ConvertUtf8ToUtf16(DebugFileName).c_str(), 0, &NumberOfCallBacks);
TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, &NumberOfCallBacks);
if(NumberOfCallBacks)
{
dprintf("TLS Callbacks: %d\n", NumberOfCallBacks);
Memory<uint*> TLSCallBacks(NumberOfCallBacks * sizeof(uint), "cbCreateProcess:TLSCallBacks");
if(!TLSGrabCallBackDataW(ConvertUtf8ToUtf16(DebugFileName).c_str(), TLSCallBacks, &NumberOfCallBacks))
if(!TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), TLSCallBacks, &NumberOfCallBacks))
dputs("failed to get TLS callback addresses!");
else
{
@ -1273,7 +1274,7 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
if(!DevicePathFromFileHandleW(LoadDll->hFile, wszFileName, sizeof(wszFileName)))
strcpy(DLLDebugFileName, "??? (GetFileNameFromHandle failed!)");
else
strcpy_s(DLLDebugFileName, MAX_PATH, ConvertUtf16ToUtf8(wszFileName).c_str());
strcpy_s(DLLDebugFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str());
}
SymLoadModuleEx(fdProcessInfo->hProcess, LoadDll->hFile, DLLDebugFileName, 0, (DWORD64)base, 0, 0, 0);
IMAGEHLP_MODULE64 modInfo;
@ -1437,7 +1438,7 @@ static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
break;
}
}
dprintf("DebugString: \"%s\"\n", DebugTextEscaped);
dprintf("DebugString: \"%s\"\n", DebugTextEscaped());
}
}
@ -1506,63 +1507,58 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
}
SetContextDataEx(hActiveThread, UE_CIP, (uint)ExceptionData->ExceptionRecord.ExceptionAddress);
}
else if(ExceptionData->ExceptionRecord.ExceptionCode == 0x406D1388) //SetThreadName exception
else if(ExceptionData->ExceptionRecord.ExceptionCode == MS_VC_EXCEPTION) //SetThreadName exception
{
if(ExceptionData->ExceptionRecord.NumberParameters == sizeof(THREADNAME_INFO) / sizeof(uint))
THREADNAME_INFO nameInfo;
memcpy(&nameInfo, ExceptionData->ExceptionRecord.ExceptionInformation, sizeof(THREADNAME_INFO));
if(nameInfo.dwThreadID == -1) //current thread
nameInfo.dwThreadID = ((DEBUG_EVENT*)GetDebugData())->dwThreadId;
if(nameInfo.dwType == 0x1000 and nameInfo.dwFlags == 0 and threadisvalid(nameInfo.dwThreadID)) //passed basic checks
{
THREADNAME_INFO nameInfo;
memcpy(&nameInfo, ExceptionData->ExceptionRecord.ExceptionInformation, sizeof(THREADNAME_INFO));
if(nameInfo.dwThreadID == -1) //current thread
nameInfo.dwThreadID = ((DEBUG_EVENT*)GetDebugData())->dwThreadId;
if(nameInfo.dwType == 0x1000 and nameInfo.dwFlags == 0 and threadisvalid(nameInfo.dwThreadID)) //passed basic checks
Memory<char*> ThreadName(MAX_THREAD_NAME_SIZE, "cbException:ThreadName");
if(memread(fdProcessInfo->hProcess, nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE - 1, 0))
{
Memory<char*> ThreadName(MAX_THREAD_NAME_SIZE, "cbException:ThreadName");
memset(ThreadName, 0, MAX_THREAD_NAME_SIZE);
if(memread(fdProcessInfo->hProcess, nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE - 1, 0))
int len = (int)strlen(ThreadName);
int escape_count = 0;
for(int i = 0; i < len; i++)
if(ThreadName[i] == '\\' or ThreadName[i] == '\"' or !isprint(ThreadName[i]))
escape_count++;
Memory<char*> ThreadNameEscaped(len + escape_count * 3 + 1, "cbException:ThreadNameEscaped");
for(int i = 0, j = 0; i < len; i++)
{
int len = (int)strlen(ThreadName);
int escape_count = 0;
for(int i = 0; i < len; i++)
if(ThreadName[i] == '\\' or ThreadName[i] == '\"' or !isprint(ThreadName[i]))
escape_count++;
Memory<char*> ThreadNameEscaped(len + escape_count * 3 + 1, "cbException:ThreadNameEscaped");
memset(ThreadNameEscaped, 0, len + escape_count * 3 + 1);
for(int i = 0, j = 0; i < len; i++)
switch(ThreadName[i])
{
switch(ThreadName[i])
{
case '\t':
j += sprintf(ThreadNameEscaped + j, "\\t");
break;
case '\f':
j += sprintf(ThreadNameEscaped + j, "\\f");
break;
case '\v':
j += sprintf(ThreadNameEscaped + j, "\\v");
break;
case '\n':
j += sprintf(ThreadNameEscaped + j, "\\n");
break;
case '\r':
j += sprintf(ThreadNameEscaped + j, "\\r");
break;
case '\\':
j += sprintf(ThreadNameEscaped + j, "\\\\");
break;
case '\"':
j += sprintf(ThreadNameEscaped + j, "\\\"");
break;
default:
if(!isprint(ThreadName[i])) //unknown unprintable character
j += sprintf(ThreadNameEscaped + j, "\\%.2x", ThreadName[i]);
else
j += sprintf(ThreadNameEscaped + j, "%c", ThreadName[i]);
break;
}
case '\t':
j += sprintf(ThreadNameEscaped + j, "\\t");
break;
case '\f':
j += sprintf(ThreadNameEscaped + j, "\\f");
break;
case '\v':
j += sprintf(ThreadNameEscaped + j, "\\v");
break;
case '\n':
j += sprintf(ThreadNameEscaped + j, "\\n");
break;
case '\r':
j += sprintf(ThreadNameEscaped + j, "\\r");
break;
case '\\':
j += sprintf(ThreadNameEscaped + j, "\\\\");
break;
case '\"':
j += sprintf(ThreadNameEscaped + j, "\\\"");
break;
default:
if(!isprint(ThreadName[i])) //unknown unprintable character
j += sprintf(ThreadNameEscaped + j, "\\%.2x", ThreadName[i]);
else
j += sprintf(ThreadNameEscaped + j, "%c", ThreadName[i]);
break;
}
dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped);
threadsetname(nameInfo.dwThreadID, ThreadNameEscaped);
}
dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped());
threadsetname(nameInfo.dwThreadID, ThreadNameEscaped);
}
}
}
@ -1634,13 +1630,13 @@ DWORD WINAPI threadDebugLoop(void* lpParameter)
bSkipExceptions = false;
bBreakOnNextDll = false;
INIT_STRUCT* init = (INIT_STRUCT*)lpParameter;
bFileIsDll = IsFileDLLW(ConvertUtf8ToUtf16(init->exe).c_str(), 0);
pDebuggedEntry = GetPE32DataW(ConvertUtf8ToUtf16(init->exe).c_str(), 0, UE_OEP);
bFileIsDll = IsFileDLLW(StringUtils::Utf8ToUtf16(init->exe).c_str(), 0);
pDebuggedEntry = GetPE32DataW(StringUtils::Utf8ToUtf16(init->exe).c_str(), 0, UE_OEP);
strcpy_s(szFileName, init->exe);
if(bFileIsDll)
fdProcessInfo = (PROCESS_INFORMATION*)InitDLLDebugW(ConvertUtf8ToUtf16(init->exe).c_str(), false, ConvertUtf8ToUtf16(init->commandline).c_str(), ConvertUtf8ToUtf16(init->currentfolder).c_str(), 0);
fdProcessInfo = (PROCESS_INFORMATION*)InitDLLDebugW(StringUtils::Utf8ToUtf16(init->exe).c_str(), false, StringUtils::Utf8ToUtf16(init->commandline).c_str(), StringUtils::Utf8ToUtf16(init->currentfolder).c_str(), 0);
else
fdProcessInfo = (PROCESS_INFORMATION*)InitDebugW(ConvertUtf8ToUtf16(init->exe).c_str(), ConvertUtf8ToUtf16(init->commandline).c_str(), ConvertUtf8ToUtf16(init->currentfolder).c_str());
fdProcessInfo = (PROCESS_INFORMATION*)InitDebugW(StringUtils::Utf8ToUtf16(init->exe).c_str(), StringUtils::Utf8ToUtf16(init->commandline).c_str(), StringUtils::Utf8ToUtf16(init->currentfolder).c_str());
if(!fdProcessInfo)
{
fdProcessInfo = &g_pi;
@ -2168,15 +2164,19 @@ static bool readwritejitkey(wchar_t* jit_key_value, DWORD* jit_key_vale_size, ch
if(lRv != ERROR_SUCCESS)
return false;
lRv = RegSetValueExW(hKey, ConvertUtf8ToUtf16(key).c_str(), 0, REG_SZ, (BYTE*)jit_key_value, (DWORD)(*jit_key_vale_size) + 1);
lRv = RegSetValueExW(hKey, StringUtils::Utf8ToUtf16(key).c_str(), 0, REG_SZ, (BYTE*)jit_key_value, (DWORD)(*jit_key_vale_size) + 1);
}
else
{
lRv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, JIT_REG_KEY, 0, key_flags, &hKey);
if(lRv != ERROR_SUCCESS)
{
if(error != NULL)
*error = ERROR_RW_FILE_NOT_FOUND;
return false;
}
lRv = RegQueryValueExW(hKey, ConvertUtf8ToUtf16(key).c_str(), 0, NULL, (LPBYTE)jit_key_value, jit_key_vale_size);
lRv = RegQueryValueExW(hKey, StringUtils::Utf8ToUtf16(key).c_str(), 0, NULL, (LPBYTE)jit_key_value, jit_key_vale_size);
if(lRv != ERROR_SUCCESS)
{
if(error != NULL)
@ -2452,7 +2452,7 @@ bool dbggetjit(char jit_entry[JIT_ENTRY_MAX_SIZE], arch arch_in, arch* arch_out,
*rw_error_out = rw_error;
return false;
}
strcpy_s(jit_entry, JIT_ENTRY_MAX_SIZE, ConvertUtf16ToUtf8(wszJitEntry).c_str());
strcpy_s(jit_entry, JIT_ENTRY_MAX_SIZE, StringUtils::Utf16ToUtf8(wszJitEntry).c_str());
return true;
}
@ -2472,7 +2472,7 @@ bool dbggetdefjit(char* jit_entry)
path[0] = '"';
wchar_t wszPath[MAX_PATH] = L"";
GetModuleFileNameW(GetModuleHandleW(NULL), wszPath, MAX_PATH);
strcpy(&path[1], ConvertUtf16ToUtf8(wszPath).c_str());
strcpy(&path[1], StringUtils::Utf16ToUtf8(wszPath).c_str());
strcat(path, ATTACH_CMD_LINE);
strcpy(jit_entry, path);
return true;
@ -2495,7 +2495,7 @@ bool dbgsetjit(char* jit_cmd, arch arch_in, arch* arch_out, readwritejitkey_erro
{
DWORD jit_cmd_size = (DWORD)strlen(jit_cmd) * sizeof(wchar_t);
readwritejitkey_error_t rw_error;
if(!readwritejitkey((wchar_t*)ConvertUtf8ToUtf16(jit_cmd).c_str(), & jit_cmd_size, "Debugger", arch_in, arch_out, & rw_error, true))
if(!readwritejitkey((wchar_t*)StringUtils::Utf8ToUtf16(jit_cmd).c_str(), & jit_cmd_size, "Debugger", arch_in, arch_out, & rw_error, true))
{
if(rw_error_out != NULL)
*rw_error_out = rw_error;
@ -2542,7 +2542,7 @@ bool dbglistprocesses(std::vector<PROCESSENTRY32>* list)
continue;
wchar_t szExePath[MAX_PATH] = L"";
if(GetModuleFileNameExW(hProcess, 0, szExePath, MAX_PATH))
strcpy_s(pe32.szExeFile, ConvertUtf16ToUtf8(szExePath).c_str());
strcpy_s(pe32.szExeFile, StringUtils::Utf16ToUtf8(szExePath).c_str());
list->push_back(pe32);
}
while(Process32Next(hProcessSnap, &pe32));

View File

@ -12,6 +12,7 @@
#define JIT_ENTRY_DEF_SIZE (MAX_PATH + sizeof(ATTACH_CMD_LINE) + 2)
#define JIT_ENTRY_MAX_SIZE 512
#define JIT_REG_KEY TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug")
#define MS_VC_EXCEPTION 0x406D1388
typedef enum
{

View File

@ -46,7 +46,7 @@ CMDRESULT cbDebugInit(int argc, char* argv[])
dputs("file does not exist!");
return STATUS_ERROR;
}
HANDLE hFile = CreateFileW(ConvertUtf8ToUtf16(arg1).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
HANDLE hFile = CreateFileW(StringUtils::Utf8ToUtf16(arg1).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(hFile == INVALID_HANDLE_VALUE)
{
dputs("could not open file!");
@ -275,17 +275,17 @@ CMDRESULT cbDebugSetBPX(int argc, char* argv[]) //bp addr [,name [,type]]
}
if(IsBPXEnabled(addr))
{
dprintf("error setting breakpoint at "fhex"!\n (IsBPXEnabled)", addr);
dprintf("error setting breakpoint at "fhex"! (IsBPXEnabled)\n", addr);
return STATUS_ERROR;
}
else if(!memread(fdProcessInfo->hProcess, (void*)addr, &oldbytes, sizeof(short), 0))
{
dprintf("error setting breakpoint at "fhex"!\n (memread)", addr);
dprintf("error setting breakpoint at "fhex"! (memread)\n", addr);
return STATUS_ERROR;
}
else if(!bpnew(addr, true, singleshoot, oldbytes, BPNORMAL, type, bpname))
{
dprintf("error setting breakpoint at "fhex"!\n (bpnew)", addr);
dprintf("error setting breakpoint at "fhex"! (bpnew)\n", addr);
return STATUS_ERROR;
}
else if(!SetBPX(addr, type, (void*)cbUserBreakpoint))
@ -1253,7 +1253,7 @@ CMDRESULT cbDebugAttach(int argc, char* argv[])
dprintf("could not get module filename %X!\n", pid);
return STATUS_ERROR;
}
strcpy_s(szFileName, ConvertUtf16ToUtf8(wszFileName).c_str());
strcpy_s(szFileName, StringUtils::Utf16ToUtf8(wszFileName).c_str());
CloseHandle(CreateThread(0, 0, threadAttachLoop, (void*)pid, 0, 0));
return STATUS_CONTINUE;
}
@ -1895,7 +1895,7 @@ CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[])
return STATUS_ERROR;
}
char szModulePath[MAX_PATH] = "";
strcpy_s(szModulePath, ConvertUtf16ToUtf8(wszModulePath).c_str());
strcpy_s(szModulePath, StringUtils::Utf16ToUtf8(wszModulePath).c_str());
char szOldSearchPath[MAX_PATH] = "";
if(!SymGetSearchPath(fdProcessInfo->hProcess, szOldSearchPath, MAX_PATH)) //backup current search path
{
@ -2133,13 +2133,12 @@ CMDRESULT cbDebugSetJIT(int argc, char* argv[])
char path[JIT_ENTRY_DEF_SIZE];
dbggetdefjit(path);
char get_entry[JIT_ENTRY_MAX_SIZE] = "";
bool get_last_jit = true;
if(!dbggetjit(get_entry, notfound, & actual_arch, NULL))
{
dprintf("Error getting JIT %s\n", (actual_arch == x64) ? "x64" : "x32");
return STATUS_ERROR;
}
strcpy_s(oldjit, get_entry);
get_last_jit = false;
else
strcpy_s(oldjit, get_entry);
jit_debugger_cmd = path;
if(!dbgsetjit(jit_debugger_cmd, notfound, & actual_arch, NULL))
@ -2147,8 +2146,11 @@ CMDRESULT cbDebugSetJIT(int argc, char* argv[])
dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32");
return STATUS_ERROR;
}
if(_stricmp(oldjit, path))
BridgeSettingSet("JIT", "Old", oldjit);
if(get_last_jit)
{
if(_stricmp(oldjit, path))
BridgeSettingSet("JIT", "Old", oldjit);
}
}
else if(!_strcmpi(argv[1], "restore"))
{

View File

@ -1,7 +1,7 @@
#ifndef _DYNAMICMEM_H
#define _DYNAMICMEM_H
template<class T>
template<typename T>
class Memory
{
public:
@ -34,7 +34,7 @@ public:
return mPtr;
}
template<class U>
template<typename U>
operator U()
{
return (U)mPtr;
@ -45,6 +45,11 @@ public:
return mPtr;
}
T operator()()
{
return mPtr;
}
size_t size()
{
return mSize;

View File

@ -299,7 +299,7 @@ CMDRESULT cbInstrChd(int argc, char* argv[])
dputs("directory doesn't exist");
return STATUS_ERROR;
}
SetCurrentDirectoryW(ConvertUtf8ToUtf16(argv[1]).c_str());
SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(argv[1]).c_str());
dputs("current directory changed!");
return STATUS_CONTINUE;
}
@ -1158,6 +1158,12 @@ CMDRESULT cbInstrRefadd(int argc, char* argv[])
return STATUS_CONTINUE;
}
struct VALUERANGE
{
uint start;
uint end;
};
/**
@fn static bool cbRefFind(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo)
@ -1181,20 +1187,25 @@ static bool cbRefFind(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO
return true;
}
bool found = false;
uint value = (uint)refinfo->userinfo;
VALUERANGE* range = (VALUERANGE*)refinfo->userinfo;
uint start = range->start;
uint end = range->end;
if((basicinfo->type & TYPE_VALUE) == TYPE_VALUE)
{
if(basicinfo->value.value == value)
uint value = basicinfo->value.value;
if(value >= start && value <= end)
found = true;
}
if((basicinfo->type & TYPE_MEMORY) == TYPE_MEMORY)
{
if(basicinfo->memory.value == value)
uint value = basicinfo->memory.value;
if(value >= start && value <= end)
found = true;
}
if((basicinfo->type & TYPE_ADDR) == TYPE_ADDR)
{
if(basicinfo->addr == value)
uint value = basicinfo->addr;
if(value >= start && value <= end)
found = true;
}
if(found)
@ -1230,18 +1241,35 @@ CMDRESULT cbInstrRefFind(int argc, char* argv[])
dputs("not enough arguments!");
return STATUS_ERROR;
}
uint value = 0;
if(!valfromstring(argv[1], &value, false))
std::string newCommand = std::string("reffindrange ") + argv[1] + std::string(",") + argv[1];
if(argc > 2)
newCommand += std::string(",") + argv[2];
if(argc > 3)
newCommand += std::string(",") + argv[3];
return cmddirectexec(dbggetcommandlist(), newCommand.c_str());
}
CMDRESULT cbInstrRefFindRange(int argc, char* argv[])
{
if(argc < 2)
{
dputs("not enough arguments!");
return STATUS_ERROR;
}
VALUERANGE range;
if(!valfromstring(argv[1], &range.start, false))
return STATUS_ERROR;
if(argc < 3 or !valfromstring(argv[2], &range.end, false))
range.end = range.start;
uint addr = 0;
if(argc < 3 or !valfromstring(argv[2], &addr))
if(argc < 4 or !valfromstring(argv[3], &addr))
addr = GetContextDataEx(hActiveThread, UE_CIP);
uint size = 0;
if(argc >= 4)
if(!valfromstring(argv[3], &size))
if(argc >= 5)
if(!valfromstring(argv[4], &size))
size = 0;
uint ticks = GetTickCount();
int found = reffind(addr, size, cbRefFind, (void*)value, false);
int found = reffind(addr, size, cbRefFind, &range, false);
dprintf("%u reference(s) in %ums\n", found, GetTickCount() - ticks);
varset("$result", found, false);
return STATUS_CONTINUE;

View File

@ -46,6 +46,7 @@ CMDRESULT cbInstrRefinit(int argc, char* argv[]);
CMDRESULT cbInstrRefadd(int argc, char* argv[]);
CMDRESULT cbInstrRefFind(int argc, char* argv[]);
CMDRESULT cbInstrRefStr(int argc, char* argv[]);
CMDRESULT cbInstrRefFindRange(int argc, char* argv[]);
CMDRESULT cbInstrSetstr(int argc, char* argv[]);
CMDRESULT cbInstrGetstr(int argc, char* argv[]);

View File

@ -1,5 +1,8 @@
#pragma once
#ifndef _LOG_H
#define _LOG_H
#include <sstream>
// a Qt's QDebug like message logging
// usage: "log() << "hi" << "there";
class log
@ -7,8 +10,8 @@ class log
public:
log();
~log();
public:
public:
template<class T>
inline log & operator<<(const T & x)
{
@ -16,8 +19,9 @@ public:
message << x;
return *this;
}
private:
std::ostringstream message;
};
#endif _LOG_H

View File

@ -575,7 +575,9 @@ bool mathfromstring(const char* string, uint* value, bool silent, bool baseonly,
memset(strright, 0, len + 1);
strncpy(strleft, string - negative, highestop_pos + negative);
strcpy(strright, string + highestop_pos + 1);
//dprintf("left: %s, right: %s, op: %c\n", strleft, strright, string[highestop_pos]);
strcpy(strleft, StringUtils::Trim(strleft).c_str());
strcpy(strright, StringUtils::Trim(strright).c_str());
//dprintf("left: %s, right: %s, op: %c\n", strleft(), strright(), string[highestop_pos]);
if(!*strright)
return false;
uint right = 0;

View File

@ -9,12 +9,10 @@
#include "memory.h"
#include "debugger.h"
#include "console.h"
#include "threading.h"
/**
@brief The patches.
*/
static PatchesInfo patches;
PatchesInfo patches;
/**
@fn bool patchset(uint addr, unsigned char oldbyte, unsigned char newbyte)
@ -40,6 +38,7 @@ bool patchset(uint addr, unsigned char oldbyte, unsigned char newbyte)
newPatch.oldbyte = oldbyte;
newPatch.newbyte = newbyte;
uint key = modhashfromva(addr);
CriticalSectionLocker locker(LockPatches);
PatchesInfo::iterator found = patches.find(key);
if(found != patches.end()) //we found a patch on the specified address
{
@ -74,6 +73,7 @@ bool patchget(uint addr, PATCHINFO* patch)
{
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockPatches);
PatchesInfo::iterator found = patches.find(modhashfromva(addr));
if(found == patches.end()) //not found
return false;
@ -101,6 +101,7 @@ bool patchdel(uint addr, bool restore)
{
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockPatches);
PatchesInfo::iterator found = patches.find(modhashfromva(addr));
if(found == patches.end()) //not found
return false;
@ -130,6 +131,7 @@ void patchdelrange(uint start, uint end, bool restore)
return;
start -= modbase;
end -= modbase;
CriticalSectionLocker locker(LockPatches);
PatchesInfo::iterator i = patches.begin();
while(i != patches.end())
{
@ -154,6 +156,7 @@ void patchdelrange(uint start, uint end, bool restore)
void patchclear(const char* mod)
{
CriticalSectionLocker locker(LockPatches);
if(!mod or !*mod)
patches.clear();
else
@ -186,6 +189,7 @@ bool patchenum(PATCHINFO* patcheslist, size_t* cbsize)
return false;
if(!patcheslist && !cbsize)
return false;
CriticalSectionLocker locker(LockPatches);
if(!patcheslist && cbsize)
{
*cbsize = patches.size() * sizeof(LOOPSINFO);
@ -246,7 +250,7 @@ int patchfile(const PATCHINFO* patchlist, int count, const char* szFileName, cha
sprintf(error, "failed to get module path of module %s", modname);
return -1;
}
if(!CopyFileW(szOriginalName, ConvertUtf8ToUtf16(szFileName).c_str(), false))
if(!CopyFileW(szOriginalName, StringUtils::Utf8ToUtf16(szFileName).c_str(), false))
{
if(error)
strcpy(error, "failed to make a copy of the original file (patch target is in use?)");
@ -256,7 +260,7 @@ int patchfile(const PATCHINFO* patchlist, int count, const char* szFileName, cha
DWORD LoadedSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
if(StaticFileLoadW(ConvertUtf8ToUtf16(szFileName).c_str(), UE_ACCESS_ALL, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA))
if(StaticFileLoadW(StringUtils::Utf8ToUtf16(szFileName).c_str(), UE_ACCESS_ALL, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA))
{
int patched = 0;
for(int i = 0; i < count; i++)
@ -268,7 +272,7 @@ int patchfile(const PATCHINFO* patchlist, int count, const char* szFileName, cha
*ptr = patchlist[i].newbyte;
patched++;
}
if(!StaticFileUnloadW(ConvertUtf8ToUtf16(szFileName).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA))
if(!StaticFileUnloadW(StringUtils::Utf8ToUtf16(szFileName).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA))
{
if(error)
strcpy(error, "StaticFileUnload failed");

View File

@ -53,7 +53,7 @@ void pluginload(const char* pluginDir)
//load new plugins
wchar_t currentDir[deflen] = L"";
GetCurrentDirectoryW(deflen, currentDir);
SetCurrentDirectoryW(ConvertUtf8ToUtf16(pluginDir).c_str());
SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(pluginDir).c_str());
char searchName[deflen] = "";
#ifdef _WIN64
sprintf(searchName, "%s\\*.dp64", pluginDir);
@ -61,7 +61,7 @@ void pluginload(const char* pluginDir)
sprintf(searchName, "%s\\*.dp32", pluginDir);
#endif // _WIN64
WIN32_FIND_DATAW foundData;
HANDLE hSearch = FindFirstFileW(ConvertUtf8ToUtf16(searchName).c_str(), &foundData);
HANDLE hSearch = FindFirstFileW(StringUtils::Utf8ToUtf16(searchName).c_str(), &foundData);
if(hSearch == INVALID_HANDLE_VALUE)
{
SetCurrentDirectoryW(currentDir);
@ -73,8 +73,8 @@ void pluginload(const char* pluginDir)
//set plugin data
pluginData.initStruct.pluginHandle = curPluginHandle;
char szPluginPath[MAX_PATH] = "";
sprintf_s(szPluginPath, "%s\\%s", pluginDir, ConvertUtf16ToUtf8(foundData.cFileName).c_str());
pluginData.hPlugin = LoadLibraryW(ConvertUtf8ToUtf16(szPluginPath).c_str()); //load the plugin library
sprintf_s(szPluginPath, "%s\\%s", pluginDir, StringUtils::Utf16ToUtf8(foundData.cFileName).c_str());
pluginData.hPlugin = LoadLibraryW(StringUtils::Utf8ToUtf16(szPluginPath).c_str()); //load the plugin library
if(!pluginData.hPlugin)
{
dprintf("[PLUGIN] Failed to load plugin: %s\n", foundData.cFileName);

View File

@ -137,7 +137,7 @@ static int scriptinternalstep(int fromIp) //internal step routine
static bool scriptcreatelinemap(const char* filename)
{
HANDLE hFile = CreateFileW(ConvertUtf8ToUtf16(filename).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
HANDLE hFile = CreateFileW(StringUtils::Utf8ToUtf16(filename).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(hFile == INVALID_HANDLE_VALUE)
{
GuiScriptError(0, "CreateFile failed...");

View File

@ -0,0 +1,81 @@
#include "stringutils.h"
#include <windows.h>
#include <iostream>
#include <sstream>
std::vector<String> StringUtils::Split(const String & s, char delim, std::vector<String> & elems)
{
std::stringstream ss(s);
String item;
while(std::getline(ss, item, delim))
{
if(!item.length())
continue;
elems.push_back(item);
}
return elems;
}
std::vector<String> StringUtils::Split(const String & s, char delim)
{
std::vector<String> elems;
Split(s, delim, elems);
return elems;
}
//Trim functions taken from: http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring/16743707#16743707
const String StringUtils::WHITESPACE = " \n\r\t";
String StringUtils::Trim(const String & s)
{
return TrimRight(TrimLeft(s));
}
String StringUtils::TrimLeft(const String & s)
{
size_t startpos = s.find_first_not_of(StringUtils::WHITESPACE);
return (startpos == String::npos) ? "" : s.substr(startpos);
}
String StringUtils::TrimRight(const String & s)
{
size_t endpos = s.find_last_not_of(StringUtils::WHITESPACE);
return (endpos == String::npos) ? "" : s.substr(0, endpos + 1);
}
//Conversion functions taken from: http://www.nubaria.com/en/blog/?p=289
String StringUtils::Utf16ToUtf8(const WString & wstr)
{
String convertedString;
int requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, 0, 0, 0, 0);
if(requiredSize > 0)
{
std::vector<char> buffer(requiredSize);
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &buffer[0], requiredSize, 0, 0);
convertedString.assign(buffer.begin(), buffer.end() - 1);
}
return convertedString;
}
String StringUtils::Utf16ToUtf8(const wchar_t* wstr)
{
return Utf16ToUtf8(wstr ? WString(wstr) : WString());
}
WString StringUtils::Utf8ToUtf16(const String & str)
{
WString convertedString;
int requiredSize = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, 0, 0);
if(requiredSize > 0)
{
std::vector<wchar_t> buffer(requiredSize);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &buffer[0], requiredSize);
convertedString.assign(buffer.begin(), buffer.end() - 1);
}
return convertedString;
}
WString StringUtils::Utf8ToUtf16(const char* str)
{
return Utf8ToUtf16(str ? String(str) : String());
}

27
x64_dbg_dbg/stringutils.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef _STRINGUTILS_H
#define _STRINGUTILS_H
#include <string>
#include <vector>
typedef std::string String;
typedef std::wstring WString;
class StringUtils
{
public:
static std::vector<String> Split(const String & s, char delim, std::vector<String> & elems);
static std::vector<String> Split(const String & s, char delim);
static String Trim(const String & s);
static String TrimLeft(const String & s);
static String TrimRight(const String & s);
static String Utf16ToUtf8(const WString & wstr);
static String Utf16ToUtf8(const wchar_t* wstr);
static WString Utf8ToUtf16(const String & str);
static WString Utf8ToUtf16(const char* str);
private:
static const String WHITESPACE;
};
#endif //_STRINGUTILS_H

View File

@ -195,7 +195,7 @@ void symdownloadallsymbols(const char* szSymbolStore)
dprintf("SymUnloadModule64("fhex") failed!\n", modbase);
continue;
}
if(!SymLoadModuleEx(fdProcessInfo->hProcess, 0, ConvertUtf16ToUtf8(szModulePath).c_str(), 0, (DWORD64)modbase, 0, 0, 0))
if(!SymLoadModuleEx(fdProcessInfo->hProcess, 0, StringUtils::Utf16ToUtf8(szModulePath).c_str(), 0, (DWORD64)modbase, 0, 0, 0))
{
dprintf("SymLoadModuleEx("fhex") failed!\n", modbase);
continue;
@ -222,7 +222,7 @@ bool symfromname(const char* name, uint* addr)
{
if(!name or !strlen(name) or !addr or !_strnicmp(name, "ordinal", 7)) //skip 'OrdinalXXX'
return false;
char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)];
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
@ -253,12 +253,13 @@ const char* symgetsymbolicname(uint addr)
else //no user labels
{
DWORD64 displacement = 0;
char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)];
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement)
{
pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
if(!bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE))
strcpy_s(label, pSymbol->Name);
retval = true;

View File

@ -8,6 +8,7 @@
#include "console.h"
#include "undocumented.h"
#include "memory.h"
#include "threading.h"
/**
@brief List of threads.
@ -46,8 +47,10 @@ void threadcreate(CREATE_THREAD_DEBUG_INFO* CreateThread)
*curInfo.threadName = '\0';
if(!threadNum)
strcpy(curInfo.threadName, "Main Thread");
CriticalSectionLocker locker(LockThreads);
threadList.push_back(curInfo);
threadNum++;
locker.unlock(); //prevent possible deadlocks
GuiUpdateThreadView();
}
@ -61,12 +64,14 @@ void threadcreate(CREATE_THREAD_DEBUG_INFO* CreateThread)
void threadexit(DWORD dwThreadId)
{
CriticalSectionLocker locker(LockThreads);
for(unsigned int i = 0; i < threadList.size(); i++)
if(threadList.at(i).dwThreadId == dwThreadId)
{
threadList.erase(threadList.begin() + i);
break;
}
locker.unlock(); //prevent possible deadlocks
GuiUpdateThreadView();
}
@ -79,7 +84,9 @@ void threadexit(DWORD dwThreadId)
void threadclear()
{
threadNum = 0;
CriticalSectionLocker locker(LockThreads);
std::vector<THREADINFO>().swap(threadList);
locker.unlock(); //prevent possible deadlocks
GuiUpdateThreadView();
}
@ -127,6 +134,7 @@ static DWORD GetThreadLastError(uint tebAddress)
void threadgetlist(THREADLIST* list)
{
CriticalSectionLocker locker(LockThreads);
int count = (int)threadList.size();
list->count = count;
if(!count)
@ -161,6 +169,7 @@ void threadgetlist(THREADLIST* list)
bool threadisvalid(DWORD dwThreadId)
{
CriticalSectionLocker locker(LockThreads);
for(unsigned int i = 0; i < threadList.size(); i++)
if(threadList.at(i).dwThreadId == dwThreadId)
return true;
@ -180,6 +189,7 @@ bool threadisvalid(DWORD dwThreadId)
bool threadsetname(DWORD dwThreadId, const char* name)
{
CriticalSectionLocker locker(LockThreads);
for(unsigned int i = 0; i < threadList.size(); i++)
if(threadList.at(i).dwThreadId == dwThreadId)
{
@ -203,6 +213,7 @@ bool threadsetname(DWORD dwThreadId, const char* name)
HANDLE threadgethandle(DWORD dwThreadId)
{
CriticalSectionLocker locker(LockThreads);
for(unsigned int i = 0; i < threadList.size(); i++)
if(threadList.at(i).dwThreadId == dwThreadId)
return threadList.at(i).hThread;
@ -221,6 +232,7 @@ HANDLE threadgethandle(DWORD dwThreadId)
DWORD threadgetid(HANDLE hThread)
{
CriticalSectionLocker locker(LockThreads);
for(unsigned int i = 0; i < threadList.size(); i++)
if(threadList.at(i).hThread == hThread)
return threadList.at(i).dwThreadId;

View File

@ -21,6 +21,16 @@ bool waitislocked(WAIT_ID id);
enum CriticalSectionLock
{
LockMemoryPages,
LockVariables,
LockModules,
LockComments,
LockLabels,
LockBookmarks,
LockFunctions,
LockLoops,
LockBreakpoints,
LockPatches,
LockThreads,
LockLast
};

View File

@ -303,16 +303,193 @@ static bool isregister(const char* string)
return false;
}
/**
@fn bool valflagfromstring(uint eflags, const char* string)
#define MXCSRFLAG_IE 0x1
#define MXCSRFLAG_DE 0x2
#define MXCSRFLAG_ZE 0x4
#define MXCSRFLAG_OE 0x8
#define MXCSRFLAG_UE 0x10
#define MXCSRFLAG_PE 0x20
#define MXCSRFLAG_DAZ 0x40
#define MXCSRFLAG_IM 0x80
#define MXCSRFLAG_DM 0x100
#define MXCSRFLAG_ZM 0x200
#define MXCSRFLAG_OM 0x400
#define MXCSRFLAG_UM 0x800
#define MXCSRFLAG_PM 0x1000
#define MXCSRFLAG_FZ 0x8000
@brief Valflagfromstrings.
typedef struct
{
char* name;
unsigned int flag;
@param eflags The eflags.
@param string The string.
} FLAG_NAME_VALUE_TABLE_t;
@return true if it succeeds, false if it fails.
*/
#define MXCSR_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, MXCSRFLAG_##flag_name }
unsigned int getmxcsrflagfromstring(const char* string)
{
static FLAG_NAME_VALUE_TABLE_t mxcsrnameflagtable[] =
{
MXCSR_NAME_FLAG_TABLE_ENTRY(IE),
MXCSR_NAME_FLAG_TABLE_ENTRY(DE),
MXCSR_NAME_FLAG_TABLE_ENTRY(ZE),
MXCSR_NAME_FLAG_TABLE_ENTRY(OE),
MXCSR_NAME_FLAG_TABLE_ENTRY(UE),
MXCSR_NAME_FLAG_TABLE_ENTRY(PE),
MXCSR_NAME_FLAG_TABLE_ENTRY(DAZ),
MXCSR_NAME_FLAG_TABLE_ENTRY(IM),
MXCSR_NAME_FLAG_TABLE_ENTRY(DM),
MXCSR_NAME_FLAG_TABLE_ENTRY(ZM),
MXCSR_NAME_FLAG_TABLE_ENTRY(OM),
MXCSR_NAME_FLAG_TABLE_ENTRY(UM),
MXCSR_NAME_FLAG_TABLE_ENTRY(PM),
MXCSR_NAME_FLAG_TABLE_ENTRY(FZ)
};
int i;
for(i = 0; i < (sizeof(mxcsrnameflagtable) / sizeof(*mxcsrnameflagtable)); i++)
{
if(scmp(string, mxcsrnameflagtable[i].name))
return mxcsrnameflagtable[i].flag;
}
return 0;
}
bool valmxcsrflagfromstring(uint mxcsrflags, const char* string)
{
unsigned int flag = getmxcsrflagfromstring(string);
if(flag == 0)
return false;
return (bool)((int)(mxcsrflags & flag) != 0);
}
#define x87STATUSWORD_FLAG_I 0x1
#define x87STATUSWORD_FLAG_D 0x2
#define x87STATUSWORD_FLAG_Z 0x4
#define x87STATUSWORD_FLAG_O 0x8
#define x87STATUSWORD_FLAG_U 0x10
#define x87STATUSWORD_FLAG_P 0x20
#define x87STATUSWORD_FLAG_SF 0x40
#define x87STATUSWORD_FLAG_IR 0x80
#define x87STATUSWORD_FLAG_C0 0x100
#define x87STATUSWORD_FLAG_C1 0x200
#define x87STATUSWORD_FLAG_C2 0x400
#define x87STATUSWORD_FLAG_C3 0x4000
#define x87STATUSWORD_FLAG_B 0x8000
#define X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, x87STATUSWORD_FLAG_##flag_name }
unsigned int getx87statuswordflagfromstring(const char* string)
{
static FLAG_NAME_VALUE_TABLE_t statuswordflagtable[] =
{
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(I),
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(D),
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(Z),
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(O),
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(U),
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(P),
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(SF),
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(IR),
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C0),
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C1),
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C2),
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C3),
X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(B)
};
int i;
for(i = 0; i < (sizeof(statuswordflagtable) / sizeof(*statuswordflagtable)); i++)
{
if(scmp(string, statuswordflagtable[i].name))
return statuswordflagtable[i].flag;
}
return 0;
}
bool valx87statuswordflagfromstring(uint statusword, const char* string)
{
unsigned int flag = getx87statuswordflagfromstring(string);
if(flag == 0)
return false;
return (bool)((int)(statusword & flag) != 0);
}
#define x87CONTROLWORD_FLAG_IM 0x1
#define x87CONTROLWORD_FLAG_DM 0x2
#define x87CONTROLWORD_FLAG_ZM 0x4
#define x87CONTROLWORD_FLAG_OM 0x8
#define x87CONTROLWORD_FLAG_UM 0x10
#define x87CONTROLWORD_FLAG_PM 0x20
#define x87CONTROLWORD_FLAG_IEM 0x80
#define x87CONTROLWORD_FLAG_IC 0x1000
#define X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, x87CONTROLWORD_FLAG_##flag_name }
unsigned int getx87controlwordflagfromstring(const char* string)
{
static FLAG_NAME_VALUE_TABLE_t controlwordflagtable[] =
{
X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IM),
X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(DM),
X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(ZM),
X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(OM),
X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(UM),
X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(PM),
X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IEM),
X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IC)
};
int i;
for(i = 0; i < (sizeof(controlwordflagtable) / sizeof(*controlwordflagtable)); i++)
{
if(scmp(string, controlwordflagtable[i].name))
return controlwordflagtable[i].flag;
}
return 0;
}
bool valx87controlwordflagfromstring(uint controlword, const char* string)
{
unsigned int flag = getx87controlwordflagfromstring(string);
if(flag == 0)
return false;
return (bool)((int)(controlword & flag) != 0);
}
unsigned short valmxcsrfieldfromstring(uint mxcsrflags, const char* string)
{
if(scmp(string, "RC"))
return ((mxcsrflags & 0x6000) >> 13);
return 0;
}
unsigned short valx87statuswordfieldfromstring(uint statusword, const char* string)
{
if(scmp(string, "TOP"))
return ((statusword & 0x3800) >> 11);
return 0;
}
unsigned short valx87controlwordfieldfromstring(uint controlword, const char* string)
{
if(scmp(string, "PC"))
return ((controlword & 0x300) >> 8);
if(scmp(string, "RC"))
return ((controlword & 0xC00) >> 10);
return 0;
}
bool valflagfromstring(uint eflags, const char* string)
{
@ -1090,7 +1267,7 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
if(apiname)
{
char modname[MAX_MODULE_SIZE] = "";
strcpy(modname, name);
strcpy_s(modname, name);
modname[apiname - name] = 0;
apiname++;
if(!strlen(apiname))
@ -1490,6 +1667,7 @@ bool valfromstring(const char* string, uint* value, bool silent, bool baseonly,
return false; //nothing was OK
}
bool longEnough(const char* str, size_t min_length)
/**
@fn bool valfromstring(const char* string, uint* value, bool silent, bool baseonly)
@ -1503,11 +1681,16 @@ bool valfromstring(const char* string, uint* value, bool silent, bool baseonly,
@return true if it succeeds, false if it fails.
*/
bool valfromstring(const char* string, uint* value, bool silent, bool baseonly)
{
return valfromstring(string, value, silent, baseonly, 0, 0, 0);
size_t length = 0;
while(str[length] && length < min_length)
length++;
if(length == min_length)
return true;
return false;
}
bool startsWith(const char* pre, const char* str)
/**
@fn bool valfromstring(const char* string, uint* value, bool silent)
@ -1520,25 +1703,400 @@ bool valfromstring(const char* string, uint* value, bool silent, bool baseonly)
@return true if it succeeds, false if it fails.
*/
bool valfromstring(const char* string, uint* value, bool silent)
{
return valfromstring(string, value, silent, false);
size_t lenpre = strlen(pre);
return longEnough(str, lenpre) ? StrNCmpI(str, pre, (int) lenpre) == 0 : false;
}
/**
@fn bool valfromstring(const char* string, uint* value)
#define MxCsr_PRE_FIELD_STRING "MxCsr_"
#define x87SW_PRE_FIELD_STRING "x87SW_"
#define x87CW_PRE_FIELD_STRING "x87CW_"
#define x87TW_PRE_FIELD_STRING "x87TW_"
#define MMX_PRE_FIELD_STRING "MM"
#define XMM_PRE_FIELD_STRING "XMM"
#define YMM_PRE_FIELD_STRING "YMM"
#define x8780BITFPU_PRE_FIELD_STRING "x87r"
#define STRLEN_USING_SIZEOF(string) (sizeof(string) - 1)
@brief Valfromstrings.
@param string The string.
@param [in,out] value If non-null, the value.
@return true if it succeeds, false if it fails.
*/
bool valfromstring(const char* string, uint* value)
void fpustuff(const char* string, uint value)
{
return valfromstring(string, value, true);
uint xorval = 0;
uint flags = 0;
uint flag = 0;
bool set = false;
if(value)
set = true;
if(startsWith(MxCsr_PRE_FIELD_STRING, string))
{
if(StrNCmpI(string + STRLEN_USING_SIZEOF(MxCsr_PRE_FIELD_STRING), "RC", (int) strlen("RC")) == 0)
{
uint flags = GetContextDataEx(hActiveThread, UE_MXCSR);
int i = 3;
i <<= 13;
flags &= ~i;
value <<= 13;
flags |= value;
SetContextDataEx(hActiveThread, UE_MXCSR, flags);
}
else
{
uint flags = GetContextDataEx(hActiveThread, UE_MXCSR);
flag = getmxcsrflagfromstring(string + STRLEN_USING_SIZEOF(MxCsr_PRE_FIELD_STRING));
if(flags & flag and !set)
xorval = flag;
else if(set)
xorval = flag;
SetContextDataEx(hActiveThread, UE_MXCSR, flags ^ xorval);
}
}
else if(startsWith(x87TW_PRE_FIELD_STRING, string))
{
unsigned int i;
string += STRLEN_USING_SIZEOF(x87TW_PRE_FIELD_STRING);
i = atoi(string);
if(i > 7)
return;
flags = GetContextDataEx(hActiveThread, UE_X87_TAGWORD);
flag = 3;
flag <<= i * 2;
flags &= ~flag;
flag = value;
flag <<= i * 2;
flags |= flag;
SetContextDataEx(hActiveThread, UE_X87_TAGWORD, (unsigned short) flags);
}
else if(startsWith(x87SW_PRE_FIELD_STRING, string))
{
if(StrNCmpI(string + STRLEN_USING_SIZEOF(x87SW_PRE_FIELD_STRING), "TOP", (int) strlen("TOP")) == 0)
{
uint flags = GetContextDataEx(hActiveThread, UE_X87_STATUSWORD);
int i = 7;
i <<= 11;
flags &= ~i;
value <<= 11;
flags |= value;
SetContextDataEx(hActiveThread, UE_X87_STATUSWORD, flags);
}
else
{
uint flags = GetContextDataEx(hActiveThread, UE_X87_STATUSWORD);
flag = getx87statuswordflagfromstring(string + STRLEN_USING_SIZEOF(x87SW_PRE_FIELD_STRING));
if(flags & flag and !set)
xorval = flag;
else if(set)
xorval = flag;
SetContextDataEx(hActiveThread, UE_X87_STATUSWORD, flags ^ xorval);
}
}
else if(startsWith(x87CW_PRE_FIELD_STRING, string))
{
if(StrNCmpI(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING), "RC", (int) strlen("RC")) == 0)
{
uint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD);
int i = 3;
i <<= 10;
flags &= ~i;
value <<= 10;
flags |= value;
SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags);
}
else if(StrNCmpI(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING), "PC", (int) strlen("PC")) == 0)
{
uint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD);
int i = 3;
i <<= 8;
flags &= ~i;
value <<= 8;
flags |= value;
SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags);
}
else
{
uint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD);
flag = getx87controlwordflagfromstring(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING));
if(flags & flag and !set)
xorval = flag;
else if(set)
xorval = flag;
SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags ^ xorval);
}
}
else if(StrNCmpI(string, "x87TagWord", (int) strlen(string)) == 0)
{
SetContextDataEx(hActiveThread, UE_X87_TAGWORD, (unsigned short) value);
}
else if(StrNCmpI(string, "x87StatusWord", (int) strlen(string)) == 0)
{
SetContextDataEx(hActiveThread, UE_X87_STATUSWORD, (unsigned short) value);
}
else if(StrNCmpI(string, "x87ControlWord", (int) strlen(string)) == 0)
{
SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, (unsigned short) value);
}
else if(StrNCmpI(string, "MxCsr", (int) strlen(string)) == 0)
{
SetContextDataEx(hActiveThread, UE_MXCSR, value);
}
else if(startsWith(x8780BITFPU_PRE_FIELD_STRING, string))
{
string += STRLEN_USING_SIZEOF(x8780BITFPU_PRE_FIELD_STRING);
DWORD registerindex;
bool found = true;
switch(*string)
{
case '0':
registerindex = UE_x87_r0;
break;
case '1':
registerindex = UE_x87_r1;
break;
case '2':
registerindex = UE_x87_r2;
break;
case '3':
registerindex = UE_x87_r3;
break;
case '4':
registerindex = UE_x87_r4;
break;
case '5':
registerindex = UE_x87_r5;
break;
case '6':
registerindex = UE_x87_r6;
break;
case '7':
registerindex = UE_x87_r7;
break;
default:
found = false;
break;
}
if(found)
SetContextDataEx(hActiveThread, registerindex, value);
}
else if(startsWith(MMX_PRE_FIELD_STRING, string))
{
string += STRLEN_USING_SIZEOF(MMX_PRE_FIELD_STRING);
DWORD registerindex;
bool found = true;
switch(*string)
{
case '0':
registerindex = UE_MMX0;
break;
case '1':
registerindex = UE_MMX1;
break;
case '2':
registerindex = UE_MMX2;
break;
case '3':
registerindex = UE_MMX3;
break;
case '4':
registerindex = UE_MMX4;
break;
case '5':
registerindex = UE_MMX5;
break;
case '6':
registerindex = UE_MMX6;
break;
case '7':
registerindex = UE_MMX7;
break;
default:
found = false;
break;
}
if(found)
SetContextDataEx(hActiveThread, registerindex, value);
}
else if(startsWith(XMM_PRE_FIELD_STRING, string))
{
string += STRLEN_USING_SIZEOF(XMM_PRE_FIELD_STRING);
DWORD registerindex;
bool found = true;
switch(atoi(string))
{
case 0:
registerindex = UE_XMM0;
break;
case 1:
registerindex = UE_XMM1;
break;
case 2:
registerindex = UE_XMM2;
break;
case 3:
registerindex = UE_XMM3;
break;
case 4:
registerindex = UE_XMM4;
break;
case 5:
registerindex = UE_XMM5;
break;
case 6:
registerindex = UE_XMM6;
break;
case 7:
registerindex = UE_XMM7;
break;
case 8:
registerindex = UE_XMM8;
break;
case 9:
registerindex = UE_XMM9;
break;
case 10:
registerindex = UE_XMM10;
break;
case 11:
registerindex = UE_XMM11;
break;
case 12:
registerindex = UE_XMM12;
break;
case 13:
registerindex = UE_XMM13;
break;
case 14:
registerindex = UE_XMM14;
break;
case 15:
registerindex = UE_XMM15;
break;
default:
found = false;
break;
}
if(found)
SetContextDataEx(hActiveThread, registerindex, value);
}
else if(startsWith(YMM_PRE_FIELD_STRING, string))
{
string += STRLEN_USING_SIZEOF(YMM_PRE_FIELD_STRING);
DWORD registerindex;
bool found = true;
switch(atoi(string))
{
case 0:
registerindex = UE_YMM0;
break;
case 1:
registerindex = UE_YMM1;
break;
case 2:
registerindex = UE_YMM2;
break;
case 3:
registerindex = UE_YMM3;
break;
case 4:
registerindex = UE_YMM4;
break;
case 5:
registerindex = UE_YMM5;
break;
case 6:
registerindex = UE_YMM6;
break;
case 7:
registerindex = UE_YMM7;
break;
case 8:
registerindex = UE_YMM8;
break;
case 9:
registerindex = UE_YMM9;
break;
case 10:
registerindex = UE_YMM10;
break;
case 11:
registerindex = UE_YMM11;
break;
case 12:
registerindex = UE_YMM12;
break;
case 13:
registerindex = UE_YMM13;
break;
case 14:
registerindex = UE_YMM14;
break;
case 15:
registerindex = UE_YMM15;
break;
default:
found = false;
break;
}
if(found)
SetContextDataEx(hActiveThread, registerindex, value);
}
}
/**
@ -1628,11 +2186,25 @@ bool valtostring(const char* string, uint* value, bool silent)
{
uint csp = GetContextDataEx(hActiveThread, UE_CSP);
GuiStackDumpAt(csp, csp);
GuiUpdateRegisterView();
}
else
GuiUpdateAllViews(); //repaint gui
return ok;
}
else if((*string == '_'))
{
if(!DbgIsDebugging())
{
if(!silent)
dputs("not debugging!");
return false;
}
fpustuff(string + 1, * value);
GuiUpdateAllViews(); //repaint gui
return true;
}
else if(*string == '!' and isflag(string + 1)) //flag
{
if(!DbgIsDebugging())

View File

@ -7,11 +7,15 @@
bool valuesignedcalc();
void valuesetsignedcalc(bool a);
bool valapifromstring(const char* name, uint* value, int* value_size, bool printall, bool silent, bool* hexonly);
bool valfromstring(const char* string, uint* value, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly);
bool valfromstring(const char* string, uint* value, bool silent, bool baseonly);
bool valfromstring(const char* string, uint* value, bool silent);
bool valfromstring(const char* string, uint* value);
bool valfromstring(const char* string, uint* value, bool silent = true, bool baseonly = false, int* value_size = 0, bool* isvar = 0, bool* hexonly = 0);
bool valflagfromstring(uint eflags, const char* string);
bool valtostring(const char* string, uint* value, bool silent);
bool valmxcsrflagfromstring(uint mxcsrflags, const char* string);
bool valx87statuswordflagfromstring(uint statusword, const char* string);
bool valx87controlwordflagfromstring(uint controlword, const char* string);
unsigned short valmxcsrfieldfromstring(uint mxcsrflags, const char* string);
unsigned short valx87statuswordfieldfromstring(uint statusword, const char* string);
unsigned short valx87controlwordfieldfromstring(uint controlword, const char* string);
void fpustuff(const char* string, uint value);
#endif // _VALUE_H

View File

@ -5,6 +5,7 @@
*/
#include "variable.h"
#include "threading.h"
/**
@brief The variables.
@ -55,7 +56,8 @@ static void varsetvalue(VAR* var, VAR_VALUE* value)
static bool varset(const char* name, VAR_VALUE* value, bool setreadonly)
{
std::string name_;
CriticalSectionLocker locker(LockVariables);
String name_;
if(*name != '$')
name_ = "$";
name_ += name;
@ -78,7 +80,7 @@ static bool varset(const char* name, VAR_VALUE* value, bool setreadonly)
void varinit()
{
variables.clear();
varfree();
//General variables
varnew("$result\1$res", 0, VAR_SYSTEM);
varnew("$result1\1$res1", 0, VAR_SYSTEM);
@ -104,6 +106,7 @@ void varinit()
void varfree()
{
CriticalSectionLocker locker(LockVariables);
variables.clear();
}
@ -120,9 +123,6 @@ VAR* vargetptr()
return 0;
}
#include <iostream>
#include <sstream>
/**
@fn std::vector<std::string> & split(const std::string & s, char delim, std::vector<std::string> & elems)
@ -135,19 +135,6 @@ VAR* vargetptr()
@return A std::vector&lt;std::string&gt;&amp;
*/
std::vector<std::string> & split(const std::string & s, char delim, std::vector<std::string> & elems)
{
std::stringstream ss(s);
std::string item;
while(std::getline(ss, item, delim))
{
if(!item.length())
continue;
elems.push_back(item);
}
return elems;
}
/**
@fn std::vector<std::string> split(const std::string & s, char delim)
@ -159,13 +146,6 @@ std::vector<std::string> & split(const std::string & s, char delim, std::vector<
@return A std::vector&lt;std::string&gt;
*/
std::vector<std::string> split(const std::string & s, char delim)
{
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
/**
@fn bool varnew(const char* name, uint value, VAR_TYPE type)
@ -180,13 +160,14 @@ std::vector<std::string> split(const std::string & s, char delim)
bool varnew(const char* name, uint value, VAR_TYPE type)
{
CriticalSectionLocker locker(LockVariables);
if(!name)
return false;
std::vector<std::string> names = split(name, '\1');
std::string firstName;
std::vector<String> names = StringUtils::Split(name, '\1');
String firstName;
for(int i = 0; i < (int)names.size(); i++)
{
std::string name_;
String name_;
name = names.at(i).c_str();
if(*name != '$')
name_ = "$";
@ -223,7 +204,8 @@ bool varnew(const char* name, uint value, VAR_TYPE type)
static bool varget(const char* name, VAR_VALUE* value, int* size, VAR_TYPE* type)
{
std::string name_;
CriticalSectionLocker locker(LockVariables);
String name_;
if(*name != '$')
name_ = "$";
name_ += name;
@ -367,7 +349,8 @@ bool varset(const char* name, const char* string, bool setreadonly)
bool vardel(const char* name, bool delsystem)
{
std::string name_;
CriticalSectionLocker locker(LockVariables);
String name_;
if(*name != '$')
name_ = "$";
name_ += name;
@ -383,7 +366,7 @@ bool vardel(const char* name, bool delsystem)
{
VariableMap::iterator del = found;
found++;
if(found->second.name == std::string(name))
if(found->second.name == String(name))
variables.erase(del);
}
return true;
@ -403,7 +386,8 @@ bool vardel(const char* name, bool delsystem)
bool vargettype(const char* name, VAR_TYPE* type, VAR_VALUE_TYPE* valtype)
{
std::string name_;
CriticalSectionLocker locker(LockVariables);
String name_;
if(*name != '$')
name_ = "$";
name_ += name;
@ -432,6 +416,7 @@ bool vargettype(const char* name, VAR_TYPE* type, VAR_VALUE_TYPE* valtype)
bool varenum(VAR* entries, size_t* cbsize)
{
CriticalSectionLocker locker(LockVariables);
if(!entries && !cbsize || !variables.size())
return false;
if(!entries && cbsize)

View File

@ -32,21 +32,21 @@ struct VAR_VALUE
struct VAR
{
std::string name;
std::string alias;
String name;
String alias;
VAR_TYPE type;
VAR_VALUE value;
};
struct CaseInsensitiveCompare
{
bool operator()(const std::string & str1, const std::string & str2) const
bool operator()(const String & str1, const String & str2) const
{
return _stricmp(str1.c_str(), str2.c_str()) < 0;
}
};
typedef std::map<std::string, VAR, CaseInsensitiveCompare> VariableMap;
typedef std::map<String, VAR, CaseInsensitiveCompare> VariableMap;
//functions
void varinit();

View File

@ -10,7 +10,6 @@
#include "variable.h"
#include "instruction.h"
#include "debugger.h"
#include "data.h"
#include "simplescript.h"
#include "console.h"
#include "math.h"
@ -235,12 +234,13 @@ static void registercommands()
dbgcmdnew("msgyn", cbScriptMsgyn, false);
//data
dbgcmdnew("reffind\1findref\1ref", cbInstrRefFind, true);
dbgcmdnew("refstr\1strref", cbInstrRefStr, true);
dbgcmdnew("reffind\1findref\1ref", cbInstrRefFind, true); //find references to a value
dbgcmdnew("refstr\1strref", cbInstrRefStr, true); //find string references
dbgcmdnew("find", cbInstrFind, true); //find a pattern
dbgcmdnew("findall", cbInstrFindAll, true); //find all patterns
dbgcmdnew("modcallfind", cbInstrModCallFind, true); //find intermodular calls
dbgcmdnew("findasm\1asmfind", cbInstrFindAsm, true); //find instruction
dbgcmdnew("reffindrange\1findrefrange\1refrange", cbInstrRefFindRange, true);
//undocumented
dbgcmdnew("bench", cbDebugBenchmark, true); //benchmark test (readmem etc)
@ -349,6 +349,8 @@ static void efree_json(void* ptr)
extern "C" DLL_EXPORT const char* _dbg_dbginit()
{
if(!EngineCheckStructAlignment(UE_STRUCT_TITAN_ENGINE_CONTEXT, sizeof(TITAN_ENGINE_CONTEXT_t)))
return "Invalid TITAN_ENGINE_CONTEXT_t alignment!";
dbginit();
dbgfunctionsinit();
json_set_alloc_funcs(emalloc_json, efree_json);
@ -356,21 +358,21 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
if(!GetModuleFileNameW(hInst, wszDir, deflen))
return "GetModuleFileNameW failed!";
char dir[deflen] = "";
strcpy_s(dir, ConvertUtf16ToUtf8(wszDir).c_str());
strcpy_s(dir, StringUtils::Utf16ToUtf8(wszDir).c_str());
int len = (int)strlen(dir);
while(dir[len] != '\\')
len--;
dir[len] = 0;
strcpy(alloctrace, dir);
PathAppendA(alloctrace, "\\alloctrace.txt");
DeleteFileW(ConvertUtf8ToUtf16(alloctrace).c_str());
DeleteFileW(StringUtils::Utf8ToUtf16(alloctrace).c_str());
setalloctrace(alloctrace);
strcpy(dbbasepath, dir); //debug directory
PathAppendA(dbbasepath, "db");
CreateDirectoryW(ConvertUtf8ToUtf16(dbbasepath).c_str(), 0); //create database directory
CreateDirectoryW(StringUtils::Utf8ToUtf16(dbbasepath).c_str(), 0); //create database directory
strcpy(szSymbolCachePath, dir);
PathAppendA(szSymbolCachePath, "symbols");
SetCurrentDirectoryW(ConvertUtf8ToUtf16(dir).c_str());;
SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(dir).c_str());;
gMsgStack = msgallocstack();
if(!gMsgStack)
return "Could not allocate message stack!";
@ -380,15 +382,15 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
char plugindir[deflen] = "";
strcpy(plugindir, dir);
PathAppendA(plugindir, "plugins");
CreateDirectoryW(ConvertUtf8ToUtf16(plugindir).c_str(), 0);
CreateDirectoryW(StringUtils::Utf8ToUtf16(plugindir).c_str(), 0);
pluginload(plugindir);
//handle command line
int argc = 0;
wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc);
if(argc == 2) //we have an argument
{
UString str = "init \"";
str += ConvertUtf16ToUtf8(argv[1]);
String str = "init \"";
str += StringUtils::Utf16ToUtf8(argv[1]);
str += "\"";
DbgCmdExec(str.c_str());
}
@ -396,10 +398,10 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
{
if(_wcsicmp(argv[1], L"-a") == 0 && !_wcsicmp(argv[3], L"-e"))
{
UString str = "attach .";
str += ConvertUtf16ToUtf8(argv[2]);
String str = "attach .";
str += StringUtils::Utf16ToUtf8(argv[2]);
str += ", .";
str += ConvertUtf16ToUtf8(argv[4]);
str += StringUtils::Utf16ToUtf8(argv[4]);
DbgCmdExec(str.c_str());
}
}

View File

@ -33,12 +33,10 @@
<ClCompile Include="reference.cpp" />
<ClCompile Include="simplescript.cpp" />
<ClCompile Include="stackinfo.cpp" />
<ClCompile Include="stringutils.cpp" />
<ClCompile Include="symbolinfo.cpp" />
<ClCompile Include="thread.cpp" />
<ClCompile Include="threading.cpp" />
<ClCompile Include="UString\Exception.cpp" />
<ClCompile Include="UString\String.cpp" />
<ClCompile Include="UString\UString.cpp" />
<ClCompile Include="value.cpp" />
<ClCompile Include="variable.cpp" />
<ClCompile Include="x64_dbg.cpp" />
@ -58,7 +56,6 @@
<ClInclude Include="breakpoint.h" />
<ClInclude Include="command.h" />
<ClInclude Include="console.h" />
<ClInclude Include="data.h" />
<ClInclude Include="dbghelp\dbghelp.h" />
<ClInclude Include="debugger.h" />
<ClInclude Include="debugger_commands.h" />
@ -83,14 +80,12 @@
<ClInclude Include="reference.h" />
<ClInclude Include="simplescript.h" />
<ClInclude Include="stackinfo.h" />
<ClInclude Include="stringutils.h" />
<ClInclude Include="symbolinfo.h" />
<ClInclude Include="thread.h" />
<ClInclude Include="threading.h" />
<ClInclude Include="TitanEngine\TitanEngine.h" />
<ClInclude Include="undocumented.h" />
<ClInclude Include="UString\Exception.h" />
<ClInclude Include="UString\String.h" />
<ClInclude Include="UString\UString.h" />
<ClInclude Include="value.h" />
<ClInclude Include="variable.h" />
<ClInclude Include="x64_dbg.h" />

View File

@ -13,33 +13,6 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
<Filter Include="Header Files\BeaEngine">
<UniqueIdentifier>{6028af23-e8de-4db7-b1c7-bee2b5a4402b}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\dbghelp">
<UniqueIdentifier>{5623fb24-3b6d-49a6-a0d3-1cfcc46f87bd}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\TitanEngine">
<UniqueIdentifier>{23226861-3b20-42db-8dd6-c5d276ba7a83}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\XEDParse">
<UniqueIdentifier>{6b85ff77-8866-4618-9d46-006d8c349f8f}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\DeviceNameResolver">
<UniqueIdentifier>{f4eb1487-15d6-4836-9d20-339d0f18c31f}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\jansson">
<UniqueIdentifier>{b63305e2-2b10-46eb-839f-5e9080fa8ad8}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\lz4">
<UniqueIdentifier>{6a8d58f0-1417-4bff-aecd-0f9f5e0641f9}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\UString">
<UniqueIdentifier>{adf51b13-6f3b-4b04-9ba9-21fb7a38150d}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\UString">
<UniqueIdentifier>{ee24febc-948e-4226-ba0e-68a9b449fb23}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Interfaces/Exports">
<UniqueIdentifier>{44fd9eb7-2017-49b8-8d9a-dec680632343}</UniqueIdentifier>
</Filter>
@ -55,6 +28,45 @@
<Filter Include="Source Files\Debugger Core">
<UniqueIdentifier>{52e2c3ae-0223-4216-b896-41d9f171f731}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Debugger Core">
<UniqueIdentifier>{164592cf-e2c9-4c98-abf6-ea47d37653a1}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Third Party">
<UniqueIdentifier>{d2362bf7-ff20-493d-be01-0fb7e6dca8c9}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Third Party\TitanEngine">
<UniqueIdentifier>{23226861-3b20-42db-8dd6-c5d276ba7a83}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Third Party\XEDParse">
<UniqueIdentifier>{6b85ff77-8866-4618-9d46-006d8c349f8f}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Third Party\BeaEngine">
<UniqueIdentifier>{6028af23-e8de-4db7-b1c7-bee2b5a4402b}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Third Party\dbghelp">
<UniqueIdentifier>{5623fb24-3b6d-49a6-a0d3-1cfcc46f87bd}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Third Party\DeviceNameResolver">
<UniqueIdentifier>{f4eb1487-15d6-4836-9d20-339d0f18c31f}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Third Party\jansson">
<UniqueIdentifier>{b63305e2-2b10-46eb-839f-5e9080fa8ad8}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Third Party\lz4">
<UniqueIdentifier>{6a8d58f0-1417-4bff-aecd-0f9f5e0641f9}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Interfaces/Exports">
<UniqueIdentifier>{714f2eb1-20d7-47ed-a641-ba8a66da2e7a}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Utilities">
<UniqueIdentifier>{938130d5-63d6-44c2-9604-70f1f101890c}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Core">
<UniqueIdentifier>{ccf4c0a0-bb97-4090-acc5-bc6b343300bf}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Information">
<UniqueIdentifier>{b006b04c-d7ea-49cb-b097-0cac1388f98e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
@ -63,15 +75,6 @@
<ClCompile Include="x64_dbg.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UString\Exception.cpp">
<Filter>Source Files\UString</Filter>
</ClCompile>
<ClCompile Include="UString\String.cpp">
<Filter>Source Files\UString</Filter>
</ClCompile>
<ClCompile Include="UString\UString.cpp">
<Filter>Source Files\UString</Filter>
</ClCompile>
<ClCompile Include="_dbgfunctions.cpp">
<Filter>Source Files\Interfaces/Exports</Filter>
</ClCompile>
@ -96,12 +99,6 @@
<ClCompile Include="math.cpp">
<Filter>Source Files\Core</Filter>
</ClCompile>
<ClCompile Include="murmurhash.cpp">
<Filter>Source Files\Core</Filter>
</ClCompile>
<ClCompile Include="msgqueue.cpp">
<Filter>Source Files\Core</Filter>
</ClCompile>
<ClCompile Include="threading.cpp">
<Filter>Source Files\Core</Filter>
</ClCompile>
@ -162,163 +159,163 @@
<ClCompile Include="log.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="stringutils.cpp">
<Filter>Source Files\Utilities</Filter>
</ClCompile>
<ClCompile Include="murmurhash.cpp">
<Filter>Source Files\Utilities</Filter>
</ClCompile>
<ClCompile Include="msgqueue.cpp">
<Filter>Source Files\Utilities</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="_exports.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="_global.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="addrinfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="argument.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="breakpoint.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="command.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="console.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="data.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="debugger.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="instruction.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="math.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="memory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="msgqueue.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="simplescript.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="threading.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="value.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="variable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="x64_dbg.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="plugin_loader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="_plugins.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="_plugin_types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="assemble.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="disasm_helper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="symbolinfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="stackinfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="thread.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="undocumented.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="disasm_fast.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="reference.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="BeaEngine\basic_types.h">
<Filter>Header Files\BeaEngine</Filter>
<Filter>Header Files\Third Party\BeaEngine</Filter>
</ClInclude>
<ClInclude Include="BeaEngine\BeaEngine.h">
<Filter>Header Files\BeaEngine</Filter>
<Filter>Header Files\Third Party\BeaEngine</Filter>
</ClInclude>
<ClInclude Include="BeaEngine\export.h">
<Filter>Header Files\BeaEngine</Filter>
<Filter>Header Files\Third Party\BeaEngine</Filter>
</ClInclude>
<ClInclude Include="BeaEngine\macros.h">
<Filter>Header Files\BeaEngine</Filter>
<Filter>Header Files\Third Party\BeaEngine</Filter>
</ClInclude>
<ClInclude Include="dbghelp\dbghelp.h">
<Filter>Header Files\dbghelp</Filter>
<Filter>Header Files\Third Party\dbghelp</Filter>
</ClInclude>
<ClInclude Include="XEDParse\XEDParse.h">
<Filter>Header Files\XEDParse</Filter>
<Filter>Header Files\Third Party\XEDParse</Filter>
</ClInclude>
<ClInclude Include="TitanEngine\TitanEngine.h">
<Filter>Header Files\TitanEngine</Filter>
<Filter>Header Files\Third Party\TitanEngine</Filter>
</ClInclude>
<ClInclude Include="DeviceNameResolver\DeviceNameResolver.h">
<Filter>Header Files\DeviceNameResolver</Filter>
<Filter>Header Files\Third Party\DeviceNameResolver</Filter>
</ClInclude>
<ClInclude Include="jansson\jansson.h">
<Filter>Header Files\jansson</Filter>
<Filter>Header Files\Third Party\jansson</Filter>
</ClInclude>
<ClInclude Include="jansson\jansson_config.h">
<Filter>Header Files\jansson</Filter>
</ClInclude>
<ClInclude Include="murmurhash.h">
<Filter>Header Files</Filter>
<Filter>Header Files\Third Party\jansson</Filter>
</ClInclude>
<ClInclude Include="lz4\lz4.h">
<Filter>Header Files\lz4</Filter>
<Filter>Header Files\Third Party\lz4</Filter>
</ClInclude>
<ClInclude Include="lz4\lz4file.h">
<Filter>Header Files\lz4</Filter>
<Filter>Header Files\Third Party\lz4</Filter>
</ClInclude>
<ClInclude Include="lz4\lz4hc.h">
<Filter>Header Files\lz4</Filter>
<Filter>Header Files\Third Party\lz4</Filter>
</ClInclude>
<ClInclude Include="_dbgfunctions.h">
<Filter>Header Files</Filter>
<ClInclude Include="_global.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
<ClInclude Include="patches.h">
<Filter>Header Files</Filter>
<ClInclude Include="argument.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
<ClInclude Include="console.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
<ClInclude Include="command.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
<ClInclude Include="math.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
<ClInclude Include="threading.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
<ClInclude Include="value.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
<ClInclude Include="variable.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
<ClInclude Include="plugin_loader.h">
<Filter>Header Files\Core</Filter>
</ClInclude>
<ClInclude Include="debugger.h">
<Filter>Header Files\Debugger Core</Filter>
</ClInclude>
<ClInclude Include="debugger_commands.h">
<Filter>Header Files</Filter>
<Filter>Header Files\Debugger Core</Filter>
</ClInclude>
<ClInclude Include="handle.h">
<Filter>Header Files</Filter>
<ClInclude Include="instruction.h">
<Filter>Header Files\Debugger Core</Filter>
</ClInclude>
<ClInclude Include="addrinfo.h">
<Filter>Header Files\Information</Filter>
</ClInclude>
<ClInclude Include="breakpoint.h">
<Filter>Header Files\Information</Filter>
</ClInclude>
<ClInclude Include="stackinfo.h">
<Filter>Header Files\Information</Filter>
</ClInclude>
<ClInclude Include="symbolinfo.h">
<Filter>Header Files\Information</Filter>
</ClInclude>
<ClInclude Include="_plugins.h">
<Filter>Header Files\Interfaces/Exports</Filter>
</ClInclude>
<ClInclude Include="_exports.h">
<Filter>Header Files\Interfaces/Exports</Filter>
</ClInclude>
<ClInclude Include="_dbgfunctions.h">
<Filter>Header Files\Interfaces/Exports</Filter>
</ClInclude>
<ClInclude Include="_plugin_types.h">
<Filter>Header Files\Interfaces/Exports</Filter>
</ClInclude>
<ClInclude Include="assemble.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="disasm_fast.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="disasm_helper.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="memory.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="patches.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="reference.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="simplescript.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="thread.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="dynamicmem.h">
<Filter>Header Files</Filter>
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="handle.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="log.h">
<Filter>Header Files</Filter>
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="UString\Exception.h">
<Filter>Header Files\UString</Filter>
<ClInclude Include="undocumented.h">
<Filter>Header Files\Debugger Core</Filter>
</ClInclude>
<ClInclude Include="UString\String.h">
<Filter>Header Files\UString</Filter>
<ClInclude Include="stringutils.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="UString\UString.h">
<Filter>Header Files\UString</Filter>
<ClInclude Include="murmurhash.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="msgqueue.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -17,6 +17,7 @@
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
@ -55,12 +56,10 @@ IDI_ICON1 ICON "..\\bug.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Manifest
// RT_MANIFEST
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
1 RT_MANIFEST ".\\manifest.xml"
1 RT_MANIFEST ".\\manifest.xml"
/////////////////////////////////////////////////////////////////////////////
//
@ -68,8 +67,8 @@ IDI_ICON1 ICON "..\\bug.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,0,2,2
PRODUCTVERSION 0,0,2,2
FILEVERSION 0,0,2,3
PRODUCTVERSION 0,0,2,3
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -85,7 +84,7 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "x64_dbg"
VALUE "FileVersion", "0.0.2.2"
VALUE "FileVersion", "0.0.2.3"
VALUE "LegalCopyright", "x64dbg.com"
VALUE "ProductName", "x64_dbg"
VALUE "ProductVersion", "V2.2ALPHA"

View File

@ -19,6 +19,10 @@
<ItemGroup>
<ResourceCompile Include="resource.rc" />
</ItemGroup>
<ItemGroup>
<None Include="..\bug.ico" />
<None Include="manifest.xml" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3A22175E-6B72-FDCC-1603-C4A2163C7900}</ProjectGuid>
<Keyword>Win32Proj</Keyword>

View File

@ -29,4 +29,10 @@
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\bug.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="manifest.xml" />
</ItemGroup>
</Project>

View File

@ -267,26 +267,30 @@ void HexDump::printSelected(QPainter* painter, int_t rowBase, int rowOffset, int
{
if((col > 0) && ((col - 1) < mDescriptor.size()))
{
int wI = 0;
ColumnDescriptor_t curDescriptor = mDescriptor.at(col - 1);
int wBytePerRowCount = getBytePerRowCount();
int_t wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset;
int wItemPixWidth = getItemPixelWidth(mDescriptor.at(col - 1));
int wItemPixWidth = getItemPixelWidth(curDescriptor);
int wCharWidth = getCharWidth();
if(wItemPixWidth == wCharWidth)
x += 4;
int wSelectionX;
int wSelectionWidth;
for(wI = 0; wI < mDescriptor.at(col - 1).itemCount; wI++)
for(int i = 0; i < curDescriptor.itemCount; i++)
{
if(isSelected(wRva + wI * getSizeOf(mDescriptor.at(col - 1).data.itemSize)) == true)
int wSelectionX = x + i * wItemPixWidth;
if(isSelected(wRva + i * getSizeOf(curDescriptor.data.itemSize)) == true)
{
wSelectionX = x + wI * wItemPixWidth;
wSelectionWidth = wItemPixWidth > w - (wSelectionX - x) ? w - (wSelectionX - x) : wItemPixWidth;
int wSelectionWidth = wItemPixWidth > w - (wSelectionX - x) ? w - (wSelectionX - x) : wItemPixWidth;
wSelectionWidth = wSelectionWidth < 0 ? 0 : wSelectionWidth;
painter->setPen(textColor);
painter->fillRect(QRect(wSelectionX, y, wSelectionWidth, h), QBrush(selectionColor));
}
int separator = curDescriptor.separator;
if(i && separator && !(i % separator))
{
painter->setPen(separatorColor);
painter->drawLine(wSelectionX, y, wSelectionX, y + h);
}
}
}
}

View File

@ -72,6 +72,7 @@ public:
{
bool isData;
int itemCount;
int separator;
DataDescriptor_t data;
} ColumnDescriptor_t;

View File

@ -262,6 +262,9 @@ void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event)
if(historyHasNext())
mGotoMenu->addAction(mGotoNext);
mGotoMenu->addAction(mGotoExpression);
char modname[MAX_MODULE_SIZE] = "";
if(DbgGetModuleAt(wVA, modname))
mGotoMenu->addAction(mGotoFileOffset);
wMenu->addMenu(mGotoMenu);
wMenu->addSeparator();
@ -436,6 +439,10 @@ void CPUDisassembly::setupRightClickContextMenu()
this->addAction(mGotoExpression);
connect(mGotoExpression, SIGNAL(triggered()), this, SLOT(gotoExpression()));
// File offset action
mGotoFileOffset = new QAction("File Offset", this);
connect(mGotoFileOffset, SIGNAL(triggered()), this, SLOT(gotoFileOffset()));
//-------------------- Follow in Dump ----------------------------
// Menu
mFollowMenu = new QMenu("&Follow in Dump", this);
@ -889,6 +896,27 @@ void CPUDisassembly::gotoExpression()
}
}
void CPUDisassembly::gotoFileOffset()
{
if(!DbgIsDebugging())
return;
char modname[MAX_MODULE_SIZE] = "";
if(!DbgFunctions()->ModNameFromAddr(rvaToVa(getInitialSelection()), modname, true))
{
QMessageBox::critical(this, "Error!", "Not inside a module...");
return;
}
GotoDialog mGotoDialog(this);
mGotoDialog.fileOffset = true;
mGotoDialog.modName = QString(modname);
mGotoDialog.setWindowTitle("Goto File Offset in " + QString(modname));
if(mGotoDialog.exec() != QDialog::Accepted)
return;
uint_t value = DbgValFromString(mGotoDialog.expressionText.toUtf8().constData());
value = DbgFunctions()->FileOffsetToVa(modname, value);
DbgCmdExec(QString().sprintf("disasm \"%p\"", value).toUtf8().constData());
}
void CPUDisassembly::followActionSlot()
{
QAction* action = qobject_cast<QAction*>(sender());

View File

@ -43,6 +43,7 @@ public slots:
void toggleFunction();
void assembleAt();
void gotoExpression();
void gotoFileOffset();
void followActionSlot();
void gotoPrevious();
void gotoNext();
@ -102,6 +103,7 @@ private:
QAction* msetHwBPOnSlot2Action;
QAction* msetHwBPOnSlot3Action;
QAction* mGotoExpression;
QAction* mGotoFileOffset;
QAction* mGotoPrevious;
QAction* mGotoNext;
QAction* mReferenceSelectedAddress;

View File

@ -231,6 +231,12 @@ void CPUDump::setupContextMenu()
this->addAction(mFindPatternAction);
connect(mFindPatternAction, SIGNAL(triggered()), this, SLOT(findPattern()));
//Find References
mFindReferencesAction = new QAction("Find &References", this);
mFindReferencesAction->setShortcutContext(Qt::WidgetShortcut);
this->addAction(mFindReferencesAction);
connect(mFindReferencesAction, SIGNAL(triggered()), this, SLOT(findReferencesSlot()));
//Goto menu
mGotoMenu = new QMenu("&Goto", this);
//Goto->Expression
@ -240,6 +246,11 @@ void CPUDump::setupContextMenu()
connect(mGotoExpression, SIGNAL(triggered()), this, SLOT(gotoExpressionSlot()));
mGotoMenu->addAction(mGotoExpression);
// Goto->File offset
mGotoFileOffset = new QAction("File Offset", this);
connect(mGotoFileOffset, SIGNAL(triggered()), this, SLOT(gotoFileOffsetSlot()));
mGotoMenu->addAction(mGotoFileOffset);
//Hex menu
mHexMenu = new QMenu("&Hex", this);
//Hex->Ascii
@ -344,6 +355,7 @@ void CPUDump::refreshShortcutsSlot()
mUndoSelection->setShortcut(ConfigShortcut("ActionUndoSelection"));
mSetLabelAction->setShortcut(ConfigShortcut("ActionSetLabel"));
mFindPatternAction->setShortcut(ConfigShortcut("ActionFindPattern"));
mFindReferencesAction->setShortcut(ConfigShortcut("ActionFindReferences"));
mGotoExpression->setShortcut(ConfigShortcut("ActionGotoExpression"));
}
@ -552,6 +564,27 @@ void CPUDump::gotoExpressionSlot()
}
}
void CPUDump::gotoFileOffsetSlot()
{
if(!DbgIsDebugging())
return;
char modname[MAX_MODULE_SIZE] = "";
if(!DbgFunctions()->ModNameFromAddr(rvaToVa(getInitialSelection()), modname, true))
{
QMessageBox::critical(this, "Error!", "Not inside a module...");
return;
}
GotoDialog mGotoDialog(this);
mGotoDialog.fileOffset = true;
mGotoDialog.modName = QString(modname);
mGotoDialog.setWindowTitle("Goto File Offset in " + QString(modname));
if(mGotoDialog.exec() != QDialog::Accepted)
return;
uint_t value = DbgValFromString(mGotoDialog.expressionText.toUtf8().constData());
value = DbgFunctions()->FileOffsetToVa(modname, value);
DbgCmdExec(QString().sprintf("dump \"%p\"", value).toUtf8().constData());
}
void CPUDump::hexAsciiSlot()
{
Config()->setUint("HexDump", "DefaultView", (uint_t)ViewHexAscii);
@ -561,6 +594,7 @@ void CPUDump::hexAsciiSlot()
wColDesc.isData = true; //hex byte
wColDesc.itemCount = 16;
wColDesc.separator = 4;
dDesc.itemSize = Byte;
dDesc.byteMode = HexByte;
wColDesc.data = dDesc;
@ -568,6 +602,7 @@ void CPUDump::hexAsciiSlot()
wColDesc.isData = true; //ascii byte
wColDesc.itemCount = 16;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -575,6 +610,7 @@ void CPUDump::hexAsciiSlot()
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -592,6 +628,7 @@ void CPUDump::hexUnicodeSlot()
wColDesc.isData = true; //hex byte
wColDesc.itemCount = 16;
wColDesc.separator = 4;
dDesc.itemSize = Byte;
dDesc.byteMode = HexByte;
wColDesc.data = dDesc;
@ -599,6 +636,7 @@ void CPUDump::hexUnicodeSlot()
wColDesc.isData = true; //unicode short
wColDesc.itemCount = 8;
wColDesc.separator = 0;
dDesc.itemSize = Word;
dDesc.wordMode = UnicodeWord;
wColDesc.data = dDesc;
@ -606,6 +644,7 @@ void CPUDump::hexUnicodeSlot()
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -623,6 +662,7 @@ void CPUDump::textAsciiSlot()
wColDesc.isData = true; //ascii byte
wColDesc.itemCount = 64;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -630,6 +670,7 @@ void CPUDump::textAsciiSlot()
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -647,6 +688,7 @@ void CPUDump::textUnicodeSlot()
wColDesc.isData = true; //unicode short
wColDesc.itemCount = 64;
wColDesc.separator = 0;
dDesc.itemSize = Word;
dDesc.wordMode = UnicodeWord;
wColDesc.data = dDesc;
@ -654,6 +696,7 @@ void CPUDump::textUnicodeSlot()
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -671,12 +714,14 @@ void CPUDump::integerSignedShortSlot()
wColDesc.isData = true; //signed short
wColDesc.itemCount = 8;
wColDesc.separator = 0;
wColDesc.data.itemSize = Word;
wColDesc.data.wordMode = SignedDecWord;
appendResetDescriptor(8 + charwidth * 55, "Signed short (16-bit)", false, wColDesc);
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -694,12 +739,14 @@ void CPUDump::integerSignedLongSlot()
wColDesc.isData = true; //signed long
wColDesc.itemCount = 4;
wColDesc.separator = 0;
wColDesc.data.itemSize = Dword;
wColDesc.data.dwordMode = SignedDecDword;
appendResetDescriptor(8 + charwidth * 47, "Signed long (32-bit)", false, wColDesc);
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -717,12 +764,14 @@ void CPUDump::integerSignedLongLongSlot()
wColDesc.isData = true; //signed long long
wColDesc.itemCount = 2;
wColDesc.separator = 0;
wColDesc.data.itemSize = Qword;
wColDesc.data.qwordMode = SignedDecQword;
appendResetDescriptor(8 + charwidth * 41, "Signed long long (64-bit)", false, wColDesc);
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -740,12 +789,14 @@ void CPUDump::integerUnsignedShortSlot()
wColDesc.isData = true; //unsigned short
wColDesc.itemCount = 8;
wColDesc.separator = 0;
wColDesc.data.itemSize = Word;
wColDesc.data.wordMode = UnsignedDecWord;
appendResetDescriptor(8 + charwidth * 47, "Unsigned short (16-bit)", false, wColDesc);
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -763,12 +814,14 @@ void CPUDump::integerUnsignedLongSlot()
wColDesc.isData = true; //unsigned long
wColDesc.itemCount = 4;
wColDesc.separator = 0;
wColDesc.data.itemSize = Dword;
wColDesc.data.dwordMode = UnsignedDecDword;
appendResetDescriptor(8 + charwidth * 43, "Unsigned long (32-bit)", false, wColDesc);
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -786,12 +839,14 @@ void CPUDump::integerUnsignedLongLongSlot()
wColDesc.isData = true; //unsigned long long
wColDesc.itemCount = 2;
wColDesc.separator = 0;
wColDesc.data.itemSize = Qword;
wColDesc.data.qwordMode = UnsignedDecQword;
appendResetDescriptor(8 + charwidth * 41, "Unsigned long long (64-bit)", false, wColDesc);
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -809,12 +864,14 @@ void CPUDump::integerHexShortSlot()
wColDesc.isData = true; //hex short
wColDesc.itemCount = 8;
wColDesc.separator = 0;
wColDesc.data.itemSize = Word;
wColDesc.data.wordMode = HexWord;
appendResetDescriptor(8 + charwidth * 34, "Hex short (16-bit)", false, wColDesc);
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -832,12 +889,14 @@ void CPUDump::integerHexLongSlot()
wColDesc.isData = true; //hex long
wColDesc.itemCount = 4;
wColDesc.separator = 0;
wColDesc.data.itemSize = Dword;
wColDesc.data.dwordMode = HexDword;
appendResetDescriptor(8 + charwidth * 35, "Hex long (32-bit)", false, wColDesc);
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -855,12 +914,14 @@ void CPUDump::integerHexLongLongSlot()
wColDesc.isData = true; //hex long long
wColDesc.itemCount = 2;
wColDesc.separator = 0;
wColDesc.data.itemSize = Qword;
wColDesc.data.qwordMode = HexQword;
appendResetDescriptor(8 + charwidth * 33, "Hex long long (64-bit)", false, wColDesc);
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -878,12 +939,14 @@ void CPUDump::floatFloatSlot()
wColDesc.isData = true; //float dword
wColDesc.itemCount = 4;
wColDesc.separator = 0;
wColDesc.data.itemSize = Dword;
wColDesc.data.dwordMode = FloatDword;
appendResetDescriptor(8 + charwidth * 55, "Float (32-bit)", false, wColDesc);
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -901,12 +964,14 @@ void CPUDump::floatDoubleSlot()
wColDesc.isData = true; //float qword
wColDesc.itemCount = 2;
wColDesc.separator = 0;
wColDesc.data.itemSize = Qword;
wColDesc.data.qwordMode = DoubleQword;
appendResetDescriptor(8 + charwidth * 47, "Double (64-bit)", false, wColDesc);
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -924,12 +989,14 @@ void CPUDump::floatLongDoubleSlot()
wColDesc.isData = true; //float qword
wColDesc.itemCount = 2;
wColDesc.separator = 0;
wColDesc.data.itemSize = Tword;
wColDesc.data.twordMode = FloatTword;
appendResetDescriptor(8 + charwidth * 59, "Long double (80-bit)", false, wColDesc);
wColDesc.isData = false; //empty column
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -947,6 +1014,7 @@ void CPUDump::addressSlot()
wColDesc.isData = true; //void*
wColDesc.itemCount = 1;
wColDesc.separator = 0;
#ifdef _WIN64
wColDesc.data.itemSize = Qword;
wColDesc.data.qwordMode = HexQword;
@ -958,6 +1026,7 @@ void CPUDump::addressSlot()
wColDesc.isData = false; //comments
wColDesc.itemCount = 1;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
@ -1101,6 +1170,17 @@ void CPUDump::hardwareRemoveSlot()
DbgCmdExec(QString("bphwc " + addr_text).toUtf8().constData());
}
void CPUDump::findReferencesSlot()
{
SELECTIONDATA selection;
GuiSelectionGet(GUI_DISASSEMBLY, &selection);
QString addrStart = QString("%1").arg(rvaToVa(getSelectionStart()), sizeof(int_t) * 2, 16, QChar('0')).toUpper();
QString addrEnd = QString("%1").arg(rvaToVa(getSelectionEnd()), sizeof(int_t) * 2, 16, QChar('0')).toUpper();
QString addrDisasm = QString("%1").arg(selection.start, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
DbgCmdExec(QString("findrefrange " + addrStart + ", " + addrEnd + ", " + addrDisasm).toUtf8().constData());
emit displayReferencesWidget();
}
void CPUDump::binaryEditSlot()
{
HexEditDialog hexEdit(this);

View File

@ -39,6 +39,7 @@ public slots:
void setLabelSlot();
void gotoExpressionSlot();
void gotoFileOffsetSlot();
void hexAsciiSlot();
void hexUnicodeSlot();
@ -74,6 +75,7 @@ public slots:
void findPattern();
void undoSelectionSlot();
void followStackSlot();
void findReferencesSlot();
private:
QMenu* mBreakpointMenu;
@ -109,6 +111,7 @@ private:
QMenu* mGotoMenu;
QAction* mGotoExpression;
QAction* mGotoFileOffset;
QMenu* mHexMenu;
QAction* mHexAsciiAction;
@ -152,6 +155,7 @@ private:
QAction* mBinaryPasteAction;
QAction* mBinaryPasteIgnoreSizeAction;
QAction* mFindPatternAction;
QAction* mFindReferencesAction;
QAction* mUndoSelection;
QMenu* mSpecialMenu;

View File

@ -158,19 +158,19 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
const int_t cur_VA = CodePtr->getBase() + InstrBuffer->at(line).rva;
#ifdef _WIN64
if(cur_VA == regDump.cax) drawLabel(&painter, line, "RAX");
if(cur_VA == regDump.cbx) drawLabel(&painter, line, "RBX");
if(cur_VA == regDump.ccx) drawLabel(&painter, line, "RCX");
if(cur_VA == regDump.cdx) drawLabel(&painter, line, "RDX");
if(cur_VA == regDump.csi) drawLabel(&painter, line, "RSI");
if(cur_VA == regDump.cdi) drawLabel(&painter, line, "RDI");
if(cur_VA == regDump.regcontext.cax) drawLabel(&painter, line, "RAX");
if(cur_VA == regDump.regcontext.cbx) drawLabel(&painter, line, "RBX");
if(cur_VA == regDump.regcontext.ccx) drawLabel(&painter, line, "RCX");
if(cur_VA == regDump.regcontext.cdx) drawLabel(&painter, line, "RDX");
if(cur_VA == regDump.regcontext.csi) drawLabel(&painter, line, "RSI");
if(cur_VA == regDump.regcontext.cdi) drawLabel(&painter, line, "RDI");
#else //x86
if(cur_VA == regDump.cax) drawLabel(&painter, line, "EAX");
if(cur_VA == regDump.cbx) drawLabel(&painter, line, "EBX");
if(cur_VA == regDump.ccx) drawLabel(&painter, line, "ECX");
if(cur_VA == regDump.cdx) drawLabel(&painter, line, "EDX");
if(cur_VA == regDump.csi) drawLabel(&painter, line, "ESI");
if(cur_VA == regDump.cdi) drawLabel(&painter, line, "EDI");
if(cur_VA == regDump.regcontext.cax) drawLabel(&painter, line, "EAX");
if(cur_VA == regDump.regcontext.cbx) drawLabel(&painter, line, "EBX");
if(cur_VA == regDump.regcontext.ccx) drawLabel(&painter, line, "ECX");
if(cur_VA == regDump.regcontext.cdx) drawLabel(&painter, line, "EDX");
if(cur_VA == regDump.regcontext.csi) drawLabel(&painter, line, "ESI");
if(cur_VA == regDump.regcontext.cdi) drawLabel(&painter, line, "EDI");
#endif
}

View File

@ -17,6 +17,7 @@ CPUStack::CPUStack(QWidget* parent) : HexDump(parent)
wColDesc.isData = true; //void*
wColDesc.itemCount = 1;
wColDesc.separator = 0;
#ifdef _WIN64
wColDesc.data.itemSize = Qword;
wColDesc.data.qwordMode = HexQword;
@ -28,6 +29,7 @@ CPUStack::CPUStack(QWidget* parent) : HexDump(parent)
wColDesc.isData = false; //comments
wColDesc.itemCount = 0;
wColDesc.separator = 0;
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;

View File

@ -33,6 +33,8 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
mGeneralRegs = new RegistersView(0);
mGeneralRegs->setFixedWidth(1000);
mGeneralRegs->setFixedHeight(1400);
mGeneralRegs->ShowFPU(true);
QScrollArea* scrollArea = new QScrollArea;
scrollArea->setWidget(mGeneralRegs);
@ -40,10 +42,20 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
scrollArea->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal{border:1px solid grey;background:#f1f1f1;height:10px}QScrollBar::handle:horizontal{background:#aaa;min-width:20px;margin:1px}QScrollBar::add-line:horizontal,QScrollBar::sub-line:horizontal{width:0;height:0}");
scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar:vertical{border:1px solid grey;background:#f1f1f1;width:10px}QScrollBar::handle:vertical{background:#aaa;min-height:20px;margin:1px}QScrollBar::add-line:vertical,QScrollBar::sub-line:vertical{width:0;height:0}");
mRegsTab = new QTabWidget(this);
mRegsTab->addTab(scrollArea, "General");
QPushButton* button_changeview = new QPushButton("");
ui->mTopRightFrameLayout->addWidget(mRegsTab);
mGeneralRegs->SetChangeButton(button_changeview);
button_changeview->setStyleSheet("Text-align:left;padding: 4px;padding-left: 10px;");
QFont font = QFont("Lucida Console");
font.setStyleHint(QFont::Monospace);
font.setPointSize(8);
button_changeview->setFont(font);
connect(button_changeview, SIGNAL(clicked()), mGeneralRegs, SLOT(onChangeFPUViewAction()));
ui->mTopRightFrameLayout->addWidget(button_changeview);
ui->mTopRightFrameLayout->addWidget(scrollArea);
mDump = new CPUDump(0); //dump widget
ui->mBotLeftFrameLayout->addWidget(mDump);

View File

@ -36,7 +36,6 @@ public:
CPUStack* mStack;
RegistersView* mGeneralRegs;
CPUInfoBox* mInfo;
QTabWidget* mRegsTab;
private:
Ui::CPUWidget* ui;

View File

@ -19,6 +19,7 @@ GotoDialog::GotoDialog(QWidget* parent) : QDialog(parent), ui(new Ui::GotoDialog
ui->editExpression->setFocus();
validRangeStart = 0;
validRangeEnd = 0;
fileOffset = false;
mValidateThread = new GotoDialogValidateThread(this);
connect(this, SIGNAL(finished(int)), this, SLOT(finishedSlot(int)));
}
@ -57,6 +58,24 @@ void GotoDialog::validateExpression()
ui->buttonOk->setEnabled(false);
expressionText.clear();
}
else if(fileOffset)
{
uint_t offset = DbgValFromString(expression.toUtf8().constData());
uint_t va = DbgFunctions()->FileOffsetToVa(modName.toUtf8().constData(), offset);
if(va)
{
QString addrText = QString("%1").arg(va, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
ui->labelError->setText(QString("<font color='#00DD00'><b>Correct expression! -> </b></font>" + addrText));
ui->buttonOk->setEnabled(true);
expressionText = expression;
}
else
{
ui->labelError->setText("<font color='red'><b>Invalid file offset...</b></font>");
ui->buttonOk->setEnabled(false);
expressionText.clear();
}
}
else
{
uint_t addr = DbgValFromString(expression.toUtf8().constData());

View File

@ -20,6 +20,8 @@ public:
QString expressionText;
uint_t validRangeStart;
uint_t validRangeEnd;
bool fileOffset;
QString modName;
void showEvent(QShowEvent* event);
void hideEvent(QHideEvent* event);
void validateExpression();

View File

@ -12,6 +12,7 @@ LineEditDialog::LineEditDialog(QWidget* parent) : QDialog(parent), ui(new Ui::Li
setModal(true); //modal window
ui->checkBox->hide();
bChecked = false;
this->fixed_size = 0;
}
LineEditDialog::~LineEditDialog()
@ -24,6 +25,12 @@ void LineEditDialog::setCursorPosition(int position)
ui->textEdit->setCursorPosition(position);
}
void LineEditDialog::ForceSize(unsigned int size)
{
this->fixed_size = size;
}
void LineEditDialog::setText(const QString & text)
{
ui->textEdit->setText(text);
@ -52,6 +59,23 @@ void LineEditDialog::setCheckBoxText(const QString & text)
void LineEditDialog::on_textEdit_textChanged(const QString & arg1)
{
editText = arg1;
if(this->fixed_size != 0)
{
if(arg1.size() != this->fixed_size)
{
ui->buttonOk->setEnabled(false);
QString symbolct = "";
int ct = arg1.size() - (int) this->fixed_size;
if(ct > 0)
symbolct = "+";
ui->label->setText(QString("<font color='red'>") + QString("CT: ") + symbolct + QString::number(ct) + QString("</font>"));
}
else
{
ui->buttonOk->setEnabled(true);
ui->label->setText(QString(""));
}
}
}
void LineEditDialog::on_checkBox_toggled(bool checked)

View File

@ -22,6 +22,7 @@ public:
void setCheckBox(bool bSet);
void setCheckBoxText(const QString & text);
void setCursorPosition(int position);
void ForceSize(unsigned int size);
private slots:
void on_textEdit_textChanged(const QString & arg1);
@ -29,6 +30,7 @@ private slots:
private:
Ui::LineEditDialog* ui;
unsigned int fixed_size;
};
#endif // LINEEDITDIALOG_H

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>373</width>
<width>414</width>
<height>72</height>
</rect>
</property>
@ -17,62 +17,56 @@
<iconset resource="../../resource.qrc">
<normaloff>:/icons/images/ui-combo-box-edit.png</normaloff>:/icons/images/ui-combo-box-edit.png</iconset>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>351</width>
<height>53</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLineEdit" name="textEdit"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonOk">
<property name="text">
<string>&amp;OK</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonCancel">
<property name="text">
<string>&amp;Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLineEdit" name="textEdit"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="minimumSize">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonOk">
<property name="text">
<string>&amp;OK</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonCancel">
<property name="text">
<string>&amp;Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../../resource.qrc"/>

View File

@ -477,7 +477,7 @@ void MainWindow::displayAboutWidget()
QString title = "About x32_dbg";
#endif
title += QString().sprintf(" v%d", BridgeGetDbgVersion());
QMessageBox msg(QMessageBox::Information, title, "Website:\nhttp://x64dbg.com\n\nAttribution:\nIcons8 (http://icons8.com)\nYusuke Kamiyamane (http://p.yusukekamiyamane.com)");
QMessageBox msg(QMessageBox::Information, title, "Website:\nhttp://x64dbg.com\n\nAttribution:\nIcons8 (http://icons8.com)\nYusuke Kamiyamane (http://p.yusukekamiyamane.com)\n\nCompiled on:\n"__DATE__", "__TIME__);
msg.setWindowIcon(QIcon(":/icons/images/information.png"));
msg.setParent(this, Qt::Dialog);
msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint));
@ -963,7 +963,7 @@ void MainWindow::changeCommandLine()
cmdline = new char[cbsize];
DbgFunctions()->GetCmdline(cmdline, 0);
mLineEdit.setText(QString(cmdline));
delete cmdline;
delete[] cmdline;
}
mLineEdit.setCursorPosition(0);

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,14 @@
#define IsCharacterRegister(x) ((x>=CAX && x<CIP))
typedef struct
{
QString string;
unsigned int value;
} STRING_VALUE_TABLE_t;
#define SIZE_TABLE(table) (sizeof(table) / sizeof(*table))
namespace Ui
{
class RegistersView;
@ -27,6 +35,31 @@ public:
EFLAGS, CF, PF, AF, ZF, SF, TF, IF, DF, OF,
GS, FS, ES, DS, CS, SS,
DR0, DR1, DR2, DR3, DR6, DR7,
// x87 stuff
x87r0, x87r1, x87r2, x87r3, x87r4, x87r5, x87r6, x87r7,
x87TagWord, x87ControlWord, x87StatusWord,
// x87 Tag Word fields
x87TW_0, x87TW_1, x87TW_2, x87TW_3, x87TW_4, x87TW_5,
x87TW_6, x87TW_7,
// x87 Status Word fields
x87SW_B, x87SW_C3, x87SW_TOP, x87SW_C2, x87SW_C1, x87SW_O,
x87SW_IR, x87SW_SF, x87SW_P, x87SW_U, x87SW_Z,
x87SW_D, x87SW_I, x87SW_C0,
// x87 Control Word fields
x87CW_IC, x87CW_RC, x87CW_PC, x87CW_IEM, x87CW_PM,
x87CW_UM, x87CW_OM, x87CW_ZM, x87CW_DM, x87CW_IM,
//MxCsr
MxCsr, MxCsr_FZ, MxCsr_PM, MxCsr_UM, MxCsr_OM, MxCsr_ZM,
MxCsr_IM, MxCsr_DM, MxCsr_DAZ, MxCsr_PE, MxCsr_UE, MxCsr_OE,
MxCsr_ZE, MxCsr_DE, MxCsr_IE, MxCsr_RC,
// MMX and XMM
MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15,
// YMM
YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7, YMM8,
YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15,
UNKNOWN
};
@ -67,6 +100,9 @@ public slots:
void setRegister(REGISTER_NAME reg, uint_t value);
void debugStateChangedSlot(DBGSTATE state);
void repaint();
void ShowFPU(bool set_showfpu);
void onChangeFPUViewAction();
void SetChangeButton(QPushButton* push_button);
signals:
void refresh();
@ -78,9 +114,9 @@ protected:
virtual void keyPressEvent(QKeyEvent* event);
// use-in-class-only methods
void drawRegister(QPainter* p, REGISTER_NAME reg, uint_t value);
void drawRegister(QPainter* p, REGISTER_NAME reg, char* value);
void setRegisters(REGDUMP* reg);
int_t registerValue(const REGDUMP* regd, const REGISTER_NAME reg);
char* registerValue(const REGDUMP* regd, const REGISTER_NAME reg);
bool identifyRegister(const int y, const int x, REGISTER_NAME* clickedReg);
void displayEditDialog();
@ -89,6 +125,8 @@ protected slots:
void fontsUpdatedSlot();
void onIncrementAction();
void onDecrementAction();
void onIncrementx87StackAction();
void onDecrementx87StackAction();
void onZeroAction();
void onSetToOneAction();
void onModifyAction();
@ -98,18 +136,55 @@ protected slots:
void onFollowInDisassembly();
void onFollowInDump();
void onFollowInStack();
void InitMappings();
QString getRegisterLabel(REGISTER_NAME);
int CompareRegisters(const REGISTER_NAME reg_name, REGDUMP* regdump1, REGDUMP* regdump2);
SIZE_T GetSizeRegister(const REGISTER_NAME reg_name);
QString GetRegStringValueFromValue(REGISTER_NAME reg , char* value);
QString GetTagWordStateString(unsigned short);
unsigned int GetTagWordValueFromString(QString string);
QString GetControlWordPCStateString(unsigned short);
unsigned int GetControlWordPCValueFromString(QString string);
QString GetControlWordRCStateString(unsigned short);
unsigned int GetControlWordRCValueFromString(QString string);
QString GetMxCsrRCStateString(unsigned short);
unsigned int GetMxCsrRCValueFromString(QString string);
void ModifyFields(QString title, STRING_VALUE_TABLE_t* table, SIZE_T size);
unsigned int GetStatusWordTOPValueFromString(QString string);
QString GetStatusWordTOPStateString(unsigned short state);
private:
QPushButton* mChangeViewButton;
bool mShowFpu;
int mVScrollOffset;
int mRowsNeeded;
int yTopSpacing;
int mButtonHeight;
QSet<REGISTER_NAME> mUINTDISPLAY;
QSet<REGISTER_NAME> mUSHORTDISPLAY;
QSet<REGISTER_NAME> mDWORDDISPLAY;
QSet<REGISTER_NAME> mBOOLDISPLAY;
QSet<REGISTER_NAME> mLABELDISPLAY;
QSet<REGISTER_NAME> mONLYMODULEANDLABELDISPLAY;
QSet<REGISTER_NAME> mSETONEZEROTOGGLE;
QSet<REGISTER_NAME> mMODIFYDISPLAY;
QSet<REGISTER_NAME> mFIELDVALUE;
QSet<REGISTER_NAME> mTAGWORD;
QSet<REGISTER_NAME> mCANSTOREADDRESS;
QSet<REGISTER_NAME> mINCREMENTDECREMET;
QSet<REGISTER_NAME> mFPUx87_80BITSDISPLAY;
QSet<REGISTER_NAME> mFPU;
// holds current selected register
REGISTER_NAME mSelected;
// general purposes register id s (cax, ..., r8, ....)
QSet<REGISTER_NAME> mGPR;
// all flags
QSet<REGISTER_NAME> mFlags;
// FPU x87, XMM and MMX registers
QSet<REGISTER_NAME> mFPUx87;
QSet<REGISTER_NAME> mFPUMMX;
QSet<REGISTER_NAME> mFPUXMM;
QSet<REGISTER_NAME> mFPUYMM;
// contains all id's of registers if there occurs a change
QSet<REGISTER_NAME> mRegisterUpdates;
// registers that do not allow changes
@ -135,6 +210,9 @@ private:
QAction* wCM_FollowInDisassembly;
QAction* wCM_FollowInDump;
QAction* wCM_FollowInStack;
QAction* wCM_Incrementx87Stack;
QAction* wCM_Decrementx87Stack;
QAction* wCM_ChangeFPUView;
int_t mCip;
};

View File

@ -281,6 +281,7 @@ void ScriptView::contextMenuSlot(const QPoint & pos)
wMenu->addMenu(mLoadMenu);
if(getRowCount())
{
wMenu->addAction(mScriptReload);
wMenu->addAction(mScriptUnload);
wMenu->addSeparator();
wMenu->addAction(mScriptBpToggle);
@ -350,6 +351,11 @@ void ScriptView::setupContextMenu()
connect(mScriptLoad, SIGNAL(triggered()), this, SLOT(openFile()));
mLoadMenu->addAction(mScriptLoad);
mScriptReload = new QAction("Reload Script", this);
mScriptReload->setShortcutContext(Qt::WidgetShortcut);
this->addAction(mScriptReload);
connect(mScriptReload, SIGNAL(triggered()), this, SLOT(reload()));
mScriptUnload = new QAction("Unload Script", this);
mScriptUnload->setShortcutContext(Qt::WidgetShortcut);
this->addAction(mScriptUnload);
@ -397,6 +403,7 @@ void ScriptView::setupContextMenu()
void ScriptView::refreshShortcutsSlot()
{
mScriptLoad->setShortcut(ConfigShortcut("ActionLoadScript"));
mScriptReload->setShortcut(ConfigShortcut("ActionReloadScript"));
mScriptUnload->setShortcut(ConfigShortcut("ActionUnloadScript"));
mScriptRun->setShortcut(ConfigShortcut("ActionRunScript"));
mScriptBpToggle->setShortcut(ConfigShortcut("ActionToggleBreakpointScript"));
@ -498,7 +505,7 @@ void ScriptView::setInfoLine(int line, QString info)
void ScriptView::openFile()
{
QString filename = QFileDialog::getOpenFileName(this, tr("Select script"), 0, tr("Script files (*.txt *.scr);;All files (*.*)"));
filename = QFileDialog::getOpenFileName(this, tr("Select script"), 0, tr("Script files (*.txt *.scr);;All files (*.*)"));
if(!filename.length())
return;
filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes)
@ -506,6 +513,14 @@ void ScriptView::openFile()
DbgScriptLoad(filename.toUtf8().constData());
}
void ScriptView::reload()
{
if(!filename.length())
return;
DbgScriptUnload();
DbgScriptLoad(filename.toUtf8().constData());
}
void ScriptView::unload()
{
DbgScriptUnload();

View File

@ -25,6 +25,7 @@ public slots:
void setTitle(QString title);
void setInfoLine(int line, QString info);
void openFile();
void reload();
void unload();
void run();
void bpToggle();
@ -46,9 +47,11 @@ private:
//private variables
int mIpLine;
bool mEnableSyntaxHighlighting;
QString filename;
QMenu* mLoadMenu;
QAction* mScriptLoad;
QAction* mScriptReload;
QAction* mScriptUnload;
QAction* mScriptRun;
QAction* mScriptRunCursor;

View File

@ -0,0 +1,23 @@
#include "selectfields.h"
#include "ui_selectfields.h"
SelectFields::SelectFields(QWidget* parent) :
QDialog(parent),
ui(new Ui::SelectFields)
{
ui->setupUi(this);
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint);
#endif
setModal(true);
}
QListWidget* SelectFields::GetList(void)
{
return ui->listWidget;
}
SelectFields::~SelectFields()
{
delete ui;
}

View File

@ -0,0 +1,25 @@
#ifndef SELECTFIELDS_H
#define SELECTFIELDS_H
#include <QDialog>
#include <QListWidget>
namespace Ui
{
class SelectFields;
}
class SelectFields : public QDialog
{
Q_OBJECT
public:
explicit SelectFields(QWidget* parent = 0);
QListWidget* GetList(void);
~SelectFields();
private:
Ui::SelectFields* ui;
};
#endif // SELECTFIELDS_H

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SelectFields</class>
<widget class="QDialog" name="SelectFields">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>213</width>
<height>181</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="windowIcon">
<iconset resource="../../resource.qrc">
<normaloff>:/icons/images/log.png</normaloff>:/icons/images/log.png</iconset>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="listWidget"/>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../resource.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SelectFields</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SelectFields</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -173,39 +173,39 @@ void SettingsDialog::LoadSettings()
#ifndef _WIN64
isx64 = false;
#endif
if(DbgFunctions()->GetJit)
{
bool jit_auto_on;
DbgFunctions()->GetJit(jit_entry, isx64);
DbgFunctions()->GetDefJit(jit_def_entry);
bool jit_auto_on;
bool get_jit_works;
get_jit_works = DbgFunctions()->GetJit(jit_entry, isx64);
DbgFunctions()->GetDefJit(jit_def_entry);
if(get_jit_works)
{
if(_strcmpi(jit_entry, jit_def_entry) == 0)
settings.miscSetJIT = true;
else
settings.miscSetJIT = false;
ui->editJIT->setText(jit_entry);
ui->editJIT->setCursorPosition(0);
}
else
settings.miscSetJIT = false;
ui->editJIT->setText(jit_entry);
ui->editJIT->setCursorPosition(0);
ui->chkSetJIT->setCheckState(bool2check(settings.miscSetJIT));
ui->chkSetJIT->setCheckState(bool2check(settings.miscSetJIT));
if(DbgFunctions()->GetJitAuto(&jit_auto_on))
{
if(!jit_auto_on)
settings.miscSetJITAuto = true;
else
settings.miscSetJITAuto = false;
bool get_jit_auto_works = DbgFunctions()->GetJitAuto(&jit_auto_on);
if(!get_jit_auto_works || !jit_auto_on)
settings.miscSetJITAuto = true;
else
settings.miscSetJITAuto = false;
ui->chkConfirmBeforeAtt->setCheckState(bool2check(settings.miscSetJITAuto));
}
ui->chkConfirmBeforeAtt->setCheckState(bool2check(settings.miscSetJITAuto));
if(!DbgFunctions()->IsProcessElevated())
{
ui->chkSetJIT->setDisabled(true);
ui->chkConfirmBeforeAtt->setDisabled(true);
ui->lbladminwarning->setText(QString("Warning: Run the debugger as Admin to enable JIT."));
}
if(!DbgFunctions()->IsProcessElevated())
{
ui->chkSetJIT->setDisabled(true);
ui->chkConfirmBeforeAtt->setDisabled(true);
ui->lbladminwarning->setText(QString("Warning: Run the debugger as Admin to enable JIT."));
}
}
bJitOld = settings.miscSetJIT;
bJitAutoOld = settings.miscSetJITAuto;
}

View File

@ -241,6 +241,7 @@ Configuration::Configuration() : QObject()
defaultShortcuts.insert("ActionGotoExpression", Shortcut(tr("Actions -> Goto Expression"), "Ctrl+G"));
defaultShortcuts.insert("ActionFindReferencesToSelectedAddress", Shortcut(tr("Actions -> Find References to Selected Address"), "Ctrl+R"));
defaultShortcuts.insert("ActionFindPattern", Shortcut(tr("Actions -> Find Pattern"), "Ctrl+B"));
defaultShortcuts.insert("ActionFindReferences", Shortcut(tr("Actions -> Find References"), "Ctrl+R"));
defaultShortcuts.insert("ActionHighlightingMode", Shortcut(tr("Actions -> Highlighting Mode"), "Ctrl+H"));
defaultShortcuts.insert("ActionFind", Shortcut(tr("Actions -> Find"), "Ctrl+F"));
@ -252,6 +253,7 @@ Configuration::Configuration() : QObject()
defaultShortcuts.insert("ActionCopy", Shortcut(tr("Actions -> Copy"), "Ctrl+C"));
defaultShortcuts.insert("ActionCopySymbol", Shortcut(tr("Actions -> Copy Symbol"), "Ctrl+S"));
defaultShortcuts.insert("ActionLoadScript", Shortcut(tr("Actions -> Load Script"), "Ctrl+O"));
defaultShortcuts.insert("ActionReloadScript", Shortcut(tr("Actions -> Reload Script"), "Ctrl+R"));
defaultShortcuts.insert("ActionUnloadScript", Shortcut(tr("Actions -> Unload Script"), "Ctrl+U"));
defaultShortcuts.insert("ActionRunScript", Shortcut(tr("Actions -> Run Script"), "Space"));
defaultShortcuts.insert("ActionToggleBreakpointScript", Shortcut(tr("Actions -> Toggle Script Breakpoint"), "F2"));

View File

@ -83,7 +83,8 @@ SOURCES += \
Src/BasicView/ShortcutEdit.cpp \
Src/Gui/CalculatorDialog.cpp \
Src/Gui/AttachDialog.cpp \
Src/Gui/PageMemoryRights.cpp
Src/Gui/PageMemoryRights.cpp \
Src/Gui/SelectFields.cpp
HEADERS += \
@ -145,7 +146,8 @@ HEADERS += \
Src/BasicView/ShortcutEdit.h \
Src/Gui/CalculatorDialog.h \
Src/Gui/AttachDialog.h \
Src/Gui/PageMemoryRights.h
Src/Gui/PageMemoryRights.h \
Src/Gui/SelectFields.h
INCLUDEPATH += \
@ -179,7 +181,8 @@ FORMS += \
Src/Gui/ShortcutsDialog.ui \
Src/Gui/CalculatorDialog.ui \
Src/Gui/AttachDialog.ui \
Src/Gui/PageMemoryRights.ui
Src/Gui/PageMemoryRights.ui \
Src/Gui/SelectFields.ui
INCLUDEPATH += $$PWD/Src/Bridge

View File

@ -149,7 +149,7 @@ static bool BrowseFileOpen(HWND owner, const wchar_t* filter, const wchar_t* def
@brief A macro that defines shellext executable key.
*/
#define SHELLEXT_EXE_KEY L"exefile\\shell\\Debug with x64_dbg\\Command"
/**
@ -157,7 +157,7 @@ static bool BrowseFileOpen(HWND owner, const wchar_t* filter, const wchar_t* def
@brief A macro that defines shellext DLL key.
*/
#define SHELLEXT_DLL_KEY L"dllfile\\shell\\Debug with x64_dbg\\Command"
/**
@ -296,7 +296,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
if(MessageBoxW(0, L"Do you want to register a shell extension?", L"Question", MB_YESNO | MB_ICONQUESTION) == IDYES)
{
wchar_t szLauncherCommand[MAX_PATH] = L"";
swprintf_s(szLauncherCommand, sizeof(szLauncherCommand), L"\"%s\" \"%%1\"", szModulePath);
swprintf_s(szLauncherCommand, _countof(szLauncherCommand), L"\"%s\" \"%%1\"", szModulePath);
RegisterShellExtension(SHELLEXT_EXE_KEY, szLauncherCommand);
RegisterShellExtension(SHELLEXT_DLL_KEY, szLauncherCommand);
}