unit LzOpenProcessU;
interface
uses
Windows, SysUtils;
type
NTSTATUS = DWORD;
PVOID = Pointer;
SYSTEM_INFORMATION_CLASS = ULONG;
type
PUnicodeString = ^TUnicodeString;
TUnicodeString = packed record
Length: Word;
MaximumLength: Word;
Buffer: PWideChar;
end;
type
PObjectAttributes = ^TObjectAttributes;
TObjectAttributes = packed record
Length: Cardinal;
RootDirectory: THandle;
ObjectName: PUnicodeString;
Attributes: Cardinal;
SecurityDescriptor: Pointer;
SecurityQualityOfService: Pointer;
end;
type
PClientId = ^TClientId;
TClientId = packed record
UniqueProcess: Cardinal;
UniqueThread: Cardinal;
end;
type
PROCESS_BASIC_INFORMATION = ^TPROCESS_BASIC_INFORMATION;
TPROCESS_BASIC_INFORMATION = packed record
ExitStatus: NTSTATUS;
PebBaseAddress: ULONG;
AffinityMask: ULONG;
BasePriority: ULONG;
UniqueProcessId: ULONG;
InheritedFromUniqueProcessId: ULONG;
end;
type
PTSYSTEM_HANDLE_TABLE_ENTRY_INFO = ^TSYSTEM_HANDLE_TABLE_ENTRY_INFO;
TSYSTEM_HANDLE_TABLE_ENTRY_INFO = record
UniqueProcessId : SHORT;
CreatorBackTraceIndex : SHORT;
ObjectTypeIndex : BYTE ;
HandleAttributes : BYTE ;
HandleValue : SHORT;
pObject : DWORD ;
GrantedAccess : ULONG ;
end;
function ZwQueryInformationProcess(ProcessHandle: THANDLE; ProcessInformationClass: ULONG; ProcessInformation: PVOID; ProcessInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall; external 'ntdll.dll';
function ZwQuerySystemInformation(SystemInformationClass: SYSTEM_INFORMATION_CLASS; SystemInformation: PVOID; SystemInformationLength: ULONG; lpReturnLength: PULONG): NTSTATUS; stdcall; external 'ntdll.dll';
function ZwDuplicateObject(SourceProcessHandle: THANDLE; SourceHandle: THANDLE; TargetProcessHandle: THANDLE; TargetHandle: PHANDLE; DesiredAccess: ACCESS_MASK; Attributes: ULONG; Options: ULONG): NTSTATUS; stdcall; external 'ntdll.dll';
function ZwOpenProcess(ProcessHandle: PHandle; DesiredAccess: ACCESS_MASK; ObjectAttributes: PObjectAttributes; ClientId: PClientId): NTSTATUS; stdcall; external 'ntdll.dll';
function ZwTerminateProcess(ProcessHandle: DWORD; ExitStatus: DWORD): NTSTATUS; stdcall; external 'ntdll.dll';
function ZwClose(
Handle: THandle): NTSTATUS; stdcall; external 'ntdll.dll';
function LzOpenProcess(dwDesiredAccess, ProcessId: Cardinal; TryZwFirst: Boolean): Cardinal;
implementation
uses
Unit1 {Form1};
function NT_SUCCESS(Status: Integer):Boolean; inline;
begin
Result:= (Status >= 0);
end;
function LzOpenProcess(dwDesiredAccess, ProcessId: Cardinal; TryZwFirst: Boolean): Cardinal;
var
st: Cardinal;
cid: TClientId;
oa: TObjectAttributes;
NumOfHandle: Integer;
pbi: TPROCESS_BASIC_INFORMATION;
I: Integer;
hProcessToDup,hProcessCur,hProcessToRet: Cardinal;
arySize: Cardinal;
TempNum: Cardinal;
bytBuf: array of Byte;
h_info: array of TSYSTEM_HANDLE_TABLE_ENTRY_INFO;
begin
Result:=0;
ZeroMemory(@oa, SizeOf(oa));
ZeroMemory(@cid, SizeOf(cid));
oa.Length:=SizeOf(oa);
if TryZwFirst then
begin
cid.UniqueProcess:=ProcessId;
st:=ZwOpenProcess(@hProcessToRet, dwDesiredAccess, @oa, @cid);
if NT_SUCCESS(st) then
begin
Result:=hProcessToRet;
Exit;
end;
end;
SetLength(bytBuf,1024);
st:=ZwQuerySystemInformation(16{SystemModuleInformation}, @bytBuf, Length(bytBuf), @arySize);
Form1.Memo1.Lines.Add('0x' + IntToHex(st, 8));
if not NT_SUCCESS(st) then
begin
if st<>$C0000004{STATUS_INFO_LENGTH_MISMATCH} then Exit;
SetLength(bytBuf, arySize);
st:=ZwQuerySystemInformation(16{SystemModuleInformation}, @bytBuf, arySize, @TempNum);
if not NT_SUCCESS(st) then Exit;
end;
NumOfHandle:=PULONG(@bytBuf)^;
SetLength(h_info, NumOfHandle);
CopyMemory(@h_info, Pointer(Cardinal(@bytBuf)+SizeOf(ULONG)), SizeOf(TSYSTEM_HANDLE_TABLE_ENTRY_INFO)*NumOfHandle);
for I := Low(h_info) to High(h_info) do
begin
if h_info[I].ObjectTypeIndex=5{OB_TYPE_PROCESS} then
begin
cid.UniqueProcess:=h_info[I].UniqueProcessId;
st:=ZwOpenProcess(@hProcessToDup, $40{PROCESS_DUP_HANDLE}, @oa, @cid);
if NT_SUCCESS(st) then
begin
st:=ZwDuplicateObject(hProcessToDup, h_info[I].HandleValue, $FFFFFFFF{ZwGetCurrentProcess}, @hProcessCur, PROCESS_ALL_ACCESS, 0, $4{DUPLICATE_SAME_ATTRIBUTES});
if NT_SUCCESS(st) then
begin
st:=ZwQueryInformationProcess(hProcessCur, 0{ProcessBasicInformation}, @pbi, SizeOf(TPROCESS_BASIC_INFORMATION), nil);
if NT_SUCCESS(st) then
begin
if pbi.UniqueProcessId = ProcessId then
begin
st:= ZwDuplicateObject(hProcessToDup, h_info[I].HandleValue, $FFFFFFFF{ZwGetCurrentProcess}, @hProcessToRet, dwDesiredAccess, 0, $4{DUPLICATE_SAME_ATTRIBUTES});
if NT_SUCCESS(st) then Result := hProcessToRet;
end;
end;
end;
ZwClose(hProcessCur);
end;
ZwClose(hProcessToDup);
end;
end;
end;
end.