Merge branch 'dev' into add-pcie-support

This commit is contained in:
Björn Ruytenberg 2024-12-02 15:49:27 +01:00
commit 453dff9ac4
29 changed files with 680 additions and 123 deletions

View file

@ -9,8 +9,11 @@ New release of the HyperDbg Debugger.
### Added
- Added the local APIC command (xAPIC and x2APIC modes) ([link](https://docs.hyperdbg.org/commands/extension-commands/apic))
- Added the I/O APIC command ([link](https://docs.hyperdbg.org/commands/extension-commands/ioapic))
- The new link is added to help increase the number of EPT hook breakpoints in a single page ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/number-of-ept-hooks-in-one-page))
### Changed
- The link for changing the communication buffer size is updated ([link](https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/increase-communication-buffer-size))
## [0.10.2.0] - 2024-10-11
New release of the HyperDbg Debugger.

View file

@ -22,11 +22,6 @@
#include <ntifs.h>
#include <Windef.h>
//
// Definition of Intel primitives (External header)
//
// #include "ia32-doc/out/ia32.h"
//
// Import Configuration and Definitions
//

View file

@ -68,102 +68,17 @@ IoApicWrite(volatile IO_APIC_ENT * IoApicBaseVa, UINT32 Reg, UINT64 Data)
}
}
/**
* @brief Dump redirections
*
* @param Desc
* @param CommandReg
* @param DestSelf
* @param Lh
* @param Ll
*
* @return ULONG
*/
ULONG
ApicDumpRedir(PUCHAR Desc,
BOOLEAN CommandReg,
BOOLEAN DestSelf,
ULONGLONG Lh,
ULONGLONG Ll)
{
static PUCHAR DelMode[] = {
(PUCHAR) "FixedDel",
(PUCHAR) "LowestDl",
(PUCHAR) "res010 ",
(PUCHAR) "remoterd",
(PUCHAR) "NMI ",
(PUCHAR) "RESET ",
(PUCHAR) "res110 ",
(PUCHAR) "ExtINTA "};
static PUCHAR DesShDesc[] = {(PUCHAR) "",
(PUCHAR) " Dest=Self",
(PUCHAR) " Dest=ALL",
(PUCHAR) " Dest=Othrs"};
ULONG Del, Dest, Delstat, Rirr, Trig, Masked, Destsh;
Del = (Ll >> 8) & 0x7;
Dest = (Ll >> 11) & 0x1;
Delstat = (Ll >> 12) & 0x1;
Rirr = (Ll >> 14) & 0x1;
Trig = (Ll >> 15) & 0x1;
Masked = (Ll >> 16) & 0x1;
Destsh = (Ll >> 18) & 0x3;
if (CommandReg)
{
//
// command reg's don't have a mask
//
Masked = 0;
}
Log("%s: %016llx Vec:%02X %s ",
Desc,
Ll,
Ll & 0xff,
DelMode[Del]);
if (DestSelf)
{
Log("%s", DesShDesc[1]);
}
else if (CommandReg && Destsh)
{
Log("%s", DesShDesc[Destsh]);
}
else
{
if (Dest)
{
Log("Lg:%08x", Lh);
}
else
{
Log("PhysDest:%02X", (Lh >> 56) & 0xFF);
}
}
Log("%s %s %s %s\n",
Delstat ? "-Pend" : " ",
Trig ? "level" : "edge ",
Rirr ? "rirr" : " ",
Masked ? "masked" : " ");
return 0;
}
/**
* @brief Dump I/O APIC
* @param IoApicPackets
*
* @return VOID
*/
VOID
ApicDumpIoApic()
ApicDumpIoApic(IO_APIC_ENTRY_PACKETS * IoApicPackets)
{
UINT32 Index, Max;
UCHAR Desc[40];
UINT32 Index = 0;
UINT32 Max;
UINT64 ll, lh;
UINT64 ApicBasePa = IO_APIC_DEFAULT_BASE_ADDR;
@ -172,22 +87,41 @@ ApicDumpIoApic()
Max = (ll >> 16) & 0xff;
Log("IoApic @ %08x ID:%x (%x) Arb:%x\n",
ApicBasePa,
IoApicRead(g_IoApicBase, IO_ID_REGISTER) >> 24,
ll & 0xFF,
IoApicRead(g_IoApicBase, IO_ARB_ID_REGISTER));
// Log("IoApic @ %08x ID:%x (%x) Arb:%x\n",
// ApicBasePa,
// IoApicRead(g_IoApicBase, IO_ID_REGISTER) >> 24,
// ll & 0xFF,
// IoApicRead(g_IoApicBase, IO_ARB_ID_REGISTER));
//
// Fill the I/O APIC
//
IoApicPackets->ApicBasePa = (UINT32)ApicBasePa;
IoApicPackets->ApicBaseVa = (UINT64)g_IoApicBase;
IoApicPackets->IoIdReg = (UINT32)IoApicRead(g_IoApicBase, IO_ID_REGISTER);
IoApicPackets->IoLl = (UINT32)ll;
IoApicPackets->IoArbIdReg = (UINT32)IoApicRead(g_IoApicBase, IO_ARB_ID_REGISTER);
//
// Dump inti table
//
Max *= 2;
for (Index = 0; Index <= Max; Index += 2)
{
if (Index >= MAX_NUMBER_OF_IO_APIC_ENTRIES)
{
//
// To prevent overflow of the target buffer
//
return;
}
ll = IoApicRead(g_IoApicBase, IO_REDIR_BASE + Index + 0);
lh = IoApicRead(g_IoApicBase, IO_REDIR_BASE + Index + 1);
sprintf((CHAR *)Desc, "Inti%02X.", Index / 2);
ApicDumpRedir(Desc, FALSE, FALSE, lh, ll);
IoApicPackets->LlLhData[Index] = ll;
IoApicPackets->LlLhData[Index + 1] = lh;
}
}
@ -298,8 +232,6 @@ ApicStoretLocalApicInXApicMode(PLAPIC_PAGE LApicBuffer)
BOOLEAN
ApicStoreLocalApicInX2ApicMode(PLAPIC_PAGE LApicBuffer)
{
ApicDumpIoApic();
//
// Store fields
//
@ -361,7 +293,28 @@ ApicTriggerGenericNmi()
}
/**
* @brief Stire the details of APIC in xAPIC and x2APIC mode
* @brief Trigger NMI on X2APIC or APIC based on Current system
*
* @return VOID
*/
VOID
ApicTriggerGenericSmi()
{
LogInfo("Generating SMIs");
if (g_CompatibilityCheck.IsX2Apic)
{
// X2ApicIcrWrite((4 << 8) | (1 << 14) | (3 << 18), 0);
X2ApicIcrWrite((2 << 8) | (1 << 14) | (3 << 18), 0);
}
else
{
// XApicIcrWrite((4 << 8) | (1 << 14) | (3 << 18), 0);
XApicIcrWrite((2 << 8) | (1 << 14) | (3 << 18), 0);
}
}
/**
* @brief Store the details of APIC in xAPIC and x2APIC mode
* @param LApicBuffer
* @param IsUsingX2APIC
*
@ -382,6 +335,28 @@ ApicStoreLocalApicFields(PLAPIC_PAGE LApicBuffer, PBOOLEAN IsUsingX2APIC)
}
}
/**
* @brief Store the details of I/O APIC
* @param IoApicPackets
*
* @return BOOLEAN
*/
BOOLEAN
ApicStoreIoApicFields(IO_APIC_ENTRY_PACKETS * IoApicPackets)
{
//
// Dump I/O APIC Entries
// Note that I/O APIC is not accessed through MSRs (e.g., X2APIC)
// So, it's all about the physical memory
//
ApicDumpIoApic(IoApicPackets);
//
// There is not error defined for it at the moment
//
return TRUE;
}
/**
* @brief Initialize APIC
*

View file

@ -819,10 +819,22 @@ VmFuncEnableAndCheckForPreviousExternalInterrupts(UINT32 CoreId)
* @param LocalApicBuffer
* @param IsUsingX2APIC
*
* @return VOID
* @return BOOLEAN
*/
BOOLEAN
VmFuncApicStoreLocalApicFields(PLAPIC_PAGE LocalApicBuffer, PBOOLEAN IsUsingX2APIC)
{
return ApicStoreLocalApicFields(LocalApicBuffer, IsUsingX2APIC);
}
/**
* @brief Store the details of I/O APIC
* @param IoApicPackets
*
* @return BOOLEAN
*/
BOOLEAN
VmFuncApicStoreIoApicFields(IO_APIC_ENTRY_PACKETS * IoApicPackets)
{
return ApicStoreIoApicFields(IoApicPackets);
}

View file

@ -0,0 +1,42 @@
/**
* @file Idt.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Routines for Interrupt Descriptor Table
* @details
*
* @version 0.11
* @date 2024-11-20
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
/**
* @brief Dump IDT Table based on current core
*
* @return VOID
*/
VOID
IdtDumpInterruptEntries()
{
KDESCRIPTOR64 descr;
__sidt(&descr.Limit);
ULONG n = (descr.Limit + 1) / sizeof(KIDTENTRY64);
if (n > 0)
{
int i = 0;
KIDTENTRY64 * pidte = (KIDTENTRY64 *)descr.Base;
do
{
ULONG_PTR addr = ((ULONG_PTR)pidte->OffsetHigh << 32) +
((ULONG_PTR)pidte->OffsetMiddle << 16) + pidte->OffsetLow;
LogInfo("Interrupt %u -> %p\n", i++, addr);
} while (pidte++, --n);
}
}

View file

@ -144,10 +144,12 @@ VmxVmexitHandler(_Inout_ PGUEST_REGS GuestRegs)
}
case VMX_EXIT_REASON_EXECUTE_RDMSR:
{
//
// Handle vm-exit, events, dispatches and perform changes
//
DispatchEventRdmsr(VCpu);
break;
}
case VMX_EXIT_REASON_IO_SMI:
case VMX_EXIT_REASON_SMI:
{
LogInfo("VM-exit reason SMM %llx | qual: %llx", ExitReason, VCpu->ExitQualification);
break;
}

View file

@ -141,6 +141,7 @@
#define APIC_EILVT2 0x520
#define APIC_EILVT3 0x530
#define APIC_BASE_MSR 0x800
#define APIC_BASE_MSR 0x800
//////////////////////////////////////////////////
@ -214,6 +215,9 @@ ApicUninitialize();
BOOLEAN
ApicStoreLocalApicFields(PLAPIC_PAGE LApicBuffer, PBOOLEAN IsUsingX2APIC);
BOOLEAN
ApicStoreIoApicFields(IO_APIC_ENTRY_PACKETS * IoApicPackets);
VOID
ApicSelfIpi(UINT32 Vector);

View file

@ -0,0 +1,49 @@
/**
* @file Idt.h
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Headers relating to Interrupt Descriptor Table
* @details
*
* @version 0.11
* @date 2024-11-20
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#pragma once
//////////////////////////////////////////////////
// Definition //
//////////////////////////////////////////////////
typedef union _KIDTENTRY64
{
struct
{
USHORT OffsetLow;
USHORT Selector;
USHORT IstIndex : 3;
USHORT Reserved0 : 5;
USHORT Type : 5;
USHORT Dpl : 2;
USHORT Present : 1;
USHORT OffsetMiddle;
ULONG OffsetHigh;
ULONG Reserved1;
};
UINT64 Alignment;
} KIDTENTRY64, *PKIDTENTRY64;
typedef struct _KDESCRIPTOR64
{
USHORT Pad[3];
USHORT Limit;
PVOID Base;
} KDESCRIPTOR64, *PKDESCRIPTOR64;
//////////////////////////////////////////////////
// Functions //
//////////////////////////////////////////////////
VOID
IdtDumpInterruptEntries();

View file

@ -161,6 +161,7 @@
<ClCompile Include="code\memory\PoolManager.c" />
<ClCompile Include="code\memory\Segmentation.c" />
<ClCompile Include="code\memory\SwitchLayout.c" />
<ClCompile Include="code\processor\Idt.c" />
<ClCompile Include="code\transparency\Transparency.c" />
<ClCompile Include="code\vmm\ept\Ept.c" />
<ClCompile Include="code\vmm\ept\Invept.c" />
@ -262,6 +263,7 @@
<ClInclude Include="header\memory\PoolManager.h" />
<ClInclude Include="header\memory\Segmentation.h" />
<ClInclude Include="header\memory\SwitchLayout.h" />
<ClInclude Include="header\processor\Idt.h" />
<ClInclude Include="header\transparency\Transparency.h" />
<ClInclude Include="header\vmm\ept\Ept.h" />
<ClInclude Include="header\vmm\ept\Invept.h" />

View file

@ -135,6 +135,12 @@
<Filter Include="header\components\optimizations">
<UniqueIdentifier>{0c6f7e8d-4829-4a45-b09d-4c40cfcc5cf7}</UniqueIdentifier>
</Filter>
<Filter Include="code\processor">
<UniqueIdentifier>{36f1d8ba-6527-4c1b-8016-ae66d1bd41e7}</UniqueIdentifier>
</Filter>
<Filter Include="header\processor">
<UniqueIdentifier>{8efcd014-6f76-436f-bca7-33f1cf2bd980}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="code\common\Common.c">
@ -308,6 +314,9 @@
<ClCompile Include="code\devices\Pci.c">
<Filter>code\devices</Filter>
</ClCompile>
<ClCompile Include="code\processor\Idt.c">
<Filter>code\processor</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
@ -574,6 +583,9 @@
<ClInclude Include="header\devices\Pci.h">
<Filter>header\devices</Filter>
</ClInclude>
<ClInclude Include="header\processor\Idt.h">
<Filter>header\processor</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<MASM Include="code\assembly\AsmCommon.asm">

View file

@ -105,6 +105,7 @@
#include "vmm/vmx/Events.h"
#include "devices/Apic.h"
#include "devices/Pci.h"
#include "processor/Idt.h"
#include "vmm/vmx/Mtf.h"
#include "vmm/vmx/Counters.h"
#include "vmm/vmx/IdtEmulation.h"

View file

@ -22,8 +22,9 @@
UINT32
ExtensionCommandPerformActionsForApicRequests(PDEBUGGER_APIC_REQUEST ApicRequest)
{
BOOLEAN IsUsingX2APIC = FALSE;
PLAPIC_PAGE BufferToStoreLApic = (LAPIC_PAGE *)(((CHAR *)ApicRequest) + sizeof(DEBUGGER_APIC_REQUEST));
BOOLEAN IsUsingX2APIC = FALSE;
PLAPIC_PAGE BufferToStoreLApic = (LAPIC_PAGE *)(((CHAR *)ApicRequest) + sizeof(DEBUGGER_APIC_REQUEST));
PIO_APIC_ENTRY_PACKETS BufferToStoreIoApic = (IO_APIC_ENTRY_PACKETS *)(((CHAR *)ApicRequest) + sizeof(DEBUGGER_APIC_REQUEST));
if (ApicRequest->ApicType == DEBUGGER_APIC_REQUEST_TYPE_READ_LOCAL_APIC)
{
@ -43,6 +44,28 @@ ExtensionCommandPerformActionsForApicRequests(PDEBUGGER_APIC_REQUEST ApicRequest
// There was an error performing the action
//
ApicRequest->KernelStatus = DEBUGGER_ERROR_APIC_ACTIONS_ERROR;
return sizeof(DEBUGGER_APIC_REQUEST);
}
}
else if (ApicRequest->ApicType == DEBUGGER_APIC_REQUEST_TYPE_READ_IO_APIC)
{
if (VmFuncApicStoreIoApicFields(BufferToStoreIoApic))
{
//
// The status was okay
//
ApicRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
return sizeof(DEBUGGER_APIC_REQUEST) + sizeof(IO_APIC_ENTRY_PACKETS);
}
else
{
//
// There was an error performing the action
//
ApicRequest->KernelStatus = DEBUGGER_ERROR_APIC_ACTIONS_ERROR;
return sizeof(DEBUGGER_APIC_REQUEST);
}
}
@ -52,6 +75,7 @@ ExtensionCommandPerformActionsForApicRequests(PDEBUGGER_APIC_REQUEST ApicRequest
// Invalid request
//
ApicRequest->KernelStatus = DEBUGGER_ERROR_APIC_ACTIONS_ERROR;
return sizeof(DEBUGGER_APIC_REQUEST);
}
}

View file

@ -160,7 +160,7 @@ SerialConnectionSend(CHAR * Buffer, UINT32 Length)
if (Length + SERIAL_END_OF_BUFFER_CHARS_COUNT > MaxSerialPacketSize)
{
LogError("Err, buffer is above the maximum buffer size that can be sent to debuggee (%d > %d), "
"for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/increase-communication-buffer-size",
"for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/increase-communication-buffer-size",
Length + SERIAL_END_OF_BUFFER_CHARS_COUNT,
MaxSerialPacketSize);
return FALSE;
@ -197,7 +197,7 @@ SerialConnectionSendTwoBuffers(CHAR * Buffer1, UINT32 Length1, CHAR * Buffer2, U
if ((Length1 + Length2 + SERIAL_END_OF_BUFFER_CHARS_COUNT) > MaxSerialPacketSize)
{
LogError("Err, buffer is above the maximum buffer size that can be sent to debuggee (%d > %d), "
"for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/increase-communication-buffer-size",
"for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/increase-communication-buffer-size",
Length1 + Length2 + SERIAL_END_OF_BUFFER_CHARS_COUNT,
MaxSerialPacketSize);
return FALSE;
@ -252,7 +252,7 @@ SerialConnectionSendThreeBuffers(CHAR * Buffer1,
if ((Length1 + Length2 + Length3 + SERIAL_END_OF_BUFFER_CHARS_COUNT) > MaxSerialPacketSize)
{
LogError("Err, buffer is above the maximum buffer size that can be sent to debuggee (%d > %d), "
"for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/increase-communication-buffer-size",
"for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/increase-communication-buffer-size",
Length1 + Length2 + Length3 + SERIAL_END_OF_BUFFER_CHARS_COUNT,
MaxSerialPacketSize);
return FALSE;

View file

@ -1032,6 +1032,7 @@ typedef struct _DEBUGGEE_STEP_PACKET
typedef enum _DEBUGGER_APIC_REQUEST_TYPE
{
DEBUGGER_APIC_REQUEST_TYPE_READ_LOCAL_APIC,
DEBUGGER_APIC_REQUEST_TYPE_READ_IO_APIC,
} DEBUGGER_APIC_REQUEST_TYPE;
@ -1156,6 +1157,67 @@ typedef struct _LAPIC_PAGE
UINT8 Reserved3F4[0x0C]; // valid only for X2APIC
} LAPIC_PAGE, *PLAPIC_PAGE;
/* ==============================================================================================
*/
/**
* @brief Maximum number of I/O APIC entries
* @details Usually 256 entries are enough (but we allocate 400 for systems with more
* I/O APIC entries)
* We're not gonna make the packet bigger than it's needed
*
*/
#define MAX_NUMBER_OF_IO_APIC_ENTRIES 400
/**
* @brief The structure of I/O APIC result packet in HyperDbg
*
*/
typedef struct _IO_APIC_ENTRY_PACKETS
{
UINT64 ApicBasePa;
UINT64 ApicBaseVa;
UINT32 IoIdReg;
UINT32 IoLl;
UINT32 IoArbIdReg;
UINT64 LlLhData[MAX_NUMBER_OF_IO_APIC_ENTRIES];
} IO_APIC_ENTRY_PACKETS, *PIO_APIC_ENTRY_PACKETS;
/**
* @brief check so the IO_APIC_ENTRY_PACKETS should be smaller than packet size
*
*/
static_assert(sizeof(IO_APIC_ENTRY_PACKETS) < PacketChunkSize,
"err (static_assert), size of PacketChunkSize should be bigger than IO_APIC_ENTRY_PACKETS");
/* ==============================================================================================
*/
/**
* @brief Maximum number of IDT entries
*
*/
#define MAX_NUMBER_OF_IDT_ENTRIES 256
/**
* @brief The structure of IDT entries result packet in HyperDbg
*
*/
typedef struct _INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS
{
UINT32 KernelStatus;
UINT64 IdtEntry[MAX_NUMBER_OF_IDT_ENTRIES];
} INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS, *PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS;
/**
* @brief check so the INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS should be smaller than packet size
*
*/
static_assert(sizeof(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS) < PacketChunkSize,
"err (static_assert), size of PacketChunkSize should be bigger than INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS");
/* ==============================================================================================
*/

View file

@ -218,6 +218,9 @@ VmFuncVmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t C
IMPORT_EXPORT_VMM BOOLEAN
VmFuncApicStoreLocalApicFields(PLAPIC_PAGE LocalApicBuffer, PBOOLEAN IsUsingX2APIC);
IMPORT_EXPORT_VMM BOOLEAN
VmFuncApicStoreIoApicFields(IO_APIC_ENTRY_PACKETS * IoApicPackets);
//////////////////////////////////////////////////
// Configuration Functions //
//////////////////////////////////////////////////

View file

@ -234,10 +234,13 @@ hyperdbg_u_start_process_with_args(const WCHAR * path, const WCHAR * arguments);
//
// APIC related command
// Exported functionality of the '!apic' command
// Exported functionality of the '!apic', and '!ioapic' commands
//
IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
hyperdbg_u_command_get_local_apic(PLAPIC_PAGE local_apic, BOOLEAN * is_using_x2apic);
hyperdbg_u_get_local_apic(PLAPIC_PAGE local_apic, BOOLEAN * is_using_x2apic);
IMPORT_EXPORT_LIBHYPERDBG BOOLEAN
hyperdbg_u_get_io_apic(IO_APIC_ENTRY_PACKETS * io_apic);
//
// Assembler

View file

@ -1,5 +1,5 @@
/**
* @file ~.cpp
* @file core.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief show and change processor
* @details

View file

@ -0,0 +1,58 @@
/**
* @file gg.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief gg command
* @details
* @version 0.11
* @date 2024-11-19
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
/**
* @brief help of the g command
*
* @return VOID
*/
VOID
CommandGgHelp()
{
ShowMessages("gg : shows and changes the operating processor.\n\n");
ShowMessages("syntax : \tgg\n");
ShowMessages("syntax : \tgg [wp]\n");
ShowMessages("\n");
ShowMessages("\t\te.g : gg \n");
ShowMessages("\t\te.g : gg wp \n");
}
/**
* @brief gg command handler
*
* @param CommandTokens
* @param Command
*
* @return VOID
*/
VOID
CommandGg(vector<CommandToken> CommandTokens, string Command)
{
if (CommandTokens.size() == 1)
{
ShowMessages("Good Game! :)\n");
}
else if (CommandTokens.size() == 2 && CompareLowerCaseStrings(CommandTokens.at(1), "wp"))
{
ShowMessages("Good Game, Well Played! :)\n");
}
else
{
ShowMessages("incorrect use of the '%s'\n\n",
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandGgHelp();
return;
}
}

View file

@ -83,6 +83,7 @@ CommandApicSendRequest(DEBUGGER_APIC_REQUEST_TYPE ApicType,
//
if (!KdSendApicActionPacketsToDebuggee(ApicRequest, RequestSize))
{
free(ApicRequest);
return FALSE;
}
else
@ -90,6 +91,7 @@ CommandApicSendRequest(DEBUGGER_APIC_REQUEST_TYPE ApicType,
*IsUsingX2APIC = ApicRequest->IsUsingX2APIC;
RtlCopyMemory(ApicBuffer, (PVOID)(((CHAR *)ApicRequest) + sizeof(DEBUGGER_APIC_REQUEST)), ExpectedRequestSize);
free(ApicRequest);
return TRUE;
}
}
@ -106,8 +108,7 @@ CommandApicSendRequest(DEBUGGER_APIC_REQUEST_TYPE ApicType,
ApicRequest, // Input Buffer to driver.
SIZEOF_DEBUGGER_APIC_REQUEST, // Input buffer length
ApicRequest, // Output Buffer from driver.
RequestSize, // Length of output
// buffer in bytes.
RequestSize, // Length of output buffer in bytes.
&ReturnedLength, // Bytes placed in buffer.
NULL // synchronous call
);
@ -115,6 +116,19 @@ CommandApicSendRequest(DEBUGGER_APIC_REQUEST_TYPE ApicType,
if (!Status)
{
ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
free(ApicRequest);
return FALSE;
}
if (ReturnedLength != RequestSize && ReturnedLength != SIZEOF_DEBUGGER_APIC_REQUEST)
{
//
// An err occurred
//
ShowMessages("err, apic request failed\n");
free(ApicRequest);
return FALSE;
}
@ -126,6 +140,7 @@ CommandApicSendRequest(DEBUGGER_APIC_REQUEST_TYPE ApicType,
*IsUsingX2APIC = ApicRequest->IsUsingX2APIC;
RtlCopyMemory(ApicBuffer, (PVOID)(((CHAR *)ApicRequest) + sizeof(DEBUGGER_APIC_REQUEST)), ExpectedRequestSize);
free(ApicRequest);
return TRUE;
}
else
@ -134,6 +149,8 @@ CommandApicSendRequest(DEBUGGER_APIC_REQUEST_TYPE ApicType,
// An err occurred, no results
//
ShowErrorMessage(ApicRequest->KernelStatus);
free(ApicRequest);
return FALSE;
}
}

View file

@ -0,0 +1,239 @@
/**
* @file ioapic.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief !ioapic command
* @details
* @version 0.11
* @date 2024-11-18
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
//
// Global Variables
//
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
/**
* @brief help of the !ioapic command
*
* @return VOID
*/
VOID
CommandIoapicHelp()
{
ShowMessages("!ioapic : shows the details of I/O APIC entries.\n\n");
ShowMessages("syntax : \t!ioapic\n");
ShowMessages("\n");
ShowMessages("\t\te.g : !ioapic\n");
}
/**
* @brief Request to get I/O APIC
*
* @param IolApic
*
* @return BOOLEAN
*/
BOOLEAN
HyperDbgGetIoApic(IO_APIC_ENTRY_PACKETS * IoApic)
{
BOOLEAN IsUsingX2APIC; // not used since I/O APIC is accessed through memory (not MSR)
return CommandApicSendRequest(DEBUGGER_APIC_REQUEST_TYPE_READ_IO_APIC,
IoApic,
sizeof(IO_APIC_ENTRY_PACKETS),
&IsUsingX2APIC);
}
/**
* @brief Show redirections
*
* @param Desc
* @param CommandReg
* @param DestSelf
* @param Lh
* @param Ll
*
* @return ULONG
*/
ULONG
CommandIoapicShowRedir(PUCHAR Desc,
BOOLEAN CommandReg,
BOOLEAN DestSelf,
ULONGLONG Lh,
ULONGLONG Ll)
{
static PUCHAR DelMode[] = {
(PUCHAR) "FixedDel",
(PUCHAR) "LowestDl",
(PUCHAR) "res010 ",
(PUCHAR) "remoterd",
(PUCHAR) "NMI ",
(PUCHAR) "RESET ",
(PUCHAR) "res110 ",
(PUCHAR) "ExtINTA "};
static PUCHAR DesShDesc[] = {(PUCHAR) "",
(PUCHAR) " Dest=Self",
(PUCHAR) " Dest=ALL",
(PUCHAR) " Dest=Othrs"};
ULONG Del, Dest, Delstat, Rirr, Trig, Masked, Destsh;
Del = (Ll >> 8) & 0x7;
Dest = (Ll >> 11) & 0x1;
Delstat = (Ll >> 12) & 0x1;
Rirr = (Ll >> 14) & 0x1;
Trig = (Ll >> 15) & 0x1;
Masked = (Ll >> 16) & 0x1;
Destsh = (Ll >> 18) & 0x3;
if (CommandReg)
{
//
// command reg's don't have a mask
//
Masked = 0;
}
ShowMessages("%s: %s Vec:%02X %s ",
Desc,
SeparateTo64BitValue(Ll).c_str(),
Ll & 0xff,
DelMode[Del]);
if (DestSelf)
{
ShowMessages("%s", DesShDesc[1]);
}
else if (CommandReg && Destsh)
{
ShowMessages("%s", DesShDesc[Destsh]);
}
else
{
if (Dest)
{
ShowMessages("Lg:%08x", Lh);
}
else
{
ShowMessages("PhysDest:%02X", (Lh >> 56) & 0xFF);
}
}
ShowMessages("%s %s %s %s\n",
Delstat ? "-Pend" : " ",
Trig ? "level" : "edge ",
Rirr ? "rirr" : " ",
Masked ? "masked" : " ");
return 0;
}
/**
* @brief Show I/O APIC
* @param IoApicPackets
*
* @return VOID
*/
VOID
CommandIoapicShowIoApicEntries(IO_APIC_ENTRY_PACKETS * IoApicPackets)
{
UINT32 Index = 0;
UINT32 Max;
UCHAR Desc[40];
UINT64 ll, lh;
UINT64 ApicBasePa = IoApicPackets->ApicBasePa;
ll = IoApicPackets->IoLl;
Max = (ll >> 16) & 0xff;
ShowMessages("IoApic @ %08x ID:%x (%x) Arb:%x\t I/O APIC VA: %s\n",
ApicBasePa,
IoApicPackets->IoIdReg >> 24,
ll & 0xFF,
IoApicPackets->IoArbIdReg,
SeparateTo64BitValue(IoApicPackets->ApicBaseVa).c_str());
//
// Dump inti table
//
Max *= 2;
for (Index = 0; Index <= Max; Index += 2)
{
if (Index >= MAX_NUMBER_OF_IO_APIC_ENTRIES)
{
//
// The buffer is now invalid
//
ShowMessages("err, there are additional entries in the I/O APIC that are not fully displayed in the results");
return;
}
ll = IoApicPackets->LlLhData[Index];
lh = IoApicPackets->LlLhData[Index + 1];
sprintf((CHAR *)Desc, "Inti%02X.", Index / 2);
CommandIoapicShowRedir(Desc, FALSE, FALSE, lh, ll);
}
}
/**
* @brief !ioapic command handler
*
* @param CommandTokens
* @param Command
*
* @return VOID
*/
VOID
CommandIoapic(vector<CommandToken> CommandTokens, string Command)
{
IO_APIC_ENTRY_PACKETS * IoApicPackets = NULL;
if (CommandTokens.size() != 1)
{
ShowMessages("incorrect use of the '%s'\n\n",
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandIoapicHelp();
return;
}
//
// Allocate buffer for I/O APIC
//
IoApicPackets = (IO_APIC_ENTRY_PACKETS *)malloc(sizeof(IO_APIC_ENTRY_PACKETS));
if (IoApicPackets == NULL)
{
ShowMessages("err, allocating buffer for receiving I/O APIC");
}
RtlZeroMemory(IoApicPackets, sizeof(IO_APIC_ENTRY_PACKETS));
//
// Get the I/O APIC buffer
//
if (HyperDbgGetIoApic(IoApicPackets) == TRUE)
{
//
// Show (dump) entries
//
CommandIoapicShowIoApicEntries(IoApicPackets);
}
//
// Deallocate the buffer
//
free(IoApicPackets);
}

View file

@ -228,7 +228,9 @@ ShowErrorMessage(UINT32 Error)
case DEBUGGER_ERROR_MAXIMUM_BREAKPOINT_FOR_A_SINGLE_PAGE_IS_HIT:
ShowMessages("err, the maximum breakpoint for a single page is hit, "
"you cannot apply more breakpoints in this page (%x)\n",
"you cannot apply more breakpoints in this page (%x)\n"
"please refer to https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/number-of-ept-hooks-in-one-page"
" for further information\n",
Error);
break;

View file

@ -1347,6 +1347,8 @@ InitializeCommandsDictionary()
g_CommandsList["g"] = {&CommandG, &CommandGHelp, DEBUGGER_COMMAND_G_ATTRIBUTES};
g_CommandsList["go"] = {&CommandG, &CommandGHelp, DEBUGGER_COMMAND_G_ATTRIBUTES};
g_CommandsList["gg"] = {&CommandGg, &CommandGgHelp, DEBUGGER_COMMAND_GG_ATTRIBUTES};
g_CommandsList[".attach"] = {&CommandAttach, &CommandAttachHelp, DEBUGGER_COMMAND_ATTACH_ATTRIBUTES};
g_CommandsList["attach"] = {&CommandAttach, &CommandAttachHelp, DEBUGGER_COMMAND_ATTACH_ATTRIBUTES};
@ -1449,6 +1451,8 @@ InitializeCommandsDictionary()
g_CommandsList["!lapic"] = {&CommandApic, &CommandApicHelp, DEBUGGER_COMMAND_APIC_ATTRIBUTES};
g_CommandsList["!localapic"] = {&CommandApic, &CommandApicHelp, DEBUGGER_COMMAND_APIC_ATTRIBUTES};
g_CommandsList["!ioapic"] = {&CommandIoapic, &CommandIoapicHelp, DEBUGGER_COMMAND_IOAPIC_ATTRIBUTES};
g_CommandsList["!monitor"] = {&CommandMonitor, &CommandMonitorHelp, DEBUGGER_COMMAND_MONITOR_ATTRIBUTES};
g_CommandsList["!vmcall"] = {&CommandVmcall, &CommandVmcallHelp, DEBUGGER_COMMAND_VMCALL_ATTRIBUTES};

View file

@ -1629,7 +1629,7 @@ KdSendPacketToDebuggee(const CHAR * Buffer, UINT32 Length, BOOLEAN SendEndOfBuff
if (Length + SERIAL_END_OF_BUFFER_CHARS_COUNT > MaxSerialPacketSize)
{
ShowMessages("err, buffer is above the maximum buffer size that can be sent to debuggee (%d > %d), "
"for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/increase-communication-buffer-size\n",
"for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/increase-communication-buffer-size\n",
Length + SERIAL_END_OF_BUFFER_CHARS_COUNT,
MaxSerialPacketSize);
return FALSE;
@ -1799,7 +1799,7 @@ KdCommandPacketAndBufferToDebuggee(
MaxSerialPacketSize)
{
ShowMessages("err, buffer is above the maximum buffer size that can be sent to debuggee (%d > %d), "
"for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/increase-communication-buffer-size",
"for more information, please visit https://docs.hyperdbg.org/tips-and-tricks/misc/customize-build/increase-communication-buffer-size",
sizeof(DEBUGGER_REMOTE_PACKET) + BufferLength + SERIAL_END_OF_BUFFER_CHARS_COUNT,
MaxSerialPacketSize);

View file

@ -695,11 +695,24 @@ hyperdbg_u_stepping_step_over_for_gu(BOOLEAN last_instruction)
* @return BOOLEAN
*/
BOOLEAN
hyperdbg_u_command_get_local_apic(PLAPIC_PAGE local_apic, BOOLEAN * is_using_x2apic)
hyperdbg_u_get_local_apic(PLAPIC_PAGE local_apic, BOOLEAN * is_using_x2apic)
{
return HyperDbgGetLocalApic(local_apic, is_using_x2apic);
}
/**
* @brief Get I/O APIC
*
* @param io_apic
*
* @return BOOLEAN
*/
BOOLEAN
hyperdbg_u_get_io_apic(IO_APIC_ENTRY_PACKETS * io_apic)
{
return HyperDbgGetIoApic(io_apic);
}
/**
* @brief Run hwdbg script
*

View file

@ -236,6 +236,8 @@ typedef std::map<std::string, COMMAND_DETAIL> CommandType;
#define DEBUGGER_COMMAND_G_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
#define DEBUGGER_COMMAND_GG_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_ABSOLUTE_LOCAL | DEBUGGER_COMMAND_ATTRIBUTE_REPEAT_ON_ENTER
#define DEBUGGER_COMMAND_ATTACH_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
#define DEBUGGER_COMMAND_DETACH_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
@ -324,6 +326,8 @@ typedef std::map<std::string, COMMAND_DETAIL> CommandType;
#define DEBUGGER_COMMAND_APIC_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
#define DEBUGGER_COMMAND_IOAPIC_ATTRIBUTES DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
#define DEBUGGER_COMMAND_CORE_ATTRIBUTES \
DEBUGGER_COMMAND_ATTRIBUTE_LOCAL_COMMAND_IN_DEBUGGER_MODE
@ -579,6 +583,9 @@ CommandEvents(vector<CommandToken> CommandTokens, string Command);
VOID
CommandG(vector<CommandToken> CommandTokens, string Command);
VOID
CommandGg(vector<CommandToken> CommandTokens, string Command);
VOID
CommandLm(vector<CommandToken> CommandTokens, string Command);
@ -705,6 +712,9 @@ CommandRev(vector<CommandToken> CommandTokens, string Command);
VOID
CommandApic(vector<CommandToken> CommandTokens, string Command);
VOID
CommandIoapic(vector<CommandToken> CommandTokens, string Command);
VOID
CommandTrack(vector<CommandToken> CommandTokens, string Command);

View file

@ -282,3 +282,12 @@ HyperDbgDebugCloseRemoteDebugger();
BOOLEAN
HyperDbgGetLocalApic(PLAPIC_PAGE LocalApic, PBOOLEAN IsUsingX2APIC);
BOOLEAN
HyperDbgGetIoApic(IO_APIC_ENTRY_PACKETS * IoApic);
BOOLEAN
CommandApicSendRequest(DEBUGGER_APIC_REQUEST_TYPE ApicType,
PVOID ApicBuffer,
UINT32 ExpectedRequestSize,
PBOOLEAN IsUsingX2APIC);

View file

@ -141,6 +141,9 @@ CommandEventsHelp();
VOID
CommandGHelp();
VOID
CommandGgHelp();
VOID
CommandClsHelp();
@ -216,6 +219,9 @@ CommandCoreHelp();
VOID
CommandApicHelp();
VOID
CommandIoapicHelp();
VOID
CommandProcessHelp();

View file

@ -164,12 +164,14 @@
<ClCompile Include="code\debugger\commands\debugging-commands\a.cpp" />
<ClCompile Include="code\debugger\commands\debugging-commands\core.cpp" />
<ClCompile Include="code\debugger\commands\debugging-commands\dt-struct.cpp" />
<ClCompile Include="code\debugger\commands\debugging-commands\gg.cpp" />
<ClCompile Include="code\debugger\commands\debugging-commands\gu.cpp" />
<ClCompile Include="code\debugger\commands\debugging-commands\k.cpp" />
<ClCompile Include="code\debugger\commands\debugging-commands\preactivate.cpp" />
<ClCompile Include="code\debugger\commands\debugging-commands\prealloc.cpp" />
<ClCompile Include="code\debugger\commands\extension-commands\apic.cpp" />
<ClCompile Include="code\debugger\commands\extension-commands\crwrite.cpp" />
<ClCompile Include="code\debugger\commands\extension-commands\ioapic.cpp" />
<ClCompile Include="code\debugger\commands\extension-commands\pcitree.cpp" />
<ClCompile Include="code\debugger\commands\extension-commands\rev.cpp" />
<ClCompile Include="code\debugger\commands\extension-commands\trace.cpp" />

View file

@ -566,9 +566,17 @@
<Filter>code\debugger\commands\hwdbg-commands</Filter>
</ClCompile>
<ClCompile Include="code\debugger\commands\extension-commands\pcitree.cpp">
<Filter>code\debugger\commands\extension-commands</Filter>
</ClCompile>
<ClCompile Include="code\debugger\commands\extension-commands\apic.cpp">
<Filter>code\debugger\commands\extension-commands</Filter>
</ClCompile>
<ClCompile Include="code\debugger\commands\extension-commands\ioapic.cpp">
<Filter>code\debugger\commands\extension-commands</Filter>
</ClCompile>
<ClCompile Include="code\debugger\commands\debugging-commands\gg.cpp">
<Filter>code\debugger\commands\debugging-commands</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<MASM Include="code\assembly\asm-vmx-checks.asm">