mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-22 23:44:38 +00:00
238 lines
6.2 KiB
C++
238 lines
6.2 KiB
C++
/**
|
|
* @file idt.cpp
|
|
* @author Sina Karvandi (sina@hyperdbg.org)
|
|
* @brief !idt command
|
|
* @details
|
|
* @version 0.12
|
|
* @date 2024-12-30
|
|
*
|
|
* @copyright This project is released under the GNU Public License v3.
|
|
*
|
|
*/
|
|
#include "pch.h"
|
|
|
|
//
|
|
// Global Variables
|
|
//
|
|
extern BOOLEAN g_IsSerialConnectedToRemoteDebuggee;
|
|
extern BOOLEAN g_IsKdModuleLoaded;
|
|
extern BOOLEAN g_AddressConversion;
|
|
|
|
/**
|
|
* @brief help of the !idt command
|
|
*
|
|
* @return VOID
|
|
*/
|
|
VOID
|
|
CommandIdtHelp()
|
|
{
|
|
ShowMessages("!ioapic : shows entries of Interrupt Descriptor Table (IDT).\n\n");
|
|
|
|
ShowMessages("syntax : \t!idt [IdtEntry (hex)]\n");
|
|
|
|
ShowMessages("\n");
|
|
ShowMessages("\t\te.g : !idt\n");
|
|
ShowMessages("\t\te.g : !idt 1d\n");
|
|
}
|
|
|
|
/**
|
|
* @brief Send IDT entry requests
|
|
*
|
|
* @param IdtPacket
|
|
*
|
|
* @return VOID
|
|
*/
|
|
BOOLEAN
|
|
HyperDbgGetIdtEntry(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS * IdtPacket)
|
|
{
|
|
BOOL Status;
|
|
ULONG ReturnedLength;
|
|
|
|
if (g_IsSerialConnectedToRemoteDebuggee)
|
|
{
|
|
//
|
|
// Send the request over serial kernel debugger
|
|
//
|
|
if (!KdSendQueryIdtPacketsToDebuggee(IdtPacket))
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AssertShowMessageReturnStmt(g_IsKdModuleLoaded, g_DeviceHandle, ASSERT_MESSAGE_KD_NOT_LOADED, ASSERT_MESSAGE_DRIVER_NOT_LOADED, AssertReturnFalse);
|
|
|
|
//
|
|
// Send IOCTL
|
|
//
|
|
Status = DeviceIoControl(
|
|
g_DeviceHandle, // Handle to device
|
|
IOCTL_QUERY_IDT_ENTRY, // IO Control Code (IOCTL)
|
|
IdtPacket, // Input Buffer to driver.
|
|
SIZEOF_INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS, // Input buffer length (not used in this case)
|
|
IdtPacket, // Output Buffer from driver.
|
|
SIZEOF_INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS, // Length of output buffer in bytes.
|
|
&ReturnedLength, // Bytes placed in buffer.
|
|
NULL // synchronous call
|
|
);
|
|
|
|
if (!Status)
|
|
{
|
|
ShowMessages("ioctl failed with code 0x%x\n", GetLastError());
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
if (IdtPacket->KernelStatus == DEBUGGER_OPERATION_WAS_SUCCESSFUL)
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// An err occurred, no results
|
|
//
|
|
ShowErrorMessage(IdtPacket->KernelStatus);
|
|
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief !idt command handler
|
|
*
|
|
* @param CommandTokens
|
|
* @param Command
|
|
*
|
|
* @return VOID
|
|
*/
|
|
VOID
|
|
CommandIdt(vector<CommandToken> CommandTokens, string Command)
|
|
{
|
|
UINT32 IdtEntry;
|
|
INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS * IdtPacket = NULL;
|
|
BOOLEAN ShowAllEntries = TRUE;
|
|
UINT64 UsedBaseAddress = NULL;
|
|
|
|
//
|
|
// Check if the command should show all entries or just one entry
|
|
//
|
|
if (CommandTokens.size() == 1)
|
|
{
|
|
ShowAllEntries = TRUE;
|
|
}
|
|
else if (CommandTokens.size() == 2)
|
|
{
|
|
ShowAllEntries = FALSE;
|
|
|
|
//
|
|
// Get the IDT entry number
|
|
//
|
|
if (ConvertTokenToUInt32(CommandTokens.at(1), &IdtEntry) == FALSE)
|
|
{
|
|
ShowMessages("err, invalid IDT entry number\n");
|
|
return;
|
|
}
|
|
|
|
if (IdtEntry > MAX_NUMBER_OF_IDT_ENTRIES)
|
|
{
|
|
ShowMessages("err, invalid IDT entry number\n");
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ShowMessages("incorrect use of the '%s'\n\n",
|
|
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
|
|
|
|
CommandIdtHelp();
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Allocate buffer for IDT entry
|
|
//
|
|
IdtPacket = (INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS *)malloc(sizeof(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS));
|
|
|
|
if (IdtPacket == NULL)
|
|
{
|
|
ShowMessages("err, allocating buffer for receiving IDT entries");
|
|
}
|
|
|
|
RtlZeroMemory(IdtPacket, sizeof(INTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS));
|
|
|
|
//
|
|
// Get the IDT buffer
|
|
//
|
|
if (HyperDbgGetIdtEntry(IdtPacket) == TRUE)
|
|
{
|
|
//
|
|
// Show (dump) entries
|
|
//
|
|
if (ShowAllEntries)
|
|
{
|
|
ShowMessages("IDT Entries:\n\n");
|
|
|
|
for (UINT32 i = 0; i < MAX_NUMBER_OF_IDT_ENTRIES; i++)
|
|
{
|
|
ShowMessages("IDT[0x%x:%d]\t: %s\t",
|
|
i,
|
|
i,
|
|
SeparateTo64BitValue(IdtPacket->IdtEntry[i]).c_str());
|
|
|
|
//
|
|
// Apply addressconversion of settings here
|
|
//
|
|
if (g_AddressConversion)
|
|
{
|
|
//
|
|
// Showing function names here
|
|
//
|
|
if (SymbolShowFunctionNameBasedOnAddress(IdtPacket->IdtEntry[i], &UsedBaseAddress))
|
|
{
|
|
//
|
|
// The symbol address is showed (nothing to do)
|
|
//
|
|
}
|
|
}
|
|
|
|
ShowMessages("\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ShowMessages("IDT[0x%x:%d] : %s\t",
|
|
IdtEntry,
|
|
IdtEntry,
|
|
SeparateTo64BitValue(IdtPacket->IdtEntry[IdtEntry]).c_str());
|
|
|
|
//
|
|
// Apply addressconversion of settings here
|
|
//
|
|
if (g_AddressConversion)
|
|
{
|
|
//
|
|
// Showing function names here
|
|
//
|
|
if (SymbolShowFunctionNameBasedOnAddress(IdtPacket->IdtEntry[IdtEntry], &UsedBaseAddress))
|
|
{
|
|
//
|
|
// The symbol address is showed (nothing to do)
|
|
//
|
|
}
|
|
|
|
ShowMessages("\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Deallocate the buffer
|
|
//
|
|
free(IdtPacket);
|
|
}
|