Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse extension host callbacks on 24h2 and 25h2 #36

Merged
merged 1 commit into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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