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)
|
||||
{
|
||||
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);
|
||||
break;
|
||||
case EXIT_PROCESS_DEBUG_EVENT:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "ntdll.h"
|
||||
|
||||
static DWORD BaseSetLastNTError(IN NTSTATUS Status)
|
||||
{
|
||||
DWORD dwErrCode;
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
#include "Debugger.NativeAttach.h"
|
||||
#include "Debugger.h"
|
||||
#include "Debugger.Thread.Registers.h"
|
||||
|
||||
|
|
@ -37,29 +38,52 @@ namespace GleeBug
|
|||
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,
|
||||
szCommandLineCreateProcess,
|
||||
nullptr,
|
||||
nullptr,
|
||||
FALSE,
|
||||
DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | (newConsole ? CREATE_NEW_CONSOLE : 0) | (startSuspended ? CREATE_SUSPENDED : 0),
|
||||
creationFlags,
|
||||
nullptr,
|
||||
szCurrentDirectory,
|
||||
&mMainStartupInfo,
|
||||
&mMainProcess);
|
||||
|
||||
if (result && mDisableAslr)
|
||||
{
|
||||
HollowProcessWithoutASLR(szFileNameCreateProcess, mMainProcess);
|
||||
DebugActiveProcess_(mMainProcess.dwProcessId);
|
||||
DebugSetProcessKillOnExit(TRUE);
|
||||
if (!startSuspended)
|
||||
ResumeThread(mMainProcess.hThread);
|
||||
}
|
||||
|
||||
delete[] szCreateWithCmdLine;
|
||||
mAttachedToProcess = false;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Debugger::Attach(DWORD processId, decltype(&DebugActiveProcess) debugActiveProcess)
|
||||
bool Debugger::Attach(DWORD processId)
|
||||
{
|
||||
//don't allow attaching when still debugging
|
||||
if(mIsDebugging)
|
||||
return false;
|
||||
if(!debugActiveProcess(processId))
|
||||
if(!DebugActiveProcess_(processId))
|
||||
return false;
|
||||
mAttachedToProcess = true;
|
||||
memset(&mMainStartupInfo, 0, sizeof(mMainStartupInfo));
|
||||
|
|
@ -102,4 +126,113 @@ namespace GleeBug
|
|||
mDetachAndBreak = true;
|
||||
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.
|
||||
\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)
|
||||
|
|
@ -293,6 +293,7 @@ namespace GleeBug
|
|||
bool mDetachAndBreak = false;
|
||||
bool mAttachedToProcess = false;
|
||||
bool mSafeStep = true;
|
||||
bool mDisableAslr = false;
|
||||
|
||||
/**
|
||||
\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.
|
||||
*/
|
||||
Thread* mThread = nullptr;
|
||||
|
||||
private:
|
||||
bool HollowProcessWithoutASLR(const wchar_t* szFileName, PROCESS_INFORMATION& pi);
|
||||
ULONG_PTR mDebugModuleImageBase = 0;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@
|
|||
<ItemGroup>
|
||||
<ClInclude Include="Debugger.Breakpoint.h" />
|
||||
<ClInclude Include="Debugger.Dll.h" />
|
||||
<ClInclude Include="Debugger.NativeAttach.h" />
|
||||
<ClInclude Include="Debugger.Process.h" />
|
||||
<ClInclude Include="Debugger.h" />
|
||||
<ClInclude Include="Debugger.Thread.h" />
|
||||
|
|
@ -196,6 +197,7 @@
|
|||
<ClInclude Include="Debugger.Thread.Registers.h" />
|
||||
<ClInclude Include="Debugger.Thread.Registers.Register.h" />
|
||||
<ClInclude Include="GleeBug.h" />
|
||||
<ClInclude Include="ntdll.h" />
|
||||
<ClInclude Include="oprintf.h" />
|
||||
<ClInclude Include="Static.BufferFile.h" />
|
||||
<ClInclude Include="Static.File.h" />
|
||||
|
|
|
|||
|
|
@ -199,6 +199,12 @@
|
|||
<ClInclude Include="stringutils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Debugger.NativeAttach.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ntdll.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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 "FileMap.h"
|
||||
#include "PEB.h"
|
||||
#include "NativeAttach.h"
|
||||
#include "Global.Engine.Context.h"
|
||||
#include "Hider.h"
|
||||
|
||||
|
|
@ -68,7 +67,7 @@ public:
|
|||
|
||||
bool AttachDebugger(DWORD ProcessId, bool KillOnExit, LPVOID DebugInfo, LPVOID CallBack)
|
||||
{
|
||||
if(!Attach(ProcessId, DebugActiveProcess_))
|
||||
if(!Attach(ProcessId))
|
||||
return false;
|
||||
mCbATTACHBREAKPOINT = STEPCALLBACK(CallBack);
|
||||
mAttachProcessInfo = (PROCESS_INFORMATION*)DebugInfo;
|
||||
|
|
@ -188,12 +187,12 @@ public:
|
|||
case UE_ENGINE_SET_DEBUG_PRIVILEGE:
|
||||
mSetDebugPrivilege = VariableSet;
|
||||
break;
|
||||
case UE_ENGINE_SAFE_ATTACH:
|
||||
mSafeAttach = VariableSet;
|
||||
break;
|
||||
case UE_ENGINE_SAFE_STEP:
|
||||
mSafeStep = VariableSet;
|
||||
break;
|
||||
case UE_ENGINE_DISABLE_ASLR:
|
||||
mDisableAslr = VariableSet;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1301,7 +1300,6 @@ private: //functions
|
|||
|
||||
private: //variables
|
||||
bool mSetDebugPrivilege = false;
|
||||
bool mSafeAttach = false;
|
||||
typedef void(*CUSTOMHANDLER)(const void*);
|
||||
typedef void(*STEPCALLBACK)();
|
||||
typedef STEPCALLBACK BPCALLBACK;
|
||||
|
|
|
|||
|
|
@ -154,7 +154,6 @@
|
|||
<ClInclude Include="FileMap.h" />
|
||||
<ClInclude Include="Global.Engine.Context.h" />
|
||||
<ClInclude Include="Hider.h" />
|
||||
<ClInclude Include="NativeAttach.h" />
|
||||
<ClInclude Include="ntdll.h" />
|
||||
<ClInclude Include="PEB.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
|
|
|
|||
|
|
@ -43,9 +43,6 @@
|
|||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NativeAttach.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ntdll.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
Loading…
Reference in New Issue