#1
|
|||
|
|||
[Delphi] Check if ASLR is enabled
Check if ASLR is enabled.
Code:
{************************************ * Coded by Agmcz * * Hints by naquadria * * Date: 2018-01-07 * ************************************} unit uCheckASLR; interface uses Windows; function CheckASLR(const FileName: string): Boolean; implementation const IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = $0040; IMAGE_DIRECTORY_ENTRY_BASERELOC = 5; function CheckASLR(const FileName: string): Boolean; var hFile: THandle; hMapping: DWORD; pMap: Pointer; dwSize: DWORD; IDH: PImageDosHeader; INH: PImageNtHeaders; ISH: PImageSectionHeader; n: Word; dwRelocAddr, dwRelocSize: DWORD; begin Result := False; hFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if hFile <> INVALID_HANDLE_VALUE then begin dwSize := GetFileSize(hFile, nil); hMapping := CreateFileMapping(hFile, nil, PAGE_READONLY, 0, dwSize, nil); if hMapping <> 0 then begin pMap := MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); if pMap <> nil then begin IDH := PImageDosHeader(pMap); if IDH.e_magic = IMAGE_DOS_SIGNATURE then begin INH := PImageNtHeaders(DWORD(pMap) + LongWord(IDH._lfanew)); if INH.Signature = IMAGE_NT_SIGNATURE then begin if (INH.OptionalHeader.DllCharacteristics and IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) = IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE then begin ISH := PImageSectionHeader(DWORD(pMap) + LongWord(IDH._lfanew) + SizeOf(DWORD) + SizeOf(INH.FileHeader) + INH.FileHeader.SizeOfOptionalHeader); dwRelocAddr := INH.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; dwRelocSize := INH.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; if (dwRelocAddr <> 0) and (dwRelocSize <> 0) then begin for n := 0 to INH.FileHeader.NumberOfSections - 1 do begin if ISH.VirtualAddress = dwRelocAddr then begin if (ISH.Misc.VirtualSize <> 0) and (ISH.PointerToRawData <> 0) and (ISH.SizeOfRawData <> 0) then Result := True; Break; end; Inc(ISH); end; end; end; end; end; UnmapViewOfFile(pMap); end; CloseHandle(hMapping); end; CloseHandle(hFile); end; end; end. |
#2
|
|||
|
|||
Can post the attachment outside of this board? Thx
|
#3
|
|||
|
|||
Hi,
Code:
https://nofile.io/f/YtbJBoKEcTt/ASLR+Checker.rar |
#4
|
|||
|
|||
Why not simply check the bit "Relocations Stripped" at PE characteristics, as does the PE_ASLR.HEM HIEW32 plugin?
Last edited by dosprog; 04-08-2018 at 02:19. |
#5
|
|||
|
|||
Because that's just plain wrong, the two flags don't exclude each other.
|
#6
|
|||
|
|||
But when DLLCHARACTERISTICS.RelocationsStrippedBit=1 all others ignored. Agree?
..however you are right, if the file is processed by the plugin PE_ASLR.HEM with this bit set to 1, then additional checks will be required after clear it. Last edited by dosprog; 04-08-2018 at 03:21. |
#7
|
|||
|
|||
Microsoft didn't implement two linker options for fun, these are two individual flags doing different things and can be enabled or disabled independently from each other.
So if you want to know if a file is ASLR enabled, then you check the flag telling you if a file is ASLR enabled and not the flag telling you if a file has relocations. (I'm aware the code posted here does check for a relocation table, but relocations are no requirement for ASLR) |
#8
|
|||
|
|||
you must check bit "IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE" in PE.OPTIONAL_HEADER.DllCharacteristics member.
|
#9
|
|||
|
|||
more...
check if ASLR is enabled from process Code:
unit uCheckASLR; // Original C++ Source: https://stackoverflow.com/questions/47105480/how-to-check-if-aslr-is-enabled-for-a-process // Converted to Delphi by Agmcz 28-12-2017 2:25:32 interface uses Windows; function CheckASLR(dwProcessId: ULONG; out bASLR: Boolean): ULONG; implementation const PROCESS_QUERY_LIMITED_INFORMATION = $1000; type TSectionImageInformation = record TransferAddress: Pointer; ZeroBits: ULONG; MaximumStackSize: ULONG; CommittedStackSize: ULONG; SubSystemType: ULONG; MinorSubsystemVersion: Word; MajorSubsystemVersion: Word; GpValue: ULONG; ImageCharacteristics: Word; DllCharacteristics: Word; Machine: Word; ImageContainsCode: Boolean; ImageFlags: Byte; LoaderFlags: ULONG; ImageFileSize: ULONG; CheckSum: ULONG; end; PROCESSINFOCLASS = ( ProcessBasicInformation, ProcessQuotaLimits, ProcessIoCounters, ProcessVmCounters, ProcessTimes, ProcessBasePriority, ProcessRaisePriority, ProcessDebugPort, ProcessExceptionPort, ProcessAccessToken, ProcessLdtInformation, ProcessLdtSize, ProcessDefaultHardErrorMode, ProcessIoPortHandlers, ProcessPooledUsageAndLimits, ProcessWorkingSetWatch, ProcessUserModeIOPL, ProcessEnableAlignmentFaultFixup, ProcessPriorityClass, ProcessWx86Information, ProcessHandleCount, ProcessAffinityMask, ProcessPriorityBoost, ProcessDeviceMap, ProcessSessionInformation, ProcessForegroundInformation, ProcessWow64Information, ProcessImageFileName, ProcessLUIDDeviceMapsEnabled, ProcessBreakOnTermination, ProcessDebugObjectHandle, ProcessDebugFlags, ProcessHandleTracing, ProcessIoPriority, ProcessExecuteFlags, ProcessResourceManagement, ProcessCookie, ProcessImageInformation, MaxProcessInfoClass); type NTSTATUS = LongWord; function NtQueryInformationProcess(ProcessHandle: THandle; ProcessInformationClass: PROCESSINFOCLASS; ProcessInformation: Pointer; ProcessInformationLength: ULONG; ReturnLength: PULONG ): LongInt; stdcall; external 'ntdll.dll'; function RtlNtStatusToDosError(Status: NTSTATUS): Integer; stdcall; external 'ntdll.dll'; function CheckASLR(dwProcessId: ULONG; out bASLR: Boolean): ULONG; var hProcess: THandle; sii: TSectionImageInformation; status: NTSTATUS; begin hProcess := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, dwProcessId); if (hProcess <> 0) and (hProcess <> INVALID_HANDLE_VALUE) then begin status := NtQueryInformationProcess(hProcess, ProcessImageInformation, @sii, SizeOf(sii), 0); CloseHandle(hProcess); if 0 <= status then begin bASLR := Boolean(sii.ImageFlags); Result := NOERROR; Exit; end; Result := RtlNtStatusToDosError(status); Exit; end; Result := GetLastError; end; end. |
#10
|
|||
|
|||
theres a bug in the code above..
bASLR := Boolean(sii.ImageFlags); right there.. ImageFlags is a set of bitflags, to test for the aslr portion you need to and it and check the result, so you need to check bit 2, you're just blindly assuming that any non zero value for the whole thing means alsr is enabled.. this is wrong ----- UINT8 ImageFlags; // 0x0023 / 0x0033; 0x0001 / 0x0001 Bytes struct // 7 / 7 elements; 0x0001 / 0x0001 Bytes { UINT8 ComPlusNativeReady : 1; // 0x0023 / 0x0033; Bit: 0 UINT8 ComPlusILOnly : 1; // 0x0023 / 0x0033; Bit: 1 UINT8 ImageDynamicallyRelocated : 1; // 0x0023 / 0x0033; Bit: 2 UINT8 ImageMappedFlat : 1; // 0x0023 / 0x0033; Bit: 3 UINT8 BaseBelow4gb : 1; // 0x0023 / 0x0033; Bit: 4 UINT8 ComPlusPrefer32bit : 1; // 0x0023 / 0x0033; Bit: 5 UINT8 Reserved : 2; // 0x0023 / 0x0033; Bits: 6 - 7 }; |
#11
|
|||
|
|||
Okay
now it works correctly. Code:
unit uCheckASLR; // Original C++ Source: https://stackoverflow.com/questions/47105480/how-to-check-if-aslr-is-enabled-for-a-process // Ported to Delphi by Agmcz 28-12-2017 2:25:32 // Fix 04-08-2018 10:56:25 interface uses Windows; function CheckASLR(dwProcessId: LongWord; out bASLR: Boolean): LongWord; implementation const PROCESS_QUERY_LIMITED_INFORMATION = $1000; type TSectionImageInformation = record TransferAddress: Pointer; ZeroBits: LongWord; MaximumStackSize: LongWord; CommittedStackSize: LongWord; SubSystemType: LongWord; MinorSubsystemVersion: Word; MajorSubsystemVersion: Word; GpValue: LongWord; ImageCharacteristics: Word; DllCharacteristics: Word; Machine: Word; ImageContainsCode: Boolean; ImageFlags: Byte; LoaderFlags: LongWord; ImageFileSize: LongWord; CheckSum: LongWord; end; PROCESSINFOCLASS = ( ProcessBasicInformation, ProcessQuotaLimits, ProcessIoCounters, ProcessVmCounters, ProcessTimes, ProcessBasePriority, ProcessRaisePriority, ProcessDebugPort, ProcessExceptionPort, ProcessAccessToken, ProcessLdtInformation, ProcessLdtSize, ProcessDefaultHardErrorMode, ProcessIoPortHandlers, ProcessPooledUsageAndLimits, ProcessWorkingSetWatch, ProcessUserModeIOPL, ProcessEnableAlignmentFaultFixup, ProcessPriorityClass, ProcessWx86Information, ProcessHandleCount, ProcessAffinityMask, ProcessPriorityBoost, ProcessDeviceMap, ProcessSessionInformation, ProcessForegroundInformation, ProcessWow64Information, ProcessImageFileName, ProcessLUIDDeviceMapsEnabled, ProcessBreakOnTermination, ProcessDebugObjectHandle, ProcessDebugFlags, ProcessHandleTracing, ProcessIoPriority, ProcessExecuteFlags, ProcessResourceManagement, ProcessCookie, ProcessImageInformation, MaxProcessInfoClass); type NTSTATUS = LongWord; function NtQueryInformationProcess(ProcessHandle: THandle; ProcessInformationClass: PROCESSINFOCLASS; ProcessInformation: Pointer; ProcessInformationLength: ULONG; ReturnLength: PULONG ): LongInt; stdcall; external 'ntdll.dll'; function RtlNtStatusToDosError(Status: NTSTATUS): Integer; stdcall; external 'ntdll.dll'; function ImageDynamicallyRelocated(sii: TSectionImageInformation): Boolean; begin Result := (sii.ImageFlags and (1 shl 2)) = 1; end; function CheckASLR(dwProcessId: LongWord; out bASLR: Boolean): LongWord; var hProcess: THandle; sii: TSectionImageInformation; status: NTSTATUS; begin hProcess := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, dwProcessId); if (hProcess <> 0) and (hProcess <> INVALID_HANDLE_VALUE) then begin status := NtQueryInformationProcess(hProcess, ProcessImageInformation, @sii, SizeOf(sii), 0); CloseHandle(hProcess); if 0 <= status then begin bASLR := ImageDynamicallyRelocated(sii); Result := NOERROR; Exit; end; Result := RtlNtStatusToDosError(status); Exit; end; Result := GetLastError; end; end. |
The Following User Gave Reputation+1 to Agmcz For This Useful Post: | ||
Insid3Code (04-10-2018) |
#12
|
|||
|
|||
What is the version of Delphi that you guys are using?
|
#13
|
|||
|
|||
Fix func ImageDynamicallyRelocated
Code:
unit uCheckASLR; // Original C++ Source: https://stackoverflow.com/questions/47105480/how-to-check-if-aslr-is-enabled-for-a-process // Ported to Delphi by Agmcz 28-12-2017 2:25:32 // Fix 08-04-2018 10:56:25 // Fix2 01-05-2018 2:28:15 interface uses Windows; function CheckASLR(dwProcessId: LongWord; out bASLR: Boolean): LongWord; implementation const PROCESS_QUERY_LIMITED_INFORMATION = $1000; type TSectionImageInformation = record TransferAddress: Pointer; ZeroBits: LongWord; MaximumStackSize: LongWord; CommittedStackSize: LongWord; SubSystemType: LongWord; MinorSubsystemVersion: Word; MajorSubsystemVersion: Word; GpValue: LongWord; ImageCharacteristics: Word; DllCharacteristics: Word; Machine: Word; ImageContainsCode: Boolean; ImageFlags: Byte; LoaderFlags: LongWord; ImageFileSize: LongWord; CheckSum: LongWord; end; PROCESSINFOCLASS = ( ProcessBasicInformation, ProcessQuotaLimits, ProcessIoCounters, ProcessVmCounters, ProcessTimes, ProcessBasePriority, ProcessRaisePriority, ProcessDebugPort, ProcessExceptionPort, ProcessAccessToken, ProcessLdtInformation, ProcessLdtSize, ProcessDefaultHardErrorMode, ProcessIoPortHandlers, ProcessPooledUsageAndLimits, ProcessWorkingSetWatch, ProcessUserModeIOPL, ProcessEnableAlignmentFaultFixup, ProcessPriorityClass, ProcessWx86Information, ProcessHandleCount, ProcessAffinityMask, ProcessPriorityBoost, ProcessDeviceMap, ProcessSessionInformation, ProcessForegroundInformation, ProcessWow64Information, ProcessImageFileName, ProcessLUIDDeviceMapsEnabled, ProcessBreakOnTermination, ProcessDebugObjectHandle, ProcessDebugFlags, ProcessHandleTracing, ProcessIoPriority, ProcessExecuteFlags, ProcessTlsInformation, ProcessCookie, ProcessImageInformation, ProcessCycleTime, ProcessPagePriority, ProcessInstrumentationCallback, ProcessThreadStackAllocation, ProcessWorkingSetWatchEx, ProcessImageFileNameWin32, ProcessImageFileMapping, ProcessAffinityUpdateMode, ProcessMemoryAllocationMode, ProcessGroupInformation, ProcessTokenVirtualizationEnabled, ProcessConsoleHostProcess, ProcessWindowInformation, MaxProcessInfoClass); type NTSTATUS = LongWord; function NtQueryInformationProcess(ProcessHandle: THandle; ProcessInformationClass: PROCESSINFOCLASS; ProcessInformation: Pointer; ProcessInformationLength: ULONG; ReturnLength: PULONG ): LongInt; stdcall; external 'ntdll.dll'; function RtlNtStatusToDosError(Status: NTSTATUS): Integer; stdcall; external 'ntdll.dll'; function ImageDynamicallyRelocated(sii: TSectionImageInformation): Boolean; asm MOVZX EAX, BYTE PTR SS:[sii.ImageFlags] SHR AL, 2 AND EAX, 1 end; function CheckASLR(dwProcessId: LongWord; out bASLR: Boolean): LongWord; var hProcess: THandle; sii: TSectionImageInformation; status: NTSTATUS; begin hProcess := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, dwProcessId); if (hProcess <> 0) and (hProcess <> INVALID_HANDLE_VALUE) then begin status := NtQueryInformationProcess(hProcess, ProcessImageInformation, @sii, SizeOf(sii), 0); CloseHandle(hProcess); if 0 <= status then begin bASLR := ImageDynamicallyRelocated(sii); Result := NOERROR; Exit; end; Result := RtlNtStatusToDosError(status); Exit; end; Result := GetLastError; end; end. |
The Following 3 Users Say Thank You to Agmcz For This Useful Post: | ||
#14
|
|||
|
|||
You can use delphi7 or a newer version.
|
#15
|
|||
|
|||
Check ASLR from Remote PEB
More..
Check ASLR from Remote PEB Code:
unit uCheckASLR; {************************************ * Coded by Agmcz * * Date: 01-05-2018 * ************************************} interface uses Windows; function CheckASLRPEB32(hProcess: THandle): Boolean; implementation type PProcessBasicInformation = ^TProcessBasicInformation; TProcessBasicInformation = record ExitStatus: LongInt; PebBaseAddress: Pointer; AffinityMask: Cardinal; BasePriority: LongInt; UniqueProcessId: Cardinal; InheritedFromUniqueProcessId: Cardinal; end; function NtQueryInformationProcess(ProcessHandle: THandle; ProcessInformationClass: DWORD {PROCESSINFOCLASS}; ProcessInformation: Pointer; ProcessInformationLength: ULONG; ReturnLength: PULONG): LongInt; stdcall; external 'ntdll.dll'; function NtReadVirtualMemory(ProcessHandle: THandle; BaseAddress: Pointer; Buffer: Pointer; BufferLength: ULONG; ReturnLength: PULONG): Longint; stdcall; external 'ntdll.dll'; function ImageDynamicallyRelocated(BitField: Byte): Boolean; asm SHR AL, 2 AND AL, 1 end; function CheckASLRPEB32(hProcess: THandle): Boolean; var PBI: TProcessBasicInformation; BitField: Byte; begin Result := False; if (hProcess <> 0) and (hProcess <> INVALID_HANDLE_VALUE) then begin if NtQueryInformationProcess(hProcess, 0{ProcessBasicInformation = 0}, @PBI, SizeOf(TProcessBasicInformation), 0) = 0 then begin if NtReadVirtualMemory(hProcess, Pointer(DWORD(PBI.PebBaseAddress) + 3), @BitField{Peb.BitField}, SizeOf(Byte), 0) = 0 then Result := ImageDynamicallyRelocated(BitField); end; end; end; end. |
The Following 2 Users Say Thank You to Agmcz For This Useful Post: | ||
Insid3Code (05-02-2018), ontryit (05-02-2018) |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
[Delphi] Loader shows how to patch PE protected with ASLR | Sn!per X | Source Code | 1 | 11-28-2015 00:33 |
Help Me - CRC Check and FileSize Check | byvs | General Discussion | 11 | 07-31-2003 13:32 |