- Security
- A
Analysis of CVE-2025-27736 vulnerability in Power Dependency Coordinator
This article is dedicated to the bug in Power Dependency Coordinator, patched by Microsoft in April of this year.
Exposure of sensitive information to an unauthorized actor in Windows Power Dependency Coordinator allows an authorized attacker to disclose information locally.
https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-27736
Exploiting this vulnerability could allow the disclosure of certain memory address within kernel space. Knowing the exact location of kernel memory could be potentially leveraged by an attacker for other malicious activities.
In the context of Windows 11 24H2 changes with the restriction of NtQuerySystemInformation for determining object addresses, bugs like this become even more relevant, which is why I was interested in looking at an example of such a vulnerability.
Tools required include IDA Pro, BinDiff, WinDbg, for testing - Windows 11 or Windows 10 x64 with updates until April 2025 (for testing PoC functionality) and up-to-date updates (for testing PoC after updates).
What is Power Dependency Coordinator?
Power Dependency Coordinator (pdc.sys) is related to power management and allows devices to quickly exit sleep mode. It was introduced in Windows 8.0.
There is not much said about this driver, for example, in the Internal Architecture of Windows, there is a useful mention of this component in the chapter dedicated to ALPC. It states that pdc.sys registers a callback to communicate with clients via ALPC, which we will later observe when reversing the driver.
Patch Analysis
As already mentioned, Power Dependency Coordinator is the driver pdc.sys
Download two versions of the driver from
and proceed with patch analysis.
You need to download the pdc.sys version before April 2025 and the April version.
After comparing with BinDiff, it is clear that not many functions are changed, and they are mostly related to activation.
There are 7 changed functions in total.
PdcpV2SendCallbackMessage
PdcpV2Deactivation
PdcpV2Renew
PdcpV2Activation
PdcpCompleteResiliencyOperation
PdcpCreateActivationInstance
PdcActivatorInitialize
The article will use the terms "activation" and "resiliency". Here I am focusing on the function names within pdc and its structures that are important for analysis. For example, PdcpV2Activation contains "Activation" in its name, so this function is related to activation. PdcpV2Renew also implies it relates to activation, as it is called from the function PdcV2ActivatorReceive.
If you look at where the functions PdcpV2Activation, PdcpV2Renew, PdcpV2Deactivation are called, you will quickly find the function PdcProcessMessage, which is called from PdcpAlpcProcessMessages, and PdcpAlpcProcessMessages, in turn, from PdcMessageCallback. Other changed functions are also reachable through PdcMessageCallback.
PdcMessageCallback is a callback set by ALPC port via ZwAlpcSetInformation. From preliminary patch analysis, it is clear that we need to work with ALPC to call the relevant functions. Therefore, below is the minimum required information about ALPC and its use in PDC.
What is ALPC?
ALPC (Advanced Local Procedure Call) is an inter-process communication (IPC) mechanism. It is one of the basic mechanisms in Windows, and many system components use ALPC for communication (e.g., local RPC, csrss, lsass, and others).
In general, ALPC is an undocumented mechanism, and Microsoft does not expect its direct use or provide high-level APIs, so it requires the use of functions from ntdll.
The basic concepts of ALPC necessary for understanding this article are as follows:
ALPC port is a Windows kernel object (like a process, thread, event). ALPC is based on the client-server principle. The server creates an ALPC port, and clients can connect to this port to exchange messages. The ALPC port is created by the function NtAlpcCreatePort, and the client connects to the port via NtAlpcConnectPort.
The server can accept or reject a connection request from the client using the NtAlpcAcceptConnectPort function.ALPC ports are divided into three types. The first one is the Connection Port, which is created by the server (NtAlpcCreatePort), and clients connect to it. Upon connecting a client to the server (NtAlpcConnectPort), two additional ports are created: the Server Communication Port and the Client Communication Port for the server and client, respectively.
ALPC message. A message in a special format used for data exchange between the ALPC client and server. Messages are sent and received by the NtAlpcSendWaitReceivePort function. ALPC messages must start with the _PORT_MESSAGE structure.
In the screenshot below, open ALPC ports for the lsass process are shown
In general, there has been quite a bit written about ALPC, so there is no need to repeat it. Those interested can refer to the sources below
Windows Internal Architecture. Key Components and Capabilities. 7th edition (second part) - Advanced Local Procedure Call
SyScan'14 Singapore: All About The Rpc, Lrpc, Alpc, And Lpc In Your Pc By Alex Ionescu
Communication with Power Dependency Coordinator Clients
The Power Dependency Coordinator creates an ALPC port \PdcPort for communication with clients.
In WinDbg, you can view information about \PdcPort and display information about connected clients. First, you need to find the object address using the !object command, and then display ALPC-specific information with the !alpc command
0: kd> !object \PdcPort
Object: ffffd783a9115cc0 Type: (ffffd783a57f44f0) ALPC Port
ObjectHeader: ffffd783a9115c90 (new version)
HandleCount: 1 PointerCount: 32606
Directory Object: ffffc48cd0206bb0 Name: PdcPort
0: kd> !alpc /p ffffd783a9115cc0
Port ffffd783a9115cc0
Type : ALPC_CONNECTION_PORT
CommunicationInfo : ffffc48cd05e41b0
ConnectionPort : ffffd783a9115cc0 (PdcPort), Connections
ClientCommunicationPort : 0000000000000000
ServerCommunicationPort : 0000000000000000
OwnerProcess : ffffd783a56d5040 (System), Connections
SequenceNo : 0x00000020 (32)
CompletionPort : 0000000000000000
CompletionList : 0000000000000000
ConnectionPending : No
ConnectionRefused : No
Disconnected : No
Closed : No
FlushOnClose : Yes
ReturnExtendedInfo : No
Waitable : No
Security : Static
Wow64CompletionList : No
Main queue is empty.
Direct message queue is empty.
Large message queue is empty.
Pending queue is empty.
Canceled queue is empty.
0: kd> !alpc /lpc ffffd783a9115cc0
ffffd783a9115cc0('PdcPort') 0, 30 connections
ffffd783aa17f790 0 ->ffffd783aa17f9f0 0 ffffd783aa0020c0('svchost.exe')
ffffd783aa2d0070 0 ->ffffd783aa2d02d0 0 ffffd783aa0020c0('svchost.exe')
ffffd783aa2cf9a0 0 ->ffffd783aa2cfc00 0 ffffd783aa0020c0('svchost.exe')
ffffd783aa2cdd60 0 ->ffffd783aa2cf740 0 ffffd783aa0020c0('svchost.exe')
ffffd783aa2bbd80 0 ->ffffd783aa2cdb00 0 ffffd783aa0020c0('svchost.exe')
ffffd783a9768070 0 ->ffffd783a97682d0 0 ffffd783aa0020c0('svchost.exe')
ffffd783aa185070 0 ->ffffd783aa1852d0 0 ffffd783aa0020c0('svchost.exe')
ffffd783a5849790 0 ->ffffd783a58499f0 0 ffffd783aa4bb080('svchost.exe')
ffffd783a574c530 0 ->ffffd783a575c070 0 ffffd783aa4bb080('svchost.exe')
ffffd783aa7139f0 0 ->ffffd783a57d19f0 0 ffffd783aa65a080('svchost.exe')
ffffd783aa8b4dd0 0 ->ffffd783aa8b5dd0 0 ffffd783aa7d6080('svchost.exe')
ffffd783a9f4ede0 0 ->ffffd783aa735de0 0 ffffd783aa7d6080('svchost.exe')
ffffd783aa8ec9f0 0 ->ffffd783aa8ed9f0 0 ffffd783aa7d6080('svchost.exe')
ffffd783aa9e7070 0 ->ffffd783aa9e72d0 0 ffffd783aa8df080('svchost.exe')
ffffd783aa9e6530 0 ->ffffd783aa9e6790 0 ffffd783aa8df080('svchost.exe')
ffffd783aaa3cd60 0 ->ffffd783aaa3db00 0 ffffd783aaa19080('svchost.exe')
ffffd783aaa3ad60 0 ->ffffd783aaa3bb00 0 ffffd783aaa19080('svchost.exe')
ffffd783aaab22d0 0 ->ffffd783aaab2530 0 ffffd783aaaa0080('svchost.exe')
ffffd783aaab1c00 0 ->ffffd783aaab2070 0 ffffd783aaaa0080('svchost.exe')
ffffd783aaab1740 0 ->ffffd783aaab19a0 0 ffffd783aaaa0080('svchost.exe')
ffffd783ac1ee9f0 0 ->ffffd783ac1eec50 0 ffffd783aad4d080('svchost.exe')
ffffd783aac8b2d0 0 ->ffffd783aac8b530 0 ffffd783aad540c0('svchost.exe')
ffffd783ac7149f0 0 ->ffffd783ac714c50 0 ffffd783ac564080('svchost.exe')
ffffd783acb64070 0 ->ffffd783acb642d0 0 ffffd783acaf7080('svchost.exe')
ffffd783acb639f0 0 ->ffffd783acb63c50 0 ffffd783aad73080('MsMpEng.exe')
ffffd783acb5f530 0 ->ffffd783acb5f790 0 ffffd783ac7f0080('explorer.exe')
ffffd783acdb7b60 0 ->ffffd783acdb7dc0 0 ffffd783aae31080('svchost.exe')
ffffd783aca0b2d0 0 ->ffffd783aabd97d0 0 ffffd783ace5d080('msedge.exe')
ffffd783ad5c42d0 0 ->ffffd783ad5c4070 0 ffffd783aa654080('svchost.exe')
ffffd783ad80f070 0 ->ffffd783ad80f2d0 0 ffffd783a9f59080('svchost.exe')
Command !alpc /lpc for Connection Port shows the clients connected to the port.
As seen, \PdcPort is actively used in the system, with connected clients including svchost, msedge, and explorer.
Now let's look at the message format expected by pdc.sys. Since communication happens via ALPC, the message header will contain _PORT_MESSAGE, followed by pdc-specific data. The pdc message has a common header up to offset 0x38 in the _PDC_MESSAGE structure, followed by data specific to each message.
1: kd> dt pdc!_PDC_MESSAGE
+0x000 Alpc : _PORT_MESSAGE
+0x028 Type : Uint4B
+0x028 MessageType : PDC_MESSAGE_TYPE
+0x02c ClientVersion : _PDC_CLIENT_VERSION
+0x02c Reserved : [2] Uint4B
+0x038 Register : _PDC_MSG_REGISTRATION
+0x038 Resiliency : _PDC_MSG_RESILIENCY
+0x038 Notification : _PDC_MSG_NOTIFICATION
+0x038 Activation : _PDC_MSG_ACTIVATION
+0x038 ActivationV2 : _PDC_MSG_ACTIVATION_V2
+0x038 ActivationRenewalV2 : _PDC_MSG_ACTIVATION_RENEWAL_V2
+0x038 ActivatorCallbackV2 : _PDC_MSG_ACTIVATOR_CALLBACK_V2
+0x038 DeactivationV2 : _PDC_MSG_ACTIVATION_DEACTIVATE_V2
+0x038 ActivatorCallbackV1 : _PDC_MSG_ACTIVATOR_CALLBACK_V1
+0x038 SuspendResume : _PDC_MSG_SUSPENDRESUME
+0x038 Task : _PDC_MSG_TASK
+0x038 SignalChange : _PDC_SIGNAL_CHANGE
+0x038 ProfileUpdate : _PDC_MSG_PPM_PROFILE_UPDATE
+0x038 SleepstudyHelperMessage : _PDC_SLEEPSTUDY_HELPER_MESSAGE
pdc has several message types, and we will be interested in just a few of them – related to client registration, activation, and resiliency. This article will focus on the first two types. The message type is determined by the MessageType field. For registration, the message type should be set to PdcRegisterMessage, and for activation - Pdcv2ActivationMessage.
0: kd> dt PDC_MESSAGE_TYPE
PdcRegisterMessage = 0n0
PdcUnregisterMessage = 0n1
PdcNotificationMessage = 0n2
PdcControlMessage = 0n3
PdcActivationMessage = 0n4
PdcResiliencyMessage = 0n5
PdcSuspendResumeMessage = 0n6
PdcTaskMessage = 0n7
PdcSignalChangeMessage = 0n8
PdcPpmProfileMessage = 0n9
Pdcv2ActivationMessage = 0n10
Pdcv2ActivationRenewalMessage = 0n11
Pdcv2ActivationCallbackMessage = 0n12
Pdcv2DeactivationMessage = 0n13
Pdcv1ActivationCallbackMessage = 0n14
PdcSleepstudyHelperMessage = 0n15
When the client connects to the pdc function NtAlpcConnectPort, it must send a registration message (_PDC_MSG_REGISTRATION), which will contain information about the connecting client. The pdc will check the validity of this client's connection in several stages. If the registration message fails validation, the pdc rejects the connection. If the registration message is correct and the server accepts the connection, messages of other types can then be sent.
pdc!_PDC_MSG_REGISTRATION
+0x000 ClientId : Uint4B
+0x004 ClientType : PDC_CLIENT_TYPE
+0x008 TriageContext : Uint8B
+0x010 ClientTypeData :
+0x0bc ModuleName : [64] Wchar
Let us take a closer look at the process of validating the registration message.
Here, the important field is ClientId. The pdc has predefined (static) client types, and the message must specify a valid client type. The static client types are defined in pdc.sys (array pdc!PdcClientInfo).
In general, the maximum number of clients on Windows 10 is 0x73, and on Windows 11 it is 0x7C.
If we analyze the interaction with the PdcClientInfo array and its contents, we will see that the clients are named and have flags. In some cases, flags may be important, for example, if the flag 0x200 is set, the client must be kernel-mode (the message must be sent from kernel mode).
You can gather a list of clients along with their flags using this script for IDA Pro.
Script output (for convenience, the output indicates whether the client is kernel-mode or user-mode)
ClientIndex 0x0: flags 0 (UserMode) Client name "Invalid client"
ClientIndex 0x1: flags 6003 (UserMode) Client name "PLM"
ClientIndex 0x2: flags C4 (UserMode) Client name "NQM"
ClientIndex 0x3: flags 3 (UserMode) Client name "WNS"
ClientIndex 0x4: flags 246 (KernelMode) Client name "DAM"
ClientIndex 0x5: flags C4 (UserMode) Client name "WCM"
ClientIndex 0x6: flags 0 (UserMode) Client name "6"
ClientIndex 0x7: flags C3 (UserMode) Client name "NCSI"
ClientIndex 0x8: flags 1 (UserMode) Client name "DHCP"
ClientIndex 0x9: flags 341 (KernelMode) Client name "TCPIP"
...
ClientIndex 0x1E: flags 82 (UserMode) Client name "Test network service client"
ClientIndex 0x1F: flags 102 (UserMode) Client name "Test system service client"
ClientIndex 0x20: flags 7 (UserMode) Client name "Test client"
ClientIndex 0x21: flags 7 (UserMode) Client name "Test client"
ClientIndex 0x22: flags 42 (UserMode) Client name "Shell"
ClientIndex 0x23: flags 111 (UserMode) Client name "Maintenance Scheduler"
ClientIndex 0x24: flags 10 (UserMode) Client name "Sync Client"
ClientIndex 0x25: flags 1 (UserMode) Client name "Image Download Manager"
ClientIndex 0x26: flags 26041 (UserMode) Client name "Cortana Voice Activation"
...
ClientIndex 0x4A: flags 343 (KernelMode) Client name "Xbox System VM Quiescence Client"
ClientIndex 0x4B: flags 244 (KernelMode) Client name "Xbox Host VM Quiescence Client"
ClientIndex 0x4C: flags 41 (UserMode) Client name "Print Job Manager"
ClientIndex 0x4D: flags 41 (UserMode) Client name "Universal Telemetry Client"
ClientIndex 0x4E: flags 41 (UserMode) Client name "Windows Error Reporting"
…
ClientIndex 0x70: flags 80000 (UserMode) Client name "PDC User Mode Sleepstudy Helper Library Client"
ClientIndex 0x71: flags 80200 (KernelMode) Client name "PDC Kernel Mode Sleepstudy Helper Library Client"
ClientIndex 0x72: flags 142 (UserMode) Client name "Container Manager user mode notification client"
For the pdc to accept a connection from the client, the registration message must pass several checks. First, pdc!PdcSanitizeClientMessage will check the message size (0x300 or 0x320 is allowed) and ClientVersion.
Possible values for ClientVersion
0: kd> dt pdc!_PDC_CLIENT_VERSION
PdcClientVersionInvalid = 0n0
PdcClientVersionRs1 = 0n1
PdcClientVersionRs3 = 0n2
PdcClientVersionRs4 = 0n3
PdcClientVersionRs5 = 0n4
PdcClientVersion19H1 = 0n5
PdcClientVersionCurrent = 0n5
Next, pdc!PdcValidateClient will check the ClientIndex – the client index in the pdc!PdcClientInfo array.
As mentioned above, each client in this array contains flags. For validation, the 0x200 flag is important, as it indicates that this is a kernel mode client, and pdc will check the KTHREAD.PreviousMode of the current thread. For kernel mode clients, the call must be from the kernel, and KTHREAD.PreviousMode must be set to 0.
This means that we need to specify the index of a client from pdc!PdcClientInfo that is not in kernel mode, otherwise we will not pass validation. The client used to trigger the vulnerability was 0x26 "Cortana Voice Activation".
Another important field is ClientType, which has the PDC_CLIENT_TYPE type.
1: kd> dt pdc!PDC_CLIENT_TYPE
PdcNotificationClient = 0n0
PdcResiliencyClient = 0n1
PdcActivator = 0n2
PdcSuspendResumeClient = 0n3
PdcTaskClient = 0n4
PdcSignalClient = 0n5
PdcPpmProfileClient = 0n6
Pdcv2Activator = 0n7
PdcSleepstudyClient = 0n8
PdcInvalidType = 0n9
For activation, it must have the value PdcActivator (2) or Pdcv2Activator (7). Since the modified functions have v2 in their name, Pdcv2Activator is the appropriate choice in our case. PdcAllocateUserClient relies on the ClientType value during client initialization. If all validations pass successfully, pdc will also allocate a special structure (pdc_client) by calling PdcAllocateUserClient, containing information about the connected client.
Next, the client can send messages of other types, for example, the message format for activation will be as follows:
1: kd> dt _PDC_MSG_ACTIVATION_V2
pdc!_PDC_MSG_ACTIVATION_V2
+0x000 OperationStatus : Int4B
+0x004 ErrorDetail : _PDC_ACTIVATOR_ERROR_DETAIL
+0x008 PdcActivationInstanceHandle : Uint8B
+0x010 ActivityType : PDC_ACTIVITY_TYPE
+0x018 Flags : Uint8B
+0x020 StartTimeTolerance : Uint4B
+0x024 ExpectedMaximumDuration : Uint4B
+0x028 Task : [128] Wchar
+0x128 SubTask : [128] Wchar
+0x228 ExtraActivationParameters : _PDC_EXTRA_ACTIVATION_PARAMETERS
+0x240 DiagnosticContext : _PDC_DIAGNOSTIC_CONTEXT64
Thus, the features of interacting with pdc necessary for further patch analysis have been reviewed.
More detailed patch analysis
As mentioned earlier, there are several modified functions. Let's consider one of them – PdcpV2Activation.
When analyzing in BinDiff (vulnerable file on the left, patched file on the right), we can conclude that the bug is somehow related to the call of the PdcpReplyActivatorClient function (in the new version, PdcpV2ReplyActivation calls the same PdcpPrintActivationMessage and PdcpReplyActivatorClient), as its parameters undergo additional validation in the new pdc.sys version. In the old version of pdc.sys, PdcpReplyActivatorClient is passed a pointer to the pdc_client structure, where the value returned by the PdcpCreateActivationInstance function is stored at offset 0x190.
Let's take a closer look at this function. PdcpCreateActivationInstance allocates a block of memory (activation_instance) in NonPagedPoolNx with a size of 0x348 on Win 11 and 0x340 on Win 10, fills this memory block, and returns a pointer to it.
This already resembles the essence of the bug. Now let's take a closer look at what PdcpReplyActivatorClient does next with the saved kernel pointer. This function is designed to send a response to the client in pdc.sys. PdcpReplyActivatorClient can send the response either from user mode (in which case control will go to PdcSendUserMessage) or from kernel mode (PdcSendKernelMessage). We are interested in the first option, so let's consider the PdcSendUserMessage function. It's also important to mention that PdcpReplyActivatorClient offsets the pointer to the structure containing the kernel pointer by 0x150 before passing it to PdcSendUserMessage. Thus, the kernel pointer will now be at offset 0x40.
Inside PdcSendUserMessage, after preparing the message for sending ZwAlpcSendWaitReceivePort, the pointer remains unchanged. Now, this needs to be tested in practice.
Bug Trigger
It turns out that triggering the bug was enough by sending the v2 activation message (_PDC_MSG_ACTIVATION_V2), which called PdcpV2Activation, causing pdc.sys in the response message to return an address from NonPagedPoolNx.
For successful triggering, one had to join the port \PdcPort with the correct registration message, send the activation message, and receive the response from NtAlpcSendWaitReceivePort.
Thus, PdcpCreateActivationInstance allocates a memory block of size 0x348 on Win 11, and this address will be placed in the response message ALPC for the client (in this case, ours).
Below is the call stack from PoC to PdcpV2Activation
00 fffff80615a92071 : ffffa10c2b0d0ea0 ffffa10c2b0d0f00 ffffa10c2b0d12b8 0000000000000000 : pdc!PdcpV2Activation+0x136 01 fffff80615aadf96 : ffffd783a9115cc0 ffffa10c00000000 ffffc48cdd0f8c20 ffffa10c2b0d0e30 : pdc!PdcV2ActivatorReceive+0x11
02 fffff80615aad642 : ffffc48cd07a0fc0 ffffa10c2b0d0f00 ffffa10c2b0d12b8 0000000000000000 : pdc!PdcProcessReceivedUserMessage+0x62 03 fffff80615aad8b4 : ffffffff80000194 ffffd783a5ff7101 ffffd783a5ff7101 ffffd783a5ffe648 : pdc!PdcProcessMessage+0x50a
04 fffff80615aad129 : ffffd783a5ff7190 ffffd783a5ffe650 0000000000000000 ffff840101361e90 : pdc!PdcpAlpcProcessMessages+0x94 05 fffff80683a7dd77 : ffffc48cdd6b20c0 ffffd783a9115cc0 7ffffffffffffffc 0000000000000000 : pdc!PdcMessageCallback+0x9
06 fffff80683f1b366 : ffffc48cdd6b20c0 ffffd783a9115cc0 ffffd783a5ffe640 0000000000000000 : nt!ExNotifyCallback+0xb7 07 fffff80683f1a44d : ffffc48cdd0f8c20 ffffd78300000000 0000000000000004 0000000000000000 : nt!AlpcpCompleteDispatchMessage+0xdd6
08 fffff80683f1e1d2 : ffffd78300000004 ffffd783b204ea08 0000000000000004 00000000000000f8 : nt!AlpcpDispatchNewMessage+0x2ed 09 fffff80683eab3ae : 0000000000000000 0000000000000000 000002026c3d0000 0000000000000006 : nt!AlpcpSendMessage+0x982
0a fffff80683cfd355 : ffffa10c2b0d1b60 ffffd783b204e080 000000443094f738 0000000000000000 : nt!NtAlpcSendWaitReceivePort+0x24e 0b 00007ffb5cc808d4 : 00007ff7b13e1357 0000000000000000 000002026c3cf4c0 0000000000000000 : nt!KiSystemServiceCopyEnd+0x25
0c 00007ff7b13e1357 : 0000000000000000 000002026c3cf4c0 0000000000000000 000000000000014c : ntdll!NtAlpcSendWaitReceivePort+0x14 0d 00007ff7b13e1b2c : 0000000000000000 0000000000000000 0000000000000001 0000000000000001 : CVE_2025_27736!wmain+0x297
If you trace PdcpV2Activation to PdcpCreateActivationInstance and PdcpReplyActivatorClient to ZwAlpcSendWaitReceivePort, you will see that the response message at offset 0x40 contains the address returned by PdcpCreateActivationInstance.
Patch and Vulnerability Causes
If you look at what happens in the fixed version of the driver in the PdcpV2Activation function, you will see that instead of the address returned from PdcpCreateActivationInstance (activation_instance), now at the same offset 0x190, the value taken from the address activation_instance + 0x340 is placed.
To understand what is now being passed to the client instead of the address, you need to look at the PdcpCreateActivationInstance function. The value at offset 0x340 is set from the structure pdc_client+0x480, and now the meaning of this field is the number of activations called by the client (presumably).
Updated PdcpCreateActivationInstance
By the way, the field pdc_client + 0x480 is initialized to 1 in the modified PdcActivatorInitialize
If you check the PoC on the updated system, everything will be confirmed; instead of the address, it will now be 1 for the first activation call.
In conclusion, let's look at other modified functions related to activation.
PdcpV2Renew – is not of interest, since the activation handle handling has been changed there. In general, the kernel address returned in the message is the activation handle, and this function expects it in the received message. Previously, the function simply extracted the activation handle from the message and then used this address, but now the PdcpDecodeActivationInstanceHandle function is called. By the way, this is new in the fixed version of the driver.
PdcpV2Deactivation contains a change similar to PdcpV2Renew.
As for the cause of the bug, I have a hypothesis about how the kernel address might have ended up in the structure passed to the usermode. It is likely related to the fact that pdc handles both kernel and usermode clients, and initially, the kernel address was needed for kernel clients. This hypothesis is supported by the fact that the same data is passed to both client types by PdcpReplyActivatorClient.
Summary
An interesting bug was reviewed in the rare (in terms of occurrences in patches) component of Power Dependency Coordinator. Of course, there are still many questions about the driver's operation and the potential of the bug that were not addressed in the article.
- Here's the translated text you requested: How I made friends with Yandex Cloud and Gemini API without migrating to foreign servers
- A hole in Cloudflare’s shield: how the attack on Jabber.ru exposed a problem no one has talked about since 2023
- AI Security with a French Flavor or an Analysis of Securing Artificial Intelligence from ETSI. Part 1
Write comment