mirror of https://github.com/x64dbg/GleeBug
Implement UE_ENGINE_DISABLE_ASLR
This commit is contained in:
parent
39934ea3ae
commit
b435ee57d3
|
|
@ -138,6 +138,18 @@ namespace GleeBug
|
||||||
switch(mDebugEvent.dwDebugEventCode)
|
switch(mDebugEvent.dwDebugEventCode)
|
||||||
{
|
{
|
||||||
case CREATE_PROCESS_DEBUG_EVENT:
|
case CREATE_PROCESS_DEBUG_EVENT:
|
||||||
|
// HACK: when hollowing the process the debug event still delivers the original image base
|
||||||
|
if (mDisableAslr && mDebugModuleImageBase != 0)
|
||||||
|
{
|
||||||
|
auto startAddress = ULONG_PTR(mDebugEvent.u.CreateProcessInfo.lpStartAddress);
|
||||||
|
if (startAddress)
|
||||||
|
{
|
||||||
|
startAddress -= ULONG_PTR(mDebugEvent.u.CreateProcessInfo.lpBaseOfImage);
|
||||||
|
startAddress += mDebugModuleImageBase;
|
||||||
|
mDebugEvent.u.CreateProcessInfo.lpStartAddress = LPTHREAD_START_ROUTINE(startAddress);
|
||||||
|
}
|
||||||
|
mDebugEvent.u.CreateProcessInfo.lpBaseOfImage = LPVOID(mDebugModuleImageBase);
|
||||||
|
}
|
||||||
createProcessEvent(mDebugEvent.u.CreateProcessInfo);
|
createProcessEvent(mDebugEvent.u.CreateProcessInfo);
|
||||||
break;
|
break;
|
||||||
case EXIT_PROCESS_DEBUG_EVENT:
|
case EXIT_PROCESS_DEBUG_EVENT:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "ntdll.h"
|
||||||
|
|
||||||
static DWORD BaseSetLastNTError(IN NTSTATUS Status)
|
static DWORD BaseSetLastNTError(IN NTSTATUS Status)
|
||||||
{
|
{
|
||||||
DWORD dwErrCode;
|
DWORD dwErrCode;
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "Debugger.NativeAttach.h"
|
||||||
#include "Debugger.h"
|
#include "Debugger.h"
|
||||||
#include "Debugger.Thread.Registers.h"
|
#include "Debugger.Thread.Registers.h"
|
||||||
|
|
||||||
|
|
@ -37,29 +38,52 @@ namespace GleeBug
|
||||||
szFileNameCreateProcess = nullptr;
|
szFileNameCreateProcess = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto creationFlags = DEBUG_PROCESS;
|
||||||
|
creationFlags |= DEBUG_ONLY_THIS_PROCESS; // TODO: support child process debugging
|
||||||
|
if (newConsole)
|
||||||
|
creationFlags |= CREATE_NEW_CONSOLE;
|
||||||
|
if (startSuspended)
|
||||||
|
creationFlags |= CREATE_SUSPENDED;
|
||||||
|
|
||||||
|
if (mDisableAslr)
|
||||||
|
{
|
||||||
|
creationFlags |= CREATE_SUSPENDED;
|
||||||
|
// We will attach manually later
|
||||||
|
creationFlags &= ~(DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS);
|
||||||
|
}
|
||||||
|
|
||||||
bool result = !!CreateProcessW(szFileNameCreateProcess,
|
bool result = !!CreateProcessW(szFileNameCreateProcess,
|
||||||
szCommandLineCreateProcess,
|
szCommandLineCreateProcess,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
FALSE,
|
FALSE,
|
||||||
DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | (newConsole ? CREATE_NEW_CONSOLE : 0) | (startSuspended ? CREATE_SUSPENDED : 0),
|
creationFlags,
|
||||||
nullptr,
|
nullptr,
|
||||||
szCurrentDirectory,
|
szCurrentDirectory,
|
||||||
&mMainStartupInfo,
|
&mMainStartupInfo,
|
||||||
&mMainProcess);
|
&mMainProcess);
|
||||||
|
|
||||||
|
if (result && mDisableAslr)
|
||||||
|
{
|
||||||
|
HollowProcessWithoutASLR(szFileNameCreateProcess, mMainProcess);
|
||||||
|
DebugActiveProcess_(mMainProcess.dwProcessId);
|
||||||
|
DebugSetProcessKillOnExit(TRUE);
|
||||||
|
if (!startSuspended)
|
||||||
|
ResumeThread(mMainProcess.hThread);
|
||||||
|
}
|
||||||
|
|
||||||
delete[] szCreateWithCmdLine;
|
delete[] szCreateWithCmdLine;
|
||||||
mAttachedToProcess = false;
|
mAttachedToProcess = false;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Debugger::Attach(DWORD processId, decltype(&DebugActiveProcess) debugActiveProcess)
|
bool Debugger::Attach(DWORD processId)
|
||||||
{
|
{
|
||||||
//don't allow attaching when still debugging
|
//don't allow attaching when still debugging
|
||||||
if(mIsDebugging)
|
if(mIsDebugging)
|
||||||
return false;
|
return false;
|
||||||
if(!debugActiveProcess(processId))
|
if(!DebugActiveProcess_(processId))
|
||||||
return false;
|
return false;
|
||||||
mAttachedToProcess = true;
|
mAttachedToProcess = true;
|
||||||
memset(&mMainStartupInfo, 0, sizeof(mMainStartupInfo));
|
memset(&mMainStartupInfo, 0, sizeof(mMainStartupInfo));
|
||||||
|
|
@ -102,4 +126,113 @@ namespace GleeBug
|
||||||
mDetachAndBreak = true;
|
mDetachAndBreak = true;
|
||||||
mDetach = false;
|
mDetach = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool GetPeData(HANDLE hFile, ULONG_PTR& imageBase, ULONG_PTR& entryPoint)
|
||||||
|
{
|
||||||
|
IMAGE_DOS_HEADER idh;
|
||||||
|
DWORD read = 0;
|
||||||
|
if (!ReadFile(hFile, &idh, sizeof(idh), &read, nullptr))
|
||||||
|
return false;
|
||||||
|
if (idh.e_magic != IMAGE_DOS_SIGNATURE)
|
||||||
|
return false;
|
||||||
|
if (!SetFilePointer(hFile, idh.e_lfanew, nullptr, FILE_BEGIN))
|
||||||
|
return false;
|
||||||
|
IMAGE_NT_HEADERS64 inth;
|
||||||
|
if (!ReadFile(hFile, &inth, sizeof(inth), &read, nullptr))
|
||||||
|
return false;
|
||||||
|
if (inth.Signature != IMAGE_NT_SIGNATURE)
|
||||||
|
return false;
|
||||||
|
switch (inth.FileHeader.Machine)
|
||||||
|
{
|
||||||
|
case IMAGE_FILE_MACHINE_AMD64:
|
||||||
|
{
|
||||||
|
imageBase = inth.OptionalHeader.ImageBase;
|
||||||
|
entryPoint = inth.OptionalHeader.AddressOfEntryPoint;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IMAGE_FILE_MACHINE_I386:
|
||||||
|
{
|
||||||
|
auto nth32 = (IMAGE_NT_HEADERS32*)&inth;
|
||||||
|
imageBase = nth32->OptionalHeader.ImageBase;
|
||||||
|
entryPoint = nth32->OptionalHeader.AddressOfEntryPoint;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Debugger::HollowProcessWithoutASLR(const wchar_t* szFileName, PROCESS_INFORMATION& pi)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
auto hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||||
|
if (hFile != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
// Retrieve image base and entry point
|
||||||
|
ULONG_PTR debugModuleEntryPoint = 0;
|
||||||
|
if (GetPeData(hFile, mDebugModuleImageBase, debugModuleEntryPoint))
|
||||||
|
{
|
||||||
|
SetFilePointer(hFile, 0, nullptr, FILE_BEGIN);
|
||||||
|
|
||||||
|
auto hMapping = CreateFileMappingW(hFile, nullptr, SEC_IMAGE | PAGE_READONLY, 0, 0, nullptr);
|
||||||
|
if (hMapping)
|
||||||
|
{
|
||||||
|
CONTEXT ctx;
|
||||||
|
ctx.ContextFlags = CONTEXT_ALL;
|
||||||
|
if (GetThreadContext(pi.hThread, &ctx))
|
||||||
|
{
|
||||||
|
PVOID imageBase;
|
||||||
|
// TODO: support wow64 processes
|
||||||
|
#ifdef _WIN64
|
||||||
|
auto& pebRegister = ctx.Rdx;
|
||||||
|
auto& entryPointRegister = ctx.Rcx;
|
||||||
|
#else
|
||||||
|
auto& pebRegister = ctx.Ebx;
|
||||||
|
auto& entryPointRegister = ctx.Eax;
|
||||||
|
#endif // _WIN64
|
||||||
|
if (ReadProcessMemory(pi.hProcess, (char*)pebRegister + offsetof(PEB, ImageBaseAddress), &imageBase, sizeof(PVOID), nullptr))
|
||||||
|
{
|
||||||
|
auto status = NtUnmapViewOfSection(pi.hProcess, imageBase);
|
||||||
|
if (status == STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
SIZE_T viewSize = 0;
|
||||||
|
imageBase = PVOID(mDebugModuleImageBase);
|
||||||
|
status = NtMapViewOfSection(hMapping, pi.hProcess, &imageBase, 0, 0, nullptr, &viewSize, ViewUnmap, 0, PAGE_READONLY);
|
||||||
|
if (status == STATUS_SUCCESS || status == STATUS_IMAGE_NOT_AT_BASE)
|
||||||
|
{
|
||||||
|
if (WriteProcessMemory(pi.hProcess, (char*)pebRegister + offsetof(PEB, ImageBaseAddress), &imageBase, sizeof(PVOID), nullptr))
|
||||||
|
{
|
||||||
|
entryPointRegister = mDebugModuleImageBase + debugModuleEntryPoint;
|
||||||
|
if (SetThreadContext(pi.hThread, &ctx))
|
||||||
|
{
|
||||||
|
success = true;
|
||||||
|
#ifndef _WIN64
|
||||||
|
// For Wow64 processes, also adjust the 64-bit PEB
|
||||||
|
if (IsThisProcessWow64() && !WriteProcessMemory(pi.hProcess, (char*)pebRegister - 0x1000 + 0x10, &imageBase, sizeof(PVOID), nullptr))
|
||||||
|
success = false;
|
||||||
|
#endif // _WIN64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hMapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
mDebugModuleImageBase = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -47,7 +47,7 @@ namespace GleeBug
|
||||||
\param processId Process to attach to.
|
\param processId Process to attach to.
|
||||||
\return true if the debuggee was attached to successfully, false otherwise.
|
\return true if the debuggee was attached to successfully, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool Attach(DWORD processId, decltype(&DebugActiveProcess) = &DebugActiveProcess);
|
bool Attach(DWORD processId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Stops the debuggee (terminate the process)
|
\brief Stops the debuggee (terminate the process)
|
||||||
|
|
@ -293,6 +293,7 @@ namespace GleeBug
|
||||||
bool mDetachAndBreak = false;
|
bool mDetachAndBreak = false;
|
||||||
bool mAttachedToProcess = false;
|
bool mAttachedToProcess = false;
|
||||||
bool mSafeStep = true;
|
bool mSafeStep = true;
|
||||||
|
bool mDisableAslr = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief The current process (can be null in some cases).
|
\brief The current process (can be null in some cases).
|
||||||
|
|
@ -303,6 +304,10 @@ namespace GleeBug
|
||||||
\brief The current thread (can be null in some cases). Should be a copy of mProcess->thread.
|
\brief The current thread (can be null in some cases). Should be a copy of mProcess->thread.
|
||||||
*/
|
*/
|
||||||
Thread* mThread = nullptr;
|
Thread* mThread = nullptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool HollowProcessWithoutASLR(const wchar_t* szFileName, PROCESS_INFORMATION& pi);
|
||||||
|
ULONG_PTR mDebugModuleImageBase = 0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Debugger.Breakpoint.h" />
|
<ClInclude Include="Debugger.Breakpoint.h" />
|
||||||
<ClInclude Include="Debugger.Dll.h" />
|
<ClInclude Include="Debugger.Dll.h" />
|
||||||
|
<ClInclude Include="Debugger.NativeAttach.h" />
|
||||||
<ClInclude Include="Debugger.Process.h" />
|
<ClInclude Include="Debugger.Process.h" />
|
||||||
<ClInclude Include="Debugger.h" />
|
<ClInclude Include="Debugger.h" />
|
||||||
<ClInclude Include="Debugger.Thread.h" />
|
<ClInclude Include="Debugger.Thread.h" />
|
||||||
|
|
@ -196,6 +197,7 @@
|
||||||
<ClInclude Include="Debugger.Thread.Registers.h" />
|
<ClInclude Include="Debugger.Thread.Registers.h" />
|
||||||
<ClInclude Include="Debugger.Thread.Registers.Register.h" />
|
<ClInclude Include="Debugger.Thread.Registers.Register.h" />
|
||||||
<ClInclude Include="GleeBug.h" />
|
<ClInclude Include="GleeBug.h" />
|
||||||
|
<ClInclude Include="ntdll.h" />
|
||||||
<ClInclude Include="oprintf.h" />
|
<ClInclude Include="oprintf.h" />
|
||||||
<ClInclude Include="Static.BufferFile.h" />
|
<ClInclude Include="Static.BufferFile.h" />
|
||||||
<ClInclude Include="Static.File.h" />
|
<ClInclude Include="Static.File.h" />
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,12 @@
|
||||||
<ClInclude Include="stringutils.h">
|
<ClInclude Include="stringutils.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Debugger.NativeAttach.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ntdll.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="zyan-disassembler-engine\include\Zydis\Internal\GeneratedTypes.inc">
|
<None Include="zyan-disassembler-engine\include\Zydis\Internal\GeneratedTypes.inc">
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
|
|
@ -6,7 +6,6 @@
|
||||||
#include "TitanEngine.h"
|
#include "TitanEngine.h"
|
||||||
#include "FileMap.h"
|
#include "FileMap.h"
|
||||||
#include "PEB.h"
|
#include "PEB.h"
|
||||||
#include "NativeAttach.h"
|
|
||||||
#include "Global.Engine.Context.h"
|
#include "Global.Engine.Context.h"
|
||||||
#include "Hider.h"
|
#include "Hider.h"
|
||||||
|
|
||||||
|
|
@ -68,7 +67,7 @@ public:
|
||||||
|
|
||||||
bool AttachDebugger(DWORD ProcessId, bool KillOnExit, LPVOID DebugInfo, LPVOID CallBack)
|
bool AttachDebugger(DWORD ProcessId, bool KillOnExit, LPVOID DebugInfo, LPVOID CallBack)
|
||||||
{
|
{
|
||||||
if(!Attach(ProcessId, DebugActiveProcess_))
|
if(!Attach(ProcessId))
|
||||||
return false;
|
return false;
|
||||||
mCbATTACHBREAKPOINT = STEPCALLBACK(CallBack);
|
mCbATTACHBREAKPOINT = STEPCALLBACK(CallBack);
|
||||||
mAttachProcessInfo = (PROCESS_INFORMATION*)DebugInfo;
|
mAttachProcessInfo = (PROCESS_INFORMATION*)DebugInfo;
|
||||||
|
|
@ -188,12 +187,12 @@ public:
|
||||||
case UE_ENGINE_SET_DEBUG_PRIVILEGE:
|
case UE_ENGINE_SET_DEBUG_PRIVILEGE:
|
||||||
mSetDebugPrivilege = VariableSet;
|
mSetDebugPrivilege = VariableSet;
|
||||||
break;
|
break;
|
||||||
case UE_ENGINE_SAFE_ATTACH:
|
|
||||||
mSafeAttach = VariableSet;
|
|
||||||
break;
|
|
||||||
case UE_ENGINE_SAFE_STEP:
|
case UE_ENGINE_SAFE_STEP:
|
||||||
mSafeStep = VariableSet;
|
mSafeStep = VariableSet;
|
||||||
break;
|
break;
|
||||||
|
case UE_ENGINE_DISABLE_ASLR:
|
||||||
|
mDisableAslr = VariableSet;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1301,7 +1300,6 @@ private: //functions
|
||||||
|
|
||||||
private: //variables
|
private: //variables
|
||||||
bool mSetDebugPrivilege = false;
|
bool mSetDebugPrivilege = false;
|
||||||
bool mSafeAttach = false;
|
|
||||||
typedef void(*CUSTOMHANDLER)(const void*);
|
typedef void(*CUSTOMHANDLER)(const void*);
|
||||||
typedef void(*STEPCALLBACK)();
|
typedef void(*STEPCALLBACK)();
|
||||||
typedef STEPCALLBACK BPCALLBACK;
|
typedef STEPCALLBACK BPCALLBACK;
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,6 @@
|
||||||
<ClInclude Include="FileMap.h" />
|
<ClInclude Include="FileMap.h" />
|
||||||
<ClInclude Include="Global.Engine.Context.h" />
|
<ClInclude Include="Global.Engine.Context.h" />
|
||||||
<ClInclude Include="Hider.h" />
|
<ClInclude Include="Hider.h" />
|
||||||
<ClInclude Include="NativeAttach.h" />
|
|
||||||
<ClInclude Include="ntdll.h" />
|
<ClInclude Include="ntdll.h" />
|
||||||
<ClInclude Include="PEB.h" />
|
<ClInclude Include="PEB.h" />
|
||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,6 @@
|
||||||
<ClInclude Include="resource.h">
|
<ClInclude Include="resource.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="NativeAttach.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ntdll.h">
|
<ClInclude Include="ntdll.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue