-
Notifications
You must be signed in to change notification settings - Fork 278
Process Operations
Protecting processes from killing and dumping using PsProcessType
obcallback that runs every time a handle to a process is requested. This feature is not enabled when the driver is loaded reflectively.
OB_PREOP_CALLBACK_STATUS OnPreOpenProcess(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION Info)
RegistrationContext [PVOID] -- Unused.
Info [POB_PRE_OPERATION_INFORMATION] -- Contains important information such as process name, handle to the process, process type, etc.
# Protect process
NidhoggClient.exe process add <PID>
# Unprotect process
NidhoggClient.exe process remove <PID>
The function begins by checking if the operation is a kernel handle operation. If it is, it returns OB_PREOP_SUCCESS
.
Next, it checks if there are any protected processes. If there are none, it returns OB_PREOP_SUCCESS
.
The function then gets the process ID of the process object in the Info structure.
It checks if the process ID is in the list of protected processes. If it is, it removes the following permissions from the process:
-
PROCESS_VM_OPERATION
: The ability to perform virtual memory operations. -
PROCESS_VM_READ
: The ability to read from the process's virtual memory. -
PROCESS_CREATE_THREAD
: The ability to create a new thread in the process. -
PROCESS_DUP_HANDLE
: The ability to duplicate the process's handles. -
PROCESS_TERMINATE
: The ability to terminate the process. Finally, it returnsOB_PREOP_SUCCESS
.
Hiding processes by removing the entry from from the process links list. This operation is not PatchGuard safe.
NTSTATUS ProcessUtils::HideProcess(ULONG pid)
pid [ULONG] -- PID to hide.
# Hiding process
NidhoggClient.exe process hide <PID>
# Unhiding process
NidhoggClient.exe process unhide <PID>
The function begins by getting the offsets of the ActiveProcessLinks
and ProcessLock
in the EPROCESS
structure. If either of these operations fail, it returns STATUS_UNSUCCESSFUL
.
Next, it looks up the process by the provided PID
. If this operation fails, it returns the status of the operation.
The function then gets the list entry of the process in the process list and the lock of the process list.
It acquires the process list lock to avoid accessing problems.
The function then adds the process to the list of hidden processes. If this operation fails, it releases the process list lock, dereferences the process object, and returns STATUS_UNSUCCESSFUL
.
The function then removes the process from the process list, releases the process list lock, and dereferences the process object.
Finally, it returns the status of the operation. If the operation was successful, it means that the process was successfully hidden. If the status is STATUS_UNSUCCESSFUL
, it means that the process was not hidden.
Elevating process by changing the token to SYSTEM token.
NTSTATUS ProcessUtils::ElevateProcess(ULONG pid)
pid [ULONG] -- PID to elevate.
NidhoggClient.exe process elevate<PID>
The function begins by looking up the target process using the provided PID
and the SYSTEM
process. It also gets the offset of the token in the EPROCESS
structure.
If either of these operations fail, it returns the status of the operation.
The function then replaces the token of the target process with the token of the SYSTEM
process. This effectively gives the target process the same privileges as the SYSTEM
process.
Finally, it dereferences the SYSTEM
process and the target process and returns the status of the operation. If the operation was successful, it means that the process was successfully elevated. If the status is not STATUS_SUCCESS
, it means that the process was not elevated.
Modifying the process signature to give or strip any kind of PP (Protected Process) or PPL (Protected Process Light).
NTSTATUS ProcessUtils::SetProcessSignature(ProcessSignature* ProcessSignature)
ProcessSignature [ProcessSignature*] -- Contains the process PID, signer type and signature signer.
NidhoggClient.exe process signature <PID> <SIGNER TYPE> <SIGNATURE SIGNER>
The function begins by looking up the process using the PID
from the ProcessSignature
structure. If this operation fails, it returns the status of the operation.
Next, it calculates the new signature level by shifting the signer type left by 4 bits and ORing it with the signature signer.
The function then gets the process signature by adding the signature level offset to the process.
It sets the SignatureLevel
, Type
, and Signer
of the process signature to the new signature level, signer type, and signature signer, respectively.
Finally, it dereferences the process and returns the status of the operation. If the operation was successful, it means that the process signature was successfully set. If the status is not STATUS_SUCCESS
, it means that the process signature was not set.
Protecting threads from killing using PsThreadType
obcallback that runs every time a handle to a process is requested. This feature is not enabled when the driver is loaded reflectively.
OB_PREOP_CALLBACK_STATUS OnPreOpenThread(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION Info)
RegistrationContext [PVOID] -- Unused.
Info [POB_PRE_OPERATION_INFORMATION] -- Contains important information such as thread name, handle to the thread, thread type, etc.
# Protect thread
NidhoggClient.exe thread add <TID>
# Unprotect thread
NidhoggClient.exe thread remove <TID>
The function begins by checking if the operation is a kernel handle operation. If it is, it returns OB_PREOP_SUCCESS
.
Next, it checks if there are any protected threads. If there are none, it returns OB_PREOP_SUCCESS
.
The function then gets the thread ID and the owner process ID of the thread object in the Info
structure. It also gets the caller process ID.
It checks if the caller process is the owner of the thread or the SYSTEM
process. If it is, it returns OB_PREOP_SUCCESS
.
The function then checks if the thread ID is in the list of protected threads. If it is, it removes the following permissions from the thread:
-
THREAD_TERMINATE
: The ability to terminate the thread. -
THREAD_SUSPEND_RESUME
: The ability to suspend and resume the thread. -
THREAD_SET_CONTEXT
: The ability to set the context of the thread. Finally, it returnsOB_PREOP_SUCCESS
.
Hiding a thread by removing it from the thread list entry. Upon Nidhogg unloading, the thread is restored to the original process or explorer
if the original process died to avoid BSODs.
NTSTATUS ProcessUtils::HideThread(ULONG tid)
tid [ULONG] -- TID to hide.
# Hide thread
NidhoggClient.exe thread hide <TID>
# Unhide thread
NidhoggClient.exe thread unhide <TID>
The function begins by getting the offsets of the ThreadListEntry
and ThreadLock
in the ETHREAD
structure. If either of these operations fail, it returns STATUS_UNSUCCESSFUL
.
Next, it looks up the thread by the provided TID
. If this operation fails, it returns the status of the operation.
The function then gets the owning process of the thread. If the owning process is NULL
, it dereferences the thread object and returns STATUS_NOT_FOUND
.
It gets the PID
of the owning process. If the PID
is 0, it dereferences the thread object and returns STATUS_NOT_FOUND
.
The function then gets the list entry of the thread in the thread list and the lock of the thread list.
It acquires the thread list lock to avoid accessing problems.
The function then tries to remove the thread from the thread list. If this operation fails, it sets the status to STATUS_UNSUCCESSFUL
.
It releases the thread list lock and dereferences the thread object.
If the status of the operation is successful, it adds the thread to the list of hidden threads.
Finally, it returns the status of the operation. If the operation was successful, it means that the thread was successfully hidden. If the status is STATUS_UNSUCCESSFUL
, it means that the thread was not hidden.