mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-10-26 08:31:23 +00:00
The kernel module now links and compiles, there are still a lot of empty TODOs left, there are empty stubs for hypertrace, assembly files and kdserial etc. these can be introduced one by one. My first step will be loading the kernel module from the userspace cli. Big step forward! :)
284 lines
No EOL
5.8 KiB
C
284 lines
No EOL
5.8 KiB
C
/**
|
|
* @file Common.c
|
|
* @author Sina Karvandi (sina@hyperdbg.org)
|
|
* @brief Routines for common tasks in debugger
|
|
* @details
|
|
* @version 0.2
|
|
* @date 2023-01-22
|
|
*
|
|
* @copyright This project is released under the GNU Public License v3.
|
|
*
|
|
*/
|
|
#include "pch.h"
|
|
|
|
/**
|
|
* @brief Checks whether the process with ProcId exists or not
|
|
*
|
|
* @details this function should NOT be called from vmx-root mode
|
|
*
|
|
* @param UINT32 ProcId
|
|
* @return BOOLEAN Returns true if the process
|
|
* exists and false if it the process doesn't exist
|
|
*/
|
|
BOOLEAN
|
|
CommonIsProcessExist(UINT32 ProcId)
|
|
{
|
|
PEPROCESS TargetEprocess;
|
|
|
|
if (PlatformProcessLookupByProcessId((HANDLE)ProcId, &TargetEprocess) != STATUS_SUCCESS)
|
|
{
|
|
//
|
|
// There was an error, probably the process id was not found
|
|
//
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
PlatformObjectDereference(TargetEprocess);
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Get handle from Process Id
|
|
* @param Handle
|
|
* @param ProcessId
|
|
*
|
|
* @return NTSTATUS
|
|
*/
|
|
_Use_decl_annotations_
|
|
NTSTATUS
|
|
CommonGetHandleFromProcess(UINT32 ProcessId, PHANDLE Handle)
|
|
{
|
|
NTSTATUS Status;
|
|
Status = STATUS_SUCCESS;
|
|
OBJECT_ATTRIBUTES ObjAttr = {0};
|
|
CLIENT_ID Cid = {0};
|
|
InitializeObjectAttributes(&ObjAttr, NULL, 0, NULL, NULL);
|
|
|
|
Cid.UniqueProcess = (HANDLE)ProcessId;
|
|
Cid.UniqueThread = (HANDLE)0;
|
|
|
|
Status = PlatformProcessOpen(Handle, PROCESS_ALL_ACCESS, &ObjAttr, &Cid);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
* @brief Get process name by eprocess
|
|
*
|
|
* @param Eprocess Process eprocess
|
|
* @return PCHAR Returns a pointer to the process name
|
|
*/
|
|
PCHAR
|
|
CommonGetProcessNameFromProcessControlBlock(PEPROCESS Eprocess)
|
|
{
|
|
PCHAR Result = 0;
|
|
|
|
//
|
|
// We can't use PlatformProcessLookupByProcessId as in pageable and not
|
|
// work on vmx-root
|
|
//
|
|
Result = (CHAR *)PlatformProcessGetImageFileName(Eprocess);
|
|
|
|
return Result;
|
|
}
|
|
|
|
/**
|
|
* @brief The undocumented way of NtOpenProcess
|
|
* @param ProcessHandle
|
|
* @param DesiredAccess
|
|
* @param ProcessId
|
|
* @param AccessMode
|
|
*
|
|
* @return NTSTATUS
|
|
*/
|
|
NTSTATUS
|
|
CommonUndocumentedNtOpenProcess(
|
|
PHANDLE ProcessHandle,
|
|
ACCESS_MASK DesiredAccess,
|
|
HANDLE ProcessId,
|
|
KPROCESSOR_MODE AccessMode)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
ACCESS_STATE AccessState;
|
|
CHAR AuxData[0x200] = {0};
|
|
PEPROCESS ProcessObject = NULL;
|
|
HANDLE ProcHandle = NULL;
|
|
|
|
Status = PlatformSeCreateAccessState(
|
|
&AccessState,
|
|
AuxData,
|
|
DesiredAccess,
|
|
(PGENERIC_MAPPING)((PCHAR)*PsProcessType + 52));
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return Status;
|
|
}
|
|
|
|
AccessState.PreviouslyGrantedAccess |= AccessState.RemainingDesiredAccess;
|
|
AccessState.RemainingDesiredAccess = 0;
|
|
|
|
Status = PlatformProcessLookupByProcessId(ProcessId, &ProcessObject);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
PlatformSeDeleteAccessState(&AccessState);
|
|
return Status;
|
|
}
|
|
Status = PlatformObjectOpenByPointer(
|
|
ProcessObject,
|
|
0,
|
|
&AccessState,
|
|
0,
|
|
*PsProcessType,
|
|
AccessMode,
|
|
&ProcHandle);
|
|
|
|
PlatformSeDeleteAccessState(&AccessState);
|
|
|
|
PlatformObjectDereference(ProcessObject);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
*ProcessHandle = ProcHandle;
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
* @brief Kill a user-mode process with different methods
|
|
* @param ProcessId
|
|
* @param KillingMethod
|
|
*
|
|
* @return BOOLEAN
|
|
*/
|
|
_Use_decl_annotations_
|
|
BOOLEAN
|
|
CommonKillProcess(UINT32 ProcessId, PROCESS_KILL_METHODS KillingMethod)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
HANDLE ProcessHandle = NULL;
|
|
PEPROCESS Process = NULL;
|
|
|
|
if (ProcessId == NULL_ZERO)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
switch (KillingMethod)
|
|
{
|
|
case PROCESS_KILL_METHOD_1:
|
|
|
|
Status = CommonGetHandleFromProcess(ProcessId, &ProcessHandle);
|
|
|
|
if (!NT_SUCCESS(Status) || ProcessHandle == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Call ZwTerminateProcess with NULL handle
|
|
//
|
|
Status = PlatformProcessTerminate(ProcessHandle, 0);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
break;
|
|
|
|
case PROCESS_KILL_METHOD_2:
|
|
|
|
CommonUndocumentedNtOpenProcess(
|
|
&ProcessHandle,
|
|
PROCESS_ALL_ACCESS,
|
|
(HANDLE)ProcessId,
|
|
KernelMode);
|
|
|
|
if (ProcessHandle == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Call ZwTerminateProcess with NULL handle
|
|
//
|
|
Status = PlatformProcessTerminate(ProcessHandle, 0);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
break;
|
|
|
|
case PROCESS_KILL_METHOD_3:
|
|
|
|
//
|
|
// Get the base address of process's executable image and unmap it
|
|
//
|
|
Status = PlatformMemUnmapViewOfSection(Process, PlatformProcessGetSectionBaseAddress(Process));
|
|
|
|
//
|
|
// Dereference the target process
|
|
//
|
|
PlatformObjectDereference(Process);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
//
|
|
// Unknown killing method
|
|
//
|
|
return FALSE;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// If we reached here, it means the functionality of
|
|
// the above codes was successful
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
* @brief Validate core number
|
|
* @param CoreNumber
|
|
*
|
|
* @return BOOLEAN
|
|
*/
|
|
_Use_decl_annotations_
|
|
BOOLEAN
|
|
CommonValidateCoreNumber(UINT32 CoreNumber)
|
|
{
|
|
ULONG ProcessorsCount;
|
|
|
|
ProcessorsCount = PlatformCpuGetActiveProcessorCount();
|
|
|
|
if (CoreNumber >= ProcessorsCount)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Get cpuid results
|
|
*
|
|
* @param Func
|
|
* @param SubFunc
|
|
* @param CpuInfo
|
|
* @return VOID
|
|
*/
|
|
VOID
|
|
CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, INT * CpuInfo)
|
|
{
|
|
CpuCpuIdEx(CpuInfo, Func, SubFunc);
|
|
} |