{"id":96295,"date":"2017-06-07T07:00:00","date_gmt":"2017-06-07T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=96295"},"modified":"2019-03-13T01:12:37","modified_gmt":"2019-03-13T08:12:37","slug":"20170607-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20170607-00\/?p=96295","title":{"rendered":"On enabling NX and ASLR for a module after the fact"},"content":{"rendered":"<p>A customer wanted to enable NX (also known as Data Execution Prevention, or DEP) and ASLR for some executables and DLLs. There are two ways of doing this: <\/p>\n<ul>\n<li>Enable the options at link time by passing the     linker command line options     <code>\/NX&shy;COMPAT<\/code> and     <code>\/DYNAMIC&shy;BASE<\/code>,     and for good measure     <code>\/HIGH&shy;ENTROPYVA<\/code>. <\/li>\n<li>    Build the modules the usual way,     and then use the <code>EDITBIN<\/code>     program with those same command line options     to enable the features on the files in question. <\/li>\n<\/ul>\n<p>For reasons the customer didn&#8217;t provide (but which I can guess),&sup1; there are a handful of files that they cannot relink, so they are forced to use the <code>EDITBIN<\/code> approach for those files. <\/p>\n<p>What the customer found was that both the linker and the <code>EDITBIN<\/code> approaches seemed to be fine with <code>\/NX&shy;COMPAT<\/code>. But the story was different with the <code>\/DYNAMIC&shy;BASE<\/code> flag. <\/p>\n<p>Specifically, the linker approach was creating a larger file due to a new <code>.reloc<\/code> section. The file produced by the <code>EDITBIN<\/code> approach didn&#8217;t have a <code>.reloc<\/code> section, and dumping the header reports <b>Relocations stripped<\/b>. Furthermore, when running <code>EDITBIN<\/code>, it generated the ominous warning message, &#8220;Warning LNK4259: &#8216;\/DYNAMIC&shy;BASE&#8217; is not compatible with &#8216;\/FIXED&#8217;; image may not run.&#8221; It appears that linking with the <code>\/DYNAMIC&shy;BASE<\/code> flag implicitly sets <code>\/FIXED:NO<\/code>, but the <code>EDITBIN<\/code> command doesn&#8217;t apply the same behavior, and it doesn&#8217;t support the <code>\/FIXED:NO<\/code> command line option. <\/p>\n<p>The customer had the following questions: <\/p>\n<ul>\n<li>Are the linker approach and the the <code>EDITBIN<\/code> approach for enabling <code>\/NX&shy;COMPAT<\/code> equivalent? <\/li>\n<\/ul>\n<p>Yes, enabling NX via the linker <code>\/NX&shy;COMPAT<\/code> flag is equivalent to enabling it with <code>EDITBIN<\/code>. In both cases, they set the <code>IMAGE_<\/code><code>DLL&shy;CHARACTERISTICS_<\/code><code>NX_<\/code><code>COMPAT<\/code> bit in the <code>IMAGE_<\/code><code>OPTIONAL_<\/code><code>HEADER<\/code>&#8216;s <code>Dll&shy;Characteristics<\/code>. <\/p>\n<ul>\n<li>Are the linker approach and the the <code>EDITBIN<\/code> approach for enabling <code>\/DYNAMIC&shy;BASE<\/code> equivalent? <\/li>\n<\/ul>\n<p>The answer depends on what color glasses you&#8217;re wearing. If you&#8217;re wearing <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20110512-00\/?p=10683\">kernel-colored glasses<\/a>, then yes, the two approaches are the same because both set the <code>IMAGE_<\/code><code>DLL&shy;CHARACTERISTICS_<\/code><code>DYNAMIC_<\/code><code>BASE<\/code> bit in the <code>IMAGE_<\/code><code>OPTIONAL_<\/code><code>HEADER<\/code>&#8216;s <code>Dll&shy;Characteristics<\/code>. But in reality, they are not the same, because of the behavior noted above with respect to relocations. If you ask the linker for <code>\/DYNAMIC&shy;BASE<\/code>, it will default to <code>\/FIXED:NO<\/code> because <code>\/DYNAMIC&shy;BASE<\/code> means &#8220;My base address can be moved around&#8221;, which is the opposite of <code>\/FIXED<\/code>, which means &#8220;My base address cannot change.&#8221; <\/p>\n<p>If you say <code>\/FIXED<\/code>, then the linker does not generate &#8220;relocations&#8221;, which are the bits of information that describe what adjustments need to be made to your DLL in order to make it happy at its new location. Trying to turn on <code>\/DYNAMIC&shy;BASE<\/code> with <code>EDITBIN<\/code> on a binary that is <code>\/FIXED<\/code> doesn&#8217;t work because <code>EDITBIN<\/code> doesn&#8217;t know how to regenerate the <code>.reloc<\/code> section. <\/p>\n<p>If you want to enable <code>\/DYNAMIC&shy;BASE<\/code>, then you cannot link with <code>\/FIXED<\/code>. <\/p>\n<ul>\n<li>Are there any adverse consequences of mixing ASLR-enabled DLLs and non-ASLR-enabled DLLs in the same process? <\/li>\n<\/ul>\n<p>There are no consequences beyond those already stated on the tin. The ASLR-enabled binaries will be subject to ASLR, and the non-ASLR-enabled binaries will not. You can mix and match freely within a process. Just be aware that the non-ASLR-enabled binaries will not be randomly relocated, which means that those binaries will not benefit from the security protections provided by ASLR. <\/p>\n<ul>\n<li>Are there any adverse consequences of mixing NX-enabled DLLs and non-NX-enabled DLLs in the same process? <\/li>\n<\/ul>\n<p>The NX setting is process-wide, and the process takes its NX state from the <code>\/NX&shy;ENABLED<\/code> state of the executable, <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20110824-00\/?p=9823\">not from any DLLs<\/a>. It&#8217;s yet another one of the module flags that <a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20140502-00\/?p=1093\">are meaningless for DLLs<\/a>. So mix it up in the DLLs all you want. Nobody will care, because the flag is ignored for DLLs anyway. <\/p>\n<ul>\n<li>Are there any adverse consequences of mixing EXEs and DLLs which use different approaches for enabling NX and\/or ASLR? For example, is there an unexpected interaction between an EXE which enabled ASLR with <code>EDITBIN<\/code> and a DLL that enabled ASLR with a linker switch? How can I tell whether an EXE or DLL has had its NX or ASLR bit set via the linker as opposed to the <code>EDITBIN<\/code> program? <\/li>\n<\/ul>\n<p>There is no way to tell how the NX or ASLR attributes were enabled. Using the linker or <code>EDITBIN<\/code> both lead to the same binary. There&#8217;s nothing that records who set the bit. As a result, it doesn&#8217;t matter how you enabled NX and ASLR. The system behaves the same regardless of how you enabled them. <\/p>\n<p><b>Bonus chatter<\/b>: There is <a HREF=\"https:\/\/msdn.microsoft.com\/en-us\/library\/bb430720.aspx\">some text on MSDN<\/a> (which got copied into <a HREF=\"https:\/\/technet.microsoft.com\/en-us\/library\/security\/dn848375.aspx\">a glossary on TechNet<\/a>) which says <\/p>\n<blockquote CLASS=\"q\"><p>For a component to support ASLR, all components that it loads must also support ASLR. For example, if A.exe consumes B.dll and C.dll, all three must support ASLR. <\/p><\/blockquote>\n<p>Nobody is quite sure how that text got into the documentation, since it&#8217;s not true. One of the original authors of that article surmises that perhaps what they were trying to say was &#8220;In order for a process to take full advantage of ASLR, the executable and all DLLs must support ASLR,&#8221; but somehow the message got garbled during editing. <\/p>\n<p>Given what we already know about <a HREF=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/\">how the loader shares pages in the face of ASLR<\/a>, having a DLL be subject to ASLR in some processes but not others would create extra work for the loader, because it now has to be able to keep up to two copies of every DLL in memory: A randomly-located version for ASLR, and a non-relocated version for non-ASLR. It&#8217;s extra work for no real benefit, so I can understand why they don&#8217;t do it. <\/p>\n<p>&sup1; I can think of a few reasons why the customer cannot relink all of the files. One possibility is that they don&#8217;t have the source code any more. Another is that they have the source code, but they don&#8217;t have the build tools any more. (For example, it may be built with a very old compiler that doesn&#8217;t work any more.) Or they have the source code, and they have the tools, but they simply don&#8217;t want to take the risk that relinking the file might result in an unexpected change to the program. (For example, if it was linked with an older version of the linker, and they have since upgraded to a newer version.) <\/p>\n","protected":false},"excerpt":{"rendered":"<p>You can flip the bit, but you can&#8217;t regenerate relocation information.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-96295","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>You can flip the bit, but you can&#8217;t regenerate relocation information.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96295","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=96295"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96295\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=96295"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=96295"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=96295"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}