diff --git a/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c b/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c index a1d7a793..24a9826b 100644 --- a/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c +++ b/hyperdbg/hyperkd/code/debugger/commands/ExtensionCommands.c @@ -641,26 +641,61 @@ ExtensionCommandIoBitmapResetAllCores() /** * @brief routines for !pcitree * - * @param PcitreeReqPacket + * @param PcitreePacket * @param OperateOnVmxRoot * @return VOID */ VOID -ExtensionCommandPcitree(PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreeReqPacket, BOOLEAN OperateOnVmxRoot) +ExtensionCommandPcitree(PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreePacket, BOOLEAN OperateOnVmxRoot) { - DWORD DeviceIdVendorId = 0; + DWORD DeviceIdVendorId = 0xFFFFFFFF; + DWORD ClassCode = 0xFFFFFFFF; + UINT8 EpNum = 0; - DeviceIdVendorId = (DWORD)PciReadCam(PcitreeReqPacket->RequestedBus, PcitreeReqPacket->RequestedDevice, PcitreeReqPacket->RequestedFunction, 0, sizeof(DWORD)); - if (DeviceIdVendorId != 0xFFFFFFFF) + LogInfo("Enumerating endpoints...\n"); + + for (UINT8 b = 0; b < BUS_MAX_NUM; b++) { - LogInfo("DeviceIdVendorId: %x\n", DeviceIdVendorId); - PcitreeReqPacket->Device.Function[0].ConfigSpace.CommonHeader.DeviceId = (UINT16)(DeviceIdVendorId >> 16); - PcitreeReqPacket->Device.Function[0].ConfigSpace.CommonHeader.VendorId = (UINT16)(DeviceIdVendorId & 0xFFFF); - PcitreeReqPacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL; + for (UINT8 d = 0; d < DEVICE_MAX_NUM; d++) + { + for (UINT8 f = 0; f < FUNCTION_MAX_NUM; f++) + { + DeviceIdVendorId = (DWORD)PciReadCam(b, d, f, 0, sizeof(DWORD)); + + if (DeviceIdVendorId != 0xFFFFFFFF) + { + PcitreePacket->Endpoints[EpNum].Bus = b; + PcitreePacket->Endpoints[EpNum].Device = d; + PcitreePacket->Endpoints[EpNum].Function = f; + PcitreePacket->Endpoints[EpNum].ConfigSpace.VendorId = (UINT16)(DeviceIdVendorId & 0xFFFF); + PcitreePacket->Endpoints[EpNum].ConfigSpace.DeviceId = (UINT16)(DeviceIdVendorId >> 16); + + ClassCode = (DWORD)PciReadCam(b, d, f, 0, sizeof(DWORD)); + PcitreePacket->Endpoints[EpNum].ConfigSpace.ClassCode[0] = (UINT8)((ClassCode >> 24) & 0xFF); + PcitreePacket->Endpoints[EpNum].ConfigSpace.ClassCode[1] = (UINT8)((ClassCode >> 16) & 0xFF); + PcitreePacket->Endpoints[EpNum].ConfigSpace.ClassCode[2] = (UINT8)((ClassCode >> 8) & 0xFF); + + EpNum++; + if (EpNum == EP_MAX_NUM) + { + LogError("Reached maximum number of endpoints (%u) that can be stored in debuggee response packet.\n", EP_MAX_NUM); + break; + } + } + } + } + } + PcitreePacket->EndpointsTotalNum = EpNum; + + LogInfo("Enumerated %u endpoints.\n", PcitreePacket->EndpointsTotalNum); + + if (PcitreePacket->EndpointsTotalNum) + { + PcitreePacket->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL; } else { - PcitreeReqPacket->KernelStatus = DEBUGGER_ERROR_INVALID_ADDRESS; + PcitreePacket->KernelStatus = DEBUGGER_ERROR_INVALID_ADDRESS; } // diff --git a/hyperdbg/include/SDK/headers/Pcie.h b/hyperdbg/include/SDK/headers/Pcie.h index 3ac2e349..e769a17f 100644 --- a/hyperdbg/include/SDK/headers/Pcie.h +++ b/hyperdbg/include/SDK/headers/Pcie.h @@ -30,14 +30,15 @@ #define FUNCTION_BIT_WIDTH 3 // -// NOTES -// - To speed up PCI device enumeration, the parameters below limit the max BDF range to what might be reasonably expected on real-world systems. -// - Ensure the following parameters do not result in exceeding MaxSerialPacketSize. Consider sending multiple packets if necessary. +// NOTE +// On real-world systems, the number of endpoints will likely not exceed 255. +// If increasing EP_MAX_NUM is necessary, ensure PCI_EP_MINIMAL[EP_MAX_NUM] does not result in exceeding MaxSerialPacketSize. // #define DOMAIN_MAX_NUM 0 -#define BUS_MAX_NUM 32 +#define BUS_MAX_NUM 255 #define DEVICE_MAX_NUM 32 #define FUNCTION_MAX_NUM 8 +#define EP_MAX_NUM 255 /** * @brief PCI Common Header @@ -77,6 +78,32 @@ typedef struct _PORTABLE_PCI_DEVICE_HEADER UINT8 MaxLat; // Max_Lat } PORTABLE_PCI_DEVICE_HEADER, *PPORTABLE_PCI_DEVICE_HEADER; +/** + * @brief PCI Configuration Space Minimal Header for !pcitree + * + */ +typedef struct _PORTABLE_PCI_CONFIG_SPACE_HEADER_MINIMAL +{ + // + // Common header + // + UINT16 VendorId; + UINT16 DeviceId; + UINT8 ClassCode[3]; +} PORTABLE_PCI_CONFIG_SPACE_HEADER_MINIMAL, *PPORTABLE_PCI_CONFIG_SPACE_HEADER_MINIMAL; + +/** + * @brief PCI Endpoint Minimal Data Structure for !pcitree + * + */ +typedef struct _PCI_EP_MINIMAL +{ + UINT8 Bus : BUS_BIT_WIDTH; + UINT8 Device : DEVICE_BIT_WIDTH; + UINT8 Function : FUNCTION_BIT_WIDTH; + PORTABLE_PCI_CONFIG_SPACE_HEADER_MINIMAL ConfigSpace; +} PCI_EP_MINIMAL, *PPCI_EP_MINIMAL; + /** * @brief PCI Configuration Space Header * @@ -94,6 +121,7 @@ typedef struct _PORTABLE_PCI_CONFIG_SPACE_HEADER */ typedef struct _PCI_FUNCTION { + UINT8 Function : FUNCTION_BIT_WIDTH; PORTABLE_PCI_CONFIG_SPACE_HEADER ConfigSpace; } PCI_FUNCTION, *PPCI_FUNCTION; @@ -103,6 +131,7 @@ typedef struct _PCI_FUNCTION */ typedef struct _PCI_DEVICE { + UINT8 Device : DEVICE_BIT_WIDTH; PCI_FUNCTION Function[FUNCTION_MAX_NUM]; } PCI_DEVICE, *PPCI_DEVICE; @@ -112,6 +141,7 @@ typedef struct _PCI_DEVICE */ typedef struct _PCI_BUS { + UINT8 Bus : BUS_BIT_WIDTH; PCI_DEVICE Device[DEVICE_MAX_NUM]; } PCI_BUS, *PPCI_BUS; diff --git a/hyperdbg/include/SDK/headers/RequestStructures.h b/hyperdbg/include/SDK/headers/RequestStructures.h index 8063c6ce..546f5b4c 100644 --- a/hyperdbg/include/SDK/headers/RequestStructures.h +++ b/hyperdbg/include/SDK/headers/RequestStructures.h @@ -1316,16 +1316,14 @@ typedef struct _DEBUGGEE_REGISTER_WRITE_DESCRIPTION sizeof(DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET) /** - * @brief Pcitree Request-Response Packet. Represents one PCI device. + * @brief Pcitree Request-Response Packet. Represents PCI device tree. * */ typedef struct _DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET { - UINT32 KernelStatus; - UINT8 RequestedBus : BUS_BIT_WIDTH; - UINT8 RequestedDevice : DEVICE_BIT_WIDTH; - UINT8 RequestedFunction : FUNCTION_BIT_WIDTH; - PCI_DEVICE Device; + UINT32 KernelStatus; + UINT8 EndpointsTotalNum; + PCI_EP_MINIMAL Endpoints[EP_MAX_NUM]; } DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET, *PDEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET; diff --git a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pcitree.cpp b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pcitree.cpp index beff463a..999b205c 100644 --- a/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pcitree.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/commands/extension-commands/pcitree.cpp @@ -45,8 +45,7 @@ CommandPcitree(vector CommandTokens, string Command) { BOOL Status; ULONG ReturnedLength; - DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreeReqPacket = {0}; - DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreeRespPacket = {0}; + DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET PcitreePacket = {0}; if (CommandTokens.size() != 1) { @@ -56,76 +55,72 @@ CommandPcitree(vector CommandTokens, string Command) return; } - for (UINT8 b = 0; b < BUS_MAX_NUM; b++) + // + // Send buffer + // + if (g_IsSerialConnectedToRemoteDebuggee) { - for (UINT8 d = 0; d < DEVICE_MAX_NUM; d++) + KdSendPcitreePacketToDebuggee(&PcitreePacket); + } + else + { + AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn); + + ShowMessages("Sending IOCTL\n"); + + // + // Send IOCTL + // + Status = DeviceIoControl( + g_DeviceHandle, // Handle to device + IOCTL_PCIE_ENDPOINT_ENUM, // IO Control Code (IOCTL) + &PcitreePacket, // Input Buffer to driver. + SIZEOF_DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET, // Input buffer length + &PcitreePacket, // Output Buffer from driver. + SIZEOF_DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET, // Length of output + // buffer in bytes. + &ReturnedLength, // Bytes placed in buffer. + NULL // synchronous call + ); + + ShowMessages("Done sending IOCTL\n"); + + if (!Status) { - for (UINT8 f = 0; f < FUNCTION_MAX_NUM; f++) + ShowMessages("ioctl failed with code 0x%x\n", GetLastError()); + return; + } + + if (PcitreePacket.KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL) + { + // + // Print PCI device tree + // + ShowMessages("%-12s | %-9s | %s\n%s\n", "DBDF", "VID:DID", "Class Code", "---------------------------------------"); + for (UINT8 i = 0; i < (PcitreePacket.EndpointsTotalNum < EP_MAX_NUM ? PcitreePacket.EndpointsTotalNum : EP_MAX_NUM); i++) { - // - // Prepare buffer - // - PcitreeReqPacket.RequestedBus = b; - PcitreeReqPacket.RequestedDevice = d; - PcitreeReqPacket.RequestedFunction = f; + ShowMessages("%04x:%02x:%02x:%x | %04x:%04x | %04x%04x%04x\n", + 0, // TODO: Add support for domains beyond 0000 + PcitreePacket.Endpoints[i].Bus, + PcitreePacket.Endpoints[i].Device, + PcitreePacket.Endpoints[i].Function, + PcitreePacket.Endpoints[i].ConfigSpace.VendorId, + PcitreePacket.Endpoints[i].ConfigSpace.DeviceId, + PcitreePacket.Endpoints[i].ConfigSpace.ClassCode[0], + PcitreePacket.Endpoints[i].ConfigSpace.ClassCode[1], + PcitreePacket.Endpoints[i].ConfigSpace.ClassCode[2] - // - // Send buffer - // - if (g_IsSerialConnectedToRemoteDebuggee) - { - KdSendPcitreePacketToDebuggee(&PcitreeReqPacket); - } - else - { - AssertShowMessageReturnStmt(g_DeviceHandle, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturn); - - ShowMessages("Sending IOCTL\n"); - - // - // Send IOCTL - // - Status = DeviceIoControl( - g_DeviceHandle, // Handle to device - IOCTL_PCIE_ENDPOINT_ENUM, // IO Control Code (IOCTL) - &PcitreeReqPacket, // Input Buffer to driver. - SIZEOF_DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET, // Input buffer length - &PcitreeRespPacket, // Output Buffer from driver. - SIZEOF_DEBUGGEE_PCITREE_REQUEST_RESPONSE_PACKET, // Length of output - // buffer in bytes. - &ReturnedLength, // Bytes placed in buffer. - NULL // synchronous call - ); - - ShowMessages("Done sending IOCTL\n"); - - if (!Status) - { - ShowMessages("ioctl failed with code 0x%x\n", GetLastError()); - return; - } - - if (PcitreeRespPacket.KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL) - { - ShowMessages("Result: (%04x:%2x:%2x:%x) VID:DID: %x:%x\n", - 0, - PcitreeRespPacket.RequestedBus, - PcitreeRespPacket.RequestedDevice, - PcitreeRespPacket.RequestedFunction, - PcitreeRespPacket.Device.Function[0].ConfigSpace.CommonHeader.VendorId, - PcitreeRespPacket.Device.Function[0].ConfigSpace.CommonHeader.DeviceId); - } - else - { - // - // An err occurred, no results - // - ShowMessages("An err occured, no results:"); - - ShowErrorMessage(PcitreeRespPacket.KernelStatus); - } - } + ); } } + else + { + // + // An err occurred, no results + // + ShowMessages("An err occured, no results:"); + + ShowErrorMessage(PcitreePacket.KernelStatus); + } } } diff --git a/hyperdbg/libhyperdbg/code/debugger/kernel-level/kernel-listening.cpp b/hyperdbg/libhyperdbg/code/debugger/kernel-level/kernel-listening.cpp index 2e499bcc..072b5c49 100644 --- a/hyperdbg/libhyperdbg/code/debugger/kernel-level/kernel-listening.cpp +++ b/hyperdbg/libhyperdbg/code/debugger/kernel-level/kernel-listening.cpp @@ -1052,19 +1052,28 @@ StartAgain: if (PcitreePacket->KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL) { // - // TODO: Add support for domains beyond 0000 + // Print PCI device tree // - ShowMessages("Got packet from debuggee: (%04x:%02x:%02x:%x) VID:DID: %04x:%04x\n", - 0, - PcitreePacket->RequestedBus, - PcitreePacket->RequestedDevice, - PcitreePacket->RequestedFunction, - PcitreePacket->Device.Function[0].ConfigSpace.CommonHeader.VendorId, - PcitreePacket->Device.Function[0].ConfigSpace.CommonHeader.DeviceId); + ShowMessages("%-12s | %-9s | %s\n%s\n", "DBDF", "VID:DID", "Class Code", "---------------------------------------"); + for (UINT8 i = 0; i < (PcitreePacket->EndpointsTotalNum < EP_MAX_NUM ? PcitreePacket->EndpointsTotalNum : EP_MAX_NUM); i++) + { + ShowMessages("%04x:%02x:%02x:%x | %04x:%04x | %04x%04x%04x\n", + 0, // TODO: Add support for domains beyond 0000 + PcitreePacket->Endpoints[i].Bus, + PcitreePacket->Endpoints[i].Device, + PcitreePacket->Endpoints[i].Function, + PcitreePacket->Endpoints[i].ConfigSpace.VendorId, + PcitreePacket->Endpoints[i].ConfigSpace.DeviceId, + PcitreePacket->Endpoints[i].ConfigSpace.ClassCode[0], + PcitreePacket->Endpoints[i].ConfigSpace.ClassCode[1], + PcitreePacket->Endpoints[i].ConfigSpace.ClassCode[2] + + ); + } } else { - // ShowErrorMessage(PcitreePacket->KernelStatus); + ShowErrorMessage(PcitreePacket->KernelStatus); } //