<?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; General</title>
	<atom:link href="http://blog.koroirc.com/category/programming/general/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.koroirc.com</link>
	<description>Thoughts while coding.</description>
	<lastBuildDate>Sun, 23 Jan 2011 07:56:45 +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>Trimming executables Part 1: Getting rid of the C runtime</title>
		<link>http://blog.koroirc.com/2008/09/trimming-executables-part-1-getting-rid-of-the-c-runtime/</link>
		<comments>http://blog.koroirc.com/2008/09/trimming-executables-part-1-getting-rid-of-the-c-runtime/#comments</comments>
		<pubDate>Tue, 09 Sep 2008 21:52:20 +0000</pubDate>
		<dc:creator>Koro</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.koroirc.com/?p=32</guid>
		<description><![CDATA[In a previous post I mentioned my problems with the Visual C Runtimes past version 6.0. This post is post 1 of n, with n having a high probability of being 2, on how to trim executable / download size. I will explain how to get rid of the beast that is the CRT, while [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="/2008/06/visual-cpp-woes/">previous post</a> I mentioned my problems with the Visual C Runtimes past version 6.0. This post is post 1 of <i>n</i>, with <i>n</i> having a high probability of being 2, on how to trim executable / download size. I will explain how to get rid of the beast that is the CRT, while retaining functionality.</p>
<h3>The simplest way: Don&#8217;t use it altogether</h3>
<p>For a very small project, most of the time, the only reason you actually use the CRT, is because you don&#8217;t know that you can <i>not</i> use it. But you can tell the compiler that you don&#8217;t want it, and here&#8217;s how.</p>
<p>The first thing to do is to turn on the <code>/Zl</code> (omit default library names) compiler option in your project / makefile. I find this cleaner than using the <code>/NODEFAULTLIB</code> linker option, because it only affects the CRT default libraries. Anyway, at this point, you&#8217;ve already done it, the CRT will not be linked anymore in your binary.</p>
<p>But suddenly, your project will not link anymore. One of the first reasons for that is because the CRT inserts its own entry point and the linker expects to find it, but since you have removed the CRT you&#8217;ll have to supply your own versions of these. Hopefully, the names of the entry points don&#8217;t change much, it&#8217;s just a matter of picking the right one:</p>
<blockquote><pre>
// __DllMainCRTStartup@12
extern "C" BOOL WINAPI _DllMainCRTStartup(HINSTANCE, DWORD, LPVOID);
// _WinMainCRTStartup
extern "C" __declspec(noreturn) void __cdecl WinMainCRTStartup(void);
// _mainCRTStartup
extern "C" __declspec(noreturn) void _cdecl mainCRTStartup(void);
</pre>
</blockquote>
<p>You&#8217;ll instantly notice that the <code>WinMain</code> and <code>main</code> entry points are declared with <code>__declspec(noreturn)</code> and have a <code>void</code> return type. That is not totally true. You <i>can</i> return from that function, at least in Windows NT, and <code>BaseProcessStart</code> will happily terminate the thread. But <b>only</b> the thread. That is why I prefer to end these functions with a call to <code>ExitProcess</code> instead.</p>
<p>As for the <code>DllMain</code> entry points, there is a big probability that it won&#8217;t be needed. The CRT absolutely needs it to do some initialization, but if you&#8217;re like me, and try to do as little as possible in this function, you probably just have a call to <code>DisableThreadLibraryCalls</code> and then return <code>TRUE</code>. If that is the case, you can use the <code>/NOENTRY</code> linker option, which will link the DLL with no entry point at all.</p>
<p>Next, you will encounter linking errors because several &#8220;special&#8221; CRT symbols are referenced by code that is added by the compiler. Hopefully, these are easy to weed out:</p>
<table>
<thead>
<tr>
<th>Symbol reference</th>
<th>How to get rid of it</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>___security_cookie</code><br />
<code>@__security_check_cookie@4</code>
</td>
<td>Setting the <code>/GS-</code> compiler option. (VS: set &#8220;Buffer Security Check&#8221; to No)</td>
</tr>
<tr>
<td>
<code>@_RTC_CheckStackVars@8</code><br />
<code>__RTC_CheckEsp</code><br />
<code>__RTC_Shutdown</code><br />
<code>__RTC_InitBase</code>
</td>
<td>Removing all the <code>/RTC<i>xx</i></code> compiler option. (VS: set &#8220;Basic Runtime Checks&#8221; to Default)</td>
</tr>
<tr>
<td>
<code>__chkstk</code>
</td>
<td>Not using more than 4k of stack variables.</td>
</tr>
<tr>
<td>
<code>_memset</code><br />
<code>_memcpy</code>
</td>
<td>Not using the assignment operator to initialize structs inside functions, or to copy between structs.</td>
</tr>
</tbody>
</table>
<p>Note that is you are doing operations on <code>__int64</code>&#8217;s or using structured exception handlers (SEH), you <b>will</b> need the CRT. More on this later.</p>
<p>The last part on getting rid of the CRT is to replace CRT calls to equivalent API calls. I have put together a quick little table mapping the must used functions:</p>
<table>
<thead>
<tr>
<th>CRT function</th>
<th>Win32 API function</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>str<i>xxx</i></code></td>
<td><code>lstr<i>xxx</i></code></td>
</tr>
<tr>
<td><code>sprintf</code></td>
<td><code>wsprintf</code></td>
</tr>
<tr>
<td><code>vsprintf</code></td>
<td><code>wvsprintf</code></td>
</tr>
<tr>
<td><code>malloc</code></td>
<td><code>HeapAlloc</code></td>
</tr>
<tr>
<td><code>realloc</code></td>
<td><code>HeapReAlloc</code></td>
</tr>
<tr>
<td><code>free</code></td>
<td><code>HeapFree</code></td>
</tr>
</tbody>
</table>
<p>I&#8217;m not going to list every function out there, but the point is, for the most simplistic functions of the CRT, there is often a straightforward Win32 API equivalent. When there is not, it is usually simple to code one (such as <code>atol</code>). But, as you can see, as soon as the project grows a little, it becomes quickly unusable in practice.</p>
<p>Also, note that <code>wsprintf</code> and <code>wvsprintf</code> <a href="http://blogs.msdn.com/oldnewthing/archive/2008/03/10/8080067.aspx">do not support floating point</a>.</p>
<h3>The fraught-with-peril way: Use it a little.</h3>
<p>The problem with the CRT is the lengthy initialization code it adds to an EXE, even when linked dynamically. It seems to want to call every <code>KERNEL32</code> API under the sun, even if in the end you will just use it for a string compare or two.</p>
<p>But sometimes you absolutely need to link in some stand-alone code from the CRT, such as the <code>__int64</code> support code (<code>__<i>x</i>llmul</code> and <code>__<i>x</i>lldiv</code>, respectively). One quick way is to skip the initialization code by redirecting the entry point with the <code>/ENTRY</code> linker option. That way, execution starts right to your code, and (in your release build at least) the CRT initialization code won&#8217;t be linked in at all.</p>
<p>I have to take a break and post a disclaimer here: <b>skipping the CRT initialization code is dangerous. Lots of CRT functions, even simples ones as <code>memcpy</code> or <code>strcmp</code>, reference global CRT variables which need to be initialized. Use this at your own risk, and in case of doubt, double-check the CRT source code.</b></p>
<p>This therefore implies that you can&#8217;t really call CRT functions anyway, apart from standalone ones. So the same rules as if you were not using the CRT at all apply, except for the fact that accidentally referencing a CRT symbol will be much harder to spot because it won&#8217;t cause a link error anymore. So, obviously, this is not a way that I often use.</p>
<h3>The safest way: Use another CRT</h3>
<p>This is the method I use for KoroIRC. Basically, this is using another set of header files and library files when compiling the program.</p>
<p>I found that the safest way to do it is not to change VS&#8217;s library and include paths, but rather to build my release binaries using a special script, and build my debug builds using the regular CRT with the <code>/MT</code> compiler option. I don&#8217;t care if my debug binaries weigh 1MB and have tons of dead code in them, as I never ship them.</p>
<p>The trick is to make a little batch file like this:</p>
<blockquote><pre>
@echo off
set INCLUDE=<i>altcrt\include</i>;%INCLUDE%
set LIB=<i>altcrt\lib</i>;%LIB%
devenv <i>solution.sln</i> /rebuild "Release^|Win32" /useenv
</pre>
</blockquote>
<p>Replace <i>altcrt</i> with the proper path to your alternate CRT, run this in a Visual Studio Command Prompt, and let it churn.</p>
<p>I will now finish this post by presenting two alternate CRT&#8217;s you can use.</p>
<h4>Lightweight but undocumented: NTDLL&#8217;s mini-CRT</h4>
<p>A little-known fact is that <code>NTDLL.DLL</code> embeds its own CRT, probably for use by operating system components and native applications. Of course, you won&#8217;t find complex functions such as <code>rand</code> or <code>time</code> but all string functions, and more importantly, SEH support functions, are there. Since it is always loaded in all processes anyway, it costs nothing to use, except Windows 9x compatibility of course.</p>
<p>To use it, you&#8217;ll need the <a href="http://www.microsoft.com/whdc/devtools/ddk/default.mspx">Windows DDK</a>, which includes all the header files and library files needed in order to import from <code>NTDLL</code>. However, in order to be able to use it with PSDK-compiled applications, you will need to extract only the right files, that is, the whole contents of the <code>inc\crt</code> directory and the <code>lib\wxp\i386\ntdll.lib</code> file for x86 or <code>lib\wnet\amd64\ntdll.lib</code> for x64. Then it is only a matter of using them with the little script I presented earlier.</p>
<h4>Harder but safer: Good old MSVCRT</h4>
<p>In order to do that, you will need two things: an old Visual Studio 6.0 CD, and a copy of the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=D8EECD75-1FC4-49E5-BC66-9DA2B03D9B92&#038;displaylang=en">Windows Server 2003 SP1 Platform SDK</a> that was released just before Visual Studio 2005.</p>
<p>On the Visual Studio 6.0 CD, you will be able to extract the VS6 CRT headers from the <code>VC98\INCLUDE</code> directory, and the libraries from the <code>VC98\LIB</code> directory. The only problem is that they are mixed with Platform SDK files, so you&#8217;ll have to pick them one by one. Luckily, I have thown together <a href="/blogdata/vs6crt_x86.txt">this list</a> of what files belong to the CRT.</p>
<p>The Platform SDK release linked above is special because it contailed a prerelease version of the x64 compiler that came with Visual Studio 2005. As such it also contains everything necessary in order to link with Windows x64&#8217;s <code>MSVCRT.DLL</code>. Hopefully, this time, the headers are in their own subdirectory, <code>Include\crt</code>. The libraries are in <code>Lib\amd64</code> and the PDB files are in <code>NoRedist\Win64\AMD64</code>.</p>
<p>With all this in hand, you should be able to link with <code>MSVCRT.DLL</code> on x86 and x64 using the script.</p>
<h3>Conclusion</h3>
<p>With these methods, it is possible to reduce either the executable size or the download size (for not having to redistribute more recent CRTs) for your program. Of course, this only applies if you program mostly in C, because when you start using C++ or worse, the STL, these approaches stop working well.</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/trimming-executables-part-1-getting-rid-of-the-c-runtime/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Visual C++ woes</title>
		<link>http://blog.koroirc.com/2008/06/visual-cpp-woes/</link>
		<comments>http://blog.koroirc.com/2008/06/visual-cpp-woes/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 19:21:28 +0000</pubDate>
		<dc:creator>Koro</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.koroirc.com/?p=5</guid>
		<description><![CDATA[It seems that with every new version of Visual Studio, Microsoft does something to alienate its users in regard to the C runtime, compiler and/or linker.
Back in the days of Visual Studio 6.0 (still, in my opinion, the best version to have ever existed, despite its age1), things were simple. There were no useless compiler [...]]]></description>
			<content:encoded><![CDATA[<p>It seems that with every new version of Visual Studio, Microsoft does something to alienate its users in regard to the C runtime, compiler and/or linker.</p>
<p>Back in the days of Visual Studio 6.0 (still, in my opinion, the best version to have ever existed, despite its <a href="#p5footer">age<sup>1</sup></a>), things were simple. There were no useless compiler flags to disable in every project, and the C runtime library was <code>MSVCRT.DLL</code>, which was distributed with the operating system. Actually, <a href="http://blogs.msdn.com/oldnewthing/archive/2008/01/11/7065021.aspx">this is not fully the case</a>, but <code>MSVCRT.DLL</code> has always been there due to the strong reliance of operating system components on it. It was therefore very simple to create small applications and to distribute them.</p>
<p>Then came Visual Studio 7.0, a.k.a. Visual Studio .NET 2002. Suddenly, someone somewhere decided that <code>MSVCRT.DLL</code> belonged &#8220;to the operating system&#8221; and not to Visual C++, and that therefore, its C runtime should now reside in a new, separate, redistributable DLL, <code>MSVCR70.DLL</code>. So suddenly, there was no real incentive to compile with <code>/MD</code>, as it would create the need to distribute a ~330k DLL along with the application. Personally, I would have remained with Visual Studio 6.0, but in the latest Platform SDK, which at the time was the then-new Windows XP SP2 Platform SDK, suddenly the format of the <code>.lib</code> files was just slightly incompatible with the aging linker.</p>
<p>I think it was in Visual Studio 7.1, which, by the way, I have never used personally, that the damned <code>/GS</code> compiler flag was introduced. What a better way to inflate code size uselessly than to add a prolog and epilog in every function that checks for a &#8220;security cookie&#8221;? Personally, I never allocate buffers and strings on the stack anyway, and when I do, I very strictly validate their length, so the protection offered by this flag is quite nil to me.</p>
<p>Then, in Visual Studio 8.0 (2005), somebody sure got angered at all the developers that were copying <code>MSVCR7x.DLL</code> around freely, so it was spoken: <em>&#8220;From now on, the C runtime will only be installed by our own installer&#8221;</em>. So, to install <code>MSVCR80.DLL</code> on a system, it&#8217;s not as simple anymore as just including the file in your installer and dumping it in the application&#8217;s directory during installation, you have to have a freaking <em>manifest</em> to even be able to load it! And of course, since this uses Fusion, the files need to be installed into specific subdirectories of the <code>WinSxS</code> directory, and therefore, the only &#8220;installer&#8221; qualified to do it correctly is the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=32bc1bee-a3f9-4c13-9c99-220b62a191ee&amp;displaylang=en">Visual C++ 2005 Reditributable Package</a>, which weighs a whopping 2.6 MB! Quite a lot for what would have been an application of a few hundred kilobytes, now isn&#8217;t it? And to make sure you don&#8217;t <em>ever</em> try to bypass this &#8220;rule&#8221; and copy it in the application&#8217;s directory, the DLL does a check at startup to see if it was loaded &#8220;correctly&#8221;, and, if not, refuses to load.</p>
<p>Now, it isn&#8217;t that bad, I found a workaround to that (which I will explain in a future post), so I got used to that version and grew to like it.</p>
<p>I then recently got Visual Studio 9.0 (2008) and installed it. Not that it was really useful, since I already had the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=9BE1FC7F-0542-47F1-88DD-61E3EF88C402&amp;displaylang=en">Windows Vista (February CTP) SDK</a> installed over my Visual Studio 2005 installation, but I installed it just to be using the latest version. Actually, it&#8217;s not so bad, it&#8217;s even an improvement over the previous version. The <code>/DYNAMICBASE</code> and <code>/NXCOMPAT</code> flags are enabled by default (<a href="http://blog.koroirc.com/2008/06/migrating-a-project-from-vs2005-to-vs2008-disables-aslr/">unless you migrate your project from Visual Studio 2005</a>), and the operating system and subsystem version number in the PE headers were finally bumped to being set to 5.0 by default. That last point is also the frustrating point though. It was probably done that way because version 9.0 of the C runtime wouldn&#8217;t run correctly on anything lower than 5.0 anyway, but if you are not using the C runtime at all, there is no reason to set them to 5.0, other than artificially restricting the versions of Windows your program can run on. So, you might say, <em>&#8220;let&#8217;s just tell the linker to set them back to 4.0 then&#8221;</em>. Except, when you try to do that, you get this lovely little error:</p>
<blockquote><p><code>LINK : warning LNK4010: invalid subsystem version number 4.0; default subsystem version assumed</code></p></blockquote>
<p>Yes, you guessed right. The linker <em>won&#8217;t</em> let you set 4.0 as the subsystem version number. It looks quite like an useless restriction put there just to annoy some of us who still support, or just want to code for Windows 9x/NT4.</p>
<p>But as always, something like that isn&#8217;t enough to stop me, I created my own workaround:</p>
<p><a href="http://www.korosoft.net/programs/snapshot/pever.png"><img src='http://www.korosoft.net/programs/snapshot/pever_preview.png'/></a></p>
<p>The fact that an executable linked with Visual Studio 2008, but not using its C runtime, runs fine on Windows NT 4.0 afterwards proves how much of an artificial restriction that is.</p>
<p>The tool is up for download <a href="http://www.korosoft.net/programs/pever.rar">here</a>.</p>
<p><a name="p5footer"></a></p>
<ol>
<li><small>It&#8217;s not so bad once you install <a href="http://www.wndtabs.com/">WndTabs</a> and work around the few bugs in the resouce editor.</small></li>
</ol>
<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/06/visual-cpp-woes/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Migrating a project from VS2005 to VS2008 disables ASLR</title>
		<link>http://blog.koroirc.com/2008/06/migrating-a-project-from-vs2005-to-vs2008-disables-aslr/</link>
		<comments>http://blog.koroirc.com/2008/06/migrating-a-project-from-vs2005-to-vs2008-disables-aslr/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 23:26:19 +0000</pubDate>
		<dc:creator>Koro</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.koroirc.com/?p=4</guid>
		<description><![CDATA[I just spent about an hour trying to figure out why some of KoroIRC&#8217;s binaries did not have the IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE and IMAGE_DLLCHARACTERISTICS_NX_COMPAT flags enabled in their PE header, and some other had them.
Oddly, only the older projects in the solution had this problem, the newer were OK. I spent a while wondering if it might [...]]]></description>
			<content:encoded><![CDATA[<p>I just spent about an hour trying to figure out why some of KoroIRC&#8217;s binaries did not have the <code>IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE</code> and <code>IMAGE_DLLCHARACTERISTICS_NX_COMPAT</code> flags enabled in their PE header, and some other had them.</p>
<p>Oddly, only the <em>older</em> projects in the solution had this problem, the newer were OK. I spent a while wondering if it might have been a linker bug, then I decided to look at the build log. Surprisingly, the affected projects had the <code>/DYNAMICBASE:NO</code> linker switch specified, even though I specified the opposite in the solution-global <code>.vsprops</code> files.</p>
<p>So I decided to take a look directly in the <code>.vsproj</code> files, and lo and behold, in the linker options, the following lines where there:</p>
<blockquote><p><code>RandomizedBaseAddress="1"<br />
DataExecutionPrevention="0"</code></p></blockquote>
<p>Since I <strong>never</strong> add stuff directly to the <code>.vsproj</code> files, because I prefer <code>.vsprops</code> files which allow sharing common settings between projects, then in the migration from VS2005 to VS2008, it must have &#8220;helpfully&#8221; inserted these for me.</p>
<p>To quote Stan from South Park, &#8220;I learned something today&#8230;&#8221;</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/06/migrating-a-project-from-vs2005-to-vs2008-disables-aslr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

