Skip to content

Commit

Permalink
Parse extension host callbacks on 24h2 and 25h2
Browse files Browse the repository at this point in the history
  • Loading branch information
yardenshafir committed Apr 8, 2024
1 parent 5191941 commit 7ed5308
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 22 deletions.
1 change: 1 addition & 0 deletions Source/Shared/ntos/ntbuilds.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,4 @@
// Windows 11 Active Development Branch
#define NT_WIN11_DEV 23615 //dev
#define NT_WIN11_24H2 26020 //canary (24H2)
#define NT_WIN11_25H2 26080 //canary (25H2)
47 changes: 41 additions & 6 deletions Source/Shared/ntos/ntos.h
Original file line number Diff line number Diff line change
Expand Up @@ -5238,32 +5238,67 @@ typedef VOID(NTAPI* PEX_HOST_NOTIFICATION) (
_In_ ULONG NotificationType,
_In_opt_ PVOID Context);

typedef struct _EX_EXTENSION_INFORMATION {
typedef struct _EX_EXTENSION_INFORMATION_V1 {
USHORT Id;
USHORT Version;
USHORT FunctionCount;
} EX_EXTENSION_INFORMATION, * PEX_EXTENSION_INFORMATION;
} EX_EXTENSION_INFORMATION_V1, * PEX_EXTENSION_INFORMATION_V1;

typedef struct _EX_EXTENSION_VERSION {
USHORT MajorVersion;
USHORT MinorVersion;
} EX_EXTENSION_VERSION, * PEX_EXTENSION_VERSION;

typedef struct _EX_EXTENSION_INFORMATION_V2 {
USHORT Id;
EX_EXTENSION_VERSION Version;
USHORT FunctionCount;
} EX_EXTENSION_INFORMATION_V2, * PEX_EXTENSION_INFORMATION_V2;

typedef struct _EX_HOST_TABLE {
EX_EXTENSION_INFORMATION_V2 HostInformation;
PVOID FunctionTable; //calbacks
} EX_HOST_TABLE, * PEX_HOST_TABLE;

typedef struct _EX_HOST_PARAMS {
EX_EXTENSION_INFORMATION HostInformation;
EX_EXTENSION_INFORMATION_V1 HostInformation;
POOL_TYPE PoolType;
PVOID HostTable;
PVOID NotificationRoutine;
PVOID NotificationContext;
} EX_HOST_PARAMS, * PEX_HOST_PARAMS;

typedef struct _EX_HOST_ENTRY {
typedef struct _EX_HOST_ENTRY_V1 {
LIST_ENTRY ListEntry;
LONG RefCounter;
EX_HOST_PARAMS HostParameters;
EX_RUNDOWN_REF RundownProtection;
EX_PUSH_LOCK PushLock;
PVOID FunctionTable; //callbacks
ULONG Flags;
} EX_HOST_ENTRY, * PEX_HOST_ENTRY;
} EX_HOST_ENTRY_V1, * PEX_HOST_ENTRY_V1;

typedef struct _EX_HOST_ENTRY_V2 {
LIST_ENTRY ListEntry;
EX_EXTENSION_INFORMATION_V2 HostInformation;
ULONG64 RefCounter;
EX_PUSH_LOCK PushLock;
PEX_HOST_TABLE HostTablesPtr;
USHORT HostTablesCount;
PEX_HOST_TABLE CurrentHostTableEntry; //only set when an extension registers
PVOID NotificationRoutine;
PVOID NotificationContext;
EX_EXTENSION_VERSION ExtensionVersion;
EX_RUNDOWN_REF RundownProtection;
PVOID FunctionTable;
USHORT ExtensionTableFunctionCount;
ULONG Pad;
ULONG Flags;
EX_HOST_TABLE HostTables[1];
} EX_HOST_ENTRY_V2, * PEX_HOST_ENTRY_V2;

typedef struct _EX_EXTENSION_REGISTRATION {
EX_EXTENSION_INFORMATION Information;
EX_EXTENSION_INFORMATION_V1 Information;
PVOID FunctionTable;
PVOID* HostTable;
PDRIVER_OBJECT DriverObject;
Expand Down
104 changes: 88 additions & 16 deletions Source/WinObjEx64/extras/extrasCallbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -2527,11 +2527,21 @@ OBEX_FINDCALLBACK_ROUTINE(FindExHostCallbacks)
ULONG_PTR kvarAddress = 0;
PBYTE ptrCode;
LONG Rel = 0;
ULONG Index, c;
ULONG Index, c, callIndex;
hde64s hs;

UNREFERENCED_PARAMETER(QueryFlags);

// another call was added in 24H2 to ExfAcquirePushLockSharedEx
if (g_NtBuildNumber > NT_WIN11_23H2)
{
callIndex = 2;
}
else
{
callIndex = 1;
}

if (kdIsSymAvailable((PSYMCONTEXT)g_kdctx.NtOsSymContext)) {

kdGetAddressFromSymbol(&g_kdctx,
Expand All @@ -2552,7 +2562,7 @@ OBEX_FINDCALLBACK_ROUTINE(FindExHostCallbacks)
Index = 0;

//
// Find ExpFindHost
// Find ExpFindHost / ExpFindCompatibleHost
//

do {
Expand All @@ -2572,14 +2582,48 @@ OBEX_FINDCALLBACK_ROUTINE(FindExHostCallbacks)
if (ptrCode[Index] == 0xE8)
c++;

if (c > 1) {
if (c > callIndex) {
Rel = *(PLONG)(ptrCode + Index + 1);
break;
}

Index += hs.len;

} while (Index < 256);
} while (Index < 512);

//
// If this is 25H2, the call is to ExpFindCompatibleHost
// Need to do another search to find the call to ExpFindHost
//
if (g_NtBuildNumber >= NT_WIN11_25H2)
{
ptrCode = ptrCode + Index + 5 + Rel;
Rel = 0;
Index = 0;
do {

hde64_disasm(ptrCode + Index, &hs);
if (hs.flags & F_ERROR)
break;

//
// Find call instruction.
//
if (hs.len != 5) {
Index += hs.len;
continue;
}

if (ptrCode[Index] == 0xE8)
{
Rel = *(PLONG)(ptrCode + Index + 1);
break;
}

Index += hs.len;

} while (Index < 128);
}

if (Rel == 0)
return 0;
Expand Down Expand Up @@ -4717,14 +4761,31 @@ OBEX_DISPLAYCALLBACK_ROUTINE(DumpExHostCallbacks)
{
LIST_ENTRY ListEntry;

EX_HOST_ENTRY HostEntry;
EX_HOST_ENTRY_V1 HostEntryV1;
EX_HOST_ENTRY_V2 HostEntryV2;
PVOID HostEntry;
ULONG HostEntrySize;

ULONG_PTR ListHead = KernelVariableAddress;
ULONG_PTR* HostTableDump;
ULONG NumberOfCallbacks, i;
PVOID NotificationRoutine;
PVOID FunctionTable;

HTREEITEM RootItem;

// Starting build 26080 (25H2) the structures were updated
if (g_NtBuildNumber < NT_WIN11_25H2)
{
HostEntrySize = sizeof(HostEntryV1);
HostEntry = &HostEntryV1;
}
else
{
HostEntrySize = sizeof(HostEntryV2);
HostEntry = &HostEntryV2;
}

//
// Add callback root entry to the treelist.
//
Expand All @@ -4749,27 +4810,38 @@ OBEX_DISPLAYCALLBACK_ROUTINE(DumpExHostCallbacks)
// Walk list entries.
//
while ((ULONG_PTR)ListEntry.Flink != ListHead) {

RtlSecureZeroMemory(&HostEntry, sizeof(HostEntry));
RtlSecureZeroMemory(HostEntry, HostEntrySize);

if (!kdReadSystemMemory((ULONG_PTR)ListEntry.Flink,
&HostEntry,
sizeof(HostEntry)))
HostEntry,
HostEntrySize))
{
break;
}

// read extension function table
if (g_NtBuildNumber < NT_WIN11_25H2)
{
NumberOfCallbacks = HostEntryV1.HostParameters.HostInformation.FunctionCount;
NotificationRoutine = HostEntryV1.HostParameters.NotificationRoutine;
FunctionTable = HostEntryV1.FunctionTable;
}
else
{
NumberOfCallbacks = HostEntryV2.ExtensionTableFunctionCount;
NotificationRoutine = HostEntryV2.NotificationRoutine;
FunctionTable = HostEntryV2.FunctionTable;
}

//
// Find not an empty host table.
//
NumberOfCallbacks = HostEntry.HostParameters.HostInformation.FunctionCount;

if (NumberOfCallbacks) {

if (HostEntry.HostParameters.NotificationRoutine) {
if (NotificationRoutine) {
AddEntryToList(TreeList,
RootItem,
(ULONG_PTR)HostEntry.HostParameters.NotificationRoutine,
(ULONG_PTR)NotificationRoutine,
L"NotificationRoutine",
Modules);

Expand All @@ -4778,12 +4850,12 @@ OBEX_DISPLAYCALLBACK_ROUTINE(DumpExHostCallbacks)
//
// Read function table.
//
if (HostEntry.FunctionTable) {
if (FunctionTable) {
HostTableDump = (ULONG_PTR*)supHeapAlloc(NumberOfCallbacks * sizeof(PVOID));
if (HostTableDump) {

if (kdReadSystemMemory(
(ULONG_PTR)HostEntry.FunctionTable,
(ULONG_PTR)FunctionTable,
HostTableDump,
NumberOfCallbacks * sizeof(PVOID)))
{
Expand All @@ -4805,7 +4877,7 @@ OBEX_DISPLAYCALLBACK_ROUTINE(DumpExHostCallbacks)
}
}

ListEntry.Flink = HostEntry.ListEntry.Flink;
ListEntry.Flink = ((LIST_ENTRY*)(HostEntry))->Flink;
}
}

Expand Down

0 comments on commit 7ed5308

Please sign in to comment.