word64 fn00000001400012BC(word32 edx, word64 rdi, word64 r13, selector gs, word64 qwArg08, word64 qwArg10) { if (fn0000000140001600(0x01, edx, r13) == 0x00) { word64 rcx_362; byte bl_363; fn0000000140001974(0x07, qwLoc04, qwArg00, qwArg04, qwArg0C, out rcx_362, out bl_363); int3(); } Mem23[fp - 0x14 + 0x00:byte] = 0x00; word32 eax_25 = fn00000001400015C4(gs); word64 rax_28 = DPB(rax, eax_25, 0); byte bl_29 = (byte) eax_25; word32 ecx_33 = Mem23[0x00000001400035B0 + 0x00:word32]; if (ecx_33 == 0x01) { ecx_33 = 0x07; word64 rcx_355; rax_28 = DPB(rax, fn0000000140001974(0x07, qwLoc04, qwArg00, qwArg04, qwArg0C, out rcx_355, out bl_29), 0); } word64 rax_233; if (ecx_33 == 0x00) { Mem331[0x00000001400035B0 + 0x00:word32] = 0x01; word64 rax_334 = DPB(rax_28, _initterm_e(0x00000001400021B8, 0x00000001400021D0), 0); if (_initterm_e(0x00000001400021B8, 0x00000001400021D0) != 0x00) { rax_233 = DPB(rax_28, 0xFF, 0); return rax_233; } _initterm(0x00000001400021A0, 0x00000001400021B0); Mem344[0x00000001400035B0 + 0x00:word32] = 0x02; }
// Call this function as soon as possible. Basically should be at the moment you // jump into your C/C++ kernel. But keep in mind that kernel is not yet initialized, // and you can't use a lot of stuff in your constructors! bool CallConstructors() { // Do C initialization int initret = _initterm_e(__xi_a, __xi_z); if (initret != 0) { return false; } // Do C++ initialization _initterm(__xc_a, __xc_z); return true; }
void __cdecl mainCRTStartup( void ) { // // Call C initializers. // _initterm_e(__xi_a, __xi_z); // // Call C++ initializers. // _initterm(__xc_a, __xc_z); // // Exit with whatever main will return. // create_argc_and_argv(); int exit_code = main(__argc, __argv); destroy_argc_and_argv(); exit(exit_code); }
int __tmainCRTStartup( void ) { #ifdef _WINMAIN_ _TUCHAR* lpszCommandLine; STARTUPINFO StartupInfo; BOOL inDoubleQuote = FALSE; __try { /* Note: MSDN specifically notes that GetStartupInfo returns no error, and throws unspecified SEH if it fails, so the very general exception handler below is appropriate */ GetStartupInfo(&StartupInfo); } __except (EXCEPTION_EXECUTE_HANDLER) { return 255; } #endif /* _WINMAIN_ */ /* * Guard the initialization code and the call to user's main, or * WinMain, function in a __try/__except statement. */ __try { /* * There is a possiblity that the module where this object is * linked into is a mixed module. In all the cases we gurantee that * native initialization will occur before managed initialization. * Also in anycase this code should never be called when some other * code is initializing native code, that's why we exit in that case. * * Do runtime startup initializers. * * Note: the only possible entry we'll be executing here is for * __lconv_init, pulled in from charmax.obj only if the EXE was * compiled with -J. All other .CRT$XI* initializers are only * run as part of the CRT itself, and so for the CRT DLL model * are not found in the EXE. For that reason, we call _initterm, * not _initterm_e, because __lconv_init will never return failure, * and _initterm_e is not exported from the CRT DLL. * * Note further that, when using the CRT DLL, executing the * .CRT$XI* initializers is only done for an EXE, not for a DLL * using the CRT DLL. That is to make sure the -J setting for * the EXE is not overriden by that of any DLL. */ void* lock_free = 0; void* fiberid = ((PNT_TIB)NtCurrentTeb())->StackBase; int nested = FALSE; while ((lock_free = InterlockedCompareExchangePointer((volatile PVOID*)&__native_startup_lock, fiberid, 0)) != 0) { if (lock_free == fiberid) { nested = TRUE; break; } /* some other thread is running native startup/shutdown during a cctor/domain unload. Should only happen if this DLL was built using the Everett-compat loader lock fix in vcclrit.h */ /* wait for the other thread to complete init before we return */ Sleep(1000); } if (__native_startup_state == __initializing) { _amsg_exit(_RT_CRT_INIT_CONFLICT); } else if (__native_startup_state == __uninitialized) { __native_startup_state = __initializing; #ifndef _SYSCRT if (_initterm_e(__xi_a, __xi_z) != 0) { return 255; } #else /* _SYSCRT */ _initterm((_PVFV*)(void*)__xi_a, (_PVFV*)(void*)__xi_z); #endif /* _SYSCRT */ } else { has_cctor = 1; } /* * do C++ constructors (initializers) specific to this EXE */ if (__native_startup_state == __initializing) { _initterm(__xc_a, __xc_z); __native_startup_state = __initialized; } _ASSERTE(__native_startup_state == __initialized); if (!nested) { /* For X86, the definition of InterlockedExchangePointer wrongly causes warning C4312 */ #pragma warning(push) #pragma warning(disable:4312) InterlockedExchangePointer((volatile PVOID*)&__native_startup_lock, 0); #pragma warning(pop) } /* * If we have any dynamically initialized __declspec(thread) * variables, then invoke their initialization for the primary * thread used to start the process, by calling __dyn_tls_init * through a callback defined in tlsdyn.obj. */ if (__dyn_tls_init_callback != NULL && _IsNonwritableInCurrentImage((PBYTE)&__dyn_tls_init_callback)) { __dyn_tls_init_callback(NULL, DLL_THREAD_ATTACH, NULL); } /* Enable buffer count checking if linking against static lib */ _CrtSetCheckCount(TRUE); #ifdef _WINMAIN_ /* * Skip past program name (first token in command line). * Check for and handle quoted program name. */ #ifdef WPRFLAG /* OS may not support "W" flavors */ if (_wcmdln == NULL) { return 255; } lpszCommandLine = (wchar_t*)_wcmdln; #else /* WPRFLAG */ lpszCommandLine = (unsigned char*)_acmdln; #endif /* WPRFLAG */ while (*lpszCommandLine > SPACECHAR || (*lpszCommandLine && inDoubleQuote)) { /* * Flip the count from 1 to 0 or 0 to 1 if current character * is DOUBLEQUOTE */ if (*lpszCommandLine == DQUOTECHAR) { inDoubleQuote = !inDoubleQuote; } #ifdef _MBCS if (_ismbblead(*lpszCommandLine)) { if (lpszCommandLine) { lpszCommandLine++; } } #endif /* _MBCS */ ++lpszCommandLine; } /* * Skip past any white space preceeding the second token. */ while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR)) { lpszCommandLine++; } #ifdef WPRFLAG mainret = wWinMain( #else /* WPRFLAG */ mainret = WinMain( #endif /* WPRFLAG */ (HINSTANCE)&__ImageBase, NULL, lpszCommandLine, StartupInfo.dwFlags & STARTF_USESHOWWINDOW ? StartupInfo.wShowWindow : SW_SHOWDEFAULT ); #else /* _WINMAIN_ */ #ifdef WPRFLAG __winitenv = envp; mainret = wmain(argc, argv, envp); #else /* WPRFLAG */ __initenv = envp; mainret = main(argc, argv, envp); #endif /* WPRFLAG */ #endif /* _WINMAIN_ */ /* * Note that if the exe is managed app, we don't really need to * call exit or _c_exit. .cctor should be able to take care of * this. */ if (!managedapp) exit(mainret); if (has_cctor == 0) _cexit(); } __except (_XcptFilter(GetExceptionCode(), GetExceptionInformation())) { /* * Should never reach here */ mainret = GetExceptionCode(); /* * Note that if the exe is managed app, we don't really need to * call exit or _c_exit. .cctor should be able to take care of * this. */ if (!managedapp) { _exit(mainret); } if (has_cctor == 0) { _cexit(); } } /* end of try - except */ return mainret; }
BOOL WINAPI _CRT_INIT( HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved ) { /* * If this is a process detach notification, check that there has * been a prior (successful) process attachment. */ if ( dwReason == DLL_PROCESS_DETACH ) { if ( __proc_attached > 0 ) __proc_attached--; else /* * no prior process attach. just return failure. */ return FALSE; } #ifdef _M_IX86 /* * Set the local copy of the Pentium FDIV adjustment flag */ _adjust_fdiv = * _imp___adjust_fdiv; #endif /* _M_IX86 */ /* * do C++ constructors (initializers) specific to this DLL */ if ( dwReason == DLL_PROCESS_ATTACH ) { /* * There is a possiblity that the module where this object is * linked into is a mixed module. In all the cases we gurantee * that native initialization will occur before managed * initialization. Also in anycase this code should never be * called when some other code is initializing native code, * that's why we exit in that case. * * The case that is illegal is when managed code is executed for * the first time in loader lock. But there can be case when dll is * loaded in LoadLibrary and CLR could be already loaded in this * case it is perfectly OK to execute .cctor. */ void *lock_free=0; void *fiberid=((PNT_TIB)NtCurrentTeb())->StackBase; int nested=FALSE; while((lock_free=InterlockedCompareExchangePointer((volatile PVOID *)&__native_startup_lock, fiberid, 0))!=0) { if(lock_free==fiberid) { nested=TRUE; break; } /* some other thread is running native startup/shutdown during a cctor/domain unload. Should only happen if this DLL was built using the Everett-compat loader lock fix in vcclrit.h */ /* wait for the other thread to complete init before we return */ Sleep(1000); } if (__native_startup_state != __uninitialized) { _amsg_exit( _RT_CRT_INIT_CONFLICT); } else { /* * Set the native startup state to initializing. */ __native_startup_state = __initializing; /* * Invoke C initializers. */ #ifndef _SYSCRT if (_initterm_e( __xi_a, __xi_z ) != 0) return FALSE; #else /* _SYSCRT */ _initterm((_PVFV *)(void *)__xi_a, (_PVFV *)(void *)__xi_z); #endif /* _SYSCRT */ /* * Invoke C++ constructors */ _initterm(__xc_a,__xc_z); /* * Set the native initialization state to initialized. */ __native_startup_state = __initialized; } if(!nested) { /* For X86, the definition of InterlockedExchangePointer wrongly causes warning C4312 */ #pragma warning(push) #pragma warning(disable:4312) InterlockedExchangePointer((volatile PVOID *)&__native_startup_lock,0); #pragma warning(pop) } /* * If we have any dynamically initialized __declspec(thread) * variables, then invoke their initialization for the thread on * which the DLL is being loaded, by calling __dyn_tls_init through * a callback defined in tlsdyn.obj. We can't rely on the OS * calling __dyn_tls_init with DLL_PROCESS_ATTACH because, on * Win2K3 and before, that call happens before the CRT is * initialized. */ if (__dyn_tls_init_callback != NULL && _IsNonwritableInCurrentImage((PBYTE)&__dyn_tls_init_callback)) { __dyn_tls_init_callback(hDllHandle, DLL_THREAD_ATTACH, lpreserved); } /* Enable buffer count checking if linking against static lib */ _CrtSetCheckCount(TRUE); /* * Increment the process attached flag. */ __proc_attached++; } else if ( dwReason == DLL_PROCESS_DETACH ) { /* * Any basic clean-up code that goes here must be * duplicated below in _DllMainCRTStartup for the * case where the user's DllMain() routine fails on a * Process Attach notification. This does not include * calling user C++ destructors, etc. */ /* * do _onexit/atexit() terminators * (if there are any) * * These terminators MUST be executed in * reverse order (LIFO)! * * NOTE: * This code assumes that __onexitbegin * points to the first valid onexit() * entry and that __onexitend points * past the last valid entry. If * __onexitbegin == __onexitend, the * table is empty and there are no * routines to call. */ void *lock_free=0; while((lock_free=InterlockedCompareExchangePointer((volatile PVOID *)&__native_startup_lock, (PVOID)1, 0))!=0) { /* some other thread is running native startup/shutdown during a cctor/domain unload. Should only happen if this DLL was built using the Everett-compat loader lock fix in vcclrit.h */ /* wait for the other thread to complete init before we return */ Sleep(1000); } if(__native_startup_state!=__initialized) { /* somehow we are in a very bad state running shutdown when we have not started */ _amsg_exit( _RT_CRT_INIT_CONFLICT); } else { _PVFV * onexitbegin = (_PVFV *)_decode_pointer(__onexitbegin); if (onexitbegin) { _PVFV * onexitend = (_PVFV *)_decode_pointer(__onexitend); while ( --onexitend >= onexitbegin ) /* * if current table entry is not * NULL, call thru it. */ if ( *onexitend != NULL ) (**onexitend)(); /* * free the block holding onexit table to * avoid memory leaks. Also zero the ptr * variables so that they are clearly cleaned up. */ _free_crt ( onexitbegin ) ; __onexitbegin = __onexitend = (_PVFV *)_encoded_null(); } __native_startup_state = __uninitialized; /* For X86, the definition of InterlockedExchangePointer wrongly causes warning C4312 */ #pragma warning(push) #pragma warning(disable:4312) InterlockedExchangePointer((volatile PVOID *)&__native_startup_lock,0); #pragma warning(pop) } } return TRUE; }
// address: 0x4014ec void _start() { __size16 ax; // r0 __size16 cx; // r1 unsigned char dl; // r10 __size32 eax; // r24 __size32 *ebp; // r29 __size32 ebx; // r27 __size32 ecx; // r25 __size32 edi; // r31 int edx; // r26 __size32 esi; // r30 int esp; // r28 void *esp_1; // r28{8} void *esp_2; // r28{44} void *esp_3; // r28{191} int local0; // m[esp - 4] int local1; // m[esp - 24] int local2; // m[esp - 20] unsigned int local3; // m[esp - 12] int local4; // m[esp - 8] void *local5; // esp_3{191} esi = proc1(local1, local2, esi); /* Warning: also results in ebx, edi */ esp_1 = proc2(16, ebx, esi, edi); /* Warning: also results in ebp */ local5 = esp_1; ebx = 0; *(__size32*)(ebp - 4) = 0; eax = *24; esi = *(eax + 4); *(__size32*)(ebp - 28) = 0; edi = 0x403374; for(;;) { esp_3 = local5; *(__size32*)(esp_3 - 4) = 0; *(__size32*)(esp_3 - 8) = esi; *(__size32*)(esp_3 - 12) = 0x403374; eax = InterlockedCompareExchange(); /* Warning: also results in edx */ if (eax == 0) { goto L24; } if (eax == esi) { break; } *(__size32*)(esp_3 - 16) = 1000; esp_2 = Sleep(*(esp_3 - 16)); local5 = esp_2; } *(__size32*)(ebp - 28) = 1; L24: esi = 1; if (global61 != 1) { if (global61 != 0) { global68 = 1; L16: if (global61 == 1) { *(__size32*)(esp_3 - 16) = 0x4020cc; *(__size32*)(esp_3 - 20) = 0x4020c4; edx = _initterm(); global61 = 2; } if (*(ebp - 28) == 0) { *(__size32*)(esp_3 - 16) = 0; *(__size32*)(esp_3 - 20) = 0x403374; edx = InterlockedExchange(*(esp_3 - 20), *(esp_3 - 16)); } esp = esp_3 - 12; if (*0x403380 != 0) { *(__size32*)(esp_3 - 16) = 0x403380; eax = proc5(*(esp_3 - 16), dl, edx, 0); /* Warning: also results in ax, cx, dl, edx */ ecx = *(esp_3 - 16); esp = esp_3 - 12; if (eax != 0) { *(__size32*)(esp_3 - 16) = 0; *(__size32*)(esp_3 - 20) = 2; *(__size32*)(esp_3 - 24) = 0; (*global53)(local1, local2, pc, 0x4021d8, 16, ax, cx, dl, eax, ecx, edx, 0, ebp, 1, 0x403374, LOGICALFLAGS32(eax), LOGICALFLAGS32(eax), LOGICALFLAGS32(eax)); } } *(__size32*)0x23cc = global75; local0 = global75; local4 = global76; local3 = global77; eax = proc6(*(esp - 12), *(esp - 8), 0x23cc, ebx, esi, edi); /* Warning: also results in ebx */ global79 = eax; if (*0x403024 == ebx) { local0 = eax; exit(*(esp - 4)); } if (*0x403034 == ebx) { _cexit(); } *(__size32*)(ebp - 4) = -2; } else { global61 = 1; *(__size32*)(esp_3 - 16) = 0x4020dc; *(__size32*)(esp_3 - 20) = 0x4020d0; eax = _initterm_e(); /* Warning: also results in edx */ esp = esp_3 - 12; if (eax == 0) { goto L16; } else { *(__size32*)(ebp - 4) = -2; } } } else { *(__size32*)(esp_3 - 16) = 31; edx = _amsg_exit(); goto L16; } proc8(ebp); return; }