Sorry

This feed does not validate.

Source: http://kobyk.wordpress.com/feed/

  1. <?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
  2. xmlns:content="http://purl.org/rss/1.0/modules/content/"
  3. xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  4. xmlns:dc="http://purl.org/dc/elements/1.1/"
  5. xmlns:atom="http://www.w3.org/2005/Atom"
  6. xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  7. xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  8. xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
  9. >
  10.  
  11. <channel>
  12. <title>KK&#039;s Blog</title>
  13. <atom:link href="https://kobyk.wordpress.com/feed/" rel="self" type="application/rss+xml" />
  14. <link>https://kobyk.wordpress.com</link>
  15. <description>I don&#039;t have to put up with this shit...</description>
  16. <lastBuildDate>Sat, 26 Nov 2011 09:04:25 +0000</lastBuildDate>
  17. <language>en</language>
  18. <sy:updatePeriod>
  19. hourly </sy:updatePeriod>
  20. <sy:updateFrequency>
  21. 1 </sy:updateFrequency>
  22. <generator>http://wordpress.com/</generator>
  23. <cloud domain='kobyk.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
  24. <image>
  25. <url>https://s0.wp.com/i/buttonw-com.png</url>
  26. <title>KK&#039;s Blog</title>
  27. <link>https://kobyk.wordpress.com</link>
  28. </image>
  29. <atom:link rel="search" type="application/opensearchdescription+xml" href="https://kobyk.wordpress.com/osd.xml" title="KK&#039;s Blog" />
  30. <atom:link rel='hub' href='https://kobyk.wordpress.com/?pushpress=hub'/>
  31. <item>
  32. <title>Modifying a Visual C++ 2010 project&#8217;s Platform Toolset programmatically with IVCRulePropertyStorage</title>
  33. <link>https://kobyk.wordpress.com/2011/11/26/modifying-a-visual-c-2010-projects-platform-toolset-programmatically-with-ivcrulepropertystorage/</link>
  34. <comments>https://kobyk.wordpress.com/2011/11/26/modifying-a-visual-c-2010-projects-platform-toolset-programmatically-with-ivcrulepropertystorage/#comments</comments>
  35. <dc:creator><![CDATA[Koby Kahane]]></dc:creator>
  36. <pubDate>Sat, 26 Nov 2011 09:04:25 +0000</pubDate>
  37. <category><![CDATA[C++]]></category>
  38. <guid isPermaLink="false">http://kobyk.wordpress.com/?p=56</guid>
  39.  
  40. <description><![CDATA[Back from a long hiatus. Lately I&#8217;ve been migrating a large legacy code base from Visual C++ 2008 to Visual C++ 2010. Visual C++ 2010 supports Native Multi-Targeting, which lets you use the Visual Studio 2010 IDE and the new &#8230; <a href="https://kobyk.wordpress.com/2011/11/26/modifying-a-visual-c-2010-projects-platform-toolset-programmatically-with-ivcrulepropertystorage/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
  41. <content:encoded><![CDATA[<p>Back from a long hiatus.</p>
  42. <p>Lately I&#8217;ve been migrating a large legacy code base from Visual C++ 2008 to Visual C++ 2010. Visual C++ 2010 supports Native <a title="C++ Native Multi-Targeting" href="http://blogs.msdn.com/b/vcblog/archive/2009/12/08/c-native-multi-targeting.aspx">Multi-Targeting</a>, which lets you use the Visual Studio 2010 IDE and the new MSBuild-based C++ project system (*.vcxproj files, etc.) while invoking a legacy compiler like Visual C++ 2008 for the actual build, or for invoking the modern compiler with special INCLUDE and LIB directory settings (e.g., using the Windows Driver Kit&#8217;s headers and import libraries).</p>
  43. <p>The &#8220;Platform Toolset&#8221; is the project setting which specifies which baseline compiler settings apply. Visual Studio 2010 bundles the &#8220;v100&#8221; platform toolset for using the Visual C++ 2010 compiler and the &#8220;v90&#8221; platform toolset for using the Visual C++ 2008 compiler. The Windows SDK 7.1 includes the &#8220;Windows7.1SDK&#8221; platform toolset which invokes the Visual C++ 2010 compiler, but with the SDK&#8217;s build environment. The latest Intel C++ Compiler includes a &#8220;Intel C++ Compiler XE 12.0&#8221; toolset, as well. A third party has even created a<a title="VS2003 Platform Toolset for VS2010" href="http://vs2003.blogspot.com/"> platform toolset for the antiquated Visual C++ 2003 compiler</a>.</p>
  44. <p>The IDE GUI exposes the Platform Toolset project setting in the General property sheet. By right clicking a project in Solution Explorer, clicking Properties and going to General under Configuration Properties, you can change the setting on a per-build configuration basis. Solution Explorer is clever enough to let you group select several or all of the projects in the open solution and group-modifying the platform toolset in the properties dialog. For many cases, this may be sufficient.</p>
  45. <p>However, if you want to modify the platform toolset en masse, but based on more complicated criteria, or just wish to achieve a higher degree of automation in the migration process, you may prefer to modify the setting programmatically like I did.</p>
  46. <p>Visual Studio has an automation model for modifying project settings and for many other IDE tasks. This object model is accessible from Visual Studio Macros (which have unfortunately been removed from the Visual Studio 11 Developer Preview) and from other forms of Visual Studio extensibility such as add-ins. After some browsing of the documentation and searching the Web, it is clear how to modify things like the project&#8217;s Linker OutputFile property. However, it took me a while to figure out how to access other properties like the PlatformToolset.</p>
  47. <p>It turns out that project settings that have appeared recently are not accessible in straightforward way like the older ones. That is, they are not properties of the VCProject object or its child objects. Instead, <a title="How to read/write the new Visual C++ project properties" href="http://blogs.msdn.com/b/visualstudio/archive/2010/01/15/how-to-read-write-the-new-visual-c-project-properties.aspx">there is a new interface</a> for manipulating these properties, <a title="IVCRulePropertyStorage" href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.vcprojectengine.ivcrulepropertystorage.aspx">IVCRulePropertyStorage</a>.</p>
  48. <p>With this interface, the PlatformToolset property in the General property sheet becomes easily accessible. To illustrate, the following is an example Visual Studio macro that changes the platform toolset of any project in the solution using the &#8220;v100&#8221; toolset to the &#8220;Windows7.1SDK&#8221; toolset:</p>
  49. <pre class="brush: vb; title: ; wrap-lines: false; notranslate">
  50.  
  51. Option Strict On
  52. Option Explicit On
  53.  
  54. Imports System
  55. Imports EnvDTE
  56. Imports EnvDTE80
  57. Imports EnvDTE90
  58. Imports EnvDTE90a
  59. Imports EnvDTE100
  60. Imports System.Diagnostics
  61. Imports Microsoft.VisualStudio.VCProject
  62. Imports Microsoft.VisualStudio.VCProjectEngine
  63.  
  64. Public Module Module1
  65. Sub RetargetProjects()
  66.  For Each p As Project In DTE.Solution.Projects
  67.    If p.Kind = vcContextGuids.vcContextGuidVCProject Then
  68.      Dim prj As VCProject = CType(p.Object, VCProject)
  69.  
  70.      For Each cfg As VCConfiguration In CType(prj.Configurations, IVCCollection)
  71.        Dim generalRule As IVCRulePropertyStorage = CType(cfg.Rules.Item(&quot;ConfigurationGeneral&quot;), IVCRulePropertyStorage)
  72.  
  73.        Dim currentPlatformToolset = generalRule.GetUnevaluatedPropertyValue(&quot;PlatformToolset&quot;)
  74.  
  75.        If currentPlatformToolset = &quot;v100&quot; Then
  76.          generalRule.SetPropertyValue(&quot;PlatformToolset&quot;, &quot;Windows7.1SDK&quot;)
  77.        End If
  78.      Next
  79.    End If
  80.  Next
  81. End Sub
  82. End Module
  83.  
  84. </pre>
  85. <p>You need to add references to the VCProject and VCProjectEngine assemblies in your macro project to access the types of the Visual C++ Project Model used in this macro.</p>
  86. <p>Stay tuned for more useful functionality of IVCRulePropertyStorage.</p>
  87. ]]></content:encoded>
  88. <wfw:commentRss>https://kobyk.wordpress.com/2011/11/26/modifying-a-visual-c-2010-projects-platform-toolset-programmatically-with-ivcrulepropertystorage/feed/</wfw:commentRss>
  89. <slash:comments>3</slash:comments>
  90. <media:content url="https://1.gravatar.com/avatar/1d5c3d0abc3891afb6e88eebc51b004c3ed48b5fc2bc4a0f0ff7f6e507c80ed4?s=96&#38;d=identicon&#38;r=G" medium="image">
  91. <media:title type="html">KK</media:title>
  92. </media:content>
  93. </item>
  94. <item>
  95. <title>Visual Studio 2010 Beta 2 debugger may be confused by your symbol path</title>
  96. <link>https://kobyk.wordpress.com/2009/11/05/visual-studio-2010-beta-2-debugger-may-be-confused-by-your-symbol-path/</link>
  97. <comments>https://kobyk.wordpress.com/2009/11/05/visual-studio-2010-beta-2-debugger-may-be-confused-by-your-symbol-path/#comments</comments>
  98. <dc:creator><![CDATA[Koby Kahane]]></dc:creator>
  99. <pubDate>Thu, 05 Nov 2009 18:30:37 +0000</pubDate>
  100. <category><![CDATA[C++]]></category>
  101. <category><![CDATA[Windbg]]></category>
  102. <guid isPermaLink="false">http://kobyk.wordpress.com/?p=52</guid>
  103.  
  104. <description><![CDATA[I&#8217;ve been evaluating Microsoft&#8217;s Visual Studio 2010 Beta 2 release recently on my Windows 7 x64 system. As can be expected, the beta has quite a few rough edges, but overall I like the new WPF-based IDE GUI and the &#8230; <a href="https://kobyk.wordpress.com/2009/11/05/visual-studio-2010-beta-2-debugger-may-be-confused-by-your-symbol-path/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
  105. <content:encoded><![CDATA[<p>I&#8217;ve been evaluating Microsoft&#8217;s Visual Studio 2010 Beta 2 release recently on my Windows 7 x64 system. As can be expected, the beta has quite a few rough edges, but overall I like the new WPF-based IDE GUI and the refreshed code Editor in particular (I like how selecting a block of code now preserves syntax highlighting while the block is highlighted, for instance).</p>
  106. <p>The new GUI does have some badness. I had particular distaste for the poor aliasing of tooltips in the editor. This can be seen, for example, when hovering over a function name like &#8220;printf&#8221;. The menu bar&#8217;s dark blue color scheme also appears rather peculiar.</p>
  107. <p>Besides the &#8220;bling&#8221;, notable changes include the Visual C++ 2010 CRT reverting to the traditional deployment model used by the Visual C++ 2003 CRT. More specifically, the CRT DLLs no longer use SxS binding (&#8220;Fusion&#8221;) and are now simply deployed to the &#8220;system32&#8221; directory or to the application&#8217;s directory, as desired. Dropping SxS has some obvious disadvantages (SxS binding redirects would no longer be able to redirect applications that load a private copy of the CRT DLLs to updated versions with bug fixes and security updates) but presumably the pain of integrating SxS deployment into the setup process, which required either an MSI installation or pseudo-documented use of the SxS API, resulted in too much negative feedback and they chose to revert to the legacy approach.</p>
  108. <p>Visual C++ projects are now built with MSBuild, like their C# and other .NET counterparts. This should have several benefits. One that comes to mind is the the Windows Installer XML Toolset&#8217;s Votive (its VS IDE integration component) should be able to support C++ projects as References in addition to .NET projects.</p>
  109. <p>A more important update to the project system is support for multi-targeting. Most of Microsoft&#8217;s discussions on the subject mainly deal with said support for .NET projects, with the new Visual Studio being able to target .NET 2.0 through .NET 4.0 on a per-project basis. However, similar support is offered for native multi-targeting. A per-project setting specifies the &#8220;toolset&#8221; with which it is to be built. The product comes built-in with toolset definitions for the VC++ 10 and the VC++ 9 compilers, but since toolset definitions are simple XML files describing tool paths, older compilers and custom definitions are easy to define. Indeed, a toolset definition can be found for the Windows 7 SDK build environment. I foresee using this functionality to build user-space applications with headers and tools from the Windows Driver Kit build environment, resulting in being able to link with the OS CRT (msvcrt.dll) in a clean way, without modifying global Visual C++ directory settings, but rather keeping the changes contained to specific projects.</p>
  110. <p>My enthusiasm for testing the product was struck a severe blow when my first attempt to run the Visual C++ debugger on a &#8220;Hello, World!&#8221; console application went awry. The IDE was hung for a good 15-20 seconds. The IDE sat frozen for quite a bit after F10 was pressed to initiate the debugging session, finally presented the console window for the test application and then spent some more time being frozen. After a lengthy wait, the session was finally ready.</p>
  111. <p>But the worst part was that when the debugging session was finally ready, debugging symbols for all modules except the application .exe and the VC 10 CRT were NOT loaded! It appeared as though the lengthy wait was all for naught.</p>
  112. <p>The experience was sufficiently poor for me to report it to Microsoft through one of the feedback channels. I was eventually contacted by helpful folks from the Visual Studio Debugger team and we analyzed the problem in an e-mail exchange. The performance issue is the result of problematic contents of the symbol path I configured for the debugger.</p>
  113. <p>As I mentioned, I&#8217;m evaluating the beta on a Windows 7 machine. For this reason, the Windows 7 symbol packages, available from Microsoft&#8217;s public symbols download page, are deployed in my system and are a part of the symbol path defined by the _NT_SYMBOL_PATH environment variable. Since this is an x64 machine and I find myself debugging 32-bit processes quite often, both the 32-bit and 64-bit symbol packages are installed. My initial symbol path was:</p>
  114. <p><em>C:\Symbols;C:\Symbols32;CACHE*C:\websymbols;SRV*http://msdl.microsoft.com/download/symbols</em></p>
  115. <p>The first issue with this symbol path is that the x64 symbols package (extracted to C:\Symbols) and the x86 symbols package (extracted to C:\Symbols32) are specified as directories in the symbol path, rather than symbol stores. This is what you&#8217;d expect from symbol packages designed for local deployment, but it turns out that the Windows 7 symbol packages, unlike the PDB packages for previous versions of Windows, come in the symbol store directory layout rather than the flat directory layout. This means, for example, that the symbols for ntdll.dll are in a path like <em>C:\Symbols\ntdll.pdb\CFF40300FD804691B73E12CF2A150EE02\ntdll.pdb</em> rather than the simpler <em>C:\Symbols\dll\ntdll.pdb</em>.</p>
  116. <p>I did not notice this issue, however, before installing Visual Studio 2010 Beta 2, because apparently Windbg doesn&#8217;t mind when stores are specified in this syntax, as it exercises some sort of heuristic to determine the layout of a symbol directory. However, Visual Studio 2010 Beta 2 is not as liberal. Examining its I/Os with Sysinternals Process Monitor determined that it wasn&#8217;t trying to find PDBs under the symbol directories except directly under them or in a &#8220;dll&#8221; subdirectory, rather than looking for the appropriate hash as it would in a symbol store. The resolution for this issue is simple enough, refer to the Windows 7 symbol packages with SRV* syntax in the symbol path. Therefore, the symbol path is updated to something like:</p>
  117. <p><em>SRV*C:\Symbols;SRV*C:\Symbols32;CACHE*C:\websymbols;SRV*http://msdl.microsoft.com/download/symbols</em></p>
  118. <p>With this change in place, the Visual Studio 2010 Beta 2 debugger was able to pick up symbols for system DLLs from the local stores, and now the debugging session started instantly. But the question remained: even if the debugger didn&#8217;t know how to look for symbols under C:\Symbols and C:\Symbols32 when they were not specified with a srv* directive, why did it download symbols from the HTTP public store, only to end up starting with symbols not being loaded for any of the system DLLs in the debugged process?</p>
  119. <p>To get to the bottom of this, the local symbol caches were removed from the symbol path. At this point, it was</p>
  120. <p><em>CACHE*C:\websymbols;SRV*http://msdl.microsoft.com/download/symbols</em></p>
  121. <p>Running the debugger with this stripped down symbol path reproduced the poor debugger startup experience and the worse issue of symbols being downloaded only to end up not being used. At this point, Sysinternals Process Monitor was used to examine the actions of the debugger. Two curious facts were revealed.</p>
  122. <p>The first was that the Visual Studio debugger was literally examining a directory called &#8220;cache*C:\websymbols&#8221; under its path in a vain attempt to find symbols. Since the &#8220;cache*&#8221; string made it to a file open request, obviously the cache* directive in the _NT_SYMBOL_PATH variable was not being correctly parsed or understood by the debugger.</p>
  123. <p>The result of this deficiency is that the Visual Studio debugger should be using some default local cache directory for the downloaded symbols, instead of the one explicitly specified by the cache* directive. Therefore, the same behavior would be expected with the following symbol path:</p>
  124. <p><em>SRV*http://msdl.microsoft.com/download/symbols</em></p>
  125. <p>And indeed, a quick check revealed that the same peculiarity reproduced with this symbol path setting: symbols were being downloaded from the HTTP server, but in the end of the process, symbols were not loaded for any of the system modules in the debugged process. Whatever the default directory is, attempts to download symbols there resulted in their loss into oblivion.</p>
  126. <p>Specifying the local symbol cache using the SRV* directive is also possible. This is the legacy approach, before Windbg recommend using CACHE* instead. A symbol path of this form is</p>
  127. <p><em>SRV*C:\websymbols*http://msdl.microsoft.com/download/symbols</em></p>
  128. <p>With this symbol path in place, the Visual Studio 2010 Beta 2 debugger both downloaded symbols from the HTTP store and actually ended up using them. Specifying the cache directory with CACHE* or not at all triggered the bug, while specifying it the old fashioned way in the SRV* directive satisfied the debugger.</p>
  129. <p>As a result, my guidance for the Visual Studio 2010 Beta 2 debugger users experiencing performance issues or other symbol problems that have no issue with their symbol path when used with Windbg is:</p>
  130. <ol>
  131. <li>For each directory in your _NT_SYMBOL_PATH, determine whether it is in the &#8220;flat&#8221; format or in symbol store format. Prefix symbol stores with SRV*, changing &#8220;C:\Symbols&#8221; to &#8220;SRV*C:\Symbols&#8221;. Windows 7 users in particular should be aware that the symbol packages for their platforms should be specified with SRV* syntax for Visual Studio 2010 Beta 2.</li>
  132. <li>Specify local caches directories for remote symbol stores (SMB or HTTP) directly in the SRV* directive, to have Visual Studio 2010 Beta 2 pick them up. It is OK to keep the CACHE* directive in your symbol path as well, but for the time being, Visual Studio 2010 Beta 2 does not seem to use it correctly.</li>
  133. </ol>
  134. <p>The Visual Studio Debugger team is addressing issues revealed by the investigation of this behavior for the forthcoming RTM release of Visual Studio 2010. However, several significant deficiencies in debugger symbol support will not be addressed in the 2010 release. One is that symbol loading is done synchronously rather than asynchronously to the debugging session. The other being that unless manual symbol loading is used, no progress indication nor cancellation UI is presented as the symbols are being transferred from a remote store. Therefore, the perceived performance of symbol support in the debugger will leave something to be desired for the time being.</p>
  135. ]]></content:encoded>
  136. <wfw:commentRss>https://kobyk.wordpress.com/2009/11/05/visual-studio-2010-beta-2-debugger-may-be-confused-by-your-symbol-path/feed/</wfw:commentRss>
  137. <slash:comments>2</slash:comments>
  138. <media:content url="https://1.gravatar.com/avatar/1d5c3d0abc3891afb6e88eebc51b004c3ed48b5fc2bc4a0f0ff7f6e507c80ed4?s=96&#38;d=identicon&#38;r=G" medium="image">
  139. <media:title type="html">KK</media:title>
  140. </media:content>
  141. </item>
  142. <item>
  143. <title>IDA v5.4 supports Windbg as a debugger backend</title>
  144. <link>https://kobyk.wordpress.com/2009/01/30/ida-v54-supports-windbg-as-a-debugger-backend/</link>
  145. <comments>https://kobyk.wordpress.com/2009/01/30/ida-v54-supports-windbg-as-a-debugger-backend/#comments</comments>
  146. <dc:creator><![CDATA[Koby Kahane]]></dc:creator>
  147. <pubDate>Fri, 30 Jan 2009 19:16:32 +0000</pubDate>
  148. <category><![CDATA[Kernel]]></category>
  149. <category><![CDATA[Windbg]]></category>
  150. <guid isPermaLink="false">http://kobyk.wordpress.com/?p=48</guid>
  151.  
  152. <description><![CDATA[A new release of IDA, the Interactive Disassembler, has been recently released featuring new debugger integration capabilities. IDA&#8217;s existing built-in debugger often proved lackluster, but IDA&#8217;s static analysis and navigation features are, of course, unrivaled by anything else. I always &#8230; <a href="https://kobyk.wordpress.com/2009/01/30/ida-v54-supports-windbg-as-a-debugger-backend/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
  153. <content:encoded><![CDATA[<p>A new release of IDA, the Interactive Disassembler, has been recently released featuring new debugger integration capabilities. IDA&#8217;s existing built-in debugger often proved lackluster, but IDA&#8217;s static analysis and navigation features are, of course, unrivaled by anything else. I always wished IDA would address the weakness of its debugging features and now they have done so in the v5.4 release. The new version can drive a gdb debugging server (as embedded platforms often provide), a Bochs virtual machine (great for BIOS and boot loader debugging) and most importantly DbgEng, the Microsoft debugging engine used by Windbg. Since Windbg sessions often involve heavy use of PDBs, IDA v5.4 has improved its support for importing data from PDBs and now uses more of their embedded type information (previously the third party Determina PDB plugin attempted to improve IDA&#8217;s PDB support). To top things off, the Python plugin is now bundled with IDA, as well.</p>
  154. <p>I haven&#8217;t had the chance to use the new version yet, but Hex Rays have a great demo video <a href="http://hexblog.com/2009/01/kernel_debugging_with_ida.html">posted here</a>. The only thing notable that appears missing is a nice UI for examining the stack trace, but if push comes to shove the Windbg command line can be used to invoke &#8220;k&#8221;, as demonstrated.</p>
  155. ]]></content:encoded>
  156. <wfw:commentRss>https://kobyk.wordpress.com/2009/01/30/ida-v54-supports-windbg-as-a-debugger-backend/feed/</wfw:commentRss>
  157. <slash:comments>4</slash:comments>
  158. <media:content url="https://1.gravatar.com/avatar/1d5c3d0abc3891afb6e88eebc51b004c3ed48b5fc2bc4a0f0ff7f6e507c80ed4?s=96&#38;d=identicon&#38;r=G" medium="image">
  159. <media:title type="html">KK</media:title>
  160. </media:content>
  161. </item>
  162. <item>
  163. <title>Windbg 6.10.3.233 released</title>
  164. <link>https://kobyk.wordpress.com/2008/11/21/windbg-6103233-released/</link>
  165. <comments>https://kobyk.wordpress.com/2008/11/21/windbg-6103233-released/#comments</comments>
  166. <dc:creator><![CDATA[Koby Kahane]]></dc:creator>
  167. <pubDate>Fri, 21 Nov 2008 05:50:02 +0000</pubDate>
  168. <category><![CDATA[Windbg]]></category>
  169. <guid isPermaLink="false">http://kobyk.wordpress.com/?p=43</guid>
  170.  
  171. <description><![CDATA[Version 6.10.3.233 of the Debugging Tools for Windows package has been available for a few days now. The big news on this one is lots of FireWire debugging changes. An updated host driver is provided and claims of greater reliability &#8230; <a href="https://kobyk.wordpress.com/2008/11/21/windbg-6103233-released/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
  172. <content:encoded><![CDATA[<p>Version 6.10.3.233 of the Debugging Tools for Windows package has been available for a few days now.</p>
  173. <p>The big news on this one is lots of FireWire debugging changes. An updated host driver is provided and claims of greater reliability and controller compatibility are made. Additional changes include better WOW64 support, claims of performance improvements to the various debuggers in the package (it remains to be seen how significant those are), many improvements to the almighty !analyze extension command and extensive updates to the debugger documentation. Absent from this release is NT 4.0 support. I suppose not many will miss it at this point.</p>
  174. <p>Developers using the debugger API may be interested that symbols for dbghelp.dll v6.10.3.233 are available from the public symbol store, while symbols for dbgeng.dll v6.10.3.233 are once again missing, a sorry tradition of making the debugger interface consumer&#8217;s life hard since the 6.8 debugger release, if I recall correctly.</p>
  175. ]]></content:encoded>
  176. <wfw:commentRss>https://kobyk.wordpress.com/2008/11/21/windbg-6103233-released/feed/</wfw:commentRss>
  177. <slash:comments>1</slash:comments>
  178. <media:content url="https://1.gravatar.com/avatar/1d5c3d0abc3891afb6e88eebc51b004c3ed48b5fc2bc4a0f0ff7f6e507c80ed4?s=96&#38;d=identicon&#38;r=G" medium="image">
  179. <media:title type="html">KK</media:title>
  180. </media:content>
  181. </item>
  182. <item>
  183. <title>Oops! Microsoft private symbols accidently leaked in Visual Studio 2010 CTP VM image</title>
  184. <link>https://kobyk.wordpress.com/2008/10/29/oops-microsoft-private-symbols-accidently-leaked-in-visual-studio-2010-ctp-vm-image/</link>
  185. <comments>https://kobyk.wordpress.com/2008/10/29/oops-microsoft-private-symbols-accidently-leaked-in-visual-studio-2010-ctp-vm-image/#comments</comments>
  186. <dc:creator><![CDATA[Koby Kahane]]></dc:creator>
  187. <pubDate>Wed, 29 Oct 2008 15:08:18 +0000</pubDate>
  188. <category><![CDATA[Windbg]]></category>
  189. <guid isPermaLink="false">http://kobyk.wordpress.com/?p=41</guid>
  190.  
  191. <description><![CDATA[I downloaded Microsoft&#8217;s newly released Visual Studio 2010 CTP virtual machine disk image hoping for a few surprises, but I certainly didn&#8217;t expect this&#8230; The Visual Studio 2010 CTP is a huge multi-gigabyte VM running Windows Server 2008. The first &#8230; <a href="https://kobyk.wordpress.com/2008/10/29/oops-microsoft-private-symbols-accidently-leaked-in-visual-studio-2010-ctp-vm-image/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
  192. <content:encoded><![CDATA[<p>I downloaded Microsoft&#8217;s newly released Visual Studio 2010 CTP virtual machine disk image hoping for a few surprises, but I certainly didn&#8217;t expect this&#8230;</p>
  193. <p>The Visual Studio 2010 CTP is a huge multi-gigabyte VM running Windows Server 2008. The first thing I did with it is start up Visual C++ 2010, create a Win32 console application and run it in the debugger. I looked at the stack trace and saw the following:<br />
  194. <code><br />
  195. vc10app.exe!wmain(int argc=1, wchar_t * * argv=0x000d1470)  Line 8<br />
  196. vc10app.exe!__tmainCRTStartup()  Line 564 + 0x19 bytes<br />
  197. vc10app.exe!wmainCRTStartup()  Line 392<br />
  198. kernel32.dll!BaseThreadInitThunk(unsigned long <strong>RunProcessInit</strong>=0, long (void *)* <strong>StartAddress</strong>=0x00000000, void * <strong>Argument</strong>=0x7ffdf000)  Line 66 + 0x5 bytes<br />
  199. ntdll.dll!__RtlUserThreadStart(long (void *)* <strong>StartAddress</strong>=0x013b1073, void * <strong>Argument</strong>=0x7ffdf000)  Line 2740<br />
  200. ntdll.dll!_RtlUserThreadStart(long (void *)* <strong>StartAddress</strong>=0x013b1073, void * <strong>Argument</strong>=0x7ffdf000)  Line 2672 + 0xb bytes</code></p>
  201. <p>vc10app is the name of my test console application. I go over stack traces on a daily basis so the special thing about this one immediately caught my attention. Notice that the wmain() function of my console application has full debugging information (as expected for something I wrote) and the parameter names argc and argv are visible in the stack trace. Under normal circumstances, only public debugging symbols are available for Microsoft OS components like kernel32 and ntdll. In this CTP VM, however, the StartAddress and Argument parameters were visible as well.</p>
  202. <p>Public debugging symbols are stripped versions of the original private symbols generated by the build process. They do not contain parameter information and do not contain the names of local variables in functions. Note however that for C++ functions, name mangling results in parameter types being visible in public symbols as well. Normally, when running the debugger in a system configured to use Microsoft&#8217;s public symbols, names for internal functions are visible in stack traces, but the names of arguments and locals never are.</p>
  203. <p>I opened the Modules tab of the Visual Studio debugger to determine where the debugger is picking up these symbols for kernel32 and ntdll. The debugger was using C:\ppa\symstore as the symbol store. I opened the C:\ppa directory and saw that a Visual Studio Profiler session for a matrix multiplication application was stored there.</p>
  204. <p>Apparently someone with access to Microsoft&#8217;s internal symbol store ran a profiling session on this matrix multiplication application, perhaps to ensure profiling is functional on the CTP VM. The private symbols retrieved for the session were persisted in the CTP&#8217;s disk and made their way to the public release. To ensure my hypothesis was correct, I installed Windbg on the machine, opened ntdll.dll as a crash dump and loaded symbols from the store directory:<br />
  205. <code><br />
  206. Microsoft (R) Windows Debugger Version 6.9.0003.113 X86<br />
  207. Copyright (c) Microsoft Corporation. All rights reserved.<br />
  208. Loading Dump File [C:\Windows\System32\ntdll.dll]<br />
  209. Symbol search path is: SRV*c:\ppa\symcache;.<br />
  210. Executable search path is:<br />
  211. ModLoad: 77ed0000 77ff7000   C:\Windows\System32\ntdll.dll<br />
  212. eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=00000000<br />
  213. eip=77ed0000 esp=00000000 ebp=00000000 iopl=0         nv up di pl nz na po nc<br />
  214. cs=0000  ss=0000  ds=0000  es=0000  fs=0000  gs=0000             efl=00000000<br />
  215. ntdll!`string'<br />
  216. (ntdll+0x0):<br />
  217. 77ed0000 4d              dec     ebp<br />
  218. 0:000&gt; .reload /f<br />
  219. .<br />
  220. Loading unloaded module list<br />
  221. 0:000&gt; lm<br />
  222. start    end        module name<br />
  223. 77ed0000 77ff7000   ntdll      <strong>(private pdb symbols)  c:\ppa\symcache\ntdll.pdb</strong>\B958B2F91A5A46B889DAFAB4D140CF252\ntdll.pdb<br />
  224. 0:000&gt; x ntdll!RtlAllocateHeap<br />
  225. 77f358a6 ntdll!RtlAllocateHeap <strong>(void *, unsigned long, unsigned long)</strong><br />
  226. 0:000&gt; dv /f ntdll!RtlAllocateHeap<br />
  227. @ebp+0x08      HeapHandle<br />
  228. @ebp+0x0c           Flags<br />
  229. @ebp+0x10            Size<br />
  230. @ebp+0x08       ExtraSize<br />
  231. @ebp-0x04  AllocationSize<br />
  232. @ebp-0x08     Interceptor<br />
  233. @ebp-0x58 ExceptionRecord</code></p>
  234. <p>The private PDB for ntdll.dll found in this CTP VM image notes how HeapHandle, Flags, Size and ExtraSize are the parameter names for RtlAllocateHeap. Furthermore, AllocationSize, Interceptor and ExceptionRecord are used as local names in this API.</p>
  235. <p>Private PDBs also feature source information. This is also visible in this case:<br />
  236. <code><br />
  237. 0:000&gt; ln ntdll!RtlAllocateHeap<br />
  238. <strong>d:\rtm\base\ntos\rtl\heap.c</strong>(<strong>1508</strong>)<br />
  239. <strong>Source Depot: basedepot.sys-ntgroup.ntdev.microsoft.com:2003 //depot/longhorn_rtm/base/ntos/rtl/heap.c#1</strong><br />
  240. (77f358a6)   ntdll!RtlAllocateHeap   |  (77f35997)   ntdll!RtlpLowFragHeapFree<br />
  241. Exact matches:<br />
  242. ntdll!RtlAllocateHeap (void *, unsigned long, unsigned long)</code></p>
  243. <p>The PDB features references to the source file from the Windows source tree for RtlAllocateHeap and the other APIs. Additionally, it appears to contain a custom reference to Microsoft&#8217;s internal source control system, Source Depot, presumably to facilitate the debugger retrieving up to date sources automatically when those are not available locally.</p>
  244. <p>It&#8217;s interesting how scattered bits of information in a debugging symbols file provide a fascinating insight into Windows. Hope you enjoyed the surprise as much as I did&#8230;</p>
  245. ]]></content:encoded>
  246. <wfw:commentRss>https://kobyk.wordpress.com/2008/10/29/oops-microsoft-private-symbols-accidently-leaked-in-visual-studio-2010-ctp-vm-image/feed/</wfw:commentRss>
  247. <slash:comments>9</slash:comments>
  248. <media:content url="https://1.gravatar.com/avatar/1d5c3d0abc3891afb6e88eebc51b004c3ed48b5fc2bc4a0f0ff7f6e507c80ed4?s=96&#38;d=identicon&#38;r=G" medium="image">
  249. <media:title type="html">KK</media:title>
  250. </media:content>
  251. </item>
  252. <item>
  253. <title>Installing filter drivers with DIFxApp and a WiX v3 MSI</title>
  254. <link>https://kobyk.wordpress.com/2008/10/21/installing-filter-drivers-with-difxapp-and-a-wix-v3-msi/</link>
  255. <comments>https://kobyk.wordpress.com/2008/10/21/installing-filter-drivers-with-difxapp-and-a-wix-v3-msi/#comments</comments>
  256. <dc:creator><![CDATA[Koby Kahane]]></dc:creator>
  257. <pubDate>Mon, 20 Oct 2008 21:11:01 +0000</pubDate>
  258. <category><![CDATA[Kernel]]></category>
  259. <guid isPermaLink="false">http://kobyk.wordpress.com/?p=36</guid>
  260.  
  261. <description><![CDATA[The designers of Windows Installer probably did not have driver installation in mind. Indeed, the ServiceInstall MSI database table does not even allow for service types SERVICE_KERNEL_DRIVER and SERVICE_FILE_SYSTEM_DRIVER in the ServiceType column. Originally, Microsoft encouraged driver installation by means &#8230; <a href="https://kobyk.wordpress.com/2008/10/21/installing-filter-drivers-with-difxapp-and-a-wix-v3-msi/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
  262. <content:encoded><![CDATA[<p>The designers of Windows Installer probably did not have driver installation in mind. Indeed, the <a href="http://msdn.microsoft.com/en-us/library/aa371637(VS.85).aspx">ServiceInstall MSI database table</a> does not even allow for service types SERVICE_KERNEL_DRIVER and SERVICE_FILE_SYSTEM_DRIVER in the ServiceType column. Originally, Microsoft encouraged driver installation by means of a &#8220;setup application&#8221;, custom code invoking the <a href="http://msdn.microsoft.com/en-us/library/cc185682(VS.85).aspx">SetupAPI</a>. The Setup API functions would be used to examine an <a href="http://msdn.microsoft.com/en-us/library/ms790220.aspx">.INF file</a> describing required steps for the driver&#8217;s installation. Back in Windows NT 4.0, even .INF files were often avoided in lieu of directly setting up the legacy driver service in the system registry with C code.</p>
  263. <p>Enter Windows 2000 with Plug and Play. Now the system uses .INF files it maintains in a store to locate and install drivers for devices on demand. When a new device is inserted, the system looks for an .INF file with a matching hardware identifier. For most hardware devices, .INF based installation becomes a de-facto requirement. However, for other driver categories, such as file system filters, device class filters, etc., an .INF file is but one way of performing the driver installation process.</p>
  264. <p>Microsoft, when confronted by driver setup authors who denounce .INF files as having cryptic, old-fashioned syntax, non-ideal diagnosibility and debuggability and other shortcomings, persists in encouraging their use. They are a WHQL logo requirement and in some cases it is claimed they will be the only way to install drivers in future Windows releases.</p>
  265. <p>Often driver installation is but a part of the installation process of a larger application program. For applications, Microsoft encourages (and mandates as a logo requirement) the use of MSI packages and the Windows Installer service. In order to avoid having every MSI setup author who needs to perform driver installation roll his own custom invocation of the driver&#8217;s .INF installation and in a bid to improve driver installation&#8217;s synergy with Windows Installer in general, Microsoft created <a href="http://msdn.microsoft.com/en-us/library/ms790295.aspx">DIFxApp</a> &#8211; Driver Install Frameworks for Applications.</p>
  266. <p>MSI and DIFxApp&#8217;s .INF based installation make for an odd couple. The Windows Installer model is transactional &#8211; describe what changes should be made to the system and let Windows Installer determine how to execute them and importantly, how to roll them back. After having encouraged COM DLLs to encapsulate the details of their installation and registration with the Self-Registration DllRegisterServer export for years, describing the individual elements of the COM registration using an MSI&#8217;s <a href="http://msdn.microsoft.com/en-us/library/aa371168(VS.85).aspx">Registry table</a> is now encouraged instead. DllUnregisterServer can fail in mysterious ways due to missing dependencies, etc., leaving cruft behind during uninstallation. By contrast, rolling back insertions made from the Registry table is always possible for the MSI service. If COM&#8217;s long standing installation architecture was set aside to better align with MSI&#8217;s model, one would expect a similar occurance for drivers. However, DIFxApp, the solution for installing drivers with MSI, is the moral equivalent of COM Self-Registration. If a driver&#8217;s .INF does not remove all changes it made during installation, the uninstallation process is bound to be imperfect. MSI&#8217;s ability to diagnose whether a driver&#8217;s installation has been damaged is limited and thwarted.</p>
  267. <p>Be that as it may, .INF files&#8217; tight integration with the Plug and Play system, the fact they are a logo requirement and uniformity considerations are compelling arguments for their use. From this point forward, it shall be assumed that .INF based installation and MSI integration have been chosen.</p>
  268. <p>If you&#8217;ve developed a common PnP WDM driver, you probably already have an .INF for installation purposes. That .INF can usually be used as is with DIFxApp, which assumes PnP drivers by default. It is for other driver categories that the process becomes more tricky. I&#8217;ll discuss filter drivers of three varieties in particular &#8211; file system filters, file system minifilters and device class filters.</p>
  269. <p>For illustration purposes, let&#8217;s consider a typical file system minifilter driver, DirFilter, which is presently a pet project of mine that will eventually perform interesting modifications to directory listing I/O operations. The following is DirFilter&#8217;s .INF file:</p>
  270. <p><code><br />
  271. [Version]<br />
  272. Signature = "$Windows NT$"<br />
  273. Class = "ActivityMonitor"<br />
  274. ClassGuid = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2}<br />
  275. Provider = %Koby%<br />
  276. DriverVer = 09/12/2008,1.0.0.0<br />
  277. CatalogFile = dirfilter.cat<br />
  278. <strong>DriverPackageType = FileSystemMinifilter</strong><br />
  279. [DestinationDirs]<br />
  280. DefaultDestDir = %DIRID_DRIVERS%<br />
  281. DirFilter.DriverFiles = %DIRID_DRIVERS%<br />
  282. [DefaultInstall]<br />
  283. OptionDesc  = %ServiceDescription%<br />
  284. CopyFiles   = DirFilter.DriverFiles<br />
  285. [DefaultInstall.Services]<br />
  286. AddService  = %ServiceName%,,DirFilter.Service<br />
  287. [DefaultUninstall]<br />
  288. DelFiles   = DirFilter.DriverFiles<br />
  289. [DefaultUninstall.Services]<br />
  290. DelService = %ServiceName%,0x200      ;Ensure service is stopped before deleting<br />
  291. [DirFilter.Service]<br />
  292. DisplayName      = %ServiceName%<br />
  293. Description      = %ServiceDescription%<br />
  294. ServiceBinary    = %12%\%DriverName%.sys ; DIRID_DRIVERS<br />
  295. Dependencies     = "FltMgr"<br />
  296. ServiceType      = %SERVICE_FILE_SYSTEM_DRIVER%<br />
  297. StartType        = %SERVICE_DEMAND_START%<br />
  298. ErrorControl     = %SERVICE_ERROR_NORMAL%<br />
  299. LoadOrderGroup   = "FSFilter Activity Monitor"<br />
  300. AddReg           = DirFilter.AddRegistry<br />
  301. [DirFilter.AddRegistry]<br />
  302. HKR,"Instances","DefaultInstance",0x00000000,%Instance1.Name%<br />
  303. HKR,"Instances\"%Instance1.Name%,"Altitude",0x00000000,%Instance1.Altitude%<br />
  304. HKR,"Instances\"%Instance1.Name%,"Flags",0x00010001,%Instance1.Flags%<br />
  305. [DirFilter.DriverFiles]<br />
  306. %DriverName%.sys<br />
  307. [SourceDisksFiles]<br />
  308. dirfilter.sys = 1<br />
  309. [SourceDisksNames]<br />
  310. 1 = %DiskId1%<br />
  311. [Strings]<br />
  312. Koby = "Koby Kahane"<br />
  313. DIRID_DRIVERS = 12<br />
  314. SERVICE_FILE_SYSTEM_DRIVER = 2<br />
  315. SERVICE_DEMAND_START = 2<br />
  316. SERVICE_ERROR_NORMAL = 1<br />
  317. ServiceDescription = "DirFilter minifilter driver"<br />
  318. ServiceName = "DirFilter"<br />
  319. DriverName = "DirFilter"<br />
  320. DiskId1 = "DirFilter minifilter installation media"<br />
  321. ; Instance specific information.<br />
  322. Instance1.Name = "DirFilter Instance"<br />
  323. Instance1.Altitude = "370021" ; Real world minifilters should use Microsoft allocated altitude<br />
  324. Instance1.Flags = 0x0 ; Allow automatic attachments</code></p>
  325. <p>This is, I believe, a pretty typical .INF for a minifilter. A default instance of it is set up at an altitude in an appropriate filter load order group. This is as good a place as any to note the importance of requesting a <a href="http://connect.microsoft.com/content/content.aspx?ContentID=2512&amp;SiteID=221">Minifilter Altitude Allocation</a> from Microsoft for public drivers rather than using some random number which may end up causing conflicts and interoperability issues. From my experience, it takes Microsoft two months or so to respond to an allocation request so make sure to take care of it early in your release cycle.</p>
  326. <p>As a first step towards a DIFxApp-based MSI driver installation, write an .INF file that will work when right clicking it and selecting Install from Explorer&#8217;s popup menu. This calls SetupAPI&#8217;s <a href="http://msdn.microsoft.com/en-us/library/aa376957(VS.85).aspx">InstallHinfSection</a> on the .INF file&#8217;s <a href="http://msdn.microsoft.com/en-us/library/aa376957(VS.85).aspx">DefaultInstall</a> section. Further, ensure that the uninstallation process works as expected, and leaves no trails behind, by using InstallHinfSection to invoke the DefaultUninstall section of the file.</p>
  327. <p>You may discover that you are encountering difficulty at this stage. I recommend running the <a href="http://msdn.microsoft.com/en-us/library/ms792443.aspx">ChkINF</a> utility, which analyzes .INF files for errors and mishaps, before testing the .INF file and indeed after every modification to an existing file. ChkINF, while sometimes terse, is nowhere near as cryptic as errors you will receive from SetupAPI. However, if you encounter setup errors even after ChkINF has verified your file, you can utilize <a href="http://msdn.microsoft.com/en-us/library/ms791354.aspx">verbose SetupAPI logging</a> to further diagnose setup issues.</p>
  328. <p>With a working &#8220;right-click Install&#8221; .INF file, the time is ripe for integration into an MSI installer. First of all, DIFxApp requires an additional directive in the <a href="http://msdn.microsoft.com/en-us/library/ms794526.aspx">Version section</a> of your .INF file, the <a href="http://msdn.microsoft.com/en-us/library/ms790242.aspx">DriverPackageType</a>. The driver package type is used by DIFx to determine what steps are required for the installation of your specific type of driver. For example, if you fail to specify the type of your file system filter, DIFx assumes it is a PnP driver and the &#8220;installation&#8221; will just import the .INF into the system driver store. No service will be created and success will not be achieved. Unfortunately, the documentation for the DriverPackageType is sorely lacking at best. You will see it only mentions ClassFilter and PlugAndPlay as possible types in MSDN. MSDN proves a disappointment. However, another Microsoft information source, their <a href="http://download.microsoft.com/download/5/b/5/5b5bec17-ea71-4653-9539-204a672f11cf/DIFXtools_reqs.doc">Requirements for Driver Packages that are Used with the DIFx Tools</a> document, calls for the use of DIFx for Class Filters, Plug and Play drivers, File System &amp; File System Filter drivers, Network drivers, Kernel Service Drivers and Export Drivers. The DriverPackageType values ClassFilter, FileSystem, FileSystemFilter, KernelModule, KernelService, Network and PlugAndPlay are documented there. You may notice that a special type for minifilters is conspicuously absent from the list. At first, I figured perhaps DIFx has no need for a distinction between legacy filters and minifilters. Later, an <a href="http://www.osronline.com/showThread.cfm?link=62820">old post</a> (free registration required) on OSR&#8217;s NTFSD mailing list turned my attention to the fact DIFx will require a system restart for a minifilter, even though it can be loaded and unloaded without one. Neal Christiansen, Microsoft&#8217;s File System Filter Group Lead, replies (back in 2004) that appropriate support for minifilter installation is forthcoming. I therefore set out to discover whether DIFxApp as available today provides special support for minifilters.</p>
  329. <p>When the Windows Server 2008 WDK is installed to the default location, the x86 versions of the DIFxApp MSI custom action DLLs reside in C:\WINDDK\6001.18000\redist\DIFx\DIFxApp\English\WixLib\x86. I examined them with the <a href="http://www.hex-rays.com/idapro/">Interactive Disassembler</a> and was happy to see Microsoft made available public symbols (.PDBs) for them. To make a long story short, the DriverPackageType field is examined by DIFxApp in the SetupAPI::CDriverPackage::GetDriverType(CRefPtr&lt;SetupAPI::CInf&gt;, DRVPKG_TYPE&amp;) function in DIFxAppA.dll, which references a global table, dubbed DriverTypeStringList, for possible package types:</p>
  330. <p><a href="https://kobyk.files.wordpress.com/2008/10/drivertypestringlist.png"><img data-attachment-id="39" data-permalink="https://kobyk.wordpress.com/2008/10/21/installing-filter-drivers-with-difxapp-and-a-wix-v3-msi/drivertypestringlist1/" data-orig-file="https://kobyk.files.wordpress.com/2008/10/drivertypestringlist1.png" data-orig-size="1247,263" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="DriverTypeStringList" data-image-description="" data-image-caption="" data-medium-file="https://kobyk.files.wordpress.com/2008/10/drivertypestringlist1.png?w=300" data-large-file="https://kobyk.files.wordpress.com/2008/10/drivertypestringlist1.png?w=584" class="alignnone size-full wp-image-39" title="DriverTypeStringList" src="https://kobyk.files.wordpress.com/2008/10/drivertypestringlist1.png?w=584" alt=""   srcset="https://kobyk.files.wordpress.com/2008/10/drivertypestringlist1.png?w=446&amp;h=94 446w, https://kobyk.files.wordpress.com/2008/10/drivertypestringlist1.png?w=891&amp;h=188 891w, https://kobyk.files.wordpress.com/2008/10/drivertypestringlist1.png?w=150&amp;h=32 150w, https://kobyk.files.wordpress.com/2008/10/drivertypestringlist1.png?w=300&amp;h=63 300w, https://kobyk.files.wordpress.com/2008/10/drivertypestringlist1.png?w=768&amp;h=162 768w" sizes="(max-width: 450px) 100vw, 450px" /></a></p>
  331. <p>It is now evident that available driver package types as of DIFx 2.1 are ClassCoInstaller, ClassFilter, DeviceFilter, FileSystem, FileSystemFilter, <strong>FileSystemMinifilter</strong>, KernelModule, KernelService, NdisImMiniport, Network and PlugAndPlay. With this information, I opted for the FileSystemMinifilter type for DirFilter&#8217;s installation .INF file.</p>
  332. <p>Next, a catalog file is required by DIFx. Even though the purpose of the catalog is to be WHQL signed by Microsoft, DIFx can be used to install drivers without WHQL certification. Nevertheless, the catalog still needs to be there. The easy way is to use the <a href="http://msdn.microsoft.com/en-us/library/bb931742.aspx">Inf2Cat</a> tool for the catalog&#8217;s generation. Place the .INF file and the driver files it references in a staging area and you can run it like so:<br />
  333. <code><br />
  334. E:\Projects\dirfilter\staging&gt;<strong>inf2cat</strong> /driver:E:\Projects\dirfilter\staging /os:Server2008_X86,Vista_X86,Server2003_X86,XP_X86,2000 /verbose</code></p>
  335. <p>Specifying, of course, the operating systems and platforms appropriate for your driver.</p>
  336. <p>An .INF file, a .CAT file and a .SYS file are the three files required for a DIFxApp driver package. The DIFxApp model requires your MSI to install these files to a source directory, per driver package (i.e., if you have multiple drivers, they&#8217;ll need multiple .INFs in multiple directories) and performs the installation from there to the Windows driver store and eventually the drivers directory under system32.</p>
  337. <p>Microsoft distributes a WiX library and documentation for using it with DIFxApp. However, that library targets the older WiX v2.0 release. WiX v3.0 is the actively developed version, and has different schema, semantics and a slightly different integration model with DIFxApp. If you use WiX v2.0, consult <a href="http://msdn.microsoft.com/en-us/library/ms790289.aspx">Microsoft&#8217;s documentation</a>. Otherwise, let&#8217;s proceed. The following .wxs file is the sample installer I wrote for installing DirFilter with DIFxApp:</p>
  338. <pre class="brush: xml; title: ; notranslate">
  339.  
  340. &lt;?xml version='1.0' encoding='windows-1252'?&gt;
  341. &lt;Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'
  342.      xmlns:difx='http://schemas.microsoft.com/wix/DifxAppExtension'&gt;
  343.     &lt;Product Name='DirFilterInstaller' Id='59486bf1-77ad-460f-802d-29dbab0f78be' Language='1033' Codepage='1252' Version='1.0' Manufacturer='KK' UpgradeCode='96fe2ba0-fe8b-45b4-85ef-ea9aca103e6f'&gt;
  344.         &lt;Package Id='*' Keywords='DirFilter' Description='DirFilter Installer' Comments='Installs DirFilter' Manufacturer='KK' InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' /&gt;
  345.         &lt;Media Id='1' Cabinet='DirFilterInstaller.cab' EmbedCab='yes' DiskPrompt='DirFilter Media' /&gt;
  346.         &lt;Property Id='DiskPrompt' Value='DirFilter Install Media' /&gt;
  347.         &lt;Directory Id='TARGETDIR' Name='SourceDir'&gt;
  348.             &lt;Directory Id='ProgramFilesFolder'&gt;
  349.                 &lt;Directory Id='INSTALLDIR' Name='DirFilterApp'&gt;
  350.                     &lt;Directory Id='DirFilterAppDrivers' Name='Drivers'&gt;
  351.                         &lt;Directory Id='DirFilterDir' Name='DirFilter'&gt;
  352.                             &lt;Component Id='DirFilterDriver' Guid='8c64e674-5476-46e4-93cd-ba1ae78622df'&gt;
  353.                                 &lt;File Id='DirFilterSYS' Name='DirFilter.sys' DiskId='1' Source='DirFilter.sys' KeyPath='yes' /&gt;
  354.                                 &lt;File Id='DirFilterINF' Name='DirFilter.inf' DiskId='1' Source='DirFilter.inf' /&gt;
  355.                                 &lt;File Id='DirFilterCAT' Name='DirFilter.cat' DiskId='1' Source='DirFilter.cat' /&gt;
  356.                                 &lt;difx:Driver Legacy='yes' /&gt;
  357.                             &lt;/Component&gt;
  358.                         &lt;/Directory&gt;
  359.                     &lt;/Directory&gt;
  360.                 &lt;/Directory&gt;
  361.             &lt;/Directory&gt;
  362.         &lt;/Directory&gt;
  363.         &lt;Feature Id='Complete' Level='1'&gt;
  364.             &lt;ComponentRef Id='DirFilterDriver' /&gt;
  365.         &lt;/Feature&gt;
  366.         &lt;UIRef Id=&quot;WixUI_Minimal&quot; /&gt;
  367.     &lt;/Product&gt;
  368. &lt;/Wix&gt;
  369.  
  370. </pre>
  371. <p>Several points are worth mentioning regarding this installer:</p>
  372. <ul>
  373. <li>The XML schema for the WiX v3 DIFxApp extension is referenced at the top of the file. This is required for the Driver element to work. Note that in WiX v3, the Driver element is used instead of driver-specific attributes that were available for the Component element in the WiX v2 DIFxApp extension.</li>
  374. <li>As said before, DIFx requires one driver per directory and one driver per .INF file. The driver component is placed in a directory under the application&#8217;s directory. Additional drivers will be placed in additional components under additional directories.</li>
  375. <li>The &#8220;Legacy&#8221; attribute is used in the DIFx Driver element because my driver package is not WHQL signed. Of course the best solution for this is to ensure your driver is up to par and actually get WHQL certification. You should also note that Legacy mode disables integrity checks, allowing the driver installation to appear successful even when critical files are missing, etc.</li>
  376. <li>Do NOT copy the GUIDs I used if you end copying and pasting from this example. Make sure you generate your own with <a href="http://msdn.microsoft.com/en-us/library/aa373930(VS.85).aspx">uuidgen</a> and replace them.</li>
  377. </ul>
  378. <p>The .wxs source for this WiX installer is straightforward enough. However, actually compiling it and linking it requires referencing several external dependencies. When running Candle, the WiX compiler, the WixDifxAppExtension should be referenced (and others you may depend on, such as WixUIExtension). When running Light, the WiX linker, you should reference the extension as before. Additionally, in the newer builds of WiX v3.0, multiplatform support for DIFx requires you reference the .wixlib with the DIFxApp custom action DLLs for the appropriate platform:<br />
  379. <code><br />
  380. E:\Projects\dirfilter\staging&gt;%WIX_PATH%\<strong>candle</strong> -ext %WIX_PATH%\WixUIExtension.dll -ext %WIX_PATH%\WixDifxAppExtension.dll DirFilterInstaller.wxs<br />
  381. Microsoft (R) Windows Installer Xml Compiler version 3.0.4617.0<br />
  382. Copyright (C) Microsoft Corporation. All rights reserved.<br />
  383. </code><code><br />
  384. DirFilterInstaller.wxs<br />
  385. </code><code><br />
  386. E:\Projects\dirfilter\staging&gt;%WIX_PATH%\<strong>light</strong> -ext %WIX_PATH%\WixUIExtension.dll -<br />
  387. ext %WIX_PATH%\<strong>WixDifxAppExtension.dll</strong> DirFilterInstaller.wixobj %WIX_PATH%\<strong>difx<br />
  388. app_x86.wixlib</strong> -o DirFilterInstaller.msi<br />
  389. Microsoft (R) Windows Installer Xml Linker version 3.0.4617.0<br />
  390. Copyright (C) Microsoft Corporation. All rights reserved.</code></p>
  391. <p>(The WIX_PATH environment variable is set to WiX 3.0&#8217;s bin directory on my system.)</p>
  392. <p>Failing to reference WixDifxAppExtension or difxapp_[platform].wixlib will result in assorted compilation or linkage errors during installer build.</p>
  393. <p>When debugging DIFxApp driver installation, usually the interesting things are performed by the SetupAPI directly and therefore the SetupAPI log should be examined first. However, DIFxApp&#8217;s custom actions write diagnostic information into the MSI log (which can be enabled with a command-line switch to msiexec) and can provide additional insight into the driver installation process. Here&#8217;s an excerpt from the MSI log of a successful DirFilter installation:<br />
  394. <code><br />
  395. MSI (s) (2C:44) [20:22:39:061]: Executing op: ActionStart(Name=MsiInstallDrivers,,)<br />
  396. Action 20:22:39: MsiInstallDrivers.<br />
  397. MSI (s) (2C:44) [20:22:39:077]: Executing op: CustomActionSchedule(Action=MsiInstallDrivers,ActionType=3073,Source=BinaryData,Target=InstallDriverPackages,CustomActionData=2.15{8C64E674-5476-46E4-93CD-BA1AE78622DF}C:\Program Files\DirFilterApp\Drivers\DirFilter\82DirFilterInstallerKK)<br />
  398. MSI (s) (2C:90) [20:22:39:092]: Invoking remote custom action. DLL: C:\WINDOWS\Installer\MSI29.tmp, Entrypoint: InstallDriverPackages<br />
  399. DIFXAPP: ENTER: InstallDriverPackages()<br />
  400. DIFXAPP: INFO: 'CustomActionData' property 'DIFxApp Version' is '2.1'.<br />
  401. DIFXAPP: INFO: 'CustomActionData' property 'UI Level' is '5'.<br />
  402. DIFXAPP: INFO: 'CustomActionData' property 'componentId' is '{8C64E674-5476-46E4-93CD-BA1AE78622DF}'.<br />
  403. DIFXAPP: INFO: 'CustomActionData' property 'componentPath' is 'C:\Program Files\DirFilterApp\Drivers\DirFilter\'.<br />
  404. DIFXAPP: INFO: 'CustomActionData' property 'flags' is 0x8.<br />
  405. DIFXAPP: INFO: 'CustomActionData' property 'installState' is '2'.<br />
  406. DIFXAPP: INFO: 'CustomActionData' property 'ProductName' is 'DirFilterInstaller'.<br />
  407. DIFXAPP: INFO: 'CustomActionData' property 'ManufacturerName' is 'KK'.<br />
  408. DIFXAPP: INFO: user SID of user performing the install is 'S-1-5-21-1417001333-651377827-725345543-1003'.<br />
  409. DIFXAPP: INFO: opening HKEY_USERS\S-1-5-21-1417001333-651377827-725345543-1003\Software\Microsoft\Windows\CurrentVersion\DIFxApp\Components\{8C64E674-5476-46E4-93CD-BA1AE78622DF} (User's SID: 'S-1-5-21-1417001333-651377827-725345543-1003') ...<br />
  410. DIFXAPP: INFO:   ENTER:  DriverPackageInstallW<br />
  411. DIFXAPP: INFO:   Copied 'DirFilter.inf' to driver store...<br />
  412. DIFXAPP: INFO:   Copied 'dirfilter.cat' to driver store...<br />
  413. DIFXAPP: INFO:   Commiting queue...<br />
  414. DIFXAPP: INFO:   Copied file: 'C:\Program Files\DirFilterApp\Drivers\DirFilter\dirfilter.sys' -&gt; 'C:\WINDOWS\system32\DRVSTORE\DirFilter_11E71DD96C3AADF7CDEC882620E8410DECE9B5EF\dirfilter.sys'.<br />
  415. DIFXAPP: INFO:   Installing INF file "C:\WINDOWS\system32\DRVSTORE\DirFilter_11E71DD96C3AADF7CDEC882620E8410DECE9B5EF\DirFilter.inf" of Type 4.<br />
  416. DIFXAPP: INFO:   Installing File System Driver 'C:\WINDOWS\system32\DRVSTORE\DirFilter_11E71DD96C3AADF7CDEC882620E8410DECE9B5EF\DirFilter.inf'<br />
  417. DIFXAPP: INFO:   Service 'DirFilter' was started<br />
  418. <strong>DIFXAPP: SUCCESS:Installation completed with code 0x0.<br />
  419. DIFXAPP: INFO:   RETURN: DriverPackageInstallW  (0x0)</strong><br />
  420. DIFXAPP: INFO:   ENTER:  DriverPackageGetPathW<br />
  421. DIFXAPP: SUCCESS:Found driver store entry.<br />
  422. DIFXAPP: INFO:   RETURN: DriverPackageGetPathW  (0x7A)<br />
  423. DIFXAPP: INFO:   ENTER:  DriverPackageGetPathW<br />
  424. DIFXAPP: SUCCESS:Found driver store entry.<br />
  425. DIFXAPP: INFO:   RETURN: DriverPackageGetPathW  (0x0)<br />
  426. DIFXAPP: INFO: driver store entry for 'C:\Program Files\DirFilterApp\Drivers\DirFilter\DirFilter.inf' is 'C:\WINDOWS\system32\DRVSTORE\DirFilter_11E71DD96C3AADF7CDEC882620E8410DECE9B5EF\DirFilter.inf'.<br />
  427. DIFXAPP: INFO: The component Id '{8C64E674-5476-46E4-93CD-BA1AE78622DF}' is now set to point to driver store: 'C:\WINDOWS\system32\DRVSTORE\DirFilter_11E71DD96C3AADF7CDEC882620E8410DECE9B5EF\DirFilter.inf'<br />
  428. <strong>DIFXAPP: INFO: A reboot is not needed to install the component </strong>'{8C64E674-5476-46E4-93CD-BA1AE78622DF}'.<br />
  429. DIFXAPP: RETURN: InstallDriverPackages() 0 (0x0)</code></p>
  430. <p>Notice how DIFxApp places a copy of your driver package in the system driver store, a behavior which is distinct from &#8220;right-click Install&#8221; .INF invocation. Notice also it reports whether the installation operation with SetupAPI was successful and will additionally take care of scheduling a reboot if the driver package so requires.</p>
  431. <p>DIFxApp works equally well for installing a legacy file system filter. Simply use the FileSystemFilter DriverPackageType value instead.</p>
  432. <p>Device class filters require special consideration. MSDN has a page about <a href="http://msdn.microsoft.com/en-us/library/ms791322.aspx">Installing a Filter Driver</a>. For device filters, the process is straightforward &#8211; your .INF simply adds an UpperFilter under the appropriate device&#8217;s hardware key, using the special &#8220;HKR&#8221; relative root. However, a device class filter has no hardware key to refer to and indeed may wish to filter several distinct device classes. The MSDN page says one ought to write a custom &#8220;setup application&#8221; that shall invoke the .INF file for the several device classes of interest, as desired. However, DIFxApp offers no such flexibility and it does not appear that it can be used to drive such an .INF file. However, the fact it has a ClassFilter type clearly implies it has device class filters in mind.</p>
  433. <p>As is often the case, the answer to this dillemma lies in the WDK. The WDK features a sample WiX v2.0 project for illustrating DIFxApp&#8217;s use, which in fact installs a class filter. In a default installation, you can find it in C:\WINDDK\6001.18000\src\setup\DIFxApp\WiXLib\ClassFilter.wxs. Nearby, in C:\WINDDK\6001.18000\src\setup\infs\clasfilt\ClasFilt.Inf, resides the sample .INF file. Among other things, the file includes an explicit registration as a class UpperFilter:<br />
  434. <code><br />
  435. [ClassFilter_AddReg]<br />
  436. ;<br />
  437. ; Change {setup-ClassGUID} to the string form of the ClassGUID that you are installing the filter on.<br />
  438. ;<br />
  439. ; Change UpperFilters to LowerFilters if this is a lower class filter.<br />
  440. ;<br />
  441. HKLM, System\CurrentControlSet\Control\Class\{setup-ClassGUID}, UpperFilters, 0x00010008, clasfilt</code></p>
  442. <p>Fair enough. Multiple entries can be included in the registry section for UpperFilter registration directly under the class keys of interest. However, if you opt for this approach you may find to your dismay you no longer fall in ChkINF&#8217;s favor:<br />
  443. <code><br />
  444. (W22.1.2213) INF files should not set registry entries under 'HKLM,System\CurrentControlSet\Control\Class'.</code></p>
  445. <p>I guess you&#8217;re damned if you do and damned if you don&#8217;t. I suggest not drinking ChkINF&#8217;s Kool-Aid, setting up the device class filter registration directly and using DIFxApp rather than iterating with a custom setup application, obviously.</p>
  446. <p>Hopefully this lengthy writeup will prove useful to other authors of MSI-based driver installations.</p>
  447. ]]></content:encoded>
  448. <wfw:commentRss>https://kobyk.wordpress.com/2008/10/21/installing-filter-drivers-with-difxapp-and-a-wix-v3-msi/feed/</wfw:commentRss>
  449. <slash:comments>15</slash:comments>
  450. <media:content url="https://1.gravatar.com/avatar/1d5c3d0abc3891afb6e88eebc51b004c3ed48b5fc2bc4a0f0ff7f6e507c80ed4?s=96&#38;d=identicon&#38;r=G" medium="image">
  451. <media:title type="html">KK</media:title>
  452. </media:content>
  453.  
  454. <media:content url="https://kobyk.files.wordpress.com/2008/10/drivertypestringlist1.png" medium="image">
  455. <media:title type="html">DriverTypeStringList</media:title>
  456. </media:content>
  457. </item>
  458. <item>
  459. <title>Implementing an LSA proxy authentication package</title>
  460. <link>https://kobyk.wordpress.com/2008/08/30/implementing-an-lsa-proxy-authentication-package/</link>
  461. <comments>https://kobyk.wordpress.com/2008/08/30/implementing-an-lsa-proxy-authentication-package/#comments</comments>
  462. <dc:creator><![CDATA[Koby Kahane]]></dc:creator>
  463. <pubDate>Sat, 30 Aug 2008 14:57:26 +0000</pubDate>
  464. <category><![CDATA[C++]]></category>
  465. <guid isPermaLink="false">http://kobyk.wordpress.com/?p=33</guid>
  466.  
  467. <description><![CDATA[LSA authentication packages are a part of the core security ecosystem in Windows NT. LSA APs are provided with credentials by logon applications, such as Winlogon, authenticate these credentials and provide the logon application with a logon session handle if &#8230; <a href="https://kobyk.wordpress.com/2008/08/30/implementing-an-lsa-proxy-authentication-package/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
  468. <content:encoded><![CDATA[<p><a href="http://msdn.microsoft.com/en-us/library/aa374733(VS.85).aspx">LSA authentication packages</a> are a part of the core security ecosystem in Windows NT. LSA APs are provided with credentials by logon applications, such as Winlogon, authenticate these credentials and provide the logon application with a logon session handle if authentication was successful. Two authentication packages provided with Windows are of special interest. <a href="http://msdn.microsoft.com/en-us/library/aa378753(VS.85).aspx">MSV1_0</a> authenticates user credentials against the local SAM database or against a domain controller through the legacy logon protocols. <a href="http://msdn.microsoft.com/en-us/library/aa377942(VS.85).aspx">Kerberos.dll</a> uses the Kerberos protocol with modern domain controllers (or third party KDCs, etc.) for establishing logon sessions.</p>
  469. <p>Applications that want to provide value-added logon functionality wish to become involved in the logon process. Winlogon provides the <a href="http://msdn.microsoft.com/en-us/library/aa380543.aspx">GINA</a> facility before Windows Vista and the new <a href="http://msdn.microsoft.com/en-us/library/bb648647(VS.85).aspx">Credential Providers</a> in Windows Vista and later to allow involvement in the end-user logon experience.</p>
  470. <p>While customizing the logon process is done at the logon application side with GINAs or CPs, sometimes customization is required at the authentication side, in the <a href="http://msdn.microsoft.com/en-us/library/aa378326(VS.85).aspx">Local Security Authority</a> subsystem. For instance, a fingerprint reader may customize the logon UI to allow fingerprint scanning as a means of authentication. The customized logon application will call <a href="http://msdn.microsoft.com/en-us/library/aa378292(VS.85).aspx">LsaLogonUser</a> with the fingerprint scanner&#8217;s custom LSA authentication package as the desired authenticator. The fingerprint LSA AP will scan a fingerprint database it maintains to perform the authentication process. That would be an independent LSA authenticaion package.</p>
  471. <p>There are other scenarios in which the regular MSV1_0/Kerberos based logon authentication process is desired, but special pre or post-processing is required. In Windows XP, the problematic GINA architecture makes replacing the GINA cumbersome, as multiple third-party applications may attempt to install conflicting GINA replacements. Indeed, Microsoft documentation has been modified retroactively to recommend <a href="http://msdn.microsoft.com/en-us/library/aa378292(VS.85).aspx">GINA hooks and stubs</a> in lieu of outright replacement of the MSGINA implementation previously suggested.</p>
  472. <p>With the ability to instrument the logon application at the GINA side limited and version dependent (a totally different approach is required for Vista&#8217;s CPs), the alternative of instrumentation at the LSA side warrants exploration. We can implement an LSA <em>proxy</em> authentication package. Such a package would appear to the LSA server as an ordinary package, but would be implemented by delegating to original APs like MSV1_0 and Kerberos, providing it with monitoring and instrumentation capabilities.</p>
  473. <p>LSA authentication packages are loaded by LSASS at system startup by enumerating them from the registry value <em>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Security Packages</em>. Both LSA authentication packages (APs) and security providers (SSPs) are registered at that location. For the purposes of this post, we&#8217;ll ignore pure SSPs and focus only on APs. We will register our proxy authentication package instead of MSV1_0 (and possibly Kerberos) at this location, and leave loading of the original APs to our proxy AP implementation.</p>
  474. <p>Let us examine the system&#8217;s core APs, MSV1_0 and Kerberos:<br />
  475. <code><br />
  476. C:\WINDOWS\system32&gt;dumpbin /exports <strong>msv1_0.dll</strong><br />
  477. Microsoft (R) COFF/PE Dumper Version 9.00.30729.01<br />
  478. Copyright (C) Microsoft Corporation.  All rights reserved.<br />
  479. Dump of file msv1_0.dll<br />
  480. File Type: DLL<br />
  481. Section contains the following exports for msv1_0.dll<br />
  482. 00000000 characteristics<br />
  483. 48025C84 time date stamp Sun Apr 13 22:18:28 2008<br />
  484. 0.00 version<br />
  485. 1 ordinal base<br />
  486. 32 number of functions<br />
  487. 17 number of names<br />
  488. ordinal hint RVA      name<br />
  489. 5    0 0000175C LsaApCallPackage = _LsaApCallPackage@28<br />
  490. 6    1 00014BC8 LsaApCallPackagePassthrough = _LsaApCallPackagePassthr<br />
  491. ough@28<br />
  492. 7    2 00014A59 LsaApCallPackageUntrusted = _LsaApCallPackageUntrusted<br />
  493. @28<br />
  494. 8    3 0000BDBB LsaApInitializePackage = _LsaApInitializePackage@20<br />
  495. 9    4 0000F7FE LsaApLogonTerminated = _LsaApLogonTerminated@4<br />
  496. 10    5 00007498 LsaApLogonUserEx2 = _LsaApLogonUserEx2@64<br />
  497. 11    6 0001A7E5 <strong><em>Msv1_0ExportSubAuthenticationRoutine</em></strong> = _Msv1_0ExportSu<br />
  498. bAuthenticationRoutine@40<br />
  499. 12    7 0001A7C6 <em><strong>Msv1_0SubAuthenticationPresent</strong></em> = _Msv1_0SubAuthenticat<br />
  500. ionPresent@4<br />
  501. 13    8 00016E63 MsvGetLogonAttemptCount = _MsvGetLogonAttemptCount@0<br />
  502. 2    9 0001B704 MsvIsLocalhostAliases = ?MsvIsLocalhostAliases@@YGHPAU<br />
  503. _UNICODE_STRING@@@Z (int __stdcall MsvIsLocalhostAliases(struct _UNICODE_STRING<br />
  504. *))<br />
  505. 14    A 00016E59 MsvSamLogoff = _MsvSamLogoff@12<br />
  506. 15    B 0000A7BA MsvSamValidate = _MsvSamValidate@52<br />
  507. 16    C 00016E6E MsvValidateTarget = _MsvValidateTarget@12<br />
  508. 1    D 0000E415 <strong>SpInitialize</strong> = _SpInitialize@12<br />
  509. 32    E 00006BC2 SpInstanceInit = _SpInstanceInit@12<br />
  510. 3    F 0000F08F <strong>SpLsaModeInitialize</strong> = ?SpLsaModeInitialize@@YGJKPAKPAP<br />
  511. AU_SECPKG_FUNCTION_TABLE@@0@Z (long __stdcall SpLsaModeInitialize(unsigned long,<br />
  512. unsigned long *,struct _SECPKG_FUNCTION_TABLE * *,unsigned long *))<br />
  513. 4   10 00006AE0 <strong>SpUserModeInitialize</strong> = ?SpUserModeInitialize@@YGJKPAKP<br />
  514. APAU_SECPKG_USER_FUNCTION_TABLE@@0@Z (long __stdcall SpUserModeInitialize(unsign<br />
  515. ed long,unsigned long *,struct _SECPKG_USER_FUNCTION_TABLE * *,unsigned long *))<br />
  516. Summary<br />
  517. 2000 .data<br />
  518. 2000 .reloc<br />
  519. 2000 .rsrc<br />
  520. 1D000 .text<br />
  521. C:\WINDOWS\system32&gt;dumpbin /exports <strong>kerberos.dll</strong><br />
  522. Microsoft (R) COFF/PE Dumper Version 9.00.30729.01<br />
  523. Copyright (C) Microsoft Corporation.  All rights reserved.<br />
  524. Dump of file kerberos.dll<br />
  525. File Type: DLL<br />
  526. Section contains the following exports for Kerberos.dll<br />
  527. 00000000 characteristics<br />
  528. 48025C4A time date stamp Sun Apr 13 22:17:30 2008<br />
  529. 0.00 version<br />
  530. 1 ordinal base<br />
  531. 32 number of functions<br />
  532. 10 number of names<br />
  533. ordinal hint RVA      name<br />
  534. 5    0 00026F8A KerbCreateTokenFromTicket = _KerbCreateTokenFromTicket<br />
  535. @44<br />
  536. 2    1 00025773 KerbDomainChangeCallback = ?KerbDomainChangeCallback@@<br />
  537. YGXW4_POLICY_NOTIFICATION_INFORMATION_CLASS@@@Z (void __stdcall KerbDomainChange<br />
  538. Callback(enum _POLICY_NOTIFICATION_INFORMATION_CLASS))<br />
  539. 6    2 000018B0 KerbFree = _KerbFree@4<br />
  540. 7    3 00020A71 KerbIsInitialized = _KerbIsInitialized@0<br />
  541. 8    4 00020A7C KerbKdcCallBack = _KerbKdcCallBack@0<br />
  542. 9    5 0000380B KerbMakeKdcCall = _KerbMakeKdcCall@32<br />
  543. 1    6 00013CAD <strong>SpInitialize</strong> = _SpInitialize@12<br />
  544. 32    7 0000EDDF SpInstanceInit = _SpInstanceInit@12<br />
  545. 3    8 000151DE <strong>SpLsaModeInitialize</strong> = ?SpLsaModeInitialize@@YGJKPAKPAP<br />
  546. AU_SECPKG_FUNCTION_TABLE@@0@Z (long __stdcall SpLsaModeInitialize(unsigned long,<br />
  547. unsigned long *,struct _SECPKG_FUNCTION_TABLE * *,unsigned long *))<br />
  548. 4    9 0000ED1E <strong>SpUserModeInitialize</strong> = ?SpUserModeInitialize@@YGJKPAKP<br />
  549. APAU_SECPKG_USER_FUNCTION_TABLE@@0@Z (long __stdcall SpUserModeInitialize(unsign<br />
  550. ed long,unsigned long *,struct _SECPKG_USER_FUNCTION_TABLE * *,unsigned long *))<br />
  551. Summary<br />
  552. 2000 .data<br />
  553. 3000 .reloc<br />
  554. 3000 .rsrc<br />
  555. 43000 .text</code></p>
  556. <p>Both DLLs export the <a href="http://msdn.microsoft.com/en-us/library/aa380171(VS.85).aspx">SpInitialize</a> function used for SSP initialization and for AP initialization export <a href="http://msdn.microsoft.com/en-us/library/aa380175(VS.85).aspx">SpLsaModeInitialize</a> and <a href="http://msdn.microsoft.com/en-us/library/aa380185(VS.85).aspx">SpUserModeInitialize</a>, called in LSASS context and in logon application context by secur32.dll, respectively.</p>
  557. <p>As can be seen in MSV1_0&#8217;s export table, it provides a <a href="http://msdn.microsoft.com/en-us/library/aa374786(VS.85).aspx">subauthentication package</a> facility for those interested in becoming involved in the logon process. Clearly, this is the facility Microsoft intended third-parties to use, rather than creating proxy authentication packages. Unfortunately, subauthentication packages only provide a subset of authentication package functionality, primarily failing to provide access to the interactive logon (as opposed to the network logon) process. You should carefully consider your requirements. If they can be met with a subauthentication package, it is best to opt for that approach as it is far more likely to remain intact in Windows 7 and beyond. That said, the proxy authentication package model is given some legitimacy by <a href="http://msdn.microsoft.com/en-us/library/aa374784(VS.85).aspx">this diagram</a>, illustrating delegation to MSV1_0 by a hypothetical third-party custom authentication package.</p>
  558. <p>It is interesting to note that MSV1_0 chooses to export the various LSA AP functions, such as LsaApLogonUserEx2, etc., via its DLL export table, while Kerberos opts not to export them, though quick examination of Kerberos.dll&#8217;s public symbols clearly illustrates the presence of the AP functions. So how does the LSA server know how to find and call the various AP functions? They are provided in a function dispatch table filled by the AP at initialization time, when <a href="http://msdn.microsoft.com/en-us/library/aa380175(VS.85).aspx">SpLsaModeInitialize</a> or <a href="http://msdn.microsoft.com/en-us/library/aa380185(VS.85).aspx">SpUserModeInitialize</a> are invoked (depending on the context of the AP&#8217;s use).</p>
  559. <p>Keeping in mind that MSV1_0 was around before Kerberos was added to Windows NT in the Windows 2000 release and therefore may have remaining legacy cruft, reviewing the disassembly of the LSA server DLL, LSASRV, reveals that LSA first calls the Initialize functions to let the AP fill the function dispatch table, but then promptly examines the AP&#8217;s export table with <a href="http://msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx">GetProcAddress</a> in the aptly named <strong>lsasrv!BindOldPackage</strong> function. This function appears to be invoked for the AP even when the function dispatch table has been filled. However, empirical evidence appears to suggest that the function dispatch table takes precedence over the contents of the export table. Indeed, Kerberos opts to do away with the export table entirely.</p>
  560. <p>It appears that the export-based model was replaced with the dispatch table based model at some point during the lifetime of Windows NT. The export model has an obvious disadvantage of allowing a single DLL to implement only a single authentication package, a restriction will come back to later. The dispatch table model, on the other hand, allows the initialization function to return multiple dispatch tables, for multiple authentication packages, from a single DLL. This may yet prove useful for a proxy package.</p>
  561. <p>In order to explore the feasibility of creating a proxy LSA authentication package, I wrote a test DLL, dubbed &#8220;LsaPrxAp&#8221;. This DLL provides the <a href="http://msdn.microsoft.com/en-us/library/aa380171(VS.85).aspx">SpInitialize</a>, SpLsaModeInitialize and SpUserModeInitialize exports. When invoked, it loads msv1_0 if it is not yet loaded. The DLL&#8217;s Initialize functions call the original msv1_0&#8217;s Initialize functions and then hook the authentication package by replacing function pointers with pointers to implementations of the LSA AP functions residing in LSAPrxAp. The original function pointers are saved in a global data structure so that LSAPrxAp&#8217;s stubs can invoke them while having value-added processing during the logon sequence. Since the name of the authentication package is the one provided in the SpLsaModeInitialize function by the AP, rather than the DLL&#8217;s name, it is easy to proxy the MSV1_0 module and become involved in the logon process. I did not bother with supporting Kerberos in my test, but hypothetically the proxy AP can call the Initialize functions for both MSV1_0 and Kerberos and return two dispatch tables as the parameter model for it allows.</p>
  562. <p>Proxying a known authentication package of a known revision is one thing, but a more generic approach warrants special consideration. In both XP and Vista, the APs provide the latest <a href="http://msdn.microsoft.com/en-us/library/aa378257(VS.85).aspx">LsaApLogonUserEx2 </a>function. However, it is preceeded by <a href="http://msdn.microsoft.com/en-us/library/aa378248(VS.85).aspx">LsaApLogonUserEx</a> and <a href="http://msdn.microsoft.com/en-us/library/aa378244(VS.85).aspx">LsaApLogonUser</a>. The documentation for AP developers seems to indicate it is still legitimate to only support one of the older variants. Therefore, the proxy should take note that NULL function pointers in the dispatch table provided by the original APs are possible and should react accordingly.</p>
  563. <p>As I investigated the behavior of the LSA server with respect to the export-based model for locating LSA AP functions vs. the function dispatch table model, I considered the problem of implementing a generic proxy if the dispatch table model was not preferred over the export table. The proxy AP would have to load the original AP and only have an LsaApLogonUserEx2 function if the original AP has. If the original AP has no <a href="http://msdn.microsoft.com/en-us/library/aa378244(VS.85).aspx">LsaApLogonUser</a> function exported, neither should the proxy AP. This presents special complication since compiling a different proxy AP for every possible set of exports is not feasible. I reiterate that the problem is theoretical since the function dispatch table model has no such fallacy.</p>
  564. <p>In order to deal with this issue, I devised an approach where the proxy AP would initially export all possible LSA AP functions. At runtime, as the actual exports of the original AP is detected, functions that are missing from the original AP can be unexported from the proxy AP. I discuss the technique of unexporting functions through name obfuscation in the <a href="https://kobyk.wordpress.com/2008/08/30/unexporting-a-function-from-a-dll-at-runtime-by-name-obfuscation/">previous post</a>.</p>
  565. <p>Successfully compiling an LSA AP DLL required numerous acts of header juggling. For reference purposes, I provide the sequence I used:</p>
  566. <pre class="brush: cpp; title: ; notranslate">
  567. #include &lt;ntstatus.h&gt;
  568. #define WIN32_NO_STATUS
  569. #include &lt;Windows.h&gt;
  570. #include &lt;NTSecAPI.h&gt;
  571. #define SECURITY_WIN32
  572. #include &lt;SSPI.h&gt;
  573.  
  574. #ifndef NT_SUCCESS
  575. #define NT_SUCCESS(Status) ((NTSTATUS)(Status) &gt;= 0)
  576. #endif
  577.  
  578. // LsaApCallPackageUntrusted is partially missing from NTSecPkg.h
  579. typedef NTSTATUS
  580. (NTAPI LSA_AP_CALL_PACKAGE_UNTRUSTED)(
  581. __in PLSA_CLIENT_REQUEST ClientRequest,
  582. __in PVOID ProtocolSubmitBuffer,
  583. __in PVOID ClientBufferBase,
  584. __in ULONG SubmitBufferLength,
  585. __out PVOID* ProtocolReturnBuffer,
  586. __out PULONG ReturnBufferLength,
  587. __out PNTSTATUS ProtocolStatus
  588. );
  589. </pre>
  590. <p>The WIN32_NO_STATUS definition is required to prevent Windows.h from defining the NTSTATUS values. Letting ntstatus.h define them is required because Windows.h only defines a subset of the required values. SSPI.h requires choosing between Win32, Kernel-mode and Macintosh Classic (heh&#8230;) usage, resulting in the SECURITY_WIN32 preprocessor definition. The NTSecPkg.h header included with the Windows SDK I&#8217;m using makes the embarrassing error of missing the prototype for <a href="http://msdn.microsoft.com/en-us/library/aa378218(VS.85).aspx">LsaApCallPackageUntrusted</a>, while curiously attempting to provide the function pointer type for it.</p>
  591. <p>It is wise to avoid loading the original AP DLLs during DllMain, due to potential loader lock issues. The first functions invoked after an AP DLL has been mapped to a process are those that fill the function dispatch table; SpInitialize for the SSP case, SpLsaModeInitialize for the LSASS-side AP case and SpUserModeInitialize for the secur32.dll logon application (Winlogon) side case. All three functions ought to load the original AP if required and perform any required hooking of the dispatch tables, pointing to your own proxy functions.</p>
  592. <p>The initialization functions should also extract the function pointers for the original AP implementations and preserve them in global data. This can later be used to forward calls to the original implementation. Consider the implementation of LsaApCallPackage in my LsaPrxAp test DLL:</p>
  593. <pre class="brush: cpp; title: ; notranslate">
  594. NTSTATUS NTAPI LsaApCallPackage(
  595. __in PLSA_CLIENT_REQUEST ClientRequest,
  596. __in PVOID ProtocolSubmitBuffer,
  597. __in PVOID ClientBufferBase,
  598. __in ULONG SubmitBufferLength,
  599. __out PVOID* ProtocolReturnBuffer,
  600. __out PULONG ReturnBufferLength,
  601. __out PNTSTATUS ProtocolStatus
  602. )
  603. {
  604. OutputDebugString(TEXT(&quot;lsaaprxap LsaApCallPackage\n&quot;));
  605.  
  606. return g_LsaPrxApFunctionTable.pLsaApCallPackage(
  607. ClientRequest, ProtocolSubmitBuffer, ClientBufferBase,
  608. SubmitBufferLength, ProtocolReturnBuffer, ReturnBufferLength,
  609. ProtocolStatus);
  610. }
  611. </pre>
  612. <p>Obviously a real-world proxy AP would perform required processing before or after forwarding to the original function pointer preserved in global data, as well.</p>
  613. <p>Hopefully this primer on implementing an LSA proxy AP will prove to be a welcome addition to Microsoft&#8217;s sparse documentation on LSA authentication packages.</p>
  614. ]]></content:encoded>
  615. <wfw:commentRss>https://kobyk.wordpress.com/2008/08/30/implementing-an-lsa-proxy-authentication-package/feed/</wfw:commentRss>
  616. <slash:comments>21</slash:comments>
  617. <media:content url="https://1.gravatar.com/avatar/1d5c3d0abc3891afb6e88eebc51b004c3ed48b5fc2bc4a0f0ff7f6e507c80ed4?s=96&#38;d=identicon&#38;r=G" medium="image">
  618. <media:title type="html">KK</media:title>
  619. </media:content>
  620. </item>
  621. <item>
  622. <title>Unexporting a function from a DLL at runtime by name obfuscation</title>
  623. <link>https://kobyk.wordpress.com/2008/08/30/unexporting-a-function-from-a-dll-at-runtime-by-name-obfuscation/</link>
  624. <comments>https://kobyk.wordpress.com/2008/08/30/unexporting-a-function-from-a-dll-at-runtime-by-name-obfuscation/#comments</comments>
  625. <dc:creator><![CDATA[Koby Kahane]]></dc:creator>
  626. <pubDate>Sat, 30 Aug 2008 14:56:34 +0000</pubDate>
  627. <category><![CDATA[C++]]></category>
  628. <guid isPermaLink="false">http://kobyk.wordpress.com/?p=32</guid>
  629.  
  630. <description><![CDATA[Usually, the set of functions exported by a Windows DLL is considered to be immutable. When load-time binding is used, functions appearing in the loading module&#8217;s import table are resolved against the export table of the loaded DLL. If any &#8230; <a href="https://kobyk.wordpress.com/2008/08/30/unexporting-a-function-from-a-dll-at-runtime-by-name-obfuscation/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
  631. <content:encoded><![CDATA[<p>Usually, the set of functions exported by a Windows DLL is considered to be immutable. When load-time binding is used, functions appearing in the loading module&#8217;s import table are resolved against the export table of the loaded DLL. If any imported functions are missing, the loader aborts the module load attempt and unmaps the modules.</p>
  632. <p>Library clients which require a more flexible reaction to the presence or absence of specific exports opt for a more dynamic binding approach, either late binding via <a href="http://msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx">GetProcAddress</a> directly or through the Visual C++ <a href="http://msdn.microsoft.com/en-us/library/151kt790.aspx">delay loading</a> facility, which allows for setting callbacks for missing modules or exports.</p>
  633. <p>Recently, as I was experimenting with implementing an LSA proxy authentication package (more on that in a followup post) I considered the issue of properly implementing a proxy DLL for a DLL whose set of exports is only partially known to the proxy. Modern LSA APs have a callback function that provides a function dispatch table and do no rely on the module&#8217;s export table, but for pedagogic purposes let us consider an hypothetical situation in which the export table is the only lookup apparatus in use by the LSA.</p>
  634. <p>In the case of an LSA authentication package, the package may provide an implementation of either <a href="http://msdn.microsoft.com/en-us/library/aa378244(VS.85).aspx">LsaApLogonUser</a>, <a href="http://msdn.microsoft.com/en-us/library/aa378248(VS.85).aspx">LsaApLogonUserEx</a> or <a href="http://msdn.microsoft.com/en-us/library/aa378257(VS.85).aspx">LsaApLogonUserEx2</a>. An original LSA AP can export one or more of these functions. If we want to create a generic LSA AP proxy DLL, we may wish to have a specific export from our module, loaded in lieu of the original AP, only if the original module also had it. This presents difficulty since we may not be able to predict the specific set of exports during proxy compile time.</p>
  635. <p>If we recognize that DLL exports are in fact a poor man&#8217;s native code reflection mechanism, we can adopt a non-traditional approach of dynamic modification of our module&#8217;s set of exported functions. Our proxy DLL shall initially (at compile time) export all functions that could potentially be exported by the original DLL, e.g. by a module definition (.DEF) file like this:<br />
  636. <code><br />
  637. LIBRARY "lsaprxap"<br />
  638. EXPORTS<br />
  639. LsaApInitializePackage<br />
  640. <strong>LsaApLogonUser<br />
  641. LsaApLogonUserEx<br />
  642. LsaApLogonUserEx2</strong><br />
  643. LsaApCallPackage<br />
  644. LsaApCallPackagePassthrough<br />
  645. LsaApLogonTerminated<br />
  646. LsaApCallPackageUntrusted<br />
  647. SpInitialize<br />
  648. SpInstanceInit<br />
  649. SpLsaModeInitialize<br />
  650. SpUserModeInitialize</code></p>
  651. <p>Notice how we export all three functions, even though some may not appear in the original DLL. LSA uses late binding via GetProcAddress to decide which function in the AP to call. If we export LsaApLogonUserEx2 and our original DLL does not have that function, we&#8217;ll have nothing to do when our proxy function is called (no original to forward to after our own processing). There is no telling what will happen if we return STATUS_NOT_IMPLEMENTED. Besides, LSA AP&#8217;s are only an illustration, and in other cases the export might not even have the option to return a failure exit code. Therefore, the behavior we desire is that GetProcAddress for LsaApLogonUserEx2 will fail and return NULL if the original DLL for which we are acting as a proxy does not export LsaApLogonUserEx2 itself.</p>
  652. <p>The names and addresses of exported functions from a DLL appear in the PE image&#8217;s export directory. By accessing the export directory, looking up an exported function of interest and removing it we can alter the behavior of GetProcAddress for the exported function at runtime, after the module has been loaded. Note that this alteration is only useful for GetProcAddress invocations from that time forward, and callers that invoked GetProcAddress earlier and cached the result or callers that used load-time binding against our export table already obtained a function pointer to the exported function. Therefore, this technique is only useful in limited circumstances.</p>
  653. <p>The export directory points to a block of null-terminated string pointers, indexed by export ordinal. In order to outright remove an export from the middle of the export table, we&#8217;d have to copy the export table aside, remove the desired functions and point the PE header to the new export table. This is a feasible, but cumbersome approach. Instead I opted for an alternative technique &#8211; obfuscating the name of the export to prevent GetProcAddress callers from resolving it by its well-known name. The function is still exported, but its name is unknown to other callers. This is probably sufficient for the vast majority of cases. As for the obfuscation itself, in this illustration we&#8217;ll merely increment the character value of the first letter in the export:</p>
  654. <pre class="brush: cpp; title: ; notranslate">
  655. // Set by the linker to the base address of the module.
  656. EXTERN_C IMAGE_DOS_HEADER __ImageBase;
  657.  
  658. void UnexportFunction(LPSTR ExportName)
  659. {
  660. IMAGE_DOS_HEADER* dosHeader = &amp;__ImageBase;
  661. assert(dosHeader-&gt;e_magic == IMAGE_DOS_SIGNATURE);
  662. IMAGE_NT_HEADERS* ntHeaders = reinterpret_cast&lt;IMAGE_NT_HEADERS*&gt;(
  663. reinterpret_cast&lt;BYTE*&gt;(dosHeader) + dosHeader-&gt;e_lfanew);
  664. assert(ntHeaders-&gt;Signature == 0x00004550);
  665. IMAGE_OPTIONAL_HEADER* optionalHeader = &amp;ntHeaders-&gt;OptionalHeader;
  666. IMAGE_DATA_DIRECTORY* exportDataDirectory =
  667. &amp;optionalHeader-&gt;DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
  668. IMAGE_EXPORT_DIRECTORY* exportDirectory = reinterpret_cast&lt;IMAGE_EXPORT_DIRECTORY*&gt;(
  669. reinterpret_cast&lt;BYTE*&gt;(dosHeader) + exportDataDirectory-&gt;VirtualAddress);
  670.  
  671. ULONG* addressOfNames = reinterpret_cast&lt;ULONG*&gt;(
  672. reinterpret_cast&lt;BYTE*&gt;(dosHeader) + exportDirectory-&gt;AddressOfNames);
  673. for (DWORD i = 0; i &lt; exportDirectory-&gt;NumberOfFunctions; i++)
  674. {
  675. LPSTR exportFunctionName = reinterpret_cast&lt;LPSTR&gt;(
  676. reinterpret_cast&lt;BYTE*&gt;(dosHeader) + addressOfNames[i]);
  677. if (strcmp(exportFunctionName, ExportName) == 0)
  678. {
  679. DWORD oldProtect = 0;
  680. BOOL rc = VirtualProtect(
  681. exportFunctionName,
  682. strlen(exportFunctionName),
  683. PAGE_READWRITE,
  684. &amp;oldProtect);
  685. if (rc == FALSE)
  686. {
  687. OutputDebugString(TEXT(&quot;VirtualProtect failed.\n&quot;));
  688. }
  689. exportFunctionName[0]++;
  690. break;
  691. }
  692. }
  693. }
  694. </pre>
  695. <p>The sample UnexportFunction function iterates over the current module&#8217;s export table until the function of interest is encountered. Since the export table is mapped as read-only memory, <a href="http://msdn.microsoft.com/en-us/library/aa366898(VS.85).aspx">VirtualProtect </a>must be used to allow for its modification. The string containing the name of the exported function is modified in place as a trivial obfuscation. This is sufficient to result in the &#8220;unexporting&#8221; of the symbol:</p>
  696. <pre class="brush: cpp; title: ; notranslate">
  697. FARPROC before = GetProcAddress((HMODULE)&amp;__ImageBase, &quot;LsaApLogonUser&quot;);
  698. UnexportFunction(&quot;LsaApLogonUser&quot;);
  699. FARPROC after = GetProcAddress((HMODULE)&amp;__ImageBase, &quot;LsaApLogonUser&quot;);
  700. assert(before != after);
  701. assert(after == NULL);
  702. </pre>
  703. <p>With this tool of export entry removal at our disposal, we can devise an architecture in which the proxy DLL contains all exports that are feasible to be present in the original DLL at runtime. Through &#8220;reflection&#8221; of the original DLL, the proxy shall determine which redundant exports it wishes to hide, resulting it runtime behavior consistent with that of the original DLL (again, assuming only late binding with GetProcAddress is used).</p>
  704. <p>What if we are unable to construct a superset of all possible exports from the original DLL? Perhaps we wish to be future-proof as new, unknown exports are added to the original DLL. For that a variety of solutions may be considered. In particular, copying the original DLL&#8217;s export table to our own and inserting hooks as needed comes to mind. Perhaps a topic for a future post&#8230;</p>
  705. ]]></content:encoded>
  706. <wfw:commentRss>https://kobyk.wordpress.com/2008/08/30/unexporting-a-function-from-a-dll-at-runtime-by-name-obfuscation/feed/</wfw:commentRss>
  707. <slash:comments>3</slash:comments>
  708. <media:content url="https://1.gravatar.com/avatar/1d5c3d0abc3891afb6e88eebc51b004c3ed48b5fc2bc4a0f0ff7f6e507c80ed4?s=96&#38;d=identicon&#38;r=G" medium="image">
  709. <media:title type="html">KK</media:title>
  710. </media:content>
  711. </item>
  712. <item>
  713. <title>Debugging user-mode BootExecute native applications with kd</title>
  714. <link>https://kobyk.wordpress.com/2008/07/26/debugging-user-mode-bootexecute-native-applications-with-kd/</link>
  715. <comments>https://kobyk.wordpress.com/2008/07/26/debugging-user-mode-bootexecute-native-applications-with-kd/#comments</comments>
  716. <dc:creator><![CDATA[Koby Kahane]]></dc:creator>
  717. <pubDate>Sat, 26 Jul 2008 14:25:48 +0000</pubDate>
  718. <category><![CDATA[Windbg]]></category>
  719. <guid isPermaLink="false">http://kobyk.wordpress.com/?p=26</guid>
  720.  
  721. <description><![CDATA[Debugging code executing during system startup always poses a unique challenge. One may need to debug a custom or built-in Windows service right from the start, when attaching to it after it has initialized proves insufficient or inappropriate. When developing &#8230; <a href="https://kobyk.wordpress.com/2008/07/26/debugging-user-mode-bootexecute-native-applications-with-kd/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
  722. <content:encoded><![CDATA[<p>Debugging code executing during system startup always poses a unique challenge. One may need to debug a custom or built-in Windows service right from the start, when attaching to it after it has initialized proves insufficient or inappropriate. When developing a <a href="http://msdn.microsoft.com/en-us/library/aa375198(VS.85).aspx#hook">GINA hook</a> or <a href="http://msdn.microsoft.com/en-us/library/aa375198(VS.85).aspx#stub">GINA stub</a>, the need to debug the Winlogon process before the logon process is performed arises. The inability of the Visual Studio Debugger to be useful in these situations is one of the reasons people turn to Windbg.</p>
  723. <p>For debugging Windows services or the Winlogon process during startup, <a href="http://msdn.microsoft.com/en-us/library/cc267855.aspx">Image File Execution Options </a>provides a workable solution. As soon as a process of the name specified under the Image File Execution Options registry key is created, the debugger command-line specified in the Debugger value is executed in lieu of the original command-line, which is appended to the debugger command-line. The debugger started might be Visual Studio&#8217;s, if appropriate, an interactive Windbg in other cases or an NTSD remote debugging server when you will not or cannot do things like make the service process interactive.</p>
  724. <p>For the vast majority of startup applications, the aforementioned technique is both quite sufficient and convenient. However, there is another, perhaps esoteric, category of startup processes. These run a very early stage of the boot process. They are the <a href="http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/regentry/46697.mspx?mfr=true">BootExecute</a> applications.</p>
  725. <p>BootExecute applications are started by the Session Manager (smss.exe) before invoking the &#8220;initial command&#8221; (Winlogon in XP) and before the various subsystems are started. As far as user-mode goes, it doesn&#8217;t get much earlier than this. Because of their early nature, a significant constraint is in place for BootExecute applications: they are native applications.</p>
  726. <p>Do not confuse this usage of &#8220;native&#8221; with native code vs. .NET managed code. In this context, native means that only the Windows NT Native API, resident in ntdll.dll, is available. At this stage, the Win32 subsystem, composed of the kernel-mode win32k.sys component and the user-mode client/server runtime, CSRSS, have not yet been started by SMSS. Not even the Kernel32 library is usable by BootExecute applications.</p>
  727. <p>What are these useful for? Those special tasks that must be performed before everything else has started in the system, yet remain in the domain of user-mode work. Consider these two typical examples:</p>
  728. <ul>
  729. <li>AutoCheck, the BootExecute variant of the CHKDSK tool, used to examine the boot volume before it is locked and to fix critical file-system errors.</li>
  730. <li>Sysinternals PageDefrag, a BootExecute utility that defragments the Paging File, registry hives and other files inaccessible to defragging by the normal Win32 Disk Defragmentation tool.</li>
  731. </ul>
  732. <p>We can confirm that AutoCheck is indeed a native application by examining it with Visual C++&#8217;s DUMPBIN utility:<br />
  733. <code><br />
  734. C:\WINDOWS\system32&gt;dumpbin /headers autochk.exe<br />
  735. Microsoft (R) COFF/PE Dumper Version 9.00.21022.08<br />
  736. Copyright (C) Microsoft Corporation.  All rights reserved.<br />
  737. </code><code><br />
  738. Dump of file autochk.exe<br />
  739. </code><code><br />
  740. PE signature found<br />
  741. </code><code><br />
  742. File Type: EXECUTABLE IMAGE<br />
  743. </code><code><br />
  744. FILE HEADER VALUES<br />
  745. 14C machine (x86)<br />
  746. 4 number of sections<br />
  747. 48025203 time date stamp Sun Apr 13 21:33:39 2008<br />
  748. 0 file pointer to symbol table<br />
  749. 0 number of symbols<br />
  750. E0 size of optional header<br />
  751. 10E characteristics<br />
  752. Executable<br />
  753. Line numbers stripped<br />
  754. Symbols stripped<br />
  755. 32 bit word machine<br />
  756. </code><code><br />
  757. OPTIONAL HEADER VALUES<br />
  758. 10B magic # (PE32)<br />
  759. 7.10 linker version<br />
  760. 5B800 size of code<br />
  761. 34200 size of initialized data<br />
  762. 0 size of uninitialized data<br />
  763. D6B9 <strong>entry point (0100D6B9) _NtProcessStartupForGS@4</strong><br />
  764. 1000 base of code<br />
  765. 5D000 base of data<br />
  766. 1000000 image base (01000000 to 01091FFF)<br />
  767. 1000 section alignment<br />
  768. 200 file alignment<br />
  769. 5.01 operating system version<br />
  770. 5.01 image version<br />
  771. 5.01 subsystem version<br />
  772. 0 Win32 version<br />
  773. 92000 size of image<br />
  774. 400 size of headers<br />
  775. 96A6F checksum<br />
  776. 1 <strong>subsystem (Native)</strong><br />
  777. 0 DLL characteristics<br />
  778. 40000 size of stack reserve<br />
  779. 1000 size of stack commit<br />
  780. 100000 size of heap reserve<br />
  781. 1000 size of heap commit<br />
  782. 0 loader flags<br />
  783. 10 number of directories<br />
  784. ... <strong>snipped </strong>...</code></p>
  785. <p>Notice the subsystem specified for AutoChk is the native subsystem. Notice further that the application&#8217;s entrypoint is NtProcessStartup (in its /GS compiler stack buffer overflow protection stub form).</p>
  786. <p>As for PageDefrag, it takes advantage of the Session Manager running its BootExecute application before it has enabled use of the Paging File.</p>
  787. <p>You may find reasons of your own to develop a BootExecute native application, or you may find yourself in a situation requiring debugging of an existing BootExecute application. For instance, you may wish to debug the interactions of AutoChk&#8217;s volume locking attempts with your file system filter driver.</p>
  788. <p>Unfortunately, these native applications pose a special difficulty to the user-mode debugger. NTSD is a Win32 application and must be invoked only after the Win32 subsystem has been initialized. Therefore, invocation of NTSD for debugging BootExecute applications is out of the question. Indeed, it is quite likely the Image File Execution Options registry key is not even consulted for BootExecute invocations, as that would be quite pointless.</p>
  789. <p>Theoretically, this problem could be addressed by the development of a native subsystem user mode debugger, in lieu of the Win32-based NTSD. <a href="http://www.alex-ionescu.com/">Alex Ionescu</a>, most recently contributing to the eagerly awaited <a href="http://www.microsoft.com/mspress/books/12069.aspx">5th edition of the Windows Internals book</a>, has discussed the specifics of the NT Native Debugging API (DbgUi, etc.) in a series of articles titled <a href="http://www.openrce.org/articles/full_view/24">Windows Native Debugging Internals</a>.</p>
  790. <p>At the moment, however, I am unaware of any available native subsystem user mode debugger. Such a tool may or may not be available internally in Microsoft. Presumably the Windows developers would benefit from such functionality, but they might also be content with using the kernel debugger for those purposes.</p>
  791. <p>Be that as it may, the rest of us must turn to the kernel debugger for resolution. The kernel debugger can be used for source-level debugging of user-mode applications, including native subsystem applications. The special difficulty with using it is getting to break in the right place at the right time. In lieu of a Image File Execution Options-style apparatus, an alternative approach is required.</p>
  792. <p>When modifying the native BootExecute application in question is feasible, the simple approach of adding an invocation of ntdll&#8217;s <a href="http://msdn.microsoft.com/en-us/library/ms792809.aspx">DbgBreakPoint</a> API to the top of the NtProcessStartup process entrypoint is probably the quickest way to get the desired effect. In the absence of a user-mode debugger, the debug break will make its way to the kernel debugger. The debugger will notice the presence of the user-mode module, load symbols and source and the usual debugger functions will be accessible. If source is not available, in many cases the image can be patched to contain either an invocation of DbgBreakPoint or just an inline INT 3, as appropriate.</p>
  793. <p>Such an approach, however, may not be feasible at all times and has the significant disadvantage of making the modified native application hang when a kernel debugger is not attached to the system at boot. Ideally, we&#8217;d like to break at process startup without modifying the native application at all.</p>
  794. <p>When using the user-mode debugger, &#8220;sxe ld&#8221; can break when user-mode modules are mapped by the loader, as documented in <a href="http://msdn.microsoft.com/en-us/library/cc266379.aspx">Controlling Exceptions and Events</a>. Normally, the kernel debugger does not provide that capability. However, it turns out that it can do so, once appropriately configured.</p>
  795. <p>Before booting with the kernel debugger, turn on the &#8220;<a href="http://msdn.microsoft.com/en-us/library/cc265929.aspx">Enable loading of kernel debugger symbols</a>&#8221; Global Flag, using the GFlags utility bundled with the Debugging Tools for Windows:<br />
  796. <code><br />
  797. C:\Program Files\Debugging Tools for Windows&gt;gflags /r +ksl<br />
  798. Current Boot Registry Settings are: 00040000<br />
  799. ksl - Enable loading of kernel debugger symbols</code></p>
  800. <p>Although the name and description of this Global Flag appear to have nothing to do with user-mode module load events in the kernel debugger, they acheive the desired effect. Once enabled, we can reboot with the kernel debugger attached and ask for the kernel debugger to break once the desired native application is mapped:<br />
  801. <code><br />
  802. Microsoft (R) Windows Debugger Version 6.9.0003.113 X86<br />
  803. Copyright (c) Microsoft Corporation. All rights reserved.<br />
  804. </code><code><br />
  805. Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE<br />
  806. Kernel Debugger connection established.  (Initial Breakpoint requested)<br />
  807. Symbol search path is: C:\WINDOWS\Symbols;SRV*E:\SymStore*http://referencesource.microsoft.com/symbols;SRV*E:\SymStore*http://msdl.microsoft.com/download/symbols<br />
  808. Executable search path is:<br />
  809. Windows XP Kernel Version 2600 MP (1 procs) Free x86 compatible<br />
  810. Built by: 2600.xpsp.080413-2111<br />
  811. Kernel base = 0x804dc000 PsLoadedModuleList = 0x805684c0<br />
  812. System Uptime: not available<br />
  813. Break instruction exception - code 80000003 (first chance)<br />
  814. ... <strong>snipped breakpoint warning message</strong> ...<br />
  815. nt!RtlpBreakWithStatusInstruction:<br />
  816. 804e7a42 cc              int     3<br />
  817. kd&gt; <strong>sxe ld:autochk</strong><br />
  818. kd&gt; <strong>g</strong><br />
  819. nt!DebugService2+0x10:<br />
  820. 8050ae56 cc              int     3</code></p>
  821. <p>Setting the kernel debugger to break on the load of the AutoChk native BootExecute application resulted in our desired break. Let us consider the context of this break:<br />
  822. <code><br />
  823. 0: kd&gt; kb<br />
  824. ChildEBP RetAddr  Args to Child<br />
  825. f738d9fc 8050b2f9 f738da40 f738da10 00000003 nt!DebugService2+0x10<br />
  826. f738da20 805c533a f738da40 01000000 82953020 nt!DbgLoadImageSymbols+0x42<br />
  827. f738da70 805c51f0 82ab9c28 01000000 82953020 nt!MiLoadUserSymbols+0x169<br />
  828. f738dab4 8058d013 82ab9c28 01000000 f738db5c nt!MiMapViewOfImageSection+0x4b6<br />
  829. f738db10 80504e27 00000004 82953110 f738db5c nt!MmMapViewOfSection+0x13c<br />
  830. f738db6c 80590520 e165ec14 00000000 e1412398 nt!<strong>MmInitializeProcessAddressSpace</strong>+0x33d<br />
  831. f738dcbc 8059082f 0015f870 001f0fff 0015f7d8 nt!<strong>PspCreateProcess</strong>+0x333<br />
  832. f738dd10 805b54b2 0015f870 001f0fff 0015f7d8 nt!NtCreateProcessEx+0x7e<br />
  833. f738dd3c 804e298f 0015f870 001f0fff 0015f7d8 nt!NtCreateProcess+0x3d<br />
  834. f738dd3c 7c90e4f4 0015f870 001f0fff 0015f7d8 nt!KiFastCallEntry+0xfc<br />
  835. WARNING: Frame IP not in any known module. Following frames may be wrong.<br />
  836. 0015f830 00000000 00000000 00000000 00000000 0x7c90e4f4<br />
  837. 0: kd&gt; !process 0 0<br />
  838. **** NT ACTIVE PROCESS DUMP ****<br />
  839. PROCESS 82bc9830  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000<br />
  840. DirBase: 02f40000  ObjectTable: e1002e40  HandleCount:  46.<br />
  841. Image: System<br />
  842. </code><code><br />
  843. PROCESS 82935128  SessionId: none  Cid: 0218    Peb: 7ffd9000  ParentCid: 0004<br />
  844. DirBase: 0899b000  ObjectTable: e13fbc68  HandleCount:   7.<br />
  845. Image: smss.exe</code></p>
  846. <p>Although AutoChk has been mapped into memory, the AutoChk process is still in the process of being created. Indeed, the AutoChk process is as of yet absent from the system process list displayed by the <a href="http://msdn.microsoft.com/en-us/library/cc267076.aspx">!process</a> debugger extension command.</p>
  847. <p>However, AutoChk&#8217;s pseudo-created state does not prevent us from taking this opportunity to set up a debug breakpoint at the top of user code:<br />
  848. <code><br />
  849. 1: kd&gt; lm m autochk<br />
  850. start    end        module name<br />
  851. 01000000 01092000   autochk    (deferred)<br />
  852. 1: kd&gt; bp <strong>autochk!NtProcessStartup</strong><br />
  853. 1: kd&gt; bl<br />
  854. 0 e 0100dd3d     0001 (0001) autochk!NtProcessStartup</code></p>
  855. <p>Beware that if you perform a symbol reload with the <a href="http://msdn.microsoft.com/en-us/library/cc266830.aspx">.reload</a> command after the module load event for autochk has fired off, you may find that it has disappeared from the debugger&#8217;s loaded module list&#8230; Just make sure you set up your breakpoint immediately after the event break.</p>
  856. <p>It is easy enough to set a breakpoint at the application&#8217;s NtProcessStartup entrypoint before the EPROCESS is available, but we may wish to to set early breakpoints in process context elsewhere. To that end, we may proceed to the return from the process creation API from the module load event break, until the process is listed in the system process list:<br />
  857. <code><br />
  858. 1: kd&gt; k<br />
  859. ChildEBP RetAddr<br />
  860. f7b619fc 8050b2f9 nt!DebugService2+0x10<br />
  861. f7b61a20 805c533a nt!DbgLoadImageSymbols+0x42<br />
  862. f7b61a70 805c51f0 nt!MiLoadUserSymbols+0x169<br />
  863. f7b61ab4 8058d013 nt!MiMapViewOfImageSection+0x4b6<br />
  864. f7b61b10 80504e27 nt!MmMapViewOfSection+0x13c<br />
  865. f7b61b6c 80590520 nt!MmInitializeProcessAddressSpace+0x33d<br />
  866. f7b61cbc 8059082f <strong>nt!PspCreateProcess</strong>+0x333<br />
  867. f7b61d10 805b54b2 nt!NtCreateProcessEx+0x7e<br />
  868. f7b61d3c 804e298f nt!NtCreateProcess+0x3d<br />
  869. f7b61d3c 7c90e4f4 nt!KiFastCallEntry+0xfc<br />
  870. 0015f830 00000000 ntdll!KiFastSystemCallRet<br />
  871. 1: kd&gt; <strong>gu; gu; gu; gu; gu; gu; gu</strong><br />
  872. nt!NtCreateProcessEx+0x7e:<br />
  873. 8059082f e87a76f5ff      call    nt!_SEH_epilog (804e7eae)<br />
  874. 1: kd&gt; !process 0 0<br />
  875. **** NT ACTIVE PROCESS DUMP ****<br />
  876. PROCESS 82bc9830  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000<br />
  877. DirBase: 02f40000  ObjectTable: e1002e40  HandleCount:  46.<br />
  878. Image: System<br />
  879. </code><code><br />
  880. PROCESS 829b4128  SessionId: none  Cid: 0228    Peb: 7ffd7000  ParentCid: 0004<br />
  881. DirBase: 08bbb000  ObjectTable: e1468f58  HandleCount:   8.<br />
  882. Image: smss.exe<br />
  883. </code><code><br />
  884. PROCESS <strong>8294a3d0 </strong>SessionId: none  Cid: 0238    Peb: 7ffd6000  ParentCid: 0228<br />
  885. DirBase: 08d40000  ObjectTable: e13fd408  HandleCount:   0.<br />
  886. Image: <strong>autochk.exe</strong></code></p>
  887. <p>By examining our location in the call stack after the module load event fires, we can see that returning from the Process Manager&#8217;s process creation routine PspCreateProcess would require going up 7 times. With that routine&#8217;s execution completed, the EPROCESS for autochk is now listed in the system process list and its value can be used as a context parameter for breakpoint commands, etc.</p>
  888. <p>With the breakpoint on the native entrypoint in place, we can resume system execution and have the kernel debugger land right where we want it:<br />
  889. <code><br />
  890. 1: kd&gt; g<br />
  891. Breakpoint 0 hit<br />
  892. autochk!NtProcessStartup:<br />
  893. 001b:0100dd3d 8bff            mov     edi,edi<br />
  894. 1: kd&gt; kb<br />
  895. ChildEBP RetAddr  Args to Child<br />
  896. 0006fff4 00000000 7ffde000 000000c8 0000010a <strong>autochk!NtProcessStartup</strong><br />
  897. 1: kd&gt; .process<br />
  898. Implicit process is now 82935020<br />
  899. 1: kd&gt; .thread<br />
  900. Implicit thread is now 8293f020</code></p>
  901. <p>From this point, convenient source debugging of the native application is also possible if it&#8217;s your own custom written application. The various features such as Locals, Watches, single stepping, etc., work as expected. Some quirks of kernel debugging of a user process should be taken into consideration (make sure breakpoints have an EPROCESS and ETHREAD context specified when appropriate to avoid venturing into other processes by accident, etc.) and the inaccessibility of some user-mode debugger extension commands may prove inconvenient.</p>
  902. <p>Sure beats DbgPrints, though!</p>
  903. ]]></content:encoded>
  904. <wfw:commentRss>https://kobyk.wordpress.com/2008/07/26/debugging-user-mode-bootexecute-native-applications-with-kd/feed/</wfw:commentRss>
  905. <slash:comments>1</slash:comments>
  906. <media:content url="https://1.gravatar.com/avatar/1d5c3d0abc3891afb6e88eebc51b004c3ed48b5fc2bc4a0f0ff7f6e507c80ed4?s=96&#38;d=identicon&#38;r=G" medium="image">
  907. <media:title type="html">KK</media:title>
  908. </media:content>
  909. </item>
  910. <item>
  911. <title>Replacing boot load drivers with the Windows Boot Debugger</title>
  912. <link>https://kobyk.wordpress.com/2008/07/04/replacing-boot-load-drivers-with-the-windows-boot-debugger/</link>
  913. <comments>https://kobyk.wordpress.com/2008/07/04/replacing-boot-load-drivers-with-the-windows-boot-debugger/#comments</comments>
  914. <dc:creator><![CDATA[Koby Kahane]]></dc:creator>
  915. <pubDate>Fri, 04 Jul 2008 20:03:12 +0000</pubDate>
  916. <category><![CDATA[Kernel]]></category>
  917. <category><![CDATA[Windbg]]></category>
  918. <guid isPermaLink="false">http://kobyk.wordpress.com/?p=25</guid>
  919.  
  920. <description><![CDATA[Recently, I&#8217;ve been assigned to work on fixing several bugs in a Windows file system filter driver. Debugging native code has always been characterized by the tedious and cumbersome modify, compile and link, copy, run, repeat&#8230; cycle, but in the &#8230; <a href="https://kobyk.wordpress.com/2008/07/04/replacing-boot-load-drivers-with-the-windows-boot-debugger/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
  921. <content:encoded><![CDATA[<p>Recently, I&#8217;ve been assigned to work on fixing several bugs in a Windows file system filter driver. Debugging native code has always been characterized by the tedious and cumbersome modify, compile and link, copy, run, repeat&#8230; cycle, but in the case of kernel-mode development, the overhead of that cycle is even more acute.</p>
  922. <p>I&#8217;ve found that booting the target system or virtual machine every time you want to replace a driver file with an updated build and then rebooting to have the new driver loaded significantly prolongs the cycle. Therefore, I was happy to discover Windbg&#8217;s <a href="http://msdn.microsoft.com/en-us/library/cc266813.aspx">.kdfiles</a> command.</p>
  923. <p>The .kdfiles command configure&#8217;s the kernel debugger&#8217;s driver replacement map. Whenever the NT Memory Manager attempts to load a driver image, it consults the kernel debugger, if attached, asking it for an alternative driver image. If the debugger has one, it is transmitted over the kernel debugging connection from the host to the target, and used in lieu of the target&#8217;s local driver image.</p>
  924. <p>Using the driver replacement map makes it easier to replace a driver with an updated version. However, in its usual form, the replacement map feature has a significant limitation &#8211; it cannot replace boot load drivers.</p>
  925. <p>To understand the logic behind this restriction, one must consider the nature of boot driver loading. While demand-start drivers are started by the user-mode Service Control Manager (SCM) and system-start drivers are loaded by NTOSKRNL&#8217;s IoInitSystem function, boot drivers are, as their name suggests, required for the system to boot and are therefore loaded by osloader, a part of ntldr (this description is for pre-Vista systems).</p>
  926. <p>By the time the NT kernel is up and its Memory Manager consults the kernel debugger and its driver replacement map, it is far too late to do anything about those drivers which have been pre-loaded by the OS loader. The initial breakpoint offered by the kernel debugger is simply too late.</p>
  927. <p>Fortunately, Microsoft recognized the importance of providing a driver replacement map for boot load drivers and provides a somewhat esoteric solution in the form of the debug version of NTLDR.</p>
  928. <p>The debug version of NTLDR expects the kernel debugger to attach to it during system startup. Unlike the kernel debugger, it is not configured with the boot.ini file and is always configured to a 115,200 baud connection on the COM1 serial port.</p>
  929. <p>The documentation for .kdfiles points out that the Windows Driver Kit (WDK) bundles a debug version of NTLDR in the debug subdirectory. However, such a file is nowhere to be found there, probably because the WDK now contains the Vista checked kernel in its debug directory and the modern Vista boot loader is distinct from NTLDR. More on Windows Vista later, but for now let&#8217;s concentrate on Windows XP.</p>
  930. <p>Failing to locate the debug NTLDR in the WDK, I turned back in time to the Windows Server 2003 SP1 IFS Kit, a variant of the Windows Server 2003 SP1 DDK for file system and file system filter developers. I was glad to find the ntldr_dbg file in its debug subdirectory.</p>
  931. <p>However, my happiness quickly turned to disappointment when I replaced the original NTLDR with ntldr_dbg in a Windows XP virtual machine. The system refused to boot, claiming that NTLDR was corrupt. Since the debug directory in the IFS kit contains checked kernel binaries for Windows Server 2003 SP1, I figured that the provided version of ntldr_dbg is a match for that version, as well.</p>
  932. <p>I turned to the archives, so to speak, and dusted off old MSDN Subscription CDs. I eventually turned up the rather antiquated Windows XP SP1 DDK. In there, I found another version of ntldr_dbg. I placed it as required and this time the system booted successfully.</p>
  933. <p>It is unfortunate that one has to dig up the DDK of yore to locate the boot debugger. It really ought to be more accessible.</p>
  934. <p>With the debug version of NTLDR is in place, when you boot the system, right before the OS loader menu appears, you see the following message:<br />
  935. <code>Boot Debugger Using: COM1 (Baud Rate 115200)</code></p>
  936. <p>Once the message is displayed, NTLDR blocks waiting for a kernel debugger to connect. I start the kernel debugger the way I&#8217;d usually start it:<br />
  937. <code>windbg -b -k com:pipe,port=\\.\pipe\com_1</code></p>
  938. <p>Soon enough, however, it is evident that this is no ordinary kernel debugging session:<br />
  939. <code><br />
  940. Microsoft (R) Windows Debugger Version 6.9.0003.113 X86<br />
  941. Copyright (c) Microsoft Corporation. All rights reserved.</code><br />
  942. <code><br />
  943. Opened \\.\pipe\com_1<br />
  944. Waiting to reconnect...<br />
  945. BD: <strong>Boot Debugger</strong> Initialized<br />
  946. Connected to <strong>Windows Boot Debugger</strong> 2600 x86 compatible target, ptr64 FALSE<br />
  947. Kernel Debugger connection established.  (Initial Breakpoint requested)<br />
  948. Symbol search path is: C:\WINDOWS\Symbols;SRV*E:\SymStore*http://referencesource.microsoft.com/symbols;SRV*E:\SymStore*http://msdl.microsoft.com/download/symbols<br />
  949. Executable search path is:<br />
  950. <strong>Module List address is NULL - debugger not initialized properly.</strong><br />
  951. <strong>WARNING: .reload failed, module list may be incomplete</strong><br />
  952. <strong>KdDebuggerData.KernBase &lt; SystemRangeStart</strong><br />
  953. <strong>Windows Boot Debugger</strong> Kernel Version 2600 UP Checked x86 compatible<br />
  954. <strong>Primary image base = 0x00000000 Loaded module list = 0x00000000</strong><br />
  955. System Uptime: not available<br />
  956. Break instruction exception - code 80000003 (first chance)<br />
  957. 0041cf70 cc              int     3<br />
  958. kd&gt;</code></p>
  959. <p>Windbg has attached to the Windows Boot Debugger, a debugging environment provided by the debug version of NTLDR at a very early stage of system startup, well before the NT kernel has been loaded. Indeed, the initial breakpoint at the boot debugger occurs before an OS to start has been selected at the loader boot menu.</p>
  960. <p>With the boot debugger at its initial breakpoint, we can set up the driver replacement map as desired. For instance, we can replace NTFS and NDIS with their counterparts from the checked build of Windows XP:<br />
  961. <code><br />
  962. kd&gt; .kdfiles -m \WINDOWS\system32\drivers\Ntfs.sys C:\Stuff\xpsp3checked\Ntfs.sys<br />
  963. Added mapping for '\WINDOWS\system32\drivers\Ntfs.sys'<br />
  964. kd&gt; .kdfiles -m \WINDOWS\system32\drivers\Ndis.sys C:\Stuff\xpsp3checked\Ndis.sys<br />
  965. Added mapping for '\WINDOWS\system32\drivers\Ndis.sys'<br />
  966. kd&gt; g<br />
  967. BD: osloader.exe base address 00400000<br />
  968. BD: \WINDOWS\system32\NTKRNLMP.CHK base address 80A02000<br />
  969. BD: \WINDOWS\system32\HALMACPI.CHK base address 80100000<br />
  970. BD: \WINDOWS\system32\KDCOM.DLL base address 80010000<br />
  971. BD: \WINDOWS\system32\BOOTVID.dll base address 80001000<br />
  972. BD: \WINDOWS\system32\DRIVERS\ACPI.sys base address 8014C000<br />
  973. BD: \WINDOWS\system32\DRIVERS\WMILIB.SYS base address 80007000<br />
  974. BD: \WINDOWS\system32\DRIVERS\pci.sys base address 80062000<br />
  975. BD: \WINDOWS\system32\DRIVERS\isapnp.sys base address 80012000<br />
  976. BD: \WINDOWS\system32\DRIVERS\compbatt.sys base address 80009000<br />
  977. BD: \WINDOWS\system32\DRIVERS\BATTC.SYS base address 8000C000<br />
  978. BD: \WINDOWS\system32\DRIVERS\intelide.sys base address 8001C000<br />
  979. BD: \WINDOWS\system32\DRIVERS\PCIIDEX.SYS base address 8017A000<br />
  980. BD: \WINDOWS\System32\Drivers\MountMgr.sys base address 80181000<br />
  981. BD: \WINDOWS\system32\DRIVERS\ftdisk.sys base address 8018C000<br />
  982. BD: \WINDOWS\System32\drivers\dmload.sys base address 8001E000<br />
  983. BD: \WINDOWS\System32\drivers\dmio.sys base address 801AB000<br />
  984. BD: \WINDOWS\System32\Drivers\PartMgr.sys base address 801D1000<br />
  985. BD: \WINDOWS\System32\Drivers\VolSnap.sys base address 801D6000<br />
  986. BD: \WINDOWS\system32\DRIVERS\atapi.sys base address 801E3000<br />
  987. BD: \WINDOWS\system32\DRIVERS\vmscsi.sys base address 80073000<br />
  988. BD: \WINDOWS\system32\DRIVERS\SCSIPORT.SYS base address 801FB000<br />
  989. BD: \WINDOWS\system32\DRIVERS\disk.sys base address 80213000<br />
  990. BD: \WINDOWS\system32\DRIVERS\CLASSPNP.SYS base address 8021C000<br />
  991. BD: \WINDOWS\system32\drivers\fltmgr.sys base address 80229000<br />
  992. BD: \WINDOWS\system32\DRIVERS\sr.sys base address 802A7000<br />
  993. BD: \WINDOWS\System32\Drivers\KSecDD.sys base address 802B9000<br />
  994. KD: Accessing 'C:\Stuff\xpsp3checked\Ntfs.sys' (\WINDOWS\System32\Drivers\Ntfs.sys)<br />
  995. File size 814K.... ....BD: Loaded remote file \WINDOWS\System32\Drivers\Ntfs.sys<br />
  996. </code><code><br />
  997. BlLoadImageEx: <strong>Pulled \WINDOWS\System32\Drivers\Ntfs.sys from Kernel Debugger</strong><br />
  998. BD: \WINDOWS\System32\Drivers\Ntfs.sys base address 802D0000<br />
  999. KD: Accessing 'C:\Stuff\xpsp3checked\Ndis.sys' (\WINDOWS\System32\Drivers\NDIS.sys)<br />
  1000. File size 424K.... ....BD: Loaded remote file \WINDOWS\System32\Drivers\NDIS.sys<br />
  1001. </code><code><br />
  1002. BlLoadImageEx: <strong>Pulled \WINDOWS\System32\Drivers\NDIS.sys from Kernel Debugger</strong><br />
  1003. BD: \WINDOWS\System32\Drivers\NDIS.sys base address 804DC000<br />
  1004. Shutdown occurred...unloading all symbol tables.<br />
  1005. Waiting to reconnect.</code></p>
  1006. <p>We can see that the boot debugger picked up our driver replacements and transferred them from the host to the target through the kernel debugger connection. Alas, this can be a lengthy process for an obese driver over the 115,200 baud link&#8230;</p>
  1007. <p>Beyond being useful for replacing your own drivers, which is what I had in mind when I looked into this feature, the boot debugger can be used to easily go back and forth between Windows free build and checked build operating system components, as illustrated above. However, such use is not without its problems.</p>
  1008. <p>For one, replacing the kernel and the HAL with their checked counterparts through the driver replacement map does not work. An error citing kernel corruption results from such an attempt. The traditional way of using a checked kernel, by placing an appropriate entry in boot.ini, is still required.</p>
  1009. <p>When testing a file system filter driver, apart from using the checked version of the I/O Manager through the use of the checked NT kernel, it is advantageous to use checked versions of underlying file system drivers such as NTFS. The checked versions can assert when you pass on requests to them in a way which violates the file system&#8217;s locking hierarchy and which may lead to deadlocks. Replacing the NTFS driver with the driver replacement map feature worked as expected, apart from causing NDIS to bugcheck during system boot with some sort of paging error. The issue was resolved by replacing NDIS with its checked counterpart through the driver replacement map, as well.</p>
  1010. <p>However, for a reason I do not understand, when placing the checked build of the Filter Manager, useful for debugging file system minifilters, there was no such luck. The boot loader complained after transferring the checked Filter Manager that the NTFS driver was corrupt. I disabled System File Protection and replaced the free drivers with the checked drivers on disk, the traditional way and the system booted with the checked NTFS and Filter Manager successfully. So it appears that the boot-time driver replacement map feature can be a bit flaky&#8230;</p>
  1011. <p>It is probably best to place checked operating system components the traditional way and only replace your own, frequently modified drivers with the boot debugger and the driver replacement map.</p>
  1012. <p>So much for Windows XP and the legacy NTLDR. But what about Windows Vista?</p>
  1013. <p>At first, the situation looked promising. In Windows Vista, the boot debugger is built-in. It can, for instance, be enabled for an existing boot entry with the Boot Configuration Database editor from an elevated command prompt:<br />
  1014. <code><br />
  1015. C:\Windows\system32&gt;bcdedit /enum<br />
  1016. </code><code><br />
  1017. Windows Boot Manager<br />
  1018. --------------------<br />
  1019. identifier              {bootmgr}<br />
  1020. device                  partition=C:<br />
  1021. description             Windows Boot Manager<br />
  1022. locale                  en-US<br />
  1023. inherit                 {globalsettings}<br />
  1024. default                 {current}<br />
  1025. displayorder            {current}<br />
  1026. {5761b19a-1e8a-11dd-bcd4-000c29797dc6}<br />
  1027. toolsdisplayorder       {memdiag}<br />
  1028. timeout                 30<br />
  1029. </code><code><br />
  1030. Windows Boot Loader<br />
  1031. -------------------<br />
  1032. identifier              {current}<br />
  1033. device                  partition=C:<br />
  1034. path                    \Windows\system32\winload.exe<br />
  1035. description             Microsoft Windows Vista<br />
  1036. locale                  en-US<br />
  1037. inherit                 {bootloadersettings}<br />
  1038. osdevice                partition=C:<br />
  1039. systemroot              \Windows<br />
  1040. resumeobject            {694d30db-e737-11dc-814f-e01223f3682a}<br />
  1041. nx                      OptIn<br />
  1042. </code><code><br />
  1043. Windows Boot Loader<br />
  1044. -------------------<br />
  1045. identifier <strong> {5761b19a-1e8a-11dd-bcd4-000c29797dc6}</strong><br />
  1046. device                  partition=C:<br />
  1047. path                    \Windows\system32\winload.exe<br />
  1048. description             Debugging<br />
  1049. locale                  en-US<br />
  1050. inherit                 {bootloadersettings}<br />
  1051. osdevice                partition=C:<br />
  1052. systemroot              \Windows<br />
  1053. resumeobject            {694d30db-e737-11dc-814f-e01223f3682a}<br />
  1054. nx                      OptIn<br />
  1055. debug                   Yes<br />
  1056. </code><code><br />
  1057. C:\Windows\system32&gt;bcdedit /bootdebug <strong>{5761b19a-1e8a-11dd-bcd4-000c29797dc6}</strong> ON<br />
  1058. </code><code><br />
  1059. The operation completed successfully.</code></p>
  1060. <p>Unlike the XP boot debugger, the Vista boot debugger is set for a specific boot loader menu entry. Once we reboot and pick the entry for which boot debugging is enabled, we can attach:<br />
  1061. <code><br />
  1062. Microsoft (R) Windows Debugger Version 6.9.0003.113 X86<br />
  1063. Copyright (c) Microsoft Corporation. All rights reserved.<br />
  1064. </code><code><br />
  1065. Opened \\.\pipe\com_1<br />
  1066. Waiting to reconnect...<br />
  1067. BD: Boot Debugger Initialized<br />
  1068. Connected to <strong>Windows Boot Debugger</strong> 6001 x86 compatible target, ptr64 FALSE<br />
  1069. Kernel Debugger connection established.  (Initial Breakpoint requested)<br />
  1070. Symbol search path is: C:\WINDOWS\Symbols;SRV*E:\SymStore*http://referencesource.microsoft.com/symbols;SRV*E:\SymStore*http://msdl.microsoft.com/download/symbols<br />
  1071. Executable search path is:<br />
  1072. Windows Boot Debugger Kernel Version 6001 UP Free x86 compatible<br />
  1073. Primary image base = 0x00584000 Loaded module list = 0x00684e78<br />
  1074. System Uptime: not available<br />
  1075. Break instruction exception - code 80000003 (first chance)<br />
  1076. winload!RtlpBreakWithStatusInstruction:<br />
  1077. 005bce88 cc              int     3<br />
  1078. kd&gt; k<br />
  1079. ChildEBP RetAddr<br />
  1080. 00120c6c 005b0862 winload!RtlpBreakWithStatusInstruction<br />
  1081. 00120e84 005b0760 winload!vDbgPrintExWithPrefixInternal+0x100<br />
  1082. 00120e94 0058bdaf winload!DbgPrint+0x11<br />
  1083. 00120eb0 0058bf6d winload!BlBdStart+0x81<br />
  1084. 00120f48 005a2f88 winload!BlBdInitialize+0x172<br />
  1085. 00120f64 005a28c2 winload!InitializeLibrary+0x168<br />
  1086. 00120f7c 0058513a winload!BlInitializeLibrary+0x42<br />
  1087. 00120fe8 0044646a <strong>winload!OslMain</strong>+0x13a<br />
  1088. WARNING: Frame IP not in any known module. Following frames may be wrong.<br />
  1089. 00000000 f000ff53 0x44646a<br />
  1090. 00000000 00000000 0xf000ff53</code></p>
  1091. <p>We can see that in Vista, the boot debugger&#8217;s initial break is in the new winload.exe, replacing the osloader.exe embedded in ntldr of yesteryear. At this point the boot load drivers have yet to be loaded, so it would be perfect to set the .kdfiles driver replacement map at this point.</p>
  1092. <p>Alas, no such luck. It turns out the boot load driver replacement map feature is MIA in Windows Vista. This is confirmed by Microsoft&#8217;s Doron Holan in a <a href="http://www.osronline.com/showThread.cfm?link=108173">reply to a post</a> (free registration required) in OSR&#8217;s WINDBG mailing list. It is unclear what is the point of bundling the boot debugger with the regular operating system, unlike in the case of the hard to find ntldr_dbg for XP, only for it to be completely useless&#8230; Anyone using the boot debugger for purposes other than boot load driver replacement is probably working for Microsoft, so why should the boot debugger be a part of the OS if it is now missing what seems to be its most important functionality?</p>
  1093. <p>Hopefully the boot load driver replacement map will make a comeback in the Windows 7 boot debugger&#8230;</p>
  1094. ]]></content:encoded>
  1095. <wfw:commentRss>https://kobyk.wordpress.com/2008/07/04/replacing-boot-load-drivers-with-the-windows-boot-debugger/feed/</wfw:commentRss>
  1096. <slash:comments>5</slash:comments>
  1097. <media:content url="https://1.gravatar.com/avatar/1d5c3d0abc3891afb6e88eebc51b004c3ed48b5fc2bc4a0f0ff7f6e507c80ed4?s=96&#38;d=identicon&#38;r=G" medium="image">
  1098. <media:title type="html">KK</media:title>
  1099. </media:content>
  1100. </item>
  1101. </channel>
  1102. </rss>
  1103.  
Copyright © 2002-9 Sam Ruby, Mark Pilgrim, Joseph Walton, and Phil Ringnalda