<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>KoroIRC Developer Blog &#187; Reverse Engineering</title>
	<atom:link href="http://blog.koroirc.com/category/reverse-engineering/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.koroirc.com</link>
	<description>Thoughts while coding.</description>
	<lastBuildDate>Tue, 06 Jul 2010 13:30:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>How to bring back regular window captions in Windows Live Messenger 9</title>
		<link>http://blog.koroirc.com/2009/01/how-to-bring-back-regular-window-captions-in-windows-live-messenger-9/</link>
		<comments>http://blog.koroirc.com/2009/01/how-to-bring-back-regular-window-captions-in-windows-live-messenger-9/#comments</comments>
		<pubDate>Wed, 14 Jan 2009 17:27:54 +0000</pubDate>
		<dc:creator>Koro</dc:creator>
				<category><![CDATA[Reverse Engineering]]></category>

		<guid isPermaLink="false">http://blog.koroirc.com/?p=63</guid>
		<description><![CDATA[I hate skinned applications. Hate them, with a burning passion. The only thing I hate more are skinned applications that &#8220;try&#8221; to look native but spectacularly fail on anything else but the default theme.
Now, it ain&#8217;t so bad when applications restrict that to their client area. It is still useless and disrespectful of my settings, [...]]]></description>
			<content:encoded><![CDATA[<p>I hate skinned applications. Hate them, with a burning passion. The only thing I hate more are skinned applications that &#8220;try&#8221; to look native but spectacularly fail on anything else but the default theme.</p>
<p>Now, it ain&#8217;t so bad when applications restrict that to their client area. It is still useless and disrespectful of my settings, but at least it&#8217;s contained. But more and more apps take bolder steps at spitting in the face of my settings — hint: I set them that way <i>for a reason</i>, because I like it that way — and, sadly, Microsoft is no exception to this.</p>
<p>Windows Live Messenger is a big culprit in this case. Up until Wave 3, even though it defaulted to using custom window captions, a simple &#8220;Show the menu bar&#8221; would bring the regular ones back. But, as it seems to be the fashion these days, that possibility was <b>removed</b>. That, and they also now impose ClearType usage, even if you explicitly disabled it. Not that important now, since LCD screens are everywhere, but <a href="/blogdata/old_crt_monitor.jpg">my old CRT monitor</a> only broke 6 months ago.</p>
<p>But if you played a little with WLM9, you notice it reverts to regular window captions in certain cases, like if you maximize a window. A little poking around in WinDbg quickly shows that it&#8217;s just using window regions to do its bidding. That, along with a friend that showed me that under Aero Glass, it actually just lets the window manager do its job and uses regular captions, was more than enough to tip me off that something could be done very easily about this problem.</p>
<p>My first try was to try and block the <code>SetWindowRgn</code> call outright. I basically overwrite the code for that function in the process&#8217; memory with the assembly equivalent of this:</p>
<blockquote><pre>
int HookSetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw)
{
    if (hRgn)
        DeleteObject(hRgn);
    return 1;
}
</pre>
</blockquote>
<p>There are multiple problems with this approach. First, since WLM hides the whole caption and window borders, it has to handle <code>WM_NCHITTEST</code> in order to allow window resizing from within its client area. Since it also still thinks the caption and borders are hidden, it does not handle these cases, and as such, returns <code>HTBOTTOM</code> when the cursor is on the window caption. Also, the theming system in <code>UxTheme.dll</code> also calls this function &mdash; why it does not call <code>NtUserSetWindowRgn</code> directly is beyond me &mdash; in order to have those round window corners, and this &#8220;fix&#8221; disables that too.</p>
<p>My second and final solution came upon noticing that when WLM itself decides to show these captions, they work properly, and also the pseudo-caption inside the client area disapprears, too. If there was a way to trick WLM into thinking one of the &#8220;show the caption&#8221; conditions is met, it would by itself comply and show it without additional work. I first tried to hook the <code>IsZoomed</code> function directly to make it always return <code>TRUE</code>, but again it caused problems with <code>UxTheme.dll</code>.</p>
<p>I started by looking for calls to <code>SetWindowRgn</code> in all of WLM&#8217;s binaries. One of these files is <code>UxCore.dll</code>. Now, the fun part with exporting C++ classes or functions directly with <code>__declspec(dllexport)</code> is that all the decorated names are kept intact, which is <i>very</i> handy for reverse engineering like this since they contain full parameters and return type information. It did not take much time to find the <code>UXFramelessManager</code> class, which is responsible for hiding or showing the window caption, and handling everything that is associated with it. That class has a method called <code>UpdateFrame</code>, which does the work of determining if a window region needs to be set, and setting or clearing it as needed.</p>
<p>The <code>UpdateFrame</code> method checks that at least one of these three conditions is met:</p>
<ul>
<li>The window is maximized</li>
<li>Aero Glass is enabled</li>
<li>High Contrast Mode is enabled</li>
</ul>
<p>If that is the case, it will set a <code>NULL</code> region for the window and not do any custom handling of the <code>WM_NCHITTEST</code> message. So, I figured, let&#8217;s make it think the window is always maximized! The code that does this check is:</p>
<blockquote><pre>
7033e028  push  dword ptr [esi+8]
7033e02b  shr   eax,13h
7033e02e  and   al,1
7033e030  mov   byte ptr [ebp-1],al
7033e033  call  dword ptr [__imp__IsZoomed@4]
</pre>
</blockquote>
<p>The instruction at <code>7033e028</code> pushes the <code>HWND</code> of the window on the stack. The next three instructions are interleaved code that does something else, probably due to agressive compiler optimization settings, then the call is done at <code>7033e033</code>. So all we need to do is to change the code to just always assume <code>IsZoomed</code> returned <code>TRUE</code>, padding as appropriate with <code>NOP</code>s:</p>
<blockquote><pre>
7033e028  nop
7033e029  nop
7033e02a  nop
7033e02b  shr   eax,13h
7033e02e  and   al,1
7033e030  mov   byte ptr [ebp-1],al
7033e033  mov   eax,1
7033e038  nop
</pre>
</blockquote>
<p>All that was needed was to patch that new stream of instructions at the right file offset in <code>UxCore.dll</code>:</p>
<blockquote><p><code>0003D428 -> 90 90 90 C1 E8 13 24 01 88 45 FF B8 01 00 00 00 90</code></p></blockquote>
<p>Upon starting WLM, I had my window captions indeed:</p>
<p><a href="/blogdata/wlm9_conversation_with_frame.png"><img src="/blogdata/wlm9_conversation_with_frame_preview.png" width="410" height="150" alt="WLM9 conversation window with regular window caption" /></a></p>
<p>(Yes, I went back to Windows Classic, despite my <a href="/2008/08/three-good-black-uxtheme-skins/">claims to the contrary</a>.)</p>
<p>There is still a bug with this though. It it not apparent under Windows Classic, but <code>UxTheme.dll</code> causes problems again, albeit a minor one this time. Basically, <code>UpdateFrame</code> will still call <code>SetWindowRgn</code> on window creation with a <code>NULL</code> region, clearing the one set by <code>UxTheme.dll</code>. This is the code that does it:</p>
<blockquote><pre>
7033e141  push   1
7033e143  push   ebx
7033e144  push   dword ptr [esi+8]
7033e147  call   dword ptr [__imp__SetWindowRgn@12]
</pre>
</blockquote>
<p>Note that <code>EBX</code> is zeroed out at the beginning of the function, so this code is the equivalent of:</p>
<blockquote><pre>
SetWindowRgn(m_hWnd,NULL,TRUE);
</pre>
</blockquote>
<p>All we have to do is to replace that whole code sequence with <code>NOP</code>s again. I won&#8217;t present the code here, but directly the bytes to patch in the file:</p>
<blockquote><p><code>0003D541 -> 90 90 90 90 90 90 90 90 90 90 90 90</code></p></blockquote>
<p>Once this is patched, WLM will have regular window captions, with no glitch (that I found yet). It is sad though, that I had to resort to patching code for such a trivial matter, especially that older versions of WLM allowed this, so they actually had to <b>remove</b> code to make it not-work&#8230;</p>
<p>All code addresses and listings comes from <code>UxCore.dll</code> version 14.0.8050.1202 in the WLM installation directory. Make sure you have that exact same version before patching the file, of course.</p>
<p><b>Update</b>: This also works with <code>UxCore.dll</code> version 14.0.8064.206, as none of the offsets have changed.</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-5247335033190484";
google_ad_slot = "8828688937";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.koroirc.com/2009/01/how-to-bring-back-regular-window-captions-in-windows-live-messenger-9/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Getting around the manifest check in the C Runtime DLL</title>
		<link>http://blog.koroirc.com/2008/09/getting-around-the-manifest-check-in-the-c-runtime-dll/</link>
		<comments>http://blog.koroirc.com/2008/09/getting-around-the-manifest-check-in-the-c-runtime-dll/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 20:47:33 +0000</pubDate>
		<dc:creator>Koro</dc:creator>
				<category><![CDATA[Reverse Engineering]]></category>

		<guid isPermaLink="false">http://blog.koroirc.com/?p=62</guid>
		<description><![CDATA[Today&#8217;s article is again about my &#8220;archnemesis&#8221;, the Visual Studio 2005/2008 CRT. As I mentioned in a previous article, this CRT will refuse to load if it&#8217;s not loaded with a manifest, and today I document how it checks that, and then, how to bypass it. This can be very useful, for example, to get [...]]]></description>
			<content:encoded><![CDATA[<p>Today&#8217;s article is again about my &#8220;archnemesis&#8221;, the Visual Studio 2005/2008 CRT. As I mentioned in a <a href="/2008/06/visual-cpp-woes/">previous article</a>, this CRT will refuse to load if it&#8217;s not loaded with a manifest, and today I document how it checks that, and then, how to bypass it. This can be very useful, for example, to get MSVCR80.DLL to load under WINE.</p>
<p>The core of the manifest checking is in the <code>_check_manifest</code> function, which is located in <code>crtlib.c</code> in the CRT source. As the name suggests, this code is only linked in when compiling a DLL version of the CRT.</p>
<p>Here is what the code does:</p>
<ol>
<li>First, it checks for the presence of the <code>FindActCtxSectionStringW</code> function in <code>KERNEL32.DLL</code>. If this step fails (i.e. <code>GetProcAddress</code> returns <code>NULL</code>), then it assumes that the OS it&#8217;s running on does not support Fusion, and returns with success.</li>
<li>Then, it checks if both of <code>MSCOREE.DLL</code> and <code>PGORT90.DLL</code> are loaded in the process&#8217; address space, and if yes, assumes it was loaded for instrumentation and returns success.</li>
<li>It then retrieves the path of where it was loaded and of the <code>system32</code> directory.</li>
<li>When the paths are retrieved, it checks explicitly that it wasn&#8217;t loaded from <code>system32</code>. If it was loaded from there, it immediately returns a failure.</li>
<li>Then, it checks the current activation context with <code>FindActCtxSectionString</code> to check if it was referenced in the manifest. If that isn&#8217;t the case, it returns a failure.</li>
<li>It then makes sure it was loaded from under the <code>WinSxS</code> folder in the Windows directory by doing a string compare of that path and its own path. If that is the case, it returns with success.</li>
<li>This last check happens only if the previous check failed. It will try to find a file called <code>Microsoft.VC80.CRT.manifest</code> (or <code>Microsoft.VC80.DebugCRT.manifest</code> if it&#8217;s the debug version) in the same folder from which it was loaded, and if found, will return success.</li>
<li>If it comes here, it assumes that it was wrongfully loaded and returns a failure.
</li>
</ol>
<p>Note that over the course of these checks, it uses multiple fixed-size string buffers. The one that is used to retrive the path of the Windows and the <code>system32</code> directories is <code>MAX_PATH</code> in size, whereas the others are 8000 characters in size. If any of these buffers overflow at any time, it will just bail out of the checks and return success.</p>
<p>Also, WINE does have an implementation of activation contexts, found <a href="http://source.winehq.org/source/dlls/kernel32/actctx.c">here</a> (<code>KERNEL32</code> wrappers) and <a href="http://source.winehq.org/source/dlls/ntdll/actctx.c">here</a> (actual implementation in <code>NTDLL</code>). Except for some reason, it fails to go grab <code>MSVCR80.DLL</code> from the <code>WinSxS</code> directory, instead returning with status 0xc0000135. It&#8217;s not that the functionality is not there however, as a quick look into WINE&#8217;s source (in <a href="http://source.winehq.org/source/dlls/ntdll/loader.c"><code>loader.c</code></a> to be exact) shows a neat little function called <code>find_actctx_dll</code> that gets called from <code>find_dll_file</code>.</p>
<p>So, now that you understand how it works, the solution to bypass it becomes very simple.</p>
<p>You can take the long route and recompile your own version of the CRT with the <code>_check_manifest</code> function dummyfied. A quick look at some installed apps on my computer shows that a few apps do it. Firefox has its <code>MOZCRT19.DLL</code> and Winamp has <code>NSCRT.DLL</code>, although the latter is an older version of the CRT.</p>
<p>The previous solution is quite complicated for such a simple detail. Also, if you wish to redistribute the DLL with your application, you have to name it something else than <code>MSVCR80.DLL</code>. So you still have to redistribute it even if you got rid of the manifest check.</p>
<p>Follow me here for a <i>much</i> quickier-and-dirtier hack. Basically, you just have to patch 5 bytes in the DLL file to disable the manifest checking. <b>Disclaimer: I don&#8217;t think the EULA allows you to do that, and it would not be a good idea to redistribute those patched DLLs. Do it at your own risk.</b></p>
<p>I have tested with versions 8.0.50727.1433 and 8.0.50727.3053 of <code>MSVCR80.DLL</code> and it worked well. After that, I was able to drop them into my <code>system32</code> directory in a WINE install and they would work flawlessly. So, you need to patch the following bytes at the following file offset:</p>
<blockquote><p><code>00001D76 -> B8 01 00 00 00 C3</code></p></blockquote>
<p>This effectively turns the content of the <code>_check_manifest</code> function into nothing more than a <code>return TRUE</code>.</p>
<p>I hope that this goes to show again that using manifests for the CRT was a <i>really bad</i> idea. It just pushes more people to either statically link to it, compile their own or try to find another way to get over that restriction, all of which are not really beneficial in the long term. It defeats the purpose of DLLs, which was to share code between processes.</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-5247335033190484";
google_ad_slot = "8828688937";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.koroirc.com/2008/09/getting-around-the-manifest-check-in-the-c-runtime-dll/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
