MCH3: W10 Insider DllHost injecting crash

c++ / delphi package - dll injection and api hooking
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by madshi »

Ok, I'll work on a fix, already have something in mind.
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by madshi »

@Iconic, AFAIU, a thread can only disable dynamic code restrictions if the process allows threads to do that (AllowThreadOptOut). Isn't it unlikely that any Microsoft process which enables dynamic code restriction would allow threads to opt out?
EaSy
Posts: 150
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by EaSy »

You have 3 options:
1) Leave dynamic code prohibited processes be.
2) Implement NtTestAlert hook without VirtualProtect calls (maybe indirect jmp).
3) Call driver/serverapp to manipulate process memory for you. Set event or smth like that (From the presentation I included in this thread before: Mitigation check is done on the calling process and not on the target process).
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by madshi »

As I said, I already have a plan on how to fix the injection stability problem. That's not the problem. The problem is if it will be possible to load dlls and hook apis in processes like dllhost by trying to change the mitigation somehow. But probably doing so might harm security, so it might not be a good idea to automatically do such things from within madCodeHook.
EaSy
Posts: 150
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by EaSy »

We will be satisfied even if no "dynamic code prohibited" process is injected at all for now. But it can change in time when we will know what are the clear intentions behind this and how the apps will use this in future.
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by madshi »

Here's a beta build which should fix the problem, for both 32bit and 64bit win10. Can you confirm?

http://madshi.net/madCollectionBeta.exe (installer 2.8.2.1)
iconic
Site Admin
Posts: 1064
Joined: Wed Jun 08, 2005 5:08 am

Re: MCH3: W10 Insider DllHost injecting crash

Post by iconic »

Ran some quick tests (mainly out of curiosity), SetProcessMitigationPolicy() will definitely not allow threads to opt out if a previous call to SetProcessMitigationPolicy() was already made which prevents it. However, since this is called at run-time and not a linker flag handed to it at compile time it can definitely be worked around, although perhaps not advisable since this is meant to be a security enhancement for the process' address space. These policies are designed to allow you to reconfigure them only if you're adding enhanced restrictions, not removing any of the current policy restrictions.

Anyhow, my test code is below as there aren't a lot of great examples online from what I see, at least with definitions all in one place.

Code: Select all

typedef enum _PROCESS_MITIGATION_POLICY { 
     ProcessDEPPolicy                    = 0,
     ProcessASLRPolicy                   = 1,
     ProcessDynamicCodePolicy            = 2,
     ProcessStrictHandleCheckPolicy      = 3,
     ProcessSystemCallDisablePolicy      = 4,
     ProcessMitigationOptionsMask        = 5,
     ProcessExtensionPointDisablePolicy  = 6,
     ProcessControlFlowGuardPolicy       = 7,
     ProcessSignaturePolicy              = 8,
     ProcessFontDisablePolicy            = 9,
     ProcessImageLoadPolicy              = 10,
     MaxProcessMitigationPolicy          = 11
   } PROCESS_MITIGATION_POLICY, *PPROCESS_MITIGATION_POLICY;




  typedef struct _PROCESS_MITIGATION_DYNAMIC_CODE_POLICY {
      union {
          DWORD  Flags;
        struct {
             DWORD ProhibitDynamicCode  :1;
             DWORD AllowThreadOptOut  :1;
            DWORD ReservedFlags  :30;
           };
        };
     } PROCESS_MITIGATION_DYNAMIC_CODE_POLICY, *PPROCESS_MITIGATION_DYNAMIC_CODE_POLICY;



  typedef BOOL (WINAPI *PSetProcessMitigationPolicy)(PROCESS_MITIGATION_POLICY MitigationPolicy,
                                                     PVOID lpBuffer,
						     SIZE_T dwLength);


/* 
  Get/SetThreadInformation() share the same prototype, no sense in creating 2
*/

  typedef BOOL (WINAPI *PGetSetThreadInformation)(HANDLE hThread,
                                                  ULONG ThreadInformationClass,
                                                  PULONG ThreadInformation,
                                                  ULONG ThreadInformationSize);


   #define THREAD_DYNAMIC_CODE_DISALLOW 0
   #define THREAD_DYNAMIC_CODE_ALLOW 1
   #define ThreadDynamicCodePolicy 2
   #define ERROR_DYNAMIC_CODE_BLOCKED 0x677
   #define gpa_SpmP "SetProcessMitigationPolicy"
   #define gpa_Sti "SetThreadInformation"
   #define gpa_Gti "GetThreadInformation"
   #define KRNL32 L"kernel32.dll"




void TestDynCodeModify()
{
   HMODULE hKrnl32 = GetModuleHandleW(KRNL32);

   PSetProcessMitigationPolicy Spmp = 
                         (PSetProcessMitigationPolicy)GetProcAddress(hKrnl32,
		                    "SetProcessMitigationPolicy");

   PGetSetThreadInformation Sti = 
		                 (PGetSetThreadInformation)GetProcAddress(hKrnl32, 
						   "SetThreadInformation");

   PGetSetThreadInformation Gti = 
                        (PGetSetThreadInformation)GetProcAddress(hKrnl32, 
						"GetThreadInformation");

  if (Spmp == NULL || Sti == NULL || Gti == NULL)
  {
     printf("A function pointer is NULL... Aborting\n");
     getchar();
     return;
  }

   PROCESS_MITIGATION_DYNAMIC_CODE_POLICY Pmdcp = {0};
   /* 
      prohibit dynamic code modifications but allow threads to opt out individually 
   */
   Pmdcp.ProhibitDynamicCode = 1;
   /* 
      has to be set in first call to SetProcessMitigationPolicy() otherwise it is ignored 
   */
   Pmdcp.AllowThreadOptOut = 1;

 if (Spmp(ProcessDynamicCodePolicy, &Pmdcp, sizeof(PROCESS_MITIGATION_DYNAMIC_CODE_POLICY)))
 {
     printf("SetProcessMitigationPolicy(DYNAMIC_CODE_POLICY) Success!!!\n\n");
 }
  else
 {
     printf("SetProcessMitigationPolicy() Failed - 0x%08x\n", GetLastError());
     getchar();
     return;
 }

    DWORD dwThreadPolicy = THREAD_DYNAMIC_CODE_ALLOW;

 if (Sti(GetCurrentThread(), ThreadDynamicCodePolicy, &dwThreadPolicy, sizeof(DWORD)))
  {
     printf("Allowing Current Thread to Make PAGE_EXECUTE_XxX Modifications\n");
  }
else
  { 
     printf("SetThreadInformation() Failed - 0x%08x\n", GetLastError());
     getchar();
     return;
  }

    printf("Checking Current Thread Policy for Dynamic Code Modifications...\n");

  if (Gti(GetCurrentThread(), ThreadDynamicCodePolicy, &dwThreadPolicy, sizeof(DWORD)))
  {
     printf("Current Thread Policy Allows for Dynamic Code Modifications: %s\n", ((dwThreadPolicy != 0) ? "YES" : "NO"));
  }
else
  {
     printf("GetThreadInformation() Failed - 0x%08x\n", GetLastError());
     getchar();
     return;
  }

    ULONG oldProtect;

 if (VirtualProtect((void*)GetModuleHandle(NULL), 2, PAGE_EXECUTE_READWRITE, &oldProtect))
 {
     printf("VirtualProtect() Succeeded!\n");
     VirtualProtect((void*)GetModuleHandle(NULL), 2, oldProtect, &oldProtect);
 }
else
  {
     printf("VirtualProtect() Failed - 0x%08x\n", GetLastError());
     getchar();
     return;
  }

    printf("\n");

   dwThreadPolicy = THREAD_DYNAMIC_CODE_DISALLOW;
  
 if (Sti(GetCurrentThread(), ThreadDynamicCodePolicy, &dwThreadPolicy, sizeof(DWORD)))
  {
    printf("DisAllowing Current Thread to Make PAGE_EXECUTE_XxX Modifications\n");
  }
else
  { 
    printf("SetThreadInformation() Failed - 0x%08x\n", GetLastError());
    getchar();
    return;
  } 

    printf("Checking Current Thread Policy for Dynamic Code Modifications...\n");

  if (Gti(GetCurrentThread(), ThreadDynamicCodePolicy, &dwThreadPolicy, sizeof(DWORD)))
  {
    printf("Current Thread Policy Allows for Dynamic Code Modifications: %s\n", ((dwThreadPolicy != 0) ? "YES" : "NO"));
  }
else
  {
     printf("GetThreadInformation() Failed - 0x%08x\n", GetLastError());
     getchar();
     return;
  }

 if (VirtualProtect((void*)GetModuleHandle(NULL), 2, PAGE_EXECUTE_READWRITE, &oldProtect))
 {
     printf("Success! VirtualProtect() Succeeded!\n");
     VirtualProtect((void*)GetModuleHandle(NULL), 2, oldProtect, &oldProtect);
     getchar();
 }
else
  {
     printf("VirtualProtect() Failed - 0x%08x\n", GetLastError());
     printf("Expected Error on Failure (ERROR_DYNAMIC_CODE_BLOCKED) Returned: %s\n", (GetLastError() ==            ERROR_DYNAMIC_CODE_BLOCKED) ? "YES" : "NO");
     getchar();
     return;
  }
}
--Iconic
Attachments
PMPTest_Win10_x64.png
PMPTest_Win10_x64.png (20.73 KiB) Viewed 14156 times
EaSy
Posts: 150
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by EaSy »

You can set mitigation policies as startup info or in registry without any api call.


PP
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by madshi »

Thanks iconic, having some sample code might come in handy in the future!
iconic
Site Admin
Posts: 1064
Joined: Wed Jun 08, 2005 5:08 am

Re: MCH3: W10 Insider DllHost injecting crash

Post by iconic »

Ahh yes, I do recall seeing the STARTUPINFO structure modified prior to a CreateProcess call with some of these policies in the past now that I think about it. But I've personally not used them, yet. Seems that MS is making the building of a sandbox more attractive as an option. Thanks for the additional info, EaSy

--Iconic
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by madshi »

EaSy wrote:sorry, but I must ask you. Will you be able to fix this or at least work around this before the creators update goes live (in 4 days)? Thx.
We would love to have at least 1 day to prepare updates, because it also affects all versions of MCH previously released.
Have you had a chance to test my fixed beta build yet? Thanks...
EaSy
Posts: 150
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by EaSy »

Hi,
I am testing it now. Second RW memory page works OK, so the dllhost is not crashing or hanging anymore.
But I am experiencing some issue with "non-main thread waiting" part of the code you have implemeted. I am debugging it right now. Maybe it is related, maybe not.

PP
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by madshi »

Ok, thanks.
madshi
Site Admin
Posts: 10749
Joined: Sun Mar 21, 2004 5:25 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by madshi »

P.S: Which program did you use to list the mitigations (see screenshot first page)? Is it the Process Explorer? Or something else?
EaSy
Posts: 150
Joined: Tue Oct 23, 2012 12:33 pm

Re: MCH3: W10 Insider DllHost injecting crash

Post by EaSy »

Hi,
I am taking my suspicion back. It was caused by windbg breakpoint on nttestalert (MCH wasn't able to rewrite it). Everything looks OK.

Thx for quick fix!

PS: I am using Process Hacker http://processhacker.sourceforge.net/

PP
Post Reply