<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Rubato and Chord</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/reiley/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/reiley/feed.xml</link>
    <description>Reiley&amp;#039;s technical blog</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:24:27 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Batch File with Self-Awareness</title>
      <link>https://docs.microsoft.com/archive/blogs/reiley/batch-file-with-self-awareness</link>
      <pubDate>Mon, 09 Sep 2013 05:19:00 GMT</pubDate>
      <dc:creator><![CDATA[Reiley Yang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/reiley/2013/09/09/batch-file-with-self-awareness/</guid>
      <description><![CDATA[Batch file is a double-edged sword, the good side is&nbsp;that&nbsp;batch file&nbsp;runs on almost...]]></description>
      <content:encoded><![CDATA[<p>Batch file is a double-edged sword, the good side is&nbsp;that&nbsp;batch file&nbsp;runs on almost all of the Microsoft platforms, while the evil side is people just&nbsp;couldn't get it right.</p>
<p>At the highest level, batch file is interpreted by the command processor, which&nbsp;is cmd.exe or command.com. The interpreter is in charge of:</p>
<ul>
<li>Process&nbsp;escape sequences (e.g. caret).</li>
<li>Expand environment variables.</li>
<li>Split the command string into parts.</li>
<li>Determine if the command is an internal command (e.g. ECHO), alias (which is specified using DOSKEY or <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms681935.aspx">AddConsoleAlias</a>), or external command (which is controlled by PATH and PATHEXT).</li>
<li>Maintain command process and return value.</li>
<li>Take care of code page, pipe and I/O redirection.</li>
</ul>
<p>What the command processor does&nbsp;<strong>not</strong> care are the C/C++ style "argv" parsing and double quotes - it is the responsibility of&nbsp;individual process to parse the command line, although in normal case this is handled by <a title="CRT" href="https://msdn.microsoft.com/en-us/library/a1y7w461.aspx" target="_blank">CRT</a> or <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/bb776391.aspx" target="_blank">shell32!CommandLineToArgvW</a>.</p>
<p>Let's jump to today's question - how do you write a batch file that prints out the full path of itself? (hint: %~dpnx0 and %~f0 have bug and won't work if the batch is invoked with double quotes).</p>
<p>&nbsp;</p>
<p>I've put my answer as follows:<br /><br /></p>
<pre style="background: white; color: black; font-family: Consolas;">@ECHO OFF

SETLOCAL
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION

IF EXIST "%~f0" (
  IF NOT "%~x0" == "" (
    GOTO ENTRYPOINT
  )
)

SET PATH_CDR=%CD%;%PATH%
:FINDNEXT
FOR /F "delims=; tokens=1,*" %%P IN ("!PATH_CDR!") DO (
  SET PATH_CAR=%%P
  IF "!PATH_CAR:~-1!" == "\" (
    SET PATH_CAR=!PATH_CAR:~0,-1!
  )
  IF NOT "!PATH_CAR!" == "" (
    FOR %%X IN (%PATHEXT:;=;%) DO (
      IF EXIST "!PATH_CAR!\%~n0%%X" (
        SET PATH_CAR=!PATH_CAR!\%~n0%%X
        GOTO TRAMPOLINE
      )
    )
  )
  SET PATH_CDR=%%Q
  IF DEFINED PATH_CDR (
    GOTO FINDNEXT
  )
)
ECHO Error: failed to detect batch file path 1&gt;&amp;2
EXIT /B -1

:TRAMPOLINE
CALL "!PATH_CAR!" %*
EXIT /B !ERRORLEVEL!

:ENTRYPOINT
SETLOCAL DISABLEDELAYEDEXPANSION
ECHO %~f0

EXIT /B %ERRORLEVEL%
</pre>]]></content:encoded>
    </item>
    <item>
      <title>Pop Quiz - JavaScript for Fun</title>
      <link>https://docs.microsoft.com/archive/blogs/reiley/pop-quiz-javascript-for-fun</link>
      <pubDate>Sat, 15 Jun 2013 09:16:00 GMT</pubDate>
      <dc:creator><![CDATA[Reiley Yang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/reiley/2013/06/15/pop-quiz-javascript-for-fun/</guid>
      <description><![CDATA[Most people could write something in JavaScript, though they barely made it correct.
I started...]]></description>
      <content:encoded><![CDATA[<p>Most people could write something in JavaScript, though they barely made it correct.</p>
<p>I started using JavaScript while I was in school, and the project I gave myself was to implement a <a title="Scheme" href="https://en.wikipedia.org/wiki/Scheme_%28programming_language%29Scheme" target="_blank">Scheme</a> interpreter&nbsp;that runs in&nbsp;web browsers. As a result, I've realized the tight relationship between JavaScript and Scheme, I became&nbsp;a fan of JavaScript and have been using it a lot.</p>
<p>Before the quiz,&nbsp;let me tell a&nbsp;brief story of JavaScript.</p>
<p>The JavaScript language was implemented by <a title="Brendan Eich" href="https://en.wikipedia.org/wiki/Brendan_Eich" target="_blank">Brendan Eich</a> of Netscape, soon Microsoft developed a dialect called JScript and shipped with Internet Explorer in 1996. Later in the same year the standardization started, and the first version was authored by <a title="Guy Steele" href="https://en.wikipedia.org/wiki/Guy_L._Steele,_Jr." target="_blank">Guy Steele</a>, who also created Scheme and authored the Java language specification. The specification was named as ECMA-262, since the specification came after JavaScript and JScript, in order to compromise&nbsp;among Netscape, Microsoft and Sun, a new name ECMAScript was picked.</p>
<p>Despite of it's Java-like syntax, JavaScript shares many concepts with functional programming language. This mixture makes JavaScript easy to use (also easy to misuse), expressive, powerful and&nbsp;popular.</p>
<p>Microsoft has a long history of providing JavaScript implementations, including JScript, JScript.NET and <a title="Chakra" href="https://en.wikipedia.org/wiki/Chakra_%28JavaScript_engine%29" target="_blank">Chakra</a>. While the old JScript engine is in sustaining engineering mode, JScript.NET seems to be deprecated, it's quite promising that Chakra has been powering both the latest&nbsp;Internet Explorer and <a title="Windows Runtime" href="https://msdn.microsoft.com/en-us/library/hh710230.aspx" target="_blank">Windows Runtime</a>.</p>
<p>Now let's put the question - what would you get from the following page?</p>
<hr style="width: 100%;" width="100%" />
<pre style="background: white; color: black; font-family: Consolas;"><span style="color: blue;">&lt;</span><span style="color: maroon;">html</span><span style="color: blue;">&gt;</span>
<span style="color: blue;">&lt;</span><span style="color: maroon;">head</span><span style="color: blue;">&gt;</span>
&nbsp;&nbsp;<span style="color: blue;">&lt;</span><span style="color: maroon;">title</span><span style="color: blue;">&gt;</span>JavaScript&nbsp;for&nbsp;Fun<span style="color: blue;">&lt;/</span><span style="color: maroon;">title</span><span style="color: blue;">&gt;</span>
&nbsp;&nbsp;<span style="color: blue;">&lt;</span><span style="color: maroon;">script</span>&nbsp;<span style="color: red;">type</span><span style="color: blue;">=</span><span style="color: blue;">"text/javascript"</span><span style="color: blue;">&gt;</span>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;S&nbsp;=&nbsp;{};
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">for</span>&nbsp;(<span style="color: blue;">var</span>&nbsp;N&nbsp;<span style="color: blue;">in</span>&nbsp;(<span style="color: blue;">function</span>&nbsp;()&nbsp;{&nbsp;<span style="color: blue;">return</span>&nbsp;<span style="color: blue;">this</span>;&nbsp;}).call(<span style="color: blue;">function</span>&nbsp;(_)&nbsp;{&nbsp;<span style="color: blue;">return</span>&nbsp;_;&nbsp;}()))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S[N]&nbsp;=&nbsp;<span style="color: blue;">true</span>;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">this</span>.undefined&nbsp;=&nbsp;1;
&nbsp;&nbsp;&nbsp;&nbsp;undefined&nbsp;=&nbsp;2;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;undefined&nbsp;=&nbsp;3;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;A&nbsp;=&nbsp;<span style="color: blue;">this</span>.undefined;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">this</span>.B&nbsp;=&nbsp;undefined;
<span style="color: blue;">&lt;/</span><span style="color: maroon;">script</span><span style="color: blue;">&gt;</span>
<span style="color: blue;">&lt;/</span><span style="color: maroon;">head</span><span style="color: blue;">&gt;</span>
<span style="color: blue;">&lt;</span><span style="color: maroon;">body</span><span style="color: blue;">&gt;</span>
&nbsp;&nbsp;<span style="color: blue;">&lt;</span><span style="color: maroon;">script</span>&nbsp;<span style="color: red;">type</span><span style="color: blue;">=</span><span style="color: blue;">"text/javascript"</span><span style="color: blue;">&gt;</span>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;C&nbsp;=&nbsp;<span style="color: #a31515;">'global&nbsp;var&nbsp;C'</span>;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">this</span>.D&nbsp;=&nbsp;<span style="color: #a31515;">'global&nbsp;this.D'</span>;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">function</span>&nbsp;F()&nbsp;{&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">this</span>.G&nbsp;=&nbsp;<span style="color: blue;">function</span>&nbsp;()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">return</span>&nbsp;(<span style="color: blue;">function</span>&nbsp;()&nbsp;{&nbsp;<span style="color: blue;">return</span>&nbsp;<span style="color: blue;">this</span>;&nbsp;}).call(<span style="color: blue;">function</span>&nbsp;(_)&nbsp;{&nbsp;<span style="color: blue;">return</span>&nbsp;_;&nbsp;}());
&nbsp;&nbsp;&nbsp;&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">this</span>.H&nbsp;=&nbsp;<span style="color: blue;">function</span>&nbsp;()&nbsp;{&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">delete</span>&nbsp;F;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">delete</span>&nbsp;G;
&nbsp;&nbsp;&nbsp;&nbsp;eval(<span style="color: #a31515;">'var&nbsp;Z&nbsp;=&nbsp;"global&nbsp;eval&nbsp;var"'</span>);
&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color: blue;">function</span>&nbsp;(global)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;undefined&nbsp;=&nbsp;<span style="color: #a31515;">'defined'</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;E&nbsp;=&nbsp;undefined;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;X&nbsp;=&nbsp;<span style="color: #a31515;">'local&nbsp;var&nbsp;X'</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">this</span>.Y&nbsp;=&nbsp;<span style="color: #a31515;">'local&nbsp;this.Y'</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">delete</span>&nbsp;H;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eval(<span style="color: #a31515;">'I&nbsp;=&nbsp;"it&nbsp;just&nbsp;works"'</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eval(<span style="color: #a31515;">'var&nbsp;J&nbsp;=&nbsp;"local&nbsp;eval&nbsp;var"'</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert((<span style="color: blue;">function</span>&nbsp;(O)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;R&nbsp;=&nbsp;[];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">for</span>&nbsp;(<span style="color: blue;">var</span>&nbsp;M&nbsp;<span style="color: blue;">in</span>&nbsp;O)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">if</span>&nbsp;(!S.hasOwnProperty(M))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R.push(M&nbsp;+&nbsp;<span style="color: #a31515;">':&nbsp;'</span>&nbsp;+&nbsp;String(O[M]));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">return</span>&nbsp;<span style="color: #a31515;">'['</span>&nbsp;+&nbsp;R.sort().join(<span style="color: #a31515;">',&nbsp;'</span>)&nbsp;+&nbsp;<span style="color: #a31515;">']'</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;})(global));
&nbsp;&nbsp;&nbsp;&nbsp;})(<span style="color: blue;">this</span>);
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;K&nbsp;=&nbsp;<span style="color: #a31515;">'global&nbsp;var&nbsp;K'</span>;
<span style="color: blue;">&lt;/</span><span style="color: maroon;">script</span><span style="color: blue;">&gt;</span>
<span style="color: blue;">&lt;/</span><span style="color: maroon;">body</span><span style="color: blue;">&gt;</span>
<span style="color: blue;">&lt;/</span><span style="color: maroon;">html</span><span style="color: blue;">&gt;</span>
</pre>
<hr style="width: 100%;" width="100%" />
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Vector Deleting Destructor</title>
      <link>https://docs.microsoft.com/archive/blogs/reiley/vector-deleting-destructor</link>
      <pubDate>Thu, 09 May 2013 07:24:00 GMT</pubDate>
      <dc:creator><![CDATA[Reiley Yang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/reiley/2013/05/09/vector-deleting-destructor/</guid>
      <description><![CDATA[Today one guy in my team asked a question regarding the behavior of delete[] operator in C++&nbsp;-...]]></description>
      <content:encoded><![CDATA[<p>Today one guy in my team asked a question regarding the behavior of delete[] operator in C++&nbsp;- how does the program know it needs to call <span style="font-family: verdana,geneva;">CBar::~CBar</span> instead of <span style="font-family: verdana,geneva;">CFoo::~CFoo</span>?</p>
<p><em>Note that the vector deleting destructor is a feature in Microsoft C++ Compiler,&nbsp;not&nbsp;required by&nbsp;the C++ standard.</em></p>
<pre style="background: white; color: black; font-family: Consolas;"><span style="color: blue;">#define</span>&nbsp;<span style="color: #6f008a;">_CRTDBG_MAP_ALLOC</span>
<span style="color: blue;">#include</span>&nbsp;<span style="color: #a31515;">&lt;malloc.h&gt;</span>
<span style="color: blue;">#include</span>&nbsp;<span style="color: #a31515;">&lt;crtdbg.h&gt;</span>

<span style="color: blue;">class</span>&nbsp;<span style="color: #2b91af;">CFoo</span>
{
<span style="color: blue;">public</span>:
&nbsp;&nbsp;<span style="color: blue;">virtual</span>&nbsp;~CFoo()&nbsp;=&nbsp;0;
};

<span style="color: blue;">class</span>&nbsp;<span style="color: #2b91af;">CBar</span>
{
&nbsp;&nbsp;<span style="color: blue;">virtual</span>&nbsp;~CBar()
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #6f008a;">_CrtDbgBreak</span>();
&nbsp;&nbsp;}
};

<span style="color: blue;">void</span>&nbsp;<span style="color: blue;">__cdecl</span>&nbsp;main()
{
&nbsp;&nbsp;<span style="color: #2b91af;">CBar</span>*&nbsp;p&nbsp;=&nbsp;<span style="color: blue;">new</span>&nbsp;<span style="color: #2b91af;">CBar</span>[1];
&nbsp;&nbsp;<span style="color: blue;">delete</span>[]&nbsp;(<span style="color: #2b91af;">CFoo</span>*)p;&nbsp;<span style="color: green;">//&nbsp;what&nbsp;does&nbsp;this&nbsp;mean?</span>
&nbsp;&nbsp;_CrtDumpMemoryLeaks();
}&nbsp;</pre>
<p>Well the short answer would be - how does virtual destructor work and how does the program know the actual number of elements in the array?</p>
<p>If you've spent time on understanding the object layout in C++ and COM, you would know that virtual functions are backed by <strong><em>vtable</em></strong>, and it will not be too difficult to understand <a title="BSTR" href="https://blogs.msdn.com/b/ericlippert/archive/2003/09/12/52976.aspx" target="_blank">BSTR</a>.</p>
<p>So we are ready for the answer - <strong>delete[] is a combination of BSTR and virtual function</strong>.</p>
<pre style="background: white; color: black; font-family: Consolas;">CBar::`vector deleting destructor':
000007F7CD2E1140  mov         dword ptr [rsp+10h],edx  
000007F7CD2E1144  mov         qword ptr [rsp+8],rcx  
000007F7CD2E1149  sub         rsp,28h  
000007F7CD2E114D  mov         eax,dword ptr [rsp+38h]  
<span style="color: #ff00ff;">000007F7CD2E1151 and eax,2<br />000007F7CD2E1154 test eax,eax<br />000007F7CD2E1156 je CBar::`vector deleting destructor'+5Eh (07F7CD2E119Eh)</span>  
000007F7CD2E1158  lea         <span style="color: #ff0000;">r9</span>,[CBar::~CBar (07F7CD2E1120h)] <span style="color: #0000ff;">; the address of CBar::~CBar</span> 
000007F7CD2E115F  mov         rax,qword ptr [this]             <span style="color: #0000ff;">; this pointer</span>  
000007F7CD2E1164  mov         <span style="color: #ff0000;">r8d</span>,dword ptr [rax-8]            <span style="color: #0000ff;">; array size *((size_t*)this - 1)</span>  
000007F7CD2E1168  mov         <span style="color: #ff0000;">edx</span>,8                            <span style="color: #0000ff;">; sizeof(CBar)</span>  
000007F7CD2E116D  mov         <span style="color: #ff0000;">rcx</span>,qword ptr [this]             <span style="color: #0000ff;">; this pointer</span>  
000007F7CD2E1172  call        `<span style="color: #0000ff;">vector destructor iterator</span>' (07F7CD2E1220h)  
</pre>
<p>As you can see here, the <strong>vector deleting destructor</strong> was emitted as a virtual function in <strong>vtable</strong>, it takes a flag parameter, if <span style="font-family: verdana,geneva;">flag &amp; 0x2</span> equals to true, the actual function <strong>vector destructor iterator</strong> would get called.</p>
<p>The size of array was stored using the BSTR approach, passed in via the <strong>r8d</strong> register.</p>
<p>The callstack from Visual Studio Debugger also tells us the same thing:</p>
<pre style="background: white; color: black; font-family: Consolas;">crtdbg.exe!<span style="color: #ff00ff;">`vector destructor iterator'(void * __t, unsigned __int64 __s, int __n, void (void *) * __f)</span>	C++
crtdbg.exe!<span style="color: #ff00ff;">CBar::`vector deleting destructor'(unsigned int)</span>	C++
crtdbg.exe!main() Line 22	C++
crtdbg.exe!__tmainCRTStartup() Line 536	C
crtdbg.exe!mainCRTStartup() Line 377	C
kernel32.dll!BaseThreadInitThunk()	Unknown
ntdll.dll!RtlUserThreadStart()	Unknown
</pre>
<p>Regarding the actual meaning of the flag I mentioned, I'll leave it as a homework for the readers (hint: you may try out the <a title="DGML" href="https://blogs.msdn.com/b/reiley/archive/2012/08/19/visualize-assembly-using-dgml.aspx" target="_blank">DGML</a> tool).</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Undocumented Environment Variables</title>
      <link>https://docs.microsoft.com/archive/blogs/reiley/undocumented-environment-variables</link>
      <pubDate>Wed, 08 May 2013 07:09:00 GMT</pubDate>
      <dc:creator><![CDATA[Reiley Yang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/reiley/2013/05/08/undocumented-environment-variables/</guid>
      <description><![CDATA[Although we have less Easter Eggs,&nbsp;there are still a huge number of&nbsp;undocumented...]]></description>
      <content:encoded><![CDATA[<p>Although we have less <a title="Easter Eggs" href="https://blogs.msdn.com/b/larryosterman/archive/2005/10/21/483608.aspx" target="_blank">Easter Eggs</a>,&nbsp;there are still a huge number of&nbsp;<a title="undocumented behaviors" href="https://blogs.msdn.com/b/reiley/archive/2011/10/30/undocumented-windbg.aspx" target="_blank">undocumented behaviors</a>.</p>
<p>Recently I'm writing&nbsp;a CLR profiler using ICorProfilerCallback for fun, the CLR profiler was modeled as an in-proc COM server, and the activition was done through environment variables:</p>
<ul>
<li>SET COR_ENABLE_PROFILING=1</li>
<li>SET COR_PROFILER={XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}</li>
<li>SET COR_PROFILER_PATH="C:\FOO\BAR\MyProfiler.dll"</li>
</ul>
<p>Immediately I realized there must be a lot more environment variables, and it&nbsp;was a perfect time to use WinDBG:&nbsp;</p>
<pre style="background: white; color: black; font-family: Consolas;"><span style="font-family: verdana,geneva; background-color: #c0c0c0;">cdb.exe -hd -g -G -xi ld -xe cpr -c "bu KERNELBASE!GetEnvironmentVariableW \"du @rcx; gc\"; g" "%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\csc.exe"</span></pre>
<pre style="background: #ffffe0; color: black; font-family: Consolas;">0:000&gt; cdb: Reading initial command 'bu KERNELBASE!GetEnvironmentVariableW "du @rcx; gc"; g'
000007fe`581406f0  "<span style="color: #ff0000;">SHIM_DEBUG_LEVEL</span>"
000007fe`58140428  "<span style="color: #ff0000;">SHIM_FILE_LOG</span>"
000007fe`581406f0  "<span style="color: #ff0000;">SHIM_DEBUG_LEVEL</span>"
SHIMVIEW: ShimInfo(Complete)
(ba0.db8): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
000007fe`5c4eada0 cc              int     3
0:000&gt; g
Microsoft (R) Visual C# Compiler version 4.0.30319.17929
for Microsoft (R) .NET Framework 4.5
Copyright (C) Microsoft Corporation. All rights reserved.

warning CS2008: No source files specified
000000a3`60e9c230  "<span style="color: #0000ff;">COMPlus_Version</span>"
000000a3`60e9c230  "<span style="color: #0000ff;">COMPlus_InstallRoot</span>"
000000a3`60e9b790  "COMPlus_InstallRoot"
000000a3`60e9c140  "<span style="color: #0000ff;">COMPlus_DefaultVersion</span>"
000000a3`60e9bad0  "COMPlus_InstallRoot"
000000a3`60e9b880  "COMPlus_InstallRoot"
000000a3`60e9b8a0  "<span style="color: #0000ff;">COMPlus_3gbEatMem</span>"
000000a3`60e9b400  "<span style="color: #0000ff;">COMPLUS_CLRLoadLogDir</span>"
000000a3`60e9b1d0  "COMPlus_InstallRoot"
000000a3`60e9b180  "COMPlus_NicPath"
000000a3`60e9b180  "<span style="color: #0000ff;">COMPlus_RegistryRoot</span>"
000000a3`60e9b180  "<span style="color: #0000ff;">COMPlus_AssemblyPath</span>"
000000a3`60e9b180  "<span style="color: #0000ff;">COMPlus_AssemblyPath2</span>"
000000a3`60e9ab80  "COMPLUS_InstallRoot"
000000a3`60e9ab40  "COMPLUS_DefaultVersion"
000000a3`60e9ab40  "COMPLUS_Version"
000000a3`60e9af60  "COMPLUS_ApplicationMigrationRunt"
000000a3`60e9afa0  "imeActivationConfigPath"
000000a3`60e9afb0  "<span style="color: #0000ff;">COMPLUS_OnlyUseLatestCLR</span>"
000007fe`51a06580  "APPX_PROCESS"
000000a3`60e9af60  "COMPLUS_BuildFlavor"
000007f6`2e5c16a8  "LIB"
error CS1562: Outputs without source must have the /out option specified
</pre>
<p>As we can see, the red parts are the environment variables used by Application Compatibility team for debugging a shim.</p>
<p>The blue parts are the environment variables used by COMPLUS, which was the original name for .NET.</p>
<p>Notice that there is no guarantee of completeness using my WinDBG approach, since GetEnvironmentVariableW is not the only way to retrieve environment variables.</p>
<p>I'll leave a homework for the readers - find the environment variables consumed by the Visual Studio IDE (hint: you need to modify the command line to make it work under 32bit).</p>]]></content:encoded>
    </item>
    <item>
      <title>The Pit of Success</title>
      <link>https://docs.microsoft.com/archive/blogs/reiley/the-pit-of-success</link>
      <pubDate>Sat, 27 Apr 2013 07:55:00 GMT</pubDate>
      <dc:creator><![CDATA[Reiley Yang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/reiley/2013/04/27/the-pit-of-success/</guid>
      <description><![CDATA[The Pit of Success: in stark contrast to a summit, a peak, or a journey across a desert to find...]]></description>
      <content:encoded><![CDATA[<p><span style="color: #000000; font-family: book antiqua,palatino; font-size: medium;"><em>The Pit of Success: in stark contrast to a summit, a peak, or a journey across a desert to find victory through many trials and surprises, we want our customers to simply fall into winning practices by using our platform and frameworks. To the extent that we make it easy to get into trouble we fail.</em></span></p>
<p style="text-align: right;"><span style="color: #000000; font-family: book antiqua,palatino; font-size: medium;"><em>- by Rico Mariani</em></span></p>
<p>In my <a title="self-introduction" href="https://blogs.msdn.com/b/reiley/archive/2011/07/11/hello-world.aspx" target="_blank">self-introduction</a>, I mentioned my past experience on developing ATL, CRT, MFC and STL. I've learned a lot from this experience, and as I work with people who develop services based on .NET platform, there are many interesting findings. Each time I stepped back and looked at things that have been developed, the more I&nbsp;love the&nbsp;"The Pit of Success" concept&nbsp;brought up by&nbsp;Rico Mariani. So here I'm trying to share some of my <em>personal</em> understanding.</p>
<p>ATL (not including ATL Server)&nbsp;is my personal favorite library for the following reasons:</p>
<ul>
<li>ATL is a library instead of framework</li>
<ul>
<li>in order to adopt ATL you don't have to change any existing architecture</li>
</ul>
<li>ATL is lightweight</li>
<ul>
<li>in most cases you can just use ATL header files, without dealing with *.lib files and DLLs</li>
<li>ATL won't bloat the binary size too much</li>
<li>ATL won't harm performance for sure</li>
</ul>
<li>ATL is predictable</li>
<ul>
<li>debugging through ATL source is straightforward</li>
<li>the main purpose of ATL is to make COM programming easier in C++, not to hide the complexity of the operating system concepts</li>
<li>the COM wrapper has a very clear definition on the thread safety</li>
</ul>
</ul>
<p>CRT is the library from which I learned a lot:</p>
<ul>
<li>CRT acts as a bridge between the operating system and most applications</li>
<ul>
<li>dealing with <a title="application startup and cleanup" href="https://blogs.msdn.com/b/reiley/archive/2011/12/14/crt-startup.aspx" target="_blank">application startup and cleanup</a></li>
<li>providing runtime services (e.g. backing C++ exception scope with SEH and exception filters)</li>
<li>balancing between the underlying system implementation and the&nbsp;C/C++ standard specification</li>
</ul>
<li>CRT has evil contracts with C++ compiler toolchain</li>
<li>CRT is not only consumed by normal applications, but also by operating system and compiler toolchain (which sounds like an infinite loop)</li>
<li>CRT always sits in the frontline of supporting new hardware architecture</li>
<li>CRT needs to be the most stable and compatible library</li>
</ul>
<p>MFC is a framework consisting of class libraries:</p>
<ul>
<li>it's easy to get started with MFC</li>
<li>MFC takes care of window management, messaging, COM and many great things</li>
<li>you really need to understand MFC in order to use it well, especially when you run into bug hell</li>
</ul>
<p>STL is a C++ template library, which I've used&nbsp;extensively (in combination with <a title="Boost" href="https://www.boost.org/" target="_blank">Boost</a>) when I was in school, when I developed STL and when I have good reason to use STL:</p>
<ul>
<li>if I have a free choice, normally&nbsp;I would tend not to use STL</li>
<li>debugging template code is not easy, especially the code that makes extensive use of template meta-programming and <a title="macro" href="https://blogs.msdn.com/b/reiley/archive/2011/08/12/macro-revisited.aspx" target="_blank">macro</a>&nbsp;meta-programming</li>
<li>running code coverage analysis against template code is tricky (source line coverage is almost meaningless, you have to use basic block coverage)</li>
<li>it's bad idea to pass (e.g. parameter, exception)&nbsp;STL objects across module boundary, since&nbsp;the underlying contract (e.g. object layout) might be different</li>
<li>binary size might bloat and turn into a serious problem</li>
</ul>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Error and Exception Revisited</title>
      <link>https://docs.microsoft.com/archive/blogs/reiley/error-and-exception-revisited</link>
      <pubDate>Fri, 05 Apr 2013 07:18:00 GMT</pubDate>
      <dc:creator><![CDATA[Reiley Yang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/reiley/2013/04/05/error-and-exception-revisited/</guid>
      <description><![CDATA[Unless suffering is the direct and immediate object of life, our existence must entirely fail of its...]]></description>
      <content:encoded><![CDATA[<p><span style="color: #000000; font-family: book antiqua,palatino; font-size: medium;"><em>Unless suffering is the direct and immediate object of life, our existence must entirely fail of its aim. It is absurd to look upon the enormous amount of pain that abounds everywhere in the world, and originates in needs and necessities inseparable from life itself, as serving no purpose at all and the result of mere chance. Each separate misfortune, as it comes, seems, no doubt, to be something exceptional; but misfortune in general is the rule.</em></span></p>
<p style="text-align: right;"><span style="color: #000000; font-family: book antiqua,palatino; font-size: medium;"><em>- by Arthur Schopenhauer</em></span></p>
<p>In the world of programming, error and exceptions seem to be unavoidable, this is especially true when it comes to writing production quality code.</p>
<p>Windows programming&nbsp;can be&nbsp;challenging when both error and exception are used.</p>
<p><strong><span style="color: #000080; font-family: courier new,courier; font-size: large;">Exception</span></strong></p>
<p>Exception always exists, even if you don't care,&nbsp;it would disrupt the normal flow of execution. In Windows operating system exception is implemented as SEH/VEH, with the support from CPU.</p>
<p>The key characteristics of exception in Windows are:</p>
<ol>
<li>Disrupt the normal flow of execution, which translates to pipeline invalidation and slowness.</li>
<li>Can be used consistently in&nbsp;user mode and kernel mode.</li>
<li>Has a lot of great features like continue execution, first chance versus second chance.</li>
<li>Unhandled exception would go to the operating system, which would kill the application (e.g. Dr. Watson)&nbsp;or system (e.g. BSOD).</li>
<li>If you swallow the exceptions used by the operating system or runtime (which you shouldn't catch), the application might not function correctly (e.g. you might get access violation while accessing the PAGE_GUARD page from callstack).</li>
</ol>
<p>The third famous exception is Out of Memory - for device drivers and server application, you always want to handle it; for client application, probably not as critical (e.g. if Visual Studio IDE is running out of memory, we just let it crash).</p>
<p>The second famous exception is Stack Overflow - for hosting environment and fundamental libraries like CRT, you need to take it into consideration; in&nbsp;other cases it means you have design issue, and normally&nbsp;you don't want to handle it.</p>
<p>Let's take a look at the following pseudo code:</p>
<pre style="background: white; color: black; font-family: Consolas;">try
{
  // do something
}
catch(StackOverflowException ex)
{
  log("oops, stack overflow {0}", ex.stack);
  throw ex;
}
finally
{
  // close file handle, etc.
}
</pre>
<p>&nbsp;There are several things I can tell:</p>
<ol>
<li>Having "throw ex" would ruin the exception information, better use "throw" instead.</li>
<li>The "log" function doesn't have much stack space, it could trigger another stack overflow.</li>
<li>When the exception was re-thrown, we are already miles away from the&nbsp;original place of the problem -&nbsp;we are not keeping the scene intact, and nobody would want to debug a dump file for this case.</li>
<li>The process is dying, close file handle will not make it any better,&nbsp;operating system&nbsp;would do that for you. More importantly, it is very likely that you are making things even worse.</li>
<li>If you are using latest version of .NET framework, normally you are <strong>NOT</strong>&nbsp;allowed to catch StackOverflowException:
<blockquote style="margin-right: 0px;" dir="ltr">
<div style="background: #cccccc;"><span style="font-family: verdana,geneva;">In prior versions of the .NET Framework, your application could catch a StackOverflowException object (for example, to recover from unbounded recursion). However, that practice is currently discouraged because significant additional code is required to reliably catch a stack overflow exception and continue program execution.<br /><br /><span style="color: #bf100c;">Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default.</span> Consequently, users are advised to write their code to detect and prevent a stack overflow. For example, if your application depends on recursion, use a counter or a state condition to terminate the recursive loop. Note that an application that hosts the common language runtime (CLR) can specify that the CLR unload the application domain where the stack overflow exception occurs and let the corresponding process continue. For more information, see ICLRPolicyManager Interface and Hosting Overview.</span><br /><br /><span style="font-family: verdana,geneva;">Windows 95, Windows 98, Windows 98 Second Edition, Windows Millennium Edition Platform Note: A thrown StackOverflowException cannot be caught by a try-catch block. Consequently, the exception causes the process to terminate immediately.</span></div>
</blockquote>
</li>
</ol>
<p>The most famous exception is Access Violation, in normal cases this would be a killer bug which stop the entire development team.</p>
<p><strong><span style="color: #000080; font-family: courier new,courier; font-size: large;">Error</span></strong></p>
<p>Error is more like a convention, the main characteristics of error are:</p>
<ol>
<li>Lightweight -&nbsp;doesn't require infrastructure support from operating system and CPU.</li>
<li>Less picky comparing to exception&nbsp;-&nbsp;error wouldn't complain whether you've paid enough attention to it, however it might eventually kill you if not handled properly.</li>
</ol>
<p><span style="font-size: medium;"><strong><span style="color: #000080; font-family: courier new,courier;">Windows Error Code</span></strong></span></p>
<p>Most Win32 API would return BOOL value. If FALSE is returned, the error code is stored in TEB as DWORD, which can be retrieved by using GetLastError.</p>
<p>You can use WinDBG's <a title="!ext.gle" href="https://msdn.microsoft.com/en-us/library/windows/hardware/ff563177.aspx" target="_blank">!ext.gle</a> or Visual Studio's <a title="$ERR" href="https://blogs.msdn.com/b/reiley/archive/2011/08/13/did-you-know.aspx" target="_blank">$ERR</a> trick to retrieve the last error code from TEB, which also work for dump files.</p>
<p>The good side of storing last error in a central place (e.g. TEB) is the ability to set <a title="Data Breakpoint" href="https://blogs.msdn.com/b/reiley/archive/2011/07/21/data-breakpoint.aspx" target="_blank">Data Breakpoint</a>&nbsp;to see where is the&nbsp;error coming from. Also in later version of Windows there is a feature to do similar things:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/66/6433.SetLastError.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-66/6433.SetLastError.png"><img style="border: 0px currentColor;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/66/6433.SetLastError.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/0x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-66/6433.SetLastError.png" alt="" /></a></p>
<p>Registry API in advapi32.dll is special, Windows error code is returned directly as LONG (signed long).</p>
<p>WinSock and NetAPI have similar concept but different mapping.</p>
<p><span style="font-size: medium;"><strong><span style="color: #000080; font-family: courier new,courier;">NTSTATUS</span></strong></span></p>
<p>Lower layer of the operating system makes use of NTSTATUS, which has a similar structure as Win32 error, an incomplete mapping table can be found from <a title="Mapping NT Status Error Codes to Win32 Error Codes" href="https://support.microsoft.com/kb/113996" target="_blank">Mapping NT Status Error Codes to Win32 Error Codes</a>.</p>
<p>For LSA (Local Security Authority)&nbsp;specifically, the NTSTATUS return value can be converted to Win32 error using <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms721800.aspx" target="_blank">LsaNtStatusToWinError</a>.</p>
<p><span style="font-size: medium;"><strong><span style="color: #000080; font-family: courier new,courier;">HRESULT</span></strong></span></p>
<p>COM makes use of HRESULT, which was designed to be a super container for all kinds of error codes. There is a macro HRESULT_FROM_WIN32 (p.s. in later version of Windows this has been <a title="changed to an inline function" href="https://blogs.msdn.com/b/matthew_van_eerde/archive/2007/12/28/the-evolution-of-hresult-from-win32.aspx" target="_blank">changed to an inline function</a>)&nbsp;which converts Windows Error Code to HRESULT.</p>
<p>One caveat about HRESULT is that one has to always keep in mind of S_OK, S_FALSE, SUCCEEDED and FAILED, and understand the differences.</p>
<p>&nbsp;</p>
<p>Since there are so many different kinds of error codes, even people working in Microsoft may get confused, that's why people tend to create tools and make the situation better:</p>
<ol>
<li>WinDBG extension command <a title="!ext.error" href="https://msdn.microsoft.com/en-us/library/windows/hardware/ff562998.aspx" target="_blank">!ext.error</a>, which supports both Windows Error Code and NTSTATUS.</li>
<li><a title="Visual Studio debugger" href="https://msdn.microsoft.com/en-us/library/5tbh0w11.aspx" target="_blank">Visual Studio debugger</a>.</li>
<li><a title="Error Code Look-up" href="https://www.microsoft.com/en-us/download/details.aspx?id=985" target="_blank">Error Code Look-up</a> tool, implemented by the Exchange team.</li>
</ol>]]></content:encoded>
    </item>
    <item>
      <title>A Debugging Approach to Windows RT</title>
      <link>https://docs.microsoft.com/archive/blogs/reiley/a-debugging-approach-to-windows-rt</link>
      <pubDate>Wed, 26 Dec 2012 05:11:00 GMT</pubDate>
      <dc:creator><![CDATA[Reiley Yang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/reiley/2012/12/26/a-debugging-approach-to-windows-rt/</guid>
      <description><![CDATA[Recently I got a Surface with Windows&nbsp;RT. Needless to mention, it's wonderful!
I've figured...]]></description>
      <content:encoded><![CDATA[<p>Recently I got a <a title="Surface with Windows RT" href="https://en.wikipedia.org/wiki/Microsoft_Surface" target="_blank">Surface with Windows&nbsp;RT</a>. Needless to mention, it's wonderful!</p>
<p>I've figured out&nbsp;some quick facts about Windows RT by looking at the <span style="font-family: verdana,geneva;">C:\Windows\system32\ntdll.dll</span> from Windows RT:</p>
<ul>
<li>A&nbsp;complete NT (instead of WINCE) kernel and almost a full stack of Windows operating system.</li>
<li>Almost the same&nbsp;<a title="PE/COFF" href="https://msdn.microsoft.com/en-us/windows/hardware/gg463119.aspx" target="_blank">PE/COFF</a> structure as x86.</li>
<li>Using ARM's "non classic RISC style" Thumb-2 instruction set (<span style="font-family: verdana,geneva;">pImageNtHeaders-&gt;FileHeader.Machine == <strong>IMAGE_FILE_MACHINE_ARMNT</strong></span>), which has great code density, and in turn gives smaller binary and less memory pressure.</li>
</ul>
<p>I've never had a chance to debug Thumb-2 code before, so I've listed the things I need to grasp:</p>
<ul>
<li>Fundamental ARM architecture and Thumb-2 instructions.</li>
<li>ABI (Application Binary Interface), calling convention and&nbsp;exception handling mechanism.</li>
<li>Programming and debugging.</li>
</ul>
<p><strong><span style="color: #000080; font-family: courier new,courier; font-size: large;">Programming</span></strong></p>
<p>Although Visual Studio 2012 doesn't&nbsp;have an ARM version,&nbsp;it&nbsp;does included the x86 cross toolchain which allows targeting ARM architecture, which can be found from <strong><span style="font-family: verdana,geneva;">%ProgramFiles(x86)%\Microsoft Visual Studio 11.0\VC\bin\x86_arm\</span></strong>. By setting the correct environment variable (INCLUDE, LIB, LIBPATH, PATH) we can generate ARM module smoothly.</p>
<pre style="background: white; color: black; font-family: Consolas;"><span style="color: blue;">int</span>&nbsp;main()
{
&nbsp;&nbsp;<span style="color: blue;">return</span>&nbsp;0;
}
</pre>
<pre style="background: #ffffe0; color: black; font-family: Consolas;">C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\<span style="background-color: #00ff00;">x86_arm</span>&gt;<strong>cl.exe&nbsp;/link /NODEFAULTLIB&nbsp;/ENTRY:main test.cpp</strong>
<span style="color: #ff0000;">Microsoft (R) C/C++ Optimizing Compiler Version 17.00.51106.1 for ARM </span>Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp
Microsoft (R) Incremental Linker Version 11.00.51106.1
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:test.exe
/machine:arm
/NODEFAULTLIB
/ENTRY:main
test.obj
</pre>
<p>By default Visual Studio doesn't allow generating native ARM binary, and the restriction was from a MSBuild property named <strong>WindowsSDKDesktopARMSupport</strong>, by setting this property to true I could target ARM native without an issue.</p>
<p>Another problem is that Windows SDK doesn't have the ARM version of import libraries, which means we don't have files like gdi32.lib and shell32.lib. The solution would be creating one either by writing a DEF file, or creating a stub module. Since we can get the&nbsp;ARM version of DLLs&nbsp;from Windows RT, it is easy to dump the export directory and create DEF file automatically, as long as the DLLs we use is not exporting mangled name (otherwise I would prefer to use stub module approach).</p>
<p>This is what I got while running my very first hello.exe on Windows RT :)</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/66/1307.HelloSurface.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-66/1307.HelloSurface.png"><img style="border: 0px currentColor;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/66/1307.HelloSurface.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/0x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-66/1307.HelloSurface.png" alt="" /></a></p>
<p>For pure managed code programming, the .NET runtime in Surface RT&nbsp;comes with the standard&nbsp;C# compiler:</p>
<pre style="background: white; color: black; font-family: Consolas;"><span style="color: blue;">class</span>&nbsp;<span style="color: #2b91af;">Hello</span>
{
&nbsp;&nbsp;<span style="color: blue;">static</span>&nbsp;<span style="color: blue;">void</span>&nbsp;Main()
&nbsp;&nbsp;{
&nbsp;&nbsp;}
}
</pre>
<pre style="background: #ffffe0; color: black; font-family: Consolas;">C:\Users\Reiley\Desktop&gt;"<strong>%WINDIR%\Microsoft.NET\Framework\v4.0.30319\csc.exe</strong>" /noconfig /debug+ /platform:anycpu hello.cs
Microsoft (R) Visual <span style="color: #ff0000;">C# Compiler version 4.0.30319.17929 </span>
for Microsoft (R) <span style="color: #ff0000;">.NET Framework 4.5</span>
Copyright (C) Microsoft Corporation. All rights reserved.
</pre>
<p>And this time I got something worse:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/66/1220.MsilSurface.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-66/1220.MsilSurface.png"><img style="border: 0px currentColor;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/66/1220.MsilSurface.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/0x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-66/1220.MsilSurface.png" alt="" width="700" height="135" /></a></p>
<p>After changing the compiler flag&nbsp;to target ARM instead of AnyCPU, it became better and I was again greeted with the "Windows cannot verify the digital signature ..." dialog.</p>
<pre style="background: #ffffe0; color: black; font-family: Consolas;">C:\Users\Reiley\Desktop&gt;"<strong>%WINDIR%\Microsoft.NET\Framework\v4.0.30319\csc.exe</strong>" /noconfig /debug+ /platform:<span style="color: #ff0000;"><strong>arm</strong></span> hello.cs
</pre>
<p><strong><span style="color: #000080; font-family: courier new,courier; font-size: large;">Debugging</span></strong></p>
<p>The x86 and amd64 version of WinDBG both support various architectures including ARM Thumb-2, which means you can open dump files from a PC. This is a good place to get started, and actually I copied notepad.exe from Surface to my PC and used&nbsp;<strong><span style="font-family: verdana,geneva;">cdb.exe -z notepad.exe</span></strong> to familiar myself with the ARM PE structure and disassembly.</p>
<p>There is no&nbsp;ARM version of WinDBG&nbsp;available for public download. Also ntsd.exe is no longer shipped as part of the Windows since Vista.</p>
<p>Visual Studio 2012 comes with a great debugger, together with a fantastic remote debugging agent. Jason Zander already explained how to setup remote debugging from his great&nbsp;article "<a title="What you need to know about developing for Windows on ARM" href="https://blogs.msdn.com/b/jasonz/archive/2012/06/12/what-you-need-to-know-about-developing-for-windows-on-arm-woa.aspx" target="_blank">What you need to know about developing for Windows on ARM</a>". I'll just put a conclusion here:</p>
<ol>
<li>Visual Studio 2012 doesn't have ARM version, in fact only x86 version is available.</li>
<li>Visual Studio 2012 supports remote kernel debugging, however there is no direct way to enable kernel debugging on Windows RT device.</li>
<li>Visual Studio 2012 comes with an ARM version of remote debugging agent, which makes it possible to do user mode debugging&nbsp;on&nbsp;nearly all processes. To unleash the power, run&nbsp;remote debugging agent (msvsmon) as a service under an administrator account.</li>
<li>User mode debugging on Windows RT is powerful enough that you can do whatever hack you like.</li>
</ol>
<p>&nbsp;</p>
<p>(to be continued...)</p>]]></content:encoded>
    </item>
    <item>
      <title>Postmortem Debugging - Better Late Than Never</title>
      <link>https://docs.microsoft.com/archive/blogs/reiley/postmortem-debugging-better-late-than-never</link>
      <pubDate>Sun, 21 Oct 2012 08:52:00 GMT</pubDate>
      <dc:creator><![CDATA[Reiley Yang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/reiley/2012/10/21/postmortem-debugging-better-late-than-never/</guid>
      <description><![CDATA[If&nbsp;there is a consistent repro, I&nbsp;would definitely prefer&nbsp;Early Debugging. However in...]]></description>
      <content:encoded><![CDATA[<p>If&nbsp;there is a consistent repro, I&nbsp;would definitely prefer&nbsp;<a title="Early Debugging" href="https://blogs.msdn.com/b/reiley/archive/2011/10/30/early-debugging.aspx" target="_blank">Early Debugging</a>. However in the real life postmortem debugging seems to be unavoidable.&nbsp;</p>
<p>There are three concepts I wish to clarify before digging into the details:</p>
<ol>
<li>
<p><strong>AeDebug</strong> is a set of&nbsp;registry keys which specify the behavior when unhandled exception happened in an user mode application.</p>
<ul>
<li><span style="font-family: verdana,geneva;">\\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AeDebug</span></li>
<li><span style="font-family: verdana,geneva;">\\HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug</span></li>
</ul>
<p>By&nbsp;default AeDebug is configured to use drwtsn32.exe, which would capture a dump and terminate the application in problem.</p>
</li>
<li>
<p><strong>Just-In-Time Debugging</strong>&nbsp;(a.k.a. JIT Debugging) is a feature provided by most debuggers (e.g. CDB, NTSD, WinDBG and Visual Studio Debugger), which allows the debugger to be launched and attached to the application in problem.</p>
<p>The JIT debugger shipped with Visual Studio&nbsp;is called <strong>vsjitdebugger.exe</strong>, which would pop up a window and let you decide&nbsp;the next step. Visual Studio stepped further by allowing JIT debugging for scripts.</p>
<p>Needless to mention, JIT Debugging is normally built on top of AeDebug.</p>
</li>
<li>
<p><strong>Postmortem Debugging</strong> is an overloaded term which could mean debugging a dump, or&nbsp;JIT debugging.</p>
<p>Since I will cover JIT debugging in another article, I would prefer referring dump file debugging as Postmortem Debugging.&nbsp;</p>
</li>
</ol>
<p>Okay, now let's go back to the topic, what would you do after receiving a dump file?</p>
<ol>
<li>Understand the&nbsp;source of the dump file - under which condition was the dump file generated. Once you've confirmed the dump is coming from a trusted source, try to find out when and where&nbsp;the dump file was taken.<br /><br /><span style="font-family: Consolas,courier new,courier;">0:001&gt; <strong>.time</strong><br /> Debug session time: Mon Dec 3 17:36:58.997 2012 (UTC - 8:00)<br /> System Uptime: 2 days 23:31:41.638<br /> Process Uptime: 0 days 0:00:14.156<br /> Kernel time: 0 days 0:00:00.015<br />User time: 0 days 0:00:00.000<br /> <br /> 0:001&gt; <strong>vertarget</strong><br /> Windows 7 Version 7601 (Service Pack 1) MP (8 procs) Free x64 Product: LanManNt, suite: Enterprise TerminalServer SingleUserTS<br /> kernel32.dll version: 6.1.7601.17514 (win7sp1_rtm.101119-1850)<br /> Machine Name:<br /> Debug session time: Mon Dec 3 18:37:21.103 2012 (UTC - 8:00)<br /> System Uptime: 3 days 0:32:03.743<br /> Process Uptime: 0 days 1:00:36.261<br /> Kernel time: 0 days 0:00:00.015<br /> User time: 0 days 0:00:00.000<br /><br />0:000&gt; <strong>.lastevent</strong><br />Last event: 14d0.1874: Break instruction exception - code 80000003 (first chance)</span><br /><br /></li>
<li>Check the dump file type&nbsp;- mini dump or full dump, kernel dump or user mode dump, whether the dump contains an exception record. Normally WinDBG would&nbsp;display the dump type when you open a dump file, here we'll use&nbsp;the command learned in <a title="Undocumented WinDBG" href="https://blogs.msdn.com/b/reiley/archive/2011/10/30/undocumented-windbg.aspx" target="_blank">Undocumented WinDBG</a>.<br />&nbsp;<span style="font-family: Consolas,courier new,courier;">&nbsp;<br /> 0:001&gt; <strong>.dumpdebug</strong><br /> ----- User Mini Dump Analysis<br /> MINIDUMP_HEADER:<br />Version&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A793 (6804)<br />NumberOfStreams 14<br />Flags&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9164<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0004 MiniDumpWithHandleData<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0020 MiniDumpWithUnloadedModules<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0040 MiniDumpWithIndirectlyReferencedMemory<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0100 MiniDumpWithProcessThreadData<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1000 MiniDumpWithThreadInfo<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8000 MiniDumpWithFullAuxiliaryState</span></li>
</ol>
<p>If it's a user mode dump, additional information needs to be retrieved from the dump.</p>
<ol>
<li>What is the command line, and whether the process is a generic host&nbsp;such like dllhost.exe, svchost.exe taskhost.exe and w3wp.exe.</li>
<li>Understand the bitness - whether it is a 64bit process or 32bit process.&nbsp;It&nbsp;would be tricky while debugging a 64bit dump of WOW32 process.</li>
<li>Whether CLR is involved, and what is the CLR version (note there could be more than one CLR hosted).</li>
</ol>
<p>(to be continued...)</p>]]></content:encoded>
    </item>
    <item>
      <title>Windows 8 and conhost.exe</title>
      <link>https://docs.microsoft.com/archive/blogs/reiley/windows-8-and-conhost-exe</link>
      <pubDate>Thu, 13 Sep 2012 07:01:00 GMT</pubDate>
      <dc:creator><![CDATA[Reiley Yang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/reiley/2012/09/13/windows-8-and-conhost-exe/</guid>
      <description><![CDATA[While debugging a console application on Windows 8, I noticed the console application is trying to...]]></description>
      <content:encoded><![CDATA[<p>While debugging a console application on Windows 8, I noticed the console application is trying to create a process in the very beginning:</p>
<p><span style="font-family: verdana,geneva; font-size: small; background-color: #c0c0c0;">windbg.exe -xe ld:ntdll.dll -c "bm ntdll!*CreateProcess*; g; k" cmd.exe</span></p>
<pre style="background: white; color: black; font-family: Consolas;">CommandLine: cmd.exe<br />ModLoad: 000007ff`01d60000 000007ff`01f1e000&nbsp;&nbsp; ntdll.dll<br />ntdll!RtlUserThreadStart:<br />000007ff`01d7c3d0 4883ec48&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub&nbsp;&nbsp;&nbsp;&nbsp; rsp,48h<br />Processing initial command 'bm ntdll!*CreateProcess*; g; k'<br />0:000&gt; bm ntdll!*CreateProcess*; g; k<br />&nbsp; 1: 000007ff`01d90f60 @!"ntdll!RtlCreateProcessParametersEx"<br />&nbsp; 2: 000007ff`01d63070 @!"ntdll!NtCreateProcessEx"<br />breakpoint 2 redefined<br />&nbsp; 2: 000007ff`01d63070 @!"ntdll!ZwCreateProcessEx"<br />&nbsp; 3: 000007ff`01e1bf74 @!"ntdll!RtlCreateProcessReflection"<br />&nbsp; 4: 000007ff`01da8bb4 @!"ntdll!RtlpCreateProcessRegistryInfo"<br />&nbsp; 5: 000007ff`01e1ceac @!"ntdll!RtlCreateProcessParameters"<br />&nbsp; 6: 000007ff`01d63651 @!"ntdll!ZwCreateProcess"<br />breakpoint 6 redefined<br />&nbsp; 6: 000007ff`01d63651 @!"ntdll!NtCreateProcess"<br />Breakpoint 1 hit<br />Child-SP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RetAddr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Call Site<br />000000bf`8268e558 000007fe`feea02a4 ntdll!RtlCreateProcessParametersEx<br />000000bf`8268e560 000007fe`feea00be KERNELBASE!ConsoleLaunchServerProcess+0x60<br />000000bf`8268e5f0 000007fe`fee95d40 KERNELBASE!ConsoleAllocate+0xf6<br />000000bf`8268e8c0 000007fe`fee7f6db KERNELBASE!ConsoleInitialize+0x1d1<br />000000bf`8268e950 000007fe`fee7230d KERNELBASE!KernelBaseBaseDllInitialize+0x4dd<br />000000bf`8268ec20 000007ff`01d6b9be KERNELBASE!KernelBaseDllInitialize+0xd<br />000000bf`8268ec50 000007ff`01d8b3fc ntdll!LdrpCallInitRoutine+0x3e<br />000000bf`8268eca0 000007ff`01d8a88b ntdll!LdrpInitializeNode+0x192<br />000000bf`8268eda0 000007ff`01d8e74e ntdll!LdrpInitializeGraph+0x6f<br />000000bf`8268ede0 000007ff`01d8c322 ntdll!LdrpInitializeGraph+0x8d<br />000000bf`8268ee20 000007ff`01d8cc02 ntdll!LdrpPrepareModuleForExecution+0x1a5<br />000000bf`8268ee70 000007ff`01d8337b ntdll!LdrpLoadDll+0x344<br />000000bf`8268f0a0 000007ff`01d9264f ntdll!LdrLoadDll+0xa7<br />000000bf`8268f120 000007ff`01d91826 ntdll!LdrpInitializeProcess+0x1664<br />000000bf`8268f420 000007ff`01d7c1ae ntdll!_LdrpInitialize+0x1565e<br />000000bf`8268f490 00000000`00000000 ntdll!LdrInitializeThunk+0xe</pre>
<pre style="background: white; color: black; font-family: Consolas;"><br />0:000&gt; <strong>dc rbx</strong><br />000000bf`8268e660&nbsp; 00000000 00000000 00000000 00000000&nbsp; ................<br />000000bf`8268e670&nbsp; 003f005c 005c003f 003a0043 0057005c&nbsp; <span style="color: #0000ff;">\.?.?.\.C.:.\.W.</span><br />000000bf`8268e680&nbsp; 004e0049 004f0044 00530057 0073005c&nbsp; <span style="color: #0000ff;">I.N.D.O.W.S.\.s.</span><br />000000bf`8268e690&nbsp; 00730079 00650074 0033006d 005c0032&nbsp; <span style="color: #0000ff;">y.s.t.e.m.3.2.\.</span><br />000000bf`8268e6a0&nbsp; 006f0063 0068006e 0073006f 002e0074&nbsp; <span style="color: #0000ff;">c.o.n.h.o.s.t...</span><br />000000bf`8268e6b0&nbsp; 00780065 00200065 00780030 00660066&nbsp; <span style="color: #0000ff;">e.x.e. .0.x.</span>f.f.<br />000000bf`8268e6c0&nbsp; 00660066 00660066 00660066 00000000&nbsp; f.f.f.f.f.f.....<br />000000bf`8268e6d0&nbsp; 8268e960 000000bf 00000008 00000000&nbsp; `.h.............</pre>
<p>This means conhost.exe process&nbsp;on Windows 8 will be created by the console application itself, instead of the CSRSS. And conhost.exe would always have the native bitness (on Windows 8 64bit version, only 64bit version of conhost.exe is available).</p>
<p>Now&nbsp;debug into conhost.exe using<strong> <span style="font-family: verdana,geneva;">.childdbg</span></strong>, it's pretty clear that conhost.exe is in charge of drawing the console window, handling user inputs and communicate with the console application:</p>
<pre style="background: white; color: black; font-family: Consolas;">0&nbsp; Id: 124c.d34 Suspend: 1 Teb: 000007f6`3311b000 Unfrozen<br />Child-SP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RetAddr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Call Site<br />00000094`85aefb38 000007f6`33b91146 ntdll!NtWaitForSingleObject+0xa<br />00000094`85aefb40 000007ff`00c9167e <span style="color: #0000ff;">conhost!ConsoleIoThread</span>+0xda<br />00000094`85aefd80 000007ff`01d7c3f1 KERNEL32!BaseThreadInitThunk+0x1a<br />00000094`85aefdb0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d</pre>
<pre style="background: white; color: black; font-family: Consolas;">#&nbsp; 1&nbsp; Id: 124c.1428 Suspend: 1 Teb: 000007f6`3311e000 Unfrozen<br />Child-SP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RetAddr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Call Site<br />00000094`85b6fd28 000007ff`0140171e <span style="color: #ff0000;">conhost!ConsoleWindowProc</span><br />00000094`85b6fd30 000007ff`014014d7 USER32!UserCallWinProcCheckWow+0x13a<br />00000094`85b6fdf0 000007f6`33b92fcc USER32!DispatchMessageWorker+0x1a7<br />00000094`85b6fe70 000007ff`00c9167e <span style="color: #0000ff;">conhost!ConsoleInputThread</span>+0xd2<br />00000094`85b6fed0 000007ff`01d7c3f1 KERNEL32!BaseThreadInitThunk+0x1a<br />00000094`85b6ff00 00000000`00000000 ntdll!RtlUserThreadStart+0x1d</pre>
<p>And cmd.exe itself doesn't draw the console window at all:</p>
<pre style="background: white; color: black; font-family: Consolas;">0&nbsp; Id: 1aec.5ec Suspend: 1 Teb: 000007f7`b280d000 Unfrozen<br />Child-SP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RetAddr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Call Site<br />00000008`50fff5b8 000007fe`fee8f17c ntdll!NtDeviceIoControlFile+0xa<br />00000008`50fff5c0 000007fe`fef0bb29 KERNELBASE!ConsoleCallServerGeneric+0x118<br />00000008`50fff710 000007fe`fef0b986 KERNELBASE!ReadConsoleInternal+0x131<br />00000008`50fff850 000007f7`b3621025 KERNELBASE!ReadConsoleW+0x1a<br />00000008`50fff890 000007f7`b362bd3e cmd!ReadBufFromConsole+0x111<br />00000008`50fff960 000007f7`b3604aae cmd!_chkstk+0x3820<br />00000008`50fffae0 000007f7`b36042e4 <span style="color: #0000ff;">cmd!Lex+0x4be</span><br />00000008`50fffb50 000007f7`b362d560 <span style="color: #0000ff;">cmd!Parser+0x128</span><br />00000008`50fffba0 000007f7`b361b721 cmd!_chkstk+0x5032<br />00000008`50fffc00 000007ff`00c9167e cmd!mystrchr+0x27d<br />00000008`50fffc40 000007ff`01d7c3f1 KERNEL32!BaseThreadInitThunk+0x1a<br />00000008`50fffc70 00000000`00000000 ntdll!RtlUserThreadStart+0x1d</pre>
<p>The interesting thing is that if we use <a title="Spy++" href="https://msdn.microsoft.com/en-us/library/dd460760" target="_blank">Spy++</a>, it would report that the console window is associated with the <a title="main thread" href="https://blogs.msdn.com/b/reiley/archive/2011/11/09/the-main-thread-problem.aspx" target="_blank">main thread</a>&nbsp;of cmd.exe process! I believe this is a hack in the underlying implementation of&nbsp;<strong><span style="font-family: verdana,geneva;">GetWindowThreadProcessId</span></strong>&nbsp;for backward compatibility. Also, Spy++ cannot be used to inspect conhost.exe message loop.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/66/0882.spyxx.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-66/0882.spyxx.png"><img width="566" height="201" style="border: 0px currentColor;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/66/0882.spyxx.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/0x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-66/0882.spyxx.png" /></a></p>
<p>Due to the <a title="side effects" href="https://blogs.msdn.com/b/reiley/archive/2011/08/28/side-effects-of-debugger.aspx" target="_blank">side effects</a> of <a title="IFEO" href="https://blogs.msdn.com/b/reiley/archive/2011/07/30/a-debugging-approach-to-ifeo.aspx" target="_blank">IFEO</a> Debugger, console application would fail to start if IFEO Debugger is enabled for conhost.exe.</p>
<p>The following call stack showed conhost.exe just created a normal window from Console Input Thread:</p>
<pre style="background: white; color: black; font-family: Consolas;">USER32!<span style="color: #0000ff;">CreateWindowExW</span><br />conhost!CreateWindowsWindow+0x105<br />conhost!InitWindowsSubsystem+0x69<br />conhost!ConsoleInputThread+0x22<br />KERNEL32!BaseThreadInitThunk+0x1a<br />ntdll!RtlUserThreadStart+0x1d</pre>
<pre style="background: white; color: black; font-family: Consolas;">0:001&gt; <strong>du @rdx</strong><br />000007f6`33b9d460&nbsp; "<span style="color: #ff00ff;">ConsoleWindowClass</span>"</pre>
<pre style="background: white; color: black; font-family: Consolas;">0:001&gt; <strong>du @r8</strong><br />00000025`f7dc37c0&nbsp; "<span style="color: #ff00ff;">C:\WINDOWS\SYSTEM32\cmd.exe</span>"</pre>
<p>When cmd.exe exits, the Console I/O&nbsp;Thread would be notified:</p>
<pre style="background: white; color: black; font-family: Consolas;"><strong>ntdll!NtTerminateProcess</strong>+0xa<br /><strong>ntdll!RtlExitUserProcess</strong>+0xb6<br /><span style="color: #0000ff;">conhost!ConsoleIoThread</span>+0xac4<br />KERNEL32!BaseThreadInitThunk+0x1a<br />ntdll!RtlUserThreadStart+0x1d</pre>
<p>(to be continued...)</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Visualize Assembly using DGML</title>
      <link>https://docs.microsoft.com/archive/blogs/reiley/visualize-assembly-using-dgml</link>
      <pubDate>Sun, 19 Aug 2012 08:54:00 GMT</pubDate>
      <dc:creator><![CDATA[Reiley Yang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/reiley/2012/08/19/visualize-assembly-using-dgml/</guid>
      <description><![CDATA[Starting from Visual Studio 2010 Ultimate there is a cool feature called DGML (Directed Graph Markup...]]></description>
      <content:encoded><![CDATA[<p>Starting from Visual Studio 2010 Ultimate there is a cool feature called DGML (<a title="DGML" href="https://en.wikipedia.org/wiki/DGML" target="_blank">Directed Graph Markup Language</a>).</p>
<p>I wrote a small script to convert the disassembled code from WinDBG into a DGML.</p>
<p>In order to use it, simply type the following commands under a debug session:</p>
<p><span style="font-family: verdana,geneva; font-size: small; background-color: #c0c0c0;">.shell<span style="color: #000000;"> -o <strong>LoadLibraryA</strong>.dgml -ci "uf <strong>kernel32!LoadLibraryA</strong>" cscript</span>.exe /nologo dasm2dgml.js</span></p>
<p>A&nbsp;DGML file will be generated with the given name, and&nbsp;here is what it looks like:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/66/8154.DGML.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-66/8154.DGML.png"><img style="border: 0px currentColor;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/66/8154.DGML.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/0x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-66/8154.DGML.png" /></a></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/66/7446.DGML.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-66/7446.DGML.png"></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/46/66/2451.DGML.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-46-66/2451.DGML.png"></a></p>
<p>Here is the source code:</p>
<hr width="100%" style="width: 100%;" />
<pre style="background: white; color: black; font-family: Consolas;"><span style="color: blue;">var</span>&nbsp;EBB&nbsp;=&nbsp;[];

<span style="color: blue;">var</span>&nbsp;hypertext=<span style="color: blue;">function</span>(s){
&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;r=[],L=s.length;
&nbsp;&nbsp;<span style="color: blue;">for</span>(<span style="color: blue;">var</span>&nbsp;i=0;i&lt;L;i++){
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;c=s.charAt(i);
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">switch</span>(c){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">case</span>&nbsp;<span style="color: maroon;">'"'</span>:r.push(<span style="color: maroon;">'&amp;quot;'</span>);<span style="color: blue;">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">case</span>&nbsp;<span style="color: maroon;">'&amp;'</span>:r.push(<span style="color: maroon;">'&amp;amp;'</span>);<span style="color: blue;">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">case</span>&nbsp;<span style="color: maroon;">'&lt;'</span>:r.push(<span style="color: maroon;">'&amp;lt;'</span>);<span style="color: blue;">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">case</span>&nbsp;<span style="color: maroon;">'&gt;'</span>:r.push(<span style="color: maroon;">'&amp;gt;'</span>);<span style="color: blue;">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">default</span>:r.push(c);}}
&nbsp;&nbsp;<span style="color: blue;">return</span>&nbsp;r.join(<span style="color: maroon;">''</span>);
};

<span style="color: blue;">var</span>&nbsp;map=<span style="color: blue;">function</span>(f,v){<span style="color: blue;">var</span>&nbsp;L=v.length,r=[];<span style="color: blue;">for</span>(<span style="color: blue;">var</span>&nbsp;i=0;i&lt;L;i++)r.push(f(v[i]));<span style="color: blue;">return</span>&nbsp;r;};

(<span style="color: blue;">function</span>(){
&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;blk;

&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;CExtendedBasicBlock&nbsp;=&nbsp;<span style="color: blue;">function</span>(name,&nbsp;previous,&nbsp;next){
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">this</span>.Address&nbsp;=&nbsp;<span style="color: maroon;">''</span>;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">this</span>.Code&nbsp;=&nbsp;[];
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">this</span>.Name&nbsp;=&nbsp;name;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">this</span>.Previous&nbsp;=&nbsp;previous;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">this</span>.Next&nbsp;=&nbsp;next;
&nbsp;&nbsp;};

&nbsp;&nbsp;<span style="color: blue;">while</span>(<span style="color: blue;">true</span>)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">if</span>(WScript.StdIn.AtEndOfStream)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;strSourceLine&nbsp;=&nbsp;WScript.StdIn.ReadLine().replace(/(^\s+)|(\s+$)/g,&nbsp;<span style="color: maroon;">''</span>);
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">if</span>(!strSourceLine)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">continue</span>;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">if</span>(strSourceLine.match(/.*:$/))
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;blk&nbsp;=&nbsp;<span style="color: blue;">new</span>&nbsp;CExtendedBasicBlock(strSourceLine.slice(0,&nbsp;-1));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EBB.push(blk);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">else</span>
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;blk.Address&nbsp;=&nbsp;blk.Address&nbsp;||&nbsp;strSourceLine.match(/^[^\s]+/)[0];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;blk.Code.push(strSourceLine.replace(/[^\s]*\s+/,&nbsp;<span style="color: maroon;">''</span>).replace(/[^\s]*\s+/,&nbsp;<span style="color: maroon;">''</span>));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
})();

EBB&nbsp;=&nbsp;EBB.sort(<span style="color: blue;">function</span>(x,&nbsp;y){&nbsp;<span style="color: blue;">return</span>&nbsp;x.Address&nbsp;==&nbsp;y.Address&nbsp;?&nbsp;0&nbsp;:&nbsp;x.Address&nbsp;&gt;&nbsp;y.Address&nbsp;?&nbsp;1&nbsp;:&nbsp;-1;&nbsp;});
<span style="color: blue;">for</span>(<span style="color: blue;">var</span>&nbsp;i&nbsp;=&nbsp;1;&nbsp;i&nbsp;&lt;&nbsp;EBB.length;&nbsp;i++)
{
&nbsp;&nbsp;EBB[i].Previous&nbsp;=&nbsp;EBB[i&nbsp;-&nbsp;1];
&nbsp;&nbsp;EBB[i].Previous.Next&nbsp;=&nbsp;EBB[i];
}

WScript.Echo(<span style="color: maroon;">'&lt;DirectedGraph&nbsp;Background="#FFFFFF"&nbsp;GraphDirection="TopToBottom"&nbsp;xmlns="https://schemas.microsoft.com/vs/2009/dgml"&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&lt;Nodes&gt;'</span>);
map(<span style="color: blue;">function</span>(blk){
&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;content&nbsp;=&nbsp;hypertext(blk.Name&nbsp;+&nbsp;<span style="color: maroon;">'&nbsp;('</span>&nbsp;+&nbsp;blk.Address&nbsp;+&nbsp;<span style="color: maroon;">')'</span>)&nbsp;+&nbsp;<span style="color: maroon;">'&amp;#xD;&amp;#xA;'</span>;
&nbsp;&nbsp;map(<span style="color: blue;">function</span>(instruction){
&nbsp;&nbsp;&nbsp;&nbsp;content&nbsp;+=&nbsp;<span style="color: maroon;">'&amp;#xD;&amp;#xA;'</span>&nbsp;+&nbsp;hypertext(instruction);
&nbsp;&nbsp;},&nbsp;blk.Code);
&nbsp;&nbsp;WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&lt;Node&nbsp;Id="'</span>&nbsp;+&nbsp;hypertext(blk.Name)&nbsp;+&nbsp;<span style="color: maroon;">'"&nbsp;Label="'</span>&nbsp;+&nbsp;content&nbsp;+&nbsp;<span style="color: maroon;">'"&nbsp;/&gt;'</span>);
},&nbsp;EBB);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&lt;/Nodes&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&lt;Links&gt;'</span>);
map(<span style="color: blue;">function</span>(blk){
&nbsp;&nbsp;map(<span style="color: blue;">function</span>(instruction){
&nbsp;&nbsp;&nbsp;&nbsp;map(<span style="color: blue;">function</span>(x){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">var</span>&nbsp;idx&nbsp;=&nbsp;instruction.indexOf(x.Name);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;idx&nbsp;=&nbsp;idx&nbsp;&gt;=&nbsp;0&nbsp;?&nbsp;instruction.charAt(idx&nbsp;+&nbsp;x.Name.length)&nbsp;:&nbsp;-1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">if</span>(idx&nbsp;==&nbsp;<span style="color: maroon;">''</span>&nbsp;||&nbsp;idx&nbsp;==&nbsp;<span style="color: maroon;">'&nbsp;'</span>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&lt;Link&nbsp;Source="'</span>&nbsp;+&nbsp;hypertext(blk.Name)&nbsp;+&nbsp;<span style="color: maroon;">'"&nbsp;Target="'</span>&nbsp;+&nbsp;hypertext(x.Name)&nbsp;+&nbsp;<span style="color: maroon;">'"&nbsp;/&gt;'</span>);
&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;EBB);
&nbsp;&nbsp;},&nbsp;blk.Code);
&nbsp;&nbsp;<span style="color: blue;">if</span>(blk.Next&nbsp;&amp;&amp;&nbsp;!(blk.Code[blk.Code.length&nbsp;-&nbsp;1].match(/^[^\s]+/)[0]&nbsp;<span style="color: blue;">in</span>&nbsp;{jmp:&nbsp;0,&nbsp;ret:&nbsp;0}))
&nbsp;&nbsp;&nbsp;&nbsp;WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&lt;Link&nbsp;Category="FallThrough"&nbsp;Source="'</span>&nbsp;+&nbsp;hypertext(blk.Name)&nbsp;+&nbsp;<span style="color: maroon;">'"&nbsp;Target="'</span>&nbsp;+&nbsp;hypertext(blk.Next.Name)&nbsp;+&nbsp;<span style="color: maroon;">'"&nbsp;/&gt;'</span>);
},&nbsp;EBB);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&lt;/Links&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&lt;Styles&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&lt;Style&nbsp;TargetType="Node"&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Setter&nbsp;Property="FontFamily"&nbsp;Value="Consolas"&nbsp;/&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Setter&nbsp;Property="FontSize"&nbsp;Value="11"&nbsp;/&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Setter&nbsp;Property="Background"&nbsp;Value="White"&nbsp;/&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Setter&nbsp;Property="NodeRadius"&nbsp;Value="2"&nbsp;/&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Style&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&lt;Style&nbsp;TargetType="Link"&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Condition&nbsp;Expression="HasCategory(\'FallThrough\')"&nbsp;/&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Setter&nbsp;Property="Background"&nbsp;Value="Red"&nbsp;/&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Setter&nbsp;Property="Stroke"&nbsp;Value="Red"&nbsp;/&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Style&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&nbsp;&nbsp;&lt;/Styles&gt;'</span>);
WScript.Echo(<span style="color: maroon;">'&lt;/DirectedGraph&gt;'</span>);
</pre>
<hr width="100%" style="width: 100%;" />
<p>Notes:</p>
<ol>
<li>This script cannot generate 100% accurate control flow diagram, you will have to do further analysis (e.g. <strong>jmp eax</strong>).</li>
<li>I haven't got a chance to test under WOA (ARM32), so I leave it as a homework for our readers.</li>
</ol>
<p>Enjoy:)</p>]]></content:encoded>
    </item>
  </channel>
</rss>