mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-23 07:54:39 +00:00
234 lines
5.2 KiB
C++
234 lines
5.2 KiB
C++
/**
|
|
* @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"
|
|
|
|
/**
|
|
* @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);
|
|
}
|