mirror of
https://github.com/winterknife/EVENSTAR
synced 2026-06-21 14:13:51 +00:00
added ReadIDTDbgExt project
This commit is contained in:
@@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GetCPL", "GetCPL\GetCPL.vcx
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PagingDbgExt", "PagingDbgExt\PagingDbgExt.vcxproj", "{4321EA53-183E-4104-887D-5CBFC14E4211}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReadIDTDbgExt", "ReadIDTDbgExt\ReadIDTDbgExt.vcxproj", "{32175898-45C7-4C47-990E-EBB9DA9D0992}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Release|x64 = Release|x64
|
||||
@@ -20,6 +22,8 @@ Global
|
||||
{F9AB9899-9F93-4252-B634-740F19CCC1DC}.Release|x64.Build.0 = Release|x64
|
||||
{4321EA53-183E-4104-887D-5CBFC14E4211}.Release|x64.ActiveCfg = Release|x64
|
||||
{4321EA53-183E-4104-887D-5CBFC14E4211}.Release|x64.Build.0 = Release|x64
|
||||
{32175898-45C7-4C47-990E-EBB9DA9D0992}.Release|x64.ActiveCfg = Release|x64
|
||||
{32175898-45C7-4C47-990E-EBB9DA9D0992}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
// ========================================================================
|
||||
// File: BaseDataTypes.h
|
||||
//
|
||||
// Author: winterknife
|
||||
//
|
||||
// Description: Type definitions for common Windows base data types made
|
||||
// for maintaining uniformity across all User Mode and Kernel Mode code
|
||||
//
|
||||
// Modifications:
|
||||
// 2021-07-31 Created
|
||||
// 2022-08-13 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
// Pragmas
|
||||
// ========================================================================
|
||||
|
||||
#pragma once
|
||||
|
||||
// ========================================================================
|
||||
// Type definitions
|
||||
// ========================================================================
|
||||
|
||||
#pragma region TYPEDEFS
|
||||
|
||||
// 8-bit unsigned integer, range = 0 - 255, unsigned char
|
||||
typedef unsigned __int8 BYTE, *PBYTE;
|
||||
|
||||
// 16-bit unsigned integer, range = 0 - 65535, unsigned short
|
||||
typedef unsigned __int16 WORD, *PWORD;
|
||||
|
||||
// 32-bit unsigned integer, range = 0 - 4294967295, unsigned int or unsigned long
|
||||
typedef unsigned long DWORD, *PDWORD;
|
||||
|
||||
// 64-bit unsigned integer, range = 0 - 18446744073709551615, unsigned long long
|
||||
typedef unsigned __int64 QWORD, *PQWORD;
|
||||
|
||||
// Should be TRUE(1) or FALSE(0), unsigned char or bool
|
||||
typedef unsigned __int8 BOOLEAN, *PBOOLEAN;
|
||||
|
||||
// 8-bit UTF-8/Multibyte/ANSI character, char
|
||||
typedef __int8 CHAR, *PCHAR;
|
||||
|
||||
// 16-bit UTF-16/Wide/UNICODE character, unsigned short
|
||||
typedef wchar_t WCHAR, *PWCHAR;
|
||||
|
||||
// Pointer to any type, size = 4 bytes or 8 bytes depending on code bitness
|
||||
typedef void* PVOID;
|
||||
|
||||
// Pointer to a constant of any type
|
||||
typedef const void* PCVOID;
|
||||
|
||||
// Pointer to constant null-terminated string of ANSI characters
|
||||
typedef _Null_terminated_ const __int8* PCSTR;
|
||||
|
||||
// Pointer to constant null-terminated string of UNICODE characters
|
||||
typedef _Null_terminated_ const wchar_t* PCWSTR;
|
||||
|
||||
// Pointer to constant null-terminated string of ANSI or UNICODE characters depending on character encoding scheme
|
||||
#if defined(UNICODE)
|
||||
typedef const __wchar_t* PCTSTR;
|
||||
#else
|
||||
typedef const __int8* PCTSTR;
|
||||
#endif
|
||||
|
||||
// 32-bit or 64-bit unsigned integer, range = 0 - 4294967295 or 18446744073709551615 depending on compiler bitness
|
||||
// Used for casting pointers
|
||||
#if defined(_WIN64)
|
||||
typedef unsigned __int64 DWORD_PTR, *PDWORD_PTR;
|
||||
#else
|
||||
typedef unsigned long DWORD_PTR, *PDWORD_PTR;
|
||||
#endif
|
||||
|
||||
#pragma endregion
|
||||
@@ -0,0 +1,155 @@
|
||||
// ========================================================================
|
||||
// File: Common.h
|
||||
//
|
||||
// Author: winterknife
|
||||
//
|
||||
// Description: Contains the common stuff for this project
|
||||
//
|
||||
// Modifications:
|
||||
// 2021-08-21 Created
|
||||
// 2025-06-23 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
// Pragmas
|
||||
// ========================================================================
|
||||
|
||||
#pragma once
|
||||
|
||||
// Specify program entry point
|
||||
#pragma comment(linker, "/ENTRY:DllInit")
|
||||
|
||||
// Merge sections
|
||||
#if defined (_MSC_VER)
|
||||
#if (_MSC_VER >= 1920)
|
||||
#pragma comment(linker, "/MERGE:_RDATA=.rdata")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Emit error message at compile time if trying to build for 32-bit x86 target
|
||||
#if !defined(_WIN64)
|
||||
#error x86 build target is unsupported!
|
||||
#endif
|
||||
|
||||
// ========================================================================
|
||||
// Includes
|
||||
// ========================================================================
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define _NO_CRT_STDIO_INLINE
|
||||
#include <Windows.h>
|
||||
#include <intrin.h>
|
||||
#include <stdio.h>
|
||||
#include "BaseDataTypes.h"
|
||||
|
||||
#pragma intrinsic(__stosb)
|
||||
#pragma intrinsic(__movsb)
|
||||
#pragma intrinsic(strlen)
|
||||
#pragma intrinsic(strcmp)
|
||||
|
||||
// ========================================================================
|
||||
// Macros
|
||||
// ========================================================================
|
||||
|
||||
#pragma region MACROS
|
||||
|
||||
// Module name
|
||||
#define __MODULE__ "ReadIDTDbgExt"
|
||||
|
||||
// Comment out for final build
|
||||
//#define DEBUG_BUILD
|
||||
|
||||
// Print debug message macro
|
||||
#ifdef DEBUG_BUILD
|
||||
#define STRIP(...) __VA_ARGS__
|
||||
#define DEBUG_PREFIX "[DBG]: "
|
||||
#define DEBUG_PRINT(_x_, ...) printf(DEBUG_PREFIX _x_, ##__VA_ARGS__);
|
||||
#else
|
||||
#define DEBUG_PRINT(_x_, ...) void(0)
|
||||
#endif
|
||||
|
||||
// Stringizing operator macro
|
||||
#ifndef _CRT_STRINGIZE
|
||||
#define _CRT_STRINGIZE_(x) #x
|
||||
#define _CRT_STRINGIZE(x) _CRT_STRINGIZE_(x)
|
||||
#endif
|
||||
|
||||
// Get mangled name of a function
|
||||
#define GET_MANGLED_FUNCTION_NAME __pragma(message(__FILE__ _CRT_STRINGIZE((__LINE__): \nfunction:\t) __FUNCSIG__ " is mangled to: " __FUNCDNAME__))
|
||||
|
||||
// To set alternate name of decorated x86 IAT global function pointer
|
||||
#ifdef _X86_
|
||||
// Uses undocumented /ALTERNATENAME linker flag
|
||||
#define ALT_NAME(name, n) __pragma(comment(linker, _CRT_STRINGIZE(/ALTERNATENAME:__imp__##name##@##n####=___imp_##name)))
|
||||
#else
|
||||
#define ALT_NAME(name, n)
|
||||
#endif
|
||||
|
||||
// To declare/initialize global IAT function pointers for run-time dynamic linking, use on global scope
|
||||
#define IMP_FUNC(name, n) EXTERN_C_START PVOID __imp_##name = NULL; EXTERN_C_END ALT_NAME(name, n)
|
||||
|
||||
// To declare/initialize local function pointers for run-time dynamic linking, use on local scope
|
||||
// Warning: will ignore SAL annotations
|
||||
#define IMP_FUNC_PIC(name) typedef decltype(name) __type_##name; __type_##name* ##name = NULL;
|
||||
|
||||
// Check if a function is in a delay loaded module, use on a global scope
|
||||
#define CHECK_DELAY_LOAD(f) extern "C" extern void* __imp_load_ ##f; void test_delay_load ##f(){ (__imp_load_ ##f) ? 1 : 0; }
|
||||
|
||||
// Macro to indicate a specific function to the linker as the first in the link order
|
||||
#define CODE_BEGIN code_seg(push, ".text")
|
||||
|
||||
// Macro to indicate the end of the specific function to the linker
|
||||
#define CODE_END code_seg(pop)
|
||||
|
||||
// Macro to disable all compiler optimizations for a specific function
|
||||
#define OPTIMIZATION_OFF optimize("", off)
|
||||
|
||||
// Macro to re-enable/reset compiler optimizations for a specific function
|
||||
#define OPTIMIZATION_ON optimize("", on)
|
||||
|
||||
// Macro to enable compiler optimizations for generating short sequences of machine code for a specific function
|
||||
#if defined(_M_IX86)
|
||||
#define OPTIMIZATION_SIZE optimize("gsy", on)
|
||||
#else
|
||||
#define OPTIMIZATION_SIZE optimize("gs", on)
|
||||
#endif
|
||||
|
||||
// Macro to enable compiler optimizations for generating fast sequences of machine code for a specific function
|
||||
#if defined(_M_IX86)
|
||||
#define OPTIMIZATION_SPEED optimize("gty", on)
|
||||
#else
|
||||
#define OPTIMIZATION_SPEED optimize("gt", on)
|
||||
#endif
|
||||
|
||||
// Macro to fill a block of memory with zeroes given it's address and length in bytes by generating store string instruction (rep stosb)
|
||||
// Enhanced REP STOSB/MOVSB (ERMSB) are only available since Ivy Bridge Intel microarchitecture (2012/2013)
|
||||
// Processors that provide support for enhanced MOVSB/STOSB operations are enumerated by the CPUID feature flag: CPUID:(EAX=7H, ECX=0H):EBX.ERMSB[bit 9] = 1
|
||||
#define ZERO_MEMORY(Destination, Length) __stosb((PBYTE)Destination, 0, Length)
|
||||
|
||||
// Macro to copy a block of memory given it's source address, destination address and the number of bytes to copy by generating move string instruction (rep movsb)
|
||||
#define COPY_MEMORY(Destination, Source, Count) __movsb((PBYTE)Destination, (const PBYTE)Source, Count)
|
||||
|
||||
#pragma endregion
|
||||
|
||||
// ========================================================================
|
||||
// C inline routines
|
||||
// ========================================================================
|
||||
|
||||
#pragma region INLINES
|
||||
|
||||
/// @brief To compare two blocks of memory and return the number of bytes that match
|
||||
/// @param pcSource1 Pointer to the first block of memory
|
||||
/// @param pcSource2 Pointer to the second block of memory
|
||||
/// @param dwptrLength The number of bytes to compare
|
||||
/// @return Number of bytes in the two blocks that match, if all bytes match up to the specified Length value, the Length value is returned
|
||||
extern "C" __forceinline DWORD_PTR __stdcall compare_memory(_In_ const PVOID pcSource1, _In_ const PVOID pcSource2, _In_ DWORD_PTR dwptrLength) {
|
||||
// Init local variables
|
||||
DWORD_PTR dwptrIndex = 0;
|
||||
|
||||
// Start comparing the two blocks of memory
|
||||
for (dwptrIndex = 0; (dwptrIndex < dwptrLength) && (((PBYTE)pcSource1)[dwptrIndex] == ((PBYTE)pcSource2)[dwptrIndex]); dwptrIndex++);
|
||||
|
||||
return dwptrIndex;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
@@ -0,0 +1,59 @@
|
||||
// ========================================================================
|
||||
// File: DbgExt.h
|
||||
//
|
||||
// Author: winterknife
|
||||
//
|
||||
// Description: Header file for DbgExt.cpp source file
|
||||
//
|
||||
// Modifications:
|
||||
// 2024-10-08 Created
|
||||
// 2024-10-08 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
// Pragmas
|
||||
// ========================================================================
|
||||
|
||||
#pragma once
|
||||
|
||||
// ========================================================================
|
||||
// Includes
|
||||
// ========================================================================
|
||||
|
||||
#include "Common.h"
|
||||
#define KDEXT_64BIT
|
||||
#include <WDBGEXTS.H>
|
||||
#include <ntverp.h>
|
||||
|
||||
// ========================================================================
|
||||
// C routine declarations
|
||||
// ========================================================================
|
||||
|
||||
#pragma region DECLARATIONS
|
||||
|
||||
/// @brief Load and initialize the extension module
|
||||
/// @param pWindbgExtensionApis Pointer to WINDBG_EXTENSION_APIS64 structure
|
||||
/// @param woMajorVersion Specifies the Microsoft Windows build type
|
||||
/// @param woMinorVersion Specifies the Windows build number of the target system
|
||||
/// @return None
|
||||
extern "C" __declspec(dllexport) VOID __stdcall WinDbgExtensionDllInit(
|
||||
_In_ PWINDBG_EXTENSION_APIS pWindbgExtensionApis,
|
||||
_In_ WORD woMajorVersion,
|
||||
_In_ WORD woMinorVersion
|
||||
);
|
||||
|
||||
/// @brief Returns version information about the extension DLL
|
||||
/// @param None
|
||||
/// @return Pointer to EXT_API_VERSION structure
|
||||
extern "C" __declspec(dllexport) LPEXT_API_VERSION __stdcall ExtensionApiVersion(
|
||||
VOID
|
||||
);
|
||||
|
||||
/// @brief Verifies that the extension module version matches the debugger version, and outputs a warning message if there is a mismatch
|
||||
/// @param None
|
||||
/// @return None
|
||||
extern "C" __declspec(dllexport) VOID __stdcall CheckVersion(
|
||||
VOID
|
||||
);
|
||||
|
||||
#pragma endregion
|
||||
@@ -0,0 +1,99 @@
|
||||
// ========================================================================
|
||||
// File: ReadInterruptDescriptorTable.h
|
||||
//
|
||||
// Author: winterknife
|
||||
//
|
||||
// Description: Header file for ReadInterruptDescriptorTable.cpp source file
|
||||
//
|
||||
// Modifications:
|
||||
// 2025-06-23 Created
|
||||
// 2025-06-28 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
// Pragmas
|
||||
// ========================================================================
|
||||
|
||||
#pragma once
|
||||
|
||||
// ========================================================================
|
||||
// Includes
|
||||
// ========================================================================
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
// ========================================================================
|
||||
// Structures/Enumerations/Unions
|
||||
// ========================================================================
|
||||
|
||||
#pragma region STRUCTS_ENUMS_UNIONS
|
||||
|
||||
// Interrupt Descriptor Table Register (IDTR)
|
||||
#pragma pack(push, 1)
|
||||
typedef struct _IDTR {
|
||||
WORD Limit;
|
||||
QWORD BaseAddress;
|
||||
} IDTR, *PIDTR;
|
||||
#pragma pack(pop)
|
||||
|
||||
// Interrupt/Trap Gate
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4201)
|
||||
#pragma pack(push, 1)
|
||||
typedef struct _INTERRUPT_TRAP_GATE_DESCRIPTOR {
|
||||
WORD OffsetLow; // bits 00 - 15
|
||||
WORD SegmentSelector; // bits 16 - 31
|
||||
struct {
|
||||
WORD IST : 3; // bits 32 - 34 (Interrupt Stack Table)
|
||||
WORD Reserved1 : 5; // bits 35 - 39 (0)
|
||||
WORD Type : 4; // bits 40 - 43
|
||||
WORD Reserved2 : 1; // bit 44 (0)
|
||||
WORD DPL : 2; // bits 45 - 46 (Descriptor Privilege Level)
|
||||
WORD P : 1; // bit 47 (Segment Present flag)
|
||||
};
|
||||
WORD OffsetMiddle; // bits 48 - 63
|
||||
DWORD OffsetHigh; // bits 64 - 95
|
||||
DWORD Reserved3; // bits 96 - 127 (0)
|
||||
} INTERRUPT_TRAP_GATE_DESCRIPTOR, *PINTERRUPT_TRAP_GATE_DESCRIPTOR;
|
||||
#pragma pack(pop)
|
||||
#pragma warning(pop)
|
||||
|
||||
#pragma endregion
|
||||
|
||||
// ========================================================================
|
||||
// C routine declarations
|
||||
// ========================================================================
|
||||
|
||||
#pragma region DECLARATIONS
|
||||
|
||||
/// @brief Built-in help command for the debugger extension DLL
|
||||
/// @param hCurrentProcess Handle for the current process
|
||||
/// @param hCurrentThread Handle for the current thread
|
||||
/// @param qwCurrentPc Program counter
|
||||
/// @param dwProcessor Current processor
|
||||
/// @param strArgs Command line arguments
|
||||
/// @return None
|
||||
extern "C" __declspec(dllexport) VOID __stdcall help(
|
||||
_In_ HANDLE hCurrentProcess,
|
||||
_In_ HANDLE hCurrentThread,
|
||||
_In_ QWORD qwCurrentPc,
|
||||
_In_ DWORD dwProcessor,
|
||||
_In_z_ PCSTR strArgs
|
||||
);
|
||||
|
||||
/// @brief Built-in command to read and parse the gate descriptors in the Interrupt Descriptor Table (IDT)
|
||||
/// @param hCurrentProcess Handle for the current process
|
||||
/// @param hCurrentThread Handle for the current thread
|
||||
/// @param qwCurrentPc Program counter
|
||||
/// @param dwProcessor Current processor
|
||||
/// @param strArgs Command line arguments
|
||||
/// @return None
|
||||
extern "C" __declspec(dllexport) VOID __stdcall read_idt(
|
||||
_In_ HANDLE hCurrentProcess,
|
||||
_In_ HANDLE hCurrentThread,
|
||||
_In_ QWORD qwCurrentPc,
|
||||
_In_ DWORD dwProcessor,
|
||||
_In_z_ PCSTR strArgs
|
||||
);
|
||||
|
||||
#pragma endregion
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{32175898-45c7-4c47-990e-ebb9da9d0992}</ProjectGuid>
|
||||
<RootNamespace>ReadIDTDbgExt</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>.\Bin\x64\</OutDir>
|
||||
<IntDir>.\Temp\x64\</IntDir>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<SuppressStartupBanner>false</SuppressStartupBanner>
|
||||
<AdditionalOptions>%(AdditionalOptions) /homeparams</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
<AdditionalDependencies>Shlwapi.lib</AdditionalDependencies>
|
||||
<AdditionalOptions>/EMITPOGOPHASEINFO /NOVCFEATURE /NOCOFFGRPINFO /FILEALIGN:0x200 /PDBALTPATH:$(ProjectName).pdb /Brepro /RELEASE /EMITTOOLVERSIONINFO:NO /NOIMPLIB /NOEXP %(AdditionalOptions)</AdditionalOptions>
|
||||
<ShowProgress>LinkVerbose</ShowProgress>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Src\DbgExt.cpp" />
|
||||
<ClCompile Include="Src\DllMain.cpp" />
|
||||
<ClCompile Include="Src\ReadInterruptDescriptorTable.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Inc\BaseDataTypes.h" />
|
||||
<ClInclude Include="Inc\Common.h" />
|
||||
<ClInclude Include="Inc\DbgExt.h" />
|
||||
<ClInclude Include="Inc\ReadInterruptDescriptorTable.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Src\DbgExt.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Src\DllMain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Src\ReadInterruptDescriptorTable.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Inc\BaseDataTypes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Inc\Common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Inc\DbgExt.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Inc\ReadInterruptDescriptorTable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,61 @@
|
||||
// ========================================================================
|
||||
// File: DbgExt.cpp
|
||||
//
|
||||
// Author: winterknife
|
||||
//
|
||||
// Description: Source file that contains the basic template for a
|
||||
// WdbgExts extension DLL
|
||||
//
|
||||
// Modifications:
|
||||
// 2024-10-08 Created
|
||||
// 2025-06-23 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
// Includes
|
||||
// ========================================================================
|
||||
|
||||
#include "../Inc/DbgExt.h"
|
||||
|
||||
// ========================================================================
|
||||
// Globals
|
||||
// ========================================================================
|
||||
|
||||
#pragma region GLOBALS
|
||||
|
||||
EXT_API_VERSION ApiVersion = { 10, 0, EXT_API_VERSION_NUMBER64, 0 };
|
||||
WINDBG_EXTENSION_APIS ExtensionApis;
|
||||
DWORD SavedMajorVersion;
|
||||
DWORD SavedMinorVersion;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
// ========================================================================
|
||||
// Routines
|
||||
// ========================================================================
|
||||
|
||||
#pragma region ROUTINES
|
||||
|
||||
VOID __stdcall WinDbgExtensionDllInit(
|
||||
_In_ PWINDBG_EXTENSION_APIS pWindbgExtensionApis,
|
||||
_In_ WORD woMajorVersion,
|
||||
_In_ WORD woMinorVersion
|
||||
) {
|
||||
ExtensionApis = *pWindbgExtensionApis;
|
||||
SavedMajorVersion = woMajorVersion;
|
||||
SavedMinorVersion = woMinorVersion;
|
||||
}
|
||||
|
||||
LPEXT_API_VERSION __stdcall ExtensionApiVersion(
|
||||
VOID
|
||||
) {
|
||||
return &ApiVersion;
|
||||
}
|
||||
|
||||
VOID __stdcall CheckVersion(
|
||||
VOID
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
@@ -0,0 +1,57 @@
|
||||
// ========================================================================
|
||||
// File: DllMain.cpp
|
||||
//
|
||||
// Author: winterknife
|
||||
//
|
||||
// Description: Source file that contains the DLL entry point
|
||||
//
|
||||
// Modifications:
|
||||
// 2024-10-08 Created
|
||||
// 2024-10-08 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
// Includes
|
||||
// ========================================================================
|
||||
|
||||
#include "../Inc/Common.h"
|
||||
|
||||
// ========================================================================
|
||||
// Routines
|
||||
// ========================================================================
|
||||
|
||||
#pragma region ROUTINES
|
||||
|
||||
#pragma CODE_BEGIN
|
||||
/// @brief DLL entry point
|
||||
/// @param hModule A handle to the DLL module
|
||||
/// @param dwReason The reason code that indicates why the DLL entry-point function is being called
|
||||
/// @param dwReserved Reserved
|
||||
/// @return TRUE if DLL initialization succeeds or FALSE if it fails
|
||||
extern "C" __declspec(noinline) BOOLEAN __stdcall DllInit(
|
||||
_In_ HMODULE hModule,
|
||||
_In_ DWORD dwReason,
|
||||
_In_opt_ DWORD dwReserved
|
||||
) {
|
||||
UNREFERENCED_PARAMETER(hModule);
|
||||
UNREFERENCED_PARAMETER(dwReserved);
|
||||
|
||||
switch (dwReason) {
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_ATTACH:
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#pragma CODE_END
|
||||
|
||||
#pragma endregion
|
||||
@@ -0,0 +1,206 @@
|
||||
// ========================================================================
|
||||
// File: ReadInterruptDescriptorTable.cpp
|
||||
//
|
||||
// Author: winterknife
|
||||
//
|
||||
// Description: Source file that contains the necessary routines to read and
|
||||
// parse all the gate descriptors in the Interrupt Descriptor Table (IDT)
|
||||
//
|
||||
// Modifications:
|
||||
// 2025-06-23 Created
|
||||
// 2025-06-29 Updated
|
||||
// ========================================================================
|
||||
|
||||
// ========================================================================
|
||||
// Includes
|
||||
// ========================================================================
|
||||
|
||||
#include "../Inc/ReadInterruptDescriptorTable.h"
|
||||
#include "../Inc/DbgExt.h"
|
||||
#include <Shlwapi.h>
|
||||
|
||||
// ========================================================================
|
||||
// Routines
|
||||
// ========================================================================
|
||||
|
||||
#pragma region ROUTINES
|
||||
|
||||
_Use_decl_annotations_
|
||||
VOID __stdcall help(
|
||||
HANDLE hCurrentProcess,
|
||||
HANDLE hCurrentThread,
|
||||
QWORD qwCurrentPc,
|
||||
DWORD dwProcessor,
|
||||
PCSTR strArgs
|
||||
) {
|
||||
UNREFERENCED_PARAMETER(hCurrentProcess);
|
||||
UNREFERENCED_PARAMETER(hCurrentThread);
|
||||
UNREFERENCED_PARAMETER(qwCurrentPc);
|
||||
UNREFERENCED_PARAMETER(dwProcessor);
|
||||
UNREFERENCED_PARAMETER(strArgs);
|
||||
|
||||
dprintf(
|
||||
"Help for debugger extension DLL ReadIDTDbgExt.dll\n"
|
||||
" help - Show help menu\n"
|
||||
" read_idt - Read and parse the gate descriptors in the Interrupt Descriptor Table (IDT)\n"
|
||||
);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
VOID __stdcall read_idt(
|
||||
HANDLE hCurrentProcess,
|
||||
HANDLE hCurrentThread,
|
||||
QWORD qwCurrentPc,
|
||||
DWORD dwProcessor,
|
||||
PCSTR strArgs
|
||||
) {
|
||||
UNREFERENCED_PARAMETER(hCurrentProcess);
|
||||
UNREFERENCED_PARAMETER(hCurrentThread);
|
||||
UNREFERENCED_PARAMETER(qwCurrentPc);
|
||||
UNREFERENCED_PARAMETER(strArgs);
|
||||
|
||||
// Reload symbols
|
||||
ReloadSymbols(NULL);
|
||||
|
||||
dprintf("[!] Current processor number = %d\n", dwProcessor);
|
||||
|
||||
// Init local variables
|
||||
QWORD qwIdtBaseKva = 0;
|
||||
QWORD qwIdtLimit = 0;
|
||||
QWORD qwKpcrKva = 0;
|
||||
QWORD qwKprcbKva = 0;
|
||||
DWORD dwKinterruptTableBaseOffset = 0;
|
||||
QWORD qwKinterruptTableBaseKva = 0;
|
||||
DWORD dwIndex = 0;
|
||||
INTERRUPT_TRAP_GATE_DESCRIPTOR interruptTrapGateDescriptor; ZERO_MEMORY(&interruptTrapGateDescriptor, sizeof(INTERRUPT_TRAP_GATE_DESCRIPTOR));
|
||||
QWORD qwInterruptHandlerKva = 0;
|
||||
QWORD qwKinterruptKva = 0;
|
||||
CHAR charrSymbolName[MAX_PATH]; ZERO_MEMORY(&charrSymbolName, sizeof(charrSymbolName));
|
||||
DWORD_PTR dwptrDisplacement = 0;
|
||||
CHAR charrBuffer[MAX_PATH]; ZERO_MEMORY(&charrBuffer, sizeof(charrBuffer));
|
||||
|
||||
// Determine if the target uses 64-bit pointers
|
||||
if (!IsPtr64()) {
|
||||
dprintf("[-] IA-32 target is not supported by this extension!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Read IDT Base Address
|
||||
if (!GetExpressionEx("@idtr", &qwIdtBaseKva, NULL)) {
|
||||
dprintf("[-] Error evaluating MASM expression!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
dprintf("[+] IDT Base Address=0x%I64X\n", qwIdtBaseKva);
|
||||
|
||||
// Read IDT Limit
|
||||
if (!GetExpressionEx("@idtl", &qwIdtLimit, NULL)) {
|
||||
dprintf("[-] Error evaluating MASM expression!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
dprintf("[+] IDT Limit=0x%X\n", qwIdtLimit);
|
||||
|
||||
// Get Kernel Processor Control Region (KPCR) KVA
|
||||
if (!GetExpressionEx("@$pcr", &qwKpcrKva, NULL)) {
|
||||
dprintf("[-] Error evaluating MASM expression!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
dprintf("[+] nt!_KPCR KVA=0x%I64X\n", qwKpcrKva);
|
||||
|
||||
// Get Kernel Processor Control Block (KPRCB) KVA
|
||||
if (!ReadPointer((qwKpcrKva + 0x20), &qwKprcbKva)) {
|
||||
dprintf("[-] Error reading pointer!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
dprintf("[+] nt!_KPRCB KVA=0x%I64X\n", qwKprcbKva);
|
||||
|
||||
// Get interrupt object table base offset
|
||||
// WinDbg command: dt nt!_KPRCB InterruptObject
|
||||
if (GetFieldOffset("nt!_KPRCB", "InterruptObject", &dwKinterruptTableBaseOffset)) {
|
||||
dprintf("[-] Error getting structure offset!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Get interrupt object table base KVA
|
||||
qwKinterruptTableBaseKva = qwKprcbKva + dwKinterruptTableBaseOffset;
|
||||
dprintf("[+] nt!_KPRCB.InterruptObject[0] KVA=0x%I64X\n", qwKinterruptTableBaseKva);
|
||||
|
||||
// The Interrupt Descriptor Table (IDT) associates each exception or interrupt vector with a gate descriptor for the procedure used to service the associated exception or interrupt
|
||||
// The IDT is an array of 16-byte descriptors (in IA-32e mode)
|
||||
// There are only 256 interrupt or exception vectors so the IDT should contain a maximum of 256 descriptors
|
||||
// The IDT lies in the KVAS
|
||||
// In IA-32e mode, there can be two types of entries in the IDT: interrupt gate descriptor and trap gate descriptor
|
||||
// When an exception/interrupt is handled through an interrupt gate, the EFLAGS.IF flag is automatically cleared, which disables maskable hardware interrupts
|
||||
// If an exception/interrupt is handled through a trap gate, the EFLAGS.IF flag is not cleared
|
||||
// Vector numbers in the range 0 through 31 are reserved by the Intel 64 and IA-32 architectures for architecture-defined exceptions and interrupts
|
||||
// Vector numbers in the range 32 to 255 are designated as user-defined interrupts and are not reserved by the Intel 64 and IA-32 architecture
|
||||
for (dwIndex = 0; dwIndex < 256; dwIndex++) {
|
||||
if (!ReadMemory((qwIdtBaseKva + (dwIndex * sizeof(INTERRUPT_TRAP_GATE_DESCRIPTOR))), &interruptTrapGateDescriptor, sizeof(INTERRUPT_TRAP_GATE_DESCRIPTOR), NULL)) {
|
||||
dprintf("[-] Error reading virtual memory!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Check for empty descriptor slots
|
||||
// All empty descriptor slots in the IDT should have the present flag for the descriptor set to 0
|
||||
if (interruptTrapGateDescriptor.P == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the address of the entry point of the Interrupt Service Routine (ISR)
|
||||
qwInterruptHandlerKva = __ll_lshift(interruptTrapGateDescriptor.OffsetHigh, 32) + __ll_lshift(interruptTrapGateDescriptor.OffsetMiddle, 16) + interruptTrapGateDescriptor.OffsetLow;
|
||||
|
||||
// Get the interrupt object corresponding to the interrupt vector from the array of interrupt object pointers
|
||||
if (!ReadPointer((qwKinterruptTableBaseKva + (dwIndex * sizeof(PVOID))), &qwKinterruptKva)) {
|
||||
dprintf("[-] Error reading pointer!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Get the ISR KVA from the interrupt object
|
||||
if (qwKinterruptKva) {
|
||||
if (!ReadPointer((qwKinterruptKva + 0x20), &qwInterruptHandlerKva)) {
|
||||
dprintf("[-] Error reading pointer!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!qwInterruptHandlerKva) {
|
||||
if (!ReadPointer((qwKinterruptKva + 0x18), &qwInterruptHandlerKva)) {
|
||||
dprintf("[-] Error reading pointer!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the symbol name
|
||||
GetSymbol(qwInterruptHandlerKva, charrSymbolName, &dwptrDisplacement);
|
||||
wnsprintfA(charrBuffer, MAX_PATH, "%s+0x%X", charrSymbolName, (WORD)dwptrDisplacement);
|
||||
|
||||
// Display IDT gate descriptor
|
||||
dprintf("----------------------------------------------------------------------\n");
|
||||
|
||||
dprintf("[+] Vector Number: 0x%X (0n%d)\n", dwIndex, dwIndex);
|
||||
|
||||
if (interruptTrapGateDescriptor.Type == 14)
|
||||
dprintf("[+] Type: Interrupt Gate\n");
|
||||
else if (interruptTrapGateDescriptor.Type == 15)
|
||||
dprintf("[+] Type: Trap Gate\n");
|
||||
|
||||
dprintf("[+] Segment Selector=0x%X\n", interruptTrapGateDescriptor.SegmentSelector);
|
||||
|
||||
if (dwptrDisplacement)
|
||||
dprintf("[+] ISR KVA=0x%I64X (%s)\n", qwInterruptHandlerKva, charrBuffer);
|
||||
else
|
||||
dprintf("[+] ISR KVA=0x%I64X (%s)\n", qwInterruptHandlerKva, charrSymbolName);
|
||||
|
||||
if (interruptTrapGateDescriptor.IST)
|
||||
dprintf("[+] IST=0x%X\n", interruptTrapGateDescriptor.IST);
|
||||
|
||||
dprintf("[+] DPL=0x%X\n", interruptTrapGateDescriptor.DPL);
|
||||
|
||||
dprintf("----------------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
cleanup:
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
Reference in New Issue
Block a user