Delphi ZwAssignProcessToJobObject:访问被拒绝

Delphi ZwAssignProcessToJobObject:访问被拒绝,delphi,winapi,kill-process,Delphi,Winapi,Kill Process,我正在尝试完成一个确定的进程(),但在此之前我需要ZwAssignProcessToJobObject(),我编写了以下小代码来演示我的问题,其中状态返回0xC0000022(访问被拒绝)。有办法解决吗 type NTSTATUS = cardinal; PClientId = ^TClientId; TClientId = record UniqueProcess: THandle; UniqueThread: THandle; end; PObjectAttri

我正在尝试完成一个确定的进程(),但在此之前我需要
ZwAssignProcessToJobObject()
,我编写了以下小代码来演示我的问题,其中
状态
返回0xC0000022(访问被拒绝)。有办法解决吗

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;
以下是我的解决方案:

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;

查找的src代码。由于多种原因,它可能返回
状态\u访问\u被拒绝
。在您的情况下,最可能的情况是-如果作业中已存在流程,或者如果作业会话id与流程会话id不同。您的代码不清楚-您使用的流程是什么。为什么你要做你要做的事,而不是简单地终止process@RbMm非常感谢。解决了@如果你对发布/接收答案不感兴趣,考虑删除问题。您介意解释一下为什么不使用
TerminateProcess
?与
pe.szExeFile
相比,
Arr
持有空字符串有什么区别?@kobik,这是一种杀死任何进程(例如rootkits)的解决方案。在这种情况下,请在问题中指定这一事实。