/*++ Copyright (C) 2000-2001 Microsoft Corporation Module Name: winmgmt.cpp Abstract: the Service main function, initialization routines, ecc --*/ #include "precomp.h" #include #include #include #include "cntserv.h" #include "winmgmt.h" #include "sched.h" #include "resync2.h" #include #include #include #include "wstlallc.h" // // Defines // //*********************************************************************** #define CORE_PROVIDER_UNLOAD_TIMEOUT ( 30 * 1000 ) //*********************************************************************** // // Globals // //*********************************************************************** HINSTANCE g_hInstance; //*********************************************************************** // // Dll Entry points and export points // //*********************************************************************** BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { BOOL bRet = TRUE; switch(ul_reason_for_call) { case DLL_PROCESS_ATTACH: g_hInstance = hModule; DisableThreadLibraryCalls(hModule); bRet = CStaticCritSec::anyFailure()?FALSE:TRUE; break; case DLL_PROCESS_DETACH: break; } return bRet; }; // // // InitialBreak // /////////////////////////////////////////////////////////// BOOL InitialBreak() { HKEY hKey; LONG lRet; BOOL bRet = FALSE; lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, HOME_REG_PATH, 0, KEY_READ, &hKey); if (ERROR_SUCCESS == lRet) { DWORD dwType; DWORD dwVal; DWORD dwSize = sizeof(DWORD); lRet = RegQueryValueEx(hKey, INITIAL_BREAK, NULL, &dwType, (BYTE *)&dwVal, &dwSize); if (ERROR_SUCCESS == lRet && dwType == REG_DWORD && dwVal) { bRet = TRUE; } RegCloseKey(hKey); } return bRet; } // // the global structure // struct _PROG_RESOURCES g_ProgRes; void _PROG_RESOURCES::Init() { m_bOleInitialized = NULL; m_pLoginFactory = NULL; m_pBackupFactory = NULL; m_dwLoginClsFacReg = 0; m_dwBackupClsFacReg = 0; g_fSetup = FALSE; g_fDoResync = TRUE; hMainMutex = NULL; bShuttingDownWinMgmt = FALSE; gbCoreLoaded = FALSE; ServiceStatus = SERVICE_STOPPED; ghCoreCanUnload = NULL; ghProviderCanUnload = NULL; ghMofDirChange = NULL; szHotMofDirectory = NULL; pWbemVssWriter = NULL; bWbemVssWriterSubscribed = false; dwWaitThreadID = GetCurrentThreadId(); }; BOOL _PROG_RESOURCES::Phase1Build() { hMainMutex = CreateMutex(NULL, FALSE, NULL); g_fSetup = CheckSetupSwitch(); if ( g_fSetup ) { SetNoShellADAPSwitch(); } // Look in the registry to decide if we will launch a resync perf or not g_fDoResync = CheckNoResyncSwitch(); // // set this to have the Console Control Handler notification // SetProcessShutdownParameters(0x400,0); // // set to some defined value parames that might be outstanding if someone killed us // RegSetDWORD(HKEY_LOCAL_MACHINE,HOME_REG_PATH,DO_THROTTLE,1); return hMainMutex?TRUE:FALSE; }; BOOL _PROG_RESOURCES::Phase2Build(HANDLE hTerminateEvt) { ghCoreCanUnload = CreateEvent(NULL,FALSE,FALSE, TEXT("WINMGMT_COREDLL_CANSHUTDOWN")); if (NULL == ghCoreCanUnload) { // create a non-named event that nobody will set ghCoreCanUnload = CreateEvent(NULL,FALSE,FALSE,NULL); if (NULL == ghCoreCanUnload) return FALSE; } ghProviderCanUnload = CreateEvent(NULL,FALSE,FALSE, TEXT("WINMGMT_PROVIDER_CANSHUTDOWN")); if (NULL == ghProviderCanUnload) { // create a non-named event that nobody will set ghProviderCanUnload = CreateEvent(NULL,FALSE,FALSE,NULL); if (NULL == ghProviderCanUnload) return FALSE; } if (!m_Monitor.Init()) { return FALSE; } // don't create a writer if during setup if (!g_fSetup) { pWbemVssWriter = new CWbemVssWriter; if (!pWbemVssWriter) { TRACE((LOG_WINMGMT,"WINMGMT could not create the VssWriter\n")); return FALSE; } } return TRUE; } CForwardFactory g_FactoryLogin(CLSID_InProcWbemLevel1Login); BOOL _PROG_RESOURCES::RegisterLogin() { HRESULT sc; DWORD dwFlags = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER; g_ProgRes.m_pLoginFactory = &g_FactoryLogin; g_ProgRes.m_pLoginFactory->AddRef(); sc = CoRegisterClassObject(CLSID_WbemLevel1Login, g_ProgRes.m_pLoginFactory, dwFlags, REGCLS_MULTIPLEUSE, &g_ProgRes.m_dwLoginClsFacReg); if(sc != S_OK) { DEBUGTRACE((LOG_WINMGMT,"Failed to register the " "CLSID_WbemLevel1Login class factory, " "sc = 0x%x\n", sc)); return FALSE; } else { DEBUGTRACE((LOG_WINMGMT, "Registered class factory with flags: 0x%X\n",dwFlags)); return TRUE; } } BOOL _PROG_RESOURCES::RevokeLogin() { if(m_pLoginFactory) { CoRevokeClassObject(m_dwLoginClsFacReg); m_dwLoginClsFacReg = 0; m_pLoginFactory->Release(); m_pLoginFactory = NULL; } return TRUE; } CForwardFactory g_FactoryBackUp(CLSID_WbemBackupRestore); BOOL _PROG_RESOURCES::RegisterBackup() { HRESULT sc; DWORD dwFlags = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER; g_ProgRes.m_pBackupFactory = &g_FactoryBackUp; g_ProgRes.m_pBackupFactory->AddRef(); sc = CoRegisterClassObject(CLSID_WbemBackupRestore, g_ProgRes.m_pBackupFactory, dwFlags, REGCLS_MULTIPLEUSE, &g_ProgRes.m_dwBackupClsFacReg); if(sc != S_OK) { TRACE((LOG_WINMGMT,"Failed to register the " "Backup/recovery class factory, " "sc = 0x%x\n", sc)); return FALSE; } else { return TRUE; } } BOOL _PROG_RESOURCES::RevokeBackup() { if(m_pBackupFactory) { CoRevokeClassObject(m_dwBackupClsFacReg); m_dwBackupClsFacReg = 0; m_pBackupFactory->Release(); m_pBackupFactory = NULL; } return TRUE; } _PROG_RESOURCES::Phase1Delete(BOOL bIsSystemShutdown) { if (!bIsSystemShutdown) { if(ghCoreCanUnload) { CloseHandle(ghCoreCanUnload); ghCoreCanUnload = NULL; }; if(ghProviderCanUnload) { CloseHandle(ghProviderCanUnload); ghProviderCanUnload = NULL; } if(ghMofDirChange) { CloseHandle(ghMofDirChange); ghMofDirChange = NULL; } } if (m_Monitor.IsRegistred()) { m_Monitor.Unregister(bIsSystemShutdown); } if (!bIsSystemShutdown) { m_Monitor.Uninit(); if(szHotMofDirectory) { delete [] szHotMofDirectory; szHotMofDirectory = NULL; } } // shut down and delete our writer for volume snapshot backup if (pWbemVssWriter && !bIsSystemShutdown) { if (bWbemVssWriterSubscribed) { HRESULT hRes = pWbemVssWriter->Unsubscribe(); if (SUCCEEDED(hRes)) { bWbemVssWriterSubscribed = false; } else { TRACE((LOG_WINMGMT,"WINMGMT Could not unsubscribe the VssWriter\n")); } } delete pWbemVssWriter; pWbemVssWriter = NULL; } return TRUE; } _PROG_RESOURCES::Phase2Delete(BOOL bIsSystemShutdown) { // do anyway COM cleanup // we are on Server now, we can afford it RevokeLogin(); RevokeBackup(); if(m_bOleInitialized) { CoUninitialize(); m_bOleInitialized = FALSE; } return TRUE; } BOOL _PROG_RESOURCES::Phase3Delete() { if (hMainMutex) { CloseHandle(hMainMutex); hMainMutex = NULL; } return TRUE; } // // // IsShutDown // // ///////////////////////////////////////////////////////////////// BOOL WINAPI IsShutDown(void) { return g_ProgRes.bShuttingDownWinMgmt; } // // // ShutDownCore // // ///////////////////////////////////////////////////////////////// bool ShutDownCore(BOOL bProcessShutdown,BOOL bIsSystemShutDown) { SCODE sc = WBEM_E_FAILED; HMODULE hCoreModule = LoadLibrary(__TEXT("wbemcore.dll")); if(hCoreModule) { pfnShutDown pfn = (pfnShutDown)GetProcAddress(hCoreModule, "Shutdown"); if(pfn) { sc = (pfn)(bProcessShutdown,bIsSystemShutDown); DEBUGTRACE((LOG_WINMGMT, "core is being shut down by WinMgmt, it returned 0x%x\n",sc)); } FreeLibrary(hCoreModule); } return sc == S_OK; } // // // void Cleanup // // Revokes Factories and close Ole etc. // /////////////////////////////////////////////////////////////////// void Cleanup(BOOL bIsSystemShutDown) { if (!bIsSystemShutDown) { DEBUGTRACE((LOG_WINMGMT,"+ Cleanup(%d), ID = %x\n", bIsSystemShutDown,GetCurrentProcessId())); } g_ProgRes.Phase1Delete(bIsSystemShutDown); // If the core is still loaded, call its shutdown function ShutDownCore(TRUE,bIsSystemShutDown); if (!bIsSystemShutDown) { CoFreeUnusedLibrariesEx ( 0 , 0 ) ; CoFreeUnusedLibrariesEx ( 0 , 0 ) ; } g_ProgRes.Phase2Delete(bIsSystemShutDown); if (!bIsSystemShutDown) { DEBUGTRACE((LOG_WINMGMT,"- Cleanup()\n")); } } // // // BOOL Initialize // // /////////////////////////////////////////////////////////////// BOOL Initialize(HANDLE hTerminateEvt) { if (NULL == hTerminateEvt) return FALSE; // Set the error mode. This is used to provent the system from putting up dialog boxs to // open files UINT errormode = SetErrorMode(0); errormode |= SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS; SetErrorMode(errormode); DEBUGTRACE((LOG_WINMGMT,"+ Initialize, pid = %x\n", GetCurrentProcessId())); if(!InitHotMofStuff(&g_ProgRes)) return FALSE; if (!g_ProgRes.Phase2Build(hTerminateEvt)) return FALSE; // Initialize Ole SCODE sc; sc = CoInitializeEx(NULL,COINIT_MULTITHREADED); if(FAILED(sc)) { ERRORTRACE((LOG_WINMGMT,"WINMGMT Could not initialize Ole\n")); return FALSE; } else { g_ProgRes.m_bOleInitialized = TRUE; } // // Call the initialize function in core // HMODULE hCoreModule = NULL; if (GetModuleHandleEx(0,__TEXT("wbemcore.dll"),&hCoreModule)) { OnDelete flm(hCoreModule); HRESULT (STDAPICALLTYPE *pfn)(DWORD); pfn = (long (__stdcall *)(DWORD))GetProcAddress(hCoreModule, "Reinitialize"); if(pfn) { sc = (*pfn)(0); DEBUGTRACE((LOG_WINMGMT, "wbemcore!Reinitialize() returned 0x%x\n",sc)); } else { DEBUGTRACE((LOG_WINMGMT, "failed to re-initialize core\n")); return FALSE; } } g_ProgRes.RegisterLogin(); g_ProgRes.RegisterBackup(); g_ProgRes.ServiceStatus = SERVICE_RUNNING; // initialize our writer for volume snapshot backup // this must be after CoInitializeEx and after wbem is initialized // (this pointer will be NULL during setup) if (g_ProgRes.pWbemVssWriter) { HRESULT hRes = g_ProgRes.pWbemVssWriter->Initialize(); if (SUCCEEDED(hRes)) { hRes = g_ProgRes.pWbemVssWriter->Subscribe(); if (SUCCEEDED(hRes)) { g_ProgRes.bWbemVssWriterSubscribed = true; } else { DEBUGTRACE((LOG_WINMGMT,"WINMGMT Could not subscribe the VssWriter\n")); } } else { DEBUGTRACE((LOG_WINMGMT,"WINMGMT Could not initialize the VssWriter\n")); } } DEBUGTRACE((LOG_WINMGMT,"- Initialize\n")); return TRUE; } // // // WaitingFunction // // DESCRIPTION: // // Here is where we wait for messages and events during WinMgmt execution. // We return from here when the program/service is being stopped. // ////////////////////////////////////////////////////////////////// void WaitingFunction(HANDLE hTerminate) { DEBUGTRACE((LOG_WINMGMT,"+ WaitingFunction\n")); CSched sched; HANDLE hEvents[] = {hTerminate, g_ProgRes.ghCoreCanUnload, g_ProgRes.ghProviderCanUnload, g_ProgRes.ghMofDirChange // important, must be last entry!!!! }; int iNumEvents = sizeof(hEvents) / sizeof(HANDLE); DWORD dwFlags; SCODE sc; CPersistentConfig per; per.TidyUp(); sched.SetWorkItem(PossibleStartCore, 60000); //Load any MOFs in the MOF directory if needed... LoadMofsInDirectory(g_ProgRes.szHotMofDirectory); // resync the perf counters if // we haven't turned this off for debugging AND // we are not running during setup if(GLOB_IsResyncAllowed()) { ResyncPerf(RESYNC_TYPE_INITIAL); GLOB_GetMonitor()->Register(); } while(TRUE) { DWORD dwDelay = sched.GetWaitPeriod(); DWORD dwObj = WaitForMultipleObjects(iNumEvents, hEvents, FALSE, dwDelay); switch (dwObj) { case 0: // bail out for terminate event { if (SERVICE_SHUTDOWN != g_ProgRes.ServiceStatus) { DEBUGTRACE((LOG_WINMGMT,"hTerminate set: reason %x\n",g_ProgRes.ServiceStatus)); } { CInMutex im(g_ProgRes.hMainMutex); g_ProgRes.bShuttingDownWinMgmt = TRUE; } // call cleanup outside of a Mutex Cleanup((g_ProgRes.ServiceStatus == SERVICE_SHUTDOWN)?TRUE:FALSE); } return; case 1: // core can unload DEBUGTRACE((LOG_WINMGMT,"Got a core can unload event\n")); sched.SetWorkItem(FirstCoreShutdown, 30000); // 30 seconds until next unloac; break; case 2: // provider can unload { DEBUGTRACE((LOG_WINMGMT,"Got a provider can unload event\n")); CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ; CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ; sched.SetWorkItem(FinalCoreShutdown, CORE_PROVIDER_UNLOAD_TIMEOUT); // 11 minutes until next unloac; } break; case 3: // change in the hot mof directory { DEBUGTRACE((LOG_WINMGMT,"Got change in the hot mof directory\n")); LoadMofsInDirectory(g_ProgRes.szHotMofDirectory); //Continue to monitor changes if (!FindNextChangeNotification(g_ProgRes.ghMofDirChange)) { iNumEvents--; } } break; case WAIT_TIMEOUT: DEBUGTRACE((LOG_WINMGMT,"Got a TIMEOUT work item\n")); if(sched.IsWorkItemDue(FirstCoreShutdown)) { // All the clients have left the core and a decent time interval has passed. Set the // WINMGMT_CORE_CAN_BACKUP event. When the core is done, it will set the WINMGMT_CORE_BACKUP_DONE // event which will start the final unloading. DEBUGTRACE((LOG_WINMGMT,"Got a FirstCoreShutdown work item\n")); sched.ClearWorkItem(FirstCoreShutdown); CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ; CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ; } if(sched.IsWorkItemDue(FinalCoreShutdown)) { CInMutex im(g_ProgRes.hMainMutex); DEBUGTRACE((LOG_WINMGMT,"Got a FinalCoreShutdown work item\n")); CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ; CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ; sched.ClearWorkItem(FinalCoreShutdown); } if(sched.IsWorkItemDue(PossibleStartCore)) { sched.StartCoreIfEssNeeded(); sched.ClearWorkItem(PossibleStartCore); } break; } } } //*************************************************************************** // // MyService::MyService // // DESCRIPTION: // // Constructor. // //*************************************************************************** MyService::MyService(DWORD CtrlAccepted):CNtService(CtrlAccepted) { m_hStopEvent = CreateEvent(NULL,TRUE,FALSE,NULL); if(m_hStopEvent == NULL) { DEBUGTRACE((LOG_WINMGMT,"MyService could not initialize\n")); } } //*************************************************************************** // // MyService::~MyService // // DESCRIPTION: // // Destructor. // //*************************************************************************** MyService::~MyService() { if(m_hStopEvent) CloseHandle(m_hStopEvent); } //*************************************************************************** // // DWORD MyService::WorkerThread // // DESCRIPTION: // // Where the service runs. In this case, the service just waits for // the terminate event to be set. // // RETURN VALUE: // // 0 //*************************************************************************** DWORD MyService::WorkerThread() { DEBUGTRACE((LOG_WINMGMT,"+ Service::WorkerThread\n")); if(!::Initialize(m_hStopEvent)) return 0; WaitingFunction(m_hStopEvent); if (SERVICE_SHUTDOWN != g_ProgRes.ServiceStatus ) { DEBUGTRACE((LOG_WINMGMT,"- Service::WorkerThread\n")); } return 0; } // // // VOID MyService::Log // /////////////////////////////////////////////////////////////////// VOID MyService::Log( IN LPCSTR lpszMsg) { TRACE((LOG_WINMGMT,lpszMsg)); } // // // the stop function // ////////////////////////////////////////////////////////////////// VOID MyService::Stop(BOOL bSystemShutDownCalled) { if (bSystemShutDownCalled) { WbemSetMachineShutdown(TRUE); } g_ProgRes.ServiceStatus = (bSystemShutDownCalled)?SERVICE_SHUTDOWN:SERVICE_STOPPED; SetEvent(m_hStopEvent); }; // // MyService::Pause // //////////////////////////////////////////////////////////////////// HRESULT WbemPauseService() { HRESULT hr = WBEM_S_NO_ERROR; g_ProgRes.ServiceStatus = SERVICE_PAUSED; g_ProgRes.RevokeLogin(); GLOB_GetMonitor()->Unregister(FALSE); SCODE sc = WBEM_E_FAILED; HMODULE hCoreModule = LoadLibraryEx(__TEXT("wbemcore.dll"),NULL,0); if(hCoreModule) { pfnShutDown pfn = (pfnShutDown)GetProcAddress(hCoreModule, "Shutdown"); if(pfn) { sc = pfn(FALSE,FALSE); DEBUGTRACE((LOG_WINMGMT, "core is being shut down by WinMgmt, it returned 0x%x\n",sc)); } else hr = WBEM_E_CRITICAL_ERROR; FreeLibrary(hCoreModule); } else hr = WBEM_E_CRITICAL_ERROR; return hr; } VOID MyService::Pause() { WbemPauseService(); } // // MyService::Continue // //////////////////////////////////////////////////////////////////// HRESULT WbemContinueService() { HRESULT hr = WBEM_S_NO_ERROR; SCODE sc = WBEM_E_FAILED; HMODULE hCoreModule = LoadLibraryEx(__TEXT("wbemcore.dll"),NULL,0); if(hCoreModule) { HRESULT (STDAPICALLTYPE *pfn)(DWORD); pfn = (long (__stdcall *)(DWORD))GetProcAddress(hCoreModule, "Reinitialize"); if(pfn) { sc = (*pfn)(0); DEBUGTRACE((LOG_WINMGMT, "core is being resumed: it returned 0x%x\n",sc)); } else hr = WBEM_E_CRITICAL_ERROR; FreeLibrary(hCoreModule); } else hr = WBEM_E_CRITICAL_ERROR; g_ProgRes.RegisterLogin(); GLOB_GetMonitor()->Register(); g_ProgRes.ServiceStatus = SERVICE_RUNNING; return hr; } VOID MyService::Continue() { WbemContinueService(); } // // // this function will be executed before // the final SetServiceStatus(SERVICE_STOPPED) // ////////////////////////////////////////////////////////// VOID MyService::FinalCleanup() { g_ProgRes.Phase3Delete(); RegSetDWORD(HKEY_LOCAL_MACHINE, HOME_REG_PATH, TEXT("ProcessID"), 0); } // // // publish process ID in the registry // //////////////////////////////////////////////////// DWORD RegSetDWORD(HKEY hKey, TCHAR * pName, TCHAR * pValue, DWORD dwValue) { HKEY hKey2; LONG lRet; lRet = RegOpenKeyEx(hKey, pName, 0, KEY_WRITE, &hKey2); if (ERROR_SUCCESS == lRet) { DWORD dwType = REG_DWORD; DWORD dwSize = sizeof(DWORD); lRet = RegSetValueEx(hKey2, pValue, NULL, dwType, (BYTE *)&dwValue, dwSize); RegCloseKey(hKey2); } return lRet; } DWORD RegGetDWORD(HKEY hKey, TCHAR * pName, TCHAR * pValue, DWORD * pdwValue) { HKEY hKey2; LONG lRet; if (0 == pdwValue) return ERROR_INVALID_PARAMETER; lRet = RegOpenKeyEx(hKey, pName, 0, KEY_READ, &hKey2); if (ERROR_SUCCESS == lRet) { DWORD dwSize = sizeof(DWORD); DWORD dwType =0; lRet = RegQueryValueEx(hKey2, pValue, NULL, &dwType, (BYTE *)pdwValue, &dwSize); if (ERROR_SUCCESS == lRet && REG_DWORD != dwType) { lRet = ERROR_INVALID_DATATYPE; } RegCloseKey(hKey2); } return lRet; } // // // Interceptor // // /////////////////////////////////////////////////////////// #ifdef INSTRUMENTED_BUILD #ifdef _X86_ #include struct HEAP_ENTRY { WORD Size; WORD PrevSize; BYTE SegmentIndex; BYTE Flags; BYTE UnusedBytes; BYTE SmallTagIndex; }; #define HEAP_SLOW_FLAGS 0x7d030f60 // only the "header" typedef struct _HEAP { HEAP_ENTRY Entry; ULONG Signature; ULONG Flags; ULONG ForceFlags; } HEAP; BOOL g_FaultHeapEnabled = FALSE; BOOL g_FaultFileEnabled = FALSE; ULONG g_Seed; ULONG g_Factor = 100000; ULONG g_Percent = 0x20; //ULONG g_RowOfFailures = 10; //LONG g_NumFailInARow = 0; //LONG g_NumFailedAllocation = 0; BOOL g_bDisableBreak = FALSE; LONG g_nSuccConn = 0; #define SIZE_JUMP_ADR 5 #define SIZE_SAVED_INSTR 12 void _declspec(naked) Prolog__ReadFile(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // dist nop ; // dist nop ; // dist nop ; // dist } } BOOL _I_ReadFile( HANDLE hFile, // handle to file LPVOID lpBuffer, // data buffer DWORD nNumberOfBytesToRead, // number of bytes to read LPDWORD lpNumberOfBytesRead, // number of bytes read LPOVERLAPPED lpOverlapped // offset ){ DWORD * pDw = (DWORD *)_alloca(sizeof(DWORD)); BOOL bRet; LONG Ret = RtlRandomEx(&g_Seed); if (g_FaultFileEnabled && (Ret%g_Factor < g_Percent)) { if (lpNumberOfBytesRead) *lpNumberOfBytesRead = 0; SetLastError(-1); return FALSE; } _asm{ push lpOverlapped; push lpNumberOfBytesRead; push nNumberOfBytesToRead; push lpBuffer; push hFile; call Prolog__ReadFile; mov bRet,eax } return bRet; } void _declspec(naked) Prolog__WriteFile(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // dist nop ; // dist nop ; // dist } } BOOL _I_WriteFile( HANDLE hFile, // handle to file LPCVOID lpBuffer, // data buffer DWORD nNumberOfBytesToWrite, // number of bytes to write LPDWORD lpNumberOfBytesWritten, // number of bytes written LPOVERLAPPED lpOverlapped // overlapped buffer ){ DWORD * pDw = (DWORD *)_alloca(sizeof(DWORD)); BOOL bRet; LONG Ret = RtlRandomEx(&g_Seed); if (g_FaultFileEnabled && (Ret%g_Factor < g_Percent)) { if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = 0; SetLastError(-1); return FALSE; } _asm{ push lpOverlapped; push lpNumberOfBytesWritten; push nNumberOfBytesToWrite; push lpBuffer; push hFile; call Prolog__WriteFile; mov bRet,eax } return bRet; } void _declspec(naked) Prolog__CreateEvent(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // dist nop ; // dist } } HANDLE _I_CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, // SD BOOL bManualReset, // reset type BOOL bInitialState, // initial state LPCWSTR lpName // object name ) { DWORD * pDw = (DWORD *)_alloca(sizeof(DWORD)); HANDLE hHandle; LONG Ret = RtlRandomEx(&g_Seed); if (g_FaultFileEnabled && (Ret%g_Factor < g_Percent)) { SetLastError(-1); return NULL; } _asm{ push lpName; push bInitialState; push bManualReset; push lpEventAttributes call Prolog__CreateEvent; mov hHandle,eax } return hHandle; } void _declspec(naked) Prolog__RtlFreeHeap(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; } } #define SPACE_STACK_ALLOC (4*sizeof(ULONG_PTR)) DWORD _I_RtlFreeHeap(VOID * pHeap,DWORD Flags,VOID * pBlock) { ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD)); Flags |= (((HEAP *)pHeap)->Flags) | (((HEAP *)pHeap)->ForceFlags); DWORD dwRet; if (pBlock && !(HEAP_SLOW_FLAGS & Flags)) { HEAP_ENTRY * pEntry = (HEAP_ENTRY *)pBlock-1; DWORD RealSize = pEntry->Size * sizeof(HEAP_ENTRY); DWORD Size = RealSize - pEntry->UnusedBytes; ULONG_PTR * pL = (ULONG_PTR *)pBlock; if (0 == (pEntry->Flags & 0x01) ||0xf0f0f0f0 == pL[1] ) { if (!g_bDisableBreak) DebugBreak(); } DWORD CanMemset = RealSize-sizeof(HEAP_ENTRY); memset(pBlock,0xF0,(CanMemset > SPACE_STACK_ALLOC)?CanMemset-SPACE_STACK_ALLOC:CanMemset); if (pEntry->Size >=4) { RtlCaptureStackBackTrace (1, (4 == pEntry->Size)?4:6, (PVOID *)(pEntry+2), pLong); } } _asm { push pBlock ; push Flags ; push pHeap ; call Prolog__RtlFreeHeap ; mov dwRet,eax ; } return dwRet; } void _declspec(naked) Prolog__RtlAllocateHeap(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // to make this distinct } } VOID * _I_RtlAllocateHeap(VOID * pHeap,DWORD Flags,DWORD Size) { ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD)); Flags |= (((HEAP *)pHeap)->Flags) | (((HEAP *)pHeap)->ForceFlags); VOID * pRet; DWORD NewSize = (Size < (3*sizeof(HEAP_ENTRY)))?(3*sizeof(HEAP_ENTRY)+SPACE_STACK_ALLOC):(Size+SPACE_STACK_ALLOC); /* if (g_FaultHeapEnabled && g_NumFailInARow) { InterlockedDecrement(&g_NumFailInARow); goto here; } */ LONG Ret = RtlRandomEx(&g_Seed); if (g_FaultHeapEnabled && (Ret%g_Factor < g_Percent)) { // g_NumFailInARow = g_RowOfFailures; //here: // InterlockedIncrement(&g_NumFailedAllocation); return NULL; } _asm { push NewSize ; push Flags ; push pHeap ; call Prolog__RtlAllocateHeap ; mov pRet,eax ; } if (pRet && !(HEAP_SLOW_FLAGS & Flags) ) { if (NewSize <= 0xffff) NewSize = sizeof(HEAP_ENTRY)*((HEAP_ENTRY *)pRet-1)->Size; if (!(HEAP_ZERO_MEMORY & Flags)) { memset(pRet,0xc0,NewSize-sizeof(HEAP_ENTRY)); } RtlCaptureStackBackTrace(1, 4, (PVOID *)((BYTE *)pRet+(NewSize-SPACE_STACK_ALLOC-sizeof(HEAP_ENTRY))), pLong); } return pRet; } void _declspec(naked) Prolog__RtlReAllocateHeap(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist } } VOID * _I_RtlReAllocateHeap( HANDLE pHeap, // handle to heap block DWORD Flags, // heap reallocation options LPVOID lpMem, // pointer to memory to reallocate SIZE_T Size // number of bytes to reallocate ){ ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD)); Flags |= (((HEAP *)pHeap)->Flags) | (((HEAP *)pHeap)->ForceFlags); VOID * pRet; DWORD NewSize = (Size < (3*sizeof(HEAP_ENTRY)))?(3*sizeof(HEAP_ENTRY)+SPACE_STACK_ALLOC):(Size+SPACE_STACK_ALLOC); _asm { push NewSize ; push lpMem ; push Flags ; push pHeap ; call Prolog__RtlReAllocateHeap ; mov pRet,eax ; } if (pRet && !(HEAP_SLOW_FLAGS & Flags) ) { if (NewSize <= 0xffff) NewSize = sizeof(HEAP_ENTRY)*((HEAP_ENTRY *)pRet-1)->Size; RtlCaptureStackBackTrace(1, 4, (PVOID *)((BYTE *)pRet+(NewSize-SPACE_STACK_ALLOC-sizeof(HEAP_ENTRY))), pLong); } return pRet; } void _declspec(naked) Prolog__RtlValidateHeap(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist } } BOOL _I_RtlValidateHeap( HANDLE pHeap, // handle to heap block DWORD dwFlags, // heap reallocation options LPVOID lpMem // pointer to memory to validate ){ ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD)); BOOL bRet; g_bDisableBreak = TRUE; _asm { push lpMem ; push dwFlags ; push pHeap ; call Prolog__RtlValidateHeap ; mov bRet,eax ; } g_bDisableBreak = FALSE; return bRet; } #if 0 #define MAX_REMEMBER (1024) struct CSCCTrace { VOID * p1; VOID * p2; DWORD Tid; ULONG_PTR Trace[5]; } g_CSCCTrace[MAX_REMEMBER]; LONG g_CSCCIndex = -1; void _declspec(naked) Prolog__CoSwitchCallContext(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist } } HRESULT WINAPI _I_CoSwitchCallContext(IUnknown * pNew, IUnknown ** ppOld) { ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG )); long nIndex = InterlockedIncrement(&g_CSCCIndex); nIndex %= MAX_REMEMBER; CSCCTrace * pTrace = &g_CSCCTrace[nIndex]; pTrace->p1 = pNew; if (ppOld) pTrace->p2 = *ppOld; else pTrace->p2 = 0; pTrace->Tid =GetCurrentThreadId(); RtlCaptureStackBackTrace (1,5,(PVOID *)pTrace->Trace,pLong); HRESULT hRes; _asm { push ppOld; push pNew; call Prolog__CoSwitchCallContext; mov hRes,eax; }; return hRes; } #endif void _declspec(naked) Prolog__MoveFileW(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist } } BOOL WINAPI _I_MoveFileW(WCHAR * lpExistingFileName, WCHAR * lpNewFileName) { ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG )); LONG Ret = RtlRandomEx(&g_Seed); if (g_FaultFileEnabled && (Ret%g_Factor < g_Percent)) { SetLastError(-1); return FALSE; } BOOL bRet; HRESULT hRes; _asm { push lpNewFileName; push lpExistingFileName; call Prolog__MoveFileW; mov bRet,eax; }; return bRet; } void _declspec(naked) Prolog__NtOpenThreadToken(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist } } class TokenBackTrace { private: CStaticCritSec cs_; struct Trace { DWORD Tid_; PVOID StackTrace_[6]; Trace() { ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG )); Tid_ = GetCurrentThreadId(); RtlCaptureStackBackTrace (3,6,(PVOID *)StackTrace_,pLong); } }; typedef std::map, wbem_allocator > HandleMap; HandleMap map_; DWORD TlsIndex_; struct SetUnsetTls { DWORD Idx; SetUnsetTls(TokenBackTrace & TBT) { Idx = TBT.TlsIndex_; LONG lVal = (LONG)TlsGetValue(Idx); lVal++; TlsSetValue(Idx,(LPVOID)lVal); } ~SetUnsetTls() { LONG lVal = (LONG)TlsGetValue(Idx); lVal--; TlsSetValue(Idx,(LPVOID)lVal); } }; public: TokenBackTrace() { TlsIndex_ = TlsAlloc(); }; ~TokenBackTrace() { TlsFree(TlsIndex_); } void Add(HANDLE hToken) { LONG * pLong = (LONG * )_alloca(sizeof(LONG )); //DbgPrintfA(0,"A Tid %08x\n",GetCurrentThreadId()); SetUnsetTls Tls(*this); CInCritSec ics(&cs_); try { map_.insert(HandleMap::value_type(hToken,Trace())); } catch(CX_Exception &) { }; } void Remove(HANDLE hToken) { SetUnsetTls Tls(*this); LONG lVal = (LONG)TlsGetValue(TlsIndex_); if (lVal > 1) return; //RTL_CRITICAL_SECTION * pcs = &cs_; //DbgPrintfA(0,"R Tid %08x\n",GetCurrentThreadId()); //if (pcs->LockSemaphore && pcs->LockSemaphore == hToken) return; CInCritSec ics(&cs_); if (map_.empty()) return; HandleMap::iterator it = map_.find(hToken); if (map_.end() != it) { map_.erase(it); } } void Empty() { CInCritSec ics(&cs_); map_.clear(); } } g_TBT; BOOL WINAPI _I_NtOpenThreadToken(HANDLE hThread, DWORD DesiredAccess, BOOL bOpenAsSelf, HANDLE * phToken) { ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG )); BOOL bRet; HANDLE hToken = NULL; HANDLE * phLocToken = &hToken; _asm { push phLocToken; push bOpenAsSelf; push DesiredAccess; push hThread; call Prolog__NtOpenThreadToken; mov bRet,eax; }; if (phToken) *phToken = hToken; if (hToken) { g_TBT.Add(hToken); } return bRet; } void _declspec(naked) Prolog__NtOpenProcessToken(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist } } BOOL WINAPI _I_NtOpenProcessToken (HANDLE ProcessHandle, DWORD DesiredAccess, HANDLE * pTokenHandle) { ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG )); BOOL bRet; HANDLE hToken = NULL; HANDLE * phLocToken = &hToken; _asm { push phLocToken; push DesiredAccess; push ProcessHandle; call Prolog__NtOpenProcessToken; mov bRet,eax; }; if (pTokenHandle) *pTokenHandle = hToken; if (hToken) { g_TBT.Add(hToken); } return bRet; } void _declspec(naked) Prolog__NtClose(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist } } BOOL WINAPI _I_NtClose(HANDLE hHandle) { ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG )); if (hHandle) g_TBT.Remove(hHandle); BOOL bRet; _asm { push hHandle; call Prolog__NtClose; mov bRet,eax; }; return bRet; } void _declspec(naked) Prolog__DuplicateTokenEx(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist } } BOOL WINAPI _I_DuplicateTokenEx(HANDLE hExistingToken, DWORD dwDesiredAccess, LPSECURITY_ATTRIBUTES lpTokenAttributes, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, TOKEN_TYPE TokenType, PHANDLE phNewToken) { ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG )); BOOL bRet; HANDLE hToken = NULL; HANDLE * phLocToken = &hToken; _asm { push phLocToken; push TokenType; push ImpersonationLevel; push lpTokenAttributes; push dwDesiredAccess; push hExistingToken; call Prolog__DuplicateTokenEx; mov bRet,eax; }; if (phNewToken) *phNewToken = hToken; if (hToken) { g_TBT.Add(hToken); } return bRet; } void _declspec(naked) Prolog__DuplicateHandle(){ _asm { // this is the space for the "saved istructions" nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; nop ; // this is the place for the JMP nop ; nop ; nop ; nop ; nop ; nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist nop ; // dist } } BOOL WINAPI _I_DuplicateHandle( HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions) { ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG )); BOOL bRet; HANDLE hToken = NULL; HANDLE * phLocToken = &hToken; _asm { push dwOptions; push bInheritHandle; push dwDesiredAccess; push phLocToken; push hTargetProcessHandle; push hSourceHandle; push hSourceProcessHandle; call Prolog__DuplicateHandle; mov bRet,eax; }; if (lpTargetHandle) *lpTargetHandle = hToken; if (hToken) { g_TBT.Add(hToken); } return bRet; } void intercept2(WCHAR * Module, LPSTR Function, VOID * NewRoutine, VOID * pPrologStorage, DWORD Size) { FARPROC OldRoutine = GetProcAddress(GetModuleHandleW(Module),Function); if (OldRoutine) { MEMORY_BASIC_INFORMATION MemBI; DWORD dwOldProtect; BOOL bRet, bRet2; DWORD dwRet; dwRet = VirtualQuery(OldRoutine,&MemBI,sizeof(MemBI)); bRet = VirtualProtect(MemBI.BaseAddress, MemBI.RegionSize, PAGE_EXECUTE_WRITECOPY, &dwOldProtect); dwRet = VirtualQuery(pPrologStorage,&MemBI,sizeof(MemBI)); bRet2 = VirtualProtect(MemBI.BaseAddress, MemBI.RegionSize, PAGE_EXECUTE_WRITECOPY, &dwOldProtect); if (bRet && bRet2) { VOID * pToJump = (VOID *)NewRoutine; BYTE Arr[SIZE_JUMP_ADR] = { 0xe9 }; LONG * pOffset = (LONG *)&Arr[1]; * pOffset = (LONG)NewRoutine - (LONG)OldRoutine - SIZE_JUMP_ADR ; // save the old code memcpy(pPrologStorage,OldRoutine,Size); // put the new code memset(OldRoutine,0x90,Size); memcpy(OldRoutine,Arr,SIZE_JUMP_ADR); // adjust the prolog to continue * pOffset = (LONG)OldRoutine + Size - (LONG)pPrologStorage - SIZE_SAVED_INSTR - SIZE_JUMP_ADR; // magic for nops memcpy((BYTE *)pPrologStorage+SIZE_SAVED_INSTR,Arr,SIZE_JUMP_ADR); } } else { OutputDebugStringA("GetProcAddress FAIL\n"); } } void unintercept(WCHAR * Module, LPSTR Function, VOID * pPrologStorage, DWORD Size) { FARPROC OldRoutine = GetProcAddress(GetModuleHandleW(Module),Function); if (OldRoutine) { memcpy((void *)OldRoutine,pPrologStorage,Size); } } #endif /*_X86_*/ #ifndef STATUS_POSSIBLE_DEADLOCK #define STATUS_POSSIBLE_DEADLOCK (0xC0000194L) #endif class CSetVectoredHandler { private: // static ULONG_PTR Base; // static ULONG_PTR Limit; PVOID pVectorHandler; enum ExceptionTypes { StatusAccessViolation, CXXException, StatusNoMemory, OtherExceptions, LastException }; static LONG ExceptionCounters[LastException]; /* BOOL GetDllLimits(WCHAR * pDllName) { UNICODE_STRING DllName; RtlInitUnicodeString(&DllName,pDllName); PEB_LDR_DATA * pLdr = NtCurrentPeb()->Ldr; LIST_ENTRY * pHeadEntry = &pLdr->InLoadOrderModuleList; LIST_ENTRY * pEntry = pLdr->InLoadOrderModuleList.Flink; BOOL bFound = FALSE; while (pHeadEntry != pEntry) { LDR_DATA_TABLE_ENTRY * pData = CONTAINING_RECORD(pEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); if (0 == wbem_wcsicmp(DllName.Buffer,pData->BaseDllName.Buffer)) { //OutputDebugStringA("found\n"); Base = (ULONG_PTR)pData->DllBase; Limit = Base + (ULONG_PTR)pData->SizeOfImage; bFound = TRUE; break; } pEntry = pEntry->Flink; } return bFound; } */ public: CSetVectoredHandler() { pVectorHandler = NULL; //if (GetDllLimits(L"fastprox.dll")) //{ pVectorHandler = AddVectoredExceptionHandler(TRUE,CSetVectoredHandler::VectoredHandler); //} }; ~CSetVectoredHandler() { if (pVectorHandler) RemoveVectoredExceptionHandler(pVectorHandler); }; static LONG WINAPI VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo) { PEXCEPTION_RECORD pExr = ExceptionInfo->ExceptionRecord; PCONTEXT pCxr = ExceptionInfo->ContextRecord; switch (pExr->ExceptionCode) { case STATUS_PRIVILEGED_INSTRUCTION: case STATUS_INVALID_HANDLE: case STATUS_STACK_OVERFLOW: case STATUS_POSSIBLE_DEADLOCK: case STATUS_ACCESS_VIOLATION: InterlockedIncrement(&ExceptionCounters[(LONG)StatusAccessViolation]); DebugBreak(); break; case 0xe06d7363: InterlockedIncrement(&ExceptionCounters[(LONG)CXXException]); break; case STATUS_NO_MEMORY: InterlockedIncrement(&ExceptionCounters[(LONG)StatusNoMemory]); break; default: InterlockedIncrement(&ExceptionCounters[(LONG)OtherExceptions]); break; } return EXCEPTION_CONTINUE_SEARCH; } } g_C; LONG CSetVectoredHandler::ExceptionCounters[CSetVectoredHandler::LastException]; #endif // // // Run The Serivce // /////////////////////////////////////////////// void RunService(DWORD dwNumServicesArgs, LPWSTR *lpServiceArgVectors) { MyService ThisService(SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_PAUSE_CONTINUE); ThisService.Run(SERVICE_NAME, dwNumServicesArgs, lpServiceArgVectors, (void *)&ThisService); } // // // ServiceMain // /////////////////////////////////////////////////////////// VOID WINAPI ServiceMain(DWORD dwNumServicesArgs, LPWSTR *lpServiceArgVectors) { #ifdef INSTRUMENTED_BUILD #ifdef _X86_ intercept2(L"ntdll.dll","RtlFreeHeap",_I_RtlFreeHeap,Prolog__RtlFreeHeap,5); intercept2(L"ntdll.dll","RtlAllocateHeap",_I_RtlAllocateHeap,Prolog__RtlAllocateHeap,5); intercept2(L"ntdll.dll","RtlReAllocateHeap",_I_RtlReAllocateHeap,Prolog__RtlReAllocateHeap,5); intercept2(L"ntdll.dll","RtlValidateHeap",_I_RtlValidateHeap,Prolog__RtlValidateHeap,7); intercept2(L"kernel32.dll","CreateEventW",_I_CreateEvent,Prolog__CreateEvent,6); intercept2(L"kernel32.dll","WriteFile",_I_WriteFile,Prolog__WriteFile,7); intercept2(L"kernel32.dll","ReadFile",_I_ReadFile,Prolog__ReadFile,7); intercept2(L"kernel32.dll","MoveFileW",_I_MoveFileW,Prolog__MoveFileW,6); /* intercept2(L"ntdll.dll","NtClose",_I_NtClose,Prolog__NtClose,5); intercept2(L"ntdll.dll","NtOpenThreadToken",_I_NtOpenThreadToken,Prolog__NtOpenThreadToken,5); intercept2(L"ntdll.dll","NtOpenProcessToken",_I_NtOpenProcessToken,Prolog__NtOpenProcessToken,5); intercept2(L"advapi32.dll","DuplicateTokenEx",_I_DuplicateTokenEx,Prolog__DuplicateTokenEx,6); intercept2(L"kernel32.dll","DuplicateHandle",_I_DuplicateHandle,Prolog__DuplicateHandle,7); */ g_nSuccConn = 0; #endif /*_X86_*/ #endif RegSetDWORD(HKEY_LOCAL_MACHINE, HOME_REG_PATH, TEXT("ProcessID"), GetCurrentProcessId()); #ifdef DBG if (InitialBreak()) { DebugBreak(); } #endif g_ProgRes.Init(); g_ProgRes.Phase1Build(); RunService(dwNumServicesArgs,lpServiceArgVectors); #ifdef INSTRUMENTED_BUILD #ifdef _X86_ unintercept(L"ntdll.dll","RtlFreeHeap",Prolog__RtlFreeHeap,5); unintercept(L"ntdll.dll","RtlAllocateHeap",Prolog__RtlAllocateHeap,5); unintercept(L"ntdll.dll","RtlReAllocateHeap",Prolog__RtlReAllocateHeap,5); unintercept(L"ntdll.dll","RtlValidateHeap",Prolog__RtlValidateHeap,7); unintercept(L"kernel32.dll","CreateEventW",Prolog__CreateEvent,6); unintercept(L"kernel32.dll","WriteFile",Prolog__WriteFile,7); unintercept(L"kernel32.dll","ReadFile",Prolog__ReadFile,7); unintercept(L"kernel32.dll","MoveFileW",Prolog__MoveFileW,6); /* unintercept(L"ntdll.dll","NtOpenThreadToken",Prolog__NtOpenThreadToken,5); unintercept(L"ntdll.dll","NtOpenProcessToken",Prolog__NtOpenProcessToken,5); unintercept(L"ntdll.dll","NtClose",Prolog__NtClose,5); unintercept(L"advapi32.dll","DuplicateTokenEx",Prolog__DuplicateTokenEx,6); unintercept(L"kernel32.dll","DuplicateHandle",Prolog__DuplicateHandle,7); */ #endif /*_X86_*/ #endif }