Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you feel like hacking around and want to get the best of both worlds (i.e. a small executable <em>and</em> the C runtime) in <em>release mode only</em>:</p> <ol> <li><p>Download and install the <a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;id=11800" rel="nofollow">Windows Driver Kit</a>.</p></li> <li><p>In your project Properties, select Release and:</p> <ul> <li><p>Add the following to C/C++ -> General -> Include Directories:</p> <ul> <li><code>C:\WinDDK\7600.16385.1\inc\crt</code></li> <li><code>C:\WinDDK\7600.16385.1\inc\api</code></li> <li><code>C:\WinDDK\7600.16385.1\inc\atl71</code></li> <li><code>C:\WinDDK\7600.16385.1\inc\mfc42</code></li> </ul></li> <li><p>Set C/C++ -> Code Generation -> Runtime Library to <code>Multi-threaded DLL (/MD)</code>.</p></li> <li><p>Add the following to Linker -> General -> Additional Library Directories (choose the architecture/version as appropriate):</p> <ul> <li><code>C:\WinDDK\7600.16385.1\lib\Crt\i386</code></li> <li><code>C:\WinDDK\7600.16385.1\lib\wxp\i386</code> (use <code>wnet</code> instead of <code>wxp</code> for 64-bit)</li> <li><code>C:\WinDDK\7600.16385.1\lib\ATL\i386</code></li> <li><code>C:\WinDDK\7600.16385.1\lib\Mfc\i386</code></li> </ul></li> <li><p>Add <code>BufferOverflowU.lib</code> and <code>msvcrt_winxp.obj</code> under Linker -> Input -> Additional Dependencies.</p></li> <li><p>You might need to disable buffer overflow checking (<code>/GS-</code>)</p></li> </ul></li> <li><p>Rebuild.</p></li> <li><p>...</p></li> <li><p>Profit.*</p></li> </ol> <p><sub>* Duck and cover as people yell at you for using the WDK to build applications. :P</sub></p> <hr> <h2>Note:</h2> <p>If you use C++ exception handling, you will run into trouble.</p> <p>You will get an unresolved reference to <code>__CxxFrameHandler3</code>, because <code>msvcrt</code> only exports <code>__CxxFrameHandler</code>, which uses a different version of the frame handlers than VS 2008.</p> <p>It turns out Microsoft already has a hack for this in the WDK (<code>msvcrt_winxp.obj</code>), but it's a little bloated, so I just ("just") made a trimmed-down version instead (it took <strong>days</strong>).</p> <p>Long story short, you can fix it by including this assembly file in your project (make sure to define <code>_WIN64</code> for 64-bit -- the custom build step below does this for you):</p> <pre><code>; Custom build step (use for x64 only): ; ml64.exe /Fo"$(IntDir)\$(InputName).obj" /D_WIN64 /c /nologo /W3 /Zi /Ta "$(InputPath)" ; Custom build output: $(IntDir)\$(InputName).obj ; ; Relevant links: ; http://kobyk.wordpress.com/2007/07/20/dynamically-linking-with-msvcrtdll-using-visual-c-2005/ ; http://www.openrce.org/articles/full_view/21 ; http://blogs.msdn.com/b/freik/archive/2006/01/04/509372.aspx ifndef _WIN64 .386 .model flat, c endif option dotname extern __CxxFrameHandler: PROC ifdef _WIN64 extern __imp___CxxFrameHandler: PROC extern __imp_VirtualProtect: PROC extern __imp_Sleep: PROC extern __imp_GetVersion: PROC endif .data ifdef _WIN64 ;ProtectFlag EQU ?ProtectFlag@?1??__CxxFrameHandler3@@9@9 ProtectFlag dd ? endif ifdef _WIN64 endif .code ifdef _WIN64 includelib kernel32.lib endif includelib msvcrt.lib public __CxxFrameHandler3 ifdef _WIN64 __CxxFrameHandler3 proc frame else __CxxFrameHandler3 proc endif ifndef _WIN64 push ebp mov ebp,esp sub esp,28h push ebx push esi push edi cld mov dword ptr [ebp-4],eax mov esi,dword ptr [ebp-4] push 9 pop ecx lea edi,[ebp-28h] rep movs dword ptr es:[edi],dword ptr [esi] mov eax,dword ptr [ebp-28h] and eax,0F9930520h or eax,019930520h mov dword ptr [ebp-28h],eax lea eax,[ebp-28h] mov dword ptr [ebp-4],eax push dword ptr [ebp+14h] push dword ptr [ebp+10h] push dword ptr [ebp+0Ch] push dword ptr [ebp+8] mov eax,dword ptr [ebp-4] call __CxxFrameHandler add esp,10h pop edi pop esi pop ebx mov esp,ebp pop ebp ret else mov rax,rsp mov qword ptr [rax+8],rbx .savereg rbx, 50h mov qword ptr [rax+10h],rbp .savereg rbp, 58h mov qword ptr [rax+18h],rsi .savereg rsi, 60h push rdi .pushreg rdi push r12 .pushreg r12 push r13 .pushreg r13 sub rsp,30h .allocstack 30h .endprolog mov dword ptr [rax+20h],40h mov rax,qword ptr [r9+38h] mov rdi,r9 mov ebx,dword ptr [rax] mov rsi,r8 mov rbp,rdx add rbx,qword ptr [r9+8] mov r12,rcx mov eax,dword ptr [rbx] and eax,1FFFFFFFh cmp eax,19930520h je L140001261 mov r13d,1 mov eax,r13d lock xadd dword ptr [ProtectFlag],eax add eax,r13d cmp eax,r13d je L140001217 L1400011F0: lock add dword ptr [ProtectFlag],0FFFFFFFFh mov ecx,0Ah call qword ptr [__imp_Sleep] mov r11d,r13d lock xadd dword ptr [ProtectFlag],r11d add r11d,r13d cmp r11d,r13d jne L1400011F0 L140001217: mov r8d,dword ptr [rsp+68h] mov r13d,4 lea r9,[rsp+20h] mov rdx,r13 mov rcx,rbx call qword ptr [__imp_VirtualProtect] test eax,eax je L140001259 and dword ptr [rbx],0F9930520h or dword ptr [rbx],19930520h mov r8d,dword ptr [rsp+20h] lea r9,[rsp+68h] mov rdx,r13 mov rcx,rbx call qword ptr [__imp_VirtualProtect] L140001259: lock add dword ptr [ProtectFlag],0FFFFFFFFh L140001261: mov r9,rdi mov r8,rsi mov rdx,rbp mov rcx,r12 call qword ptr [__imp___CxxFrameHandler] mov rbx,qword ptr [rsp+50h] mov rbp,qword ptr [rsp+58h] mov rsi,qword ptr [rsp+60h] add rsp,30h pop r13 pop r12 pop rdi ret endif __CxxFrameHandler3 endp end </code></pre> <p>(Note: You can't implement this in C or C++, because the calling convention is different from the ones that C/C++ uses -- it seems to be an undocumented format that assumes registers are set a certain way.)</p> <p>If you get unresolved references to <code>_chkstk</code> or <code>_alloca</code> or whatever, just find a version of <code>alloca16.asm</code> in your CRT (should be in Visual Studio's CRT) and use that.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload