How to check if my code is executing inside a Managed App or Native App?

If you check the CRT source code (inside VC\crt\src\crt0.c) you can find an interesting function check_managed_app() that returns 1 if managed app, 0 if not based on the COM Runtime Descriptor in the Image Data Directory of the PE or PE+ header.

You can generalize it to test if you are running as part of a managed process or native process.

 extern "C" int WRAPPER_API check_managed_app (LPVOID pImageBase)
{
  PIMAGE_DOS_HEADER pDOSHeader;
  PIMAGE_NT_HEADERS pPEHeader;

  pDOSHeader = (PIMAGE_DOS_HEADER)pImageBase;
  if ( pDOSHeader == NULL || pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE )
      return 0;

  pPEHeader = (PIMAGE_NT_HEADERS)((char *)pDOSHeader + pDOSHeader->e_lfanew);

  if ( pPEHeader->Signature != IMAGE_NT_SIGNATURE )
      return 0;

  if (pPEHeader->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
      return 0;

  if (pPEHeader->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)
      return 0;

  return pPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress != 0;
}

You can invoke it from managed code as shown below:

     [DllImport("MyWrapper.dll")]
    private static extern bool check_managed_app(System.IntPtr pBaseAddress);
    bool Interface1.AmIInsideManagedApp()
    {
        return check_managed_app(Process.GetCurrentProcess().MainModule.BaseAddress);
    }

A similar call from C++ should look like below:

 extern  "C" IMAGE_DOS_HEADER __ImageBase;
 
  check_managed_app(&__ImageBase);

Disclaimer: The usual "use it at your own risk" conditions apply.

Comments

  • Anonymous
    February 29, 2008
    If you check the CRT source code (inside VCcrtsrccrt0.c ) you can find an interesting function check_managed_app