Process Hacker and Windows discussion

 
Zorkov Igor
Member
Posts: 112
Joined: 18 Jan 2011 10:11
OS: Windows 7, 10
Location: Великая Русь
Contact:

Suspend process in kernel mode on 2003 and XP

03 Feb 2011 10:16

To suspend process in kernel mode PH use PsSuspendProcess but this function available on Vista or higher as far as I know

PH can't suspend process in kernel mode on 2003 and XP?
 
User avatar
wj32
Founder
Posts: 948
Joined: 17 Jan 2011 05:19
OS: Windows
Location: Australia
Contact:

Re: Suspend process in kernel mode on 2003 and XP

03 Feb 2011 10:18

No. I'm not going to insert my own suspend APC, because it will seriously confuse users when they find out they can't resume the process using anything other than PH.
 
Zorkov Igor
Member
Posts: 112
Joined: 18 Jan 2011 10:11
OS: Windows 7, 10
Location: Великая Русь
Contact:

Re: Suspend process in kernel mode on 2003 and XP

03 Feb 2011 10:33

How about use ZwSuspendProcess?
 
scorpion007
Member
Posts: 22
Joined: 01 Feb 2011 06:56

Re: Suspend process in kernel mode on 2003 and XP

03 Feb 2011 10:44

Does Proc Explorer support suspending processes in XP? If so, how do they do it?
 
Zorkov Igor
Member
Posts: 112
Joined: 18 Jan 2011 10:11
OS: Windows 7, 10
Location: Великая Русь
Contact:

Re: Suspend process in kernel mode on 2003 and XP

03 Feb 2011 10:50

When I the first time for session start PH with administrator privileges and then close PH kprocesshacker.sys is still loaded and next time I can start PH without administrator privileges to suspend a system process for example
 
User avatar
wj32
Founder
Posts: 948
Joined: 17 Jan 2011 05:19
OS: Windows
Location: Australia
Contact:

Re: Suspend process in kernel mode on 2003 and XP

03 Feb 2011 10:57

How about use ZwSuspendProcess?
Is that exported from ntoskrnl?
Does Proc Explorer support suspending processes in XP? If so, how do they do it?
What does this have to do with suspending processes in kernel-mode?
 
Zorkov Igor
Member
Posts: 112
Joined: 18 Jan 2011 10:11
OS: Windows 7, 10
Location: Великая Русь
Contact:

Re: Suspend process in kernel mode on 2003 and XP

03 Feb 2011 12:15

Is that exported from ntoskrnl?
No, but to find the address easily in user mode and sent to the driver, at least in delphi

[delphi]ZwSuspendProcessAddress := (GetProcAddress(GetModuleHandleW('ntdll.dll'), 'NtSuspendProcess'));[/delphi]

But I am assured it it is easily possible to translate on C

Here a complied example and sources http://www.onlinedisk.ru/file/602227/

User
[delphi file="SuspendProcess.pas"]

unit SuspendProcess;

interface

uses
Windows, WinSvc, SysUtils, Dialogs;

var
DriverDevice: THANDLE = 0;

function ZwSuspendProcess(ProcessHandle: ULONG): Boolean;

implementation

function EnablePrivilege(Privilege: WideString): Boolean;
var
TokenHandle: THandle;
TokenPrivileges: TTokenPrivileges;
ReturnLength: Cardinal;
begin
Result := False;
if Windows.OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, TokenHandle) then
begin
try
LookupPrivilegeValueW(nil, PWideChar(Privilege), TokenPrivileges.Privileges[0].Luid);
TokenPrivileges.PrivilegeCount := 1;
TokenPrivileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
if AdjustTokenPrivileges(TokenHandle, False, TokenPrivileges, 0, nil, ReturnLength) then
Result := True;
finally
CloseHandle(TokenHandle);
end;
end;
end;

procedure LoadDriver(DriverPath: WideString);
var
hSCManager, hService: SC_HANDLE;
lpServiceArgVectors: PWideChar;
begin
hSCManager := 0;
hSCManager := OpenSCManagerW(nil, nil, SC_MANAGER_ALL_ACCESS);

if hSCManager <> 0 then
begin
hService := 0;
hService := CreateServiceW(hSCManager,
'ZwSuspendProcess',
'ZwSuspendProcess',
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
PWideChar(DriverPath),
nil,
nil,
nil,
nil,
nil);

hService := 0;
lpServiceArgVectors := nil;

hService := OpenServiceW(hSCManager, 'ZwSuspendProcess', SERVICE_ALL_ACCESS);
if hService <> 0 then
begin
if StartServiceW(hService, 0, PWideChar(lpServiceArgVectors)) then
begin

end
else
begin
//ShowMessage(SysErrorMessage(GetLastError));
end;

CloseServiceHandle(hService);
end;
CloseServiceHandle(hSCManager);
end;

DriverDevice := CreateFileW('\\.\' + 'ZWSUSPENDPROCESS', GENERIC_READ or GENERIC_WRITE, 0, PSECURITY_DESCRIPTOR(nil), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
end;

procedure UnloadDriver;
var
hSCManager, hService: SC_HANDLE;
lpServiceStatus: TServiceStatus;
begin
if (DriverDevice <> 0) then
CloseHandle(DriverDevice);

hSCManager := 0;
hSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);

if hSCManager <> 0 then
begin

hService := 0;
hService := OpenService(hSCManager, 'ZwSuspendProcess', SERVICE_ALL_ACCESS);
if (hService <> 0) then
begin
ControlService(hService, SERVICE_CONTROL_STOP, lpServiceStatus);
DeleteService(hService);
Waitforsingleobject(hService, infinite);
CloseServiceHandle(hService);
end;

CloseServiceHandle(hSCManager);
end;
end;

function CTL_CODE(DeviceType: Integer; Func: Integer; Meth: Integer; Access: Integer): DWORD;
begin
Result := (DeviceType shl 16) or (Access shl 14) or (Func shl 2) or (Meth);
end;

type
TZwSuspendProcessInfo = record
ProcessHandle: ULONG;
ZwSuspendProcessAddress: Pointer;
end;
PZwSuspendProcessInfo = ^TZwSuspendProcessInfo;

function ZwSuspendProcess(ProcessHandle: ULONG): Boolean;
var
dwBytesReturned: DWORD;
ZwSuspendProcessInfo: TZwSuspendProcessInfo;
begin
Result := False;
ZwSuspendProcessInfo.ProcessHandle := ProcessHandle;
ZwSuspendProcessInfo.ZwSuspendProcessAddress := (GetProcAddress(GetModuleHandleW('ntdll.dll'), 'NtSuspendProcess'));
Result := DeviceIoControl(DriverDevice, CTL_CODE($F100, $0900, 0, 0), @ZwSuspendProcessInfo, SizeOf(ZwSuspendProcessInfo), nil, 0, dwBytesReturned, 0);
end;
[/delphi]

Driver
[c file="ZwSuspendProcess.c"]
#include "ntifs.h"
#include <ntddk.h>

#define IOCTL_ZW_SUSPEND_PROCESS CTL_CODE(0xF100, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define DWORD unsigned long
#define WORD unsigned short

void UnloadDriver(PDRIVER_OBJECT DriverObject);

NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;

extern PServiceDescriptorTableEntry KeServiceDescriptorTable;

typedef NTSTATUS (*_ZwSuspendProcess)(IN ULONG ProcessHandle);

_ZwSuspendProcess ZwSuspendProcess;

void UnloadDriver(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING DeviceName;

IoDeleteDevice(DriverObject->DeviceObject);

RtlInitUnicodeString(&DeviceName, L"\\DosDevices\\ZWSUSPENDPROCESS");
IoDeleteSymbolicLink(&DeviceName);
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS Status;
UNICODE_STRING DriverName;
UNICODE_STRING DeviceName;
PDEVICE_OBJECT DeviceObject;

RtlInitUnicodeString(&DriverName, L"\\Device\\ZWSUSPENDPROCESS");
Status = IoCreateDevice(DriverObject, 0, &DriverName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);

if(Status != STATUS_SUCCESS)
return Status;

RtlInitUnicodeString(&DeviceName, L"\\DosDevices\\ZWSUSPENDPROCESS");
Status = IoCreateSymbolicLink(&DeviceName, &DriverName);

if(Status != STATUS_SUCCESS)
{
IoDeleteDevice(DeviceObject);
return Status;
}

DriverObject->DriverUnload = UnloadDriver;
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;

return Status;
}

NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;

IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}

typedef struct _ZwSuspendProcessInfo
{
ULONG ProcessHandle;
PVOID ZwSuspendProcessAddress;
}
TZwSuspendProcessInfo, *PZwSuspendProcessInfo;

NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);

switch(IrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_ZW_SUSPEND_PROCESS:
{
DWORD FunctionAddress;
int ZwSuspendProcessPosition;

TZwSuspendProcessInfo ZwSuspendProcessInfo = *(PZwSuspendProcessInfo)Irp->AssociatedIrp.SystemBuffer;

FunctionAddress = NULL;
ZwSuspendProcessPosition = 0;
FunctionAddress = ZwSuspendProcessInfo.ZwSuspendProcessAddress;
if (FunctionAddress)
{
ZwSuspendProcessPosition = *((WORD*)(FunctionAddress + 1));
ZwSuspendProcess = (_ZwSuspendProcess)(*(((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase + ZwSuspendProcessPosition));

Status = ZwSuspendProcess(ZwSuspendProcessInfo.ProcessHandle);
}

break;
}

default: break;
}

Irp->IoStatus.Status = Status;

if(Status == STATUS_SUCCESS)
Irp->IoStatus.Information = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
else
Irp->IoStatus.Information = 0;

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return Status;
}
[/c]
 
User avatar
wj32
Founder
Posts: 948
Joined: 17 Jan 2011 05:19
OS: Windows
Location: Australia
Contact:

Re: Suspend process in kernel mode on 2003 and XP

03 Feb 2011 19:55

And what if NtSuspendProcess is hooked, making the system call number invalid?