Revert "Merged in Nukem9/x64_dbg/master (pull request #45)"
This reverts commitb6735aad53
, reversing changes made to20fa55cc2b
.
This commit is contained in:
parent
b6735aad53
commit
4798a29660
|
@ -0,0 +1,93 @@
|
|||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include <stdint.h>
|
||||
|
||||
#define uint size_t
|
||||
#define PAGE_SIZE 0x1000
|
||||
|
||||
#ifdef _WIN64
|
||||
#define HIGHEST_USER_ADDR 0x7FFFFFEFFFF
|
||||
#else //x86
|
||||
#define HIGHEST_USER_ADDR 0x7FFEFFFF
|
||||
#endif // _WIN64
|
||||
|
||||
bool readblock(uint addr, unsigned char block[PAGE_SIZE])
|
||||
{
|
||||
printf("readblock(%X[%X])\n", addr, PAGE_SIZE);
|
||||
memset(block, 0xFF, PAGE_SIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool memread(uint addr, unsigned char* data, uint size)
|
||||
{
|
||||
//check if the address is inside user space
|
||||
if(addr > HIGHEST_USER_ADDR)
|
||||
return false;
|
||||
|
||||
puts("-start-");
|
||||
printf(" addr: %X\n size: %X\n", addr, size);
|
||||
|
||||
//calculate the start page
|
||||
uint start = addr & ~(PAGE_SIZE - 1);
|
||||
printf(" start: %X\n", start);
|
||||
|
||||
//calculate the end page
|
||||
uint end = addr + size;
|
||||
uint x = end & (PAGE_SIZE - 1);
|
||||
if(x)
|
||||
end += (PAGE_SIZE - x);
|
||||
printf(" end: %X\n", end);
|
||||
|
||||
//calculate the number of pages to read
|
||||
uint npages = (end - start) / PAGE_SIZE;
|
||||
printf("npages: %d\n\n", npages);
|
||||
|
||||
//go over all pages
|
||||
for(uint i = 0, j = start; i < npages; i++)
|
||||
{
|
||||
//read one page (j should always align with PAGE_SIZE)
|
||||
unsigned char block[PAGE_SIZE];
|
||||
if(!readblock(j, block))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//these are the offsets and sizes in the block to write to append to the output buffer
|
||||
uint roffset = 0;
|
||||
uint rsize = PAGE_SIZE;
|
||||
|
||||
if(i == npages - 1) //last page (first because there might only be one page)
|
||||
{
|
||||
rsize = size - (j - start); //remaining size
|
||||
}
|
||||
else if(i == 0) //first page
|
||||
{
|
||||
roffset = addr & (PAGE_SIZE - 1);
|
||||
rsize = PAGE_SIZE - roffset;
|
||||
}
|
||||
|
||||
printf("roffset: %X\n rsize: %X\n", roffset, rsize);
|
||||
puts("");
|
||||
|
||||
//copy the required block data in the output buffer
|
||||
memcpy(data, block + roffset, rsize);
|
||||
data += rsize;
|
||||
|
||||
j += rsize;
|
||||
}
|
||||
|
||||
puts("--end--\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned char out[0x10000] = {0};
|
||||
memread(0x12A45, out, 0x3456);
|
||||
memread(0x12000, out, 0x456);
|
||||
memread(0x12000, out, 0x3456);
|
||||
memread(0x12000, out, 0x4000);
|
||||
memread(0x12ff0, out, 0x16);
|
||||
memread(0x100, out, 0x3090);
|
||||
return 0;
|
||||
}
|
23
x64_dbg.sln
23
x64_dbg.sln
|
@ -1,8 +1,6 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "x64_dbg_bridge", "x64_dbg_bridge\x64_dbg_bridge.vcxproj", "{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "x64_dbg_exe", "x64_dbg_exe\x64_dbg_exe.vcxproj", "{3A22175E-6B72-FDCC-1603-C4A2163C7900}"
|
||||
|
@ -19,39 +17,22 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "x64_dbg_launcher", "x64_dbg
|
|||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}.Debug|x64.Build.0 = Debug|x64
|
||||
{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}.Release|Win32.Build.0 = Release|Win32
|
||||
{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}.Release|x64.ActiveCfg = Release|x64
|
||||
{944D9923-CB1A-6F6C-BCBC-9E00A71954C1}.Release|x64.Build.0 = Release|x64
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Debug|x64.Build.0 = Debug|x64
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Release|Win32.Build.0 = Release|Win32
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Release|x64.ActiveCfg = Release|x64
|
||||
{3A22175E-6B72-FDCC-1603-C4A2163C7900}.Release|x64.Build.0 = Release|x64
|
||||
{E6548308-401E-3A8A-5819-905DB90522A6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{E6548308-401E-3A8A-5819-905DB90522A6}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E6548308-401E-3A8A-5819-905DB90522A6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E6548308-401E-3A8A-5819-905DB90522A6}.Debug|x64.Build.0 = Debug|x64
|
||||
{E6548308-401E-3A8A-5819-905DB90522A6}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E6548308-401E-3A8A-5819-905DB90522A6}.Release|Win32.Build.0 = Release|Win32
|
||||
{E6548308-401E-3A8A-5819-905DB90522A6}.Release|x64.ActiveCfg = Release|x64
|
||||
{E6548308-401E-3A8A-5819-905DB90522A6}.Release|x64.Build.0 = Release|x64
|
||||
{AC3F927A-4079-4C97-B8BE-8D04546802E7}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{AC3F927A-4079-4C97-B8BE-8D04546802E7}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{AC3F927A-4079-4C97-B8BE-8D04546802E7}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{AC3F927A-4079-4C97-B8BE-8D04546802E7}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{AC3F927A-4079-4C97-B8BE-8D04546802E7}.Release|Win32.Build.0 = Release|Win32
|
||||
{AC3F927A-4079-4C97-B8BE-8D04546802E7}.Release|x64.ActiveCfg = Release|Win32
|
||||
|
|
|
@ -540,8 +540,8 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
int ThreadNumber;
|
||||
HANDLE Handle;
|
||||
DWORD ThreadId;
|
||||
HANDLE hThread;
|
||||
DWORD dwThreadId;
|
||||
duint ThreadStartAddress;
|
||||
duint ThreadLocalBase;
|
||||
char threadName[MAX_THREAD_NAME_SIZE];
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
|
@ -35,22 +27,10 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
@ -58,15 +38,9 @@
|
|||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
@ -74,22 +48,11 @@
|
|||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>x32_bridge</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\x32\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>x32_bridge</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\x64\</OutDir>
|
||||
<TargetName>x64_bridge</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\x64\</OutDir>
|
||||
<TargetName>x64_bridge</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -106,22 +69,6 @@
|
|||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -136,20 +83,6 @@
|
|||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>BUILD_BRIDGE;WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
|
|
@ -5,19 +5,9 @@
|
|||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerCommand>$(OutDir)\x32_dbg.exe</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LocalDebuggerCommand>$(OutDir)\x64_dbg.exe</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerCommand>$(OutDir)\x64_dbg.exe</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -24,7 +24,7 @@ static bool _assembleatex(duint addr, const char* instruction, char* error, bool
|
|||
|
||||
static bool _sectionfromaddr(duint addr, char* section)
|
||||
{
|
||||
HMODULE hMod = (HMODULE)ModBaseFromAddr(addr);
|
||||
HMODULE hMod = (HMODULE)modbasefromaddr(addr);
|
||||
if(!hMod)
|
||||
return false;
|
||||
wchar_t curModPath[MAX_PATH] = L"";
|
||||
|
@ -72,7 +72,7 @@ static bool _patchinrange(duint start, duint end)
|
|||
|
||||
static bool _mempatch(duint va, const unsigned char* src, duint size)
|
||||
{
|
||||
return MemPatch((void*)va, (void*)src, size, 0);
|
||||
return mempatch(fdProcessInfo->hProcess, (void*)va, src, size, 0);
|
||||
}
|
||||
|
||||
static void _patchrestorerange(duint start, duint end)
|
||||
|
@ -162,17 +162,17 @@ bool _getprocesslist(DBGPROCESSINFO** entries, int* count)
|
|||
|
||||
static void _memupdatemap()
|
||||
{
|
||||
MemUpdateMap(fdProcessInfo->hProcess);
|
||||
memupdatemap(fdProcessInfo->hProcess);
|
||||
}
|
||||
|
||||
void dbgfunctionsinit()
|
||||
{
|
||||
_dbgfunctions.AssembleAtEx = _assembleatex;
|
||||
_dbgfunctions.SectionFromAddr = _sectionfromaddr;
|
||||
_dbgfunctions.ModNameFromAddr = ModNameFromAddr;
|
||||
_dbgfunctions.ModBaseFromAddr = ModBaseFromAddr;
|
||||
_dbgfunctions.ModBaseFromName = ModBaseFromName;
|
||||
_dbgfunctions.ModSizeFromAddr = ModSizeFromAddr;
|
||||
_dbgfunctions.ModNameFromAddr = modnamefromaddr;
|
||||
_dbgfunctions.ModBaseFromAddr = modbasefromaddr;
|
||||
_dbgfunctions.ModBaseFromName = modbasefromname;
|
||||
_dbgfunctions.ModSizeFromAddr = modsizefromaddr;
|
||||
_dbgfunctions.Assemble = assemble;
|
||||
_dbgfunctions.PatchGet = _patchget;
|
||||
_dbgfunctions.PatchInRange = _patchinrange;
|
||||
|
@ -181,12 +181,12 @@ void dbgfunctionsinit()
|
|||
_dbgfunctions.PatchEnum = (PATCHENUM)patchenum;
|
||||
_dbgfunctions.PatchRestore = _patchrestore;
|
||||
_dbgfunctions.PatchFile = (PATCHFILE)patchfile;
|
||||
_dbgfunctions.ModPathFromAddr = ModPathFromAddr;
|
||||
_dbgfunctions.ModPathFromName = ModPathFromName;
|
||||
_dbgfunctions.ModPathFromAddr = modpathfromaddr;
|
||||
_dbgfunctions.ModPathFromName = modpathfromname;
|
||||
_dbgfunctions.DisasmFast = disasmfast;
|
||||
_dbgfunctions.MemUpdateMap = _memupdatemap;
|
||||
_dbgfunctions.GetCallStack = _getcallstack;
|
||||
_dbgfunctions.SymbolDownloadAllSymbols = SymDownloadAllSymbols;
|
||||
_dbgfunctions.SymbolDownloadAllSymbols = symdownloadallsymbols;
|
||||
_dbgfunctions.GetJit = _getjit;
|
||||
_dbgfunctions.GetJitAuto = _getjitauto;
|
||||
_dbgfunctions.GetDefJit = dbggetdefjit;
|
||||
|
|
|
@ -26,17 +26,17 @@ static bool bOnlyCipAutoComments = false;
|
|||
|
||||
extern "C" DLL_EXPORT duint _dbg_memfindbaseaddr(duint addr, duint* size)
|
||||
{
|
||||
return MemFindBaseAddr(addr, size);
|
||||
return memfindbaseaddr(addr, size);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT bool _dbg_memread(duint addr, unsigned char* dest, duint size, duint* read)
|
||||
{
|
||||
return MemRead((void*)addr, dest, size, read);
|
||||
return memread(fdProcessInfo->hProcess, (void*)addr, dest, size, read);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT bool _dbg_memwrite(duint addr, const unsigned char* src, duint size, duint* written)
|
||||
{
|
||||
return MemWrite((void*)addr, (void*)src, size, written);
|
||||
return memwrite(fdProcessInfo->hProcess, (void*)addr, src, size, written);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT bool _dbg_memmap(MEMMAP* memmap)
|
||||
|
@ -57,7 +57,7 @@ extern "C" DLL_EXPORT bool _dbg_memmap(MEMMAP* memmap)
|
|||
|
||||
extern "C" DLL_EXPORT bool _dbg_memisvalidreadptr(duint addr)
|
||||
{
|
||||
return MemIsValidReadPtr(addr);
|
||||
return memisvalidreadptr(fdProcessInfo->hProcess, addr);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT bool _dbg_valfromstring(const char* string, duint* value)
|
||||
|
@ -69,7 +69,6 @@ extern "C" DLL_EXPORT bool _dbg_isdebugging()
|
|||
{
|
||||
if(IsFileBeingDebugged())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -94,7 +93,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
|
|||
bool retval = false;
|
||||
if(addrinfo->flags & flagmodule) //get module
|
||||
{
|
||||
if(ModNameFromAddr(addr, addrinfo->module, false)) //get module name
|
||||
if(modnamefromaddr(addr, addrinfo->module, false)) //get module name
|
||||
retval = true;
|
||||
}
|
||||
if(addrinfo->flags & flaglabel)
|
||||
|
@ -122,7 +121,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
|
|||
if(disasmfast(addr, &basicinfo) && basicinfo.branch && !basicinfo.call && basicinfo.memory.value) //thing is a JMP
|
||||
{
|
||||
uint val = 0;
|
||||
if(MemRead((void*)basicinfo.memory.value, &val, sizeof(val), 0))
|
||||
if(memread(fdProcessInfo->hProcess, (const void*)basicinfo.memory.value, &val, sizeof(val), 0))
|
||||
{
|
||||
if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) and !displacement)
|
||||
{
|
||||
|
@ -138,12 +137,12 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
|
|||
}
|
||||
if(addrinfo->flags & flagbookmark)
|
||||
{
|
||||
addrinfo->isbookmark = BookmarkGet(addr);
|
||||
addrinfo->isbookmark = bookmarkget(addr);
|
||||
retval = true;
|
||||
}
|
||||
if(addrinfo->flags & flagfunction)
|
||||
{
|
||||
if(FunctionGet(addr, &addrinfo->function.start, &addrinfo->function.end))
|
||||
if(functionget(addr, &addrinfo->function.start, &addrinfo->function.end))
|
||||
retval = true;
|
||||
}
|
||||
if(addrinfo->flags & flagloop)
|
||||
|
@ -154,7 +153,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
|
|||
if(addrinfo->flags & flagcomment)
|
||||
{
|
||||
*addrinfo->comment = 0;
|
||||
if(CommentGet(addr, addrinfo->comment))
|
||||
if(commentget(addr, addrinfo->comment))
|
||||
retval = true;
|
||||
else
|
||||
{
|
||||
|
@ -300,15 +299,15 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoset(duint addr, ADDRINFO* addrinfo)
|
|||
}
|
||||
if(addrinfo->flags & flagcomment) //set comment
|
||||
{
|
||||
if(CommentSet(addr, addrinfo->comment, true))
|
||||
if(commentset(addr, addrinfo->comment, true))
|
||||
retval = true;
|
||||
}
|
||||
if(addrinfo->flags & flagbookmark) //set bookmark
|
||||
{
|
||||
if(addrinfo->isbookmark)
|
||||
retval = BookmarkSet(addr, true);
|
||||
retval = bookmarkset(addr, true);
|
||||
else
|
||||
retval = BookmarkDelete(addr);
|
||||
retval = bookmarkdel(addr);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
@ -318,20 +317,20 @@ extern "C" DLL_EXPORT int _dbg_bpgettypeat(duint addr)
|
|||
static uint cacheAddr;
|
||||
static int cacheBpCount;
|
||||
static int cacheResult;
|
||||
int bpcount = BpGetList(nullptr);
|
||||
int bpcount = bpgetlist(0);
|
||||
if(cacheAddr != addr or cacheBpCount != bpcount)
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
cacheAddr = addr;
|
||||
cacheResult = 0;
|
||||
cacheBpCount = bpcount;
|
||||
if(BpGet(addr, BPNORMAL, 0, &bp))
|
||||
if(bpget(addr, BPNORMAL, 0, &bp))
|
||||
if(bp.enabled)
|
||||
cacheResult |= bp_normal;
|
||||
if(BpGet(addr, BPHARDWARE, 0, &bp))
|
||||
if(bpget(addr, BPHARDWARE, 0, &bp))
|
||||
if(bp.enabled)
|
||||
cacheResult |= bp_hardware;
|
||||
if(BpGet(addr, BPMEMORY, 0, &bp))
|
||||
if(bpget(addr, BPMEMORY, 0, &bp))
|
||||
if(bp.enabled)
|
||||
cacheResult |= bp_memory;
|
||||
}
|
||||
|
@ -504,7 +503,7 @@ extern "C" DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* bpmap)
|
|||
if(!bpmap)
|
||||
return 0;
|
||||
std::vector<BREAKPOINT> list;
|
||||
int bpcount = BpGetList(&list);
|
||||
int bpcount = bpgetlist(&list);
|
||||
if(bpcount == 0)
|
||||
{
|
||||
bpmap->count = 0;
|
||||
|
@ -567,7 +566,7 @@ extern "C" DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* bpmap)
|
|||
curBp.addr = list[i].addr;
|
||||
curBp.enabled = list[i].enabled;
|
||||
//TODO: fix this
|
||||
if(MemIsValidReadPtr(curBp.addr))
|
||||
if(memisvalidreadptr(fdProcessInfo->hProcess, curBp.addr))
|
||||
curBp.active = true;
|
||||
strcpy_s(curBp.mod, list[i].mod);
|
||||
strcpy_s(curBp.name, list[i].name);
|
||||
|
@ -614,7 +613,7 @@ extern "C" DLL_EXPORT uint _dbg_getbranchdestination(uint addr)
|
|||
|
||||
extern "C" DLL_EXPORT bool _dbg_functionoverlaps(uint start, uint end)
|
||||
{
|
||||
return FunctionOverlaps(start, end);
|
||||
return functionoverlaps(start, end);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* param2)
|
||||
|
@ -690,7 +689,7 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||
case DBG_SYMBOL_ENUM:
|
||||
{
|
||||
SYMBOLCBINFO* cbInfo = (SYMBOLCBINFO*)param1;
|
||||
SymEnum(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user);
|
||||
symenum(cbInfo->base, cbInfo->cbSymbolEnum, cbInfo->user);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -702,7 +701,7 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||
|
||||
case DBG_MODBASE_FROM_NAME:
|
||||
{
|
||||
return ModBaseFromName((const char*)param1);
|
||||
return modbasefromname((const char*)param1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -720,7 +719,7 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||
|
||||
case DBG_GET_THREAD_LIST:
|
||||
{
|
||||
ThreadGetList((THREADLIST*)param1);
|
||||
threadgetlist((THREADLIST*)param1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -776,7 +775,7 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||
if(!param1 or !param2)
|
||||
return 0;
|
||||
unsigned char data[16];
|
||||
if(!MemRead(param1, data, sizeof(data), 0))
|
||||
if(!memread(fdProcessInfo->hProcess, param1, data, sizeof(data), 0))
|
||||
return 0;
|
||||
DISASM disasm;
|
||||
memset(&disasm, 0, sizeof(disasm));
|
||||
|
@ -805,28 +804,28 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||
case DBG_FUNCTION_GET:
|
||||
{
|
||||
FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1;
|
||||
return (uint)FunctionGet(info->addr, &info->start, &info->end);
|
||||
return (uint)functionget(info->addr, &info->start, &info->end);
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_FUNCTION_OVERLAPS:
|
||||
{
|
||||
FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1;
|
||||
return (uint)FunctionOverlaps(info->start, info->end);
|
||||
return (uint)functionoverlaps(info->start, info->end);
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_FUNCTION_ADD:
|
||||
{
|
||||
FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1;
|
||||
return (uint)FunctionAdd(info->start, info->end, info->manual);
|
||||
return (uint)functionadd(info->start, info->end, info->manual);
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_FUNCTION_DEL:
|
||||
{
|
||||
FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1;
|
||||
return (uint)FunctionDelete(info->addr);
|
||||
return (uint)functiondel(info->addr);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -867,7 +866,7 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||
case DBG_IS_BP_DISABLED:
|
||||
{
|
||||
BREAKPOINT bp;
|
||||
if(BpGet((uint)param1, BPNORMAL, 0, &bp))
|
||||
if(bpget((uint)param1, BPNORMAL, 0, &bp))
|
||||
return !(uint)bp.enabled;
|
||||
return (uint)false;
|
||||
}
|
||||
|
@ -875,13 +874,13 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||
|
||||
case DBG_SET_AUTO_COMMENT_AT:
|
||||
{
|
||||
return (uint)CommentSet((uint)param1, (const char*)param2, false);
|
||||
return (uint)commentset((uint)param1, (const char*)param2, false);
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_DELETE_AUTO_COMMENT_RANGE:
|
||||
{
|
||||
CommentDelRange((uint)param1, (uint)param2);
|
||||
commentdelrange((uint)param1, (uint)param2);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -899,25 +898,25 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||
|
||||
case DBG_SET_AUTO_BOOKMARK_AT:
|
||||
{
|
||||
return (uint)BookmarkSet((uint)param1, false);
|
||||
return (uint)bookmarkset((uint)param1, false);
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_DELETE_AUTO_BOOKMARK_RANGE:
|
||||
{
|
||||
BookmarkDelRange((uint)param1, (uint)param2);
|
||||
bookmarkdelrange((uint)param1, (uint)param2);
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_SET_AUTO_FUNCTION_AT:
|
||||
{
|
||||
return (uint)FunctionAdd((uint)param1, (uint)param2, false);
|
||||
return (uint)functionadd((uint)param1, (uint)param2, false);
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_DELETE_AUTO_FUNCTION_RANGE:
|
||||
{
|
||||
FunctionDelRange((uint)param1, (uint)param2);
|
||||
functiondelrange((uint)param1, (uint)param2);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -97,7 +97,9 @@ bool arraycontains(const char* cmd_list, const char* cmd)
|
|||
|
||||
bool scmp(const char* a, const char* b)
|
||||
{
|
||||
return _stricmp(a, b) == 0;
|
||||
if(_stricmp(a, b))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void formathex(char* string)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef _GLOBAL_H
|
||||
#define _GLOBAL_H
|
||||
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define WINVER 0x0501
|
||||
#define _WIN32_IE 0x0500
|
||||
|
||||
|
@ -16,7 +16,6 @@
|
|||
#include <stdarg.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <tlhelp32.h>
|
||||
#include "..\x64_dbg_bridge\bridgemain.h"
|
||||
#include "jansson\jansson.h"
|
||||
|
@ -52,6 +51,42 @@ typedef unsigned long uint;
|
|||
typedef long sint;
|
||||
#endif // _WIN64
|
||||
|
||||
enum BITMASK
|
||||
{
|
||||
BIT1 = 0x1,
|
||||
BIT2 = 0x2,
|
||||
BIT3 = 0x4,
|
||||
BIT4 = 0x8,
|
||||
BIT5 = 0x10,
|
||||
BIT6 = 0x20,
|
||||
BIT7 = 0x40,
|
||||
BIT8 = 0x80,
|
||||
BIT9 = 0x100,
|
||||
BIT10 = 0x200,
|
||||
BIT11 = 0x400,
|
||||
BIT12 = 0x800,
|
||||
BIT13 = 0x1000,
|
||||
BIT14 = 0x2000,
|
||||
BIT15 = 0x4000,
|
||||
BIT16 = 0x8000,
|
||||
BIT17 = 0x10000,
|
||||
BIT18 = 0x20000,
|
||||
BIT19 = 0x40000,
|
||||
BIT20 = 0x80000,
|
||||
BIT21 = 0x100000,
|
||||
BIT22 = 0x200000,
|
||||
BIT23 = 0x400000,
|
||||
BIT24 = 0x800000,
|
||||
BIT25 = 0x1000000,
|
||||
BIT26 = 0x2000000,
|
||||
BIT27 = 0x4000000,
|
||||
BIT28 = 0x8000000,
|
||||
BIT29 = 0x10000000,
|
||||
BIT30 = 0x20000000,
|
||||
BIT31 = 0x40000000,
|
||||
BIT32 = 0x80000000
|
||||
};
|
||||
|
||||
enum arch
|
||||
{
|
||||
notfound,
|
||||
|
|
|
@ -21,12 +21,12 @@ void dbsave()
|
|||
dprintf("saving database...");
|
||||
DWORD ticks = GetTickCount();
|
||||
JSON root = json_object();
|
||||
CommentCacheSave(root);
|
||||
commentcachesave(root);
|
||||
labelcachesave(root);
|
||||
BookmarkCacheSave(root);
|
||||
FunctionCacheSave(root);
|
||||
bookmarkcachesave(root);
|
||||
functioncachesave(root);
|
||||
loopcachesave(root);
|
||||
BpCacheSave(root);
|
||||
bpcachesave(root);
|
||||
WString wdbpath = StringUtils::Utf8ToUtf16(dbpath);
|
||||
if(json_object_size(root))
|
||||
{
|
||||
|
@ -68,7 +68,7 @@ void dbload()
|
|||
return;
|
||||
}
|
||||
FILE* jsonFile = 0;
|
||||
if(_wfopen_s(&jsonFile, wdbpath.c_str(), L"rb") != 0)
|
||||
if(_wfopen_s(&jsonFile, wdbpath.c_str(), L"rb"))
|
||||
{
|
||||
dputs("\nfailed to open database file!");
|
||||
return;
|
||||
|
@ -82,12 +82,12 @@ void dbload()
|
|||
dputs("\ninvalid database file (JSON)!");
|
||||
return;
|
||||
}
|
||||
CommentCacheLoad(root);
|
||||
commentcacheload(root);
|
||||
labelcacheload(root);
|
||||
BookmarkCacheLoad(root);
|
||||
FunctionCacheLoad(root);
|
||||
bookmarkcacheload(root);
|
||||
functioncacheload(root);
|
||||
loopcacheload(root);
|
||||
BpCacheLoad(root);
|
||||
bpcacheload(root);
|
||||
json_decref(root); //free root
|
||||
dprintf("%ums\n", GetTickCount() - ticks);
|
||||
}
|
||||
|
@ -95,12 +95,12 @@ void dbload()
|
|||
void dbclose()
|
||||
{
|
||||
dbsave();
|
||||
CommentClear();
|
||||
commentclear();
|
||||
labelclear();
|
||||
BookmarkClear();
|
||||
FunctionClear();
|
||||
bookmarkclear();
|
||||
functionclear();
|
||||
loopclear();
|
||||
BpClear();
|
||||
bpclear();
|
||||
patchclear();
|
||||
}
|
||||
|
||||
|
@ -111,44 +111,44 @@ bool apienumexports(uint base, EXPORTENUMCALLBACK cbEnum)
|
|||
VirtualQueryEx(fdProcessInfo->hProcess, (const void*)base, &mbi, sizeof(mbi));
|
||||
uint size = mbi.RegionSize;
|
||||
Memory<void*> buffer(size, "apienumexports:buffer");
|
||||
if(!MemRead((void*)base, buffer, size, 0))
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)base, buffer, size, 0))
|
||||
return false;
|
||||
IMAGE_NT_HEADERS* pnth = (IMAGE_NT_HEADERS*)((uint)buffer + GetPE32DataFromMappedFile((ULONG_PTR)buffer, 0, UE_PE_OFFSET));
|
||||
uint export_dir_rva = pnth->OptionalHeader.DataDirectory[0].VirtualAddress;
|
||||
uint export_dir_size = pnth->OptionalHeader.DataDirectory[0].Size;
|
||||
IMAGE_EXPORT_DIRECTORY export_dir;
|
||||
memset(&export_dir, 0, sizeof(export_dir));
|
||||
MemRead((void*)(export_dir_rva + base), &export_dir, sizeof(export_dir), 0);
|
||||
memread(fdProcessInfo->hProcess, (const void*)(export_dir_rva + base), &export_dir, sizeof(export_dir), 0);
|
||||
unsigned int NumberOfNames = export_dir.NumberOfNames;
|
||||
if(!export_dir.NumberOfFunctions or !NumberOfNames) //no named exports
|
||||
return false;
|
||||
char modname[MAX_MODULE_SIZE] = "";
|
||||
ModNameFromAddr(base, modname, true);
|
||||
modnamefromaddr(base, modname, true);
|
||||
uint original_name_va = export_dir.Name + base;
|
||||
char original_name[deflen] = "";
|
||||
memset(original_name, 0, sizeof(original_name));
|
||||
MemRead((void*)original_name_va, original_name, deflen, 0);
|
||||
memread(fdProcessInfo->hProcess, (const void*)original_name_va, original_name, deflen, 0);
|
||||
char* AddrOfFunctions_va = (char*)(export_dir.AddressOfFunctions + base);
|
||||
char* AddrOfNames_va = (char*)(export_dir.AddressOfNames + base);
|
||||
char* AddrOfNameOrdinals_va = (char*)(export_dir.AddressOfNameOrdinals + base);
|
||||
for(DWORD i = 0; i < NumberOfNames; i++)
|
||||
{
|
||||
DWORD curAddrOfName = 0;
|
||||
MemRead(AddrOfNames_va + sizeof(DWORD)*i, &curAddrOfName, sizeof(DWORD), 0);
|
||||
memread(fdProcessInfo->hProcess, AddrOfNames_va + sizeof(DWORD)*i, &curAddrOfName, sizeof(DWORD), 0);
|
||||
char* cur_name_va = (char*)(curAddrOfName + base);
|
||||
char cur_name[deflen] = "";
|
||||
memset(cur_name, 0, deflen);
|
||||
MemRead(cur_name_va, cur_name, deflen, 0);
|
||||
memread(fdProcessInfo->hProcess, cur_name_va, cur_name, deflen, 0);
|
||||
WORD curAddrOfNameOrdinals = 0;
|
||||
MemRead(AddrOfNameOrdinals_va + sizeof(WORD)*i, &curAddrOfNameOrdinals, sizeof(WORD), 0);
|
||||
memread(fdProcessInfo->hProcess, AddrOfNameOrdinals_va + sizeof(WORD)*i, &curAddrOfNameOrdinals, sizeof(WORD), 0);
|
||||
DWORD curFunctionRva = 0;
|
||||
MemRead(AddrOfFunctions_va + sizeof(DWORD)*curAddrOfNameOrdinals, &curFunctionRva, sizeof(DWORD), 0);
|
||||
memread(fdProcessInfo->hProcess, AddrOfFunctions_va + sizeof(DWORD)*curAddrOfNameOrdinals, &curFunctionRva, sizeof(DWORD), 0);
|
||||
|
||||
if(curFunctionRva >= export_dir_rva and curFunctionRva < export_dir_rva + export_dir_size)
|
||||
{
|
||||
char forwarded_api[deflen] = "";
|
||||
memset(forwarded_api, 0, deflen);
|
||||
MemRead((void*)(curFunctionRva + base), forwarded_api, deflen, 0);
|
||||
memread(fdProcessInfo->hProcess, (void*)(curFunctionRva + base), forwarded_api, deflen, 0);
|
||||
int len = (int)strlen(forwarded_api);
|
||||
int j = 0;
|
||||
while(forwarded_api[j] != '.' and j < len)
|
||||
|
|
|
@ -67,12 +67,12 @@ bool assembleat(uint addr, const char* instruction, int* size, char* error, bool
|
|||
if(size)
|
||||
*size = destSize;
|
||||
|
||||
bool ret = MemPatch((void*)addr, dest, destSize, 0);
|
||||
bool ret = mempatch(fdProcessInfo->hProcess, (void*)addr, dest, destSize, 0);
|
||||
if(ret && fillnop && nopsize)
|
||||
{
|
||||
if(size)
|
||||
*size += nopsize;
|
||||
if(!MemPatch((void*)(addr + destSize), nops, nopsize, 0))
|
||||
if(!mempatch(fdProcessInfo->hProcess, (void*)(addr + destSize), nops, nopsize, 0))
|
||||
ret = false;
|
||||
}
|
||||
GuiUpdatePatches();
|
||||
|
|
|
@ -4,206 +4,159 @@
|
|||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
|
||||
typedef std::unordered_map<uint, BOOKMARKSINFO> BookmarksInfo;
|
||||
typedef std::map<uint, BOOKMARKSINFO> BookmarksInfo;
|
||||
|
||||
static BookmarksInfo bookmarks;
|
||||
|
||||
bool BookmarkSet(uint Address, bool Manual)
|
||||
bool bookmarkset(uint addr, bool manual)
|
||||
{
|
||||
// CHECK: Export call
|
||||
if(!DbgIsDebugging())
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr))
|
||||
return false;
|
||||
|
||||
// Validate the incoming address
|
||||
if(!MemIsValidReadPtr(Address))
|
||||
return false;
|
||||
|
||||
BOOKMARKSINFO bookmark;
|
||||
ModNameFromAddr(Address, bookmark.mod, true);
|
||||
bookmark.addr = Address;
|
||||
bookmark.manual = Manual;
|
||||
|
||||
// Exclusive lock to insert new data
|
||||
EXCLUSIVE_ACQUIRE(LockBookmarks);
|
||||
|
||||
if(!bookmarks.insert(std::make_pair(Address, bookmark)).second)
|
||||
return BookmarkDelete(Address);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool BookmarkGet(uint Address)
|
||||
bool bookmarkget(uint addr)
|
||||
{
|
||||
// CHECK: Export call
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
SHARED_ACQUIRE(LockBookmarks);
|
||||
return (bookmarks.count(Address) > 0);
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
if(bookmarks.count(modhashfromva(addr)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BookmarkDelete(uint Address)
|
||||
bool bookmarkdel(uint addr)
|
||||
{
|
||||
// CHECK: Export call
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockBookmarks);
|
||||
return (bookmarks.erase(Address) > 0);
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
return (bookmarks.erase(modhashfromva(addr)) > 0);
|
||||
}
|
||||
|
||||
void BookmarkDelRange(uint Start, uint End)
|
||||
void bookmarkdelrange(uint start, uint end)
|
||||
{
|
||||
// CHECK: Export call
|
||||
if(!DbgIsDebugging())
|
||||
return;
|
||||
|
||||
// Are all bookmarks going to be deleted?
|
||||
// 0x00000000 - 0xFFFFFFFF
|
||||
if(Start == 0 && End == ~0)
|
||||
bool bDelAll = (start == 0 && end == ~0); //0x00000000-0xFFFFFFFF
|
||||
uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end))
|
||||
return;
|
||||
start -= modbase;
|
||||
end -= modbase;
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
BookmarksInfo::iterator i = bookmarks.begin();
|
||||
while(i != bookmarks.end())
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockBookmarks);
|
||||
bookmarks.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure 'Start' and 'End' reference the same module
|
||||
uint moduleBase = ModBaseFromAddr(Start);
|
||||
|
||||
if(moduleBase != ModBaseFromAddr(End))
|
||||
return;
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockBookmarks);
|
||||
for(auto itr = bookmarks.begin(); itr != bookmarks.end();)
|
||||
if(i->second.manual) //ignore manual
|
||||
{
|
||||
// Ignore manually set entries
|
||||
if(itr->second.manual)
|
||||
{
|
||||
itr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// [Start, End)
|
||||
if(itr->second.addr >= Start && itr->second.addr < End)
|
||||
itr = bookmarks.erase(itr);
|
||||
else
|
||||
itr++;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BookmarkCacheSave(JSON Root)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockBookmarks);
|
||||
|
||||
const JSON jsonBookmarks = json_array();
|
||||
const JSON jsonAutoBookmarks = json_array();
|
||||
|
||||
// Save to the JSON root
|
||||
for(auto & itr : bookmarks)
|
||||
{
|
||||
JSON currentBookmark = json_object();
|
||||
|
||||
// The address must be adjusted to use an offset
|
||||
// OFFSET = ADDRESS - MOD_BASE
|
||||
uint virtualOffset = itr.second.addr - ModBaseFromAddr(itr.second.addr);
|
||||
|
||||
json_object_set_new(currentBookmark, "module", json_string(itr.second.mod));
|
||||
json_object_set_new(currentBookmark, "address", json_hex(virtualOffset));
|
||||
|
||||
if(itr.second.manual)
|
||||
json_array_append_new(jsonBookmarks, currentBookmark);
|
||||
if(bDelAll || (i->second.addr >= start && i->second.addr < end))
|
||||
bookmarks.erase(i++);
|
||||
else
|
||||
json_array_append_new(jsonAutoBookmarks, currentBookmark);
|
||||
i++;
|
||||
}
|
||||
|
||||
if(json_array_size(jsonBookmarks))
|
||||
json_object_set(Root, "bookmarks", jsonBookmarks);
|
||||
|
||||
if(json_array_size(jsonAutoBookmarks))
|
||||
json_object_set(Root, "autobookmarks", jsonAutoBookmarks);
|
||||
|
||||
json_decref(jsonBookmarks);
|
||||
json_decref(jsonAutoBookmarks);
|
||||
}
|
||||
|
||||
void BookmarkCacheLoad(JSON Root)
|
||||
void bookmarkcachesave(JSON root)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockBookmarks);
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
const JSON jsonbookmarks = json_array();
|
||||
const JSON jsonautobookmarks = json_array();
|
||||
for(BookmarksInfo::iterator i = bookmarks.begin(); i != bookmarks.end(); ++i)
|
||||
{
|
||||
const BOOKMARKSINFO curBookmark = i->second;
|
||||
JSON curjsonbookmark = json_object();
|
||||
json_object_set_new(curjsonbookmark, "module", json_string(curBookmark.mod));
|
||||
json_object_set_new(curjsonbookmark, "address", json_hex(curBookmark.addr));
|
||||
if(curBookmark.manual)
|
||||
json_array_append_new(jsonbookmarks, curjsonbookmark);
|
||||
else
|
||||
json_array_append_new(jsonautobookmarks, curjsonbookmark);
|
||||
}
|
||||
if(json_array_size(jsonbookmarks))
|
||||
json_object_set(root, "bookmarks", jsonbookmarks);
|
||||
json_decref(jsonbookmarks);
|
||||
if(json_array_size(jsonautobookmarks))
|
||||
json_object_set(root, "autobookmarks", jsonautobookmarks);
|
||||
json_decref(jsonautobookmarks);
|
||||
}
|
||||
|
||||
// Inline lambda to parse each JSON entry
|
||||
auto AddBookmarks = [](const JSON Object, bool Manual)
|
||||
void bookmarkcacheload(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
bookmarks.clear();
|
||||
const JSON jsonbookmarks = json_object_get(root, "bookmarks");
|
||||
if(jsonbookmarks)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
|
||||
json_array_foreach(Object, i, value)
|
||||
json_array_foreach(jsonbookmarks, i, value)
|
||||
{
|
||||
BOOKMARKSINFO bookmarkInfo;
|
||||
memset(&bookmarkInfo, 0, sizeof(BOOKMARKSINFO));
|
||||
|
||||
// Load the module name
|
||||
BOOKMARKSINFO curBookmark;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(bookmarkInfo.mod, mod);
|
||||
|
||||
// Load address and set auto-generated flag
|
||||
bookmarkInfo.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
bookmarkInfo.manual = Manual;
|
||||
|
||||
// The offset must be adjusted to use virtual addressing
|
||||
// ADDRESS = OFFSET + MOD_BASE
|
||||
bookmarkInfo.addr += ModBaseFromName(bookmarkInfo.mod);
|
||||
|
||||
bookmarks.insert(std::make_pair(bookmarkInfo.addr, bookmarkInfo));
|
||||
strcpy_s(curBookmark.mod, mod);
|
||||
else
|
||||
*curBookmark.mod = '\0';
|
||||
curBookmark.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
curBookmark.manual = true;
|
||||
const uint key = modhashfromname(curBookmark.mod) + curBookmark.addr;
|
||||
bookmarks.insert(std::make_pair(key, curBookmark));
|
||||
}
|
||||
};
|
||||
|
||||
// Remove existing entries
|
||||
bookmarks.clear();
|
||||
|
||||
const JSON jsonBookmarks = json_object_get(Root, "bookmarks");
|
||||
const JSON jsonAutoBookmarks = json_object_get(Root, "autobookmarks");
|
||||
|
||||
// Load user-set bookmarks
|
||||
if(jsonBookmarks)
|
||||
AddBookmarks(jsonBookmarks, true);
|
||||
|
||||
// Load auto-set bookmarks
|
||||
if(jsonAutoBookmarks)
|
||||
AddBookmarks(jsonAutoBookmarks, false);
|
||||
}
|
||||
JSON jsonautobookmarks = json_object_get(root, "autobookmarks");
|
||||
if(jsonautobookmarks)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonautobookmarks, i, value)
|
||||
{
|
||||
BOOKMARKSINFO curBookmark;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curBookmark.mod, mod);
|
||||
else
|
||||
*curBookmark.mod = '\0';
|
||||
curBookmark.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
curBookmark.manual = false;
|
||||
const uint key = modhashfromname(curBookmark.mod) + curBookmark.addr;
|
||||
bookmarks.insert(std::make_pair(key, curBookmark));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool BookmarkEnum(BOOKMARKSINFO* List, size_t* Size)
|
||||
bool bookmarkenum(BOOKMARKSINFO* bookmarklist, size_t* cbsize)
|
||||
{
|
||||
// The array container must be set, or the size must be set, or both
|
||||
if(!List && !Size)
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
SHARED_ACQUIRE(LockBookmarks);
|
||||
|
||||
// Return the size if set
|
||||
if(Size)
|
||||
if(!bookmarklist && !cbsize)
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
if(!bookmarklist && cbsize)
|
||||
{
|
||||
*Size = bookmarks.size() * sizeof(BOOKMARKSINFO);
|
||||
|
||||
if(!List)
|
||||
return true;
|
||||
*cbsize = bookmarks.size() * sizeof(BOOKMARKSINFO);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Copy struct over
|
||||
for(auto & itr : bookmarks)
|
||||
int j = 0;
|
||||
for(BookmarksInfo::iterator i = bookmarks.begin(); i != bookmarks.end(); ++i, j++)
|
||||
{
|
||||
*List = itr.second;
|
||||
List++;
|
||||
bookmarklist[j] = i->second;
|
||||
bookmarklist[j].addr += modbasefromname(bookmarklist[j].mod);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BookmarkClear()
|
||||
void bookmarkclear()
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockBookmarks);
|
||||
bookmarks.clear();
|
||||
CriticalSectionLocker locker(LockBookmarks);
|
||||
BookmarksInfo().swap(bookmarks);
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#ifndef _BOOKMARK_H
|
||||
#define _BOOKMARK_H
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
|
@ -9,11 +10,13 @@ struct BOOKMARKSINFO
|
|||
bool manual;
|
||||
};
|
||||
|
||||
bool BookmarkSet(uint Address, bool Manual);
|
||||
bool BookmarkGet(uint Address);
|
||||
bool BookmarkDelete(uint Address);
|
||||
void BookmarkDelRange(uint Start, uint End);
|
||||
void BookmarkCacheSave(JSON Root);
|
||||
void BookmarkCacheLoad(JSON Root);
|
||||
bool BookmarkEnum(BOOKMARKSINFO* List, size_t* Size);
|
||||
void BookmarkClear();
|
||||
bool bookmarkset(uint addr, bool manual);
|
||||
bool bookmarkget(uint addr);
|
||||
bool bookmarkdel(uint addr);
|
||||
void bookmarkdelrange(uint start, uint end);
|
||||
void bookmarkcachesave(JSON root);
|
||||
void bookmarkcacheload(JSON root);
|
||||
bool bookmarkenum(BOOKMARKSINFO* bookmarklist, size_t* cbsize);
|
||||
void bookmarkclear();
|
||||
|
||||
#endif //_BOOKMARK_H
|
|
@ -11,385 +11,266 @@ typedef std::map<BreakpointKey, BREAKPOINT> BreakpointsInfo;
|
|||
|
||||
static BreakpointsInfo breakpoints;
|
||||
|
||||
BREAKPOINT* BpInfoFromAddr(BP_TYPE Type, uint Address)
|
||||
{
|
||||
//
|
||||
// NOTE: THIS DOES _NOT_ USE LOCKS
|
||||
//
|
||||
auto found = breakpoints.find(BreakpointKey(Type, ModHashFromAddr(Address)));
|
||||
|
||||
// Was the module found with this address?
|
||||
if(found == breakpoints.end())
|
||||
return nullptr;
|
||||
|
||||
return &found->second;
|
||||
}
|
||||
|
||||
int BpGetList(std::vector<BREAKPOINT>* List)
|
||||
{
|
||||
// CHECK: Exported function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
SHARED_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Did the caller request an output?
|
||||
if(List)
|
||||
{
|
||||
// Enumerate all breakpoints in the global list, fixing the relative
|
||||
// offset to a virtual address
|
||||
for(auto & i : breakpoints)
|
||||
{
|
||||
BREAKPOINT currentBp = i.second;
|
||||
currentBp.addr += ModBaseFromName(currentBp.mod);
|
||||
currentBp.active = MemIsValidReadPtr(currentBp.addr);
|
||||
|
||||
List->push_back(currentBp);
|
||||
}
|
||||
}
|
||||
|
||||
return (int)breakpoints.size();
|
||||
}
|
||||
|
||||
bool BpNew(uint Address, bool Enable, bool Singleshot, short OldBytes, BP_TYPE Type, DWORD TitanType, const char* Name)
|
||||
{
|
||||
// CHECK: Command function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
// Fail if the address is a bad memory region
|
||||
if(!MemIsValidReadPtr(Address))
|
||||
return false;
|
||||
|
||||
// Fail if the breakpoint already exists
|
||||
if(BpGet(Address, Type, Name, nullptr))
|
||||
return false;
|
||||
|
||||
// Default to an empty name if one wasn't supplied
|
||||
if(!Name)
|
||||
Name = "";
|
||||
|
||||
BREAKPOINT bp;
|
||||
memset(&bp, 0, sizeof(BREAKPOINT));
|
||||
|
||||
ModNameFromAddr(Address, bp.mod, true);
|
||||
strcpy_s(bp.name, Name);
|
||||
|
||||
bp.active = true;
|
||||
bp.addr = Address - ModBaseFromAddr(Address);
|
||||
bp.enabled = Enable;
|
||||
bp.oldbytes = OldBytes;
|
||||
bp.singleshoot = Singleshot;
|
||||
bp.titantype = TitanType;
|
||||
bp.type = Type;
|
||||
|
||||
// Insert new entry to the global list
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
breakpoints.insert(std::make_pair(BreakpointKey(Type, ModHashFromAddr(Address)), bp));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BpGet(uint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp)
|
||||
{
|
||||
// CHECK: Export/Command function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
SHARED_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Name is optional
|
||||
if(!Name || Name[0] == '\0')
|
||||
{
|
||||
// Perform a lookup by address only
|
||||
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
|
||||
|
||||
if(!bpInfo)
|
||||
return false;
|
||||
|
||||
// Succeed even if the user didn't request anything
|
||||
if(!Bp)
|
||||
return true;
|
||||
|
||||
*Bp = *bpInfo;
|
||||
Bp->addr += ModBaseFromAddr(Address);
|
||||
Bp->active = MemIsValidReadPtr(Bp->addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Do a lookup by breakpoint name
|
||||
for(auto & i : breakpoints)
|
||||
{
|
||||
// Do the names match?
|
||||
if(strcmp(Name, i.second.name) != 0)
|
||||
continue;
|
||||
|
||||
// Fill out the optional user buffer
|
||||
if(Bp)
|
||||
{
|
||||
*Bp = i.second;
|
||||
Bp->addr += ModBaseFromAddr(Address);
|
||||
Bp->active = MemIsValidReadPtr(Bp->addr);
|
||||
}
|
||||
|
||||
// Return true if the name was found at all
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BpDelete(uint Address, BP_TYPE Type)
|
||||
{
|
||||
// CHECK: Command function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
// Erase the index from the global list
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
return (breakpoints.erase(BreakpointKey(Type, ModHashFromAddr(Address))) > 0);
|
||||
}
|
||||
|
||||
bool BpEnable(uint Address, BP_TYPE Type, bool Enable)
|
||||
{
|
||||
// CHECK: Command function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Check if the breakpoint exists first
|
||||
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
|
||||
|
||||
if(!bpInfo)
|
||||
return false;
|
||||
|
||||
bpInfo->enabled = Enable;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BpSetName(uint Address, BP_TYPE Type, const char* Name)
|
||||
{
|
||||
// CHECK: Future(?); This is not used anywhere
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
// If a name wasn't supplied, set to nothing
|
||||
if(!Name)
|
||||
Name = "";
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Check if the breakpoint exists first
|
||||
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
|
||||
|
||||
if(!bpInfo)
|
||||
return false;
|
||||
|
||||
strcpy_s(bpInfo->name, Name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BpSetTitanType(uint Address, BP_TYPE Type, int TitanType)
|
||||
{
|
||||
// CHECK: Command function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Set the TitanEngine type, separate from BP_TYPE
|
||||
BREAKPOINT* bpInfo = BpInfoFromAddr(Type, Address);
|
||||
|
||||
if(!bpInfo)
|
||||
return false;
|
||||
|
||||
bpInfo->titantype = TitanType;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module)
|
||||
int bpgetlist(std::vector<BREAKPOINT>* list)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
SHARED_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Loop each entry, executing the user's callback
|
||||
bool callbackStatus = false;
|
||||
|
||||
for(auto & i : breakpoints)
|
||||
{
|
||||
// If a module name was sent, check it
|
||||
if(Module && Module[0] != '\0')
|
||||
{
|
||||
if(strcmp(i.second.mod, Module) != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
BREAKPOINT bpInfo = i.second;
|
||||
bpInfo.addr += ModBaseFromName(bpInfo.mod);
|
||||
bpInfo.active = MemIsValidReadPtr(bpInfo.addr);
|
||||
|
||||
// Execute the callback
|
||||
if(!EnumCallback(&bpInfo))
|
||||
callbackStatus = false;
|
||||
}
|
||||
|
||||
return callbackStatus;
|
||||
}
|
||||
|
||||
bool BpEnumAll(BPENUMCALLBACK EnumCallback)
|
||||
{
|
||||
return BpEnumAll(EnumCallback, nullptr);
|
||||
}
|
||||
|
||||
int BpGetCount(BP_TYPE Type, bool EnabledOnly)
|
||||
{
|
||||
SHARED_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Count the number of enabled/disabled breakpoint types
|
||||
BREAKPOINT curBp;
|
||||
int count = 0;
|
||||
|
||||
for(auto & i : breakpoints)
|
||||
CriticalSectionLocker locker(LockBreakpoints);
|
||||
for(BreakpointsInfo::iterator i = breakpoints.begin(); i != breakpoints.end(); ++i)
|
||||
{
|
||||
// Check if the type matches
|
||||
if(i.first.first != Type)
|
||||
continue;
|
||||
|
||||
// If it's not enabled, skip it
|
||||
if(EnabledOnly && !i.second.enabled)
|
||||
continue;
|
||||
|
||||
curBp = i->second;
|
||||
curBp.addr += modbasefromname(curBp.mod);
|
||||
curBp.active = memisvalidreadptr(fdProcessInfo->hProcess, curBp.addr);
|
||||
count++;
|
||||
if(list)
|
||||
list->push_back(curBp);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void BpToBridge(const BREAKPOINT* Bp, BRIDGEBP* BridgeBp)
|
||||
bool bpnew(uint addr, bool enabled, bool singleshoot, short oldbytes, BP_TYPE type, DWORD titantype, const char* name)
|
||||
{
|
||||
//
|
||||
// Convert a debugger breakpoint to an open/exported
|
||||
// bridge breakpoint
|
||||
//
|
||||
// TOOD: ASSERT(?) These should never be null
|
||||
if(!Bp || !BridgeBp)
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or bpget(addr, type, name, 0))
|
||||
return false;
|
||||
BREAKPOINT bp;
|
||||
modnamefromaddr(addr, bp.mod, true);
|
||||
uint modbase = modbasefromaddr(addr);
|
||||
bp.active = true;
|
||||
bp.addr = addr - modbase;
|
||||
bp.enabled = enabled;
|
||||
if(name and * name)
|
||||
strcpy_s(bp.name, name);
|
||||
else
|
||||
*bp.name = '\0';
|
||||
bp.oldbytes = oldbytes;
|
||||
bp.singleshoot = singleshoot;
|
||||
bp.titantype = titantype;
|
||||
bp.type = type;
|
||||
CriticalSectionLocker locker(LockBreakpoints);
|
||||
breakpoints.insert(std::make_pair(BreakpointKey(type, modhashfromva(addr)), bp));
|
||||
return true;
|
||||
}
|
||||
|
||||
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)));
|
||||
if(found == breakpoints.end()) //not found
|
||||
return false;
|
||||
if(!bp)
|
||||
return true;
|
||||
curBp = found->second;
|
||||
curBp.addr += modbasefromaddr(addr);
|
||||
curBp.active = memisvalidreadptr(fdProcessInfo->hProcess, curBp.addr);
|
||||
*bp = curBp;
|
||||
return true;
|
||||
}
|
||||
for(BreakpointsInfo::iterator i = breakpoints.begin(); i != breakpoints.end(); ++i)
|
||||
{
|
||||
curBp = i->second;
|
||||
if(name and * name)
|
||||
{
|
||||
if(!strcmp(name, curBp.name))
|
||||
{
|
||||
if(bp)
|
||||
{
|
||||
curBp.addr += modbasefromname(curBp.mod);
|
||||
curBp.active = memisvalidreadptr(fdProcessInfo->hProcess, curBp.addr);
|
||||
*bp = curBp;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bpdel(uint addr, BP_TYPE type)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockBreakpoints);
|
||||
return (breakpoints.erase(BreakpointKey(type, modhashfromva(addr))) > 0);
|
||||
}
|
||||
|
||||
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;
|
||||
breakpoints[found->first].enabled = enable;
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
strcpy_s(breakpoints[found->first].name, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
breakpoints[found->first].titantype = titantype;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bpenumall(BPENUMCALLBACK cbEnum, const char* module)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
bool retval = true;
|
||||
BREAKPOINT curBp;
|
||||
CriticalSectionLocker locker(LockBreakpoints);
|
||||
BreakpointsInfo::iterator i = breakpoints.begin();
|
||||
while(i != breakpoints.end())
|
||||
{
|
||||
BreakpointsInfo::iterator j = i;
|
||||
++i;
|
||||
curBp = j->second;
|
||||
curBp.addr += modbasefromname(curBp.mod); //RVA to VA
|
||||
curBp.active = memisvalidreadptr(fdProcessInfo->hProcess, curBp.addr); //TODO: wtf am I doing?
|
||||
if(module and * module)
|
||||
{
|
||||
if(!strcmp(curBp.mod, module))
|
||||
{
|
||||
if(!cbEnum(&curBp))
|
||||
retval = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!cbEnum(&curBp))
|
||||
retval = false;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool bpenumall(BPENUMCALLBACK cbEnum)
|
||||
{
|
||||
return bpenumall(cbEnum, 0);
|
||||
}
|
||||
|
||||
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))
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void bptobridge(const BREAKPOINT* bp, BRIDGEBP* bridge)
|
||||
{
|
||||
if(!bp or !bridge)
|
||||
return;
|
||||
|
||||
memset(BridgeBp, 0, sizeof(BRIDGEBP));
|
||||
strcpy_s(BridgeBp->mod, Bp->mod);
|
||||
strcpy_s(BridgeBp->name, Bp->name);
|
||||
|
||||
BridgeBp->active = Bp->active;
|
||||
BridgeBp->addr = Bp->addr;
|
||||
BridgeBp->enabled = Bp->enabled;
|
||||
BridgeBp->singleshoot = Bp->singleshoot;
|
||||
|
||||
switch(Bp->type)
|
||||
memset(bridge, 0, sizeof(BRIDGEBP));
|
||||
bridge->active = bp->active;
|
||||
bridge->addr = bp->addr;
|
||||
bridge->enabled = bp->enabled;
|
||||
strcpy_s(bridge->mod, bp->mod);
|
||||
strcpy_s(bridge->name, bp->name);
|
||||
bridge->singleshoot = bp->singleshoot;
|
||||
switch(bp->type)
|
||||
{
|
||||
case BPNORMAL:
|
||||
BridgeBp->type = bp_normal;
|
||||
bridge->type = bp_normal;
|
||||
break;
|
||||
case BPHARDWARE:
|
||||
BridgeBp->type = bp_hardware;
|
||||
bridge->type = bp_hardware;
|
||||
break;
|
||||
case BPMEMORY:
|
||||
BridgeBp->type = bp_memory;
|
||||
break;
|
||||
bridge->type = bp_memory;
|
||||
break; //so that's why it didn't show in the gui.
|
||||
default:
|
||||
BridgeBp->type = bp_none;
|
||||
bridge->type = bp_none;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BpCacheSave(JSON Root)
|
||||
void bpcachesave(JSON root)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Create a JSON array to store each sub-object with a breakpoint
|
||||
const JSON jsonBreakpoints = json_array();
|
||||
|
||||
// Loop all breakpoints
|
||||
for(auto & i : breakpoints)
|
||||
CriticalSectionLocker locker(LockBreakpoints);
|
||||
const JSON jsonbreakpoints = json_array();
|
||||
for(BreakpointsInfo::iterator i = breakpoints.begin(); i != breakpoints.end(); ++i)
|
||||
{
|
||||
auto & breakpoint = i.second;
|
||||
|
||||
// Ignore single-shot breakpoints
|
||||
if(breakpoint.singleshoot)
|
||||
continue;
|
||||
|
||||
JSON jsonObj = json_object();
|
||||
json_object_set_new(jsonObj, "address", json_hex(breakpoint.addr));
|
||||
json_object_set_new(jsonObj, "enabled", json_boolean(breakpoint.enabled));
|
||||
|
||||
// "Normal" breakpoints save the old data
|
||||
if(breakpoint.type == BPNORMAL)
|
||||
json_object_set_new(jsonObj, "oldbytes", json_hex(breakpoint.oldbytes));
|
||||
|
||||
json_object_set_new(jsonObj, "type", json_integer(breakpoint.type));
|
||||
json_object_set_new(jsonObj, "titantype", json_hex(breakpoint.titantype));
|
||||
json_object_set_new(jsonObj, "name", json_string(breakpoint.name));
|
||||
json_object_set_new(jsonObj, "module", json_string(breakpoint.mod));
|
||||
json_array_append_new(jsonBreakpoints, jsonObj);
|
||||
const BREAKPOINT curBreakpoint = i->second;
|
||||
if(curBreakpoint.singleshoot)
|
||||
continue; //skip
|
||||
JSON curjsonbreakpoint = json_object();
|
||||
json_object_set_new(curjsonbreakpoint, "address", json_hex(curBreakpoint.addr));
|
||||
json_object_set_new(curjsonbreakpoint, "enabled", json_boolean(curBreakpoint.enabled));
|
||||
if(curBreakpoint.type == BPNORMAL)
|
||||
json_object_set_new(curjsonbreakpoint, "oldbytes", json_hex(curBreakpoint.oldbytes));
|
||||
json_object_set_new(curjsonbreakpoint, "type", json_integer(curBreakpoint.type));
|
||||
json_object_set_new(curjsonbreakpoint, "titantype", json_hex(curBreakpoint.titantype));
|
||||
json_object_set_new(curjsonbreakpoint, "name", json_string(curBreakpoint.name));
|
||||
json_object_set_new(curjsonbreakpoint, "module", json_string(curBreakpoint.mod));
|
||||
json_array_append_new(jsonbreakpoints, curjsonbreakpoint);
|
||||
}
|
||||
|
||||
if(json_array_size(jsonBreakpoints))
|
||||
json_object_set(Root, "breakpoints", jsonBreakpoints);
|
||||
|
||||
// Notify garbage collector
|
||||
json_decref(jsonBreakpoints);
|
||||
if(json_array_size(jsonbreakpoints))
|
||||
json_object_set(root, "breakpoints", jsonbreakpoints);
|
||||
json_decref(jsonbreakpoints);
|
||||
}
|
||||
|
||||
void BpCacheLoad(JSON Root)
|
||||
void bpcacheload(JSON root)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
|
||||
// Remove all existing elements
|
||||
CriticalSectionLocker locker(LockBreakpoints);
|
||||
breakpoints.clear();
|
||||
|
||||
// Get a handle to the root object -> breakpoints subtree
|
||||
const JSON jsonBreakpoints = json_object_get(Root, "breakpoints");
|
||||
|
||||
// Return if there was nothing to load
|
||||
if(!jsonBreakpoints)
|
||||
return;
|
||||
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonBreakpoints, i, value)
|
||||
const JSON jsonbreakpoints = json_object_get(root, "breakpoints");
|
||||
if(jsonbreakpoints)
|
||||
{
|
||||
BREAKPOINT breakpoint;
|
||||
memset(&breakpoint, 0, sizeof(BREAKPOINT));
|
||||
|
||||
if(breakpoint.type == BPNORMAL)
|
||||
breakpoint.oldbytes = (short)json_hex_value(json_object_get(value, "oldbytes"));
|
||||
breakpoint.type = (BP_TYPE)json_integer_value(json_object_get(value, "type"));
|
||||
breakpoint.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
breakpoint.enabled = json_boolean_value(json_object_get(value, "enabled"));
|
||||
breakpoint.titantype = (DWORD)json_hex_value(json_object_get(value, "titantype"));
|
||||
|
||||
// Name
|
||||
const char* name = json_string_value(json_object_get(value, "name"));
|
||||
|
||||
if(name)
|
||||
strcpy_s(breakpoint.name, name);
|
||||
|
||||
// Module
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(breakpoint.mod, mod);
|
||||
|
||||
// Build the hash map key: MOD_HASH + ADDRESS
|
||||
const uint key = ModHashFromName(breakpoint.mod) + breakpoint.addr;
|
||||
breakpoints.insert(std::make_pair(BreakpointKey(breakpoint.type, key), breakpoint));
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonbreakpoints, i, value)
|
||||
{
|
||||
BREAKPOINT curBreakpoint;
|
||||
memset(&curBreakpoint, 0, sizeof(BREAKPOINT));
|
||||
curBreakpoint.type = (BP_TYPE)json_integer_value(json_object_get(value, "type"));
|
||||
if(curBreakpoint.type == BPNORMAL)
|
||||
curBreakpoint.oldbytes = (short)json_hex_value(json_object_get(value, "oldbytes"));
|
||||
curBreakpoint.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
curBreakpoint.enabled = json_boolean_value(json_object_get(value, "enabled"));
|
||||
curBreakpoint.titantype = (DWORD)json_hex_value(json_object_get(value, "titantype"));
|
||||
const char* name = json_string_value(json_object_get(value, "name"));
|
||||
if(name)
|
||||
strcpy_s(curBreakpoint.name, name);
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curBreakpoint.mod, mod);
|
||||
const uint key = modhashfromname(curBreakpoint.mod) + curBreakpoint.addr;
|
||||
breakpoints.insert(std::make_pair(BreakpointKey(curBreakpoint.type, key), curBreakpoint));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BpClear()
|
||||
void bpclear()
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockBreakpoints);
|
||||
breakpoints.clear();
|
||||
CriticalSectionLocker locker(LockBreakpoints);
|
||||
BreakpointsInfo().swap(breakpoints);
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
#pragma once
|
||||
#ifndef _BREAKPOINT_H
|
||||
#define _BREAKPOINT_H
|
||||
|
||||
#include "_global.h"
|
||||
#include "TitanEngine\TitanEngine.h"
|
||||
|
||||
//macros
|
||||
#define TITANSETDRX(titantype, drx) titantype &= 0x0FF; titantype |= (drx<<8)
|
||||
#define TITANGETDRX(titantype) (titantype >> 8) & 0xF
|
||||
#define TITANSETTYPE(titantype, type) titantype &= 0xF0F; titantype |= (type<<4)
|
||||
|
@ -10,6 +12,7 @@
|
|||
#define TITANSETSIZE(titantype, size) titantype &= 0xFF0; titantype |= size;
|
||||
#define TITANGETSIZE(titantype) titantype & 0xF
|
||||
|
||||
//enums
|
||||
enum BP_TYPE
|
||||
{
|
||||
BPNORMAL = 0,
|
||||
|
@ -17,6 +20,7 @@ enum BP_TYPE
|
|||
BPMEMORY = 2
|
||||
};
|
||||
|
||||
//structs
|
||||
struct BREAKPOINT
|
||||
{
|
||||
uint addr;
|
||||
|
@ -30,21 +34,23 @@ struct BREAKPOINT
|
|||
char mod[MAX_MODULE_SIZE];
|
||||
};
|
||||
|
||||
// Breakpoint enumeration callback
|
||||
//typedefs
|
||||
typedef bool (*BPENUMCALLBACK)(const BREAKPOINT* bp);
|
||||
|
||||
BREAKPOINT* BpInfoFromAddr(BP_TYPE Type, uint Address);
|
||||
int BpGetList(std::vector<BREAKPOINT>* List);
|
||||
bool BpNew(uint Address, bool Enable, bool Singleshot, short OldBytes, BP_TYPE Type, DWORD TitanType, const char* Name);
|
||||
bool BpGet(uint Address, BP_TYPE Type, const char* Name, BREAKPOINT* Bp);
|
||||
bool BpDelete(uint Address, BP_TYPE Type);
|
||||
bool BpEnable(uint Address, BP_TYPE Type, bool Enable);
|
||||
bool BpSetName(uint Address, BP_TYPE Type, const char* Name);
|
||||
bool BpSetTitanType(uint Address, BP_TYPE Type, int TitanType);
|
||||
bool BpEnumAll(BPENUMCALLBACK EnumCallback, const char* Module);
|
||||
bool BpEnumAll(BPENUMCALLBACK EnumCallback);
|
||||
int BpGetCount(BP_TYPE Type, bool EnabledOnly = false);
|
||||
void BpToBridge(const BREAKPOINT* Bp, BRIDGEBP* BridgeBp);
|
||||
void BpCacheSave(JSON Root);
|
||||
void BpCacheLoad(JSON Root);
|
||||
void BpClear();
|
||||
//functions
|
||||
int bpgetlist(std::vector<BREAKPOINT>* list);
|
||||
bool bpnew(uint addr, bool enabled, bool singleshoot, short oldbytes, BP_TYPE type, DWORD titantype, const char* name);
|
||||
bool bpget(uint addr, BP_TYPE type, const char* name, BREAKPOINT* bp);
|
||||
bool bpdel(uint addr, BP_TYPE type);
|
||||
bool bpenable(uint addr, BP_TYPE type, bool enable);
|
||||
bool bpsetname(uint addr, BP_TYPE type, const char* name);
|
||||
bool bpsettitantype(uint addr, BP_TYPE type, int titantype);
|
||||
bool bpenumall(BPENUMCALLBACK cbEnum);
|
||||
bool bpenumall(BPENUMCALLBACK cbEnum, const char* module);
|
||||
int bpgetcount(BP_TYPE type, bool enabledonly = false);
|
||||
void bptobridge(const BREAKPOINT* bp, BRIDGEBP* bridge);
|
||||
void bpcachesave(JSON root);
|
||||
void bpcacheload(JSON root);
|
||||
void bpclear();
|
||||
|
||||
#endif // _BREAKPOINT_H
|
||||
|
|
|
@ -4,245 +4,179 @@
|
|||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
|
||||
typedef std::unordered_map<uint, COMMENTSINFO> CommentsInfo;
|
||||
typedef std::map<uint, COMMENTSINFO> CommentsInfo;
|
||||
|
||||
static CommentsInfo comments;
|
||||
|
||||
bool CommentSet(uint Address, const char* Text, bool Manual)
|
||||
bool commentset(uint addr, const char* text, bool manual)
|
||||
{
|
||||
// CHECK: Exported/Command function
|
||||
if(!DbgIsDebugging())
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or text[0] == '\1' or strlen(text) >= MAX_COMMENT_SIZE - 1)
|
||||
return false;
|
||||
|
||||
// A valid memory address must be supplied
|
||||
if(!MemIsValidReadPtr(Address))
|
||||
return false;
|
||||
|
||||
// Make sure the string is supplied, within bounds, and not a special delimiter
|
||||
if(!Text || Text[0] == '\1' || strlen(Text) >= MAX_COMMENT_SIZE - 1)
|
||||
return false;
|
||||
|
||||
// Delete the comment if no text was supplied
|
||||
if(Text[0] == '\0')
|
||||
if(!*text) //NOTE: delete when there is no text
|
||||
{
|
||||
CommentDelete(Address);
|
||||
commentdel(addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fill out the structure
|
||||
COMMENTSINFO comment;
|
||||
strcpy_s(comment.text, Text);
|
||||
ModNameFromAddr(Address, comment.mod, true);
|
||||
|
||||
comment.manual = Manual;
|
||||
comment.addr = Address;
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockComments);
|
||||
|
||||
// Insert if possible, otherwise replace
|
||||
if (!comments.insert(std::make_pair(Address, comment)).second)
|
||||
comments[Address] = comment;
|
||||
|
||||
comment.manual = manual;
|
||||
strcpy_s(comment.text, text);
|
||||
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;
|
||||
}
|
||||
|
||||
bool CommentGet(uint Address, char* Text)
|
||||
bool commentget(uint addr, char* text)
|
||||
{
|
||||
// CHECK: Exported/Command function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
SHARED_ACQUIRE(LockComments);
|
||||
|
||||
// Get an existing comment and copy the string buffer
|
||||
auto found = comments.find(Address);
|
||||
|
||||
// Was it found?
|
||||
if(found == comments.end())
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
const CommentsInfo::iterator found = comments.find(modhashfromva(addr));
|
||||
if(found == comments.end()) //not found
|
||||
return false;
|
||||
|
||||
strcpy_s(Text, MAX_COMMENT_SIZE, found->second.text);
|
||||
strcpy_s(text, MAX_COMMENT_SIZE, found->second.text);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommentDelete(uint Address)
|
||||
bool commentdel(uint addr)
|
||||
{
|
||||
// CHECK: Command/Sub function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockComments);
|
||||
return (comments.erase(Address) > 0);
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
return (comments.erase(modhashfromva(addr)) == 1);
|
||||
}
|
||||
|
||||
void CommentDelRange(uint Start, uint End)
|
||||
void commentdelrange(uint start, uint end)
|
||||
{
|
||||
// CHECK: Export function
|
||||
if(!DbgIsDebugging())
|
||||
return;
|
||||
|
||||
// Are all comments going to be deleted?
|
||||
// 0x00000000 - 0xFFFFFFFF
|
||||
if(Start == 0 && End == ~0)
|
||||
bool bDelAll = (start == 0 && end == ~0); //0x00000000-0xFFFFFFFF
|
||||
uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end))
|
||||
return;
|
||||
start -= modbase;
|
||||
end -= modbase;
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
CommentsInfo::iterator i = comments.begin();
|
||||
while(i != comments.end())
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockComments);
|
||||
comments.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure 'Start' and 'End' reference the same module
|
||||
uint moduleBase = ModBaseFromAddr(Start);
|
||||
|
||||
if(moduleBase != ModBaseFromAddr(End))
|
||||
return;
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockComments);
|
||||
for(auto itr = comments.begin(); itr != comments.end();)
|
||||
if(i->second.manual) //ignore manual
|
||||
{
|
||||
// Ignore manually set entries
|
||||
if(itr->second.manual)
|
||||
{
|
||||
itr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// [Start, End)
|
||||
if(itr->second.addr >= Start && itr->second.addr < End)
|
||||
itr = comments.erase(itr);
|
||||
else
|
||||
itr++;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommentCacheSave(JSON Root)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockComments);
|
||||
|
||||
const JSON jsonComments = json_array();
|
||||
const JSON jsonAutoComments = json_array();
|
||||
|
||||
// Build the JSON array
|
||||
for(auto & itr : comments)
|
||||
{
|
||||
JSON currentComment = json_object();
|
||||
|
||||
// OFFSET = ADDRESS - MOD_BASE
|
||||
uint virtualOffset = itr.second.addr - ModBaseFromAddr(itr.second.addr);
|
||||
|
||||
json_object_set_new(currentComment, "module", json_string(itr.second.mod));
|
||||
json_object_set_new(currentComment, "address", json_hex(virtualOffset));
|
||||
json_object_set_new(currentComment, "text", json_string(itr.second.text));
|
||||
|
||||
if(itr.second.manual)
|
||||
json_array_append_new(jsonComments, currentComment);
|
||||
if(bDelAll || (i->second.addr >= start && i->second.addr < end))
|
||||
comments.erase(i++);
|
||||
else
|
||||
json_array_append_new(jsonAutoComments, currentComment);
|
||||
i++;
|
||||
}
|
||||
|
||||
// Save to the JSON root
|
||||
if(json_array_size(jsonComments))
|
||||
json_object_set(Root, "comments", jsonComments);
|
||||
|
||||
if(json_array_size(jsonAutoComments))
|
||||
json_object_set(Root, "autocomments", jsonAutoComments);
|
||||
|
||||
json_decref(jsonComments);
|
||||
json_decref(jsonAutoComments);
|
||||
}
|
||||
|
||||
void CommentCacheLoad(JSON Root)
|
||||
void commentcachesave(JSON root)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockBookmarks);
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
const JSON jsoncomments = json_array();
|
||||
const JSON jsonautocomments = json_array();
|
||||
for(CommentsInfo::iterator i = comments.begin(); i != comments.end(); ++i)
|
||||
{
|
||||
const COMMENTSINFO curComment = i->second;
|
||||
JSON curjsoncomment = json_object();
|
||||
json_object_set_new(curjsoncomment, "module", json_string(curComment.mod));
|
||||
json_object_set_new(curjsoncomment, "address", json_hex(curComment.addr));
|
||||
json_object_set_new(curjsoncomment, "text", json_string(curComment.text));
|
||||
if(curComment.manual)
|
||||
json_array_append_new(jsoncomments, curjsoncomment);
|
||||
else
|
||||
json_array_append_new(jsonautocomments, curjsoncomment);
|
||||
}
|
||||
if(json_array_size(jsoncomments))
|
||||
json_object_set(root, "comments", jsoncomments);
|
||||
json_decref(jsoncomments);
|
||||
if(json_array_size(jsonautocomments))
|
||||
json_object_set(root, "autocomments", jsonautocomments);
|
||||
json_decref(jsonautocomments);
|
||||
}
|
||||
|
||||
// Inline lambda to parse each JSON entry
|
||||
auto AddBookmarks = [](const JSON Object, bool Manual)
|
||||
void commentcacheload(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
comments.clear();
|
||||
const JSON jsoncomments = json_object_get(root, "comments");
|
||||
if(jsoncomments)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
|
||||
json_array_foreach(Object, i, value)
|
||||
json_array_foreach(jsoncomments, i, value)
|
||||
{
|
||||
COMMENTSINFO commentInfo;
|
||||
|
||||
// Module
|
||||
COMMENTSINFO curComment;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(commentInfo.mod, mod);
|
||||
strcpy_s(curComment.mod, mod);
|
||||
else
|
||||
commentInfo.mod[0] = '\0';
|
||||
|
||||
// Address/Manual
|
||||
commentInfo.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
commentInfo.manual = Manual;
|
||||
|
||||
// String value
|
||||
*curComment.mod = '\0';
|
||||
curComment.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
curComment.manual = true;
|
||||
const char* text = json_string_value(json_object_get(value, "text"));
|
||||
|
||||
if(text)
|
||||
strcpy_s(commentInfo.text, text);
|
||||
strcpy_s(curComment.text, text);
|
||||
else
|
||||
{
|
||||
// Skip blank comments
|
||||
continue;
|
||||
}
|
||||
|
||||
// ADDRESS = OFFSET + MOD_BASE
|
||||
commentInfo.addr += ModBaseFromName(commentInfo.mod);
|
||||
|
||||
comments.insert(std::make_pair(commentInfo.addr, commentInfo));
|
||||
continue; //skip
|
||||
const uint key = modhashfromname(curComment.mod) + curComment.addr;
|
||||
comments.insert(std::make_pair(key, curComment));
|
||||
}
|
||||
};
|
||||
|
||||
// Remove existing entries
|
||||
comments.clear();
|
||||
|
||||
const JSON jsonComments = json_object_get(Root, "comments");
|
||||
const JSON jsonAutoComments = json_object_get(Root, "autocomments");
|
||||
|
||||
// Load user-set comments
|
||||
if(jsonComments)
|
||||
AddBookmarks(jsonComments, true);
|
||||
|
||||
// Load auto-set comments
|
||||
if(jsonAutoComments)
|
||||
AddBookmarks(jsonAutoComments, false);
|
||||
}
|
||||
JSON jsonautocomments = json_object_get(root, "autocomments");
|
||||
if(jsonautocomments)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonautocomments, i, value)
|
||||
{
|
||||
COMMENTSINFO curComment;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curComment.mod, mod);
|
||||
else
|
||||
*curComment.mod = '\0';
|
||||
curComment.addr = (uint)json_hex_value(json_object_get(value, "address"));
|
||||
curComment.manual = false;
|
||||
const char* text = json_string_value(json_object_get(value, "text"));
|
||||
if(text)
|
||||
strcpy_s(curComment.text, text);
|
||||
else
|
||||
continue; //skip
|
||||
const uint key = modhashfromname(curComment.mod) + curComment.addr;
|
||||
comments.insert(std::make_pair(key, curComment));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CommentEnum(COMMENTSINFO* List, size_t* Size)
|
||||
bool commentenum(COMMENTSINFO* commentlist, size_t* cbsize)
|
||||
{
|
||||
// CHECK: Command function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
// At least 1 parameter must be supplied
|
||||
if(!List && !Size)
|
||||
if(!commentlist && !cbsize)
|
||||
return false;
|
||||
|
||||
SHARED_ACQUIRE(LockComments);
|
||||
|
||||
// Check if the user requested size only
|
||||
if(Size)
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
if(!commentlist && cbsize)
|
||||
{
|
||||
*Size = comments.size() * sizeof(COMMENTSINFO);
|
||||
|
||||
if(!List)
|
||||
return true;
|
||||
*cbsize = comments.size() * sizeof(COMMENTSINFO);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Populate the returned array
|
||||
for(auto & itr : comments)
|
||||
int j = 0;
|
||||
for(CommentsInfo::iterator i = comments.begin(); i != comments.end(); ++i, j++)
|
||||
{
|
||||
*List = itr.second;
|
||||
List++;
|
||||
commentlist[j] = i->second;
|
||||
commentlist[j].addr += modbasefromname(commentlist[j].mod);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommentClear()
|
||||
void commentclear()
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockComments);
|
||||
comments.clear();
|
||||
CriticalSectionLocker locker(LockComments);
|
||||
CommentsInfo().swap(comments);
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#ifndef _COMMENT_H
|
||||
#define _COMMENT_H
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
|
@ -10,11 +11,13 @@ struct COMMENTSINFO
|
|||
bool manual;
|
||||
};
|
||||
|
||||
bool CommentSet(uint Address, const char* Text, bool Manual);
|
||||
bool CommentGet(uint Address, char* Text);
|
||||
bool CommentDelete(uint Address);
|
||||
void CommentDelRange(uint Start, uint End);
|
||||
void CommentCacheSave(JSON Root);
|
||||
void CommentCacheLoad(JSON Root);
|
||||
bool CommentEnum(COMMENTSINFO* List, size_t* Size);
|
||||
void CommentClear();
|
||||
bool commentset(uint addr, const char* text, bool manual);
|
||||
bool commentget(uint addr, char* text);
|
||||
bool commentdel(uint addr);
|
||||
void commentdelrange(uint start, uint end);
|
||||
void commentcachesave(JSON root);
|
||||
void commentcacheload(JSON root);
|
||||
bool commentenum(COMMENTSINFO* commentlist, size_t* cbsize);
|
||||
void commentclear();
|
||||
|
||||
#endif //_COMMENT_H
|
|
@ -1,18 +1,18 @@
|
|||
#include "console.h"
|
||||
#include "threading.h"
|
||||
|
||||
void dputs(const char* Text)
|
||||
static char msg[66000] = "";
|
||||
|
||||
void dputs(const char* text)
|
||||
{
|
||||
dprintf("%s\n", Text);
|
||||
dprintf("%s\n", text);
|
||||
}
|
||||
|
||||
void dprintf(const char* Format, ...)
|
||||
void dprintf(const char* format, ...)
|
||||
{
|
||||
CriticalSectionLocker locker(LockDprintf);
|
||||
va_list args;
|
||||
char buffer[16384];
|
||||
|
||||
va_start(args, Format);
|
||||
vsnprintf_s(buffer, _TRUNCATE, Format, args);
|
||||
va_end(args);
|
||||
|
||||
GuiAddLogMessage(buffer);
|
||||
va_start(args, format);
|
||||
vsnprintf(msg, sizeof(msg), format, args);
|
||||
GuiAddLogMessage(msg);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#pragma once
|
||||
#ifndef _CONSOLE_H
|
||||
#define _CONSOLE_H
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
void dputs(const char* Text);
|
||||
void dprintf(const char* Format, ...);
|
||||
//functions
|
||||
void dputs(const char* text);
|
||||
void dprintf(const char* format, ...);
|
||||
|
||||
#endif // _CONSOLE_H
|
||||
|
|
|
@ -10,6 +10,7 @@ DWORD
|
|||
__in DWORD flags
|
||||
)
|
||||
{
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return UnDecorateSymbolName(name, outputString, maxStringLength, flags);
|
||||
}
|
||||
BOOL
|
||||
|
@ -18,7 +19,7 @@ BOOL
|
|||
__in DWORD64 BaseOfDll
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymUnloadModule64(hProcess, BaseOfDll);
|
||||
}
|
||||
BOOL
|
||||
|
@ -27,7 +28,7 @@ BOOL
|
|||
__in_opt PCSTR SearchPath
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymSetSearchPath(hProcess, SearchPath);
|
||||
}
|
||||
DWORD
|
||||
|
@ -35,7 +36,7 @@ DWORD
|
|||
__in DWORD SymOptions
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymSetOptions(SymOptions);
|
||||
}
|
||||
BOOL
|
||||
|
@ -45,7 +46,7 @@ BOOL
|
|||
__in BOOL fInvadeProcess
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymInitialize(hProcess, UserSearchPath, fInvadeProcess);
|
||||
}
|
||||
BOOL
|
||||
|
@ -55,7 +56,7 @@ BOOL
|
|||
__in ULONG64 UserContext
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymRegisterCallback64(hProcess, CallbackFunction, UserContext);
|
||||
}
|
||||
DWORD64
|
||||
|
@ -70,7 +71,7 @@ DWORD64
|
|||
__in_opt DWORD Flags
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymLoadModuleEx(hProcess, hFile, ImageName, ModuleName, BaseOfDll, DllSize, Data, Flags);
|
||||
}
|
||||
BOOL
|
||||
|
@ -80,7 +81,7 @@ BOOL
|
|||
__out PIMAGEHLP_MODULE64 ModuleInfo
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymGetModuleInfo64(hProcess, qwAddr, ModuleInfo);
|
||||
}
|
||||
BOOL
|
||||
|
@ -90,7 +91,7 @@ BOOL
|
|||
__in DWORD SearchPathLength
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymGetSearchPath(hProcess, SearchPath, SearchPathLength);
|
||||
}
|
||||
BOOL
|
||||
|
@ -102,19 +103,9 @@ BOOL
|
|||
__in_opt PVOID UserContext
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymEnumSymbols(hProcess, BaseOfDll, Mask, EnumSymbolsCallback, UserContext);
|
||||
}
|
||||
BOOL
|
||||
SafeSymEnumerateModules64(
|
||||
__in HANDLE hProcess,
|
||||
__in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback,
|
||||
__in_opt PVOID UserContext
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
return SymEnumerateModules64(hProcess, EnumModulesCallback, UserContext);
|
||||
}
|
||||
BOOL
|
||||
SafeSymEnumerateModules(
|
||||
__in HANDLE hProcess,
|
||||
|
@ -122,7 +113,7 @@ BOOL
|
|||
__in_opt PVOID UserContext
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymEnumerateModules(hProcess, EnumModulesCallback, UserContext);
|
||||
}
|
||||
BOOL
|
||||
|
@ -133,7 +124,7 @@ BOOL
|
|||
__out PIMAGEHLP_LINE64 Line64
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymGetLineFromAddr64(hProcess, qwAddr, pdwDisplacement, Line64);
|
||||
}
|
||||
BOOL
|
||||
|
@ -143,7 +134,7 @@ BOOL
|
|||
__inout PSYMBOL_INFO Symbol
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymFromName(hProcess, Name, Symbol);
|
||||
}
|
||||
BOOL
|
||||
|
@ -154,7 +145,7 @@ BOOL
|
|||
__inout PSYMBOL_INFO Symbol
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymFromAddr(hProcess, Address, Displacement, Symbol);
|
||||
}
|
||||
BOOL
|
||||
|
@ -162,6 +153,6 @@ BOOL
|
|||
__in HANDLE hProcess
|
||||
)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockSym);
|
||||
CriticalSectionLocker locker(LockSym);
|
||||
return SymCleanup(hProcess);
|
||||
}
|
|
@ -71,12 +71,6 @@ BOOL
|
|||
__in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
|
||||
__in_opt PVOID UserContext
|
||||
);
|
||||
BOOL
|
||||
SafeSymEnumerateModules64(
|
||||
__in HANDLE hProcess,
|
||||
__in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback,
|
||||
__in_opt PVOID UserContext
|
||||
);
|
||||
BOOL
|
||||
SafeSymEnumerateModules(
|
||||
__in HANDLE hProcess,
|
||||
|
|
|
@ -49,7 +49,7 @@ static DWORD WINAPI memMapThread(void* ptr)
|
|||
if(cachePrivateUsage != PrivateUsage && !dbgisrunning()) //update the memory map when
|
||||
{
|
||||
cachePrivateUsage = PrivateUsage;
|
||||
MemUpdateMap(fdProcessInfo->hProcess);
|
||||
memupdatemap(fdProcessInfo->hProcess);
|
||||
}
|
||||
Sleep(1000);
|
||||
}
|
||||
|
@ -58,8 +58,8 @@ static DWORD WINAPI memMapThread(void* ptr)
|
|||
|
||||
void dbginit()
|
||||
{
|
||||
ExceptionCodeInit();
|
||||
ErrorCodeInit();
|
||||
exceptioninit();
|
||||
errorinit();
|
||||
CloseHandle(CreateThread(0, 0, memMapThread, 0, 0, 0));
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ uint dbgdebuggedbase()
|
|||
void dbgdisablebpx()
|
||||
{
|
||||
std::vector<BREAKPOINT> list;
|
||||
int bpcount = BpGetList(&list);
|
||||
int bpcount = bpgetlist(&list);
|
||||
for(int i = 0; i < bpcount; i++)
|
||||
{
|
||||
if(list[i].type == BPNORMAL and IsBPXEnabled(list[i].addr))
|
||||
|
@ -93,7 +93,7 @@ void dbgdisablebpx()
|
|||
void dbgenablebpx()
|
||||
{
|
||||
std::vector<BREAKPOINT> list;
|
||||
int bpcount = BpGetList(&list);
|
||||
int bpcount = bpgetlist(&list);
|
||||
for(int i = 0; i < bpcount; i++)
|
||||
{
|
||||
if(list[i].type == BPNORMAL and !IsBPXEnabled(list[i].addr) and list[i].enabled)
|
||||
|
@ -185,7 +185,7 @@ DWORD WINAPI updateCallStackThread(void* ptr)
|
|||
void DebugUpdateGui(uint disasm_addr, bool stack)
|
||||
{
|
||||
uint cip = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
if(MemIsValidReadPtr(disasm_addr))
|
||||
if(memisvalidreadptr(fdProcessInfo->hProcess, disasm_addr))
|
||||
GuiDisasmAt(disasm_addr, cip);
|
||||
uint csp = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
if(stack)
|
||||
|
@ -198,24 +198,24 @@ void DebugUpdateGui(uint disasm_addr, bool stack)
|
|||
}
|
||||
char modname[MAX_MODULE_SIZE] = "";
|
||||
char modtext[MAX_MODULE_SIZE * 2] = "";
|
||||
if(!ModNameFromAddr(disasm_addr, modname, true))
|
||||
if(!modnamefromaddr(disasm_addr, modname, true))
|
||||
*modname = 0;
|
||||
else
|
||||
sprintf(modtext, "Module: %s - ", modname);
|
||||
char title[1024] = "";
|
||||
sprintf(title, "File: %s - PID: %X - %sThread: %X", szBaseFileName, fdProcessInfo->dwProcessId, modtext, ThreadGetId(hActiveThread));
|
||||
sprintf(title, "File: %s - PID: %X - %sThread: %X", szBaseFileName, fdProcessInfo->dwProcessId, modtext, threadgetid(hActiveThread));
|
||||
GuiUpdateWindowTitle(title);
|
||||
GuiUpdateAllViews();
|
||||
}
|
||||
|
||||
void cbUserBreakpoint()
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
BREAKPOINT bp;
|
||||
BRIDGEBP pluginBp;
|
||||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
bpInfo.breakpoint = 0;
|
||||
if(!BpGet(GetContextDataEx(hActiveThread, UE_CIP), BPNORMAL, 0, &bp) and bp.enabled)
|
||||
if(!bpget(GetContextDataEx(hActiveThread, UE_CIP), BPNORMAL, 0, &bp) and bp.enabled)
|
||||
dputs("Breakpoint reached not in list!");
|
||||
else
|
||||
{
|
||||
|
@ -225,7 +225,7 @@ void cbUserBreakpoint()
|
|||
bptype = "UD2";
|
||||
else if((titantype & UE_BREAKPOINT_TYPE_LONG_INT3) == UE_BREAKPOINT_TYPE_LONG_INT3)
|
||||
bptype = "LONG INT3";
|
||||
const char* symbolicname = SymGetSymbolicName(bp.addr);
|
||||
const char* symbolicname = symgetsymbolicname(bp.addr);
|
||||
if(symbolicname)
|
||||
{
|
||||
if(*bp.name)
|
||||
|
@ -241,8 +241,8 @@ void cbUserBreakpoint()
|
|||
dprintf("%s breakpoint at "fhex"!\n", bptype, bp.addr);
|
||||
}
|
||||
if(bp.singleshoot)
|
||||
BpDelete(bp.addr, BPNORMAL);
|
||||
BpToBridge(&bp, &pluginBp);
|
||||
bpdel(bp.addr, BPNORMAL);
|
||||
bptobridge(&bp, &pluginBp);
|
||||
bpInfo.breakpoint = &pluginBp;
|
||||
}
|
||||
GuiSetDebugState(paused);
|
||||
|
@ -260,13 +260,13 @@ void cbUserBreakpoint()
|
|||
|
||||
void cbHardwareBreakpoint(void* ExceptionAddress)
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
uint cip = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
BREAKPOINT bp;
|
||||
BRIDGEBP pluginBp;
|
||||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
bpInfo.breakpoint = 0;
|
||||
if(!BpGet((uint)ExceptionAddress, BPHARDWARE, 0, &bp))
|
||||
if(!bpget((uint)ExceptionAddress, BPHARDWARE, 0, &bp))
|
||||
dputs("Hardware breakpoint reached not in list!");
|
||||
else
|
||||
{
|
||||
|
@ -302,7 +302,7 @@ void cbHardwareBreakpoint(void* ExceptionAddress)
|
|||
bptype = "write";
|
||||
break;
|
||||
}
|
||||
const char* symbolicname = SymGetSymbolicName(bp.addr);
|
||||
const char* symbolicname = symgetsymbolicname(bp.addr);
|
||||
if(symbolicname)
|
||||
{
|
||||
if(*bp.name)
|
||||
|
@ -317,7 +317,7 @@ void cbHardwareBreakpoint(void* ExceptionAddress)
|
|||
else
|
||||
dprintf("Hardware breakpoint (%s%s) at "fhex"!\n", bpsize, bptype, bp.addr);
|
||||
}
|
||||
BpToBridge(&bp, &pluginBp);
|
||||
bptobridge(&bp, &pluginBp);
|
||||
bpInfo.breakpoint = &pluginBp;
|
||||
}
|
||||
GuiSetDebugState(paused);
|
||||
|
@ -335,15 +335,15 @@ void cbHardwareBreakpoint(void* ExceptionAddress)
|
|||
|
||||
void cbMemoryBreakpoint(void* ExceptionAddress)
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
uint cip = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
uint size;
|
||||
uint base = MemFindBaseAddr((uint)ExceptionAddress, &size, true);
|
||||
uint base = memfindbaseaddr((uint)ExceptionAddress, &size, true);
|
||||
BREAKPOINT bp;
|
||||
BRIDGEBP pluginBp;
|
||||
PLUG_CB_BREAKPOINT bpInfo;
|
||||
bpInfo.breakpoint = 0;
|
||||
if(!BpGet(base, BPMEMORY, 0, &bp))
|
||||
if(!bpget(base, BPMEMORY, 0, &bp))
|
||||
dputs("Memory breakpoint reached not in list!");
|
||||
else
|
||||
{
|
||||
|
@ -363,7 +363,7 @@ void cbMemoryBreakpoint(void* ExceptionAddress)
|
|||
bptype = " (read/write/execute)";
|
||||
break;
|
||||
}
|
||||
const char* symbolicname = SymGetSymbolicName(bp.addr);
|
||||
const char* symbolicname = symgetsymbolicname(bp.addr);
|
||||
if(symbolicname)
|
||||
{
|
||||
if(*bp.name)
|
||||
|
@ -378,11 +378,11 @@ void cbMemoryBreakpoint(void* ExceptionAddress)
|
|||
else
|
||||
dprintf("Memory breakpoint%s at "fhex" ("fhex")!\n", bptype, bp.addr, ExceptionAddress);
|
||||
}
|
||||
BpToBridge(&bp, &pluginBp);
|
||||
bptobridge(&bp, &pluginBp);
|
||||
bpInfo.breakpoint = &pluginBp;
|
||||
}
|
||||
if(bp.singleshoot)
|
||||
BpDelete(bp.addr, BPMEMORY); //delete from breakpoint list
|
||||
bpdel(bp.addr, BPMEMORY); //delete from breakpoint list
|
||||
GuiSetDebugState(paused);
|
||||
DebugUpdateGui(cip, true);
|
||||
//lock
|
||||
|
@ -487,7 +487,7 @@ static bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
|
|||
case BPMEMORY:
|
||||
{
|
||||
uint size = 0;
|
||||
MemFindBaseAddr(bp->addr, &size);
|
||||
memfindbaseaddr(bp->addr, &size);
|
||||
if(!SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, (void*)cbMemoryBreakpoint))
|
||||
dprintf("Could not set memory breakpoint "fhex"!\n", bp->addr);
|
||||
}
|
||||
|
@ -503,7 +503,7 @@ static bool cbSetModuleBreakpoints(const BREAKPOINT* bp)
|
|||
}
|
||||
int titantype = bp->titantype;
|
||||
TITANSETDRX(titantype, drx);
|
||||
BpSetTitanType(bp->addr, BPHARDWARE, titantype);
|
||||
bpsettitantype(bp->addr, BPHARDWARE, titantype);
|
||||
if(!SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), (void*)cbHardwareBreakpoint))
|
||||
dprintf("Could not set hardware breakpoint "fhex"!\n", bp->addr);
|
||||
}
|
||||
|
@ -540,7 +540,7 @@ static bool cbRemoveModuleBreakpoints(const BREAKPOINT* bp)
|
|||
|
||||
void cbStep()
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
isStepping = false;
|
||||
GuiSetDebugState(paused);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
|
@ -559,7 +559,7 @@ void cbStep()
|
|||
|
||||
static void cbRtrFinalStep()
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
GuiSetDebugState(paused);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
//lock
|
||||
|
@ -576,7 +576,7 @@ static unsigned char getCIPch()
|
|||
{
|
||||
unsigned char ch = 0x90;
|
||||
uint cip = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
MemRead((void*)cip, &ch, 1, 0);
|
||||
memread(fdProcessInfo->hProcess, (void*)cip, &ch, 1, 0);
|
||||
return ch;
|
||||
}
|
||||
|
||||
|
@ -604,8 +604,8 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||
}
|
||||
dprintf("Process Started: "fhex" %s\n", base, DebugFileName);
|
||||
|
||||
MemUpdateMap(fdProcessInfo->hProcess);
|
||||
GuiDumpAt(MemFindBaseAddr(GetContextData(UE_CIP), 0) + PAGE_SIZE); //dump somewhere
|
||||
memupdatemap(fdProcessInfo->hProcess);
|
||||
GuiDumpAt(memfindbaseaddr(GetContextData(UE_CIP), 0)+PAGE_SIZE); //dump somewhere
|
||||
|
||||
//init program database
|
||||
int len = (int)strlen(szFileName);
|
||||
|
@ -633,12 +633,12 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||
memset(&modInfo, 0, sizeof(modInfo));
|
||||
modInfo.SizeOfStruct = sizeof(modInfo);
|
||||
if(SafeSymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo))
|
||||
ModLoad((uint)base, modInfo.ImageSize, modInfo.ImageName);
|
||||
modload((uint)base, modInfo.ImageSize, modInfo.ImageName);
|
||||
dbggetprivateusage(fdProcessInfo->hProcess, true);
|
||||
MemUpdateMap(fdProcessInfo->hProcess); //update memory map
|
||||
memupdatemap(fdProcessInfo->hProcess); //update memory map
|
||||
char modname[256] = "";
|
||||
if(ModNameFromAddr((uint)base, modname, true))
|
||||
BpEnumAll(cbSetModuleBreakpoints, modname);
|
||||
if(modnamefromaddr((uint)base, modname, true))
|
||||
bpenumall(cbSetModuleBreakpoints, modname);
|
||||
GuiUpdateBreakpointsView();
|
||||
if(!bFileIsDll and !bIsAttached) //Set entry breakpoint
|
||||
{
|
||||
|
@ -688,7 +688,7 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||
threadInfo.hThread = CreateProcessInfo->hThread;
|
||||
threadInfo.lpStartAddress = CreateProcessInfo->lpStartAddress;
|
||||
threadInfo.lpThreadLocalBase = CreateProcessInfo->lpThreadLocalBase;
|
||||
ThreadCreate(&threadInfo);
|
||||
threadcreate(&threadInfo);
|
||||
}
|
||||
|
||||
static void cbExitProcess(EXIT_PROCESS_DEBUG_INFO* ExitProcess)
|
||||
|
@ -702,9 +702,9 @@ static void cbExitProcess(EXIT_PROCESS_DEBUG_INFO* ExitProcess)
|
|||
|
||||
static void cbCreateThread(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
||||
{
|
||||
ThreadCreate(CreateThread); //update thread list
|
||||
threadcreate(CreateThread); //update thread list
|
||||
DWORD dwThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId;
|
||||
hActiveThread = ThreadGetHandle(dwThreadId);
|
||||
hActiveThread = threadgethandle(dwThreadId);
|
||||
|
||||
if(settingboolget("Events", "ThreadEntry"))
|
||||
{
|
||||
|
@ -723,7 +723,7 @@ static void cbCreateThread(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
|||
if(settingboolget("Events", "ThreadStart"))
|
||||
{
|
||||
dbggetprivateusage(fdProcessInfo->hProcess, true);
|
||||
MemUpdateMap(fdProcessInfo->hProcess); //update memory map
|
||||
memupdatemap(fdProcessInfo->hProcess); //update memory map
|
||||
//update GUI
|
||||
GuiSetDebugState(paused);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
|
@ -739,13 +739,13 @@ static void cbCreateThread(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
|||
|
||||
static void cbExitThread(EXIT_THREAD_DEBUG_INFO* ExitThread)
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
DWORD dwThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId;
|
||||
PLUG_CB_EXITTHREAD callbackInfo;
|
||||
callbackInfo.ExitThread = ExitThread;
|
||||
callbackInfo.dwThreadId = dwThreadId;
|
||||
plugincbcall(CB_EXITTHREAD, &callbackInfo);
|
||||
ThreadExit(dwThreadId);
|
||||
threadexit(dwThreadId);
|
||||
dprintf("Thread %X exit\n", dwThreadId);
|
||||
|
||||
if(settingboolget("Events", "ThreadEnd"))
|
||||
|
@ -765,7 +765,7 @@ static void cbExitThread(EXIT_THREAD_DEBUG_INFO* ExitThread)
|
|||
|
||||
static void cbSystemBreakpoint(void* ExceptionData)
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
//log message
|
||||
if(bIsAttached)
|
||||
dputs("Attach breakpoint reached!");
|
||||
|
@ -773,7 +773,7 @@ static void cbSystemBreakpoint(void* ExceptionData)
|
|||
dputs("System breakpoint reached!");
|
||||
bSkipExceptions = false; //we are not skipping first-chance exceptions
|
||||
uint cip = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
GuiDumpAt(MemFindBaseAddr(cip, 0, true)); //dump somewhere
|
||||
GuiDumpAt(memfindbaseaddr(cip, 0, true)); //dump somewhere
|
||||
|
||||
//plugin callbacks
|
||||
PLUG_CB_SYSTEMBREAKPOINT callbackInfo;
|
||||
|
@ -797,7 +797,7 @@ static void cbSystemBreakpoint(void* ExceptionData)
|
|||
|
||||
static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
void* base = LoadDll->lpBaseOfDll;
|
||||
char DLLDebugFileName[deflen] = "";
|
||||
if(!GetFileNameFromHandle(LoadDll->hFile, DLLDebugFileName))
|
||||
|
@ -813,12 +813,12 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
|||
memset(&modInfo, 0, sizeof(modInfo));
|
||||
modInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
|
||||
if(SafeSymGetModuleInfo64(fdProcessInfo->hProcess, (DWORD64)base, &modInfo))
|
||||
ModLoad((uint)base, modInfo.ImageSize, modInfo.ImageName);
|
||||
modload((uint)base, modInfo.ImageSize, modInfo.ImageName);
|
||||
dbggetprivateusage(fdProcessInfo->hProcess, true);
|
||||
MemUpdateMap(fdProcessInfo->hProcess); //update memory map
|
||||
memupdatemap(fdProcessInfo->hProcess); //update memory map
|
||||
char modname[256] = "";
|
||||
if(ModNameFromAddr((uint)base, modname, true))
|
||||
BpEnumAll(cbSetModuleBreakpoints, modname);
|
||||
if(modnamefromaddr((uint)base, modname, true))
|
||||
bpenumall(cbSetModuleBreakpoints, modname);
|
||||
GuiUpdateBreakpointsView();
|
||||
bool bAlreadySetEntry = false;
|
||||
|
||||
|
@ -900,15 +900,15 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll)
|
|||
|
||||
static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
PLUG_CB_UNLOADDLL callbackInfo;
|
||||
callbackInfo.UnloadDll = UnloadDll;
|
||||
plugincbcall(CB_UNLOADDLL, &callbackInfo);
|
||||
|
||||
void* base = UnloadDll->lpBaseOfDll;
|
||||
char modname[256] = "???";
|
||||
if(ModNameFromAddr((uint)base, modname, true))
|
||||
BpEnumAll(cbRemoveModuleBreakpoints, modname);
|
||||
if(modnamefromaddr((uint)base, modname, true))
|
||||
bpenumall(cbRemoveModuleBreakpoints, modname);
|
||||
GuiUpdateBreakpointsView();
|
||||
SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)base);
|
||||
dprintf("DLL Unloaded: "fhex" %s\n", base, modname);
|
||||
|
@ -928,12 +928,13 @@ static void cbUnloadDll(UNLOAD_DLL_DEBUG_INFO* UnloadDll)
|
|||
wait(WAITID_RUN);
|
||||
}
|
||||
|
||||
ModUnload((uint)base);
|
||||
modunload((uint)base);
|
||||
}
|
||||
|
||||
static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
PLUG_CB_OUTPUTDEBUGSTRING callbackInfo;
|
||||
callbackInfo.DebugString = DebugString;
|
||||
plugincbcall(CB_OUTPUTDEBUGSTRING, &callbackInfo);
|
||||
|
@ -941,7 +942,7 @@ static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
|
|||
if(!DebugString->fUnicode) //ASCII
|
||||
{
|
||||
Memory<char*> DebugText(DebugString->nDebugStringLength + 1, "cbOutputDebugString:DebugText");
|
||||
if(MemRead(DebugString->lpDebugStringData, DebugText, DebugString->nDebugStringLength, 0))
|
||||
if(memread(fdProcessInfo->hProcess, DebugString->lpDebugStringData, DebugText, DebugString->nDebugStringLength, 0))
|
||||
{
|
||||
String str = String(DebugText);
|
||||
if(str != lastDebugText) //fix for every string being printed twice
|
||||
|
@ -972,7 +973,7 @@ static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString)
|
|||
|
||||
static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
||||
{
|
||||
hActiveThread = ThreadGetHandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
hActiveThread = threadgethandle(((DEBUG_EVENT*)GetDebugData())->dwThreadId);
|
||||
PLUG_CB_EXCEPTION callbackInfo;
|
||||
callbackInfo.Exception = ExceptionData;
|
||||
unsigned int ExceptionCode = ExceptionData->ExceptionRecord.ExceptionCode;
|
||||
|
@ -1018,18 +1019,18 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData)
|
|||
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
|
||||
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((void*)nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE - 1, 0))
|
||||
if(memread(fdProcessInfo->hProcess, nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE - 1, 0))
|
||||
{
|
||||
String ThreadNameEscaped = StringUtils::Escape(ThreadName);
|
||||
dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped.c_str());
|
||||
ThreadSetName(nameInfo.dwThreadID, ThreadNameEscaped.c_str());
|
||||
threadsetname(nameInfo.dwThreadID, ThreadNameEscaped.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
const char* exceptionName = ExceptionCodeToName(ExceptionCode);
|
||||
const char* exceptionName = exceptionnamefromcode(ExceptionCode);
|
||||
if(ExceptionData->dwFirstChance) //first chance exception
|
||||
{
|
||||
if(exceptionName)
|
||||
|
@ -1150,8 +1151,8 @@ DWORD WINAPI threadDebugLoop(void* lpParameter)
|
|||
RemoveAllBreakPoints(UE_OPTION_REMOVEALL); //remove all breakpoints
|
||||
//cleanup
|
||||
dbclose();
|
||||
ModClear();
|
||||
ThreadClear();
|
||||
modclear();
|
||||
threadclear();
|
||||
GuiSetDebugState(stopped);
|
||||
dputs("debugging stopped!");
|
||||
varset("$hp", (uint)0, true);
|
||||
|
@ -1162,7 +1163,7 @@ DWORD WINAPI threadDebugLoop(void* lpParameter)
|
|||
|
||||
bool cbDeleteAllBreakpoints(const BREAKPOINT* bp)
|
||||
{
|
||||
if(BpDelete(bp->addr, BPNORMAL) and (!bp->enabled or DeleteBPX(bp->addr)))
|
||||
if(bpdel(bp->addr, BPNORMAL) and (!bp->enabled or DeleteBPX(bp->addr)))
|
||||
return true;
|
||||
|
||||
dprintf("Delete breakpoint failed: "fhex"\n", bp->addr);
|
||||
|
@ -1174,7 +1175,7 @@ bool cbEnableAllBreakpoints(const BREAKPOINT* bp)
|
|||
if(bp->type != BPNORMAL or bp->enabled)
|
||||
return true;
|
||||
|
||||
if(!BpEnable(bp->addr, BPNORMAL, true) or !SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint))
|
||||
if(!bpenable(bp->addr, BPNORMAL, true) or !SetBPX(bp->addr, bp->titantype, (void*)cbUserBreakpoint))
|
||||
{
|
||||
dprintf("Could not enable breakpoint "fhex"\n", bp->addr);
|
||||
return false;
|
||||
|
@ -1187,7 +1188,7 @@ bool cbDisableAllBreakpoints(const BREAKPOINT* bp)
|
|||
if(bp->type != BPNORMAL or !bp->enabled)
|
||||
return true;
|
||||
|
||||
if(!BpEnable(bp->addr, BPNORMAL, false) or !DeleteBPX(bp->addr))
|
||||
if(!bpenable(bp->addr, BPNORMAL, false) or !DeleteBPX(bp->addr))
|
||||
{
|
||||
dprintf("Could not disable breakpoint "fhex"\n", bp->addr);
|
||||
return false;
|
||||
|
@ -1207,8 +1208,8 @@ bool cbEnableAllHardwareBreakpoints(const BREAKPOINT* bp)
|
|||
}
|
||||
int titantype = bp->titantype;
|
||||
TITANSETDRX(titantype, drx);
|
||||
BpSetTitanType(bp->addr, BPHARDWARE, titantype);
|
||||
if(!BpEnable(bp->addr, BPHARDWARE, true) or !SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), (void*)cbHardwareBreakpoint))
|
||||
bpsettitantype(bp->addr, BPHARDWARE, titantype);
|
||||
if(!bpenable(bp->addr, BPHARDWARE, true) or !SetHardwareBreakPoint(bp->addr, drx, TITANGETTYPE(bp->titantype), TITANGETSIZE(bp->titantype), (void*)cbHardwareBreakpoint))
|
||||
{
|
||||
dprintf("could not enable hardware breakpoint "fhex"\n", bp->addr);
|
||||
return false;
|
||||
|
@ -1220,7 +1221,7 @@ bool cbDisableAllHardwareBreakpoints(const BREAKPOINT* bp)
|
|||
{
|
||||
if(bp->type != BPHARDWARE or !bp->enabled)
|
||||
return true;
|
||||
if(!BpEnable(bp->addr, BPHARDWARE, false) or !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
if(!bpenable(bp->addr, BPHARDWARE, false) or !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
{
|
||||
dprintf("Could not disable hardware breakpoint "fhex"\n", bp->addr);
|
||||
return false;
|
||||
|
@ -1233,8 +1234,8 @@ bool cbEnableAllMemoryBreakpoints(const BREAKPOINT* bp)
|
|||
if(bp->type != BPMEMORY or bp->enabled)
|
||||
return true;
|
||||
uint size = 0;
|
||||
MemFindBaseAddr(bp->addr, &size);
|
||||
if(!BpEnable(bp->addr, BPMEMORY, true) or !SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, (void*)cbMemoryBreakpoint))
|
||||
memfindbaseaddr(bp->addr, &size);
|
||||
if(!bpenable(bp->addr, BPMEMORY, true) or !SetMemoryBPXEx(bp->addr, size, bp->titantype, !bp->singleshoot, (void*)cbMemoryBreakpoint))
|
||||
{
|
||||
dprintf("Could not enable memory breakpoint "fhex"\n", bp->addr);
|
||||
return false;
|
||||
|
@ -1246,7 +1247,7 @@ bool cbDisableAllMemoryBreakpoints(const BREAKPOINT* bp)
|
|||
{
|
||||
if(bp->type != BPMEMORY or !bp->enabled)
|
||||
return true;
|
||||
if(!BpEnable(bp->addr, BPMEMORY, false) or !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
if(!bpenable(bp->addr, BPMEMORY, false) or !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
{
|
||||
dprintf("Could not disable memory breakpoint "fhex"\n", bp->addr);
|
||||
return false;
|
||||
|
@ -1281,8 +1282,8 @@ bool cbDeleteAllMemoryBreakpoints(const BREAKPOINT* bp)
|
|||
if(!bp->enabled)
|
||||
return true;
|
||||
uint size;
|
||||
MemFindBaseAddr(bp->addr, &size);
|
||||
if(!BpDelete(bp->addr, BPMEMORY) or !RemoveMemoryBPX(bp->addr, size))
|
||||
memfindbaseaddr(bp->addr, &size);
|
||||
if(!bpdel(bp->addr, BPMEMORY) or !RemoveMemoryBPX(bp->addr, size))
|
||||
{
|
||||
dprintf("Delete memory breakpoint failed: "fhex"\n", bp->addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -1294,7 +1295,7 @@ bool cbDeleteAllHardwareBreakpoints(const BREAKPOINT* bp)
|
|||
{
|
||||
if(!bp->enabled)
|
||||
return true;
|
||||
if(!BpDelete(bp->addr, BPHARDWARE) or !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
if(!bpdel(bp->addr, BPHARDWARE) or !DeleteHardwareBreakPoint(TITANGETDRX(bp->titantype)))
|
||||
{
|
||||
dprintf("Delete hardware breakpoint failed: "fhex"\n", bp->addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -1366,8 +1367,8 @@ DWORD WINAPI threadAttachLoop(void* lpParameter)
|
|||
RemoveAllBreakPoints(UE_OPTION_REMOVEALL); //remove all breakpoints
|
||||
//cleanup
|
||||
dbclose();
|
||||
ModClear();
|
||||
ThreadClear();
|
||||
modclear();
|
||||
threadclear();
|
||||
GuiSetDebugState(stopped);
|
||||
dputs("debugging stopped!");
|
||||
varset("$hp", (uint)0, true);
|
||||
|
@ -1742,7 +1743,7 @@ static bool getcommandlineaddr(uint* addr, cmdline_error_t* cmd_line_error)
|
|||
|
||||
//cast-trick to calculate the address of the remote peb field ProcessParameters
|
||||
cmd_line_error->addr = (uint) & (((PPEB) cmd_line_error->addr)->ProcessParameters);
|
||||
if(!MemRead((void*)cmd_line_error->addr, &pprocess_parameters, sizeof(pprocess_parameters), &size))
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)cmd_line_error->addr, &pprocess_parameters, sizeof(pprocess_parameters), &size))
|
||||
{
|
||||
cmd_line_error->type = CMDL_ERR_READ_PEBBASE;
|
||||
return false;
|
||||
|
@ -1761,7 +1762,7 @@ static bool patchcmdline(uint getcommandline, uint new_command_line, cmdline_err
|
|||
unsigned char data[100];
|
||||
|
||||
cmd_line_error->addr = getcommandline;
|
||||
if(!MemRead((void*) cmd_line_error->addr, & data, sizeof(data), & size))
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*) cmd_line_error->addr, & data, sizeof(data), & size))
|
||||
{
|
||||
cmd_line_error->type = CMDL_ERR_READ_GETCOMMANDLINEBASE;
|
||||
return false;
|
||||
|
@ -1795,7 +1796,7 @@ static bool patchcmdline(uint getcommandline, uint new_command_line, cmdline_err
|
|||
#endif
|
||||
|
||||
//update the pointer in the debuggee
|
||||
if(!MemWrite((void*)command_line_stored, &new_command_line, sizeof(new_command_line), &size))
|
||||
if(!memwrite(fdProcessInfo->hProcess, (void*)command_line_stored, &new_command_line, sizeof(new_command_line), &size))
|
||||
{
|
||||
cmd_line_error->addr = command_line_stored;
|
||||
cmd_line_error->type = CMDL_ERR_WRITE_GETCOMMANDLINESTORED;
|
||||
|
@ -1864,21 +1865,21 @@ bool dbgsetcmdline(const char* cmd_line, cmdline_error_t* cmd_line_error)
|
|||
|
||||
new_command_line.Buffer = command_linewstr;
|
||||
|
||||
uint mem = (uint)MemAllocRemote(0, new_command_line.Length * 2, PAGE_READWRITE);
|
||||
uint mem = (uint)memalloc(fdProcessInfo->hProcess, 0, new_command_line.Length * 2, PAGE_READWRITE);
|
||||
if(!mem)
|
||||
{
|
||||
cmd_line_error->type = CMDL_ERR_ALLOC_UNICODEANSI_COMMANDLINE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!MemWrite((void*)mem, new_command_line.Buffer, new_command_line.Length, &size))
|
||||
if(!memwrite(fdProcessInfo->hProcess, (void*)mem, new_command_line.Buffer, new_command_line.Length, &size))
|
||||
{
|
||||
cmd_line_error->addr = mem;
|
||||
cmd_line_error->type = CMDL_ERR_WRITE_UNICODE_COMMANDLINE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!MemWrite((void*)(mem + new_command_line.Length), (void*)cmd_line, strlen(cmd_line) + 1, &size))
|
||||
if(!memwrite(fdProcessInfo->hProcess, (void*)(mem + new_command_line.Length), cmd_line, strlen(cmd_line) + 1, &size))
|
||||
{
|
||||
cmd_line_error->addr = mem + new_command_line.Length;
|
||||
cmd_line_error->type = CMDL_ERR_WRITE_ANSI_COMMANDLINE;
|
||||
|
@ -1889,7 +1890,7 @@ bool dbgsetcmdline(const char* cmd_line, cmdline_error_t* cmd_line_error)
|
|||
return false;
|
||||
|
||||
new_command_line.Buffer = (PWSTR) mem;
|
||||
if(!MemWrite((void*)command_line_addr, &new_command_line, sizeof(new_command_line), &size))
|
||||
if(!memwrite(fdProcessInfo->hProcess, (void*)command_line_addr, &new_command_line, sizeof(new_command_line), &size))
|
||||
{
|
||||
cmd_line_error->addr = command_line_addr;
|
||||
cmd_line_error->type = CMDL_ERR_WRITE_PEBUNICODE_COMMANDLINE;
|
||||
|
@ -1911,7 +1912,7 @@ bool dbggetcmdline(char** cmd_line, cmdline_error_t* cmd_line_error)
|
|||
if(!getcommandlineaddr(&cmd_line_error->addr, cmd_line_error))
|
||||
return false;
|
||||
|
||||
if(!MemRead((void*)cmd_line_error->addr, &CommandLine, sizeof(CommandLine), &size))
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)cmd_line_error->addr, &CommandLine, sizeof(CommandLine), &size))
|
||||
{
|
||||
cmd_line_error->type = CMDL_ERR_READ_PROCPARM_PTR;
|
||||
return false;
|
||||
|
@ -1920,7 +1921,7 @@ bool dbggetcmdline(char** cmd_line, cmdline_error_t* cmd_line_error)
|
|||
Memory<wchar_t*> wstr_cmd(CommandLine.Length + sizeof(wchar_t));
|
||||
|
||||
cmd_line_error->addr = (uint) CommandLine.Buffer;
|
||||
if(!MemRead((void*)cmd_line_error->addr, wstr_cmd, CommandLine.Length, &size))
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)cmd_line_error->addr, wstr_cmd, CommandLine.Length, &size))
|
||||
{
|
||||
cmd_line_error->type = CMDL_ERR_READ_PROCPARM_CMDLINE;
|
||||
return false;
|
||||
|
|
|
@ -209,7 +209,7 @@ CMDRESULT cbDebugSetBPX(int argc, char* argv[]) //bp addr [,name [,type]]
|
|||
const char* bpname = 0;
|
||||
if(*argname)
|
||||
bpname = argname;
|
||||
if(BpGet(addr, BPNORMAL, bpname, 0))
|
||||
if(bpget(addr, BPNORMAL, bpname, 0))
|
||||
{
|
||||
dputs("Breakpoint already set!");
|
||||
return STATUS_CONTINUE;
|
||||
|
@ -219,12 +219,12 @@ CMDRESULT cbDebugSetBPX(int argc, char* argv[]) //bp addr [,name [,type]]
|
|||
dprintf("Error setting breakpoint at "fhex"! (IsBPXEnabled)\n", addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(!MemRead((void*)addr, &oldbytes, sizeof(short), 0))
|
||||
else if(!memread(fdProcessInfo->hProcess, (void*)addr, &oldbytes, sizeof(short), 0))
|
||||
{
|
||||
dprintf("Error setting breakpoint at "fhex"! (memread)\n", addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
else if(!BpNew(addr, true, singleshoot, oldbytes, BPNORMAL, type, bpname))
|
||||
else if(!bpnew(addr, true, singleshoot, oldbytes, BPNORMAL, type, bpname))
|
||||
{
|
||||
dprintf("Error setting breakpoint at "fhex"! (bpnew)\n", addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -244,21 +244,21 @@ CMDRESULT cbDebugDeleteBPX(int argc, char* argv[])
|
|||
char arg1[deflen] = "";
|
||||
if(!argget(*argv, arg1, 0, true)) //delete all breakpoints
|
||||
{
|
||||
if(!BpGetCount(BPNORMAL))
|
||||
if(!bpgetcount(BPNORMAL))
|
||||
{
|
||||
dputs("No breakpoints to delete!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnumAll(cbDeleteAllBreakpoints)) //at least one deletion failed
|
||||
if(!bpenumall(cbDeleteAllBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs("All breakpoints deleted!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
BREAKPOINT found;
|
||||
if(BpGet(0, BPNORMAL, arg1, &found)) //found a breakpoint with name
|
||||
if(bpget(0, BPNORMAL, arg1, &found)) //found a breakpoint with name
|
||||
{
|
||||
if(!BpDelete(found.addr, BPNORMAL))
|
||||
if(!bpdel(found.addr, BPNORMAL))
|
||||
{
|
||||
dprintf("Delete breakpoint failed (bpdel): "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -272,12 +272,12 @@ CMDRESULT cbDebugDeleteBPX(int argc, char* argv[])
|
|||
return STATUS_CONTINUE;
|
||||
}
|
||||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPNORMAL, 0, &found)) //invalid breakpoint
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!BpDelete(found.addr, BPNORMAL))
|
||||
if(!bpdel(found.addr, BPNORMAL))
|
||||
{
|
||||
dprintf("Delete breakpoint failed (bpdel): "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -298,21 +298,21 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
|
|||
char arg1[deflen] = "";
|
||||
if(!argget(*argv, arg1, 0, true)) //enable all breakpoints
|
||||
{
|
||||
if(!BpGetCount(BPNORMAL))
|
||||
if(!bpgetcount(BPNORMAL))
|
||||
{
|
||||
dputs("No breakpoints to enable!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnumAll(cbEnableAllBreakpoints)) //at least one enable failed
|
||||
if(!bpenumall(cbEnableAllBreakpoints)) //at least one enable failed
|
||||
return STATUS_ERROR;
|
||||
dputs("All breakpoints enabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
BREAKPOINT found;
|
||||
if(BpGet(0, BPNORMAL, arg1, &found)) //found a breakpoint with name
|
||||
if(bpget(0, BPNORMAL, arg1, &found)) //found a breakpoint with name
|
||||
{
|
||||
if(!BpEnable(found.addr, BPNORMAL, true) or !SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint))
|
||||
if(!bpenable(found.addr, BPNORMAL, true) or !SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint))
|
||||
{
|
||||
dprintf("Could not enable breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -321,7 +321,7 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
|
|||
return STATUS_CONTINUE;
|
||||
}
|
||||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPNORMAL, 0, &found)) //invalid breakpoint
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
|
@ -332,7 +332,7 @@ CMDRESULT cbDebugEnableBPX(int argc, char* argv[])
|
|||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnable(found.addr, BPNORMAL, true) or !SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint))
|
||||
if(!bpenable(found.addr, BPNORMAL, true) or !SetBPX(found.addr, found.titantype, (void*)cbUserBreakpoint))
|
||||
{
|
||||
dprintf("Could not enable breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -347,21 +347,21 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
|
|||
char arg1[deflen] = "";
|
||||
if(!argget(*argv, arg1, 0, true)) //delete all breakpoints
|
||||
{
|
||||
if(!BpGetCount(BPNORMAL))
|
||||
if(!bpgetcount(BPNORMAL))
|
||||
{
|
||||
dputs("No breakpoints to disable!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnumAll(cbDisableAllBreakpoints)) //at least one deletion failed
|
||||
if(!bpenumall(cbDisableAllBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs("All breakpoints disabled!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
BREAKPOINT found;
|
||||
if(BpGet(0, BPNORMAL, arg1, &found)) //found a breakpoint with name
|
||||
if(bpget(0, BPNORMAL, arg1, &found)) //found a breakpoint with name
|
||||
{
|
||||
if(!BpEnable(found.addr, BPNORMAL, false) or !DeleteBPX(found.addr))
|
||||
if(!bpenable(found.addr, BPNORMAL, false) or !DeleteBPX(found.addr))
|
||||
{
|
||||
dprintf("Could not disable breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -370,7 +370,7 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
|
|||
return STATUS_CONTINUE;
|
||||
}
|
||||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPNORMAL, 0, &found)) //invalid breakpoint
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPNORMAL, 0, &found)) //invalid breakpoint
|
||||
{
|
||||
dprintf("No such breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
|
@ -380,7 +380,7 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
|
|||
dputs("Breakpoint already disabled!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnable(found.addr, BPNORMAL, false) or !DeleteBPX(found.addr))
|
||||
if(!bpenable(found.addr, BPNORMAL, false) or !DeleteBPX(found.addr))
|
||||
{
|
||||
dprintf("Could not disable breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -392,7 +392,7 @@ CMDRESULT cbDebugDisableBPX(int argc, char* argv[])
|
|||
|
||||
CMDRESULT cbDebugBplist(int argc, char* argv[])
|
||||
{
|
||||
BpEnumAll(cbBreakpointList);
|
||||
bpenumall(cbBreakpointList);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -458,7 +458,7 @@ CMDRESULT cbDebugDisasm(int argc, char* argv[])
|
|||
if(argget(*argv, arg1, 0, true))
|
||||
if(!valfromstring(arg1, &addr))
|
||||
addr = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
if(!MemIsValidReadPtr(addr))
|
||||
if(!memisvalidreadptr(fdProcessInfo->hProcess, addr))
|
||||
return STATUS_CONTINUE;
|
||||
DebugUpdateGui(addr, false);
|
||||
return STATUS_CONTINUE;
|
||||
|
@ -505,16 +505,16 @@ CMDRESULT cbDebugSetMemoryBpx(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
uint size = 0;
|
||||
uint base = MemFindBaseAddr(addr, &size, true);
|
||||
uint base = memfindbaseaddr(addr, &size, true);
|
||||
bool singleshoot = false;
|
||||
if(!restore)
|
||||
singleshoot = true;
|
||||
if(BpGet(base, BPMEMORY, 0, 0))
|
||||
if(bpget(base, BPMEMORY, 0, 0))
|
||||
{
|
||||
dputs("Hardware breakpoint already set!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpNew(base, true, singleshoot, 0, BPMEMORY, type, 0) or !SetMemoryBPXEx(base, size, type, restore, (void*)cbMemoryBreakpoint))
|
||||
if(!bpnew(base, true, singleshoot, 0, BPMEMORY, type, 0) or !SetMemoryBPXEx(base, size, type, restore, (void*)cbMemoryBreakpoint))
|
||||
{
|
||||
dputs("Error setting memory breakpoint!");
|
||||
return STATUS_ERROR;
|
||||
|
@ -529,23 +529,23 @@ CMDRESULT cbDebugDeleteMemoryBreakpoint(int argc, char* argv[])
|
|||
char arg1[deflen] = "";
|
||||
if(!argget(*argv, arg1, 0, true)) //delete all breakpoints
|
||||
{
|
||||
if(!BpGetCount(BPMEMORY))
|
||||
if(!bpgetcount(BPMEMORY))
|
||||
{
|
||||
dputs("no memory breakpoints to delete!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnumAll(cbDeleteAllMemoryBreakpoints)) //at least one deletion failed
|
||||
if(!bpenumall(cbDeleteAllMemoryBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs("All memory breakpoints deleted!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
BREAKPOINT found;
|
||||
if(BpGet(0, BPMEMORY, arg1, &found)) //found a breakpoint with name
|
||||
if(bpget(0, BPMEMORY, arg1, &found)) //found a breakpoint with name
|
||||
{
|
||||
uint size;
|
||||
MemFindBaseAddr(found.addr, &size);
|
||||
if(!BpDelete(found.addr, BPMEMORY) or !RemoveMemoryBPX(found.addr, size))
|
||||
memfindbaseaddr(found.addr, &size);
|
||||
if(!bpdel(found.addr, BPMEMORY) or !RemoveMemoryBPX(found.addr, size))
|
||||
{
|
||||
dprintf("Delete memory breakpoint failed: "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -553,14 +553,14 @@ CMDRESULT cbDebugDeleteMemoryBreakpoint(int argc, char* argv[])
|
|||
return STATUS_CONTINUE;
|
||||
}
|
||||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPMEMORY, 0, &found)) //invalid breakpoint
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPMEMORY, 0, &found)) //invalid breakpoint
|
||||
{
|
||||
dprintf("No such memory breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
uint size;
|
||||
MemFindBaseAddr(found.addr, &size);
|
||||
if(!BpDelete(found.addr, BPMEMORY) or !RemoveMemoryBPX(found.addr, size))
|
||||
memfindbaseaddr(found.addr, &size);
|
||||
if(!bpdel(found.addr, BPMEMORY) or !RemoveMemoryBPX(found.addr, size))
|
||||
{
|
||||
dprintf("Delete memory breakpoint failed: "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -655,12 +655,12 @@ CMDRESULT cbDebugSetHardwareBreakpoint(int argc, char* argv[])
|
|||
TITANSETTYPE(titantype, type);
|
||||
TITANSETSIZE(titantype, titsize);
|
||||
//TODO: hwbp in multiple threads TEST
|
||||
if(BpGet(addr, BPHARDWARE, 0, 0))
|
||||
if(bpget(addr, BPHARDWARE, 0, 0))
|
||||
{
|
||||
dputs("Hardware breakpoint already set!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpNew(addr, true, false, 0, BPHARDWARE, titantype, 0))
|
||||
if(!bpnew(addr, true, false, 0, BPHARDWARE, titantype, 0))
|
||||
{
|
||||
dputs("error setting hardware breakpoint (bpnew)!");
|
||||
return STATUS_ERROR;
|
||||
|
@ -680,21 +680,21 @@ CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[])
|
|||
char arg1[deflen] = "";
|
||||
if(!argget(*argv, arg1, 0, true)) //delete all breakpoints
|
||||
{
|
||||
if(!BpGetCount(BPHARDWARE))
|
||||
if(!bpgetcount(BPHARDWARE))
|
||||
{
|
||||
dputs("No hardware breakpoints to delete!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnumAll(cbDeleteAllHardwareBreakpoints)) //at least one deletion failed
|
||||
if(!bpenumall(cbDeleteAllHardwareBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs("All hardware breakpoints deleted!");
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
BREAKPOINT found;
|
||||
if(BpGet(0, BPHARDWARE, arg1, &found)) //found a breakpoint with name
|
||||
if(bpget(0, BPHARDWARE, arg1, &found)) //found a breakpoint with name
|
||||
{
|
||||
if(!BpDelete(found.addr, BPHARDWARE) or !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype)))
|
||||
if(!bpdel(found.addr, BPHARDWARE) or !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype)))
|
||||
{
|
||||
dprintf("Delete hardware breakpoint failed: "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -702,12 +702,12 @@ CMDRESULT cbDebugDeleteHardwareBreakpoint(int argc, char* argv[])
|
|||
return STATUS_CONTINUE;
|
||||
}
|
||||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPHARDWARE, 0, &found)) //invalid breakpoint
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPHARDWARE, 0, &found)) //invalid breakpoint
|
||||
{
|
||||
dprintf("No such hardware breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!BpDelete(found.addr, BPHARDWARE) or !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype)))
|
||||
if(!bpdel(found.addr, BPHARDWARE) or !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype)))
|
||||
{
|
||||
dprintf("Delete hardware breakpoint failed: "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -724,7 +724,7 @@ CMDRESULT cbDebugAlloc(int argc, char* argv[])
|
|||
if(argget(*argv, arg1, 0, true))
|
||||
if(!valfromstring(arg1, &size, false))
|
||||
return STATUS_ERROR;
|
||||
uint mem = (uint)MemAllocRemote(0, size, PAGE_EXECUTE_READWRITE);
|
||||
uint mem = (uint)memalloc(fdProcessInfo->hProcess, 0, size, PAGE_EXECUTE_READWRITE);
|
||||
if(!mem)
|
||||
dputs("VirtualAllocEx failed");
|
||||
else
|
||||
|
@ -732,7 +732,7 @@ CMDRESULT cbDebugAlloc(int argc, char* argv[])
|
|||
if(mem)
|
||||
varset("$lastalloc", mem, true);
|
||||
dbggetprivateusage(fdProcessInfo->hProcess, true);
|
||||
MemUpdateMap(fdProcessInfo->hProcess);
|
||||
memupdatemap(fdProcessInfo->hProcess);
|
||||
GuiUpdateMemoryView();
|
||||
varset("$res", mem, false);
|
||||
return STATUS_CONTINUE;
|
||||
|
@ -760,7 +760,7 @@ CMDRESULT cbDebugFree(int argc, char* argv[])
|
|||
if(!ok)
|
||||
dputs("VirtualFreeEx failed");
|
||||
dbggetprivateusage(fdProcessInfo->hProcess, true);
|
||||
MemUpdateMap(fdProcessInfo->hProcess);
|
||||
memupdatemap(fdProcessInfo->hProcess);
|
||||
GuiUpdateMemoryView();
|
||||
varset("$res", ok, false);
|
||||
return STATUS_CONTINUE;
|
||||
|
@ -786,7 +786,7 @@ CMDRESULT cbDebugMemset(int argc, char* argv[])
|
|||
}
|
||||
else
|
||||
{
|
||||
uint base = MemFindBaseAddr(addr, &size, true);
|
||||
uint base = memfindbaseaddr(addr, &size, true);
|
||||
if(!base)
|
||||
{
|
||||
dputs("invalid address specified");
|
||||
|
@ -806,15 +806,15 @@ CMDRESULT cbDebugMemset(int argc, char* argv[])
|
|||
|
||||
CMDRESULT cbDebugBenchmark(int argc, char* argv[])
|
||||
{
|
||||
uint addr = MemFindBaseAddr(GetContextDataEx(hActiveThread, UE_CIP), 0);
|
||||
uint addr = memfindbaseaddr(GetContextDataEx(hActiveThread, UE_CIP), 0);
|
||||
DWORD ticks = GetTickCount();
|
||||
char comment[MAX_COMMENT_SIZE] = "";
|
||||
for(uint i = addr; i < addr + 100000; i++)
|
||||
{
|
||||
CommentSet(i, "test", false);
|
||||
commentset(i, "test", false);
|
||||
labelset(i, "test", false);
|
||||
BookmarkSet(i, false);
|
||||
FunctionAdd(i, i, false);
|
||||
bookmarkset(i, false);
|
||||
functionadd(i, i, false);
|
||||
}
|
||||
dprintf("%ums\n", GetTickCount() - ticks);
|
||||
return STATUS_CONTINUE;
|
||||
|
@ -962,7 +962,7 @@ CMDRESULT cbDebugStackDump(int argc, char* argv[])
|
|||
}
|
||||
duint csp = GetContextDataEx(hActiveThread, UE_CSP);
|
||||
duint size = 0;
|
||||
duint base = MemFindBaseAddr(csp, &size);
|
||||
duint base = memfindbaseaddr(csp, &size);
|
||||
if(base && addr >= base && addr < (base + size))
|
||||
GuiStackDumpAt(addr, csp);
|
||||
else
|
||||
|
@ -1035,13 +1035,13 @@ CMDRESULT cbDebugSwitchthread(int argc, char* argv[])
|
|||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &threadid, false))
|
||||
return STATUS_ERROR;
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//switch thread
|
||||
hActiveThread = ThreadGetHandle((DWORD)threadid);
|
||||
hActiveThread = threadgethandle((DWORD)threadid);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
dputs("Thread switched!");
|
||||
return STATUS_CONTINUE;
|
||||
|
@ -1053,13 +1053,13 @@ CMDRESULT cbDebugSuspendthread(int argc, char* argv[])
|
|||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &threadid, false))
|
||||
return STATUS_ERROR;
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//suspend thread
|
||||
if(SuspendThread(ThreadGetHandle((DWORD)threadid)) == -1)
|
||||
if(SuspendThread(threadgethandle((DWORD)threadid)) == -1)
|
||||
{
|
||||
dputs("Error suspending thread");
|
||||
return STATUS_ERROR;
|
||||
|
@ -1075,13 +1075,13 @@ CMDRESULT cbDebugResumethread(int argc, char* argv[])
|
|||
if(argc > 1)
|
||||
if(!valfromstring(argv[1], &threadid, false))
|
||||
return STATUS_ERROR;
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//resume thread
|
||||
if(ResumeThread(ThreadGetHandle((DWORD)threadid)) == -1)
|
||||
if(ResumeThread(threadgethandle((DWORD)threadid)) == -1)
|
||||
{
|
||||
dputs("Error resuming thread");
|
||||
return STATUS_ERROR;
|
||||
|
@ -1101,13 +1101,13 @@ CMDRESULT cbDebugKillthread(int argc, char* argv[])
|
|||
if(argc > 2)
|
||||
if(!valfromstring(argv[2], &exitcode, false))
|
||||
return STATUS_ERROR;
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//terminate thread
|
||||
if(TerminateThread(ThreadGetHandle((DWORD)threadid), (DWORD)exitcode) != 0)
|
||||
if(TerminateThread(threadgethandle((DWORD)threadid), (DWORD)exitcode) != 0)
|
||||
{
|
||||
GuiUpdateAllViews();
|
||||
dputs("Thread terminated");
|
||||
|
@ -1119,16 +1119,18 @@ CMDRESULT cbDebugKillthread(int argc, char* argv[])
|
|||
|
||||
CMDRESULT cbDebugSuspendAllThreads(int argc, char* argv[])
|
||||
{
|
||||
dprintf("%d/%d thread(s) suspended\n", ThreadSuspendAll(), ThreadGetCount());
|
||||
|
||||
int threadCount = threadgetcount();
|
||||
int suspendedCount = threadsuspendall();
|
||||
dprintf("%d/%d thread(s) suspended\n", suspendedCount, threadCount);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
CMDRESULT cbDebugResumeAllThreads(int argc, char* argv[])
|
||||
{
|
||||
dprintf("%d/%d thread(s) resumed\n", ThreadResumeAll(), ThreadGetCount());
|
||||
|
||||
int threadCount = threadgetcount();
|
||||
int resumeCount = threadresumeall();
|
||||
dprintf("%d/%d thread(s) resumed\n", resumeCount, threadCount);
|
||||
GuiUpdateAllViews();
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
@ -1183,13 +1185,13 @@ CMDRESULT cbDebugSetPriority(int argc, char* argv[])
|
|||
return STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
if(!ThreadIsValid((DWORD)threadid)) //check if the thread is valid
|
||||
if(!threadisvalid((DWORD)threadid)) //check if the thread is valid
|
||||
{
|
||||
dprintf("Invalid thread %X\n", threadid);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
//set thread priority
|
||||
if(SetThreadPriority(ThreadGetHandle((DWORD)threadid), (int)priority) == 0)
|
||||
if(SetThreadPriority(threadgethandle((DWORD)threadid), (int)priority) == 0)
|
||||
{
|
||||
dputs("Error setting thread priority");
|
||||
return STATUS_ERROR;
|
||||
|
@ -1210,12 +1212,12 @@ CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[])
|
|||
}
|
||||
if(!argget(*argv, arg1, 0, true)) //enable all hardware breakpoints
|
||||
{
|
||||
if(!BpGetCount(BPHARDWARE))
|
||||
if(!bpgetcount(BPHARDWARE))
|
||||
{
|
||||
dputs("No hardware breakpoints to enable!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnumAll(cbEnableAllHardwareBreakpoints)) //at least one enable failed
|
||||
if(!bpenumall(cbEnableAllHardwareBreakpoints)) //at least one enable failed
|
||||
return STATUS_ERROR;
|
||||
dputs("All hardware breakpoints enabled!");
|
||||
GuiUpdateAllViews();
|
||||
|
@ -1223,7 +1225,7 @@ CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[])
|
|||
}
|
||||
BREAKPOINT found;
|
||||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint
|
||||
{
|
||||
dprintf("No such hardware breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
|
@ -1235,8 +1237,8 @@ CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[])
|
|||
return STATUS_CONTINUE;
|
||||
}
|
||||
TITANSETDRX(found.titantype, drx);
|
||||
BpSetTitanType(found.addr, BPHARDWARE, found.titantype);
|
||||
if(!BpEnable(found.addr, BPHARDWARE, true) or !SetHardwareBreakPoint(found.addr, drx, TITANGETTYPE(found.titantype), TITANGETSIZE(found.titantype), (void*)cbHardwareBreakpoint))
|
||||
bpsettitantype(found.addr, BPHARDWARE, found.titantype);
|
||||
if(!bpenable(found.addr, BPHARDWARE, true) or !SetHardwareBreakPoint(found.addr, drx, TITANGETTYPE(found.titantype), TITANGETSIZE(found.titantype), (void*)cbHardwareBreakpoint))
|
||||
{
|
||||
dprintf("Could not enable hardware breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -1251,12 +1253,12 @@ CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[])
|
|||
char arg1[deflen] = "";
|
||||
if(!argget(*argv, arg1, 0, true)) //delete all hardware breakpoints
|
||||
{
|
||||
if(!BpGetCount(BPHARDWARE))
|
||||
if(!bpgetcount(BPHARDWARE))
|
||||
{
|
||||
dputs("No hardware breakpoints to disable!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnumAll(cbDisableAllHardwareBreakpoints)) //at least one deletion failed
|
||||
if(!bpenumall(cbDisableAllHardwareBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs("All hardware breakpoints disabled!");
|
||||
GuiUpdateAllViews();
|
||||
|
@ -1264,7 +1266,7 @@ CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[])
|
|||
}
|
||||
BREAKPOINT found;
|
||||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPHARDWARE, 0, &found)) //invalid hardware breakpoint
|
||||
{
|
||||
dprintf("No such hardware breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
|
@ -1274,7 +1276,7 @@ CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[])
|
|||
dputs("Hardware breakpoint already disabled!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnable(found.addr, BPHARDWARE, false) or !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype)))
|
||||
if(!bpenable(found.addr, BPHARDWARE, false) or !DeleteHardwareBreakPoint(TITANGETDRX(found.titantype)))
|
||||
{
|
||||
dprintf("Could not disable hardware breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -1295,12 +1297,12 @@ CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[])
|
|||
}
|
||||
if(!argget(*argv, arg1, 0, true)) //enable all memory breakpoints
|
||||
{
|
||||
if(!BpGetCount(BPMEMORY))
|
||||
if(!bpgetcount(BPMEMORY))
|
||||
{
|
||||
dputs("No hardware breakpoints to enable!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnumAll(cbEnableAllHardwareBreakpoints)) //at least one enable failed
|
||||
if(!bpenumall(cbEnableAllHardwareBreakpoints)) //at least one enable failed
|
||||
return STATUS_ERROR;
|
||||
dputs("All memory breakpoints enabled!");
|
||||
GuiUpdateAllViews();
|
||||
|
@ -1308,7 +1310,7 @@ CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[])
|
|||
}
|
||||
BREAKPOINT found;
|
||||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint
|
||||
{
|
||||
dprintf("No such memory breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
|
@ -1320,8 +1322,8 @@ CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[])
|
|||
return STATUS_CONTINUE;
|
||||
}
|
||||
uint size = 0;
|
||||
MemFindBaseAddr(found.addr, &size);
|
||||
if(!BpEnable(found.addr, BPMEMORY, true) or !SetMemoryBPXEx(found.addr, size, found.titantype, !found.singleshoot, (void*)cbMemoryBreakpoint))
|
||||
memfindbaseaddr(found.addr, &size);
|
||||
if(!bpenable(found.addr, BPMEMORY, true) or !SetMemoryBPXEx(found.addr, size, found.titantype, !found.singleshoot, (void*)cbMemoryBreakpoint))
|
||||
{
|
||||
dprintf("Could not enable memory breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -1336,12 +1338,12 @@ CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[])
|
|||
char arg1[deflen] = "";
|
||||
if(!argget(*argv, arg1, 0, true)) //delete all memory breakpoints
|
||||
{
|
||||
if(!BpGetCount(BPMEMORY))
|
||||
if(!bpgetcount(BPMEMORY))
|
||||
{
|
||||
dputs("No memory breakpoints to disable!");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
if(!BpEnumAll(cbDisableAllMemoryBreakpoints)) //at least one deletion failed
|
||||
if(!bpenumall(cbDisableAllMemoryBreakpoints)) //at least one deletion failed
|
||||
return STATUS_ERROR;
|
||||
dputs("All memory breakpoints disabled!");
|
||||
GuiUpdateAllViews();
|
||||
|
@ -1349,7 +1351,7 @@ CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[])
|
|||
}
|
||||
BREAKPOINT found;
|
||||
uint addr = 0;
|
||||
if(!valfromstring(arg1, &addr) or !BpGet(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint
|
||||
if(!valfromstring(arg1, &addr) or !bpget(addr, BPMEMORY, 0, &found)) //invalid memory breakpoint
|
||||
{
|
||||
dprintf("No such memory breakpoint \"%s\"\n", arg1);
|
||||
return STATUS_ERROR;
|
||||
|
@ -1360,8 +1362,8 @@ CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[])
|
|||
return STATUS_CONTINUE;
|
||||
}
|
||||
uint size = 0;
|
||||
MemFindBaseAddr(found.addr, &size);
|
||||
if(!BpEnable(found.addr, BPMEMORY, false) or !RemoveMemoryBPX(found.addr, size))
|
||||
memfindbaseaddr(found.addr, &size);
|
||||
if(!bpenable(found.addr, BPMEMORY, false) or !RemoveMemoryBPX(found.addr, size))
|
||||
{
|
||||
dprintf("Could not disable memory breakpoint "fhex"\n", found.addr);
|
||||
return STATUS_ERROR;
|
||||
|
@ -1382,13 +1384,13 @@ CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[])
|
|||
}
|
||||
if(argc < 2) //no arguments
|
||||
{
|
||||
SymDownloadAllSymbols(szSymbolStore); //download symbols for all modules
|
||||
symdownloadallsymbols(szSymbolStore); //download symbols for all modules
|
||||
GuiSymbolRefreshCurrent();
|
||||
dputs("Done! See symbol log for more information");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
//get some module information
|
||||
uint modbase = ModBaseFromName(argv[1]);
|
||||
uint modbase = modbasefromname(argv[1]);
|
||||
if(!modbase)
|
||||
{
|
||||
dprintf("Invalid module \"%s\"!\n", argv[1]);
|
||||
|
@ -1798,7 +1800,7 @@ CMDRESULT cbDebugSetPageRights(int argc, char* argv[])
|
|||
|
||||
//update the memory map
|
||||
dbggetprivateusage(fdProcessInfo->hProcess, true);
|
||||
MemUpdateMap(fdProcessInfo->hProcess);
|
||||
memupdatemap(fdProcessInfo->hProcess);
|
||||
GuiUpdateMemoryView();
|
||||
|
||||
dprintf("New rights of "fhex": %s\n", addr, rights);
|
||||
|
@ -1815,7 +1817,7 @@ CMDRESULT cbDebugLoadLib(int argc, char* argv[])
|
|||
}
|
||||
|
||||
LoadLibThreadID = fdProcessInfo->dwThreadId;
|
||||
HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID);
|
||||
HANDLE LoadLibThread = threadgethandle((DWORD)LoadLibThreadID);
|
||||
|
||||
DLLNameMem = VirtualAllocEx(fdProcessInfo->hProcess, NULL, strlen(argv[1]) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
ASMAddr = VirtualAllocEx(fdProcessInfo->hProcess, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
|
@ -1826,7 +1828,7 @@ CMDRESULT cbDebugLoadLib(int argc, char* argv[])
|
|||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(!MemWrite(DLLNameMem, argv[1], strlen(argv[1]), NULL))
|
||||
if(!memwrite(fdProcessInfo->hProcess, DLLNameMem, argv[1], strlen(argv[1]), NULL))
|
||||
{
|
||||
dprintf("Error: couldn't write process memory");
|
||||
return STATUS_ERROR;
|
||||
|
@ -1867,7 +1869,7 @@ CMDRESULT cbDebugLoadLib(int argc, char* argv[])
|
|||
SetContextDataEx(LoadLibThread, UE_CIP, (uint)ASMAddr);
|
||||
SetBPX((uint)ASMAddr + counter, UE_SINGLESHOOT | UE_BREAKPOINT_TYPE_INT3, (void*)cbLoadLibBPX);
|
||||
|
||||
ThreadSuspendAll();
|
||||
threadsuspendall();
|
||||
ResumeThread(LoadLibThread);
|
||||
|
||||
unlock(WAITID_RUN);
|
||||
|
@ -1878,7 +1880,7 @@ CMDRESULT cbDebugLoadLib(int argc, char* argv[])
|
|||
void cbLoadLibBPX()
|
||||
{
|
||||
uint LibAddr = 0;
|
||||
HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID);
|
||||
HANDLE LoadLibThread = threadgethandle((DWORD)LoadLibThreadID);
|
||||
#ifdef _WIN64
|
||||
LibAddr = GetContextDataEx(LoadLibThread, UE_RAX);
|
||||
#else
|
||||
|
@ -1889,7 +1891,7 @@ void cbLoadLibBPX()
|
|||
SetFullContextDataEx(LoadLibThread, &backupctx);
|
||||
VirtualFreeEx(fdProcessInfo->hProcess, DLLNameMem, 0, MEM_RELEASE);
|
||||
VirtualFreeEx(fdProcessInfo->hProcess, ASMAddr, 0, MEM_RELEASE);
|
||||
ThreadResumeAll();
|
||||
threadresumeall();
|
||||
//update GUI
|
||||
GuiSetDebugState(paused);
|
||||
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
|
||||
|
@ -2000,7 +2002,7 @@ CMDRESULT cbDebugSetCmdline(int argc, char* argv[])
|
|||
|
||||
//update the memory map
|
||||
dbggetprivateusage(fdProcessInfo->hProcess, true);
|
||||
MemUpdateMap(fdProcessInfo->hProcess);
|
||||
memupdatemap(fdProcessInfo->hProcess);
|
||||
GuiUpdateMemoryView();
|
||||
|
||||
dprintf("New command line: %s\n", argv[1]);
|
||||
|
|
|
@ -117,7 +117,7 @@ bool disasmfast(unsigned char* data, uint addr, BASIC_INSTRUCTION_INFO* basicinf
|
|||
bool disasmfast(uint addr, BASIC_INSTRUCTION_INFO* basicinfo)
|
||||
{
|
||||
unsigned int data[16];
|
||||
if(!MemRead((void*)addr, data, sizeof(data), 0))
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)addr, data, sizeof(data), 0))
|
||||
return false;
|
||||
return disasmfast((unsigned char*)data, addr, basicinfo);
|
||||
}
|
|
@ -321,11 +321,11 @@ bool disasmispossiblestring(uint addr)
|
|||
{
|
||||
unsigned char data[11];
|
||||
memset(data, 0, sizeof(data));
|
||||
if(!MemRead((void*)addr, data, sizeof(data) - 3, 0))
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)addr, data, sizeof(data) - 3, 0))
|
||||
return false;
|
||||
uint test = 0;
|
||||
memcpy(&test, data, sizeof(uint));
|
||||
if(MemIsValidReadPtr(test)) //imports/pointers
|
||||
if(memisvalidreadptr(fdProcessInfo->hProcess, test)) //imports/pointers
|
||||
return false;
|
||||
if(isasciistring(data, sizeof(data)) or isunicodestring(data, _countof(data)))
|
||||
return true;
|
||||
|
@ -340,11 +340,11 @@ bool disasmgetstringat(uint addr, STRING_TYPE* type, char* ascii, char* unicode,
|
|||
return false;
|
||||
Memory<unsigned char*> data((maxlen + 1) * 2, "disasmgetstringat:data");
|
||||
memset(data, 0, (maxlen + 1) * 2);
|
||||
if(!MemRead((void*)addr, data, (maxlen + 1) * 2, 0))
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)addr, data, (maxlen + 1) * 2, 0))
|
||||
return false;
|
||||
uint test = 0;
|
||||
memcpy(&test, data, sizeof(uint));
|
||||
if(MemIsValidReadPtr(test))
|
||||
if(memisvalidreadptr(fdProcessInfo->hProcess, test))
|
||||
return false;
|
||||
if(isasciistring(data, maxlen))
|
||||
{
|
||||
|
@ -442,7 +442,7 @@ int disasmgetsize(uint addr, unsigned char* data)
|
|||
int disasmgetsize(uint addr)
|
||||
{
|
||||
char data[16];
|
||||
if(!MemRead((void*)addr, data, sizeof(data), 0))
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)addr, data, sizeof(data), 0))
|
||||
return 1;
|
||||
return disasmgetsize(addr, (unsigned char*)data);
|
||||
}
|
|
@ -1,73 +1,64 @@
|
|||
#pragma once
|
||||
#ifndef _DYNAMICMEM_H
|
||||
#define _DYNAMICMEM_H
|
||||
|
||||
template<typename T>
|
||||
class Memory
|
||||
{
|
||||
public:
|
||||
//
|
||||
// This class guarantees that the returned allocated memory
|
||||
// will always be zeroed
|
||||
//
|
||||
Memory(const char* Reason = "Memory:???")
|
||||
Memory(const char* reason = "Memory:???")
|
||||
{
|
||||
m_Ptr = nullptr;
|
||||
m_Size = 0;
|
||||
m_Reason = Reason;
|
||||
mPtr = 0;
|
||||
mSize = 0;
|
||||
mReason = reason;
|
||||
}
|
||||
|
||||
Memory(size_t Size, const char* Reason = "Memory:???")
|
||||
Memory(size_t size, const char* reason = "Memory:???")
|
||||
{
|
||||
m_Ptr = reinterpret_cast<T>(emalloc(Size));
|
||||
m_Size = Size;
|
||||
m_Reason = Reason;
|
||||
|
||||
memset(m_Ptr, 0, Size);
|
||||
mPtr = reinterpret_cast<T>(emalloc(size));
|
||||
mSize = size;
|
||||
mReason = reason;
|
||||
memset(mPtr, 0, size);
|
||||
}
|
||||
|
||||
~Memory()
|
||||
{
|
||||
if (m_Ptr)
|
||||
efree(m_Ptr);
|
||||
efree(mPtr);
|
||||
}
|
||||
|
||||
T realloc(size_t Size, const char* Reason = "Memory:???")
|
||||
T realloc(size_t size, const char* reason = "Memory:???")
|
||||
{
|
||||
m_Ptr = reinterpret_cast<T>(erealloc(m_Ptr, Size));
|
||||
m_Size = Size;
|
||||
m_Reason = Reason;
|
||||
|
||||
return (T)memset(m_Ptr, 0, m_Size);
|
||||
mPtr = reinterpret_cast<T>(erealloc(mPtr, size));
|
||||
mSize = size;
|
||||
mReason = reason;
|
||||
memset(mPtr, 0, size);
|
||||
return mPtr;
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return m_Size;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
operator U()
|
||||
{
|
||||
return (U)m_Ptr;
|
||||
return (U)mPtr;
|
||||
}
|
||||
|
||||
operator T()
|
||||
{
|
||||
return m_Ptr;
|
||||
return mPtr;
|
||||
}
|
||||
|
||||
T operator()()
|
||||
{
|
||||
return m_Ptr;
|
||||
return mPtr;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
T operator+(const U& Other)
|
||||
{
|
||||
return m_Ptr + Other;
|
||||
}
|
||||
size_t size()
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
private:
|
||||
T m_Ptr;
|
||||
size_t m_Size;
|
||||
const char* m_Reason;
|
||||
};
|
||||
T mPtr;
|
||||
size_t mSize;
|
||||
const char* mReason;
|
||||
};
|
||||
|
||||
#endif //_DYNAMICMEM_H
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,7 @@
|
|||
#pragma once
|
||||
#ifndef _ERROR_H
|
||||
#define _ERROR_H
|
||||
|
||||
void ErrorCodeInit();
|
||||
const char* ErrorCodeToName(unsigned int ErrorCode);
|
||||
void errorinit();
|
||||
const char* errornamefromcode(unsigned int ErrorCode);
|
||||
|
||||
#endif //_ERROR_H
|
|
@ -1,79 +1,77 @@
|
|||
#include "exception.h"
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
std::unordered_map<unsigned int, const char*> ExceptionNames;
|
||||
static std::map<unsigned int, const char*> exceptionNames;
|
||||
|
||||
void ExceptionCodeInit()
|
||||
void exceptioninit()
|
||||
{
|
||||
ExceptionNames.clear();
|
||||
ExceptionNames.insert(std::make_pair(0x04242420, "CLRDBG_NOTIFICATION_EXCEPTION_CODE"));
|
||||
ExceptionNames.insert(std::make_pair(0x40000005, "STATUS_SEGMENT_NOTIFICATION"));
|
||||
ExceptionNames.insert(std::make_pair(0x4000001C, "STATUS_WX86_UNSIMULATE"));
|
||||
ExceptionNames.insert(std::make_pair(0x4000001D, "STATUS_WX86_CONTINUE"));
|
||||
ExceptionNames.insert(std::make_pair(0x4000001E, "STATUS_WX86_SINGLE_STEP"));
|
||||
ExceptionNames.insert(std::make_pair(0x4000001F, "STATUS_WX86_BREAKPOINT"));
|
||||
ExceptionNames.insert(std::make_pair(0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE"));
|
||||
ExceptionNames.insert(std::make_pair(0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE"));
|
||||
ExceptionNames.insert(std::make_pair(0x40000022, "STATUS_WX86_EXCEPTION_CHAIN"));
|
||||
ExceptionNames.insert(std::make_pair(0x40000028, "STATUS_WX86_CREATEWX86TIB"));
|
||||
ExceptionNames.insert(std::make_pair(0x40010003, "DBG_TERMINATE_THREAD"));
|
||||
ExceptionNames.insert(std::make_pair(0x40010004, "DBG_TERMINATE_PROCESS"));
|
||||
ExceptionNames.insert(std::make_pair(0x40010005, "DBG_CONTROL_C"));
|
||||
ExceptionNames.insert(std::make_pair(0x40010006, "DBG_PRINTEXCEPTION_C"));
|
||||
ExceptionNames.insert(std::make_pair(0x40010007, "DBG_RIPEXCEPTION"));
|
||||
ExceptionNames.insert(std::make_pair(0x40010008, "DBG_CONTROL_BREAK"));
|
||||
ExceptionNames.insert(std::make_pair(0x40010009, "DBG_COMMAND_EXCEPTION"));
|
||||
ExceptionNames.insert(std::make_pair(0x406D1388, "MS_VC_EXCEPTION"));
|
||||
ExceptionNames.insert(std::make_pair(0x80000001, "EXCEPTION_GUARD_PAGE"));
|
||||
ExceptionNames.insert(std::make_pair(0x80000002, "EXCEPTION_DATATYPE_MISALIGNMENT"));
|
||||
ExceptionNames.insert(std::make_pair(0x80000003, "EXCEPTION_BREAKPOINT"));
|
||||
ExceptionNames.insert(std::make_pair(0x80000004, "EXCEPTION_SINGLE_STEP"));
|
||||
ExceptionNames.insert(std::make_pair(0x80000026, "STATUS_LONGJUMP"));
|
||||
ExceptionNames.insert(std::make_pair(0x80000029, "STATUS_UNWIND_CONSOLIDATE"));
|
||||
ExceptionNames.insert(std::make_pair(0x80010001, "DBG_EXCEPTION_NOT_HANDLED"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000005, "EXCEPTION_ACCESS_VIOLATION"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000006, "EXCEPTION_IN_PAGE_ERROR"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000008, "EXCEPTION_INVALID_HANDLE"));
|
||||
ExceptionNames.insert(std::make_pair(0xC000000D, "STATUS_INVALID_PARAMETER"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000017, "STATUS_NO_MEMORY"));
|
||||
ExceptionNames.insert(std::make_pair(0xC000001D, "EXCEPTION_ILLEGAL_INSTRUCTION"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000025, "EXCEPTION_NONCONTINUABLE_EXCEPTION"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000026, "EXCEPTION_INVALID_DISPOSITION"));
|
||||
ExceptionNames.insert(std::make_pair(0xC000008C, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
|
||||
ExceptionNames.insert(std::make_pair(0xC000008D, "EXCEPTION_FLT_DENORMAL_OPERAND"));
|
||||
ExceptionNames.insert(std::make_pair(0xC000008E, "EXCEPTION_FLT_DIVIDE_BY_ZERO"));
|
||||
ExceptionNames.insert(std::make_pair(0xC000008F, "EXCEPTION_FLT_INEXACT_RESULT"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000090, "EXCEPTION_FLT_INVALID_OPERATION"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000091, "EXCEPTION_FLT_OVERFLOW"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000092, "EXCEPTION_FLT_STACK_CHECK"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000093, "EXCEPTION_FLT_UNDERFLOW"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000094, "EXCEPTION_INT_DIVIDE_BY_ZERO"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000095, "EXCEPTION_INT_OVERFLOW"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000096, "EXCEPTION_PRIV_INSTRUCTION"));
|
||||
ExceptionNames.insert(std::make_pair(0xC00000FD, "EXCEPTION_STACK_OVERFLOW"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000135, "STATUS_DLL_NOT_FOUND"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000138, "STATUS_ORDINAL_NOT_FOUND"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND"));
|
||||
ExceptionNames.insert(std::make_pair(0xC000013A, "STATUS_CONTROL_C_EXIT"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000142, "STATUS_DLL_INIT_FAILED"));
|
||||
ExceptionNames.insert(std::make_pair(0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000194, "EXCEPTION_POSSIBLE_DEADLOCK"));
|
||||
ExceptionNames.insert(std::make_pair(0xC00001A5, "STATUS_INVALID_EXCEPTION_HANDLER"));
|
||||
ExceptionNames.insert(std::make_pair(0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS"));
|
||||
ExceptionNames.insert(std::make_pair(0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS"));
|
||||
ExceptionNames.insert(std::make_pair(0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR"));
|
||||
ExceptionNames.insert(std::make_pair(0xC00002C9, "STATUS_REG_NAT_CONSUMPTION"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000409, "STATUS_STACK_BUFFER_OVERRUN"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000417, "STATUS_INVALID_CRUNTIME_PARAMETER"));
|
||||
ExceptionNames.insert(std::make_pair(0xC0000420, "STATUS_ASSERTION_FAILURE"));
|
||||
ExceptionNames.insert(std::make_pair(0xE0434352, "CLR_EXCEPTION"));
|
||||
ExceptionNames.insert(std::make_pair(0xE06D7363, "CPP_EH_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0x40000005, "STATUS_SEGMENT_NOTIFICATION"));
|
||||
exceptionNames.insert(std::make_pair(0x4000001C, "STATUS_WX86_UNSIMULATE"));
|
||||
exceptionNames.insert(std::make_pair(0x4000001D, "STATUS_WX86_CONTINUE"));
|
||||
exceptionNames.insert(std::make_pair(0x4000001E, "STATUS_WX86_SINGLE_STEP"));
|
||||
exceptionNames.insert(std::make_pair(0x4000001F, "STATUS_WX86_BREAKPOINT"));
|
||||
exceptionNames.insert(std::make_pair(0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE"));
|
||||
exceptionNames.insert(std::make_pair(0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE"));
|
||||
exceptionNames.insert(std::make_pair(0x40000022, "STATUS_WX86_EXCEPTION_CHAIN"));
|
||||
exceptionNames.insert(std::make_pair(0x40000028, "STATUS_WX86_CREATEWX86TIB"));
|
||||
exceptionNames.insert(std::make_pair(0x40010003, "DBG_TERMINATE_THREAD"));
|
||||
exceptionNames.insert(std::make_pair(0x40010004, "DBG_TERMINATE_PROCESS"));
|
||||
exceptionNames.insert(std::make_pair(0x40010005, "DBG_CONTROL_C"));
|
||||
exceptionNames.insert(std::make_pair(0x40010006, "DBG_PRINTEXCEPTION_C"));
|
||||
exceptionNames.insert(std::make_pair(0x40010007, "DBG_RIPEXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0x40010008, "DBG_CONTROL_BREAK"));
|
||||
exceptionNames.insert(std::make_pair(0x40010009, "DBG_COMMAND_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0x80000001, "EXCEPTION_GUARD_PAGE"));
|
||||
exceptionNames.insert(std::make_pair(0x80000002, "EXCEPTION_DATATYPE_MISALIGNMENT"));
|
||||
exceptionNames.insert(std::make_pair(0x80000003, "EXCEPTION_BREAKPOINT"));
|
||||
exceptionNames.insert(std::make_pair(0x80000004, "EXCEPTION_SINGLE_STEP"));
|
||||
exceptionNames.insert(std::make_pair(0x80000026, "STATUS_LONGJUMP"));
|
||||
exceptionNames.insert(std::make_pair(0x80000029, "STATUS_UNWIND_CONSOLIDATE"));
|
||||
exceptionNames.insert(std::make_pair(0x80010001, "DBG_EXCEPTION_NOT_HANDLED"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000005, "EXCEPTION_ACCESS_VIOLATION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000006, "EXCEPTION_IN_PAGE_ERROR"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000008, "EXCEPTION_INVALID_HANDLE"));
|
||||
exceptionNames.insert(std::make_pair(0xC000000D, "STATUS_INVALID_PARAMETER"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000017, "STATUS_NO_MEMORY"));
|
||||
exceptionNames.insert(std::make_pair(0xC000001D, "EXCEPTION_ILLEGAL_INSTRUCTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000025, "EXCEPTION_NONCONTINUABLE_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000026, "EXCEPTION_INVALID_DISPOSITION"));
|
||||
exceptionNames.insert(std::make_pair(0xC000008C, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
|
||||
exceptionNames.insert(std::make_pair(0xC000008D, "EXCEPTION_FLT_DENORMAL_OPERAND"));
|
||||
exceptionNames.insert(std::make_pair(0xC000008E, "EXCEPTION_FLT_DIVIDE_BY_ZERO"));
|
||||
exceptionNames.insert(std::make_pair(0xC000008F, "EXCEPTION_FLT_INEXACT_RESULT"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000090, "EXCEPTION_FLT_INVALID_OPERATION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000091, "EXCEPTION_FLT_OVERFLOW"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000092, "EXCEPTION_FLT_STACK_CHECK"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000093, "EXCEPTION_FLT_UNDERFLOW"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000094, "EXCEPTION_INT_DIVIDE_BY_ZERO"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000095, "EXCEPTION_INT_OVERFLOW"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000096, "EXCEPTION_PRIV_INSTRUCTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC00000FD, "EXCEPTION_STACK_OVERFLOW"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000135, "STATUS_DLL_NOT_FOUND"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000138, "STATUS_ORDINAL_NOT_FOUND"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND"));
|
||||
exceptionNames.insert(std::make_pair(0xC000013A, "STATUS_CONTROL_C_EXIT"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000142, "STATUS_DLL_INIT_FAILED"));
|
||||
exceptionNames.insert(std::make_pair(0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000194, "EXCEPTION_POSSIBLE_DEADLOCK"));
|
||||
exceptionNames.insert(std::make_pair(0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS"));
|
||||
exceptionNames.insert(std::make_pair(0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS"));
|
||||
exceptionNames.insert(std::make_pair(0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR"));
|
||||
exceptionNames.insert(std::make_pair(0xC00002C9, "STATUS_REG_NAT_CONSUMPTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000409, "STATUS_STACK_BUFFER_OVERRUN"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000417, "STATUS_INVALID_CRUNTIME_PARAMETER"));
|
||||
exceptionNames.insert(std::make_pair(0xC0000420, "STATUS_ASSERTION_FAILURE"));
|
||||
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(0x406D1388, "MS_VC_EXCEPTION"));
|
||||
exceptionNames.insert(std::make_pair(0xC00001A5, "STATUS_INVALID_EXCEPTION_HANDLER"));
|
||||
}
|
||||
|
||||
const char* ExceptionCodeToName(unsigned int ExceptionCode)
|
||||
const char* exceptionnamefromcode(unsigned int ExceptionCode)
|
||||
{
|
||||
if(!ExceptionNames.count(ExceptionCode))
|
||||
return nullptr;
|
||||
|
||||
return ExceptionNames[ExceptionCode];
|
||||
if(!exceptionNames.count(ExceptionCode))
|
||||
return 0;
|
||||
return exceptionNames[ExceptionCode];
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
#pragma once
|
||||
#ifndef _EXCEPTION_H
|
||||
#define _EXCEPTION_H
|
||||
|
||||
void ExceptionCodeInit();
|
||||
const char* ExceptionCodeToName(unsigned int ExceptionCode);
|
||||
void exceptioninit();
|
||||
const char* exceptionnamefromcode(unsigned int ExceptionCode);
|
||||
|
||||
#endif //_EXCEPTIONS_H
|
|
@ -8,257 +8,185 @@ typedef std::map<ModuleRange, FUNCTIONSINFO, ModuleRangeCompare> FunctionsInfo;
|
|||
|
||||
static FunctionsInfo functions;
|
||||
|
||||
bool FunctionAdd(uint Start, uint End, bool Manual)
|
||||
bool functionadd(uint start, uint end, bool manual)
|
||||
{
|
||||
// CHECK: Export/Command function
|
||||
if(!DbgIsDebugging())
|
||||
if(!DbgIsDebugging() or end < start or !memisvalidreadptr(fdProcessInfo->hProcess, start))
|
||||
return false;
|
||||
|
||||
// Make sure memory is readable
|
||||
if(!MemIsValidReadPtr(Start))
|
||||
const uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end)) //the function boundaries are not in the same module
|
||||
return false;
|
||||
|
||||
// Fail if boundary exceeds module size
|
||||
const uint moduleBase = ModBaseFromAddr(Start);
|
||||
|
||||
if(moduleBase != ModBaseFromAddr(End))
|
||||
if(functionoverlaps(start, end))
|
||||
return false;
|
||||
|
||||
// Fail if 'Start' and 'End' are incompatible
|
||||
if(Start > End || FunctionOverlaps(Start, End))
|
||||
return false;
|
||||
|
||||
FUNCTIONSINFO function;
|
||||
ModNameFromAddr(Start, function.mod, true);
|
||||
function.start = Start - moduleBase;
|
||||
function.end = End - moduleBase;
|
||||
function.manual = Manual;
|
||||
|
||||
// Insert to global table
|
||||
EXCLUSIVE_ACQUIRE(LockFunctions);
|
||||
|
||||
functions.insert(std::make_pair(ModuleRange(ModHashFromAddr(moduleBase), Range(function.start, function.end)), function));
|
||||
modnamefromaddr(start, function.mod, true);
|
||||
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;
|
||||
}
|
||||
|
||||
bool FunctionGet(uint Address, uint* Start, uint* End)
|
||||
bool functionget(uint addr, uint* start, uint* end)
|
||||
{
|
||||
// CHECK: Exported function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
const uint modbase = ModBaseFromAddr(Address);
|
||||
|
||||
// Lookup by module hash, then function range
|
||||
SHARED_ACQUIRE(LockFunctions);
|
||||
|
||||
auto found = functions.find(ModuleRange(ModHashFromAddr(modbase), Range(Address - modbase, Address - modbase)));
|
||||
|
||||
// Was this range found?
|
||||
if(found == functions.end())
|
||||
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;
|
||||
|
||||
if(Start)
|
||||
*Start = found->second.start + modbase;
|
||||
|
||||
if(End)
|
||||
*End = found->second.end + modbase;
|
||||
|
||||
if(start)
|
||||
*start = found->second.start + modbase;
|
||||
if(end)
|
||||
*end = found->second.end + modbase;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FunctionOverlaps(uint Start, uint End)
|
||||
bool functionoverlaps(uint start, uint end)
|
||||
{
|
||||
// CHECK: Exported function
|
||||
if(!DbgIsDebugging())
|
||||
if(!DbgIsDebugging() or end < start)
|
||||
return false;
|
||||
|
||||
// A function can't end before it begins
|
||||
if(Start > End)
|
||||
return false;
|
||||
|
||||
const uint moduleBase = ModBaseFromAddr(Start);
|
||||
|
||||
SHARED_ACQUIRE(LockFunctions);
|
||||
return (functions.count(ModuleRange(ModHashFromAddr(moduleBase), Range(Start - moduleBase, End - moduleBase))) > 0);
|
||||
const uint modbase = modbasefromaddr(start);
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
return (functions.count(ModuleRange(modhashfromva(modbase), Range(start - modbase, end - modbase))) > 0);
|
||||
}
|
||||
|
||||
bool FunctionDelete(uint Address)
|
||||
bool functiondel(uint addr)
|
||||
{
|
||||
// CHECK: Exported function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
const uint moduleBase = ModBaseFromAddr(Address);
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockFunctions);
|
||||
return (functions.erase(ModuleRange(ModHashFromAddr(moduleBase), Range(Address - moduleBase, Address - moduleBase))) > 0);
|
||||
const uint modbase = modbasefromaddr(addr);
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
return (functions.erase(ModuleRange(modhashfromva(modbase), Range(addr - modbase, addr - modbase))) > 0);
|
||||
}
|
||||
|
||||
void FunctionDelRange(uint Start, uint End)
|
||||
void functiondelrange(uint start, uint end)
|
||||
{
|
||||
// CHECK: Exported function
|
||||
if(!DbgIsDebugging())
|
||||
return;
|
||||
|
||||
// Should all functions be deleted?
|
||||
// 0x00000000 - 0xFFFFFFFF
|
||||
if(Start == 0 && End == ~0)
|
||||
bool bDelAll = (start == 0 && end == ~0); //0x00000000-0xFFFFFFFF
|
||||
uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end))
|
||||
return;
|
||||
start -= modbase;
|
||||
end -= modbase;
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
FunctionsInfo::iterator i = functions.begin();
|
||||
while(i != functions.end())
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockFunctions);
|
||||
functions.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// The start and end address must be in the same module
|
||||
uint moduleBase = ModBaseFromAddr(Start);
|
||||
|
||||
if(moduleBase != ModBaseFromAddr(End))
|
||||
return;
|
||||
|
||||
// Convert these to a relative offset
|
||||
Start -= moduleBase;
|
||||
End -= moduleBase;
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockFunctions);
|
||||
for(auto itr = functions.begin(); itr != functions.end();)
|
||||
if(i->second.manual) //ignore manual
|
||||
{
|
||||
// Ignore manually set entries
|
||||
if(itr->second.manual)
|
||||
{
|
||||
itr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// [Start, End]
|
||||
if(itr->second.end >= Start && itr->second.start <= End)
|
||||
itr = functions.erase(itr);
|
||||
else
|
||||
itr++;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FunctionCacheSave(JSON Root)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockFunctions);
|
||||
|
||||
// Allocate JSON object array
|
||||
const JSON jsonFunctions = json_array();
|
||||
const JSON jsonAutoFunctions = json_array();
|
||||
|
||||
for(auto & i : functions)
|
||||
{
|
||||
JSON currentFunction = json_object();
|
||||
|
||||
json_object_set_new(currentFunction, "module", json_string(i.second.mod));
|
||||
json_object_set_new(currentFunction, "start", json_hex(i.second.start));
|
||||
json_object_set_new(currentFunction, "end", json_hex(i.second.end));
|
||||
|
||||
if(i.second.manual)
|
||||
json_array_append_new(jsonFunctions, currentFunction);
|
||||
if(bDelAll or !(i->second.start <= end and i->second.end >= start))
|
||||
functions.erase(i++);
|
||||
else
|
||||
json_array_append_new(jsonAutoFunctions, currentFunction);
|
||||
i++;
|
||||
}
|
||||
|
||||
if(json_array_size(jsonFunctions))
|
||||
json_object_set(Root, "functions", jsonFunctions);
|
||||
|
||||
if(json_array_size(jsonAutoFunctions))
|
||||
json_object_set(Root, "autofunctions", jsonAutoFunctions);
|
||||
|
||||
// Decrease reference count to avoid leaking memory
|
||||
json_decref(jsonFunctions);
|
||||
json_decref(jsonAutoFunctions);
|
||||
}
|
||||
|
||||
void FunctionCacheLoad(JSON Root)
|
||||
void functioncachesave(JSON root)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockFunctions);
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
const JSON jsonfunctions = json_array();
|
||||
const JSON jsonautofunctions = json_array();
|
||||
for(FunctionsInfo::iterator i = functions.begin(); i != functions.end(); ++i)
|
||||
{
|
||||
const FUNCTIONSINFO curFunction = i->second;
|
||||
JSON curjsonfunction = json_object();
|
||||
json_object_set_new(curjsonfunction, "module", json_string(curFunction.mod));
|
||||
json_object_set_new(curjsonfunction, "start", json_hex(curFunction.start));
|
||||
json_object_set_new(curjsonfunction, "end", json_hex(curFunction.end));
|
||||
if(curFunction.manual)
|
||||
json_array_append_new(jsonfunctions, curjsonfunction);
|
||||
else
|
||||
json_array_append_new(jsonautofunctions, curjsonfunction);
|
||||
}
|
||||
if(json_array_size(jsonfunctions))
|
||||
json_object_set(root, "functions", jsonfunctions);
|
||||
json_decref(jsonfunctions);
|
||||
if(json_array_size(jsonautofunctions))
|
||||
json_object_set(root, "autofunctions", jsonautofunctions);
|
||||
json_decref(jsonautofunctions);
|
||||
}
|
||||
|
||||
// Delete existing entries
|
||||
void functioncacheload(JSON root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
functions.clear();
|
||||
|
||||
// Inline lambda to enumerate all JSON array indices
|
||||
auto InsertFunctions = [](const JSON Object, bool Manual)
|
||||
const JSON jsonfunctions = json_object_get(root, "functions");
|
||||
if(jsonfunctions)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(Object, i, value)
|
||||
json_array_foreach(jsonfunctions, i, value)
|
||||
{
|
||||
FUNCTIONSINFO function;
|
||||
|
||||
// Copy module name
|
||||
FUNCTIONSINFO curFunction;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(function.mod, mod);
|
||||
strcpy_s(curFunction.mod, mod);
|
||||
else
|
||||
function.mod[0] = '\0';
|
||||
|
||||
// Function address
|
||||
function.start = (uint)json_hex_value(json_object_get(value, "start"));
|
||||
function.end = (uint)json_hex_value(json_object_get(value, "end"));
|
||||
function.manual = Manual;
|
||||
|
||||
// Sanity check
|
||||
if(function.end < function.start)
|
||||
continue;
|
||||
|
||||
const uint key = ModHashFromName(function.mod);
|
||||
functions.insert(std::make_pair(ModuleRange(ModHashFromName(function.mod), Range(function.start, function.end)), function));
|
||||
*curFunction.mod = '\0';
|
||||
curFunction.start = (uint)json_hex_value(json_object_get(value, "start"));
|
||||
curFunction.end = (uint)json_hex_value(json_object_get(value, "end"));
|
||||
if(curFunction.end < curFunction.start)
|
||||
continue; //invalid function
|
||||
curFunction.manual = true;
|
||||
const uint key = modhashfromname(curFunction.mod);
|
||||
functions.insert(std::make_pair(ModuleRange(modhashfromname(curFunction.mod), Range(curFunction.start, curFunction.end)), curFunction));
|
||||
}
|
||||
};
|
||||
|
||||
const JSON jsonFunctions = json_object_get(Root, "functions");
|
||||
const JSON jsonAutoFunctions = json_object_get(Root, "autofunctions");
|
||||
|
||||
if(jsonFunctions)
|
||||
InsertFunctions(jsonFunctions, true);
|
||||
|
||||
if(jsonAutoFunctions)
|
||||
InsertFunctions(jsonAutoFunctions, false);
|
||||
}
|
||||
JSON jsonautofunctions = json_object_get(root, "autofunctions");
|
||||
if(jsonautofunctions)
|
||||
{
|
||||
size_t i;
|
||||
JSON value;
|
||||
json_array_foreach(jsonautofunctions, i, value)
|
||||
{
|
||||
FUNCTIONSINFO curFunction;
|
||||
const char* mod = json_string_value(json_object_get(value, "module"));
|
||||
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
|
||||
strcpy_s(curFunction.mod, mod);
|
||||
else
|
||||
*curFunction.mod = '\0';
|
||||
curFunction.start = (uint)json_hex_value(json_object_get(value, "start"));
|
||||
curFunction.end = (uint)json_hex_value(json_object_get(value, "end"));
|
||||
if(curFunction.end < curFunction.start)
|
||||
continue; //invalid function
|
||||
curFunction.manual = true;
|
||||
const uint key = modhashfromname(curFunction.mod);
|
||||
functions.insert(std::make_pair(ModuleRange(modhashfromname(curFunction.mod), Range(curFunction.start, curFunction.end)), curFunction));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FunctionEnum(FUNCTIONSINFO* List, size_t* Size)
|
||||
bool functionenum(FUNCTIONSINFO* functionlist, size_t* cbsize)
|
||||
{
|
||||
// CHECK: Exported function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
// If a list isn't passed and the size not requested, fail
|
||||
if(!List && !Size)
|
||||
if(!functionlist && !cbsize)
|
||||
return false;
|
||||
|
||||
SHARED_ACQUIRE(LockFunctions);
|
||||
|
||||
// Did the caller request the buffer size needed?
|
||||
if(Size)
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
if(!functionlist && cbsize)
|
||||
{
|
||||
*Size = functions.size() * sizeof(FUNCTIONSINFO);
|
||||
|
||||
if(!List)
|
||||
return true;
|
||||
*cbsize = functions.size() * sizeof(FUNCTIONSINFO);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fill out the buffer
|
||||
for(auto & itr : functions)
|
||||
int j = 0;
|
||||
for(FunctionsInfo::iterator i = functions.begin(); i != functions.end(); ++i, j++)
|
||||
{
|
||||
// Adjust for relative to virtual addresses
|
||||
uint moduleBase = ModBaseFromName(itr.second.mod);
|
||||
|
||||
*List = itr.second;
|
||||
List->start += moduleBase;
|
||||
List->end += moduleBase;
|
||||
|
||||
List++;
|
||||
functionlist[j] = i->second;
|
||||
uint modbase = modbasefromname(functionlist[j].mod);
|
||||
functionlist[j].start += modbase;
|
||||
functionlist[j].end += modbase;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FunctionClear()
|
||||
void functionclear()
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockFunctions);
|
||||
functions.clear();
|
||||
CriticalSectionLocker locker(LockFunctions);
|
||||
FunctionsInfo().swap(functions);
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#ifndef _FUNCTION_H
|
||||
#define _FUNCTION_H
|
||||
|
||||
#include "addrinfo.h"
|
||||
|
||||
|
@ -10,12 +11,14 @@ struct FUNCTIONSINFO
|
|||
bool manual;
|
||||
};
|
||||
|
||||
bool FunctionAdd(uint Start, uint End, bool Manual);
|
||||
bool FunctionGet(uint Address, uint* Start, uint* End);
|
||||
bool FunctionOverlaps(uint Start, uint End);
|
||||
bool FunctionDelete(uint Address);
|
||||
void FunctionDelRange(uint Start, uint End);
|
||||
void FunctionCacheSave(JSON Root);
|
||||
void FunctionCacheLoad(JSON Root);
|
||||
bool FunctionEnum(FUNCTIONSINFO* List, size_t* Size);
|
||||
void FunctionClear();
|
||||
bool functionadd(uint start, uint end, bool manual);
|
||||
bool functionget(uint addr, uint* start, uint* end);
|
||||
bool functionoverlaps(uint start, uint end);
|
||||
bool functiondel(uint addr);
|
||||
void functiondelrange(uint start, uint end);
|
||||
void functioncachesave(JSON root);
|
||||
void functioncacheload(JSON root);
|
||||
bool functionenum(FUNCTIONSINFO* functionlist, size_t* cbsize);
|
||||
void functionclear();
|
||||
|
||||
#endif //_FUNCTION_H
|
|
@ -158,7 +158,7 @@ CMDRESULT cbInstrMov(int argc, char* argv[])
|
|||
}
|
||||
//Check the destination
|
||||
uint dest;
|
||||
if(!valfromstring(argv[1], &dest) || !MemIsValidReadPtr(dest))
|
||||
if(!valfromstring(argv[1], &dest) || !memisvalidreadptr(fdProcessInfo->hProcess, dest))
|
||||
{
|
||||
dprintf("invalid destination \"%s\"\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
|
@ -175,7 +175,7 @@ CMDRESULT cbInstrMov(int argc, char* argv[])
|
|||
data[j] = res;
|
||||
}
|
||||
//Move data to destination
|
||||
if(!MemWrite((void*)dest, data, data.size(), 0))
|
||||
if(!memwrite(fdProcessInfo->hProcess, (void*)dest, data, data.size(), 0))
|
||||
{
|
||||
dprintf("failed to write to "fhex"\n", dest);
|
||||
return STATUS_ERROR;
|
||||
|
@ -294,7 +294,7 @@ CMDRESULT cbInstrCmt(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!CommentSet(addr, argv[2], true))
|
||||
if(!commentset(addr, argv[2], true))
|
||||
{
|
||||
dputs("error setting comment");
|
||||
return STATUS_ERROR;
|
||||
|
@ -312,7 +312,7 @@ CMDRESULT cbInstrCmtdel(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!CommentDelete(addr))
|
||||
if(!commentdel(addr))
|
||||
{
|
||||
dputs("error deleting comment");
|
||||
return STATUS_ERROR;
|
||||
|
@ -368,7 +368,7 @@ CMDRESULT cbInstrBookmarkSet(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!BookmarkSet(addr, true))
|
||||
if(!bookmarkset(addr, true))
|
||||
{
|
||||
dputs("failed to set bookmark!");
|
||||
return STATUS_ERROR;
|
||||
|
@ -387,7 +387,7 @@ CMDRESULT cbInstrBookmarkDel(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!BookmarkDelete(addr))
|
||||
if(!bookmarkdel(addr))
|
||||
{
|
||||
dputs("failed to delete bookmark!");
|
||||
return STATUS_ERROR;
|
||||
|
@ -454,7 +454,7 @@ CMDRESULT cbFunctionAdd(int argc, char* argv[])
|
|||
uint end = 0;
|
||||
if(!valfromstring(argv[1], &start, false) or !valfromstring(argv[2], &end, false))
|
||||
return STATUS_ERROR;
|
||||
if(!FunctionAdd(start, end, true))
|
||||
if(!functionadd(start, end, true))
|
||||
{
|
||||
dputs("failed to add function");
|
||||
return STATUS_ERROR;
|
||||
|
@ -474,7 +474,7 @@ CMDRESULT cbFunctionDel(int argc, char* argv[])
|
|||
uint addr = 0;
|
||||
if(!valfromstring(argv[1], &addr, false))
|
||||
return STATUS_ERROR;
|
||||
if(!FunctionDelete(addr))
|
||||
if(!functiondel(addr))
|
||||
{
|
||||
dputs("failed to delete function");
|
||||
return STATUS_ERROR;
|
||||
|
@ -1053,7 +1053,7 @@ CMDRESULT cbInstrCopystr(int argc, char* argv[])
|
|||
dprintf("invalid address \"%s\"!\n", argv[1]);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
if(!MemPatch((void*)addr, string, strlen(string), 0))
|
||||
if(!mempatch(fdProcessInfo->hProcess, (void*)addr, string, strlen(string), 0))
|
||||
{
|
||||
dputs("memwrite failed!");
|
||||
return STATUS_ERROR;
|
||||
|
@ -1084,14 +1084,14 @@ CMDRESULT cbInstrFind(int argc, char* argv[])
|
|||
if(pattern[len - 1] == '#')
|
||||
pattern[len - 1] = '\0';
|
||||
uint size = 0;
|
||||
uint base = MemFindBaseAddr(addr, &size, true);
|
||||
uint base = memfindbaseaddr(addr, &size, true);
|
||||
if(!base)
|
||||
{
|
||||
dprintf("invalid memory address "fhex"!\n", addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
Memory<unsigned char*> data(size, "cbInstrFind:data");
|
||||
if(!MemRead((void*)base, data, size, 0))
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)base, data, size, 0))
|
||||
{
|
||||
dputs("failed to read memory!");
|
||||
return STATUS_ERROR;
|
||||
|
@ -1136,14 +1136,14 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
|
|||
if(pattern[len - 1] == '#')
|
||||
pattern[len - 1] = '\0';
|
||||
uint size = 0;
|
||||
uint base = MemFindBaseAddr(addr, &size, true);
|
||||
uint base = memfindbaseaddr(addr, &size, true);
|
||||
if(!base)
|
||||
{
|
||||
dprintf("invalid memory address "fhex"!\n", addr);
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
Memory<unsigned char*> data(size, "cbInstrFindAll:data");
|
||||
if(!MemRead((void*)base, data, size, 0))
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)base, data, size, 0))
|
||||
{
|
||||
dputs("failed to read memory!");
|
||||
return STATUS_ERROR;
|
||||
|
@ -1192,7 +1192,7 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
|
|||
if(findData)
|
||||
{
|
||||
Memory<unsigned char*> printData(patternsize, "cbInstrFindAll:printData");
|
||||
MemRead((void*)result, printData, patternsize, 0);
|
||||
memread(fdProcessInfo->hProcess, (const void*)result, printData, patternsize, 0);
|
||||
for(int j = 0, k = 0; j < patternsize; j++)
|
||||
{
|
||||
if(j)
|
||||
|
@ -1270,14 +1270,14 @@ CMDRESULT cbInstrCommentList(int argc, char* argv[])
|
|||
GuiReferenceAddColumn(0, "Comment");
|
||||
GuiReferenceReloadData();
|
||||
size_t cbsize;
|
||||
CommentEnum(0, &cbsize);
|
||||
commentenum(0, &cbsize);
|
||||
if(!cbsize)
|
||||
{
|
||||
dputs("no comments");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Memory<COMMENTSINFO*> comments(cbsize, "cbInstrCommentList:comments");
|
||||
CommentEnum(comments, 0);
|
||||
commentenum(comments, 0);
|
||||
int count = (int)(cbsize / sizeof(COMMENTSINFO));
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -1339,14 +1339,14 @@ CMDRESULT cbInstrBookmarkList(int argc, char* argv[])
|
|||
GuiReferenceAddColumn(0, "Disassembly");
|
||||
GuiReferenceReloadData();
|
||||
size_t cbsize;
|
||||
BookmarkEnum(0, &cbsize);
|
||||
bookmarkenum(0, &cbsize);
|
||||
if(!cbsize)
|
||||
{
|
||||
dputs("no bookmarks");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Memory<BOOKMARKSINFO*> bookmarks(cbsize, "cbInstrBookmarkList:bookmarks");
|
||||
BookmarkEnum(bookmarks, 0);
|
||||
bookmarkenum(bookmarks, 0);
|
||||
int count = (int)(cbsize / sizeof(BOOKMARKSINFO));
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -1374,14 +1374,14 @@ CMDRESULT cbInstrFunctionList(int argc, char* argv[])
|
|||
GuiReferenceAddColumn(0, "Label/Comment");
|
||||
GuiReferenceReloadData();
|
||||
size_t cbsize;
|
||||
FunctionEnum(0, &cbsize);
|
||||
functionenum(0, &cbsize);
|
||||
if(!cbsize)
|
||||
{
|
||||
dputs("no functions");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Memory<FUNCTIONSINFO*> functions(cbsize, "cbInstrFunctionList:functions");
|
||||
FunctionEnum(functions, 0);
|
||||
functionenum(functions, 0);
|
||||
int count = (int)(cbsize / sizeof(FUNCTIONSINFO));
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -1400,7 +1400,7 @@ CMDRESULT cbInstrFunctionList(int argc, char* argv[])
|
|||
else
|
||||
{
|
||||
char comment[MAX_COMMENT_SIZE] = "";
|
||||
if(CommentGet(functions[i].start, comment))
|
||||
if(commentget(functions[i].start, comment))
|
||||
GuiReferenceSetCellContent(i, 3, comment);
|
||||
}
|
||||
}
|
||||
|
@ -1446,7 +1446,7 @@ CMDRESULT cbInstrLoopList(int argc, char* argv[])
|
|||
else
|
||||
{
|
||||
char comment[MAX_COMMENT_SIZE] = "";
|
||||
if(CommentGet(loops[i].start, comment))
|
||||
if(commentget(loops[i].start, comment))
|
||||
GuiReferenceSetCellContent(i, 3, comment);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
#include "memory.h"
|
||||
#include "debugger.h"
|
||||
|
||||
typedef std::unordered_map<uint, LABELSINFO> LabelsInfo;
|
||||
typedef std::map<uint, LABELSINFO> LabelsInfo;
|
||||
|
||||
static LabelsInfo labels;
|
||||
|
||||
bool labelset(uint addr, const char* text, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or !MemIsValidReadPtr(addr) or !text or strlen(text) >= MAX_LABEL_SIZE - 1 or strstr(text, "&"))
|
||||
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or strlen(text) >= MAX_LABEL_SIZE - 1 or strstr(text, "&"))
|
||||
return false;
|
||||
if(!*text) //NOTE: delete when there is no text
|
||||
{
|
||||
|
@ -20,11 +20,11 @@ bool labelset(uint addr, const char* text, bool manual)
|
|||
LABELSINFO label;
|
||||
label.manual = manual;
|
||||
strcpy_s(label.text, text);
|
||||
ModNameFromAddr(addr, label.mod, true);
|
||||
label.addr = addr - ModBaseFromAddr(addr);
|
||||
uint key = ModHashFromAddr(addr);
|
||||
modnamefromaddr(addr, label.mod, true);
|
||||
label.addr = addr - modbasefromaddr(addr);
|
||||
uint key = modhashfromva(addr);
|
||||
CriticalSectionLocker locker(LockLabels);
|
||||
if(!labels.insert(std::make_pair(ModHashFromAddr(key), label)).second) //already present
|
||||
if(!labels.insert(std::make_pair(modhashfromva(key), label)).second) //already present
|
||||
labels[key] = label;
|
||||
return true;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ bool labelfromstring(const char* text, uint* addr)
|
|||
if(!strcmp(i->second.text, text))
|
||||
{
|
||||
if(addr)
|
||||
*addr = i->second.addr + ModBaseFromName(i->second.mod);
|
||||
*addr = i->second.addr + modbasefromname(i->second.mod);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ bool labelget(uint addr, char* text)
|
|||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockLabels);
|
||||
const LabelsInfo::iterator found = labels.find(ModHashFromAddr(addr));
|
||||
const LabelsInfo::iterator found = labels.find(modhashfromva(addr));
|
||||
if(found == labels.end()) //not found
|
||||
return false;
|
||||
if(text)
|
||||
|
@ -64,7 +64,7 @@ bool labeldel(uint addr)
|
|||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockLabels);
|
||||
return (labels.erase(ModHashFromAddr(addr)) > 0);
|
||||
return (labels.erase(modhashfromva(addr)) > 0);
|
||||
}
|
||||
|
||||
void labeldelrange(uint start, uint end)
|
||||
|
@ -72,8 +72,8 @@ void labeldelrange(uint start, uint end)
|
|||
if(!DbgIsDebugging())
|
||||
return;
|
||||
bool bDelAll = (start == 0 && end == ~0); //0x00000000-0xFFFFFFFF
|
||||
uint modbase = ModBaseFromAddr(start);
|
||||
if(modbase != ModBaseFromAddr(end))
|
||||
uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end))
|
||||
return;
|
||||
start -= modbase;
|
||||
end -= modbase;
|
||||
|
@ -146,7 +146,7 @@ void labelcacheload(JSON root)
|
|||
for(int i = 0; i < len; i++)
|
||||
if(curLabel.text[i] == '&')
|
||||
curLabel.text[i] = ' ';
|
||||
const uint key = ModHashFromName(curLabel.mod) + curLabel.addr;
|
||||
const uint key = modhashfromname(curLabel.mod) + curLabel.addr;
|
||||
labels.insert(std::make_pair(key, curLabel));
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ void labelcacheload(JSON root)
|
|||
strcpy_s(curLabel.text, text);
|
||||
else
|
||||
continue; //skip
|
||||
const uint key = ModHashFromName(curLabel.mod) + curLabel.addr;
|
||||
const uint key = modhashfromname(curLabel.mod) + curLabel.addr;
|
||||
labels.insert(std::make_pair(key, curLabel));
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ bool labelenum(LABELSINFO* labellist, size_t* cbsize)
|
|||
for(LabelsInfo::iterator i = labels.begin(); i != labels.end(); ++i, j++)
|
||||
{
|
||||
labellist[j] = i->second;
|
||||
labellist[j].addr += ModBaseFromName(labellist[j].mod);
|
||||
labellist[j].addr += modbasefromname(labellist[j].mod);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -10,16 +10,16 @@ static LoopsInfo loops;
|
|||
|
||||
bool loopadd(uint start, uint end, bool manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or end < start or !MemIsValidReadPtr(start))
|
||||
if(!DbgIsDebugging() or end < start or !memisvalidreadptr(fdProcessInfo->hProcess, start))
|
||||
return false;
|
||||
const uint modbase = ModBaseFromAddr(start);
|
||||
if(modbase != ModBaseFromAddr(end)) //the function boundaries are not in the same mem page
|
||||
const uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end)) //the function boundaries are not in the same mem page
|
||||
return false;
|
||||
int finaldepth;
|
||||
if(loopoverlaps(0, start, end, &finaldepth)) //loop cannot overlap another loop
|
||||
return false;
|
||||
LOOPSINFO loop;
|
||||
ModNameFromAddr(start, loop.mod, true);
|
||||
modnamefromaddr(start, loop.mod, true);
|
||||
loop.start = start - modbase;
|
||||
loop.end = end - modbase;
|
||||
loop.depth = finaldepth;
|
||||
|
@ -29,7 +29,7 @@ bool loopadd(uint start, uint end, bool manual)
|
|||
loop.parent = 0;
|
||||
loop.manual = manual;
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
loops.insert(std::make_pair(DepthModuleRange(finaldepth, ModuleRange(ModHashFromAddr(modbase), Range(loop.start, loop.end))), loop));
|
||||
loops.insert(std::make_pair(DepthModuleRange(finaldepth, ModuleRange(modhashfromva(modbase), Range(loop.start, loop.end))), loop));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -38,9 +38,9 @@ bool loopget(int depth, uint addr, uint* start, uint* end)
|
|||
{
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
const uint modbase = ModBaseFromAddr(addr);
|
||||
const uint modbase = modbasefromaddr(addr);
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
LoopsInfo::iterator found = loops.find(DepthModuleRange(depth, ModuleRange(ModHashFromAddr(modbase), Range(addr - modbase, addr - modbase))));
|
||||
LoopsInfo::iterator found = loops.find(DepthModuleRange(depth, ModuleRange(modhashfromva(modbase), Range(addr - modbase, addr - modbase))));
|
||||
if(found == loops.end()) //not found
|
||||
return false;
|
||||
if(start)
|
||||
|
@ -56,10 +56,10 @@ bool loopoverlaps(int depth, uint start, uint end, int* finaldepth)
|
|||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
const uint modbase = ModBaseFromAddr(start);
|
||||
const uint modbase = modbasefromaddr(start);
|
||||
uint curStart = start - modbase;
|
||||
uint curEnd = end - modbase;
|
||||
const uint key = ModHashFromAddr(modbase);
|
||||
const uint key = modhashfromva(modbase);
|
||||
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
|
||||
|
@ -145,7 +145,7 @@ void loopcacheload(JSON root)
|
|||
if(curLoop.end < curLoop.start)
|
||||
continue; //invalid loop
|
||||
curLoop.manual = true;
|
||||
loops.insert(std::make_pair(DepthModuleRange(curLoop.depth, ModuleRange(ModHashFromName(curLoop.mod), Range(curLoop.start, curLoop.end))), curLoop));
|
||||
loops.insert(std::make_pair(DepthModuleRange(curLoop.depth, ModuleRange(modhashfromname(curLoop.mod), Range(curLoop.start, curLoop.end))), curLoop));
|
||||
}
|
||||
}
|
||||
JSON jsonautoloops = json_object_get(root, "autoloops");
|
||||
|
@ -168,45 +168,36 @@ void loopcacheload(JSON root)
|
|||
if(curLoop.end < curLoop.start)
|
||||
continue; //invalid loop
|
||||
curLoop.manual = false;
|
||||
loops.insert(std::make_pair(DepthModuleRange(curLoop.depth, ModuleRange(ModHashFromName(curLoop.mod), Range(curLoop.start, curLoop.end))), curLoop));
|
||||
loops.insert(std::make_pair(DepthModuleRange(curLoop.depth, ModuleRange(modhashfromname(curLoop.mod), Range(curLoop.start, curLoop.end))), curLoop));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool loopenum(LOOPSINFO* List, size_t* Size)
|
||||
bool loopenum(LOOPSINFO* looplist, size_t* cbsize)
|
||||
{
|
||||
// If looplist or size is not requested, fail
|
||||
if(!List && !Size)
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
SHARED_ACQUIRE(LockLoops);
|
||||
|
||||
// See if the caller requested an output size
|
||||
if(Size)
|
||||
if(!looplist && !cbsize)
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
if(!looplist && cbsize)
|
||||
{
|
||||
*Size = loops.size() * sizeof(LOOPSINFO);
|
||||
|
||||
if(!List)
|
||||
return true;
|
||||
*cbsize = loops.size() * sizeof(LOOPSINFO);
|
||||
return true;
|
||||
}
|
||||
|
||||
for(auto itr = loops.begin(); itr != loops.end(); itr++)
|
||||
int j = 0;
|
||||
for(LoopsInfo::iterator i = loops.begin(); i != loops.end(); ++i, j++)
|
||||
{
|
||||
*List = itr->second;
|
||||
|
||||
// Adjust the offset to a real virtual address
|
||||
uint modbase = ModBaseFromName(List->mod);
|
||||
List->start += modbase;
|
||||
List->end += modbase;
|
||||
|
||||
List++;
|
||||
looplist[j] = i->second;
|
||||
uint modbase = modbasefromname(looplist[j].mod);
|
||||
looplist[j].start += modbase;
|
||||
looplist[j].end += modbase;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void loopclear()
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockLoops);
|
||||
loops.clear();
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
LoopsInfo().swap(loops);
|
||||
}
|
|
@ -1,19 +1,12 @@
|
|||
#include "math.h"
|
||||
#include "value.h"
|
||||
|
||||
enum BRACKET_TYPE
|
||||
{
|
||||
BRACKET_FREE,
|
||||
BRACKET_OPEN,
|
||||
BRACKET_CLOSE,
|
||||
};
|
||||
|
||||
struct BRACKET_PAIR
|
||||
{
|
||||
int openpos;
|
||||
int closepos;
|
||||
int layer;
|
||||
BRACKET_TYPE isset;
|
||||
int isset; //0=free, 1=open, 2=close
|
||||
};
|
||||
|
||||
struct EXPRESSION
|
||||
|
@ -25,8 +18,7 @@ struct EXPRESSION
|
|||
|
||||
/*
|
||||
operator precedence
|
||||
0 (INVALID/NONE)
|
||||
1 ( ) (PARENTHESIS)
|
||||
1 ( )
|
||||
2 ~ (NOT)
|
||||
3 * / % (MUL DIV)
|
||||
4 + - (ADD SUB)
|
||||
|
@ -35,21 +27,18 @@ operator precedence
|
|||
7 ^ (XOR)
|
||||
8 | (OR)
|
||||
*/
|
||||
|
||||
int mathisoperator(char ch)
|
||||
{
|
||||
//
|
||||
// The lower the number, the higher the priority.
|
||||
// Zero indicates no operator was found.
|
||||
//
|
||||
if(ch == '(' || ch == ')')
|
||||
if(ch == '(' or ch == ')')
|
||||
return 1;
|
||||
else if(ch == '~')
|
||||
return 2;
|
||||
else if(ch == '*' || ch == '`' || ch == '/' || ch == '%')
|
||||
else if(ch == '*' or ch == '`' or ch == '/' or ch == '%')
|
||||
return 3;
|
||||
else if(ch == '+' || ch == '-')
|
||||
else if(ch == '+' or ch == '-')
|
||||
return 4;
|
||||
else if(ch == '<' || ch == '>')
|
||||
else if(ch == '<' or ch == '>')
|
||||
return 5;
|
||||
else if(ch == '&')
|
||||
return 6;
|
||||
|
@ -57,7 +46,6 @@ int mathisoperator(char ch)
|
|||
return 7;
|
||||
else if(ch == '|')
|
||||
return 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -69,13 +57,10 @@ void mathformat(char* text)
|
|||
{
|
||||
int len = (int)strlen(text);
|
||||
Memory<char*> temp(len + 1, "mathformat:temp");
|
||||
|
||||
for (int i = 0, j = 0; i < len; i++)
|
||||
{
|
||||
if (mathisoperator(text[i]) < 3 || text[i] != text[i + 1])
|
||||
j += sprintf(temp + j, "%c", text[i]);
|
||||
}
|
||||
|
||||
memset(temp, 0, len + 1);
|
||||
for(int i = 0, j = 0; i < len; i++)
|
||||
if(mathisoperator(text[i]) < 3 or text[i] != text[i + 1])
|
||||
j += sprintf(temp + j, "%c", text[i]);
|
||||
strcpy(text, temp);
|
||||
}
|
||||
|
||||
|
@ -84,138 +69,172 @@ void mathformat(char* text)
|
|||
*/
|
||||
bool mathcontains(const char* text)
|
||||
{
|
||||
// Skip negative values
|
||||
if(*text == '-')
|
||||
if(*text == '-') //ignore negative values
|
||||
text++;
|
||||
|
||||
// Search the entire string looking for a math operator
|
||||
for (; text[0] != '\0'; text++)
|
||||
{
|
||||
if (mathisoperator(text[0]))
|
||||
return true;
|
||||
}
|
||||
|
||||
int len = (int)strlen(text);
|
||||
for(int i = 0; i < len; i++)
|
||||
if(mathisoperator(text[i]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef __MINGW64__
|
||||
inline unsigned long long umulhi(unsigned long long x, unsigned long long y)
|
||||
static inline unsigned long long umulhi(unsigned long long x, unsigned long long y)
|
||||
{
|
||||
return (unsigned long long)(((__uint128_t)x * y) >> 64);
|
||||
}
|
||||
|
||||
inline long long mulhi(long long x, long long y)
|
||||
static inline long long mulhi(long long x, long long y)
|
||||
{
|
||||
return (long long)(((__int128_t)x * y) >> 64);
|
||||
}
|
||||
#elif _WIN64
|
||||
#include <intrin.h>
|
||||
inline unsigned long long umulhi(unsigned long long x, unsigned long long y)
|
||||
static inline unsigned long long umulhi(unsigned long long x, unsigned long long y)
|
||||
{
|
||||
unsigned __int64 res;
|
||||
_umul128(x, y, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline long long mulhi(long long x, long long y)
|
||||
static inline long long mulhi(long long x, long long y)
|
||||
{
|
||||
__int64 res;
|
||||
_mul128(x, y, &res);
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
inline unsigned int umulhi(unsigned int x, unsigned int y)
|
||||
static inline unsigned int umulhi(unsigned int x, unsigned int y)
|
||||
{
|
||||
return (unsigned int)(((unsigned long long)x * y) >> 32);
|
||||
}
|
||||
|
||||
inline int mulhi(int x, int y)
|
||||
static inline int mulhi(int x, int y)
|
||||
{
|
||||
return (int)(((long long)x * y) >> 32);
|
||||
}
|
||||
#endif //__MINGW64__
|
||||
|
||||
template<typename T>
|
||||
bool MathDoOperation(char op, T left, T right, T* result)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case '*':
|
||||
*result = left * right;
|
||||
return true;
|
||||
case '`':
|
||||
*result = umulhi(left, right);
|
||||
return true;
|
||||
case '/':
|
||||
if (right)
|
||||
{
|
||||
*result = left / right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case '%':
|
||||
if (right)
|
||||
{
|
||||
*result = left % right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case '+':
|
||||
*result = left + right;
|
||||
return true;
|
||||
case '-':
|
||||
*result = left - right;
|
||||
return true;
|
||||
case '<':
|
||||
*result = left << right;
|
||||
return true;
|
||||
case '>':
|
||||
*result = left >> right;
|
||||
return true;
|
||||
case '&':
|
||||
*result = left & right;
|
||||
return true;
|
||||
case '^':
|
||||
*result = left ^ right;
|
||||
return true;
|
||||
case '|':
|
||||
*result = left | right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mathdounsignedoperation(char op, uint left, uint right, uint* result)
|
||||
{
|
||||
return MathDoOperation<uint>(op, left, right, result);
|
||||
switch(op)
|
||||
{
|
||||
case '*':
|
||||
*result = left * right;
|
||||
return true;
|
||||
case '`':
|
||||
*result = umulhi(left, right);
|
||||
return true;
|
||||
case '/':
|
||||
if(right)
|
||||
{
|
||||
*result = left / right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case '%':
|
||||
if(right)
|
||||
{
|
||||
*result = left % right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case '+':
|
||||
*result = left + right;
|
||||
return true;
|
||||
case '-':
|
||||
*result = left - right;
|
||||
return true;
|
||||
case '<':
|
||||
*result = left << right;
|
||||
return true;
|
||||
case '>':
|
||||
*result = left >> right;
|
||||
return true;
|
||||
case '&':
|
||||
*result = left & right;
|
||||
return true;
|
||||
case '^':
|
||||
*result = left ^ right;
|
||||
return true;
|
||||
case '|':
|
||||
*result = left | right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mathdosignedoperation(char op, sint left, sint right, sint* result)
|
||||
{
|
||||
return MathDoOperation<sint>(op, left, right, result);
|
||||
switch(op)
|
||||
{
|
||||
case '*':
|
||||
*result = left * right;
|
||||
return true;
|
||||
case '`':
|
||||
*result = mulhi(left, right);
|
||||
return true;
|
||||
case '/':
|
||||
if(right)
|
||||
{
|
||||
*result = left / right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case '%':
|
||||
if(right)
|
||||
{
|
||||
*result = left % right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case '+':
|
||||
*result = left + right;
|
||||
return true;
|
||||
case '-':
|
||||
*result = left - right;
|
||||
return true;
|
||||
case '<':
|
||||
*result = left << right;
|
||||
return true;
|
||||
case '>':
|
||||
*result = left >> right;
|
||||
return true;
|
||||
case '&':
|
||||
*result = left & right;
|
||||
return true;
|
||||
case '^':
|
||||
*result = left ^ right;
|
||||
return true;
|
||||
case '|':
|
||||
*result = left | right;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void fillpair(EXPRESSION* expstruct, int pos, int layer)
|
||||
static void fillpair(EXPRESSION* expstruct, int pos, int layer)
|
||||
{
|
||||
for(int i = 0; i < expstruct->total_pairs; i++)
|
||||
{
|
||||
if(expstruct->pairs[i].isset == BRACKET_FREE)
|
||||
if(!expstruct->pairs[i].isset)
|
||||
{
|
||||
expstruct->pairs[i].layer = layer;
|
||||
expstruct->pairs[i].openpos = pos;
|
||||
expstruct->pairs[i].isset = BRACKET_OPEN;
|
||||
expstruct->pairs[i].layer = layer;
|
||||
expstruct->pairs[i].openpos = pos;
|
||||
expstruct->pairs[i].isset = 1;
|
||||
break;
|
||||
}
|
||||
else if(expstruct->pairs[i].layer == layer && expstruct->pairs[i].isset == BRACKET_OPEN)
|
||||
else if(expstruct->pairs[i].layer == layer and expstruct->pairs[i].isset == 1)
|
||||
{
|
||||
expstruct->pairs[i].closepos = pos;
|
||||
expstruct->pairs[i].isset = BRACKET_CLOSE;
|
||||
expstruct->pairs[i].closepos = pos;
|
||||
expstruct->pairs[i].isset = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int matchpairs(EXPRESSION* expstruct, char* expression, int endlayer)
|
||||
|
||||
static int matchpairs(EXPRESSION* expstruct, char* expression, int endlayer)
|
||||
{
|
||||
int layer = endlayer;
|
||||
int len = (int)strlen(expression);
|
||||
|
@ -243,7 +262,7 @@ int matchpairs(EXPRESSION* expstruct, char* expression, int endlayer)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int expressionformat(char* exp)
|
||||
static int expressionformat(char* exp)
|
||||
{
|
||||
int len = (int)strlen(exp);
|
||||
int open = 0;
|
||||
|
@ -266,36 +285,35 @@ int expressionformat(char* exp)
|
|||
return open;
|
||||
}
|
||||
|
||||
void adjustpairs(EXPRESSION* exps, int cur_open, int cur_close, int cur_len, int new_len)
|
||||
static void adjustpairs(EXPRESSION* exps, int cur_open, int cur_close, int cur_len, int new_len)
|
||||
{
|
||||
for(int i = 0; i < exps->total_pairs; i++)
|
||||
{
|
||||
if(exps->pairs[i].openpos > cur_open)
|
||||
exps->pairs[i].openpos += new_len - cur_len;
|
||||
|
||||
if(exps->pairs[i].closepos > cur_close)
|
||||
exps->pairs[i].closepos += new_len - cur_len;
|
||||
}
|
||||
}
|
||||
|
||||
bool printlayer(char* exp, EXPRESSION* exps, int layer, bool silent, bool baseonly)
|
||||
static bool printlayer(char* exp, EXPRESSION* exps, int layer, bool silent, bool baseonly)
|
||||
{
|
||||
for(int i = 0; i < exps->total_pairs; i++)
|
||||
{
|
||||
if(exps->pairs[i].layer == layer)
|
||||
{
|
||||
int open = exps->pairs[i].openpos;
|
||||
int close = exps->pairs[i].closepos;
|
||||
int len = close - open;
|
||||
char temp[256] = "";
|
||||
char backup[256] = "";
|
||||
|
||||
char temp[256];
|
||||
int open = exps->pairs[i].openpos;
|
||||
int close = exps->pairs[i].closepos;
|
||||
int len = close - open;
|
||||
strncpy(temp, exp + open + 1, len - 1);
|
||||
|
||||
char backup[256];
|
||||
strcpy_s(backup, exp + open + len + 1);
|
||||
|
||||
uint value;
|
||||
if(!mathfromstring(temp, &value, silent, baseonly, nullptr, nullptr))
|
||||
if(!mathfromstring(temp, &value, silent, baseonly, 0, 0))
|
||||
return false;
|
||||
|
||||
adjustpairs(exps, open, close, len + 1, sprintf(exp + open, "%"fext"X", value));
|
||||
|
@ -305,41 +323,32 @@ bool printlayer(char* exp, EXPRESSION* exps, int layer, bool silent, bool baseon
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mathhandlebrackets(char* expression, bool silent, bool baseonly)
|
||||
{
|
||||
int totalPairs = expressionformat(expression);
|
||||
|
||||
if(totalPairs == -1)
|
||||
EXPRESSION expstruct;
|
||||
expstruct.expression = expression;
|
||||
int total_pairs = expressionformat(expression);
|
||||
if(total_pairs == -1)
|
||||
return false;
|
||||
else if(!totalPairs)
|
||||
else if(!total_pairs)
|
||||
return true;
|
||||
expstruct.total_pairs = total_pairs;
|
||||
|
||||
Memory<BRACKET_PAIR*> pairs(totalPairs * sizeof(BRACKET_PAIR), "mathhandlebrackets:pairs");
|
||||
|
||||
EXPRESSION expStruct;
|
||||
expStruct.expression = expression;
|
||||
expStruct.total_pairs = totalPairs;
|
||||
expStruct.pairs = pairs;
|
||||
|
||||
matchpairs(&expStruct, expression, 0);
|
||||
|
||||
Memory<BRACKET_PAIR*> pairs(expstruct.total_pairs * sizeof(BRACKET_PAIR), "mathhandlebrackets:expstruct.pairs");
|
||||
expstruct.pairs = pairs;
|
||||
memset(expstruct.pairs, 0, expstruct.total_pairs * sizeof(BRACKET_PAIR));
|
||||
matchpairs(&expstruct, expression, 0);
|
||||
int deepest = 0;
|
||||
for (int i = 0; i < expStruct.total_pairs; i++)
|
||||
{
|
||||
if (expStruct.pairs[i].layer > deepest)
|
||||
deepest = expStruct.pairs[i].layer;
|
||||
}
|
||||
|
||||
for (int i = deepest; i > 0; i--)
|
||||
{
|
||||
if (!printlayer(expression, &expStruct, i, silent, baseonly))
|
||||
return false;
|
||||
}
|
||||
for(int i = 0; i < expstruct.total_pairs; i++)
|
||||
if(expstruct.pairs[i].layer > deepest)
|
||||
deepest = expstruct.pairs[i].layer;
|
||||
|
||||
for(int i = deepest; i > 0; i--)
|
||||
if(!printlayer(expression, &expstruct, i, silent, baseonly))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -370,6 +379,8 @@ bool mathfromstring(const char* string, uint* value, bool silent, bool baseonly,
|
|||
return valfromstring(string, value, silent, baseonly, value_size, isvar, 0);
|
||||
Memory<char*> strleft(len + 1 + negative, "mathfromstring:strleft");
|
||||
Memory<char*> strright(len + 1, "mathfromstring:strright");
|
||||
memset(strleft, 0, len + 1);
|
||||
memset(strright, 0, len + 1);
|
||||
strncpy(strleft, string - negative, highestop_pos + negative);
|
||||
strcpy(strright, string + highestop_pos + 1);
|
||||
strcpy(strleft, StringUtils::Trim(strleft).c_str());
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#ifndef _MATH_H
|
||||
#define _MATH_H
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
|
@ -8,4 +9,6 @@ bool mathcontains(const char* text);
|
|||
bool mathhandlebrackets(char* expression, bool silent, bool baseonly);
|
||||
bool mathfromstring(const char* string, uint* value, bool silent, bool baseonly, int* value_size, bool* isvar);
|
||||
bool mathdounsignedoperation(char op, uint left, uint right, uint* result);
|
||||
bool mathdosignedoperation(char op, sint left, sint right, sint* result);
|
||||
bool mathdosignedoperation(char op, sint left, sint right, sint* result);
|
||||
|
||||
#endif // _MATH_H
|
||||
|
|
|
@ -5,16 +5,10 @@
|
|||
#include "threading.h"
|
||||
#include "module.h"
|
||||
|
||||
#define PAGE_SHIFT (12)
|
||||
#define PAGE_SIZE (4096)
|
||||
#define PAGE_ALIGN(Va) ((ULONG_PTR)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1)))
|
||||
#define BYTES_TO_PAGES(Size) (((Size) >> PAGE_SHIFT) + (((Size) & (PAGE_SIZE - 1)) != 0))
|
||||
#define ROUND_TO_PAGES(Size) (((ULONG_PTR)(Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
|
||||
|
||||
MemoryMap memoryPages;
|
||||
bool bListAllPages = false;
|
||||
|
||||
void MemUpdateMap(HANDLE hProcess)
|
||||
void memupdatemap(HANDLE hProcess)
|
||||
{
|
||||
CriticalSectionLocker locker(LockMemoryPages);
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
|
@ -33,7 +27,7 @@ void MemUpdateMap(HANDLE hProcess)
|
|||
curAllocationBase = (uint)mbi.AllocationBase;
|
||||
MEMPAGE curPage;
|
||||
*curPage.info = 0;
|
||||
ModNameFromAddr(MyAddress, curPage.info, true);
|
||||
modnamefromaddr(MyAddress, curPage.info, true);
|
||||
memcpy(&curPage.mbi, &mbi, sizeof(mbi));
|
||||
pageVector.push_back(curPage);
|
||||
}
|
||||
|
@ -56,11 +50,11 @@ void MemUpdateMap(HANDLE hProcess)
|
|||
if(!pageVector.at(i).info[0] || (scmp(curMod, pageVector.at(i).info) && !bListAllPages)) //there is a module
|
||||
continue; //skip non-modules
|
||||
strcpy(curMod, pageVector.at(i).info);
|
||||
uint base = ModBaseFromName(pageVector.at(i).info);
|
||||
uint base = modbasefromname(pageVector.at(i).info);
|
||||
if(!base)
|
||||
continue;
|
||||
std::vector<MODSECTIONINFO> sections;
|
||||
if(!ModSectionsFromAddr(base, §ions))
|
||||
if(!modsectionsfromaddr(base, §ions))
|
||||
continue;
|
||||
int SectionNumber = (int)sections.size();
|
||||
if(!SectionNumber) //no sections = skip
|
||||
|
@ -129,187 +123,102 @@ void MemUpdateMap(HANDLE hProcess)
|
|||
}
|
||||
}
|
||||
|
||||
uint MemFindBaseAddr(uint addr, uint* Size, bool refresh)
|
||||
uint memfindbaseaddr(uint addr, uint* size, bool refresh)
|
||||
{
|
||||
// Update the memory map if needed
|
||||
if(refresh)
|
||||
MemUpdateMap(fdProcessInfo->hProcess);
|
||||
|
||||
SHARED_ACQUIRE(LockMemoryPages);
|
||||
|
||||
// Search for the memory page address
|
||||
auto found = memoryPages.find(std::make_pair(addr, addr));
|
||||
|
||||
memupdatemap(fdProcessInfo->hProcess); //update memory map
|
||||
CriticalSectionLocker locker(LockMemoryPages);
|
||||
MemoryMap::iterator found = memoryPages.find(std::make_pair(addr, addr));
|
||||
if(found == memoryPages.end())
|
||||
return 0;
|
||||
|
||||
// Return the allocation region size when requested
|
||||
if(Size)
|
||||
*Size = found->second.mbi.RegionSize;
|
||||
|
||||
if(size)
|
||||
*size = found->second.mbi.RegionSize;
|
||||
return found->first.first;
|
||||
}
|
||||
|
||||
bool MemRead(void* BaseAddress, void* Buffer, SIZE_T Size, SIZE_T* NumberOfBytesRead)
|
||||
bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead)
|
||||
{
|
||||
// Fast fail if address is invalid
|
||||
if (!MemIsCanonicalAddress((uint)BaseAddress))
|
||||
return false;
|
||||
|
||||
// Buffer must be supplied and size must be greater than 0
|
||||
if (!Buffer || Size <= 0)
|
||||
return false;
|
||||
|
||||
// If the 'bytes read' parameter is null, use a temp
|
||||
SIZE_T bytesReadTemp = 0;
|
||||
|
||||
if (!NumberOfBytesRead)
|
||||
NumberOfBytesRead = &bytesReadTemp;
|
||||
|
||||
// Normal single-call read
|
||||
bool ret = MemoryReadSafe(fdProcessInfo->hProcess, BaseAddress, Buffer, Size, NumberOfBytesRead);
|
||||
|
||||
if (ret && *NumberOfBytesRead == Size)
|
||||
return true;
|
||||
|
||||
// Read page-by-page (Skip if only 1 page exists)
|
||||
// If (SIZE > PAGE_SIZE) or (ADDRESS exceeds boundary), multiple reads will be needed
|
||||
SIZE_T pageCount = BYTES_TO_PAGES(Size);
|
||||
|
||||
if (pageCount > 1)
|
||||
{
|
||||
// Determine the number of bytes between ADDRESS and the next page
|
||||
uint offset = 0;
|
||||
uint readBase = (uint)BaseAddress;
|
||||
uint readSize = ROUND_TO_PAGES(readBase) - readBase;
|
||||
|
||||
// Reset the bytes read count
|
||||
*NumberOfBytesRead = 0;
|
||||
|
||||
for (SIZE_T i = 0; i < pageCount; i++)
|
||||
{
|
||||
SIZE_T bytesRead = 0;
|
||||
|
||||
if (MemoryReadSafe(fdProcessInfo->hProcess, (PVOID)readBase, ((PBYTE)Buffer + offset), readSize, &bytesRead))
|
||||
*NumberOfBytesRead += bytesRead;
|
||||
|
||||
offset += readSize;
|
||||
readBase += readSize;
|
||||
|
||||
Size -= readSize;
|
||||
readSize = (Size > PAGE_SIZE) ? PAGE_SIZE : Size;
|
||||
}
|
||||
}
|
||||
|
||||
SetLastError(ERROR_PARTIAL_COPY);
|
||||
return (*NumberOfBytesRead > 0);
|
||||
}
|
||||
|
||||
bool MemWrite(void* BaseAddress, void* Buffer, SIZE_T Size, SIZE_T* NumberOfBytesWritten)
|
||||
{
|
||||
// Fast fail if address is invalid
|
||||
if (!MemIsCanonicalAddress((uint)BaseAddress))
|
||||
return false;
|
||||
|
||||
// Buffer must be supplied and size must be greater than 0
|
||||
if(!Buffer || Size <= 0)
|
||||
if(!hProcess or !lpBaseAddress or !lpBuffer or !nSize) //generic failures
|
||||
return false;
|
||||
|
||||
// If the 'bytes written' parameter is null, use a temp
|
||||
SIZE_T bytesWrittenTemp = 0;
|
||||
|
||||
if(!NumberOfBytesWritten)
|
||||
NumberOfBytesWritten = &bytesWrittenTemp;
|
||||
|
||||
// Try a regular WriteProcessMemory call
|
||||
bool ret = MemoryWriteSafe(fdProcessInfo->hProcess, BaseAddress, Buffer, Size, NumberOfBytesWritten);
|
||||
|
||||
if(ret && * NumberOfBytesWritten == Size)
|
||||
return true;
|
||||
|
||||
// Write page-by-page (Skip if only 1 page exists)
|
||||
// See: MemRead
|
||||
SIZE_T pageCount = BYTES_TO_PAGES(Size);
|
||||
|
||||
if (pageCount > 1)
|
||||
{
|
||||
// Determine the number of bytes between ADDRESS and the next page
|
||||
uint offset = 0;
|
||||
uint writeBase = (uint)BaseAddress;
|
||||
uint writeSize = ROUND_TO_PAGES(writeBase) - writeBase;
|
||||
|
||||
// Reset the bytes read count
|
||||
*NumberOfBytesWritten = 0;
|
||||
|
||||
for (SIZE_T i = 0; i < pageCount; i++)
|
||||
{
|
||||
SIZE_T bytesWritten = 0;
|
||||
|
||||
if (MemoryWriteSafe(fdProcessInfo->hProcess, (PVOID)writeBase, ((PBYTE)Buffer + offset), writeSize, &bytesWritten))
|
||||
*NumberOfBytesWritten += bytesWritten;
|
||||
|
||||
offset += writeSize;
|
||||
writeBase += writeSize;
|
||||
|
||||
Size -= writeSize;
|
||||
writeSize = (Size > PAGE_SIZE) ? PAGE_SIZE : Size;
|
||||
}
|
||||
}
|
||||
|
||||
SetLastError(ERROR_PARTIAL_COPY);
|
||||
return (*NumberOfBytesWritten > 0);
|
||||
}
|
||||
|
||||
bool MemPatch(void* BaseAddress, void* Buffer, SIZE_T Size, SIZE_T* NumberOfBytesWritten)
|
||||
{
|
||||
// Buffer and size must be valid
|
||||
if(!Buffer || Size <= 0)
|
||||
return false;
|
||||
|
||||
// Allocate the memory
|
||||
Memory<unsigned char*> oldData(Size, "mempatch:oldData");
|
||||
|
||||
if(!MemRead(BaseAddress, oldData, Size, nullptr))
|
||||
SIZE_T read = 0;
|
||||
DWORD oldprotect = 0;
|
||||
bool ret = MemoryReadSafe(hProcess, (void*)lpBaseAddress, lpBuffer, nSize, &read); //try 'normal' RPM
|
||||
if(ret and read == nSize) //'normal' RPM worked!
|
||||
{
|
||||
// If no memory can be read, no memory can be written. Fail out
|
||||
// of this function.
|
||||
return false;
|
||||
if(lpNumberOfBytesRead)
|
||||
*lpNumberOfBytesRead = read;
|
||||
return true;
|
||||
}
|
||||
|
||||
for(SIZE_T i = 0; i < Size; i++)
|
||||
patchset((uint)BaseAddress + i, oldData[i], ((unsigned char*)Buffer)[i]);
|
||||
|
||||
return MemWrite(BaseAddress, Buffer, Size, NumberOfBytesWritten);
|
||||
for(uint i = 0; i < nSize; i++) //read byte-per-byte
|
||||
{
|
||||
unsigned char* curaddr = (unsigned char*)lpBaseAddress + i;
|
||||
unsigned char* curbuf = (unsigned char*)lpBuffer + i;
|
||||
ret = MemoryReadSafe(hProcess, curaddr, curbuf, 1, 0); //try 'normal' RPM
|
||||
if(!ret) //we failed
|
||||
{
|
||||
if(lpNumberOfBytesRead)
|
||||
*lpNumberOfBytesRead = i;
|
||||
SetLastError(ERROR_PARTIAL_COPY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemIsValidReadPtr(uint Address)
|
||||
bool memwrite(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten)
|
||||
{
|
||||
if(!hProcess or !lpBaseAddress or !lpBuffer or !nSize) //generic failures
|
||||
return false;
|
||||
SIZE_T written = 0;
|
||||
DWORD oldprotect = 0;
|
||||
bool ret = MemoryWriteSafe(hProcess, lpBaseAddress, lpBuffer, nSize, &written);
|
||||
if(ret and written == nSize) //'normal' WPM worked!
|
||||
{
|
||||
if(lpNumberOfBytesWritten)
|
||||
*lpNumberOfBytesWritten = written;
|
||||
return true;
|
||||
}
|
||||
for(uint i = 0; i < nSize; i++) //write byte-per-byte
|
||||
{
|
||||
unsigned char* curaddr = (unsigned char*)lpBaseAddress + i;
|
||||
unsigned char* curbuf = (unsigned char*)lpBuffer + i;
|
||||
ret = MemoryWriteSafe(hProcess, curaddr, curbuf, 1, 0); //try 'normal' WPM
|
||||
if(!ret) //we failed
|
||||
{
|
||||
if(lpNumberOfBytesWritten)
|
||||
*lpNumberOfBytesWritten = i;
|
||||
SetLastError(ERROR_PARTIAL_COPY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mempatch(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten)
|
||||
{
|
||||
if(!hProcess or !lpBaseAddress or !lpBuffer or !nSize) //generic failures
|
||||
return false;
|
||||
Memory<unsigned char*> olddata(nSize, "mempatch:olddata");
|
||||
if(!memread(hProcess, lpBaseAddress, olddata, nSize, 0))
|
||||
return memwrite(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten);
|
||||
unsigned char* newdata = (unsigned char*)lpBuffer;
|
||||
for(uint i = 0; i < nSize; i++)
|
||||
patchset((uint)lpBaseAddress + i, olddata[i], newdata[i]);
|
||||
return memwrite(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten);
|
||||
}
|
||||
|
||||
bool memisvalidreadptr(HANDLE hProcess, uint addr)
|
||||
{
|
||||
unsigned char a = 0;
|
||||
return MemRead((void*)Address, &a, 1, nullptr);
|
||||
return memread(hProcess, (void*)addr, &a, 1, 0);
|
||||
}
|
||||
|
||||
bool MemIsCanonicalAddress(uint Address)
|
||||
void* memalloc(HANDLE hProcess, uint addr, SIZE_T size, DWORD fdProtect)
|
||||
{
|
||||
#ifndef _WIN64
|
||||
// 32-bit mode only supports 4GB max, so limits are
|
||||
// not an issue
|
||||
return true;
|
||||
#else
|
||||
// The most-significant 16 bits must be all 1 or all 0.
|
||||
// (64 - 16) = 48bit linear address range.
|
||||
//
|
||||
// 0xFFFF800000000000 = Significant 16 bits set
|
||||
// 0x0000800000000000 = 48th bit set
|
||||
return (((Address & 0xFFFF800000000000) + 0x800000000000) & ~0x800000000000) == 0;
|
||||
#endif // _WIN64
|
||||
return VirtualAllocEx(hProcess, (void*)addr, size, MEM_RESERVE | MEM_COMMIT, fdProtect);
|
||||
}
|
||||
|
||||
void* MemAllocRemote(uint Address, SIZE_T Size, DWORD Protect)
|
||||
void memfree(HANDLE hProcess, uint addr)
|
||||
{
|
||||
return VirtualAllocEx(fdProcessInfo->hProcess, (void*)Address, Size, MEM_RESERVE | MEM_COMMIT, Protect);
|
||||
}
|
||||
|
||||
void MemFreeRemote(uint Address)
|
||||
{
|
||||
VirtualFreeEx(fdProcessInfo->hProcess, (void*)Address, 0, MEM_RELEASE);
|
||||
VirtualFreeEx(hProcess, (void*)addr, 0, MEM_RELEASE);
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef _MEMORY_H
|
||||
#define _MEMORY_H
|
||||
|
||||
#include "_global.h"
|
||||
#include "addrinfo.h"
|
||||
|
||||
|
@ -6,12 +9,13 @@ typedef std::map<Range, MEMPAGE, RangeCompare> MemoryMap;
|
|||
extern MemoryMap memoryPages;
|
||||
extern bool bListAllPages;
|
||||
|
||||
void MemUpdateMap(HANDLE hProcess);
|
||||
uint MemFindBaseAddr(uint addr, uint* Size, bool refresh = false);
|
||||
bool MemRead(void* BaseAddress, void* Buffer, SIZE_T Size, SIZE_T* NumberOfBytesRead);
|
||||
bool MemWrite(void* BaseAddress, void* Buffer, SIZE_T Size, SIZE_T* NumberOfBytesWritten);
|
||||
bool MemPatch(void* BaseAddress, void* Buffer, SIZE_T Size, SIZE_T* NumberOfBytesWritten);
|
||||
bool MemIsValidReadPtr(uint Address);
|
||||
bool MemIsCanonicalAddress(uint Address);
|
||||
void* MemAllocRemote(uint Address, SIZE_T Size, DWORD Protect);
|
||||
void MemFreeRemote(uint Address);
|
||||
void memupdatemap(HANDLE hProcess);
|
||||
uint memfindbaseaddr(uint addr, uint* size, bool refresh = false);
|
||||
bool memread(HANDLE hProcess, const void* lpBaseAddress, void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead);
|
||||
bool memwrite(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten);
|
||||
bool mempatch(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten);
|
||||
bool memisvalidreadptr(HANDLE hProcess, uint addr);
|
||||
void* memalloc(HANDLE hProcess, uint addr, SIZE_T size, DWORD fdProtect);
|
||||
void memfree(HANDLE hProcess, uint addr);
|
||||
|
||||
#endif // _MEMORY_H
|
||||
|
|
|
@ -6,262 +6,194 @@
|
|||
|
||||
static ModulesInfo modinfo;
|
||||
|
||||
bool ModLoad(uint Base, uint Size, const char* FullPath)
|
||||
///module functions
|
||||
bool modload(uint base, uint size, const char* fullpath)
|
||||
{
|
||||
//
|
||||
// Handle a new module being loaded
|
||||
//
|
||||
// TODO: Do loaded modules always require a path?
|
||||
if(!Base || !Size || !FullPath)
|
||||
if(!base or !size or !fullpath)
|
||||
return false;
|
||||
char name[deflen] = "";
|
||||
|
||||
int len = (int)strlen(fullpath);
|
||||
while(fullpath[len] != '\\' and len)
|
||||
len--;
|
||||
if(len)
|
||||
len++;
|
||||
strcpy_s(name, fullpath + len);
|
||||
_strlwr(name);
|
||||
len = (int)strlen(name);
|
||||
name[MAX_MODULE_SIZE - 1] = 0; //ignore later characters
|
||||
while(name[len] != '.' and len)
|
||||
len--;
|
||||
MODINFO info;
|
||||
|
||||
// Break the module path into a directory and file name
|
||||
char dir[deflen];
|
||||
char* file;
|
||||
|
||||
if(GetFullPathNameA(FullPath, ARRAYSIZE(dir), dir, &file) == 0)
|
||||
return false;
|
||||
|
||||
// Make everything lowercase
|
||||
_strlwr(dir);
|
||||
|
||||
// Copy the extension into the module struct
|
||||
{
|
||||
char* extensionPos = strrchr(file, '.');
|
||||
|
||||
if(extensionPos)
|
||||
{
|
||||
strcpy_s(info.extension, extensionPos);
|
||||
extensionPos[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the name to the module struct
|
||||
strcpy_s(info.name, file);
|
||||
|
||||
// Module base address/size/hash index
|
||||
info.hash = ModHashFromName(info.name);
|
||||
info.base = Base;
|
||||
info.size = Size;
|
||||
|
||||
// Process module sections
|
||||
memset(&info, 0, sizeof(MODINFO));
|
||||
info.sections.clear();
|
||||
|
||||
WString wszFullPath = StringUtils::Utf8ToUtf16(FullPath);
|
||||
if(StaticFileLoadW(wszFullPath.c_str(), UE_ACCESS_READ, false, &info.Handle, &info.FileMapSize, &info.MapHandle, &info.FileMapVA))
|
||||
info.hash = modhashfromname(name);
|
||||
if(len)
|
||||
{
|
||||
// Get the entry point
|
||||
info.entry = GetPE32DataFromMappedFile(info.FileMapVA, 0, UE_OEP) + info.base;
|
||||
strcpy_s(info.extension, name + len);
|
||||
name[len] = 0; //remove extension
|
||||
}
|
||||
info.base = base;
|
||||
info.size = size;
|
||||
strcpy_s(info.name, name);
|
||||
|
||||
// Enumerate all PE sections
|
||||
int sectionCount = (int)GetPE32DataFromMappedFile(info.FileMapVA, 0, UE_SECTIONNUMBER);
|
||||
|
||||
for(int i = 0; i < sectionCount; i++)
|
||||
//process module sections
|
||||
HANDLE FileHandle;
|
||||
DWORD LoadedSize;
|
||||
HANDLE FileMap;
|
||||
ULONG_PTR FileMapVA;
|
||||
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
|
||||
int SectionCount = (int)GetPE32DataFromMappedFile(FileMapVA, 0, UE_SECTIONNUMBER);
|
||||
if(SectionCount > 0)
|
||||
{
|
||||
MODSECTIONINFO curSection;
|
||||
|
||||
curSection.addr = GetPE32DataFromMappedFile(info.FileMapVA, i, UE_SECTIONVIRTUALOFFSET) + info.base;
|
||||
curSection.size = GetPE32DataFromMappedFile(info.FileMapVA, i, UE_SECTIONVIRTUALSIZE);
|
||||
const char* sectionName = (const char*)GetPE32DataFromMappedFile(info.FileMapVA, i, UE_SECTIONNAME);
|
||||
|
||||
// Escape section name when needed
|
||||
strcpy_s(curSection.name, StringUtils::Escape(sectionName).c_str());
|
||||
|
||||
// Add entry to the vector
|
||||
info.sections.push_back(curSection);
|
||||
for(int i = 0; i < SectionCount; i++)
|
||||
{
|
||||
MODSECTIONINFO curSection;
|
||||
curSection.addr = GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALOFFSET) + base;
|
||||
curSection.size = GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONVIRTUALSIZE);
|
||||
const char* SectionName = (const char*)GetPE32DataFromMappedFile(FileMapVA, i, UE_SECTIONNAME);
|
||||
//escape section name when needed
|
||||
int len = (int)strlen(SectionName);
|
||||
int escape_count = 0;
|
||||
for(int k = 0; k < len; k++)
|
||||
if(SectionName[k] == '\\' or SectionName[k] == '\"' or !isprint(SectionName[k]))
|
||||
escape_count++;
|
||||
strcpy_s(curSection.name, StringUtils::Escape(SectionName).c_str());
|
||||
info.sections.push_back(curSection);
|
||||
}
|
||||
}
|
||||
StaticFileUnloadW(wszFullPath.c_str(), false, FileHandle, LoadedSize, FileMap, FileMapVA);
|
||||
}
|
||||
|
||||
// Add module to list
|
||||
EXCLUSIVE_ACQUIRE(LockModules);
|
||||
modinfo.insert(std::make_pair(Range(Base, Base + Size - 1), info));
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
SymUpdateModuleList();
|
||||
//add module to list
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
modinfo.insert(std::make_pair(Range(base, base + size - 1), info));
|
||||
symupdatemodulelist();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModUnload(uint Base)
|
||||
bool modunload(uint base)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockModules);
|
||||
|
||||
// Find the iterator index
|
||||
const auto found = modinfo.find(Range(Base, Base));
|
||||
|
||||
if(found == modinfo.end())
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(base, base));
|
||||
if(found == modinfo.end()) //not found
|
||||
return false;
|
||||
|
||||
// Remove it from the list
|
||||
modinfo.erase(found);
|
||||
|
||||
// Unload everything from TitanEngine
|
||||
StaticFileUnloadW(nullptr, false, found->second.Handle, found->second.FileMapSize, found->second.MapHandle, found->second.FileMapVA);
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
// Update symbols
|
||||
SymUpdateModuleList();
|
||||
symupdatemodulelist();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModClear()
|
||||
void modclear()
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockModules);
|
||||
modinfo.clear();
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
// Tell the symbol updater
|
||||
SymUpdateModuleList();
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
ModulesInfo().swap(modinfo);
|
||||
symupdatemodulelist();
|
||||
}
|
||||
|
||||
MODINFO* ModInfoFromAddr(uint Address)
|
||||
bool modnamefromaddr(uint addr, char* modname, bool extension)
|
||||
{
|
||||
//
|
||||
// NOTE: THIS DOES _NOT_ USE LOCKS
|
||||
//
|
||||
auto found = modinfo.find(Range(Address, Address));
|
||||
|
||||
// Was the module found with this address?
|
||||
if(found == modinfo.end())
|
||||
return nullptr;
|
||||
|
||||
return &found->second;
|
||||
}
|
||||
|
||||
bool ModNameFromAddr(uint Address, char* Name, bool Extension)
|
||||
{
|
||||
if(!Name)
|
||||
if(!modname)
|
||||
return false;
|
||||
|
||||
SHARED_ACQUIRE(LockModules);
|
||||
|
||||
// Get a pointer to module information
|
||||
auto module = ModInfoFromAddr(Address);
|
||||
|
||||
if(!module)
|
||||
*modname = '\0';
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
|
||||
if(found == modinfo.end()) //not found
|
||||
return false;
|
||||
|
||||
// Copy initial module name
|
||||
strcpy_s(Name, MAX_MODULE_SIZE, module->name);
|
||||
|
||||
if(Extension)
|
||||
strcat_s(Name, MAX_MODULE_SIZE, module->extension);
|
||||
|
||||
String mod = found->second.name;
|
||||
if(extension)
|
||||
mod += found->second.extension;
|
||||
strcpy_s(modname, MAX_MODULE_SIZE, mod.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
uint ModBaseFromAddr(uint Address)
|
||||
uint modbasefromaddr(uint addr)
|
||||
{
|
||||
SHARED_ACQUIRE(LockModules);
|
||||
|
||||
auto module = ModInfoFromAddr(Address);
|
||||
|
||||
if(!module)
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
|
||||
if(found == modinfo.end()) //not found
|
||||
return 0;
|
||||
|
||||
return module->base;
|
||||
return found->second.base;
|
||||
}
|
||||
|
||||
uint ModHashFromAddr(uint Address)
|
||||
uint modhashfromva(uint va) //return a unique hash from a VA
|
||||
{
|
||||
//
|
||||
// Returns a unique hash from a virtual address
|
||||
//
|
||||
SHARED_ACQUIRE(LockModules);
|
||||
|
||||
auto module = ModInfoFromAddr(Address);
|
||||
|
||||
if(!module)
|
||||
return Address;
|
||||
|
||||
return module->hash + (Address - module->base);
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(va, va));
|
||||
if(found == modinfo.end()) //not found
|
||||
return va;
|
||||
return found->second.hash + (va - found->second.base);
|
||||
}
|
||||
|
||||
uint ModHashFromName(const char* Module)
|
||||
uint modhashfromname(const char* mod) //return MODINFO.hash
|
||||
{
|
||||
//
|
||||
// return MODINFO.hash (based on the name)
|
||||
//
|
||||
if(!Module || Module[0] == '\0')
|
||||
if(!mod or !*mod)
|
||||
return 0;
|
||||
|
||||
return murmurhash(Module, (int)strlen(Module));
|
||||
int len = (int)strlen(mod);
|
||||
return murmurhash(mod, len);
|
||||
}
|
||||
|
||||
uint ModBaseFromName(const char* Module)
|
||||
uint modbasefromname(const char* modname)
|
||||
{
|
||||
if(!Module || strlen(Module) >= MAX_MODULE_SIZE)
|
||||
if(!modname or strlen(modname) >= MAX_MODULE_SIZE)
|
||||
return 0;
|
||||
|
||||
SHARED_ACQUIRE(LockModules);
|
||||
|
||||
for(auto itr = modinfo.begin(); itr != modinfo.end(); itr++)
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
for(ModulesInfo::iterator i = modinfo.begin(); i != modinfo.end(); ++i)
|
||||
{
|
||||
char currentModule[MAX_MODULE_SIZE];
|
||||
strcpy_s(currentModule, itr->second.name);
|
||||
strcat_s(currentModule, itr->second.extension);
|
||||
|
||||
// Test with and without extension
|
||||
if(!_stricmp(currentModule, Module) || !_stricmp(itr->second.name, Module))
|
||||
return itr->second.base;
|
||||
MODINFO* curMod = &i->second;
|
||||
char curmodname[MAX_MODULE_SIZE] = "";
|
||||
sprintf(curmodname, "%s%s", curMod->name, curMod->extension);
|
||||
if(!_stricmp(curmodname, modname)) //with extension
|
||||
return curMod->base;
|
||||
if(!_stricmp(curMod->name, modname)) //without extension
|
||||
return curMod->base;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint ModSizeFromAddr(uint Address)
|
||||
uint modsizefromaddr(uint addr)
|
||||
{
|
||||
SHARED_ACQUIRE(LockModules);
|
||||
|
||||
auto module = ModInfoFromAddr(Address);
|
||||
|
||||
if(!module)
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
|
||||
if(found == modinfo.end()) //not found
|
||||
return 0;
|
||||
|
||||
return module->size;
|
||||
return found->second.size;
|
||||
}
|
||||
|
||||
bool ModSectionsFromAddr(uint Address, std::vector<MODSECTIONINFO>* Sections)
|
||||
bool modsectionsfromaddr(uint addr, std::vector<MODSECTIONINFO>* sections)
|
||||
{
|
||||
SHARED_ACQUIRE(LockModules);
|
||||
|
||||
auto module = ModInfoFromAddr(Address);
|
||||
|
||||
if(!module)
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
|
||||
if(found == modinfo.end()) //not found
|
||||
return false;
|
||||
|
||||
// Copy vector <-> vector
|
||||
*Sections = module->sections;
|
||||
*sections = found->second.sections;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint ModEntryFromAddr(uint Address)
|
||||
uint modentryfromaddr(uint addr)
|
||||
{
|
||||
SHARED_ACQUIRE(LockModules);
|
||||
|
||||
auto module = ModInfoFromAddr(Address);
|
||||
|
||||
if(!module)
|
||||
CriticalSectionLocker locker(LockModules);
|
||||
const ModulesInfo::iterator found = modinfo.find(Range(addr, addr));
|
||||
if(found == modinfo.end()) //not found
|
||||
return 0;
|
||||
|
||||
return module->entry;
|
||||
return found->second.entry;
|
||||
}
|
||||
|
||||
int ModPathFromAddr(duint Address, char* Path, int Size)
|
||||
int modpathfromaddr(duint addr, char* path, int size)
|
||||
{
|
||||
SHARED_ACQUIRE(LockModules);
|
||||
|
||||
auto module = ModInfoFromAddr(Address);
|
||||
|
||||
if(!module)
|
||||
Memory<wchar_t*> wszModPath(size * sizeof(wchar_t), "modpathfromaddr:wszModPath");
|
||||
if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbasefromaddr(addr), wszModPath, size))
|
||||
{
|
||||
*path = '\0';
|
||||
return 0;
|
||||
|
||||
strcpy_s(Path, Size, module->path);
|
||||
return (int)strlen(Path);
|
||||
}
|
||||
strcpy_s(path, size, StringUtils::Utf16ToUtf8(wszModPath()).c_str());
|
||||
return (int)strlen(path);
|
||||
}
|
||||
|
||||
int ModPathFromName(const char* Module, char* Path, int Size)
|
||||
int modpathfromname(const char* modname, char* path, int size)
|
||||
{
|
||||
return ModPathFromAddr(ModBaseFromName(Module), Path, Size);
|
||||
}
|
||||
return modpathfromaddr(modbasefromname(modname), path, size);
|
||||
}
|
||||
|
|
|
@ -1,47 +1,40 @@
|
|||
#pragma once
|
||||
#ifndef _MODULE_H
|
||||
#define _MODULE_H
|
||||
|
||||
#include "_global.h"
|
||||
#include "addrinfo.h"
|
||||
|
||||
struct MODSECTIONINFO
|
||||
{
|
||||
uint addr; // Virtual address
|
||||
uint size; // Virtual size
|
||||
char name[50]; // Escaped section name
|
||||
uint addr; //va
|
||||
uint size; //virtual size
|
||||
char name[50];
|
||||
};
|
||||
|
||||
struct MODINFO
|
||||
{
|
||||
uint base; // Module base
|
||||
uint size; // Module size
|
||||
uint hash; // Full module name hash
|
||||
uint entry; // Entry point
|
||||
|
||||
char name[MAX_MODULE_SIZE]; // Module name (without extension)
|
||||
char extension[MAX_MODULE_SIZE]; // File extension
|
||||
char path[MAX_PATH]; // File path (in UTF8)
|
||||
|
||||
HANDLE Handle; // Handle to the file opened by TitanEngine
|
||||
HANDLE MapHandle; // Handle to the memory map
|
||||
ULONG_PTR FileMapVA; // File map virtual address (Debugger local)
|
||||
DWORD FileMapSize; // File map virtual size
|
||||
|
||||
uint base; //module base
|
||||
uint size; //module size
|
||||
uint hash; //full module name hash
|
||||
uint entry; //entry point
|
||||
char name[MAX_MODULE_SIZE]; //module name (without extension)
|
||||
char extension[MAX_MODULE_SIZE]; //file extension
|
||||
std::vector<MODSECTIONINFO> sections;
|
||||
};
|
||||
|
||||
typedef std::map<Range, MODINFO, RangeCompare> ModulesInfo;
|
||||
|
||||
bool ModLoad(uint Base, uint Size, const char* FullPath);
|
||||
bool ModUnload(uint Base);
|
||||
void ModClear();
|
||||
MODINFO* ModInfoFromAddr(uint Address);
|
||||
bool ModNameFromAddr(uint Address, char* Name, bool Extension);
|
||||
uint ModBaseFromAddr(uint Address);
|
||||
uint ModHashFromAddr(uint Address);
|
||||
uint ModHashFromName(const char* Module);
|
||||
uint ModBaseFromName(const char* Module);
|
||||
uint ModSizeFromAddr(uint Address);
|
||||
bool ModSectionsFromAddr(uint Address, std::vector<MODSECTIONINFO>* Sections);
|
||||
uint ModEntryFromAddr(uint Address);
|
||||
int ModPathFromAddr(duint Address, char* Path, int Size);
|
||||
int ModPathFromName(const char* Module, char* Path, int Size);
|
||||
bool modload(uint base, uint size, const char* fullpath);
|
||||
bool modunload(uint base);
|
||||
void modclear();
|
||||
bool modnamefromaddr(uint addr, char* modname, bool extension);
|
||||
uint modbasefromaddr(uint addr);
|
||||
uint modhashfromva(uint va);
|
||||
uint modhashfromname(const char* mod);
|
||||
uint modbasefromname(const char* modname);
|
||||
uint modsizefromaddr(uint addr);
|
||||
bool modsectionsfromaddr(uint addr, std::vector<MODSECTIONINFO>* sections);
|
||||
uint modentryfromaddr(uint addr);
|
||||
int modpathfromaddr(duint addr, char* path, int size);
|
||||
int modpathfromname(const char* modname, char* path, int size);
|
||||
|
||||
#endif //_MODULE_H
|
|
@ -10,16 +10,16 @@ static PatchesInfo patches;
|
|||
|
||||
bool patchset(uint addr, unsigned char oldbyte, unsigned char newbyte)
|
||||
{
|
||||
if(!DbgIsDebugging() || !MemIsValidReadPtr(addr))
|
||||
if(!DbgIsDebugging() || !memisvalidreadptr(fdProcessInfo->hProcess, addr))
|
||||
return false;
|
||||
if(oldbyte == newbyte)
|
||||
return true; //no need to make a patch for a byte that is equal to itself
|
||||
PATCHINFO newPatch;
|
||||
newPatch.addr = addr - ModBaseFromAddr(addr);
|
||||
ModNameFromAddr(addr, newPatch.mod, true);
|
||||
newPatch.addr = addr - modbasefromaddr(addr);
|
||||
modnamefromaddr(addr, newPatch.mod, true);
|
||||
newPatch.oldbyte = oldbyte;
|
||||
newPatch.newbyte = newbyte;
|
||||
uint key = ModHashFromAddr(addr);
|
||||
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
|
||||
|
@ -45,13 +45,13 @@ bool patchget(uint addr, PATCHINFO* patch)
|
|||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockPatches);
|
||||
PatchesInfo::iterator found = patches.find(ModHashFromAddr(addr));
|
||||
PatchesInfo::iterator found = patches.find(modhashfromva(addr));
|
||||
if(found == patches.end()) //not found
|
||||
return false;
|
||||
if(patch)
|
||||
{
|
||||
*patch = found->second;
|
||||
patch->addr += ModBaseFromAddr(addr);
|
||||
patch->addr += modbasefromaddr(addr);
|
||||
return true;
|
||||
}
|
||||
return (found->second.oldbyte != found->second.newbyte);
|
||||
|
@ -62,11 +62,11 @@ bool patchdel(uint addr, bool restore)
|
|||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
CriticalSectionLocker locker(LockPatches);
|
||||
PatchesInfo::iterator found = patches.find(ModHashFromAddr(addr));
|
||||
PatchesInfo::iterator found = patches.find(modhashfromva(addr));
|
||||
if(found == patches.end()) //not found
|
||||
return false;
|
||||
if(restore)
|
||||
MemWrite((void*)(found->second.addr + ModBaseFromAddr(addr)), &found->second.oldbyte, sizeof(char), 0);
|
||||
memwrite(fdProcessInfo->hProcess, (void*)(found->second.addr + modbasefromaddr(addr)), &found->second.oldbyte, sizeof(char), 0);
|
||||
patches.erase(found);
|
||||
return true;
|
||||
}
|
||||
|
@ -76,8 +76,8 @@ void patchdelrange(uint start, uint end, bool restore)
|
|||
if(!DbgIsDebugging())
|
||||
return;
|
||||
bool bDelAll = (start == 0 && end == ~0); //0x00000000-0xFFFFFFFF
|
||||
uint modbase = ModBaseFromAddr(start);
|
||||
if(modbase != ModBaseFromAddr(end))
|
||||
uint modbase = modbasefromaddr(start);
|
||||
if(modbase != modbasefromaddr(end))
|
||||
return;
|
||||
start -= modbase;
|
||||
end -= modbase;
|
||||
|
@ -88,7 +88,7 @@ void patchdelrange(uint start, uint end, bool restore)
|
|||
if(bDelAll || (i->second.addr >= start && i->second.addr < end))
|
||||
{
|
||||
if(restore)
|
||||
MemWrite((void*)(i->second.addr + modbase), &i->second.oldbyte, sizeof(char), 0);
|
||||
memwrite(fdProcessInfo->hProcess, (void*)(i->second.addr + modbase), &i->second.oldbyte, sizeof(char), 0);
|
||||
patches.erase(i++);
|
||||
}
|
||||
else
|
||||
|
@ -130,7 +130,7 @@ bool patchenum(PATCHINFO* patcheslist, size_t* cbsize)
|
|||
for(PatchesInfo::iterator i = patches.begin(); i != patches.end(); ++i, j++)
|
||||
{
|
||||
patcheslist[j] = i->second;
|
||||
uint modbase = ModBaseFromName(patcheslist[j].mod);
|
||||
uint modbase = modbasefromname(patcheslist[j].mod);
|
||||
patcheslist[j].addr += modbase;
|
||||
}
|
||||
return true;
|
||||
|
@ -154,7 +154,7 @@ int patchfile(const PATCHINFO* patchlist, int count, const char* szFileName, cha
|
|||
sprintf(error, "not all patches are in module %s", modname);
|
||||
return -1;
|
||||
}
|
||||
uint modbase = ModBaseFromName(modname);
|
||||
uint modbase = modbasefromname(modname);
|
||||
if(!modbase) //module not loaded
|
||||
{
|
||||
if(error)
|
||||
|
|
|
@ -303,7 +303,7 @@ void plugincbcall(CBTYPE cbType, void* callbackInfo)
|
|||
if(pluginCallbackList.at(i).cbType == cbType)
|
||||
{
|
||||
CBPLUGIN cbPlugin = pluginCallbackList.at(i).cbPlugin;
|
||||
if(!IsBadReadPtr((const void*)cbPlugin, sizeof(uint)))
|
||||
if(memisvalidreadptr(GetCurrentProcess(), (uint)cbPlugin))
|
||||
cbPlugin(cbType, callbackInfo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ int reffind(uint addr, uint size, CBREF cbRef, void* userinfo, bool silent, cons
|
|||
uint start_size;
|
||||
uint base;
|
||||
uint base_size;
|
||||
base = MemFindBaseAddr(addr, &base_size, true);
|
||||
base = memfindbaseaddr(addr, &base_size, true);
|
||||
if(!base or !base_size)
|
||||
{
|
||||
if(!silent)
|
||||
|
@ -33,7 +33,7 @@ int reffind(uint addr, uint size, CBREF cbRef, void* userinfo, bool silent, cons
|
|||
start_size = maxsize;
|
||||
}
|
||||
Memory<unsigned char*> data(start_size, "reffind:data");
|
||||
if(!MemRead((void*)start_addr, data, start_size, 0))
|
||||
if(!memread(fdProcessInfo->hProcess, (const void*)start_addr, data, start_size, 0))
|
||||
{
|
||||
if(!silent)
|
||||
dputs("error reading memory");
|
||||
|
@ -53,7 +53,7 @@ int reffind(uint addr, uint size, CBREF cbRef, void* userinfo, bool silent, cons
|
|||
refinfo.userinfo = userinfo;
|
||||
char fullName[deflen] = "";
|
||||
char modname[MAX_MODULE_SIZE] = "";
|
||||
if(ModNameFromAddr(start_addr, modname, true))
|
||||
if(modnamefromaddr(start_addr, modname, true))
|
||||
sprintf_s(fullName, "%s (%s)", name, modname);
|
||||
else
|
||||
sprintf_s(fullName, "%s (%p)", name, start_addr);
|
||||
|
|
|
@ -12,17 +12,17 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
|||
{
|
||||
uint data = 0;
|
||||
memset(comment, 0, sizeof(STACK_COMMENT));
|
||||
MemRead((void*)addr, &data, sizeof(uint), 0);
|
||||
if(!MemIsValidReadPtr(data)) //the stack value is no pointer
|
||||
memread(fdProcessInfo->hProcess, (const void*)addr, &data, sizeof(uint), 0);
|
||||
if(!memisvalidreadptr(fdProcessInfo->hProcess, data)) //the stack value is no pointer
|
||||
return false;
|
||||
|
||||
uint size = 0;
|
||||
uint base = MemFindBaseAddr(data, &size);
|
||||
uint base = memfindbaseaddr(data, &size);
|
||||
uint readStart = data - 16 * 4;
|
||||
if(readStart < base)
|
||||
readStart = base;
|
||||
unsigned char disasmData[256];
|
||||
MemRead((void*)readStart, disasmData, sizeof(disasmData), 0);
|
||||
memread(fdProcessInfo->hProcess, (const void*)readStart, disasmData, sizeof(disasmData), 0);
|
||||
uint prev = disasmback(disasmData, 0, sizeof(disasmData), data - readStart, 1);
|
||||
uint previousInstr = readStart + prev;
|
||||
|
||||
|
@ -44,7 +44,7 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
|||
if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
|
||||
strcpy_s(label, addrinfo.label);
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
ModNameFromAddr(data, module, false);
|
||||
modnamefromaddr(data, module, false);
|
||||
char returnToAddr[MAX_COMMENT_SIZE] = "";
|
||||
if(*module)
|
||||
sprintf(returnToAddr, "%s.", module);
|
||||
|
@ -60,7 +60,7 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
|||
if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
|
||||
strcpy_s(label, addrinfo.label);
|
||||
*module = 0;
|
||||
ModNameFromAddr(data, module, false);
|
||||
modnamefromaddr(data, module, false);
|
||||
char returnFromAddr[MAX_COMMENT_SIZE] = "";
|
||||
if(*module)
|
||||
sprintf(returnFromAddr, "%s.", module);
|
||||
|
@ -94,7 +94,7 @@ bool stackcommentget(uint addr, STACK_COMMENT* comment)
|
|||
if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
|
||||
strcpy_s(label, addrinfo.label);
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
ModNameFromAddr(data, module, false);
|
||||
modnamefromaddr(data, module, false);
|
||||
char addrInfo[MAX_COMMENT_SIZE] = "";
|
||||
if(*module) //module
|
||||
{
|
||||
|
@ -118,12 +118,12 @@ void stackgetcallstack(uint csp, CALLSTACK* callstack)
|
|||
callstack->total = 0;
|
||||
if(!DbgIsDebugging() or csp % sizeof(uint)) //alignment problem
|
||||
return;
|
||||
if(!MemIsValidReadPtr(csp))
|
||||
if(!memisvalidreadptr(fdProcessInfo->hProcess, csp))
|
||||
return;
|
||||
std::vector<CALLSTACKENTRY> callstackVector;
|
||||
DWORD ticks = GetTickCount();
|
||||
uint stacksize = 0;
|
||||
uint stackbase = MemFindBaseAddr(csp, &stacksize, false);
|
||||
uint stackbase = memfindbaseaddr(csp, &stacksize, false);
|
||||
if(!stackbase) //super-fail (invalid stack address)
|
||||
return;
|
||||
//walk up the stack
|
||||
|
@ -131,16 +131,16 @@ void stackgetcallstack(uint csp, CALLSTACK* callstack)
|
|||
while(i != stackbase + stacksize)
|
||||
{
|
||||
uint data = 0;
|
||||
MemRead((void*)i, &data, sizeof(uint), 0);
|
||||
if(MemIsValidReadPtr(data)) //the stack value is a pointer
|
||||
memread(fdProcessInfo->hProcess, (const void*)i, &data, sizeof(uint), 0);
|
||||
if(memisvalidreadptr(fdProcessInfo->hProcess, data)) //the stack value is a pointer
|
||||
{
|
||||
uint size = 0;
|
||||
uint base = MemFindBaseAddr(data, &size);
|
||||
uint base = memfindbaseaddr(data, &size);
|
||||
uint readStart = data - 16 * 4;
|
||||
if(readStart < base)
|
||||
readStart = base;
|
||||
unsigned char disasmData[256];
|
||||
MemRead((void*)readStart, disasmData, sizeof(disasmData), 0);
|
||||
memread(fdProcessInfo->hProcess, (const void*)readStart, disasmData, sizeof(disasmData), 0);
|
||||
uint prev = disasmback(disasmData, 0, sizeof(disasmData), data - readStart, 1);
|
||||
uint previousInstr = readStart + prev;
|
||||
BASIC_INSTRUCTION_INFO basicinfo;
|
||||
|
@ -153,7 +153,7 @@ void stackgetcallstack(uint csp, CALLSTACK* callstack)
|
|||
if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
|
||||
strcpy_s(label, addrinfo.label);
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
ModNameFromAddr(data, module, false);
|
||||
modnamefromaddr(data, module, false);
|
||||
char returnToAddr[MAX_COMMENT_SIZE] = "";
|
||||
if(*module)
|
||||
sprintf(returnToAddr, "%s.", module);
|
||||
|
@ -176,7 +176,7 @@ void stackgetcallstack(uint csp, CALLSTACK* callstack)
|
|||
if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo))
|
||||
strcpy_s(label, addrinfo.label);
|
||||
*module = 0;
|
||||
ModNameFromAddr(data, module, false);
|
||||
modnamefromaddr(data, module, false);
|
||||
char returnFromAddr[MAX_COMMENT_SIZE] = "";
|
||||
if(*module)
|
||||
sprintf(returnFromAddr, "%s.", module);
|
||||
|
|
|
@ -11,234 +11,166 @@ struct SYMBOLCBDATA
|
|||
void* user;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK EnumSymbols(PSYMBOL_INFO SymInfo, ULONG SymbolSize, PVOID UserContext)
|
||||
static BOOL CALLBACK EnumSymbols(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
|
||||
{
|
||||
int len = (int)strlen(pSymInfo->Name);
|
||||
SYMBOLINFO curSymbol;
|
||||
memset(&curSymbol, 0, sizeof(SYMBOLINFO));
|
||||
|
||||
curSymbol.addr = (duint)SymInfo->Address;
|
||||
curSymbol.decoratedSymbol = (char*)BridgeAlloc(strlen(SymInfo->Name) + 1);
|
||||
curSymbol.addr = (duint)pSymInfo->Address;
|
||||
curSymbol.decoratedSymbol = (char*)BridgeAlloc(len + 1);
|
||||
strcpy_s(curSymbol.decoratedSymbol, len + 1, pSymInfo->Name);
|
||||
curSymbol.undecoratedSymbol = (char*)BridgeAlloc(MAX_SYM_NAME);
|
||||
strcpy_s(curSymbol.decoratedSymbol, strlen(SymInfo->Name) + 1, SymInfo->Name);
|
||||
|
||||
// Skip bad ordinals
|
||||
if(strstr(SymInfo->Name, "Ordinal"))
|
||||
if(strstr(pSymInfo->Name, "Ordinal"))
|
||||
{
|
||||
// Does the symbol point to the module base?
|
||||
if(SymInfo->Address == SymInfo->ModBase)
|
||||
//skip bad ordinals
|
||||
if(pSymInfo->Address == pSymInfo->ModBase)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Convert a mangled/decorated C++ name to a readable format
|
||||
if(!SafeUnDecorateSymbolName(SymInfo->Name, curSymbol.undecoratedSymbol, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
if(!SafeUnDecorateSymbolName(pSymInfo->Name, curSymbol.undecoratedSymbol, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
{
|
||||
BridgeFree(curSymbol.undecoratedSymbol);
|
||||
curSymbol.undecoratedSymbol = nullptr;
|
||||
curSymbol.undecoratedSymbol = 0;
|
||||
}
|
||||
else if(!strcmp(curSymbol.decoratedSymbol, curSymbol.undecoratedSymbol))
|
||||
{
|
||||
BridgeFree(curSymbol.undecoratedSymbol);
|
||||
curSymbol.undecoratedSymbol = nullptr;
|
||||
curSymbol.undecoratedSymbol = 0;
|
||||
}
|
||||
|
||||
SYMBOLCBDATA* cbData = (SYMBOLCBDATA*)UserContext;
|
||||
cbData->cbSymbolEnum(&curSymbol, cbData->user);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void SymEnum(uint Base, CBSYMBOLENUM EnumCallback, void* UserData)
|
||||
void symenum(uint base, CBSYMBOLENUM cbSymbolEnum, void* user)
|
||||
{
|
||||
SYMBOLCBDATA symbolCbData;
|
||||
symbolCbData.cbSymbolEnum = EnumCallback;
|
||||
symbolCbData.user = UserData;
|
||||
|
||||
// Enumerate every single symbol for the module in 'base'
|
||||
if(!SafeSymEnumSymbols(fdProcessInfo->hProcess, Base, "*", EnumSymbols, &symbolCbData))
|
||||
dputs("SymEnumSymbols failed!");
|
||||
symbolCbData.cbSymbolEnum = cbSymbolEnum;
|
||||
symbolCbData.user = user;
|
||||
char mask[] = "*";
|
||||
SafeSymEnumSymbols(fdProcessInfo->hProcess, base, mask, EnumSymbols, &symbolCbData);
|
||||
}
|
||||
|
||||
bool SymGetModuleList(std::vector<SYMBOLMODULEINFO>* List)
|
||||
#ifdef _WIN64
|
||||
static BOOL CALLBACK EnumModules(LPCTSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext)
|
||||
#else
|
||||
static BOOL CALLBACK EnumModules(LPCTSTR ModuleName, ULONG BaseOfDll, PVOID UserContext)
|
||||
#endif //_WIN64
|
||||
{
|
||||
//
|
||||
// Inline lambda enum
|
||||
//
|
||||
auto EnumModules = [](LPCTSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext) -> BOOL
|
||||
{
|
||||
SYMBOLMODULEINFO curModule;
|
||||
curModule.base = (duint)BaseOfDll;
|
||||
|
||||
// Terminate module name if one isn't found
|
||||
if(!ModNameFromAddr(curModule.base, curModule.name, true))
|
||||
curModule.name[0] = '\0';
|
||||
|
||||
((std::vector<SYMBOLMODULEINFO>*)UserContext)->push_back(curModule);
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
// Execute the symbol enumerator (Force cast to STDCALL)
|
||||
if(!SafeSymEnumerateModules64(fdProcessInfo->hProcess, EnumModules, List))
|
||||
{
|
||||
dputs("SymEnumerateModules64 failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
SYMBOLMODULEINFO curModule;
|
||||
memset(&curModule, 0, sizeof(SYMBOLMODULEINFO));
|
||||
curModule.base = BaseOfDll;
|
||||
modnamefromaddr(BaseOfDll, curModule.name, true);
|
||||
((std::vector<SYMBOLMODULEINFO>*)UserContext)->push_back(curModule);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void SymUpdateModuleList()
|
||||
void symupdatemodulelist()
|
||||
{
|
||||
// Build the vector of modules
|
||||
std::vector<SYMBOLMODULEINFO> modList;
|
||||
|
||||
if(!SymGetModuleList(&modList))
|
||||
return;
|
||||
|
||||
// Create a new array to be sent to the GUI thread
|
||||
size_t moduleCount = modList.size();
|
||||
SYMBOLMODULEINFO *data = (SYMBOLMODULEINFO *)BridgeAlloc(moduleCount * sizeof(SYMBOLMODULEINFO));
|
||||
|
||||
// Direct copy from std::vector data
|
||||
memcpy(data, modList.data(), moduleCount * sizeof(SYMBOLMODULEINFO));
|
||||
|
||||
// Send the module data to the GUI for updating
|
||||
GuiSymbolUpdateModuleList((int)moduleCount, data);
|
||||
modList.clear();
|
||||
SafeSymEnumerateModules(fdProcessInfo->hProcess, EnumModules, &modList);
|
||||
int modcount = (int)modList.size();
|
||||
SYMBOLMODULEINFO* modListBridge = (SYMBOLMODULEINFO*)BridgeAlloc(sizeof(SYMBOLMODULEINFO) * modcount);
|
||||
for(int i = 0; i < modcount; i++)
|
||||
memcpy(&modListBridge[i], &modList.at(i), sizeof(SYMBOLMODULEINFO));
|
||||
GuiSymbolUpdateModuleList(modcount, modListBridge);
|
||||
}
|
||||
|
||||
void SymDownloadAllSymbols(const char* SymbolStore)
|
||||
void symdownloadallsymbols(const char* szSymbolStore)
|
||||
{
|
||||
// Default to Microsoft's symbol server
|
||||
if(!SymbolStore)
|
||||
SymbolStore = "http://msdl.microsoft.com/download/symbols";
|
||||
|
||||
// Build the vector of modules
|
||||
if(!szSymbolStore)
|
||||
szSymbolStore = "http://msdl.microsoft.com/download/symbols";
|
||||
std::vector<SYMBOLMODULEINFO> modList;
|
||||
|
||||
if(!SymGetModuleList(&modList))
|
||||
modList.clear();
|
||||
SafeSymEnumerateModules(fdProcessInfo->hProcess, EnumModules, &modList);
|
||||
int modcount = (int)modList.size();
|
||||
if(!modcount)
|
||||
return;
|
||||
|
||||
// Skip loading if there aren't any found modules
|
||||
if(modList.size() <= 0)
|
||||
return;
|
||||
|
||||
// Backup the current symbol search path
|
||||
char oldSearchPath[MAX_PATH];
|
||||
|
||||
if(!SafeSymGetSearchPath(fdProcessInfo->hProcess, oldSearchPath, MAX_PATH))
|
||||
char szOldSearchPath[MAX_PATH] = "";
|
||||
if(!SafeSymGetSearchPath(fdProcessInfo->hProcess, szOldSearchPath, MAX_PATH)) //backup current path
|
||||
{
|
||||
dputs("SymGetSearchPath failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the custom server path and directory
|
||||
char customSearchPath[MAX_PATH * 2];
|
||||
sprintf_s(customSearchPath, "SRV*%s*%s", szSymbolCachePath, SymbolStore);
|
||||
|
||||
if(!SafeSymSetSearchPath(fdProcessInfo->hProcess, customSearchPath))
|
||||
char szServerSearchPath[MAX_PATH * 2] = "";
|
||||
sprintf_s(szServerSearchPath, "SRV*%s*%s", szSymbolCachePath, szSymbolStore);
|
||||
if(!SafeSymSetSearchPath(fdProcessInfo->hProcess, szServerSearchPath)) //update search path
|
||||
{
|
||||
dputs("SymSetSearchPath (1) failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Reload
|
||||
for(auto & module : modList)
|
||||
for(int i = 0; i < modcount; i++) //reload all modules
|
||||
{
|
||||
dprintf("Downloading symbols for %s...\n", module.name);
|
||||
|
||||
wchar_t modulePath[MAX_PATH];
|
||||
if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)module.base, modulePath, MAX_PATH))
|
||||
dprintf("downloading symbols for %s...\n", modList.at(i).name);
|
||||
uint modbase = modList.at(i).base;
|
||||
wchar_t szModulePath[MAX_PATH] = L"";
|
||||
if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbase, szModulePath, MAX_PATH))
|
||||
{
|
||||
dprintf("GetModuleFileNameExW("fhex") failed!\n", module.base);
|
||||
dprintf("GetModuleFileNameExW("fhex") failed!\n", modbase);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)module.base))
|
||||
if(!SafeSymUnloadModule64(fdProcessInfo->hProcess, (DWORD64)modbase))
|
||||
{
|
||||
dprintf("SymUnloadModule64("fhex") failed!\n", module.base);
|
||||
dprintf("SymUnloadModule64("fhex") failed!\n", modbase);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!SafeSymLoadModuleEx(fdProcessInfo->hProcess, 0, StringUtils::Utf16ToUtf8(modulePath).c_str(), 0, (DWORD64)module.base, 0, 0, 0))
|
||||
if(!SafeSymLoadModuleEx(fdProcessInfo->hProcess, 0, StringUtils::Utf16ToUtf8(szModulePath).c_str(), 0, (DWORD64)modbase, 0, 0, 0))
|
||||
{
|
||||
dprintf("SymLoadModuleEx("fhex") failed!\n", module.base);
|
||||
dprintf("SymLoadModuleEx("fhex") failed!\n", modbase);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the old search path
|
||||
if(!SafeSymSetSearchPath(fdProcessInfo->hProcess, oldSearchPath))
|
||||
if(!SafeSymSetSearchPath(fdProcessInfo->hProcess, szOldSearchPath)) //restore search path
|
||||
{
|
||||
dputs("SymSetSearchPath (2) failed!");
|
||||
}
|
||||
}
|
||||
|
||||
bool SymAddrFromName(const char* Name, uint* Address)
|
||||
bool symfromname(const char* name, uint* addr)
|
||||
{
|
||||
if(!Name || Name[0] == '\0')
|
||||
if(!name or !strlen(name) or !addr or !_strnicmp(name, "ordinal", 7)) //skip 'OrdinalXXX'
|
||||
return false;
|
||||
|
||||
if(!Address)
|
||||
return false;
|
||||
|
||||
// Skip 'OrdinalXXX'
|
||||
if(!_strnicmp(Name, "Ordinal", 7))
|
||||
return false;
|
||||
|
||||
// According to MSDN:
|
||||
// Note that the total size of the data is the SizeOfStruct + (MaxNameLen - 1) * sizeof(TCHAR)
|
||||
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
|
||||
|
||||
PSYMBOL_INFO symbol = (PSYMBOL_INFO)&buffer;
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
symbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
|
||||
if(!SafeSymFromName(fdProcessInfo->hProcess, Name, symbol))
|
||||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
if(!SafeSymFromName(fdProcessInfo->hProcess, name, pSymbol))
|
||||
return false;
|
||||
|
||||
*Address = (uint)symbol->Address;
|
||||
*addr = (uint)pSymbol->Address;
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* SymGetSymbolicName(uint Address)
|
||||
const char* symgetsymbolicname(uint addr)
|
||||
{
|
||||
//
|
||||
// This resolves an address to a module and symbol:
|
||||
// [modname.]symbolname
|
||||
//
|
||||
char label[MAX_SYM_NAME];
|
||||
|
||||
// User labels have priority, but if one wasn't found,
|
||||
// default to a symbol lookup
|
||||
if(!labelget(Address, label))
|
||||
//[modname.]symbolname
|
||||
static char symbolicname[MAX_MODULE_SIZE + MAX_SYM_NAME] = "";
|
||||
char label[MAX_SYM_NAME] = "";
|
||||
bool retval = false;
|
||||
if(labelget(addr, label)) //user labels have priority
|
||||
retval = true;
|
||||
else //no user labels
|
||||
{
|
||||
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
|
||||
|
||||
PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
symbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
|
||||
// Perform a symbol lookup
|
||||
DWORD64 displacement = 0;
|
||||
|
||||
if(!SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)Address, &displacement, symbol))
|
||||
return nullptr;
|
||||
|
||||
// If the symbol wasn't at offset 0 (start from the beginning) ignore it
|
||||
if(displacement != 0)
|
||||
return nullptr;
|
||||
|
||||
// Terminate the string for sanity
|
||||
symbol->Name[symbol->MaxNameLen - 1] = '\0';
|
||||
|
||||
if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(symbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
strcpy_s(label, symbol->Name);
|
||||
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
|
||||
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
pSymbol->MaxNameLen = MAX_LABEL_SIZE;
|
||||
if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement)
|
||||
{
|
||||
pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0';
|
||||
if(!bUndecorateSymbolNames or !SafeUnDecorateSymbolName(pSymbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE))
|
||||
strcpy_s(label, pSymbol->Name);
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: FIXME: STATIC VARIABLE
|
||||
static char symbolicname[MAX_MODULE_SIZE + MAX_SYM_NAME];
|
||||
char modname[MAX_MODULE_SIZE];
|
||||
|
||||
if(ModNameFromAddr(Address, modname, false))
|
||||
sprintf_s(symbolicname, "%s.%s", modname, label);
|
||||
else
|
||||
sprintf_s(symbolicname, "<%s>", label);
|
||||
|
||||
return symbolicname;
|
||||
if(retval)
|
||||
{
|
||||
char modname[MAX_MODULE_SIZE] = "";
|
||||
if(modnamefromaddr(addr, modname, false))
|
||||
sprintf(symbolicname, "%s.%s", modname, label);
|
||||
else
|
||||
sprintf(symbolicname, "<%s>", label);
|
||||
return symbolicname;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#pragma once
|
||||
#ifndef _SYMBOLINFO_H
|
||||
#define _SYMBOLINFO_H
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
void SymEnum(uint Base, CBSYMBOLENUM EnumCallback, void* UserData);
|
||||
bool SymGetModuleList(std::vector<SYMBOLMODULEINFO>* List);
|
||||
void SymUpdateModuleList();
|
||||
void SymDownloadAllSymbols(const char* SymbolStore);
|
||||
bool SymAddrFromName(const char* Name, uint* Address);
|
||||
const char* SymGetSymbolicName(uint Address);
|
||||
void symenum(uint base, CBSYMBOLENUM cbSymbolEnum, void* user);
|
||||
void symupdatemodulelist();
|
||||
void symdownloadallsymbols(const char* szSymbolStore);
|
||||
bool symfromname(const char* name, uint* addr);
|
||||
const char* symgetsymbolicname(uint addr);
|
||||
|
||||
#endif //_SYMBOLINFO_H
|
||||
|
|
|
@ -5,251 +5,151 @@
|
|||
#include "threading.h"
|
||||
|
||||
static std::vector<THREADINFO> threadList;
|
||||
static int threadNum;
|
||||
static int currentThread;
|
||||
|
||||
void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
||||
void threadcreate(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
||||
{
|
||||
THREADINFO curInfo;
|
||||
memset(&curInfo, 0, sizeof(THREADINFO));
|
||||
|
||||
curInfo.ThreadNumber = ThreadGetCount();
|
||||
curInfo.Handle = CreateThread->hThread;
|
||||
curInfo.ThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId;
|
||||
curInfo.ThreadStartAddress = (uint)CreateThread->lpStartAddress;
|
||||
curInfo.ThreadLocalBase = (uint)CreateThread->lpThreadLocalBase;
|
||||
|
||||
// The first thread (#0) is always the main program thread
|
||||
if(curInfo.ThreadNumber <= 0)
|
||||
curInfo.ThreadNumber = threadNum;
|
||||
curInfo.hThread = CreateThread->hThread;
|
||||
curInfo.dwThreadId = ((DEBUG_EVENT*)GetDebugData())->dwThreadId;
|
||||
curInfo.ThreadStartAddress = (uint)CreateThread->lpStartAddress;
|
||||
curInfo.ThreadLocalBase = (uint)CreateThread->lpThreadLocalBase;
|
||||
*curInfo.threadName = '\0';
|
||||
if(!threadNum)
|
||||
strcpy_s(curInfo.threadName, "Main Thread");
|
||||
|
||||
// Modify global thread list
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
threadList.push_back(curInfo);
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
// Notify GUI
|
||||
threadNum++;
|
||||
locker.unlock(); //prevent possible deadlocks
|
||||
GuiUpdateThreadView();
|
||||
}
|
||||
|
||||
void ThreadExit(DWORD dwThreadId)
|
||||
void threadexit(DWORD dwThreadId)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
|
||||
// Don't use a foreach loop here because of the erase() call
|
||||
for(auto itr = threadList.begin(); itr != threadList.end(); itr++)
|
||||
{
|
||||
if(itr->ThreadId == dwThreadId)
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(threadList.at(i).dwThreadId == dwThreadId)
|
||||
{
|
||||
threadList.erase(itr);
|
||||
threadList.erase(threadList.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EXCLUSIVE_RELEASE();
|
||||
locker.unlock(); //prevent possible deadlocks
|
||||
GuiUpdateThreadView();
|
||||
}
|
||||
|
||||
void ThreadClear()
|
||||
void threadclear()
|
||||
{
|
||||
// Clear the current array of threads
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
threadList.clear();
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
// Update the GUI's list
|
||||
threadNum = 0;
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
std::vector<THREADINFO>().swap(threadList);
|
||||
locker.unlock(); //prevent possible deadlocks
|
||||
GuiUpdateThreadView();
|
||||
}
|
||||
|
||||
int ThreadGetCount()
|
||||
static THREADWAITREASON GetThreadWaitReason(DWORD dwThreadId)
|
||||
{
|
||||
SHARED_ACQUIRE(LockThreads);
|
||||
return (int)threadList.size();
|
||||
}
|
||||
|
||||
void ThreadGetList(THREADLIST* list)
|
||||
{
|
||||
SHARED_ACQUIRE(LockThreads);
|
||||
|
||||
//
|
||||
// This function converts a C++ std::vector to a C-style THREADLIST[]
|
||||
// Also assume BridgeAlloc zeros the returned buffer
|
||||
//
|
||||
size_t count = threadList.size();
|
||||
|
||||
if(count <= 0)
|
||||
return;
|
||||
|
||||
list->count = (int)count;
|
||||
list->list = (THREADALLINFO*)BridgeAlloc(count * sizeof(THREADALLINFO));
|
||||
|
||||
// Fill out the list data
|
||||
for(size_t i = 0; i < count; i++)
|
||||
{
|
||||
HANDLE threadHandle = threadList[i].Handle;
|
||||
|
||||
// Get the debugger's current thread index
|
||||
if(threadHandle == hActiveThread)
|
||||
list->CurrentThread = (int)i;
|
||||
|
||||
memcpy(&list->list[i].BasicInfo, &threadList[i], sizeof(THREADINFO));
|
||||
|
||||
list->list[i].ThreadCip = GetContextDataEx(threadHandle, UE_CIP);
|
||||
list->list[i].SuspendCount = ThreadGetSuspendCount(threadHandle);
|
||||
list->list[i].Priority = ThreadGetPriority(threadHandle);
|
||||
list->list[i].WaitReason = ThreadGetWaitReason(threadHandle);
|
||||
list->list[i].LastError = ThreadGetLastError(list->list[i].BasicInfo.ThreadLocalBase);
|
||||
}
|
||||
}
|
||||
|
||||
bool ThreadIsValid(DWORD dwThreadId)
|
||||
{
|
||||
SHARED_ACQUIRE(LockThreads);
|
||||
|
||||
for(auto & entry : threadList)
|
||||
{
|
||||
if(entry.ThreadId == dwThreadId)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ThreadGetTeb(uint TEBAddress, TEB* Teb)
|
||||
{
|
||||
//
|
||||
// TODO: Keep a cached copy inside the vector
|
||||
//
|
||||
memset(Teb, 0, sizeof(TEB));
|
||||
|
||||
return MemRead((void*)TEBAddress, Teb, sizeof(TEB), nullptr);
|
||||
}
|
||||
|
||||
int ThreadGetSuspendCount(HANDLE Thread)
|
||||
{
|
||||
//
|
||||
// Suspend a thread in order to get the previous suspension count
|
||||
// WARNING: This function is very bad (threads should not be randomly interrupted)
|
||||
//
|
||||
int suspendCount = (int)SuspendThread(Thread);
|
||||
|
||||
if(suspendCount == -1)
|
||||
return 0;
|
||||
|
||||
// Resume the thread's normal execution
|
||||
ResumeThread(Thread);
|
||||
|
||||
return suspendCount;
|
||||
}
|
||||
|
||||
THREADPRIORITY ThreadGetPriority(HANDLE Thread)
|
||||
{
|
||||
return (THREADPRIORITY)GetThreadPriority(Thread);
|
||||
}
|
||||
|
||||
THREADWAITREASON ThreadGetWaitReason(HANDLE Thread)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Thread);
|
||||
|
||||
// TODO: Implement this
|
||||
//TODO: implement this
|
||||
return _Executive;
|
||||
}
|
||||
|
||||
DWORD ThreadGetLastError(uint tebAddress)
|
||||
static DWORD GetThreadLastError(uint tebAddress)
|
||||
{
|
||||
TEB teb;
|
||||
if(!ThreadGetTeb(tebAddress, &teb))
|
||||
{
|
||||
// TODO: Assert (Why would the TEB fail?)
|
||||
memset(&teb, 0, sizeof(TEB));
|
||||
if(!memread(fdProcessInfo->hProcess, (void*)tebAddress, &teb, sizeof(TEB), 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return teb.LastErrorValue;
|
||||
}
|
||||
|
||||
bool ThreadSetName(DWORD dwThreadId, const char* name)
|
||||
void threadgetlist(THREADLIST* list)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockThreads);
|
||||
|
||||
// Modifies a variable (name), so an exclusive lock is required
|
||||
for(auto & entry : threadList)
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
int count = (int)threadList.size();
|
||||
list->count = count;
|
||||
if(!count)
|
||||
return;
|
||||
list->list = (THREADALLINFO*)BridgeAlloc(count * sizeof(THREADALLINFO));
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
if(entry.ThreadId == dwThreadId)
|
||||
{
|
||||
if(!name)
|
||||
name = "";
|
||||
|
||||
strcpy_s(entry.threadName, name);
|
||||
return true;
|
||||
}
|
||||
if(hActiveThread == threadList.at(i).hThread)
|
||||
currentThread = i;
|
||||
memset(&list->list[i], 0, sizeof(THREADALLINFO));
|
||||
memcpy(&list->list[i].BasicInfo, &threadList.at(i), sizeof(THREADINFO));
|
||||
HANDLE hThread = list->list[i].BasicInfo.hThread;
|
||||
list->list[i].ThreadCip = GetContextDataEx(hThread, UE_CIP);
|
||||
list->list[i].SuspendCount = SuspendThread(hThread);
|
||||
ResumeThread(hThread);
|
||||
list->list[i].Priority = (THREADPRIORITY)GetThreadPriority(list->list[i].BasicInfo.hThread);
|
||||
list->list[i].WaitReason = GetThreadWaitReason(list->list[i].BasicInfo.dwThreadId);
|
||||
list->list[i].LastError = GetThreadLastError(list->list[i].BasicInfo.ThreadLocalBase);
|
||||
}
|
||||
list->CurrentThread = currentThread;
|
||||
}
|
||||
|
||||
bool threadisvalid(DWORD dwThreadId)
|
||||
{
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(threadList.at(i).dwThreadId == dwThreadId)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE ThreadGetHandle(DWORD dwThreadId)
|
||||
bool threadsetname(DWORD dwThreadId, const char* name)
|
||||
{
|
||||
SHARED_ACQUIRE(LockThreads);
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(threadList.at(i).dwThreadId == dwThreadId)
|
||||
{
|
||||
if(name)
|
||||
strcpy_s(threadList.at(i).threadName, name);
|
||||
else
|
||||
*threadList.at(i).threadName = '\0';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for(auto & entry : threadList)
|
||||
{
|
||||
if(entry.ThreadId == dwThreadId)
|
||||
return entry.Handle;
|
||||
}
|
||||
|
||||
// TODO: Set an assert if the handle is never found,
|
||||
// using a bad handle causes random/silent issues everywhere
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD ThreadGetId(HANDLE hThread)
|
||||
DWORD threadgetid(HANDLE hThread)
|
||||
{
|
||||
SHARED_ACQUIRE(LockThreads);
|
||||
|
||||
// Search for the ID in the local list
|
||||
for(auto & entry : threadList)
|
||||
{
|
||||
if(entry.Handle == hThread)
|
||||
return entry.ThreadId;
|
||||
}
|
||||
|
||||
// Wasn't found, check with Windows
|
||||
// NOTE: Requires VISTA+
|
||||
DWORD id = GetThreadId(hThread);
|
||||
|
||||
// Returns 0 on error;
|
||||
// TODO: Same problem with ThreadGetHandle()
|
||||
return id;
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(threadList.at(i).hThread == hThread)
|
||||
return threadList.at(i).dwThreadId;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ThreadSuspendAll()
|
||||
int threadgetcount()
|
||||
{
|
||||
//
|
||||
// SuspendThread does not modify any internal variables
|
||||
//
|
||||
SHARED_ACQUIRE(LockThreads);
|
||||
return (int)threadList.size();
|
||||
}
|
||||
|
||||
int threadsuspendall()
|
||||
{
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
int count = 0;
|
||||
for(auto & entry : threadList)
|
||||
{
|
||||
if(SuspendThread(entry.Handle) != -1)
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(SuspendThread(threadList.at(i).hThread) != -1)
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int ThreadResumeAll()
|
||||
int threadresumeall()
|
||||
{
|
||||
//
|
||||
// ResumeThread does not modify any internal variables
|
||||
//
|
||||
SHARED_ACQUIRE(LockThreads);
|
||||
|
||||
CriticalSectionLocker locker(LockThreads);
|
||||
int count = 0;
|
||||
for(auto & entry : threadList)
|
||||
{
|
||||
if(ResumeThread(entry.Handle) != -1)
|
||||
for(unsigned int i = 0; i < threadList.size(); i++)
|
||||
if(ResumeThread(threadList.at(i).hThread) != -1)
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
|
@ -1,22 +1,20 @@
|
|||
#pragma once
|
||||
#ifndef _THREAD_H
|
||||
#define _THREAD_H
|
||||
|
||||
#include "_global.h"
|
||||
#include "debugger.h"
|
||||
|
||||
void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread);
|
||||
void ThreadExit(DWORD dwThreadId);
|
||||
void ThreadClear();
|
||||
int ThreadGetCount();
|
||||
void ThreadGetList(THREADLIST* list);
|
||||
bool ThreadIsValid(DWORD dwThreadId);
|
||||
bool ThreadSetName(DWORD dwTHreadId, const char* name);
|
||||
bool ThreadGetTeb(uint TEBAddress, TEB* Teb);
|
||||
int ThreadGetSuspendCount(HANDLE Thread);
|
||||
THREADPRIORITY ThreadGetPriority(HANDLE Thread);
|
||||
THREADWAITREASON ThreadGetWaitReason(HANDLE Thread);
|
||||
DWORD ThreadGetLastError(uint tebAddress);
|
||||
bool ThreadSetName(DWORD dwThreadId, const char* name);
|
||||
HANDLE ThreadGetHandle(DWORD dwThreadId);
|
||||
DWORD ThreadGetId(HANDLE hThread);
|
||||
int ThreadSuspendAll();
|
||||
int ThreadResumeAll();
|
||||
//functions
|
||||
void threadcreate(CREATE_THREAD_DEBUG_INFO* CreateThread);
|
||||
void threadexit(DWORD dwThreadId);
|
||||
void threadclear();
|
||||
void threadgetlist(THREADLIST* list);
|
||||
bool threadisvalid(DWORD dwThreadId);
|
||||
bool threadsetname(DWORD dwTHreadId, const char* name);
|
||||
HANDLE threadgethandle(DWORD dwThreadId);
|
||||
DWORD threadgetid(HANDLE hThread);
|
||||
int threadgetcount();
|
||||
int threadsuspendall();
|
||||
int threadresumeall();
|
||||
|
||||
#endif //_THREAD_H
|
||||
|
|
|
@ -28,37 +28,53 @@ bool waitislocked(WAIT_ID id)
|
|||
return waitarray[id];
|
||||
}
|
||||
|
||||
bool SectionLockerGlobal::m_Initialized = false;
|
||||
SRWLOCK SectionLockerGlobal::m_Locks[SectionLock::LockLast];
|
||||
CRITICAL_SECTION CriticalSectionLocker::locks[LockLast] = {};
|
||||
bool CriticalSectionLocker::bInitDone = false;
|
||||
|
||||
void SectionLockerGlobal::Initialize()
|
||||
void CriticalSectionLocker::Initialize()
|
||||
{
|
||||
if(m_Initialized)
|
||||
if(bInitDone)
|
||||
return;
|
||||
|
||||
// Destroy previous data if any existed
|
||||
memset(m_Locks, 0, sizeof(m_Locks));
|
||||
|
||||
for(int i = 0; i < ARRAYSIZE(m_Locks); i++)
|
||||
InitializeSRWLock(&m_Locks[i]);
|
||||
|
||||
m_Initialized = true;
|
||||
for(int i = 0; i < LockLast; i++)
|
||||
InitializeCriticalSection(&locks[i]);
|
||||
bInitDone = true;
|
||||
}
|
||||
|
||||
void SectionLockerGlobal::Deinitialize()
|
||||
void CriticalSectionLocker::Deinitialize()
|
||||
{
|
||||
if(!m_Initialized)
|
||||
if(!bInitDone)
|
||||
return;
|
||||
|
||||
for(int i = 0; i < ARRAYSIZE(m_Locks); i++)
|
||||
for(int i = 0; i < LockLast; i++)
|
||||
{
|
||||
// Wait for the lock's ownership to be released
|
||||
AcquireSRWLockExclusive(&m_Locks[i]);
|
||||
ReleaseSRWLockExclusive(&m_Locks[i]);
|
||||
|
||||
// Invalidate data
|
||||
memset(&m_Locks[i], 0, sizeof(SRWLOCK));
|
||||
EnterCriticalSection(&locks[i]); //obtain ownership
|
||||
DeleteCriticalSection(&locks[i]);
|
||||
}
|
||||
bInitDone = false;
|
||||
}
|
||||
|
||||
m_Initialized = false;
|
||||
CriticalSectionLocker::CriticalSectionLocker(CriticalSectionLock lock)
|
||||
{
|
||||
Initialize(); //initialize critical sections
|
||||
gLock = lock;
|
||||
|
||||
EnterCriticalSection(&locks[gLock]);
|
||||
Locked = true;
|
||||
}
|
||||
|
||||
CriticalSectionLocker::~CriticalSectionLocker()
|
||||
{
|
||||
if(Locked)
|
||||
LeaveCriticalSection(&locks[gLock]);
|
||||
}
|
||||
|
||||
void CriticalSectionLocker::unlock()
|
||||
{
|
||||
Locked = false;
|
||||
LeaveCriticalSection(&locks[gLock]);
|
||||
}
|
||||
|
||||
void CriticalSectionLocker::relock()
|
||||
{
|
||||
EnterCriticalSection(&locks[gLock]);
|
||||
Locked = true;
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
#pragma once
|
||||
#ifndef _THREADING_H
|
||||
#define _THREADING_H
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
//enums
|
||||
enum WAIT_ID
|
||||
{
|
||||
WAITID_RUN,
|
||||
|
@ -16,22 +18,7 @@ void lock(WAIT_ID id);
|
|||
void unlock(WAIT_ID id);
|
||||
bool waitislocked(WAIT_ID id);
|
||||
|
||||
//
|
||||
// THREAD SYNCHRONIZATION
|
||||
//
|
||||
// Better, but requires VISTA+
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa904937%28v=vs.85%29.aspx
|
||||
//
|
||||
#define CriticalSectionLocker
|
||||
#define locker(x) EXCLUSIVE_ACQUIRE(x)
|
||||
|
||||
#define EXCLUSIVE_ACQUIRE(Index) SectionLocker<SectionLock::##Index, false> __ThreadLock;
|
||||
#define EXCLUSIVE_RELEASE() __ThreadLock.Unlock();
|
||||
|
||||
#define SHARED_ACQUIRE(Index) SectionLocker<SectionLock::##Index, true> __SThreadLock;
|
||||
#define SHARED_RELEASE() __SThreadLock.Unlock();
|
||||
|
||||
enum SectionLock
|
||||
enum CriticalSectionLock
|
||||
{
|
||||
LockMemoryPages,
|
||||
LockVariables,
|
||||
|
@ -45,75 +32,26 @@ enum SectionLock
|
|||
LockPatches,
|
||||
LockThreads,
|
||||
LockDprintf,
|
||||
LockSym,
|
||||
|
||||
// This is defined because of a bug in the Windows 8.1 kernel;
|
||||
// Calling VirtualQuery/VirtualProtect/ReadProcessMemory can and will cause
|
||||
// a deadlock.
|
||||
// https://bitbucket.org/mrexodia/x64_dbg/issue/247/x64-dbg-bug-string-references-function
|
||||
LockWin8Workaround,
|
||||
|
||||
LockLast,
|
||||
LockSym,
|
||||
LockLast
|
||||
};
|
||||
|
||||
class SectionLockerGlobal
|
||||
class CriticalSectionLocker
|
||||
{
|
||||
template<SectionLock LockIndex, bool Shared> friend class SectionLocker;
|
||||
|
||||
public:
|
||||
static void Initialize();
|
||||
static void Deinitialize();
|
||||
CriticalSectionLocker(CriticalSectionLock lock);
|
||||
~CriticalSectionLocker();
|
||||
void unlock();
|
||||
void relock();
|
||||
|
||||
private:
|
||||
static bool m_Initialized;
|
||||
static SRWLOCK m_Locks[SectionLock::LockLast];
|
||||
static void Initialize();
|
||||
static bool bInitDone;
|
||||
static CRITICAL_SECTION locks[LockLast];
|
||||
|
||||
CriticalSectionLock gLock;
|
||||
bool Locked;
|
||||
};
|
||||
|
||||
template<SectionLock LockIndex, bool Shared>
|
||||
class SectionLocker
|
||||
{
|
||||
public:
|
||||
SectionLocker()
|
||||
{
|
||||
m_LockCount = 0;
|
||||
Lock();
|
||||
}
|
||||
|
||||
~SectionLocker()
|
||||
{
|
||||
if(m_LockCount > 0)
|
||||
Unlock();
|
||||
|
||||
#ifdef _DEBUG
|
||||
// TODO: Assert that the lock count is zero on destructor
|
||||
if (m_LockCount > 0)
|
||||
__debugbreak();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void Lock()
|
||||
{
|
||||
if(Shared)
|
||||
AcquireSRWLockShared(&Internal::m_Locks[LockIndex]);
|
||||
else
|
||||
AcquireSRWLockExclusive(&Internal::m_Locks[LockIndex]);
|
||||
|
||||
m_LockCount++;
|
||||
}
|
||||
|
||||
inline void Unlock()
|
||||
{
|
||||
m_LockCount--;
|
||||
|
||||
if(Shared)
|
||||
ReleaseSRWLockShared(&Internal::m_Locks[LockIndex]);
|
||||
else
|
||||
ReleaseSRWLockExclusive(&Internal::m_Locks[LockIndex]);
|
||||
}
|
||||
|
||||
private:
|
||||
using Internal = SectionLockerGlobal;
|
||||
|
||||
protected:
|
||||
BYTE m_LockCount;
|
||||
};
|
||||
#endif // _THREADING_H
|
||||
|
|
|
@ -1189,7 +1189,7 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
|
|||
SELECTIONDATA seldata;
|
||||
memset(&seldata, 0, sizeof(seldata));
|
||||
GuiSelectionGet(GUI_DISASSEMBLY, &seldata);
|
||||
if(!ModNameFromAddr(seldata.start, modname, true))
|
||||
if(!modnamefromaddr(seldata.start, modname, true))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -1200,7 +1200,7 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print
|
|||
apiname++;
|
||||
if(!strlen(apiname))
|
||||
return false;
|
||||
uint modbase = ModBaseFromName(modname);
|
||||
uint modbase = modbasefromname(modname);
|
||||
wchar_t szModName[MAX_PATH] = L"";
|
||||
if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbase, szModName, MAX_PATH))
|
||||
{
|
||||
|
@ -1477,7 +1477,7 @@ bool valfromstring(const char* string, uint* value, bool silent, bool baseonly,
|
|||
return false;
|
||||
uint addr = *value;
|
||||
*value = 0;
|
||||
if(!MemRead((void*)addr, value, read_size, 0))
|
||||
if(!memread(fdProcessInfo->hProcess, (void*)addr, value, read_size, 0))
|
||||
{
|
||||
if(!silent)
|
||||
dputs("failed to read memory");
|
||||
|
@ -1559,7 +1559,7 @@ bool valfromstring(const char* string, uint* value, bool silent, bool baseonly,
|
|||
return true;
|
||||
else if(labelfromstring(string, value)) //then come labels
|
||||
return true;
|
||||
else if(SymAddrFromName(string, value)) //then come symbols
|
||||
else if(symfromname(string, value)) //then come symbols
|
||||
return true;
|
||||
else if(varget(string, value, value_size, 0)) //finally variables
|
||||
{
|
||||
|
@ -2025,7 +2025,7 @@ bool valtostring(const char* string, uint* value, bool silent)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
if(!MemPatch((void*)temp, value, read_size, 0))
|
||||
if(!mempatch(fdProcessInfo->hProcess, (void*)temp, value, read_size, 0))
|
||||
{
|
||||
if(!silent)
|
||||
dputs("failed to write memory");
|
||||
|
@ -2094,7 +2094,7 @@ bool valtostring(const char* string, uint* value, bool silent)
|
|||
uint valfileoffsettova(const char* modname, uint offset)
|
||||
{
|
||||
char modpath[MAX_PATH] = "";
|
||||
if(ModPathFromName(modname, modpath, MAX_PATH))
|
||||
if(modpathfromname(modname, modpath, MAX_PATH))
|
||||
{
|
||||
HANDLE FileHandle;
|
||||
DWORD LoadedSize;
|
||||
|
@ -2106,7 +2106,7 @@ uint valfileoffsettova(const char* modname, uint offset)
|
|||
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 offset < LoadedSize ? (duint)rva + modbasefromname(modname) : 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -2115,7 +2115,7 @@ uint valfileoffsettova(const char* modname, uint offset)
|
|||
uint valvatofileoffset(uint va)
|
||||
{
|
||||
char modpath[MAX_PATH] = "";
|
||||
if(ModPathFromAddr(va, modpath, MAX_PATH))
|
||||
if(modpathfromaddr(va, modpath, MAX_PATH))
|
||||
{
|
||||
HANDLE FileHandle;
|
||||
DWORD LoadedSize;
|
||||
|
@ -2123,7 +2123,7 @@ uint valvatofileoffset(uint va)
|
|||
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);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -6,36 +6,30 @@ static VAR* vars;
|
|||
|
||||
static void varsetvalue(VAR* var, VAR_VALUE* value)
|
||||
{
|
||||
// VAR_STRING needs to be freed before destroying it
|
||||
if(var->value.type == VAR_STRING)
|
||||
switch(var->value.type)
|
||||
{
|
||||
case VAR_STRING:
|
||||
var->value.u.data->clear();
|
||||
delete var->value.u.data;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Replace all information in the struct
|
||||
memcpy(&var->value, value, sizeof(VAR_VALUE));
|
||||
}
|
||||
|
||||
static bool varset(const char* name, VAR_VALUE* value, bool setreadonly)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockVariables);
|
||||
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
String name_;
|
||||
if(*name != '$')
|
||||
name_ = "$";
|
||||
name_ += name;
|
||||
VariableMap::iterator found = variables.find(name_);
|
||||
if(found == variables.end()) //not found
|
||||
if(found == variables.end()) //not found
|
||||
return false;
|
||||
if(found->second.alias.length())
|
||||
{
|
||||
// Release the lock (potential deadlock here)
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
return varset(found->second.alias.c_str(), value, setreadonly);
|
||||
}
|
||||
|
||||
if(!setreadonly && (found->second.type == VAR_READONLY || found->second.type == VAR_HIDDEN))
|
||||
return false;
|
||||
varsetvalue(&found->second, value);
|
||||
|
@ -45,55 +39,39 @@ static bool varset(const char* name, VAR_VALUE* value, bool setreadonly)
|
|||
void varinit()
|
||||
{
|
||||
varfree();
|
||||
|
||||
// General variables
|
||||
//General variables
|
||||
varnew("$result\1$res", 0, VAR_SYSTEM);
|
||||
varnew("$result1\1$res1", 0, VAR_SYSTEM);
|
||||
varnew("$result2\1$res2", 0, VAR_SYSTEM);
|
||||
varnew("$result3\1$res3", 0, VAR_SYSTEM);
|
||||
varnew("$result4\1$res4", 0, VAR_SYSTEM);
|
||||
|
||||
// InitDebug variables
|
||||
varnew("$hProcess\1$hp", 0, VAR_READONLY); // Process handle
|
||||
varnew("$pid", 0, VAR_READONLY); // Process ID
|
||||
|
||||
// Hidden variables
|
||||
//InitDebug variables
|
||||
varnew("$hProcess\1$hp", 0, VAR_READONLY);
|
||||
varnew("$pid", 0, VAR_READONLY);
|
||||
//hidden variables
|
||||
varnew("$ans\1$an", 0, VAR_HIDDEN);
|
||||
|
||||
// Read-only variables
|
||||
varnew("$lastalloc", 0, VAR_READONLY); // Last memory allocation
|
||||
varnew("$_EZ_FLAG", 0, VAR_READONLY); // Equal/zero flag for internal use (1=equal, 0=unequal)
|
||||
varnew("$_BS_FLAG", 0, VAR_READONLY); // Bigger/smaller flag for internal use (1=bigger, 0=smaller)
|
||||
//read-only variables
|
||||
varnew("$lastalloc", 0, VAR_READONLY);
|
||||
varnew("$_EZ_FLAG", 0, VAR_READONLY); //equal/zero flag for internal use (1=equal, 0=unequal)
|
||||
varnew("$_BS_FLAG", 0, VAR_READONLY); //bigger/smaller flag for internal use (1=bigger, 0=smaller)
|
||||
}
|
||||
|
||||
void varfree()
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockVariables);
|
||||
|
||||
// Each variable must be deleted manually; strings especially
|
||||
// because there are sub-allocations
|
||||
VAR_VALUE emptyValue;
|
||||
|
||||
for (auto& itr : variables)
|
||||
varsetvalue(&itr.second, &emptyValue);
|
||||
|
||||
// Now clear all vector elements
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
variables.clear();
|
||||
}
|
||||
|
||||
VAR* vargetptr()
|
||||
{
|
||||
// TODO: Implement this? Or remove it
|
||||
return nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool varnew(const char* name, uint value, VAR_TYPE type)
|
||||
{
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
if(!name)
|
||||
return false;
|
||||
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
|
||||
std::vector<String> names = StringUtils::Split(name, '\1');
|
||||
String firstName;
|
||||
for(int i = 0; i < (int)names.size(); i++)
|
||||
|
@ -122,8 +100,7 @@ bool varnew(const char* name, uint value, VAR_TYPE type)
|
|||
|
||||
static bool varget(const char* name, VAR_VALUE* value, int* size, VAR_TYPE* type)
|
||||
{
|
||||
SHARED_ACQUIRE(LockVariables);
|
||||
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
String name_;
|
||||
if(*name != '$')
|
||||
name_ = "$";
|
||||
|
@ -132,12 +109,7 @@ static bool varget(const char* name, VAR_VALUE* value, int* size, VAR_TYPE* type
|
|||
if(found == variables.end()) //not found
|
||||
return false;
|
||||
if(found->second.alias.length())
|
||||
{
|
||||
// Release the lock (potential deadlock here)
|
||||
SHARED_RELEASE();
|
||||
|
||||
return varget(found->second.alias.c_str(), value, size, type);
|
||||
}
|
||||
if(type)
|
||||
*type = found->second.type;
|
||||
if(size)
|
||||
|
@ -212,8 +184,7 @@ bool varset(const char* name, const char* string, bool setreadonly)
|
|||
|
||||
bool vardel(const char* name, bool delsystem)
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockVariables);
|
||||
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
String name_;
|
||||
if(*name != '$')
|
||||
name_ = "$";
|
||||
|
@ -222,13 +193,7 @@ bool vardel(const char* name, bool delsystem)
|
|||
if(found == variables.end()) //not found
|
||||
return false;
|
||||
if(found->second.alias.length())
|
||||
{
|
||||
// Release the lock (potential deadlock here)
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
return vardel(found->second.alias.c_str(), delsystem);
|
||||
}
|
||||
|
||||
if(!delsystem && found->second.type != VAR_USER)
|
||||
return false;
|
||||
found = variables.begin();
|
||||
|
@ -244,8 +209,7 @@ bool vardel(const char* name, bool delsystem)
|
|||
|
||||
bool vargettype(const char* name, VAR_TYPE* type, VAR_VALUE_TYPE* valtype)
|
||||
{
|
||||
SHARED_ACQUIRE(LockVariables);
|
||||
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
String name_;
|
||||
if(*name != '$')
|
||||
name_ = "$";
|
||||
|
@ -262,29 +226,18 @@ bool vargettype(const char* name, VAR_TYPE* type, VAR_VALUE_TYPE* valtype)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool varenum(VAR* List, size_t* Size)
|
||||
bool varenum(VAR* entries, size_t* cbsize)
|
||||
{
|
||||
// A list or size must be requested
|
||||
if(!List && !Size)
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
if(!entries && !cbsize || !variables.size())
|
||||
return false;
|
||||
|
||||
SHARED_ACQUIRE(LockVariables);
|
||||
|
||||
if(Size)
|
||||
if(!entries && cbsize)
|
||||
{
|
||||
// Size requested, so return it
|
||||
*Size = variables.size() * sizeof(VAR);
|
||||
|
||||
if(!List)
|
||||
return true;
|
||||
*cbsize = variables.size() * sizeof(VAR);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fill out all list entries
|
||||
for(auto & itr : variables)
|
||||
{
|
||||
*List = itr.second;
|
||||
List++;
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
for(VariableMap::iterator i = variables.begin(); i != variables.end(); ++i, j++)
|
||||
entries[j] = i->second;
|
||||
return true;
|
||||
}
|
|
@ -236,7 +236,6 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
|
|||
return "Invalid TITAN_ENGINE_CONTEXT_t alignment!";
|
||||
if(sizeof(TITAN_ENGINE_CONTEXT_t) != sizeof(REGISTERCONTEXT))
|
||||
return "Invalid REGISTERCONTEXT alignment!";
|
||||
SectionLockerGlobal::Initialize();
|
||||
dbginit();
|
||||
dbgfunctionsinit();
|
||||
json_set_alloc_funcs(emalloc_json, efree_json);
|
||||
|
@ -315,8 +314,7 @@ extern "C" DLL_EXPORT void _dbg_dbgexitsignal()
|
|||
}
|
||||
else
|
||||
DeleteFileA(alloctrace);
|
||||
|
||||
SectionLockerGlobal::Deinitialize();
|
||||
CriticalSectionLocker::Deinitialize();
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT bool _dbg_dbgcmddirectexec(const char* cmd)
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
|
@ -132,22 +124,10 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
@ -155,15 +135,9 @@
|
|||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
@ -171,37 +145,17 @@
|
|||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>x32_dbg</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\x32\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>x32_dbg</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\x64\</OutDir>
|
||||
<TargetName>x64_dbg</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\x64\</OutDir>
|
||||
<TargetName>x64_dbg</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;BUILD_DBG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<InterproceduralOptimization>MultiFile</InterproceduralOptimization>
|
||||
<OptimizeForWindowsApplication>true</OptimizeForWindowsApplication>
|
||||
<UseIntelOptimizedHeaders>true</UseIntelOptimizedHeaders>
|
||||
<GenerateAlternateCodePaths>AVXI</GenerateAlternateCodePaths>
|
||||
<LevelOfStaticAnalysis>None</LevelOfStaticAnalysis>
|
||||
<ModeOfStaticAnalysis>None</ModeOfStaticAnalysis>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
|
@ -212,45 +166,12 @@
|
|||
<AdditionalDependencies>lz4\lz4_x86.lib;jansson\jansson_x86.lib;DeviceNameResolver\DeviceNameResolver_x86.lib;XEDParse\XEDParse_x86.lib;$(SolutionDir)bin\x32\x32_bridge.lib;dbghelp\dbghelp_x86.lib;TitanEngine\TitanEngine_x86.lib;BeaEngine\BeaEngine.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;BUILD_DBG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<InterproceduralOptimization>NoIPO</InterproceduralOptimization>
|
||||
<OptimizeForWindowsApplication>false</OptimizeForWindowsApplication>
|
||||
<UseIntelOptimizedHeaders>true</UseIntelOptimizedHeaders>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>false</EnableCOMDATFolding>
|
||||
<OptimizeReferences>false</OptimizeReferences>
|
||||
<AdditionalDependencies>lz4\lz4_x86.lib;jansson\jansson_x86.lib;DeviceNameResolver\DeviceNameResolver_x86.lib;XEDParse\XEDParse_x86.lib;$(SolutionDir)bin\x32\x32_bridge.lib;dbghelp\dbghelp_x86.lib;TitanEngine\TitanEngine_x86.lib;BeaEngine\BeaEngine.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;BUILD_DBG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<InterproceduralOptimization>MultiFile</InterproceduralOptimization>
|
||||
<OptimizeForWindowsApplication>true</OptimizeForWindowsApplication>
|
||||
<UseIntelOptimizedHeaders>true</UseIntelOptimizedHeaders>
|
||||
<GenerateAlternateCodePaths>AVXI</GenerateAlternateCodePaths>
|
||||
<LevelOfStaticAnalysis>None</LevelOfStaticAnalysis>
|
||||
<ModeOfStaticAnalysis>None</ModeOfStaticAnalysis>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<UseProcessorExtensions>AVXI</UseProcessorExtensions>
|
||||
<CheckUndimensionedArrays>false</CheckUndimensionedArrays>
|
||||
<CheckPointers>None</CheckPointers>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
@ -260,29 +181,6 @@
|
|||
<AdditionalDependencies>lz4\lz4_x64.lib;jansson\jansson_x64.lib;DeviceNameResolver\DeviceNameResolver_x64.lib;XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64\x64_bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;BeaEngine\BeaEngine_64.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;BUILD_DBG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<InterproceduralOptimization>NoIPO</InterproceduralOptimization>
|
||||
<OptimizeForWindowsApplication>false</OptimizeForWindowsApplication>
|
||||
<UseIntelOptimizedHeaders>false</UseIntelOptimizedHeaders>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<CheckPointers>Rw</CheckPointers>
|
||||
<CheckDanglingPointers>None</CheckDanglingPointers>
|
||||
<CheckUndimensionedArrays>true</CheckUndimensionedArrays>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>false</EnableCOMDATFolding>
|
||||
<OptimizeReferences>false</OptimizeReferences>
|
||||
<AdditionalDependencies>lz4\lz4_x64.lib;jansson\jansson_x64.lib;DeviceNameResolver\DeviceNameResolver_x64.lib;XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64\x64_bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;BeaEngine\BeaEngine_64.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<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="Source Files\Interfaces/Exports">
|
||||
<UniqueIdentifier>{44fd9eb7-2017-49b8-8d9a-dec680632343}</UniqueIdentifier>
|
||||
</Filter>
|
||||
|
|
|
@ -5,19 +5,9 @@
|
|||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerCommand>$(OutDir)\x32_dbg.exe</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LocalDebuggerCommand>$(OutDir)\x64_dbg.exe</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerCommand>$(OutDir)\x64_dbg.exe</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1,14 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
|
@ -31,9 +23,6 @@
|
|||
<None Include="..\bug.ico" />
|
||||
<None Include="manifest.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="app.manifest" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{3A22175E-6B72-FDCC-1603-C4A2163C7900}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
|
@ -42,22 +31,10 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
@ -65,15 +42,9 @@
|
|||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
@ -82,25 +53,12 @@
|
|||
<TargetName>x32_dbg</TargetName>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\x32\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>x32_dbg</TargetName>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\x64\</OutDir>
|
||||
<TargetName>x64_dbg</TargetName>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\x64\</OutDir>
|
||||
<TargetName>x64_dbg</TargetName>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -120,25 +78,6 @@
|
|||
</AdditionalManifestDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>$(SolutionDir)bin\x32\x32_bridge.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ProgramDatabaseFile>$(TargetDir)$(TargetName)_exe.pdb</ProgramDatabaseFile>
|
||||
<AdditionalManifestDependencies>
|
||||
</AdditionalManifestDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -157,24 +96,6 @@
|
|||
</AdditionalManifestDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>$(SolutionDir)bin\x64\x64_bridge.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ProgramDatabaseFile>$(TargetDir)$(TargetName)_exe.pdb</ProgramDatabaseFile>
|
||||
<AdditionalManifestDependencies>
|
||||
</AdditionalManifestDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
|
|
@ -35,7 +35,4 @@
|
|||
</None>
|
||||
<None Include="manifest.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="app.manifest" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -32,7 +32,6 @@ AbstractTableView::AbstractTableView(QWidget* parent) : QAbstractScrollArea(pare
|
|||
setVerticalScrollBar(new AbstractTableScrollBar(verticalScrollBar()));
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
memset(&mScrollBarAttributes, 0, sizeof(mScrollBarAttributes));
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
horizontalScrollBar()->setRange(0, 0);
|
||||
horizontalScrollBar()->setPageStep(650);
|
||||
mMouseWheelScrollDelta = 4;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include "NewTypes.h"
|
||||
#include "StringUtil.h"
|
||||
|
||||
//Hacky class that fixes a really annoying cursor problem
|
||||
class AbstractTableScrollBar : public QScrollBar
|
||||
|
|
|
@ -1480,7 +1480,7 @@ QString Disassembly::getAddrText(int_t cur_addr, char label[MAX_LABEL_SIZE])
|
|||
#endif //_WIN64
|
||||
}
|
||||
}
|
||||
addrText += AddressToString(cur_addr);
|
||||
addrText += QString("%1").arg(cur_addr, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
char label_[MAX_LABEL_SIZE] = "";
|
||||
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label_)) //has label
|
||||
{
|
||||
|
|
|
@ -404,7 +404,7 @@ QString CPUDump::paintContent(QPainter* painter, int_t rowBase, int rowOffset, i
|
|||
#endif //_WIN64
|
||||
}
|
||||
}
|
||||
addrText += AddressToString(cur_addr);
|
||||
addrText += QString("%1").arg(cur_addr, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label)) //has label
|
||||
{
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
|
|
|
@ -184,7 +184,7 @@ void CPUInfoBox::disasmSelectionChanged(int_t parVA)
|
|||
char section[MAX_SECTION_SIZE] = "";
|
||||
if(DbgFunctions()->SectionFromAddr(parVA, section))
|
||||
info += "\"" + QString(section) + "\":";
|
||||
info += AddressToString(parVA);
|
||||
info += QString("%1").arg(parVA, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
char label[MAX_LABEL_SIZE] = "";
|
||||
if(DbgGetLabelAt(parVA, SEG_DEFAULT, label))
|
||||
info += " <" + QString(label) + ">";
|
||||
|
|
|
@ -224,7 +224,7 @@ QString CPUStack::paintContent(QPainter* painter, int_t rowBase, int rowOffset,
|
|||
#endif //_WIN64
|
||||
}
|
||||
}
|
||||
addrText += AddressToString(cur_addr);
|
||||
addrText += QString("%1").arg(cur_addr, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
|
||||
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label)) //has label
|
||||
{
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
|
|
|
@ -123,12 +123,12 @@ void HexEditDialog::dataChangedSlot()
|
|||
ui->lineEditUnicode->setText(unicode);
|
||||
}
|
||||
|
||||
void HexEditDialog::on_lineEditAscii_textEdited(const QString & arg1)
|
||||
void HexEditDialog::on_lineEditAscii_textEdited(const QString &arg1)
|
||||
{
|
||||
on_btnAscii2Hex_clicked();
|
||||
}
|
||||
|
||||
void HexEditDialog::on_lineEditUnicode_textEdited(const QString & arg1)
|
||||
void HexEditDialog::on_lineEditUnicode_textEdited(const QString &arg1)
|
||||
{
|
||||
on_btnUnicode2Hex_clicked();
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ private slots:
|
|||
void on_btnUnicode2Hex_clicked();
|
||||
void on_chkKeepSize_toggled(bool checked);
|
||||
void dataChangedSlot();
|
||||
void on_lineEditAscii_textEdited(const QString & arg1);
|
||||
void on_lineEditUnicode_textEdited(const QString & arg1);
|
||||
void on_lineEditAscii_textEdited(const QString &arg1);
|
||||
void on_lineEditUnicode_textEdited(const QString &arg1);
|
||||
|
||||
private:
|
||||
Ui::HexEditDialog* ui;
|
||||
|
|
|
@ -20,7 +20,6 @@ MemoryMapView::MemoryMapView(StdTable* parent) : StdTable(parent)
|
|||
connect(Bridge::getBridge(), SIGNAL(updateMemory()), this, SLOT(refreshMap()));
|
||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(stateChangedSlot(DBGSTATE)));
|
||||
connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint)));
|
||||
connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot()));
|
||||
|
||||
setupContextMenu();
|
||||
}
|
||||
|
@ -147,11 +146,6 @@ void MemoryMapView::contextMenuSlot(const QPoint & pos)
|
|||
wMenu->exec(mapToGlobal(pos)); //execute context menu
|
||||
}
|
||||
|
||||
void MemoryMapView::doubleClickedSlot()
|
||||
{
|
||||
followDisassemblerSlot();
|
||||
}
|
||||
|
||||
QString MemoryMapView::getProtectionString(DWORD Protect)
|
||||
{
|
||||
#define RIGHTS_STRING (sizeof("ERWCG") + 1)
|
||||
|
|
|
@ -28,7 +28,6 @@ public slots:
|
|||
void memoryRemoveSlot();
|
||||
void memoryExecuteSingleshootToggleSlot();
|
||||
void contextMenuSlot(const QPoint & pos);
|
||||
void doubleClickedSlot();
|
||||
void switchView();
|
||||
void pageMemoryRights();
|
||||
void refreshMap();
|
||||
|
|
|
@ -199,10 +199,6 @@ void SymbolView::updateSymbolList(int module_count, SYMBOLMODULEINFO* modules)
|
|||
mModuleList->setCellContent(i, 1, modules[i].name);
|
||||
}
|
||||
mModuleList->reloadData();
|
||||
|
||||
// This BridgeFree call must remain here because of how arguments
|
||||
// are passed; they are thread-thread delayed so passing a stack
|
||||
// variable can not work.
|
||||
if(modules)
|
||||
BridgeFree(modules);
|
||||
}
|
||||
|
|
|
@ -223,7 +223,7 @@ void ThreadView::updateThreadList()
|
|||
setCellContent(i, 0, "Main");
|
||||
else
|
||||
setCellContent(i, 0, QString("%1").arg(threadList.list[i].BasicInfo.ThreadNumber, 0, 10));
|
||||
setCellContent(i, 1, QString("%1").arg(threadList.list[i].BasicInfo.ThreadId, 0, 16).toUpper());
|
||||
setCellContent(i, 1, QString("%1").arg(threadList.list[i].BasicInfo.dwThreadId, 0, 16).toUpper());
|
||||
setCellContent(i, 2, QString("%1").arg(threadList.list[i].BasicInfo.ThreadStartAddress, sizeof(int_t) * 2, 16, QChar('0')).toUpper());
|
||||
setCellContent(i, 3, QString("%1").arg(threadList.list[i].BasicInfo.ThreadLocalBase, sizeof(int_t) * 2, 16, QChar('0')).toUpper());
|
||||
setCellContent(i, 4, QString("%1").arg(threadList.list[i].ThreadCip, sizeof(int_t) * 2, 16, QChar('0')).toUpper());
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef STRINGUTIL_H
|
||||
#define STRINGUTIL_H
|
||||
|
||||
#include <QString>
|
||||
#include "NewTypes.h"
|
||||
|
||||
static QString AddressToString(int_t Address)
|
||||
{
|
||||
//
|
||||
// This function exists because of how QT handles
|
||||
// variables in strings.
|
||||
//
|
||||
// QString::arg():
|
||||
// ((int32)0xFFFF0000) == 0xFFFFFFFFFFFF0000 with sign extension
|
||||
//
|
||||
char temp[32];
|
||||
|
||||
#ifdef _WIN64
|
||||
sprintf_s(temp, "%016llX", Address);
|
||||
#else
|
||||
sprintf_s(temp, "%08X", Address);
|
||||
#endif // _WIN64
|
||||
|
||||
return QString(temp);
|
||||
}
|
||||
|
||||
#endif // STRINGUTIL_H
|
|
@ -151,8 +151,7 @@ HEADERS += \
|
|||
Src/Gui/PageMemoryRights.h \
|
||||
Src/Gui/SelectFields.h \
|
||||
Src/Gui/ReferenceManager.h \
|
||||
Src/Bridge/BridgeResult.h \
|
||||
Src/Utils/StringUtil.h
|
||||
Src/Bridge/BridgeResult.h
|
||||
|
||||
|
||||
INCLUDEPATH += \
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
|
@ -27,12 +23,6 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
@ -40,9 +30,6 @@
|
|||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
@ -51,13 +38,6 @@
|
|||
<TargetName>x96_dbg</TargetName>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>x96_dbg</TargetName>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -77,25 +57,6 @@
|
|||
</AdditionalManifestDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;X64_DBG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ProgramDatabaseFile>$(TargetDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<AdditionalManifestDependencies>
|
||||
</AdditionalManifestDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
|
Loading…
Reference in New Issue