From bb9c4e30d7275a4fae2c16762b90cda6d5899bad Mon Sep 17 00:00:00 2001 From: SinaKarvandi Date: Tue, 19 Nov 2024 13:56:22 +0100 Subject: [PATCH 1/5] add support for IO APIC --- hyperdbg/hyperhv/code/devices/Apic.c | 144 ++++------- hyperdbg/hyperhv/code/interface/Export.c | 14 +- hyperdbg/hyperhv/header/devices/Apic.h | 4 + .../debugger/commands/ExtensionCommands.c | 27 +- .../include/SDK/headers/RequestStructures.h | 35 +++ .../SDK/imports/kernel/HyperDbgVmmImports.h | 3 + .../commands/debugging-commands/core.cpp | 2 +- .../commands/debugging-commands/gg.cpp | 58 +++++ .../commands/extension-commands/ioapic.cpp | 230 ++++++++++++++++++ .../code/debugger/core/interpreter.cpp | 4 + hyperdbg/libhyperdbg/header/commands.h | 10 + hyperdbg/libhyperdbg/header/debugger.h | 6 + hyperdbg/libhyperdbg/header/help.h | 6 + hyperdbg/libhyperdbg/libhyperdbg.vcxproj | 2 + .../libhyperdbg/libhyperdbg.vcxproj.filters | 8 + 15 files changed, 450 insertions(+), 103 deletions(-) create mode 100644 hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gg.cpp create mode 100644 hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp diff --git a/hyperdbg/hyperhv/code/devices/Apic.c b/hyperdbg/hyperhv/code/devices/Apic.c index 9a2d4410..36228346 100644 --- a/hyperdbg/hyperhv/code/devices/Apic.c +++ b/hyperdbg/hyperhv/code/devices/Apic.c @@ -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,33 @@ 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) { 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->LlData[Index] = ll; + IoApicPackets->LhData[Index] = lh; } } @@ -298,8 +224,6 @@ ApicStoretLocalApicInXApicMode(PLAPIC_PAGE LApicBuffer) BOOLEAN ApicStoreLocalApicInX2ApicMode(PLAPIC_PAGE LApicBuffer) { - ApicDumpIoApic(); - // // Store fields // @@ -361,7 +285,7 @@ ApicTriggerGenericNmi() } /** - * @brief Stire the details of APIC in xAPIC and x2APIC mode + * @brief Store the details of APIC in xAPIC and x2APIC mode * @param LApicBuffer * @param IsUsingX2APIC * @@ -382,6 +306,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 * diff --git a/hyperdbg/hyperhv/code/interface/Export.c b/hyperdbg/hyperhv/code/interface/Export.c index bee44b89..174edb5f 100644 --- a/hyperdbg/hyperhv/code/interface/Export.c +++ b/hyperdbg/hyperhv/code/interface/Export.c @@ -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); +} diff --git a/hyperdbg/hyperhv/header/devices/Apic.h b/hyperdbg/hyperhv/header/devices/Apic.h index 4a69b51d..a33598ea 100644 --- a/hyperdbg/hyperhv/header/devices/Apic.h +++ b/hyperdbg/hyperhv/header/devices/Apic.h @@ -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); diff --git a/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c b/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c index 30362b6f..265ff2c6 100644 --- a/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c +++ b/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c @@ -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); + } + } + 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); } } diff --git a/hyperdbg/include/SDK/headers/RequestStructures.h b/hyperdbg/include/SDK/headers/RequestStructures.h index d98fcc1a..b7d9435a 100644 --- a/hyperdbg/include/SDK/headers/RequestStructures.h +++ b/hyperdbg/include/SDK/headers/RequestStructures.h @@ -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,40 @@ 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 half of the 256 entries is enough + * We're not gonna make the packet bigger than it's needed + * + */ +#define MAX_NUMBER_OF_IO_APIC_ENTRIES 0xff / 2 + +/** + * @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 LlData[MAX_NUMBER_OF_IO_APIC_ENTRIES]; + UINT64 LhData[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"); + /* ============================================================================================== */ diff --git a/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h b/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h index 165bf2ef..a79726a9 100644 --- a/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h +++ b/hyperdbg/include/SDK/imports/kernel/HyperDbgVmmImports.h @@ -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 // ////////////////////////////////////////////////// diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/core.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/core.cpp index 67e7a690..2a1852db 100644 --- a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/core.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/core.cpp @@ -1,5 +1,5 @@ /** - * @file ~.cpp + * @file core.cpp * @author Sina Karvandi (sina@hyperdbg.org) * @brief show and change processor * @details diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gg.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gg.cpp new file mode 100644 index 00000000..ca856e22 --- /dev/null +++ b/hyperdbg/libhyperdbg/code/debugger/commands/debugging-commands/gg.cpp @@ -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 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; + } +} diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp new file mode 100644 index 00000000..6f39c1ad --- /dev/null +++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp @@ -0,0 +1,230 @@ +/** + * @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(PIO_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) + { + ll = IoApicPackets->LlData[Index]; + lh = IoApicPackets->LhData[Index]; + + 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 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); +} diff --git a/hyperdbg/libhyperdbg/code/debugger/core/interpreter.cpp b/hyperdbg/libhyperdbg/code/debugger/core/interpreter.cpp index a1d3c669..0f2bc7d9 100644 --- a/hyperdbg/libhyperdbg/code/debugger/core/interpreter.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/core/interpreter.cpp @@ -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}; diff --git a/hyperdbg/libhyperdbg/header/commands.h b/hyperdbg/libhyperdbg/header/commands.h index 6b29a2e3..d7061086 100644 --- a/hyperdbg/libhyperdbg/header/commands.h +++ b/hyperdbg/libhyperdbg/header/commands.h @@ -236,6 +236,8 @@ typedef std::map 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 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 CommandTokens, string Command); VOID CommandG(vector CommandTokens, string Command); +VOID +CommandGg(vector CommandTokens, string Command); + VOID CommandLm(vector CommandTokens, string Command); @@ -705,6 +712,9 @@ CommandRev(vector CommandTokens, string Command); VOID CommandApic(vector CommandTokens, string Command); +VOID +CommandIoapic(vector CommandTokens, string Command); + VOID CommandTrack(vector CommandTokens, string Command); diff --git a/hyperdbg/libhyperdbg/header/debugger.h b/hyperdbg/libhyperdbg/header/debugger.h index bd596ee2..2c88288e 100644 --- a/hyperdbg/libhyperdbg/header/debugger.h +++ b/hyperdbg/libhyperdbg/header/debugger.h @@ -282,3 +282,9 @@ HyperDbgDebugCloseRemoteDebugger(); BOOLEAN HyperDbgGetLocalApic(PLAPIC_PAGE LocalApic, PBOOLEAN IsUsingX2APIC); + +BOOLEAN +CommandApicSendRequest(DEBUGGER_APIC_REQUEST_TYPE ApicType, + PVOID ApicBuffer, + UINT32 ExpectedRequestSize, + PBOOLEAN IsUsingX2APIC); diff --git a/hyperdbg/libhyperdbg/header/help.h b/hyperdbg/libhyperdbg/header/help.h index ad32fe24..c1368d95 100644 --- a/hyperdbg/libhyperdbg/header/help.h +++ b/hyperdbg/libhyperdbg/header/help.h @@ -141,6 +141,9 @@ CommandEventsHelp(); VOID CommandGHelp(); +VOID +CommandGgHelp(); + VOID CommandClsHelp(); @@ -216,6 +219,9 @@ CommandCoreHelp(); VOID CommandApicHelp(); +VOID +CommandIoapicHelp(); + VOID CommandProcessHelp(); diff --git a/hyperdbg/libhyperdbg/libhyperdbg.vcxproj b/hyperdbg/libhyperdbg/libhyperdbg.vcxproj index ed77089d..9478beb2 100644 --- a/hyperdbg/libhyperdbg/libhyperdbg.vcxproj +++ b/hyperdbg/libhyperdbg/libhyperdbg.vcxproj @@ -164,12 +164,14 @@ + + diff --git a/hyperdbg/libhyperdbg/libhyperdbg.vcxproj.filters b/hyperdbg/libhyperdbg/libhyperdbg.vcxproj.filters index ee646d83..793cd4dd 100644 --- a/hyperdbg/libhyperdbg/libhyperdbg.vcxproj.filters +++ b/hyperdbg/libhyperdbg/libhyperdbg.vcxproj.filters @@ -566,9 +566,17 @@ code\debugger\commands\hwdbg-commands + code\debugger\commands\extension-commands + code\debugger\commands\extension-commands + + code\debugger\commands\extension-commands + + + code\debugger\commands\debugging-commands + From 13befcfa00222e1c6957ceeed9d5743906da5f72 Mon Sep 17 00:00:00 2001 From: SinaKarvandi Date: Wed, 20 Nov 2024 14:44:03 +0100 Subject: [PATCH 2/5] fix interrupt redirection issues --- .../code/debugger/commands/ExtensionCommands.c | 3 ++- .../SDK/imports/user/HyperDbgLibImports.h | 7 +++++-- .../commands/extension-commands/apic.cpp | 18 ++++++++++++++++++ .../commands/extension-commands/ioapic.cpp | 2 +- hyperdbg/libhyperdbg/code/export/export.cpp | 15 ++++++++++++++- hyperdbg/libhyperdbg/header/debugger.h | 3 +++ 6 files changed, 43 insertions(+), 5 deletions(-) diff --git a/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c b/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c index 265ff2c6..e6ed191b 100644 --- a/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c +++ b/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c @@ -48,7 +48,7 @@ ExtensionCommandPerformActionsForApicRequests(PDEBUGGER_APIC_REQUEST ApicRequest return sizeof(DEBUGGER_APIC_REQUEST); } } - if (ApicRequest->ApicType == DEBUGGER_APIC_REQUEST_TYPE_READ_IO_APIC) + else if (ApicRequest->ApicType == DEBUGGER_APIC_REQUEST_TYPE_READ_IO_APIC) { if (VmFuncApicStoreIoApicFields(BufferToStoreIoApic)) { @@ -75,6 +75,7 @@ ExtensionCommandPerformActionsForApicRequests(PDEBUGGER_APIC_REQUEST ApicRequest // Invalid request // ApicRequest->KernelStatus = DEBUGGER_ERROR_APIC_ACTIONS_ERROR; + return sizeof(DEBUGGER_APIC_REQUEST); } } diff --git a/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h b/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h index 936e6885..d78bd4f9 100644 --- a/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h +++ b/hyperdbg/include/SDK/imports/user/HyperDbgLibImports.h @@ -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 diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/apic.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/apic.cpp index 1418e20c..01b930fd 100644 --- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/apic.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/apic.cpp @@ -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; } } @@ -115,6 +117,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 +141,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 +150,8 @@ CommandApicSendRequest(DEBUGGER_APIC_REQUEST_TYPE ApicType, // An err occurred, no results // ShowErrorMessage(ApicRequest->KernelStatus); + + free(ApicRequest); return FALSE; } } diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp index 6f39c1ad..649fb671 100644 --- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp @@ -40,7 +40,7 @@ CommandIoapicHelp() * @return BOOLEAN */ BOOLEAN -HyperDbgGetIoApic(PIO_APIC_ENTRY_PACKETS IoApic) +HyperDbgGetIoApic(IO_APIC_ENTRY_PACKETS * IoApic) { BOOLEAN IsUsingX2APIC; // not used since I/O APIC is accessed through memory (not MSR) diff --git a/hyperdbg/libhyperdbg/code/export/export.cpp b/hyperdbg/libhyperdbg/code/export/export.cpp index 1e76792c..78c87525 100644 --- a/hyperdbg/libhyperdbg/code/export/export.cpp +++ b/hyperdbg/libhyperdbg/code/export/export.cpp @@ -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 * diff --git a/hyperdbg/libhyperdbg/header/debugger.h b/hyperdbg/libhyperdbg/header/debugger.h index 2c88288e..b1f48726 100644 --- a/hyperdbg/libhyperdbg/header/debugger.h +++ b/hyperdbg/libhyperdbg/header/debugger.h @@ -283,6 +283,9 @@ HyperDbgDebugCloseRemoteDebugger(); BOOLEAN HyperDbgGetLocalApic(PLAPIC_PAGE LocalApic, PBOOLEAN IsUsingX2APIC); +BOOLEAN +HyperDbgGetIoApic(IO_APIC_ENTRY_PACKETS * IoApic); + BOOLEAN CommandApicSendRequest(DEBUGGER_APIC_REQUEST_TYPE ApicType, PVOID ApicBuffer, From 62535c94da77dbd3e4f9ce4f93bfbe74faa51e34 Mon Sep 17 00:00:00 2001 From: SinaKarvandi Date: Wed, 20 Nov 2024 15:39:21 +0100 Subject: [PATCH 3/5] fix overflow error in showing interrupt entries --- CHANGELOG.md | 1 + hyperdbg/hyperhv/code/devices/Apic.c | 12 ++++++++++-- hyperdbg/include/SDK/headers/RequestStructures.h | 8 ++++---- .../debugger/commands/extension-commands/apic.cpp | 3 +-- .../debugger/commands/extension-commands/ioapic.cpp | 13 +++++++++++-- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71b3a84b..7a99b885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ 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)) ### Changed diff --git a/hyperdbg/hyperhv/code/devices/Apic.c b/hyperdbg/hyperhv/code/devices/Apic.c index 36228346..90e6c499 100644 --- a/hyperdbg/hyperhv/code/devices/Apic.c +++ b/hyperdbg/hyperhv/code/devices/Apic.c @@ -109,11 +109,19 @@ ApicDumpIoApic(IO_APIC_ENTRY_PACKETS * IoApicPackets) 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); - IoApicPackets->LlData[Index] = ll; - IoApicPackets->LhData[Index] = lh; + IoApicPackets->LlLhData[Index] = ll; + IoApicPackets->LlLhData[Index + 1] = lh; } } diff --git a/hyperdbg/include/SDK/headers/RequestStructures.h b/hyperdbg/include/SDK/headers/RequestStructures.h index b7d9435a..216490ca 100644 --- a/hyperdbg/include/SDK/headers/RequestStructures.h +++ b/hyperdbg/include/SDK/headers/RequestStructures.h @@ -1162,11 +1162,12 @@ typedef struct _LAPIC_PAGE /** * @brief Maximum number of I/O APIC entries - * @details Usually half of the 256 entries is enough + * @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 0xff / 2 +#define MAX_NUMBER_OF_IO_APIC_ENTRIES 400 /** * @brief The structure of I/O APIC result packet in HyperDbg @@ -1179,8 +1180,7 @@ typedef struct _IO_APIC_ENTRY_PACKETS UINT32 IoIdReg; UINT32 IoLl; UINT32 IoArbIdReg; - UINT64 LlData[MAX_NUMBER_OF_IO_APIC_ENTRIES]; - UINT64 LhData[MAX_NUMBER_OF_IO_APIC_ENTRIES]; + UINT64 LlLhData[MAX_NUMBER_OF_IO_APIC_ENTRIES]; } IO_APIC_ENTRY_PACKETS, *PIO_APIC_ENTRY_PACKETS; diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/apic.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/apic.cpp index 01b930fd..e91d2c5c 100644 --- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/apic.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/apic.cpp @@ -108,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 ); diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp index 649fb671..41734745 100644 --- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/ioapic.cpp @@ -170,8 +170,17 @@ CommandIoapicShowIoApicEntries(IO_APIC_ENTRY_PACKETS * IoApicPackets) for (Index = 0; Index <= Max; Index += 2) { - ll = IoApicPackets->LlData[Index]; - lh = IoApicPackets->LhData[Index]; + 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); From b7043b48aeab253cfe6b05cae7f12e6c59c0281c Mon Sep 17 00:00:00 2001 From: SinaKarvandi Date: Tue, 26 Nov 2024 11:44:06 +0100 Subject: [PATCH 4/5] Add IDT Entries interpreter --- examples/kernel/hyperdbg_driver/header/pch.h | 5 -- hyperdbg/hyperhv/code/devices/Apic.c | 21 ++++++++ hyperdbg/hyperhv/code/processor/Idt.c | 42 ++++++++++++++++ hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c | 10 ++-- hyperdbg/hyperhv/header/processor/Idt.h | 49 +++++++++++++++++++ hyperdbg/hyperhv/hyperhv.vcxproj | 2 + hyperdbg/hyperhv/hyperhv.vcxproj.filters | 12 +++++ hyperdbg/hyperhv/pch.h | 1 + .../include/SDK/headers/RequestStructures.h | 27 ++++++++++ 9 files changed, 160 insertions(+), 9 deletions(-) create mode 100644 hyperdbg/hyperhv/code/processor/Idt.c create mode 100644 hyperdbg/hyperhv/header/processor/Idt.h diff --git a/examples/kernel/hyperdbg_driver/header/pch.h b/examples/kernel/hyperdbg_driver/header/pch.h index b185300a..bc1ec58b 100644 --- a/examples/kernel/hyperdbg_driver/header/pch.h +++ b/examples/kernel/hyperdbg_driver/header/pch.h @@ -22,11 +22,6 @@ #include #include -// -// Definition of Intel primitives (External header) -// -// #include "ia32-doc/out/ia32.h" - // // Import Configuration and Definitions // diff --git a/hyperdbg/hyperhv/code/devices/Apic.c b/hyperdbg/hyperhv/code/devices/Apic.c index 90e6c499..a989f95b 100644 --- a/hyperdbg/hyperhv/code/devices/Apic.c +++ b/hyperdbg/hyperhv/code/devices/Apic.c @@ -292,6 +292,27 @@ ApicTriggerGenericNmi() } } +/** + * @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 diff --git a/hyperdbg/hyperhv/code/processor/Idt.c b/hyperdbg/hyperhv/code/processor/Idt.c new file mode 100644 index 00000000..2cc23a44 --- /dev/null +++ b/hyperdbg/hyperhv/code/processor/Idt.c @@ -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); + } +} diff --git a/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c b/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c index c61843a8..6e6aed9c 100644 --- a/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c +++ b/hyperdbg/hyperhv/code/vmm/vmx/Vmexit.c @@ -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; } diff --git a/hyperdbg/hyperhv/header/processor/Idt.h b/hyperdbg/hyperhv/header/processor/Idt.h new file mode 100644 index 00000000..996d8f84 --- /dev/null +++ b/hyperdbg/hyperhv/header/processor/Idt.h @@ -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(); diff --git a/hyperdbg/hyperhv/hyperhv.vcxproj b/hyperdbg/hyperhv/hyperhv.vcxproj index 1cdfa91d..dfbb01a1 100644 --- a/hyperdbg/hyperhv/hyperhv.vcxproj +++ b/hyperdbg/hyperhv/hyperhv.vcxproj @@ -161,6 +161,7 @@ + @@ -262,6 +263,7 @@ + diff --git a/hyperdbg/hyperhv/hyperhv.vcxproj.filters b/hyperdbg/hyperhv/hyperhv.vcxproj.filters index 373891c6..f08e0f43 100644 --- a/hyperdbg/hyperhv/hyperhv.vcxproj.filters +++ b/hyperdbg/hyperhv/hyperhv.vcxproj.filters @@ -135,6 +135,12 @@ {0c6f7e8d-4829-4a45-b09d-4c40cfcc5cf7} + + {36f1d8ba-6527-4c1b-8016-ae66d1bd41e7} + + + {8efcd014-6f76-436f-bca7-33f1cf2bd980} + @@ -308,6 +314,9 @@ code\devices + + code\processor + @@ -574,6 +583,9 @@ header\devices + + header\processor + diff --git a/hyperdbg/hyperhv/pch.h b/hyperdbg/hyperhv/pch.h index 6f0f6fbb..0f7edbbc 100644 --- a/hyperdbg/hyperhv/pch.h +++ b/hyperdbg/hyperhv/pch.h @@ -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" diff --git a/hyperdbg/include/SDK/headers/RequestStructures.h b/hyperdbg/include/SDK/headers/RequestStructures.h index 216490ca..c24e704c 100644 --- a/hyperdbg/include/SDK/headers/RequestStructures.h +++ b/hyperdbg/include/SDK/headers/RequestStructures.h @@ -1194,6 +1194,33 @@ static_assert(sizeof(IO_APIC_ENTRY_PACKETS) < PacketChunkSize, /* ============================================================================================== */ +/** + * @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"); + +/* ============================================================================================== + */ + /** * @brief The structure of .formats result packet in HyperDbg * From 1ebe1ada385aab831ca7772664a8d54e9a35bca7 Mon Sep 17 00:00:00 2001 From: SinaKarvandi Date: Wed, 27 Nov 2024 14:16:41 +0100 Subject: [PATCH 5/5] change and add links for increasing communication buffer size and EPT hooks in a single page --- CHANGELOG.md | 2 ++ .../hyperkd/code/debugger/communication/SerialConnection.c | 6 +++--- hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp | 4 +++- hyperdbg/libhyperdbg/code/debugger/kernel-level/kd.cpp | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a99b885..e7b00057 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,10 @@ 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. diff --git a/hyperdbg/hyperkd/code/debugger/communication/SerialConnection.c b/hyperdbg/hyperkd/code/debugger/communication/SerialConnection.c index e1791071..33adbafe 100644 --- a/hyperdbg/hyperkd/code/debugger/communication/SerialConnection.c +++ b/hyperdbg/hyperkd/code/debugger/communication/SerialConnection.c @@ -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; diff --git a/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp b/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp index f8238167..7a2d3f10 100644 --- a/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/core/debugger.cpp @@ -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; diff --git a/hyperdbg/libhyperdbg/code/debugger/kernel-level/kd.cpp b/hyperdbg/libhyperdbg/code/debugger/kernel-level/kd.cpp index 092a318d..2855e614 100644 --- a/hyperdbg/libhyperdbg/code/debugger/kernel-level/kd.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/kernel-level/kd.cpp @@ -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);