Some of you may know that Windows Vista introduced a new type of process, called a "protected process". This type of process has restrictions placed on it regardless of the ACL and integrity level of it. The following operations are allowed on a protected process from outside of the protected process integrity space:
Note that these must be in the DACL for the process (just like a normal process) - but all other process rights are skipped when checking the DACL. Similar access checks are applied to threads that belong to protected processes. Because how the system checks process rights is not the topic of this thread, we won't go into much detail and skip straight to the chase...
I am trying to find out what is going on inside a "protected process" by dumping its user-address space, but I can't. Why is this?
Put simply - in order to dump the user-address space of a protected process, you must yourself be running as a protected process - but Microsoft limits usage of protected processes by third parties. Here I will show you how to use a kernel debugger to (on your own, local machine) generate a user-mode memory dump of a process that is protected. It involves knowledge of using WinDbg (as this is the debugger we will use, but other kernel debuggers can be used, too) and the various commands associated with kernel debugging (kd and lkd).
Essentially what we are required to do is use the kernel debugger to modify the EPROCESS structure of our own program. Inside the structure we are interested in the ProtectedProcess member, which is a single bit of a union representing 22 bits of information defining various aspects of the process. Its layout looks like this:
In order to set the process as a protected process, we must turn on the 11th bit (starting at zero) using the kernel debugger. Assuming all other bits are turned off, turning on just the 11th bit gives us 0x800, or 2048 in decimal, so we must modify the memory location for these flags to be at least this value. To do this, we can simply take the the value of the Flags2 member and bitwise OR it with 0x800, and then write the resulting value to the memory location. Let's start shall we?
Stage 1: Turning on local kernel debugging
The following will show you how to boot your system with kernel debugging enabled. The easiest way is to use the BCDEdit utility from the command line:
1. Start a Command Prompt elevated (Run as administrator).
2. Type the following command and then press ENTER: bcdedit /debug on
3. Restart the computer.
Stage 2: Start the local kernel debugger (WinDbg only)
The following steps are for WinDbg only. If you prefer to use another kernel debugger (that can utilize the same commands that are to follow, setup local kernel debugging according to it).
1. Open WinDbg elevated (Run as administrator).
2. Press CTRL+K to launch the Kernel Debugging window.
3. Select the Local tab and click OK.
4. If everything succeeded you should see your local kernel debug session start like the following image:

With that out of the way, it is time to run some commands!
Stage 3: Modify the EPROCESS structure of your program
The following steps outline how to make Task Manager (taskmgr.exe) a protected process so that we can use it to create user-address space memory dumps of other protected processes. This can be achieved by right clicking the process in the list in Task Manager and selecting Create Dump File. Creating a user dump requires, amongst others, the PROCESS_VM_READ access right - which is unavailable to a process which opens a handle to a protected process, unless of course, it is a protected process itself. You can try this by trying to create a dump file of the audiodg.exe process - it will fail with an access denied error message. After completing the following steps, however, you will successfully be able to create a dump file of audiodg.exe from Task Manager. In other news, replace my example of taskmgr.exe with YOUR OWN program that you want to make a protected process.
1. First, we need to get a list of all the processes on the machine - to do this execute the !dml_proc command in the debugger.
2. We are now presented with each running process in the system. Here is output from my machine:
The Address column is the one we are most interested in. For our example, taskmgr.exe has an address of fffffa80`05608060. We will use this next. Replace fffffa80`05608060 EVERYWHERE in the below steps with the address of the process you wish to modify.
3. Dump the value of the _EPROCESS!Flags2 member with the following command: dt _EPROCESS fffffa80`05608060 -y Flags2. Here is my output:
4. With my Flags2 member having the default vale of 0xd00, I must now modify it so that it causes the ProtectedProcess bit to be set. As explained earlier, we can bitwise OR this value with 0x800 to turn on the ProtectedProcess bit. (0xd00 | 0x800 = 0xd800). Note down the value you get when performing this operation - my value (and likely yours too) is 0xd800.
5. Rewrite the memory for our Flags2 member. In Step 3 above, we see that the Flags2 member is offset 0x43c bytes from the process address. The memory address we will be writing to therefore will be process address+0x43c, in this case it is fffffa80`05608060+0x43c. Execute the following command: ed fffffa80`05608060+0x43c 0xd800.
6. Verify that the ProtectedProcess bit has been set. Execute the following command: dt _EPROCESS fffffa80`05608060 -y ProtectedProcess. Here is my output:
The 0y1 tells us that the bit has been set correctly. You can now proceed to creating a dump file of a protected process.
NOTE: On some systems I have seen Task Manager throw up an error "Not enough storage space is available to process this command". If this occurs for you either using my Task Manager example, or with your own program, you can reverse the process and REMOVE the ProtectedProcess bit from the process that you want to create a dump file of. The steps are the same, however you modify the EPROCESS structure of the target process, and you remove the value 0x800 (by using bitwise AND from NOT of 0x800) from the Flags2 member instead.
Edited by tompsonn - 8/31/12 at 7:59am
- Termination (PROCESS_TERMINATE)
- Suspension and resumption (PROCESS_SUSPEND_RESUME)
- Synchronization (SYNCHRONIZE)
Note that these must be in the DACL for the process (just like a normal process) - but all other process rights are skipped when checking the DACL. Similar access checks are applied to threads that belong to protected processes. Because how the system checks process rights is not the topic of this thread, we won't go into much detail and skip straight to the chase...
I am trying to find out what is going on inside a "protected process" by dumping its user-address space, but I can't. Why is this?
Put simply - in order to dump the user-address space of a protected process, you must yourself be running as a protected process - but Microsoft limits usage of protected processes by third parties. Here I will show you how to use a kernel debugger to (on your own, local machine) generate a user-mode memory dump of a process that is protected. It involves knowledge of using WinDbg (as this is the debugger we will use, but other kernel debuggers can be used, too) and the various commands associated with kernel debugging (kd and lkd).
Essentially what we are required to do is use the kernel debugger to modify the EPROCESS structure of our own program. Inside the structure we are interested in the ProtectedProcess member, which is a single bit of a union representing 22 bits of information defining various aspects of the process. Its layout looks like this:
Code:
typedef struct _EPROCESS
{
/* ... previous entries */
union
{
ULONG32 Flags2;
struct
{
ULONG32 JobNotReallyActive : 1; // 0 BitPosition
ULONG32 AccountingFolded : 1; // 1 BitPosition
ULONG32 NewProcessReported : 1; // 2 BitPosition
ULONG32 ExitProcessReported : 1; // 3 BitPosition
ULONG32 ReportCommitChanges : 1; // 4 BitPosition
ULONG32 LastReportMemory : 1; // 5 BitPosition
ULONG32 ReportPhysicalPageChanges : 1; // 6 BitPosition
ULONG32 HandleTableRundown : 1; // 7 BitPosition
ULONG32 NeedsHandleRundown : 1; // 8 BitPosition
ULONG32 RefTraceEnabled : 1; // 9 BitPosition
ULONG32 NumaAware : 1; // 10 BitPosition
ULONG32 ProtectedProcess : 1; // 11 BitPosition
ULONG32 DefaultPagePriority : 3; // 12 BitPosition
ULONG32 PrimaryTokenFrozen : 1; // 15 BitPosition
ULONG32 ProcessVerifierTarget : 1; // 16 BitPosition
ULONG32 StackRandomizationDisabled : 1; // 17 BitPosition
ULONG32 AffinityPermanent : 1; // 18 BitPosition
ULONG32 AffinityUpdateEnable : 1; // 19 BitPosition
ULONG32 PropagateNode : 1; // 20 BitPosition
ULONG32 ExplicitAffinity : 1; // 21 BitPosition
};
};
/* ... following entries */
} EPROCESS, *PEPROCESS;
In order to set the process as a protected process, we must turn on the 11th bit (starting at zero) using the kernel debugger. Assuming all other bits are turned off, turning on just the 11th bit gives us 0x800, or 2048 in decimal, so we must modify the memory location for these flags to be at least this value. To do this, we can simply take the the value of the Flags2 member and bitwise OR it with 0x800, and then write the resulting value to the memory location. Let's start shall we?
WARNING: If followed incorrectly, the following steps can cause your machine to bugcheck with, often MEMORY_MANAGEMENT. You MUST ensure you write the correct values to memory as the NT kernel will notice if a system structure or memory location has been corrupted as a result of an incorrect memory edit and will blue screen the machine ASAP.
Stage 1: Turning on local kernel debugging
The following will show you how to boot your system with kernel debugging enabled. The easiest way is to use the BCDEdit utility from the command line:
1. Start a Command Prompt elevated (Run as administrator).
2. Type the following command and then press ENTER: bcdedit /debug on
3. Restart the computer.
Stage 2: Start the local kernel debugger (WinDbg only)
The following steps are for WinDbg only. If you prefer to use another kernel debugger (that can utilize the same commands that are to follow, setup local kernel debugging according to it).
1. Open WinDbg elevated (Run as administrator).
2. Press CTRL+K to launch the Kernel Debugging window.
3. Select the Local tab and click OK.
4. If everything succeeded you should see your local kernel debug session start like the following image:
With that out of the way, it is time to run some commands!
Stage 3: Modify the EPROCESS structure of your program
The following steps outline how to make Task Manager (taskmgr.exe) a protected process so that we can use it to create user-address space memory dumps of other protected processes. This can be achieved by right clicking the process in the list in Task Manager and selecting Create Dump File. Creating a user dump requires, amongst others, the PROCESS_VM_READ access right - which is unavailable to a process which opens a handle to a protected process, unless of course, it is a protected process itself. You can try this by trying to create a dump file of the audiodg.exe process - it will fail with an access denied error message. After completing the following steps, however, you will successfully be able to create a dump file of audiodg.exe from Task Manager. In other news, replace my example of taskmgr.exe with YOUR OWN program that you want to make a protected process.
1. First, we need to get a list of all the processes on the machine - to do this execute the !dml_proc command in the debugger.
2. We are now presented with each running process in the system. Here is output from my machine:
Code:
lkd> !dml_proc
Address PID Image file name
fffffa80`03cd2040 4 System
fffffa80`04270b30 10c smss.exe
fffffa80`043e3060 164 csrss.exe
fffffa80`0503d910 198 wininit.exe
fffffa80`05037060 1a0 csrss.exe
fffffa80`050dd5f0 1e0 services.exe
fffffa80`050eb060 1f8 winlogon.exe
fffffa80`050fa460 208 lsass.exe
fffffa80`050fe400 21c lsm.exe
fffffa80`04ab1360 288 svchost.exe
fffffa80`04aef740 2d8 svchost.exe
fffffa80`050a5b30 34c svchost.exe
fffffa80`051719e0 380 svchost.exe
fffffa80`05180b30 398 svchost.exe
fffffa80`051e7b30 178 svchost.exe
fffffa80`05217060 394 svchost.exe
fffffa80`052c5060 4cc spoolsv.exe
fffffa80`052fe060 4e8 svchost.exe
fffffa80`05383b30 560 svchost.exe
fffffa80`05454b30 610 sqlwriter.exe
fffffa80`0547ab30 640 winvnc4.exe
fffffa80`054a8b30 664 winvnc4.exe
fffffa80`054ab490 66c conhost.exe
fffffa80`054b6b30 6a4 vmtoolsd.exe
fffffa80`055b11d0 62c dllhost.exe
fffffa80`055b0060 3c4 msdtc.exe
fffffa80`055b6620 83c svchost.exe
fffffa80`0569c060 9a4 dwm.exe
fffffa80`0540d7d0 9bc explorer.exe
fffffa80`056fc7a0 9fc taskhost.exe
fffffa80`0576b310 a88 VMwareTray.exe
fffffa80`05674b30 a90 vmtoolsd.exe
fffffa80`05775b30 aa0 wc.exe
fffffa80`04b2db30 b64 SearchIndexer.
fffffa80`05836960 bdc wmpnetwk.exe
fffffa80`058aeb30 af0 explorer.exe
fffffa80`0552ab30 150 windbg.exe
fffffa80`056edb30 81c mspaint.exe
fffffa80`03d9eb30 2b0 svchost.exe
fffffa80`045bd9c0 680 svchost.exe
fffffa80`05912060 5c4 WmiPrvSE.exe
fffffa80`05608060 92c taskmgr.exe
The Address column is the one we are most interested in. For our example, taskmgr.exe has an address of fffffa80`05608060. We will use this next. Replace fffffa80`05608060 EVERYWHERE in the below steps with the address of the process you wish to modify.
3. Dump the value of the _EPROCESS!Flags2 member with the following command: dt _EPROCESS fffffa80`05608060 -y Flags2. Here is my output:
Code:
lkd> dt _EPROCESS fffffa80`05608060 -y Flags2
nt!_EPROCESS
+0x43c Flags2 : 0xd000
4. With my Flags2 member having the default vale of 0xd00, I must now modify it so that it causes the ProtectedProcess bit to be set. As explained earlier, we can bitwise OR this value with 0x800 to turn on the ProtectedProcess bit. (0xd00 | 0x800 = 0xd800). Note down the value you get when performing this operation - my value (and likely yours too) is 0xd800.
5. Rewrite the memory for our Flags2 member. In Step 3 above, we see that the Flags2 member is offset 0x43c bytes from the process address. The memory address we will be writing to therefore will be process address+0x43c, in this case it is fffffa80`05608060+0x43c. Execute the following command: ed fffffa80`05608060+0x43c 0xd800.
6. Verify that the ProtectedProcess bit has been set. Execute the following command: dt _EPROCESS fffffa80`05608060 -y ProtectedProcess. Here is my output:
Code:
lkd> dt _EPROCESS fffffa80`05608060 -y ProtectedProcess
nt!_EPROCESS
+0x43c ProtectedProcess : 0y1
The 0y1 tells us that the bit has been set correctly. You can now proceed to creating a dump file of a protected process.
NOTE: On some systems I have seen Task Manager throw up an error "Not enough storage space is available to process this command". If this occurs for you either using my Task Manager example, or with your own program, you can reverse the process and REMOVE the ProtectedProcess bit from the process that you want to create a dump file of. The steps are the same, however you modify the EPROCESS structure of the target process, and you remove the value 0x800 (by using bitwise AND from NOT of 0x800) from the Flags2 member instead.
Edited by tompsonn - 8/31/12 at 7:59am









