Skip to content

Commit

Permalink
query for process type (32-bit or 64-bit) from VMX-root and IOCTL
Browse files Browse the repository at this point in the history
  • Loading branch information
SinaKarvandi committed Jul 20, 2023
1 parent c20e2df commit 9d239cc
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ ListeningSerialPortInDebugger()
RtlZeroMemory(g_CurrentRunningInstruction, MAXIMUM_INSTR_SIZE);
memcpy(g_CurrentRunningInstruction, &PausePacket->InstructionBytesOnRip, MAXIMUM_INSTR_SIZE);

g_IsRunningInstruction32Bit = PausePacket->Is32BitAddress;
g_IsRunningInstruction32Bit = PausePacket->IsProcessorOn32BitMode;

//
// Show additional messages before showing assembly and pausing
Expand Down Expand Up @@ -283,13 +283,13 @@ ListeningSerialPortInDebugger()
//
if (HyperDbgLengthDisassemblerEngine(PausePacket->InstructionBytesOnRip,
MAXIMUM_INSTR_SIZE,
PausePacket->Is32BitAddress ? FALSE : TRUE) > PausePacket->ReadInstructionLen)
PausePacket->IsProcessorOn32BitMode ? FALSE : TRUE) > PausePacket->ReadInstructionLen)
{
ShowMessages("oOh, no! there might be a misinterpretation in disassembling the current instruction\n");
}
}

if (!PausePacket->Is32BitAddress)
if (!PausePacket->IsProcessorOn32BitMode)
{
//
// Show diassembles
Expand Down Expand Up @@ -338,7 +338,7 @@ ListeningSerialPortInDebugger()
//
CommandTrackHandleReceivedInstructions(&PausePacket->InstructionBytesOnRip[0],
MAXIMUM_INSTR_SIZE,
PausePacket->Is32BitAddress ? FALSE : TRUE,
PausePacket->IsProcessorOn32BitMode ? FALSE : TRUE,
PausePacket->Rip);

//
Expand Down
13 changes: 13 additions & 0 deletions hyperdbg/hprdbgctrl/code/debugger/misc/readmem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ HyperDbgReadMemoryAndDisassemble(DEBUGGER_SHOW_MEMORY_STYLE Style,
ReadMem.Style = Style;
ReadMem.DtDetails = DtDetails;

//
// Check if this is used for disassembler or not
//
if (Style == DEBUGGER_SHOW_COMMAND_DISASSEMBLE64 ||
Style == DEBUGGER_SHOW_COMMAND_DISASSEMBLE32)
{
ReadMem.IsForDisasm = TRUE;
}
else
{
ReadMem.IsForDisasm = FALSE;
}

//
// send the request
//
Expand Down
114 changes: 111 additions & 3 deletions hyperdbg/hprdbgkd/code/debugger/commands/DebuggerCommands.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,85 @@ DebuggerCommandReadMemory(PDEBUGGER_READ_MEMORY ReadMemRequest, PVOID UserBuffer
UINT32 Size;
UINT64 Address;
DEBUGGER_READ_MEMORY_TYPE MemType;
BOOLEAN Is32BitProcess = FALSE;

//
// Adjust the parameters
//
Pid = ReadMemRequest->Pid;
Size = ReadMemRequest->Size;
Address = ReadMemRequest->Address;
MemType = ReadMemRequest->MemoryType;

if (Size && Address != NULL)
{
return MemoryManagerReadProcessMemoryNormal((HANDLE)Pid, Address, MemType, (PVOID)UserBuffer, Size, ReturnSize);
if (MemoryManagerReadProcessMemoryNormal((HANDLE)Pid, Address, MemType, (PVOID)UserBuffer, Size, ReturnSize))
{
//
// Reading memory was successful
//

//
// *** Now, we check whether this a disassembly request for a virtual address
// or not, if so, we'll detect whether the target process is 32-bit or 64-bit ***
//

//
// Check if the address is on a 32-bit mode process or not (just in case of disassembling)
//
if (ReadMemRequest->MemoryType == DEBUGGER_READ_VIRTUAL_ADDRESS && ReadMemRequest->IsForDisasm)
{
//
// Check if the address is in the canonical range for kernel space
//
if (ReadMemRequest->Address >= 0xFFFF800000000000 && ReadMemRequest->Address <= 0xFFFFFFFFFFFFFFFF)
{
//
// The address is in the range of canonical kernel space, so it's 64-bit process
//
ReadMemRequest->Is32BitAddress = FALSE;
}
else
{
//
// The address is in the user-mode and the memory type is a virtual address
// for disassembly, so we have to query whether the target process is a
// 32-bit process or a 64-bit process
//
if (UserAccessIsWow64Process(ReadMemRequest->Pid, &Is32BitProcess))
{
ReadMemRequest->Is32BitAddress = Is32BitProcess;
}
else
{
//
// We couldn't determine the type of process, let's assume that it's a
// 64-bit process by default
//
ReadMemRequest->Is32BitAddress = FALSE;
}
}
}

//
// Anyway, the read was successful
//
return TRUE;
}
else
{
//
// Reading memory was not successful
//
return FALSE;
}
}
else
{
return STATUS_UNSUCCESSFUL;
//
// Parameters are invalid
//
return FALSE;
}
}

Expand All @@ -60,7 +126,8 @@ DebuggerCommandReadMemoryVmxRoot(PDEBUGGER_READ_MEMORY ReadMemRequest, UCHAR * U
UINT64 Address;
UINT64 OffsetInUserBuffer;
DEBUGGER_READ_MEMORY_TYPE MemType;
PLIST_ENTRY TempList = 0;
BOOLEAN Is32BitProcess = FALSE;
PLIST_ENTRY TempList = 0;

Pid = ReadMemRequest->Pid;
Size = ReadMemRequest->Size;
Expand Down Expand Up @@ -131,6 +198,47 @@ DebuggerCommandReadMemoryVmxRoot(PDEBUGGER_READ_MEMORY ReadMemRequest, UCHAR * U
ReadMemRequest->KernelStatus = DEBUGGER_ERROR_MEMORY_TYPE_INVALID;
return FALSE;
}

//
// Check if the address is on a 32-bit mode process or not (just in case of disassembling)
//
if (ReadMemRequest->MemoryType == DEBUGGER_READ_VIRTUAL_ADDRESS && ReadMemRequest->IsForDisasm)
{
//
// Check if the address is in the canonical range for kernel space
//
if (ReadMemRequest->Address >= 0xFFFF800000000000 && ReadMemRequest->Address <= 0xFFFFFFFFFFFFFFFF)
{
//
// The address is in the range of canonical kernel space, so it's 64-bit process
//
ReadMemRequest->Is32BitAddress = FALSE;
}
else
{
//
// The address is in the user-mode and the memory type is a virtual address
// for disassembly, so we have to query whether the target process is a
// 32-bit process or a 64-bit process
//
if (UserAccessIsWow64ProcessByEprocess(PsGetCurrentProcess(), &Is32BitProcess))
{
ReadMemRequest->Is32BitAddress = Is32BitProcess;
}
else
{
//
// We couldn't determine the type of process, let's assume that it's a
// 64-bit process by default
//
ReadMemRequest->Is32BitAddress = FALSE;
}
}
}

//
// Set the final status of memory read as it was successful
//
ReadMemRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
*ReturnSize = Size;

Expand Down
4 changes: 2 additions & 2 deletions hyperdbg/hprdbgkd/code/debugger/kernel-level/Kd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2760,8 +2760,8 @@ KdManageSystemHaltOnVmxRoot(PROCESSOR_DEBUGGING_STATE * DbgState,
//
// Set the RIP and mode of execution
//
PausePacket.Rip = LastVmexitRip;
PausePacket.Is32BitAddress = KdIsGuestOnUsermode32Bit();
PausePacket.Rip = LastVmexitRip;
PausePacket.IsProcessorOn32BitMode = KdIsGuestOnUsermode32Bit();

//
// Set disassembly state
Expand Down
47 changes: 31 additions & 16 deletions hyperdbg/hprdbgkd/code/debugger/user-level/UserAccess.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,30 +702,17 @@ UserAccessPrintLoadedModulesX86_2(PEPROCESS Proc)
}

/**
* @brief Detects whether process is 32-bit or 64-bit
* @brief Detects whether process is 32-bit or 64-bit by using EPROCESS pointer
* @details This function should be called in vmx non-root
*
* @param ProcessId
* @param SourceProcess
* @param Is32Bit
*
* @return BOOLEAN
*/
BOOLEAN
UserAccessIsWow64Process(HANDLE ProcessId, PBOOLEAN Is32Bit)
UserAccessIsWow64ProcessByEprocess(PEPROCESS SourceProcess, PBOOLEAN Is32Bit)
{
PEPROCESS SourceProcess;
KAPC_STATE State = {0};

if (PsLookupProcessByProcessId(ProcessId, &SourceProcess) != STATUS_SUCCESS)
{
//
// if the process not found
//
return FALSE;
}

ObDereferenceObject(SourceProcess);

if (g_PsGetProcessWow64Process == NULL || g_PsGetProcessPeb == NULL)
{
return FALSE;
Expand Down Expand Up @@ -756,6 +743,34 @@ UserAccessIsWow64Process(HANDLE ProcessId, PBOOLEAN Is32Bit)
}
}

/**
* @brief Detects whether process is 32-bit or 64-bit
* @details This function should be called in vmx non-root
*
* @param ProcessId
* @param Is32Bit
*
* @return BOOLEAN
*/
BOOLEAN
UserAccessIsWow64Process(HANDLE ProcessId, PBOOLEAN Is32Bit)
{
PEPROCESS SourceProcess;
KAPC_STATE State = {0};

if (PsLookupProcessByProcessId(ProcessId, &SourceProcess) != STATUS_SUCCESS)
{
//
// if the process not found
//
return FALSE;
}

ObDereferenceObject(SourceProcess);

return UserAccessIsWow64ProcessByEprocess(SourceProcess, Is32Bit);
}

/**
* @brief Get details about loaded modules
* @details This function should be called in vmx non-root
Expand Down
3 changes: 3 additions & 0 deletions hyperdbg/hprdbgkd/code/driver/Ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Status = STATUS_INVALID_PARAMETER;
break;
}

break;

case IOCTL_RETURN_IRP_PENDING_PACKETS_AND_DISALLOW_IOCTL:
Expand All @@ -123,6 +124,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
TRUE);

Status = STATUS_SUCCESS;

break;

case IOCTL_TERMINATE_VMX:
Expand Down Expand Up @@ -544,6 +546,7 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
DoNotChangeInformation = TRUE;

break;

case IOCTL_DEBUGGER_SEARCH_MEMORY:

//
Expand Down
3 changes: 3 additions & 0 deletions hyperdbg/hprdbgkd/header/debugger/user-level/UserAccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ UserAccessGetLoadedModules(PUSERMODE_LOADED_MODULE_DETAILS ProcessLoadedModuleRe
BOOLEAN
UserAccessIsWow64Process(HANDLE ProcessId, PBOOLEAN Is32Bit);

BOOLEAN
UserAccessIsWow64ProcessByEprocess(PEPROCESS SourceProcess, PBOOLEAN Is32Bit);

BOOLEAN
UserAccessCheckForLoadedModuleDetails(UINT32 CoreId);

Expand Down
4 changes: 2 additions & 2 deletions hyperdbg/include/SDK/Headers/DataTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ typedef struct _DEBUGGER_PAUSE_PACKET_RECEIVED
typedef struct _DEBUGGEE_KD_PAUSED_PACKET
{
UINT64 Rip;
BOOLEAN Is32BitAddress; // if true shows that the address should be interpreted in 32-bit mode
BOOLEAN IgnoreDisassembling; // if check if diassembling should be ignored or not
BOOLEAN IsProcessorOn32BitMode; // if true shows that the address should be interpreted in 32-bit mode
BOOLEAN IgnoreDisassembling; // if check if diassembling should be ignored or not
DEBUGGEE_PAUSING_REASON PausingReason;
ULONG CurrentCore;
UINT64 EventTag;
Expand Down
2 changes: 2 additions & 0 deletions hyperdbg/include/SDK/Headers/RequestStructures.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ typedef struct _DEBUGGER_READ_MEMORY
UINT32 Pid; // Read from cr3 of what process
UINT64 Address;
UINT32 Size;
BOOLEAN IsForDisasm; // Debugger sets whether the read memory is for diassembler or not
BOOLEAN Is32BitAddress; // Debuggee sets the status of address
DEBUGGER_READ_MEMORY_TYPE MemoryType;
DEBUGGER_READ_READING_TYPE ReadingType;
PDEBUGGER_DT_COMMAND_OPTIONS DtDetails;
Expand Down

0 comments on commit 9d239cc

Please sign in to comment.