Einzelnen Beitrag anzeigen

flashcoder

Registriert seit: 10. Nov 2013
83 Beiträge
 
#1

How kill process using your duplicated handle?

  Alt 3. Dez 2017, 03:53
I have the following code based in this question , but comes a error 0xC0000004(STATUS_INFO_LENGTH_MISMATCH) in this line:
Code:
st:=ZwQuerySystemInformation(16{SystemModuleInformation}, @bytBuf, Length(bytBuf), @arySize);
Then when "jump" to:
Code:
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;
I got a Acess Violation here:
Code:
SetLength(bytBuf, arySize);
How fix?


Complete code:
Code:
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.
Form1:
Code:
var
  Form1: TForm1;

implementation

uses
  LzOpenProcessU;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
const
   STATUS_SUCCESS = $00000000;
var
  hproc: DWORD;
  Status: NTSTATUS;
begin
  Status:= STATUS_SUCCESS;
  hproc := LzOpenProcess(PROCESS_ALL_ACCESS, GetPidByName('notepad.exe'), False);
  if hproc > 0 then
    Status := ZwTerminateProcess(hproc, 0);
  Form1.Memo1.Lines.Add('ZwTerminateProcess() = 0x' + IntToHex(Status, 8));
end;
PS: Running in Windows Ultimte 7 x64

Geändert von flashcoder ( 3. Dez 2017 um 04:05 Uhr)
  Mit Zitat antworten Zitat