Say, if I have a process ID PID
, is there a WinAPI to find out if ASLR is enabled/disabled for that specific process?
ASLR enabled not per process but for only those executable which have IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
in IMAGE_OPTIONAL_HEADER
.DllCharacteristics
member. and of course must have relocs.
for check, are exe file (from which process created) dynamically relocated - we can use NtQueryInformationProcess
with ProcessImageInformation
- it return SECTION_IMAGE_INFORMATION
for exe file. process can be opened with PROCESS_QUERY_LIMITED_INFORMATION
(this is enough. and this let us open even protected processes). the ImageDynamicallyRelocated
bit is say - are ASLR applied for image.
ULONG CheckASLR(ULONG dwProcessId, BOOLEAN& bASLR)
{
if (HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessId))
{
SECTION_IMAGE_INFORMATION sii;
NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessImageInformation, &sii, sizeof(sii), 0);
CloseHandle(hProcess);
if (0 <= status)
{
bASLR = sii.ImageDynamicallyRelocated;
return NOERROR;
}
return RtlNtStatusToDosError(status);
}
return GetLastError();
}
if we want query this not only for exe file but for specific module, need first get path of this module (can use GetMappedFileName
), open file, create section for it and query this section for SectionImageInformation
. on exit we again got SECTION_IMAGE_INFORMATION
NTSTATUS CheckASLR(HANDLE hProcess, PVOID hmod, BOOLEAN& bASLR)
{
static volatile UCHAR guz = 0;
PVOID stack = alloca(guz);
SIZE_T cb = 0, rcb = MAX_PATH*sizeof(WCHAR);
union {
PVOID buf;
PUNICODE_STRING ObjectName;
};
NTSTATUS status;
do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}
if (0 <= (status = NtQueryVirtualMemory(hProcess, hmod, MemoryMappedFilenameInformation, buf, cb, &rcb)))
{
HANDLE hFile, hSection;
IO_STATUS_BLOCK iosb;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, ObjectName };
status = NtOpenFile(&hFile, FILE_GENERIC_READ, &oa, &iosb, FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT);
if (0 <= status)
{
status = NtCreateSection(&hSection, SECTION_QUERY, 0, 0, PAGE_READONLY, SEC_IMAGE, hFile);
NtClose(hFile);
if (0 <= status)
{
SECTION_IMAGE_INFORMATION sii;
status = ZwQuerySection(hSection, SectionImageInformation, &sii, sizeof(sii), 0);
NtClose(hSection);
if (0 <= status)
{
bASLR = sii.ImageDynamicallyRelocated;
}
}
}
break;
}
} while (status == STATUS_BUFFER_OVERFLOW );
return status;
}