mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-09 17:19:26 +00:00
pcitree: Send PCI device tree in one flattened buffer. Add EP Class Code and remove BDF probing limits.
This commit is contained in:
parent
e714e3e6ad
commit
29071cad41
5 changed files with 163 additions and 96 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,8 +45,7 @@ CommandPcitree(vector<CommandToken> 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<CommandToken> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue