{$APPTYPE CONSOLE}
{$TYPEDADDRESS ON}
{$ifdef WIN64}
{$FATAL DEP policy cannot be queried in 64bit - compile for 32bit}
{$endif}
program _QueryInformationProcess;
uses
Windows,
sysutils
;
{$ifdef VER90}
type
DWORD = longint;
PDWORD = ^DWORD;
{$endif}
type
NTSTATUS = DWORD;
pboolean = ^boolean;
const
{ 22 34 } ProcessExecuteFlags = 34; { TPROCESS_DEP_POLICY }
ntdll = 'ntdll';
PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $FFFF;
STATUS_SUCCESS = 0;
type
{ bit types for bitfields - since Delphi 2 does not support bitfields }
{ these types are FPC only }
T1BIT = 0 .. $1;
T2BITS = 0 .. $3;
T3BITS = 0 .. $7;
T4BITS = 0 .. $F;
T5BITS = 0 .. $1F;
T6BITS = 0 .. $3F;
T7BITS = 0 .. $7F;
T8BITS = 0 .. $FF; { byte }
T9BITS = 0 .. $1FF;
T10BITS = 0 .. $3FF;
T11BITS = 0 .. $7FF;
T12BITS = 0 .. $FFF;
T13BITS = 0 .. $1FFF;
T14BITS = 0 .. $3FFF;
T15BITS = 0 .. $7FFF;
T16BITS = 0 .. $FFFF; { word }
T17BITS = 0 .. $1FFFF;
T18BITS = 0 .. $3FFFF;
T19BITS = 0 .. $7FFFF;
T20BITS = 0 .. $FFFFF;
T21BITS = 0 .. $1FFFFF;
T22BITS = 0 .. $3FFFFF;
T23BITS = 0 .. $7FFFFF;
T24BITS = 0 .. $FFFFFF;
T25BITS = 0 .. $1FFFFFF;
T26BITS = 0 .. $3FFFFFF;
T27BITS = 0 .. $7FFFFFF;
T28BITS = 0 .. $FFFFFFF;
T29BITS = 0 .. $1FFFFFFF;
T30BITS = 0 .. $3FFFFFFF;
T31BITS = 0 .. $7FFFFFFF;
{$ifdef FPC}
type
{ _PROCESS_DEP_POLICY - 32bit only }
PPROCESS_DEP_POLICY = ^TPROCESS_DEP_POLICY;
TPROCESS_DEP_POLICY = bitpacked record
Unknown28 : T28BITS;
Permanent : T1BIT;
DepEnabledThunk : T1BIT;
DepDisabled : T1BIT;
Unknown1 : T1BIT;
end;
{$endif}
{$ifdef VER90}
type
{ _PROCESS_DEP_POLICY - 32bit only }
PPROCESS_DEP_POLICY = ^TPROCESS_DEP_POLICY;
TPROCESS_DEP_POLICY = record
ExecuteFlags : DWORD;
end;
{$endif}
function NtQueryInformationProcess(ProcessHandle : THANDLE;
ProcessInformationClass : DWORD;
ProcessInformation : pointer;
ProcessInformationLength : DWORD;
ReturnLength : PDWORD)
: NTSTATUS; stdcall; external ntdll;
function IsDebuggerPresent {$ifdef FPC} () {$endif}
: BOOL; stdcall external kernel32;
function _itoa
(
{ _in_ } In32bitInteger : integer;
{ _out_ } OutAsciizString : pchar;
{ _in_ } InRadix : DWORD
)
: pchar; cdecl external ntdll; { !! CDECL }
function GetProcessDEPPolicy
(
{ _in_ } InProcessHandle : THANDLE;
{ _out_ } OutFlags : PDWORD;
{ _out_ } OutPermanent : pboolean { 4th bit set }
)
: BOOL; stdcall external kernel32;
var
ProcessHandle : THANDLE;
var
{ variable for GetProcessDEPPolicy }
Flags : DWORD;
Permanent : boolean;
var
{ variables for NtQueryInformationProcess }
ProcessExecuteFlagsData : TPROCESS_DEP_POLICY;
BufferSize : DWORD;
ReturnLength : DWORD;
Status : NTSTATUS;
itoa_buf : packed array[0..127] of char;
begin
writeln;
writeln;
// since we are dealing with our own process we can specify PROCESS_ALL_ACCESS
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS,
FALSE,
GetCurrentProcessId());
if ProcessHandle = 0 then Halt(1);
{ use the API to verify the results }
writeln;
writeln;
if not GetProcessDEPPolicy(ProcessHandle,
@Flags,
@Permanent) then
begin
{ this shouldn't happen }
writeln;
writeln;
writeln(' GetProcessDEPPolicy failed.');
end;
writeln;
writeln(' Flags = ', Flags);
writeln(' Permanent = ', Permanent); { 4th bit of DWORD }
{ ------------------------------------------------------------------------- }
{ get the same results using NtQueryInformationProcess }
writeln;
writeln;
writeln(' ProcessExecuteFlags : ', ord(ProcessExecuteFlags), ' (d) ',
IntToHex(ord(ProcessExecuteFlags), 0), ' (h)');
BufferSize := sizeof(ProcessExecuteFlagsData);
ReturnLength := 0;
writeln;
writeln;
writeln(' Buffer size : ', BufferSize);
ZeroMemory(@ProcessExecuteFlagsData, sizeof(ProcessExecuteFlagsData));
if IsDebuggerPresent then DebugBreak();
Status := NtQueryInformationProcess(ProcessHandle,
ProcessExecuteFlags,
@ProcessExecuteFlagsData,
BufferSize,
@ReturnLength);
if IsDebuggerPresent then DebugBreak();
if Status <> STATUS_SUCCESS then
begin
writeln;
writeln;
writeln(' NtQueryInformationProcess failed. NTSTATUS : ',
IntToHex(Status, 0));
end;
writeln;
writeln(' returned length : ', ReturnLength);
writeln;
writeln;
{ output the result in binary for reference }
writeln(' ', _itoa(DWORD(ProcessExecuteFlagsData), itoa_buf, 2));
writeln;
{$ifdef FPC}
with ProcessExecuteFlagsData do
begin
writeln(' ProcessExecuteFlagsData = $', IntToHex(DWORD(ProcessExecuteFlagsData), 0));
writeln;
writeln(' Unknown28 = $', IntToHex(Unknown28, 0));
writeln(' Permanent = ', Permanent);
writeln(' DepEnabledThunk = ', DepEnabledThunk);
writeln(' DepDisabled = ', DepDisabled);
writeln(' Unknown1 = ', Unknown1);
end;
{$endif}
{$ifdef VER90}
writeln;
writeln;
writeln(' Process execute flags : ',
IntToHex(ProcessExecuteFlagsData.ExecuteFlags, 0));
{$endif}
writeln;
writeln('Press <enter>/<result> to end this program.');
readln;
end.