5

It seems like driver based injection using APC calls fails on MicrosoftEdge and it's related processes (browser_broker.exe , MicrosoftEdgeCP.exe and MicrosoftEdge.exe).

Looking into the problem, it looks like this application is protected process and uses the ProcessDynamicCodePolicy flag which prevents the driver from allocate new executable memory.

Eventually, shortly after trying to inject to those processes, they all fail due to the following reason (exception 0xC0000409, STATUS_STACK_BUFFER_OVERRUN).

Description:
Faulting application name: MicrosoftEdgeCP.exe, version: 11.0.15063.674, time stamp: 0x59cdf479
Faulting module name: ntdll.dll, version: 10.0.15063.1324, time stamp: 0x28af0ac0
Exception code: 0xc0000409
Fault offset: 0x00000000000a9f80
Faulting process ID: 0x1580
Faulting application start time: 0x01d503e311af20b8
Faulting application path: C:\Windows\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdgeCP.exe
Faulting module path: C:\Windows\SYSTEM32\ntdll.dll
Report ID: 112c6adc-0898-4441-90b6-f1a17b668af1
Faulting package full name: Microsoft.MicrosoftEdge_40.15063.674.0_neutral__8wekyb3d8bbwe

Does the above output hint that this is the problem I'm facing?

Is there any way to detect from the driver that this process is protected?

3
  • Since you're asking for drivers and the existing answer refers specifically to UM code, potentially introducing limitations with regard to permissible IRQL, you may want to check out the article series by Alex Ionescu (here and here and here)
    – 0xC0000022L
    Commented Aug 5, 2019 at 10:00
  • @0xC0000022L, I understood that there's a difference between protected process, an attribute that only Microsoft can entitle to a process and processes that can set ProcessDynamicCodePolicy by themselves using SetProcessMitigationPolicy. For the second type of processes I wish to override this bit from the driver. do you know if SetProcessMitigationPolicy is also available from kernel space ?
    – Zohar81
    Commented Aug 5, 2019 at 10:25
  • I highly doubt it as I think that this is implemented differently from PPL. I think either way you won't get around APCs to execute some user mode code, which places you in a catch 22 situation of sorts. And actually anti-malware vendors can also mark specific processes as PPL, provided they have an ELAM and the files of the designated PPL are signed as described by the ELAM. Details are in fact subject to NDAs.
    – 0xC0000022L
    Commented Aug 5, 2019 at 10:33

1 Answer 1

6

Is there any way to detect from the driver that this process is protected ?

Disclaimer: This following procedure depends on undocmented data structure which is extracted from PDB symbol of combase.dll file. As usual this may not work in future Windows OS version.

This is the sample C code to detect protected process. The program accepts a valid process ID in its first argument. This code need to be linked with ntdll.lib library. In user mode, this code may need to be run as administrator for some processes.

#include <Windows.h>
#include <winternl.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct _PROCESS_EXTENDED_BASIC_INFORMATION {
    size_t Size;
    PROCESS_BASIC_INFORMATION BasicInfo;
    union {
        unsigned int Flags;
        struct {
            unsigned int IsProtectedProcess : 1;
            unsigned int IsWow64Process : 1;
            unsigned int IsProcessDeleting : 1;
            unsigned int IsCrossSessionCreate : 1;
            unsigned int IsFrozen : 1;
            unsigned int IsBackground : 1;
            unsigned int IsStronglyNamed : 1;
            unsigned int IsSecureProcess : 1;
            unsigned int IsSubsystemProcess : 1;
            unsigned int SpareBits : 23;
        };
    };
} PROCESS_EXTENDED_BASIC_INFORMATION, *PPROCESS_EXTENDED_BASIC_INFORMATION; /* size: 0x0040 */

int main(int argc, char *argv[])
{
    if (argc < 2)
        return;

    void *hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, atoi(argv[1]));
    if (hProcess != NULL)
    {
        unsigned int ret;
        PROCESS_EXTENDED_BASIC_INFORMATION pInfo;
        memset(&pInfo, 0, sizeof pInfo);

        NTSTATUS Status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pInfo, sizeof pInfo, &ret);
        if (Status == 0)
            printf("Protected: %d\n", pInfo.IsProtectedProcess);
        CloseHandle(hProcess);
    }
    else
        printf("OpenProcess error: %d\n", GetLastError());
}

To add or change process mitigation policy flags, programs use SetProcessMitigationPolicy() function which uses NtSetInformationProcess() function (retrieved from KernelBase.dll). Here is a sample C code which enables dynamic code policy.

#include <Windows.h>
#include <winternl.h>

typedef struct _PROCESS_MITIGATION_POLICY_INFORMATION {
    PROCESS_MITIGATION_POLICY Policy;
    union {
        PROCESS_MITIGATION_ASLR_POLICY ASLRPolicy;
        PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY StrictHandleCheckPolicy;
        PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY SystemCallDisablePolicy;
        PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY ExtensionPointDisablePolicy;
        PROCESS_MITIGATION_DYNAMIC_CODE_POLICY DynamicCodePolicy;
        PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY ControlFlowGuardPolicy;
        PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY SignaturePolicy;
        PROCESS_MITIGATION_FONT_DISABLE_POLICY FontDisablePolicy;
        PROCESS_MITIGATION_IMAGE_LOAD_POLICY ImageLoadPolicy;
        PROCESS_MITIGATION_SYSTEM_CALL_FILTER_POLICY SystemCallFilterPolicy;
        PROCESS_MITIGATION_PAYLOAD_RESTRICTION_POLICY PayloadRestrictionPolicy;
        PROCESS_MITIGATION_CHILD_PROCESS_POLICY ChildProcessPolicy;
        PROCESS_MITIGATION_SIDE_CHANNEL_ISOLATION_POLICY SideChannelIsolationPolicy;
    };
} PROCESS_MITIGATION_POLICY_INFORMATION, *PPROCESS_MITIGATION_POLICY_INFORMATION; /* size: 0x0008 */

int main(void)
{
    PROCESS_MITIGATION_POLICY_INFORMATION PolicyInfo = { 0 };
    PolicyInfo.Policy = ProcessDynamicCodePolicy;
    PolicyInfo.DynamicCodePolicy.ProhibitDynamicCode = TRUE;

    NTSTATUS Status = NtSetInformationProcess(
        GetCurrentProcess(),
        52, /* ProcessMitigationPolicy */
        &PolicyInfo,
        sizeof PolicyInfo);
}

Any one of the policy can be enabled with this method. Use Zw alternatives of Nt function to use in kernel mode. All of these undocumented structures can also be found in ProcessHacker/phnt repository.

5
  • Hi, I think that your methodology deals with revealing protected process - an attribute that only Microsoft can entitle to a process, and can be detected also using the call PsIsProtectedProcess from kernel space . I look for processes that can set the flag ProcessDynamicCodePolicy by themselves using SetProcessMitigationPolicy. For those processes I wish to override this bit from the driver. do you know if SetProcessMitigationPolicy is also available from kernel space ?
    – Zohar81
    Commented Aug 5, 2019 at 10:28
  • @Zohar81 Edited my answer with internals of SetProcessMitigationPolicy(). Also I don't know if this works for PPL or containerized UWP processes.
    – Biswapriyo
    Commented Aug 5, 2019 at 18:29
  • @Zohar81 If it can be set with NtSetInformationProcess it stands to reason that this is part of either EPROCESS or KPROCESS (likely the former) and so can be manipulated from within a driver. I'd give WinDbg a try to figure out how the structures look. ProcessHacker is also usually a good source for this kind of information.
    – 0xC0000022L
    Commented Aug 6, 2019 at 6:00
  • @0xC0000022L Yes, there is a MitigationFlagsValues structure in EPROCESS. But the structure is too long and volatile to include in a source code. Even it vaires with every builds of Windows 10.
    – Biswapriyo
    Commented Aug 6, 2019 at 8:42
  • @Biswapriyo Didn't even ProcessHacker pioneer a method by which the debug symbols matching the currently running system are used to extract the respective offsets and then use that? I've at least seen that before. Admittedly probably not a good idea to do this kind of stuff in KM, though ;)
    – 0xC0000022L
    Commented Aug 6, 2019 at 9:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.