Protection process
Posted: Wed Jun 19, 2013 6:55 pm
Bring to your attention, one way, to protect the process of terminate. He founded the interception kernel functions such as NtOpenProcess and NtTerminateProcess. This is done by substitution of the addresses in the table SST (SYSTEM SERVICE TABLE). This is possible only, ring 0, operating system, and therefore need a driver.
Code drivers pbNoKill.sys. Code for works with the driver - a file DrUserModeFramework.pbi. The test code which demonstrates operation of driver.You can not terminate the process the program, using Task Manager.
Download files
Code drivers pbNoKill.sys.
Code: Select all
Declare DriverEntry(*DriverObject, *RegistryPath)
; Объявляем прототип True функции для перехватываемой функции.
Prototype pNtOpenProcess(*ProcessHandle, DesiredAccess,
*ObjectAttributes, *ClientId)
Prototype.i pNtTerminateProcess(ProcessHandle.i, ExitStatus.i)
Global TrueNtOpenProcess.pNtOpenProcess=0 ; Оригинальная функция из ядра.
Global TrueNtTerminateProcess.pNtTerminateProcess=0 ; Оригинальная функция из ядра.
Global gOpenProcId=0, gTerminateProcId=0, gMyPID.l=0
*A=@DriverEntry()
!jmp [p_A]
#Debug = #False ; #True
IncludePath #PB_Compiler_Home+"DDK\"
XIncludeFile "ntddk.pbi"
XIncludeFile "ntstatus.pbi"
XIncludeFile "ntfunct.pbi"
Import "ntoskrnl.lib"
*KeServiceDescriptorTable.SERVICE_DESCRIPTOR_TABLE As "__imp__KeServiceDescriptorTable"
*NtBuildNumber.Unicode As "__imp__NtBuildNumber"
*MmUserProbeAddress As "__imp__MmUserProbeAddress"
EndImport
#IOCTL_NewPid = $200
Macro NTCALL(_function)
*KeServiceDescriptorTable\ntoskrnl\ServiceTable\ar[_function]
EndMacro
Macro KernelDebug(String)
CompilerIf #Debug = #True
DbgPrint(@String)
CompilerEndIf
EndMacro
EnableExplicit
Procedure NewNtOpenProcess(*ProcessHandle, DesiredAccess,
*ObjectAttributes, *ClientId.CLIENT_ID)
Protected ProcessId
If gMyPID<>0
; If *ClientId > *MmUserProbeAddress
; KernelDebug("*ClientId > *MmUserProbeAddress")
; ProcedureReturn #STATUS_INVALID_PARAMETER
; EndIf
MOV ebx, *ClientId
CMP ebx, *MmUserProbeAddress
!JBE newntopenprocess__m1
KernelDebug("*ClientId > *MmUserProbeAddress")
ProcedureReturn #STATUS_INVALID_PARAMETER
!newntopenprocess__m1:
If *ClientId
ProcessId = *ClientId\UniqueProcess
Else
KernelDebug("*ClientId = 0")
ProcedureReturn #STATUS_INVALID_PARAMETER
EndIf
If gMyPID = ProcessId
KernelDebug("My Process")
ProcedureReturn #STATUS_ACCESS_DENIED
Else
Goto m2
EndIf
Else
m2:
If TrueNtOpenProcess
ProcedureReturn TrueNtOpenProcess(*ProcessHandle, DesiredAccess,
*ObjectAttributes, *ClientId)
Else
ProcedureReturn #STATUS_INVALID_ADDRESS
EndIf
EndIf
EndProcedure
Procedure GetPID(ProcessHandle)
Protected *obj, ProcessId
ProcessId = $FFFFFFFF
If ObReferenceObjectByHandle(ProcessHandle, 0 ,0, #KernelMode,
@*obj,#Null) = #STATUS_SUCCESS
ProcessId = PsGetProcessId(*obj)
ObDereferenceObject(*obj)
EndIf
ProcedureReturn ProcessId
EndProcedure
Procedure.i NewNtTerminateProcess(ProcessHandle.i, ExitStatus.i)
If gMyPID<> 0 And GetPID(ProcessHandle) = gMyPID
KernelDebug("Terminate my process")
ProcedureReturn #STATUS_ACCESS_DENIED
Else
If TrueNtTerminateProcess
ProcedureReturn TrueNtTerminateProcess(ProcessHandle, ExitStatus)
Else
ProcedureReturn #STATUS_INVALID_ADDRESS
EndIf
EndIf
EndProcedure
Procedure DeviceIoControl(*DeviceObject.DEVICE_OBJECT, *pIrp.IRP)
Protected ntStatus, *Point, *Stack.IO_STACK_LOCATION
Protected inBuffersize, outBuffersize, CtrlBuff.l
Protected Code
*Stack = *pIrp\Tail\Overlay\CurrentStackLocation
inBuffersize = *Stack\Parameters\DeviceIoControl\InputBufferLength
outBuffersize = *Stack\Parameters\DeviceIoControl\OutputBufferLength
If inBuffersize>=4
CtrlBuff = PeekL(*pIrp\SystemBuffer)
Code = *Stack\Parameters\DeviceIoControl\IoControlCode
ntStatus = #STATUS_SUCCESS
Select Code
Case #IOCTL_NewPid
gMyPID = CtrlBuff
Default
ntStatus = #STATUS_UNSUCCESSFUL
EndSelect
Else
ntStatus = #STATUS_BUFFER_TOO_SMALL
EndIf
*pIrp\IoStatus\Information = 0
*pIrp\IoStatus\Status = ntStatus
IoCompleteRequest(*pIrp, #IO_NO_INCREMENT)
ProcedureReturn ntStatus
EndProcedure
Procedure CreateDispatch(*DeviceObject.DEVICE_OBJECT, *pIrp.IRP)
*pIrp\IoStatus\Information = 0
*pIrp\IoStatus\Status = #STATUS_SUCCESS
IoCompleteRequest(*pIrp, #IO_NO_INCREMENT)
ProcedureReturn #STATUS_SUCCESS
EndProcedure
Macro UnInterception()
CLI ; запрещаем прерывания
MOV eax, cr0
MOV CR0Reg,eax
AND eax,$FFFEFFFF ; сбросить WP bit
MOV cr0, eax
If TrueNtOpenProcess
NTCALL(gOpenProcId) = TrueNtOpenProcess
EndIf
If TrueNtTerminateProcess
NTCALL(gTerminateProcId) = TrueNtTerminateProcess
EndIf
MOV eax, CR0Reg
MOV cr0, eax ; востановить содержимое CR0
STI ; разрешаем прерывания
EndMacro
Procedure DriverUnload(*DriverObject.DRIVER_OBJECT)
Protected uniDOSString.UNICODE_STRING
Protected CR0Reg.i
UnInterception()
RtlInitUnicodeString(@uniDOSString, ?DosDevices)
IoDeleteSymbolicLink (@uniDOSString)
IoDeleteDevice(*DriverObject\DeviceObject)
EndProcedure
Macro Interception()
Select *NtBuildNumber\u
Case 2195 ; Win 2000
gOpenProcId = $06A
gTerminateProcId = 0 ; Не перехватывать, т. к. в ядре отсутствует Native фукнция PsGetProcessId()!
Case 2600 ; Win XP
gOpenProcId = $07A
gTerminateProcId = $101
Case 3790 ; Win 2003.
gOpenProcId = $80
gTerminateProcId = $10A
Case 6000, ; Win Vista RTM.
6001, ; Win Vista SP1 и Win Server 2008 RTM.
6002 ; Win Vista SP2 и Win Server 2008 SP2.
gOpenProcId = $C2
If *NtBuildNumber\u=6000
gTerminateProcId = $152
Else
gTerminateProcId = $14e
EndIf
Case 7600, ; Win 7 RTM и Win Server 2008 R2 RTM.
7601 ; Win 7 SP1 и Win Server 2008 R2 SP1.
gOpenProcId = $BE
gTerminateProcId = $172
Case 9200 ; Win 8.
gOpenProcId = 0 ; Не перехватывать, т. к. BSoD.
gTerminateProcId = $23
Default
ProcedureReturn #STATUS_NOT_IMPLEMENTED
EndSelect
; Устанавливаем перехваты.
If gOpenProcId>0
TrueNtOpenProcess = NTCALL(gOpenProcId)
If TrueNtOpenProcess = 0
ProcedureReturn #STATUS_INVALID_ADDRESS
EndIf
Else
TrueNtOpenProcess = 0
EndIf
If gTerminateProcId>0
TrueNtTerminateProcess = NTCALL(gTerminateProcId)
If TrueNtTerminateProcess = 0
ProcedureReturn #STATUS_INVALID_ADDRESS
EndIf
Else
TrueNtTerminateProcess = 0
EndIf
CLI ; запрещаем прерывания
MOV eax, cr0
MOV CR0Reg,eax
AND eax,$FFFEFFFF ; сбросить WP bit
MOV cr0, eax
If gOpenProcId>0
NTCALL(gOpenProcId) = @NewNtOpenProcess()
EndIf
If gTerminateProcId>0
NTCALL(gTerminateProcId) = @NewNtTerminateProcess()
EndIf
MOV eax, CR0Reg
MOV cr0, eax ; востановить содержимое CR0
STI ; разрешаем прерывания
EndMacro
Procedure DriverEntry(*DriverObject.DRIVER_OBJECT, *RegistryPath.UNICODE_STRING)
Protected deviceObject.DEVICE_OBJECT
Protected uniNameString.UNICODE_STRING
Protected uniDOSString.UNICODE_STRING, status
Protected CR0Reg.i
If *KeServiceDescriptorTable And *NtBuildNumber
Interception()
RtlInitUnicodeString(@uniNameString, ?Device)
RtlInitUnicodeString(@uniDOSString, ?DosDevices)
status = IoCreateDevice(*DriverObject, 0, @uniNameString, #FILE_DEVICE_UNKNOWN,
0, #False, @deviceObject)
If status <> #STATUS_SUCCESS
UnInterception()
ProcedureReturn status
EndIf
status = IoCreateSymbolicLink(@uniDOSString, @uniNameString)
If status <> #STATUS_SUCCESS
IoDeleteDevice(@deviceObject) ; Мы должны сами убирать "хвосты" в режиме ядра!
UnInterception()
ProcedureReturn status
EndIf
*DriverObject\DriverUnload = @DriverUnload()
*DriverObject\MajorFunction[#IRP_MJ_CREATE] = @CreateDispatch()
*DriverObject\MajorFunction[#IRP_MJ_CLOSE] = @CreateDispatch()
*DriverObject\MajorFunction[#IRP_MJ_DEVICE_CONTROL] = @DeviceIoControl()
ProcedureReturn #STATUS_SUCCESS
Else
ProcedureReturn #STATUS_INVALID_SYSTEM_SERVICE
EndIf
EndProcedure
DataSection
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x86
Device:
!du '\Device\pbNoKill', 0, 0
DosDevices:
!du '\DosDevices\pbNoKill', 0, 0
CompilerCase #PB_Processor_x64
Device:
!du '\Device\pbNoKill_x64', 0, 0
DosDevices:
!du '\DosDevices\pbNoKill_x64', 0, 0
CompilerEndSelect
EndDataSection
Code: Select all
Procedure Driver_Start(ServiceName.s) ; Запуск драйвера.
Protected hSCManager.l, hServ.l, Result
Result=#False
hSCManager = OpenSCManager_(#Null, #Null, #SC_MANAGER_ALL_ACCESS)
If hSCManager = 0
If GetLastError_() = #ERROR_ACCESS_DENIED
hSCManager = OpenSCManager_(#Null, #Null, #GENERIC_READ)
hServ = OpenService_(hSCManager, ServiceName, #GENERIC_EXECUTE)
If StartService_(hServ, 0, #Null)
Result=#True
EndIf
EndIf
Else
hServ = OpenService_(hSCManager, ServiceName, #GENERIC_EXECUTE)
If StartService_(hServ, 0, #Null)
Result=#True
Else
ErrorCode=GetLastError_()
If ErrorCode=1056
Result=#True
EndIf
EndIf
EndIf
If hServ : CloseServiceHandle_(hServ) : EndIf
If hSCManager : CloseServiceHandle_(hSCManager) : EndIf
ProcedureReturn Result
EndProcedure
Procedure Driver_UnInstall(ServiceName.s) ; Деинсталяция драйвера.
Protected ServiceStatus.SERVICE_STATUS
hSCManager = OpenSCManager_(#Null, #Null, #SC_MANAGER_ALL_ACCESS)
hServ = OpenService_(hSCManager, ServiceName, #SERVICE_ALL_ACCESS)
If hServ<>#Null
ControlService=ControlService_(hServ, #SERVICE_CONTROL_STOP, @ServiceStatus)
DeleteService_(hServ)
EndIf
If hServ : CloseServiceHandle_(hServ) : EndIf
If hSCManager : CloseServiceHandle_(hSCManager) : EndIf
EndProcedure
Procedure Driver_Install(FileName.s, ServiceName.s, DisplayName.s) ; Инсталляция драйвера в систему.
Protected Result, Mgr, Ser, Count
Result=#False
Count=0
Driver_Install_M1:
Mgr = OpenSCManager_(#Null, #Null, #SC_MANAGER_ALL_ACCESS)
If Mgr
Ser = CreateService_(Mgr, ServiceName, DisplayName, #SERVICE_ALL_ACCESS, #SERVICE_KERNEL_DRIVER, #SERVICE_SYSTEM_START, #SERVICE_ERROR_NORMAL, FileName, #Null, 0, 0, 0, 0)
ErrorCode=GetLastError_()
If Ser
Result=#True
ElseIf ErrorCode=1073
Result=#True
ElseIf ErrorCode=1072
If Count=0
If Ser : CloseServiceHandle_(Ser) : EndIf
If Mgr : CloseServiceHandle_(Mgr) : EndIf
Driver_UnInstall(ServiceName)
Count+1
Goto Driver_Install_M1
EndIf
EndIf
EndIf
If Ser : CloseServiceHandle_(Ser) : EndIf
If Mgr : CloseServiceHandle_(Mgr) : EndIf
ProcedureReturn Result
EndProcedure
Procedure OpenDriver(FileName.s, DriverName.s, ServiceName.s, DisplayName.s)
Protected Result, hDriver
Result=0
hDriver = CreateFile_("\\.\"+DriverName, #GENERIC_READ | #GENERIC_WRITE, 0, 0, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL, 0)
If hDriver=#INVALID_HANDLE_VALUE
If Driver_Install(FileName, ServiceName, DisplayName)
If Driver_Start(ServiceName)
hDriver = CreateFile_("\\.\"+DriverName, #GENERIC_READ | #GENERIC_WRITE, 0, 0, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL, 0)
If hDriver <> #INVALID_HANDLE_VALUE
Result=hDriver
EndIf
EndIf
EndIf
Else
Result=hDriver
EndIf
ProcedureReturn Result
EndProcedure
Code: Select all
XIncludeFile "DrUserModeFramework.pbi"
#IOCTL_NewPid = $200
#DrName = "pbNoKill"
SetCurrentDirectory(GetPathPart(ProgramFilename()))
g_hSemaphore_runonly = CreateSemaphore_(#Null,0,1,"pbNoKilltest_runs")
If g_hSemaphore_runonly And GetLastError_()=#ERROR_ALREADY_EXISTS
CloseHandle_(g_hSemaphore_runonly)
MessageRequester("", "The program is already running!", #MB_ICONWARNING)
End
EndIf
hDriver=OpenDriver(GetPathPart(ProgramFilename())+#DrName+".sys", #DrName, #DrName, #DrName)
If hDriver=0
Driver_UnInstall(#DrName)
MessageRequester("", "Failed to load driver")
End
EndIf
PID = GetCurrentProcessId_()
Code = DeviceIoControl_(hDriver, #IOCTL_NewPid, @PID, 4, 0, 0, @BytesReturned, 0)
If Code
OpenWindow(0, 0, 0, 222, 200, "Test "+#DrName, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TextGadget(0, 4, 10, 210, 30, "Try to complete the process of this program with Task Manager")
ButtonGadget(4, 10,170, 200, 20, "Close")
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget
If EventGadget()=4
Break
EndIf
EndIf
ForEver
Else
Code = GetLastError_()
MessageRequester("", "Error "+Str(Code)+" when applying to the driver")
EndIf
CloseHandle_(hDriver)
Driver_UnInstall(#DrName)
CloseHandle_(g_hSemaphore_runonly)
Download files