About SystemHandleInformation on 64 bits application

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


About SystemHandleInformation on 64 bits application



I need know how enumarate handles on 64 bits applicatio, i made it on32 bits and works perfectly, but the same code compiled as 64 bits only show some handles.
i already changed variables to longword for example but without success.
i read about SystemHandleInformation on x64 should be another value instead $10 (16 dec) but tried without success.


const
SystemHandleInformation = $10;
STATUS_SUCCESS = $00000000;
STATUS_BUFFER_OVERFLOW = $80000005;
STATUS_INFO_LENGTH_MISMATCH = $C0000004;
//
type
NTSTATUS = Cardinal;
OBJECT_INFORMATION_CLASS = (ObjectBasicInformation, ObjectNameInformation,
ObjectTypeInformation, ObjectAllTypesInformation, ObjectHandleInformation);
//
SYSTEM_HANDLE = packed record
uIdProcess : ULONG;
ObjectType : UCHAR;
Flags : UCHAR;
Handle : Word;
pObject : Pointer;
GrantedAccess : ACCESS_MASK;
end;
PSYSTEM_HANDLE = ^SYSTEM_HANDLE;
SYSTEM_HANDLE_ARRAY = Array[0..0] of SYSTEM_HANDLE;
PSYSTEM_HANDLE_ARRAY = ^SYSTEM_HANDLE_ARRAY;
//
SYSTEM_HANDLE_INFORMATION = packed record
uCount : ULONG;
Handles : SYSTEM_HANDLE_ARRAY;
end;
PSYSTEM_HANDLE_INFORMATION = ^SYSTEM_HANDLE_INFORMATION;
//
TNtQuerySystemInformation = function (SystemInformationClass:DWORD; SystemInformation:pointer; SystemInformationLength:DWORD; ReturnLength:PDWORD):THandle; stdcall;
TNtQueryObject = function (ObjectHandle:cardinal; ObjectInformationClass:OBJECT_INFORMATION_CLASS; ObjectInformation:pointer; Length:ULONG;ResultLength:PDWORD):THandle;stdcall;
TNtQueryInformationProcess = function (hProcess: THandle; ProcessInformationClass: Integer; var ProcessInformation; ProcessInformationLength: Integer; var ReturnLength: Integer): Integer; stdcall;

Procedure EnumerateOpenFiles();
const
HANDLE_BUFFER_INCREASE_CHUNK = 5000 * 1024;
var
sDummy : string;
hProcess : THandle;
hObject : THandle;
ResultLength: DWORD;
aBufferSize : DWORD;
aIndex : Integer;
pHandleInfo : PSYSTEM_HANDLE_INFORMATION;
HDummy : THandle;

lpszProcess : PWideChar;
begin
AbufferSize := HANDLE_BUFFER_INCREASE_CHUNK;
pHandleInfo := AllocMem(AbufferSize);
HDummy := NTQuerySystemInformation(SystemHandleInformation, pHandleInfo, AbufferSize, @ResultLength); //Get the list of handles

if(HDummy = STATUS_SUCCESS) then
begin
for aIndex := 0 to pHandleInfo^.uCount-1 do
begin
hProcess := OpenProcess(PROCESS_DUP_HANDLE or PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, pHandleInfo.Handles[aIndex].uIdProcess); //open the process to get aditional info
if(hProcess <> INVALID_HANDLE_VALUE) then
begin
hObject := 0;

if DuplicateHandle(hProcess, pHandleInfo.Handles[aIndex].Handle, GetCurrentProcess(), @hObject, STANDARD_RIGHTS_REQUIRED, FALSE, 0) then //Get a copy of the original handle
begin
lpszProcess := AllocMem(MAX_PATH);
if GetModuleFileNameEx(hProcess, 0,lpszProcess, MAX_PATH) <> 0 then
sDummy:=lpszProcess
else
sDummy:= 'System Process';

if (pHandleInfo.Handles[aIndex].ObjectType = 7) then begin
Form1.Memo1.Lines.Add(Format('PID [%d] Process [%s]', [pHandleInfo.Handles[aIndex].uIdProcess, sDummy]));
Form1.Memo1.Lines.Add('----------------------------------------------------------------------------');
end;
end;

FreeMem(lpszProcess);
CloseHandle(hObject);
end;

CloseHandle(hProcess);
end;
end;
end;

FreeMem(pHandleInfo);
Form1.Memo1.Lines.Add('Finish');
end;



That works perfectly on x86 application, but when i change to x64 he don't show the same results as x86, anyone know why?





Wasn't this same question asked recently?
– David Heffernan
7 hours ago





@David Yes, and someone advised to delete prior and re-ask.
– Jerry Dodge
7 hours ago





I'd start by logging failures, but from experience GrantedAccess doesn't always allow access unless you run as TrustedInstaller.
– FredS
6 hours ago





PROCESS_BASIC_INFORMATION looks absolutely wrong. DWORD only happened to be the matching size in 32 bit, but it's not the case anymore for 64 bit.
– Günther the Beautiful
6 hours ago


PROCESS_BASIC_INFORMATION


DWORD





Indeed nothing similar to the actual api. Packing also looks suspicious.
– Sertac Akyuz
5 hours ago






1 Answer
1



Local variable names and two unremoved comments suggest that this is a variation on code posted by RRUZ at 2009 here. At that time there was no 64 bit Delphi version so it was not possible for him to test the code on 64 bits. Anyway, I was able to test this with XE2 on W7x64 using "jwanative.pas" for the missing NtQuerySystemInformation from your sample. You also have one end too many, you need to remove the end that comes before FreeMem(lpszProcess);. Otherwise the code will not compile - probably a copy/paste error on your part.


NtQuerySystemInformation


end


end


FreeMem(lpszProcess);



The error is mis-packing the SYSTEM_HANDLE and SYSTEM_HANDLE_INFORMATION records, their layouts are messed up for 64 bit when packed. This page by Geoff Chappell (have to acknowledge according to the site's terms) suggests that


SYSTEM_HANDLE


SYSTEM_HANDLE_INFORMATION



The SYSTEM_HANDLE_INFORMATION is 0x14 and 0x20 bytes in 32-bit and
64-bit Windows, respectively.



Unpack it to have 32 bytes in x64 instead of 28 while packed.



Similarly, this page suggests:



The SYSTEM_HANDLE_TABLE_ENTRY_INFO structure is 0x10 or 0x18 bytes in
32-bit and 64-bit Windows, respectively.



Unpack your record and it will be 24 bytes on x64 instead of 20 while packed. Although the members slightly differ, you'll be able to see it runs about the same as on x32.




Note that the code may or may not run on later/future versions of OS. Microsoft not only does not fully document system information retrieval but also warn that



The NtQuerySystemInformation function and the structures that it
returns are internal to the operating system and subject to change
from one release of Windows to another.






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Stripe::AuthenticationError No API key provided. Set your API key using “Stripe.api_key = ”

CRM reporting Extension - SSRS instance is blank

Keycloak server returning user_not_found error when user is already imported with LDAP