Improve the DisableAslr functionality

It will now retry 10 times to get the image to load at the expected base
This commit is contained in:
Duncan Ogilvie 2022-09-10 00:55:19 +02:00
parent b435ee57d3
commit 807951bac6
6 changed files with 202 additions and 158 deletions

View File

@ -52,6 +52,8 @@ namespace GleeBug
creationFlags &= ~(DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS); creationFlags &= ~(DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS);
} }
int retries = 0;
retry_no_aslr:
bool result = !!CreateProcessW(szFileNameCreateProcess, bool result = !!CreateProcessW(szFileNameCreateProcess,
szCommandLineCreateProcess, szCommandLineCreateProcess,
nullptr, nullptr,
@ -65,12 +67,22 @@ namespace GleeBug
if(result && mDisableAslr) if(result && mDisableAslr)
{ {
HollowProcessWithoutASLR(szFileNameCreateProcess, mMainProcess); if(!HollowProcessWithoutASLR(szFileNameCreateProcess, mMainProcess))
{
TerminateThread(mMainProcess.hThread, STATUS_CONFLICTING_ADDRESSES);
TerminateProcess(mMainProcess.hProcess, STATUS_CONFLICTING_ADDRESSES);
if(retries++ < 10)
goto retry_no_aslr;
result = false;
}
else
{
DebugActiveProcess_(mMainProcess.dwProcessId); DebugActiveProcess_(mMainProcess.dwProcessId);
DebugSetProcessKillOnExit(TRUE); DebugSetProcessKillOnExit(TRUE);
if(!startSuspended) if(!startSuspended)
ResumeThread(mMainProcess.hThread); ResumeThread(mMainProcess.hThread);
} }
}
delete[] szCreateWithCmdLine; delete[] szCreateWithCmdLine;
mAttachedToProcess = false; mAttachedToProcess = false;
@ -146,7 +158,7 @@ namespace GleeBug
{ {
case IMAGE_FILE_MACHINE_AMD64: case IMAGE_FILE_MACHINE_AMD64:
{ {
imageBase = inth.OptionalHeader.ImageBase; imageBase = (ULONG_PTR)inth.OptionalHeader.ImageBase;
entryPoint = inth.OptionalHeader.AddressOfEntryPoint; entryPoint = inth.OptionalHeader.AddressOfEntryPoint;
} }
break; break;
@ -165,6 +177,22 @@ namespace GleeBug
return true; return true;
} }
#ifndef _WIN64
static bool isThisProcessWow64()
{
typedef BOOL(WINAPI * tIsWow64Process)(HANDLE hProcess, PBOOL Wow64Process);
BOOL bIsWow64 = FALSE;
static auto fnIsWow64Process = (tIsWow64Process)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
if(fnIsWow64Process)
{
fnIsWow64Process(GetCurrentProcess(), &bIsWow64);
}
return (bIsWow64 != FALSE);
}
#endif
bool Debugger::HollowProcessWithoutASLR(const wchar_t* szFileName, PROCESS_INFORMATION & pi) bool Debugger::HollowProcessWithoutASLR(const wchar_t* szFileName, PROCESS_INFORMATION & pi)
{ {
bool success = false; bool success = false;
@ -194,6 +222,13 @@ namespace GleeBug
auto & entryPointRegister = ctx.Eax; auto & entryPointRegister = ctx.Eax;
#endif // _WIN64 #endif // _WIN64
if(ReadProcessMemory(pi.hProcess, (char*)pebRegister + offsetof(PEB, ImageBaseAddress), &imageBase, sizeof(PVOID), nullptr)) if(ReadProcessMemory(pi.hProcess, (char*)pebRegister + offsetof(PEB, ImageBaseAddress), &imageBase, sizeof(PVOID), nullptr))
{
if(ULONG_PTR(imageBase) == mDebugModuleImageBase)
{
// Already at the right base
success = true;
}
else
{ {
auto status = NtUnmapViewOfSection(pi.hProcess, imageBase); auto status = NtUnmapViewOfSection(pi.hProcess, imageBase);
if(status == STATUS_SUCCESS) if(status == STATUS_SUCCESS)
@ -201,17 +236,25 @@ namespace GleeBug
SIZE_T viewSize = 0; SIZE_T viewSize = 0;
imageBase = PVOID(mDebugModuleImageBase); imageBase = PVOID(mDebugModuleImageBase);
status = NtMapViewOfSection(hMapping, pi.hProcess, &imageBase, 0, 0, nullptr, &viewSize, ViewUnmap, 0, PAGE_READONLY); status = NtMapViewOfSection(hMapping, pi.hProcess, &imageBase, 0, 0, nullptr, &viewSize, ViewUnmap, 0, PAGE_READONLY);
if(status == STATUS_CONFLICTING_ADDRESSES)
{
// Remap in a random location (otherwise the process will crash)
imageBase = 0;
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(status == STATUS_SUCCESS || status == STATUS_IMAGE_NOT_AT_BASE)
{ {
if(WriteProcessMemory(pi.hProcess, (char*)pebRegister + offsetof(PEB, ImageBaseAddress), &imageBase, sizeof(PVOID), nullptr)) if(WriteProcessMemory(pi.hProcess, (char*)pebRegister + offsetof(PEB, ImageBaseAddress), &imageBase, sizeof(PVOID), nullptr))
{ {
auto expectedBase = mDebugModuleImageBase == ULONG_PTR(imageBase);
mDebugModuleImageBase = ULONG_PTR(imageBase);
entryPointRegister = mDebugModuleImageBase + debugModuleEntryPoint; entryPointRegister = mDebugModuleImageBase + debugModuleEntryPoint;
if(SetThreadContext(pi.hThread, &ctx)) if(SetThreadContext(pi.hThread, &ctx))
{ {
success = true; success = expectedBase;
#ifndef _WIN64 #ifndef _WIN64
// For Wow64 processes, also adjust the 64-bit PEB // For Wow64 processes, also adjust the 64-bit PEB
if (IsThisProcessWow64() && !WriteProcessMemory(pi.hProcess, (char*)pebRegister - 0x1000 + 0x10, &imageBase, sizeof(PVOID), nullptr)) if(isThisProcessWow64() && !WriteProcessMemory(pi.hProcess, (char*)pebRegister - 0x1000 + 0x10, &imageBase, sizeof(PVOID), nullptr))
success = false; success = false;
#endif // _WIN64 #endif // _WIN64
} }
@ -220,6 +263,7 @@ namespace GleeBug
} }
} }
} }
}
CloseHandle(hMapping); CloseHandle(hMapping);
} }