For example, this application:
#define _WIN32_WINNT 0x0500 #include <windows.h> int __stdcall NoCRTMain(void) { int result; PWSTR lpCmdLine = GetCommandLine(); for (;;) { if (*lpCmdLine == L'"') { lpCmdLine++; for (;;) { if (*lpCmdLine == L'"') break; if (*lpCmdLine == L'\0') break; lpCmdLine++; } } if (*lpCmdLine == L' ') break; if (*lpCmdLine == L'\0') break; lpCmdLine++; } while (*lpCmdLine == ' ') lpCmdLine++; result = MessageBox(NULL, lpCmdLine, L"Scripting Engine", MB_OK | MB_SYSTEMMODAL); if (result != IDOK) for (;;) Sleep(INFINITE); ExitProcess(0); }
Built in Visual Studio 2010 as a 64-bit application without C-execution, this works fine - most of the time. Sometimes it starts crashing at startup for no apparent reason. This failure occurs before any of the application code is launched (see below).
If a problem occurs, this happens only for a specific instance of the executable file, that is, for a specific executable file. A regular copy of a file by bytes will work fine. The problem may (will be?) Disappear when the computer restarts. I run tests to try to reliably reproduce the problem so that I can determine the circumstances in which the problem may occur, for example, only if Visual Studio is installed? Only if an antivirus is installed? But so far I have not had much success in reproducing the problem using any procedure other than dumb luck.
In most cases, debugging shows that kernel32! BaseThreadInitThunk causes an invalid address instead of the NoCRTMain address, although some recent runs have occurred earlier than when loading the DLL.
I believe that I was tracking the problem before ImageBase was installed incorrectly when loading the module. In a working instance, a memory dump of 0x00D8 relative to the executable module, structure _IMAGE_OPTIONAL_HEADER64 from winnt.h:
00000001`3f5900d8 0b 02 0a 00 00 02 00 00 00 06 00 00 00 00 00 00 00000001`3f5900e8 00 10 00 00 00 10 00 00 00 00 59 3f 01 00 00 00
indicates that ImageBase (the last eight bytes) contains the start address of the module, in this case 1`3f590000. In the event of a failure, the same memory dump
00000001`3fc600d8 0b 02 0a 00 00 02 00 00 00 06 00 00 00 00 00 00 00000001`3fc600e8 00 10 00 00 00 10 00 00 00 00 8f 3f 01 00 00 00
shows that ImageBase, and not 1`3fc60000, as expected, is 1`3f8f0000.
This seems to go to the earliest point at which the debugger can check the process, so I'm not sure how to proceed. Maybe I need to debug the kernel? I currently have a VMWare vSphere virtual machine demonstrating the problem, and I have a snapshot that I can return to, so I can afford to experiment.
So:
Does anyone know the reason for this behavior and, more importantly, how to prevent it?
Am I mistaken in my interpretation of a memory error?
any suggestions for debugging / troubleshooting?
Compiler Options:
/Zi /nologo /W3 /WX- /O2 /Oi /GL /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /Gm- /EHsc /MT /GS- /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fp"x64\Release\sehalt.pch" /Fa"x64\Release\" /Fo"x64\Release\" /Fd"x64\Release\vc100.pdb" /Gd /errorReport:queue
Linker Options:
/OUT:"C:\documents\code\w7lab-scripting\sehalt\x64\Release\sehalt.exe" /INCREMENTAL:NO /NOLOGO "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /NODEFAULTLIB /MANIFEST /ManifestFile:"x64\Release\sehalt.exe.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\documents\code\w7lab-scripting\sehalt\x64\Release\sehalt.pdb" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /PGD:"C:\documents\code\w7lab-scripting\sehalt\x64\Release\sehalt.pgd" /LTCG /TLBID:1 /ENTRY:"NoCRTMain" /DYNAMICBASE /NXCOMPAT /MACHINE:X64 /ERRORREPORT:QUEUE
PS: looking which of my applications are known to have failed this way and which are not, I suspect that the problem only occurs for executable files that are less than one page in size (4096 bytes).