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:
commit
fde43663fd
|
|
@ -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)
|
||||
63
clean.bat
63
clean.bat
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
</DIV>
|
||||
<LI>
|
||||
<DIV>
|
||||
Sigma </DIV>
|
||||
<LI>
|
||||
<DIV><A href="http://blog.tr4ceflow.com/"
|
||||
<DIV><A href="http://blog.tr4ceflow.com"
|
||||
target=_blank>tr4ceflow</A>
|
||||
</DIV></LI></UL></body></HTML>
|
||||
</DIV>
|
||||
<LI>
|
||||
<DIV><A href="http://www.fr33project.org"
|
||||
target=_blank>Dreg</A>
|
||||
</DIV></LI></UL></body></HTML>
|
||||
|
|
|
|||
|
|
@ -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 > 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 of/inside a memory page to look in.
|
||||
When not specified CIP will be used. </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> </P></body>
|
||||
</html>
|
||||
BIN
help/x64_dbg.wcp
BIN
help/x64_dbg.wcp
Binary file not shown.
43
release.bat
43
release.bat
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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, ®context->x87fpu);
|
||||
regcontext->MxCsr = titcontext->MxCsr;
|
||||
memcpy(regcontext->XmmRegisters, titcontext->XmmRegisters, sizeof(regcontext->XmmRegisters));
|
||||
memcpy(regcontext->YmmRegisters, titcontext->YmmRegisters, sizeof(regcontext->YmmRegisters));
|
||||
}
|
||||
|
||||
static void TranslateTitanFpuRegister(const x87FPURegister_t* titanReg, X87FPUREGISTER* reg)
|
||||
{
|
||||
memcpy(reg->data, titanReg->data, sizeof(reg->data));
|
||||
reg->st_value = titanReg->st_value;
|
||||
reg->tag = titanReg->tag;
|
||||
}
|
||||
|
||||
static void TranslateTitanFpuRegisters(const x87FPURegister_t titanFpu[8], X87FPUREGISTER fpu[8])
|
||||
{
|
||||
for(int i = 0; i < 8; i++)
|
||||
TranslateTitanFpuRegister(&titanFpu[i], &fpu[i]);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump)
|
||||
{
|
||||
|
|
@ -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, ®dump->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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include "argument.h"
|
||||
#include "console.h"
|
||||
#include "UString/UString.h"
|
||||
|
||||
/*
|
||||
formatarg:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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[]);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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...");
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,16 @@ bool waitislocked(WAIT_ID id);
|
|||
enum CriticalSectionLock
|
||||
{
|
||||
LockMemoryPages,
|
||||
LockVariables,
|
||||
LockModules,
|
||||
LockComments,
|
||||
LockLabels,
|
||||
LockBookmarks,
|
||||
LockFunctions,
|
||||
LockLoops,
|
||||
LockBreakpoints,
|
||||
LockPatches,
|
||||
LockThreads,
|
||||
LockLast
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<std::string>&
|
||||
*/
|
||||
|
||||
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<std::string>
|
||||
*/
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ public:
|
|||
{
|
||||
bool isData;
|
||||
int itemCount;
|
||||
int separator;
|
||||
DataDescriptor_t data;
|
||||
} ColumnDescriptor_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ public:
|
|||
CPUStack* mStack;
|
||||
RegistersView* mGeneralRegs;
|
||||
CPUInfoBox* mInfo;
|
||||
QTabWidget* mRegsTab;
|
||||
|
||||
private:
|
||||
Ui::CPUWidget* ui;
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>&OK</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonCancel">
|
||||
<property name="text">
|
||||
<string>&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>&OK</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonCancel">
|
||||
<property name="text">
|
||||
<string>&Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../resource.qrc"/>
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue