NXCOMPAT and the C# compiler

The C# compiler in Visual Studio 2008 and the .NET 3.5 Framework (csc.exe) is now generating PE files with the NXCOMPAT bit set. What is that bit and who cares, you ask? You may very well care if your application interops with native binaries or exposes a plugin model to 3rd parties. First, some background…

DEP is short for Data Execution Prevention. It is a technology that exists in Microsoft operating systems which prevents execution of code from memory pages which are not marked as executable. DEP exists to reduce the attack surface available to malicious software that is trying to hijack a process, and it has been acknowledged to be very helpful in that regard. In Windows Vista, the set of processes and applications to which DEP is applied is configurable by administrators, but there is also a role for application developers.

In the header of a PE file there is a flag called IMAGE_DLLCHARACTERISTICS_NX_COMPAT. This flag affects whether or not the OS enables DEP for a process. Setting this flag tells the OS that the image is compatible with DEP. For executable images, if this flag is set, the process is run with DEP enabled unless the machine is configured with the DEP policy set to AlwaysOff. If the image is a DLL and the flag is set, the OS skips checking the DLL against a compatibility database which results in a small performance improvement. All of this applies to x86, 32-bit processes only. On a 64-bit OS, DEP is always enabled for 64-bit processes, but 32-bit processes are configured by the PE flag and system policy as described above. So how does one control the flag in the PE header?

Since the C# compiler emits PE files which are MSIL only and therefore compatible with DEP, the output binaries from the VS 2008 and .NET 3.5 C# compilers have this flag set. Our expectation is that the vast majority of C# executables produced by these compilers will be part of a DEP-compatible application. For that reason we did not surface a compiler switch to configure the NXCOMPAT setting. Of course you can write a C# application that uses a native or mixed binary which is not compatible with DEP. Some ATL types in 7.1 and earlier used to do simple code generation into data pages which is a DEP no-no. If your application is generating IP_ON_HEAP exceptions, then you may need to clear the IMAGE_DLLCHARACTERISTICS_NX_COMPAT flag for your executable. To do this you can use EDITBIN.EXE from the VC toolset like so:

editbin.exe /NXCOMPAT:NO <your binary>

If you’re using Visual Studio, you can add a post build step to your executable’s project. You’ll need to setup the environment so that EDITBIN’s dependencies can be resolved. Since the post build steps you author in Visual Studio’s properties page are written into a batch file that is launched by the build process, you can use Visual Studio’s VSVARS32.BAT to establish the right environment. My post build step looks like this:

call $(DevEnvDir)..\tools\vsvars32.bat
editbin.exe /NXCOMPAT:NO $(TargetPath)

If you sign the binary in Visual Studio, flipping the IMAGE_DLLCHARACTERISTICS_NX_COMPAT flag in the post build step after the binary has been signed will result in an assembly that will fail strong name validation. To work around this you’ll need to begin signing your binary as part of the post build steps. To do this, use SN.EXE from the Windows SDK.

The .NET 2.0 and VS 2005 compilers are also affected

We like DEP so much that when you install .NET Framework 2.0 SP1 your C# compilers in VS 2005 and .NET Framework 2.0 will also begin to emit binaries with the IMAGE_DLLCHARACTERISTICS_NX_COMPAT bit set. This will undoubtedly surprise a few developers…download a framework service pack, recompile, run your app, and you’re now getting IP_ON_HEAP exceptions. Obviously this is not ideal, but aggressively building a computing ecosystem filled with DEP-enabled applications and their accompanying security benefits is very beneficial to Windows users. If you begin to encounter IP_ON_HEAP exceptions after installing .NET Framework 2.0 SP1, you can use the same technique described above to clear the IMAGE_DLLCHARACTERISTICS_NX_COMPAT bit in VS 2005. The only difference I’m aware of is that the SDK (and therefore the location of SN.EXE) has moved.

Comments (20)

  1. goran.kimovski says:

    Hey Ed,

    your blog is timed as if I asked for it 😉

    I have a question around the impact of NXCOMPAT and DEP on ASP.NET applications which use interops to work with COM components, in particular when the native components are built with pre-VS2005, i.e. link o/use pre-ATL80.

    My understanding is that the ASP.NET worker process is not marked with NXCOMPAT, thus even if the C# compiler outputs NX compatible assembly, when run on IIS, DEP should not prevent the ASP.NET app from running. Is this correct?

    If this is not correct, i.e. the process is NXCOMPAT, my next question would be if aspnet_compiler.exe also produces NXCOMPAT assemblies when .NET 2.0 fwk SP1 is installed on the IIS machine? If that is true, is there a risk that an ASP.NET app that was running fine with .NET 2.0 fwk RTM all of a sudden starts to fail when the ASPX files get recompiled?

    Thank you,


  2. rbirkby says:

    To complicate matters further, there are 2 versions of sn.exe – 32bit and 64bit. The 64bit one AFAIK isn’t shipped with the NDP. It comes as part of the Windows SDK.

  3. Welcome to the thirty-eighth Community Convergence. These posts are designed to keep you in touch with

  4. Spike0xFF says:

    Hi Ed – I just ran into this problem – or rather, a panicky user of my company’s ActiveX control ran into it.

    It’s listed as an open issue over on the Connect site, so I pointed to your blog entry as a possible work-around.

    I’m torn between absolutely admiring your work – I’ve worked on a few compilers – and needing to say, this NXCOMPAT thing was kind of rude.  I don’t mean that personally – may I explain?

    Figure 10,000 developers out there, who maintain apps that use 3rd party ActiveX controls and who are working in VS. They upgrade their IDE at some point, then (possibly at a completely different time) their app gets launched on Vista. Up comes this message: "Unable to get window handle for the EZTwainX control, windowless ActiveX controls are not supported."  Notice that the message names the control, and precisely describes the problem (incorrectly, but precisely.)  What does the developer do? Goes off to ding the vendor of the control, because it has been clearly identified as the cause of the problem: "Hey, your control doesn’t work on Vista!" The control vendor, if they still exist, scratches their head – in my case, my control has been in development and use on Vista since August. I check the code: Nope, it’s always windowed. What the heck? Google, read, google, read some more – with luck and patience, find your blog entry.


    1. Rebuild my control using VS 2005 or 2008, retest, and redistribute to app developer, who updates it in his app, retests, and redistributes his (or her) app…

    2. Have developer rework their build process using your suggestions.

    3. Or, as suggested by one poster – disable NX on any affected Vista machine! (it’s a one-liner)

    Suppose the control and application developers manage to handle each incident for 100$.  Cost in the field: $1,000,000 (US).  Unless you have reason to believe there are fewer than 10,000 developers babysitting apps that use ActiveX controls built with VS2003 or earlier?  Personally, I’d bet the number is higher.  I understand the asymmetry of the situation, just wanted to put "a bug in your ear" as my mother used to say.

  5. Spike0xFF says:

    I forgot to say what really made me mad about this NXCOMPAT thing: It’s wrong! It’s a bug!  Writing a file with the NXCOMPAT flag, without making *any effort* to verify that the file is actually NX-compatible, is a bug.  It may be politically correct, but it isn’t any less of a bug than marking all exe’s as ’64-bit code’ because "64 bits is twice as cool!"  Investing effort to implement a bug, and then shipping it?? What were you thinking?

  6. laue says:

    在VS 2008中使用非托管DLL的时候,可能出现内存位置访问无效的错误,文章介绍了我找寻到的解决方案

  7. kadorken@thinkage.ca says:

    We are now busy tracking down DEP errors (from within the .NET library) in OUR application (i.e. we are now testing Microsoft’s code in our application)  just because we now have .NET SP1 installed on our development computer. Our (just) released application was built just before .NET SP1 magically appeared on our build computer so our current customers are SAFE for now. However, I just discovered our build computer has been updated; Magically our application has now been blessed with NXCOMPAT; it will now fail (IN the MICROSOFT .NET LIBRARY NOT OUR CODE). Good thing people have started blogging about this (and we found this one) before I inadvertently (WITHOUT KNOWLEDGE) released a update to our application with potential bugs in it.

    Thanks for NOT providing a compiler switch so I can add even MORE lines to our Postbuild.cmd process.

    Not a happy camper.

  8. behearn says:

    This decision has a big impact for our product, too.  We’re about to release a new version and suddenly QA starts finding the DEP error in web pages, where there were none before.  Product management is freaking out. There is no indication in the error messages or logs we can find about exactly what the problem is.  So I end up googling it and find this blog.  Well, I sincerely appreciate that it’s documented somewhere, but…

    We use many third party components in our ASP.NET and WinForms applications that we cannot recompile.

    It is an extremely poor decision on Microsoft’s part to have made a "breaking change" like this in a service pack that gets automatically deployed via windows update!  We are upset about this because we didn’t expect breaking changes in a service pack, and now have to dedicate time to deal with it.  We have enough problems of our own to deal with without Microsoft making matters worse.  My feedback is this: put "breaking changes" into major releases of the framework, rather than into a "mandatory" service pack.  

    Disappointed and wary of future service packs

  9. hkabla says:


    I have a piece of code that compiles under MS Studio 2008 and works fine on Windows Vista. But the same .exe generates a ‘execution denied’ error on XP. Is there a chance that this strange behavior on XP comes from DEP? Could you help me find the way to fix this?

  10. GWardell says:


    So far I haven’t been bit by this so I think this is funny because not executing data pages has been built into Intel chips since the 80386 and on into the current Pentium chips.  This was a "feature" of the old CTOS operating system when running in "protected mode".

    The problem was Windows 32 bit mode didn’t take advantage of it, choosing instead to use all 32bits for a memory address instead of using the segment descriptor and offset method needed for protected mode.

  11. asmundwego@hotmail.com says:

    I tried to run it on my exe, and it worked fine.

    Then I tried to include it in the post-build event like you said:

    call $(DevEnvDir)..toolsvsvars32.bat

    editbin.exe /NXCOMPAT:NO $(TargetPath)

    This gave the following error when I build it:

    The command "call C:Program FilesMicrosoft Visual Studio 9.0Common7IDE..toolsvsvars32.bat

    editbin.exe /NXCOMPAT:NO D:WorkDotNetRadiusStudio.NETRadiusStudiobinReleaseStudioVision.exe" exited with code 9009.

    This is also a problem inside Visual Studio, because it is a GUI control that fails to load in the forms designer. Could this be solved by running EDITBIN.EXE on devenv.exe?

  12. rajshreedugar says:

    Hi Awe,

    try the following in the post build event command line:-

    call "$(DevEnvDir)….VCbinvcvars32.bat"

    call "$(DevEnvDir)….VCbineditbin.exe" /NXCOMPAT:NO "$(TargetPath)"

    This works fine for VS2005. You might want to change the location if you are using any other versions of VS. But be sure to include the path within quotes.



  13. Windows vista wont Allow ATL control on the machine. We have Data Execution Prevention to stop Executing

  14. N!kky says:

    Hi All,

    I’ve got a similar issue. I’ve got a bug with by COM Interop and by using the following command in my build it get rids of the issue:

    call $(DevEnvDir)..toolsvsvars32.bat

    editbin.exe /NXCOMPAT:NO $(TargetPath)

    I’ve got it to work without signing my assemblies with a strong Name. However when we release our software we need to sign our assemblies using a .snk file. I’ve added the above code to my post build event however i can no longer run my app since it fails with Strong Validation Failed. What i need to do is call the above code and then sign my .exe file. How do i do this through the post build events? I’m currently using the Signing tab in visual studio 9 in my projects properties to sign my assemblies. Is there any other way to do this via the post build event?

    Have seen the following command but can not get it to work because i dont know what to put for MyModule.netmodule parameter

    al /out:MyAssembly.dll MyModule.netmodule /keyfile:sgKey.snk

    Any ideas? Any suggestions will be help. Thanks in advance.

    Regards Nik

  15. ajsllc says:

    I added this to my post-build event on a VB project.

    call "$(DevEnvDir)….VCbinvcvars32.bat"

    call "$(DevEnvDir)….VCbineditbin.exe" /NXCOMPAT:NO "$(TargetPath)"

    It executes successfully, but if the "primary output" of that project is included in a deployment project, the exe that gets included in the output MSI does NOT have DEP disabled.

    I have found that targetpath points to …..projectname\binx86Releaseprojectname.exe

    by experimentation, I have also found that if I edit bin ……projectnamebinx86Release\……objx86releaseprojectname.exe

    that is, the obj folder instead of the bin folder

    then the exe that gets included in the MSI DOES have DEP disabled.

    I’m a happy camper, my problem is resolved, but I am curious as to why.

    Is it that the deployment project pulls the output from the wrong folder,

    or is it some timing issue about when things are copied from obj to bin?

  16. ajsllc says:

    I should have added that I am using Visual Studio 2008

  17. sdasari says:

    I am using VS 2005 and Mappoint Active X control, when i build the application on Vista i am getting the error Mappoint Failed to Load. The i have added the  

    call "$(DevEnvDir)….VCbinvcvars32.bat"

    call "$(DevEnvDir)….VCbineditbin.exe" /NXCOMPAT:NO "$(TargetPath)"

    and executed the application, this time Mappoint is working fine. When i deploy same project with ClickOnce deployment, i am getting Mappoint Failed to load on Vista Desktop. Please suggest me, how can i solve this problem.

  18. rowter says:

    I got a mappoint failed to load error.

    What should i include in the "$(TargetPath")" . What should this be pointing to?

  19. Sharad says:

    Is Ed Maurer beiing facetitious when he says they love it so much!!?? Talk of "seemless backward compatiblity"

  20. Vinod.P.K says:

    Hi ,

    I have a legacy  COM dll  built in VC++6.0

    Could you please let me know if there is a way to make it  DEP  compatible in Visual studio 6.0?

    Please let me know. Your help in this is greatly appreciated.