ZwAssignProcessToJobObject:ACCESS_DENIED

时间:2017-11-29 04:36:53

标签: delphi winapi kill-process

我正在尝试最终确定一个已确定的流程(reference),但在我需要ZwAssignProcessToJobObject()之前,我在下面的小代码中演示了我的问题,其中Status正在返回 0xC0000022 ACCESS_DENIED )。有办法解决吗?

type
  NTSTATUS = cardinal;
  PClientId = ^TClientId;
  TClientId = record
    UniqueProcess: THandle;
    UniqueThread: THandle;
end;

PObjectAttributes = ^TObjectAttributes;
  TObjectAttributes = packed record
  Length: Cardinal;
  RootDirectory: THandle;
  ObjectName: PUnicodeString;
  Attributes: Cardinal;
  SecurityDescriptor: Pointer;
  SecurityQualityOfService: Pointer;
 end;
  OBJECT_ATTRIBUTES = ^TObjectAttributes;
  POBJECT_ATTRIBUTES = ^OBJECT_ATTRIBUTES;

const
  STATUS_SUCCESS = $00000000;

var
 Status: NTSTATUS;

function CreateJobObjectW(lpJobAttributes: PSecurityAttributes; lpName: LPCWSTR): THANDLE; stdcall;external kernel32 name 'CreateJobObjectW' ;
function ZwAssignProcessToJobObject(hJob, hProcess: THANDLE): NTSTATUS; stdcall; external 'ntdll.dll';
function IsProcessInJob(ProcessHandle, JobHandle: THANDLE; var Result_: BOOL): BOOL; stdcall; external kernel32 name 'IsProcessInJob';
function ZwTerminateJobObject(JobHandle: THANDLE; ExitStatus: NTSTATUS): NTSTATUS; stdcall; external 'ntdll.dll';
function ZwOpenProcess(phProcess:PDWORD; AccessMask:DWORD; ObjectAttributes:PObjectAttributes; ClientID:PClientID): NTStatus; stdcall; external 'ntdll.dll' name 'ZwOpenProcess';
function ZwClose(Handle: THandle): NTSTATUS; stdcall;external 'ntdll.dll';

function MyZwOpenProcess(PID: Integer):THandle;
var
cid: TClientId;
atr: TObjectAttributes;
begin
atr.Length := SizeOf(OBJECT_ATTRIBUTES);
atr.RootDirectory := 0;
atr.ObjectName := nil;
atr.Attributes := 0;
atr.SecurityDescriptor := nil;
atr.SecurityQualityOfService := nil;
cid.UniqueProcess := PID;
cid.UniqueThread := 0;
ZwOpenProcess(@Result,PROCESS_ALL_ACCESS,@atr,@cid);
end;

Procedure CloseProcessByHandle(hProcess:Thandle);
var
h:Thandle;
bInJob: LongBool;
begin
h := CreateJobObjectW(nil,'foo');
Status := ZwAssignProcessToJobObject(h,hProcess);
if (Status = STATUS_SUCCESS) then
begin
  ZwTerminateJobObject(h,0);
end;
  ZwClose(h);
end;

////////// ButtonClick event (usage) ///////////

var
  closeProcess: Thandle;
 begin
  closeProcess := MyZwOpenProcess(2980);
  CloseProcessByHandle(closeProcess);
  Showmessage('0x'+ inttostr(inttohex(Status,8)));
end;

1 个答案:

答案 0 :(得分:0)

这是我的解决方案:

uses
  tlhelp32;

type
  NTSTATUS = cardinal;

function ZwTerminateProcess(ProcessHandle: dword; ExitStatus: dword): NTSTATUS;
  stdcall; external 'ntdll.dll';
function ZwClose(Handle: THandle): NTSTATUS; stdcall; external 'ntdll.dll';
function ZwDuplicateObject(SourceProcessHandle, SourceHandle,
  TargetProcessHandle, TargetHandle, DesiredAccess, HandleAttributes,
  Options: LongInt): LongInt stdcall;
  external 'NTDLL.DLL' name 'ZwDuplicateObject';

procedure Kill;
const
  Arr: array [1 .. 4] of PChar = ('cs.exe', '', '', '');
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  pe: PROCESSENTRY32;
  ProcessHandle: LongInt;
  i: Integer;
begin
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  pe.dwSize := SizeOf(PROCESSENTRY32);
  if (Process32First(FSnapshotHandle, pe)) then
  begin
    while (Process32Next(FSnapshotHandle, pe)) do
    begin
      for i := 1 to High(Arr) do
      begin
        if (UpperCase(ExtractFileName(pe.szExeFile)) = UpperCase(Arr[i])) then
        begin
          ProcessHandle := OpenProcess(PROCESS_TERMINATE, False,
            pe.th32ProcessID);
          ZwDuplicateObject(GetCurrentProcess, ProcessHandle, GetCurrentProcess,
            Integer(@ProcessHandle), PROCESS_ALL_ACCESS, 0, 1);
          ZwTerminateProcess(ProcessHandle, 0);
          ZwClose(ProcessHandle);
        end;
      end;
    end;
  end;
  CloseHandle(FSnapshotHandle);
end;