Improve no ASLR by retrying

This commit is contained in:
Duncan Ogilvie 2022-09-10 01:13:09 +02:00
parent d0b7e5addd
commit 259f1e88e3
1 changed files with 55 additions and 26 deletions

View File

@ -61,6 +61,7 @@ static bool HollowProcessWithoutASLR(const wchar_t* szFileName, PROCESS_INFORMAT
if (GetThreadContext(pi.hThread, &ctx))
{
PVOID imageBase;
// TODO: support wow64 processes
#ifdef _WIN64
auto& pebRegister = ctx.Rdx;
auto& entryPointRegister = ctx.Rcx;
@ -69,6 +70,13 @@ static bool HollowProcessWithoutASLR(const wchar_t* szFileName, PROCESS_INFORMAT
auto& entryPointRegister = ctx.Eax;
#endif // _WIN64
if (ReadProcessMemory(pi.hProcess, (char*)pebRegister + offsetof(PEB, ImageBaseAddress), &imageBase, sizeof(PVOID), nullptr))
{
if (ULONG_PTR(imageBase) == DebugModuleImageBase)
{
// Already at the right base
success = true;
}
else
{
auto status = NtUnmapViewOfSection(pi.hProcess, imageBase);
if (status == STATUS_SUCCESS)
@ -76,14 +84,22 @@ static bool HollowProcessWithoutASLR(const wchar_t* szFileName, PROCESS_INFORMAT
SIZE_T viewSize = 0;
imageBase = PVOID(DebugModuleImageBase);
status = NtMapViewOfSection(hMapping, pi.hProcess, &imageBase, 0, 0, nullptr, &viewSize, ViewUnmap, 0, PAGE_READONLY);
if(!(status != 0 && status != STATUS_IMAGE_NOT_AT_BASE))
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 (WriteProcessMemory(pi.hProcess, (char*)pebRegister + offsetof(PEB, ImageBaseAddress), &imageBase, sizeof(PVOID), nullptr))
{
auto expectedBase = DebugModuleImageBase == ULONG_PTR(imageBase);
DebugModuleImageBase = ULONG_PTR(imageBase);
entryPointRegister = DebugModuleImageBase + DebugModuleEntryPoint;
if (SetThreadContext(pi.hThread, &ctx))
{
success = true;
success = expectedBase;
#ifndef _WIN64
// For Wow64 processes, also adjust the 64-bit PEB
if (IsThisProcessWow64() && !WriteProcessMemory(pi.hProcess, (char*)pebRegister - 0x1000 + 0x10, &imageBase, sizeof(PVOID), nullptr))
@ -95,6 +111,7 @@ static bool HollowProcessWithoutASLR(const wchar_t* szFileName, PROCESS_INFORMAT
}
}
}
}
CloseHandle(hMapping);
}
@ -105,7 +122,6 @@ static bool HollowProcessWithoutASLR(const wchar_t* szFileName, PROCESS_INFORMAT
if(!success)
{
DebugModuleImageBase = 0;
DebugModuleEntryPoint = 0;
}
return success;
@ -147,6 +163,8 @@ __declspec(dllexport) void* TITCALL InitDebugW(wchar_t* szFileName, wchar_t* szC
szCommandLineCreateProcess = (wchar_t*)createWithCmdLine.c_str();
szFileNameCreateProcess = 0;
}
int retries = 0;
retry_no_aslr:
// Temporarily disable the debug privilege so the child doesn't inherit it (this evades debugger detection)
if(engineEnableDebugPrivilege)
EngineSetDebugPrivilege(GetCurrentProcess(), false);
@ -157,11 +175,22 @@ __declspec(dllexport) void* TITCALL InitDebugW(wchar_t* szFileName, wchar_t* szC
{
if(engineDisableAslr)
{
HollowProcessWithoutASLR(szFileName, dbgProcessInformation);
if (!HollowProcessWithoutASLR(szFileName, dbgProcessInformation))
{
TerminateThread(dbgProcessInformation.hThread, STATUS_CONFLICTING_ADDRESSES);
TerminateProcess(dbgProcessInformation.hProcess, STATUS_CONFLICTING_ADDRESSES);
if (retries++ < 10)
goto retry_no_aslr;
memset(&dbgProcessInformation, 0, sizeof(PROCESS_INFORMATION));
return nullptr;
}
else
{
DebugActiveProcess_(dbgProcessInformation.dwProcessId);
DebugSetProcessKillOnExit(TRUE);
ResumeThread(dbgProcessInformation.hThread);
}
}
DebugAttachedToProcess = false;
DebugAttachedProcessCallBack = NULL;
return &dbgProcessInformation;