<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>The NT DLL Loader: DLL_PROCESS_ATTACH reentrancy - step 3 - quality requirements</title><link>http://blogs.msdn.com/mgrier/archive/2005/06/24/432455.aspx</link><description>Now we're loaded for bear! We understand how PEs which are either launched via CreateProcess() or loaded via LoadLibrary() are the roots of directed cyclic graphs. Each new graph is turned into a linear initialization-order list where nodes further from</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: The NT DLL Loader: DLL_PROCESS_ATTACH reentrancy - step 3 - quality requirements</title><link>http://blogs.msdn.com/mgrier/archive/2005/06/24/432455.aspx#432481</link><pubDate>Sat, 25 Jun 2005 02:26:15 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:432481</guid><dc:creator>DanT</dc:creator><description>Is it a crash due to the initializer to whatever loaded foo.dll will succeed because it may not call GetProcAddress in its initializer (only LoadLibrary())? So further calls into that library will explode, because they will drop the GetProcAddress()?</description></item><item><title>re: The NT DLL Loader: DLL_PROCESS_ATTACH reentrancy - step 3 - quality requirements</title><link>http://blogs.msdn.com/mgrier/archive/2005/06/24/432455.aspx#432505</link><pubDate>Sat, 25 Jun 2005 04:04:38 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:432505</guid><dc:creator>LarryOsterman</dc:creator><description>Dan, &lt;br&gt;&lt;br&gt;What wll the DLL_PROCESS_ATTACH routine return for the initializer for bar.dll?</description></item><item><title>re: The NT DLL Loader: DLL_PROCESS_ATTACH reentrancy - step 3 - quality requirements</title><link>http://blogs.msdn.com/mgrier/archive/2005/06/24/432455.aspx#432645</link><pubDate>Sat, 25 Jun 2005 21:43:12 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:432645</guid><dc:creator>DanT</dc:creator><description>The code snippet seems to suggest it will return OK, even though the foo.dll isn't initialized properly.&lt;br&gt;Can't the loader do any checking to see if a dependency fails? It seems like it could mark the  dlls loaded if a dependency fails along the line somewhere. Since this is in PROCESS_ATTACH, it could verify dependencies on return of DllMain, before it returns to whoever loaded bar.dll.&lt;br&gt;&lt;br&gt;Sorry it took so long... RSS needs a more visible way to track comments (just found the link buried in the site rss).</description></item><item><title>re: The NT DLL Loader: DLL_PROCESS_ATTACH reentrancy - step 3 - quality requirements</title><link>http://blogs.msdn.com/mgrier/archive/2005/06/24/432455.aspx#432985</link><pubDate>Mon, 27 Jun 2005 11:59:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:432985</guid><dc:creator>Graham Harper</dc:creator><description>My guess is if the call to GPA returns NULL the calling code should be checking GetLastError() to see the reason for the failure. &lt;br&gt;&lt;br&gt;It is entirely possible (I assume) for GPA to fail for reasons that don't warrant SomeOther.dll propagating a FALSE return to the loader out of its initialization section. On-the-other-hand there are some circumstances where SomeOther.dll MUST fail in order accurately reflect the state of its dependencies.</description></item><item><title>User32.dll init in Longhorn</title><link>http://blogs.msdn.com/mgrier/archive/2005/06/24/432455.aspx#433355</link><pubDate>Tue, 28 Jun 2005 17:36:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:433355</guid><dc:creator>Radim Picha</dc:creator><description>mgrier,&lt;br&gt;I would need just one thing - could LH's user32.dll in it's DllMain call GPA in order to init imm32.dll it loaded?&lt;br&gt;&lt;br&gt;Description:&lt;br&gt;User32.dll's DllMain in Longhorn loads imm32.dll. Imm32.dll's DllMain then fills imm entries (pointers to imm functions) in user32's data. After loading imm32.dll, user32.dll's DllMain calls one of those imm entries. If the entry (ImmRegisterClient)returns FALSE, user32's init is stopped and DllMain returns FALSE too (user32 remains semi-inited).&lt;br&gt;&lt;br&gt;When user32 is &amp;quot;preloaded&amp;quot; (loaded when LdrpLdrDatabaseIsSetup == FALSE; before executing DllMains of modules statically linked to main module), imm32 gets loaded but it's DllMain is not called (at this place I would need user32 to init imm32 via GPA). User32's DllMain then goes on and calls entry for ImmRegisterClient. Entry for ImmRegisterClient is supposed to be filled by imm32's DllMain; originally it points to simple stub that returns TRUE in LH 5048 but FALSE in 5082. That's why in LH 5048 user32's DllMain goes on but on LH5082 it returns FALSE immediatelly.&lt;br&gt;&lt;br&gt;[Of course, when user32.dll is loaded when LdrpLdrDatabaseIsSetup == TRUE; when/after executing DllMains of modules statically linked to main module), imm32 gets loaded, it's DllMain is called and fills imm entries.]&lt;br&gt;&lt;br&gt;==================&lt;br&gt;Second problem (any NT): when there's nothing to init, TLS callbacks of main module are not inited too (called with process_attach). You can see it in LdrpRunInitializeRoutines. Example: - create .exe that has tls callbacks and imports from kernel32 only) and run it on XP+.&lt;br&gt;&lt;br&gt;Thank you,&lt;br&gt;Radim Picha</description></item><item><title>re: The NT DLL Loader: DLL_PROCESS_ATTACH reentrancy - step 3 - quality requirements</title><link>http://blogs.msdn.com/mgrier/archive/2005/06/24/432455.aspx#433362</link><pubDate>Tue, 28 Jun 2005 18:08:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:433362</guid><dc:creator>mgrier</dc:creator><description>Radim, I'll contact you directly about the user32 issue.  I'm unaware of any cases where user32 is loaded that early so I'd like to understand.  In general the pattern you're using is dangerous, but in practice it's almost impossible to dynamically load user32 so barring cycles, it typically works.&lt;br&gt;&lt;br&gt;RE: TLS:&lt;br&gt;&lt;br&gt;loader-based TLS has never worked until recently for dynamically loaded PEs since the whole TLS block has to be allocated at the time of thread initialization.  There was a checkin to enable this recently for the dynamic cases so you might be able to depend on this feature in LH.  In practice, due to the general loader reentrancy issues, you're better off managing your TLS manually anyways.</description></item><item><title>re: The NT DLL Loader: DLL_PROCESS_ATTACH reentrancy - step 3 - quality requirements</title><link>http://blogs.msdn.com/mgrier/archive/2005/06/24/432455.aspx#437566</link><pubDate>Mon, 11 Jul 2005 19:58:06 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:437566</guid><dc:creator>Radim Picha</dc:creator><description>mgrier,&lt;br&gt;I've just tested LH 5098 and the behaviour is the same. There's nothing so hard to understand - the situation is the same:&lt;br&gt;user32.dll loads imm32.dll from it's DllMain on DLL_PROCESS_ATTACH. imm32 fills in some entries (pointers) in &amp;quot;user32 table for imm32&amp;quot;.&lt;br&gt;&lt;br&gt;This is all. It is supposed that imm32's DllMain is executed (with DLL_PROCESS_ATTACH)-&amp;gt; imm32.dll is supposed to be loaded at time when simple LoadLibrary not only loads module but also calls its DllMain. But what if imm32 is loaded in time when DllMain is not called?&lt;br&gt;&lt;br&gt;Once again:&lt;br&gt;a) user32 is loaded at time when LoadLibrary also executes DllMain:&lt;br&gt;user32.DllMain -&amp;gt; LoadLibrary(&amp;quot;imm32&amp;quot;) -&amp;gt; imm32.DllMain -&amp;gt; FillInImmEntriesInUser32()&lt;br&gt;&lt;br&gt;b) user32 is loaded at time when LoadLibrary  doesn't execute DllMain:&lt;br&gt;user32.DllMain -&amp;gt; LoadLibrary(&amp;quot;imm32&amp;quot;)&lt;br&gt;&lt;br&gt;The only thing that works in case b) as module initializator is calling GPA. Therefore I need user32.dll to call GPA from its DllMain immediatelly after LoadLibrary(&amp;quot;imm32&amp;quot;).&lt;br&gt;&lt;br&gt;You could tell me : &amp;quot;hey what is it? loading a dll before 'process init' is not allowed&amp;quot;. I could answer: &amp;quot;what about application verifier, what about shim engine?&amp;quot;.&lt;br&gt;&lt;br&gt;TLS.&lt;br&gt;I know what's written in books (TLS works for statically modules only). Therefore I wrote what new I found. I wrote nothing about (dynamic) loading. Just create simple .exe (it means static module) with TLS callbacks that imports from kernel32.dll only, run it on XP+ (kernel32.dll is preloaded and inited) and you will see that the callbacks are not called (because all modules (kernel32.dll, resp. ntdll.dll) were already inited. There's  a logical bug in LdrpRunInitializeRoutines.&lt;br&gt;This bug is Nt-omnipresent it is not LH-specific.&lt;br&gt;&lt;br&gt;That's all I had to say and I am true.&lt;br&gt;My e-mail is Radim.Picha@seznam.cz&lt;br&gt;&lt;br&gt;Thank you.</description></item></channel></rss>