{"id":2794,"date":"2015-01-28T16:49:21","date_gmt":"2015-01-28T16:49:21","guid":{"rendered":"http:\/\/www.hexacorn.com\/blog\/?p=2794"},"modified":"2015-01-28T16:49:21","modified_gmt":"2015-01-28T16:49:21","slug":"beyond-good-ol-run-key-part-25","status":"publish","type":"post","link":"https:\/\/www.hexacorn.com\/blog\/2015\/01\/28\/beyond-good-ol-run-key-part-25\/","title":{"rendered":"Beyond good ol\u2019 Run key, Part 25"},"content":{"rendered":"<p>I have already covered persistence mechanisms that rely on localization features implemented by popular programming platforms (<a href=\"https:\/\/www.hexacorn.com\/blog\/2015\/01\/03\/beyond-good-ol-run-key-part-21\/\">MFC<\/a> and <a href=\"https:\/\/www.hexacorn.com\/blog\/2015\/01\/01\/beyond-good-ol-run-key-part-20\/\">Visual Basic<\/a>). These features support localization efforts by automatically loading language-specific DLLs anytime a program written in any of these platforms starts.<\/p>\n<p>You may (or not) be wondering if there is more to it.<\/p>\n<p>What may immediately come to mind here is a simple question: what about Delphi (or more broadly: what about Borlandish apps)?<\/p>\n<p>When the Borlandish application is executed it queries very characteristic registry keys that you may see in the Process Monitor anytime you start f.ex. a Delphi application:<\/p>\n<ul>\n<li>\n<pre>HKCU\\Software\\Borland\\Locales<\/pre>\n<\/li>\n<li>\n<pre>HKLM\\Software\\Borland\\Locales<\/pre>\n<\/li>\n<li>\n<pre>HKCU\\Software\\Borland\\Delphi\\Locales<\/pre>\n<\/li>\n<\/ul>\n<p>Other (newer) Borlandish applications may include not only Delphi reference, but also Code Gear and Embarcadero:<\/p>\n<ul>\n<li>\n<pre>HKCU\\Software\\CodeGear\\Locales<\/pre>\n<\/li>\n<li>\n<pre>HKCU\\Software\\Embarcadero\\Locales<\/pre>\n<\/li>\n<\/ul>\n<p>and query them as well. These keys are queried for an entry which is a full path of the executed application e.g. for c:\\foo.exe it could be:<\/p>\n<ul>\n<li>\n<pre>HKCU\\Software\\Borland\\Locales<\/pre>\n<ul>\n<li>\n<pre>c:\\foo.exe = abc<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>If such entry exists, it should contain a value maximum 5 bytes long and identify a file extension of the requested localization library. In our example it is &#8216;abc&#8217;. The file extension will then be appended to the file name of the application (after removing the original file extension, typically &#8216;.exe&#8217;). Notably, if the entry is not there, or more than 5 bytes long the application will try to use the value of a Deafult key under<\/p>\n<ul>\n<li>\n<pre>HKCU\\Software\\Borland\\Locales<\/pre>\n<ul>\n<li>{Default} = def<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>If none of the 2 values exist, the file extension for the localization DLL will be based on the current locale for the calling thread e.g. for English it could be .ENU, .EN.<\/p>\n<p>Once the file extensions are sorted the program will call LoadLibraryEx API and attempt\u00a0 to load the localization DLL as follows:<\/p>\n<ul>\n<li>&lt;appname&gt;.&lt;file extension&gt; if Locale registry entries exist<\/li>\n<li>&lt;appname&gt;.ENU &#8211; if the above fails<\/li>\n<li>&lt;appname&gt;.EN &#8211; if the above fails<\/li>\n<\/ul>\n<p>Also, as a side effect of the way LoadLibraryEx works, the API will query for the following DLL names and will load them if .ENU\/.EN files don&#8217;t exist (respectively):<\/p>\n<ul>\n<li>&lt;appname&gt;.ENU.DLL<\/li>\n<li>&lt;appname&gt;.EN.DLL<\/li>\n<\/ul>\n<p>The good news is that all these libraries are loaded using LoadLibraryEx functions with the LOAD_LIBRARY_AS_DATAFILE flag. So, while Borlandish apps do support external localization DLLs they load them properly i.e. not as a code, but as data. As far as I can tell this was implemented correctly from the very first version of Delphi that supported localized DLLs.<\/p>\n<p>That pretty much kills the idea of using such DLLs as a persistence mechanism.<\/p>\n<p>Well sort of, you could always use a pattern matching to find a DLL loading routine in the existing Borlandish binary and patch it. Patch requires a flip of a single bit to disable LOAD_LIBRARY_AS_DATAFILE (0x2) &#8211; this would enable loading of localization DLLs as a code.\u00a0 Quite honestly, this is lame and while it could be a good idea a decade ago or so, now any modification to an existing .exe will most likely trigger an AV alert (since it looks like a possible viral infection).<\/p>\n<p>So, while it&#8217;s not really a persistence mechanism it was still worth exploring even if just for the sake of ruling it out and understanding what these Locales keys are.<\/p>\n<p>If you are a bit disappointed I can only say that the topic of this post leads us directly to the part 26. It will be about yet another Frankenstein&#8217;s Monster \ud83d\ude42<\/p>\n<p>Stay tuned.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have already covered persistence mechanisms that rely on localization features implemented by popular programming platforms (MFC and Visual Basic). These features support localization efforts by automatically loading language-specific DLLs anytime a program written in any of these platforms starts. &hellip; <a href=\"https:\/\/www.hexacorn.com\/blog\/2015\/01\/28\/beyond-good-ol-run-key-part-25\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[13,35,15,19,9],"tags":[],"_links":{"self":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/2794"}],"collection":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/comments?post=2794"}],"version-history":[{"count":3,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/2794\/revisions"}],"predecessor-version":[{"id":2801,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/posts\/2794\/revisions\/2801"}],"wp:attachment":[{"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/media?parent=2794"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/categories?post=2794"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hexacorn.com\/blog\/wp-json\/wp\/v2\/tags?post=2794"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}